Browse Source

qcacmn: Destroy rx tid spinlock when peer is freed

Currently the rx tid spinlock is destroyed from
peer delete (based on peer state) or peer unmap handler.
This can lead to a race condition when the peer is
deleted before the peer map command is processed/received.

Fix the above race condition by destroying the rx tid
spinlock only when the peer handle is destroyed/freed.

Change-Id: Iaf7ccea11a95732c1aa20e66af6dd4a9a66517c5
CRs-Fixed: 2763533
Rakesh Pillai 4 years ago
parent
commit
351a71f1d3
2 changed files with 4 additions and 5 deletions
  1. 4 3
      dp/wifi3.0/dp_main.c
  2. 0 2
      dp/wifi3.0/dp_peer.c

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

@@ -5593,9 +5593,6 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 
 		dp_set_peer_isolation(peer, false);
 
-		for (i = 0; i < DP_MAX_TIDS; i++)
-			qdf_spinlock_create(&peer->rx_tid[i].tid_lock);
-
 		dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT);
 
 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
@@ -6422,6 +6419,7 @@ void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id mod_id)
 	struct cdp_peer_cookie peer_cookie;
 	struct dp_peer *tmp_peer;
 	bool found = false;
+	int tid;
 
 	if (mod_id > DP_MOD_ID_RX)
 		QDF_ASSERT(qdf_atomic_dec_return(&peer->mod_refs[mod_id]) >= 0);
@@ -6487,6 +6485,9 @@ void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id mod_id)
 		DP_AST_ASSERT(TAILQ_EMPTY(&peer->ast_entry_list));
 		dp_peer_update_state(soc, peer, DP_PEER_STATE_FREED);
 
+		for (tid = 0; tid < DP_MAX_TIDS; tid++)
+			qdf_spinlock_destroy(&peer->rx_tid[tid].tid_lock);
+
 		qdf_mem_free(peer);
 
 		/*

+ 0 - 2
dp/wifi3.0/dp_peer.c

@@ -2939,8 +2939,6 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
 			tid_delete_mask);
 	}
 #endif
-	for (tid = 0; tid < DP_MAX_TIDS; tid++)
-		qdf_spinlock_destroy(&peer->rx_tid[tid].tid_lock);
 }
 
 #ifdef FEATURE_PERPKT_INFO