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:

committed by
Madan Koyyalamudi

parent
08c37be1d9
commit
bde0001eed
@@ -2913,6 +2913,48 @@ dp_soc_near_full_interrupt_attach(struct dp_soc *soc, int num_irq,
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* dp_soc_interrupt_attach() - Register handlers for DP interrupts
|
||||||
* @txrx_soc: DP SOC handle
|
* @txrx_soc: DP SOC handle
|
||||||
@@ -3011,7 +3053,7 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc)
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dp_init_err("%pK: failed, ret = %d", soc, ret);
|
dp_init_err("%pK: failed, ret = %d", soc, ret);
|
||||||
|
dp_soc_interrupt_detach(txrx_soc);
|
||||||
return QDF_STATUS_E_FAILURE;
|
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;
|
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_MAX_MPDUS_PER_TID 128
|
||||||
#define AVG_TIDS_PER_CLIENT 2
|
#define AVG_TIDS_PER_CLIENT 2
|
||||||
#define AVG_FLOWS_PER_TID 2
|
#define AVG_FLOWS_PER_TID 2
|
||||||
|
@@ -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)
|
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);
|
qdf_mem_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user