forked from rubenslte/android_kernel_samsung_msm8226
mm: only force scan in reclaim when none of the LRUs are big enough.
Prior to this change, we would decide whether to force scan a LRU during
reclaim if that LRU itself was too small for the current priority.
However, this can lead to the file LRU getting force scanned even if
there are a lot of anonymous pages we can reclaim, leading to hot file
pages getting needlessly reclaimed.
To address this, we instead only force scan when none of the reclaimable
LRUs are big enough.
Gives huge improvements with zswap. For example, when doing -j20 kernel
build in a 500MB container with zswap enabled, runtime (in seconds) is
greatly reduced:
x without this change
+ with this change
N Min Max Median Avg Stddev
x 5 700.997 790.076 763.928 754.05 39.59493
+ 5 141.634 197.899 155.706 161.9 21.270224
Difference at 95.0% confidence
-592.15 +/- 46.3521
-78.5293% +/- 6.14709%
(Student's t, pooled s = 31.7819)
Should also give some improvements in regular (non-zswap) swap cases.
Yes, hughd found significant speedup using regular swap, with several
memcgs under pressure; and it should also be effective in the non-memcg
case, whenever one or another zone LRU is forced too small.
Change-Id: I1c580ee7c73239781afe8967f43abb1b3e247a0f
Signed-off-by: Suleiman Souhlal <suleiman@google.com>
Signed-off-by: Hugh Dickins <hughd@google.com>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: Rafael Aquini <aquini@redhat.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Cc: Seth Jennings <sjennings@variantweb.net>
Cc: Bob Liu <bob.liu@oracle.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Luigi Semenzato <semenzato@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Francescodario Cuzzocrea
parent
cb96c8daf1
commit
367a867ab7
+21
-10
@@ -1819,6 +1819,8 @@ static void get_scan_count(struct mem_cgroup_zone *mz, struct scan_control *sc,
|
||||
enum lru_list lru;
|
||||
int noswap = 0;
|
||||
bool force_scan = false;
|
||||
bool some_scanned;
|
||||
int pass;
|
||||
|
||||
/*
|
||||
* If the zone or memcg is small, nr[l] can be 0. This
|
||||
@@ -1910,18 +1912,27 @@ static void get_scan_count(struct mem_cgroup_zone *mz, struct scan_control *sc,
|
||||
fraction[1] = fp;
|
||||
denominator = ap + fp + 1;
|
||||
out:
|
||||
for_each_evictable_lru(lru) {
|
||||
int file = is_file_lru(lru);
|
||||
unsigned long scan;
|
||||
some_scanned = false;
|
||||
/* Only use force_scan on second pass. */
|
||||
for (pass = 0; !some_scanned && pass < 2; pass++) {
|
||||
for_each_evictable_lru(lru) {
|
||||
int file = is_file_lru(lru);
|
||||
unsigned long scan;
|
||||
|
||||
scan = zone_nr_lru_pages(mz, lru);
|
||||
if (sc->priority || noswap || !vmscan_swappiness(sc)) {
|
||||
scan >>= sc->priority;
|
||||
if (!scan && force_scan)
|
||||
scan = SWAP_CLUSTER_MAX;
|
||||
scan = div64_u64(scan * fraction[file], denominator);
|
||||
scan = zone_nr_lru_pages(mz, lru);
|
||||
if (sc->priority || noswap || !vmscan_swappiness(sc)) {
|
||||
scan >>= sc->priority;
|
||||
if (!scan && pass && force_scan)
|
||||
scan = SWAP_CLUSTER_MAX;
|
||||
scan = div64_u64(scan * fraction[file], denominator);
|
||||
}
|
||||
nr[lru] = scan;
|
||||
/*
|
||||
* Skip the second pass and don't force_scan,
|
||||
* if we found something to scan.
|
||||
*/
|
||||
some_scanned |= !!scan;
|
||||
}
|
||||
nr[lru] = scan;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user