summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgbian <gbian@codeaurora.org>2016-11-24 11:21:30 +0800
committerqcabuildsw <qcabuildsw@localhost>2016-11-29 16:07:14 -0800
commitaf61eefb22787e1ed00baef06af2c37934adcf19 (patch)
treef8c04bed0050f34a38df0adfb4053b7b6d85107a
parentbfc6d488802ac3e015efe8bc0edff0c44ac8fa64 (diff)
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
-rw-r--r--core/hdd/src/wlan_hdd_softap_tx_rx.c40
-rw-r--r--core/hdd/src/wlan_hdd_tx_rx.c38
2 files changed, 78 insertions, 0 deletions
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
index 89c232111682..ea8c3c55ab55 100644
--- a/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -198,6 +198,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 */
/**
@@ -317,10 +337,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
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 511f7407248c..87baf8dd453e 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -153,6 +153,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
@@ -270,6 +282,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 */
/**
@@ -447,8 +467,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;
}