Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/Documentation/trace/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 140 kB image not shown  

Quelle  ftrace.rst   Sprache: unbekannt

 
Spracherkennung für: .rst vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

========================
ftrace - Function Tracer
========================

Copyright 2008 Red Hat Inc.

:Author:   Steven Rostedt <srostedt@redhat.com>
:License:  The GNU Free Documentation License, Version 1.2
          (dual licensed under the GPL v2)
:Original Reviewers:  Elias Oltmanns, Randy Dunlap, Andrew Morton,
        John Kacur, and David Teigland.

- Written for: 2.6.28-rc2
- Updated for: 3.10
- Updated for: 4.13 - Copyright 2017 VMware Inc. Steven Rostedt
- Converted to rst format - Changbin Du <changbin.du@intel.com>

Introduction
------------

Ftrace is an internal tracer designed to help out developers and
designers of systems to find what is going on inside the kernel.
It can be used for debugging or analyzing latencies and
performance issues that take place outside of user-space.

Although ftrace is typically considered the function tracer, it
is really a framework of several assorted tracing utilities.
There's latency tracing to examine what occurs between interrupts
disabled and enabled, as well as for preemption and from a time
a task is woken to the task is actually scheduled in.

One of the most common uses of ftrace is the event tracing.
Throughout the kernel is hundreds of static event points that
can be enabled via the tracefs file system to see what is
going on in certain parts of the kernel.

See events.rst for more information.


Implementation Details
----------------------

See Documentation/trace/ftrace-design.rst for details for arch porters and such.


The File System
---------------

Ftrace uses the tracefs file system to hold the control files as
well as the files to display output.

When tracefs is configured into the kernel (which selecting any ftrace
option will do) the directory /sys/kernel/tracing will be created. To mount
this directory, you can add to your /etc/fstab file::

 tracefs       /sys/kernel/tracing       tracefs defaults        0       0

Or you can mount it at run time with::

 mount -t tracefs nodev /sys/kernel/tracing

For quicker access to that directory you may want to make a soft link to
it::

 ln -s /sys/kernel/tracing /tracing

.. attention::

  Before 4.1, all ftrace tracing control files were within the debugfs
  file system, which is typically located at /sys/kernel/debug/tracing.
  For backward compatibility, when mounting the debugfs file system,
  the tracefs file system will be automatically mounted at:

  /sys/kernel/debug/tracing

  All files located in the tracefs file system will be located in that
  debugfs file system directory as well.

.. attention::

  Any selected ftrace option will also create the tracefs file system.
  The rest of the document will assume that you are in the ftrace directory
  (cd /sys/kernel/tracing) and will only concentrate on the files within that
  directory and not distract from the content with the extended
  "/sys/kernel/tracing" path name.

That's it! (assuming that you have ftrace configured into your kernel)

