On Sat, 2021-02-13 at 13:16 +0100, Greg Kroah-Hartman wrote: > On Sat, Feb 13, 2021 at 01:58:44PM +0200, Matti Vaittinen wrote: > > A few drivers which need a delayed work-queue must cancel work at > > exit. > > Some of those implement remove solely for this purpose. Help > > drivers > > to avoid unnecessary remove and error-branch implementation by > > adding > > managed verision of delayed work initialization > > > > Signed-off-by: Matti Vaittinen <matti.vaittinen@xxxxxxxxxxxxxxxxx> > > That's not a good idea. As this would kick in when the device is > removed from the system, not when it is unbound from the driver, > right? > > > --- > > drivers/base/devres.c | 33 +++++++++++++++++++++++++++++++++ > > include/linux/device.h | 5 +++++ > > 2 files changed, 38 insertions(+) > > > > diff --git a/drivers/base/devres.c b/drivers/base/devres.c > > index fb9d5289a620..2879595bb5a4 100644 > > --- a/drivers/base/devres.c > > +++ b/drivers/base/devres.c > > @@ -1231,3 +1231,36 @@ void devm_free_percpu(struct device *dev, > > void __percpu *pdata) > > (void *)pdata)); > > } > > EXPORT_SYMBOL_GPL(devm_free_percpu); > > + > > +static void dev_delayed_work_drop(struct device *dev, void *res) > > +{ > > + cancel_delayed_work_sync(*(struct delayed_work **)res); > > +} > > + > > +/** > > + * devm_delayed_work_autocancel - Resource-managed work allocation > > + * @dev: Device which lifetime work is bound to > > + * @pdata: work to be cancelled when device exits > > + * > > + * Initialize work which is automatically cancelled when device > > exits. > > There is no such thing in the driver model as "when device exits". > Please use the proper terminology as I do not understand what you > think > this is doing here... > > > + * A few drivers need delayed work which must be cancelled before > > driver > > + * is unload to avoid accessing removed resources. > > + * devm_delayed_work_autocancel() can be used to omit the explicit > > + * cancelleation when driver is unload. > > + */ > > +int devm_delayed_work_autocancel(struct device *dev, struct > > delayed_work *w, > > + void (*worker)(struct work_struct > > *work)) > > +{ > > + struct delayed_work **ptr; > > + > > + ptr = devres_alloc(dev_delayed_work_drop, sizeof(*ptr), > > GFP_KERNEL); > > + if (!ptr) > > + return -ENOMEM; > > + > > + INIT_DELAYED_WORK(w, worker); > > + *ptr = w; > > + devres_add(dev, ptr); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(devm_delayed_work_autocancel); > > diff --git a/include/linux/device.h b/include/linux/device.h > > index 1779f90eeb4c..192456198de7 100644 > > --- a/include/linux/device.h > > +++ b/include/linux/device.h > > @@ -27,6 +27,7 @@ > > #include <linux/uidgid.h> > > #include <linux/gfp.h> > > #include <linux/overflow.h> > > +#include <linux/workqueue.h> > > #include <linux/device/bus.h> > > #include <linux/device/class.h> > > #include <linux/device/driver.h> > > @@ -249,6 +250,10 @@ void __iomem *devm_of_iomap(struct device > > *dev, > > struct device_node *node, int index, > > resource_size_t *size); > > > > +/* delayed work which is cancelled when driver exits */ > > Not when the "driver exits". > > There is two different lifespans here (well 3). Code and > data*2. Don't > confuse them as that will just cause lots of problems. > > The move toward more and more "devm" functions is not the way to go > as > they just more and more make things easier to get wrong. > > APIs should be impossible to get wrong, this one is going to be > almost > impossible to get right. Thanks for prompt reply. I guess I must've misunderstood some of this concept. Frankly to say, I don't understand how the devm based irq management works and this does not. Maybe I'd better study this further then. Best Regards Matti Vaittinen