Jelajahi Sumber

qcacld-3.0: Use skb_orphan instead of skb_unshare in TX

To use skb_orphan instead of skb_unshare, this is
aimed to prevent addition skb_alloc possible failures
in TX path, then avoid of unnecessary packet drop when
memory runs low.

Change-Id: Ic8dfdb09c73a1071678612430fff2f23180ad336
CRs-Fixed: 3162137
Yu Tian 3 tahun lalu
induk
melakukan
6243b01b13

+ 49 - 0
core/hdd/inc/wlan_hdd_softap_tx_rx.h

@@ -351,4 +351,53 @@ QDF_STATUS hdd_softap_ind_l2_update(struct hdd_adapter *adapter,
 	return QDF_STATUS_SUCCESS;
 }
 #endif
+#ifndef QCA_LL_LEGACY_TX_FLOW_CONTROL
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+/**
+ * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan
+ * @adapter: pointer to HDD adapter
+ * @skb: pointer to skb data packet
+ *
+ * Return: pointer to skb structure
+ */
+static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
+					     struct sk_buff *skb)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_skb_fill_gso_size(adapter->dev, skb);
+
+	if (skb_cloned(skb)) {
+		++adapter->hdd_stats.tx_rx_stats.
+			per_cpu[qdf_get_smp_processor_id()].tx_orphaned;
+		skb_orphan(skb);
+		return skb;
+	}
+
+	if (unlikely(hdd_ctx->config->tx_orphan_enable)) {
+		/*
+		 * For UDP packets we want to orphan the packet to allow the app
+		 * to send more packets. The flow would ultimately be controlled
+		 * by the limited number of tx descriptors for the vdev.
+		 */
+		++adapter->hdd_stats.tx_rx_stats.
+			per_cpu[qdf_get_smp_processor_id()].tx_orphaned;
+		skb_orphan(skb);
+	}
+
+	return skb;
+}
+#else
+static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
+					     struct sk_buff *skb)
+{
+	struct sk_buff *nskb;
+
+	hdd_skb_fill_gso_size(adapter->dev, skb);
+	nskb = skb_unshare(skb, GFP_ATOMIC);
+
+	return nskb;
+}
+#endif
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 #endif /* end #if !defined(WLAN_HDD_SOFTAP_TX_RX_H) */

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

@@ -227,41 +227,6 @@ static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
 
 	return skb;
 }
-
-#else
-/**
- * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan
- * @adapter: pointer to HDD adapter
- * @skb: pointer to skb data packet
- *
- * Return: pointer to skb structure
- */
-static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
-		struct sk_buff *skb) {
-
-	struct sk_buff *nskb;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
-	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-#endif
-	int cpu;
-
-	hdd_skb_fill_gso_size(adapter->dev, skb);
-
-	nskb = skb_unshare(skb, GFP_ATOMIC);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
-	if (unlikely(hdd_ctx->config->tx_orphan_enable) && (nskb == skb)) {
-		/*
-		 * For UDP packets we want to orphan the packet to allow the app
-		 * to send more packets. The flow would ultimately be controlled
-		 * by the limited number of tx descriptors for the vdev.
-		 */
-		cpu = qdf_get_smp_processor_id();
-		++adapter->hdd_stats.tx_rx_stats.per_cpu[cpu].tx_orphaned;
-		skb_orphan(skb);
-	}
-#endif
-	return nskb;
-}
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 
 #define IEEE8021X_AUTH_TYPE_EAP 0

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

@@ -440,41 +440,6 @@ void hdd_get_tx_resource(struct hdd_adapter *adapter,
 		}
 	}
 }
-
-#else
-/**
- * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan
- * @adapter: pointer to HDD adapter
- * @skb: pointer to skb data packet
- *
- * Return: pointer to skb structure
- */
-static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
-		struct sk_buff *skb) {
-
-	struct sk_buff *nskb;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
-	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-#endif
-	int cpu;
-
-	hdd_skb_fill_gso_size(adapter->dev, skb);
-
-	nskb = skb_unshare(skb, GFP_ATOMIC);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
-	if (unlikely(hdd_ctx->config->tx_orphan_enable) && (nskb == skb)) {
-		/*
-		 * For UDP packets we want to orphan the packet to allow the app
-		 * to send more packets. The flow would ultimately be controlled
-		 * by the limited number of tx descriptors for the vdev.
-		 */
-		cpu = qdf_get_smp_processor_id();
-		++adapter->hdd_stats.tx_rx_stats.per_cpu[cpu].tx_orphaned;
-		skb_orphan(skb);
-	}
-#endif
-	return nskb;
-}
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 
 uint32_t hdd_txrx_get_tx_ack_count(struct hdd_adapter *adapter)