After mounting tracefs you will have access to the control and output files
of ftrace. Here is a list of some of the key files:


 Note: all time values are in microseconds.

  current_tracer:

 This is used to set or display the current tracer
 that is configured. Changing the current tracer clears
 the ring buffer content as well as the "snapshot" buffer.

  available_tracers:

 This holds the different types of tracers that
 have been compiled into the kernel. The
 tracers listed here can be configured by
 echoing their name into current_tracer.

  tracing_on:

 This sets or displays whether writing to the trace
 ring buffer is enabled. Echo 0 into this file to disable
 the tracer or 1 to enable it. Note, this only disables
 writing to the ring buffer, the tracing overhead may
 still be occurring.

 The kernel function tracing_off() can be used within the
 kernel to disable writing to the ring buffer, which will
 set this file to "0". User space can re-enable tracing by
 echoing "1" into the file.

 Note, the function and event trigger "traceoff" will also
 set this file to zero and stop tracing. Which can also
 be re-enabled by user space using this file.

  trace:

 This file holds the output of the trace in a human
 readable format (described below). Opening this file for
 writing with the O_TRUNC flag clears the ring buffer content.
        Note, this file is not a consumer. If tracing is off
        (no tracer running, or tracing_on is zero), it will produce
        the same output each time it is read. When tracing is on,
        it may produce inconsistent results as it tries to read
        the entire buffer without consuming it.

  trace_pipe:

 The output is the same as the "trace" file but this
 file is meant to be streamed with live tracing.
 Reads from this file will block until new data is
 retrieved.  Unlike the "trace" file, this file is a
 consumer. This means reading from this file causes
 sequential reads to display more current data. Once
 data is read from this file, it is consumed, and
 will not be read again with a sequential read. The
 "trace" file is static, and if the tracer is not
 adding more data, it will display the same
 information every time it is read.

  trace_options:

 This file lets the user control the amount of data
 that is displayed in one of the above output
 files. Options also exist to modify how a tracer
 or events work (stack traces, timestamps, etc).

  options:

 This is a directory that has a file for every available
 trace option (also in trace_options). Options may also be set
 or cleared by writing a "1" or "0" respectively into the
 corresponding file with the option name.

  tracing_max_latency:

 Some of the tracers record the max latency.
 For example, the maximum time that interrupts are disabled.
 The maximum time is saved in this file. The max trace will also be
 stored, and displayed by "trace". A new max trace will only be
 recorded if the latency is greater than the value in this file
 (in microseconds).

 By echoing in a time into this file, no latency will be recorded
 unless it is greater than the time in this file.

  tracing_thresh:

 Some latency tracers will record a trace whenever the
 latency is greater than the number in this file.
 Only active when the file contains a number greater than 0.
 (in microseconds)

  buffer_percent:

 This is the watermark for how much the ring buffer needs to be filled
 before a waiter is woken up. That is, if an application calls a
 blocking read syscall on one of the per_cpu trace_pipe_raw files, it
 will block until the given amount of data specified by buffer_percent
 is in the ring buffer before it wakes the reader up. This also
 controls how the splice system calls are blocked on this file::

   0   - means to wake up as soon as there is any data in the ring buffer.
   50  - means to wake up when roughly half of the ring buffer sub-buffers
         are full.
   100 - means to block until the ring buffer is totally full and is
         about to start overwriting the older data.

  buffer_size_kb:

 This sets or displays the number of kilobytes each CPU
 buffer holds. By default, the trace buffers are the same size
 for each CPU. The displayed number is the size of the
 CPU buffer and not total size of all buffers. The
 trace buffers are allocated in pages (blocks of memory
 that the kernel uses for allocation, usually 4 KB in size).
 A few extra pages may be allocated to accommodate buffer management
 meta-data. If the last page allocated has room for more bytes
 than requested, the rest of the page will be used,
 making the actual allocation bigger than requested or shown.
 ( Note, the size may not be a multiple of the page size
 due to buffer management meta-data. )

 Buffer sizes for individual CPUs may vary
 (see "per_cpu/cpu0/buffer_size_kb" below), and if they do
 this file will show "X".

  buffer_total_size_kb:

 This displays the total combined size of all the trace buffers.

  buffer_subbuf_size_kb:

 This sets or displays the sub buffer size. The ring buffer is broken up
 into several same size "sub buffers". An event can not be bigger than
 the size of the sub buffer. Normally, the sub buffer is the size of the
 architecture's page (4K on x86). The sub buffer also contains meta data
 at the start which also limits the size of an event.  That means when
 the sub buffer is a page size, no event can be larger than the page
 size minus the sub buffer meta data.

 Note, the buffer_subbuf_size_kb is a way for the user to specify the
 minimum size of the subbuffer. The kernel may make it bigger due to the
 implementation details, or simply fail the operation if the kernel can
 not handle the request.

 Changing the sub buffer size allows for events to be larger than the
 page size.

 Note: When changing the sub-buffer size, tracing is stopped and any
 data in the ring buffer and the snapshot buffer will be discarded.

  free_buffer:

 If a process is performing tracing, and the ring buffer should be
 shrunk "freed" when the process is finished, even if it were to be
 killed by a signal, this file can be used for that purpose. On close
 of this file, the ring buffer will be resized to its minimum size.
 Having a process that is tracing also open this file, when the process
 exits its file descriptor for this file will be closed, and in doing so,
 the ring buffer will be "freed".

 It may also stop tracing if disable_on_free option is set.

  tracing_cpumask:

 This is a mask that lets the user only trace on specified CPUs.
 The format is a hex string representing the CPUs.

  set_ftrace_filter:

 When dynamic ftrace is configured in (see the
 section below "dynamic ftrace"), the code is dynamically
 modified (code text rewrite) to disable calling of the
 function profiler (mcount). This lets tracing be configured
 in with practically no overhead in performance.  This also
 has a side effect of enabling or disabling specific functions
 to be traced. Echoing names of functions into this file
 will limit the trace to only those functions.
 This influences the tracers "function" and "function_graph"
 and thus also function profiling (see "function_profile_enabled").

 The functions listed in "available_filter_functions" are what
 can be written into this file.

 This interface also allows for commands to be used. See the
 "Filter commands" section for more details.

 As a speed up, since processing strings can be quite expensive
 and requires a check of all functions registered to tracing, instead
 an index can be written into this file. A number (starting with "1")
 written will instead select the same corresponding at the line position
 of the "available_filter_functions" file.

  set_ftrace_notrace:

 This has an effect opposite to that of
 set_ftrace_filter. Any function that is added here will not
 be traced. If a function exists in both set_ftrace_filter
 and set_ftrace_notrace, the function will _not_ be traced.

  set_ftrace_pid:

 Have the function tracer only trace the threads whose PID are
 listed in this file.

 If the "function-fork" option is set, then when a task whose
 PID is listed in this file forks, the child's PID will
 automatically be added to this file, and the child will be
 traced by the function tracer as well. This option will also
 cause PIDs of tasks that exit to be removed from the file.

  set_ftrace_notrace_pid:

        Have the function tracer ignore threads whose PID are listed in
        this file.

        If the "function-fork" option is set, then when a task whose
 PID is listed in this file forks, the child's PID will
 automatically be added to this file, and the child will not be
 traced by the function tracer as well. This option will also
 cause PIDs of tasks that exit to be removed from the file.

        If a PID is in both this file and "set_ftrace_pid", then this
        file takes precedence, and the thread will not be traced.

  set_event_pid:

 Have the events only trace a task with a PID listed in this file.
 Note, sched_switch and sched_wake_up will also trace events
 listed in this file.

 To have the PIDs of children of tasks with their PID in this file
 added on fork, enable the "event-fork" option. That option will also
 cause the PIDs of tasks to be removed from this file when the task
 exits.

  set_event_notrace_pid:

 Have the events not trace a task with a PID listed in this file.
 Note, sched_switch and sched_wakeup will trace threads not listed
 in this file, even if a thread's PID is in the file if the
        sched_switch or sched_wakeup events also trace a thread that should
        be traced.

 To have the PIDs of children of tasks with their PID in this file
 added on fork, enable the "event-fork" option. That option will also
 cause the PIDs of tasks to be removed from this file when the task
 exits.

  set_graph_function:

 Functions listed in this file will cause the function graph
 tracer to only trace these functions and the functions that
 they call. (See the section "dynamic ftrace" for more details).
 Note, set_ftrace_filter and set_ftrace_notrace still affects
 what functions are being traced.

  set_graph_notrace:

 Similar to set_graph_function, but will disable function graph
 tracing when the function is hit until it exits the function.
 This makes it possible to ignore tracing functions that are called
 by a specific function.

  available_filter_functions:

 This lists the functions that ftrace has processed and can trace.
 These are the function names that you can pass to
 "set_ftrace_filter", "set_ftrace_notrace",
 "set_graph_function", or "set_graph_notrace".
 (See the section "dynamic ftrace" below for more details.)

  available_filter_functions_addrs:

 Similar to available_filter_functions, but with address displayed
 for each function. The displayed address is the patch-site address
 and can differ from /proc/kallsyms address.

  dyn_ftrace_total_info:

 This file is for debugging purposes. The number of functions that
 have been converted to nops and are available to be traced.

  enabled_functions:

 This file is more for debugging ftrace, but can also be useful
 in seeing if any function has a callback attached to it.
 Not only does the trace infrastructure use ftrace function
 trace utility, but other subsystems might too. This file
 displays all functions that have a callback attached to them
 as well as the number of callbacks that have been attached.
 Note, a callback may also call multiple functions which will
 not be listed in this count.

 If the callback registered to be traced by a function with
 the "save regs" attribute (thus even more overhead), a 'R'
 will be displayed on the same line as the function that
 is returning registers.

 If the callback registered to be traced by a function with
 the "ip modify" attribute (thus the regs->ip can be changed),
 an 'I' will be displayed on the same line as the function that
 can be overridden.

 If a non ftrace trampoline is attached (BPF) a 'D' will be displayed.
 Note, normal ftrace trampolines can also be attached, but only one
 "direct" trampoline can be attached to a given function at a time.

 Some architectures can not call direct trampolines, but instead have
 the ftrace ops function located above the function entry point. In
 such cases an 'O' will be displayed.

 If a function had either the "ip modify" or a "direct" call attached to
 it in the past, a 'M' will be shown. This flag is never cleared. It is
 used to know if a function was every modified by the ftrace infrastructure,
 and can be used for debugging.

 If the architecture supports it, it will also show what callback
 is being directly called by the function. If the count is greater
 than 1 it most likely will be ftrace_ops_list_func().

 If the callback of a function jumps to a trampoline that is
 specific to the callback and which is not the standard trampoline,
 its address will be printed as well as the function that the
 trampoline calls.

  touched_functions:

 This file contains all the functions that ever had a function callback
 to it via the ftrace infrastructure. It has the same format as
 enabled_functions but shows all functions that have every been
 traced.

 To see any function that has every been modified by "ip modify" or a
 direct trampoline, one can perform the following command:

 grep ' M ' /sys/kernel/tracing/touched_functions

  function_profile_enabled:

 When set it will enable all functions with either the function
 tracer, or if configured, the function graph tracer. It will
 keep a histogram of the number of functions that were called
 and if the function graph tracer was configured, it will also keep
 track of the time spent in those functions. The histogram
 content can be displayed in the files:

 trace_stat/function<cpu> ( function0, function1, etc).

  trace_stat:

 A directory that holds different tracing stats.

  kprobe_events:

 Enable dynamic trace points. See kprobetrace.rst.

  kprobe_profile:

 Dynamic trace points stats. See kprobetrace.rst.

  max_graph_depth:

 Used with the function graph tracer. This is the max depth
 it will trace into a function. Setting this to a value of
 one will show only the first kernel function that is called
 from user space.

  printk_formats:

 This is for tools that read the raw format files. If an event in
 the ring buffer references a string, only a pointer to the string
 is recorded into the buffer and not the string itself. This prevents
 tools from knowing what that string was. This file displays the string
 and address for the string allowing tools to map the pointers to what
 the strings were.

  saved_cmdlines:

 Only the pid of the task is recorded in a trace event unless
 the event specifically saves the task comm as well. Ftrace
 makes a cache of pid mappings to comms to try to display
 comms for events. If a pid for a comm is not listed, then
 "<...>" is displayed in the output.

 If the option "record-cmd" is set to "0", then comms of tasks
 will not be saved during recording. By default, it is enabled.

  saved_cmdlines_size:

 By default, 128 comms are saved (see "saved_cmdlines" above). To
 increase or decrease the amount of comms that are cached, echo
 the number of comms to cache into this file.

  saved_tgids:

 If the option "record-tgid" is set, on each scheduling context switch
 the Task Group ID of a task is saved in a table mapping the PID of
 the thread to its TGID. By default, the "record-tgid" option is
 disabled.

  snapshot:

 This displays the "snapshot" buffer and also lets the user
 take a snapshot of the current running trace.
 See the "Snapshot" section below for more details.

  stack_max_size:

 When the stack tracer is activated, this will display the
 maximum stack size it has encountered.
 See the "Stack Trace" section below.

  stack_trace:

 This displays the stack back trace of the largest stack
 that was encountered when the stack tracer is activated.
 See the "Stack Trace" section below.

  stack_trace_filter:

 This is similar to "set_ftrace_filter" but it limits what
 functions the stack tracer will check.

  trace_clock:

 Whenever an event is recorded into the ring buffer, a
 "timestamp" is added. This stamp comes from a specified
 clock. By default, ftrace uses the "local" clock. This
 clock is very fast and strictly per cpu, but on some
 systems it may not be monotonic with respect to other
 CPUs. In other words, the local clocks may not be in sync
 with local clocks on other CPUs.

 Usual clocks for tracing::

   # cat trace_clock
   [local] global counter x86-tsc

 The clock with the square brackets around it is the one in effect.

 local:
  Default clock, but may not be in sync across CPUs

 global:
  This clock is in sync with all CPUs but may
  be a bit slower than the local clock.

 counter:
  This is not a clock at all, but literally an atomic
  counter. It counts up one by one, but is in sync
  with all CPUs. This is useful when you need to
  know exactly the order events occurred with respect to
  each other on different CPUs.

 uptime:
  This uses the jiffies counter and the time stamp
  is relative to the time since boot up.

 perf:
  This makes ftrace use the same clock that perf uses.
  Eventually perf will be able to read ftrace buffers
  and this will help out in interleaving the data.

 x86-tsc:
  Architectures may define their own clocks. For
  example, x86 uses its own TSC cycle clock here.

 ppc-tb:
  This uses the powerpc timebase register value.
  This is in sync across CPUs and can also be used
  to correlate events across hypervisor/guest if
  tb_offset is known.

 mono:
  This uses the fast monotonic clock (CLOCK_MONOTONIC)
  which is monotonic and is subject to NTP rate adjustments.

 mono_raw:
  This is the raw monotonic clock (CLOCK_MONOTONIC_RAW)
  which is monotonic but is not subject to any rate adjustments
  and ticks at the same rate as the hardware clocksource.

 boot:
  This is the boot clock (CLOCK_BOOTTIME) and is based on the
  fast monotonic clock, but also accounts for time spent in
  suspend. Since the clock access is designed for use in
  tracing in the suspend path, some side effects are possible
  if clock is accessed after the suspend time is accounted before
  the fast mono clock is updated. In this case, the clock update
  appears to happen slightly sooner than it normally would have.
  Also on 32-bit systems, it's possible that the 64-bit boot offset
  sees a partial update. These effects are rare and post
  processing should be able to handle them. See comments in the
  ktime_get_boot_fast_ns() function for more information.

 tai:
  This is the tai clock (CLOCK_TAI) and is derived from the wall-
  clock time. However, this clock does not experience
  discontinuities and backwards jumps caused by NTP inserting leap
  seconds. Since the clock access is designed for use in tracing,
  side effects are possible. The clock access may yield wrong
  readouts in case the internal TAI offset is updated e.g., caused
  by setting the system time or using adjtimex() with an offset.
  These effects are rare and post processing should be able to
  handle them. See comments in the ktime_get_tai_fast_ns()
  function for more information.

 To set a clock, simply echo the clock name into this file::

   # echo global > trace_clock

 Setting a clock clears the ring buffer content as well as the
 "snapshot" buffer.

  trace_marker:

 This is a very useful file for synchronizing user space
 with events happening in the kernel. Writing strings into
 this file will be written into the ftrace buffer.

 It is useful in applications to open this file at the start
 of the application and just reference the file descriptor
 for the file::

  void trace_write(const char *fmt, ...)
  {
   va_list ap;
   char buf[256];
   int n;

   if (trace_fd < 0)
    return;

   va_start(ap, fmt);
   n = vsnprintf(buf, 256, fmt, ap);
   va_end(ap);

   write(trace_fd, buf, n);
  }

 start::

  trace_fd = open("trace_marker", O_WRONLY);

 Note: Writing into the trace_marker file can also initiate triggers
       that are written into /sys/kernel/tracing/events/ftrace/print/trigger
       See "Event triggers" in Documentation/trace/events.rst and an
              example in Documentation/trace/histogram.rst (Section 3.)

  trace_marker_raw:

 This is similar to trace_marker above, but is meant for binary data
 to be written to it, where a tool can be used to parse the data
 from trace_pipe_raw.

  uprobe_events:

 Add dynamic tracepoints in programs.
 See uprobetracer.rst

  uprobe_profile:

 Uprobe statistics. See uprobetrace.txt

  instances:

 This is a way to make multiple trace buffers where different
 events can be recorded in different buffers.
 See "Instances" section below.

  events:

 This is the trace event directory. It holds event tracepoints
 (also known as static tracepoints) that have been compiled
 into the kernel. It shows what event tracepoints exist
 and how they are grouped by system. There are "enable"
 files at various levels that can enable the tracepoints
 when a "1" is written to them.

 See events.rst for more information.

  set_event:

 By echoing in the event into this file, will enable that event.

 See events.rst for more information.

  available_events:

 A list of events that can be enabled in tracing.

 See events.rst for more information.

  timestamp_mode:

 Certain tracers may change the timestamp mode used when
 logging trace events into the event buffer.  Events with
 different modes can coexist within a buffer but the mode in
 effect when an event is logged determines which timestamp mode
 is used for that event.  The default timestamp mode is
 'delta'.

 Usual timestamp modes for tracing:

   # cat timestamp_mode
   [delta] absolute

   The timestamp mode with the square brackets around it is the
   one in effect.

   delta: Default timestamp mode - timestamp is a delta against
          a per-buffer timestamp.

   absolute: The timestamp is a full timestamp, not a delta
                 against some other value.  As such it takes up more
                 space and is less efficient.

  hwlat_detector:

 Directory for the Hardware Latency Detector.
 See "Hardware Latency Detector" section below.

  per_cpu:

 This is a directory that contains the trace per_cpu information.

  per_cpu/cpu0/buffer_size_kb:

 The ftrace buffer is defined per_cpu. That is, there's a separate
 buffer for each CPU to allow writes to be done atomically,
 and free from cache bouncing. These buffers may have different
 size buffers. This file is similar to the buffer_size_kb
 file, but it only displays or sets the buffer size for the
 specific CPU. (here cpu0).

  per_cpu/cpu0/trace:

 This is similar to the "trace" file, but it will only display
 the data specific for the CPU. If written to, it only clears
 the specific CPU buffer.

  per_cpu/cpu0/trace_pipe

 This is similar to the "trace_pipe" file, and is a consuming
 read, but it will only display (and consume) the data specific
 for the CPU.

  per_cpu/cpu0/trace_pipe_raw

 For tools that can parse the ftrace ring buffer binary format,
 the trace_pipe_raw file can be used to extract the data
 from the ring buffer directly. With the use of the splice()
 system call, the buffer data can be quickly transferred to
 a file or to the network where a server is collecting the
 data.

 Like trace_pipe, this is a consuming reader, where multiple
 reads will always produce different data.

  per_cpu/cpu0/snapshot:

 This is similar to the main "snapshot" file, but will only
 snapshot the current CPU (if supported). It only displays
 the content of the snapshot for a given CPU, and if
 written to, only clears this CPU buffer.

  per_cpu/cpu0/snapshot_raw:

 Similar to the trace_pipe_raw, but will read the binary format
 from the snapshot buffer for the given CPU.

  per_cpu/cpu0/stats:

 This displays certain stats about the ring buffer:

 entries:
  The number of events that are still in the buffer.

 overrun:
  The number of lost events due to overwriting when
  the buffer was full.

 commit overrun:
  Should always be zero.
  This gets set if so many events happened within a nested
  event (ring buffer is re-entrant), that it fills the
  buffer and starts dropping events.

 bytes:
  Bytes actually read (not overwritten).

 oldest event ts:
  The oldest timestamp in the buffer

 now ts:
  The current timestamp

 dropped events:
  Events lost due to overwrite option being off.

 read events:
  The number of events read.

