10 hotfixes. 8 are cc:stable. 9 are for MM.

There's a 3-patch series of DAMON fixes from Josh Law and SeongJae Park.
 The rest are singletons - please see the changelogs for details.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCacgT5AAKCRDdBJ7gKXxA
 jgYVAQDLam92lD7fD0IwdOFE36zlOcJNK4WjHSEf2y9fFFnUWQD/QPnVX+q7fR5t
 ZE8ZKhVkMa2w6A2VISdt9Msqm++5RQg=
 =oCV1
 -----END PGP SIGNATURE-----

Merge tag 'mm-hotfixes-stable-2026-03-28-10-45' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc fixes from Andrew Morton:
 "10 hotfixes.  8 are cc:stable.  9 are for MM.

  There's a 3-patch series of DAMON fixes from Josh Law and SeongJae
  Park. The rest are singletons - please see the changelogs for details"

* tag 'mm-hotfixes-stable-2026-03-28-10-45' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  mm/mseal: update VMA end correctly on merge
  bug: avoid format attribute warning for clang as well
  mm/pagewalk: fix race between concurrent split and refault
  mm/memory: fix PMD/PUD checks in follow_pfnmap_start()
  mm/damon/sysfs: check contexts->nr in repeat_call_fn
  mm/damon/sysfs: check contexts->nr before accessing contexts_arr[0]
  mm/damon/sysfs: fix param_ctx leak on damon_sysfs_new_test_ctx() failure
  mm/swap: fix swap cache memcg accounting
  MAINTAINERS, mailmap: update email address for Harry Yoo
  mm/huge_memory: fix folio isn't locked in softleaf_to_folio()
master
Linus Torvalds 2026-03-28 14:19:55 -07:00
commit 0bcb517f0a
9 changed files with 77 additions and 32 deletions

View File

@ -316,6 +316,7 @@ Hans Verkuil <hverkuil@kernel.org> <hverkuil-cisco@xs4all.nl>
Hans Verkuil <hverkuil@kernel.org> <hansverk@cisco.com>
Hao Ge <hao.ge@linux.dev> <gehao@kylinos.cn>
Harry Yoo <harry.yoo@oracle.com> <42.hyeyoo@gmail.com>
Harry Yoo <harry@kernel.org> <harry.yoo@oracle.com>
Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>
Heiko Carstens <hca@linux.ibm.com> <heiko.carstens@de.ibm.com>
Heiko Stuebner <heiko@sntech.de> <heiko.stuebner@bqreaders.com>

View File

@ -16883,7 +16883,7 @@ M: Lorenzo Stoakes <ljs@kernel.org>
R: Rik van Riel <riel@surriel.com>
R: Liam R. Howlett <Liam.Howlett@oracle.com>
R: Vlastimil Babka <vbabka@kernel.org>
R: Harry Yoo <harry.yoo@oracle.com>
R: Harry Yoo <harry@kernel.org>
R: Jann Horn <jannh@google.com>
L: linux-mm@kvack.org
S: Maintained
@ -24349,7 +24349,7 @@ F: drivers/nvmem/layouts/sl28vpd.c
SLAB ALLOCATOR
M: Vlastimil Babka <vbabka@kernel.org>
M: Harry Yoo <harry.yoo@oracle.com>
M: Harry Yoo <harry@kernel.org>
M: Andrew Morton <akpm@linux-foundation.org>
R: Hao Li <hao.li@linux.dev>
R: Christoph Lameter <cl@gentwo.org>

View File

