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

Yuan Liu posted 2 patches 1 day, 12 hours ago
Documentation/mm/physical_memory.rst | 13 +++++++
drivers/base/memory.c                |  6 +++
include/linux/mmzone.h               | 47 ++++++++++++++++++++++
mm/internal.h                        |  8 +---
mm/memory_hotplug.c                  | 54 ++++++++++++++------------
mm/mm_init.c                         | 58 +++++++++++++++++-----------
6 files changed, 132 insertions(+), 54 deletions(-)
[PATCH v6 0/2] mm/memory_hotplug: optimize zone contiguous check when changing pfn range
Posted by Yuan Liu 1 day, 12 hours ago
This series introduces a pages_with_online_memmap member into struct
zone to avoid pageblock-by-pageblock scans across the entire zone and
improve memory hotplug performance.

Reworked how pages_with_online_memmap accounts for PFNs in early
boot memory in response to Sashiko's review comments [2], which
identified potential issues with the previous implementation.

Approach
========
Add a new zone member pages_with_online_memmap that tracks the number of
pages within the zone span that have an online memory map (including
present pages and memory holes smaller than a subsection whose memory
map has been initialized). When spanned_pages == pages_with_online_memmap
the zone is contiguous and pfn_to_page() can be called on any PFN in the
zone span without further pfn_valid() checks.

For early boot memory, pages_with_online_memmap is calculated in
memmap_init_zone_range(). Since every PFN within a memblock region
satisfies pfn_to_online_page(), the calculation aligns both boundaries
of each memblock range to PAGES_PER_SUBSECTION and counts the aligned
pages that fall within the zone span. If two adjacent memblock regions
share a subsection (i.e. the hole between them is smaller than a
subsection), the overlapping subsection pages are counted only once.
For hotplugged memory, pages_with_online_memmap is updated through
adjust_present_page_count(), which is called during memory online and
offline.

Only pages that fall within the current zone span are accounted towards
pages_with_online_memmap. A "too small" value is safe, it merely
prevents detecting a contiguous zone.

The contiguity check using pages_with_online_memmap is stricter than the
old pageblock-by-pageblock scan. The old set_zone_contiguous() iterated
at pageblock granularity via pageblock_pfn_to_page(), so a zone could be
marked contiguous even if a subsection-sized hole existed within a
pageblock. The new check requires spanned_pages == pages_with_online_memmap,
meaning every PFN in the zone span must satisfy pfn_to_online_page().

Performance
===========
1. For VM hotplug performance data, please refer to Patch 1.
2. This series also benefits CXL hotplug. Performance results are
   as follows
   https://lore.kernel.org/all/20260409023552.GA2807@AE/

Tested cases
============
1. Hotplug/unplug correctness with both online_movable and online
   policies, including partial unplug, middle-block offline gaps, and
   edge-block span shrink.
2. Large scale (256G/512G) plug/unplug performance.
3. Boot-time subsection holes (aligned/unaligned, in-zone and
   cross-zone) with correct pages_with_online_memmap accounting.
4. kernelcore=mirror: verified no overcounting.

Patch overview
==============
This series is based on the kernelcore-mirror branch [1].

Patch 1 introduces pages_with_online_memmap to replace
pageblock-by-pageblock scans across the entire zone for zone contiguity
checks.

Patch 2 avoids incorrectly shrinking the zone span during memory unplug
when a memory or hole boundary falls in the middle of a subsection.

v6 changes:
  1. Dropped patches 1-3 from v5. The kernelcore=mirror overlap issue
     that caused pages_with_online_memmap to be overcounted has been
     resolved by the series [1].
  2. Reworked pages_with_online_memmap accounting during early boot.

v5:
    https://lore.kernel.org/linux-mm/20260520093457.3719960-1-yuan1.liu@intel.com/

v4:
    https://lore.kernel.org/linux-mm/20260421125508.2317429-1-yuan1.liu@intel.com/

v3:
    https://lore.kernel.org/linux-mm/20260408031615.1831922-1-yuan1.liu@intel.com/

[1] https://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git/log/?h=kernelcore-mirror
[2] https://sashiko.dev/#/patchset/20260520093457.3719960-3-yuan1.liu@intel.com

Yuan Liu (2):
  mm/memory_hotplug: optimize zone contiguous check when changing pfn
    range
  mm/memory_hotplug: improve shrink_zone_span() subsection boundary
    checks

 Documentation/mm/physical_memory.rst | 13 +++++++
 drivers/base/memory.c                |  6 +++
 include/linux/mmzone.h               | 47 ++++++++++++++++++++++
 mm/internal.h                        |  8 +---
 mm/memory_hotplug.c                  | 54 ++++++++++++++------------
 mm/mm_init.c                         | 58 +++++++++++++++++-----------
 6 files changed, 132 insertions(+), 54 deletions(-)


base-commit: b69c2a1fa9beb4c3db24b4013e07f5cb7e7260aa
-- 
2.47.3