The Tracers
-----------

Here is the list of current tracers that may be configured.

  "function"

 Function call tracer to trace all kernel functions.

  "function_graph"

 Similar to the function tracer except that the
 function tracer probes the functions on their entry
 whereas the function graph tracer traces on both entry
 and exit of the functions. It then provides the ability
 to draw a graph of function calls similar to C code
 source.

 Note that the function graph calculates the timings of when the
 function starts and returns internally and for each instance. If
 there are two instances that run function graph tracer and traces
 the same functions, the length of the timings may be slightly off as
 each read the timestamp separately and not at the same time.

  "blk"

 The block tracer. The tracer used by the blktrace user
 application.

  "hwlat"

 The Hardware Latency tracer is used to detect if the hardware
 produces any latency. See "Hardware Latency Detector" section
 below.

  "irqsoff"

 Traces the areas that disable interrupts and saves
 the trace with the longest max latency.
 See tracing_max_latency. When a new max is recorded,
 it replaces the old trace. It is best to view this
 trace with the latency-format option enabled, which
 happens automatically when the tracer is selected.

  "preemptoff"

 Similar to irqsoff but traces and records the amount of
 time for which preemption is disabled.

  "preemptirqsoff"

 Similar to irqsoff and preemptoff, but traces and
 records the largest time for which irqs and/or preemption
 is disabled.

  "wakeup"

 Traces and records the max latency that it takes for
 the highest priority task to get scheduled after
 it has been woken up.
        Traces all tasks as an average developer would expect.

  "wakeup_rt"

        Traces and records the max latency that it takes for just
        RT tasks (as the current "wakeup" does). This is useful
        for those interested in wake up timings of RT tasks.

  "wakeup_dl"

 Traces and records the max latency that it takes for
 a SCHED_DEADLINE task to be woken (as the "wakeup" and
 "wakeup_rt" does).

  "mmiotrace"

 A special tracer that is used to trace binary module.
 It will trace all the calls that a module makes to the
 hardware. Everything it writes and reads from the I/O
 as well.

  "branch"

 This tracer can be configured when tracing likely/unlikely
 calls within the kernel. It will trace when a likely and
 unlikely branch is hit and if it was correct in its prediction
 of being correct.

  "nop"

 This is the "trace nothing" tracer. To remove all
 tracers from tracing simply echo "nop" into
 current_tracer.

