mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 06:07:32 +02:00
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:
parent
51d73513dd
commit
4753a8220a
|
|
@ -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);
|
||||
|
|
|
|||
70
mm/hugetlb.c
70
mm/hugetlb.c
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user