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
commit
0bcb517f0a
1
.mailmap
1
.mailmap
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
18
mm/memory.c
18
mm/memory.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue