소스 검색

qcacmn: Check for valid peer_id in exception path

Sometime DP might receive a exception packet with
already deleted peer id. Added a check to avoid sending
such packets.

Change-Id: Ib43d55c7930e4ddc7550d486505a56cb48e85afe
CRs-Fixed: 3285034
Sai Rupesh Chevuru 2 년 전
부모
커밋
c16d4c0cd9
3개의 변경된 파일23개의 추가작업 그리고 2개의 파일을 삭제
  1. 1 0
      dp/inc/cdp_txrx_stats_struct.h
  2. 7 2
      dp/wifi3.0/dp_stats.c
  3. 15 0
      dp/wifi3.0/dp_tx.c

+ 1 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -1826,6 +1826,7 @@ struct cdp_tx_ingress_stats {
 		uint32_t headroom_insufficient;
 		uint32_t fail_per_pkt_vdev_id_check;
 		uint32_t drop_ingress;
+		uint32_t invalid_peer_id_in_exc_path;
 	} dropped;
 
 	/* Mesh packets info */

+ 7 - 2
dp/wifi3.0/dp_stats.c

@@ -7437,6 +7437,8 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
 		       pdev->stats.tx_i.dropped.res_full);
 	DP_PRINT_STATS("	Drop Ingress = %u",
 		       pdev->stats.tx_i.dropped.drop_ingress);
+	DP_PRINT_STATS("	invalid peer id in exception path = %u",
+		       pdev->stats.tx_i.dropped.invalid_peer_id_in_exc_path);
 	DP_PRINT_STATS("Tx failed = %u",
 		       pdev->stats.tx.tx_failed);
 	DP_PRINT_STATS("	FW removed Pkts = %u",
@@ -8721,7 +8723,8 @@ void dp_update_vdev_ingress_stats(struct dp_vdev *tgtobj)
 		tgtobj->stats.tx_i.dropped.desc_na.num +
 		tgtobj->stats.tx_i.dropped.res_full +
 		tgtobj->stats.tx_i.dropped.drop_ingress +
-		tgtobj->stats.tx_i.dropped.headroom_insufficient;
+		tgtobj->stats.tx_i.dropped.headroom_insufficient +
+		tgtobj->stats.tx_i.dropped.invalid_peer_id_in_exc_path;
 }
 
 void dp_update_vdev_rate_stats(struct cdp_vdev_stats *tgtobj,
@@ -8772,6 +8775,7 @@ void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj,
 	DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.res_full);
 	DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.drop_ingress);
 	DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.headroom_insufficient);
+	DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.invalid_peer_id_in_exc_path);
 	DP_STATS_AGGR(tgtobj, srcobj, tx_i.cce_classified);
 	DP_STATS_AGGR(tgtobj, srcobj, tx_i.cce_classified_raw);
 	DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.sniffer_rcvd);
@@ -8790,7 +8794,8 @@ void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj,
 		tgtobj->stats.tx_i.dropped.desc_na.num +
 		tgtobj->stats.tx_i.dropped.res_full +
 		tgtobj->stats.tx_i.dropped.drop_ingress +
-		tgtobj->stats.tx_i.dropped.headroom_insufficient;
+		tgtobj->stats.tx_i.dropped.headroom_insufficient +
+		tgtobj->stats.tx_i.dropped.invalid_peer_id_in_exc_path;
 }
 
 QDF_STATUS dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl,

+ 15 - 0
dp/wifi3.0/dp_tx.c

@@ -3134,6 +3134,21 @@ dp_tx_send_exception(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 		goto fail;
 	}
 
+	/* for peer based metadata check if peer is valid */
+	if (tx_exc_metadata->peer_id != CDP_INVALID_PEER) {
+		struct dp_peer *peer = NULL;
+
+		 peer = dp_peer_get_ref_by_id(vdev->pdev->soc,
+					      tx_exc_metadata->peer_id,
+					      DP_MOD_ID_TX_EXCEPTION);
+		if (qdf_unlikely(!peer)) {
+			DP_STATS_INC(vdev,
+				     tx_i.dropped.invalid_peer_id_in_exc_path,
+				     1);
+			goto fail;
+		}
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_EXCEPTION);
+	}
 	/* Basic sanity checks for unsupported packets */
 
 	/* MESH mode */