From b68986ce59e52b57256eaef90c6e24493822a3ee Mon Sep 17 00:00:00 2001 From: Wenkai Lin 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 --- 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