code:
.. SPDX-License-Identifier: GPL-2.0

==============================
Trace Buffer Extension (TRBE).
==============================

    :Author:   Anshuman Khandual <anshuman.khandual@arm.com>
    :Date:     November 2020

Hardware Description
--------------------

Trace Buffer Extension (TRBE) is a percpu hardware which captures in system
memory, CPU traces generated from a corresponding percpu tracing unit. This
gets plugged in as a coresight sink device because the corresponding trace
generators (ETE), are plugged in as source device.

The TRBE is not compliant to CoreSight architecture specifications, but is
driven via the CoreSight driver framework to support the ETE (which is
CoreSight compliant) integration.

Sysfs files and directories
---------------------------

The TRBE devices appear on the existing coresight bus alongside the other
coresight devices::

	>$ ls /sys/bus/coresight/devices
	trbe0  trbe1  trbe2 trbe3

The ``trbe<N>`` named TRBEs are associated with a CPU.::

	>$ ls /sys/bus/coresight/devices/trbe0/
        align flag

*Key file items are:-*
   * ``align``: TRBE write pointer alignment
   * ``flag``: TRBE updates memory with access and dirty flags


code:
======================================
Coresight - HW Assisted Tracing on ARM
======================================

   :Author:   Mathieu Poirier <mathieu.poirier@linaro.org>
   :Date:     September 11th, 2014

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

Coresight is an umbrella of technologies allowing for the debugging of ARM
based SoC.  It includes solutions for JTAG and HW assisted tracing.  This
document is concerned with the latter.

HW assisted tracing is becoming increasingly useful when dealing with systems
that have many SoCs and other components like GPU and DMA engines.  ARM has
developed a HW assisted tracing solution by means of different components, each
being added to a design at synthesis time to cater to specific tracing needs.
Components are generally categorised as source, link and sinks and are
(usually) discovered using the AMBA bus.

"Sources" generate a compressed stream representing the processor instruction
path based on tracing scenarios as configured by users.  From there the stream
flows through the coresight system (via ATB bus) using links that are connecting
the emanating source to a sink(s).  Sinks serve as endpoints to the coresight
implementation, either storing the compressed stream in a memory buffer or
creating an interface to the outside world where data can be transferred to a
host without fear of filling up the onboard coresight memory buffer.

At typical coresight system would look like this::

  *****************************************************************
 **************************** AMBA AXI  ****************************===||
  *****************************************************************    ||
        ^                    ^                            |            ||
        |                    |                            *            **
     0000000    :::::     0000000    :::::    :::::    @@@@@@@    ||||||||||||
     0 CPU 0<-->: C :     0 CPU 0<-->: C :    : C :    @ STM @    || System ||
  |->0000000    : T :  |->0000000    : T :    : T :<--->@@@@@     || Memory ||
  |  #######<-->: I :  |  #######<-->: I :    : I :      @@@<-|   ||||||||||||
  |  # ETM #    :::::  |  # PTM #    :::::    :::::       @   |
  |   #####      ^ ^   |   #####      ^ !      ^ !        .   |   |||||||||
  | |->###       | !   | |->###       | !      | !        .   |   || DAP ||
  | |   #        | !   | |   #        | !      | !        .   |   |||||||||
  | |   .        | !   | |   .        | !      | !        .   |      |  |
  | |   .        | !   | |   .        | !      | !        .   |      |  *
  | |   .        | !   | |   .        | !      | !        .   |      | SWD/
  | |   .        | !   | |   .        | !      | !        .   |      | JTAG
  *****************************************************************<-|
 *************************** AMBA Debug APB ************************
  *****************************************************************
   |    .          !         .          !        !        .    |
   |    .          *         .          *        *        .    |
  *****************************************************************
 ******************** Cross Trigger Matrix (CTM) *******************
  *****************************************************************
   |    .     ^              .                            .    |
   |    *     !              *                            *    |
  *****************************************************************
 ****************** AMBA Advanced Trace Bus (ATB) ******************
  *****************************************************************
   |          !                        ===============         |
   |          *                         ===== F =====<---------|
   |   :::::::::                         ==== U ====
   |-->:: CTI ::<!!                       === N ===
   |   :::::::::  !                        == N ==
   |    ^         *                        == E ==
   |    !  &&&&&&&&&       IIIIIII         == L ==
   |------>&& ETB &&<......II     I        =======
   |    !  &&&&&&&&&       II     I           .
   |    !                    I     I          .
   |    !                    I REP I<..........
   |    !                    I     I
   |    !!>&&&&&&&&&       II     I           *Source: ARM ltd.
   |------>& TPIU  &<......II    I            DAP = Debug Access Port
           &&&&&&&&&       IIIIIII            ETM = Embedded Trace Macrocell
               ;                              PTM = Program Trace Macrocell
               ;                              CTI = Cross Trigger Interface
               *                              ETB = Embedded Trace Buffer
          To trace port                       TPIU= Trace Port Interface Unit
                                              SWD = Serial Wire Debug

While on target configuration of the components is done via the APB bus,
all trace data are carried out-of-band on the ATB bus.  The CTM provides
a way to aggregate and distribute signals between CoreSight components.

The coresight framework provides a central point to represent, configure and
manage coresight devices on a platform.  This first implementation centers on
the basic tracing functionality, enabling components such ETM/PTM, funnel,
replicator, TMC, TPIU and ETB.  Future work will enable more
intricate IP blocks such as STM and CTI.

Acronyms and Classification
---------------------------

Acronyms:

PTM:
    Program Trace Macrocell
ETM:
    Embedded Trace Macrocell
STM:
    System trace Macrocell
ETB:
    Embedded Trace Buffer
ITM:
    Instrumentation Trace Macrocell
TPIU:
     Trace Port Interface Unit
TMC-ETR:
        Trace Memory Controller, configured as Embedded Trace Router
TMC-ETF:
        Trace Memory Controller, configured as Embedded Trace FIFO
CTI:
    Cross Trigger Interface

Classification:

Source:
   ETMv3.x ETMv4, PTMv1.0, PTMv1.1, STM, STM500, ITM
Link:
   Funnel, replicator (intelligent or not), TMC-ETR
Sinks:
   ETBv1.0, ETB1.1, TPIU, TMC-ETF
Misc:
   CTI

Device Tree Bindings
--------------------

See Documentation/devicetree/bindings/arm/arm,coresight-\*.yaml for details.

As of this writing drivers for ITM, STMs and CTIs are not provided but are
expected to be added as the solution matures.

Framework and implementation
----------------------------

The coresight framework provides a central point to represent, configure and
manage coresight devices on a platform.  Any coresight compliant device can
register with the framework for as long as they use the right APIs:

.. c:function:: struct coresight_device *coresight_register(struct coresight_desc *desc);
.. c:function:: void coresight_unregister(struct coresight_device *csdev);

The registering function is taking a ``struct coresight_desc *desc`` and
register the device with the core framework. The unregister function takes
a reference to a ``struct coresight_device *csdev`` obtained at registration time.

If everything goes well during the registration process the new devices will
show up under /sys/bus/coresight/devices, as showns here for a TC2 platform::

    root:~# ls /sys/bus/coresight/devices/
    replicator  20030000.tpiu    2201c000.ptm  2203c000.etm  2203e000.etm
    20010000.etb         20040000.funnel  2201d000.ptm  2203d000.etm
    root:~#

The functions take a ``struct coresight_device``, which looks like this::

    struct coresight_desc {
            enum coresight_dev_type type;
            struct coresight_dev_subtype subtype;
            const struct coresight_ops *ops;
            struct coresight_platform_data *pdata;
            struct device *dev;
            const struct attribute_group **groups;
    };

The "coresight_dev_type" identifies what the device is, i.e, source link or
sink while the "coresight_dev_subtype" will characterise that type further.

The ``struct coresight_ops`` is mandatory and will tell the framework how to
perform base operations related to the components, each component having
a different set of requirement. For that ``struct coresight_ops_sink``,
``struct coresight_ops_link`` and ``struct coresight_ops_source`` have been
provided.

The next field ``struct coresight_platform_data *pdata`` is acquired by calling
``of_get_coresight_platform_data()``, as part of the driver's _probe routine and
``struct device *dev`` gets the device reference embedded in the ``amba_device``::

    static int etm_probe(struct amba_device *adev, const struct amba_id *id)
    {
     ...
     ...
     drvdata->dev = &adev->dev;
     ...
    }

Specific class of device (source, link, or sink) have generic operations
that can be performed on them (see ``struct coresight_ops``). The ``**groups``
is a list of sysfs entries pertaining to operations
specific to that component only.  "Implementation defined" customisations are
expected to be accessed and controlled using those entries.

Device Naming scheme
--------------------

The devices that appear on the "coresight" bus were named the same as their
parent devices, i.e, the real devices that appears on AMBA bus or the platform bus.
Thus the names were based on the Linux Open Firmware layer naming convention,
which follows the base physical address of the device followed by the device
type. e.g::

    root:~# ls /sys/bus/coresight/devices/
     20010000.etf  20040000.funnel      20100000.stm     22040000.etm
     22140000.etm  230c0000.funnel      23240000.etm     20030000.tpiu
     20070000.etr  20120000.replicator  220c0000.funnel
     23040000.etm  23140000.etm         23340000.etm

However, with the introduction of ACPI support, the names of the real
devices are a bit cryptic and non-obvious. Thus, a new naming scheme was
introduced to use more generic names based on the type of the device. The
following rules apply::

  1) Devices that are bound to CPUs, are named based on the CPU logical
     number.

     e.g, ETM bound to CPU0 is named "etm0"

  2) All other devices follow a pattern, "<device_type_prefix>N", where :

	<device_type_prefix> 	- A prefix specific to the type of the device
	N			- a sequential number assigned based on the order
				  of probing.

	e.g, tmc_etf0, tmc_etr0, funnel0, funnel1

Thus, with the new scheme the devices could appear as ::

    root:~# ls /sys/bus/coresight/devices/
     etm0     etm1     etm2         etm3  etm4      etm5      funnel0
     funnel1  funnel2  replicator0  stm0  tmc_etf0  tmc_etr0  tpiu0

