diff options
author | Jakub Kicinski <kuba@kernel.org> | 2021-01-11 16:01:00 -0800 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2021-01-11 16:01:00 -0800 |
commit | d1c8b6a3dd772f72204c341e0594c22f4ea9e69b (patch) | |
tree | fd7cbb69cd117a7a9ef46f9f79d5611f44971bf8 /net/switchdev/switchdev.c | |
parent | beb401ec50067bfef39e74f0cf80be3de3313e7d (diff) | |
parent | 8f73cc50ba2dd5a5749d3670e453c3864258b892 (diff) |
Merge branch 'get-rid-of-the-switchdev-transactional-model'
Vladimir Oltean says:
====================
Get rid of the switchdev transactional model
Changes in v4:
- Fixed build error in dsa_loop and build warning in hellcreek driver.
- Scheduling the mlxsw SPAN work item regardless of the VLAN add return
code, as per Ido's and Petr's request.
Changes in v3:
- Resolved a build warning in mv88e6xxx and tested that it actually
works properly, which resulted in an extra patch (02/11).
- Addressed Ido's minor feedback in commit 10/11 relating to a comment.
Changes in v2:
- Got rid of the vid_begin -> vid_end range too from the switchdev API.
- Actually propagating errors from DSA MDB and VLAN notifiers.
This series comes after the late realization that the prepare/commit
separation imposed by switchdev does not help literally anybody:
https://patchwork.kernel.org/project/netdevbpf/patch/20201212203901.351331-1-vladimir.oltean@nxp.com/
We should kill it before it inflicts even more damage to the error
handling logic in drivers.
Also remove the unused VLAN ranges feature from the switchdev VLAN
objects, which simplifies all drivers by quite a bit.
====================
Link: https://lore.kernel.org/r/20210109000156.1246735-1-olteanv@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r-- | net/switchdev/switchdev.c | 101 |
1 files changed, 12 insertions, 89 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 23d868545362..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. */ @@ -221,7 +188,6 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj) static int switchdev_port_obj_notify(enum switchdev_notifier_type nt, struct net_device *dev, const struct switchdev_obj *obj, - struct switchdev_trans *trans, struct netlink_ext_ack *extack) { int rc; @@ -229,7 +195,6 @@ static int switchdev_port_obj_notify(enum switchdev_notifier_type nt, struct switchdev_notifier_port_obj_info obj_info = { .obj = obj, - .trans = trans, .handled = false, }; @@ -244,48 +209,15 @@ static int switchdev_port_obj_notify(enum switchdev_notifier_type nt, return 0; } -static int switchdev_port_obj_add_now(struct net_device *dev, - const struct switchdev_obj *obj, - struct netlink_ext_ack *extack) -{ - struct switchdev_trans trans; - int err; - - ASSERT_RTNL(); - - /* Phase I: prepare for obj add. 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 obj. - */ - - trans.ph_prepare = true; - err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD, - dev, obj, &trans, extack); - if (err) - return err; - - /* Phase II: commit obj add. 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_obj_notify(SWITCHDEV_PORT_OBJ_ADD, - dev, obj, &trans, extack); - WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); - - return err; -} - static void switchdev_port_obj_add_deferred(struct net_device *dev, const void *data) { const struct switchdev_obj *obj = data; int err; - err = switchdev_port_obj_add_now(dev, obj, NULL); + ASSERT_RTNL(); + err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD, + dev, obj, NULL); if (err && err != -EOPNOTSUPP) netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", err, obj->id); @@ -307,10 +239,6 @@ static int switchdev_port_obj_add_defer(struct net_device *dev, * @obj: object to add * @extack: netlink extended ack * - * 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. */ @@ -321,7 +249,8 @@ int switchdev_port_obj_add(struct net_device *dev, if (obj->flags & SWITCHDEV_F_DEFER) return switchdev_port_obj_add_defer(dev, obj); ASSERT_RTNL(); - return switchdev_port_obj_add_now(dev, obj, extack); + return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD, + dev, obj, extack); } EXPORT_SYMBOL_GPL(switchdev_port_obj_add); @@ -329,7 +258,7 @@ static int switchdev_port_obj_del_now(struct net_device *dev, const struct switchdev_obj *obj) { return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL, - dev, obj, NULL, NULL); + dev, obj, NULL); } static void switchdev_port_obj_del_deferred(struct net_device *dev, @@ -449,7 +378,6 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev, bool (*check_cb)(const struct net_device *dev), int (*add_cb)(struct net_device *dev, const struct switchdev_obj *obj, - struct switchdev_trans *trans, struct netlink_ext_ack *extack)) { struct netlink_ext_ack *extack; @@ -462,8 +390,7 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev, if (check_cb(dev)) { /* This flag is only checked if the return value is success. */ port_obj_info->handled = true; - return add_cb(dev, port_obj_info->obj, port_obj_info->trans, - extack); + return add_cb(dev, port_obj_info->obj, extack); } /* Switch ports might be stacked under e.g. a LAG. Ignore the @@ -491,7 +418,6 @@ int switchdev_handle_port_obj_add(struct net_device *dev, bool (*check_cb)(const struct net_device *dev), int (*add_cb)(struct net_device *dev, const struct switchdev_obj *obj, - struct switchdev_trans *trans, struct netlink_ext_ack *extack)) { int err; @@ -560,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; @@ -569,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 @@ -597,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; |