summaryrefslogtreecommitdiffstats
path: root/net/switchdev/switchdev.c
diff options
context:
space:
mode:
authorPetr Machata <petrm@mellanox.com>2018-11-22 18:32:57 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-23 21:02:24 -0500
commitd17d9f5e5143125f9274194d8f7368f76b9d141f (patch)
treebf41261e370ea54e0f943ed0efd02b64729e6d9d /net/switchdev/switchdev.c
parent0e332c854f4118680b6d37b22551f2f16df806d6 (diff)
switchdev: Replace port obj add/del SDO with a notification
Drop switchdev_ops.switchdev_port_obj_add and _del. Drop the uses of this field from all clients, which were migrated to use switchdev notification in the previous patches. Add a new function switchdev_port_obj_notify() that sends the switchdev notifications SWITCHDEV_PORT_OBJ_ADD and _DEL. Update switchdev_port_obj_del_now() to dispatch to this new function. Drop __switchdev_port_obj_add() and update switchdev_port_obj_add() likewise. Signed-off-by: Petr Machata <petrm@mellanox.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r--net/switchdev/switchdev.c67
1 files changed, 25 insertions, 42 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 099434ec7996..fe23fac4dc4b 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -353,30 +353,29 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj)
353 return 0; 353 return 0;
354} 354}
355 355
356static int __switchdev_port_obj_add(struct net_device *dev, 356static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
357 const struct switchdev_obj *obj, 357 struct net_device *dev,
358 struct switchdev_trans *trans) 358 const struct switchdev_obj *obj,
359 struct switchdev_trans *trans)
359{ 360{
360 const struct switchdev_ops *ops = dev->switchdev_ops; 361 int rc;
361 struct net_device *lower_dev; 362 int err;
362 struct list_head *iter;
363 int err = -EOPNOTSUPP;
364
365 if (ops && ops->switchdev_port_obj_add)
366 return ops->switchdev_port_obj_add(dev, obj, trans);
367 363
368 /* Switch device port(s) may be stacked under 364 struct switchdev_notifier_port_obj_info obj_info = {
369 * bond/team/vlan dev, so recurse down to add object on 365 .obj = obj,
370 * each port. 366 .trans = trans,
371 */ 367 .handled = false,
368 };
372 369
373 netdev_for_each_lower_dev(dev, lower_dev, iter) { 370 rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info);
374 err = __switchdev_port_obj_add(lower_dev, obj, trans); 371 err = notifier_to_errno(rc);
375 if (err) 372 if (err) {
376 break; 373 WARN_ON(!obj_info.handled);
374 return err;
377 } 375 }
378 376 if (!obj_info.handled)
379 return err; 377 return -EOPNOTSUPP;
378 return 0;
380} 379}
381 380
382static int switchdev_port_obj_add_now(struct net_device *dev, 381static int switchdev_port_obj_add_now(struct net_device *dev,
@@ -397,7 +396,8 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
397 */ 396 */
398 397
399 trans.ph_prepare = true; 398 trans.ph_prepare = true;
400 err = __switchdev_port_obj_add(dev, obj, &trans); 399 err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
400 dev, obj, &trans);
401 if (err) { 401 if (err) {
402 /* Prepare phase failed: abort the transaction. Any 402 /* Prepare phase failed: abort the transaction. Any
403 * resources reserved in the prepare phase are 403 * resources reserved in the prepare phase are
@@ -416,7 +416,8 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
416 */ 416 */
417 417
418 trans.ph_prepare = false; 418 trans.ph_prepare = false;
419 err = __switchdev_port_obj_add(dev, obj, &trans); 419 err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
420 dev, obj, &trans);
420 WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); 421 WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
421 switchdev_trans_items_warn_destroy(dev, &trans); 422 switchdev_trans_items_warn_destroy(dev, &trans);
422 423
@@ -471,26 +472,8 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_add);
471static int switchdev_port_obj_del_now(struct net_device *dev, 472static int switchdev_port_obj_del_now(struct net_device *dev,
472 const struct switchdev_obj *obj) 473 const struct switchdev_obj *obj)
473{ 474{
474 const struct switchdev_ops *ops = dev->switchdev_ops; 475 return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL,
475 struct net_device *lower_dev; 476 dev, obj, NULL);
476 struct list_head *iter;
477 int err = -EOPNOTSUPP;
478
479 if (ops && ops->switchdev_port_obj_del)
480 return ops->switchdev_port_obj_del(dev, obj);
481
482 /* Switch device port(s) may be stacked under
483 * bond/team/vlan dev, so recurse down to delete object on
484 * each port.
485 */
486
487 netdev_for_each_lower_dev(dev, lower_dev, iter) {
488 err = switchdev_port_obj_del_now(lower_dev, obj);
489 if (err)
490 break;
491 }
492
493 return err;
494} 477}
495 478
496static void switchdev_port_obj_del_deferred(struct net_device *dev, 479static void switchdev_port_obj_del_deferred(struct net_device *dev,