diff options
author | Mel Gorman <mgorman@techsingularity.net> | 2015-11-06 19:28:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-06 20:50:42 -0500 |
commit | 974a786e63c96a2401a78ddba926f34c128474f1 (patch) | |
tree | c3551fdc6208bc2f764455cb73ad676a965a17e0 /mm/page_alloc.c | |
parent | f77cf4e4cc9d40310a7224a1a67c733aeec78836 (diff) |
mm, page_alloc: remove MIGRATE_RESERVE
MIGRATE_RESERVE preserves an old property of the buddy allocator that
existed prior to fragmentation avoidance -- min_free_kbytes worth of pages
tended to remain contiguous until the only alternative was to fail the
allocation. At the time it was discovered that high-order atomic
allocations relied on this property so MIGRATE_RESERVE was introduced. A
later patch will introduce an alternative MIGRATE_HIGHATOMIC so this patch
deletes MIGRATE_RESERVE and supporting code so it'll be easier to review.
Note that this patch in isolation may look like a false regression if
someone was bisecting high-order atomic allocation failures.
Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Christoph Lameter <cl@linux.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Vitaly Wool <vitalywool@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 148 |
1 files changed, 8 insertions, 140 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8dc6e3cd40f0..588812614377 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -817,7 +817,6 @@ static void free_pcppages_bulk(struct zone *zone, int count, | |||
817 | if (unlikely(has_isolate_pageblock(zone))) | 817 | if (unlikely(has_isolate_pageblock(zone))) |
818 | mt = get_pageblock_migratetype(page); | 818 | mt = get_pageblock_migratetype(page); |
819 | 819 | ||
820 | /* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */ | ||
821 | __free_one_page(page, page_to_pfn(page), zone, 0, mt); | 820 | __free_one_page(page, page_to_pfn(page), zone, 0, mt); |
822 | trace_mm_page_pcpu_drain(page, 0, mt); | 821 | trace_mm_page_pcpu_drain(page, 0, mt); |
823 | } while (--to_free && --batch_free && !list_empty(list)); | 822 | } while (--to_free && --batch_free && !list_empty(list)); |
@@ -1417,15 +1416,14 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, | |||
1417 | * the free lists for the desirable migrate type are depleted | 1416 | * the free lists for the desirable migrate type are depleted |
1418 | */ | 1417 | */ |
1419 | static int fallbacks[MIGRATE_TYPES][4] = { | 1418 | static int fallbacks[MIGRATE_TYPES][4] = { |
1420 | [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE }, | 1419 | [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_TYPES }, |
1421 | [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE }, | 1420 | [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_TYPES }, |
1422 | [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE }, | 1421 | [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_TYPES }, |
1423 | #ifdef CONFIG_CMA | 1422 | #ifdef CONFIG_CMA |
1424 | [MIGRATE_CMA] = { MIGRATE_RESERVE }, /* Never used */ | 1423 | [MIGRATE_CMA] = { MIGRATE_TYPES }, /* Never used */ |
1425 | #endif | 1424 | #endif |
1426 | [MIGRATE_RESERVE] = { MIGRATE_RESERVE }, /* Never used */ | ||
1427 | #ifdef CONFIG_MEMORY_ISOLATION | 1425 | #ifdef CONFIG_MEMORY_ISOLATION |
1428 | [MIGRATE_ISOLATE] = { MIGRATE_RESERVE }, /* Never used */ | 1426 | [MIGRATE_ISOLATE] = { MIGRATE_TYPES }, /* Never used */ |
1429 | #endif | 1427 | #endif |
1430 | }; | 1428 | }; |
1431 | 1429 | ||
@@ -1598,7 +1596,7 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, | |||
1598 | *can_steal = false; | 1596 | *can_steal = false; |
1599 | for (i = 0;; i++) { | 1597 | for (i = 0;; i++) { |
1600 | fallback_mt = fallbacks[migratetype][i]; | 1598 | fallback_mt = fallbacks[migratetype][i]; |
1601 | if (fallback_mt == MIGRATE_RESERVE) | 1599 | if (fallback_mt == MIGRATE_TYPES) |
1602 | break; | 1600 | break; |
1603 | 1601 | ||
1604 | if (list_empty(&area->free_list[fallback_mt])) | 1602 | if (list_empty(&area->free_list[fallback_mt])) |
@@ -1676,25 +1674,13 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order, | |||
1676 | { | 1674 | { |
1677 | struct page *page; | 1675 | struct page *page; |
1678 | 1676 | ||
1679 | retry_reserve: | ||
1680 | page = __rmqueue_smallest(zone, order, migratetype); | 1677 | page = __rmqueue_smallest(zone, order, migratetype); |
1681 | 1678 | if (unlikely(!page)) { | |
1682 | if (unlikely(!page) && migratetype != MIGRATE_RESERVE) { | ||
1683 | if (migratetype == MIGRATE_MOVABLE) | 1679 | if (migratetype == MIGRATE_MOVABLE) |
1684 | page = __rmqueue_cma_fallback(zone, order); | 1680 | page = __rmqueue_cma_fallback(zone, order); |
1685 | 1681 | ||
1686 | if (!page) | 1682 | if (!page) |
1687 | page = __rmqueue_fallback(zone, order, migratetype); | 1683 | page = __rmqueue_fallback(zone, order, migratetype); |
1688 | |||
1689 | /* | ||
1690 | * Use MIGRATE_RESERVE rather than fail an allocation. goto | ||
1691 | * is used because __rmqueue_smallest is an inline function | ||
1692 | * and we want just one call site | ||
1693 | */ | ||
1694 | if (!page) { | ||
1695 | migratetype = MIGRATE_RESERVE; | ||
1696 | goto retry_reserve; | ||
1697 | } | ||
1698 | } | 1684 | } |
1699 | 1685 | ||
1700 | trace_mm_page_alloc_zone_locked(page, order, migratetype); | 1686 | trace_mm_page_alloc_zone_locked(page, order, migratetype); |
@@ -3492,7 +3478,6 @@ static void show_migration_types(unsigned char type) | |||
3492 | [MIGRATE_UNMOVABLE] = 'U', | 3478 | [MIGRATE_UNMOVABLE] = 'U', |
3493 | [MIGRATE_RECLAIMABLE] = 'E', | 3479 | [MIGRATE_RECLAIMABLE] = 'E', |
3494 | [MIGRATE_MOVABLE] = 'M', | 3480 | [MIGRATE_MOVABLE] = 'M', |
3495 | [MIGRATE_RESERVE] = 'R', | ||
3496 | #ifdef CONFIG_CMA | 3481 | #ifdef CONFIG_CMA |
3497 | [MIGRATE_CMA] = 'C', | 3482 | [MIGRATE_CMA] = 'C', |
3498 | #endif | 3483 | #endif |
@@ -4303,120 +4288,6 @@ static inline unsigned long wait_table_bits(unsigned long size) | |||
4303 | } | 4288 | } |
4304 | 4289 | ||
4305 | /* | 4290 | /* |
4306 | * Check if a pageblock contains reserved pages | ||
4307 | */ | ||
4308 | static int pageblock_is_reserved(unsigned long start_pfn, unsigned long end_pfn) | ||
4309 | { | ||
4310 | unsigned long pfn; | ||
4311 | |||
4312 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { | ||
4313 | if (!pfn_valid_within(pfn) || PageReserved(pfn_to_page(pfn))) | ||
4314 | return 1; | ||
4315 | } | ||
4316 | return 0; | ||
4317 | } | ||
4318 | |||
4319 | /* | ||
4320 | * Mark a number of pageblocks as MIGRATE_RESERVE. The number | ||
4321 | * of blocks reserved is based on min_wmark_pages(zone). The memory within | ||
4322 | * the reserve will tend to store contiguous free pages. Setting min_free_kbytes | ||
4323 | * higher will lead to a bigger reserve which will get freed as contiguous | ||
4324 | * blocks as reclaim kicks in | ||
4325 | */ | ||
4326 | static void setup_zone_migrate_reserve(struct zone *zone) | ||
4327 | { | ||
4328 | unsigned long start_pfn, pfn, end_pfn, block_end_pfn; | ||
4329 | struct page *page; | ||
4330 | unsigned long block_migratetype; | ||
4331 | int reserve; | ||
4332 | int old_reserve; | ||
4333 | |||
4334 | /* | ||
4335 | * Get the start pfn, end pfn and the number of blocks to reserve | ||
4336 | * We have to be careful to be aligned to pageblock_nr_pages to | ||
4337 | * make sure that we always check pfn_valid for the first page in | ||
4338 | * the block. | ||
4339 | */ | ||
4340 | start_pfn = zone->zone_start_pfn; | ||
4341 | end_pfn = zone_end_pfn(zone); | ||
4342 | start_pfn = roundup(start_pfn, pageblock_nr_pages); | ||
4343 | reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >> | ||
4344 | pageblock_order; | ||
4345 | |||
4346 | /* | ||
4347 | * Reserve blocks are generally in place to help high-order atomic | ||
4348 | * allocations that are short-lived. A min_free_kbytes value that | ||
4349 | * would result in more than 2 reserve blocks for atomic allocations | ||
4350 | * is assumed to be in place to help anti-fragmentation for the | ||
4351 | * future allocation of hugepages at runtime. | ||
4352 | */ | ||
4353 | reserve = min(2, reserve); | ||
4354 | old_reserve = zone->nr_migrate_reserve_block; | ||
4355 | |||
4356 | /* When memory hot-add, we almost always need to do nothing */ | ||
4357 | if (reserve == old_reserve) | ||
4358 | return; | ||
4359 | zone->nr_migrate_reserve_block = reserve; | ||
4360 | |||
4361 | for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) { | ||
4362 | if (!early_page_nid_uninitialised(pfn, zone_to_nid(zone))) | ||
4363 | return; | ||
4364 | |||
4365 | if (!pfn_valid(pfn)) | ||
4366 | continue; | ||
4367 | page = pfn_to_page(pfn); | ||
4368 | |||
4369 | /* Watch out for overlapping nodes */ | ||
4370 | if (page_to_nid(page) != zone_to_nid(zone)) | ||
4371 | continue; | ||
4372 | |||
4373 | block_migratetype = get_pageblock_migratetype(page); | ||
4374 | |||
4375 | /* Only test what is necessary when the reserves are not met */ | ||
4376 | if (reserve > 0) { | ||
4377 | /* | ||
4378 | * Blocks with reserved pages will never free, skip | ||
4379 | * them. | ||
4380 | */ | ||
4381 | block_end_pfn = min(pfn + pageblock_nr_pages, end_pfn); | ||
4382 | if (pageblock_is_reserved(pfn, block_end_pfn)) | ||
4383 | continue; | ||
4384 | |||
4385 | /* If this block is reserved, account for it */ | ||
4386 | if (block_migratetype == MIGRATE_RESERVE) { | ||
4387 | reserve--; | ||
4388 | continue; | ||
4389 | } | ||
4390 | |||
4391 | /* Suitable for reserving if this block is movable */ | ||
4392 | if (block_migratetype == MIGRATE_MOVABLE) { | ||
4393 | set_pageblock_migratetype(page, | ||
4394 | MIGRATE_RESERVE); | ||
4395 | move_freepages_block(zone, page, | ||
4396 | MIGRATE_RESERVE); | ||
4397 | reserve--; | ||
4398 | continue; | ||
4399 | } | ||
4400 | } else if (!old_reserve) { | ||
4401 | /* | ||
4402 | * At boot time we don't need to scan the whole zone | ||
4403 | * for turning off MIGRATE_RESERVE. | ||
4404 | */ | ||
4405 | break; | ||
4406 | } | ||
4407 | |||
4408 | /* | ||
4409 | * If the reserve is met and this is a previous reserved block, | ||
4410 | * take it back | ||
4411 | */ | ||
4412 | if (block_migratetype == MIGRATE_RESERVE) { | ||
4413 | set_pageblock_migratetype(page, MIGRATE_MOVABLE); | ||
4414 | move_freepages_block(zone, page, MIGRATE_MOVABLE); | ||
4415 | } | ||
4416 | } | ||
4417 | } | ||
4418 | |||
4419 | /* | ||
4420 | * Initially all pages are reserved - free ones are freed | 4291 | * Initially all pages are reserved - free ones are freed |
4421 | * up by free_all_bootmem() once the early boot process is | 4292 | * up by free_all_bootmem() once the early boot process is |
4422 | * done. Non-atomic initialization, single-pass. | 4293 | * done. Non-atomic initialization, single-pass. |
@@ -4455,9 +4326,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, | |||
4455 | * movable at startup. This will force kernel allocations | 4326 | * movable at startup. This will force kernel allocations |
4456 | * to reserve their blocks rather than leaking throughout | 4327 | * to reserve their blocks rather than leaking throughout |
4457 | * the address space during boot when many long-lived | 4328 | * the address space during boot when many long-lived |
4458 | * kernel allocations are made. Later some blocks near | 4329 | * kernel allocations are made. |
4459 | * the start are marked MIGRATE_RESERVE by | ||
4460 | * setup_zone_migrate_reserve() | ||
4461 | * | 4330 | * |
4462 | * bitmap is created for zone's valid pfn range. but memmap | 4331 | * bitmap is created for zone's valid pfn range. but memmap |
4463 | * can be created for invalid pages (for alignment) | 4332 | * can be created for invalid pages (for alignment) |
@@ -6018,7 +5887,6 @@ static void __setup_per_zone_wmarks(void) | |||
6018 | high_wmark_pages(zone) - low_wmark_pages(zone) - | 5887 | high_wmark_pages(zone) - low_wmark_pages(zone) - |
6019 | atomic_long_read(&zone->vm_stat[NR_ALLOC_BATCH])); | 5888 | atomic_long_read(&zone->vm_stat[NR_ALLOC_BATCH])); |
6020 | 5889 | ||
6021 | setup_zone_migrate_reserve(zone); | ||
6022 | spin_unlock_irqrestore(&zone->lock, flags); | 5890 | spin_unlock_irqrestore(&zone->lock, flags); |
6023 | } | 5891 | } |
6024 | 5892 | ||