qcacmn: Fix memleak in m_copy mode
1. Assign correct first msdu payload 2. Reset mpdu fcs ok bitmap upon reception of next ppdu 3. Free rx_ppdu_buf_q in error cases Change-Id: I4f2e687d51d1e10693adc9cfcdee49190ba6815c CRs-Fixed: 2502889
This commit is contained in:
@@ -3881,6 +3881,7 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force)
|
|||||||
dp_tx_ppdu_stats_detach(pdev);
|
dp_tx_ppdu_stats_detach(pdev);
|
||||||
|
|
||||||
qdf_nbuf_free(pdev->sojourn_buf);
|
qdf_nbuf_free(pdev->sojourn_buf);
|
||||||
|
qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q);
|
||||||
|
|
||||||
dp_cal_client_detach(&pdev->cal_client_ctx);
|
dp_cal_client_detach(&pdev->cal_client_ctx);
|
||||||
|
|
||||||
@@ -7360,6 +7361,13 @@ dp_pdev_tid_stats_osif_drop(struct cdp_pdev *pdev, uint32_t val)
|
|||||||
dp_pdev->stats.tid_stats.osif_drop += val;
|
dp_pdev->stats.tid_stats.osif_drop += val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dp_pdev_disable_mcopy_code(struct dp_pdev *pdev)
|
||||||
|
{
|
||||||
|
pdev->mcopy_mode = 0;
|
||||||
|
qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_config_debug_sniffer()- API to enable/disable debug sniffer
|
* dp_config_debug_sniffer()- API to enable/disable debug sniffer
|
||||||
* @pdev_handle: DP_PDEV handle
|
* @pdev_handle: DP_PDEV handle
|
||||||
@@ -7379,7 +7387,9 @@ dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val)
|
|||||||
switch (val) {
|
switch (val) {
|
||||||
case 0:
|
case 0:
|
||||||
pdev->tx_sniffer_enable = 0;
|
pdev->tx_sniffer_enable = 0;
|
||||||
pdev->mcopy_mode = 0;
|
if (pdev->mcopy_mode)
|
||||||
|
dp_pdev_disable_mcopy_code(pdev);
|
||||||
|
|
||||||
pdev->monitor_configured = false;
|
pdev->monitor_configured = false;
|
||||||
|
|
||||||
if (!pdev->pktlog_ppdu_stats && !pdev->enhanced_stats_en &&
|
if (!pdev->pktlog_ppdu_stats && !pdev->enhanced_stats_en &&
|
||||||
@@ -7402,7 +7412,8 @@ dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val)
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
pdev->tx_sniffer_enable = 1;
|
pdev->tx_sniffer_enable = 1;
|
||||||
pdev->mcopy_mode = 0;
|
if (pdev->mcopy_mode)
|
||||||
|
dp_pdev_disable_mcopy_code(pdev);
|
||||||
pdev->monitor_configured = false;
|
pdev->monitor_configured = false;
|
||||||
|
|
||||||
if (!pdev->pktlog_ppdu_stats)
|
if (!pdev->pktlog_ppdu_stats)
|
||||||
|
@@ -548,6 +548,9 @@ dp_rx_get_fcs_ok_msdu(struct dp_pdev *pdev,
|
|||||||
qdf_nbuf_t status_nbuf = NULL;
|
qdf_nbuf_t status_nbuf = NULL;
|
||||||
unsigned long *fcs_ok_bitmap;
|
unsigned long *fcs_ok_bitmap;
|
||||||
|
|
||||||
|
if (qdf_unlikely(qdf_nbuf_is_queue_empty(&pdev->rx_ppdu_buf_q)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Obtain fcs_ok passed index from bitmap
|
/* Obtain fcs_ok passed index from bitmap
|
||||||
* this index is used to get fcs passed first msdu payload
|
* this index is used to get fcs passed first msdu payload
|
||||||
*/
|
*/
|
||||||
@@ -557,7 +560,10 @@ dp_rx_get_fcs_ok_msdu(struct dp_pdev *pdev,
|
|||||||
mpdu_fcs_ok = qdf_find_first_bit(fcs_ok_bitmap,
|
mpdu_fcs_ok = qdf_find_first_bit(fcs_ok_bitmap,
|
||||||
HAL_RX_MAX_MPDU);
|
HAL_RX_MAX_MPDU);
|
||||||
|
|
||||||
if (mpdu_fcs_ok >= HAL_RX_MAX_MPDU)
|
if (qdf_unlikely(mpdu_fcs_ok >= HAL_RX_MAX_MPDU))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
if (qdf_unlikely(!ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].nbuf))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* Get status buffer by indexing mpdu_fcs_ok index
|
/* Get status buffer by indexing mpdu_fcs_ok index
|
||||||
@@ -565,15 +571,26 @@ dp_rx_get_fcs_ok_msdu(struct dp_pdev *pdev,
|
|||||||
* and clone the buffer
|
* and clone the buffer
|
||||||
*/
|
*/
|
||||||
status_nbuf = ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].nbuf;
|
status_nbuf = ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].nbuf;
|
||||||
|
ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].nbuf = NULL;
|
||||||
|
|
||||||
/* Take ref of status nbuf as this nbuf is to be
|
/* Take ref of status nbuf as this nbuf is to be
|
||||||
* freeed by upper layer.
|
* freeed by upper layer.
|
||||||
*/
|
*/
|
||||||
qdf_nbuf_ref(status_nbuf);
|
qdf_nbuf_ref(status_nbuf);
|
||||||
|
ppdu_info->fcs_ok_msdu_info.first_msdu_payload =
|
||||||
|
ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].first_msdu_payload;
|
||||||
|
ppdu_info->fcs_ok_msdu_info.payload_len =
|
||||||
|
ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].payload_len;
|
||||||
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
/* Free the ppdu status buffer queue */
|
/* Free the ppdu status buffer queue */
|
||||||
qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q);
|
qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q);
|
||||||
|
|
||||||
|
qdf_mem_zero(&ppdu_info->ppdu_msdu_info,
|
||||||
|
(ppdu_info->com_info.mpdu_cnt_fcs_ok +
|
||||||
|
ppdu_info->com_info.mpdu_cnt_fcs_err)
|
||||||
|
* sizeof(struct hal_rx_msdu_payload_info));
|
||||||
return status_nbuf;
|
return status_nbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,6 +599,13 @@ dp_rx_handle_ppdu_status_buf(struct dp_pdev *pdev,
|
|||||||
struct hal_rx_ppdu_info *ppdu_info,
|
struct hal_rx_ppdu_info *ppdu_info,
|
||||||
qdf_nbuf_t status_nbuf)
|
qdf_nbuf_t status_nbuf)
|
||||||
{
|
{
|
||||||
|
qdf_nbuf_t dropnbuf;
|
||||||
|
|
||||||
|
if (qdf_nbuf_queue_len(&pdev->rx_ppdu_buf_q) >
|
||||||
|
HAL_RX_MAX_MPDU) {
|
||||||
|
dropnbuf = qdf_nbuf_queue_remove(&pdev->rx_ppdu_buf_q);
|
||||||
|
qdf_nbuf_free(dropnbuf);
|
||||||
|
}
|
||||||
qdf_nbuf_queue_add(&pdev->rx_ppdu_buf_q, status_nbuf);
|
qdf_nbuf_queue_add(&pdev->rx_ppdu_buf_q, status_nbuf);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -615,7 +639,6 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
|
|||||||
|
|
||||||
size = (ppdu_info->fcs_ok_msdu_info.first_msdu_payload -
|
size = (ppdu_info->fcs_ok_msdu_info.first_msdu_payload -
|
||||||
qdf_nbuf_data(nbuf));
|
qdf_nbuf_data(nbuf));
|
||||||
ppdu_info->fcs_ok_msdu_info.first_msdu_payload = NULL;
|
|
||||||
|
|
||||||
if (qdf_nbuf_pull_head(nbuf, size) == NULL)
|
if (qdf_nbuf_pull_head(nbuf, size) == NULL)
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
@@ -627,6 +650,7 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ppdu_info->fcs_ok_msdu_info.first_msdu_payload = NULL;
|
||||||
nbuf_data = (uint32_t *)qdf_nbuf_data(nbuf);
|
nbuf_data = (uint32_t *)qdf_nbuf_data(nbuf);
|
||||||
*nbuf_data = pdev->ppdu_info.com_info.ppdu_id;
|
*nbuf_data = pdev->ppdu_info.com_info.ppdu_id;
|
||||||
/* only retain RX MSDU payload in the skb */
|
/* only retain RX MSDU payload in the skb */
|
||||||
@@ -667,6 +691,12 @@ dp_rx_process_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
|
|||||||
* and devliver fcs_ok msdu buffer
|
* and devliver fcs_ok msdu buffer
|
||||||
*/
|
*/
|
||||||
if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) {
|
if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) {
|
||||||
|
if (qdf_unlikely(ppdu_info->com_info.mpdu_cnt !=
|
||||||
|
(ppdu_info->com_info.mpdu_cnt_fcs_ok +
|
||||||
|
ppdu_info->com_info.mpdu_cnt_fcs_err))) {
|
||||||
|
qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Get rx ppdu status buffer having fcs ok msdu */
|
/* Get rx ppdu status buffer having fcs ok msdu */
|
||||||
status_nbuf = dp_rx_get_fcs_ok_msdu(pdev, ppdu_info);
|
status_nbuf = dp_rx_get_fcs_ok_msdu(pdev, ppdu_info);
|
||||||
if (status_nbuf) {
|
if (status_nbuf) {
|
||||||
|
@@ -444,12 +444,16 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo,
|
|||||||
/* If last ppdu_id doesn't match new ppdu_id,
|
/* If last ppdu_id doesn't match new ppdu_id,
|
||||||
* 1. reset mpdu_cnt
|
* 1. reset mpdu_cnt
|
||||||
* 2. update last_ppdu_id with new
|
* 2. update last_ppdu_id with new
|
||||||
|
* 3. reset mpdu fcs bitmap
|
||||||
*/
|
*/
|
||||||
if (com_info->ppdu_id != com_info->last_ppdu_id) {
|
if (com_info->ppdu_id != com_info->last_ppdu_id) {
|
||||||
com_info->mpdu_cnt = 0;
|
com_info->mpdu_cnt = 0;
|
||||||
com_info->last_ppdu_id =
|
com_info->last_ppdu_id =
|
||||||
com_info->ppdu_id;
|
com_info->ppdu_id;
|
||||||
com_info->num_users = 0;
|
com_info->num_users = 0;
|
||||||
|
qdf_mem_zero(&com_info->mpdu_fcs_ok_bitmap,
|
||||||
|
HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
|
||||||
|
sizeof(com_info->mpdu_fcs_ok_bitmap[0]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user