Files
openwrt-R7800-nss/target/linux/ipq806x/patches-6.6/990-058-net-add-fast-xmit-api.patch
SqTER-PL 056b68da27 Updated iptunnel patches. Switch to codelinaro.org source.
Minor fixes and patch sorting.
2025-08-04 12:58:18 +02:00

174 lines
4.4 KiB
Diff

From 120ae502af169310aa53359d4faf2494dcee6927 Mon Sep 17 00:00:00 2001
From: Tallapragada Kalyan <quic_ktallapr@quicinc.com>
Date: Thu, 9 Jun 2022 09:32:38 +0530
Subject: [PATCH 267/281] net: set skb's fast_xmit flag in dev_fast_xmit API
set skb's fast_xmit flag in dev_fast_xmit API for linear packets
WiFi tx path can avoid some overhead due to checks based on this flag
Change-Id: Ied29f9d615d0cf48dd9dcd7fcf0fb210eb259a8f
Signed-off-by: Tallapragada Kalyan <quic_ktallapr@quicinc.com>
---
include/linux/skbuff.h | 2 ++
net/core/dev.c | 4 ++++
2 files changed, 6 insertions(+)
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -992,6 +992,8 @@ struct sk_buff {
__u8 csum_not_inet:1;
#endif
__u8 fast_forwarded:1;
+ /* Linear packets processed by dev_fast_xmit() */
+ __u8 fast_xmit:1;
/* 1 or 3 bit hole */
#if defined(CONFIG_NET_SCHED) || defined(CONFIG_NET_XGRESS)
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4305,6 +4305,144 @@ struct netdev_queue *netdev_core_pick_tx
}
/**
+ * dev_fast_xmit_vp - fast xmit the skb to a PPE virtual port
+ * @skb:buffer to transmit
+ * @dev: the device to be transmited to
+ * sucessful return true
+ * failed return false
+ */
+bool dev_fast_xmit_vp(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct netdev_queue *txq;
+ int cpu;
+ netdev_tx_t rc;
+
+ if (unlikely(!(dev->flags & IFF_UP))) {
+ return false;
+ }
+
+ if (unlikely(skb_is_nonlinear(skb))) {
+ return false;
+ }
+
+ rcu_read_lock_bh();
+ cpu = smp_processor_id();
+
+ /*
+ * TODO: Skip this altogether and eventually move this call to ppe_vp
+ * this would avoid multiple function calls when giving packet to wifi VAP.
+ */
+ txq = netdev_core_pick_tx(dev, skb, NULL);
+
+ if (likely(txq->xmit_lock_owner != cpu)) {
+#define FAST_VP_HARD_TX_LOCK(txq, cpu) { \
+ __netif_tx_lock(txq, cpu); \
+}
+
+#define FAST_VP_HARD_TX_UNLOCK(txq) { \
+ __netif_tx_unlock(txq); \
+}
+ skb->fast_xmit = 1;
+ FAST_VP_HARD_TX_LOCK(txq, cpu);
+ if (likely(!netif_xmit_stopped(txq))) {
+ rc = netdev_start_xmit(skb, dev, txq, 0);
+ if (unlikely(!dev_xmit_complete(rc))) {
+ FAST_VP_HARD_TX_UNLOCK(txq);
+ goto q_xmit;
+ }
+ FAST_VP_HARD_TX_UNLOCK(txq);
+ rcu_read_unlock_bh();
+ return true;
+ }
+ FAST_VP_HARD_TX_UNLOCK(txq);
+ }
+q_xmit:
+ skb->fast_xmit = 0;
+ rcu_read_unlock_bh();
+ return false;
+}
+EXPORT_SYMBOL(dev_fast_xmit_vp);
+
+/**
+ * dev_fast_xmit - fast xmit the skb
+ * @skb:buffer to transmit
+ * @dev: the device to be transmited to
+ * @features: the skb features could bed used
+ * sucessful return true
+ * failed return false
+ */
+bool dev_fast_xmit(struct sk_buff *skb,
+ struct net_device *dev,
+ netdev_features_t features)
+{
+ struct netdev_queue *txq;
+ int cpu;
+ netdev_tx_t rc;
+
+ /* the fast_xmit flag will avoid multiple checks in wifi xmit path */
+ if (likely(!skb_is_nonlinear(skb)))
+ skb->fast_xmit = 1;
+
+ if (unlikely(!(dev->flags & IFF_UP))) {
+ return false;
+ }
+
+ if (unlikely(skb_needs_linearize(skb, features))) {
+ return false;
+ }
+
+ rcu_read_lock_bh();
+ cpu = smp_processor_id();
+
+ /* If device don't need the dst, release it now, otherwise make sure
+ * the refcount increased.
+ */
+ if (likely(dev->priv_flags & IFF_XMIT_DST_RELEASE)) {
+ skb_dst_drop(skb);
+ } else {
+ skb_dst_force(skb);
+ }
+
+ txq = netdev_core_pick_tx(dev, skb, NULL);
+
+ if (likely(txq->xmit_lock_owner != cpu)) {
+#define FAST_HARD_TX_LOCK(features, txq, cpu) { \
+ if ((features & NETIF_F_LLTX) == 0) { \
+ __netif_tx_lock(txq, cpu); \
+ } else { \
+ __netif_tx_acquire(txq); \
+ } \
+}
+
+#define FAST_HARD_TX_UNLOCK(features, txq) { \
+ if ((features & NETIF_F_LLTX) == 0) { \
+ __netif_tx_unlock(txq); \
+ } else { \
+ __netif_tx_release(txq); \
+ } \
+}
+ netdev_features_t dev_features = dev->features;
+ FAST_HARD_TX_LOCK(dev_features, txq, cpu);
+ if (likely(!netif_xmit_stopped(txq))) {
+ rc = netdev_start_xmit(skb, dev, txq, 0);
+ if (unlikely(!dev_xmit_complete(rc))) {
+ FAST_HARD_TX_UNLOCK(dev_features, txq);
+ goto fail;
+ }
+ FAST_HARD_TX_UNLOCK(dev_features, txq);
+ rcu_read_unlock_bh();
+ return true;
+ }
+ FAST_HARD_TX_UNLOCK(dev_features, txq);
+ }
+fail:
+ rcu_read_unlock_bh();
+ return false;
+}
+EXPORT_SYMBOL(dev_fast_xmit);
+
+/**
* __dev_queue_xmit() - transmit a buffer
* @skb: buffer to transmit
* @sb_dev: suboordinate device used for L2 forwarding offload