xref: /linux/Documentation/trace/histogram-design.rst (revision 68a052239fc4b351e961f698b824f7654a346091)
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
2119