Error conditions
----------------

  For most ftrace commands, failure modes are obvious and communicated
  using standard return codes.

  For other more involved commands, extended error information may be
  available via the tracing/error_log file.  For the commands that
  support it, reading the tracing/error_log file after an error will
  display more detailed information about what went wrong, if
  information is available.  The tracing/error_log file is a circular
  error log displaying a small number (currently, 8) of ftrace errors
  for the last (8) failed commands.

  The extended error information and usage takes the form shown in
  this example::

    # echo xxx > /sys/kernel/tracing/events/sched/sched_wakeup/trigger
    echo: write error: Invalid argument

    # cat /sys/kernel/tracing/error_log
    [ 5348.887237] location: error: Couldn't yyy: zzz
      Command: xxx
               ^
    [ 7517.023364] location: error: Bad rrr: sss
      Command: ppp qqq
                   ^

  To clear the error log, echo the empty string into it::

    # echo > /sys/kernel/tracing/error_log

Examples of using the tracer
----------------------------

Here are typical examples of using the tracers when controlling
them only with the tracefs interface (without using any
user-land utilities).

Output format:
--------------

Here is an example of the output format of the file "trace"::

  # tracer: function
  #
  # entries-in-buffer/entries-written: 140080/250280   #P:4
  #
  #                              _-----=> irqs-off
  #                             / _----=> need-resched
  #                            | / _---=> hardirq/softirq
  #                            || / _--=> preempt-depth
  #                            ||| /     delay
  #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
  #              | |       |   ||||       |         |
              bash-1977  [000] .... 17284.993652: sys_close <-system_call_fastpath
              bash-1977  [000] .... 17284.993653: __close_fd <-sys_close
              bash-1977  [000] .... 17284.993653: _raw_spin_lock <-__close_fd
              sshd-1974  [003] .... 17284.993653: __srcu_read_unlock <-fsnotify
              bash-1977  [000] .... 17284.993654: add_preempt_count <-_raw_spin_lock
              bash-1977  [000] ...1 17284.993655: _raw_spin_unlock <-__close_fd
              bash-1977  [000] ...1 17284.993656: sub_preempt_count <-_raw_spin_unlock
              bash-1977  [000] .... 17284.993657: filp_close <-__close_fd
              bash-1977  [000] .... 17284.993657: dnotify_flush <-filp_close
              sshd-1974  [003] .... 17284.993658: sys_select <-system_call_fastpath
              ....

A header is printed with the tracer name that is represented by
the trace. In this case the tracer is "function". Then it shows the
number of events in the buffer as well as the total number of entries
that were written. The difference is the number of entries that were
lost due to the buffer filling up (250280 - 140080 = 110200 events
lost).

The header explains the content of the events. Task name "bash", the task
PID "1977", the CPU that it was running on "000", the latency format
(explained below), the timestamp in <secs>.<usecs> format, the
function name that was traced "sys_close" and the parent function that
called this function "system_call_fastpath". The timestamp is the time
at which the function was entered.

Latency trace format
--------------------

When the latency-format option is enabled or when one of the latency
tracers is set, the trace file gives somewhat more information to see
why a latency happened. Here is a typical trace::

  # tracer: irqsoff
  #
  # irqsoff latency trace v1.1.5 on 3.8.0-test+
  # --------------------------------------------------------------------
  # latency: 259 us, #4/4, CPU#2 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
  #    -----------------
  #    | task: ps-6143 (uid:0 nice:0 policy:0 rt_prio:0)
  #    -----------------
  #  => started at: __lock_task_sighand
  #  => ended at:   _raw_spin_unlock_irqrestore
  #
  #
  #                  _------=> CPU#            
  #                 / _-----=> irqs-off        
  #                | / _----=> need-resched    
  #                || / _---=> hardirq/softirq 
  #                ||| / _--=> preempt-depth   
  #                |||| /     delay             
  #  cmd     pid   ||||| time  |   caller      
  #     \   /      |||||  \    |   /           
        ps-6143    2d...    0us!: trace_hardirqs_off <-__lock_task_sighand
        ps-6143    2d..1  259us+: trace_hardirqs_on <-_raw_spin_unlock_irqrestore
        ps-6143    2d..1  263us+: time_hardirqs_on <-_raw_spin_unlock_irqrestore
        ps-6143    2d..1  306us : <stack trace>
   => trace_hardirqs_on_caller
   => trace_hardirqs_on
   => _raw_spin_unlock_irqrestore
   => do_task_stat
   => proc_tgid_stat
   => proc_single_show
   => seq_read
   => vfs_read
   => sys_read
   => system_call_fastpath