@ -363,6 +363,23 @@ static inline unsigned long softleaf_to_pfn(softleaf_t entry)
return swp_offset(entry) & SWP_PFN_MASK;
}
static inline void softleaf_migration_sync(softleaf_t entry,
struct folio *folio)
{
/*
* Ensure we do not race with split, which might alter tail pages into new
* folios and thus result in observing an unlocked folio.
* This matches the write barrier in __split_folio_to_order().
*/
smp_rmb();
/*
* Any use of migration entries may only occur while the
* corresponding page is locked
*/
VM_WARN_ON_ONCE(!folio_test_locked(folio));
}
/**
* softleaf_to_page() - Obtains struct page for PFN encoded within leaf entry.
* @entry: Leaf entry, softleaf_has_pfn(@entry) must return true.
@ -374,11 +391,8 @@ static inline struct page *softleaf_to_page(softleaf_t entry)
struct page *page = pfn_to_page(softleaf_to_pfn(entry));
VM_WARN_ON_ONCE(!softleaf_has_pfn(entry));
/*
* Any use of migration entries may only occur while the
* corresponding page is locked
*/
VM_WARN_ON_ONCE(softleaf_is_migration(entry) && !PageLocked(page));
if (softleaf_is_migration(entry))
softleaf_migration_sync(entry, page_folio(page));
return page;
}
@ -394,12 +408,8 @@ static inline struct folio *softleaf_to_folio(softleaf_t entry)
struct folio *folio = pfn_folio(softleaf_to_pfn(entry));
VM_WARN_ON_ONCE(!softleaf_has_pfn(entry));
/*
* Any use of migration entries may only occur while the
* corresponding folio is locked.
*/
VM_WARN_ON_ONCE(softleaf_is_migration(entry) &&
!folio_test_locked(folio));
if (softleaf_is_migration(entry))
softleaf_migration_sync(entry, folio);
return folio;
}

View File

