[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <174265452703.356712.4878516873691237055.stgit@pro.pro>
Date: Sat, 22 Mar 2025 17:42:07 +0300
From: Kirill Tkhai <tkhai@...ru>
To: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: tkhai@...ru
Subject: [PATCH NET-PREV 34/51] dsa: Make all switch tree ports relate to same nd_lock
dsa_tree_migrate_ports_from_lag_conduit() may take any
of ports as new conduit, and it will be connected to
the rest of ports (and using netdev_upper_dev_link()),
so all of them must share the same nd_lock.
xxx: Keep in mind NETDEV_CHANGEUPPER is called
by netdev_upper_dev_unlink().
Signed-off-by: Kirill Tkhai <tkhai@...ru>
---
net/dsa/dsa.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 668c729946ea..6468b03d3d46 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -1156,6 +1156,8 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *conduit,
struct dsa_switch *ds = dp->ds;
struct dsa_switch_tree *dst = ds->dst;
enum dsa_tag_protocol default_proto;
+ struct nd_lock *nd_lock, *nd_lock2;
+ struct dsa_port *first_dp;
/* Find out which protocol the switch would prefer. */
default_proto = dsa_get_tag_protocol(dp, conduit);
@@ -1213,6 +1215,18 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *conduit,
dst->tag_ops = tag_ops;
}
+ first_dp = dsa_tree_find_first_cpu(dst);
+ if (first_dp && first_dp->conduit) {
+ /* All conduits must relate the same nd_lock
+ * since dsa_tree_migrate_ports_from_lag_conduit()
+ * may take any of them from list.
+ */
+ double_lock_netdev(first_dp->conduit, &nd_lock,
+ conduit, &nd_lock2);
+ nd_lock_transfer_devices(&nd_lock, &nd_lock2);
+ double_unlock_netdev(nd_lock, nd_lock2);
+ }
+
dp->conduit = conduit;
dp->type = DSA_PORT_TYPE_CPU;
dsa_port_set_tag_protocol(dp, dst->tag_ops);
Powered by blists - more mailing lists