From: Wei Yang <richard.weiyang@gmail.com>
To: Yuan Liu <yuan1.liu@intel.com>
Cc: David Hildenbrand <david@kernel.org>,
Oscar Salvador <osalvador@suse.de>,
Mike Rapoport <rppt@kernel.org>,
Wei Yang <richard.weiyang@gmail.com>,
linux-mm@kvack.org, Nanhai Zou <nanhai.zou@intel.com>,
Chen Zhang <zhangchen.kidd@jd.com>,
Jason Zeng <jason.zeng@intel.com>, Chen Yu <yu.c.chen@intel.com>,
Pan Deng <pan.deng@intel.com>, Tianyou Li <tianyou.li@intel.com>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v10 2/2] mm/memory_hotplug: optimize zone contiguous check when changing pfn range
Date: Tue, 22 Sep 2026 12:51:45 +0000 [thread overview]
Message-ID: <20260922125145.3fygpy7gxoztsa3n@master> (raw)
In-Reply-To: <20260920084946.3266279-3-yuan1.liu@intel.com>
On Sun, Sep 20, 2026 at 04:49:46AM -0400, Yuan Liu wrote:
>When move_pfn_range_to_zone() or remove_pfn_range_from_zone() updates a
>zone, set_zone_contiguous() rescans the entire zone pageblock-by-pageblock
>to rebuild zone->contiguous. For large zones this is a significant cost
>during memory hotplug and hot-unplug.
>
>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 whose memory map has been
>initialized and for which pfn_to_online_page() succeeds.
>
>For early boot memory, pages_with_online_memmap is calculated in
>memmap_init_zone_range(). PFNs initialized by memmap_init_range() are
>included in pages_with_online_memmap, and hole PFNs for which
>pfn_to_online_page() succeeds are also counted in
>init_unavailable_range(). For hotplugged memory,
>pages_with_online_memmap is updated through adjust_present_page_count(),
>which is called during memory online and offline operations. When
>spanned_pages == pages_with_online_memmap, every PFN in the zone span
>has a valid memmap entry, so pfn_to_page() can be called for any PFN
>within the zone span without an additional pfn_valid() check.
>
>Note: this counter may temporarily undercount when pages with an
>online memory map exist outside the current zone span. Such pages
>are only created during boot, when initializing the memory map of
>pages that do not fall into any zone span. The undercount itself
>can only happen after boot, during memory hotplug, when growing
>the zone to cover such pages and later shrinking it back, which
>may result in a "too small" value. This is safe: it merely
>prevents detecting a contiguous zone.
>
>Here is an example (page numbers are just for illustration purposes):
> after boot:
> [ zone span ]
> [ zone pages ]
> spanned=10, initialized=15, online=10
> online == spanned -> contiguous
>
> growing after hotplug (hotplug 5):
> [ zone span ]
> [ zone pages ] [ zone pages ]
> spanned=30, initialized=20, online=15
> online != spanned -> not contiguous
>
> shrinking after hotunplug (hotunplug 5 again):
> [ zone span ]
> [ zone pages ]
> spanned=15, initialized=15, online=10
> online != spanned -> not contiguous although contiguous
>
>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().
>
>The following test cases of memory hotplug for a VM [1], tested in the
>environment [2], show that this optimization can significantly reduce the
>memory hotplug time [3].
>
>+----------------+------+---------------+--------------+----------------+
>| | Size | Time (before) | Time (after) | Time Reduction |
>| +------+---------------+--------------+----------------+
>| Plug Memory | 256G | 10s | 3s | 70% |
>| +------+---------------+--------------+----------------+
>| | 512G | 36s | 7s | 81% |
>+----------------+------+---------------+--------------+----------------+
>
>+----------------+------+---------------+--------------+----------------+
>| | Size | Time (before) | Time (after) | Time Reduction |
>| +------+---------------+--------------+----------------+
>| Unplug Memory | 256G | 11s | 4s | 64% |
>| +------+---------------+--------------+----------------+
>| | 512G | 36s | 9s | 75% |
>+----------------+------+---------------+--------------+----------------+
>
>[1] Qemu commands to hotplug 256G/512G memory for a VM:
> object_add memory-backend-ram,id=hotmem0,size=256G/512G,share=on
> device_add virtio-mem-pci,id=vmem1,memdev=hotmem0,bus=port1
> qom-set vmem1 requested-size 256G/512G (Plug Memory)
> qom-set vmem1 requested-size 0G (Unplug Memory)
>
>[2] Hardware : Intel Icelake server
> Guest Kernel : v7.3-rc3
> Qemu : v9.0.0
>
> Launch VM :
> qemu-system-x86_64 -accel kvm -cpu host \
> -drive file=./Centos10_cloud.qcow2,format=qcow2,if=virtio \
> -drive file=./seed.img,format=raw,if=virtio \
> -smp 3,cores=3,threads=1,sockets=1,maxcpus=3 \
> -m 2G,slots=10,maxmem=2052472M \
> -device pcie-root-port,id=port1,bus=pcie.0,slot=1,multifunction=on \
> -device pcie-root-port,id=port2,bus=pcie.0,slot=2 \
> -nographic -machine q35 \
> -nic user,hostfwd=tcp::3000-:22
>
> Guest kernel auto-onlines newly added memory blocks:
> echo online > /sys/devices/system/memory/auto_online_blocks
>
>[3] The time from typing the QEMU commands in [1] to when the output of
> 'grep MemTotal /proc/meminfo' on Guest reflects that all hotplugged
> memory is recognized.
>
>Reported-by: Nanhai Zou <nanhai.zou@intel.com>
>Reported-by: Chen Zhang <zhangchen.kidd@jd.com>
>Tested-by: Yuan Liu <yuan1.liu@intel.com>
>Reviewed-by: Jason Zeng <jason.zeng@intel.com>
>Reviewed-by: Chen Yu <yu.c.chen@intel.com>
>Reviewed-by: Pan Deng <pan.deng@intel.com>
>Co-developed-by: Tianyou Li <tianyou.li@intel.com>
>Signed-off-by: Tianyou Li <tianyou.li@intel.com>
>Signed-off-by: Yuan Liu <yuan1.liu@intel.com>
>Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
LGTM, thanks for the effort.
Reviewed-by: Wei Yang <richard.weiyang@gmail.com>
--
Wei Yang
Help you, Help me
next prev parent reply other threads:[~2026-09-22 12:51 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-20 8:49 [PATCH v10 0/2] " Yuan Liu
2026-09-20 8:49 ` [PATCH v10 1/2] mm/memory_hotplug: make shrink_zone_span() more robust Yuan Liu
2026-09-20 8:49 ` [PATCH v10 2/2] mm/memory_hotplug: optimize zone contiguous check when changing pfn range Yuan Liu
2026-09-22 12:51 ` Wei Yang [this message]
2026-09-22 13:55 ` [PATCH v10 0/2] " David Hildenbrand (Arm)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260922125145.3fygpy7gxoztsa3n@master \
--to=richard.weiyang@gmail.com \
--cc=david@kernel.org \
--cc=jason.zeng@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nanhai.zou@intel.com \
--cc=osalvador@suse.de \
--cc=pan.deng@intel.com \
--cc=rppt@kernel.org \
--cc=tianyou.li@intel.com \
--cc=yu.c.chen@intel.com \
--cc=yuan1.liu@intel.com \
--cc=zhangchen.kidd@jd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®