浏览代码

qcacmn: 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: I563ba5bccb94ea4084ecfd5d31045a5715bbfef4
CRs-Fixed: 2034991
Himanshu Agarwal 8 年之前
父节点
当前提交
740f30f614
共有 2 个文件被更改,包括 4 次插入5 次删除
  1. 3 3
      qdf/linux/src/i_qdf_nbuf.h
  2. 1 2
      qdf/linux/src/qdf_lro.c

+ 3 - 3
qdf/linux/src/i_qdf_nbuf.h

@@ -137,7 +137,7 @@ struct qdf_nbuf_cb {
 		/* Note: MAX: 40 bytes */
 		struct {
 			uint32_t lro_eligible:1,
-				no_peer_lro_ineligible:1,
+				peer_cached_buf_frm:1,
 				tcp_proto:1,
 				tcp_pure_ack:1,
 				ipv6_proto:1,
@@ -252,8 +252,8 @@ QDF_COMPILE_TIME_ASSERT(qdf_nbuf_cb_size,
 
 #define QDF_NBUF_CB_RX_LRO_ELIGIBLE(skb) \
 	(((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.lro_eligible)
-#define QDF_NBUF_CB_RX_LRO_INELIGIBLE(skb) \
-	(((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.no_peer_lro_ineligible)
+#define QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb) \
+	(((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.peer_cached_buf_frm)
 #define QDF_NBUF_CB_RX_LRO_DESC(skb) \
 	(((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.lro_desc)
 #define QDF_NBUF_CB_RX_LRO_CTX(skb) \

+ 1 - 2
qdf/linux/src/qdf_lro.c

@@ -328,7 +328,6 @@ bool qdf_lro_get_info(qdf_lro_ctx_t lro_ctx, qdf_nbuf_t nbuf,
 	int hw_lro_eligible =
 		 QDF_NBUF_CB_RX_LRO_ELIGIBLE(nbuf) &&
 		 (!QDF_NBUF_CB_RX_TCP_PURE_ACK(nbuf));
-	int rx_data_before_peer_rx = QDF_NBUF_CB_RX_LRO_INELIGIBLE(nbuf);
 
 	if (unlikely(!lro_ctx)) {
 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
@@ -336,7 +335,7 @@ bool qdf_lro_get_info(qdf_lro_ctx_t lro_ctx, qdf_nbuf_t nbuf,
 		return false;
 	}
 
-	if (!hw_lro_eligible || rx_data_before_peer_rx)
+	if (!hw_lro_eligible)
 		return false;
 
 	iph = (struct iphdr *)info->iph;