[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220818154911.2973417-5-vladimir.oltean@nxp.com>
Date: Thu, 18 Aug 2022 18:49:05 +0300
From: Vladimir Oltean <vladimir.oltean@....com>
To: netdev@...r.kernel.org
Cc: Andrew Lunn <andrew@...n.ch>,
Vivien Didelot <vivien.didelot@...il.com>,
Florian Fainelli <f.fainelli@...il.com>,
Vladimir Oltean <olteanv@...il.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
"Rafael J. Wysocki" <rafael@...nel.org>,
Kevin Hilman <khilman@...nel.org>,
Ulf Hansson <ulf.hansson@...aro.org>,
Len Brown <len.brown@...el.com>, Pavel Machek <pavel@....cz>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: [RFC PATCH net-next 04/10] net: dsa: introduce and use robust form of dsa_port_notify()
Introduce dsa_port_notify_robust(), which uses dsa_tree_notify_robust(),
and convert as many call paths to use it. Some notable exceptions are
DSA_NOTIFIER_LAG_CHANGE, for which it isn't clear how to restore the
state (or why this is allowed to return an error for that matter), and
DSA_NOTIFIER_MTU (which we'll convert separately to the robust form).
Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
net/dsa/port.c | 51 +++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 40 insertions(+), 11 deletions(-)
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 6aa6402d3ed9..2fec3df65643 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -30,6 +30,24 @@ static int dsa_port_notify(const struct dsa_port *dp, unsigned long e, void *v)
return dsa_tree_notify(dp->ds->dst, e, v);
}
+/**
+ * dsa_port_notify_robust - Notify fabric of changes to port, with rollback
+ * @dp: port on which change occurred
+ * @e: event, must be of type DSA_NOTIFIER_*
+ * @v: event-specific value.
+ * @e_rollback: event, must be of type DSA_NOTIFIER_*
+ * @v_rollback: event-specific value.
+ *
+ * Like dsa_port_notify(), except makes sure that switches are restored to the
+ * previous state in case the notifier call chain fails mid way.
+ */
+static int dsa_port_notify_robust(const struct dsa_port *dp, unsigned long e,
+ void *v, unsigned long e_rollback,
+ void *v_rollback)
+{
+ return dsa_tree_notify_robust(dp->ds->dst, e, v, e_rollback, v_rollback);
+}
+
static void dsa_port_notify_bridge_fdb_flush(const struct dsa_port *dp, u16 vid)
{
struct net_device *brport_dev = dsa_port_to_bridge_port(dp);
@@ -641,7 +659,8 @@ int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag_dev,
goto err_lag_create;
info.lag = *dp->lag;
- err = dsa_port_notify(dp, DSA_NOTIFIER_LAG_JOIN, &info);
+ err = dsa_port_notify_robust(dp, DSA_NOTIFIER_LAG_JOIN, &info,
+ DSA_NOTIFIER_LAG_LEAVE, &info);
if (err)
goto err_lag_join;
@@ -854,12 +873,14 @@ int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock)
{
unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock);
unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
- struct dsa_notifier_ageing_time_info info;
+ struct dsa_notifier_ageing_time_info info, old_info;
int err;
info.ageing_time = ageing_time;
+ old_info.ageing_time = dp->ageing_time;
- err = dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
+ err = dsa_port_notify_robust(dp, DSA_NOTIFIER_AGEING_TIME, &info,
+ DSA_NOTIFIER_AGEING_TIME, &old_info);
if (err)
return err;
@@ -971,7 +992,8 @@ int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
if (!dp->ds->fdb_isolation)
info.db.bridge.num = 0;
- return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
+ return dsa_port_notify_robust(dp, DSA_NOTIFIER_FDB_ADD, &info,
+ DSA_NOTIFIER_FDB_DEL, &info);
}
int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
@@ -1007,7 +1029,8 @@ static int dsa_port_host_fdb_add(struct dsa_port *dp,
if (!dp->ds->fdb_isolation)
info.db.bridge.num = 0;
- return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info);
+ return dsa_port_notify_robust(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info,
+ DSA_NOTIFIER_HOST_FDB_DEL, &info);
}
int dsa_port_standalone_host_fdb_add(struct dsa_port *dp,
@@ -1107,7 +1130,8 @@ int dsa_port_lag_fdb_add(struct dsa_port *dp, const unsigned char *addr,
if (!dp->ds->fdb_isolation)
info.db.bridge.num = 0;
- return dsa_port_notify(dp, DSA_NOTIFIER_LAG_FDB_ADD, &info);
+ return dsa_port_notify_robust(dp, DSA_NOTIFIER_LAG_FDB_ADD, &info,
+ DSA_NOTIFIER_LAG_FDB_DEL, &info);
}
int dsa_port_lag_fdb_del(struct dsa_port *dp, const unsigned char *addr,
@@ -1155,7 +1179,8 @@ int dsa_port_mdb_add(const struct dsa_port *dp,
if (!dp->ds->fdb_isolation)
info.db.bridge.num = 0;
- return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
+ return dsa_port_notify_robust(dp, DSA_NOTIFIER_MDB_ADD, &info,
+ DSA_NOTIFIER_MDB_DEL, &info);
}
int dsa_port_mdb_del(const struct dsa_port *dp,
@@ -1189,7 +1214,8 @@ static int dsa_port_host_mdb_add(const struct dsa_port *dp,
if (!dp->ds->fdb_isolation)
info.db.bridge.num = 0;
- return dsa_port_notify(dp, DSA_NOTIFIER_HOST_MDB_ADD, &info);
+ return dsa_port_notify_robust(dp, DSA_NOTIFIER_HOST_MDB_ADD, &info,
+ DSA_NOTIFIER_HOST_MDB_DEL, &info);
}
int dsa_port_standalone_host_mdb_add(const struct dsa_port *dp,
@@ -1274,7 +1300,8 @@ int dsa_port_vlan_add(struct dsa_port *dp,
.extack = extack,
};
- return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
+ return dsa_port_notify_robust(dp, DSA_NOTIFIER_VLAN_ADD, &info,
+ DSA_NOTIFIER_VLAN_DEL, &info);
}
int dsa_port_vlan_del(struct dsa_port *dp,
@@ -1300,7 +1327,8 @@ int dsa_port_host_vlan_add(struct dsa_port *dp,
struct dsa_port *cpu_dp = dp->cpu_dp;
int err;
- err = dsa_port_notify(dp, DSA_NOTIFIER_HOST_VLAN_ADD, &info);
+ err = dsa_port_notify_robust(dp, DSA_NOTIFIER_HOST_VLAN_ADD, &info,
+ DSA_NOTIFIER_HOST_VLAN_DEL, &info);
if (err && err != -EOPNOTSUPP)
return err;
@@ -1742,7 +1770,8 @@ int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast)
return dsa_broadcast_robust(DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info,
DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info);
- return dsa_port_notify(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info);
+ return dsa_port_notify_robust(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info,
+ DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info);
}
void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast)
--
2.34.1
Powered by blists - more mailing lists