From: Mike Rapoport <rppt@kernel.org>
To: Pratyush Yadav <pratyush@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>,
Alexander Graf <graf@amazon.com>,
Muchun Song <muchun.song@linux.dev>,
Oscar Salvador <osalvador@suse.de>,
David Hildenbrand <david@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Jason Miu <jasonmiu@google.com>,
kexec@lists.infradead.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 12/12] mm/hugetlb: make bootmem allocation work with KHO
Date: Sun, 17 May 2026 13:05:27 +0300 [thread overview]
Message-ID: <agmS5yZRflzN1M8U@kernel.org> (raw)
In-Reply-To: <20260429133928.850721-13-pratyush@kernel.org>
Hi Pratyush,
On Wed, Apr 29, 2026 at 03:39:14PM +0200, Pratyush Yadav wrote:
> From: "Pratyush Yadav (Google)" <pratyush@kernel.org>
>
> Gigantic page allocation is somewhat broken currently when KHO is used.
>
> Firstly, they break KHO scratch size accounting. RSRV_KERN is used to
> track how much memory is reserved for use by the kernel. Since
> alloc_bootmem() calls the memblock_alloc*() APIs, the hugepages
> allocated also get marked as RSRV_KERN.
The intended semantics of RSRV_KERN was to distinguish memory reserved
because it's in use by firmware from the memory reserved or allocated by
the kernel. It does not have to be directly used by the kernel, some of
PG_Reserved memory is mapped to user-space and it's not only hugetlb. There
are zero pages, VDSO and maybe something else, I don't remember.
> Allocations marked RSRV_KERN are used by KHO to calculate how much
> scratch space it should reserve to make sure the next kernel has enough
> memory to boot when it is in scratch-only phase. Counting hugepages in
The size of RSRV_KERN allocations is also used in
memblock_estimated_nr_free_pages() that's currently used by
set_max_threads() to set several rlimits and by s390 to allocate colored
zero pages. Excluding hugetlb from that will skew the calculations there.
> that blows up scratch size, and can lead to the scratch allocation
> failing, making KHO unusable. This will show up when huge pages make up
> more than 50% of the system, which is a fairly common use case.
>
> Secondly, while not supported right now, huge pages are user memory and
> can be preserved via KHO. The scratch spaces should not have any
> preserved memory. Allocating hugepages from scratch (on a KHO boot) can
> lead to them being un-preservable.
>
> Introduce memblock_alloc_nid_user(). This does two things: first, it
> instructs __memblock_alloc_range_nid() to not use scratch areas to
> fulfill allocation. If KHO is in scratch-only mode, allocations will
> only be made from extended scratch areas. Second, it removes RSRV_KERN
> from the allocation to make sure it doesn't mess up scratch size
> accounting.
>
> To reduce duplication, introduce __memblock_alloc_range_nid() which does
> exactly what memblock_alloc_range_nid() used to do, but takes the flags
> from its caller. Then make memblock_alloc_range_nid() a wrapper to it.
> This lets memblock_alloc_nid_user() re-use most of the logic without
> causing churn to update all callers of memblock_alloc_range_nid() and
> adding yet another argument to it.
That's neat :)
But I'm not too fond of the memblock_alloc_nid_user() as a concept. That
early at boot everything is still kernel, even though hugetlb pages might
become user afterwards if they are actually consumed.
Another thing, is that adding such global API to memblock could be abused
and suddenly some early code will clear RSRV_KERN for a random pieces of
memory.
If we'd still need a special memblock function for gigantic pages
allocation I'd rather make it explicit that it's for hugetlb and keep it in
mm/internal.h
I was thinking about possible alternative solutions and here's what I came
up with
1. SCRATCH_EXT nicely increases the memory pool available to memblock, but
the decision which memory can be used for which allocations becomes more
complex. It should make sure that SCRATCH is not used for hugetlb, but
OTOH it's preferred for other early allocations. With implicit
interaction between choose_memblock_flags() and should_skip_region()
this seems to me quite a headache.
memblock_reserved_clear_kern() should be changed to something else to
keep set_max_threads() working. And, IMHO, memblock_alloc_nid_user()
should be turned into memblock_alloc_gigantic_hugetlb() and only exposed
to MM code. It's even possible that it will duplicate some of
memblock_alloc_range_nid) rather than use it because hugetlb is always a
special case.
2. Split memblock_reserve() part from kho_mem_retrieve() to run before
hugetlb allocations. With this we won't need new types and APIs, we can
ensure that hugetlb allocations do not use SCRATCH by reserving scratch
areas before hugetlb allocations and releasing them afterwards.
Obviously this is the slowest option as it will slow down all memblock
allocations from the point we memblock_reserve() preserved memory. Still
realistically I wouldn't expect large impact on performance because the
heaviest part there is reserving of the preserved memory that has to
happen anyway. Also, I don't thing that a system that uses a lot of
gigantic pages will have a lot of preserved chunks scattered around.
3. Move the complexity into hugetlb and make it preserve all the gigantic
pages with KHO. This means, though, that we won't be able to increase
the number of gigantic pages after the first boot (although decreasing
it seems easy) and that we need to let scratch auto scaling understand
what were the "normal" memblock allocations and what were the
allocations of the gigantic pages.
4. Invert SCRATCH_EXT logic and instead of freeing large chunks around the
preserved memory to SCRATCH_EXT, reserve memory surrounding the
preserved areas and release scratch_only before hugetlb allocations.
We'd still need to somehow prevent hugetlb allocation spilling into
scratch and there's a nasty piece of releasing the memory around the
preserved chunks. On the bright side, I think it's feasible to defer the
release of those regions and free them when we are already
multithreaded. This probably the most involved alternative but it also
could help with the bottleneck of kho_mem_retrieve() creating too many
memblock.reserved regions.
Thoughts?
> Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org>
> ---
>
> Notes:
> Checkpatch complains here about the alignment of arguments of
> memblock_alloc_range_nid() with open parentheses. That can be ignored
> since the code already was mis-aligned, and for good reason.
>
> include/linux/memblock.h | 4 ++
> mm/hugetlb.c | 19 ++----
> mm/memblock.c | 138 ++++++++++++++++++++++++++++++---------
> 3 files changed, 116 insertions(+), 45 deletions(-)
--
Sincerely yours,
Mike.
prev parent reply other threads:[~2026-05-17 10:05 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-29 13:39 [PATCH 00/12] kho: make boot time huge page allocation work nicely with KHO Pratyush Yadav
2026-04-29 13:39 ` [PATCH 01/12] kho: generalize radix tree APIs Pratyush Yadav
2026-05-04 14:44 ` Pasha Tatashin
2026-05-05 11:20 ` Jork Loeser
2026-05-05 12:54 ` Pratyush Yadav
2026-05-05 13:12 ` Pasha Tatashin
2026-05-11 11:32 ` Mike Rapoport
2026-05-11 16:25 ` Pratyush Yadav
2026-05-13 10:32 ` Mike Rapoport
2026-04-29 13:39 ` [PATCH 02/12] kho: store incoming radix tree in kho_in Pratyush Yadav
2026-05-11 11:43 ` Mike Rapoport
2026-05-11 16:28 ` Pratyush Yadav
2026-05-12 6:46 ` Mike Rapoport
2026-04-29 13:39 ` [PATCH 03/12] kho: add a struct for radix callbacks Pratyush Yadav
2026-05-11 11:47 ` Mike Rapoport
2026-05-11 16:35 ` Pratyush Yadav
2026-05-12 6:48 ` Mike Rapoport
2026-05-12 9:11 ` Pratyush Yadav
2026-04-29 13:39 ` [PATCH 04/12] kho: add callback for table pages Pratyush Yadav
2026-05-11 11:50 ` Mike Rapoport
2026-05-11 16:36 ` Pratyush Yadav
2026-05-11 16:40 ` Pratyush Yadav
2026-04-29 13:39 ` [PATCH 05/12] kho: add data argument to radix walk callback Pratyush Yadav
2026-05-11 11:53 ` Mike Rapoport
2026-05-11 16:37 ` Pratyush Yadav
2026-04-29 13:39 ` [PATCH 06/12] kho: allow early-boot usage of the KHO radix tree Pratyush Yadav
2026-05-11 11:56 ` Mike Rapoport
2026-05-11 16:37 ` Pratyush Yadav
2026-04-29 13:39 ` [PATCH 07/12] kho: allow destroying " Pratyush Yadav
2026-05-11 11:57 ` Mike Rapoport
2026-04-29 13:39 ` [PATCH 08/12] kho: add kho_radix_init_tree() Pratyush Yadav
2026-05-06 10:51 ` Jork Loeser
2026-05-11 11:05 ` Pratyush Yadav
2026-04-29 13:39 ` [PATCH 09/12] memblock: introduce MEMBLOCK_KHO_SCRATCH_EXT Pratyush Yadav
2026-05-11 12:06 ` Mike Rapoport
2026-05-11 16:46 ` Pratyush Yadav
2026-04-29 13:39 ` [PATCH 10/12] kho: extended scratch Pratyush Yadav
2026-05-17 10:17 ` Mike Rapoport
2026-04-29 13:39 ` [PATCH 11/12] kho: return virtual address of mem_map Pratyush Yadav
2026-05-11 12:13 ` Mike Rapoport
2026-05-11 16:48 ` Pratyush Yadav
2026-05-12 6:51 ` Mike Rapoport
2026-04-29 13:39 ` [PATCH 12/12] mm/hugetlb: make bootmem allocation work with KHO Pratyush Yadav
2026-05-17 10:05 ` Mike Rapoport [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=agmS5yZRflzN1M8U@kernel.org \
--to=rppt@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=graf@amazon.com \
--cc=jasonmiu@google.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=muchun.song@linux.dev \
--cc=osalvador@suse.de \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
/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.