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
This commit is contained in:
Yu Tian 2022-03-30 19:28:57 +08:00 • committed by Madan Koyyalamudi
commit 10de640eeb
3 changed files with 50 additions and 66 deletions

View file

@ -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) */

View file

@ -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

View file

@ -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)