summaryrefslogtreecommitdiffstats
path: root/net/switchdev
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2021-01-09 02:01:50 +0200
committerJakub Kicinski <kuba@kernel.org>2021-01-11 16:00:57 -0800
commitbae33f2b5afea932176c1b9096851c81dc0983de (patch)
treef640a0aad3ecdb3891e2221d9aff3f6b467f744e /net/switchdev
parentcf6def51badebbacaedd3999a4d94761197e18b4 (diff)
downloadlinux-stable-bae33f2b5afea932176c1b9096851c81dc0983de.tar.gz
linux-stable-bae33f2b5afea932176c1b9096851c81dc0983de.tar.bz2
linux-stable-bae33f2b5afea932176c1b9096851c81dc0983de.zip
net: switchdev: remove the transaction structure from port attributes
Since the introduction of the switchdev API, port attributes were transmitted to drivers for offloading using a two-step transactional model, with a prepare phase that was supposed to catch all errors, and a commit phase that was supposed to never fail. Some classes of failures can never be avoided, like hardware access, or memory allocation. In the latter case, merely attempting to move the memory allocation to the preparation phase makes it impossible to avoid memory leaks, since commit 91cf8eceffc1 ("switchdev: Remove unused transaction item queue") which has removed the unused mechanism of passing on the allocated memory between one phase and another. It is time we admit that separating the preparation from the commit phase is something that is best left for the driver to decide, and not something that should be baked into the API, especially since there are no switchdev callers that depend on this. This patch removes the struct switchdev_trans member from switchdev port attribute notifier structures, and converts drivers to not look at this member. In part, this patch contains a revert of my previous commit 2e554a7a5d8a ("net: dsa: propagate switchdev vlan_filtering prepare phase to drivers"). For the most part, the conversion was trivial except for: - Rocker's world implementation based on Broadcom OF-DPA had an odd implementation of ofdpa_port_attr_bridge_flags_set. The conversion was done mechanically, by pasting the implementation twice, then only keeping the code that would get executed during prepare phase on top, then only keeping the code that gets executed during the commit phase on bottom, then simplifying the resulting code until this was obtained. - DSA's offloading of STP state, bridge flags, VLAN filtering and multicast router could be converted right away. But the ageing time could not, so a shim was introduced and this was left for a further commit. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Kurt Kanzenbach <kurt@linutronix.de> # hellcreek Reviewed-by: Linus Walleij <linus.walleij@linaro.org> # RTL8366RB Reviewed-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/switchdev')
-rw-r--r--net/switchdev/switchdev.c46
1 files changed, 5 insertions, 41 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 3509d362056d..855a10feef3d 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -100,15 +100,13 @@ static int switchdev_deferred_enqueue(struct net_device *dev,
static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans)
+ const struct switchdev_attr *attr)
{
int err;
int rc;
struct switchdev_notifier_port_attr_info attr_info = {
.attr = attr,
- .trans = trans,
.handled = false,
};
@@ -129,34 +127,7 @@ static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
static int switchdev_port_attr_set_now(struct net_device *dev,
const struct switchdev_attr *attr)
{
- struct switchdev_trans trans;
- int err;
-
- /* Phase I: prepare for attr set. Driver/device should fail
- * here if there are going to be issues in the commit phase,
- * such as lack of resources or support. The driver/device
- * should reserve resources needed for the commit phase here,
- * but should not commit the attr.
- */
-
- trans.ph_prepare = true;
- err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr,
- &trans);
- if (err)
- return err;
-
- /* Phase II: commit attr set. This cannot fail as a fault
- * of driver/device. If it does, it's a bug in the driver/device
- * because the driver said everythings was OK in phase I.
- */
-
- trans.ph_prepare = false;
- err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr,
- &trans);
- WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
- dev->name, attr->id);
-
- return err;
+ return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr);
}
static void switchdev_port_attr_set_deferred(struct net_device *dev,
@@ -186,10 +157,6 @@ static int switchdev_port_attr_set_defer(struct net_device *dev,
* @dev: port device
* @attr: attribute to set
*
- * Use a 2-phase prepare-commit transaction model to ensure
- * system is not left in a partially updated state due to
- * failure from driver/device.
- *
* rtnl_lock must be held and must not be in atomic section,
* in case SWITCHDEV_F_DEFER flag is not set.
*/
@@ -519,8 +486,7 @@ static int __switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans))
+ const struct switchdev_attr *attr))
{
struct net_device *lower_dev;
struct list_head *iter;
@@ -528,8 +494,7 @@ static int __switchdev_handle_port_attr_set(struct net_device *dev,
if (check_cb(dev)) {
port_attr_info->handled = true;
- return set_cb(dev, port_attr_info->attr,
- port_attr_info->trans);
+ return set_cb(dev, port_attr_info->attr);
}
/* Switch ports might be stacked under e.g. a LAG. Ignore the
@@ -556,8 +521,7 @@ int switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans))
+ const struct switchdev_attr *attr))
{
int err;