Re: [PATCH 4/4] kthread: Simplify kthread_park() completion
From: Oleg Nesterov
Date: Fri Jun 08 2018 - 05:52:29 EST
Peter,
I am travelling till the end of the next week, unlikely I will be able
to reply to emails or even read them.
But I want very much to comment this change,
On 06/07, Peter Zijlstra wrote:
>
> Now that smpboot_update_cpumask_percpu_thread() is gone, we no longer
> have anybody calling kthread_park() on already parked threads. So
> revert commit:
>
> b1f5b378e126 ("kthread: Allow kthread_park() on a parked kthread")
Great, I obviously like this patch but the changelog should be fixed ;)
smpboot_update_cpumask_percpu_thread() was actually fine. And we can
(should) revert this commit in any case. Unless I am totally confused.
So how this code
for_each_cpu_and(cpu, &tmp, cpu_online_mask)
smpboot_park_thread(plug_thread, cpu);
in smpboot_update_cpumask_percpu_thread() can hit a KTHREAD_SHOULD_PARK
thread? Lets look into kernel test robot's .config:
CONFIG_NR_CPUS=1
Now look at NR_CPUS==1 version of for_each_cpu* helpers:
#define for_each_cpu(cpu, mask) \
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
#define for_each_cpu_not(cpu, mask) \
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
#define for_each_cpu_wrap(cpu, mask, start) \
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)(start))
#define for_each_cpu_and(cpu, mask, and) \
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)and)
See? They all ignore the "mask" argument, and this is obviously wrong.
So even if the "tmp" cpumask is empty the code above always does
smpboot_park_thread(plug_thread, 0);
and hits the already parked kthread.
Oleg.