Tobias Waldekranz
2021-Apr-26 17:04 UTC
[Bridge] [RFC net-next 6/9] net: dsa: Forward offloading
Allow DSA drivers to support forward offloading from a bridge by:
- Passing calls to .ndo_dfwd_{add,del}_station to the drivers.
- Recording the subordinate device of offloaded skbs in the control
buffer so that the tagger can take the appropriate action.
Signed-off-by: Tobias Waldekranz <tobias at waldekranz.com>
---
include/net/dsa.h | 7 +++++++
net/dsa/slave.c | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 1f9ba9889034..77d4df819299 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -119,6 +119,7 @@ struct dsa_netdevice_ops {
struct dsa_skb_cb {
struct sk_buff *clone;
+ struct net_device *sb_dev;
};
struct __dsa_skb_cb {
@@ -828,6 +829,12 @@ struct dsa_switch_ops {
const struct switchdev_obj_ring_role_mrp *mrp);
int (*port_mrp_del_ring_role)(struct dsa_switch *ds, int port,
const struct switchdev_obj_ring_role_mrp *mrp);
+
+ /* L2 forward offloading */
+ void * (*dfwd_add_station)(struct dsa_switch *ds, int port,
+ struct net_device *sb_dev);
+ void (*dfwd_del_station)(struct dsa_switch *ds, int port,
+ struct net_device *sb_dev);
};
#define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 77b33bd161b8..3689ffa2dbb8 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -657,6 +657,13 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb,
struct net_device *dev)
return dsa_enqueue_skb(nskb, dev);
}
+static u16 dsa_slave_select_queue(struct net_device *dev, struct sk_buff *skb,
+ struct net_device *sb_dev)
+{
+ DSA_SKB_CB(skb)->sb_dev = sb_dev;
+ return netdev_pick_tx(dev, skb, sb_dev);
+}
+
/* ethtool operations *******************************************************/
static void dsa_slave_get_drvinfo(struct net_device *dev,
@@ -1708,10 +1715,33 @@ static int dsa_slave_fill_forward_path(struct
net_device_path_ctx *ctx,
return 0;
}
+static void *dsa_slave_dfwd_add_station(struct net_device *dev,
+ struct net_device *sb_dev)
+{
+ struct dsa_port *dp = dsa_slave_to_port(dev);
+ struct dsa_switch *ds = dp->ds;
+
+ if (ds->ops->dfwd_add_station)
+ return ds->ops->dfwd_add_station(ds, dp->index, sb_dev);
+
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+static void dsa_slave_dfwd_del_station(struct net_device *dev,
+ void *sb_dev)
+{
+ struct dsa_port *dp = dsa_slave_to_port(dev);
+ struct dsa_switch *ds = dp->ds;
+
+ if (ds->ops->dfwd_del_station)
+ ds->ops->dfwd_del_station(ds, dp->index, sb_dev);
+}
+
static const struct net_device_ops dsa_slave_netdev_ops = {
.ndo_open = dsa_slave_open,
.ndo_stop = dsa_slave_close,
.ndo_start_xmit = dsa_slave_xmit,
+ .ndo_select_queue = dsa_slave_select_queue,
.ndo_change_rx_flags = dsa_slave_change_rx_flags,
.ndo_set_rx_mode = dsa_slave_set_rx_mode,
.ndo_set_mac_address = dsa_slave_set_mac_address,
@@ -1734,6 +1764,8 @@ static const struct net_device_ops dsa_slave_netdev_ops =
{
.ndo_get_devlink_port = dsa_slave_get_devlink_port,
.ndo_change_mtu = dsa_slave_change_mtu,
.ndo_fill_forward_path = dsa_slave_fill_forward_path,
+ .ndo_dfwd_add_station = dsa_slave_dfwd_add_station,
+ .ndo_dfwd_del_station = dsa_slave_dfwd_del_station,
};
static struct device_type dsa_type = {
@@ -1914,8 +1946,8 @@ int dsa_slave_create(struct dsa_port *port)
slave_dev->features = master->vlan_features | NETIF_F_HW_TC;
if (ds->ops->port_vlan_add && ds->ops->port_vlan_del)
slave_dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
- slave_dev->hw_features |= NETIF_F_HW_TC;
- slave_dev->features |= NETIF_F_LLTX;
+ slave_dev->hw_features |= NETIF_F_HW_TC | NETIF_F_HW_L2FW_DOFFLOAD;
+ slave_dev->features |= NETIF_F_LLTX | NETIF_F_HW_L2FW_DOFFLOAD;
slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
if (!is_zero_ether_addr(port->mac))
ether_addr_copy(slave_dev->dev_addr, port->mac);
--
2.25.1
Vladimir Oltean
2021-Apr-27 10:17 UTC
[Bridge] [RFC net-next 6/9] net: dsa: Forward offloading
On Mon, Apr 26, 2021 at 07:04:08PM +0200, Tobias Waldekranz wrote:> Allow DSA drivers to support forward offloading from a bridge by: > > - Passing calls to .ndo_dfwd_{add,del}_station to the drivers. > > - Recording the subordinate device of offloaded skbs in the control > buffer so that the tagger can take the appropriate action. > > Signed-off-by: Tobias Waldekranz <tobias at waldekranz.com> > --- > include/net/dsa.h | 7 +++++++ > net/dsa/slave.c | 36 ++++++++++++++++++++++++++++++++++-- > 2 files changed, 41 insertions(+), 2 deletions(-) > > diff --git a/include/net/dsa.h b/include/net/dsa.h > index 1f9ba9889034..77d4df819299 100644 > --- a/include/net/dsa.h > +++ b/include/net/dsa.h > @@ -119,6 +119,7 @@ struct dsa_netdevice_ops { > > struct dsa_skb_cb { > struct sk_buff *clone; > + struct net_device *sb_dev; > }; > > struct __dsa_skb_cb { > @@ -828,6 +829,12 @@ struct dsa_switch_ops { > const struct switchdev_obj_ring_role_mrp *mrp); > int (*port_mrp_del_ring_role)(struct dsa_switch *ds, int port, > const struct switchdev_obj_ring_role_mrp *mrp); > + > + /* L2 forward offloading */ > + void * (*dfwd_add_station)(struct dsa_switch *ds, int port, > + struct net_device *sb_dev); > + void (*dfwd_del_station)(struct dsa_switch *ds, int port, > + struct net_device *sb_dev); > }; > > #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ > diff --git a/net/dsa/slave.c b/net/dsa/slave.c > index 77b33bd161b8..3689ffa2dbb8 100644 > --- a/net/dsa/slave.c > +++ b/net/dsa/slave.c > @@ -657,6 +657,13 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) > return dsa_enqueue_skb(nskb, dev); > } > > +static u16 dsa_slave_select_queue(struct net_device *dev, struct sk_buff *skb, > + struct net_device *sb_dev) > +{ > + DSA_SKB_CB(skb)->sb_dev = sb_dev; > + return netdev_pick_tx(dev, skb, sb_dev); > +} > +DSA_SKB_CB is going away: https://patchwork.kernel.org/project/netdevbpf/patch/20210427042203.26258-5-yangbo.lu at nxp.com/ Let's either negotiate with Yangbo on keeping it, or make .ndo_select_queue a bypass towards the tagger, where it can use its own SKB_CB structure and be more flexible in general (I think I'm leaning towards the latter).
Tobias Waldekranz
2021-May-04 14:44 UTC
[Bridge] [RFC net-next 6/9] net: dsa: Forward offloading
On Tue, Apr 27, 2021 at 13:17, Vladimir Oltean <olteanv at gmail.com> wrote:> On Mon, Apr 26, 2021 at 07:04:08PM +0200, Tobias Waldekranz wrote: >> Allow DSA drivers to support forward offloading from a bridge by: >> >> - Passing calls to .ndo_dfwd_{add,del}_station to the drivers. >> >> - Recording the subordinate device of offloaded skbs in the control >> buffer so that the tagger can take the appropriate action. >> >> Signed-off-by: Tobias Waldekranz <tobias at waldekranz.com> >> --- >> include/net/dsa.h | 7 +++++++ >> net/dsa/slave.c | 36 ++++++++++++++++++++++++++++++++++-- >> 2 files changed, 41 insertions(+), 2 deletions(-) >> >> diff --git a/include/net/dsa.h b/include/net/dsa.h >> index 1f9ba9889034..77d4df819299 100644 >> --- a/include/net/dsa.h >> +++ b/include/net/dsa.h >> @@ -119,6 +119,7 @@ struct dsa_netdevice_ops { >> >> struct dsa_skb_cb { >> struct sk_buff *clone; >> + struct net_device *sb_dev; >> }; >> >> struct __dsa_skb_cb { >> @@ -828,6 +829,12 @@ struct dsa_switch_ops { >> const struct switchdev_obj_ring_role_mrp *mrp); >> int (*port_mrp_del_ring_role)(struct dsa_switch *ds, int port, >> const struct switchdev_obj_ring_role_mrp *mrp); >> + >> + /* L2 forward offloading */ >> + void * (*dfwd_add_station)(struct dsa_switch *ds, int port, >> + struct net_device *sb_dev); >> + void (*dfwd_del_station)(struct dsa_switch *ds, int port, >> + struct net_device *sb_dev); >> }; >> >> #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ >> diff --git a/net/dsa/slave.c b/net/dsa/slave.c >> index 77b33bd161b8..3689ffa2dbb8 100644 >> --- a/net/dsa/slave.c >> +++ b/net/dsa/slave.c >> @@ -657,6 +657,13 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) >> return dsa_enqueue_skb(nskb, dev); >> } >> >> +static u16 dsa_slave_select_queue(struct net_device *dev, struct sk_buff *skb, >> + struct net_device *sb_dev) >> +{ >> + DSA_SKB_CB(skb)->sb_dev = sb_dev; >> + return netdev_pick_tx(dev, skb, sb_dev); >> +} >> + > > DSA_SKB_CB is going away: > https://patchwork.kernel.org/project/netdevbpf/patch/20210427042203.26258-5-yangbo.lu at nxp.com/ > > Let's either negotiate with Yangbo on keeping it, or make > .ndo_select_queue a bypass towards the tagger, where it can use its own > SKB_CB structure and be more flexible in general (I think I'm leaning > towards the latter).Thus far, Yangbo is a tough negotiator, giving me the silent treatment: https://lore.kernel.org/netdev/87y2d2noe5.fsf at waldekranz.com/ :) That memset is giving me a hard time. I have just disabled it on my branch at the moment. Any ideas on how to get rid of it without breaking timestamping?