From 429dc9c9e6e3fe4e470bbae7ff40221c4751b03b Mon Sep 17 00:00:00 2001 From: Namita Nair Date: Mon, 21 Aug 2023 11:41:35 -0700 Subject: [PATCH] qcacmn: Ensure rx_desc->unmapped is set to 1 before releasing lock Originally Change-Id: I9fa71bdb6d4e4aa93fc795cc5dd472a181325991 was brought in to fix a race condition between Rx buffers map/unmapped in dp_ipa_handle_rx_buf_smmu_mapping() and at the same time map/unmapped from dp rx replenish context. The fix ensured that rx_desc is unmapped and rx_desc->unmapped=1 flag will be set atomically within a lock. But Change-Id: Iadb40071fb733cc4de3291784df5075d5a099a8e introduced a flaw by releasing the lock before setting the flag to 1. This is currently causing race condition and causing double unmap calls when IPA smmu pool unmap and dp_rx_replenish unmap is running in parallel. This change will fix this issue, by setting the flag before the lock is released. Change-Id: I3533bb5f6cc0437395149cd3c718826ef0b482a3 CRs-Fixed: 3594252 --- dp/wifi3.0/be/dp_be_rx.c | 2 -- dp/wifi3.0/dp_rx.h | 1 + dp/wifi3.0/li/dp_li_rx.c | 2 -- dp/wifi3.0/rh/dp_rh_rx.c | 2 -- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/dp/wifi3.0/be/dp_be_rx.c b/dp/wifi3.0/be/dp_be_rx.c index e9fa72b599..844ee753f8 100644 --- a/dp/wifi3.0/be/dp_be_rx.c +++ b/dp/wifi3.0/be/dp_be_rx.c @@ -332,7 +332,6 @@ more_data: if (qdf_unlikely(rx_desc && rx_desc->nbuf)) { qdf_assert_always(!rx_desc->unmapped); dp_rx_nbuf_unmap(soc, rx_desc, reo_ring_num); - rx_desc->unmapped = 1; dp_rx_buffer_pool_nbuf_free(soc, rx_desc->nbuf, rx_desc->pool_id); dp_rx_add_to_free_desc_list( @@ -436,7 +435,6 @@ more_data: * in case double skb unmap happened. */ dp_rx_nbuf_unmap(soc, rx_desc, reo_ring_num); - rx_desc->unmapped = 1; DP_RX_PROCESS_NBUF(soc, nbuf_head, nbuf_tail, ebuf_head, ebuf_tail, rx_desc); diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 2ded67e2c1..98756fe924 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -2769,6 +2769,7 @@ void dp_rx_nbuf_unmap(struct dp_soc *soc, qdf_nbuf_unmap_nbytes_single(soc->osdev, rx_desc->nbuf, QDF_DMA_FROM_DEVICE, rx_desc_pool->buf_size); + rx_desc->unmapped = 1; dp_ipa_reo_ctx_buf_mapping_unlock(soc, reo_ring_num); } diff --git a/dp/wifi3.0/li/dp_li_rx.c b/dp/wifi3.0/li/dp_li_rx.c index 866ffdb633..326a672bbb 100644 --- a/dp/wifi3.0/li/dp_li_rx.c +++ b/dp/wifi3.0/li/dp_li_rx.c @@ -347,7 +347,6 @@ more_data: if (qdf_unlikely(rx_desc && rx_desc->nbuf)) { qdf_assert_always(!rx_desc->unmapped); dp_rx_nbuf_unmap(soc, rx_desc, reo_ring_num); - rx_desc->unmapped = 1; dp_rx_buffer_pool_nbuf_free(soc, rx_desc->nbuf, rx_desc->pool_id); dp_rx_add_to_free_desc_list( @@ -498,7 +497,6 @@ more_data: * in case double skb unmap happened. */ dp_rx_nbuf_unmap(soc, rx_desc, reo_ring_num); - rx_desc->unmapped = 1; DP_RX_PROCESS_NBUF(soc, nbuf_head, nbuf_tail, ebuf_head, ebuf_tail, rx_desc); diff --git a/dp/wifi3.0/rh/dp_rh_rx.c b/dp/wifi3.0/rh/dp_rh_rx.c index 6643d32cf6..2ee1e9317f 100644 --- a/dp/wifi3.0/rh/dp_rh_rx.c +++ b/dp/wifi3.0/rh/dp_rh_rx.c @@ -919,7 +919,6 @@ dp_rx_data_indication_handler(struct dp_soc *soc, qdf_nbuf_t data_ind, * in case double skb unmap happened. */ dp_rx_nbuf_unmap(soc, rx_desc, rx_ctx_id); - rx_desc->unmapped = 1; error = HTT_RX_DATA_MSDU_INFO_ERROR_VALID_GET(*(msg_word + 3)); if (qdf_unlikely(error)) { @@ -1576,7 +1575,6 @@ dp_rx_frag_indication_handler(struct dp_soc *soc, qdf_nbuf_t data_ind, dp_rx_nbuf_unmap(soc, rx_desc, rx_ctx_id); - rx_desc->unmapped = 1; dp_rx_add_to_free_desc_list(&head, &tail, rx_desc); dp_rx_buffers_replenish_simple(soc, rx_desc->pool_id,