mm/hugetlb: remove obsolete bootmem cross-zone checks

Bootmem gigantic HugeTLB pages used to be validated again during
gather_bootmem_prealloc_node() and any cross-zone pages were discarded
there.

That validation is no longer needed.  Cross-zone bootmem gigantic pages
are now detected during allocation and freed before they reach the later
bootmem gathering path, so the remaining pages are already zone-valid.

Remove the obsolete cross-zone validation, invalid-page freeing, and the
associated discarded-page accounting.

Link: https://lore.kernel.org/20260612035903.2468601-17-songmuchun@bytedance.com
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Frank van der Linden <fvdl@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Oscar Salvador (SUSE) <osalvador@kernel.org>
Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: Usama Arif <usama.arif@linux.dev>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Muchun Song 2026-06-12 11:59:00 +08:00 committed by Andrew Morton
parent 51d73513dd
commit 4753a8220a
2 changed files with 0 additions and 73 deletions

View File

@ -679,9 +679,6 @@ struct hstate {
#define HUGE_BOOTMEM_ZONES_VALID 0x0002
#define HUGE_BOOTMEM_CMA 0x0004
struct huge_bootmem_page;
bool hugetlb_bootmem_page_zones_valid(int nid, struct huge_bootmem_page *m);
int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list);
int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn);
void wait_for_freed_hugetlb_folios(void);

View File

@ -58,7 +58,6 @@ struct hstate hstates[HUGE_MAX_HSTATE];
__initdata nodemask_t hugetlb_bootmem_nodes;
__initdata struct list_head huge_boot_pages[MAX_NUMNODES];
static unsigned long hstate_boot_nrinvalid[HUGE_MAX_HSTATE] __initdata;
/*
* Due to ordering constraints across the init code for various
@ -3221,57 +3220,6 @@ static void __init prep_and_add_bootmem_folios(struct hstate *h,
}
}
bool __init hugetlb_bootmem_page_zones_valid(int nid,
struct huge_bootmem_page *m)
{
unsigned long start_pfn;
bool valid;
if (m->flags & HUGE_BOOTMEM_ZONES_VALID) {
/*
* Already validated, skip check.
*/
return true;
}
if (hugetlb_bootmem_page_earlycma(m)) {
valid = cma_validate_zones(m->cma);
goto out;
}
start_pfn = virt_to_phys(m) >> PAGE_SHIFT;
valid = !pfn_range_intersects_zones(nid, start_pfn,
pages_per_huge_page(m->hstate));
out:
if (!valid)
hstate_boot_nrinvalid[hstate_index(m->hstate)]++;
return valid;
}
/*
* Free a bootmem page that was found to be invalid (intersecting with
* multiple zones).
*
* Since it intersects with multiple zones, we can't just do a free
* operation on all pages at once, but instead have to walk all
* pages, freeing them one by one.
*/
static void __init hugetlb_bootmem_free_invalid_page(int nid, struct page *page,
struct hstate *h)
{
unsigned long npages = pages_per_huge_page(h);
unsigned long pfn;
while (npages--) {
pfn = page_to_pfn(page);
__init_page_from_nid(pfn, nid);
free_reserved_page(page);
page++;
}
}
/*
* Put bootmem huge pages into the standard lists after mem_map is up.
* Note: This only applies to gigantic (order > MAX_PAGE_ORDER) pages.
@ -3287,17 +3235,6 @@ static void __init gather_bootmem_prealloc_node(unsigned long nid)
struct folio *folio = (void *)page;
h = m->hstate;
if (!hugetlb_bootmem_page_zones_valid(nid, m)) {
/*
* Can't use this page. Initialize the
* page structures if that hasn't already
* been done, and give them to the page
* allocator.
*/
hugetlb_bootmem_free_invalid_page(nid, page, h);
continue;
}
/*
* It is possible to have multiple huge page sizes (hstates)
* in this list. If so, process each size separately.
@ -3692,20 +3629,13 @@ static void __init hugetlb_init_hstates(void)
static void __init report_hugepages(void)
{
struct hstate *h;
unsigned long nrinvalid;
for_each_hstate(h) {
char buf[32];
nrinvalid = hstate_boot_nrinvalid[hstate_index(h)];
h->max_huge_pages -= nrinvalid;
string_get_size(huge_page_size(h), 1, STRING_UNITS_2, buf, 32);
pr_info("HugeTLB: registered %s page size, pre-allocated %ld pages\n",
buf, h->nr_huge_pages);
if (nrinvalid)
pr_info("HugeTLB: %s page size: %lu invalid page%s discarded\n",
buf, nrinvalid, str_plural(nrinvalid));
pr_info("HugeTLB: %d KiB vmemmap can be freed for a %s page\n",
hugetlb_vmemmap_optimizable_size(h) / SZ_1K, buf);
}