This shows that the current tracer is "irqsoff" tracing the time
for which interrupts were disabled. It gives the trace version (which
never changes) and the version of the kernel upon which this was executed on
(3.8). Then it displays the max latency in microseconds (259 us). The number
of trace entries displayed and the total number (both are four: #4/4).
VP, KP, SP, and HP are always zero and are reserved for later use.
#P is the number of online CPUs (#P:4).

The task is the process that was running when the latency
occurred. (ps pid: 6143).

The start and stop (the functions in which the interrupts were
disabled and enabled respectively) that caused the latencies:

  - __lock_task_sighand is where the interrupts were disabled.
  - _raw_spin_unlock_irqrestore is where they were enabled again.

The next lines after the header are the trace itself. The header
explains which is which.

  cmd: The name of the process in the trace.

  pid: The PID of that process.

  CPU#: The CPU which the process was running on.

  irqs-off: 'd' interrupts are disabled. '.' otherwise.

  need-resched:
 - 'B' all, TIF_NEED_RESCHED, PREEMPT_NEED_RESCHED and TIF_RESCHED_LAZY is set,
 - 'N' both TIF_NEED_RESCHED and PREEMPT_NEED_RESCHED is set,
 - 'n' only TIF_NEED_RESCHED is set,
 - 'p' only PREEMPT_NEED_RESCHED is set,
 - 'L' both PREEMPT_NEED_RESCHED and TIF_RESCHED_LAZY is set,
 - 'b' both TIF_NEED_RESCHED and TIF_RESCHED_LAZY is set,
 - 'l' only TIF_RESCHED_LAZY is set
 - '.' otherwise.

  hardirq/softirq:
 - 'Z' - NMI occurred inside a hardirq
 - 'z' - NMI is running
 - 'H' - hard irq occurred inside a softirq.
 - 'h' - hard irq is running
 - 's' - soft irq is running
 - '.' - normal context.

  preempt-depth: The level of preempt_disabled

The above is mostly meaningful for kernel developers.

  time:
 When the latency-format option is enabled, the trace file
 output includes a timestamp relative to the start of the
 trace. This differs from the output when latency-format
 is disabled, which includes an absolute timestamp.

  delay:
 This is just to help catch your eye a bit better. And
 needs to be fixed to be only relative to the same CPU.
 The marks are determined by the difference between this
 current trace and the next trace.

   - '$' - greater than 1 second
   - '@' - greater than 100 millisecond
   - '*' - greater than 10 millisecond
   - '#' - greater than 1000 microsecond
   - '!' - greater than 100 microsecond
   - '+' - greater than 10 microsecond
   - ' ' - less than or equal to 10 microsecond.

  The rest is the same as the 'trace' file.

  Note, the latency tracers will usually end with a back trace
  to easily find where the latency occurred.

trace_options
-------------

The trace_options file (or the options directory) is used to control
what gets printed in the trace output, or manipulate the tracers.
To see what is available, simply cat the file::

  cat trace_options
 print-parent
 nosym-offset
 nosym-addr
 noverbose
 noraw
 nohex
 nobin
 noblock
 nofields
 trace_printk
 annotate
 nouserstacktrace
 nosym-userobj
 noprintk-msg-only
 context-info
 nolatency-format
 record-cmd
 norecord-tgid
 overwrite
 nodisable_on_free
 irq-info
 markers
 noevent-fork
 function-trace
 nofunction-fork
 nodisplay-graph
 nostacktrace
 nobranch

To disable one of the options, echo in the option prepended with
"no"::

  echo noprint-parent > trace_options

To enable an option, leave off the "no"::

  echo sym-offset > trace_options

Here are the available options:

  print-parent
 On function traces, display the calling (parent)
 function as well as the function being traced.
 ::

   print-parent:
    bash-4000  [01]  1477.606694: simple_strtoul <-kstrtoul

   noprint-parent:
    bash-4000  [01]  1477.606694: simple_strtoul


  sym-offset
 Display not only the function name, but also the
 offset in the function. For example, instead of
 seeing just "ktime_get", you will see
 "ktime_get+0xb/0x20".
 ::

   sym-offset:
    bash-4000  [01]  1477.606694: simple_strtoul+0x6/0xa0

  sym-addr
 This will also display the function address as well
 as the function name.
 ::

   sym-addr:
    bash-4000  [01]  1477.606694: simple_strtoul <c0339346>

  verbose
 This deals with the trace file when the
        latency-format option is enabled.
 ::

     bash  4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \
     (+0.000ms): simple_strtoul (kstrtoul)

  raw
 This will display raw numbers. This option is best for
 use with user applications that can translate the raw
 numbers better than having it done in the kernel.

  hex
 Similar to raw, but the numbers will be in a hexadecimal format.

  bin
 This will print out the formats in raw binary.

  block
 When set, reading trace_pipe will not block when polled.

  fields
 Print the fields as described by their types. This is a better
 option than using hex, bin or raw, as it gives a better parsing
 of the content of the event.

  trace_printk
 Can disable trace_printk() from writing into the buffer.

  trace_printk_dest
 Set to have trace_printk() and similar internal tracing functions
 write into this instance. Note, only one trace instance can have
 this set. By setting this flag, it clears the trace_printk_dest flag
 of the instance that had it set previously. By default, the top
 level trace has this set, and will get it set again if another
 instance has it set then clears it.

 This flag cannot be cleared by the top level instance, as it is the
 default instance. The only way the top level instance has this flag
 cleared, is by it being set in another instance.

  copy_trace_marker
 If there are applications that hard code writing into the top level
 trace_marker file (/sys/kernel/tracing/trace_marker or trace_marker_raw),
 and the tooling would like it to go into an instance, this option can
 be used. Create an instance and set this option, and then all writes
 into the top level trace_marker file will also be redirected into this
 instance.

 Note, by default this option is set for the top level instance. If it
 is disabled, then writes to the trace_marker or trace_marker_raw files
 will not be written into the top level file. If no instance has this
 option set, then a write will error with the errno of ENODEV.

  annotate
 It is sometimes confusing when the CPU buffers are full
 and one CPU buffer had a lot of events recently, thus
 a shorter time frame, were another CPU may have only had
 a few events, which lets it have older events. When
 the trace is reported, it shows the oldest events first,
 and it may look like only one CPU ran (the one with the
 oldest events). When the annotate option is set, it will
 display when a new CPU buffer started::

     <idle>-0     [001] dNs4 21169.031481: wake_up_idle_cpu <-add_timer_on
     <idle>-0     [001] dNs4 21169.031482: _raw_spin_unlock_irqrestore <-add_timer_on
     <idle>-0     [001] .Ns4 21169.031484: sub_preempt_count <-_raw_spin_unlock_irqrestore
  ##### CPU 2 buffer started ####
     <idle>-0     [002] .N.1 21169.031484: rcu_idle_exit <-cpu_idle
     <idle>-0     [001] .Ns3 21169.031484: _raw_spin_unlock <-clocksource_watchdog
     <idle>-0     [001] .Ns3 21169.031485: sub_preempt_count <-_raw_spin_unlock

  userstacktrace
 This option changes the trace. It records a
 stacktrace of the current user space thread after
 each trace event.

  sym-userobj
 when user stacktrace are enabled, look up which
 object the address belongs to, and print a
 relative address. This is especially useful when
 ASLR is on, otherwise you don't get a chance to
 resolve the address to object/file/line after
 the app is no longer running

 The lookup is performed when you read
 trace,trace_pipe. Example::

    a.out-1623  [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
    x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]


  printk-msg-only
 When set, trace_printk()s will only show the format
 and not their parameters (if trace_bprintk() or
 trace_bputs() was used to save the trace_printk()).

  context-info
 Show only the event data. Hides the comm, PID,
 timestamp, CPU, and other useful data.

  latency-format
 This option changes the trace output. When it is enabled,
 the trace displays additional information about the
 latency, as described in "Latency trace format".

  pause-on-trace
 When set, opening the trace file for read, will pause
 writing to the ring buffer (as if tracing_on was set to zero).
 This simulates the original behavior of the trace file.
 When the file is closed, tracing will be enabled again.

  hash-ptr
        When set, "%p" in the event printk format displays the
        hashed pointer value instead of real address.
        This will be useful if you want to find out which hashed
        value is corresponding to the real value in trace log.

  record-cmd
 When any event or tracer is enabled, a hook is enabled
 in the sched_switch trace point to fill comm cache
 with mapped pids and comms. But this may cause some
 overhead, and if you only care about pids, and not the
 name of the task, disabling this option can lower the
 impact of tracing. See "saved_cmdlines".

  record-tgid
 When any event or tracer is enabled, a hook is enabled
 in the sched_switch trace point to fill the cache of
 mapped Thread Group IDs (TGID) mapping to pids. See
 "saved_tgids".

  overwrite
 This controls what happens when the trace buffer is
 full. If "1" (default), the oldest events are
 discarded and overwritten. If "0", then the newest
 events are discarded.
 (see per_cpu/cpu0/stats for overrun and dropped)

  disable_on_free
 When the free_buffer is closed, tracing will
 stop (tracing_on set to 0).

  irq-info
 Shows the interrupt, preempt count, need resched data.
 When disabled, the trace looks like::

  # tracer: function
  #
  # entries-in-buffer/entries-written: 144405/9452052   #P:4
  #
  #           TASK-PID   CPU#      TIMESTAMP  FUNCTION
  #              | |       |          |         |
     <idle>-0     [002]  23636.756054: ttwu_do_activate.constprop.89 <-try_to_wake_up
     <idle>-0     [002]  23636.756054: activate_task <-ttwu_do_activate.constprop.89
     <idle>-0     [002]  23636.756055: enqueue_task <-activate_task


  markers
 When set, the trace_marker is writable (only by root).
 When disabled, the trace_marker will error with EINVAL
 on write.

  event-fork
 When set, tasks with PIDs listed in set_event_pid will have
 the PIDs of their children added to set_event_pid when those
 tasks fork. Also, when tasks with PIDs in set_event_pid exit,
 their PIDs will be removed from the file.

        This affects PIDs listed in set_event_notrace_pid as well.

  function-trace
 The latency tracers will enable function tracing
 if this option is enabled (default it is). When
 it is disabled, the latency tracers do not trace
 functions. This keeps the overhead of the tracer down
 when performing latency tests.

  function-fork
 When set, tasks with PIDs listed in set_ftrace_pid will
 have the PIDs of their children added to set_ftrace_pid
 when those tasks fork. Also, when tasks with PIDs in
 set_ftrace_pid exit, their PIDs will be removed from the
 file.

        This affects PIDs in set_ftrace_notrace_pid as well.

  display-graph
 When set, the latency tracers (irqsoff, wakeup, etc) will
 use function graph tracing instead of function tracing.

  stacktrace
 When set, a stack trace is recorded after any trace event
 is recorded.

  branch
 Enable branch tracing with the tracer. This enables branch
 tracer along with the currently set tracer. Enabling this
 with the "nop" tracer is the same as just enabling the
 "branch" tracer.

.. tip:: Some tracers have their own options. They only appear in this
       file when the tracer is active. They always appear in the
       options directory.


Here are the per tracer options:

Options for function tracer:

  func_stack_trace
 When set, a stack trace is recorded after every
 function that is recorded. NOTE! Limit the functions
 that are recorded before enabling this, with
 "set_ftrace_filter" otherwise the system performance
 will be critically degraded. Remember to disable
 this option before clearing the function filter.

Options for function_graph tracer:

 Since the function_graph tracer has a slightly different output
 it has its own options to control what is displayed.

  funcgraph-overrun
 When set, the "overrun" of the graph stack is
 displayed after each function traced. The
 overrun, is when the stack depth of the calls
 is greater than what is reserved for each task.
 Each task has a fixed array of functions to
 trace in the call graph. If the depth of the
 calls exceeds that, the function is not traced.
 The overrun is the number of functions missed
 due to exceeding this array.

  funcgraph-cpu
 When set, the CPU number of the CPU where the trace
 occurred is displayed.

  funcgraph-overhead
 When set, if the function takes longer than
 A certain amount, then a delay marker is
 displayed. See "delay" above, under the
 header description.

  funcgraph-proc
 Unlike other tracers, the process' command line
 is not displayed by default, but instead only
 when a task is traced in and out during a context
 switch. Enabling this options has the command
 of each process displayed at every line.

  funcgraph-duration
 At the end of each function (the return)
 the duration of the amount of time in the
 function is displayed in microseconds.

  funcgraph-abstime
 When set, the timestamp is displayed at each line.

  funcgraph-irqs
 When disabled, functions that happen inside an
 interrupt will not be traced.

  funcgraph-tail
 When set, the return event will include the function
 that it represents. By default this is off, and
 only a closing curly bracket "}" is displayed for
 the return of a function.

  funcgraph-retval
 When set, the return value of each traced function
 will be printed after an equal sign "=". By default
 this is off.

  funcgraph-retval-hex
 When set, the return value will always be printed
 in hexadecimal format. If the option is not set and
 the return value is an error code, it will be printed
 in signed decimal format; otherwise it will also be
 printed in hexadecimal format. By default, this option
 is off.

  sleep-time
 When running function graph tracer, to include
 the time a task schedules out in its function.
 When enabled, it will account time the task has been
 scheduled out as part of the function call.

  graph-time
 When running function profiler with function graph tracer,
 to include the time to call nested functions. When this is
 not set, the time reported for the function will only
 include the time the function itself executed for, not the
 time for functions that it called.

Options for blk tracer:

  blk_classic
 Shows a more minimalistic output.


irqsoff
-------

When interrupts are disabled, the CPU can not react to any other
external event (besides NMIs and SMIs). This prevents the timer
interrupt from triggering or the mouse interrupt from letting
the kernel know of a new mouse event. The result is a latency
with the reaction time.

The irqsoff tracer tracks the time for which interrupts are
disabled. When a new maximum latency is hit, the tracer saves
the trace leading up to that latency point so that every time a
new maximum is reached, the old saved trace is discarded and the
new trace is saved.

To reset the maximum, echo 0 into tracing_max_latency. Here is
an example::

  # echo 0 > options/function-trace
  # echo irqsoff > current_tracer
  # echo 1 > tracing_on
  # echo 0 > tracing_max_latency
  # ls -ltr
  [...]
  # echo 0 > tracing_on
  # cat trace
  # tracer: irqsoff
  #
  # irqsoff latency trace v1.1.5 on 3.8.0-test+
  # --------------------------------------------------------------------
  # latency: 16 us, #4/4, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
  #    -----------------
  #    | task: swapper/0-0 (uid:0 nice:0 policy:0 rt_prio:0)
  #    -----------------
  #  => started at: run_timer_softirq
  #  => ended at:   run_timer_softirq
  #
  #
  #                  _------=> CPU#            
  #                 / _-----=> irqs-off        
  #                | / _----=> need-resched    
  #                || / _---=> hardirq/softirq 
  #                ||| / _--=> preempt-depth   
  #                |||| /     delay             
  #  cmd     pid   ||||| time  |   caller      
  #     \   /      |||||  \    |   /           
    <idle>-0       0d.s2    0us+: _raw_spin_lock_irq <-run_timer_softirq
    <idle>-0       0dNs3   17us : _raw_spin_unlock_irq <-run_timer_softirq
    <idle>-0       0dNs3   17us+: trace_hardirqs_on <-run_timer_softirq
    <idle>-0       0dNs3   25us : <stack trace>
   => _raw_spin_unlock_irq
   => run_timer_softirq
   => __do_softirq
   => call_softirq
   => do_softirq
   => irq_exit
   => smp_apic_timer_interrupt
   => apic_timer_interrupt
   => rcu_idle_exit
   => cpu_idle
   => rest_init
   => start_kernel
   => x86_64_start_reservations
   => x86_64_start_kernel

Here we see that we had a latency of 16 microseconds (which is
very good). The _raw_spin_lock_irq in run_timer_softirq disabled
interrupts. The difference between the 16 and the displayed
timestamp 25us occurred because the clock was incremented
between the time of recording the max latency and the time of
recording the function that had that latency.

Note the above example had function-trace not set. If we set
function-trace, we get a much larger output::

 with echo 1 > options/function-trace

  # tracer: irqsoff
  #
  # irqsoff latency trace v1.1.5 on 3.8.0-test+
  # --------------------------------------------------------------------
  # latency: 71 us, #168/168, CPU#3 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
  #    -----------------
  #    | task: bash-2042 (uid:0 nice:0 policy:0 rt_prio:0)
  #    -----------------
  #  => started at: ata_scsi_queuecmd
  #  => ended at:   ata_scsi_queuecmd
  #
  #
  #                  _------=> CPU#            
  #                 / _-----=> irqs-off        
  #                | / _----=> need-resched    
  #                || / _---=> hardirq/softirq 
  #                ||| / _--=> preempt-depth   
  #                |||| /     delay             
  #  cmd     pid   ||||| time  |   caller      
  #     \   /      |||||  \    |   /           
      bash-2042    3d...    0us : _raw_spin_lock_irqsave <-ata_scsi_queuecmd
      bash-2042    3d...    0us : add_preempt_count <-_raw_spin_lock_irqsave
      bash-2042    3d..1    1us : ata_scsi_find_dev <-ata_scsi_queuecmd
      bash-2042    3d..1    1us : __ata_scsi_find_dev <-ata_scsi_find_dev
      bash-2042    3d..1    2us : ata_find_dev.part.14 <-__ata_scsi_find_dev
      bash-2042    3d..1    2us : ata_qc_new_init <-__ata_scsi_queuecmd
      bash-2042    3d..1    3us : ata_sg_init <-__ata_scsi_queuecmd
      bash-2042    3d..1    4us : ata_scsi_rw_xlat <-__ata_scsi_queuecmd
      bash-2042    3d..1    4us : ata_build_rw_tf <-ata_scsi_rw_xlat
  [...]
      bash-2042    3d..1   67us : delay_tsc <-__delay
      bash-2042    3d..1   67us : add_preempt_count <-delay_tsc
      bash-2042    3d..2   67us : sub_preempt_count <-delay_tsc
      bash-2042    3d..1   67us : add_preempt_count <-delay_tsc
      bash-2042    3d..2   68us : sub_preempt_count <-delay_tsc
      bash-2042    3d..1   68us+: ata_bmdma_start <-ata_bmdma_qc_issue
      bash-2042    3d..1   71us : _raw_spin_unlock_irqrestore <-ata_scsi_queuecmd
      bash-2042    3d..1   71us : _raw_spin_unlock_irqrestore <-ata_scsi_queuecmd
      bash-2042    3d..1   72us+: trace_hardirqs_on <-ata_scsi_queuecmd
      bash-2042    3d..1  120us : <stack trace>
   => _raw_spin_unlock_irqrestore
   => ata_scsi_queuecmd
   => scsi_dispatch_cmd
   => scsi_request_fn
   => __blk_run_queue_uncond
   => __blk_run_queue
   => blk_queue_bio
   => submit_bio_noacct
   => submit_bio
   => submit_bh
   => __ext3_get_inode_loc
   => ext3_iget
   => ext3_lookup
   => lookup_real
   => __lookup_hash
   => walk_component
   => lookup_last
   => path_lookupat
   => filename_lookup
   => user_path_at_empty
   => user_path_at
   => vfs_fstatat
   => vfs_stat
   => sys_newstat
   => system_call_fastpath


Here we traced a 71 microsecond latency. But we also see all the
functions that were called during that time. Note that by
enabling function tracing, we incur an added overhead. This
overhead may extend the latency times. But nevertheless, this
trace has provided some very helpful debugging information.

If we prefer function graph output instead of function, we can set
display-graph option::

 with echo 1 > options/display-graph

  # tracer: irqsoff
  #
  # irqsoff latency trace v1.1.5 on 4.20.0-rc6+
  # --------------------------------------------------------------------
  # latency: 3751 us, #274/274, CPU#0 | (M:desktop VP:0, KP:0, SP:0 HP:0 #P:4)
  #    -----------------
  #    | task: bash-1507 (uid:0 nice:0 policy:0 rt_prio:0)
  #    -----------------
  #  => started at: free_debug_processing
  #  => ended at:   return_to_handler
  #
  #
  #                                       _-----=> irqs-off
  #                                      / _----=> need-resched
  #                                     | / _---=> hardirq/softirq
  #                                     || / _--=> preempt-depth
  #                                     ||| /
  #   REL TIME      CPU  TASK/PID       ||||     DURATION                  FUNCTION CALLS
  #      |          |     |    |        ||||      |   |                     |   |   |   |
          0 us |   0)   bash-1507    |  d... |   0.000 us    |  _raw_spin_lock_irqsave();
          0 us |   0)   bash-1507    |  d..1 |   0.378 us    |    do_raw_spin_trylock();
          1 us |   0)   bash-1507    |  d..2 |               |    set_track() {
          2 us |   0)   bash-1507    |  d..2 |               |      save_stack_trace() {
          2 us |   0)   bash-1507    |  d..2 |               |        __save_stack_trace() {
          3 us |   0)   bash-1507    |  d..2 |               |          __unwind_start() {
          3 us |   0)   bash-1507    |  d..2 |               |            get_stack_info() {
          3 us |   0)   bash-1507    |  d..2 |   0.351 us    |              in_task_stack();
          4 us |   0)   bash-1507    |  d..2 |   1.107 us    |            }
  [...]
       3750 us |   0)   bash-1507    |  d..1 |   0.516 us    |      do_raw_spin_unlock();
       3750 us |   0)   bash-1507    |  d..1 |   0.000 us    |  _raw_spin_unlock_irqrestore();
       3764 us |   0)   bash-1507    |  d..1 |   0.000 us    |  tracer_hardirqs_on();
      bash-1507    0d..1 3792us : <stack trace>
   => free_debug_processing
   => __slab_free
   => kmem_cache_free
   => vm_area_free
   => remove_vma
   => exit_mmap
   => mmput
   => begin_new_exec
   => load_elf_binary
   => search_binary_handler
   => __do_execve_file.isra.32
   => __x64_sys_execve
   => do_syscall_64
   => entry_SYSCALL_64_after_hwframe

