On Thu, Jan 07, 2021 at 12:38:35PM +0200, Ido Schimmel wrote: > +Petr > > On Thu, Jan 07, 2021 at 01:17:20AM +0200, Vladimir Oltean wrote: > > static int mlxsw_sp_port_obj_add(struct net_device *dev, > > const struct switchdev_obj *obj, > > - struct switchdev_trans *trans, > > struct netlink_ext_ack *extack) > > { > > struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); > > const struct switchdev_obj_port_vlan *vlan; > > + struct switchdev_trans trans; > > int err = 0; > > > > switch (obj->id) { > > case SWITCHDEV_OBJ_ID_PORT_VLAN: > > vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); > > - err = mlxsw_sp_port_vlans_add(mlxsw_sp_port, vlan, trans, > > + > > Got the regression results. The call to mlxsw_sp_span_respin() should be > placed here because it needs to be triggered regardless of the return > value of mlxsw_sp_port_vlans_add().
So before, mlxsw_sp_span_respin() was called right in between the prepare phase and the commit phase, regardless of the error value of mlxsw_sp_port_vlans_add. How does that work, I assume that mlxsw_sp_span_respin_work gets to run after the commit phase because it serializes using rtnl_lock()? Then why did it matter enough to schedule it between the prepare and commit phase in the first place? And what is there to do in mlxsw_sp_span_respin_work when mlxsw_sp_port_vlans_add returns -EOPNOTSUPP, -EBUSY, -EINVAL, -EEXIST or -ENOMEM?