diff options
Diffstat (limited to 'mm/zcache.c')
-rw-r--r-- | mm/zcache.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/mm/zcache.c b/mm/zcache.c index 47200cc6de9b..0151a2c54f66 100644 --- a/mm/zcache.c +++ b/mm/zcache.c @@ -58,6 +58,8 @@ module_param_named(compressor, zcache_compressor, charp, 0); static unsigned int zcache_max_pool_percent = 10; module_param_named(max_pool_percent, zcache_max_pool_percent, uint, 0644); +static unsigned int zcache_clear_percent = 4; +module_param_named(clear_percent, zcache_clear_percent, uint, 0644); /* * zcache statistics */ @@ -187,36 +189,53 @@ static unsigned long zcache_count(struct shrinker *s, static unsigned long zcache_scan(struct shrinker *s, struct shrink_control *sc) { unsigned long active_file; + unsigned long file; long file_gap; unsigned long freed = 0; + unsigned long pool; static bool running; int i = 0; + int retries; if (running) goto end; running = true; active_file = global_page_state(NR_ACTIVE_FILE); + file = global_page_state(NR_FILE_PAGES); + pool = zcache_pages(); + + file_gap = pool - file; + + if ((file_gap >= 0) && + (totalram_pages * zcache_clear_percent / 100 > file)) { + file_gap = pool; + zcache_pool_shrink++; + goto reclaim; + } /* * file_gap == 0 means that the number of pages * stored by zcache is around twice as many as the * number of active file pages. */ - file_gap = zcache_pages() - active_file; + file_gap = pool - active_file; if (file_gap < 0) file_gap = 0; else zcache_pool_shrink++; - while (file_gap > 0) { +reclaim: + retries = file_gap; + while ((file_gap > 0) && retries) { struct zcache_pool *zpool = zcache.pools[i++ % MAX_ZCACHE_POOLS]; if (!zpool || !zpool->size) continue; if (zbud_reclaim_page(zpool->pool, 8)) { zcache_pool_shrink_fail++; - break; + retries--; + continue; } freed++; file_gap--; @@ -378,8 +397,12 @@ cleanup: */ static bool zcache_is_full(void) { - return totalram_pages * zcache_max_pool_percent / 100 < - zcache_pages(); + long file = global_page_state(NR_FILE_PAGES); + + return ((totalram_pages * zcache_max_pool_percent / 100 < + zcache_pages()) || + (totalram_pages * zcache_clear_percent / 100 > + file)); } /* |