preemptoff
----------

When preemption is disabled, we may be able to receive
interrupts but the task cannot be preempted and a higher
priority task must wait for preemption to be enabled again
before it can preempt a lower priority task.

The preemptoff tracer traces the places that disable preemption.
Like the irqsoff tracer, it records the maximum latency for
which preemption was disabled. The control of preemptoff tracer
is much like the irqsoff tracer.
::

  # echo 0 > options/function-trace
  # echo preemptoff > current_tracer
  # echo 1 > tracing_on
  # echo 0 > tracing_max_latency
  # ls -ltr
  [...]
  # echo 0 > tracing_on
  # cat trace
  # tracer: preemptoff
  #
  # preemptoff latency trace v1.1.5 on 3.8.0-test+
  # --------------------------------------------------------------------
  # latency: 46 us, #4/4, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
  #    -----------------
  #    | task: sshd-1991 (uid:0 nice:0 policy:0 rt_prio:0)
  #    -----------------
  #  => started at: do_IRQ
  #  => ended at:   do_IRQ
  #
  #
  #                  _------=> CPU#            
  #                 / _-----=> irqs-off        
  #                | / _----=> need-resched    
  #                || / _---=> hardirq/softirq 
  #                ||| / _--=> preempt-depth   
  #                |||| /     delay             
  #  cmd     pid   ||||| time  |   caller      
  #     \   /      |||||  \    |   /           
      sshd-1991    1d.h.    0us+: irq_enter <-do_IRQ
      sshd-1991    1d..1   46us : irq_exit <-do_IRQ
      sshd-1991    1d..1   47us+: trace_preempt_on <-do_IRQ
      sshd-1991    1d..1   52us : <stack trace>
   => sub_preempt_count
   => irq_exit
   => do_IRQ
   => ret_from_intr


