Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10de640e authored by Yu Tian's avatar Yu Tian Committed by Madan Koyyalamudi
Browse files

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
parent 9ee68be9
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
/*
 * 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) */
+1 −33
Original line number Diff line number Diff line
/*
 * 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
+0 −33
Original line number Diff line number Diff line
@@ -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)