Parcourir la source

qcacmn: Add Sanity checks during RX processing

- Check for rx_desc.magic before using a rx_desc retrieved from the reo
  destination ring via rx_buf_cookie (dp_rx_process). Add stats.
- Check if we end up re-using a rx_desc with rx_desc.in_use=1 in the
  replenish path (dp_rx_buffers_replenish).
- Drop RX packet and assert in case MSDU Done failures are seen in
  in the TLV during dp_rx_process. Add stats.
- Disable host2rxdma ring mask for MCL. MCL is not expected to be
  receiving these interrupts.

Change-Id: Iaa345d04b8d48814f88ed6e2237fc67696f6a20c
CRs-Fixed: 2382076
Mohit Khanna il y a 6 ans
Parent
commit
16cd1b2e8d
6 fichiers modifiés avec 76 ajouts et 41 suppressions
  1. 6 4
      dp/wifi3.0/dp_main.c
  2. 22 19
      dp/wifi3.0/dp_rx.c
  3. 42 1
      dp/wifi3.0/dp_rx.h
  4. 0 16
      dp/wifi3.0/dp_rx_err.c
  5. 5 0
      dp/wifi3.0/dp_types.h
  6. 1 1
      wlan_cfg/wlan_cfg.c

+ 6 - 4
dp/wifi3.0/dp_main.c

@@ -6859,10 +6859,14 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
 			soc->stats.rx.err.rx_invalid_peer.num);
 	DP_PRINT_STATS("HAL Ring Access Fail = %d",
 			soc->stats.rx.err.hal_ring_access_fail);
+	DP_PRINT_STATS("MSDU Done failures = %d",
+		       soc->stats.rx.err.msdu_done_fail);
 	DP_PRINT_STATS("RX frags: %d", soc->stats.rx.rx_frags);
 	DP_PRINT_STATS("RX frag wait: %d", soc->stats.rx.rx_frag_wait);
 	DP_PRINT_STATS("RX frag err: %d", soc->stats.rx.rx_frag_err);
 	DP_PRINT_STATS("RX HP out_of_sync: %d", soc->stats.rx.hp_oos);
+	DP_PRINT_STATS("RX DESC invalid magic: %u",
+		       soc->stats.rx.err.rx_desc_invalid_magic);
 	DP_PRINT_STATS("RX DUP DESC: %d",
 		       soc->stats.rx.err.hal_reo_dest_dup);
 	DP_PRINT_STATS("RX REL DUP DESC: %d",
@@ -6873,8 +6877,7 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
 				DP_RXDMA_ERR_LENGTH - index,
 				" %d", soc->stats.rx.err.rxdma_error[i]);
 	}
-	DP_PRINT_STATS("RXDMA Error (0-31):%s",
-			rxdma_error);
+	DP_PRINT_STATS("RXDMA Error (0-31):%s", rxdma_error);
 
 	index = 0;
 	for (i = 0; i < HAL_REO_ERR_MAX; i++) {
@@ -6882,8 +6885,7 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
 				DP_REO_ERR_LENGTH - index,
 				" %d", soc->stats.rx.err.reo_error[i]);
 	}
