File Index
Files and directories
Sign in
FILE

histogram-design.rst

File preview with syntax highlighting.

linux-6.19.14/Documentation/trace/histogram-design.rst RESTRUCTUREDTEXT
   1.. SPDX-License-Identifier: GPL-2.0
   2
   3======================
   4Histogram Design Notes
   5======================
   6
   7:Author: Tom Zanussi <zanussi@kernel.org>
   8
   9This document attempts to provide a description of how the ftrace
  10histograms work and how the individual pieces map to the data
  11structures used to implement them in trace_events_hist.c and
  12tracing_map.c.
  13
  14.. note::
  15   All the ftrace histogram command examples assume the working
  16   directory is the ftrace /tracing directory. For example::
  17
  18	# cd /sys/kernel/tracing
  19
  20   Also, the histogram output displayed for those commands will be
  21   generally be truncated - only enough to make the point is displayed.
  22
  23'hist_debug' trace event files
  24==============================
  25
  26If the kernel is compiled with CONFIG_HIST_TRIGGERS_DEBUG set, an
  27event file named 'hist_debug' will appear in each event's
  28subdirectory.  This file can be read at any time and will display some
  29of the hist trigger internals described in this document. Specific
  30examples and output will be described in test cases below.
  31
  32Basic histograms
  33================
  34
  35First, basic histograms.  Below is pretty much the simplest thing you
  36can do with histograms - create one with a single key on a single
  37event and cat the output::
  38
  39  # echo 'hist:keys=pid' >> events/sched/sched_waking/trigger
  40
  41  # cat events/sched/sched_waking/hist
  42
  43  { pid:      18249 } hitcount:          1
  44  { pid:      13399 } hitcount:          1
  45  { pid:      17973 } hitcount:          1
  46  { pid:      12572 } hitcount:          1
  47  ...
  48  { pid:         10 } hitcount:        921
  49  { pid:      18255 } hitcount:       1444
  50  { pid:      25526 } hitcount:       2055
  51  { pid:       5257 } hitcount:       2055
  52  { pid:      27367 } hitcount:       2055
  53  { pid:       1728 } hitcount:       2161
  54
  55  Totals:
  56    Hits: 21305
  57    Entries: 183
  58    Dropped: 0
  59
  60What this does is create a histogram on the sched_waking event using
  61pid as a key and with a single value, hitcount, which even if not
  62explicitly specified, exists for every histogram regardless.
  63
  64The hitcount value is a per-bucket value that's automatically
  65incremented on every hit for the given key, which in this case is the
  66pid.
  67
  68So in this histogram, there's a separate bucket for each pid, and each
  69bucket contains a value for that bucket, counting the number of times
  70sched_waking was called for that pid.
  71
  72Each histogram is represented by a hist_data struct.
  73
  74To keep track of each key and value field in the histogram, hist_data
  75keeps an array of these fields named fields[].  The fields[] array is
  76an array containing struct hist_field representations of each
  77histogram val and key in the histogram (variables are also included
  78here, but are discussed later). So for the above histogram we have one
  79key and one value; in this case the one value is the hitcount value,
  80which all histograms have, regardless of whether they define that
  81value or not, which the above histogram does not.
  82
  83Each struct hist_field contains a pointer to the ftrace_event_field
  84from the event's trace_event_file along with various bits related to
  85that such as the size, offset, type, and a hist_field_fn_t function,
  86which is used to grab the field's data from the ftrace event buffer
  87(in most cases - some hist_fields such as hitcount don't directly map
  88to an event field in the trace buffer - in these cases the function
  89implementation gets its value from somewhere else).  The flags field
  90indicates which type of field it is - key, value, variable, variable
  91reference, etc., with value being the default.
  92
  93The other important hist_data data structure in addition to the
  94fields[] array is the tracing_map instance created for the histogram,
  95which is held in the .map member.  The tracing_map implements the
  96lock-free hash table used to implement histograms (see
  97kernel/trace/tracing_map.h for much more discussion about the
  98low-level data structures implementing the tracing_map).  For the
  99purposes of this discussion, the tracing_map contains a number of
 100buckets, each bucket corresponding to a particular tracing_map_elt
 101object hashed by a given histogram key.
 102
 103Below is a diagram the first part of which describes the hist_data and
 104associated key and value fields for the histogram described above.  As
 105you can see, there are two fields in the fields array, one val field
 106for the hitcount and one key field for the pid key.
 107
 108Below that is a diagram of a run-time snapshot of what the tracing_map
 109might look like for a given run.  It attempts to show the
 110relationships between the hist_data fields and the tracing_map
 111elements for a couple hypothetical keys and values.::
 112
 113  +------------------+
 114  | hist_data        |
 115  +------------------+     +----------------+
 116    | .fields[]      |---->| val = hitcount |----------------------------+
 117    +----------------+     +----------------+                            |
 118    | .map           |       | .size        |                            |
 119    +----------------+       +--------------+                            |
 120                             | .offset      |                            |
 121                             +--------------+                            |
 122                             | .fn()        |                            |
 123                             +--------------+                            |
 124                                   .                                     |
 125                                   .                                     |
 126                                   .                                     |
 127                           +----------------+ <--- n_vals                |
 128                           | key = pid      |----------------------------|--+
 129                           +----------------+                            |  |
 130                             | .size        |                            |  |
 131                             +--------------+                            |  |
 132                             | .offset      |                            |  |
 133                             +--------------+                            |  |
 134                             | .fn()        |                            |  |
 135                           +----------------+ <--- n_fields              |  |
 136                           | unused         |                            |  |
 137                           +----------------+                            |  |
 138                             |              |                            |  |
 139                             +--------------+                            |  |
 140                             |              |                            |  |
 141                             +--------------+                            |  |
 142                             |              |                            |  |
 143                             +--------------+                            |  |
 144                                            n_keys = n_fields - n_vals   |  |
 145
 146The hist_data n_vals and n_fields delineate the extent of the fields[]
 147array and separate keys from values for the rest of the code.
 148
 149Below is a run-time representation of the tracing_map part of the
 150histogram, with pointers from various parts of the fields[] array
 151to corresponding parts of the tracing_map.
 152
 153The tracing_map consists of an array of tracing_map_entrys and a set
 154of preallocated tracing_map_elts (abbreviated below as map_entry and
 155map_elt).  The total number of map_entrys in the hist_data.map array =
 156map->max_elts (actually map->map_size but only max_elts of those are
 157used.  This is a property required by the map_insert() algorithm).
 158
 159If a map_entry is unused, meaning no key has yet hashed into it, its
 160.key value is 0 and its .val pointer is NULL.  Once a map_entry has
 161been claimed, the .key value contains the key's hash value and the
 162.val member points to a map_elt containing the full key and an entry
 163for each key or value in the map_elt.fields[] array.  There is an
 164entry in the map_elt.fields[] array corresponding to each hist_field
 165in the histogram, and this is where the continually aggregated sums
 166corresponding to each histogram value are kept.
 167
 168The diagram attempts to show the relationship between the
 169hist_data.fields[] and the map_elt.fields[] with the links drawn
 170between diagrams::
 171
 172  +-----------+		                                                 |  |
 173  | hist_data |		                                                 |  |
 174  +-----------+		                                                 |  |
 175    | .fields |		                                                 |  |
 176    +---------+     +-----------+		                         |  |
 177    | .map    |---->| map_entry |		                         |  |
 178    +---------+     +-----------+		                         |  |
 179                      | .key    |---> 0		                         |  |
 180                      +---------+		                         |  |
 181                      | .val    |---> NULL		                 |  |
 182                    +-----------+                                        |  |
 183                    | map_entry |                                        |  |
 184                    +-----------+                                        |  |
 185                      | .key    |---> pid = 999                          |  |
 186                      +---------+    +-----------+                       |  |
 187                      | .val    |--->| map_elt   |                       |  |
 188                      +---------+    +-----------+                       |  |
 189                           .           | .key    |---> full key *        |  |
 190                           .           +---------+    +---------------+  |  |
 191			   .           | .fields |--->| .sum (val)    |<-+  |
 192                    +-----------+      +---------+    | 2345          |  |  |
 193                    | map_entry |                     +---------------+  |  |
 194                    +-----------+                     | .offset (key) |<----+
 195                      | .key    |---> 0               | 0             |  |  |
 196                      +---------+                     +---------------+  |  |
 197                      | .val    |---> NULL                    .          |  |
 198                    +-----------+                             .          |  |
 199                    | map_entry |                             .          |  |
 200                    +-----------+                     +---------------+  |  |
 201                      | .key    |                     | .sum (val) or |  |  |
 202                      +---------+    +---------+      | .offset (key) |  |  |
 203                      | .val    |--->| map_elt |      +---------------+  |  |
 204                    +-----------+    +---------+      | .sum (val) or |  |  |
 205                    | map_entry |                     | .offset (key) |  |  |
 206                    +-----------+                     +---------------+  |  |
 207                      | .key    |---> pid = 4444                         |  |
 208                      +---------+    +-----------+                       |  |
 209                      | .val    |    | map_elt   |                       |  |
 210                      +---------+    +-----------+                       |  |
 211                                       | .key    |---> full key *        |  |
 212                                       +---------+    +---------------+  |  |
 213			               | .fields |--->| .sum (val)    |<-+  |
 214                                       +---------+    | 65523         |     |
 215                                                      +---------------+     |
 216                                                      | .offset (key) |<----+
 217                                                      | 0             |
 218                                                      +---------------+
 219                                                              .
 220                                                              .
 221                                                              .
 222                                                      +---------------+
 223                                                      | .sum (val) or |
 224                                                      | .offset (key) |
 225                                                      +---------------+
 226                                                      | .sum (val) or |
 227                                                      | .offset (key) |
 228                                                      +---------------+
 229
 230Abbreviations used in the diagrams::
 231
 232  hist_data = struct hist_trigger_data
 233  hist_data.fields = struct hist_field
 234  fn = hist_field_fn_t
 235  map_entry = struct tracing_map_entry
 236  map_elt = struct tracing_map_elt
 237  map_elt.fields = struct tracing_map_field
 238
 239Whenever a new event occurs and it has a hist trigger associated with
 240it, event_hist_trigger() is called.  event_hist_trigger() first deals
 241with the key: for each subkey in the key (in the above example, there
 242is just one subkey corresponding to pid), the hist_field that
 243represents that subkey is retrieved from hist_data.fields[] and the
 244hist_field_fn_t fn() associated with that field, along with the
 245field's size and offset, is used to grab that subkey's data from the
 246current trace record.
 247
 248Once the complete key has been retrieved, it's used to look that key
 249up in the tracing_map.  If there's no tracing_map_elt associated with
 250that key, an empty one is claimed and inserted in the map for the new
 251key.  In either case, the tracing_map_elt associated with that key is
 252returned.
 253
 254Once a tracing_map_elt available, hist_trigger_elt_update() is called.
 255As the name implies, this updates the element, which basically means
 256updating the element's fields.  There's a tracing_map_field associated
 257with each key and value in the histogram, and each of these correspond
 258to the key and value hist_fields created when the histogram was
 259created.  hist_trigger_elt_update() goes through each value hist_field
 260and, as for the keys, uses the hist_field's fn() and size and offset
 261to grab the field's value from the current trace record.  Once it has
 262that value, it simply adds that value to that field's
 263continually-updated tracing_map_field.sum member.  Some hist_field
 264fn()s, such as for the hitcount, don't actually grab anything from the
 265trace record (the hitcount fn() just increments the counter sum by 1),
 266but the idea is the same.
 267
 268Once all the values have been updated, hist_trigger_elt_update() is
 269done and returns.  Note that there are also tracing_map_fields for
 270each subkey in the key, but hist_trigger_elt_update() doesn't look at
 271them or update anything - those exist only for sorting, which can
 272happen later.
 273
 274Basic histogram test
 275--------------------
 276
 277This is a good example to try.  It produces 3 value fields and 2 key
 278fields in the output::
 279
 280  # echo 'hist:keys=common_pid,call_site.sym:values=bytes_req,bytes_alloc,hitcount' >> events/kmem/kmalloc/trigger
 281
 282To see the debug data, cat the kmem/kmalloc's 'hist_debug' file. It
 283will show the trigger info of the histogram it corresponds to, along
 284with the address of the hist_data associated with the histogram, which
 285will become useful in later examples.  It then displays the number of
 286total hist_fields associated with the histogram along with a count of
 287how many of those correspond to keys and how many correspond to values.
 288
 289It then goes on to display details for each field, including the
 290field's flags and the position of each field in the hist_data's
 291fields[] array, which is useful information for verifying that things
 292internally appear correct or not, and which again will become even
 293more useful in further examples::
 294
 295  # cat events/kmem/kmalloc/hist_debug
 296
 297  # event histogram
 298  #
 299  # trigger info: hist:keys=common_pid,call_site.sym:vals=hitcount,bytes_req,bytes_alloc:sort=hitcount:size=2048 [active]
 300  #
 301
 302  hist_data: 000000005e48c9a5
 303
 304  n_vals: 3
 305  n_keys: 2
 306  n_fields: 5
 307
 308  val fields:
 309
 310    hist_data->fields[0]:
 311      flags:
 312        VAL: HIST_FIELD_FL_HITCOUNT
 313      type: u64
 314      size: 8
 315      is_signed: 0
 316
 317    hist_data->fields[1]:
 318      flags:
 319        VAL: normal u64 value
 320      ftrace_event_field name: bytes_req
 321      type: size_t
 322      size: 8
 323      is_signed: 0
 324
 325    hist_data->fields[2]:
 326      flags:
 327        VAL: normal u64 value
 328      ftrace_event_field name: bytes_alloc
 329      type: size_t
 330      size: 8
 331      is_signed: 0
 332
 333  key fields:
 334
 335    hist_data->fields[3]:
 336      flags:
 337        HIST_FIELD_FL_KEY
 338      ftrace_event_field name: common_pid
 339      type: int
 340      size: 8
 341      is_signed: 1
 342
 343    hist_data->fields[4]:
 344      flags:
 345        HIST_FIELD_FL_KEY
 346      ftrace_event_field name: call_site
 347      type: unsigned long
 348      size: 8
 349      is_signed: 0
 350
 351The commands below can be used to clean things up for the next test::
 352
 353  # echo '!hist:keys=common_pid,call_site.sym:values=bytes_req,bytes_alloc,hitcount' >> events/kmem/kmalloc/trigger
 354
 355Variables
 356=========
 357
 358Variables allow data from one hist trigger to be saved by one hist
 359trigger and retrieved by another hist trigger.  For example, a trigger
 360on the sched_waking event can capture a timestamp for a particular
 361pid, and later a sched_switch event that switches to that pid event
 362can grab the timestamp and use it to calculate a time delta between
 363the two events::
 364
 365  # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >>
 366          events/sched/sched_waking/trigger
 367
 368  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0' >>
 369          events/sched/sched_switch/trigger
 370
 371In terms of the histogram data structures, variables are implemented
 372as another type of hist_field and for a given hist trigger are added
 373to the hist_data.fields[] array just after all the val fields.  To
 374distinguish them from the existing key and val fields, they're given a
 375new flag type, HIST_FIELD_FL_VAR (abbreviated FL_VAR) and they also
 376make use of a new .var.idx field member in struct hist_field, which
 377maps them to an index in a new map_elt.vars[] array added to the
 378map_elt specifically designed to store and retrieve variable values.
 379The diagram below shows those new elements and adds a new variable
 380entry, ts0, corresponding to the ts0 variable in the sched_waking
 381trigger above.
 382
 383sched_waking histogram
 384----------------------
 385
 386.. code-block::
 387
 388  +------------------+
 389  | hist_data        |<-------------------------------------------------------+
 390  +------------------+   +-------------------+                                |
 391    | .fields[]      |-->| val = hitcount    |                                |
 392    +----------------+   +-------------------+                                |
 393    | .map           |     | .size           |                                |
 394    +----------------+     +-----------------+                                |
 395                           | .offset         |                                |
 396                           +-----------------+                                |
 397                           | .fn()           |                                |
 398                           +-----------------+                                |
 399                           | .flags          |                                |
 400                           +-----------------+                                |
 401                           | .var.idx        |                                |
 402                         +-------------------+                                |
 403                         | var = ts0         |                                |
 404                         +-------------------+                                |
 405                           | .size           |                                |
 406                           +-----------------+                                |
 407                           | .offset         |                                |
 408                           +-----------------+                                |
 409                           | .fn()           |                                |
 410                           +-----------------+                                |
 411                           | .flags & FL_VAR |                                |
 412                           +-----------------+                                |
 413                           | .var.idx        |----------------------------+-+ |
 414                           +-----------------+                            | | |
 415			            .                                     | | |
 416				    .                                     | | |
 417                                    .                                     | | |
 418                         +-------------------+ <--- n_vals                | | |
 419                         | key = pid         |                            | | |
 420                         +-------------------+                            | | |
 421                           | .size           |                            | | |
 422                           +-----------------+                            | | |
 423                           | .offset         |                            | | |
 424                           +-----------------+                            | | |
 425                           | .fn()           |                            | | |
 426                           +-----------------+                            | | |
 427                           | .flags & FL_KEY |                            | | |
 428                           +-----------------+                            | | |
 429                           | .var.idx        |                            | | |
 430                         +-------------------+ <--- n_fields              | | |
 431                         | unused            |                            | | |
 432                         +-------------------+                            | | |
 433                           |                 |                            | | |
 434                           +-----------------+                            | | |
 435                           |                 |                            | | |
 436                           +-----------------+                            | | |
 437                           |                 |                            | | |
 438                           +-----------------+                            | | |
 439                           |                 |                            | | |
 440                           +-----------------+                            | | |
 441                           |                 |                            | | |
 442                           +-----------------+                            | | |
 443                                             n_keys = n_fields - n_vals   | | |
 444                                                                          | | |
 445
 446This is very similar to the basic case.  In the above diagram, we can
 447see a new .flags member has been added to the struct hist_field
 448struct, and a new entry added to hist_data.fields representing the ts0
 449variable.  For a normal val hist_field, .flags is just 0 (modulo
 450modifier flags), but if the value is defined as a variable, the .flags
 451contains a set FL_VAR bit.
 452
 453As you can see, the ts0 entry's .var.idx member contains the index
 454into the tracing_map_elts' .vars[] array containing variable values.
 455This idx is used whenever the value of the variable is set or read.
 456The map_elt.vars idx assigned to the given variable is assigned and
 457saved in .var.idx by create_tracing_map_fields() after it calls
 458tracing_map_add_var().
 459
 460Below is a representation of the histogram at run-time, which
 461populates the map, along with correspondence to the above hist_data and
 462hist_field data structures.
 463
 464The diagram attempts to show the relationship between the
 465hist_data.fields[] and the map_elt.fields[] and map_elt.vars[] with
 466the links drawn between diagrams.  For each of the map_elts, you can
 467see that the .fields[] members point to the .sum or .offset of a key
 468or val and the .vars[] members point to the value of a variable.  The
 469arrows between the two diagrams show the linkages between those
 470tracing_map members and the field definitions in the corresponding
 471hist_data fields[] members.::
 472
 473  +-----------+		                                                  | | |
 474  | hist_data |		                                                  | | |
 475  +-----------+		                                                  | | |
 476    | .fields |		                                                  | | |
 477    +---------+     +-----------+		                          | | |
 478    | .map    |---->| map_entry |		                          | | |
 479    +---------+     +-----------+		                          | | |
 480                      | .key    |---> 0		                          | | |
 481                      +---------+		                          | | |
 482                      | .val    |---> NULL		                  | | |
 483                    +-----------+                                         | | |
 484                    | map_entry |                                         | | |
 485                    +-----------+                                         | | |
 486                      | .key    |---> pid = 999                           | | |
 487                      +---------+    +-----------+                        | | |
 488                      | .val    |--->| map_elt   |                        | | |
 489                      +---------+    +-----------+                        | | |
 490                           .           | .key    |---> full key *         | | |
 491                           .           +---------+    +---------------+   | | |
 492			   .           | .fields |--->| .sum (val)    |   | | |
 493                           .           +---------+    | 2345          |   | | |
 494                           .        +--| .vars   |    +---------------+   | | |
 495                           .        |  +---------+    | .offset (key) |   | | |
 496                           .        |                 | 0             |   | | |
 497                           .        |                 +---------------+   | | |
 498                           .        |                         .           | | |
 499                           .        |                         .           | | |
 500                           .        |                         .           | | |
 501                           .        |                 +---------------+   | | |
 502                           .        |                 | .sum (val) or |   | | |
 503                           .        |                 | .offset (key) |   | | |
 504                           .        |                 +---------------+   | | |
 505                           .        |                 | .sum (val) or |   | | |
 506                           .        |                 | .offset (key) |   | | |
 507                           .        |                 +---------------+   | | |
 508                           .        |                                     | | |
 509                           .        +---------------->+---------------+   | | |
 510			   .                          | ts0           |<--+ | |
 511                           .                          | 113345679876  |   | | |
 512                           .                          +---------------+   | | |
 513                           .                          | unused        |   | | |
 514                           .                          |               |   | | |
 515                           .                          +---------------+   | | |
 516                           .                                  .           | | |
 517                           .                                  .           | | |
 518                           .                                  .           | | |
 519                           .                          +---------------+   | | |
 520                           .                          | unused        |   | | |
 521                           .                          |               |   | | |
 522                           .                          +---------------+   | | |
 523                           .                          | unused        |   | | |
 524                           .                          |               |   | | |
 525                           .                          +---------------+   | | |
 526                           .                                              | | |
 527                    +-----------+                                         | | |
 528                    | map_entry |                                         | | |
 529                    +-----------+                                         | | |
 530                      | .key    |---> pid = 4444                          | | |
 531                      +---------+    +-----------+                        | | |
 532                      | .val    |--->| map_elt   |                        | | |
 533                      +---------+    +-----------+                        | | |
 534                           .           | .key    |---> full key *         | | |
 535                           .           +---------+    +---------------+   | | |
 536			   .           | .fields |--->| .sum (val)    |   | | |
 537                                       +---------+    | 2345          |   | | |
 538                                    +--| .vars   |    +---------------+   | | |
 539                                    |  +---------+    | .offset (key) |   | | |
 540                                    |                 | 0             |   | | |
 541                                    |                 +---------------+   | | |
 542                                    |                         .           | | |
 543                                    |                         .           | | |
 544                                    |                         .           | | |
 545                                    |                 +---------------+   | | |
 546                                    |                 | .sum (val) or |   | | |
 547                                    |                 | .offset (key) |   | | |
 548                                    |                 +---------------+   | | |
 549                                    |                 | .sum (val) or |   | | |
 550                                    |                 | .offset (key) |   | | |
 551                                    |                 +---------------+   | | |
 552                                    |                                     | | |
 553                                    |                 +---------------+   | | |
 554			            +---------------->| ts0           |<--+ | |
 555                                                      | 213499240729  |     | |
 556                                                      +---------------+     | |
 557                                                      | unused        |     | |
 558                                                      |               |     | |
 559                                                      +---------------+     | |
 560                                                              .             | |
 561                                                              .             | |
 562                                                              .             | |
 563                                                      +---------------+     | |
 564                                                      | unused        |     | |
 565                                                      |               |     | |
 566                                                      +---------------+     | |
 567                                                      | unused        |     | |
 568                                                      |               |     | |
 569                                                      +---------------+     | |
 570
 571For each used map entry, there's a map_elt pointing to an array of
 572.vars containing the current value of the variables associated with
 573that histogram entry.  So in the above, the timestamp associated with
 574pid 999 is 113345679876, and the timestamp variable in the same
 575.var.idx for pid 4444 is 213499240729.
 576
 577sched_switch histogram
 578----------------------
 579
 580The sched_switch histogram paired with the above sched_waking
 581histogram is shown below.  The most important aspect of the
 582sched_switch histogram is that it references a variable on the
 583sched_waking histogram above.
 584
 585The histogram diagram is very similar to the others so far displayed,
 586but it adds variable references.  You can see the normal hitcount and
 587key fields along with a new wakeup_lat variable implemented in the
 588same way as the sched_waking ts0 variable, but in addition there's an
 589entry with the new FL_VAR_REF (short for HIST_FIELD_FL_VAR_REF) flag.
 590
 591Associated with the new var ref field are a couple of new hist_field
 592members, var.hist_data and var_ref_idx.  For a variable reference, the
 593var.hist_data goes with the var.idx, which together uniquely identify
 594a particular variable on a particular histogram.  The var_ref_idx is
 595just the index into the var_ref_vals[] array that caches the values of
 596each variable whenever a hist trigger is updated.  Those resulting
 597values are then finally accessed by other code such as trace action
 598code that uses the var_ref_idx values to assign param values.
 599
 600The diagram below describes the situation for the sched_switch
 601histogram referred to before::
 602
 603  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0' >>
 604          events/sched/sched_switch/trigger
 605                                                                            | |
 606  +------------------+                                                      | |
 607  | hist_data        |                                                      | |
 608  +------------------+   +-----------------------+                          | |
 609    | .fields[]      |-->| val = hitcount        |                          | |
 610    +----------------+   +-----------------------+                          | |
 611    | .map           |     | .size               |                          | |
 612    +----------------+     +---------------------+                          | |
 613 +--| .var_refs[]    |     | .offset             |                          | |
 614 |  +----------------+     +---------------------+                          | |
 615 |                         | .fn()               |                          | |
 616 |   var_ref_vals[]        +---------------------+                          | |
 617 |  +-------------+        | .flags              |                          | |
 618 |  | $ts0        |<---+   +---------------------+                          | |
 619 |  +-------------+    |   | .var.idx            |                          | |
 620 |  |             |    |   +---------------------+                          | |
 621 |  +-------------+    |   | .var.hist_data      |                          | |
 622 |  |             |    |   +---------------------+                          | |
 623 |  +-------------+    |   | .var_ref_idx        |                          | |
 624 |  |             |    | +-----------------------+                          | |
 625 |  +-------------+    | | var = wakeup_lat      |                          | |
 626 |         .           | +-----------------------+                          | |
 627 |         .           |   | .size               |                          | |
 628 |         .           |   +---------------------+                          | |
 629 |  +-------------+    |   | .offset             |                          | |
 630 |  |             |    |   +---------------------+                          | |
 631 |  +-------------+    |   | .fn()               |                          | |
 632 |  |             |    |   +---------------------+                          | |
 633 |  +-------------+    |   | .flags & FL_VAR     |                          | |
 634 |                     |   +---------------------+                          | |
 635 |                     |   | .var.idx            |                          | |
 636 |                     |   +---------------------+                          | |
 637 |                     |   | .var.hist_data      |                          | |
 638 |                     |   +---------------------+                          | |
 639 |                     |   | .var_ref_idx        |                          | |
 640 |                     |   +---------------------+                          | |
 641 |                     |             .                                      | |
 642 |                     |             .                                      | |
 643 |                     |             .                                      | |
 644 |                     | +-----------------------+ <--- n_vals              | |
 645 |                     | | key = pid             |                          | |
 646 |                     | +-----------------------+                          | |
 647 |                     |   | .size               |                          | |
 648 |                     |   +---------------------+                          | |
 649 |                     |   | .offset             |                          | |
 650 |                     |   +---------------------+                          | |
 651 |                     |   | .fn()               |                          | |
 652 |                     |   +---------------------+                          | |
 653 |                     |   | .flags              |                          | |
 654 |                     |   +---------------------+                          | |
 655 |                     |   | .var.idx            |                          | |
 656 |                     | +-----------------------+ <--- n_fields            | |
 657 |                     | | unused                |                          | |
 658 |                     | +-----------------------+                          | |
 659 |                     |   |                     |                          | |
 660 |                     |   +---------------------+                          | |
 661 |                     |   |                     |                          | |
 662 |                     |   +---------------------+                          | |
 663 |                     |   |                     |                          | |
 664 |                     |   +---------------------+                          | |
 665 |                     |   |                     |                          | |
 666 |                     |   +---------------------+                          | |
 667 |                     |   |                     |                          | |
 668 |                     |   +---------------------+                          | |
 669 |                     |                         n_keys = n_fields - n_vals | |
 670 |                     |                                                    | |
 671 |                     |						    | |
 672 |                     | +-----------------------+                          | |
 673 +---------------------->| var_ref = $ts0        |                          | |
 674                       | +-----------------------+                          | |
 675                       |   | .size               |                          | |
 676                       |   +---------------------+                          | |
 677                       |   | .offset             |                          | |
 678                       |   +---------------------+                          | |
 679                       |   | .fn()               |                          | |
 680                       |   +---------------------+                          | |
 681                       |   | .flags & FL_VAR_REF |                          | |
 682                       |   +---------------------+                          | |
 683                       |   | .var.idx            |--------------------------+ |
 684                       |   +---------------------+                            |
 685                       |   | .var.hist_data      |----------------------------+
 686                       |   +---------------------+
 687                       +---| .var_ref_idx        |
 688                           +---------------------+
 689
 690Abbreviations used in the diagrams::
 691
 692  hist_data = struct hist_trigger_data
 693  hist_data.fields = struct hist_field
 694  fn = hist_field_fn_t
 695  FL_KEY = HIST_FIELD_FL_KEY
 696  FL_VAR = HIST_FIELD_FL_VAR
 697  FL_VAR_REF = HIST_FIELD_FL_VAR_REF
 698
 699When a hist trigger makes use of a variable, a new hist_field is
 700created with flag HIST_FIELD_FL_VAR_REF.  For a VAR_REF field, the
 701var.idx and var.hist_data take the same values as the referenced
 702variable, as well as the referenced variable's size, type, and
 703is_signed values.  The VAR_REF field's .name is set to the name of the
 704variable it references.  If a variable reference was created using the
 705explicit system.event.$var_ref notation, the hist_field's system and
 706event_name variables are also set.
 707
 708So, in order to handle an event for the sched_switch histogram,
 709because we have a reference to a variable on another histogram, we
 710need to resolve all variable references first.  This is done via the
 711resolve_var_refs() calls made from event_hist_trigger().  What this
 712does is grabs the var_refs[] array from the hist_data representing the
 713sched_switch histogram.  For each one of those, the referenced
 714variable's var.hist_data along with the current key is used to look up
 715the corresponding tracing_map_elt in that histogram.  Once found, the
 716referenced variable's var.idx is used to look up the variable's value
 717using tracing_map_read_var(elt, var.idx), which yields the value of
 718the variable for that element, ts0 in the case above.  Note that both
 719the hist_fields representing both the variable and the variable
 720reference have the same var.idx, so this is straightforward.
 721
 722Variable and variable reference test
 723------------------------------------
 724
 725This example creates a variable on the sched_waking event, ts0, and
 726uses it in the sched_switch trigger.  The sched_switch trigger also
 727creates its own variable, wakeup_lat, but nothing yet uses it::
 728
 729  # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
 730
 731  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0' >> events/sched/sched_switch/trigger
 732
 733Looking at the sched_waking 'hist_debug' output, in addition to the
 734normal key and value hist_fields, in the val fields section we see a
 735field with the HIST_FIELD_FL_VAR flag, which indicates that that field
 736represents a variable.  Note that in addition to the variable name,
 737contained in the var.name field, it includes the var.idx, which is the
 738index into the tracing_map_elt.vars[] array of the actual variable
 739location.  Note also that the output shows that variables live in the
 740same part of the hist_data->fields[] array as normal values::
 741
 742  # cat events/sched/sched_waking/hist_debug
 743
 744  # event histogram
 745  #
 746  # trigger info: hist:keys=pid:vals=hitcount:ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global [active]
 747  #
 748
 749  hist_data: 000000009536f554
 750
 751  n_vals: 2
 752  n_keys: 1
 753  n_fields: 3
 754
 755  val fields:
 756
 757    hist_data->fields[0]:
 758      flags:
 759        VAL: HIST_FIELD_FL_HITCOUNT
 760      type: u64
 761      size: 8
 762      is_signed: 0
 763
 764    hist_data->fields[1]:
 765      flags:
 766        HIST_FIELD_FL_VAR
 767      var.name: ts0
 768      var.idx (into tracing_map_elt.vars[]): 0
 769      type: u64
 770      size: 8
 771      is_signed: 0
 772
 773  key fields:
 774
 775    hist_data->fields[2]:
 776      flags:
 777        HIST_FIELD_FL_KEY
 778      ftrace_event_field name: pid
 779      type: pid_t
 780      size: 8
 781      is_signed: 1
 782
 783Moving on to the sched_switch trigger hist_debug output, in addition
 784to the unused wakeup_lat variable, we see a new section displaying
 785variable references.  Variable references are displayed in a separate
 786section because in addition to being logically separate from
 787variables and values, they actually live in a separate hist_data
 788array, var_refs[].
 789
 790In this example, the sched_switch trigger has a reference to a
 791variable on the sched_waking trigger, $ts0.  Looking at the details,
 792we can see that the var.hist_data value of the referenced variable
 793matches the previously displayed sched_waking trigger, and the var.idx
 794value matches the previously displayed var.idx value for that
 795variable.  Also displayed is the var_ref_idx value for that variable
 796reference, which is where the value for that variable is cached for
 797use when the trigger is invoked::
 798
 799  # cat events/sched/sched_switch/hist_debug
 800
 801  # event histogram
 802  #
 803  # trigger info: hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs-$ts0:sort=hitcount:size=2048:clock=global [active]
 804  #
 805
 806  hist_data: 00000000f4ee8006
 807
 808  n_vals: 2
 809  n_keys: 1
 810  n_fields: 3
 811
 812  val fields:
 813
 814    hist_data->fields[0]:
 815      flags:
 816        VAL: HIST_FIELD_FL_HITCOUNT
 817      type: u64
 818      size: 8
 819      is_signed: 0
 820
 821    hist_data->fields[1]:
 822      flags:
 823        HIST_FIELD_FL_VAR
 824      var.name: wakeup_lat
 825      var.idx (into tracing_map_elt.vars[]): 0
 826      type: u64
 827      size: 0
 828      is_signed: 0
 829
 830  key fields:
 831
 832    hist_data->fields[2]:
 833      flags:
 834        HIST_FIELD_FL_KEY
 835      ftrace_event_field name: next_pid
 836      type: pid_t
 837      size: 8
 838      is_signed: 1
 839
 840  variable reference fields:
 841
 842    hist_data->var_refs[0]:
 843      flags:
 844        HIST_FIELD_FL_VAR_REF
 845      name: ts0
 846      var.idx (into tracing_map_elt.vars[]): 0
 847      var.hist_data: 000000009536f554
 848      var_ref_idx (into hist_data->var_refs[]): 0
 849      type: u64
 850      size: 8
 851      is_signed: 0
 852
 853The commands below can be used to clean things up for the next test::
 854
 855  # echo '!hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0' >> events/sched/sched_switch/trigger
 856
 857  # echo '!hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
 858
 859Actions and Handlers
 860====================
 861
 862Adding onto the previous example, we will now do something with that
 863wakeup_lat variable, namely send it and another field as a synthetic
 864event.
 865
 866The onmatch() action below basically says that whenever we have a
 867sched_switch event, if we have a matching sched_waking event, in this
 868case if we have a pid in the sched_waking histogram that matches the
 869next_pid field on this sched_switch event, we retrieve the
 870variables specified in the wakeup_latency() trace action, and use
 871them to generate a new wakeup_latency event into the trace stream.
 872
 873Note that the way the trace handlers such as wakeup_latency() (which
 874could equivalently be written trace(wakeup_latency,$wakeup_lat,next_pid)
 875are implemented, the parameters specified to the trace handler must be
 876variables.  In this case, $wakeup_lat is obviously a variable, but
 877next_pid isn't, since it's just naming a field in the sched_switch
 878trace event.  Since this is something that almost every trace() and
 879save() action does, a special shortcut is implemented to allow field
 880names to be used directly in those cases.  How it works is that under
 881the covers, a temporary variable is created for the named field, and
 882this variable is what is actually passed to the trace handler.  In the
 883code and documentation, this type of variable is called a 'field
 884variable'.
 885
 886Fields on other trace event's histograms can be used as well.  In that
 887case we have to generate a new histogram and an unfortunately named
 888'synthetic_field' (the use of synthetic here has nothing to do with
 889synthetic events) and use that special histogram field as a variable.
 890
 891The diagram below illustrates the new elements described above in the
 892context of the sched_switch histogram using the onmatch() handler and
 893the trace() action.
 894
 895First, we define the wakeup_latency synthetic event::
 896
 897  # echo 'wakeup_latency u64 lat; pid_t pid' >> synthetic_events
 898
 899Next, the sched_waking hist trigger as before::
 900
 901  # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >>
 902          events/sched/sched_waking/trigger
 903
 904Finally, we create a hist trigger on the sched_switch event that
 905generates a wakeup_latency() trace event.  In this case we pass
 906next_pid into the wakeup_latency synthetic event invocation, which
 907means it will be automatically converted into a field variable::
 908
 909  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0: \
 910          onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid)' >>
 911	  /sys/kernel/tracing/events/sched/sched_switch/trigger
 912
 913The diagram for the sched_switch event is similar to previous examples
 914but shows the additional field_vars[] array for hist_data and shows
 915the linkages between the field_vars and the variables and references
 916created to implement the field variables.  The details are discussed
 917below::
 918
 919    +------------------+
 920    | hist_data        |
 921    +------------------+   +-----------------------+
 922      | .fields[]      |-->| val = hitcount        |
 923      +----------------+   +-----------------------+
 924      | .map           |     | .size               |
 925      +----------------+     +---------------------+
 926  +---| .field_vars[]  |     | .offset             |
 927  |   +----------------+     +---------------------+
 928  |+--| .var_refs[]    |     | .offset             |
 929  ||  +----------------+     +---------------------+
 930  ||                         | .fn()               |
 931  ||   var_ref_vals[]        +---------------------+
 932  ||  +-------------+        | .flags              |
 933  ||  | $ts0        |<---+   +---------------------+
 934  ||  +-------------+    |   | .var.idx            |
 935  ||  | $next_pid   |<-+ |   +---------------------+
 936  ||  +-------------+  | |   | .var.hist_data      |
 937  ||+>| $wakeup_lat |  | |   +---------------------+
 938  ||| +-------------+  | |   | .var_ref_idx        |
 939  ||| |             |  | | +-----------------------+
 940  ||| +-------------+  | | | var = wakeup_lat      |
 941  |||        .         | | +-----------------------+
 942  |||        .         | |   | .size               |
 943  |||        .         | |   +---------------------+
 944  ||| +-------------+  | |   | .offset             |
 945  ||| |             |  | |   +---------------------+
 946  ||| +-------------+  | |   | .fn()               |
 947  ||| |             |  | |   +---------------------+
 948  ||| +-------------+  | |   | .flags & FL_VAR     |
 949  |||                  | |   +---------------------+
 950  |||                  | |   | .var.idx            |
 951  |||                  | |   +---------------------+
 952  |||                  | |   | .var.hist_data      |
 953  |||                  | |   +---------------------+
 954  |||                  | |   | .var_ref_idx        |
 955  |||                  | |   +---------------------+
 956  |||                  | |              .
 957  |||                  | |              .
 958  |||                  | |              .
 959  |||                  | |              .
 960  ||| +--------------+ | |              .
 961  +-->| field_var    | | |              .
 962   || +--------------+ | |              .
 963   ||   | var        | | |              .
 964   ||   +------------+ | |              .
 965   ||   | val        | | |              .
 966   || +--------------+ | |              .
 967   || | field_var    | | |              .
 968   || +--------------+ | |              .
 969   ||   | var        | | |              .
 970   ||   +------------+ | |              .
 971   ||   | val        | | |              .
 972   ||   +------------+ | |              .
 973   ||         .        | |              .
 974   ||         .        | |              .
 975   ||         .        | | +-----------------------+ <--- n_vals
 976   || +--------------+ | | | key = pid             |
 977   || | field_var    | | | +-----------------------+
 978   || +--------------+ | |   | .size               |
 979   ||   | var        |--+|   +---------------------+
 980   ||   +------------+ |||   | .offset             |
 981   ||   | val        |-+||   +---------------------+
 982   ||   +------------+ |||   | .fn()               |
 983   ||                  |||   +---------------------+
 984   ||                  |||   | .flags              |
 985   ||                  |||   +---------------------+
 986   ||                  |||   | .var.idx            |
 987   ||                  |||   +---------------------+ <--- n_fields
 988   ||                  |||
 989   ||                  |||                           n_keys = n_fields - n_vals
 990   ||                  ||| +-----------------------+
 991   ||                  |+->| var = next_pid        |
 992   ||                  | | +-----------------------+
 993   ||                  | |   | .size               |
 994   ||                  | |   +---------------------+
 995   ||                  | |   | .offset             |
 996   ||                  | |   +---------------------+
 997   ||                  | |   | .flags & FL_VAR     |
 998   ||                  | |   +---------------------+
 999   ||                  | |   | .var.idx            |