Some of the examples below might refer to old naming scheme and some
to the newer scheme, to give a confirmation that what you see on your
system is not unexpected. One must use the "names" as they appear on
the system under specified locations.

Topology Representation
-----------------------

Each CoreSight component has a ``connections`` directory which will contain
links to other CoreSight components. This allows the user to explore the trace
topology and for larger systems, determine the most appropriate sink for a
given source. The connection information can also be used to establish
which CTI devices are connected to a given component. This directory contains a
``nr_links`` attribute detailing the number of links in the directory.

For an ETM source, in this case ``etm0`` on a Juno platform, a typical
arrangement will be::

  linaro-developer:~# ls - l /sys/bus/coresight/devices/etm0/connections
  <file details>  cti_cpu0 -> ../../../23020000.cti/cti_cpu0
  <file details>  nr_links
  <file details>  out:0 -> ../../../230c0000.funnel/funnel2

Following the out port to ``funnel2``::

  linaro-developer:~# ls -l /sys/bus/coresight/devices/funnel2/connections
  <file details> in:0 -> ../../../23040000.etm/etm0
  <file details> in:1 -> ../../../23140000.etm/etm3
  <file details> in:2 -> ../../../23240000.etm/etm4
  <file details> in:3 -> ../../../23340000.etm/etm5
  <file details> nr_links
  <file details> out:0 -> ../../../20040000.funnel/funnel0

And again to ``funnel0``::

  linaro-developer:~# ls -l /sys/bus/coresight/devices/funnel0/connections
  <file details> in:0 -> ../../../220c0000.funnel/funnel1
  <file details> in:1 -> ../../../230c0000.funnel/funnel2
  <file details> nr_links
  <file details> out:0 -> ../../../20010000.etf/tmc_etf0

Finding the first sink ``tmc_etf0``. This can be used to collect data
as a sink, or as a link to propagate further along the chain::

  linaro-developer:~# ls -l /sys/bus/coresight/devices/tmc_etf0/connections
  <file details> cti_sys0 -> ../../../20020000.cti/cti_sys0
  <file details> in:0 -> ../../../20040000.funnel/funnel0
  <file details> nr_links
  <file details> out:0 -> ../../../20150000.funnel/funnel4

via ``funnel4``::

  linaro-developer:~# ls -l /sys/bus/coresight/devices/funnel4/connections
  <file details> in:0 -> ../../../20010000.etf/tmc_etf0
  <file details> in:1 -> ../../../20140000.etf/tmc_etf1
  <file details> nr_links
  <file details> out:0 -> ../../../20120000.replicator/replicator0

and a ``replicator0``::

  linaro-developer:~# ls -l /sys/bus/coresight/devices/replicator0/connections
  <file details> in:0 -> ../../../20150000.funnel/funnel4
  <file details> nr_links
  <file details> out:0 -> ../../../20030000.tpiu/tpiu0
  <file details> out:1 -> ../../../20070000.etr/tmc_etr0

Arriving at the final sink in the chain, ``tmc_etr0``::

  linaro-developer:~# ls -l /sys/bus/coresight/devices/tmc_etr0/connections
  <file details> cti_sys0 -> ../../../20020000.cti/cti_sys0
  <file details> in:0 -> ../../../20120000.replicator/replicator0
  <file details> nr_links

As described below, when using sysfs it is sufficient to enable a sink and
a source for successful trace. The framework will correctly enable all
intermediate links as required.

