Skip to content

Commit

Permalink
Merge tag 'mm-hotfixes-stable-2024-09-03-20-19' of git://git.kernel.o…
Browse files Browse the repository at this point in the history
…rg/pub/scm/linux/kernel/git/akpm/mm

Pull misc fixes from Andrew Morton:
 "17 hotfixes, 15 of which are cc:stable.

  Mostly MM, no identifiable theme.  And a few nilfs2 fixups"

* tag 'mm-hotfixes-stable-2024-09-03-20-19' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  alloc_tag: fix allocation tag reporting when CONFIG_MODULES=n
  mm: vmalloc: optimize vmap_lazy_nr arithmetic when purging each vmap_area
  mailmap: update entry for Jan Kuliga
  codetag: debug: mark codetags for poisoned page as empty
  mm/memcontrol: respect zswap.writeback setting from parent cg too
  scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum
  Revert "mm: skip CMA pages when they are not available"
  maple_tree: remove rcu_read_lock() from mt_validate()
  kexec_file: fix elfcorehdr digest exclusion when CONFIG_CRASH_HOTPLUG=y
  mm/slub: add check for s->flags in the alloc_tagging_slab_free_hook
  nilfs2: fix state management in error path of log writing function
  nilfs2: fix missing cleanup on rollforward recovery error
  nilfs2: protect references to superblock parameters exposed in sysfs
  userfaultfd: don't BUG_ON() if khugepaged yanks our page table
  userfaultfd: fix checks for huge PMDs
  mm: vmalloc: ensure vmap_block is initialised before adding to queue
  selftests: mm: fix build errors on armhf
  • Loading branch information
Linus Torvalds committed Sep 4, 2024
2 parents 88fac17 + 052a45c commit 76c0f27
Show file tree
Hide file tree
Showing 17 changed files with 197 additions and 124 deletions.
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ James Ketrenos <jketreno@io.(none)>
Jan Glauber <jan.glauber@gmail.com> <jang@de.ibm.com>
Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com>
Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com>
Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl>
Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com>
Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com>
Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@tuni.fi>
Expand Down
7 changes: 4 additions & 3 deletions Documentation/admin-guide/cgroup-v2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1717,9 +1717,10 @@ The following nested keys are defined.
entries fault back in or are written out to disk.

memory.zswap.writeback
A read-write single value file. The default value is "1". The
initial value of the root cgroup is 1, and when a new cgroup is
created, it inherits the current value of its parent.
A read-write single value file. The default value is "1".
Note that this setting is hierarchical, i.e. the writeback would be
implicitly disabled for child cgroups if the upper hierarchy
does so.

When this is set to 0, all swapping attempts to swapping devices
are disabled. This included both zswap writebacks, and swapping due
Expand Down
35 changes: 33 additions & 2 deletions fs/nilfs2/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,33 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
brelse(bh);
}

/**
* nilfs_abort_roll_forward - cleaning up after a failed rollforward recovery
* @nilfs: nilfs object
*/
static void nilfs_abort_roll_forward(struct the_nilfs *nilfs)
{
struct nilfs_inode_info *ii, *n;
LIST_HEAD(head);

/* Abandon inodes that have read recovery data */
spin_lock(&nilfs->ns_inode_lock);
list_splice_init(&nilfs->ns_dirty_files, &head);
spin_unlock(&nilfs->ns_inode_lock);
if (list_empty(&head))
return;

set_nilfs_purging(nilfs);
list_for_each_entry_safe(ii, n, &head, i_dirty) {
spin_lock(&nilfs->ns_inode_lock);
list_del_init(&ii->i_dirty);
spin_unlock(&nilfs->ns_inode_lock);

iput(&ii->vfs_inode);
}
clear_nilfs_purging(nilfs);
}

/**
* nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint
* @nilfs: nilfs object
Expand Down Expand Up @@ -773,15 +800,19 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
if (unlikely(err)) {
nilfs_err(sb, "error %d writing segment for recovery",
err);
goto failed;
goto put_root;
}

nilfs_finish_roll_forward(nilfs, ri);
}

failed:
put_root:
nilfs_put_root(root);
return err;

failed:
nilfs_abort_roll_forward(nilfs);
goto put_root;
}

/**
Expand Down
10 changes: 6 additions & 4 deletions fs/nilfs2/segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,9 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
nilfs_abort_logs(&logs, ret ? : err);

list_splice_tail_init(&sci->sc_segbufs, &logs);
if (list_empty(&logs))
return; /* if the first segment buffer preparation failed */

nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
nilfs_free_incomplete_logs(&logs, nilfs);

Expand Down Expand Up @@ -2056,7 +2059,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)

err = nilfs_segctor_begin_construction(sci, nilfs);
if (unlikely(err))
goto out;
goto failed;

/* Update time stamp */
sci->sc_seg_ctime = ktime_get_real_seconds();
Expand Down Expand Up @@ -2120,10 +2123,9 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
return err;

