本文共 2362 字,大约阅读时间需要 7 分钟。
/*
* This is a basic per-zone page freer. Used by both kswapd and direct reclaim.
*/
static voidshrink_zone_memcg(struct zone *zone, struct mem_cgroup *memcg,
struct scan_control *sc, unsigned long*lru_pages)
{
struct lruvec *lruvec = mem_cgroup_zone_lruvec(zone,memcg);
unsigned long nr[NR_LRU_LISTS];
unsigned long targets[NR_LRU_LISTS];
unsigned long nr_to_scan;
enum lru_list lru;
unsigned long nr_reclaimed = 0;
unsigned long nr_to_reclaim =sc->nr_to_reclaim;
struct blk_plug plug;
bool scan_adjusted;
get_scan_count(lruvec, memcg, sc, nr,lru_pages);
/* Record the original scan target forproportional adjustments later */
memcpy(targets, nr, sizeof(nr));
scan_adjusted = (global_reclaim(sc)&& !current_is_kswapd() && sc->priority == DEF_PRIORITY);
init_tlb_ubc();
blk_start_plug(&plug);
while (nr[LRU_INACTIVE_ANON] ||nr[LRU_ACTIVE_FILE] || nr[LRU_INACTIVE_FILE]) {
unsigned long nr_anon, nr_file,percentage;
unsigned long nr_scanned;
for_each_evictable_lru(lru) {
if (nr[lru]) {
nr_to_scan =min(nr[lru], SWAP_CLUSTER_MAX);
nr[lru] -=nr_to_scan;
nr_reclaimed +=shrink_list(lru, nr_to_scan,lruvec, sc);
}
}
if (nr_reclaimed <nr_to_reclaim || scan_adjusted)
continue;
nr_file = nr[LRU_INACTIVE_FILE] +nr[LRU_ACTIVE_FILE];
nr_anon = nr[LRU_INACTIVE_ANON] +nr[LRU_ACTIVE_ANON];
if (!nr_file || !nr_anon)
break;
if (nr_file > nr_anon) {
unsigned long scan_target =targets[LRU_INACTIVE_ANON] + targets[LRU_ACTIVE_ANON] + 1;
lru = LRU_BASE;
percentage = nr_anon * 100/ scan_target;
} else {
unsigned long scan_target =targets[LRU_INACTIVE_FILE] + targets[LRU_ACTIVE_FILE] + 1;
lru = LRU_FILE;
percentage = nr_file * 100/ scan_target;
}
/* Stop scanning the smaller ofthe LRU */
nr[lru] = 0;
nr[lru + LRU_ACTIVE] = 0;
lru = (lru == LRU_FILE) ? LRU_BASE: LRU_FILE;
nr_scanned = targets[lru] -nr[lru];
nr[lru] = targets[lru] * (100 -percentage) / 100;
nr[lru] -= min(nr[lru],nr_scanned);
lru += LRU_ACTIVE;
nr_scanned = targets[lru] -nr[lru];
nr[lru] = targets[lru] * (100 -percentage) / 100;
nr[lru] -= min(nr[lru],nr_scanned);
scan_adjusted = true;
}
blk_finish_plug(&plug);
sc->nr_reclaimed += nr_reclaimed;
/*Even if we did not try to evict anonpages at all, we want to rebalance the anon lru active/inactive ratio.*/
if (inactive_list_is_low(lruvec, false))
shrink_active_list(SWAP_CLUSTER_MAX,lruvec, sc, LRU_ACTIVE_ANON);
throttle_vm_writeout(sc->gfp_mask);
}
转载地址:http://uaqti.baihongyu.com/