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
This commit is contained in:
lihual
2021-07-16 17:15:08 +08:00
committed by Madan Koyyalamudi
parent 08c37be1d9
commit bde0001eed
2 changed files with 47 additions and 44 deletions

View File

@@ -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