[PATCH] zram: add zpool support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds zpool support for zram, it will allow us to use both
the zpool api and directly zsmalloc api in zram.

Signed-off-by: Geliang Tang <geliangtang@xxxxxxxxx>
---
 drivers/block/zram/zram_drv.c | 97 +++++++++++++++++++++++++++++++++++++++++++
 drivers/block/zram/zram_drv.h |  5 +++
 2 files changed, 102 insertions(+)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 9e2a83c..1f90bd0 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -43,6 +43,11 @@ static const char *default_compressor = "lzo";
 /* Module params (documentation at end) */
 static unsigned int num_devices = 1;
 
+#ifdef CONFIG_ZPOOL
+/* Compressed storage zpool to use */
+#define ZRAM_ZPOOL_DEFAULT "zsmalloc"
+#endif
+
 static inline void deprecated_attr_warn(const char *name)
 {
 	pr_warn_once("%d (%s) Attribute %s (and others) will be removed. %s\n",
@@ -228,7 +233,11 @@ static ssize_t mem_used_total_show(struct device *dev,
 	down_read(&zram->init_lock);
 	if (init_done(zram)) {
 		struct zram_meta *meta = zram->meta;
+#ifdef CONFIG_ZPOOL
+		val = zpool_get_total_size(meta->mem_pool) >> PAGE_SHIFT;
+#else
 		val = zs_get_total_pages(meta->mem_pool);
+#endif
 	}
 	up_read(&zram->init_lock);
 
@@ -296,8 +305,14 @@ static ssize_t mem_used_max_store(struct device *dev,
 	down_read(&zram->init_lock);
 	if (init_done(zram)) {
 		struct zram_meta *meta = zram->meta;
+#ifdef CONFIG_ZPOOL
+		atomic_long_set(&zram->stats.max_used_pages,
+				zpool_get_total_size(meta->mem_pool)
+				>> PAGE_SHIFT);
+#else
 		atomic_long_set(&zram->stats.max_used_pages,
 				zs_get_total_pages(meta->mem_pool));
+#endif
 	}
 	up_read(&zram->init_lock);
 
@@ -366,6 +381,18 @@ static ssize_t comp_algorithm_store(struct device *dev,
 	return len;
 }
 
+#ifdef CONFIG_ZPOOL
+static void zpool_compact(void *pool)
+{
+	zs_compact(pool);
+}
+
+static void zpool_stats(void *pool, struct zs_pool_stats *stats)
+{
+	zs_pool_stats(pool, stats);
+}
+#endif
+
 static ssize_t compact_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t len)
 {
@@ -379,7 +406,11 @@ static ssize_t compact_store(struct device *dev,
 	}
 
 	meta = zram->meta;
+#ifdef CONFIG_ZPOOL
+	zpool_compact(meta->mem_pool);
+#else
 	zs_compact(meta->mem_pool);
+#endif
 	up_read(&zram->init_lock);
 
 	return len;
@@ -416,8 +447,14 @@ static ssize_t mm_stat_show(struct device *dev,
 
 	down_read(&zram->init_lock);
 	if (init_done(zram)) {
+#ifdef CONFIG_ZPOOL
+		mem_used = zpool_get_total_size(zram->meta->mem_pool)
+				>> PAGE_SHIFT;
+		zpool_stats(zram->meta->mem_pool, &pool_stats);
+#else
 		mem_used = zs_get_total_pages(zram->meta->mem_pool);
 		zs_pool_stats(zram->meta->mem_pool, &pool_stats);
+#endif
 	}
 
 	orig_size = atomic64_read(&zram->stats.pages_stored);
@@ -490,10 +527,18 @@ static void zram_meta_free(struct zram_meta *meta, u64 disksize)
 		if (!handle)
 			continue;
 
+#ifdef CONFIG_ZPOOL
+		zpool_free(meta->mem_pool, handle);
+#else
 		zs_free(meta->mem_pool, handle);
+#endif
 	}
 
+#ifdef CONFIG_ZPOOL
+	zpool_destroy_pool(meta->mem_pool);
+#else
 	zs_destroy_pool(meta->mem_pool);
+#endif
 	vfree(meta->table);
 	kfree(meta);
 }
@@ -513,7 +558,17 @@ static struct zram_meta *zram_meta_alloc(char *pool_name, u64 disksize)
 		goto out_error;
 	}
 
+#ifdef CONFIG_ZPOOL
+	if (!zpool_has_pool(ZRAM_ZPOOL_DEFAULT)) {
+		pr_err("zpool %s not available\n", ZRAM_ZPOOL_DEFAULT);
+		goto out_error;
+	}
+
+	meta->mem_pool = zpool_create_pool(ZRAM_ZPOOL_DEFAULT,
+					pool_name, 0, NULL);
+#else
 	meta->mem_pool = zs_create_pool(pool_name);
+#endif
 	if (!meta->mem_pool) {
 		pr_err("Error creating memory pool\n");
 		goto out_error;
@@ -549,7 +604,11 @@ static void zram_free_page(struct zram *zram, size_t index)
 		return;
 	}
 
+#ifdef CONFIG_ZPOOL
+	zpool_free(meta->mem_pool, handle);
+#else
 	zs_free(meta->mem_pool, handle);
+#endif
 
 	atomic64_sub(zram_get_obj_size(meta, index),
 			&zram->stats.compr_data_size);
@@ -577,7 +636,11 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
 		return 0;
 	}
 
+#ifdef CONFIG_ZPOOL
+	cmem = zpool_map_handle(meta->mem_pool, handle, ZPOOL_MM_RO);
+#else
 	cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO);
