From 10de640eebf1d92c0974921b68b374ffc1ec374b Mon Sep 17 00:00:00 2001 From: Yu Tian Date: Wed, 30 Mar 2022 19:28:57 +0800 Subject: [PATCH] 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 --- core/hdd/inc/wlan_hdd_softap_tx_rx.h | 49 ++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_softap_tx_rx.c | 34 +------------------ core/hdd/src/wlan_hdd_tx_rx.c | 33 ------------------- 3 files changed, 50 insertions(+), 66 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_softap_tx_rx.h b/core/hdd/inc/wlan_hdd_softap_tx_rx.h index b93317c98a2c..1d432761eaa5 100644 --- a/core/hdd/inc/wlan_hdd_softap_tx_rx.h +++ b/core/hdd/inc/wlan_hdd_softap_tx_rx.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -290,4 +291,52 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, */ void hdd_softap_check_wait_for_tx_eap_pkt(struct hdd_adapter *adapter, struct qdf_mac_addr *mac_addr); + +#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.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.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) */ diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c index c19dae1aeb99..4bdd7cae9fdb 100644 --- a/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -205,39 +206,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 - - 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. - */ - ++adapter->hdd_stats.tx_rx_stats.tx_orphaned; - skb_orphan(skb); - } -#endif - return nskb; -} #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ #define IEEE8021X_AUTH_TYPE_EAP 0 diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index defe0c9bb390..f7e49376ac57 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -385,39 +385,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 - - 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. - */ - ++adapter->hdd_stats.tx_rx_stats.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)