Browse Source

qcacld-3.0: Fix bad TCP up link throughput with latest kernel

qcacld-2.0 to qcacld-3.0 propagation

TCP throttling logic changed a little after 3.19-rc1 kernel, which will
throttle the TCP packets to the host driver, it will heavily affect the
TCP UP Link throughput. So need to orphan the socket buffer asap, which
will call skb's destructor to notify the TCP stack that the SKB buffer is
unowned, And then the TCP stack will pump more packets to the host driver.

This kernel change's subject is "tcp: refine TSO autosizing".
And the commid id is: 605ad7f184b60cfaacbc038aa6c55ee68dee3c89

Here is the TCP TX throughput test data with 4.1 kernel on the customer TV,
the iperf's parameter is 85.3k, and 1 pair in default.
1. Without this change:
   HT20:   35.1 Mbps
   VHT80:  88.4 Mbps
           88.4 Mbps (2 pairs)
2. With this change:
   HT20:   82.3 Mbps
   VHT80:  115  Mbps
           164 Mbps (2 pairs)

And this change will enhance the UDP TX throughput too, but if more
packets from the kernel exceeding the driver's TX capability, the multiple
out of data packets will be dropped in the driver, so it needs to be
protected by TX following controlled (QCA_LL_TX_FLOW_CT).

And here is the UDP TX throughput data with 4.1 kernel on the customer TV:
1. Without this change:
   HT20:   100 Mbps
   VHT80:  155 Mbps
2. With this change
   HT20:   124 Mbps
   VHT80:  263 Mbps

Change-Id: I7f40c7b2c516d71f525fff4aaf2b8a71473b647f
CRs-Fixed: 1056126
gbian 8 years ago
parent
commit
ec670c5909
2 changed files with 78 additions and 0 deletions
  1. 40 0
      core/hdd/src/wlan_hdd_softap_tx_rx.c
  2. 38 0
      core/hdd/src/wlan_hdd_tx_rx.c

+ 40 - 0
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -199,6 +199,26 @@ void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume)
 
 	return;
 }
+
+static inline struct sk_buff *hdd_skb_orphan(hdd_adapter_t *pAdapter,
+		struct sk_buff *skb)
+{
+	if (pAdapter->tx_flow_low_watermark > 0)
+		skb_orphan(skb);
+	else {
+		skb = skb_unshare(skb, GFP_ATOMIC);
+	}
+
+	return skb;
+}
+
+#else
+
+static inline struct sk_buff *hdd_skb_orphan(hdd_adapter_t *pAdapter,
+		struct sk_buff *skb)
+{
+	return skb_unshare(skb, GFP_ATOMIC);
+}
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 
 /**
@@ -318,10 +338,30 @@ static int __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 #if defined (IPA_OFFLOAD)
 	if (!qdf_nbuf_ipa_owned_get(skb)) {
 #endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+		/*
+		* The TCP TX throttling logic is changed a little after
+		* 3.19-rc1 kernel, the TCP sending limit will be smaller,
+		* which will throttle the TCP packets to the host driver.
+		* The TCP UP LINK throughput will drop heavily. In order to
+		* fix this issue, need to orphan the socket buffer asap, which
+		* will call skb's destructor to notify the TCP stack that the
+		* SKB buffer is unowned. And then the TCP stack will pump more
+		* packets to host driver.
+		*
+		* The TX packets might be dropped for UDP case in the iperf
+		* testing. So need to be protected by follow control.
+		*/
+		skb = hdd_skb_orphan(pAdapter, skb);
+#else
 		/* Check if the buffer has enough header room */
 		skb = skb_unshare(skb, GFP_ATOMIC);
+#endif
+
 		if (!skb)
 			goto drop_pkt_accounting;
+
 #if defined (IPA_OFFLOAD)
 	}
 #endif

+ 38 - 0
core/hdd/src/wlan_hdd_tx_rx.c

@@ -154,6 +154,18 @@ hdd_tx_resume_false(hdd_adapter_t *pAdapter, bool tx_resume)
 }
 #endif
 
+static inline struct sk_buff *hdd_skb_orphan(hdd_adapter_t *pAdapter,
+		struct sk_buff *skb)
+{
+	if (pAdapter->tx_flow_low_watermark > 0)
+		skb_orphan(skb);
+	else {
+		skb = skb_unshare(skb, GFP_ATOMIC);
+	}
+
+	return skb;
+}
+
 /**
  * hdd_tx_resume_cb() - Resume OS TX Q.
  * @adapter_context: pointer to vdev apdapter
@@ -271,6 +283,14 @@ void hdd_get_tx_resource(hdd_adapter_t *adapter,
 	}
 }
 
+#else
+
+static inline struct sk_buff *hdd_skb_orphan(hdd_adapter_t *pAdapter,
+		struct sk_buff *skb)
+{
+	return skb_unshare(skb, GFP_ATOMIC);
+}
+
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 
 /**
@@ -448,8 +468,26 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];
 
 	if (!qdf_nbuf_ipa_owned_get(skb)) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+		/*
+		* The TCP TX throttling logic is changed a little after
+		* 3.19-rc1 kernel, the TCP sending limit will be smaller,
+		* which will throttle the TCP packets to the host driver.
+		* The TCP UP LINK throughput will drop heavily. In order to
+		* fix this issue, need to orphan the socket buffer asap, which
+		* will call skb's destructor to notify the TCP stack that the
+		* SKB buffer is unowned. And then the TCP stack will pump more
+		* packets to host driver.
+		*
+		* The TX packets might be dropped for UDP case in the iperf
+		* testing. So need to be protected by follow control.
+		*/
+		skb = hdd_skb_orphan(pAdapter, skb);
+#else
 		/* Check if the buffer has enough header room */
 		skb = skb_unshare(skb, GFP_ATOMIC);
+#endif
+
 		if (!skb)
 			goto drop_pkt_accounting;
 	}