failed_to_write:
if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
nilfs_redirty_inodes(&sci->sc_dirty_files);

failed:
if (mode == SC_LSEG_SR && nilfs_sc_cstage_get(sci) >= NILFS_ST_IFILE)
nilfs_redirty_inodes(&sci->sc_dirty_files);
if (nilfs_doing_gc())
nilfs_redirty_inodes(&sci->sc_gc_inodes);
nilfs_segctor_abort_construction(sci, nilfs, err);
Expand Down
43 changes: 33 additions & 10 deletions fs/nilfs2/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,9 +836,15 @@ ssize_t nilfs_dev_revision_show(struct nilfs_dev_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
struct nilfs_super_block **sbp = nilfs->ns_sbp;
u32 major = le32_to_cpu(sbp[0]->s_rev_level);
u16 minor = le16_to_cpu(sbp[0]->s_minor_rev_level);
struct nilfs_super_block *raw_sb;
u32 major;
u16 minor;

down_read(&nilfs->ns_sem);
raw_sb = nilfs->ns_sbp[0];
major = le32_to_cpu(raw_sb->s_rev_level);
minor = le16_to_cpu(raw_sb->s_minor_rev_level);
up_read(&nilfs->ns_sem);

return sysfs_emit(buf, "%d.%d\n", major, minor);
}
Expand All @@ -856,8 +862,13 @@ ssize_t nilfs_dev_device_size_show(struct nilfs_dev_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
struct nilfs_super_block **sbp = nilfs->ns_sbp;
u64 dev_size = le64_to_cpu(sbp[0]->s_dev_size);
struct nilfs_super_block *raw_sb;
u64 dev_size;

down_read(&nilfs->ns_sem);
raw_sb = nilfs->ns_sbp[0];
dev_size = le64_to_cpu(raw_sb->s_dev_size);
up_read(&nilfs->ns_sem);

return sysfs_emit(buf, "%llu\n", dev_size);
}
Expand All @@ -879,20 +890,32 @@ ssize_t nilfs_dev_uuid_show(struct nilfs_dev_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
struct nilfs_super_block **sbp = nilfs->ns_sbp;
struct nilfs_super_block *raw_sb;
ssize_t len;

return sysfs_emit(buf, "%pUb\n", sbp[0]->s_uuid);
down_read(&nilfs->ns_sem);
raw_sb = nilfs->ns_sbp[0];
len = sysfs_emit(buf, "%pUb\n", raw_sb->s_uuid);
up_read(&nilfs->ns_sem);

return len;
}

static
ssize_t nilfs_dev_volume_name_show(struct nilfs_dev_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
struct nilfs_super_block **sbp = nilfs->ns_sbp;
struct nilfs_super_block *raw_sb;
ssize_t len;

down_read(&nilfs->ns_sem);
raw_sb = nilfs->ns_sbp[0];
len = scnprintf(buf, sizeof(raw_sb->s_volume_name), "%s\n",
raw_sb->s_volume_name);
up_read(&nilfs->ns_sem);

return scnprintf(buf, sizeof(sbp[0]->s_volume_name), "%s\n",
sbp[0]->s_volume_name);
return len;
}

static const char dev_readme_str[] =
Expand Down
2 changes: 1 addition & 1 deletion kernel/kexec_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)

#ifdef CONFIG_CRASH_HOTPLUG
/* Exclude elfcorehdr segment to allow future changes via hotplug */
if (j == image->elfcorehdr_index)
if (i == image->elfcorehdr_index)
continue;
#endif

Expand Down
17 changes: 11 additions & 6 deletions lib/codetag.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ static inline size_t range_size(const struct codetag_type *cttype,
cttype->desc.tag_size;
}

#ifdef CONFIG_MODULES
static void *get_symbol(struct module *mod, const char *prefix, const char *name)
{
DECLARE_SEQ_BUF(sb, KSYM_NAME_LEN);
Expand Down Expand Up @@ -155,6 +154,15 @@ static struct codetag_range get_section_range(struct module *mod,
};
}

static const char *get_mod_name(__maybe_unused struct module *mod)
{
#ifdef CONFIG_MODULES
if (mod)
return mod->name;
#endif
return "(built-in)";
}

static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
{
struct codetag_range range;
Expand All @@ -164,8 +172,7 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
range = get_section_range(mod, cttype->desc.section);
if (!range.start || !range.stop) {
pr_warn("Failed to load code tags of type %s from the module %s\n",
cttype->desc.section,
mod ? mod->name : "(built-in)");
cttype->desc.section, get_mod_name(mod));
return -EINVAL;
}

Expand Down Expand Up @@ -199,6 +206,7 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
return 0;
}

#ifdef CONFIG_MODULES
void codetag_load_module(struct module *mod)
{
struct codetag_type *cttype;
Expand Down Expand Up @@ -248,9 +256,6 @@ bool codetag_unload_module(struct module *mod)

return unload_ok;
}

