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