This has some more changes. Preemption was disabled when an
interrupt came in (notice the 'h'), and was enabled on exit.
But we also see that interrupts have been disabled when entering
the preempt off section and leaving it (the 'd'). We do not know if
interrupts were enabled in the mean time or shortly after this
was over.
::

  # tracer: preemptoff
  #
  # preemptoff latency trace v1.1.5 on 3.8.0-test+
  # --------------------------------------------------------------------
  # latency: 83 us, #241/241, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
  #    -----------------
  #    | task: bash-1994 (uid:0 nice:0 policy:0 rt_prio:0)
  #    -----------------
  #  => started at: wake_up_new_task
  #  => ended at:   task_rq_unlock
  #
  #
  #                  _------=> CPU#            
  #                 / _-----=> irqs-off        
  #                | / _----=> need-resched    
  #                || / _---=> hardirq/softirq 
  #                ||| / _--=> preempt-depth   
  #                |||| /     delay             
  #  cmd     pid   ||||| time  |   caller      
  #     \   /      |||||  \    |   /           
      bash-1994    1d..1    0us : _raw_spin_lock_irqsave <-wake_up_new_task
      bash-1994    1d..1    0us : select_task_rq_fair <-select_task_rq
      bash-1994    1d..1    1us : __rcu_read_lock <-select_task_rq_fair
      bash-1994    1d..1    1us : source_load <-select_task_rq_fair
      bash-1994    1d..1    1us : source_load <-select_task_rq_fair
  [...]
      bash-1994    1d..1   12us : irq_enter <-smp_apic_timer_interrupt
      bash-1994    1d..1   12us : rcu_irq_enter <-irq_enter
      bash-1994    1d..1   13us : add_preempt_count <-irq_enter
      bash-1994    1d.h1   13us : exit_idle <-smp_apic_timer_interrupt
      bash-1994    1d.h1   13us : hrtimer_interrupt <-smp_apic_timer_interrupt
      bash-1994    1d.h1   13us : _raw_spin_lock <-hrtimer_interrupt
      bash-1994    1d.h1   14us : add_preempt_count <-_raw_spin_lock
      bash-1994    1d.h2   14us : ktime_get_update_offsets <-hrtimer_interrupt
  [...]
      bash-1994    1d.h1   35us : lapic_next_event <-clockevents_program_event
      bash-1994    1d.h1   35us : irq_exit <-smp_apic_timer_interrupt
      bash-1994    1d.h1   36us : sub_preempt_count <-irq_exit
      bash-1994    1d..2   36us : do_softirq <-irq_exit
      bash-1994    1d..2   36us : __do_softirq <-call_softirq
      bash-1994    1d..2   36us : __local_bh_disable <-__do_softirq
      bash-1994    1d.s2   37us : add_preempt_count <-_raw_spin_lock_irq
      bash-1994    1d.s3   38us : _raw_spin_unlock <-run_timer_softirq
      bash-1994    1d.s3   39us : sub_preempt_count <-_raw_spin_unlock
      bash-1994    1d.s2   39us : call_timer_fn <-run_timer_softirq
  [...]
      bash-1994    1dNs2   81us : cpu_needs_another_gp <-rcu_process_callbacks
      bash-1994    1dNs2   82us : __local_bh_enable <-__do_softirq
      bash-1994    1dNs2   82us : sub_preempt_count <-__local_bh_enable
      bash-1994    1dN.2   82us : idle_cpu <-irq_exit
      bash-1994    1dN.2   83us : rcu_irq_exit <-irq_exit
      bash-1994    1dN.2   83us : sub_preempt_count <-irq_exit
      bash-1994    1.N.1   84us : _raw_spin_unlock_irqrestore <-task_rq_unlock
      bash-1994    1.N.1   84us+: trace_preempt_on <-task_rq_unlock
      bash-1994    1.N.1  104us : <stack trace>
   => sub_preempt_count
   => _raw_spin_unlock_irqrestore
   => task_rq_unlock
   => wake_up_new_task
   => do_fork
   => sys_clone
   => stub_clone


