libwd/0006-uadk-v1-fix-memory-leak-in-wd_sgl.c.patch
2023-09-28 09:15:32 +08:00

147 lines
3.7 KiB
Diff

From a3236d7933ae96a82577fb7969b66fda07b8b93c Mon Sep 17 00:00:00 2001
From: Weili Qian <qianweili@huawei.com>
Date: Mon, 10 Jul 2023 11:49:33 +0800
Subject: [PATCH 06/26] uadk/v1: fix memory leak in wd_sgl.c
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)
--
2.25.1