From: Wang Wensheng wangwensheng4@huawei.com
The element of the pool_reg_arg could be defferent between different algorithm, so we could not judge if a newly registered POOL confilicts with an original one in the framework. Add a hook for each algorithm to solve the problem.
Pass the pool_reg_arg not only the POOL size to the init hook of the specified algorithm for the same reason above.
Delete the size element in xshm_pool structrue.
Signed-off-by: Wang Wensheng wangwensheng4@huawei.com --- lib/xshmem/xshmem_framework.c | 33 ++++++++++++++++++++++----------- lib/xshmem/xshmem_framework.h | 4 ++-- lib/xshmem/xshmem_fsc.c | 16 ++++++++++++---- 3 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/lib/xshmem/xshmem_framework.c b/lib/xshmem/xshmem_framework.c index ae6899f..61fe44a 100644 --- a/lib/xshmem/xshmem_framework.c +++ b/lib/xshmem/xshmem_framework.c @@ -199,21 +199,22 @@ static int xshmem_pool_detach(struct xshm_task *task, struct xshm_pool *xp) /* * get the POOL specified by key, create one if it not exist. */ -static struct xshm_pool *xshmem_pool_create(char *key, unsigned int key_len, - struct xshm_pool_algo *algo, unsigned int pool_size) +static struct xshm_pool *xshmem_pool_create(struct xshm_pool_algo *algo, struct xshm_reg_arg *arg) { int id, ret; struct xshm_pool *xp; struct hlist_head *bucket; + char *key = arg->key; + unsigned int key_len = arg->key_len;
bucket = hash_bucket(key, key_len);
mutex_lock(&xshmem_mutex); hlist_for_each_entry(xp, bucket, hnode) if (key_len == xp->key_len && !strncmp(key, xp->key, key_len)) { - if (xp->size != pool_size || xp->algo != algo) { + if (xp->algo != algo || !algo->xshm_pool_same(xp, arg)) { mutex_unlock(&xshmem_mutex); - pr_err("the pool size or algorithm invalid\n"); + pr_err("the pool reg arg check failed\n"); return ERR_PTR(-EINVAL); } else goto exist; @@ -226,8 +227,7 @@ static struct xshm_pool *xshmem_pool_create(char *key, unsigned int key_len, }
xp->algo = algo; - xp->size = pool_size; - ret = algo->xshm_pool_init(xp); + ret = algo->xshm_pool_init(xp, arg); if (ret < 0) { mutex_unlock(&xshmem_mutex); kfree(xp); @@ -338,7 +338,8 @@ static int ioctl_xshmem_pool_register(struct xshm_task *task, unsigned long arg) return -EFAULT; }
- xp = xshmem_pool_create(key, key_len, algo, reg_arg.pool_size); + reg_arg.key = key; + xp = xshmem_pool_create(algo, ®_arg); if (IS_ERR(xp)) return PTR_ERR(xp);
@@ -620,7 +621,8 @@ int xshmem_register_algo(struct xshm_pool_algo *algo) struct xshm_pool_algo *tmp;
if (!algo || !algo->xshm_pool_init || !algo->xshm_pool_free || - !algo->xshm_block_alloc || !algo->xshm_block_free) + !algo->xshm_block_alloc || !algo->xshm_block_free || + !algo->xshm_pool_same) return -EINVAL;
list_for_each_entry(tmp, ®istered_algo, algo_node) @@ -638,15 +640,23 @@ int xshmem_register_algo(struct xshm_pool_algo *algo) } EXPORT_SYMBOL_GPL(xshmem_register_algo);
-static int empty_algo_pool_init(struct xshm_pool *xp) +static bool empty_algo_pool_same(struct xshm_pool *xp, struct xshm_reg_arg *arg) { - pr_info("pool_init_hook: algo:%s, pool_size: %d\n", xp->algo->name, xp->size); + pr_info("pool_same_hook: algo:%s, pool_size: %d\n", xp->algo->name, arg->pool_size); + return (unsigned long)xp->private == arg->pool_size; +} + +static int empty_algo_pool_init(struct xshm_pool *xp, struct xshm_reg_arg *arg) +{ + pr_info("pool_init_hook: algo:%s, pool_size: %d\n", xp->algo->name, arg->pool_size); + xp->private = (void *)(unsigned long)arg->pool_size; return 0; }
static int empty_algo_pool_free(struct xshm_pool *xp) { - pr_info("pool_free_hook: algo:%s, pool_size: %d, pool_id:%d\n", xp->algo->name, xp->size, xp->pool_id); + pr_info("pool_free_hook: algo:%s, pool_size: %ld, pool_id:%d\n", + xp->algo->name, (unsigned long)xp->private, xp->pool_id); return 0; }
@@ -666,6 +676,7 @@ static int empty_algo_block_free(struct xshm_pool *xp, struct xshm_block *blk) static struct xshm_pool_algo empty_algo = { .num = XSHMEM_ALGO_EMPTY, .name = "empty_algo", + .xshm_pool_same = empty_algo_pool_same, .xshm_pool_init = empty_algo_pool_init, .xshm_pool_free = empty_algo_pool_free, .xshm_block_alloc = empty_algo_block_alloc, diff --git a/lib/xshmem/xshmem_framework.h b/lib/xshmem/xshmem_framework.h index 3624841..f543c27 100644 --- a/lib/xshmem/xshmem_framework.h +++ b/lib/xshmem/xshmem_framework.h @@ -11,7 +11,6 @@
struct xshm_pool { int pool_id; - int size; atomic_t refcnt;
/* Used to protect the list of TASK attached */ @@ -47,7 +46,8 @@ struct xshm_pool_algo { int num; char name[ALGO_NAME_MAX]; struct list_head algo_node; - int (*xshm_pool_init)(struct xshm_pool *xp); + bool (*xshm_pool_same)(struct xshm_pool *xp, struct xshm_reg_arg *arg); + int (*xshm_pool_init)(struct xshm_pool *xp, struct xshm_reg_arg *arg); int (*xshm_pool_free)(struct xshm_pool *xp); int (*xshm_block_alloc)(struct xshm_pool *xp, struct xshm_block *blk, u32 size); int (*xshm_block_free)(struct xshm_pool *xp, struct xshm_block *blk); diff --git a/lib/xshmem/xshmem_fsc.c b/lib/xshmem/xshmem_fsc.c index 2b18a25..941918d 100644 --- a/lib/xshmem/xshmem_fsc.c +++ b/lib/xshmem/xshmem_fsc.c @@ -65,13 +65,20 @@ static void fsc_delete_block(struct fsc_ctrl *ctrl, struct fsc_block *block) clear_bit(type, ctrl->free_map); }
-static int fsc_algo_pool_init(struct xshm_pool *xp) +static bool fsc_algo_pool_same(struct xshm_pool *xp, struct xshm_reg_arg *arg) +{ + struct fsc_ctrl *ctrl = xp->private; + + return ctrl->total_size == arg->pool_size; +} + +static int fsc_algo_pool_init(struct xshm_pool *xp, struct xshm_reg_arg *arg) { int i; struct fsc_ctrl *ctrl; struct fsc_block *block;
- if (!IS_ALIGNED(xp->size, XSHMEM_FSC_ALIGN) || !xp->size) { + if (!IS_ALIGNED(arg->pool_size, XSHMEM_FSC_ALIGN) || !arg->pool_size) { pr_err("input xshm_pool size invalid\n"); return -EINVAL; } @@ -84,14 +91,14 @@ static int fsc_algo_pool_init(struct xshm_pool *xp) return -ENOMEM; }
- ctrl->total_size = xp->size; + ctrl->total_size = arg->pool_size; ctrl->free_size = 0; INIT_LIST_HEAD(&ctrl->block_head); for (i = 0; i < ARRAY_SIZE(ctrl->free_list); i++) INIT_LIST_HEAD(&ctrl->free_list[i]);
block->start = 0; - block->size = xp->size; + block->size = arg->pool_size; list_add_tail(&block->block_node, &ctrl->block_head); fsc_insert_block(ctrl, block);
@@ -254,6 +261,7 @@ static int fsc_algo_block_free(struct xshm_pool *xp, struct xshm_block *blk) struct xshm_pool_algo fsc_algo = { .num = XSHMEM_ALGO_FSC, .name = "fsc_algo", + .xshm_pool_same = fsc_algo_pool_same, .xshm_pool_init = fsc_algo_pool_init, .xshm_pool_free = fsc_algo_pool_free, .xshm_block_alloc = fsc_algo_block_alloc,