Re: [PATCH 42/46] mm/huge_memory: split huge PUDs when adjusting VMA boundaries
From: David Hildenbrand (Arm)
Date: Thu Oct 29 2026 - 11:40:57 EST
On 10/29/26 15:40, David Hildenbrand (Arm) wrote:
> On 10/29/26 15:31, Kiryl Shutsemau wrote:
>> On Thu, Oct 29, 2026 at 03:24:29PM +0100, David Hildenbrand (Arm) wrote:
>>>
>>> __split_huge_pud() must split a leave. Either by zapping it (what we do right
>>> now) or by populating page tables (as in Usama's PoC).
>>
>> No, meant the situation when pud_leaf() is true, but split_pud is false,
>> so __split_huge_pud() is never hit. pud_present() is true so we proceed
>> to pmd_offset()
>
> Oh, yeah, I can add a WARN_ON_ONCE() for that, it would be a bug in the software.
Ah, or I can just drop the split_pud check. Let me do that.
+static void split_huge_leaf(struct vm_area_struct *vma,
+ unsigned long address)
+{
+ const bool split_pud = pud_split_required(vma, address);
+ const bool split_pmd = pmd_split_required(vma, address);
+ pgd_t *pgd;
+ p4d_t *p4d;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ /*
+ * mmap, VMA and rmap write locks protect the walk; the split helpers
+ * take the page table locks.
+ */
+ if (!split_pud && !split_pmd)
+ return;
+
+ pgd = pgd_offset(vma->vm_mm, address);
+ if (!pgd_present(*pgd))
+ return;
+
+ p4d = p4d_offset(pgd, address);
+ if (!p4d_present(*p4d))
+ return;
+
+ pud = pud_offset(p4d, address);
+ if (pud_leaf(*pud))
+ __split_huge_pud(vma, pud, address);
+ if (!split_pmd || !pud_present(*pud))
+ return;
+
+ pmd = pmd_offset(pud, address);
+ __split_huge_pmd(vma, pmd, address, false);
}
--
Cheers,
David