Loading mm/zcache.c +41 −17 Original line number Diff line number Diff line Loading @@ -64,7 +64,6 @@ module_param_named(max_pool_percent, zcache_max_pool_percent, uint, 0644); static u64 zcache_pool_limit_hit; static u64 zcache_dup_entry; static u64 zcache_zbud_alloc_fail; static u64 zcache_pool_pages; static u64 zcache_evict_zpages; static u64 zcache_evict_filepages; static u64 zcache_inactive_pages_refused; Loading Loading @@ -106,6 +105,7 @@ static atomic_t zcache_stored_pages = ATOMIC_INIT(0); struct zcache_pool { struct rb_root rbtree; rwlock_t rb_lock; /* Protects rbtree */ u64 size; struct zbud_pool *pool; /* Zbud pool used */ }; Loading Loading @@ -143,7 +143,13 @@ struct zcache_ra_handle { u64 zcache_pages(void) { return zcache_pool_pages; int i; u64 count = 0; for (i = 0; (i < MAX_ZCACHE_POOLS) && zcache.pools[i]; i++) count += zcache.pools[i]->size; return count; } static struct kmem_cache *zcache_rbnode_cache; Loading @@ -164,7 +170,7 @@ static unsigned long zcache_count(struct shrinker *s, long file_gap; active_file = global_page_state(NR_ACTIVE_FILE); file_gap = zcache_pool_pages - active_file; file_gap = zcache_pages() - active_file; if (file_gap < 0) file_gap = 0; return file_gap; Loading @@ -176,7 +182,7 @@ static unsigned long zcache_scan(struct shrinker *s, struct shrink_control *sc) long file_gap; unsigned long freed = 0; static bool running; struct zcache_pool *zpool = zcache.pools[0]; int i = 0; if (running) goto end; Loading @@ -189,21 +195,30 @@ static unsigned long zcache_scan(struct shrinker *s, struct shrink_control *sc) * stored by zcache is around twice as many as the * number of active file pages. */ file_gap = zcache_pool_pages - active_file; file_gap = zcache_pages() - active_file; if (file_gap < 0) file_gap = 0; else zcache_pool_shrink++; while (file_gap-- > 0) { while (file_gap > 0) { 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; } freed++; file_gap--; } zcache_pool_shrink_pages += freed; zcache_pool_pages = zbud_get_pool_size(zpool->pool); for (i = 0; (i < MAX_ZCACHE_POOLS) && zcache.pools[i]; i++) zcache.pools[i]->size = zbud_get_pool_size(zcache.pools[i]->pool); running = false; end: return freed; Loading Loading @@ -356,7 +371,7 @@ cleanup: static bool zcache_is_full(void) { return totalram_pages * zcache_max_pool_percent / 100 < zcache_pool_pages; zcache_pages(); } /* Loading Loading @@ -510,7 +525,7 @@ static int zcache_store_zaddr(struct zcache_pool *zpool, WARN_ON("duplicated, will be replaced!\n"); zbud_free(zpool->pool, (unsigned long)dup_zaddr); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); zcache_dup_entry++; } Loading Loading @@ -587,7 +602,7 @@ static void zcache_store_page(int pool_id, struct cleancache_filekey key, * Continue if reclaimed a page frame succ. */ zcache_evict_filepages++; zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } /* compress */ Loading Loading @@ -632,7 +647,7 @@ static void zcache_store_page(int pool_id, struct cleancache_filekey key, /* update stats */ atomic_inc(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } static int zcache_load_page(int pool_id, struct cleancache_filekey key, Loading Loading @@ -667,7 +682,7 @@ static int zcache_load_page(int pool_id, struct cleancache_filekey key, /* update stats */ atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); SetPageWasActive(page); return ret; } Loading @@ -682,7 +697,7 @@ static void zcache_flush_page(int pool_id, struct cleancache_filekey key, if (zaddr) { zbud_free(zpool->pool, (unsigned long)zaddr); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } } Loading Loading @@ -711,7 +726,7 @@ static void zcache_flush_ratree(struct zcache_pool *zpool, zbud_unmap(zpool->pool, (unsigned long)zaddrs[i]); zbud_free(zpool->pool, (unsigned long)zaddrs[i]); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } index++; Loading Loading @@ -810,7 +825,7 @@ static int zcache_evict_zpage(struct zbud_pool *pool, unsigned long zaddr) zbud_unmap(pool, zaddr); zbud_free(pool, zaddr); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(pool); zpool->size = zbud_get_pool_size(pool); zcache_evict_zpages++; } return 0; Loading Loading @@ -927,6 +942,15 @@ static struct cleancache_ops zcache_ops = { */ #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> static int pool_pages_get(void *_data, u64 *val) { *val = zcache_pages(); return 0; } DEFINE_SIMPLE_ATTRIBUTE(pool_page_fops, pool_pages_get, NULL, "%llu\n"); static struct dentry *zcache_debugfs_root; static int __init zcache_debugfs_init(void) Loading @@ -944,8 +968,8 @@ static int __init zcache_debugfs_init(void) &zcache_zbud_alloc_fail); debugfs_create_u64("duplicate_entry", S_IRUGO, zcache_debugfs_root, &zcache_dup_entry); debugfs_create_u64("pool_pages", S_IRUGO, zcache_debugfs_root, &zcache_pool_pages); debugfs_create_file("pool_pages", S_IRUGO, zcache_debugfs_root, NULL, &pool_page_fops); debugfs_create_atomic_t("stored_pages", S_IRUGO, zcache_debugfs_root, &zcache_stored_pages); debugfs_create_u64("evicted_zpages", S_IRUGO, zcache_debugfs_root, Loading Loading
mm/zcache.c +41 −17 Original line number Diff line number Diff line Loading @@ -64,7 +64,6 @@ module_param_named(max_pool_percent, zcache_max_pool_percent, uint, 0644); static u64 zcache_pool_limit_hit; static u64 zcache_dup_entry; static u64 zcache_zbud_alloc_fail; static u64 zcache_pool_pages; static u64 zcache_evict_zpages; static u64 zcache_evict_filepages; static u64 zcache_inactive_pages_refused; Loading Loading @@ -106,6 +105,7 @@ static atomic_t zcache_stored_pages = ATOMIC_INIT(0); struct zcache_pool { struct rb_root rbtree; rwlock_t rb_lock; /* Protects rbtree */ u64 size; struct zbud_pool *pool; /* Zbud pool used */ }; Loading Loading @@ -143,7 +143,13 @@ struct zcache_ra_handle { u64 zcache_pages(void) { return zcache_pool_pages; int i; u64 count = 0; for (i = 0; (i < MAX_ZCACHE_POOLS) && zcache.pools[i]; i++) count += zcache.pools[i]->size; return count; } static struct kmem_cache *zcache_rbnode_cache; Loading @@ -164,7 +170,7 @@ static unsigned long zcache_count(struct shrinker *s, long file_gap; active_file = global_page_state(NR_ACTIVE_FILE); file_gap = zcache_pool_pages - active_file; file_gap = zcache_pages() - active_file; if (file_gap < 0) file_gap = 0; return file_gap; Loading @@ -176,7 +182,7 @@ static unsigned long zcache_scan(struct shrinker *s, struct shrink_control *sc) long file_gap; unsigned long freed = 0; static bool running; struct zcache_pool *zpool = zcache.pools[0]; int i = 0; if (running) goto end; Loading @@ -189,21 +195,30 @@ static unsigned long zcache_scan(struct shrinker *s, struct shrink_control *sc) * stored by zcache is around twice as many as the * number of active file pages. */ file_gap = zcache_pool_pages - active_file; file_gap = zcache_pages() - active_file; if (file_gap < 0) file_gap = 0; else zcache_pool_shrink++; while (file_gap-- > 0) { while (file_gap > 0) { 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; } freed++; file_gap--; } zcache_pool_shrink_pages += freed; zcache_pool_pages = zbud_get_pool_size(zpool->pool); for (i = 0; (i < MAX_ZCACHE_POOLS) && zcache.pools[i]; i++) zcache.pools[i]->size = zbud_get_pool_size(zcache.pools[i]->pool); running = false; end: return freed; Loading Loading @@ -356,7 +371,7 @@ cleanup: static bool zcache_is_full(void) { return totalram_pages * zcache_max_pool_percent / 100 < zcache_pool_pages; zcache_pages(); } /* Loading Loading @@ -510,7 +525,7 @@ static int zcache_store_zaddr(struct zcache_pool *zpool, WARN_ON("duplicated, will be replaced!\n"); zbud_free(zpool->pool, (unsigned long)dup_zaddr); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); zcache_dup_entry++; } Loading Loading @@ -587,7 +602,7 @@ static void zcache_store_page(int pool_id, struct cleancache_filekey key, * Continue if reclaimed a page frame succ. */ zcache_evict_filepages++; zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } /* compress */ Loading Loading @@ -632,7 +647,7 @@ static void zcache_store_page(int pool_id, struct cleancache_filekey key, /* update stats */ atomic_inc(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } static int zcache_load_page(int pool_id, struct cleancache_filekey key, Loading Loading @@ -667,7 +682,7 @@ static int zcache_load_page(int pool_id, struct cleancache_filekey key, /* update stats */ atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); SetPageWasActive(page); return ret; } Loading @@ -682,7 +697,7 @@ static void zcache_flush_page(int pool_id, struct cleancache_filekey key, if (zaddr) { zbud_free(zpool->pool, (unsigned long)zaddr); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } } Loading Loading @@ -711,7 +726,7 @@ static void zcache_flush_ratree(struct zcache_pool *zpool, zbud_unmap(zpool->pool, (unsigned long)zaddrs[i]); zbud_free(zpool->pool, (unsigned long)zaddrs[i]); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(zpool->pool); zpool->size = zbud_get_pool_size(zpool->pool); } index++; Loading Loading @@ -810,7 +825,7 @@ static int zcache_evict_zpage(struct zbud_pool *pool, unsigned long zaddr) zbud_unmap(pool, zaddr); zbud_free(pool, zaddr); atomic_dec(&zcache_stored_pages); zcache_pool_pages = zbud_get_pool_size(pool); zpool->size = zbud_get_pool_size(pool); zcache_evict_zpages++; } return 0; Loading Loading @@ -927,6 +942,15 @@ static struct cleancache_ops zcache_ops = { */ #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> static int pool_pages_get(void *_data, u64 *val) { *val = zcache_pages(); return 0; } DEFINE_SIMPLE_ATTRIBUTE(pool_page_fops, pool_pages_get, NULL, "%llu\n"); static struct dentry *zcache_debugfs_root; static int __init zcache_debugfs_init(void) Loading @@ -944,8 +968,8 @@ static int __init zcache_debugfs_init(void) &zcache_zbud_alloc_fail); debugfs_create_u64("duplicate_entry", S_IRUGO, zcache_debugfs_root, &zcache_dup_entry); debugfs_create_u64("pool_pages", S_IRUGO, zcache_debugfs_root, &zcache_pool_pages); debugfs_create_file("pool_pages", S_IRUGO, zcache_debugfs_root, NULL, &pool_page_fops); debugfs_create_atomic_t("stored_pages", S_IRUGO, zcache_debugfs_root, &zcache_stored_pages); debugfs_create_u64("evicted_zpages", S_IRUGO, zcache_debugfs_root, Loading