2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

mm/page_alloc: add support for initializing pageblock as isolated

MIGRATE_ISOLATE is a standalone bit, so a pageblock cannot be initialized
to just MIGRATE_ISOLATE.  Add init_pageblock_migratetype() to enable
initialize a pageblock with a migratetype and isolated.

Link: https://lkml.kernel.org/r/20250617021115.2331563-4-ziy@nvidia.com
Signed-off-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kirill A. Shuemov <kirill.shutemov@linux.intel.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Richard Chang <richardycc@google.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Zi Yan 2025-06-16 22:11:11 -04:00 committed by Andrew Morton
parent e904bce2d9
commit 1bc3587a88
9 changed files with 61 additions and 20 deletions

View File

@ -314,7 +314,8 @@ extern int add_memory_driver_managed(int nid, u64 start, u64 size,
mhp_t mhp_flags); mhp_t mhp_flags);
extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
unsigned long nr_pages, unsigned long nr_pages,
struct vmem_altmap *altmap, int migratetype); struct vmem_altmap *altmap, int migratetype,
bool isolate_pageblock);
extern void remove_pfn_range_from_zone(struct zone *zone, extern void remove_pfn_range_from_zone(struct zone *zone,
unsigned long start_pfn, unsigned long start_pfn,
unsigned long nr_pages); unsigned long nr_pages);

View File

@ -41,6 +41,9 @@ static inline void set_pageblock_isolate(struct page *page)
#define MEMORY_OFFLINE 0x1 #define MEMORY_OFFLINE 0x1
#define REPORT_FAILURE 0x2 #define REPORT_FAILURE 0x2
void __meminit init_pageblock_migratetype(struct page *page,
enum migratetype migratetype,
bool isolate);
void set_pageblock_migratetype(struct page *page, enum migratetype migratetype); void set_pageblock_migratetype(struct page *page, enum migratetype migratetype);
bool move_freepages_block_isolate(struct zone *zone, struct page *page, bool move_freepages_block_isolate(struct zone *zone, struct page *page,

View File

@ -1100,8 +1100,8 @@ static void __init kho_release_scratch(void)
ulong pfn; ulong pfn;
for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages)
set_pageblock_migratetype(pfn_to_page(pfn), init_pageblock_migratetype(pfn_to_page(pfn),
MIGRATE_CMA); MIGRATE_CMA, false);
} }
} }

View File

@ -3297,8 +3297,8 @@ static void __init hugetlb_bootmem_init_migratetype(struct folio *folio,
if (folio_test_hugetlb_cma(folio)) if (folio_test_hugetlb_cma(folio))
init_cma_pageblock(folio_page(folio, i)); init_cma_pageblock(folio_page(folio, i));
else else
set_pageblock_migratetype(folio_page(folio, i), init_pageblock_migratetype(folio_page(folio, i),
MIGRATE_MOVABLE); MIGRATE_MOVABLE, false);
} }
} }

View File

@ -820,7 +820,8 @@ extern void *memmap_alloc(phys_addr_t size, phys_addr_t align,
int nid, bool exact_nid); int nid, bool exact_nid);
void memmap_init_range(unsigned long, int, unsigned long, unsigned long, void memmap_init_range(unsigned long, int, unsigned long, unsigned long,
unsigned long, enum meminit_context, struct vmem_altmap *, int); unsigned long, enum meminit_context, struct vmem_altmap *, int,
bool);
#if defined CONFIG_COMPACTION || defined CONFIG_CMA #if defined CONFIG_COMPACTION || defined CONFIG_CMA

View File

