qcacmn: Fix memory leak in dp pdev attach failure case
Currently the failure in dp_rx_pdev_mon_attach, during dp_pdev_attach_wifi3, does not cleanup the rx buffers and hence that memory is leaked. Follow the proper cleanup sequence to avoid leaking the rx buffer memory. CRs-Fixed: 2451982 Change-Id: Idef308e11c46fe3e7ae9199a6fcf05ca83210b6b
This commit is contained in:
@@ -3402,13 +3402,13 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
|
|||||||
if (dp_rx_pdev_mon_attach(pdev)) {
|
if (dp_rx_pdev_mon_attach(pdev)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
"dp_rx_pdev_mon_attach failed");
|
"dp_rx_pdev_mon_attach failed");
|
||||||
goto fail1;
|
goto rx_mon_attach_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp_wdi_event_attach(pdev)) {
|
if (dp_wdi_event_attach(pdev)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
"dp_wdi_evet_attach failed");
|
"dp_wdi_evet_attach failed");
|
||||||
goto fail1;
|
goto wdi_attach_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the reo destination during initialization */
|
/* set the reo destination during initialization */
|
||||||
@@ -3445,6 +3445,16 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
|
|||||||
|
|
||||||
return (struct cdp_pdev *)pdev;
|
return (struct cdp_pdev *)pdev;
|
||||||
|
|
||||||
|
wdi_attach_fail:
|
||||||
|
/*
|
||||||
|
* dp_mon_link_desc_pool_cleanup is done in dp_pdev_detach
|
||||||
|
* and hence need not to be done here.
|
||||||
|
*/
|
||||||
|
dp_rx_pdev_mon_detach(pdev);
|
||||||
|
|
||||||
|
rx_mon_attach_fail:
|
||||||
|
dp_rx_pdev_detach(pdev);
|
||||||
|
|
||||||
fail1:
|
fail1:
|
||||||
if (pdev->invalid_peer)
|
if (pdev->invalid_peer)
|
||||||
qdf_mem_free(pdev->invalid_peer);
|
qdf_mem_free(pdev->invalid_peer);
|
||||||
|
@@ -1484,6 +1484,78 @@ dp_rx_pdev_mon_buf_detach(struct dp_pdev *pdev, int mac_id)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_rx_pdev_mon_cmn_detach() - detach dp rx for monitor mode
|
||||||
|
* @pdev: core txrx pdev context
|
||||||
|
* @mac_id: mac_id for which deinit is to be done
|
||||||
|
*
|
||||||
|
* This function will free DP Rx resources for
|
||||||
|
* monitor mode
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS_SUCCESS: success
|
||||||
|
* QDF_STATUS_E_RESOURCES: Error return
|
||||||
|
*/
|
||||||
|
static QDF_STATUS
|
||||||
|
dp_rx_pdev_mon_cmn_detach(struct dp_pdev *pdev, int mac_id) {
|
||||||
|
struct dp_soc *soc = pdev->soc;
|
||||||
|
uint8_t pdev_id = pdev->pdev_id;
|
||||||
|
int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
|
||||||
|
|
||||||
|
dp_mon_link_desc_pool_cleanup(soc, mac_for_pdev);
|
||||||
|
dp_rx_pdev_mon_status_detach(pdev, mac_for_pdev);
|
||||||
|
dp_rx_pdev_mon_buf_detach(pdev, mac_for_pdev);
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_rx_pdev_mon_cmn_attach() - attach DP RX for monitor mode
|
||||||
|
* @pdev: core txrx pdev context
|
||||||
|
* @mac_id: mac_id for which init is to be done
|
||||||
|
*
|
||||||
|
* This function Will allocate dp rx resource and
|
||||||
|
* initialize resources for monitor mode.
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS_SUCCESS: success
|
||||||
|
* QDF_STATUS_E_RESOURCES: Error return
|
||||||
|
*/
|
||||||
|
static QDF_STATUS
|
||||||
|
dp_rx_pdev_mon_cmn_attach(struct dp_pdev *pdev, int mac_id) {
|
||||||
|
struct dp_soc *soc = pdev->soc;
|
||||||
|
uint8_t pdev_id = pdev->pdev_id;
|
||||||
|
int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
status = dp_rx_pdev_mon_buf_attach(pdev, mac_for_pdev);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||||
|
dp_err("%s: dp_rx_pdev_mon_buf_attach() failed\n", __func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dp_rx_pdev_mon_status_attach(pdev, mac_for_pdev);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||||
|
dp_err("%s: dp_rx_pdev_mon_status_attach() failed", __func__);
|
||||||
|
goto mon_buf_detach;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dp_mon_link_desc_pool_setup(soc, mac_for_pdev);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||||
|
dp_err("%s: dp_mon_link_desc_pool_setup() failed", __func__);
|
||||||
|
goto mon_status_detach;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
|
mon_status_detach:
|
||||||
|
dp_rx_pdev_mon_status_detach(pdev, mac_for_pdev);
|
||||||
|
|
||||||
|
mon_buf_detach:
|
||||||
|
dp_rx_pdev_mon_buf_detach(pdev, mac_for_pdev);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_rx_pdev_mon_attach() - attach DP RX for monitor mode
|
* dp_rx_pdev_mon_attach() - attach DP RX for monitor mode
|
||||||
* @pdev: core txrx pdev context
|
* @pdev: core txrx pdev context
|
||||||
@@ -1497,7 +1569,6 @@ dp_rx_pdev_mon_buf_detach(struct dp_pdev *pdev, int mac_id)
|
|||||||
*/
|
*/
|
||||||
QDF_STATUS
|
QDF_STATUS
|
||||||
dp_rx_pdev_mon_attach(struct dp_pdev *pdev) {
|
dp_rx_pdev_mon_attach(struct dp_pdev *pdev) {
|
||||||
struct dp_soc *soc = pdev->soc;
|
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
uint8_t pdev_id = pdev->pdev_id;
|
uint8_t pdev_id = pdev->pdev_id;
|
||||||
int mac_id;
|
int mac_id;
|
||||||
@@ -1506,37 +1577,25 @@ dp_rx_pdev_mon_attach(struct dp_pdev *pdev) {
|
|||||||
"%s: pdev attach id=%d", __func__, pdev_id);
|
"%s: pdev attach id=%d", __func__, pdev_id);
|
||||||
|
|
||||||
for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
|
for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
|
||||||
int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
|
status = dp_rx_pdev_mon_cmn_attach(pdev, mac_id);
|
||||||
|
|
||||||
status = dp_rx_pdev_mon_buf_attach(pdev, mac_for_pdev);
|
|
||||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
"%s: dp_rx_pdev_mon_buf_attach() failed\n",
|
"%s: dp_rx_pdev_mon_cmn_attach(%d) failed\n",
|
||||||
__func__);
|
__func__, mac_id);
|
||||||
return status;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
status = dp_rx_pdev_mon_status_attach(pdev, mac_for_pdev);
|
|
||||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
|
||||||
"%s: dp_rx_pdev_mon_status_attach() failed",
|
|
||||||
__func__);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = dp_mon_link_desc_pool_setup(soc, mac_for_pdev);
|
|
||||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
|
||||||
"%s: dp_mon_link_desc_pool_setup() failed",
|
|
||||||
__func__);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pdev->mon_last_linkdesc_paddr = 0;
|
pdev->mon_last_linkdesc_paddr = 0;
|
||||||
pdev->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
|
pdev->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
|
||||||
qdf_spinlock_create(&pdev->mon_lock);
|
qdf_spinlock_create(&pdev->mon_lock);
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
for (mac_id = mac_id - 1; mac_id >= 0; mac_id--)
|
||||||
|
dp_rx_pdev_mon_cmn_detach(pdev, mac_id);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDF_STATUS
|
QDF_STATUS
|
||||||
|
Reference in New Issue
Block a user