diff mbox series

[RFC,v2,1/2] linux: introduce multi-cpu dsa patch

Message ID 20220123003526.22366-2-ansuelsmth@gmail.com
State Changes Requested
Delegated to: Daniel Golle
Headers show
Series Add DSA MultiCPU port support | expand

Commit Message

Christian Marangi Jan. 23, 2022, 12:35 a.m. UTC
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 <ansuelsmth@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

Comments

Daniel Golle Jan. 23, 2022, 1:29 a.m. UTC | #1
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 <ansuelsmth@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-owner@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 <netdev@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 <netdev@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: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
> +        id S1726888AbfHXCnF (ORCPT <rfc822;netdev@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;netdev@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.behun@nic.cz>
> +To:     netdev@vger.kernel.org
> +Cc:     Andrew Lunn <andrew@lunn.ch>,
> +        Vivien Didelot <vivien.didelot@gmail.com>,
> +        Florian Fainelli <f.fainelli@gmail.com>,
> +        David Ahern <dsahern@gmail.com>,
> +        Stephen Hemminger <stephen@networkplumber.org>,
> +        =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@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.behun@nic.cz>
> +X-Mailer: git-send-email 2.21.0
> +In-Reply-To: <20190824024251.4542-1-marek.behun@nic.cz>
> +References: <20190824024251.4542-1-marek.behun@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-owner@vger.kernel.org
> +Precedence: bulk
> +List-ID: <netdev.vger.kernel.org>
> +X-Mailing-List: netdev@vger.kernel.org
> +Archived-At: <https://lore.kernel.org/netdev/20190824024251.4542-2-marek.behun@nic.cz/>
> +List-Archive: <https://lore.kernel.org/netdev/>
> +List-Post: <mailto:netdev@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.behun@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 <ansuelsmth@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 <ansuelsmth@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.behun@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.behun@nic.cz>
> +Signed-off-by: Ansuel Smith <ansuelsmth@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 <ansuelsmth@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 <ansuelsmth@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
diff mbox series

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-owner@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 <netdev@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 <netdev@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: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+        id S1726888AbfHXCnF (ORCPT <rfc822;netdev@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;netdev@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.behun@nic.cz>
+To:     netdev@vger.kernel.org
+Cc:     Andrew Lunn <andrew@lunn.ch>,
+        Vivien Didelot <vivien.didelot@gmail.com>,
+        Florian Fainelli <f.fainelli@gmail.com>,
+        David Ahern <dsahern@gmail.com>,
+        Stephen Hemminger <stephen@networkplumber.org>,
+        =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@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.behun@nic.cz>
+X-Mailer: git-send-email 2.21.0
+In-Reply-To: <20190824024251.4542-1-marek.behun@nic.cz>
+References: <20190824024251.4542-1-marek.behun@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-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <netdev.vger.kernel.org>
+X-Mailing-List: netdev@vger.kernel.org
+Archived-At: <https://lore.kernel.org/netdev/20190824024251.4542-2-marek.behun@nic.cz/>
+List-Archive: <https://lore.kernel.org/netdev/>
+List-Post: <mailto:netdev@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
+
+Signed-off-by: Marek Behún <marek.behun@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 <ansuelsmth@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 <ansuelsmth@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,
+ 	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.behun@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.behun@nic.cz>
+Signed-off-by: Ansuel Smith <ansuelsmth@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 <ansuelsmth@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 <ansuelsmth@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)
+ {