On Wed, Sep 23, 2026 at 10:24:36AM +0800, Lance Yang wrote:
quoted
mm/khugepaged.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index f49a6710933b..dab421f8233e 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1278,6 +1278,23 @@ static enum scan_result alloc_charge_folio(struct folio **foliop, struct mm_stru
return SCAN_SUCCEED;
}
+static pgtable_t alloc_deposit_pte(struct mm_struct *mm)
+{
+ /*
+ * khugepaged is run from a kernel thread, so need to manually set the
+ * correct memcg so the allocation gets charged correctly.
+ */
+ struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm);
+ struct mem_cgroup *old_memcg = set_active_memcg(memcg);
+ pgtable_t pgtable;
+
+ pgtable = pte_alloc_one(mm);
+
+ set_active_memcg(old_memcg);
+ mem_cgroup_put(memcg);
+ return pgtable;
+}
+
/*
* collapse_huge_page() expects the mmap_lock to be unlocked before entering and
* will always return with the lock unlocked, to avoid holding the mmap_lock@@ -1293,7 +1310,7 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long s
LIST_HEAD(compound_pagelist);
pmd_t *pmd, _pmd;
pte_t *pte = NULL;
- pgtable_t pgtable;
+ pgtable_t pgtable = NULL;
struct folio *folio;
spinlock_t *pmd_ptl, *pte_ptl;
enum scan_result result = SCAN_FAIL;
@@ -1310,6 +1327,12 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long s
goto out_nolock;
}
+ if (is_pmd_order(order)) {
+ pgtable = alloc_deposit_pte(mm);
+ if (!pgtable)
+ goto out_nolock;
One small thing: result is still SCAN_SUCCEED after alloc_charge_folio(),
result = alloc_charge_folio(&folio, mm, cc, order);
if (result != SCAN_SUCCEED)
goto out_nolock;
if (folio_memcg_alloc_deferred(folio)) {
result = SCAN_ALLOC_HUGE_PAGE_FAIL;
goto out_nolock;
}
if (is_pmd_order(order)) {
pgtable = alloc_deposit_pte(mm);
if (!pgtable)
goto out_nolock;
}
so if alloc_deposit_pte() fails, collapse_huge_page() returns success
without installing a PMD.
I see sashiko pointed that out too :)
Cheers, Lance
Sigh ack yeah oops :) I think SCAN_ALLOC_HUGE_PAGE_FAIL is the closest though
it's not allocating a huge page so much as the page table, but gets the correct
MADV_COLLAPSE -ENOMEM back.
(Another case of local AI review not catchign something btw! Sashiko does lean
towards over-reporting/hallucinating but catches more)
Will ask Andrew to update in reply to this patch as a quick thing rather than
respin so quick, and fix up on any respin.
--
Cheers, Lorenzo