-	DP_PRINT_STATS("REO Error(0-14):%s",
-			reo_error);
+	DP_PRINT_STATS("REO Error(0-14):%s", reo_error);
 }
 
 /**

+ 22 - 19
dp/wifi3.0/dp_rx.c

@@ -30,19 +30,6 @@
 #include "dp_rx_mon.h"
 #include "dp_ipa.h"
 
-#ifdef RX_DESC_DEBUG_CHECK
-static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
-{
-	rx_desc->magic = DP_RX_DESC_MAGIC;
-	rx_desc->nbuf = nbuf;
-}
-#else
-static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
-{
-	rx_desc->nbuf = nbuf;
-}
-#endif
-
 #ifdef CONFIG_WIN
 static inline bool dp_rx_check_ap_bridge(struct dp_vdev *vdev)
 {
@@ -93,7 +80,7 @@ void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring,
 	dp_rx_desc_dump(rx_desc);
 	hal_srng_dump_ring_desc(hal_soc, hal_ring, ring_desc);
 	hal_srng_dump_ring(hal_soc, hal_ring);
-	qdf_assert_always(rx_desc->in_use);
+	qdf_assert_always(0);
 }
 
 /*
@@ -208,7 +195,7 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
 		}
 
 		ret = qdf_nbuf_map_single(dp_soc->osdev, rx_netbuf,
-				    QDF_DMA_BIDIRECTIONAL);
+					  QDF_DMA_BIDIRECTIONAL);
 		if (qdf_unlikely(QDF_IS_STATUS_ERROR(ret))) {
 			qdf_nbuf_free(rx_netbuf);
 			DP_STATS_INC(dp_pdev, replenish.map_err, 1);
@@ -232,12 +219,16 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
 		count++;
 
 		rxdma_ring_entry = hal_srng_src_get_next(dp_soc->hal_soc,
-								rxdma_srng);
+							 rxdma_srng);
 		qdf_assert_always(rxdma_ring_entry);
 
 		next = (*desc_list)->next;
 
 		dp_rx_desc_prep(&((*desc_list)->rx_desc), rx_netbuf);
+
+		/* rx_desc.in_use should be zero at this time*/
+		qdf_assert_always((*desc_list)->rx_desc.in_use == 0);
+
 		(*desc_list)->rx_desc.in_use = 1;
 
 		dp_verbose_debug("rx_netbuf=%pK, buf=%pK, paddr=0x%llx, cookie=%d",
@@ -1597,6 +1588,14 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring,
 		 */
 		if (qdf_unlikely(!rx_desc->in_use)) {
 			DP_STATS_INC(soc, rx.err.hal_reo_dest_dup, 1);
+			dp_err("Reaping rx_desc not in use!");
+			dp_rx_dump_info_and_assert(soc, hal_ring,
+						   ring_desc, rx_desc);
+		}
+
+		if (qdf_unlikely(!dp_rx_desc_check_magic(rx_desc))) {
+			dp_err("Invalid rx_desc cookie=%d", rx_buf_cookie);
+			DP_STATS_INC(soc, rx.err.rx_desc_invalid_magic, 1);
 			dp_rx_dump_info_and_assert(soc, hal_ring,
 						   ring_desc, rx_desc);
 		}
@@ -1610,6 +1609,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring,
 		 */
 		qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf,
 					QDF_DMA_BIDIRECTIONAL);
+		rx_desc->unmapped = 1;
 
 		core_id = smp_processor_id();
 		DP_STATS_INC(soc, rx.ring_packets[core_id][ring_id], 1);
@@ -1702,12 +1702,15 @@ done:
 		dp_rx_save_tid_ts(nbuf, tid, rx_pdev->delay_stats_flag);
 		tid_stats = &rx_pdev->stats.tid_stats.tid_rx_stats[tid];
 		if (qdf_unlikely(!hal_rx_attn_msdu_done_get(rx_tlv_hdr))) {
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-					FL("MSDU DONE failure"));
+			dp_err("MSDU DONE failure");
+			DP_STATS_INC(soc, rx.err.msdu_done_fail, 1);
 			hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr,
 					QDF_TRACE_LEVEL_INFO);
 			tid_stats->fail_cnt[MSDU_DONE_FAILURE]++;
-			qdf_assert(0);
+			qdf_nbuf_free(nbuf);
+			qdf_assert_always(0);
+			nbuf = next;
+			continue;
 		}
 
 		tid_stats->msdu_cnt++;

+ 42 - 1
dp/wifi3.0/dp_rx.h

@@ -56,6 +56,7 @@
 #endif /* QCA_HOST2FW_RXBUF_RING */
 
 #define RX_BUFFER_RESERVATION   0
