aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-07 19:11:58 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-07 19:11:58 -0500
commit3cdcf1334cd76bbcabd0f273ee9a13e4cc7816bc (patch)
tree03664d96b9f9020411e9772ed21d3825a5ff69ef /net
parent1ec4864b10171b0691ee196d7006ae56d2c153f2 (diff)
parent2a47fa45d4dfbc54659d28de311a1f764b296a3c (diff)
Merge branch 'macvlan_hwaccel'
John Fastabend says: ==================== l2 hardware accelerated macvlans This patch adds support to offload macvlan net_devices to the hardware. With these patches packets are pushed to the macvlan net_device directly and do not pass through the lower dev. The patches here have made it through multiple iterations each with a slightly different focus. First I tried to push these as a new link type called "VMDQ". The patches shown here, http://comments.gmane.org/gmane.linux.network/237617 Following this implementation I renamed the link type "VSI" and addressed various comments. Finally Neil Horman picked up the patches and integrated the offload into the macvlan code. Here, http://permalink.gmane.org/gmane.linux.network/285658 The attached series is clean-up of his patches, with a few fixes. If folks find this series acceptable there are a few items we can work on next. First broadcast and multicast will use the hardware even for local traffic with this series. It would be best (I think) to use the software path for macvlan to macvlan traffic and save the PCIe bus. This depends on how much you value CPU time vs PCIE bandwidth. This will need another patch series to flush out. Also this series only allows for layer 2 mac forwarding where some hardware supports more interesting forwarding capabilities. Integrating with OVS may be useful here. As always any comments/feedback welcome. My basic I/O test is here but I've also done some link testing, SRIOV/DCB with macvlans and others, Changelog: v2: two fixes to ixgbe when all features DCB, FCoE, SR-IOV are enabled with macvlans. A VMDQ_P() reference should have been accel->pool and do not set the offset of the ring index from dfwd add call. The offset is used by SR-IOV so clearing it can cause SR-IOV quue index's to go sideways. With these fixes testing macvlan's with SRIOV enabled was successful. v3: addressed Neil's comments in ixgbe fixed error path on dfwd_add_station() in ixgbe fixed ixgbe to allow SRIOV and accelerated macvlans to coexist. v4: Dave caught some strange indentation, fixed it here ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c18
-rw-r--r--net/core/ethtool.c1
-rw-r--r--net/sched/sch_generic.c2
3 files changed, 15 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 0e6136546a8c..8ffc52e01ece 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2538,7 +2538,7 @@ static inline int skb_needs_linearize(struct sk_buff *skb,
2538} 2538}
2539 2539
2540int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, 2540int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
2541 struct netdev_queue *txq) 2541 struct netdev_queue *txq, void *accel_priv)
2542{ 2542{
2543 const struct net_device_ops *ops = dev->netdev_ops; 2543 const struct net_device_ops *ops = dev->netdev_ops;
2544 int rc = NETDEV_TX_OK; 2544 int rc = NETDEV_TX_OK;
@@ -2604,9 +2604,13 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
2604 dev_queue_xmit_nit(skb, dev); 2604 dev_queue_xmit_nit(skb, dev);
2605 2605
2606 skb_len = skb->len; 2606 skb_len = skb->len;
2607 rc = ops->ndo_start_xmit(skb, dev); 2607 if (accel_priv)
2608 rc = ops->ndo_dfwd_start_xmit(skb, dev, accel_priv);
2609 else
2610 rc = ops->ndo_start_xmit(skb, dev);
2611
2608 trace_net_dev_xmit(skb, rc, dev, skb_len); 2612 trace_net_dev_xmit(skb, rc, dev, skb_len);
2609 if (rc == NETDEV_TX_OK) 2613 if (rc == NETDEV_TX_OK && txq)
2610 txq_trans_update(txq); 2614 txq_trans_update(txq);
2611 return rc; 2615 return rc;
2612 } 2616 }
@@ -2622,7 +2626,10 @@ gso:
2622 dev_queue_xmit_nit(nskb, dev); 2626 dev_queue_xmit_nit(nskb, dev);
2623 2627
2624 skb_len = nskb->len; 2628 skb_len = nskb->len;
2625 rc = ops->ndo_start_xmit(nskb, dev); 2629 if (accel_priv)
2630 rc = ops->ndo_dfwd_start_xmit(nskb, dev, accel_priv);
2631 else
2632 rc = ops->ndo_start_xmit(nskb, dev);
2626 trace_net_dev_xmit(nskb, rc, dev, skb_len); 2633 trace_net_dev_xmit(nskb, rc, dev, skb_len);
2627 if (unlikely(rc != NETDEV_TX_OK)) { 2634 if (unlikely(rc != NETDEV_TX_OK)) {
2628 if (rc & ~NETDEV_TX_MASK) 2635 if (rc & ~NETDEV_TX_MASK)
@@ -2647,6 +2654,7 @@ out_kfree_skb:
2647out: 2654out:
2648 return rc; 2655 return rc;
2649} 2656}
2657EXPORT_SYMBOL_GPL(dev_hard_start_xmit);
2650 2658
2651static void qdisc_pkt_len_init(struct sk_buff *skb) 2659static void qdisc_pkt_len_init(struct sk_buff *skb)
2652{ 2660{
@@ -2854,7 +2862,7 @@ int dev_queue_xmit(struct sk_buff *skb)
2854 2862
2855 if (!netif_xmit_stopped(txq)) { 2863 if (!netif_xmit_stopped(txq)) {
2856 __this_cpu_inc(xmit_recursion); 2864 __this_cpu_inc(xmit_recursion);
2857 rc = dev_hard_start_xmit(skb, dev, txq); 2865 rc = dev_hard_start_xmit(skb, dev, txq, NULL);
2858 __this_cpu_dec(xmit_recursion); 2866 __this_cpu_dec(xmit_recursion);
2859 if (dev_xmit_complete(rc)) { 2867 if (dev_xmit_complete(rc)) {
2860 HARD_TX_UNLOCK(dev, txq); 2868 HARD_TX_UNLOCK(dev, txq);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 862989898f61..30071dec287a 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -96,6 +96,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
96 [NETIF_F_LOOPBACK_BIT] = "loopback", 96 [NETIF_F_LOOPBACK_BIT] = "loopback",
97 [NETIF_F_RXFCS_BIT] = "rx-fcs", 97 [NETIF_F_RXFCS_BIT] = "rx-fcs",
98 [NETIF_F_RXALL_BIT] = "rx-all", 98 [NETIF_F_RXALL_BIT] = "rx-all",
99 [NETIF_F_HW_L2FW_DOFFLOAD_BIT] = "l2-fwd-offload",
99}; 100};
100 101
101static int ethtool_get_features(struct net_device *dev, void __user *useraddr) 102static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7fc899a943a8..922a09406ba7 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -126,7 +126,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
126 126
127 HARD_TX_LOCK(dev, txq, smp_processor_id()); 127 HARD_TX_LOCK(dev, txq, smp_processor_id());
128 if (!netif_xmit_frozen_or_stopped(txq)) 128 if (!netif_xmit_frozen_or_stopped(txq))
129 ret = dev_hard_start_xmit(skb, dev, txq); 129 ret = dev_hard_start_xmit(skb, dev, txq, NULL);
130 130
131 HARD_TX_UNLOCK(dev, txq); 131 HARD_TX_UNLOCK(dev, txq);
132 132