Please see two comments inline below On Sun, Jan 23, 2022 at 01:35:25AM +0100, Ansuel Smith wrote: > Add support for multi-cpu dsa. This is a reworked version of the RFC patch > proposed some time ago. > By default every dsa port is connected to the first cpu port and the command > 'ip link set PORT cpu CPU_PORT' can be used to change the used cpu port at > runtime. > A specific function port_change_cpu_port is required to correctly setup the > port on cpu change request. > > Signed-off-by: Ansuel Smith <ansuels...@gmail.com> > --- > ...net-dsa-allow_for_multiple_CPU_ports.patch | 151 ++++++++++++++++++ > ...add_ndo_for_setting_the_cpu_property.patch | 113 +++++++++++++ > ..._set_cpu_for_changing_ports_CPU_port.patch | 89 +++++++++++ > ...clude-net-add-dsa_cpu_ports-function.patch | 34 ++++ > 4 files changed, 387 insertions(+) > create mode 100644 > target/linux/generic/hack-5.10/780-1-net-dsa-allow_for_multiple_CPU_ports.patch > create mode 100644 > target/linux/generic/hack-5.10/780-2-net-add_ndo_for_setting_the_cpu_property.patch > create mode 100644 > target/linux/generic/hack-5.10/780-3-net-dsa-implement_ndo_set_cpu_for_changing_ports_CPU_port.patch > create mode 100644 > target/linux/generic/hack-5.10/780-4-include-net-add-dsa_cpu_ports-function.patch > > diff --git > a/target/linux/generic/hack-5.10/780-1-net-dsa-allow_for_multiple_CPU_ports.patch > > b/target/linux/generic/hack-5.10/780-1-net-dsa-allow_for_multiple_CPU_ports.patch > new file mode 100644 > index 00000000..7f2f349a > --- /dev/null > +++ > b/target/linux/generic/hack-5.10/780-1-net-dsa-allow_for_multiple_CPU_ports.patch > @@ -0,0 +1,151 @@ > +From mboxrd@z Thu Jan 1 00:00:00 1970 > +Return-Path: <SRS0=lHAO=WU=vger.kernel.org=netdev-ow...@kernel.org> > +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on > + aws-us-west-2-korg-lkml-1.web.codeaurora.org > +X-Spam-Level: > +X-Spam-Status: No, score=-9.9 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, > + > DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, > + SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham > + autolearn_force=no version=3.4.0 > +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) > + by smtp.lore.kernel.org (Postfix) with ESMTP id 98EBDC3A5A2 > + for <net...@archiver.kernel.org>; Sat, 24 Aug 2019 02:43:07 +0000 (UTC) > +Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) > + by mail.kernel.org (Postfix) with ESMTP id 6168A2173B > + for <net...@archiver.kernel.org>; Sat, 24 Aug 2019 02:43:07 +0000 (UTC) > +Authentication-Results: mail.kernel.org; > + dkim=pass (1024-bit key) header.d=nic.cz header.i=@nic.cz > header.b="Kl8qU9Mx" > +Received: (majord...@vger.kernel.org) by vger.kernel.org via listexpand > + id S1726888AbfHXCnF (ORCPT <rfc822;net...@archiver.kernel.org>); > + Fri, 23 Aug 2019 22:43:05 -0400 > +Received: from mail.nic.cz ([217.31.204.67]:37268 "EHLO mail.nic.cz" > + rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP > + id S1725807AbfHXCnD (ORCPT <rfc822;net...@vger.kernel.org>); > + Fri, 23 Aug 2019 22:43:03 -0400 > +Received: from dellmb.labs.office.nic.cz (unknown > [IPv6:2001:1488:fffe:6:cac7:3539:7f1f:463]) > + by mail.nic.cz (Postfix) with ESMTP id 94D1E140D1E; > + Sat, 24 Aug 2019 04:42:59 +0200 (CEST) > +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nic.cz; s=default; > + t=1566614579; bh=jPa21EsnWy9WksW68HSx/O+la2qm4ImIACY+K2cEnLY=; > + h=From:To:Date; > + b=Kl8qU9MxZdC3EQnTetDA7VbGXYIuwCO2zS6HinOo7XykIKQDlvB7jIUcH0FQLgG6T > + BNf/aIsDASIL1PBSAlNynoTMSDf8m6I2Xo8auxQr4L6sslF683w8hY9PN7f+pYyL2R > + FQs93FIJYSp5I2NCSktTxGFNumTvYPxA8lEqBaZo= > +From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.be...@nic.cz> > +To: net...@vger.kernel.org > +Cc: Andrew Lunn <and...@lunn.ch>, > + Vivien Didelot <vivien.dide...@gmail.com>, > + Florian Fainelli <f.faine...@gmail.com>, > + David Ahern <dsah...@gmail.com>, > + Stephen Hemminger <step...@networkplumber.org>, > + =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.be...@nic.cz> > +Subject: [PATCH RFC net-next 1/3] net: dsa: allow for multiple CPU ports > +Date: Sat, 24 Aug 2019 04:42:48 +0200 > +Message-Id: <20190824024251.4542-2-marek.be...@nic.cz> > +X-Mailer: git-send-email 2.21.0 > +In-Reply-To: <20190824024251.4542-1-marek.be...@nic.cz> > +References: <20190824024251.4542-1-marek.be...@nic.cz> > +MIME-Version: 1.0 > +Content-Type: text/plain; charset=UTF-8 > +Content-Transfer-Encoding: 8bit > +X-Virus-Scanned: clamav-milter 0.100.3 at mail.nic.cz > +X-Virus-Status: Clean > +Sender: netdev-ow...@vger.kernel.org > +Precedence: bulk > +List-ID: <netdev.vger.kernel.org> > +X-Mailing-List: net...@vger.kernel.org > +Archived-At: > <https://lore.kernel.org/netdev/20190824024251.4542-2-marek.be...@nic.cz/> > +List-Archive: <https://lore.kernel.org/netdev/> > +List-Post: <mailto:net...@vger.kernel.org> > + > +Allow for multiple CPU ports in a DSA switch tree. By default assign the > +CPU ports to user ports in a round robin way, ie. if there are two CPU > +ports connected to eth0 and eth1, and five user ports (lan1..lan5), > +assign them as: > + lan1 <-> eth0 > + lan2 <-> eth1 > + lan3 <-> eth0 > + lan4 <-> eth1 > + lan5 <-> eth0
This commit message is no longer up-to-date with the code. > + > +Signed-off-by: Marek Behún <marek.be...@nic.cz> > +--- > + include/net/dsa.h | 5 +-- > + net/dsa/dsa2.c | 84 +++++++++++++++++++++++++++++++---------------- > + 2 files changed, 58 insertions(+), 31 deletions(-) > + > +--- a/net/dsa/dsa2.c > ++++ b/net/dsa/dsa2.c > +@@ -211,7 +211,7 @@ static bool dsa_tree_setup_routing_table > + return 0; > + } > + > +-static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst) > ++static void dsa_tree_teardown_default_cpus(struct dsa_switch_tree *dst) > + { > + struct dsa_port *dp; > + > +@@ -572,7 +582,7 @@ static void dsa_tree_teardown_switches(s > + dsa_switch_teardown(dp->ds); > + } > + > +-static int dsa_tree_setup_master(struct dsa_switch_tree *dst) > ++static int dsa_tree_setup_masters(struct dsa_switch_tree *dst) > + { > + struct dsa_port *dp; > + int err; > +@@ -581,14 +591,20 @@ static int dsa_tree_setup_master(struct > + if (dsa_port_is_cpu(dp)) { > + err = dsa_master_setup(dp->master, dp); > + if (err) > +- return err; > ++ goto teardown; > + } > + } > + > + return 0; > ++teardown: > ++ list_for_each_entry(dp, &dst->ports, list) > ++ if (dsa_port_is_cpu(dp)) > ++ dsa_master_teardown(dp->master); > ++ > ++ return err; > + } > + > +-static void dsa_tree_teardown_master(struct dsa_switch_tree *dst) > ++static void dsa_tree_teardown_masters(struct dsa_switch_tree *dst) > + { > + struct dsa_port *dp; > + > +@@ -620,7 +636,7 @@ static int dsa_tree_setup(struct dsa_swi > + if (err) > + goto teardown_default_cpu; > + > +- err = dsa_tree_setup_master(dst); > ++ err = dsa_tree_setup_masters(dst); > + if (err) > + goto teardown_switches; > + > +@@ -633,7 +649,7 @@ static int dsa_tree_setup(struct dsa_swi > + teardown_switches: > + dsa_tree_teardown_switches(dst); > + teardown_default_cpu: > +- dsa_tree_teardown_default_cpu(dst); > ++ dsa_tree_teardown_default_cpus(dst); > + > + return err; > + } > +@@ -645,11 +661,11 @@ static void dsa_tree_teardown(struct dsa > + if (!dst->setup) > + return; > + > +- dsa_tree_teardown_master(dst); > ++ dsa_tree_teardown_masters(dst); > + > + dsa_tree_teardown_switches(dst); > + > +- dsa_tree_teardown_default_cpu(dst); > ++ dsa_tree_teardown_default_cpus(dst); > + > + list_for_each_entry_safe(dl, next, &dst->rtable, list) { > + list_del(&dl->list); > diff --git > a/target/linux/generic/hack-5.10/780-2-net-add_ndo_for_setting_the_cpu_property.patch > > b/target/linux/generic/hack-5.10/780-2-net-add_ndo_for_setting_the_cpu_property.patch > new file mode 100644 > index 00000000..aeee31cd > --- /dev/null > +++ > b/target/linux/generic/hack-5.10/780-2-net-add_ndo_for_setting_the_cpu_property.patch > @@ -0,0 +1,113 @@ > +From 9439d87a81e3ea67f53b4e6db1e8858fdad27b48 Mon Sep 17 00:00:00 2001 > +From: Ansuel Smith <ansuels...@gmail.com> > +Date: Sun, 23 Jan 2022 00:49:10 +0100 > +Subject: [PATCH] net: add ndo for setting the cpu proprety > + > +In DSA the cpu value is used to report to which CPU port a given switch > +port is connected to. Since we want to support multi-CPU DSA, we want > +the user to be able to change this value. > + > +Add ndo_set_cpu method into the ndo structure and also create > +dev_set_cpu and call this from the netlink code, so that userspace can > +change the cpu value. > + > +Signed-off-by: Ansuel Smith <ansuels...@gmail.com> > +--- > + include/linux/netdevice.h | 5 +++++ > + include/uapi/linux/if_link.h | 1 + > + net/core/dev.c | 18 ++++++++++++++++++ > + net/core/rtnetlink.c | 7 +++++++ > + 4 files changed, 31 insertions(+) > + > +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > +index 235d5d082f1a..b1524b92efdf 100644 > +--- a/include/linux/netdevice.h > ++++ b/include/linux/netdevice.h > +@@ -1301,6 +1301,8 @@ struct netdev_net_notifier { > + * TX queue. > + * int (*ndo_get_iflink)(const struct net_device *dev); > + * Called to get the iflink value of this device. > ++ * int (*ndo_set_cpu)(struct net_device *dev, int cpu); > ++ * Called to set the cpu value of this device. > + * void (*ndo_change_proto_down)(struct net_device *dev, > + * bool proto_down); > + * This function is used to pass protocol port error state information > +@@ -1541,6 +1543,8 @@ struct net_device_ops { > + int queue_index, > + u32 maxrate); > + int (*ndo_get_iflink)(const struct net_device *dev); > ++ int (*ndo_set_cpu)(struct net_device *dev, > ++ int cpu); > + int (*ndo_change_proto_down)(struct net_device *dev, > + bool proto_down); > + int (*ndo_fill_metadata_dst)(struct net_device *dev, > +@@ -2853,6 +2857,7 @@ void dev_add_offload(struct packet_offload *po); > + void dev_remove_offload(struct packet_offload *po); > + > + int dev_get_iflink(const struct net_device *dev); > ++int dev_set_cpu(struct net_device *dev, int cpu); > + int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb); > + int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, > + struct net_device_path_stack *stack); > +diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h > +index 4ac53b30b6dc..6a6de696854b 100644 > +--- a/include/uapi/linux/if_link.h > ++++ b/include/uapi/linux/if_link.h > +@@ -279,6 +279,7 @@ enum { > + IFLA_BROADCAST, > + IFLA_IFNAME, > + IFLA_MTU, > ++ IFLA_CPU, The newly added attribute in the enum should be the last and not change the order of the existing enums, so ABI compatiblity is retained as much as possible. > + IFLA_LINK, > + IFLA_QDISC, > + IFLA_STATS, > +diff --git a/net/core/dev.c b/net/core/dev.c > +index a855e41bbe39..3335e629850d 100644 > +--- a/net/core/dev.c > ++++ b/net/core/dev.c > +@@ -621,6 +621,24 @@ int dev_get_iflink(const struct net_device *dev) > + } > + EXPORT_SYMBOL(dev_get_iflink); > + > ++/** > ++ * dev_set_cpu - set 'cpu' value of a dsa interface > ++ * @dev: target interface > ++ * @cpu: new value > ++ * > ++ * Change the cpu port to which this dsa interface is linked to. > ++ */ > ++int dev_set_cpu(struct net_device *dev, int cpu) > ++{ > ++ if (!dev->dsa_ptr) > ++ return -EOPNOTSUPP; > ++ > ++ if (dev->netdev_ops && dev->netdev_ops->ndo_set_cpu) > ++ return dev->netdev_ops->ndo_set_cpu(dev, cpu); > ++ > ++ return -EOPNOTSUPP; > ++} > ++ > + /** > + * dev_fill_metadata_dst - Retrieve tunnel egress information. > + * @dev: targeted interface > +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c > +index d6eba554b137..199bbdad685e 100644 > +--- a/net/core/rtnetlink.c > ++++ b/net/core/rtnetlink.c > +@@ -2728,6 +2728,13 @@ static int do_setlink(const struct sk_buff *skb, > + status |= DO_SETLINK_MODIFIED; > + } > + > ++ if (tb[IFLA_CPU]) { > ++ err = dev_set_cpu(dev, nla_get_u32(tb[IFLA_CPU])); > ++ if (err) > ++ goto errout; > ++ status |= DO_SETLINK_MODIFIED; > ++ } > ++ > + if (tb[IFLA_CARRIER]) { > + err = dev_change_carrier(dev, nla_get_u8(tb[IFLA_CARRIER])); > + if (err) > +-- > +2.33.1 > + > diff --git > a/target/linux/generic/hack-5.10/780-3-net-dsa-implement_ndo_set_cpu_for_changing_ports_CPU_port.patch > > b/target/linux/generic/hack-5.10/780-3-net-dsa-implement_ndo_set_cpu_for_changing_ports_CPU_port.patch > new file mode 100644 > index 00000000..62be001a > --- /dev/null > +++ > b/target/linux/generic/hack-5.10/780-3-net-dsa-implement_ndo_set_cpu_for_changing_ports_CPU_port.patch > @@ -0,0 +1,89 @@ > +From: Marek Behún <marek.be...@nic.cz> > +Subject: [PATCH RFC net-next 3/3] net: dsa: implement ndo_set_cpu for > changing port's CPU port > +Date: Sat, 24 Aug 2019 04:42:50 +0200 > + > +Implement ndo_set_cpu for DSA slave device. In multi-CPU port setup > +this should be used to change to which CPU destination port a given port > +should be connected. > + > +This adds a new operation into the DSA switch operations structure, > +port_change_cpu_port. A driver implementing this function has the > +ability to change CPU destination port of a given port. > + > +Signed-off-by: Marek Behún <marek.be...@nic.cz> > +Signed-off-by: Ansuel Smith <ansuels...@gmail.com> > +--- > + include/net/dsa.h | 6 ++++++ > + net/dsa/slave.c | 35 +++++++++++++++++++++++++++++++++++ > + 2 files changed, 41 insertions(+) > + > +--- a/include/net/dsa.h > ++++ b/include/net/dsa.h > +@@ -654,6 +654,12 @@ struct dsa_switch_ops { > + int (*port_change_mtu)(struct dsa_switch *ds, int port, > + int new_mtu); > + int (*port_max_mtu)(struct dsa_switch *ds, int port); > ++ > ++ /* > ++ * Multi-CPU port support > ++ */ > ++ int (*port_change_cpu_port)(struct dsa_switch *ds, int port, > ++ struct dsa_port *new_cpu_dp); > + }; > + > + #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) > \ > +--- a/net/dsa/slave.c > ++++ b/net/dsa/slave.c > +@@ -62,6 +62,44 @@ static int dsa_slave_get_iflink(const st > + return dsa_slave_to_master(dev)->ifindex; > + } > + > ++static int dsa_slave_set_cpu(struct net_device *dev, int cpu) > ++{ > ++ struct net_device *master = dsa_slave_to_master(dev); > ++ struct dsa_port *dp = dsa_slave_to_port(dev); > ++ struct dsa_slave_priv *p = netdev_priv(dev); > ++ struct net_device *new_cpu_dev; > ++ struct dsa_port *new_cpu_dp; > ++ int err; > ++ > ++ if (!dp->ds->ops->port_change_cpu_port) > ++ return -EOPNOTSUPP; > ++ > ++ new_cpu_dev = dev_get_by_index(dev_net(dev), cpu); > ++ if (!new_cpu_dev) > ++ return -ENODEV; > ++ > ++ new_cpu_dp = new_cpu_dev->dsa_ptr; > ++ if (!new_cpu_dp) > ++ return -EINVAL; > ++ > ++ /* new CPU port has to be on the same switch tree */ > ++ if (new_cpu_dp->dst != dp->cpu_dp->dst) > ++ return -EINVAL; > ++ > ++ err = dp->ds->ops->port_change_cpu_port(dp->ds, dp->index, new_cpu_dp); > ++ if (err) > ++ return err; > ++ > ++ if (ether_addr_equal(dev->dev_addr, master->dev_addr)) > ++ eth_hw_addr_inherit(dev, new_cpu_dev); > ++ > ++ /* should this be done atomically? */ > ++ dp->cpu_dp = new_cpu_dp; > ++ p->xmit = new_cpu_dp->tag_ops->xmit; > ++ > ++ return 0; > ++} > ++ > + static int dsa_slave_open(struct net_device *dev) > + { > + struct net_device *master = dsa_slave_to_master(dev); > +@@ -1667,6 +1705,7 @@ static const struct net_device_ops dsa_s > + .ndo_fdb_dump = dsa_slave_fdb_dump, > + .ndo_do_ioctl = dsa_slave_ioctl, > + .ndo_get_iflink = dsa_slave_get_iflink, > ++ .ndo_set_cpu = dsa_slave_set_cpu, > + #ifdef CONFIG_NET_POLL_CONTROLLER > + .ndo_netpoll_setup = dsa_slave_netpoll_setup, > + .ndo_netpoll_cleanup = dsa_slave_netpoll_cleanup, > diff --git > a/target/linux/generic/hack-5.10/780-4-include-net-add-dsa_cpu_ports-function.patch > > b/target/linux/generic/hack-5.10/780-4-include-net-add-dsa_cpu_ports-function.patch > new file mode 100644 > index 00000000..d03b8e62 > --- /dev/null > +++ > b/target/linux/generic/hack-5.10/780-4-include-net-add-dsa_cpu_ports-function.patch > @@ -0,0 +1,34 @@ > +From 2bf13a906ce96f67eb292c8e519c6d2215501d82 Mon Sep 17 00:00:00 2001 > +From: Ansuel Smith <ansuels...@gmail.com> > +Date: Sun, 4 Apr 2021 12:58:50 +0200 > +Subject: [PATCH 1/2] include: net: add dsa_cpu_ports function > + > +dsa_cpu_ports can be useful for switch that has multiple cpu port to > +retrieve the cpu mask for ACL and bridge table. > + > +Signed-off-by: Ansuel Smith <ansuels...@gmail.com> > +--- > + include/net/dsa.h | 12 ++++++++++++ > + 1 file changed, 12 insertions(+) > + > +--- a/include/net/dsa.h > ++++ b/include/net/dsa.h > +@@ -387,6 +387,18 @@ static inline u32 dsa_user_ports(struct > + return mask; > + } > + > ++static inline u32 dsa_cpu_ports(struct dsa_switch *ds) > ++{ > ++ u32 mask = 0; > ++ int p; > ++ > ++ for (p = 0; p < ds->num_ports; p++) > ++ if (dsa_is_cpu_port(ds, p)) > ++ mask |= BIT(p); > ++ > ++ return mask; > ++} > ++ > + /* Return the local port used to reach an arbitrary switch device */ > + static inline unsigned int dsa_routing_port(struct dsa_switch *ds, int > device) > + { > -- > 2.33.1 > > > _______________________________________________ > openwrt-devel mailing list > openwrt-devel@lists.openwrt.org > https://lists.openwrt.org/mailman/listinfo/openwrt-devel _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel