Compaction is good solution to get contiguos page but it makes LRU churing which is not good. This patch makes that compaction code use in-order putback so after compaction completion, migrated pages are keeping LRU ordering. Cc: KOSAKI Motohiro <kosaki.motohiro@xxxxxxxxxxxxxx> Cc: Mel Gorman <mgorman@xxxxxxx> Cc: Rik van Riel <riel@xxxxxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Signed-off-by: Minchan Kim <minchan.kim@xxxxxxxxx> --- mm/compaction.c | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index a2f6e96..480d2ac 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -211,11 +211,11 @@ static void isolate_freepages(struct zone *zone, /* Update the number of anon and file isolated pages in the zone */ static void acct_isolated(struct zone *zone, struct compact_control *cc) { - struct page *page; + struct pages_lru *pages_lru; unsigned int count[NR_LRU_LISTS] = { 0, }; - list_for_each_entry(page, &cc->migratepages, lru) { - int lru = page_lru_base_type(page); + list_for_each_entry(pages_lru, &cc->migratepages, lru) { + int lru = page_lru_base_type(pages_lru->page); count[lru]++; } @@ -281,6 +281,7 @@ static unsigned long isolate_migratepages(struct zone *zone, spin_lock_irq(&zone->lru_lock); for (; low_pfn < end_pfn; low_pfn++) { struct page *page; + struct pages_lru *pages_lru; bool locked = true; /* give a chance to irqs before checking need_resched() */ @@ -334,10 +335,16 @@ static unsigned long isolate_migratepages(struct zone *zone, continue; } + pages_lru = kmalloc(sizeof(struct pages_lru), GFP_ATOMIC); + if (pages_lru) + continue; + /* Try isolate the page */ - if (__isolate_lru_page(page, ISOLATE_BOTH, 0, - !cc->sync, 0, NULL) != 0) + if ( __isolate_lru_page(page, ISOLATE_BOTH, 0, + !cc->sync, 0, pages_lru) != 0) { + kfree(pages_lru); continue; + } VM_BUG_ON(PageTransCompound(page)); @@ -398,8 +405,9 @@ static void update_nr_listpages(struct compact_control *cc) int nr_migratepages = 0; int nr_freepages = 0; struct page *page; + struct pages_lru *pages_lru; - list_for_each_entry(page, &cc->migratepages, lru) + list_for_each_entry(pages_lru, &cc->migratepages, lru) nr_migratepages++; list_for_each_entry(page, &cc->freepages, lru) nr_freepages++; @@ -542,7 +550,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) /* Release LRU pages not migrated */ if (err) { - putback_lru_pages(&cc->migratepages); + putback_pages_lru(&cc->migratepages); cc->nr_migratepages = 0; } -- 1.7.1 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxxx For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>