> On Oct 29, 2026, at 11:50, Ritesh Harjani (IBM) <[email protected]> wrote:
> 
> Muchun Song <[email protected] <mailto:[email protected]>> writes:
> 
>> Hi Ritesh,
>> 
>>> On Oct 27, 2026, at 11:22, Ritesh Harjani (IBM) <[email protected]> 
>>> wrote:
>>> 
>>> radix__vmemmap_populate() is asked for one 16MB section, which is 16KB of
>>> struct pages. With no altmap it rounds the request down to a PMD leaf.
>>> That leaf describes 2GB of PFNs with 64KB pages (128MB with 4KB pages),
>>> so it also covers sections that are not present yet. It cannot be freed
>>> while any of those sections are still in use.
>>> 
>>> A devdax namespace that lands in the same window is marked for vmemmap 
>>> dedup.
>>> vmemmap_populate_compound_pages() treated the leaf as an existing huge 
>>> mapping
>>> and skipped it. The core then initializes only the head vmemmap page and 
>>> assumes
>>> the rest is the shared tail. Those remaining tail slots are real struct 
>>> pages
>>> still holding the page_init_poison() pattern and are not the shared tail 
>>> pages.
>> 
>> Right.
>> 
>>> __init_single_page() warns on the zone mismatch and the following pageblock 
>>> init
>>> faults in __set_pfnblock_flags_mask().
>> 
>> Yeah, the new adding warning is useful.
>> 
>>> 
>>> If the section's vmemmap is already a PMD leaf, clear its compound order
>> 
>> I think it's enough to fix this issue.
>> 
> 
> Oh yes, right! since the page init is done later and the optimizable
> order can be read from mem_section.
> 
>>> and reuse the leaf, so every struct page in the section is initialized.
>>> The shared-tail layout needs base-page PTEs, so it cannot be built on top of
>>> this leaf and dropping the leaf is not an option while the neighbouring 
>>> range
>>> is still using it. So, fail the compound populate if a leaf is still seen 
>>> there.
>>> 
>>> <Call Trace>
>>> ============
>>> [    3.467060][    T1] WARNING: mm/mm_init.c:600 at 
>>> __init_single_page+0xd0/0xf4, CPU#0: swapper/0/1
>>> <...>
>>> [    3.477419][    T1] NIP [c000000000576b30] __init_single_page+0xd0/0xf4
>>> [    3.477827][    T1] LR [c0000000005778b0] 
>>> __init_zone_device_page+0x30/0xb8
>>> [    3.478444][    T1] Call Trace:
>>> [    3.478764][    T1]  0x10000 (unreliable)
>>> [    3.479874][    T1]  memmap_init_zone_device+0x164/0x430
>>> [    3.480392][    T1]  memremap_pages+0x43c/0x93c
>>> [    3.480836][    T1]  devm_memremap_pages+0x3c/0xa4
>>> [    3.481328][    T1]  dev_dax_probe+0x264/0x3d0
>>> [    3.481817][    T1]  dax_bus_probe+0x140/0x1c8
>>> [    3.482237][    T1]  really_probe+0x108/0x580
>>> [    3.482681][    T1]  __driver_probe_device+0xcc/0x284
>>> [    3.483186][    T1]  driver_probe_device+0x5c/0x108
>>> [    3.483656][    T1]  __device_attach_driver+0x10c/0x1e8
>>> [    3.484134][    T1]  bus_for_each_drv+0xc0/0x13c
>>> <...>
>>> [    3.499972][    T1] BUG: Kernel NULL pointer dereference on read at 
>>> 0x00001400
>>> [    3.500417][    T1] Faulting instruction address: 0xc0000000005f4ecc
>>> [    3.500417][    T1] Faulting instruction address: 0xc0000000005f4ecc
>>> cpu 0x0: Vector: 300 (Data Access) at [c000000006756b50]
>>>   pc: c0000000005f4ecc: __set_pfnblock_flags_mask.constprop.0+0x34/0x160
>>>   lr: c000000000577f38: memmap_init_zone_device+0x358/0x430
>>>   pid   = 1, comm = swapper/0
>>> enter ? for help
>>> memmap_init_zone_device+0x358/0x430
>>> memmap_init_zone_device+0x220/0x430 (unreliable)
>>> memremap_pages+0x43c/0x93c
>>> devm_memremap_pages+0x3c/0xa4
>>> dev_dax_probe+0x264/0x3d0
>>> dax_bus_probe+0x140/0x1c8
>>> really_probe+0x108/0x580
>>> <...>
>>> 
>>> Fixes: bd0862382adb ("mm/sparse-vmemmap: drop Device DAX-specific 
>>> population path")
>> 
>> Actually, the right Fixes is:
>> 
>> Fixes: f2b79c0d7968 ("powerpc/book3s64/radix: add support for vmemmap 
>> optimization for radix")
>> 
>> On older kernels, these errors are silent. They trigger a kernel panic when 
>> the user
>> actually uses Device DAX, rather than during the initialization phase. 
>> 
>> So, for older kernels, we should guide them to backport the patch.
>> 
>>> Reported-by: Pavithra <[email protected]>
>>> Assisted-by: LLM
>>> Signed-off-by: Ritesh Harjani (IBM) <[email protected]>
>>> ---
>>> Fixes tag here is added since the fix is dependent upon the change 
>>> mentioned in
>>> "Fixes" tag. The Fixes commit-id is from mm-new branch. Although this could 
>>> be
>>> an older pre-existing issue, but got exposed after this patch series.
>> 
>> I knew this issue, so I have a local commit to fix it as well. I'd like to 
>> share
>> it with you, because it looks a little simple, does it work for you?
>> 
>> powerpc/mm: fix uninitialized ZONE_DEVICE struct pages with PMDs
>> 
>> PowerPC radix vmemmap population can reuse an existing PMD mapping while
>> populating a device DAX range whose section is marked as HVO-enabled. The
>> reused mapping is an ordinary vmemmap mapping: the redundant tail struct
>> pages are not remapped to the shared tail page.
>> 
>> Leaving the section marked as HVO-enabled makes later ZONE_DEVICE
>> initialization treat the range as optimized and initialize only the struct
>> pages that would be backed by a real HVO mapping. The remaining tail struct
>> pages can then be left uninitialized even though they are still used as
>> metadata for the device DAX compound page.
>> 
> 
> Here, feel free to use the call trace from my commit msg to show what goes
> wrong w/o this fix.

No problem. Thanks for your detailed msg.

> 
>> The Fixes target predates the section-based vmemmap optimization
>> infrastructure, so older kernels do not have section state that can be
>> marked non-HVO. Backports to such kernels need to handle the PMD-reuse
>> case in powerpc radix code directly, for example by initializing the tail
>> struct pages that core ZONE_DEVICE initialization would otherwise skip.
>> 
>> Mark the section as non-HVO when reusing an existing PMD mapping, so the
>> section's HVO state matches the actual vmemmap layout and all required
>> struct pages are initialized.
>> 
>> Fixes: f2b79c0d7968 ("powerpc/book3s64/radix: add support for vmemmap 
>> optimization for radix")
>> Signed-off-by: Muchun Song <[email protected]>
>> ---
>> arch/powerpc/mm/book3s64/radix_pgtable.c | 11 ++++++++++-
>> 1 file changed, 10 insertions(+), 1 deletion(-)
> 
> yes, love this approach. Thanks for sharing the fix.
> 
>> 
>> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
>> b/arch/powerpc/mm/book3s64/radix_pgtable.c
>> index 72793ace1fb6..fc3a2d4b422d 100644
>> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
>> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
>> @@ -1200,7 +1200,16 @@ static int __meminit 
>> vmemmap_populate_compound_pages(unsigned long start_pfn,
>>                      return -ENOMEM;
>> 
>>              if (pmd_leaf(READ_ONCE(*pmd))) {
>> -                    /* existing huge mapping. Skip the range */
>> +                    unsigned long addr_pfn = page_to_pfn((struct page 
>> *)addr);
>> +                    struct mem_section *ms = __pfn_to_section(addr_pfn);
>> +
>> +                    /*
>> +                     * Existing PMD mappings can cover the edges of a valid
>> +                     * HVO populate range.  They are ordinary vmemmap 
>> mappings,
>> +                     * so the current section must not be treated as 
>> HVO-backed
>> +                     * when its struct pages are initialized later.
>> +                     */
>> +                    section_set_order(ms, 0);
> 
> I think you meant "section_set_compound_order(ms, 0);"

Yes, because it's been sitting on my disk for a while, and I forgot that
this part needed to be adapted.

> 
> yes, otherwise the patch looks good to me. Can you please post this
> patch separately then? Feel free to add:
> 
> Reviewed-by: Ritesh Harjani (IBM) <[email protected] 
> <mailto:[email protected]>>

Thanks for your review. I'll send it ASAP.

> 
> I have validated the fix with my custom reproducer and I see the issue
> is fixed with this. Meanwhile, Pavithra (cc'd) is testing this and few
> other patches of your series. Once her testing is finished, she can help
> provide her Tested-by/feedback if any.

Thanks a lot to both of you for testing this.

Thanks,
Muchun

> 
>>                      next = pmd_addr_end(addr, end);
>>                      continue;
>>              }
> 
> -ritesh

Reply via email to