The above is an example of the preemptoff trace with
function-trace set. Here we see that interrupts were not disabled
the entire time. The irq_enter code lets us know that we entered
an interrupt 'h'. Before that, the functions being traced still
show that it is not in an interrupt, but we can see from the
functions themselves that this is not the case.

preemptirqsoff
--------------

Knowing the locations that have interrupts disabled or
preemption disabled for the longest times is helpful. But
sometimes we would like to know when either preemption and/or
interrupts are disabled.

Consider the following code::

    local_irq_disable();
    call_function_with_irqs_off();
    preempt_disable();
    call_function_with_irqs_and_preemption_off();
    local_irq_enable();
    call_function_with_preemption_off();
    preempt_enable();

The irqsoff tracer will record the total length of
call_function_with_irqs_off() and
call_function_with_irqs_and_preemption_off().

The preemptoff tracer will record the total length of
call_function_with_irqs_and_preemption_off() and
call_function_with_preemption_off().

But neither will trace the time that interrupts and/or
preemption is disabled. This total time is the time that we can
not schedule. To record this time, use the preemptirqsoff
tracer.

Again, using this trace is much like the irqsoff and preemptoff
tracers.
::

  # echo 0 > options/function-trace
  # echo preemptirqsoff > current_tracer
  # echo 1 > tracing_on
  # echo 0 > tracing_max_latency
  # ls -ltr
  [...]
  # echo 0 > tracing_on
  # cat trace
  # tracer: preemptirqsoff
  #
  # preemptirqsoff latency trace v1.1.5 on 3.8.0-test+
  # --------------------------------------------------------------------
  # latency: 100 us, #4/4, CPU#3 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
  #    -----------------
  #    | task: ls-2230 (uid:0 nice:0 policy:0 rt_prio:0)
  #    -----------------
  #  => started at: ata_scsi_queuecmd
  #  => ended at:   ata_scsi_queuecmd
  #
  #
  #                  _------=> CPU#            
  #                 / _-----=> irqs-off        
--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.63 Sekunden  ]