[PATCH] mm/zswap: provide unique zpool name

From: Dan Streetman
Date: Thu Apr 28 2016 - 05:16:28 EST


Instead of using "zswap" as the name for all zpools created, add
an atomic counter and use "zswap%x" with the counter number for each
zpool created, to provide a unique name for each new zpool.

As zsmalloc, one of the zpool implementations, requires/expects a
unique name for each pool created, zswap should provide a unique name.
The zsmalloc pool creation does not fail if a new pool with a
conflicting name is created, unless CONFIG_ZSMALLOC_STAT is enabled;
in that case, zsmalloc pool creation fails with -ENOMEM. Then zswap
will be unable to change its compressor parameter if its zpool is
zsmalloc; it also will be unable to change its zpool parameter back
to zsmalloc, if it has any existing old zpool using zsmalloc with
page(s) in it. Attempts to change the parameters will result in
failure to create the zpool. This changes zswap to provide a
unique name for each zpool creation.

Fixes: f1c54846ee45 ("zswap: dynamic pool creation")
Reported-by: Sergey Senozhatsky <sergey.senozhatsky@xxxxxxxxx>
Cc: Dan Streetman <dan.streetman@xxxxxxxxxxxxx>
Signed-off-by: Dan Streetman <ddstreet@xxxxxxxx>
---
mm/zswap.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/mm/zswap.c b/mm/zswap.c
index f207da7..275b22c 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -170,6 +170,8 @@ static struct zswap_tree *zswap_trees[MAX_SWAPFILES];
static LIST_HEAD(zswap_pools);
/* protects zswap_pools list modification */
static DEFINE_SPINLOCK(zswap_pools_lock);
+/* pool counter to provide unique names to zpool */
+static atomic_t zswap_pools_count = ATOMIC_INIT(0);

/* used by param callback function */
static bool zswap_init_started;
@@ -565,6 +567,7 @@ static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor)
static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
{
struct zswap_pool *pool;
+ char name[38]; /* 'zswap' + 32 char (max) num + \0 */
gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM;

pool = kzalloc(sizeof(*pool), GFP_KERNEL);
@@ -573,7 +576,10 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
return NULL;
}

- pool->zpool = zpool_create_pool(type, "zswap", gfp, &zswap_zpool_ops);
+ /* unique name for each pool specifically required by zsmalloc */
+ snprintf(name, 38, "zswap%x", atomic_inc_return(&zswap_pools_count));
+
+ pool->zpool = zpool_create_pool(type, name, gfp, &zswap_zpool_ops);
if (!pool->zpool) {
pr_err("%s zpool not available\n", type);
goto error;
--
2.7.4