From: Mike Rapoport <rppt@kernel.org>
To: "David Hildenbrand (Red Hat)" <david@kernel.org>
Cc: Tianyou Li <tianyou.li@intel.com>,
Oscar Salvador <osalvador@suse.de>,
Wei Yang <richard.weiyang@gmail.com>,
linux-mm@kvack.org, Yong Hu <yong.hu@intel.com>,
Nanhai Zou <nanhai.zou@intel.com>, Yuan Liu <yuan1.liu@intel.com>,
Tim Chen <tim.c.chen@linux.intel.com>,
Qiuxu Zhuo <qiuxu.zhuo@intel.com>,
Yu C Chen <yu.c.chen@intel.com>, Pan Deng <pan.deng@intel.com>,
Chen Zhang <zhangchen.kidd@jd.com>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4] mm/memory hotplug/unplug: Optimize zone->contiguous update when changes pfn range
Date: Tue, 2 Dec 2025 12:57:00 +0200 [thread overview]
Message-ID: <aS7F_ORMLBcAqQTz@kernel.org> (raw)
In-Reply-To: <7633c77b-44eb-41f0-9c3a-1e5034b594e3@kernel.org>
On Mon, Dec 01, 2025 at 07:54:34PM +0100, David Hildenbrand (Red Hat) wrote:
> On 12/1/25 14:22, Tianyou Li wrote:
...
> > void remove_pfn_range_from_zone(struct zone *zone,
> > unsigned long start_pfn,
> > unsigned long nr_pages)
> > @@ -551,6 +577,7 @@ void remove_pfn_range_from_zone(struct zone *zone,
> > const unsigned long end_pfn = start_pfn + nr_pages;
> > struct pglist_data *pgdat = zone->zone_pgdat;
> > unsigned long pfn, cur_nr_pages;
> > + enum zone_contiguous_state contiguous_state = CONTIGUOUS_UNDETERMINED;
> > /* Poison struct pages because they are now uninitialized again. */
> > for (pfn = start_pfn; pfn < end_pfn; pfn += cur_nr_pages) {
> > @@ -571,12 +598,13 @@ void remove_pfn_range_from_zone(struct zone *zone,
> > if (zone_is_zone_device(zone))
> > return;
> > - clear_zone_contiguous(zone);
> > + contiguous_state = clear_zone_contiguous_for_shrinking(
> > + zone, start_pfn, nr_pages);
>
> Reading this again, I wonder whether it would be nicer to have something
> like:
>
> new_contig_state = zone_contig_state_after_shrinking();
> clear_zone_contiguous(zone);
+1
> > +static enum zone_contiguous_state __meminit clear_zone_contiguous_for_growing(
> > + struct zone *zone, unsigned long start_pfn, unsigned long nr_pages)
> > +{
> > + const unsigned long end_pfn = start_pfn + nr_pages;
> > + enum zone_contiguous_state result = CONTIGUOUS_UNDETERMINED;
> > +
> > + /*
> > + * Given the moved pfn range's contiguous property is always true,
> > + * under the conditional of empty zone, the contiguous property should
> > + * be true.
> > + */
>
> I don't think that comment is required.
>
> > + if (zone_is_empty(zone))
> > + result = CONTIGUOUS_DEFINITELY;
> > +
> > + /*
> > + * If the moved pfn range does not intersect with the original zone span,
> > + * the contiguous property is surely false.
> > + */
> > + else if (end_pfn < zone->zone_start_pfn || start_pfn > zone_end_pfn(zone))
> > + result = CONTIGUOUS_DEFINITELY_NOT;
> > +
> > + /*
> > + * If the moved pfn range is adjacent to the original zone span, given
> > + * the moved pfn range's contiguous property is always true, the zone's
> > + * contiguous property inherited from the original value.
> > + */
> > + else if (end_pfn == zone->zone_start_pfn || start_pfn == zone_end_pfn(zone))
> > + result = zone->contiguous ?
> > + CONTIGUOUS_DEFINITELY : CONTIGUOUS_DEFINITELY_NOT;
> > +
> > + /*
> > + * If the original zone's hole larger than the moved pages in the range,
> > + * the contiguous property is surely false.
> > + */
> > + else if (nr_pages < (zone->spanned_pages - zone->present_pages))
> > + result = CONTIGUOUS_DEFINITELY_NOT;
> > +
>
> This is a bit unreadable :)
>
> if (zone_is_empty(zone)) {
> result = CONTIGUOUS_DEFINITELY;
> } else if (...) {
> /* ... */
> ...
> } else if (...) {
> ...
> }
If we update zone state outside this function it can be even simpler:
if (zone_is_empty(zone))
return CONTIGUOUS_DEFINITELY;
if (nr_pages < (zone->spanned_pages - zone->present_pages))
return CONTIGUOUS_DEFINITELY_NOT;
etc.
> > + clear_zone_contiguous(zone);
> > + return result;
> > +}
> > +
> > /*
> > * Associate the pfn range with the given zone, initializing the memmaps
> > * and resizing the pgdat/zone data to span the added pages. After this
> > @@ -752,8 +821,8 @@ void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
> > {
> > struct pglist_data *pgdat = zone->zone_pgdat;
> > int nid = pgdat->node_id;
> > -
> > - clear_zone_contiguous(zone);
> > + const enum zone_contiguous_state contiguous_state =
> > + clear_zone_contiguous_for_growing(zone, start_pfn, nr_pages);
> > if (zone_is_empty(zone))
> > init_currently_empty_zone(zone, start_pfn, nr_pages);
> > @@ -783,7 +852,7 @@ void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
> > MEMINIT_HOTPLUG, altmap, migratetype,
> > isolate_pageblock);
> > - set_zone_contiguous(zone);
> > + set_zone_contiguous(zone, contiguous_state);
> > }
> > struct auto_movable_stats {
> > diff --git a/mm/mm_init.c b/mm/mm_init.c
> > index 7712d887b696..06db3fcf7f95 100644
> > --- a/mm/mm_init.c
> > +++ b/mm/mm_init.c
> > @@ -2263,26 +2263,34 @@ void __init init_cma_pageblock(struct page *page)
> > }
> > #endif
> > -void set_zone_contiguous(struct zone *zone)
> > +void set_zone_contiguous(struct zone *zone, enum zone_contiguous_state state)
> > {
> > unsigned long block_start_pfn = zone->zone_start_pfn;
> > unsigned long block_end_pfn;
> > - block_end_pfn = pageblock_end_pfn(block_start_pfn);
> > - for (; block_start_pfn < zone_end_pfn(zone);
> > - block_start_pfn = block_end_pfn,
> > - block_end_pfn += pageblock_nr_pages) {
> > + if (state == CONTIGUOUS_DEFINITELY) {
> > + zone->contiguous = true;
> > + return;
> > + } else if (state == CONTIGUOUS_DEFINITELY_NOT) {
> > + // zone contiguous has already cleared as false, just return.
Please no C++ style comments.
> > + return;
> > + } else if (state == CONTIGUOUS_UNDETERMINED) {
> > + block_end_pfn = pageblock_end_pfn(block_start_pfn);
> > + for (; block_start_pfn < zone_end_pfn(zone);
> > + block_start_pfn = block_end_pfn,
> > + block_end_pfn += pageblock_nr_pages) {
> > - block_end_pfn = min(block_end_pfn, zone_end_pfn(zone));
> > + block_end_pfn = min(block_end_pfn, zone_end_pfn(zone));
> > - if (!__pageblock_pfn_to_page(block_start_pfn,
> > - block_end_pfn, zone))
> > - return;
> > - cond_resched();
> > - }
> > + if (!__pageblock_pfn_to_page(block_start_pfn,
> > + block_end_pfn, zone))
> > + return;
> > + cond_resched();
> > + }
> > - /* We confirm that there is no hole */
> > - zone->contiguous = true;
> > + /* We confirm that there is no hole */
> > + zone->contiguous = true;
> > + }
> > }
>
>
> switch (state) {
> case CONTIGUOUS_DEFINITELY:
> zone->contiguous = true;
> return;
> case CONTIGUOUS_DEFINITELY_NOT:
> return;
> default:
> break;
> }
> ... unchanged logic.
I was going to suggest rather to drop 'else'
if (state == CONTIGUOUS_DEFINITELY) {
zone->contiguous = true;
return;
}
if (state == CONTIGUOUS_DEFINITELY_NOT)
return;
... unchanged logic.
but I don't feel strongly about it.
--
Sincerely yours,
Mike.
next prev parent reply other threads:[~2025-12-02 10:57 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-01 13:22 [PATCH v4] mm/memory hotplug/unplug: Optimize zone->contiguous update when changes pfn range Tianyou Li
2025-12-01 18:54 ` David Hildenbrand (Red Hat)
2025-12-01 23:40 ` Li, Tianyou
2025-12-02 10:24 ` David Hildenbrand (Red Hat)
2025-12-02 10:41 ` Li, Tianyou
2025-12-08 15:05 ` Li, Tianyou
2025-12-02 10:57 ` Mike Rapoport [this message]
2025-12-03 9:35 ` Li, Tianyou
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=aS7F_ORMLBcAqQTz@kernel.org \
--to=rppt@kernel.org \
--cc=david@kernel.org \
--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=qiuxu.zhuo@intel.com \
--cc=richard.weiyang@gmail.com \
--cc=tianyou.li@intel.com \
--cc=tim.c.chen@linux.intel.com \
--cc=yong.hu@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.