qcacmn: Fix double free in MEC notify event

Fix double free of tx descriptors with MEC notify
event

Change-Id: I7456b14e8872fd7732afade7d49134c1fca9284b
This commit is contained in:
Chaithanya Garrepalli
2021-12-24 10:35:18 +05:30
committed by Madan Koyyalamudi
parent 0156c41d12
commit 9764cf5e3d
2 changed files with 31 additions and 37 deletions

View File

@@ -152,28 +152,24 @@ void dp_tx_process_mec_notify_be(struct dp_soc *soc, uint8_t *status)
{ {
struct dp_vdev *vdev; struct dp_vdev *vdev;
uint8_t vdev_id; uint8_t vdev_id;
uint8_t tx_status;
uint32_t *htt_desc = (uint32_t *)status; uint32_t *htt_desc = (uint32_t *)status;
tx_status = HTT_TX_WBM_COMPLETION_V3_TX_STATUS_GET(htt_desc[0]); qdf_assert_always(!soc->mec_fw_offload);
if (tx_status == HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY) {
qdf_assert_always(!soc->mec_fw_offload);
/* /*
* Get vdev id from HTT status word in case of MEC * Get vdev id from HTT status word in case of MEC
* notification * notification
*/ */
vdev_id = DP_TX_WBM_COMPLETION_V3_VDEV_ID_GET(htt_desc[4]); vdev_id = DP_TX_WBM_COMPLETION_V3_VDEV_ID_GET(htt_desc[4]);
if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT)) if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT))
return; return;
vdev = dp_vdev_get_ref_by_id(soc, vdev_id, vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
DP_MOD_ID_HTT_COMP); DP_MOD_ID_HTT_COMP);
if (!vdev) if (!vdev)
return; return;
dp_tx_mec_handler(vdev, status); dp_tx_mec_handler(vdev, status);
dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP);
}
} }
void dp_tx_process_htt_completion_be(struct dp_soc *soc, void dp_tx_process_htt_completion_be(struct dp_soc *soc,
@@ -201,7 +197,8 @@ void dp_tx_process_htt_completion_be(struct dp_soc *soc,
* notification comes from FW2WBM. Avoid access any field of tx * notification comes from FW2WBM. Avoid access any field of tx
* descriptor in case of MEC notify. * descriptor in case of MEC notify.
*/ */
dp_tx_process_mec_notify_be(soc, status); if (tx_status == HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY)
return dp_tx_process_mec_notify_be(soc, status);
/* /*
* If the descriptor is already freed in vdev_detach, * If the descriptor is already freed in vdev_detach,

View File

@@ -65,26 +65,22 @@ void dp_tx_process_mec_notify_li(struct dp_soc *soc, uint8_t *status)
{ {
struct dp_vdev *vdev; struct dp_vdev *vdev;
uint8_t vdev_id; uint8_t vdev_id;
uint8_t tx_status;
uint32_t *htt_desc = (uint32_t *)status; uint32_t *htt_desc = (uint32_t *)status;
tx_status = HTT_TX_WBM_COMPLETION_V2_TX_STATUS_GET(htt_desc[0]); /*
if (tx_status == HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY) { * Get vdev id from HTT status word in case of MEC
/* * notification
* Get vdev id from HTT status word in case of MEC */
* notification vdev_id = HTT_TX_WBM_COMPLETION_V2_VDEV_ID_GET(htt_desc[3]);
*/ if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT))
vdev_id = HTT_TX_WBM_COMPLETION_V2_VDEV_ID_GET(htt_desc[3]); return;
if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT))
return;
vdev = dp_vdev_get_ref_by_id(soc, vdev_id, vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
DP_MOD_ID_HTT_COMP); DP_MOD_ID_HTT_COMP);
if (!vdev) if (!vdev)
return; return;
dp_tx_mec_handler(vdev, status); dp_tx_mec_handler(vdev, status);
dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP);
}
} }
void dp_tx_process_htt_completion_li(struct dp_soc *soc, void dp_tx_process_htt_completion_li(struct dp_soc *soc,
@@ -112,7 +108,8 @@ void dp_tx_process_htt_completion_li(struct dp_soc *soc,
* notification comes from FW2WBM. Avoid access any field of tx * notification comes from FW2WBM. Avoid access any field of tx
* descriptor in case of MEC notify. * descriptor in case of MEC notify.
*/ */
dp_tx_process_mec_notify_li(soc, status); if (tx_status == HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY)
return dp_tx_process_mec_notify_li(soc, status);
/* /*
* If the descriptor is already freed in vdev_detach, * If the descriptor is already freed in vdev_detach,