Messages in this thread | | | Subject | Re: [patch 02/13] workqueue: Provide work_on_cpu_safe() | From | Dou Liyang <> | Date | Thu, 13 Apr 2017 19:11:32 +0800 |
| |
At 04/13/2017 04:07 AM, Thomas Gleixner wrote: > work_on_cpu() is not protected against CPU hotplug. For code which requires > to be either executed on an online CPU or to fail if the CPU is not > available the callsite would have to protect against CPU hotplug. > > Provide a function which does get/put_online_cpus() around the call to > work_on_cpu() and fails the call with -ENODEV if the target CPU is not > online. > > Preparatory patch to convert several racy task affinity manipulations. > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > Cc: Tejun Heo <tj@kernel.org> > Cc: Lai Jiangshan <jiangshanlai@gmail.com> > --- > include/linux/workqueue.h | 5 +++++ > kernel/workqueue.c | 23 +++++++++++++++++++++++ > 2 files changed, 28 insertions(+) > > --- a/include/linux/workqueue.h > +++ b/include/linux/workqueue.h > @@ -608,8 +608,13 @@ static inline long work_on_cpu(int cpu, > { > return fn(arg); > } > +static inline long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) > +{ > + return fn(arg); > +} > #else > long work_on_cpu(int cpu, long (*fn)(void *), void *arg); > +long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg); > #endif /* CONFIG_SMP */ > > #ifdef CONFIG_FREEZER > --- a/kernel/workqueue.c > +++ b/kernel/workqueue.c > @@ -4735,6 +4735,29 @@ long work_on_cpu(int cpu, long (*fn)(voi > return wfc.ret; > } > EXPORT_SYMBOL_GPL(work_on_cpu); > + > +/**
There is an extra '*' :)
Thanks, Liyang
> + * work_on_cpu_safe - run a function in thread context on a particular cpu > + * @cpu: the cpu to run on > + * @fn: the function to run > + * @arg: the function argument > + * > + * Disables CPU hotplug and calls work_on_cpu(). The caller must not hold > + * any locks which would prevent @fn from completing. > + * > + * Return: The value @fn returns. > + */ > +long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) > +{ > + long ret = -ENODEV; > + > + get_online_cpus(); > + if (cpu_online(cpu)) > + ret = work_on_cpu(cpu, fn, arg); > + put_online_cpus(); > + return ret; > +} > +EXPORT_SYMBOL_GPL(work_on_cpu_safe); > #endif /* CONFIG_SMP */ > > #ifdef CONFIG_FREEZER
| |