The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: "David Hildenbrand (Arm)" <david@kernel.org>
To: "Liu, Yuan1" <yuan1.liu@intel.com>,
	Oscar Salvador <osalvador@suse.de>,
	Mike Rapoport <rppt@kernel.org>,
	Wei Yang <richard.weiyang@gmail.com>
Cc: "linux-mm@kvack.org" <linux-mm@kvack.org>,
	"Zou, Nanhai" <nanhai.zou@intel.com>,
	Chen Zhang <zhangchen.kidd@jd.com>,
	"Zeng, Jason" <jason.zeng@intel.com>,
	"Chen, Yu C" <yu.c.chen@intel.com>,
	"Deng, Pan" <pan.deng@intel.com>,
	"Li, Tianyou" <tianyou.li@intel.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v7 2/2] mm/memory_hotplug: optimize zone contiguous check when changing pfn range
Date: Wed, 26 Aug 2026 11:06:26 +0200	[thread overview]
Message-ID: <819cc4b4-1855-4dbc-adb4-3b18d6fa2924@kernel.org> (raw)
In-Reply-To: <MW4PR11MB6936054EC741918CCFC6FDD6A3A32@MW4PR11MB6936.namprd11.prod.outlook.com>

On 8/21/26 05:17, Liu, Yuan1 wrote:
>> -----Original Message-----
>> From: David Hildenbrand (Arm) <david@kernel.org>
>> Sent: Friday, August 21, 2026 1:46 AM
>> To: Liu, Yuan1 <yuan1.liu@intel.com>; Oscar Salvador <osalvador@suse.de>;
>> Mike Rapoport <rppt@kernel.org>; Wei Yang <richard.weiyang@gmail.com>
>> Cc: linux-mm@kvack.org; Zou, Nanhai <nanhai.zou@intel.com>; Chen Zhang
>> <zhangchen.kidd@jd.com>; Zeng, Jason <jason.zeng@intel.com>; Chen, Yu C
>> <yu.c.chen@intel.com>; Deng, Pan <pan.deng@intel.com>; Li, Tianyou
>> <tianyou.li@intel.com>; linux-kernel@vger.kernel.org
>> Subject: Re: [PATCH v7 2/2] mm/memory_hotplug: optimize zone contiguous
>> check when changing pfn range
>>
>>>
>>> I think there may be an issue here: PAGE_SUBSECTION_MASK is not
>>> defined when CONFIG_FLATMEM is enabled, which would result in a
>>> build failure.
>>
>> Ah, yeah.
>>
>>>
>> until
>> actually
>>>
>>> Hi David
>>>
>>> What about the following approach? It removes the helper and changes
>>> the per-PFN online check to a per-chunk check.
>>>
>>> +       u64 pgcnt = 0, online_pgcnt = 0;
>>> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
>>> +       const unsigned long chunk = PAGES_PER_SUBSECTION;
>>> +#else
>>> +       const unsigned long chunk = epfn - spfn;
>>> +#endif
>>>
>>> -       for_each_valid_pfn(pfn, spfn, epfn) {
>>> -               __init_single_page(pfn_to_page(pfn), pfn, zone, node);
>>> -               __SetPageReserved(pfn_to_page(pfn));
>>> -               pgcnt++;
>>> +       /*
>>> +        * With VMEMMAP, subsection-sized holes can exist, and PFNs
>> within
>>> +        * these holes can fail pfn_to_online_page(). Without VMEMMAP,
>> we
>>> +        * always only have early sections when they are actually
>> online.
>>> +        */
>>> +       for (pfn = spfn; pfn < epfn; pfn += chunk) {
>>> +               const unsigned long chunk_epfn = min(pfn + chunk, epfn);
>>> +               const bool is_online
>> = !IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP) ||
>>> +                                      pfn_to_online_page(pfn);
>>> +               unsigned long p;
>>> +
>>> +               for_each_valid_pfn(p, pfn, chunk_epfn) {
>>> +                       __init_single_page(pfn_to_page(p), p, zone,
>> node);
>>> +                       __SetPageReserved(pfn_to_page(p));
>>> +                       if (is_online)
>>> +                               online_pgcnt++;
>>> +                       pgcnt++;
>>> +               }
>>
>> I'd keep the for_each_valid_pfn() the outer loop.
> 
> Hi David
> 
> Do you mean the following approach? We use for_each_valid_pfn as 
> the outer loop and, with VMEMMAP,check online PFNs 
> in PAGES_PER_SUBSECTION chunks
> 
> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
> +       const unsigned long chunk = PAGES_PER_SUBSECTION;
> +#else
> +       const unsigned long chunk = epfn - spfn;
> +#endif
> +       unsigned long pfn, next_chunk_pfn = spfn;
> +       u64 pgcnt = 0, online_pgcnt = 0;
> +       bool is_online = true;
> 
>         for_each_valid_pfn(pfn, spfn, epfn) {
>                 __init_single_page(pfn_to_page(pfn), pfn, zone, node);
>                 __SetPageReserved(pfn_to_page(pfn));
> +
> +               /*
> +                * With VMEMMAP, subsection-sized holes can exist, and PFNs
> +                * within these holes can fail pfn_to_online_page(). Without
> +                * VMEMMAP, early sections only exist when actually online.
> +                */
> +               if (IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP) &&
> +                   pfn >= next_chunk_pfn) {
> +                       is_online = !!pfn_to_online_page(pfn);
> +                       next_chunk_pfn = min(pfn + chunk, epfn);
> +               }
> +               if (is_online)
> +                       online_pgcnt++;
> +

It's hard to get it any cleaner. I was wondering whether we should just have a separate
for_each_online_pfn() call afterwards, but that's also not ideal.

I was wondering whether we should also just use pfn_section_valid() directly.

Something like the following:


diff --git a/mm/mm_init.c b/mm/mm_init.c
index e9c4204b73adb..cc7d55a71a060 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -838,22 +838,39 @@ overlap_memmap_init(unsigned long zone, unsigned long *pfn)
  *   zone/node above the hole except for the trailing pages in the last
  *   section that will be appended to the zone/node below.
  */
-static void __init init_unavailable_range(unsigned long spfn,
-                                         unsigned long epfn,
-                                         int zone, int node)
+static unsigned long __init init_unavailable_range(unsigned long spfn,
+                                                  unsigned long epfn,
+                                                  int zone, int node)
 {
+       unsigned long next_chunk_pfn __maybe_unused = spfn;
        unsigned long pfn;
-       u64 pgcnt = 0;
+       u64 online_pgcnt = 0, pgcnt = 0;
+       bool is_online = true;
 
        for_each_valid_pfn(pfn, spfn, epfn) {
                __init_single_page(pfn_to_page(pfn), pfn, zone, node);
                __SetPageReserved(pfn_to_page(pfn));
                pgcnt++;
+
+               /*
+                * With vmemmap, at this stage all pages in an early section
+                * have a valid memmap and are marked as online. However, only
+                * subsections in the subsection map are actually online.
+                */
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+               if (pfn >= next_chunk_pfn) {
+                       is_online = pfn_section_valid(__pfn_to_section(pfn), pfn);
+                       next_chunk_pfn = min(SUBSECTION_ALIGN_UP(pfn + 1), epfn);
+               }
+#endif
+               if (is_online)
+                       online_pgcnt++;
        }
 
        if (pgcnt)
                pr_info("On node %d, zone %s: %lld pages in unavailable ranges\n",
                        node, zone_names[zone], pgcnt);
+       return online_pgcnt;
 }
 
 /*


I'd love to avoid any CONFIG_SPARSEMEM_VMEMMAP, but that's hard as well :)

-- 
Cheers,

David

      reply	other threads:[~2026-08-26  9:06 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-18  8:57 [PATCH v7 0/2] mm/memory_hotplug: optimize zone contiguous check when changing pfn range Yuan Liu
2026-08-18  8:57 ` [PATCH v7 1/2] mm/memory_hotplug: make shrink_zone_span() more robust Yuan Liu
2026-08-20 12:52   ` Liu, Yuan1
2026-08-21  3:14   ` Wei Yang
2026-08-21  9:32     ` David Hildenbrand (Arm)
2026-08-18  8:57 ` [PATCH v7 2/2] mm/memory_hotplug: optimize zone contiguous check when changing pfn range Yuan Liu
2026-08-19 14:56   ` Mike Rapoport
2026-08-19 15:43     ` David Hildenbrand (Arm)
2026-08-19 15:53   ` David Hildenbrand (Arm)
2026-08-20 13:21     ` Liu, Yuan1
2026-08-20 17:46       ` David Hildenbrand (Arm)
2026-08-21  3:17         ` Liu, Yuan1
2026-08-26  9:06           ` David Hildenbrand (Arm) [this message]

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=819cc4b4-1855-4dbc-adb4-3b18d6fa2924@kernel.org \
    --to=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=richard.weiyang@gmail.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