summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mm/zcache.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/mm/zcache.c b/mm/zcache.c
index 49b0aac126e6..f329095ebb48 100644
--- a/mm/zcache.c
+++ b/mm/zcache.c
@@ -68,6 +68,9 @@ static u64 zcache_pool_pages;
static u64 zcache_evict_zpages;
static u64 zcache_evict_filepages;
static u64 zcache_reclaim_fail;
+static u64 zcache_pool_shrink;
+static u64 zcache_pool_shrink_fail;
+static u64 zcache_pool_shrink_pages;
static atomic_t zcache_stored_pages = ATOMIC_INIT(0);
#define GFP_ZCACHE \
@@ -148,6 +151,64 @@ static void zcache_rbnode_cache_destroy(void)
kmem_cache_destroy(zcache_rbnode_cache);
}
+static unsigned long zcache_count(struct shrinker *s,
+ struct shrink_control *sc)
+{
+ unsigned long active_file;
+ long file_gap;
+
+ active_file = global_page_state(NR_ACTIVE_FILE);
+ file_gap = zcache_pool_pages - active_file;
+ if (file_gap < 0)
+ file_gap = 0;
+ return file_gap;
+}
+
+static unsigned long zcache_scan(struct shrinker *s, struct shrink_control *sc)
+{
+ unsigned long active_file;
+ long file_gap;
+ unsigned long freed = 0;
+ static bool running;
+ struct zcache_pool *zpool = zcache.pools[0];
+
+ if (running)
+ goto end;
+
+ running = true;
+ active_file = global_page_state(NR_ACTIVE_FILE);
+
+ /*
+ * 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_pool_pages - active_file;
+ if (file_gap < 0)
+ file_gap = 0;
+ else
+ zcache_pool_shrink++;
+ while (file_gap-- > 0) {
+ if (zbud_reclaim_page(zpool->pool, 8)) {
+ zcache_pool_shrink_fail++;
+ break;
+ }
+ freed++;
+ }
+
+ zcache_pool_shrink_pages += freed;
+ zcache_pool_pages = zbud_get_pool_size(zpool->pool);
+ running = false;
+end:
+ return freed;
+}
+
+static struct shrinker zcache_shrinker = {
+ .scan_objects = zcache_scan,
+ .count_objects = zcache_count,
+ .seeks = DEFAULT_SEEKS * 16
+};
+
/*
* Compression functions
* (Below functions are copyed from zswap!)
@@ -875,6 +936,14 @@ static int __init zcache_debugfs_init(void)
&zcache_evict_filepages);
debugfs_create_u64("reclaim_fail", S_IRUGO, zcache_debugfs_root,
&zcache_reclaim_fail);
+ debugfs_create_u64("inactive_pages_refused", S_IRUGO,
+ zcache_debugfs_root, &zcache_inactive_pages_refused);
+ debugfs_create_u64("pool_shrink_count", S_IRUGO,
+ zcache_debugfs_root, &zcache_pool_shrink);
+ debugfs_create_u64("pool_shrink_fail", S_IRUGO,
+ zcache_debugfs_root, &zcache_pool_shrink_fail);
+ debugfs_create_u64("pool_shrink_pages", S_IRUGO,
+ zcache_debugfs_root, &zcache_pool_shrink_pages);
return 0;
}
@@ -920,6 +989,7 @@ static int __init init_zcache(void)
if (zcache_debugfs_init())
pr_warn("debugfs initialization failed\n");
+ register_shrinker(&zcache_shrinker);
return 0;
pcpufail:
zcache_comp_exit();