174 lines
4.4 KiB
Diff
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
|