Explorar el Código

qcacmn: fix null skb accessing due to incomplete scattered msdu

  If RX packets reaped from REO2SW ring hit rx_reap_loop_pkt_limit,
REO2SW ring reaping will break and stop, but for scattered msdu case,
all related buffer should be received one time for further processing,
otherwise dp_rx_sg_create can not handle correctly.

(1) make sure all buffers for scattered msdu is received then allow
break when rx_reap_loop_pkt_limit hit.
(2) refine skb unmap location in case msdu_scatter_wait_break logic is
hit, then may double unmap for same skb(not for current issue).

Change-Id: I85d385ee9c3b1a5ed56ae5e5b68636d04968553f
CRs-Fixed: 2632082
Jinwei Chen hace 5 años
padre
commit
356c6b714e
Se han modificado 1 ficheros con 20 adiciones y 16 borrados
  1. 20 16
      dp/wifi3.0/dp_rx.c

+ 20 - 16
dp/wifi3.0/dp_rx.c

@@ -1964,27 +1964,12 @@ more_data:
 
 		dp_rx_desc_nbuf_sanity_check(ring_desc, rx_desc);
 
-		/* TODO */
-		/*
-		 * Need a separate API for unmapping based on
-		 * phyiscal address
-		 */
-		qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf,
-					QDF_DMA_FROM_DEVICE);
-		rx_desc->unmapped = 1;
-
-		core_id = smp_processor_id();
-		DP_STATS_INC(soc, rx.ring_packets[core_id][ring_id], 1);
-
 		/* Get MPDU DESC info */
 		hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info);
 
 		/* Get MSDU DESC info */
 		hal_rx_msdu_desc_info_get(ring_desc, &msdu_desc_info);
 
-		if (mpdu_desc_info.mpdu_flags & HAL_MPDU_F_RETRY_BIT)
-			qdf_nbuf_set_rx_retry_flag(rx_desc->nbuf, 1);
-
 		if (qdf_unlikely(msdu_desc_info.msdu_flags &
 				 HAL_MSDU_F_MSDU_CONTINUATION)) {
 			/* previous msdu has end bit set, so current one is
@@ -2015,6 +2000,20 @@ more_data:
 
 		}
 
+		/*
+		 * move unmap after scattered msdu waiting break logic
+		 * in case double skb unmap happened.
+		 */
+		qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf,
+				      QDF_DMA_FROM_DEVICE);
+		rx_desc->unmapped = 1;
+
+		core_id = smp_processor_id();
+		DP_STATS_INC(soc, rx.ring_packets[core_id][ring_id], 1);
+
+		if (mpdu_desc_info.mpdu_flags & HAL_MPDU_F_RETRY_BIT)
+			qdf_nbuf_set_rx_retry_flag(rx_desc->nbuf, 1);
+
 		if (qdf_unlikely(mpdu_desc_info.mpdu_flags &
 				 HAL_MPDU_F_RAW_AMPDU))
 			qdf_nbuf_set_raw_frame(rx_desc->nbuf, 1);
@@ -2081,7 +2080,12 @@ more_data:
 						rx_desc);
 
 		num_rx_bufs_reaped++;
-		if (dp_rx_reap_loop_pkt_limit_hit(soc, num_rx_bufs_reaped))
+		/*
+		 * only if complete msdu is received for scatter case,
+		 * then allow break.
+		 */
+		if (is_prev_msdu_last &&
+		    dp_rx_reap_loop_pkt_limit_hit(soc, num_rx_bufs_reaped))
 			break;
 	}
 done: