tracing/osnoise: Add OSNOISE_WORKLOAD option
authorDaniel Bristot de Oliveira <bristot@kernel.org>
Thu, 17 Nov 2022 13:46:19 +0000 (14:46 +0100)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Thu, 24 Nov 2022 00:08:31 +0000 (19:08 -0500)
The osnoise tracer is not only a tracer, and a set of tracepoints,
but also a workload dispatcher.

In preparation for having other workloads, e.g., in user-space,
add an option to avoid dispatching the workload.

By not dispatching the workload, the osnoise: tracepoints become
generic events to measure the execution time of *any* task on Linux.

For example:

  # cd /sys/kernel/tracing/
  # cat osnoise/options
  DEFAULTS OSNOISE_WORKLOAD
  # echo NO_OSNOISE_WORKLOAD > osnoise/options
  # cat osnoise/options
  NO_DEFAULTS NO_OSNOISE_WORKLOAD
  # echo osnoise > set_event
  # echo osnoise > current_tracer
  # tail -8 trace
      make-94722   [002] d..3.  1371.794507: thread_noise:     make:94722 start 1371.794302286 duration 200897 ns
        sh-121042  [020] d..3.  1371.794534: thread_noise:       sh:121042 start 1371.781610976 duration 8943683 ns
      make-121097  [005] d..3.  1371.794542: thread_noise:     make:121097 start 1371.794481522 duration 60444 ns
     <...>-40      [005] d..3.  1371.794550: thread_noise: migration/5:40 start 1371.794542256 duration 7154 ns
    <idle>-0       [018] dNh2.  1371.794554: irq_noise: reschedule:253 start 1371.794553547 duration 40 ns
    <idle>-0       [018] dNh2.  1371.794561: irq_noise: local_timer:236 start 1371.794556222 duration 4890 ns
    <idle>-0       [018] .Ns2.  1371.794563: softirq_noise:    SCHED:7 start 1371.794561803 duration 992 ns
    <idle>-0       [018] d..3.  1371.794566: thread_noise: swapper/18:0 start 1371.781368110 duration 13191798 ns

In preparation for the rtla exec_time tracer/tool and
rtla osnoise --user option.

Link: https://lkml.kernel.org/r/f5cfbd37aefd419eefe9243b4d2fc38ed5753fe4.1668692096.git.bristot@kernel.org
Cc: Daniel Bristot de Oliveira <bristot@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Daniel Bristot de Oliveira <bristot@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
kernel/trace/trace_osnoise.c

index 17b77fe3950b8acae7ed3ae216d5d74114fcc09e..3f10dd1f2f1ceda6b7ac408cb4c779eda731efa7 100644 (file)
  */
 enum osnoise_options_index {
        OSN_DEFAULTS = 0,
+       OSN_WORKLOAD,
        OSN_MAX
 };
 
-static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS" };
+static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS", "OSNOISE_WORKLOAD" };
 
-#define OSN_DEFAULT_OPTIONS    0
+#define OSN_DEFAULT_OPTIONS    0x2
 unsigned long osnoise_options  = OSN_DEFAULT_OPTIONS;
 
 /*
@@ -1186,11 +1187,12 @@ trace_sched_switch_callback(void *data, bool preempt,
                            unsigned int prev_state)
 {
        struct osnoise_variables *osn_var = this_cpu_osn_var();
+       int workload = test_bit(OSN_WORKLOAD, &osnoise_options);
 
-       if (p->pid != osn_var->pid)
+       if ((p->pid != osn_var->pid) || !workload)
                thread_exit(osn_var, p);
 
-       if (n->pid != osn_var->pid)
+       if ((n->pid != osn_var->pid) || !workload)
                thread_entry(osn_var, n);
 }
 
@@ -1723,9 +1725,16 @@ static void stop_kthread(unsigned int cpu)
        struct task_struct *kthread;
 
        kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread;
-       if (kthread)
+       if (kthread) {
                kthread_stop(kthread);
-       per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL;
+               per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL;
+       } else {
+               if (!test_bit(OSN_WORKLOAD, &osnoise_options)) {
+                       per_cpu(per_cpu_osnoise_var, cpu).sampling = false;
+                       barrier();
+                       return;
+               }
+       }
 }
 
 /*
@@ -1759,6 +1768,13 @@ static int start_kthread(unsigned int cpu)
                snprintf(comm, 24, "timerlat/%d", cpu);
                main = timerlat_main;
        } else {
+               /* if no workload, just return */
+               if (!test_bit(OSN_WORKLOAD, &osnoise_options)) {
+                       per_cpu(per_cpu_osnoise_var, cpu).sampling = true;
+                       barrier();
+                       return 0;
+               }
+
                snprintf(comm, 24, "osnoise/%d", cpu);
        }