Browse Source

qcacld-3.0: drop frames in the RX thread queue during peer unmap

Because of a race that happen during vdev delete, RX packets can get
queued to the RX thread after the RX flush (done as part of peer deletion)
and by the time RX thread is woken up for processing, the netdev pointer
would be NULL leading to a crash.

Avoid this by dropping pending frames in the RX thread during peer unmap
as well.

Change-Id: Id79d7d05c487fcabfd104a15dc4038d48703b07c
CRs-Fixed: 2681195
Manikanta Pubbisetty 4 years ago
parent
commit
174d2ccae5
1 changed files with 20 additions and 0 deletions
  1. 20 0
      core/dp/txrx/ol_txrx.c

+ 20 - 0
core/dp/txrx/ol_txrx.c

@@ -3051,6 +3051,22 @@ static inline void ol_txrx_peer_free_tids(ol_txrx_peer_handle peer)
 	}
 }
 
+/**
+ * ol_txrx_peer_drop_pending_frames() - drop pending frames in the RX queue
+ * @peer: peer handle
+ *
+ * Drop pending packets pertaining to the peer from the RX thread queue.
+ *
+ * Return: None
+ */
+static void ol_txrx_peer_drop_pending_frames(struct ol_txrx_peer_t *peer)
+{
+	p_cds_sched_context sched_ctx = get_cds_sched_ctxt();
+
+	if (sched_ctx)
+		cds_drop_rxpkt_by_staid(sched_ctx, peer->local_id);
+}
+
 /**
  * ol_txrx_peer_release_ref() - release peer reference
  * @peer: peer handle
@@ -3153,6 +3169,10 @@ int ol_txrx_peer_release_ref(ol_txrx_peer_handle peer,
 				    &peer->mac_addr.raw, peer, 0,
 				    qdf_atomic_read(&peer->ref_cnt));
 		peer_id = peer->local_id;
+
+		/* Drop all pending frames in the rx thread queue */
+		ol_txrx_peer_drop_pending_frames(peer);
+
 		/* remove the reference to the peer from the hash table */
 		ol_txrx_peer_find_hash_remove(pdev, peer);