Message ID | 201108311807.53767.vladz@broadcom.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
On Wed, 31 Aug 2011 18:07:53 +0300 Vlad Zolotarov wrote: > If u want to change the implementation the way we rely on the > dev->features in the ndo_set_features() flow, which is a semantics > change, u'd rather change the __netdev_update_features() so that it > sets the dev->features before ndo_set_features() call and restores it > in case of a failure. Something like this: ... > diff --git a/net/core/dev.c b/net/core/dev.c > index b2e262e..474e539 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -5321,7 +5321,7 @@ static u32 netdev_fix_features(struct > net_device *dev, u32 features) > int __netdev_update_features(struct net_device *dev) > { > - u32 features; > + u32 features, old_features; > int err = 0; > > ASSERT_RTNL(); > @@ -5340,19 +5340,23 @@ int __netdev_update_features(struct > net_device *dev) netdev_dbg(dev, "Features changed: 0x%08x -> > 0x%08x\n", dev->features, features); > > + /* Remember the original features and set the new ones */ > + old_features = dev->features; > + dev->features = features; > + > if (dev->netdev_ops->ndo_set_features) > - err = dev->netdev_ops->ndo_set_features(dev, > features); > + err = dev->netdev_ops->ndo_set_features(dev); Drivers want to know which features changed. They compare the features argument with dev->features. Perhaps we could pass old_features as the argument. Then we'd better change the name of the callback to avoid confusion. I think it's not worth changing. I could restore dev->features before returning if bnx2x_reload_if_running() fails. Michal -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 31 Aug 2011 17:37:49 +0200 Michal Schmidt wrote: > I could restore dev->features before > returning if bnx2x_reload_if_running() fails. Or even safer - restore them always: ... u32 orig_features = dev->features; dev->features = features; ret = bnx2x_reload_if_running(dev); dev->features = orig_features; return ret; ... This way we don't have to assume anything about __netdev_update_features(). Michal -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wednesday 31 August 2011 18:51:20 Michal Schmidt wrote: > On Wed, 31 Aug 2011 17:37:49 +0200 Michal Schmidt wrote: > > I could restore dev->features before > > returning if bnx2x_reload_if_running() fails. > > Or even safer - restore them always: > ... > u32 orig_features = dev->features; > dev->features = features; > ret = bnx2x_reload_if_running(dev); > dev->features = orig_features; > return ret; > ... > This way we don't have to assume anything about > __netdev_update_features(). I agree - it's the best choice if we go for a bnx2x-only solution. thanks, vlad > > Michal > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
2011/8/31 Michal Schmidt <mschmidt@redhat.com>: > On Wed, 31 Aug 2011 17:37:49 +0200 Michal Schmidt wrote: >> I could restore dev->features before >> returning if bnx2x_reload_if_running() fails. > > Or even safer - restore them always: > ... > u32 orig_features = dev->features; > dev->features = features; > ret = bnx2x_reload_if_running(dev); > dev->features = orig_features; > return ret; > ... > This way we don't have to assume anything about > __netdev_update_features(). The assignment in __netdev_update_features() is just to save copying that assignment all over the drivers' code. This won't change unless someone wants to break^Wchange the design. Best Regards, Michał Mirosław -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0a7f619..a5f6d3e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -943,8 +943,7 @@ struct net_device_ops { struct net_device *slave_dev); u32 (*ndo_fix_features)(struct net_device *dev, u32 features); - int (*ndo_set_features)(struct net_device *dev, - u32 features); + int (*ndo_set_features)(struct net_device *dev); }; /* diff --git a/net/core/dev.c b/net/core/dev.c index b2e262e..474e539 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5321,7 +5321,7 @@ static u32 netdev_fix_features(struct net_device *dev, u32 features) int __netdev_update_features(struct net_device *dev) { - u32 features; + u32 features, old_features; int err = 0; ASSERT_RTNL(); @@ -5340,19 +5340,23 @@ int __netdev_update_features(struct net_device *dev) netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n", dev->features, features); + /* Remember the original features and set the new ones */ + old_features = dev->features; + dev->features = features; + if (dev->netdev_ops->ndo_set_features) - err = dev->netdev_ops->ndo_set_features(dev, features); + err = dev->netdev_ops->ndo_set_features(dev); if (unlikely(err < 0)) { + /* Restore the original features */ + dev->features = old_features; + netdev_err(dev, "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n", err, features, dev->features); return -1; } - if (!err) - dev->features = features; - return 1; }