1000   ||                  | |   +---------------------+
1001   ||                  | |   | .var.hist_data      |
1002   ||                  | | +-----------------------+
1003   ||                  +-->| val for next_pid      |
1004   ||                  | | +-----------------------+
1005   ||                  | |   | .size               |
1006   ||                  | |   +---------------------+
1007   ||                  | |   | .offset             |
1008   ||                  | |   +---------------------+
1009   ||                  | |   | .fn()               |
1010   ||                  | |   +---------------------+
1011   ||                  | |   | .flags              |
1012   ||                  | |   +---------------------+
1013   ||                  | |   |                     |
1014   ||                  | |   +---------------------+
1015   ||                  | |
1016   ||                  | |
1017   ||                  | | +-----------------------+
1018   +|------------------|-|>| var_ref = $ts0        |
1019    |                  | | +-----------------------+
1020    |                  | |   | .size               |
1021    |                  | |   +---------------------+
1022    |                  | |   | .offset             |
1023    |                  | |   +---------------------+
1024    |                  | |   | .fn()               |
1025    |                  | |   +---------------------+
1026    |                  | |   | .flags & FL_VAR_REF |
1027    |                  | |   +---------------------+
1028    |                  | +---| .var_ref_idx        |
1029    |                  |   +-----------------------+
1030    |                  |   | var_ref = $next_pid   |
1031    |                  |   +-----------------------+
1032    |                  |     | .size               |
1033    |                  |     +---------------------+
1034    |                  |     | .offset             |
1035    |                  |     +---------------------+
1036    |                  |     | .fn()               |
1037    |                  |     +---------------------+
1038    |                  |     | .flags & FL_VAR_REF |
1039    |                  |     +---------------------+
1040    |                  +-----| .var_ref_idx        |
1041    |                      +-----------------------+
1042    |                      | var_ref = $wakeup_lat |
1043    |                      +-----------------------+
1044    |                        | .size               |
1045    |                        +---------------------+
1046    |                        | .offset             |
1047    |                        +---------------------+
1048    |                        | .fn()               |
1049    |                        +---------------------+
1050    |                        | .flags & FL_VAR_REF |
1051    |                        +---------------------+
1052    +------------------------| .var_ref_idx        |
1053                             +---------------------+
1054
1055As you can see, for a field variable, two hist_fields are created: one
1056representing the variable, in this case next_pid, and one to actually
1057get the value of the field from the trace stream, like a normal val
1058field does.  These are created separately from normal variable
1059creation and are saved in the hist_data->field_vars[] array.  See
1060below for how these are used.  In addition, a reference hist_field is
1061also created, which is needed to reference the field variables such as
1062$next_pid variable in the trace() action.
1063
1064Note that $wakeup_lat is also a variable reference, referencing the
1065value of the expression common_timestamp-$ts0, and so also needs to
1066have a hist field entry representing that reference created.
1067
1068When hist_trigger_elt_update() is called to get the normal key and
1069value fields, it also calls update_field_vars(), which goes through
1070each field_var created for the histogram, and available from
1071hist_data->field_vars and calls val->fn() to get the data from the
1072current trace record, and then uses the var's var.idx to set the
1073variable at the var.idx offset in the appropriate tracing_map_elt's
1074variable at elt->vars[var.idx].
1075
1076Once all the variables have been updated, resolve_var_refs() can be
1077called from event_hist_trigger(), and not only can our $ts0 and
1078$next_pid references be resolved but the $wakeup_lat reference as
1079well.  At this point, the trace() action can simply access the values
1080assembled in the var_ref_vals[] array and generate the trace event.
1081
1082The same process occurs for the field variables associated with the
1083save() action.
1084
1085Abbreviations used in the diagram::
1086
1087  hist_data = struct hist_trigger_data
1088  hist_data.fields = struct hist_field
1089  field_var = struct field_var
1090  fn = hist_field_fn_t
1091  FL_KEY = HIST_FIELD_FL_KEY
1092  FL_VAR = HIST_FIELD_FL_VAR
1093  FL_VAR_REF = HIST_FIELD_FL_VAR_REF
1094
1095trace() action field variable test
1096----------------------------------
1097
1098This example adds to the previous test example by finally making use
1099of the wakeup_lat variable, but in addition also creates a couple of
1100field variables that then are all passed to the wakeup_latency() trace
1101action via the onmatch() handler.
1102
1103First, we create the wakeup_latency synthetic event::
1104
1105  # echo 'wakeup_latency u64 lat; pid_t pid; char comm[16]' >> synthetic_events
1106
1107Next, the sched_waking trigger from previous examples::
1108
1109  # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
1110
1111Finally, as in the previous test example, we calculate and assign the
1112wakeup latency using the $ts0 reference from the sched_waking trigger
1113to the wakeup_lat variable, and finally use it along with a couple
1114sched_switch event fields, next_pid and next_comm, to generate a
1115wakeup_latency trace event.  The next_pid and next_comm event fields
1116are automatically converted into field variables for this purpose::
1117
1118  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,next_comm)' >> /sys/kernel/tracing/events/sched/sched_switch/trigger
1119
1120The sched_waking hist_debug output shows the same data as in the
1121previous test example::
1122
1123  # cat events/sched/sched_waking/hist_debug
1124
1125  # event histogram
1126  #
1127  # trigger info: hist:keys=pid:vals=hitcount:ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global [active]
1128  #
1129
1130  hist_data: 00000000d60ff61f
1131
1132  n_vals: 2
1133  n_keys: 1
1134  n_fields: 3
1135
1136  val fields:
1137
1138    hist_data->fields[0]:
1139      flags:
1140        VAL: HIST_FIELD_FL_HITCOUNT
1141      type: u64
1142      size: 8
1143      is_signed: 0
1144
1145    hist_data->fields[1]:
1146      flags:
1147        HIST_FIELD_FL_VAR
1148      var.name: ts0
1149      var.idx (into tracing_map_elt.vars[]): 0
1150      type: u64
1151      size: 8
1152      is_signed: 0
1153
1154  key fields:
1155
1156    hist_data->fields[2]:
1157      flags:
1158        HIST_FIELD_FL_KEY
1159      ftrace_event_field name: pid
1160      type: pid_t
1161      size: 8
1162      is_signed: 1
1163
1164The sched_switch hist_debug output shows the same key and value fields
1165as in the previous test example - note that wakeup_lat is still in the
1166val fields section, but that the new field variables are not there -
1167although the field variables are variables, they're held separately in
1168the hist_data's field_vars[] array.  Although the field variables and
1169the normal variables are located in separate places, you can see that
1170the actual variable locations for those variables in the
1171tracing_map_elt.vars[] do have increasing indices as expected:
1172wakeup_lat takes the var.idx = 0 slot, while the field variables for
1173next_pid and next_comm have values var.idx = 1, and var.idx = 2.  Note
1174also that those are the same values displayed for the variable
1175references corresponding to those variables in the variable reference
1176fields section.  Since there are two triggers and thus two hist_data
1177addresses, those addresses also need to be accounted for when doing
1178the matching - you can see that the first variable refers to the 0
1179var.idx on the previous hist trigger (see the hist_data address
1180associated with that trigger), while the second variable refers to the
11810 var.idx on the sched_switch hist trigger, as do all the remaining
1182variable references.
1183
1184Finally, the action tracking variables section just shows the system
1185and event name for the onmatch() handler::
1186
1187  # cat events/sched/sched_switch/hist_debug
1188
1189  # event histogram
1190  #
1191  # trigger info: hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs-$ts0:sort=hitcount:size=2048:clock=global:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,next_comm) [active]
1192  #
1193
1194  hist_data: 0000000008f551b7
1195
1196  n_vals: 2
1197  n_keys: 1
1198  n_fields: 3
1199
1200  val fields:
1201
1202    hist_data->fields[0]:
1203      flags:
1204        VAL: HIST_FIELD_FL_HITCOUNT
1205      type: u64
1206      size: 8
1207      is_signed: 0
1208
1209    hist_data->fields[1]:
1210      flags:
1211        HIST_FIELD_FL_VAR
1212      var.name: wakeup_lat
1213      var.idx (into tracing_map_elt.vars[]): 0
1214      type: u64
1215      size: 0
1216      is_signed: 0
1217
1218  key fields:
1219
1220    hist_data->fields[2]:
1221      flags:
1222        HIST_FIELD_FL_KEY
1223      ftrace_event_field name: next_pid
1224      type: pid_t
1225      size: 8
1226      is_signed: 1
1227
1228  variable reference fields:
1229
1230    hist_data->var_refs[0]:
1231      flags:
1232        HIST_FIELD_FL_VAR_REF
1233      name: ts0
1234      var.idx (into tracing_map_elt.vars[]): 0
1235      var.hist_data: 00000000d60ff61f
1236      var_ref_idx (into hist_data->var_refs[]): 0
1237      type: u64
1238      size: 8
1239      is_signed: 0
1240
1241    hist_data->var_refs[1]:
1242      flags:
1243        HIST_FIELD_FL_VAR_REF
1244      name: wakeup_lat
1245      var.idx (into tracing_map_elt.vars[]): 0
1246      var.hist_data: 0000000008f551b7
1247      var_ref_idx (into hist_data->var_refs[]): 1
1248      type: u64
1249      size: 0
1250      is_signed: 0
1251
1252    hist_data->var_refs[2]:
1253      flags:
1254        HIST_FIELD_FL_VAR_REF
1255      name: next_pid
1256      var.idx (into tracing_map_elt.vars[]): 1
1257      var.hist_data: 0000000008f551b7
1258      var_ref_idx (into hist_data->var_refs[]): 2
1259      type: pid_t
1260      size: 4
1261      is_signed: 0
1262
1263    hist_data->var_refs[3]:
1264      flags:
1265        HIST_FIELD_FL_VAR_REF
1266      name: next_comm
1267      var.idx (into tracing_map_elt.vars[]): 2
1268      var.hist_data: 0000000008f551b7
1269      var_ref_idx (into hist_data->var_refs[]): 3
1270      type: char[16]
1271      size: 256
1272      is_signed: 0
1273
1274  field variables:
1275
1276    hist_data->field_vars[0]:
1277
1278      field_vars[0].var:
1279      flags:
1280        HIST_FIELD_FL_VAR
1281      var.name: next_pid
1282      var.idx (into tracing_map_elt.vars[]): 1
1283
1284      field_vars[0].val:
1285      ftrace_event_field name: next_pid
1286      type: pid_t
1287      size: 4
1288      is_signed: 1
1289
1290    hist_data->field_vars[1]:
1291
1292      field_vars[1].var:
1293      flags:
1294        HIST_FIELD_FL_VAR
1295      var.name: next_comm
1296      var.idx (into tracing_map_elt.vars[]): 2
1297
1298      field_vars[1].val:
1299      ftrace_event_field name: next_comm
1300      type: char[16]
1301      size: 256
1302      is_signed: 0
1303
1304  action tracking variables (for onmax()/onchange()/onmatch()):
1305
1306    hist_data->actions[0].match_data.event_system: sched
1307    hist_data->actions[0].match_data.event: sched_waking
1308
1309The commands below can be used to clean things up for the next test::
1310
1311  # echo '!hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,next_comm)' >> /sys/kernel/tracing/events/sched/sched_switch/trigger
1312
1313  # echo '!hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
1314
1315  # echo '!wakeup_latency u64 lat; pid_t pid; char comm[16]' >> synthetic_events
1316
1317action_data and the trace() action
1318----------------------------------
1319
1320As mentioned above, when the trace() action generates a synthetic
1321event, all the parameters to the synthetic event either already are
1322variables or are converted into variables (via field variables), and
1323finally all those variable values are collected via references to them
1324into a var_ref_vals[] array.
1325
1326The values in the var_ref_vals[] array, however, don't necessarily
1327follow the same ordering as the synthetic event params.  To address
1328that, struct action_data contains another array, var_ref_idx[] that
1329maps the trace action params to the var_ref_vals[] values.  Below is a
1330diagram illustrating that for the wakeup_latency() synthetic event::
1331
1332  +------------------+     wakeup_latency()
1333  | action_data      |       event params               var_ref_vals[]
1334  +------------------+    +-----------------+        +-----------------+
1335    | .var_ref_idx[] |--->| $wakeup_lat idx |---+    |                 |
1336    +----------------+    +-----------------+   |    +-----------------+
1337    | .synth_event   |    | $next_pid idx   |---|-+  | $wakeup_lat val |
1338    +----------------+    +-----------------+   | |  +-----------------+
1339                                   .            | +->| $next_pid val   |
1340                                   .            |    +-----------------+
1341                                   .            |           .
1342                          +-----------------+   |           .
1343			  |                 |   |           .
1344			  +-----------------+   |    +-----------------+
1345                                                +--->| $wakeup_lat val |
1346                                                     +-----------------+
1347
1348Basically, how this ends up getting used in the synthetic event probe
1349function, trace_event_raw_event_synth(), is as follows::
1350
1351  for each field i in .synth_event
1352    val_idx = .var_ref_idx[i]
1353    val = var_ref_vals[val_idx]
1354
1355action_data and the onXXX() handlers
1356------------------------------------
1357
1358The hist trigger onXXX() actions other than onmatch(), such as onmax()
1359and onchange(), also make use of and internally create hidden
1360variables.  This information is contained in the
1361action_data.track_data struct, and is also visible in the hist_debug
1362output as will be described in the example below.
1363
1364Typically, the onmax() or onchange() handlers are used in conjunction
1365with the save() and snapshot() actions.  For example::
1366
1367  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0: \
1368          onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm)' >>
1369          /sys/kernel/tracing/events/sched/sched_switch/trigger
1370
1371or::
1372
1373  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0: \
1374          onmax($wakeup_lat).snapshot()' >>
1375          /sys/kernel/tracing/events/sched/sched_switch/trigger
1376
1377save() action field variable test
1378---------------------------------
1379
1380For this example, instead of generating a synthetic event, the save()
1381action is used to save field values whenever an onmax() handler
1382detects that a new max latency has been hit.  As in the previous
1383example, the values being saved are also field values, but in this
1384case, are kept in a separate hist_data array named save_vars[].
1385
1386As in previous test examples, we set up the sched_waking trigger::
1387
1388  # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
1389
1390In this case, however, we set up the sched_switch trigger to save some
1391sched_switch field values whenever we hit a new maximum latency.  For
1392both the onmax() handler and save() action, variables will be created,
1393which we can use the hist_debug files to examine::
1394
1395  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm)' >> events/sched/sched_switch/trigger
1396
1397The sched_waking hist_debug output shows the same data as in the
1398previous test examples::
1399
1400  # cat events/sched/sched_waking/hist_debug
1401
1402  #
1403  # trigger info: hist:keys=pid:vals=hitcount:ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global [active]
1404  #
1405
1406  hist_data: 00000000e6290f48
1407
1408  n_vals: 2
1409  n_keys: 1
1410  n_fields: 3
1411
1412  val fields:
1413
1414    hist_data->fields[0]:
1415      flags:
1416        VAL: HIST_FIELD_FL_HITCOUNT
1417      type: u64
1418      size: 8
1419      is_signed: 0
1420
1421    hist_data->fields[1]:
1422      flags:
1423        HIST_FIELD_FL_VAR
1424      var.name: ts0
1425      var.idx (into tracing_map_elt.vars[]): 0
1426      type: u64
1427      size: 8
1428      is_signed: 0
1429
1430  key fields:
1431
1432    hist_data->fields[2]:
1433      flags:
1434        HIST_FIELD_FL_KEY
1435      ftrace_event_field name: pid
1436      type: pid_t
1437      size: 8
1438      is_signed: 1
1439
1440The output of the sched_switch trigger shows the same val and key
1441values as before, but also shows a couple new sections.
1442
1443First, the action tracking variables section now shows the
1444actions[].track_data information describing the special tracking
1445variables and references used to track, in this case, the running
1446maximum value.  The actions[].track_data.var_ref member contains the
1447reference to the variable being tracked, in this case the $wakeup_lat
1448variable.  In order to perform the onmax() handler function, there
1449also needs to be a variable that tracks the current maximum by getting
1450updated whenever a new maximum is hit.  In this case, we can see that
1451an auto-generated variable named ' __max' has been created and is
1452visible in the actions[].track_data.track_var variable.
1453
1454Finally, in the new 'save action variables' section, we can see that
1455the 4 params to the save() function have resulted in 4 field variables
1456being created for the purposes of saving the values of the named
1457fields when the max is hit.  These variables are kept in a separate
1458save_vars[] array off of hist_data, so are displayed in a separate
1459section::
1460
1461  # cat events/sched/sched_switch/hist_debug
1462
1463  # event histogram
1464  #
1465  # trigger info: hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs-$ts0:sort=hitcount:size=2048:clock=global:onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm) [active]
1466  #
1467
1468  hist_data: 0000000057bcd28d
1469
1470  n_vals: 2
1471  n_keys: 1
1472  n_fields: 3
1473
1474  val fields:
1475
1476    hist_data->fields[0]:
1477      flags:
1478        VAL: HIST_FIELD_FL_HITCOUNT
1479      type: u64
1480      size: 8
1481      is_signed: 0
1482
1483    hist_data->fields[1]:
1484      flags:
1485        HIST_FIELD_FL_VAR
1486      var.name: wakeup_lat
1487      var.idx (into tracing_map_elt.vars[]): 0
1488      type: u64
1489      size: 0
1490      is_signed: 0
1491
1492  key fields:
1493
1494    hist_data->fields[2]:
1495      flags:
1496        HIST_FIELD_FL_KEY
1497      ftrace_event_field name: next_pid
1498      type: pid_t
1499      size: 8
1500      is_signed: 1
1501
1502  variable reference fields:
1503
1504    hist_data->var_refs[0]:
1505      flags:
1506        HIST_FIELD_FL_VAR_REF
1507      name: ts0
1508      var.idx (into tracing_map_elt.vars[]): 0
1509      var.hist_data: 00000000e6290f48
1510      var_ref_idx (into hist_data->var_refs[]): 0
1511      type: u64
1512      size: 8
1513      is_signed: 0
1514
1515    hist_data->var_refs[1]:
1516      flags:
1517        HIST_FIELD_FL_VAR_REF
1518      name: wakeup_lat
1519      var.idx (into tracing_map_elt.vars[]): 0
1520      var.hist_data: 0000000057bcd28d
1521      var_ref_idx (into hist_data->var_refs[]): 1
1522      type: u64
1523      size: 0
1524      is_signed: 0
1525
1526  action tracking variables (for onmax()/onchange()/onmatch()):
1527
1528    hist_data->actions[0].track_data.var_ref:
1529      flags:
1530        HIST_FIELD_FL_VAR_REF
1531      name: wakeup_lat
1532      var.idx (into tracing_map_elt.vars[]): 0
1533      var.hist_data: 0000000057bcd28d
1534      var_ref_idx (into hist_data->var_refs[]): 1
1535      type: u64
1536      size: 0
1537      is_signed: 0
1538
1539    hist_data->actions[0].track_data.track_var:
1540      flags:
1541        HIST_FIELD_FL_VAR
1542      var.name: __max
1543      var.idx (into tracing_map_elt.vars[]): 1
1544      type: u64
1545      size: 8
1546      is_signed: 0
1547
1548  save action variables (save() params):
1549
1550    hist_data->save_vars[0]:
1551
1552      save_vars[0].var:
1553      flags:
1554        HIST_FIELD_FL_VAR
1555      var.name: next_comm
1556      var.idx (into tracing_map_elt.vars[]): 2
1557
1558      save_vars[0].val:
1559      ftrace_event_field name: next_comm
1560      type: char[16]
1561      size: 256
1562      is_signed: 0
1563
1564    hist_data->save_vars[1]:
1565
1566      save_vars[1].var:
1567      flags:
1568        HIST_FIELD_FL_VAR
1569      var.name: prev_pid
1570      var.idx (into tracing_map_elt.vars[]): 3
1571
1572      save_vars[1].val:
1573      ftrace_event_field name: prev_pid
1574      type: pid_t
1575      size: 4
1576      is_signed: 1
1577
1578    hist_data->save_vars[2]:
1579
1580      save_vars[2].var:
1581      flags:
1582        HIST_FIELD_FL_VAR
1583      var.name: prev_prio
1584      var.idx (into tracing_map_elt.vars[]): 4
1585
1586      save_vars[2].val:
1587      ftrace_event_field name: prev_prio
1588      type: int
1589      size: 4
1590      is_signed: 1
1591
1592    hist_data->save_vars[3]:
1593
1594      save_vars[3].var:
1595      flags:
1596        HIST_FIELD_FL_VAR
1597      var.name: prev_comm
1598      var.idx (into tracing_map_elt.vars[]): 5
1599
1600      save_vars[3].val:
1601      ftrace_event_field name: prev_comm
1602      type: char[16]
1603      size: 256
1604      is_signed: 0
1605
1606The commands below can be used to clean things up for the next test::
1607
1608  # echo '!hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm)' >> events/sched/sched_switch/trigger
1609
1610  # echo '!hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
1611
1612A couple special cases
1613======================
1614
1615While the above covers the basics of the histogram internals, there
1616are a couple of special cases that should be discussed, since they
1617tend to create even more confusion.  Those are field variables on other
1618histograms, and aliases, both described below through example tests
1619using the hist_debug files.
1620
1621Test of field variables on other histograms
1622-------------------------------------------
1623
1624This example is similar to the previous examples, but in this case,
1625the sched_switch trigger references a hist trigger field on another
1626event, namely the sched_waking event.  In order to accomplish this, a
1627field variable is created for the other event, but since an existing
1628histogram can't be used, as existing histograms are immutable, a new
1629histogram with a matching variable is created and used, and we'll see
1630that reflected in the hist_debug output shown below.
1631
1632First, we create the wakeup_latency synthetic event.  Note the
1633addition of the prio field::
1634
1635  # echo 'wakeup_latency u64 lat; pid_t pid; int prio' >> synthetic_events
1636
1637As in previous test examples, we set up the sched_waking trigger::
1638
1639  # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
1640
1641Here we set up a hist trigger on sched_switch to send a wakeup_latency
1642event using an onmatch handler naming the sched_waking event.  Note
1643that the third param being passed to the wakeup_latency() is prio,
1644which is a field name that needs to have a field variable created for
1645it.  There isn't however any prio field on the sched_switch event so
1646it would seem that it wouldn't be possible to create a field variable
1647for it.  The matching sched_waking event does have a prio field, so it
1648should be possible to make use of it for this purpose.  The problem
1649with that is that it's not currently possible to define a new variable
1650on an existing histogram, so it's not possible to add a new prio field
1651variable to the existing sched_waking histogram.  It is however
1652possible to create an additional new 'matching' sched_waking histogram
1653for the same event, meaning that it uses the same key and filters, and
1654define the new prio field variable on that.
1655
1656Here's the sched_switch trigger::
1657
1658  # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,prio)' >> events/sched/sched_switch/trigger
1659
1660And here's the output of the hist_debug information for the
1661sched_waking hist trigger.  Note that there are two histograms
1662displayed in the output: the first is the normal sched_waking
1663histogram we've seen in the previous examples, and the second is the
1664special histogram we created to provide the prio field variable.
1665
1666Looking at the second histogram below, we see a variable with the name
1667synthetic_prio.  This is the field variable created for the prio field
1668on that sched_waking histogram::
1669
1670  # cat events/sched/sched_waking/hist_debug
1671
1672  # event histogram
1673  #
1674  # trigger info: hist:keys=pid:vals=hitcount:ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global [active]
1675  #
1676
1677  hist_data: 00000000349570e4
1678
1679  n_vals: 2
1680  n_keys: 1
1681  n_fields: 3
1682
1683  val fields:
1684
1685    hist_data->fields[0]:
1686      flags:
1687        VAL: HIST_FIELD_FL_HITCOUNT
1688      type: u64
1689      size: 8
1690      is_signed: 0
1691
1692    hist_data->fields[1]:
1693      flags:
1694        HIST_FIELD_FL_VAR
1695      var.name: ts0
1696      var.idx (into tracing_map_elt.vars[]): 0
1697      type: u64
1698      size: 8
1699      is_signed: 0
1700
1701  key fields:
1702
1703    hist_data->fields[2]:
1704      flags:
1705        HIST_FIELD_FL_KEY
1706      ftrace_event_field name: pid
1707      type: pid_t
1708      size: 8
1709      is_signed: 1
1710
1711
1712  # event histogram
1713  #
1714  # trigger info: hist:keys=pid:vals=hitcount:synthetic_prio=prio:sort=hitcount:size=2048 [active]
1715  #
1716
1717  hist_data: 000000006920cf38
1718
1719  n_vals: 2
1720  n_keys: 1
1721  n_fields: 3
1722
1723  val fields:
1724
1725    hist_data->fields[0]:
1726      flags:
1727        VAL: HIST_FIELD_FL_HITCOUNT
1728      type: u64
1729      size: 8
1730      is_signed: 0
1731
1732    hist_data->fields[1]:
1733      flags:
1734        HIST_FIELD_FL_VAR
1735      ftrace_event_field name: prio
1736      var.name: synthetic_prio
1737      var.idx (into tracing_map_elt.vars[]): 0
1738      type: int
1739      size: 4
1740      is_signed: 1
1741
1742  key fields:
1743
1744    hist_data->fields[2]:
1745      flags:
1746        HIST_FIELD_FL_KEY
1747      ftrace_event_field name: pid
1748      type: pid_t
1749      size: 8
1750      is_signed: 1
1751
1752Looking at the sched_switch histogram below, we can see a reference to
1753the synthetic_prio variable on sched_waking, and looking at the
1754associated hist_data address we see that it is indeed associated with
1755the new histogram.  Note also that the other references are to a
1756normal variable, wakeup_lat, and to a normal field variable, next_pid,
1757the details of which are in the field variables section::
1758
1759  # cat events/sched/sched_switch/hist_debug
1760
1761  # event histogram
1762  #
1763  # trigger info: hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs-$ts0:sort=hitcount:size=2048:clock=global:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,prio) [active]
1764  #
1765
1766  hist_data: 00000000a73b67df
1767
1768  n_vals: 2
1769  n_keys: 1
1770  n_fields: 3
1771
1772  val fields:
1773
1774    hist_data->fields[0]:
1775      flags:
1776        VAL: HIST_FIELD_FL_HITCOUNT
1777      type: u64
1778      size: 8
1779      is_signed: 0
1780
1781    hist_data->fields[1]:
1782      flags:
1783        HIST_FIELD_FL_VAR
1784      var.name: wakeup_lat
1785      var.idx (into tracing_map_elt.vars[]): 0
1786      type: u64
1787      size: 0
1788      is_signed: 0
1789
1790  key fields:
1791
1792    hist_data->fields[2]:
1793      flags:
1794        HIST_FIELD_FL_KEY
1795      ftrace_event_field name: next_pid
1796      type: pid_t
1797      size: 8
1798      is_signed: 1
1799
1800  variable reference fields:
1801
1802    hist_data->var_refs[0]:
1803      flags:
1804        HIST_FIELD_FL_VAR_REF
1805      name: ts0
1806      var.idx (into tracing_map_elt.vars[]): 0
1807      var.hist_data: 00000000349570e4
1808      var_ref_idx (into hist_data->var_refs[]): 0
1809      type: u64
1810      size: 8
1811      is_signed: 0
1812
1813    hist_data->var_refs[1]:
1814      flags:
1815        HIST_FIELD_FL_VAR_REF
1816      name: wakeup_lat
1817      var.idx (into tracing_map_elt.vars[]): 0
1818      var.hist_data: 00000000a73b67df
1819      var_ref_idx (into hist_data->var_refs[]): 1
1820      type: u64
1821      size: 0
1822      is_signed: 0
1823
1824    hist_data->var_refs[2]:
1825      flags:
1826        HIST_FIELD_FL_VAR_REF
1827      name: next_pid
1828      var.idx (into tracing_map_elt.vars[]): 1
1829      var.hist_data: 00000000a73b67df
1830      var_ref_idx (into hist_data->var_refs[]): 2
1831      type: pid_t
1832      size: 4
1833      is_signed: 0
1834
1835    hist_data->var_refs[3]:
1836      flags:
1837        HIST_FIELD_FL_VAR_REF
1838      name: synthetic_prio
1839      var.idx (into tracing_map_elt.vars[]): 0
1840      var.hist_data: 000000006920cf38
1841      var_ref_idx (into hist_data->var_refs[]): 3
1842      type: int
1843      size: 4
1844      is_signed: 1
1845
1846  field variables:
1847
1848    hist_data->field_vars[0]:
1849
1850      field_vars[0].var:
1851      flags:
1852        HIST_FIELD_FL_VAR
1853      var.name: next_pid
1854      var.idx (into tracing_map_elt.vars[]): 1
1855
1856      field_vars[0].val:
1857      ftrace_event_field name: next_pid
1858      type: pid_t
1859      size: 4
1860      is_signed: 1
1861
1862  action tracking variables (for onmax()/onchange()/onmatch()):
1863
1864    hist_data->actions[0].match_data.event_system: sched
1865    hist_data->actions[0].match_data.event: sched_waking
1866
1867The commands below can be used to clean things up for the next test::
1868
1869  # echo '!hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,prio)' >> events/sched/sched_switch/trigger
1870
1871  # echo '!hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
1872
1873  # echo '!wakeup_latency u64 lat; pid_t pid; int prio' >> synthetic_events
1874
1875Alias test
1876----------
1877
1878This example is very similar to previous examples, but demonstrates
1879the alias flag.
1880
1881First, we create the wakeup_latency synthetic event::
1882
1883  # echo 'wakeup_latency u64 lat; pid_t pid; char comm[16]' >> synthetic_events
1884
1885Next, we create a sched_waking trigger similar to previous examples,
1886but in this case we save the pid in the waking_pid variable::
1887
1888  # echo 'hist:keys=pid:waking_pid=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
1889
1890For the sched_switch trigger, instead of using $waking_pid directly in
1891the wakeup_latency synthetic event invocation, we create an alias of
1892$waking_pid named $woken_pid, and use that in the synthetic event
1893invocation instead::
1894
1895  # echo 'hist:keys=next_pid:woken_pid=$waking_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,$woken_pid,next_comm)' >> events/sched/sched_switch/trigger
1896
1897Looking at the sched_waking hist_debug output, in addition to the
1898normal fields, we can see the waking_pid variable::
1899
1900  # cat events/sched/sched_waking/hist_debug
1901
1902  # event histogram
1903  #
1904  # trigger info: hist:keys=pid:vals=hitcount:waking_pid=pid,ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global [active]
1905  #
1906
1907  hist_data: 00000000a250528c
1908
1909  n_vals: 3
1910  n_keys: 1
1911  n_fields: 4
1912
1913  val fields:
1914
1915    hist_data->fields[0]:
1916      flags:
1917        VAL: HIST_FIELD_FL_HITCOUNT
1918      type: u64
1919      size: 8
1920      is_signed: 0
1921
1922    hist_data->fields[1]:
1923      flags:
1924        HIST_FIELD_FL_VAR
1925      ftrace_event_field name: pid
1926      var.name: waking_pid
1927      var.idx (into tracing_map_elt.vars[]): 0
1928      type: pid_t
1929      size: 4
1930      is_signed: 1
1931
1932    hist_data->fields[2]:
1933      flags:
1934        HIST_FIELD_FL_VAR
1935      var.name: ts0
1936      var.idx (into tracing_map_elt.vars[]): 1
1937      type: u64
1938      size: 8
1939      is_signed: 0
1940
1941  key fields:
1942
1943    hist_data->fields[3]:
1944      flags:
1945        HIST_FIELD_FL_KEY
1946      ftrace_event_field name: pid
1947      type: pid_t
1948      size: 8
1949      is_signed: 1
1950
1951The sched_switch hist_debug output shows that a variable named
1952woken_pid has been created but that it also has the
1953HIST_FIELD_FL_ALIAS flag set.  It also has the HIST_FIELD_FL_VAR flag
1954set, which is why it appears in the val field section.
1955
1956Despite that implementation detail, an alias variable is actually more
1957like a variable reference; in fact it can be thought of as a reference
1958to a reference.  The implementation copies the var_ref->fn() from the
1959variable reference being referenced, in this case, the waking_pid
1960fn(), which is hist_field_var_ref() and makes that the fn() of the
1961alias.  The hist_field_var_ref() fn() requires the var_ref_idx of the
1962variable reference it's using, so waking_pid's var_ref_idx is also
1963copied to the alias.  The end result is that when the value of alias
1964is retrieved, in the end it just does the same thing the original
1965reference would have done and retrieves the same value from the
1966var_ref_vals[] array.  You can verify this in the output by noting
1967that the var_ref_idx of the alias, in this case woken_pid, is the same
1968as the var_ref_idx of the reference, waking_pid, in the variable
1969reference fields section.
1970
1971Additionally, once it gets that value, since it is also a variable, it
1972then saves that value into its var.idx.  So the var.idx of the
1973woken_pid alias is 0, which it fills with the value from var_ref_idx 0
1974when its fn() is called to update itself.  You'll also notice that
1975there's a woken_pid var_ref in the variable refs section.  That is the
1976reference to the woken_pid alias variable, and you can see that it
1977retrieves the value from the same var.idx as the woken_pid alias, 0,
1978and then in turn saves that value in its own var_ref_idx slot, 3, and
1979the value at this position is finally what gets assigned to the
1980$woken_pid slot in the trace event invocation::
1981
1982  # cat events/sched/sched_switch/hist_debug
1983
1984  # event histogram
1985  #
1986  # trigger info: hist:keys=next_pid:vals=hitcount:woken_pid=$waking_pid,wakeup_lat=common_timestamp.usecs-$ts0:sort=hitcount:size=2048:clock=global:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,$woken_pid,next_comm) [active]
1987  #
1988
1989  hist_data: 0000000055d65ed0
1990
1991  n_vals: 3
1992  n_keys: 1
1993  n_fields: 4
1994
1995  val fields:
1996
1997    hist_data->fields[0]:
1998      flags:
1999        VAL: HIST_FIELD_FL_HITCOUNT
2000      type: u64
2001      size: 8
2002      is_signed: 0
2003
2004    hist_data->fields[1]:
2005      flags:
2006        HIST_FIELD_FL_VAR
2007        HIST_FIELD_FL_ALIAS
2008      var.name: woken_pid
2009      var.idx (into tracing_map_elt.vars[]): 0
2010      var_ref_idx (into hist_data->var_refs[]): 0
2011      type: pid_t
2012      size: 4
2013      is_signed: 1
2014
2015    hist_data->fields[2]:
2016      flags:
2017        HIST_FIELD_FL_VAR
2018      var.name: wakeup_lat
2019      var.idx (into tracing_map_elt.vars[]): 1
2020      type: u64
2021      size: 0
2022      is_signed: 0
2023
2024  key fields:
2025
2026    hist_data->fields[3]:
2027      flags:
2028        HIST_FIELD_FL_KEY
2029      ftrace_event_field name: next_pid
2030      type: pid_t
2031      size: 8
2032      is_signed: 1
2033
2034  variable reference fields:
2035
2036    hist_data->var_refs[0]:
2037      flags:
2038        HIST_FIELD_FL_VAR_REF
2039      name: waking_pid
2040      var.idx (into tracing_map_elt.vars[]): 0
2041      var.hist_data: 00000000a250528c
2042      var_ref_idx (into hist_data->var_refs[]): 0
2043      type: pid_t
2044      size: 4
2045      is_signed: 1
2046
2047    hist_data->var_refs[1]:
2048      flags:
2049        HIST_FIELD_FL_VAR_REF
2050      name: ts0
2051      var.idx (into tracing_map_elt.vars[]): 1
2052      var.hist_data: 00000000a250528c
2053      var_ref_idx (into hist_data->var_refs[]): 1
2054      type: u64
2055      size: 8
2056      is_signed: 0
2057
2058    hist_data->var_refs[2]:
2059      flags:
2060        HIST_FIELD_FL_VAR_REF
2061      name: wakeup_lat
2062      var.idx (into tracing_map_elt.vars[]): 1
2063      var.hist_data: 0000000055d65ed0
2064      var_ref_idx (into hist_data->var_refs[]): 2
2065      type: u64
2066      size: 0
2067      is_signed: 0
2068
2069    hist_data->var_refs[3]:
2070      flags:
2071        HIST_FIELD_FL_VAR_REF
2072      name: woken_pid
2073      var.idx (into tracing_map_elt.vars[]): 0
2074      var.hist_data: 0000000055d65ed0
2075      var_ref_idx (into hist_data->var_refs[]): 3
2076      type: pid_t
2077      size: 4
2078      is_signed: 1
2079
2080    hist_data->var_refs[4]:
2081      flags:
2082        HIST_FIELD_FL_VAR_REF
2083      name: next_comm
2084      var.idx (into tracing_map_elt.vars[]): 2
2085      var.hist_data: 0000000055d65ed0
2086      var_ref_idx (into hist_data->var_refs[]): 4
2087      type: char[16]
2088      size: 256
2089      is_signed: 0
2090
2091  field variables:
2092
2093    hist_data->field_vars[0]:
2094
2095      field_vars[0].var:
2096      flags:
2097        HIST_FIELD_FL_VAR
2098      var.name: next_comm
2099      var.idx (into tracing_map_elt.vars[]): 2
2100
2101      field_vars[0].val:
2102      ftrace_event_field name: next_comm
2103      type: char[16]
2104      size: 256
2105      is_signed: 0
2106
2107  action tracking variables (for onmax()/onchange()/onmatch()):
2108
2109    hist_data->actions[0].match_data.event_system: sched
2110    hist_data->actions[0].match_data.event: sched_waking
2111
2112The commands below can be used to clean things up for the next test::
2113
2114  # echo '!hist:keys=next_pid:woken_pid=$waking_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,$woken_pid,next_comm)' >> events/sched/sched_switch/trigger
2115
2116  # echo '!hist:keys=pid:ts0=common_timestamp.usecs' >> events/sched/sched_waking/trigger
2117
2118  # echo '!wakeup_latency u64 lat; pid_t pid; char comm[16]' >> synthetic_events
~/ Read-only file preview.