Avoid a preemptible-context splat if we get migrated (e.g. from hotplug
activity) before reaching this_cpu_osn_var(), and verify that we're
on the correct CPU after migrate_disable().

Signed-off-by: Crystal Wood <[email protected]>
---
 kernel/trace/trace_osnoise.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
index e2e1ef3f5a61..a53a07e59197 100644
--- a/kernel/trace/trace_osnoise.c
+++ b/kernel/trace/trace_osnoise.c
@@ -236,6 +236,7 @@ struct osnoise_variables {
        struct mutex            lock; /* covers kthread and fdd changes */
        struct task_struct      *kthread;
        struct fd_data          *fdd;
+       int                     cpu;
 
        struct_group(zero,
                bool                    sampling;
@@ -1912,8 +1913,8 @@ static int wait_next_period(struct timerlat_variables 
*tlat)
  */
 static int timerlat_main(void *data)
 {
-       struct osnoise_variables *osn_var = this_cpu_osn_var();
-       struct timerlat_variables *tlat = this_cpu_tmr_var();
+       struct osnoise_variables *osn_var = data;
+       struct timerlat_variables *tlat;
        struct timerlat_sample s;
        struct sched_param sp;
        unsigned long flags;
@@ -1933,6 +1934,13 @@ static int timerlat_main(void *data)
         * flag.
         */
        migrate_disable();
+       if (osn_var->cpu != smp_processor_id()) {
+               migrate_enable();
+               return 1;
+       }
+
+       tlat = this_cpu_tmr_var();
+
        raw_spin_lock_irqsave(&current->pi_lock, flags);
        current->flags &= ~(PF_NO_SETAFFINITY);
        raw_spin_unlock_irqrestore(&current->pi_lock, flags);
@@ -2061,7 +2069,7 @@ static int start_kthread(unsigned int cpu)
                snprintf(comm, 24, "osnoise/%d", cpu);
        }
 
-       kthread = kthread_run_on_cpu(main, NULL, cpu, comm);
+       kthread = kthread_run_on_cpu(main, cpu_osn_var(cpu), cpu, comm);
 
        if (IS_ERR(kthread)) {
                pr_err(BANNER "could not start sampling thread\n");
@@ -3207,8 +3215,12 @@ __init static int init_osnoise_tracer(void)
 
        mutex_init(&interface_lock);
 
-       for_each_online_cpu(cpu)
-               mutex_init(&cpu_osn_var(cpu)->lock);
+       for_each_online_cpu(cpu) {
+               struct osnoise_variables *osn = cpu_osn_var(cpu);
+
+               mutex_init(&osn->lock);
+               osn->cpu = cpu;
+       }
 
        cpumask_copy(&osnoise_cpumask, cpu_all_mask);
 
-- 
2.54.0


Reply via email to