Browse Source

qcacld-3.0: Do netif_rx_ni() for frames received before peer assoc

While processing of frames received before peer is registered in process
context, tcp_v4_rcv() is called which takes a spinlock and in between the
processing before spinlock can be released, it is getting preempted by
hif_napi_poll() as it gets executed in softirq context. It tries to take
the same spinlock in tcp_v4_rcv() resulting in deadlock.
Do netif_rx_ni() for frames received before peer is registered.

Change-Id: I6228984f209bb9312ed9d8f3937d6036918ff750
CRs-Fixed: 2034244
Himanshu Agarwal 7 years ago
parent
commit
dd2196a8f5
3 changed files with 5 additions and 3 deletions
  1. 1 1
      core/dp/txrx/ol_txrx.c
  2. 2 1
      core/hdd/src/wlan_hdd_lro.c
  3. 2 1
      core/hdd/src/wlan_hdd_tx_rx.c

+ 1 - 1
core/dp/txrx/ol_txrx.c

@@ -4647,7 +4647,7 @@ static inline int ol_txrx_drop_nbuf_list(qdf_nbuf_t buf_list)
 
 	buf = buf_list;
 	while (buf) {
-		QDF_NBUF_CB_RX_LRO_INELIGIBLE(buf) = 1;
+		QDF_NBUF_CB_RX_PEER_CACHED_FRM(buf) = 1;
 		next_buf = qdf_nbuf_queue_next(buf);
 		if (pdev)
 			TXRX_STATS_MSDU_INCR(pdev,

+ 2 - 1
core/hdd/src/wlan_hdd_lro.c

@@ -142,7 +142,8 @@ enum hdd_lro_rx_status hdd_lro_rx(hdd_context_t *hdd_ctx,
 	enum hdd_lro_rx_status status = HDD_LRO_NO_RX;
 
 	if ((adapter->dev->features & NETIF_F_LRO) &&
-		 QDF_NBUF_CB_RX_TCP_PROTO(skb)) {
+		 QDF_NBUF_CB_RX_TCP_PROTO(skb) &&
+		 !QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb)) {
 		struct qdf_lro_info info;
 		struct net_lro_desc *lro_desc = NULL;
 		struct hif_opaque_softc *hif_hdl =

+ 2 - 1
core/hdd/src/wlan_hdd_tx_rx.c

@@ -1258,7 +1258,8 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
 		if (HDD_LRO_NO_RX ==
 			 hdd_lro_rx(pHddCtx, pAdapter, skb)) {
 			if (hdd_napi_enabled(HDD_NAPI_ANY) &&
-				!pHddCtx->enableRxThread)
+				!pHddCtx->enableRxThread &&
+				!QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb))
 				rxstat = netif_receive_skb(skb);
 			else
 				rxstat = netif_rx_ni(skb);