#else /* CONFIG_MODULES */
static int codetag_module_init(struct codetag_type *cttype, struct module *mod) { return 0; }
#endif /* CONFIG_MODULES */

struct codetag_type *
Expand Down
7 changes: 2 additions & 5 deletions lib/maple_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -7566,14 +7566,14 @@ static void mt_validate_nulls(struct maple_tree *mt)
* 2. The gap is correctly set in the parents
*/
void mt_validate(struct maple_tree *mt)
__must_hold(mas->tree->ma_lock)
{
unsigned char end;

MA_STATE(mas, mt, 0, 0);
rcu_read_lock();
mas_start(&mas);
if (!mas_is_active(&mas))
goto done;
return;

while (!mte_is_leaf(mas.node))
mas_descend(&mas);
Expand All @@ -7594,9 +7594,6 @@ void mt_validate(struct maple_tree *mt)
mas_dfs_postorder(&mas, ULONG_MAX);
}
mt_validate_nulls(mt);
done:
rcu_read_unlock();

}
EXPORT_SYMBOL_GPL(mt_validate);

Expand Down
12 changes: 9 additions & 3 deletions mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -3613,8 +3613,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
memcg1_soft_limit_reset(memcg);
#ifdef CONFIG_ZSWAP
memcg->zswap_max = PAGE_COUNTER_MAX;
WRITE_ONCE(memcg->zswap_writeback,
!parent || READ_ONCE(parent->zswap_writeback));
WRITE_ONCE(memcg->zswap_writeback, true);
#endif
page_counter_set_high(&memcg->swap, PAGE_COUNTER_MAX);
if (parent) {
Expand Down Expand Up @@ -5320,7 +5319,14 @@ void obj_cgroup_uncharge_zswap(struct obj_cgroup *objcg, size_t size)
bool mem_cgroup_zswap_writeback_enabled(struct mem_cgroup *memcg)
{
/* if zswap is disabled, do not block pages going to the swapping device */
return !zswap_is_enabled() || !memcg || READ_ONCE(memcg->zswap_writeback);
if (!zswap_is_enabled())
return true;

for (; memcg; memcg = parent_mem_cgroup(memcg))
if (!READ_ONCE(memcg->zswap_writeback))
return false;

return true;
}

static u64 zswap_current_read(struct cgroup_subsys_state *css,
Expand Down
7 changes: 7 additions & 0 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,13 @@ __always_inline bool free_pages_prepare(struct page *page,
reset_page_owner(page, order);
page_table_check_free(page, order);
pgalloc_tag_sub(page, 1 << order);

/*
* The page is isolated and accounted for.
* Mark the codetag as empty to avoid accounting error
* when the page is freed by unpoison_memory().
*/
clear_page_tag_ref(page);
return false;
}

Expand Down
4 changes: 4 additions & 0 deletions mm/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,10 @@ alloc_tagging_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
if (!mem_alloc_profiling_enabled())
return;

/* slab->obj_exts might not be NULL if it was created for MEMCG accounting. */
if (s->flags & (SLAB_NO_OBJ_EXT | SLAB_NOLEAKTRACE))
return;

obj_exts = slab_obj_exts(slab);
if (!obj_exts)
return;
Expand Down
29 changes: 16 additions & 13 deletions mm/userfaultfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,27 +787,30 @@ static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx,
}

dst_pmdval = pmdp_get_lockless(dst_pmd);
/*
* If the dst_pmd is mapped as THP don't
* override it and just be strict.
*/
if (unlikely(pmd_trans_huge(dst_pmdval))) {
err = -EEXIST;
break;
}
if (unlikely(pmd_none(dst_pmdval)) &&
unlikely(__pte_alloc(dst_mm, dst_pmd))) {
err = -ENOMEM;
break;
}
/* If an huge pmd materialized from under us fail */
if (unlikely(pmd_trans_huge(*dst_pmd))) {
dst_pmdval = pmdp_get_lockless(dst_pmd);
/*
* If the dst_pmd is THP don't override it and just be strict.
* (This includes the case where the PMD used to be THP and
* changed back to none after __pte_alloc().)
*/
if (unlikely(!pmd_present(dst_pmdval) || pmd_trans_huge(dst_pmdval) ||
pmd_devmap(dst_pmdval))) {
err = -EEXIST;
break;
}
if (unlikely(pmd_bad(dst_pmdval))) {
err = -EFAULT;
break;
}

BUG_ON(pmd_none(*dst_pmd));
BUG_ON(pmd_trans_huge(*dst_pmd));
/*
* For shmem mappings, khugepaged is allowed to remove page
* tables under us; pte_offset_map_lock() will deal with that.
*/

err = mfill_atomic_pte(dst_pmd, dst_vma, dst_addr,
src_addr, flags, &folio);
Expand Down
Loading

0 comments on commit 76c0f27

Please sign in to comment.