#include <linux/math64.h>
#include <linux/crypto.h>
#include <linux/string.h>
+#include <linux/idr.h>
#include "tmem.h"
#include "../zsmalloc/zsmalloc.h"
(__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC)
#endif
-#define MAX_POOLS_PER_CLIENT 16
-
#define MAX_CLIENTS 16
#define LOCAL_CLIENT ((uint16_t)-1)
MODULE_LICENSE("GPL");
struct zcache_client {
- struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT];
+ struct idr tmem_pools;
struct zs_pool *zspool;
bool allocated;
atomic_t refcount;
goto out;
atomic_inc(&cli->refcount);
}
- if (poolid < MAX_POOLS_PER_CLIENT) {
- pool = cli->tmem_pools[poolid];
- if (pool != NULL)
- atomic_inc(&pool->refcount);
- }
+ pool = idr_find(&cli->tmem_pools, poolid);
+ if (pool != NULL)
+ atomic_inc(&pool->refcount);
out:
return pool;
}
cli->zspool = zs_create_pool("zcache", ZCACHE_GFP_MASK);
if (cli->zspool == NULL)
goto out;
+ idr_init(&cli->tmem_pools);
#endif
ret = 0;
out:
if (cli == NULL)
goto out;
atomic_inc(&cli->refcount);
- pool = cli->tmem_pools[pool_id];
+ pool = idr_find(&cli->tmem_pools, pool_id);
if (pool == NULL)
goto out;
- cli->tmem_pools[pool_id] = NULL;
+ idr_remove(&cli->tmem_pools, pool_id);
/* wait for pool activity on other cpus to quiesce */
while (atomic_read(&pool->refcount) != 0)
;
int poolid = -1;
struct tmem_pool *pool;
struct zcache_client *cli = NULL;
+ int r;
if (cli_id == LOCAL_CLIENT)
cli = &zcache_host;
goto out;
}
- for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++)
- if (cli->tmem_pools[poolid] == NULL)
- break;
- if (poolid >= MAX_POOLS_PER_CLIENT) {
- pr_info("zcache: pool creation failed: max exceeded\n");
+ do {
+ r = idr_pre_get(&cli->tmem_pools, GFP_ATOMIC);
+ if (r != 1) {
+ kfree(pool);
+ pr_info("zcache: pool creation failed: out of memory\n");
+ goto out;
+ }
+ r = idr_get_new(&cli->tmem_pools, pool, &poolid);
+ } while (r == -EAGAIN);
+ if (r) {
+ pr_info("zcache: pool creation failed: error %d\n", r);
kfree(pool);
- poolid = -1;
goto out;
}
+
atomic_set(&pool->refcount, 0);
pool->client = cli;
pool->pool_id = poolid;
tmem_new_pool(pool, flags);
- cli->tmem_pools[poolid] = pool;
pr_info("zcache: created %s tmem pool, id=%d, client=%d\n",
flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral",
poolid, cli_id);