From bde0001eedd385776015d2b09306e5104b4e5c64 Mon Sep 17 00:00:00 2001 From: lihual Date: Fri, 16 Jul 2021 17:15:08 +0800 Subject: [PATCH] qcacmn: Fix a memory leak during soc attach hif_ext_group and soc->intr_ctx[i].lro_ctx are allocated but not free while fail to register parts of ext_group in hif_register_ext_group, which cause memory leak. Fix is to detach according resource before return. Change-Id: I03ecc37437d09bf9275f128b1f2b320124a7df64 CRs-Fixed: 2988891 --- dp/wifi3.0/dp_main.c | 86 ++++++++++++++++++++++---------------------- hif/src/hif_exec.c | 5 ++- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 4729c2bc53..abf1579ca4 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -2913,6 +2913,48 @@ dp_soc_near_full_interrupt_attach(struct dp_soc *soc, int num_irq, } #endif +/* + * dp_soc_interrupt_detach() - Deregister any allocations done for interrupts + * @txrx_soc: DP SOC handle + * + * Return: none + */ +static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) +{ + struct dp_soc *soc = (struct dp_soc *)txrx_soc; + int i; + + if (soc->intr_mode == DP_INTR_POLL) { + qdf_timer_free(&soc->int_timer); + } else { + hif_deconfigure_ext_group_interrupts(soc->hif_handle); + hif_deregister_exec_group(soc->hif_handle, "dp_intr"); + hif_deregister_exec_group(soc->hif_handle, "dp_nf_intr"); + } + + for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { + soc->intr_ctx[i].tx_ring_mask = 0; + soc->intr_ctx[i].rx_ring_mask = 0; + soc->intr_ctx[i].rx_mon_ring_mask = 0; + soc->intr_ctx[i].rx_err_ring_mask = 0; + soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0; + soc->intr_ctx[i].reo_status_ring_mask = 0; + soc->intr_ctx[i].rxdma2host_ring_mask = 0; + soc->intr_ctx[i].host2rxdma_ring_mask = 0; + soc->intr_ctx[i].host2rxdma_mon_ring_mask = 0; + soc->intr_ctx[i].rx_near_full_grp_1_mask = 0; + soc->intr_ctx[i].rx_near_full_grp_2_mask = 0; + soc->intr_ctx[i].tx_ring_near_full_mask = 0; + + hif_event_history_deinit(soc->hif_handle, i); + qdf_lro_deinit(soc->intr_ctx[i].lro_ctx); + } + + qdf_mem_set(&soc->mon_intr_id_lmac_map, + sizeof(soc->mon_intr_id_lmac_map), + DP_MON_INVALID_LMAC_ID); +} + /* * dp_soc_interrupt_attach() - Register handlers for DP interrupts * @txrx_soc: DP SOC handle @@ -3011,7 +3053,7 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) if (ret) { dp_init_err("%pK: failed, ret = %d", soc, ret); - + dp_soc_interrupt_detach(txrx_soc); return QDF_STATUS_E_FAILURE; } @@ -3030,48 +3072,6 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) return QDF_STATUS_SUCCESS; } -/* - * dp_soc_interrupt_detach() - Deregister any allocations done for interrupts - * @txrx_soc: DP SOC handle - * - * Return: none - */ -static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) -{ - struct dp_soc *soc = (struct dp_soc *)txrx_soc; - int i; - - if (soc->intr_mode == DP_INTR_POLL) { - qdf_timer_free(&soc->int_timer); - } else { - hif_deconfigure_ext_group_interrupts(soc->hif_handle); - hif_deregister_exec_group(soc->hif_handle, "dp_intr"); - hif_deregister_exec_group(soc->hif_handle, "dp_nf_intr"); - } - - for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { - soc->intr_ctx[i].tx_ring_mask = 0; - soc->intr_ctx[i].rx_ring_mask = 0; - soc->intr_ctx[i].rx_mon_ring_mask = 0; - soc->intr_ctx[i].rx_err_ring_mask = 0; - soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0; - soc->intr_ctx[i].reo_status_ring_mask = 0; - soc->intr_ctx[i].rxdma2host_ring_mask = 0; - soc->intr_ctx[i].host2rxdma_ring_mask = 0; - soc->intr_ctx[i].host2rxdma_mon_ring_mask = 0; - soc->intr_ctx[i].rx_near_full_grp_1_mask = 0; - soc->intr_ctx[i].rx_near_full_grp_2_mask = 0; - soc->intr_ctx[i].tx_ring_near_full_mask = 0; - - hif_event_history_deinit(soc->hif_handle, i); - qdf_lro_deinit(soc->intr_ctx[i].lro_ctx); - } - - qdf_mem_set(&soc->mon_intr_id_lmac_map, - sizeof(soc->mon_intr_id_lmac_map), - DP_MON_INVALID_LMAC_ID); -} - #define AVG_MAX_MPDUS_PER_TID 128 #define AVG_TIDS_PER_CLIENT 2 #define AVG_FLOWS_PER_TID 2 diff --git a/hif/src/hif_exec.c b/hif/src/hif_exec.c index dbb8a988b7..a8b9ec59ab 100644 --- a/hif/src/hif_exec.c +++ b/hif/src/hif_exec.c @@ -1044,7 +1044,10 @@ struct hif_exec_context *hif_exec_create(enum hif_exec_type type, */ void hif_exec_destroy(struct hif_exec_context *ctx) { - qdf_spinlock_destroy(&ctx->irq_lock); + struct hif_softc *scn = HIF_GET_SOFTC(ctx->hif); + + if (scn->ext_grp_irq_configured) + qdf_spinlock_destroy(&ctx->irq_lock); qdf_mem_free(ctx); }