@ -747,7 +747,8 @@ static inline void section_taint_zone_device(unsigned long pfn)
*/ */
void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
unsigned long nr_pages, unsigned long nr_pages,
struct vmem_altmap *altmap, int migratetype) struct vmem_altmap *altmap, int migratetype,
bool isolate_pageblock)
{ {
struct pglist_data *pgdat = zone->zone_pgdat; struct pglist_data *pgdat = zone->zone_pgdat;
int nid = pgdat->node_id; int nid = pgdat->node_id;
@ -779,7 +780,8 @@ void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
* are reserved so nobody should be touching them so we should be safe * are reserved so nobody should be touching them so we should be safe
*/ */
memmap_init_range(nr_pages, nid, zone_idx(zone), start_pfn, 0, memmap_init_range(nr_pages, nid, zone_idx(zone), start_pfn, 0,
MEMINIT_HOTPLUG, altmap, migratetype); MEMINIT_HOTPLUG, altmap, migratetype,
isolate_pageblock);
set_zone_contiguous(zone); set_zone_contiguous(zone);
} }
@ -1104,7 +1106,8 @@ int mhp_init_memmap_on_memory(unsigned long pfn, unsigned long nr_pages,
if (mhp_off_inaccessible) if (mhp_off_inaccessible)
page_init_poison(pfn_to_page(pfn), sizeof(struct page) * nr_pages); page_init_poison(pfn_to_page(pfn), sizeof(struct page) * nr_pages);
move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_UNMOVABLE); move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_UNMOVABLE,
false);
for (i = 0; i < nr_pages; i++) { for (i = 0; i < nr_pages; i++) {
struct page *page = pfn_to_page(pfn + i); struct page *page = pfn_to_page(pfn + i);
@ -1175,7 +1178,8 @@ int online_pages(unsigned long pfn, unsigned long nr_pages,
/* associate pfn range with the zone */ /* associate pfn range with the zone */
move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_ISOLATE); move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_MOVABLE,
true);
if (!node_state(nid, N_MEMORY)) { if (!node_state(nid, N_MEMORY)) {
/* Adding memory to the node for the first time */ /* Adding memory to the node for the first time */

View File

@ -228,7 +228,7 @@ static int pagemap_range(struct dev_pagemap *pgmap, struct mhp_params *params,
zone = &NODE_DATA(nid)->node_zones[ZONE_DEVICE]; zone = &NODE_DATA(nid)->node_zones[ZONE_DEVICE];
move_pfn_range_to_zone(zone, PHYS_PFN(range->start), move_pfn_range_to_zone(zone, PHYS_PFN(range->start),
PHYS_PFN(range_len(range)), params->altmap, PHYS_PFN(range_len(range)), params->altmap,
MIGRATE_MOVABLE); MIGRATE_MOVABLE, false);
} }
mem_hotplug_done(); mem_hotplug_done();

View File

@ -685,7 +685,8 @@ void __meminit __init_page_from_nid(unsigned long pfn, int nid)
__init_single_page(pfn_to_page(pfn), pfn, zid, nid); __init_single_page(pfn_to_page(pfn), pfn, zid, nid);
if (pageblock_aligned(pfn)) if (pageblock_aligned(pfn))
set_pageblock_migratetype(pfn_to_page(pfn), MIGRATE_MOVABLE); init_pageblock_migratetype(pfn_to_page(pfn), MIGRATE_MOVABLE,
false);
} }
#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
@ -874,7 +875,8 @@ static void __init init_unavailable_range(unsigned long spfn,
void __meminit memmap_init_range(unsigned long size, int nid, unsigned long zone, void __meminit memmap_init_range(unsigned long size, int nid, unsigned long zone,
unsigned long start_pfn, unsigned long zone_end_pfn, unsigned long start_pfn, unsigned long zone_end_pfn,
enum meminit_context context, enum meminit_context context,
struct vmem_altmap *altmap, int migratetype) struct vmem_altmap *altmap, int migratetype,
bool isolate_pageblock)
{ {
unsigned long pfn, end_pfn = start_pfn + size; unsigned long pfn, end_pfn = start_pfn + size;
struct page *page; struct page *page;
@ -931,7 +933,8 @@ void __meminit memmap_init_range(unsigned long size, int nid, unsigned long zone
* over the place during system boot. * over the place during system boot.
*/ */
if (pageblock_aligned(pfn)) { if (pageblock_aligned(pfn)) {
set_pageblock_migratetype(page, migratetype); init_pageblock_migratetype(page, migratetype,
isolate_pageblock);
cond_resched(); cond_resched();
} }
pfn++; pfn++;
@ -954,7 +957,8 @@ static void __init memmap_init_zone_range(struct zone *zone,
return; return;
memmap_init_range(end_pfn - start_pfn, nid, zone_id, start_pfn, memmap_init_range(end_pfn - start_pfn, nid, zone_id, start_pfn,
zone_end_pfn, MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); zone_end_pfn, MEMINIT_EARLY, NULL, MIGRATE_MOVABLE,
false);
if (*hole_pfn < start_pfn) if (*hole_pfn < start_pfn)
init_unavailable_range(*hole_pfn, start_pfn, zone_id, nid); init_unavailable_range(*hole_pfn, start_pfn, zone_id, nid);
@ -1035,7 +1039,7 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
* because this is done early in section_activate() * because this is done early in section_activate()
*/ */
if (pageblock_aligned(pfn)) { if (pageblock_aligned(pfn)) {
set_pageblock_migratetype(page, MIGRATE_MOVABLE); init_pageblock_migratetype(page, MIGRATE_MOVABLE, false);
cond_resched(); cond_resched();
} }
@ -1996,7 +2000,8 @@ static void __init deferred_free_pages(unsigned long pfn,
/* Free a large naturally-aligned chunk if possible */ /* Free a large naturally-aligned chunk if possible */
if (nr_pages == MAX_ORDER_NR_PAGES && IS_MAX_ORDER_ALIGNED(pfn)) { if (nr_pages == MAX_ORDER_NR_PAGES && IS_MAX_ORDER_ALIGNED(pfn)) {
for (i = 0; i < nr_pages; i += pageblock_nr_pages) for (i = 0; i < nr_pages; i += pageblock_nr_pages)
set_pageblock_migratetype(page + i, MIGRATE_MOVABLE); init_pageblock_migratetype(page + i, MIGRATE_MOVABLE,
false);
__free_pages_core(page, MAX_PAGE_ORDER, MEMINIT_EARLY); __free_pages_core(page, MAX_PAGE_ORDER, MEMINIT_EARLY);
return; return;
} }
@ -2006,7 +2011,8 @@ static void __init deferred_free_pages(unsigned long pfn,
for (i = 0; i < nr_pages; i++, page++, pfn++) { for (i = 0; i < nr_pages; i++, page++, pfn++) {
if (pageblock_aligned(pfn)) if (pageblock_aligned(pfn))
set_pageblock_migratetype(page, MIGRATE_MOVABLE); init_pageblock_migratetype(page, MIGRATE_MOVABLE,
false);
__free_pages_core(page, 0, MEMINIT_EARLY); __free_pages_core(page, 0, MEMINIT_EARLY);
} }
} }
@ -2305,7 +2311,7 @@ void __init init_cma_reserved_pageblock(struct page *page)
set_page_count(p, 0); set_page_count(p, 0);
} while (++p, --i); } while (++p, --i);
set_pageblock_migratetype(page, MIGRATE_CMA); init_pageblock_migratetype(page, MIGRATE_CMA, false);
set_page_refcounted(page); set_page_refcounted(page);
/* pages were reserved and not allocated */ /* pages were reserved and not allocated */
clear_page_tag_ref(page); clear_page_tag_ref(page);
@ -2319,7 +2325,7 @@ void __init init_cma_reserved_pageblock(struct page *page)
*/ */
void __init init_cma_pageblock(struct page *page) void __init init_cma_pageblock(struct page *page)
{ {
set_pageblock_migratetype(page, MIGRATE_CMA); init_pageblock_migratetype(page, MIGRATE_CMA, false);
adjust_managed_page_count(page, pageblock_nr_pages); adjust_managed_page_count(page, pageblock_nr_pages);
page_zone(page)->cma_pages += pageblock_nr_pages; page_zone(page)->cma_pages += pageblock_nr_pages;
} }

View File

@ -544,6 +544,32 @@ __always_inline void set_pageblock_migratetype(struct page *page,
MIGRATETYPE_AND_ISO_MASK); MIGRATETYPE_AND_ISO_MASK);
} }
void __meminit init_pageblock_migratetype(struct page *page,
enum migratetype migratetype,
bool isolate)
{
unsigned long flags;
if (unlikely(page_group_by_mobility_disabled &&
migratetype < MIGRATE_PCPTYPES))
migratetype = MIGRATE_UNMOVABLE;
flags = migratetype;
#ifdef CONFIG_MEMORY_ISOLATION
if (migratetype == MIGRATE_ISOLATE) {
VM_WARN_ONCE(
1,
"Set isolate=true to isolate pageblock with a migratetype");
return;
}
if (isolate)
flags |= BIT(PB_migrate_isolate);
#endif
__set_pfnblock_flags_mask(page, page_to_pfn(page), flags,
MIGRATETYPE_AND_ISO_MASK);
}
#ifdef CONFIG_DEBUG_VM #ifdef CONFIG_DEBUG_VM
static int page_outside_zone_boundaries(struct zone *zone, struct page *page) static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
{ {