From b68986ce59e52b57256eaef90c6e24493822a3ee Mon Sep 17 00:00:00 2001
From: Wenkai Lin <linwenkai6@hisilicon.com>
Date: Thu, 10 Mar 2022 20:03:19 +0800
Subject: [PATCH 094/109] uadk: v1: fix drv_reserve_mem memory leak

share region memory should be freed and
qfr region should be unmaped if drv_reserve_mem fail.

Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
---
 v1/wd.c         |  9 +--------
 v1/wd_adapter.c | 24 ++++++++++++++++++++++--
 v1/wd_adapter.h |  1 +
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/v1/wd.c b/v1/wd.c
index 39c4167..b94ec43 100644
--- a/v1/wd.c
+++ b/v1/wd.c
@@ -618,7 +618,6 @@ err_with_dev:
 
 void wd_release_queue(struct wd_queue *q)
 {
-	struct wd_ss_region *rg;
 	struct wd_ss_region_list *head;
 	struct q_info *qinfo, *sqinfo;
 
@@ -645,13 +644,7 @@ void wd_release_queue(struct wd_queue *q)
 	if (qinfo->ss_size)
 		drv_unmap_reserve_mem(q, qinfo->ss_va, qinfo->ss_size);
 
-	while (true) {
-		rg = TAILQ_FIRST(&qinfo->ss_list);
-		if (!rg)
-			break;
-		TAILQ_REMOVE(&qinfo->ss_list, rg, next);
-		free(rg);
-	}
+	drv_free_slice(q);
 
 	wd_close_queue(q);
 	free((void *)qinfo->dev_info);
diff --git a/v1/wd_adapter.c b/v1/wd_adapter.c
index f8bef2b..e53c561 100644
--- a/v1/wd_adapter.c
+++ b/v1/wd_adapter.c
@@ -150,6 +150,20 @@ int drv_recv(struct wd_queue *q, void **req, __u32 num)
 	return hw_dio_tbl[qinfo->hw_type_id].recv(q, req, num);
 }
 
+void drv_free_slice(struct wd_queue *q)
+{
+	struct q_info *qinfo = q->qinfo;
+	struct wd_ss_region *rgn;
+
+        while (true) {
+                rgn = TAILQ_FIRST(&qinfo->ss_list);
+                if (!rgn)
+                        break;
+                TAILQ_REMOVE(&qinfo->ss_list, rgn, next);
+                free(rgn);
+        }
+}
+
 void drv_add_slice(struct wd_queue *q, struct wd_ss_region *rgn)
 {
 	struct q_info *qinfo = q->qinfo;
@@ -209,12 +223,12 @@ void *drv_reserve_mem(struct wd_queue *q, size_t size)
 		if (ret < 0) {
 			drv_show_ss_slices(q);
 			WD_ERR("get DMA fail!\n");
-			return NULL;
+			goto err_out;
 		}
 		rgn = malloc(sizeof(*rgn));
 		if (!rgn) {
 			WD_ERR("alloc ss region fail!\n");
-			return NULL;
+			goto err_out;
 		}
 		memset(rgn, 0, sizeof(*rgn));
 
@@ -231,6 +245,12 @@ void *drv_reserve_mem(struct wd_queue *q, size_t size)
 	}
 
 	return ptr;
+
+err_out:
+	drv_free_slice(q);
+	drv_unmap_reserve_mem(q, ptr, size);
+
+	return NULL;
 }
 
 void drv_unmap_reserve_mem(struct wd_queue *q, void *addr, size_t size)
diff --git a/v1/wd_adapter.h b/v1/wd_adapter.h
index e1e1233..a5edd24 100644
--- a/v1/wd_adapter.h
+++ b/v1/wd_adapter.h
@@ -67,6 +67,7 @@ void drv_close(struct wd_queue *q);
 int drv_send(struct wd_queue *q, void **req, __u32 num);
 int drv_recv(struct wd_queue *q, void **req, __u32 num);
 void drv_flush(struct wd_queue *q);
+void drv_free_slice(struct wd_queue *q);
 void *drv_reserve_mem(struct wd_queue *q, size_t size);
 void drv_unmap_reserve_mem(struct wd_queue *q, void *addr, size_t size);
 int drv_get_sgl_info(struct wd_queue *q, struct hw_sgl_info *info);
-- 
2.27.0

