Re: [PATCH v6 1/2] mm/memory_hotplug: optimize zone contiguous check when changing pfn range

Wei Yang <[email protected]>
Newsgroups org.kvack.linux-mm,org.kernel.vger.linux-kernel
Message-ID <20260809031205.h6skr3uluj3cnn7t@master>
On Fri, Aug 07, 2026 at 12:15:42PM +0000, Liu, Yuan1 wrote:
>> -----Original Message-----
>> From: David Hildenbrand (Arm) <[email protected]>
>> Sent: Friday, August 7, 2026 7:30 PM
>> To: Liu, Yuan1 <[email protected]>; Oscar Salvador <[email protected]>;
>> Mike Rapoport <[email protected]>; Wei Yang <[email protected]>
>> Cc: [email protected]; Zou, Nanhai <[email protected]>; Deng, Pan
>> <[email protected]>; Li, Tianyou <[email protected]>; Chen Zhang
>> <[email protected]>; Zeng, Jason <[email protected]>; linux-
>> [email protected]
>> Subject: Re: [PATCH v6 1/2] mm/memory_hotplug: optimize zone contiguous
>> check when changing pfn range
>> 
>> On 8/6/26 11:52, Liu, Yuan1 wrote:
>> >> -----Original Message-----
>> >> From: David Hildenbrand (Arm) <[email protected]>
>> >> Sent: Thursday, August 6, 2026 4:46 PM
>> >> To: Liu, Yuan1 <[email protected]>; Oscar Salvador
>> <[email protected]>;
>> >> Mike Rapoport <[email protected]>; Wei Yang <[email protected]>
>> >> Cc: [email protected]; Zou, Nanhai <[email protected]>; Deng, Pan
>> >> <[email protected]>; Li, Tianyou <[email protected]>; Chen Zhang
>> >> <[email protected]>; Zeng, Jason <[email protected]>; linux-
>> >> [email protected]
>> >> Subject: Re: [PATCH v6 1/2] mm/memory_hotplug: optimize zone contiguous
>> >> check when changing pfn range
>> >>
>> >>
>> >>>
>> >>> Will do.
>> >>>
>> >>>
>> >>> pages_with_online_memmap counts all PFNs where pfn_to_online_page() is
>> >>> valid. With CONFIG_SPARSEMEM_VMEMMAP, pfn_section_valid() operates at
>> >>> PAGES_PER_SUBSECTION granularity — when any page in a subsection has
>> >>> memory, the entire subsection is valid/online. So we align to
>> subsection
>> >>> boundaries to include hole pages within partially-populated
>> subsections.
>> >>
>> >> But we must never account exceeding the zone range. So I don't
>> understand
>> >> why we
>> >> would have to care about PAGES_PER_SUBSECTION here at all?
>> >
>> > We never account beyond the zone range, because `sub_start` and
>> > `sub_end` are still clamped to the zone boundaries after the
>> > alignment.
>> >
>> > The subsection alignment is needed for hole PFNs between memblocks
>> > within the zone. These hole PFNs are valid for
>> > `pfn_to_online_page()`, because they sit in a subsection that has
>> > memory, so the whole subsection's memmap is online.
>> >
>> > |----------- zone range -----------|
>> >
>> > +-----------+---------+------------+
>> > + memblock 1|  hole   | memblock 2 |
>> > +-----------+---------+------------+
>> >                ^
>> >                |
>> >                |
>> >      subsection boundary
>> 
>> Right, but init_unavailable_range() can just return how many were actually
>> initalized? Why can't we piggy-back on that?
>> 
>> I think we had something similar previously, why can't we use that?
>> 
>> We know the zone span, so we can just account all the mmap in the zone
>> span
>> that we initialize.
>> 
>> What is the problem with that?
>
>Hi David
>
>My understanding is that init_unavailable_range() initializes all
>PFNs that satisfy pfn_valid(), but not all of them satisfy
>pfn_to_online_page(), since some PFNs belong to subsections that are
>not online.
>
>You previously mentioned:
>
>  pfn_valid() says early sections always have a full memmap, so even invalid
>  subsections have a memmap. pfn_to_online_page() says an invalid subsection
>  cannot be online and its content must be stale. for_each_valid_pfn() follows
>  pfn_valid() semantics, and we use it to initialize memmap that is not going
>  to be online and account it as pages_with_online_memmap, which is wrong.
>
>  The cleanest approach is to avoid allocating memmap for subsections, which
>  also removes the special early-section handling from pfn_valid() and
>  for_each_valid_pfn().
>
>I also share the concerns raised by Sashiko in the analysis below [1]:
>
>  Scanners like isolate_migratepages_block() will then blindly iterate through
>  the pageblock and access the completely uninitialized struct pages of the hole,
>  leading to functional errors or kernel panics when reading these zero-filled
>  structures via macros like PageHuge() or page_zone().
>
>That's why we went with the current approach in v6 instead of your
>earlier suggestion. I'd really appreciate your guidance on which
>direction you think would be more appropriate.
>
>[1] https://sashiko.dev/#/patchset/20260520093457.3719960-1-yuan1.liu%40intel.com
>

Hi, Yuan & David

One thing I found is __pageblock_pfn_to_page() is ambiguous when pageblock
contains 2 subsections.

The subsection size is fixed, which is 2^21=2M. But pageblock is not fixed
size. If !CONFIG_HUGETLB_PAGE && !CONFIG_TRANSPARENT_HUGEPAGE, default
pageblock size is 4K * 2 ^ 10 = 4M, which contains 2 subsection.

For a pageblock in early section, __paeblock_pfn_to_page() result is
different when the hole is at the beginning or at the end.

Like what I did in [1], I punch a hole in Zone Normal with 2M size.

If the hole is at the beginning of the pageblock, the zone is non-contiguous.

  [    0.004079]  memory[0x2]     [0x0000000100000000-0x000000013fffffff], 0x0000000040000000 bytes on node 0 flags: 0x0
  [    0.004080]  memory[0x3]     [0x0000000140200000-0x00000001bfffffff], 0x000000007fe00000 bytes on node 0 flags: 0x0
  
If the hole is at the end of the pageblock, the zone is contiguous.

  [    0.004068]  memory[0x2]     [0x0000000100000000-0x00000001401fffff], 0x0000000040200000 bytes on node 0 flags: 0x0
  [    0.004068]  memory[0x3]     [0x0000000140400000-0x00000001bfffffff], 0x000000007fc00000 bytes on node 0 flags: 0x0

The reason is in __pageblock_pfn_to_page() we have different requirement for
start_pfn and end_pfn.

Hmm... and things would be complicated as pageblock is PAGE based but
subsection is size based. If we have large PAGE_SIZE...

Also when pageblock_pfn_to_page() is introduced in commit 7d49d8868336 ("mm,
compaction: reduce zone checking frequency in the migration scanner"), we
assume there won't be [node0 node1 node0] interleave within a single pageblock.
Would this still stand for large PAGE_SIZE?

[1]: https://lore.kernel.org/all/[email protected]/T/#u

>Best Regards,
>Liu, Yuan
>
>> Cheers,
>> 
>> David

-- 
Wei Yang
Help you, Help me
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.