+#define RX_BUFFER_SIZE 2048
 
 #define DP_PEER_METADATA_PEER_ID_MASK	0x0000ffff
 #define DP_PEER_METADATA_PEER_ID_SHIFT	0
@@ -394,7 +395,6 @@ void dp_rx_add_to_free_desc_list(union dp_rx_desc_list_elem_t **head,
 
 	new->nbuf = NULL;
 	new->in_use = 0;
-	new->unmapped = 0;
 
 	((union dp_rx_desc_list_elem_t *)new)->next = *head;
 	*head = (union dp_rx_desc_list_elem_t *)new;
@@ -991,4 +991,45 @@ void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring,
 				void *ring_desc, struct dp_rx_desc *rx_desc);
 
 void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
+#ifdef RX_DESC_DEBUG_CHECK
+/**
+ * dp_rx_desc_check_magic() - check the magic value in dp_rx_desc
+ * @rx_desc: rx descriptor pointer
+ *
+ * Return: true, if magic is correct, else false.
+ */
+static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
+{
+	if (qdf_unlikely(rx_desc->magic != DP_RX_DESC_MAGIC))
+		return false;
+
+	rx_desc->magic = 0;
+	return true;
+}
+
+/**
+ * dp_rx_desc_prep() - prepare rx desc
+ * @rx_desc: rx descriptor pointer to be prepared
+ * @nbuf: nbuf to be associated with rx_desc
+ *
+ * Return: none
+ */
+static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
+{
+	rx_desc->magic = DP_RX_DESC_MAGIC;
+	rx_desc->nbuf = nbuf;
+}
+
+#else
+
+static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
+{
+	return true;
+}
+
+static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
+{
+	rx_desc->nbuf = nbuf;
+}
+#endif /* RX_DESC_DEBUG_CHECK */
 #endif /* _DP_RX_H */

+ 0 - 16
dp/wifi3.0/dp_rx_err.c

@@ -32,22 +32,6 @@
 #include "dp_rx_defrag.h"
 #include <enet.h>	/* LLC_SNAP_HDR_LEN */
 
-#ifdef RX_DESC_DEBUG_CHECK
-static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
-{
-	if (qdf_unlikely(rx_desc->magic != DP_RX_DESC_MAGIC)) {
-		return false;
-	}
-	rx_desc->magic = 0;
-	return true;
-}
-#else
-static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
-{
-	return true;
-}
-#endif
-
 /**
  * dp_rx_mcast_echo_check() - check if the mcast pkt is a loop
  *			      back on same vap or a different vap.

+ 5 - 0
dp/wifi3.0/dp_types.h

@@ -609,8 +609,11 @@ struct dp_soc_stats {
 			uint32_t invalid_vdev;
 			/* Invalid PDEV error count */
 			uint32_t invalid_pdev;
+
 			/* Invalid sa_idx or da_idx*/
 			uint32_t invalid_sa_da_idx;
+			/* MSDU DONE failures */
+			uint32_t msdu_done_fail;
 			/* Invalid PEER Error count */
 			struct cdp_pkt_info rx_invalid_peer;
 			/* Invalid PEER ID count */
@@ -619,6 +622,8 @@ struct dp_soc_stats {
 			uint32_t hal_ring_access_fail;
 			/* RX DMA error count */
 			uint32_t rxdma_error[HAL_RXDMA_ERR_MAX];
+			/* RX REO DEST Desc Invalid Magic count */
+			uint32_t rx_desc_invalid_magic;
 			/* REO Error count */
 			uint32_t reo_error[HAL_REO_ERR_MAX];
 			/* HAL REO ERR Count */

+ 1 - 1
wlan_cfg/wlan_cfg.c

@@ -129,7 +129,7 @@ static const int rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
 					WLAN_CFG_RX_MON_RING_MASK_3};
 
 static const int host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
-					WLAN_CFG_HOST2RXDMA_RING_MASK_0,
+					0,
 					0,
 					0,
 					0,