1. Fix local variable type. 2. Fix memory leak in sgl-related interfaces.
Weili Qian (3): uadk/v1 - fix local variable type drv/qm: fix memory leak in hisi_qm_create_sglpool() uadk/v1: fix memory leak in wd_sgl.c
drv/hisi_qm_udrv.c | 7 ++--- v1/drv/hisi_rng_udrv.c | 2 +- v1/wd_sgl.c | 58 ++++++++++++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 23 deletions(-)
The return type of 'wd_reg_read' is '__u32'. Therefore, change the local variable 'ret' type from 'int' to '__u32'.
Signed-off-by: Weili Qian qianweili@huawei.com --- v1/drv/hisi_rng_udrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v1/drv/hisi_rng_udrv.c b/v1/drv/hisi_rng_udrv.c index b86a948..09fa2c3 100644 --- a/v1/drv/hisi_rng_udrv.c +++ b/v1/drv/hisi_rng_udrv.c @@ -94,7 +94,7 @@ static int rng_read(struct rng_queue_info *info, struct wcrypto_rng_msg *msg) __u32 max = msg->in_bytes; __u32 currsize = 0; int recv_count = 0; - int val; + __u32 val;
do { val = wd_reg_read((void *)((uintptr_t)info->mmio_base +
In 'hisi_qm_create_sglpool()', if 'hisi_qm_create_sgl() failed', current 'sgl_pool->sgl_num == 0', the 'hisi_qm_free_sglpool()' cannot release the applied sgl.
Signed-off-by: Weili Qian qianweili@huawei.com --- drv/hisi_qm_udrv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c index acc2877..d86a692 100644 --- a/drv/hisi_qm_udrv.c +++ b/drv/hisi_qm_udrv.c @@ -648,8 +648,7 @@ static void hisi_qm_free_sglpool(struct hisi_sgl_pool *pool)
if (pool->sgl) { for (i = 0; i < pool->sgl_num; i++) - if (pool->sgl[i]) - free(pool->sgl[i]); + free(pool->sgl[i]);
free(pool->sgl); } @@ -692,8 +691,10 @@ handle_t hisi_qm_create_sglpool(__u32 sgl_num, __u32 sge_num) /* base the sgl_num create the sgl chain */ for (i = 0; i < sgl_num; i++) { sgl_pool->sgl[i] = hisi_qm_create_sgl(sge_num); - if (!sgl_pool->sgl[i]) + if (!sgl_pool->sgl[i]) { + sgl_pool->sgl_num = i; goto err_out; + }
sgl_pool->sgl_align[i] = hisi_qm_align_sgl(sgl_pool->sgl[i], sge_num);
Add missing free() upon failure of 'wd_alloc_sgl' and 'sgl_pool_init'.
Signed-off-by: Weili Qian qianweili@huawei.com --- v1/wd_sgl.c | 58 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/v1/wd_sgl.c b/v1/wd_sgl.c index a11190a..97e4b73 100644 --- a/v1/wd_sgl.c +++ b/v1/wd_sgl.c @@ -119,6 +119,25 @@ static void sgl_sge_init(struct wd_sgl *sgl, __u8 num, void *buf) sgl->sge[num].flag &= ~FLAG_SGE_CHAIN; }
+static void sgl_chain_destory(struct wd_queue *q, struct wd_sglpool *pool) +{ + __u16 sgl_num = pool->setup.sgl_num; + struct wd_mm_br br = pool->buf_br; + struct wd_sgl *sgl; + __u16 i, j; + + for (i = 0; i < sgl_num; i++) { + sgl = pool->sgl_blk[i]; + drv_uninit_sgl(q, pool, sgl); + + for (j = 0; j < sgl->buf_num; j++) + br.free(br.usr, sgl->sge[j].buf); + } + + free(pool->sgl_blk); + pool->sgl_blk = NULL; +} + static int sgl_chain_build(struct wd_queue *q, struct wd_sglpool *pool) { struct wd_sglpool_setup *sp = &pool->setup; @@ -290,15 +309,14 @@ static int sgl_pool_init(struct wd_queue *q, struct wd_sglpool *pool) buf_pool = sgl_buf_pool_init(q, pool); if (!buf_pool) { WD_ERR("failed to create hardware buf pool.\n"); - goto err; + goto free_sgl_pool; } pool->buf_pool = buf_pool;
ret = sgl_chain_build(q, pool); if (ret) { WD_ERR("failed to build sgl chain, ret = %d.\n", ret); - sgl_buf_pool_uninit(buf_pool); - goto err; + goto free_buf_pool; }
pool->q = q; @@ -309,14 +327,19 @@ static int sgl_pool_init(struct wd_queue *q, struct wd_sglpool *pool) ret = wd_blk_alloc_failures(sgl_pool, &pool->alloc_failures); if (ret != WD_SUCCESS) { WD_ERR("wd blk alloc failures failed, ret = %d.\n", ret); - goto err; + goto free_sgl_chain; }
pool->free_sgl_num = pool->setup.sgl_num; pool->sgl_mem_sz = sp.buf_num_in_sgl * sp.buf_size;
return WD_SUCCESS; -err: + +free_sgl_chain: + sgl_chain_destory(q, pool); +free_buf_pool: + sgl_buf_pool_uninit(buf_pool); +free_sgl_pool: sgl_blk_pool_uninit(sgl_pool); return ret; } @@ -447,8 +470,6 @@ void wd_sglpool_destroy(void *pool) { struct wd_sglpool *p = pool; struct wd_sglpool_setup sp; - struct wd_sgl *sgl; - int i, j;
if (!p || !p->sgl_blk || !p->buf_pool || !p->sgl_pool) { WD_ERR("pool parameter is err!\n"); @@ -461,20 +482,11 @@ void wd_sglpool_destroy(void *pool) return; }
- for (i = 0; i < sp.sgl_num; i++) { - sgl = p->sgl_blk[i]; - drv_uninit_sgl(p->q, pool, sgl); - - for (j = 0; j < sp.buf_num_in_sgl; j++) - wd_free_blk(p->buf_pool, sgl->sge[j].buf); - } - + sgl_chain_destory(p->q, p); wd_blkpool_destroy(p->sgl_pool); p->sgl_pool = NULL; wd_blkpool_destroy(p->buf_pool); p->buf_pool = NULL; - free(p->sgl_blk); - p->sgl_blk = NULL;
free(p); } @@ -510,18 +522,26 @@ struct wd_sgl *wd_alloc_sgl(void *pool, __u32 size) WD_ERR("alloc for sg2 failed!\n"); __atomic_add_fetch(&p->alloc_failures, 1, __ATOMIC_RELAXED); - return NULL; + goto free_sg1; } __atomic_sub_fetch(&p->free_sgl_num, 1, __ATOMIC_RELAXED);
ret = wd_sgl_merge(sg1, sg2); if (ret) { WD_ERR("merge two sgls failed for u!, ret = %d.\n", ret); - return NULL; + goto free_sg2; } }
return sg1; + +free_sg2: + wd_free_blk(p->sgl_pool, sg2); + wd_get_free_blk_num(p->sgl_pool, &p->free_sgl_num); +free_sg1: + wd_free_blk(p->sgl_pool, sg1); + wd_get_free_blk_num(p->sgl_pool, &p->free_sgl_num); + return NULL; }
void wd_free_sgl(void *pool, struct wd_sgl *sgl)