From 9764cf5e3d24ee965c0a98d4df3116613a37fa60 Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Fri, 24 Dec 2021 10:35:18 +0530 Subject: [PATCH] qcacmn: Fix double free in MEC notify event Fix double free of tx descriptors with MEC notify event Change-Id: I7456b14e8872fd7732afade7d49134c1fca9284b --- dp/wifi3.0/be/dp_be_tx.c | 35 ++++++++++++++++------------------- dp/wifi3.0/li/dp_li_tx.c | 33 +++++++++++++++------------------ 2 files changed, 31 insertions(+), 37 deletions(-) diff --git a/dp/wifi3.0/be/dp_be_tx.c b/dp/wifi3.0/be/dp_be_tx.c index 5983e1cdc9..85d395174a 100644 --- a/dp/wifi3.0/be/dp_be_tx.c +++ b/dp/wifi3.0/be/dp_be_tx.c @@ -152,28 +152,24 @@ void dp_tx_process_mec_notify_be(struct dp_soc *soc, uint8_t *status) { struct dp_vdev *vdev; uint8_t vdev_id; - uint8_t tx_status; uint32_t *htt_desc = (uint32_t *)status; - tx_status = HTT_TX_WBM_COMPLETION_V3_TX_STATUS_GET(htt_desc[0]); - if (tx_status == HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY) { - qdf_assert_always(!soc->mec_fw_offload); + qdf_assert_always(!soc->mec_fw_offload); - /* - * Get vdev id from HTT status word in case of MEC - * notification - */ - vdev_id = DP_TX_WBM_COMPLETION_V3_VDEV_ID_GET(htt_desc[4]); - if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT)) - return; + /* + * Get vdev id from HTT status word in case of MEC + * notification + */ + vdev_id = DP_TX_WBM_COMPLETION_V3_VDEV_ID_GET(htt_desc[4]); + if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT)) + return; - vdev = dp_vdev_get_ref_by_id(soc, vdev_id, - DP_MOD_ID_HTT_COMP); - if (!vdev) - return; - dp_tx_mec_handler(vdev, status); - dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); - } + vdev = dp_vdev_get_ref_by_id(soc, vdev_id, + DP_MOD_ID_HTT_COMP); + if (!vdev) + return; + dp_tx_mec_handler(vdev, status); + dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); } 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 * 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, diff --git a/dp/wifi3.0/li/dp_li_tx.c b/dp/wifi3.0/li/dp_li_tx.c index e5c3d14be8..13661720a2 100644 --- a/dp/wifi3.0/li/dp_li_tx.c +++ b/dp/wifi3.0/li/dp_li_tx.c @@ -65,26 +65,22 @@ void dp_tx_process_mec_notify_li(struct dp_soc *soc, uint8_t *status) { struct dp_vdev *vdev; uint8_t vdev_id; - uint8_t tx_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 - */ - vdev_id = HTT_TX_WBM_COMPLETION_V2_VDEV_ID_GET(htt_desc[3]); - if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT)) - return; + /* + * 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)) + return; - vdev = dp_vdev_get_ref_by_id(soc, vdev_id, - DP_MOD_ID_HTT_COMP); - if (!vdev) - return; - dp_tx_mec_handler(vdev, status); - dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); - } + vdev = dp_vdev_get_ref_by_id(soc, vdev_id, + DP_MOD_ID_HTT_COMP); + if (!vdev) + return; + dp_tx_mec_handler(vdev, status); + dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); } 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 * 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,