Explorar el Código

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
Namita Nair hace 1 año
padre
commit
429dc9c9e6
Se han modificado 4 ficheros con 1 adiciones y 6 borrados
  1. 0 2
      dp/wifi3.0/be/dp_be_rx.c
  2. 1 0
      dp/wifi3.0/dp_rx.h
  3. 0 2
      dp/wifi3.0/li/dp_li_rx.c
  4. 0 2
      dp/wifi3.0/rh/dp_rh_rx.c

+ 0 - 2
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);
 

+ 1 - 0
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);
 }

+ 0 - 2
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);
 

+ 0 - 2
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,