@ -173,10 +173,8 @@ struct bug_entry *find_bug(unsigned long bugaddr)
return module_find_bug(bugaddr);
}
__diag_push();
__diag_ignore(GCC, all, "-Wsuggest-attribute=format",
"Not a valid __printf() conversion candidate.");
static void __warn_printf(const char *fmt, struct pt_regs *regs)
static __printf(1, 0)
void __warn_printf(const char *fmt, struct pt_regs *regs)
{
if (!fmt)
return;
@ -195,7 +193,6 @@ static void __warn_printf(const char *fmt, struct pt_regs *regs)
printk("%s", fmt);
}
__diag_pop();
static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long bugaddr, struct pt_regs *regs)
{

View File

@ -1524,8 +1524,10 @@ static int damon_sysfs_commit_input(void *data)
if (IS_ERR(param_ctx))
return PTR_ERR(param_ctx);
test_ctx = damon_sysfs_new_test_ctx(kdamond->damon_ctx);
if (!test_ctx)
if (!test_ctx) {
damon_destroy_ctx(param_ctx);
return -ENOMEM;
}
err = damon_commit_ctx(test_ctx, param_ctx);
if (err)
goto out;
@ -1618,9 +1620,12 @@ static int damon_sysfs_repeat_call_fn(void *data)
if (!mutex_trylock(&damon_sysfs_lock))
return 0;
if (sysfs_kdamond->contexts->nr != 1)
goto out;
damon_sysfs_upd_tuned_intervals(sysfs_kdamond);
damon_sysfs_upd_schemes_stats(sysfs_kdamond);
damon_sysfs_upd_schemes_effective_quotas(sysfs_kdamond);
out:
mutex_unlock(&damon_sysfs_lock);
return 0;
}
@ -1747,6 +1752,9 @@ static int damon_sysfs_update_schemes_tried_regions(
static int damon_sysfs_handle_cmd(enum damon_sysfs_cmd cmd,
struct damon_sysfs_kdamond *kdamond)
{
if (cmd != DAMON_SYSFS_CMD_OFF && kdamond->contexts->nr != 1)
return -EINVAL;
switch (cmd) {
case DAMON_SYSFS_CMD_ON:
return damon_sysfs_turn_damon_on(kdamond);

View File

@ -6815,11 +6815,16 @@ retry:
pudp = pud_offset(p4dp, address);
pud = pudp_get(pudp);
if (pud_none(pud))
if (!pud_present(pud))
goto out;
if (pud_leaf(pud)) {
lock = pud_lock(mm, pudp);
if (!unlikely(pud_leaf(pud))) {
pud = pudp_get(pudp);
if (unlikely(!pud_present(pud))) {
spin_unlock(lock);
goto out;
} else if (unlikely(!pud_leaf(pud))) {
spin_unlock(lock);
goto retry;
}
@ -6831,9 +6836,16 @@ retry:
pmdp = pmd_offset(pudp, address);
pmd = pmdp_get_lockless(pmdp);
if (!pmd_present(pmd))
goto out;
if (pmd_leaf(pmd)) {
lock = pmd_lock(mm, pmdp);
if (!unlikely(pmd_leaf(pmd))) {
pmd = pmdp_get(pmdp);
if (unlikely(!pmd_present(pmd))) {
spin_unlock(lock);
goto out;
} else if (unlikely(!pmd_leaf(pmd))) {
spin_unlock(lock);
goto retry;
}

View File

@ -56,7 +56,6 @@ static int mseal_apply(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
struct vm_area_struct *vma, *prev;
unsigned long curr_start = start;
VMA_ITERATOR(vmi, mm, start);
/* We know there are no gaps so this will be non-NULL. */
@ -66,6 +65,7 @@ static int mseal_apply(struct mm_struct *mm,
prev = vma;
for_each_vma_range(vmi, vma, end) {
const unsigned long curr_start = MAX(vma->vm_start, start);
const unsigned long curr_end = MIN(vma->vm_end, end);
if (!(vma->vm_flags & VM_SEALED)) {
@ -79,7 +79,6 @@ static int mseal_apply(struct mm_struct *mm,
}
prev = vma;
curr_start = curr_end;
}
return 0;

View File

@ -97,6 +97,7 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
pud_t pudval = pudp_get(pud);
pmd_t *pmd;
unsigned long next;
const struct mm_walk_ops *ops = walk->ops;
@ -105,6 +106,24 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
int err = 0;
int depth = real_depth(3);
/*
* For PTE handling, pte_offset_map_lock() takes care of checking
* whether there actually is a page table. But it also has to be
* very careful about concurrent page table reclaim.
*
* Similarly, we have to be careful here - a PUD entry that points
* to a PMD table cannot go away, so we can just walk it. But if
* it's something else, we need to ensure we didn't race something,
* so need to retry.
*
* A pertinent example of this is a PUD refault after PUD split -
* we will need to split again or risk accessing invalid memory.
*/
if (!pud_present(pudval) || pud_leaf(pudval)) {
walk->action = ACTION_AGAIN;
return 0;
}
pmd = pmd_offset(pud, addr);
do {
again:
@ -218,12 +237,12 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
else if (pud_leaf(*pud) || !pud_present(*pud))
continue; /* Nothing to do. */
if (pud_none(*pud))
goto again;
err = walk_pmd_range(pud, addr, next, walk);
if (err)
break;
if (walk->action == ACTION_AGAIN)
goto again;
} while (pud++, addr = next, addr != end);
return err;

View File

@ -494,6 +494,10 @@ static struct folio *__swap_cache_prepare_and_add(swp_entry_t entry,
__folio_set_locked(folio);
__folio_set_swapbacked(folio);
if (!charged && mem_cgroup_swapin_charge_folio(folio, NULL, gfp, entry))
goto failed;
for (;;) {
ret = swap_cache_add_folio(folio, entry, &shadow);
if (!ret)
@ -514,11 +518,6 @@ static struct folio *__swap_cache_prepare_and_add(swp_entry_t entry,
goto failed;
}
if (!charged && mem_cgroup_swapin_charge_folio(folio, NULL, gfp, entry)) {
swap_cache_del_folio(folio);
goto failed;
}
memcg1_swapin(entry, folio_nr_pages(folio));
if (shadow)
workingset_refault(folio, shadow);