From: Robin Holt <holt@xxxxxxx> Currently, memmap_init_zone() has all the smarts for initializing a single page. When we convert to initializing pages in a 2MiB chunk, we will need to do this equivalent work from two separate places so we are breaking out a helper function. Signed-off-by: Robin Holt <holt@xxxxxxx> Signed-off-by: Nathan Zimmer <nzimmer@xxxxxxx> To: "H. Peter Anvin" <hpa@xxxxxxxxx> To: Ingo Molnar <mingo@xxxxxxxxxx> Cc: Linux Kernel <linux-kernel@xxxxxxxxxxxxxxx> Cc: Linux MM <linux-mm@xxxxxxxxx> Cc: Rob Landley <rob@xxxxxxxxxxx> Cc: Mike Travis <travis@xxxxxxx> Cc: Daniel J Blueman <daniel@xxxxxxxxxxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Greg KH <gregkh@xxxxxxxxxxxxxxxxxxx> Cc: Yinghai Lu <yinghai@xxxxxxxxxx> Cc: Mel Gorman <mgorman@xxxxxxx> --- mm/mm_init.c | 2 +- mm/page_alloc.c | 73 +++++++++++++++++++++++++++++++-------------------------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/mm/mm_init.c b/mm/mm_init.c index c280a02..be8a539 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -128,7 +128,7 @@ void __init mminit_verify_pageflags_layout(void) BUG_ON(or_mask != add_mask); } -void __meminit mminit_verify_page_links(struct page *page, enum zone_type zone, +void mminit_verify_page_links(struct page *page, enum zone_type zone, unsigned long nid, unsigned long pfn) { BUG_ON(page_to_nid(page) != nid); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5adf81e..df3ec13 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -697,6 +697,45 @@ static void free_one_page(struct zone *zone, struct page *page, int order, spin_unlock(&zone->lock); } +static void __init_single_page(unsigned long pfn, unsigned long zone, int nid) +{ + struct page *page = pfn_to_page(pfn); + struct zone *z = &NODE_DATA(nid)->node_zones[zone]; + + set_page_links(page, zone, nid, pfn); + mminit_verify_page_links(page, zone, nid, pfn); + init_page_count(page); + page_mapcount_reset(page); + page_nid_reset_last(page); + SetPageReserved(page); + + /* + * Mark the block movable so that blocks are reserved for + * movable at startup. This will force kernel allocations + * to reserve their blocks rather than leaking throughout + * the address space during boot when many long-lived + * kernel allocations are made. Later some blocks near + * the start are marked MIGRATE_RESERVE by + * setup_zone_migrate_reserve() + * + * bitmap is created for zone's valid pfn range. but memmap + * can be created for invalid pages (for alignment) + * check here not to call set_pageblock_migratetype() against + * pfn out of zone. + */ + if ((z->zone_start_pfn <= pfn) + && (pfn < zone_end_pfn(z)) + && !(pfn & (pageblock_nr_pages - 1))) + set_pageblock_migratetype(page, MIGRATE_MOVABLE); + + INIT_LIST_HEAD(&page->lru); +#ifdef WANT_PAGE_VIRTUAL + /* The shift won't overflow because ZONE_NORMAL is below 4G. */ + if (!is_highmem_idx(zone)) + set_page_address(page, __va(pfn << PAGE_SHIFT)); +#endif +} + static bool free_pages_prepare(struct page *page, unsigned int order) { int i; @@ -3951,7 +3990,6 @@ static void setup_zone_migrate_reserve(struct zone *zone) void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, unsigned long start_pfn, enum memmap_context context) { - struct page *page; unsigned long end_pfn = start_pfn + size; unsigned long pfn; struct zone *z; @@ -3972,38 +4010,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, if (!early_pfn_in_nid(pfn, nid)) continue; } - page = pfn_to_page(pfn); - set_page_links(page, zone, nid, pfn); - mminit_verify_page_links(page, zone, nid, pfn); - init_page_count(page); - page_mapcount_reset(page); - page_nid_reset_last(page); - SetPageReserved(page); - /* - * Mark the block movable so that blocks are reserved for - * movable at startup. This will force kernel allocations - * to reserve their blocks rather than leaking throughout - * the address space during boot when many long-lived - * kernel allocations are made. Later some blocks near - * the start are marked MIGRATE_RESERVE by - * setup_zone_migrate_reserve() - * - * bitmap is created for zone's valid pfn range. but memmap - * can be created for invalid pages (for alignment) - * check here not to call set_pageblock_migratetype() against - * pfn out of zone. - */ - if ((z->zone_start_pfn <= pfn) - && (pfn < zone_end_pfn(z)) - && !(pfn & (pageblock_nr_pages - 1))) - set_pageblock_migratetype(page, MIGRATE_MOVABLE); - - INIT_LIST_HEAD(&page->lru); -#ifdef WANT_PAGE_VIRTUAL - /* The shift won't overflow because ZONE_NORMAL is below 4G. */ - if (!is_highmem_idx(zone)) - set_page_address(page, __va(pfn << PAGE_SHIFT)); -#endif + __init_single_page(pfn, zone, nid); } } -- 1.8.2.1 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>