From: Frank van der Linden <fvdl@google.com>
To: akpm@linux-foundation.org, muchun.song@linux.dev,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Cc: yuzhao@google.com, usamaarif642@gmail.com,
joao.m.martins@oracle.com, roman.gushchin@linux.dev,
Frank van der Linden <fvdl@google.com>
Subject: [PATCH v3 00/28] hugetlb/CMA improvements for large systems
Date: Thu, 6 Feb 2025 18:50:40 +0000 [thread overview]
Message-ID: <20250206185109.1210657-1-fvdl@google.com> (raw)
v3:
* Fix SPDX comment include file format.
* Add new hugetlb_cma.* files to MAINTAINERS
* Document new ranges/ subdir in CMA debugfs.
* Fix powerpc compilation for config without HAVE_BOOTMEM_INFO_NODE
* Fix various other nits found by kernel test robot.
* Use a PFN value of -1 to indicate a non-mirrored mapping
in sparse-vmemmap.c, not 0.
* Fix incorrect if() statement that got mangled in cma.c
v2:
* Add missing CMA debugfs code.
* Minor cleanups in hugetlb_cma changes.
* Move hugetlb_cma code to its own file to further clean
things up.
On large systems, we observed some issues with hugetlb and CMA:
1) When specifying a large number of hugetlb boot pages (hugepages=
on the commandline), the kernel may run out of memory before it
even gets to HVO. For example, if you have a 3072G system, and
want to use 3024 1G hugetlb pages for VMs, that should leave
you plenty of space for the hypervisor, provided you have the
hugetlb vmemmap optimization (HVO) enabled. However, since
the vmemmap pages are always allocated first, and then later
in boot freed, you will actually run yourself out of memory
before you can do HVO. This means not getting all the hugetlb
pages you want, and worse, failure to boot if there is an
allocation failure in the system from which it can't recover.
2) There is a system setup where you might want to use hugetlb_cma
with a large value (say, again, 3024 out of 3072G like above),
and then lower that if system usage allows it, to make room
for non-hugetlb processes. For this, a variation of the problem
above applies: the kernel runs out of unmovable space to allocate
from before you finish boot, since your CMA area takes up all
the space.
3) CMA wants to use one big contiguous area for allocations. Which
fails if you have the aforementioned 3T system with a gap in the
middle of physical memory (like the < 40bits BIOS DMA area seen on
some AMD systems). You then won't be able to set up a CMA area for
one of the NUMA nodes, leading to loss of half of your hugetlb
CMA area.
4) Under the scenario mentioned in 2), when trying to grow the
number of hugetlb pages after dropping it for a while, new
CMA allocations may fail occasionally. This is not unexpected,
some transient references on pages may prevent cma_alloc
from succeeding under memory pressure. However, the hugetlb
code then falls back to a normal contiguous alloc, which may
end up succeeding. This is not always desired behavior. If
you have a large CMA area, then the kernel has a restricted
amount of memory it can do unmovable allocations from (a well
known issue). A normal contiguous alloc may eat further in to
this space.
To resolve these issues, do the following:
* Add hooks to the section init code to do custom initialization
of memmap pages. Hugetlb bootmem (memblock) allocated pages can
then be pre-HVOed. This avoids allocating a large number of
vmemmap pages early in boot, only to have them be freed again
later, and also avoids running out of memory as described under 1).
Using these hooks for hugetlb is optional. It requires moving
hugetlb bootmem allocation to an earlier spot by the architecture.
This has been enabled on x86.
* hugetlb_cma doesn't care about the CMA area it uses being one
large contiguous range. Multiple smaller ranges are fine. The
only requirements are that the areas should be on one NUMA node,
and individual gigantic pages should be allocatable from them. So,
implement multi-range support for CMA, avoiding issue 3).
* Introduce a hugetlb_cma_only option on the commandline. This only
allows allocations from CMA for gigantic pages, if hugetlb_cma=
is also specified.
* With hugetlb_cma_only active, it also makes sense to be able to
pre-allocate gigantic hugetlb pages at boot time from the CMA
area(s). Add a rudimentary early CMA allocation interface, that
just grabs a piece of memblock-allocated space from the CMA
area, which gets marked as allocated in the CMA bitmap
when the CMA area is initialized. With this, hugepages= can
be supported with hugetlb_cma=, making scenario 2) work.
Additionally, fix some minor bugs, with one worth mentioning:
since hugetlb gigantic bootmem pages are allocated by memblock,
they may span multiple zones, as memblock doesn't (and mostly
can't) know about zones. This can cause problems. A hugetlb page
spanning multiple zones is bad, and it's worse with HVO, when
the de-HVO step effectively sneakily re-assigns pages to a
different zone than originally configured, since the tail pages
all inherit the zone from the first 60 tail pages. This condition
is not common, but can be easily reproduced using ZONE_MOVABLE.
To fix this, add checks to see if gigantic bootmem pages intersect
with multiple zones, and do not use them if they do, giving them
back to the page allocator instead.
The first patch is kind of along for the ride, except that
maintaining an available_count for a CMA area is convenient
for the multiple range support.
Frank van der Linden (28):
mm/cma: export total and free number of pages for CMA areas
mm, cma: support multiple contiguous ranges, if requested
mm/cma: introduce cma_intersects function
mm, hugetlb: use cma_declare_contiguous_multi
mm/hugetlb: fix round-robin bootmem allocation
mm/hugetlb: remove redundant __ClearPageReserved
mm/hugetlb: use online nodes for bootmem allocation
mm/hugetlb: convert cmdline parameters from setup to early
x86/mm: make register_page_bootmem_memmap handle PTE mappings
mm/bootmem_info: export register_page_bootmem_memmap
mm/sparse: allow for alternate vmemmap section init at boot
mm/hugetlb: set migratetype for bootmem folios
mm: define __init_reserved_page_zone function
mm/hugetlb: check bootmem pages for zone intersections
mm/sparse: add vmemmap_*_hvo functions
mm/hugetlb: deal with multiple calls to hugetlb_bootmem_alloc
mm/hugetlb: move huge_boot_pages list init to hugetlb_bootmem_alloc
mm/hugetlb: add pre-HVO framework
mm/hugetlb_vmemmap: fix hugetlb_vmemmap_restore_folios definition
mm/hugetlb: do pre-HVO for bootmem allocated pages
x86/setup: call hugetlb_bootmem_alloc early
x86/mm: set ARCH_WANT_SPARSEMEM_VMEMMAP_PREINIT
mm/cma: simplify zone intersection check
mm/cma: introduce a cma validate function
mm/cma: introduce interface for early reservations
mm/hugetlb: add hugetlb_cma_only cmdline option
mm/hugetlb: enable bootmem allocation from CMA areas
mm/hugetlb: move hugetlb CMA code in to its own file
Documentation/ABI/testing/sysfs-kernel-mm-cma | 13 +
.../admin-guide/kernel-parameters.txt | 7 +
Documentation/admin-guide/mm/cma_debugfs.rst | 10 +-
MAINTAINERS | 2 +
arch/powerpc/include/asm/book3s/64/hugetlb.h | 6 +
arch/powerpc/mm/hugetlbpage.c | 1 +
arch/powerpc/mm/init_64.c | 4 +
arch/s390/mm/init.c | 13 +-
arch/x86/Kconfig | 1 +
arch/x86/kernel/setup.c | 4 +-
arch/x86/mm/init_64.c | 16 +-
include/linux/bootmem_info.h | 7 +
include/linux/cma.h | 9 +
include/linux/hugetlb.h | 35 +
include/linux/mm.h | 13 +-
include/linux/mmzone.h | 35 +
mm/Kconfig | 8 +
mm/Makefile | 3 +
mm/bootmem_info.c | 4 +-
mm/cma.c | 739 +++++++++++++++---
mm/cma.h | 46 +-
mm/cma_debug.c | 61 +-
mm/cma_sysfs.c | 20 +
mm/hugetlb.c | 565 ++++++-------
mm/hugetlb_cma.c | 258 ++++++
mm/hugetlb_cma.h | 55 ++
mm/hugetlb_vmemmap.c | 199 ++++-
mm/hugetlb_vmemmap.h | 23 +-
mm/internal.h | 19 +
mm/mm_init.c | 78 +-
mm/sparse-vmemmap.c | 168 +++-
mm/sparse.c | 87 ++-
32 files changed, 2018 insertions(+), 491 deletions(-)
create mode 100644 mm/hugetlb_cma.c
create mode 100644 mm/hugetlb_cma.h
--
2.48.1.502.g6dc24dfdaf-goog
next reply other threads:[~2025-02-06 18:51 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-06 18:50 Frank van der Linden [this message]
2025-02-06 18:50 ` [PATCH v3 01/28] mm/cma: export total and free number of pages for CMA areas Frank van der Linden
2025-02-10 10:22 ` Oscar Salvador
2025-02-10 18:18 ` Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 02/28] mm, cma: support multiple contiguous ranges, if requested Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 03/28] mm/cma: introduce cma_intersects function Frank van der Linden
2025-02-14 10:02 ` Alexander Gordeev
2025-02-06 18:50 ` [PATCH v3 04/28] mm, hugetlb: use cma_declare_contiguous_multi Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 05/28] mm/hugetlb: fix round-robin bootmem allocation Frank van der Linden
2025-02-10 12:57 ` Oscar Salvador
2025-02-10 18:30 ` Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 06/28] mm/hugetlb: remove redundant __ClearPageReserved Frank van der Linden
2025-02-10 13:14 ` Oscar Salvador
2025-02-06 18:50 ` [PATCH v3 07/28] mm/hugetlb: use online nodes for bootmem allocation Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 08/28] mm/hugetlb: convert cmdline parameters from setup to early Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 09/28] x86/mm: make register_page_bootmem_memmap handle PTE mappings Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 10/28] mm/bootmem_info: export register_page_bootmem_memmap Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 11/28] mm/sparse: allow for alternate vmemmap section init at boot Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 12/28] mm/hugetlb: set migratetype for bootmem folios Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 13/28] mm: define __init_reserved_page_zone function Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 14/28] mm/hugetlb: check bootmem pages for zone intersections Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 15/28] mm/sparse: add vmemmap_*_hvo functions Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 16/28] mm/hugetlb: deal with multiple calls to hugetlb_bootmem_alloc Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 17/28] mm/hugetlb: move huge_boot_pages list init " Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 18/28] mm/hugetlb: add pre-HVO framework Frank van der Linden
2025-02-06 18:50 ` [PATCH v3 19/28] mm/hugetlb_vmemmap: fix hugetlb_vmemmap_restore_folios definition Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 20/28] mm/hugetlb: do pre-HVO for bootmem allocated pages Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 21/28] x86/setup: call hugetlb_bootmem_alloc early Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 22/28] x86/mm: set ARCH_WANT_SPARSEMEM_VMEMMAP_PREINIT Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 23/28] mm/cma: simplify zone intersection check Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 24/28] mm/cma: introduce a cma validate function Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 25/28] mm/cma: introduce interface for early reservations Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 26/28] mm/hugetlb: add hugetlb_cma_only cmdline option Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 27/28] mm/hugetlb: enable bootmem allocation from CMA areas Frank van der Linden
2025-02-06 18:51 ` [PATCH v3 28/28] mm/hugetlb: move hugetlb CMA code in to its own file Frank van der Linden
2025-02-10 18:39 ` [PATCH v3 00/28] hugetlb/CMA improvements for large systems Oscar Salvador
2025-02-10 18:56 ` Frank van der Linden
2025-02-10 23:28 ` Andrew Morton
2025-02-11 17:21 ` Frank van der Linden
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=20250206185109.1210657-1-fvdl@google.com \
--to=fvdl@google.com \
--cc=akpm@linux-foundation.org \
--cc=joao.m.martins@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=muchun.song@linux.dev \
--cc=roman.gushchin@linux.dev \
--cc=usamaarif642@gmail.com \
--cc=yuzhao@google.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