On Tue, 5 May 2020 16:02:25 +0200 Bartosz Golaszewski wrote: > From: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx> > > Provide devm_register_netdev() - a device resource managed variant > of register_netdev(). This new helper will only work for net_device > structs that have a parent device assigned and are devres managed too. > > Signed-off-by: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx> > diff --git a/net/core/dev.c b/net/core/dev.c > index 522288177bbd..99db537c9468 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -9519,6 +9519,54 @@ int register_netdev(struct net_device *dev) > } > EXPORT_SYMBOL(register_netdev); > > +struct netdevice_devres { > + struct net_device *ndev; > +}; Is there really a need to define a structure if we only need a pointer? > +static void devm_netdev_release(struct device *dev, void *this) > +{ > + struct netdevice_devres *res = this; > + > + unregister_netdev(res->ndev); > +} > + > +/** > + * devm_register_netdev - resource managed variant of register_netdev() > + * @ndev: device to register > + * > + * This is a devres variant of register_netdev() for which the unregister > + * function will be call automatically when the parent device of ndev > + * is detached. > + */ > +int devm_register_netdev(struct net_device *ndev) > +{ > + struct netdevice_devres *dr; > + int ret; > + > + /* struct net_device itself must be devres managed. */ > + BUG_ON(!(ndev->priv_flags & IFF_IS_DEVRES)); > + /* struct net_device must have a parent device - it will be the device > + * managing this resource. > + */ > + BUG_ON(!ndev->dev.parent); Please convert those to WARN_ON, and return an error. No need to crash the kernel. > + dr = devres_alloc(devm_netdev_release, sizeof(*dr), GFP_KERNEL); > + if (!dr) > + return -ENOMEM; > + > + ret = register_netdev(ndev); > + if (ret) { > + devres_free(dr); > + return ret; > + } > + > + dr->ndev = ndev; > + devres_add(ndev->dev.parent, dr); > + > + return 0; > +} > +EXPORT_SYMBOL(devm_register_netdev);