Browse Source

qcacmn: Add Sanity Checks

Stats are updated periodically and
are categorized to soc, pdev, and
vdev

While the stats are getting updated
and if pdev, or vdev gets detached
in the same time, the stats handlers
will deference a NULL pointer

Hence Add basic sanity checks to DP
layer for soc, pdev and vdev inside
stat handlers

Change-Id: Ic4919b9c205679e1d6e7c571c577339be65c1bad
phadiman 6 years ago
parent
commit
497573091a
4 changed files with 20 additions and 5 deletions
  1. 9 2
      dp/wifi3.0/dp_main.c
  2. 3 0
      dp/wifi3.0/dp_rx.c
  3. 2 1
      dp/wifi3.0/dp_rx_mon_status.c
  4. 6 2
      dp/wifi3.0/dp_tx.c

+ 9 - 2
dp/wifi3.0/dp_main.c

@@ -5980,6 +5980,9 @@ void dp_aggregate_vdev_stats(struct dp_vdev *vdev,
 
 	soc = vdev->pdev->soc;
 
+	if (!vdev)
+		return;
+
 	qdf_mem_copy(vdev_stats, &vdev->stats, sizeof(vdev->stats));
 
 	qdf_spin_lock_bh(&soc->peer_ref_mutex);
@@ -5988,11 +5991,13 @@ void dp_aggregate_vdev_stats(struct dp_vdev *vdev,
 	qdf_spin_unlock_bh(&soc->peer_ref_mutex);
 
 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
+	if (!vdev->pdev)
+		return;
+
 	dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc,
 			     vdev_stats, vdev->vdev_id,
 			     UPDATE_VDEV_STATS, vdev->pdev->pdev_id);
 #endif
-
 }
 
 /**
@@ -6078,7 +6083,6 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev)
 	dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, &pdev->stats,
 			     pdev->pdev_id, UPDATE_PDEV_STATS, pdev->pdev_id);
 #endif
-
 }
 
 /**
@@ -6696,6 +6700,9 @@ dp_txrx_host_stats_clr(struct dp_vdev *vdev)
 {
 	struct dp_peer *peer = NULL;
 
+	if (!vdev || !vdev->pdev)
+		return;
+
 	DP_STATS_CLR(vdev->pdev);
 	DP_STATS_CLR(vdev->pdev->soc);
 	DP_STATS_CLR(vdev);

+ 3 - 0
dp/wifi3.0/dp_rx.c

@@ -1225,6 +1225,9 @@ static void dp_rx_msdu_stats_update(struct dp_soc *soc,
 	if ((soc->process_rx_status) &&
 	    hal_rx_attn_first_mpdu_get(rx_tlv_hdr)) {
 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
+		if (!vdev->pdev)
+			return;
+
 		dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc,
 				     &peer->stats, peer_id,
 				     UPDATE_PEER_STATS,

+ 2 - 1
dp/wifi3.0/dp_rx_mon_status.c

@@ -93,7 +93,7 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
 	cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate;
 
 	ast_index = ppdu_info->rx_status.ast_index;
-	if (ast_index > (WLAN_UMAC_PSOC_MAX_PEERS * 2)) {
+	if (ast_index >= (WLAN_UMAC_PSOC_MAX_PEERS * 2)) {
 		cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
 		return;
 	}
@@ -528,6 +528,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 	while (!qdf_nbuf_is_queue_empty(&pdev->rx_status_q)) {
 
 		status_nbuf = qdf_nbuf_queue_remove(&pdev->rx_status_q);
+
 		rx_tlv = qdf_nbuf_data(status_nbuf);
 		rx_tlv_start = rx_tlv;
 

+ 6 - 2
dp/wifi3.0/dp_tx.c

@@ -2636,9 +2636,14 @@ dp_tx_update_peer_stats(struct dp_peer *peer,
 			struct hal_tx_completion_status *ts, uint32_t length)
 {
 	struct dp_pdev *pdev = peer->vdev->pdev;
-	struct dp_soc *soc = pdev->soc;
+	struct dp_soc *soc = NULL;
 	uint8_t mcs, pkt_type;
 
+	if (!pdev)
+		return;
+
+	soc = pdev->soc;
+
 	mcs = ts->mcs;
 	pkt_type = ts->pkt_type;
 
@@ -2718,7 +2723,6 @@ dp_tx_update_peer_stats(struct dp_peer *peer,
 			     &peer->stats, ts->peer_id,
 			     UPDATE_PEER_STATS, pdev->pdev_id);
 #endif
-
 }
 
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2