diff options
-rw-r--r-- | mm/compaction.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/mm/compaction.c b/mm/compaction.c index 1427366ad673..79bfe0e06907 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -441,25 +441,23 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, | |||
441 | 441 | ||
442 | /* Found a free page, break it into order-0 pages */ | 442 | /* Found a free page, break it into order-0 pages */ |
443 | isolated = split_free_page(page); | 443 | isolated = split_free_page(page); |
444 | if (!isolated) | ||
445 | break; | ||
446 | |||
444 | total_isolated += isolated; | 447 | total_isolated += isolated; |
448 | cc->nr_freepages += isolated; | ||
445 | for (i = 0; i < isolated; i++) { | 449 | for (i = 0; i < isolated; i++) { |
446 | list_add(&page->lru, freelist); | 450 | list_add(&page->lru, freelist); |
447 | page++; | 451 | page++; |
448 | } | 452 | } |
449 | 453 | if (!strict && cc->nr_migratepages <= cc->nr_freepages) { | |
450 | /* If a page was split, advance to the end of it */ | 454 | blockpfn += isolated; |
451 | if (isolated) { | 455 | break; |
452 | cc->nr_freepages += isolated; | ||
453 | if (!strict && | ||
454 | cc->nr_migratepages <= cc->nr_freepages) { | ||
455 | blockpfn += isolated; | ||
456 | break; | ||
457 | } | ||
458 | |||
459 | blockpfn += isolated - 1; | ||
460 | cursor += isolated - 1; | ||
461 | continue; | ||
462 | } | 456 | } |
457 | /* Advance to the end of split page */ | ||
458 | blockpfn += isolated - 1; | ||
459 | cursor += isolated - 1; | ||
460 | continue; | ||
463 | 461 | ||
464 | isolate_fail: | 462 | isolate_fail: |
465 | if (strict) | 463 | if (strict) |
@@ -469,6 +467,9 @@ isolate_fail: | |||
469 | 467 | ||
470 | } | 468 | } |
471 | 469 | ||
470 | if (locked) | ||
471 | spin_unlock_irqrestore(&cc->zone->lock, flags); | ||
472 | |||
472 | /* | 473 | /* |
473 | * There is a tiny chance that we have read bogus compound_order(), | 474 | * There is a tiny chance that we have read bogus compound_order(), |
474 | * so be careful to not go outside of the pageblock. | 475 | * so be careful to not go outside of the pageblock. |
@@ -490,9 +491,6 @@ isolate_fail: | |||
490 | if (strict && blockpfn < end_pfn) | 491 | if (strict && blockpfn < end_pfn) |
491 | total_isolated = 0; | 492 | total_isolated = 0; |
492 | 493 | ||
493 | if (locked) | ||
494 | spin_unlock_irqrestore(&cc->zone->lock, flags); | ||
495 | |||
496 | /* Update the pageblock-skip if the whole pageblock was scanned */ | 494 | /* Update the pageblock-skip if the whole pageblock was scanned */ |
497 | if (blockpfn == end_pfn) | 495 | if (blockpfn == end_pfn) |
498 | update_pageblock_skip(cc, valid_page, total_isolated, false); | 496 | update_pageblock_skip(cc, valid_page, total_isolated, false); |
@@ -1011,6 +1009,7 @@ static void isolate_freepages(struct compact_control *cc) | |||
1011 | block_end_pfn = block_start_pfn, | 1009 | block_end_pfn = block_start_pfn, |
1012 | block_start_pfn -= pageblock_nr_pages, | 1010 | block_start_pfn -= pageblock_nr_pages, |
1013 | isolate_start_pfn = block_start_pfn) { | 1011 | isolate_start_pfn = block_start_pfn) { |
1012 | unsigned long isolated; | ||
1014 | 1013 | ||
1015 | /* | 1014 | /* |
1016 | * This can iterate a massively long zone without finding any | 1015 | * This can iterate a massively long zone without finding any |
@@ -1035,8 +1034,12 @@ static void isolate_freepages(struct compact_control *cc) | |||
1035 | continue; | 1034 | continue; |
1036 | 1035 | ||
1037 | /* Found a block suitable for isolating free pages from. */ | 1036 | /* Found a block suitable for isolating free pages from. */ |
1038 | isolate_freepages_block(cc, &isolate_start_pfn, | 1037 | isolated = isolate_freepages_block(cc, &isolate_start_pfn, |
1039 | block_end_pfn, freelist, false); | 1038 | block_end_pfn, freelist, false); |
1039 | /* If isolation failed early, do not continue needlessly */ | ||
1040 | if (!isolated && isolate_start_pfn < block_end_pfn && | ||
1041 | cc->nr_migratepages > cc->nr_freepages) | ||
1042 | break; | ||
1040 | 1043 | ||
1041 | /* | 1044 | /* |
1042 | * If we isolated enough freepages, or aborted due to async | 1045 | * If we isolated enough freepages, or aborted due to async |