+#endif
 	if (size == PAGE_SIZE) {
 		copy_page(mem, cmem);
 	} else {
@@ -586,7 +649,11 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
 		ret = zcomp_decompress(zstrm, cmem, size, mem);
 		zcomp_stream_put(zram->comp);
 	}
+#ifdef CONFIG_ZPOOL
+	zpool_unmap_handle(meta->mem_pool, handle);
+#else
 	zs_unmap_object(meta->mem_pool, handle);
+#endif
 	bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
 
 	/* Should NEVER happen. Return bio error if it does. */
@@ -735,20 +802,34 @@ compress_again:
 	 * from the slow path and handle has already been allocated.
 	 */
 	if (!handle)
+#ifdef CONFIG_ZPOOL
+		ret = zpool_malloc(meta->mem_pool, clen,
+				__GFP_KSWAPD_RECLAIM |
+				__GFP_NOWARN |
+				__GFP_HIGHMEM |
+				__GFP_MOVABLE, &handle);
+#else
 		handle = zs_malloc(meta->mem_pool, clen,
 				__GFP_KSWAPD_RECLAIM |
 				__GFP_NOWARN |
 				__GFP_HIGHMEM |
 				__GFP_MOVABLE);
+#endif
 	if (!handle) {
 		zcomp_stream_put(zram->comp);
 		zstrm = NULL;
 
 		atomic64_inc(&zram->stats.writestall);
 
+#ifdef CONFIG_ZPOOL
+		ret = zpool_malloc(meta->mem_pool, clen,
+				GFP_NOIO | __GFP_HIGHMEM |
+				__GFP_MOVABLE, &handle);
+#else
 		handle = zs_malloc(meta->mem_pool, clen,
 				GFP_NOIO | __GFP_HIGHMEM |
 				__GFP_MOVABLE);
+#endif
 		if (handle)
 			goto compress_again;
 
@@ -758,16 +839,28 @@ compress_again:
 		goto out;
 	}
 
+#ifdef CONFIG_ZPOOL
+	alloced_pages = zpool_get_total_size(meta->mem_pool) >> PAGE_SHIFT;
+#else
 	alloced_pages = zs_get_total_pages(meta->mem_pool);
+#endif
 	update_used_max(zram, alloced_pages);
 
 	if (zram->limit_pages && alloced_pages > zram->limit_pages) {
+#ifdef CONFIG_ZPOOL
+		zpool_free(meta->mem_pool, handle);
+#else
 		zs_free(meta->mem_pool, handle);
+#endif
 		ret = -ENOMEM;
 		goto out;
 	}
 
+#ifdef CONFIG_ZPOOL
+	cmem = zpool_map_handle(meta->mem_pool, handle, ZPOOL_MM_WO);
+#else
 	cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_WO);
+#endif
 
 	if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) {
 		src = kmap_atomic(page);
@@ -779,7 +872,11 @@ compress_again:
 
 	zcomp_stream_put(zram->comp);
 	zstrm = NULL;
+#ifdef CONFIG_ZPOOL
+	zpool_unmap_handle(meta->mem_pool, handle);
+#else
 	zs_unmap_object(meta->mem_pool, handle);
+#endif
 
 	/*
 	 * Free memory associated with this sector
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 74fcf10..68f1222 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -17,6 +17,7 @@
 
 #include <linux/rwsem.h>
 #include <linux/zsmalloc.h>
+#include <linux/zpool.h>
 #include <linux/crypto.h>
 
 #include "zcomp.h"
@@ -91,7 +92,11 @@ struct zram_stats {
 
 struct zram_meta {
 	struct zram_table_entry *table;
+#ifdef CONFIG_ZPOOL
+	struct zpool *mem_pool;
+#else
 	struct zs_pool *mem_pool;
+#endif
 };
 
 struct zram {
-- 
1.9.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxx.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]