• Daniel Bristot de Oliveira's avatar
    trace: Add timerlat tracer · a955d7ea
    Daniel Bristot de Oliveira authored
    The timerlat tracer aims to help the preemptive kernel developers to
    found souces of wakeup latencies of real-time threads. Like cyclictest,
    the tracer sets a periodic timer that wakes up a thread. The thread then
    computes a *wakeup latency* value as the difference between the *current
    time* and the *absolute time* that the timer was set to expire. The main
    goal of timerlat is tracing in such a way to help kernel developers.
    
    Usage
    
    Write the ASCII text "timerlat" into the current_tracer file of the
    tracing system (generally mounted at /sys/kernel/tracing).
    
    For example:
    
            [root@f32 ~]# cd /sys/kernel/tracing/
            [root@f32 tracing]# echo timerlat > current_tracer
    
    It is possible to follow the trace by reading the trace trace file:
    
      [root@f32 tracing]# cat trace
      # tracer: timerlat
      #
      #                              _-----=> irqs-off
      #                             / _----=> need-resched
      #                            | / _---=> hardirq/softirq
      #                            || / _--=> preempt-depth
      #                            || /
      #                            ||||             ACTIVATION
      #         TASK-PID      CPU# ||||   TIMESTAMP    ID            CONTEXT                LATENCY
      #            | |         |   ||||      |         |                  |                       |
              <idle>-0       [000] d.h1    54.029328: #1     context    irq timer_latency       932 ns
               <...>-867     [000] ....    54.029339: #1     context thread timer_latency     11700 ns
              <idle>-0       [001] dNh1    54.029346: #1     context    irq timer_latency      2833 ns
               <...>-868     [001] ....    54.029353: #1     context thread timer_latency      9820 ns
              <idle>-0       [000] d.h1    54.030328: #2     context    irq timer_latency       769 ns
               <...>-867     [000] ....    54.030330: #2     context thread timer_latency      3070 ns
              <idle>-0       [001] d.h1    54.030344: #2     context    irq timer_latency       935 ns
               <...>-868     [001] ....    54.030347: #2     context thread timer_latency      4351 ns
    
    The tracer creates a per-cpu kernel thread with real-time priority that
    prints two lines at every activation. The first is the *timer latency*
    observed at the *hardirq* context before the activation of the thread.
    The second is the *timer latency* observed by the thread, which is the
    same level that cyclictest reports. The ACTIVATION ID field
    serves to relate the *irq* execution to its respective *thread* execution.
    
    The irq/thread splitting is important to clarify at which context
    the unexpected high value is coming from. The *irq* context can be
    delayed by hardware related actions, such as SMIs, NMIs, IRQs
    or by a thread masking interrupts. Once the timer happens, the delay
    can also be influenced by blocking caused by threads. For example, by
    postponing the scheduler execution via preempt_disable(),  by the
    scheduler execution, or by masking interrupts. Threads can
    also be delayed by the interference from other threads and IRQs.
    
    The timerlat can also take advantage of the osnoise: traceevents.
    For example:
    
            [root@f32 ~]# cd /sys/kernel/tracing/
            [root@f32 tracing]# echo timerlat > current_tracer
            [root@f32 tracing]# echo osnoise > set_event
            [root@f32 tracing]# echo 25 > osnoise/stop_tracing_total_us
            [root@f32 tracing]# tail -10 trace
                 cc1-87882   [005] d..h...   548.771078: #402268 context    irq timer_latency      1585 ns
                 cc1-87882   [005] dNLh1..   548.771082: irq_noise: local_timer:236 start 548.771077442 duration 4597 ns
                 cc1-87882   [005] dNLh2..   548.771083: irq_noise: reschedule:253 start 548.771083017 duration 56 ns
                 cc1-87882   [005] dNLh2..   548.771086: irq_noise: call_function_single:251 start 548.771083811 duration 2048 ns
                 cc1-87882   [005] dNLh2..   548.771088: irq_noise: call_function_single:251 start 548.771086814 duration 1495 ns
                 cc1-87882   [005] dNLh2..   548.771091: irq_noise: call_function_single:251 start 548.771089194 duration 1558 ns
                 cc1-87882   [005] dNLh2..   548.771094: irq_noise: call_function_single:251 start 548.771091719 duration 1932 ns
                 cc1-87882   [005] dNLh2..   548.771096: irq_noise: call_function_single:251 start 548.771094696 duration 1050 ns
                 cc1-87882   [005] d...3..   548.771101: thread_noise:      cc1:87882 start 548.771078243 duration 10909 ns
          timerlat/5-1035    [005] .......   548.771103: #402268 context thread timer_latency     25960 ns
    
    For further information see: Documentation/trace/timerlat-tracer.rst
    
    Link: https://lkml.kernel.org/r/71f18efc013e1194bcaea1e54db957de2b19ba62.1624372313.git.bristot@redhat.com
    
    Cc: Phil Auld <pauld@redhat.com>
    Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Cc: Kate Carcia <kcarcia@redhat.com>
    Cc: Jonathan Corbet <corbet@lwn.net>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Alexandre Chartre <alexandre.chartre@oracle.com>
    Cc: Clark Willaims <williams@redhat.com>
    Cc: John Kacur <jkacur@redhat.com>
    Cc: Juri Lelli <juri.lelli@redhat.com>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: x86@kernel.org
    Cc: linux-doc@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: default avatarDaniel Bristot de Oliveira <bristot@redhat.com>
    Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
    a955d7ea
trace_output.c 35.2 KB