mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
mm, compaction: fix NR_ISOLATED_* stats for pfn based migration
Since commitbda807d444
("mm: migrate: support non-lru movable page migration") isolate_migratepages_block) can isolate !PageLRU pages which would acct_isolated account as NR_ISOLATED_*. Accounting these non-lru pages NR_ISOLATED_{ANON,FILE} doesn't make any sense and it can misguide heuristics based on those counters such as pgdat_reclaimable_pages resp. too_many_isolated which would lead to unexpected stalls during the direct reclaim without any good reason. Note that __alloc_contig_migrate_range can isolate a lot of pages at once. On mobile devices such as 512M ram android Phone, it may use a big zram swap. In some cases zram(zsmalloc) uses too many non-lru but migratedable pages, such as: MemTotal: 468148 kB Normal free:5620kB Free swap:4736kB Total swap:409596kB ZRAM: 164616kB(zsmalloc non-lru pages) active_anon:60700kB inactive_anon:60744kB active_file:34420kB inactive_file:37532kB Fix this by only accounting lru pages to NR_ISOLATED_* in isolate_migratepages_block right after they were isolated and we still know they were on LRU. Drop acct_isolated because it is called after the fact and we've lost that information. Batching per-cpu counter doesn't make much improvement anyway. Also make sure that we uncharge only LRU pages when putting them back on the LRU in putback_movable_pages resp. when unmap_and_move migrates the page. [mhocko@suse.com: replace acct_isolated() with direct counting] Fixes:bda807d444
("mm: migrate: support non-lru movable page migration") Link: http://lkml.kernel.org/r/20161019080240.9682-1-mhocko@kernel.org Signed-off-by: Ming Ling <ming.ling@spreadtrum.com> Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Minchan Kim <minchan@kernel.org> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Mel Gorman <mgorman@suse.de> Cc: Joonsoo Kim <js1304@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
6d8409580b
commit
6afcf8ef0c
@ -634,22 +634,6 @@ isolate_freepages_range(struct compact_control *cc,
|
|||||||
return pfn;
|
return pfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
|
||||||
unsigned int count[2] = { 0, };
|
|
||||||
|
|
||||||
if (list_empty(&cc->migratepages))
|
|
||||||
return;
|
|
||||||
|
|
||||||
list_for_each_entry(page, &cc->migratepages, lru)
|
|
||||||
count[!!page_is_file_cache(page)]++;
|
|
||||||
|
|
||||||
mod_node_page_state(zone->zone_pgdat, NR_ISOLATED_ANON, count[0]);
|
|
||||||
mod_node_page_state(zone->zone_pgdat, NR_ISOLATED_FILE, count[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Similar to reclaim, but different enough that they don't share logic */
|
/* Similar to reclaim, but different enough that they don't share logic */
|
||||||
static bool too_many_isolated(struct zone *zone)
|
static bool too_many_isolated(struct zone *zone)
|
||||||
{
|
{
|
||||||
@ -866,6 +850,8 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
|
|||||||
|
|
||||||
/* Successfully isolated */
|
/* Successfully isolated */
|
||||||
del_page_from_lru_list(page, lruvec, page_lru(page));
|
del_page_from_lru_list(page, lruvec, page_lru(page));
|
||||||
|
inc_node_page_state(page,
|
||||||
|
NR_ISOLATED_ANON + page_is_file_cache(page));
|
||||||
|
|
||||||
isolate_success:
|
isolate_success:
|
||||||
list_add(&page->lru, &cc->migratepages);
|
list_add(&page->lru, &cc->migratepages);
|
||||||
@ -902,7 +888,6 @@ isolate_fail:
|
|||||||
spin_unlock_irqrestore(zone_lru_lock(zone), flags);
|
spin_unlock_irqrestore(zone_lru_lock(zone), flags);
|
||||||
locked = false;
|
locked = false;
|
||||||
}
|
}
|
||||||
acct_isolated(zone, cc);
|
|
||||||
putback_movable_pages(&cc->migratepages);
|
putback_movable_pages(&cc->migratepages);
|
||||||
cc->nr_migratepages = 0;
|
cc->nr_migratepages = 0;
|
||||||
cc->last_migrated_pfn = 0;
|
cc->last_migrated_pfn = 0;
|
||||||
@ -988,7 +973,6 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
|
|||||||
if (cc->nr_migratepages == COMPACT_CLUSTER_MAX)
|
if (cc->nr_migratepages == COMPACT_CLUSTER_MAX)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
acct_isolated(cc->zone, cc);
|
|
||||||
|
|
||||||
return pfn;
|
return pfn;
|
||||||
}
|
}
|
||||||
@ -1258,10 +1242,8 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
|
|||||||
low_pfn = isolate_migratepages_block(cc, low_pfn,
|
low_pfn = isolate_migratepages_block(cc, low_pfn,
|
||||||
block_end_pfn, isolate_mode);
|
block_end_pfn, isolate_mode);
|
||||||
|
|
||||||
if (!low_pfn || cc->contended) {
|
if (!low_pfn || cc->contended)
|
||||||
acct_isolated(zone, cc);
|
|
||||||
return ISOLATE_ABORT;
|
return ISOLATE_ABORT;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Either we isolated something and proceed with migration. Or
|
* Either we isolated something and proceed with migration. Or
|
||||||
@ -1271,7 +1253,6 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
acct_isolated(zone, cc);
|
|
||||||
/* Record where migration scanner will be restarted. */
|
/* Record where migration scanner will be restarted. */
|
||||||
cc->migrate_pfn = low_pfn;
|
cc->migrate_pfn = low_pfn;
|
||||||
|
|
||||||
|
15
mm/migrate.c
15
mm/migrate.c
@ -168,8 +168,6 @@ void putback_movable_pages(struct list_head *l)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list_del(&page->lru);
|
list_del(&page->lru);
|
||||||
dec_node_page_state(page, NR_ISOLATED_ANON +
|
|
||||||
page_is_file_cache(page));
|
|
||||||
/*
|
/*
|
||||||
* We isolated non-lru movable page so here we can use
|
* We isolated non-lru movable page so here we can use
|
||||||
* __PageMovable because LRU page's mapping cannot have
|
* __PageMovable because LRU page's mapping cannot have
|
||||||
@ -186,6 +184,8 @@ void putback_movable_pages(struct list_head *l)
|
|||||||
put_page(page);
|
put_page(page);
|
||||||
} else {
|
} else {
|
||||||
putback_lru_page(page);
|
putback_lru_page(page);
|
||||||
|
dec_node_page_state(page, NR_ISOLATED_ANON +
|
||||||
|
page_is_file_cache(page));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1121,8 +1121,15 @@ out:
|
|||||||
* restored.
|
* restored.
|
||||||
*/
|
*/
|
||||||
list_del(&page->lru);
|
list_del(&page->lru);
|
||||||
dec_node_page_state(page, NR_ISOLATED_ANON +
|
|
||||||
page_is_file_cache(page));
|
/*
|
||||||
|
* Compaction can migrate also non-LRU pages which are
|
||||||
|
* not accounted to NR_ISOLATED_*. They can be recognized
|
||||||
|
* as __PageMovable
|
||||||
|
*/
|
||||||
|
if (likely(!__PageMovable(page)))
|
||||||
|
dec_node_page_state(page, NR_ISOLATED_ANON +
|
||||||
|
page_is_file_cache(page));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user