Note: ``cti_sys0`` appears in two of the connections lists above.
CTIs can connect to multiple devices and are arranged in a star topology
via the CTM. See (Documentation/trace/coresight/coresight-ect.rst)
[#fourth]_ for further details.
Looking at this device we see 4 connections::

  linaro-developer:~# ls -l /sys/bus/coresight/devices/cti_sys0/connections
  <file details> nr_links
  <file details> stm0 -> ../../../20100000.stm/stm0
  <file details> tmc_etf0 -> ../../../20010000.etf/tmc_etf0
  <file details> tmc_etr0 -> ../../../20070000.etr/tmc_etr0
  <file details> tpiu0 -> ../../../20030000.tpiu/tpiu0

How to use the tracer modules
-----------------------------

There are two ways to use the Coresight framework:

1. using the perf cmd line tools.
2. interacting directly with the Coresight devices using the sysFS interface.

Preference is given to the former as using the sysFS interface
requires a deep understanding of the Coresight HW.  The following sections
provide details on using both methods.

Using the sysFS interface
~~~~~~~~~~~~~~~~~~~~~~~~~

Before trace collection can start, a coresight sink needs to be identified.
There is no limit on the amount of sinks (nor sources) that can be enabled at
any given moment.  As a generic operation, all device pertaining to the sink
class will have an "active" entry in sysfs::

    root:/sys/bus/coresight/devices# ls
    replicator  20030000.tpiu    2201c000.ptm  2203c000.etm  2203e000.etm
    20010000.etb         20040000.funnel  2201d000.ptm  2203d000.etm
    root:/sys/bus/coresight/devices# ls 20010000.etb
    enable_sink  status  trigger_cntr
    root:/sys/bus/coresight/devices# echo 1 > 20010000.etb/enable_sink
    root:/sys/bus/coresight/devices# cat 20010000.etb/enable_sink
    1
    root:/sys/bus/coresight/devices#

At boot time the current etm3x driver will configure the first address
comparator with "_stext" and "_etext", essentially tracing any instruction
that falls within that range.  As such "enabling" a source will immediately
trigger a trace capture::

    root:/sys/bus/coresight/devices# echo 1 > 2201c000.ptm/enable_source
    root:/sys/bus/coresight/devices# cat 2201c000.ptm/enable_source
    1
    root:/sys/bus/coresight/devices# cat 20010000.etb/status
    Depth:          0x2000
    Status:         0x1
    RAM read ptr:   0x0
    RAM wrt ptr:    0x19d3   <----- The write pointer is moving
    Trigger cnt:    0x0
    Control:        0x1
    Flush status:   0x0
    Flush ctrl:     0x2001
    root:/sys/bus/coresight/devices#

Trace collection is stopped the same way::

    root:/sys/bus/coresight/devices# echo 0 > 2201c000.ptm/enable_source
    root:/sys/bus/coresight/devices#

The content of the ETB buffer can be harvested directly from /dev::

    root:/sys/bus/coresight/devices# dd if=/dev/20010000.etb \
    of=~/cstrace.bin
    64+0 records in
    64+0 records out
    32768 bytes (33 kB) copied, 0.00125258 s, 26.2 MB/s
    root:/sys/bus/coresight/devices#

The file cstrace.bin can be decompressed using "ptm2human", DS-5 or Trace32.

Following is a DS-5 output of an experimental loop that increments a variable up
to a certain value.  The example is simple and yet provides a glimpse of the
wealth of possibilities that coresight provides.
::

    Info                                    Tracing enabled
    Instruction     106378866       0x8026B53C      E52DE004        false   PUSH     {lr}
    Instruction     0       0x8026B540      E24DD00C        false   SUB      sp,sp,#0xc
    Instruction     0       0x8026B544      E3A03000        false   MOV      r3,#0
    Instruction     0       0x8026B548      E58D3004        false   STR      r3,[sp,#4]
    Instruction     0       0x8026B54C      E59D3004        false   LDR      r3,[sp,#4]
    Instruction     0       0x8026B550      E3530004        false   CMP      r3,#4
    Instruction     0       0x8026B554      E2833001        false   ADD      r3,r3,#1
    Instruction     0       0x8026B558      E58D3004        false   STR      r3,[sp,#4]
    Instruction     0       0x8026B55C      DAFFFFFA        true    BLE      {pc}-0x10 ; 0x8026b54c
    Timestamp                                       Timestamp: 17106715833
    Instruction     319     0x8026B54C      E59D3004        false   LDR      r3,[sp,#4]
    Instruction     0       0x8026B550      E3530004        false   CMP      r3,#4
    Instruction     0       0x8026B554      E2833001        false   ADD      r3,r3,#1
    Instruction     0       0x8026B558      E58D3004        false   STR      r3,[sp,#4]
    Instruction     0       0x8026B55C      DAFFFFFA        true    BLE      {pc}-0x10 ; 0x8026b54c
    Instruction     9       0x8026B54C      E59D3004        false   LDR      r3,[sp,#4]
    Instruction     0       0x8026B550      E3530004        false   CMP      r3,#4
    Instruction     0       0x8026B554      E2833001        false   ADD      r3,r3,#1
    Instruction     0       0x8026B558      E58D3004        false   STR      r3,[sp,#4]
    Instruction     0       0x8026B55C      DAFFFFFA        true    BLE      {pc}-0x10 ; 0x8026b54c
    Instruction     7       0x8026B54C      E59D3004        false   LDR      r3,[sp,#4]
    Instruction     0       0x8026B550      E3530004        false   CMP      r3,#4
    Instruction     0       0x8026B554      E2833001        false   ADD      r3,r3,#1
    Instruction     0       0x8026B558      E58D3004        false   STR      r3,[sp,#4]
    Instruction     0       0x8026B55C      DAFFFFFA        true    BLE      {pc}-0x10 ; 0x8026b54c
    Instruction     7       0x8026B54C      E59D3004        false   LDR      r3,[sp,#4]
    Instruction     0       0x8026B550      E3530004        false   CMP      r3,#4
    Instruction     0       0x8026B554      E2833001        false   ADD      r3,r3,#1
    Instruction     0       0x8026B558      E58D3004        false   STR      r3,[sp,#4]
    Instruction     0       0x8026B55C      DAFFFFFA        true    BLE      {pc}-0x10 ; 0x8026b54c
    Instruction     10      0x8026B54C      E59D3004        false   LDR      r3,[sp,#4]
    Instruction     0       0x8026B550      E3530004        false   CMP      r3,#4
    Instruction     0       0x8026B554      E2833001        false   ADD      r3,r3,#1
    Instruction     0       0x8026B558      E58D3004        false   STR      r3,[sp,#4]
    Instruction     0       0x8026B55C      DAFFFFFA        true    BLE      {pc}-0x10 ; 0x8026b54c
    Instruction     6       0x8026B560      EE1D3F30        false   MRC      p15,#0x0,r3,c13,c0,#1
    Instruction     0       0x8026B564      E1A0100D        false   MOV      r1,sp
    Instruction     0       0x8026B568      E3C12D7F        false   BIC      r2,r1,#0x1fc0
    Instruction     0       0x8026B56C      E3C2203F        false   BIC      r2,r2,#0x3f
    Instruction     0       0x8026B570      E59D1004        false   LDR      r1,[sp,#4]
    Instruction     0       0x8026B574      E59F0010        false   LDR      r0,[pc,#16] ; [0x8026B58C] = 0x80550368
    Instruction     0       0x8026B578      E592200C        false   LDR      r2,[r2,#0xc]
    Instruction     0       0x8026B57C      E59221D0        false   LDR      r2,[r2,#0x1d0]
    Instruction     0       0x8026B580      EB07A4CF        true    BL       {pc}+0x1e9344 ; 0x804548c4
    Info                                    Tracing enabled
    Instruction     13570831        0x8026B584      E28DD00C        false   ADD      sp,sp,#0xc
    Instruction     0       0x8026B588      E8BD8000        true    LDM      sp!,{pc}
    Timestamp                                       Timestamp: 17107041535

Using perf framework
~~~~~~~~~~~~~~~~~~~~

Coresight tracers are represented using the Perf framework's Performance
Monitoring Unit (PMU) abstraction.  As such the perf framework takes charge of
controlling when tracing gets enabled based on when the process of interest is
scheduled.  When configured in a system, Coresight PMUs will be listed when
queried by the perf command line tool:

	linaro@linaro-nano:~$ ./perf list pmu

		List of pre-defined events (to be used in -e):

		cs_etm//                                    [Kernel PMU event]

	linaro@linaro-nano:~$

Regardless of the number of tracers available in a system (usually equal to the
amount of processor cores), the "cs_etm" PMU will be listed only once.

A Coresight PMU works the same way as any other PMU, i.e the name of the PMU is
listed along with configuration options within forward slashes '/'.  Since a
Coresight system will typically have more than one sink, the name of the sink to
work with needs to be specified as an event option.
On newer kernels the available sinks are listed in sysFS under
($SYSFS)/bus/event_source/devices/cs_etm/sinks/::

	root@localhost:/sys/bus/event_source/devices/cs_etm/sinks# ls
	tmc_etf0  tmc_etr0  tpiu0

On older kernels, this may need to be found from the list of coresight devices,
available under ($SYSFS)/bus/coresight/devices/::

	root:~# ls /sys/bus/coresight/devices/
	 etm0     etm1     etm2         etm3  etm4      etm5      funnel0
	 funnel1  funnel2  replicator0  stm0  tmc_etf0  tmc_etr0  tpiu0
	root@linaro-nano:~# perf record -e cs_etm/@tmc_etr0/u --per-thread program

As mentioned above in section "Device Naming scheme", the names of the devices could
look different from what is used in the example above. One must use the device names
as it appears under the sysFS.

The syntax within the forward slashes '/' is important.  The '@' character
tells the parser that a sink is about to be specified and that this is the sink
to use for the trace session.

More information on the above and other example on how to use Coresight with
the perf tools can be found in the "HOWTO.md" file of the openCSD gitHub
repository [#third]_.

Advanced perf framework usage
-----------------------------

AutoFDO analysis using the perf tools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

perf can be used to record and analyze trace of programs.

Execution can be recorded using 'perf record' with the cs_etm event,
specifying the name of the sink to record to, e.g::

    perf record -e cs_etm/@tmc_etr0/u --per-thread

The 'perf report' and 'perf script' commands can be used to analyze execution,
synthesizing instruction and branch events from the instruction trace.
'perf inject' can be used to replace the trace data with the synthesized events.
The --itrace option controls the type and frequency of synthesized events
(see perf documentation).

Note that only 64-bit programs are currently supported - further work is
required to support instruction decode of 32-bit Arm programs.

Tracing PID
~~~~~~~~~~~

The kernel can be built to write the PID value into the PE ContextID registers.
For a kernel running at EL1, the PID is stored in CONTEXTIDR_EL1.  A PE may
implement Arm Virtualization Host Extensions (VHE), which the kernel can
run at EL2 as a virtualisation host; in this case, the PID value is stored in
CONTEXTIDR_EL2.

perf provides PMU formats that program the ETM to insert these values into the
trace data; the PMU formats are defined as below:

  "contextid1": Available on both EL1 kernel and EL2 kernel.  When the
                kernel is running at EL1, "contextid1" enables the PID
                tracing; when the kernel is running at EL2, this enables
                tracing the PID of guest applications.

  "contextid2": Only usable when the kernel is running at EL2.  When
                selected, enables PID tracing on EL2 kernel.

  "contextid":  Will be an alias for the option that enables PID
                tracing.  I.e,
                contextid == contextid1, on EL1 kernel.
                contextid == contextid2, on EL2 kernel.

perf will always enable PID tracing at the relevant EL, this is accomplished by
automatically enable the "contextid" config - but for EL2 it is possible to make
specific adjustments using configs "contextid1" and "contextid2", E.g. if a user
wants to trace PIDs for both host and guest, the two configs "contextid1" and
"contextid2" can be set at the same time:

  perf record -e cs_etm/contextid1,contextid2/u -- vm

Generating coverage files for Feedback Directed Optimization: AutoFDO
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

'perf inject' accepts the --itrace option in which case tracing data is
removed and replaced with the synthesized events. e.g.
::

	perf inject --itrace --strip -i perf.data -o perf.data.new

Below is an example of using ARM ETM for autoFDO.  It requires autofdo
(https://github.com/google/autofdo) and gcc version 5.  The bubble
sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tutorial).
::

	$ gcc-5 -O3 sort.c -o sort
	$ taskset -c 2 ./sort
	Bubble sorting array of 30000 elements
	5910 ms

	$ perf record -e cs_etm/@tmc_etr0/u --per-thread taskset -c 2 ./sort
	Bubble sorting array of 30000 elements
	12543 ms
	[ perf record: Woken up 35 times to write data ]
	[ perf record: Captured and wrote 69.640 MB perf.data ]

	$ perf inject -i perf.data -o inj.data --itrace=il64 --strip
	$ create_gcov --binary=./sort --profile=inj.data --gcov=sort.gcov -gcov_version=1
	$ gcc-5 -O3 -fauto-profile=sort.gcov sort.c -o sort_autofdo
	$ taskset -c 2 ./sort_autofdo
	Bubble sorting array of 30000 elements
	5806 ms

Config option formats
~~~~~~~~~~~~~~~~~~~~~

The following strings can be provided between // on the perf command line to enable various options.
They are also listed in the folder /sys/bus/event_source/devices/cs_etm/format/

.. list-table::
   :header-rows: 1

   * - Option
     - Description
   * - branch_broadcast
     - Session local version of the system wide setting:
       :ref:`ETM_MODE_BB <coresight-branch-broadcast>`
   * - contextid
     - See `Tracing PID`_
   * - contextid1
     - See `Tracing PID`_
   * - contextid2
     - See `Tracing PID`_
   * - configid
     - Selection for a custom configuration. This is an implementation detail and not used directly,
       see :ref:`trace/coresight/coresight-config:Using Configurations in perf`
   * - preset
     - Override for parameters in a custom configuration, see
       :ref:`trace/coresight/coresight-config:Using Configurations in perf`
   * - sinkid
     - Hashed version of the string to select a sink, automatically set when using the @ notation.
       This is an internal implementation detail and is not used directly, see `Using perf
       framework`_.
   * - cycacc
     - Session local version of the system wide setting: :ref:`ETMv4_MODE_CYCACC
       <coresight-cycle-accurate>`
   * - retstack
     - Session local version of the system wide setting: :ref:`ETM_MODE_RETURNSTACK
       <coresight-return-stack>`
   * - timestamp
     - Session local version of the system wide setting: :ref:`ETMv4_MODE_TIMESTAMP
       <coresight-timestamp>`

How to use the STM module
-------------------------

Using the System Trace Macrocell module is the same as the tracers - the only
difference is that clients are driving the trace capture rather
than the program flow through the code.

As with any other CoreSight component, specifics about the STM tracer can be
found in sysfs with more information on each entry being found in [#first]_::

    root@genericarmv8:~# ls /sys/bus/coresight/devices/stm0
    enable_source   hwevent_select  port_enable     subsystem       uevent
    hwevent_enable  mgmt            port_select     traceid
    root@genericarmv8:~#

Like any other source a sink needs to be identified and the STM enabled before
being used::

    root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/tmc_etf0/enable_sink
    root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/stm0/enable_source

From there user space applications can request and use channels using the devfs
interface provided for that purpose by the generic STM API::

    root@genericarmv8:~# ls -l /dev/stm0
    crw-------    1 root     root       10,  61 Jan  3 18:11 /dev/stm0
    root@genericarmv8:~#

Details on how to use the generic STM API can be found here:
- Documentation/trace/stm.rst [#second]_.

The CTI & CTM Modules
---------------------

The CTI (Cross Trigger Interface) provides a set of trigger signals between
individual CTIs and components, and can propagate these between all CTIs via
channels on the CTM (Cross Trigger Matrix).

A separate documentation file is provided to explain the use of these devices.
(Documentation/trace/coresight/coresight-ect.rst) [#fourth]_.

CoreSight System Configuration
------------------------------

CoreSight components can be complex devices with many programming options.
Furthermore, components can be programmed to interact with each other across the
complete system.

A CoreSight System Configuration manager is provided to allow these complex programming
configurations to be selected and used easily from perf and sysfs.

See the separate document for further information.
(Documentation/trace/coresight/coresight-config.rst) [#fifth]_.

.. [#first] Documentation/ABI/testing/sysfs-bus-coresight-devices-stm

.. [#second] Documentation/trace/stm.rst

.. [#third] https://github.com/Linaro/perf-opencsd

.. [#fourth] Documentation/trace/coresight/coresight-ect.rst

.. [#fifth] Documentation/trace/coresight/coresight-config.rst

repo_name: angery/linux


code:
============================
Subsystem Trace Points: kmem
============================

The kmem tracing system captures events related to object and page allocation
within the kernel. Broadly speaking there are five major subheadings.

  - Slab allocation of small objects of unknown type (kmalloc)
  - Slab allocation of small objects of known type
  - Page allocation
  - Per-CPU Allocator Activity
  - External Fragmentation

This document describes what each of the tracepoints is and why they
might be useful.

1. Slab allocation of small objects of unknown type
===================================================
::

  kmalloc		call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s
  kmalloc_node	call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d
  kfree		call_site=%lx ptr=%p

Heavy activity for these events may indicate that a specific cache is
justified, particularly if kmalloc slab pages are getting significantly
internal fragmented as a result of the allocation pattern. By correlating
kmalloc with kfree, it may be possible to identify memory leaks and where
the allocation sites were.

2. Slab allocation of small objects of known type
=================================================
::

  kmem_cache_alloc	call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s
  kmem_cache_alloc_node	call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d
  kmem_cache_free		call_site=%lx ptr=%p

These events are similar in usage to the kmalloc-related events except that
it is likely easier to pin the event down to a specific cache. At the time
of writing, no information is available on what slab is being allocated from,
but the call_site can usually be used to extrapolate that information.

3. Page allocation
==================
::

  mm_page_alloc		  page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s
  mm_page_alloc_zone_locked page=%p pfn=%lu order=%u migratetype=%d cpu=%d percpu_refill=%d
  mm_page_free		  page=%p pfn=%lu order=%d
  mm_page_free_batched	  page=%p pfn=%lu order=%d cold=%d

These four events deal with page allocation and freeing. mm_page_alloc is
a simple indicator of page allocator activity. Pages may be allocated from
the per-CPU allocator (high performance) or the buddy allocator.

If pages are allocated directly from the buddy allocator, the
mm_page_alloc_zone_locked event is triggered. This event is important as high
amounts of activity imply high activity on the zone->lock. Taking this lock
impairs performance by disabling interrupts, dirtying cache lines between
CPUs and serialising many CPUs.

When a page is freed directly by the caller, the only mm_page_free event
is triggered. Significant amounts of activity here could indicate that the
callers should be batching their activities.

When pages are freed in batch, the also mm_page_free_batched is triggered.
Broadly speaking, pages are taken off the LRU lock in bulk and
freed in batch with a page list. Significant amounts of activity here could
indicate that the system is under memory pressure and can also indicate
contention on the lruvec->lru_lock.

4. Per-CPU Allocator Activity
=============================
::

  mm_page_alloc_zone_locked	page=%p pfn=%lu order=%u migratetype=%d cpu=%d percpu_refill=%d
  mm_page_pcpu_drain		page=%p pfn=%lu order=%d cpu=%d migratetype=%d

In front of the page allocator is a per-cpu page allocator. It exists only
for order-0 pages, reduces contention on the zone->lock and reduces the
amount of writing on struct page.

When a per-CPU list is empty or pages of the wrong type are allocated,
the zone->lock will be taken once and the per-CPU list refilled. The event
triggered is mm_page_alloc_zone_locked for each page allocated with the
event indicating whether it is for a percpu_refill or not.

When the per-CPU list is too full, a number of pages are freed, each one
which triggers a mm_page_pcpu_drain event.

The individual nature of the events is so that pages can be tracked
between allocation and freeing. A number of drain or refill pages that occur
consecutively imply the zone->lock being taken once. Large amounts of per-CPU
refills and drains could imply an imbalance between CPUs where too much work
is being concentrated in one place. It could also indicate that the per-CPU
lists should be a larger size. Finally, large amounts of refills on one CPU
and drains on another could be a factor in causing large amounts of cache
line bounces due to writes between CPUs and worth investigating if pages
can be allocated and freed on the same CPU through some algorithm change.

5. External Fragmentation
=========================
::

  mm_page_alloc_extfrag		page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d

External fragmentation affects whether a high-order allocation will be
successful or not. For some types of hardware, this is important although
it is avoided where possible. If the system is using huge pages and needs
to be able to resize the pool over the lifetime of the system, this value
is important.

Large numbers of this event implies that memory is fragmenting and
high-order allocations will start failing at some time in the future. One
means of reducing the occurrence of this event is to increase the size of
min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where
pageblock_size is usually the size of the default hugepage size.


code:
================
MSR Trace Events
================

The x86 kernel supports tracing most MSR (Model Specific Register) accesses.
To see the definition of the MSRs on Intel systems please see the SDM
at https://www.intel.com/sdm (Volume 3)

Available trace points:

/sys/kernel/debug/tracing/events/msr/

Trace MSR reads:

read_msr

  - msr: MSR number
  - val: Value written
  - failed: 1 if the access failed, otherwise 0

Trace MSR writes:

write_msr

  - msr: MSR number
  - val: Value written
  - failed: 1 if the access failed, otherwise 0

Trace RDPMC in kernel:

rdpmc

The trace data can be post processed with the postprocess/decode_msr.py script::

  cat /sys/kernel/debug/tracing/trace | decode_msr.py /usr/src/linux/include/asm/msr-index.h

to add symbolic MSR names.


code:
================
NMI Trace Events
================

These events normally show up here:

	/sys/kernel/debug/tracing/events/nmi

nmi_handler
-----------

You might want to use this tracepoint if you suspect that your
NMI handlers are hogging large amounts of CPU time.  The kernel
will warn if it sees long-running handlers::

	INFO: NMI handler took too long to run: 9.207 msecs

and this tracepoint will allow you to drill down and get some
more details.

Let's say you suspect that perf_event_nmi_handler() is causing
you some problems and you only want to trace that handler
specifically.  You need to find its address::

	$ grep perf_event_nmi_handler /proc/kallsyms
	ffffffff81625600 t perf_event_nmi_handler

Let's also say you are only interested in when that function is
really hogging a lot of CPU time, like a millisecond at a time.
Note that the kernel's output is in milliseconds, but the input
to the filter is in nanoseconds!  You can filter on 'delta_ns'::

	cd /sys/kernel/debug/tracing/events/nmi/nmi_handler
	echo 'handler==0xffffffff81625600 && delta_ns>1000000' > filter
	echo 1 > enable

Your output would then look like::

	$ cat /sys/kernel/debug/tracing/trace_pipe
	<idle>-0     [000] d.h3   505.397558: nmi_handler: perf_event_nmi_handler() delta_ns: 3236765 handled: 1
	<idle>-0     [000] d.h3   505.805893: nmi_handler: perf_event_nmi_handler() delta_ns: 3174234 handled: 1
	<idle>-0     [000] d.h3   506.158206: nmi_handler: perf_event_nmi_handler() delta_ns: 3084642 handled: 1
	<idle>-0     [000] d.h3   506.334346: nmi_handler: perf_event_nmi_handler() delta_ns: 3080351 handled: 1


code:
=============================
Subsystem Trace Points: power
=============================

The power tracing system captures events related to power transitions
within the kernel. Broadly speaking there are three major subheadings:

  - Power state switch which reports events related to suspend (S-states),
    cpuidle (C-states) and cpufreq (P-states)
  - System clock related changes
  - Power domains related changes and transitions

This document describes what each of the tracepoints is and why they
might be useful.

Cf. include/trace/events/power.h for the events definitions.

1. Power state switch events
============================

1.1 Trace API
-----------------

A 'cpu' event class gathers the CPU-related events: cpuidle and
cpufreq.
::

  cpu_idle		"state=%lu cpu_id=%lu"
  cpu_frequency		"state=%lu cpu_id=%lu"
  cpu_frequency_limits	"min=%lu max=%lu cpu_id=%lu"

A suspend event is used to indicate the system going in and out of the
suspend mode:
::

  machine_suspend		"state=%lu"

Note: the value of '-1' or '4294967295' for state means an exit from the current state,
i.e. trace_cpu_idle(4, smp_processor_id()) means that the system
enters the idle state 4, while trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id())
means that the system exits the previous idle state.

The event which has 'state=4294967295' in the trace is very important to the user
space tools which are using it to detect the end of the current state, and so to
correctly draw the states diagrams and to calculate accurate statistics etc.

2. Clocks events
================
The clock events are used for clock enable/disable and for
clock rate change.
::

  clock_enable		"%s state=%lu cpu_id=%lu"
  clock_disable		"%s state=%lu cpu_id=%lu"
  clock_set_rate		"%s state=%lu cpu_id=%lu"

The first parameter gives the clock name (e.g. "gpio1_iclk").
The second parameter is '1' for enable, '0' for disable, the target
clock rate for set_rate.

3. Power domains events
=======================
The power domain events are used for power domains transitions
::

  power_domain_target	"%s state=%lu cpu_id=%lu"

The first parameter gives the power domain name (e.g. "mpu_pwrdm").
The second parameter is the power domain target state.

4. PM QoS events
================
The PM QoS events are used for QoS add/update/remove request and for
target/flags update.
::

  pm_qos_update_target               "action=%s prev_value=%d curr_value=%d"
  pm_qos_update_flags                "action=%s prev_value=0x%x curr_value=0x%x"

The first parameter gives the QoS action name (e.g. "ADD_REQ").
The second parameter is the previous QoS value.
The third parameter is the current QoS value to update.

There are also events used for device PM QoS add/update/remove request.
::

  dev_pm_qos_add_request             "device=%s type=%s new_value=%d"
  dev_pm_qos_update_request          "device=%s type=%s new_value=%d"
  dev_pm_qos_remove_request          "device=%s type=%s new_value=%d"

The first parameter gives the device name which tries to add/update/remove
QoS requests.
The second parameter gives the request type (e.g. "DEV_PM_QOS_RESUME_LATENCY").
The third parameter is value to be added/updated/removed.

And, there are events used for CPU latency QoS add/update/remove request.
::

  pm_qos_add_request        "value=%d"
  pm_qos_update_request     "value=%d"
  pm_qos_remove_request     "value=%d"

The parameter is the value to be added/updated/removed.


code:
=============
Event Tracing
=============

:Author: Theodore Ts'o
:Updated: Li Zefan and Tom Zanussi

1. Introduction
===============

Tracepoints (see Documentation/trace/tracepoints.rst) can be used
without creating custom kernel modules to register probe functions
using the event tracing infrastructure.

Not all tracepoints can be traced using the event tracing system;
the kernel developer must provide code snippets which define how the
tracing information is saved into the tracing buffer, and how the
tracing information should be printed.

2. Using Event Tracing
======================

2.1 Via the 'set_event' interface
---------------------------------

The events which are available for tracing can be found in the file
/sys/kernel/debug/tracing/available_events.

To enable a particular event, such as 'sched_wakeup', simply echo it
to /sys/kernel/debug/tracing/set_event. For example::

	# echo sched_wakeup >> /sys/kernel/debug/tracing/set_event

.. Note:: '>>' is necessary, otherwise it will firstly disable all the events.

To disable an event, echo the event name to the set_event file prefixed
with an exclamation point::

	# echo '!sched_wakeup' >> /sys/kernel/debug/tracing/set_event

To disable all events, echo an empty line to the set_event file::

	# echo > /sys/kernel/debug/tracing/set_event

To enable all events, echo ``*:*`` or ``*:`` to the set_event file::

	# echo *:* > /sys/kernel/debug/tracing/set_event

The events are organized into subsystems, such as ext4, irq, sched,
etc., and a full event name looks like this: <subsystem>:<event>.  The
subsystem name is optional, but it is displayed in the available_events
file.  All of the events in a subsystem can be specified via the syntax
``<subsystem>:*``; for example, to enable all irq events, you can use the
command::

	# echo 'irq:*' > /sys/kernel/debug/tracing/set_event

2.2 Via the 'enable' toggle
---------------------------

The events available are also listed in /sys/kernel/debug/tracing/events/ hierarchy
of directories.

To enable event 'sched_wakeup'::

	# echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable

To disable it::

	# echo 0 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable

To enable all events in sched subsystem::

	# echo 1 > /sys/kernel/debug/tracing/events/sched/enable

To enable all events::

	# echo 1 > /sys/kernel/debug/tracing/events/enable

When reading one of these enable files, there are four results:

 - 0 - all events this file affects are disabled
 - 1 - all events this file affects are enabled
 - X - there is a mixture of events enabled and disabled
 - ? - this file does not affect any event

2.3 Boot option
---------------

In order to facilitate early boot debugging, use boot option::

	trace_event=[event-list]

event-list is a comma separated list of events. See section 2.1 for event
format.

3. Defining an event-enabled tracepoint
=======================================

See The example provided in samples/trace_events

4. Event formats
================

Each trace event has a 'format' file associated with it that contains
a description of each field in a logged event.  This information can
be used to parse the binary trace stream, and is also the place to
find the field names that can be used in event filters (see section 5).

It also displays the format string that will be used to print the
event in text mode, along with the event name and ID used for
profiling.

Every event has a set of ``common`` fields associated with it; these are
the fields prefixed with ``common_``.  The other fields vary between
events and correspond to the fields defined in the TRACE_EVENT
definition for that event.

Each field in the format has the form::

     field:field-type field-name; offset:N; size:N;

where offset is the offset of the field in the trace record and size
is the size of the data item, in bytes.

For example, here's the information displayed for the 'sched_wakeup'
event::

	# cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/format

	name: sched_wakeup
	ID: 60
	format:
		field:unsigned short common_type;	offset:0;	size:2;
		field:unsigned char common_flags;	offset:2;	size:1;
		field:unsigned char common_preempt_count;	offset:3;	size:1;
		field:int common_pid;	offset:4;	size:4;
		field:int common_tgid;	offset:8;	size:4;

		field:char comm[TASK_COMM_LEN];	offset:12;	size:16;
		field:pid_t pid;	offset:28;	size:4;
		field:int prio;	offset:32;	size:4;
		field:int success;	offset:36;	size:4;
		field:int cpu;	offset:40;	size:4;

	print fmt: "task %s:%d [%d] success=%d [%03d]", REC->comm, REC->pid,
		   REC->prio, REC->success, REC->cpu

This event contains 10 fields, the first 5 common and the remaining 5
event-specific.  All the fields for this event are numeric, except for
'comm' which is a string, a distinction important for event filtering.

5. Event filtering
==================

Trace events can be filtered in the kernel by associating boolean
'filter expressions' with them.  As soon as an event is logged into
the trace buffer, its fields are checked against the filter expression
associated with that event type.  An event with field values that
'match' the filter will appear in the trace output, and an event whose
values don't match will be discarded.  An event with no filter
associated with it matches everything, and is the default when no
filter has been set for an event.

5.1 Expression syntax
---------------------

A filter expression consists of one or more 'predicates' that can be
combined using the logical operators '&&' and '||'.  A predicate is
simply a clause that compares the value of a field contained within a
logged event with a constant value and returns either 0 or 1 depending
on whether the field value matched (1) or didn't match (0)::

	  field-name relational-operator value

Parentheses can be used to provide arbitrary logical groupings and
double-quotes can be used to prevent the shell from interpreting
operators as shell metacharacters.

The field-names available for use in filters can be found in the
'format' files for trace events (see section 4).

The relational-operators depend on the type of the field being tested:

The operators available for numeric fields are:

==, !=, <, <=, >, >=, &

And for string fields they are:

==, !=, ~

The glob (~) accepts a wild card character (\*,?) and character classes
([). For example::

  prev_comm ~ "*sh"
  prev_comm ~ "sh*"
  prev_comm ~ "*sh*"
  prev_comm ~ "ba*sh"

If the field is a pointer that points into user space (for example
"filename" from sys_enter_openat), then you have to append ".ustring" to the
field name::

  filename.ustring ~ "password"

As the kernel will have to know how to retrieve the memory that the pointer
is at from user space.

5.2 Setting filters
-------------------

A filter for an individual event is set by writing a filter expression
to the 'filter' file for the given event.

For example::

	# cd /sys/kernel/debug/tracing/events/sched/sched_wakeup
	# echo "common_preempt_count > 4" > filter

A slightly more involved example::

	# cd /sys/kernel/debug/tracing/events/signal/signal_generate
	# echo "((sig >= 10 && sig < 15) || sig == 17) && comm != bash" > filter

If there is an error in the expression, you'll get an 'Invalid
argument' error when setting it, and the erroneous string along with
an error message can be seen by looking at the filter e.g.::

	# cd /sys/kernel/debug/tracing/events/signal/signal_generate
	# echo "((sig >= 10 && sig < 15) || dsig == 17) && comm != bash" > filter
	-bash: echo: write error: Invalid argument
	# cat filter
	((sig >= 10 && sig < 15) || dsig == 17) && comm != bash
	^
	parse_error: Field not found

Currently the caret ('^') for an error always appears at the beginning of
the filter string; the error message should still be useful though
even without more accurate position info.

5.2.1 Filter limitations
------------------------

If a filter is placed on a string pointer ``(char *)`` that does not point
to a string on the ring buffer, but instead points to kernel or user space
memory, then, for safety reasons, at most 1024 bytes of the content is
copied onto a temporary buffer to do the compare. If the copy of the memory
faults (the pointer points to memory that should not be accessed), then the
string compare will be treated as not matching.

5.3 Clearing filters
--------------------

To clear the filter for an event, write a '0' to the event's filter
file.

To clear the filters for all events in a subsystem, write a '0' to the
subsystem's filter file.

5.3 Subsystem filters
---------------------

For convenience, filters for every event in a subsystem can be set or
cleared as a group by writing a filter expression into the filter file
at the root of the subsystem.  Note however, that if a filter for any
event within the subsystem lacks a field specified in the subsystem
filter, or if the filter can't be applied for any other reason, the
filter for that event will retain its previous setting.  This can
result in an unintended mixture of filters which could lead to
confusing (to the user who might think different filters are in
effect) trace output.  Only filters that reference just the common
fields can be guaranteed to propagate successfully to all events.

Here are a few subsystem filter examples that also illustrate the
above points:

Clear the filters on all events in the sched subsystem::

	# cd /sys/kernel/debug/tracing/events/sched
	# echo 0 > filter
	# cat sched_switch/filter
	none
	# cat sched_wakeup/filter
	none

Set a filter using only common fields for all events in the sched
subsystem (all events end up with the same filter)::

	# cd /sys/kernel/debug/tracing/events/sched
	# echo common_pid == 0 > filter
	# cat sched_switch/filter
	common_pid == 0
	# cat sched_wakeup/filter
	common_pid == 0

Attempt to set a filter using a non-common field for all events in the
sched subsystem (all events but those that have a prev_pid field retain
their old filters)::

	# cd /sys/kernel/debug/tracing/events/sched
	# echo prev_pid == 0 > filter
	# cat sched_switch/filter
	prev_pid == 0
	# cat sched_wakeup/filter
	common_pid == 0

5.4 PID filtering
-----------------

The set_event_pid file in the same directory as the top events directory
exists, will filter all events from tracing any task that does not have the
PID listed in the set_event_pid file.
::

	# cd /sys/kernel/debug/tracing
	# echo $$ > set_event_pid
	# echo 1 > events/enable

Will only trace events for the current task.

To add more PIDs without losing the PIDs already included, use '>>'.
::

	# echo 123 244 1 >> set_event_pid

6. Event triggers
=================

Trace events can be made to conditionally invoke trigger 'commands'
which can take various forms and are described in detail below;
examples would be enabling or disabling other trace events or invoking
a stack trace whenever the trace event is hit.  Whenever a trace event
with attached triggers is invoked, the set of trigger commands
associated with that event is invoked.  Any given trigger can
additionally have an event filter of the same form as described in
section 5 (Event filtering) associated with it - the command will only
be invoked if the event being invoked passes the associated filter.
If no filter is associated with the trigger, it always passes.

Triggers are added to and removed from a particular event by writing
trigger expressions to the 'trigger' file for the given event.

A given event can have any number of triggers associated with it,
subject to any restrictions that individual commands may have in that
regard.

Event triggers are implemented on top of "soft" mode, which means that
whenever a trace event has one or more triggers associated with it,
the event is activated even if it isn't actually enabled, but is
disabled in a "soft" mode.  That is, the tracepoint will be called,
but just will not be traced, unless of course it's actually enabled.
This scheme allows triggers to be invoked even for events that aren't
enabled, and also allows the current event filter implementation to be
used for conditionally invoking triggers.

The syntax for event triggers is roughly based on the syntax for
set_ftrace_filter 'ftrace filter commands' (see the 'Filter commands'
section of Documentation/trace/ftrace.rst), but there are major
differences and the implementation isn't currently tied to it in any
way, so beware about making generalizations between the two.

.. Note::
     Writing into trace_marker (See Documentation/trace/ftrace.rst)
     can also enable triggers that are written into
     /sys/kernel/tracing/events/ftrace/print/trigger

6.1 Expression syntax
---------------------

Triggers are added by echoing the command to the 'trigger' file::

  # echo 'command[:count] [if filter]' > trigger

Triggers are removed by echoing the same command but starting with '!'
to the 'trigger' file::

  # echo '!command[:count] [if filter]' > trigger

The [if filter] part isn't used in matching commands when removing, so
leaving that off in a '!' command will accomplish the same thing as
having it in.

The filter syntax is the same as that described in the 'Event
filtering' section above.

For ease of use, writing to the trigger file using '>' currently just
adds or removes a single trigger and there's no explicit '>>' support
('>' actually behaves like '>>') or truncation support to remove all
triggers (you have to use '!' for each one added.)

6.2 Supported trigger commands
------------------------------

The following commands are supported:

- enable_event/disable_event

  These commands can enable or disable another trace event whenever
  the triggering event is hit.  When these commands are registered,
  the other trace event is activated, but disabled in a "soft" mode.
  That is, the tracepoint will be called, but just will not be traced.
  The event tracepoint stays in this mode as long as there's a trigger
  in effect that can trigger it.

  For example, the following trigger causes kmalloc events to be
  traced when a read system call is entered, and the :1 at the end
  specifies that this enablement happens only once::

	  # echo 'enable_event:kmem:kmalloc:1' > \
	      /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger

  The following trigger causes kmalloc events to stop being traced
  when a read system call exits.  This disablement happens on every
  read system call exit::

	  # echo 'disable_event:kmem:kmalloc' > \
	      /sys/kernel/debug/tracing/events/syscalls/sys_exit_read/trigger

  The format is::

      enable_event:<system>:<event>[:count]
      disable_event:<system>:<event>[:count]

  To remove the above commands::

	  # echo '!enable_event:kmem:kmalloc:1' > \
	      /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger

	  # echo '!disable_event:kmem:kmalloc' > \
	      /sys/kernel/debug/tracing/events/syscalls/sys_exit_read/trigger

  Note that there can be any number of enable/disable_event triggers
  per triggering event, but there can only be one trigger per
  triggered event. e.g. sys_enter_read can have triggers enabling both
  kmem:kmalloc and sched:sched_switch, but can't have two kmem:kmalloc
  versions such as kmem:kmalloc and kmem:kmalloc:1 or 'kmem:kmalloc if
  bytes_req == 256' and 'kmem:kmalloc if bytes_alloc == 256' (they
  could be combined into a single filter on kmem:kmalloc though).

- stacktrace

  This command dumps a stacktrace in the trace buffer whenever the
  triggering event occurs.

  For example, the following trigger dumps a stacktrace every time the
  kmalloc tracepoint is hit::

	  # echo 'stacktrace' > \
		/sys/kernel/debug/tracing/events/kmem/kmalloc/trigger

  The following trigger dumps a stacktrace the first 5 times a kmalloc
  request happens with a size >= 64K::

	  # echo 'stacktrace:5 if bytes_req >= 65536' > \
		/sys/kernel/debug/tracing/events/kmem/kmalloc/trigger

  The format is::

      stacktrace[:count]

  To remove the above commands::

	  # echo '!stacktrace' > \
		/sys/kernel/debug/tracing/events/kmem/kmalloc/trigger

	  # echo '!stacktrace:5 if bytes_req >= 65536' > \
		/sys/kernel/debug/tracing/events/kmem/kmalloc/trigger

  The latter can also be removed more simply by the following (without
  the filter)::

	  # echo '!stacktrace:5' > \
		/sys/kernel/debug/tracing/events/kmem/kmalloc/trigger

  Note that there can be only one stacktrace trigger per triggering
  event.

- snapshot

  This command causes a snapshot to be triggered whenever the
  triggering event occurs.

  The following command creates a snapshot every time a block request
  queue is unplugged with a depth > 1.  If you were tracing a set of
  events or functions at the time, the snapshot trace buffer would
  capture those events when the trigger event occurred::

	  # echo 'snapshot if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

  To only snapshot once::

	  # echo 'snapshot:1 if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

  To remove the above commands::

	  # echo '!snapshot if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

	  # echo '!snapshot:1 if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

  Note that there can be only one snapshot trigger per triggering
  event.

- traceon/traceoff

  These commands turn tracing on and off when the specified events are
  hit. The parameter determines how many times the tracing system is
  turned on and off. If unspecified, there is no limit.

  The following command turns tracing off the first time a block
  request queue is unplugged with a depth > 1.  If you were tracing a
  set of events or functions at the time, you could then examine the
  trace buffer to see the sequence of events that led up to the
  trigger event::

	  # echo 'traceoff:1 if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

  To always disable tracing when nr_rq  > 1::

	  # echo 'traceoff if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

  To remove the above commands::

	  # echo '!traceoff:1 if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

	  # echo '!traceoff if nr_rq > 1' > \
		/sys/kernel/debug/tracing/events/block/block_unplug/trigger

  Note that there can be only one traceon or traceoff trigger per
  triggering event.

- hist

  This command aggregates event hits into a hash table keyed on one or
  more trace event format fields (or stacktrace) and a set of running
  totals derived from one or more trace event format fields and/or
  event counts (hitcount).

  See Documentation/trace/histogram.rst for details and examples.

7. In-kernel trace event API
============================

In most cases, the command-line interface to trace events is more than
sufficient.  Sometimes, however, applications might find the need for
more complex relationships than can be expressed through a simple
series of linked command-line expressions, or putting together sets of
commands may be simply too cumbersome.  An example might be an
application that needs to 'listen' to the trace stream in order to
maintain an in-kernel state machine detecting, for instance, when an
illegal kernel state occurs in the scheduler.

The trace event subsystem provides an in-kernel API allowing modules
or other kernel code to generate user-defined 'synthetic' events at
will, which can be used to either augment the existing trace stream
and/or signal that a particular important state has occurred.

A similar in-kernel API is also available for creating kprobe and
kretprobe events.

Both the synthetic event and k/ret/probe event APIs are built on top
of a lower-level "dynevent_cmd" event command API, which is also
available for more specialized applications, or as the basis of other
higher-level trace event APIs.

The API provided for these purposes is describe below and allows the
following:

  - dynamically creating synthetic event definitions
  - dynamically creating kprobe and kretprobe event definitions
  - tracing synthetic events from in-kernel code
  - the low-level "dynevent_cmd" API

7.1 Dyamically creating synthetic event definitions
---------------------------------------------------

There are a couple ways to create a new synthetic event from a kernel
module or other kernel code.

The first creates the event in one step, using synth_event_create().
In this method, the name of the event to create and an array defining
the fields is supplied to synth_event_create().  If successful, a
synthetic event with that name and fields will exist following that
call.  For example, to create a new "schedtest" synthetic event::

  ret = synth_event_create("schedtest", sched_fields,
                           ARRAY_SIZE(sched_fields), THIS_MODULE);

The sched_fields param in this example points to an array of struct
synth_field_desc, each of which describes an event field by type and
name::

  static struct synth_field_desc sched_fields[] = {
        { .type = "pid_t",              .name = "next_pid_field" },
        { .type = "char[16]",           .name = "next_comm_field" },
        { .type = "u64",                .name = "ts_ns" },
        { .type = "u64",                .name = "ts_ms" },
        { .type = "unsigned int",       .name = "cpu" },
        { .type = "char[64]",           .name = "my_string_field" },
        { .type = "int",                .name = "my_int_field" },
  };

See synth_field_size() for available types.

If field_name contains [n], the field is considered to be a static array.

If field_names contains[] (no subscript), the field is considered to
be a dynamic array, which will only take as much space in the event as
is required to hold the array.

Because space for an event is reserved before assigning field values
to the event, using dynamic arrays implies that the piecewise
in-kernel API described below can't be used with dynamic arrays.  The
other non-piecewise in-kernel APIs can, however, be used with dynamic
arrays.

If the event is created from within a module, a pointer to the module
must be passed to synth_event_create().  This will ensure that the
trace buffer won't contain unreadable events when the module is
removed.

At this point, the event object is ready to be used for generating new
events.

In the second method, the event is created in several steps.  This
allows events to be created dynamically and without the need to create
and populate an array of fields beforehand.

To use this method, an empty or partially empty synthetic event should
first be created using synth_event_gen_cmd_start() or
synth_event_gen_cmd_array_start().  For synth_event_gen_cmd_start(),
the name of the event along with one or more pairs of args each pair
representing a 'type field_name;' field specification should be
supplied.  For synth_event_gen_cmd_array_start(), the name of the
event along with an array of struct synth_field_desc should be
supplied. Before calling synth_event_gen_cmd_start() or
synth_event_gen_cmd_array_start(), the user should create and
initialize a dynevent_cmd object using synth_event_cmd_init().

For example, to create a new "schedtest" synthetic event with two
fields::

  struct dynevent_cmd cmd;
  char *buf;

  /* Create a buffer to hold the generated command */
  buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);

  /* Before generating the command, initialize the cmd object */
  synth_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);

  ret = synth_event_gen_cmd_start(&cmd, "schedtest", THIS_MODULE,
                                  "pid_t", "next_pid_field",
                                  "u64", "ts_ns");

Alternatively, using an array of struct synth_field_desc fields
containing the same information::

  ret = synth_event_gen_cmd_array_start(&cmd, "schedtest", THIS_MODULE,
                                        fields, n_fields);

Once the synthetic event object has been created, it can then be
populated with more fields.  Fields are added one by one using
synth_event_add_field(), supplying the dynevent_cmd object, a field
type, and a field name.  For example, to add a new int field named
"intfield", the following call should be made::

  ret = synth_event_add_field(&cmd, "int", "intfield");

See synth_field_size() for available types. If field_name contains [n]
the field is considered to be an array.

A group of fields can also be added all at once using an array of
synth_field_desc with add_synth_fields().  For example, this would add
just the first four sched_fields::

  ret = synth_event_add_fields(&cmd, sched_fields, 4);

If you already have a string of the form 'type field_name',
synth_event_add_field_str() can be used to add it as-is; it will
also automatically append a ';' to the string.

Once all the fields have been added, the event should be finalized and
registered by calling the synth_event_gen_cmd_end() function::

  ret = synth_event_gen_cmd_end(&cmd);

At this point, the event object is ready to be used for tracing new
events.

7.2 Tracing synthetic events from in-kernel code
------------------------------------------------

To trace a synthetic event, there are several options.  The first
option is to trace the event in one call, using synth_event_trace()
with a variable number of values, or synth_event_trace_array() with an
array of values to be set.  A second option can be used to avoid the
need for a pre-formed array of values or list of arguments, via
synth_event_trace_start() and synth_event_trace_end() along with
synth_event_add_next_val() or synth_event_add_val() to add the values
piecewise.

7.2.1 Tracing a synthetic event all at once
-------------------------------------------

To trace a synthetic event all at once, the synth_event_trace() or
synth_event_trace_array() functions can be used.

The synth_event_trace() function is passed the trace_event_file
representing the synthetic event (which can be retrieved using
trace_get_event_file() using the synthetic event name, "synthetic" as
the system name, and the trace instance name (NULL if using the global
trace array)), along with an variable number of u64 args, one for each
synthetic event field, and the number of values being passed.

So, to trace an event corresponding to the synthetic event definition
above, code like the following could be used::

  ret = synth_event_trace(create_synth_test, 7, /* number of values */
                          444,             /* next_pid_field */
                          (u64)"clackers", /* next_comm_field */
                          1000000,         /* ts_ns */
                          1000,            /* ts_ms */
                          smp_processor_id(),/* cpu */
                          (u64)"Thneed",   /* my_string_field */
                          999);            /* my_int_field */

All vals should be cast to u64, and string vals are just pointers to
strings, cast to u64.  Strings will be copied into space reserved in
the event for the string, using these pointers.

Alternatively, the synth_event_trace_array() function can be used to
accomplish the same thing.  It is passed the trace_event_file
representing the synthetic event (which can be retrieved using
trace_get_event_file() using the synthetic event name, "synthetic" as
the system name, and the trace instance name (NULL if using the global
trace array)), along with an array of u64, one for each synthetic
event field.

To trace an event corresponding to the synthetic event definition
above, code like the following could be used::

  u64 vals[7];

  vals[0] = 777;                  /* next_pid_field */
  vals[1] = (u64)"tiddlywinks";   /* next_comm_field */
  vals[2] = 1000000;              /* ts_ns */
  vals[3] = 1000;                 /* ts_ms */
  vals[4] = smp_processor_id();   /* cpu */
  vals[5] = (u64)"thneed";        /* my_string_field */
  vals[6] = 398;                  /* my_int_field */

The 'vals' array is just an array of u64, the number of which must
match the number of field in the synthetic event, and which must be in
the same order as the synthetic event fields.

All vals should be cast to u64, and string vals are just pointers to
strings, cast to u64.  Strings will be copied into space reserved in
the event for the string, using these pointers.

In order to trace a synthetic event, a pointer to the trace event file
is needed.  The trace_get_event_file() function can be used to get
it - it will find the file in the given trace instance (in this case
NULL since the top trace array is being used) while at the same time
preventing the instance containing it from going away::

       schedtest_event_file = trace_get_event_file(NULL, "synthetic",
                                                   "schedtest");

Before tracing the event, it should be enabled in some way, otherwise
the synthetic event won't actually show up in the trace buffer.

To enable a synthetic event from the kernel, trace_array_set_clr_event()
can be used (which is not specific to synthetic events, so does need
the "synthetic" system name to be specified explicitly).

To enable the event, pass 'true' to it::

       trace_array_set_clr_event(schedtest_event_file->tr,
                                 "synthetic", "schedtest", true);

To disable it pass false::

       trace_array_set_clr_event(schedtest_event_file->tr,
                                 "synthetic", "schedtest", false);

Finally, synth_event_trace_array() can be used to actually trace the
event, which should be visible in the trace buffer afterwards::

       ret = synth_event_trace_array(schedtest_event_file, vals,
                                     ARRAY_SIZE(vals));

To remove the synthetic event, the event should be disabled, and the
trace instance should be 'put' back using trace_put_event_file()::

       trace_array_set_clr_event(schedtest_event_file->tr,
                                 "synthetic", "schedtest", false);
       trace_put_event_file(schedtest_event_file);

If those have been successful, synth_event_delete() can be called to
remove the event::

       ret = synth_event_delete("schedtest");

7.2.2 Tracing a synthetic event piecewise
-----------------------------------------

To trace a synthetic using the piecewise method described above, the
synth_event_trace_start() function is used to 'open' the synthetic
event trace::

       struct synth_event_trace_state trace_state;

       ret = synth_event_trace_start(schedtest_event_file, &trace_state);

It's passed the trace_event_file representing the synthetic event
using the same methods as described above, along with a pointer to a
struct synth_event_trace_state object, which will be zeroed before use and
used to maintain state between this and following calls.

Once the event has been opened, which means space for it has been
reserved in the trace buffer, the individual fields can be set.  There
are two ways to do that, either one after another for each field in
the event, which requires no lookups, or by name, which does.  The
tradeoff is flexibility in doing the assignments vs the cost of a
lookup per field.

To assign the values one after the other without lookups,
synth_event_add_next_val() should be used.  Each call is passed the
same synth_event_trace_state object used in the synth_event_trace_start(),
along with the value to set the next field in the event.  After each
field is set, the 'cursor' points to the next field, which will be set
by the subsequent call, continuing until all the fields have been set
in order.  The same sequence of calls as in the above examples using
this method would be (without error-handling code)::

       /* next_pid_field */
       ret = synth_event_add_next_val(777, &trace_state);

       /* next_comm_field */
       ret = synth_event_add_next_val((u64)"slinky", &trace_state);

       /* ts_ns */
       ret = synth_event_add_next_val(1000000, &trace_state);

       /* ts_ms */
       ret = synth_event_add_next_val(1000, &trace_state);

       /* cpu */
       ret = synth_event_add_next_val(smp_processor_id(), &trace_state);

       /* my_string_field */
       ret = synth_event_add_next_val((u64)"thneed_2.01", &trace_state);

       /* my_int_field */
       ret = synth_event_add_next_val(395, &trace_state);

To assign the values in any order, synth_event_add_val() should be
used.  Each call is passed the same synth_event_trace_state object used in
the synth_event_trace_start(), along with the field name of the field
to set and the value to set it to.  The same sequence of calls as in
the above examples using this method would be (without error-handling
code)::

       ret = synth_event_add_val("next_pid_field", 777, &trace_state);
       ret = synth_event_add_val("next_comm_field", (u64)"silly putty",
                                 &trace_state);
       ret = synth_event_add_val("ts_ns", 1000000, &trace_state);
       ret = synth_event_add_val("ts_ms", 1000, &trace_state);
       ret = synth_event_add_val("cpu", smp_processor_id(), &trace_state);
       ret = synth_event_add_val("my_string_field", (u64)"thneed_9",
                                 &trace_state);
       ret = synth_event_add_val("my_int_field", 3999, &trace_state);

Note that synth_event_add_next_val() and synth_event_add_val() are
incompatible if used within the same trace of an event - either one
can be used but not both at the same time.

Finally, the event won't be actually traced until it's 'closed',
which is done using synth_event_trace_end(), which takes only the
struct synth_event_trace_state object used in the previous calls::

       ret = synth_event_trace_end(&trace_state);

Note that synth_event_trace_end() must be called at the end regardless
of whether any of the add calls failed (say due to a bad field name
being passed in).

7.3 Dyamically creating kprobe and kretprobe event definitions
--------------------------------------------------------------

To create a kprobe or kretprobe trace event from kernel code, the
kprobe_event_gen_cmd_start() or kretprobe_event_gen_cmd_start()
functions can be used.

To create a kprobe event, an empty or partially empty kprobe event
should first be created using kprobe_event_gen_cmd_start().  The name
of the event and the probe location should be specfied along with one
or args each representing a probe field should be supplied to this
function.  Before calling kprobe_event_gen_cmd_start(), the user
should create and initialize a dynevent_cmd object using
kprobe_event_cmd_init().

For example, to create a new "schedtest" kprobe event with two fields::

  struct dynevent_cmd cmd;
  char *buf;

  /* Create a buffer to hold the generated command */
  buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);

  /* Before generating the command, initialize the cmd object */
  kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);

  /*
   * Define the gen_kprobe_test event with the first 2 kprobe
   * fields.
   */
  ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test", "do_sys_open",
                                   "dfd=%ax", "filename=%dx");

Once the kprobe event object has been created, it can then be
populated with more fields.  Fields can be added using
kprobe_event_add_fields(), supplying the dynevent_cmd object along
with a variable arg list of probe fields.  For example, to add a
couple additional fields, the following call could be made::

  ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)");

Once all the fields have been added, the event should be finalized and
registered by calling the kprobe_event_gen_cmd_end() or
kretprobe_event_gen_cmd_end() functions, depending on whether a kprobe
or kretprobe command was started::

  ret = kprobe_event_gen_cmd_end(&cmd);

or::

  ret = kretprobe_event_gen_cmd_end(&cmd);

At this point, the event object is ready to be used for tracing new
events.

Similarly, a kretprobe event can be created using
kretprobe_event_gen_cmd_start() with a probe name and location and
additional params such as $retval::

  ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
                                      "do_sys_open", "$retval");

Similar to the synthetic event case, code like the following can be
used to enable the newly created kprobe event::

  gen_kprobe_test = trace_get_event_file(NULL, "kprobes", "gen_kprobe_test");

  ret = trace_array_set_clr_event(gen_kprobe_test->tr,
                                  "kprobes", "gen_kprobe_test", true);

Finally, also similar to synthetic events, the following code can be
used to give the kprobe event file back and delete the event::

  trace_put_event_file(gen_kprobe_test);

  ret = kprobe_event_delete("gen_kprobe_test");

7.4 The "dynevent_cmd" low-level API
------------------------------------

Both the in-kernel synthetic event and kprobe interfaces are built on
top of a lower-level "dynevent_cmd" interface.  This interface is
meant to provide the basis for higher-level interfaces such as the
synthetic and kprobe interfaces, which can be used as examples.

The basic idea is simple and amounts to providing a general-purpose
layer that can be used to generate trace event commands.  The
generated command strings can then be passed to the command-parsing
and event creation code that already exists in the trace event
subystem for creating the corresponding trace events.

In a nutshell, the way it works is that the higher-level interface
code creates a struct dynevent_cmd object, then uses a couple
functions, dynevent_arg_add() and dynevent_arg_pair_add() to build up
a command string, which finally causes the command to be executed
using the dynevent_create() function.  The details of the interface
are described below.

The first step in building a new command string is to create and
initialize an instance of a dynevent_cmd.  Here, for instance, we
create a dynevent_cmd on the stack and initialize it::

  struct dynevent_cmd cmd;
  char *buf;
  int ret;

  buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);

  dynevent_cmd_init(cmd, buf, maxlen, DYNEVENT_TYPE_FOO,
                    foo_event_run_command);

The dynevent_cmd initialization needs to be given a user-specified
buffer and the length of the buffer (MAX_DYNEVENT_CMD_LEN can be used
for this purpose - at 2k it's generally too big to be comfortably put
on the stack, so is dynamically allocated), a dynevent type id, which
is meant to be used to check that further API calls are for the
correct command type, and a pointer to an event-specific run_command()
callback that will be called to actually execute the event-specific
command function.

Once that's done, the command string can by built up by successive
calls to argument-adding functions.

To add a single argument, define and initialize a struct dynevent_arg
or struct dynevent_arg_pair object.  Here's an example of the simplest
possible arg addition, which is simply to append the given string as
a whitespace-separated argument to the command::

  struct dynevent_arg arg;

  dynevent_arg_init(&arg, NULL, 0);

  arg.str = name;

  ret = dynevent_arg_add(cmd, &arg);

The arg object is first initialized using dynevent_arg_init() and in
this case the parameters are NULL or 0, which means there's no
optional sanity-checking function or separator appended to the end of
the arg.

Here's another more complicated example using an 'arg pair', which is
used to create an argument that consists of a couple components added
together as a unit, for example, a 'type field_name;' arg or a simple
expression arg e.g. 'flags=%cx'::

  struct dynevent_arg_pair arg_pair;

  dynevent_arg_pair_init(&arg_pair, dynevent_foo_check_arg_fn, 0, ';');

  arg_pair.lhs = type;
  arg_pair.rhs = name;

  ret = dynevent_arg_pair_add(cmd, &arg_pair);

Again, the arg_pair is first initialized, in this case with a callback
function used to check the sanity of the args (for example, that
neither part of the pair is NULL), along with a character to be used
to add an operator between the pair (here none) and a separator to be
appended onto the end of the arg pair (here ';').

There's also a dynevent_str_add() function that can be used to simply
add a string as-is, with no spaces, delimeters, or arg check.

Any number of dynevent_*_add() calls can be made to build up the string
(until its length surpasses cmd->maxlen).  When all the arguments have
been added and the command string is complete, the only thing left to
do is run the command, which happens by simply calling
dynevent_create()::

  ret = dynevent_create(&cmd);

At that point, if the return value is 0, the dynamic event has been
created and is ready to use.

See the dynevent_cmd function definitions themselves for the details
of the API.


code:
.. SPDX-License-Identifier: GPL-2.0

==================================
Fprobe - Function entry/exit probe
==================================

.. Author: Masami Hiramatsu <mhiramat@kernel.org>

Introduction
============

Fprobe is a function entry/exit probe mechanism based on ftrace.
Instead of using ftrace full feature, if you only want to attach callbacks
on function entry and exit, similar to the kprobes and kretprobes, you can
use fprobe. Compared with kprobes and kretprobes, fprobe gives faster
instrumentation for multiple functions with single handler. This document
describes how to use fprobe.

The usage of fprobe
===================

The fprobe is a wrapper of ftrace (+ kretprobe-like return callback) to
attach callbacks to multiple function entry and exit. User needs to set up
the `struct fprobe` and pass it to `register_fprobe()`.

Typically, `fprobe` data structure is initialized with the `entry_handler`
and/or `exit_handler` as below.

.. code-block:: c

 struct fprobe fp = {
        .entry_handler  = my_entry_callback,
        .exit_handler   = my_exit_callback,
 };

To enable the fprobe, call one of register_fprobe(), register_fprobe_ips(), and
register_fprobe_syms(). These functions register the fprobe with different types
of parameters.

The register_fprobe() enables a fprobe by function-name filters.
E.g. this enables @fp on "func*()" function except "func2()".::

  register_fprobe(&fp, "func*", "func2");

The register_fprobe_ips() enables a fprobe by ftrace-location addresses.
E.g.

.. code-block:: c

  unsigned long ips[] = { 0x.... };

  register_fprobe_ips(&fp, ips, ARRAY_SIZE(ips));

And the register_fprobe_syms() enables a fprobe by symbol names.
E.g.

.. code-block:: c

  char syms[] = {"func1", "func2", "func3"};

  register_fprobe_syms(&fp, syms, ARRAY_SIZE(syms));

To disable (remove from functions) this fprobe, call::

  unregister_fprobe(&fp);

You can temporally (soft) disable the fprobe by::

  disable_fprobe(&fp);

and resume by::

  enable_fprobe(&fp);

The above is defined by including the header::

  #include <linux/fprobe.h>

Same as ftrace, the registered callbacks will start being called some time
after the register_fprobe() is called and before it returns. See
:file:`Documentation/trace/ftrace.rst`.

Also, the unregister_fprobe() will guarantee that the both enter and exit
handlers are no longer being called by functions after unregister_fprobe()
returns as same as unregister_ftrace_function().

The fprobe entry/exit handler
=============================

The prototype of the entry/exit callback function is as follows:

.. code-block:: c

 void callback_func(struct fprobe *fp, unsigned long entry_ip, struct pt_regs *regs);

Note that both entry and exit callbacks have same ptototype. The @entry_ip is
saved at function entry and passed to exit handler.

@fp
        This is the address of `fprobe` data structure related to this handler.
        You can embed the `fprobe` to your data structure and get it by
        container_of() macro from @fp. The @fp must not be NULL.

@entry_ip
        This is the ftrace address of the traced function (both entry and exit).
        Note that this may not be the actual entry address of the function but
        the address where the ftrace is instrumented.

@regs
        This is the `pt_regs` data structure at the entry and exit. Note that
        the instruction pointer of @regs may be different from the @entry_ip
        in the entry_handler. If you need traced instruction pointer, you need
        to use @entry_ip. On the other hand, in the exit_handler, the instruction
        pointer of @regs is set to the currect return address.

Share the callbacks with kprobes
================================

Since the recursion safeness of the fprobe (and ftrace) is a bit different
from the kprobes, this may cause an issue if user wants to run the same
code from the fprobe and the kprobes.

Kprobes has per-cpu 'current_kprobe' variable which protects the kprobe
handler from recursion in all cases. On the other hand, fprobe uses
only ftrace_test_recursion_trylock(). This allows interrupt context to
call another (or same) fprobe while the fprobe user handler is running.

This is not a matter if the common callback code has its own recursion
detection, or it can handle the recursion in the different contexts
(normal/interrupt/NMI.)
But if it relies on the 'current_kprobe' recursion lock, it has to check
kprobe_running() and use kprobe_busy_*() APIs.

Fprobe has FPROBE_FL_KPROBE_SHARED flag to do this. If your common callback
code will be shared with kprobes, please set FPROBE_FL_KPROBE_SHARED
*before* registering the fprobe, like:

.. code-block:: c

 fprobe.flags = FPROBE_FL_KPROBE_SHARED;

 register_fprobe(&fprobe, "func*", NULL);

This will protect your common callback from the nested call.

The missed counter
==================

The `fprobe` data structure has `fprobe::nmissed` counter field as same as
kprobes.
This counter counts up when;

 - fprobe fails to take ftrace_recursion lock. This usually means that a function
   which is traced by other ftrace users is called from the entry_handler.

 - fprobe fails to setup the function exit because of the shortage of rethook
   (the shadow stack for hooking the function return.)

The `fprobe::nmissed` field counts up in both cases. Therefore, the former
skips both of entry and exit callback and the latter skips the exit
callback, but in both case the counter will increase by 1.

Note that if you set the FTRACE_OPS_FL_RECURSION and/or FTRACE_OPS_FL_RCU to
`fprobe::ops::flags` (ftrace_ops::flags) when registering the fprobe, this
counter may not work correctly, because ftrace skips the fprobe function which
increase the counter.

Functions and structures
========================

.. kernel-doc:: include/linux/fprobe.h
.. kernel-doc:: kernel/trace/fprobe.c