Previously, a start could be lost if multiple cpus get onlined before the workqueue has a chance to run.
Signed-off-by: Crystal Wood <[email protected]> --- v5: new patch I have this in my notes as being a Sashiko comment, though I can't find the source now. I wasn't able to reproduce the race given how slow and serialized cpu hotplug operations are, but it's possible. On the other hand, user threads detach on cpu offline with no mechanism for reattaching (other than userspace figuring it out and reopening the fd), and you really probably shouldn't be offlining cpus that you're measuring with tools like this, so you could make an argument for removing the restart mechanism entirely... it'd certainly shrink the potential bug surface. This also eliminates the need for the "Always check OSN_WORKLOAD" patch. v6: Removed the OSN_WORKLOAD check from this function, and revived the "Always check OSN_WORKLOAD", so that start_kthread() can set osn->sampling in the NO_OSN_WORKLOAD osnoise case --- kernel/trace/trace_osnoise.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index a6f7fbb342b6..ff7277052af2 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -2123,7 +2123,7 @@ static int start_per_cpu_kthreads(void) #ifdef CONFIG_HOTPLUG_CPU static void osnoise_hotplug_workfn(struct work_struct *dummy) { - unsigned int cpu = smp_processor_id(); + unsigned int cpu; guard(mutex)(&trace_types_lock); @@ -2133,13 +2133,10 @@ static void osnoise_hotplug_workfn(struct work_struct *dummy) guard(cpus_read_lock)(); guard(mutex)(&interface_lock); - if (!cpu_online(cpu)) - return; - - if (!cpumask_test_cpu(cpu, &osnoise_cpumask)) - return; - - start_kthread(cpu); + for_each_online_cpu(cpu) { + if (cpumask_test_cpu(cpu, &osnoise_cpumask)) + start_kthread(cpu); + } } static DECLARE_WORK(osnoise_hotplug_work, osnoise_hotplug_workfn); @@ -2149,7 +2146,7 @@ static DECLARE_WORK(osnoise_hotplug_work, osnoise_hotplug_workfn); */ static int osnoise_cpu_init(unsigned int cpu) { - schedule_work_on(cpu, &osnoise_hotplug_work); + schedule_work(&osnoise_hotplug_work); return 0; } -- 2.54.0
