1*287e80b3SSadaf Ebrahimilibtracefs(3) 2*287e80b3SSadaf Ebrahimi============= 3*287e80b3SSadaf Ebrahimi 4*287e80b3SSadaf EbrahimiNAME 5*287e80b3SSadaf Ebrahimi---- 6*287e80b3SSadaf Ebrahimitracefs_synth_echo_cmd, tracefs_synth_get_start_hist, tracefs_synth_get_name, 7*287e80b3SSadaf Ebrahimitracefs_synth_raw_fmt, tracefs_synth_show_event, tracefs_synth_show_start_hist, tracefs_synth_show_end_hist, 8*287e80b3SSadaf Ebrahimitracefs_synth_get_event - Retrieve data of synthetic events. 9*287e80b3SSadaf Ebrahimi 10*287e80b3SSadaf EbrahimiSYNOPSIS 11*287e80b3SSadaf Ebrahimi-------- 12*287e80b3SSadaf Ebrahimi[verse] 13*287e80b3SSadaf Ebrahimi-- 14*287e80b3SSadaf Ebrahimi*#include <tracefs.h>* 15*287e80b3SSadaf Ebrahimi 16*287e80b3SSadaf Ebrahimiint *tracefs_synth_echo_cmd*(struct trace_seq pass:[*]_seq_, struct tracefs_synth pass:[*]_synth_); 17*287e80b3SSadaf Ebrahimistruct tracefs_hist pass:[*]*tracefs_synth_get_start_hist*(struct tracefs_synth pass:[*]_synth_); 18*287e80b3SSadaf Ebrahimi 19*287e80b3SSadaf Ebrahimiconst char pass:[*]*tracefs_synth_get_name*(struct tracefs_synth pass:[*]_synth_); 20*287e80b3SSadaf Ebrahimiint *tracefs_synth_raw_fmt*(struct trace_seq pass:[*]_seq_, struct tracefs_synth pass:[*]_synth_); 21*287e80b3SSadaf Ebrahimiconst char pass:[*]*tracefs_synth_show_event*(struct tracefs_synth pass:[*]_synth_); 22*287e80b3SSadaf Ebrahimiconst char pass:[*]*tracefs_synth_show_start_hist*(struct tracefs_synth pass:[*]_synth_); 23*287e80b3SSadaf Ebrahimiconst char pass:[*]*tracefs_synth_show_end_hist*(struct tracefs_synth pass:[*]_synth_); 24*287e80b3SSadaf Ebrahimistruct tep_event pass:[*]*tracefs_synth_get_event*(struct tep_handle pass:[*]_tep_, struct tracefs_synth pass:[*]_synth_); 25*287e80b3SSadaf Ebrahimi 26*287e80b3SSadaf Ebrahimi-- 27*287e80b3SSadaf Ebrahimi 28*287e80b3SSadaf EbrahimiDESCRIPTION 29*287e80b3SSadaf Ebrahimi----------- 30*287e80b3SSadaf EbrahimiSynthetic events are dynamic events that are created by matching 31*287e80b3SSadaf Ebrahimitwo other events which triggers a synthetic event. One event is the starting 32*287e80b3SSadaf Ebrahimievent which some field is recorded, and when the second event is executed, 33*287e80b3SSadaf Ebrahimiif it has a field (or fields) that matches the starting event's field (or fields) 34*287e80b3SSadaf Ebrahimithen it will trigger the synthetic event. The field values other than the matching 35*287e80b3SSadaf Ebrahimifields may be passed from the starting event to the end event to perform calculations 36*287e80b3SSadaf Ebrahimion, or to simply pass as a parameter to the synthetic event. 37*287e80b3SSadaf Ebrahimi 38*287e80b3SSadaf EbrahimiOne common use case is to set "sched_waking" as the starting event. This event is 39*287e80b3SSadaf Ebrahimitriggered when a process is awoken. Then set "sched_switch" as the ending event. 40*287e80b3SSadaf EbrahimiThis event is triggered when a new task is scheduled on the CPU. By setting 41*287e80b3SSadaf Ebrahimithe "common_pid" of both events as the matching fields, the time between the 42*287e80b3SSadaf Ebrahimitwo events is considered the wake up latency of that process. Use *TRACEFS_TIMESTAMP* 43*287e80b3SSadaf Ebrahimias a field for both events to calculate the delta in nanoseconds, or use 44*287e80b3SSadaf Ebrahimi*TRACEFS_TIMESTAMP_USECS* as the compare fields for both events to calculate the 45*287e80b3SSadaf Ebrahimidelta in microseconds. This is used as the example below. 46*287e80b3SSadaf Ebrahimi 47*287e80b3SSadaf EbrahimiSee *tracefs_synth_alloc*(3) for allocation of synthetic events, and 48*287e80b3SSadaf Ebrahimi*tracefs_synth_create*() for creating the synthetic event on the system. 49*287e80b3SSadaf Ebrahimi 50*287e80b3SSadaf Ebrahimi*tracefs_synth_echo_cmd*() acts like *tracefs_synth_create*(), but instead of creating 51*287e80b3SSadaf Ebrahimithe synthetic event in the system, it will write the echo commands to manually create 52*287e80b3SSadaf Ebrahimiit in the _seq_ given. 53*287e80b3SSadaf Ebrahimi 54*287e80b3SSadaf Ebrahimi*tracefs_synth_get_start_hist*() returns a struct tracefs_hist descriptor describing 55*287e80b3SSadaf Ebrahimithe histogram used to create the synthetic event. 56*287e80b3SSadaf Ebrahimi 57*287e80b3SSadaf Ebrahimi[verse] 58*287e80b3SSadaf Ebrahimi-- 59*287e80b3SSadaf Ebrahimienum tracefs_synth_handler { 60*287e80b3SSadaf Ebrahimi *TRACEFS_SYNTH_HANDLE_MATCH*, 61*287e80b3SSadaf Ebrahimi *TRACEFS_SYNTH_HANDLE_MAX*, 62*287e80b3SSadaf Ebrahimi *TRACEFS_SYNTH_HANDLE_CHANGE*, 63*287e80b3SSadaf Ebrahimi}; 64*287e80b3SSadaf Ebrahimi-- 65*287e80b3SSadaf Ebrahimi 66*287e80b3SSadaf Ebrahimi*tracefs_synth_get_name*() returns the name of the synthetic event or NULL on error. 67*287e80b3SSadaf EbrahimiThe returned string belongs to the synth event object and is freed with the event 68*287e80b3SSadaf Ebrahimiby *tracefs_synth_free*(). 69*287e80b3SSadaf Ebrahimi 70*287e80b3SSadaf Ebrahimi*tracefs_synth_raw_fmt*() writes the raw format strings (dynamic event and histograms) of 71*287e80b3SSadaf Ebrahimithe synthetic event in the _seq_ given. 72*287e80b3SSadaf Ebrahimi 73*287e80b3SSadaf Ebrahimi*tracefs_synth_show_event*() returns the format of the dynamic event used by the synthetic 74*287e80b3SSadaf Ebrahimievent or NULL on error. The returned string belongs to the synth event object and is freed 75*287e80b3SSadaf Ebrahimiwith the event by *tracefs_synth_free*(). 76*287e80b3SSadaf Ebrahimi 77*287e80b3SSadaf Ebrahimi*tracefs_synth_show_start_hist*() returns the format of the start histogram used by the 78*287e80b3SSadaf Ebrahimisynthetic event or NULL on error. The returned string belongs to the synth event object 79*287e80b3SSadaf Ebrahimiand is freed with the event by *tracefs_synth_free*(). 80*287e80b3SSadaf Ebrahimi 81*287e80b3SSadaf Ebrahimi*tracefs_synth_show_end_hist*() returns the format of the end histogram used by the 82*287e80b3SSadaf Ebrahimisynthetic event or NULL on error. The returned string belongs to the synth event object 83*287e80b3SSadaf Ebrahimiand is freed with the event by *tracefs_synth_free*(). 84*287e80b3SSadaf Ebrahimi 85*287e80b3SSadaf EbrahimiThe *tracefs_synth_get_event*() function returns a tep event, describing the given synthetic 86*287e80b3SSadaf Ebrahimievent. The API detects any newly created or removed dynamic events. The returned pointer to 87*287e80b3SSadaf Ebrahimitep event is controlled by @tep and must not be freed. 88*287e80b3SSadaf Ebrahimi 89*287e80b3SSadaf EbrahimiRETURN VALUE 90*287e80b3SSadaf Ebrahimi------------ 91*287e80b3SSadaf Ebrahimi*tracefs_synth_get_name*(), *tracefs_synth_show_event*(), *tracefs_synth_show_start_hist*() 92*287e80b3SSadaf Ebrahimiand *tracefs_synth_show_end_hist*() return a string owned by the synth event object. 93*287e80b3SSadaf Ebrahimi 94*287e80b3SSadaf EbrahimiThe *tracefs_synth_get_event*() function returns a pointer to a tep event or NULL in case of an 95*287e80b3SSadaf Ebrahimierror or if the requested synthetic event is missing. The returned pointer to tep event is 96*287e80b3SSadaf Ebrahimicontrolled by @tep and must not be freed. 97*287e80b3SSadaf Ebrahimi 98*287e80b3SSadaf EbrahimiAll other functions return zero on success or -1 on error. 99*287e80b3SSadaf Ebrahimi 100*287e80b3SSadaf EbrahimiERRORS 101*287e80b3SSadaf Ebrahimi------ 102*287e80b3SSadaf EbrahimiThe following errors are for all the above calls: 103*287e80b3SSadaf Ebrahimi 104*287e80b3SSadaf Ebrahimi*EPERM* Not run as root user when required. 105*287e80b3SSadaf Ebrahimi 106*287e80b3SSadaf Ebrahimi*EINVAL* Either a parameter is not valid (NULL when it should not be) 107*287e80b3SSadaf Ebrahimi or a field that is not compatible for calculations. 108*287e80b3SSadaf Ebrahimi 109*287e80b3SSadaf Ebrahimi*ENODEV* An event or one of its fields is not found. 110*287e80b3SSadaf Ebrahimi 111*287e80b3SSadaf Ebrahimi*EBADE* The fields of the start and end events are not compatible for 112*287e80b3SSadaf Ebrahimi either matching or comparing. 113*287e80b3SSadaf Ebrahimi 114*287e80b3SSadaf Ebrahimi*ENOMEM* not enough memory is available. 115*287e80b3SSadaf Ebrahimi 116*287e80b3SSadaf EbrahimiAnd more errors may have happened from the system calls to the system. 117*287e80b3SSadaf Ebrahimi 118*287e80b3SSadaf EbrahimiEXAMPLE 119*287e80b3SSadaf Ebrahimi------- 120*287e80b3SSadaf EbrahimiSee *tracefs_sql*(3) for a more indepth use of some of this code. 121*287e80b3SSadaf Ebrahimi 122*287e80b3SSadaf Ebrahimi[source,c] 123*287e80b3SSadaf Ebrahimi-- 124*287e80b3SSadaf Ebrahimi#include <stdlib.h> 125*287e80b3SSadaf Ebrahimi#include <tracefs.h> 126*287e80b3SSadaf Ebrahimi 127*287e80b3SSadaf Ebrahimi#define start_event "sched_waking" 128*287e80b3SSadaf Ebrahimi#define start_field "pid" 129*287e80b3SSadaf Ebrahimi 130*287e80b3SSadaf Ebrahimi#define end_event "sched_switch" 131*287e80b3SSadaf Ebrahimi#define end_field "next_pid" 132*287e80b3SSadaf Ebrahimi 133*287e80b3SSadaf Ebrahimi#define match_name "pid" 134*287e80b3SSadaf Ebrahimi 135*287e80b3SSadaf Ebrahimistatic struct tracefs_synth *synth; 136*287e80b3SSadaf Ebrahimi 137*287e80b3SSadaf Ebrahimistatic void make_event(void) 138*287e80b3SSadaf Ebrahimi{ 139*287e80b3SSadaf Ebrahimi struct tep_handle *tep; 140*287e80b3SSadaf Ebrahimi 141*287e80b3SSadaf Ebrahimi /* Load all events from the system */ 142*287e80b3SSadaf Ebrahimi tep = tracefs_local_events(NULL); 143*287e80b3SSadaf Ebrahimi 144*287e80b3SSadaf Ebrahimi /* Initialize the synthetic event */ 145*287e80b3SSadaf Ebrahimi synth = tracefs_synth_alloc(tep, "wakeup_lat", 146*287e80b3SSadaf Ebrahimi NULL, start_event, 147*287e80b3SSadaf Ebrahimi NULL, end_event, 148*287e80b3SSadaf Ebrahimi start_field, end_field, 149*287e80b3SSadaf Ebrahimi match_name); 150*287e80b3SSadaf Ebrahimi 151*287e80b3SSadaf Ebrahimi /* The tep is no longer needed */ 152*287e80b3SSadaf Ebrahimi tep_free(tep); 153*287e80b3SSadaf Ebrahimi 154*287e80b3SSadaf Ebrahimi 155*287e80b3SSadaf Ebrahimi /* Save the "prio" field as "prio" from the start event */ 156*287e80b3SSadaf Ebrahimi tracefs_synth_add_start_field(synth, "prio", NULL); 157*287e80b3SSadaf Ebrahimi 158*287e80b3SSadaf Ebrahimi /* Save the "next_comm" as "comm" from the end event */ 159*287e80b3SSadaf Ebrahimi tracefs_synth_add_end_field(synth, "next_comm", "comm"); 160*287e80b3SSadaf Ebrahimi 161*287e80b3SSadaf Ebrahimi /* Save the "prev_prio" as "prev_prio" from the end event */ 162*287e80b3SSadaf Ebrahimi tracefs_synth_add_end_field(synth, "prev_prio", NULL); 163*287e80b3SSadaf Ebrahimi 164*287e80b3SSadaf Ebrahimi /* 165*287e80b3SSadaf Ebrahimi * Take a microsecond time difference between end and start 166*287e80b3SSadaf Ebrahimi * and record as "delta" 167*287e80b3SSadaf Ebrahimi */ 168*287e80b3SSadaf Ebrahimi tracefs_synth_add_compare_field(synth, TRACEFS_TIMESTAMP_USECS, 169*287e80b3SSadaf Ebrahimi TRACEFS_TIMESTAMP_USECS, 170*287e80b3SSadaf Ebrahimi TRACEFS_SYNTH_DELTA_END, "delta"); 171*287e80b3SSadaf Ebrahimi 172*287e80b3SSadaf Ebrahimi /* Only record if start event "prio" is less than 100 */ 173*287e80b3SSadaf Ebrahimi tracefs_synth_append_start_filter(synth, TRACEFS_FILTER_COMPARE, 174*287e80b3SSadaf Ebrahimi "prio", TRACEFS_COMPARE_LT, "100"); 175*287e80b3SSadaf Ebrahimi 176*287e80b3SSadaf Ebrahimi /* 177*287e80b3SSadaf Ebrahimi * Only record if end event "next_prio" is less than 50 178*287e80b3SSadaf Ebrahimi * or the previous task's prio was not greater than or equal to 100. 179*287e80b3SSadaf Ebrahimi * next_prio < 50 || !(prev_prio >= 100) 180*287e80b3SSadaf Ebrahimi */ 181*287e80b3SSadaf Ebrahimi tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_COMPARE, 182*287e80b3SSadaf Ebrahimi "next_prio", TRACEFS_COMPARE_LT, "50"); 183*287e80b3SSadaf Ebrahimi tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_OR, NULL, 0, NULL); 184*287e80b3SSadaf Ebrahimi tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_NOT, NULL, 0, NULL); 185*287e80b3SSadaf Ebrahimi tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_OPEN_PAREN, NULL, 0, NULL); 186*287e80b3SSadaf Ebrahimi tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_COMPARE, 187*287e80b3SSadaf Ebrahimi "prev_prio", TRACEFS_COMPARE_GE, "100"); 188*287e80b3SSadaf Ebrahimi /* 189*287e80b3SSadaf Ebrahimi * Note, the above only added: "next_prio < 50 || !(prev_prio >= 100" 190*287e80b3SSadaf Ebrahimi * That's because, when the synth is executed, the remaining close parenthesis 191*287e80b3SSadaf Ebrahimi * will be added. That is, the string will end up being: 192*287e80b3SSadaf Ebrahimi * "next_prio < 50 || !(prev_prio >= 100)" when one of tracefs_sync_create() 193*287e80b3SSadaf Ebrahimi * or tracefs_sync_echo_cmd() is run. 194*287e80b3SSadaf Ebrahimi */ 195*287e80b3SSadaf Ebrahimi} 196*287e80b3SSadaf Ebrahimi 197*287e80b3SSadaf Ebrahimi/* Display how to create the synthetic event */ 198*287e80b3SSadaf Ebrahimistatic void show_event(void) 199*287e80b3SSadaf Ebrahimi{ 200*287e80b3SSadaf Ebrahimi struct trace_seq s; 201*287e80b3SSadaf Ebrahimi 202*287e80b3SSadaf Ebrahimi trace_seq_init(&s); 203*287e80b3SSadaf Ebrahimi 204*287e80b3SSadaf Ebrahimi tracefs_synth_echo_cmd(&s, synth); 205*287e80b3SSadaf Ebrahimi trace_seq_terminate(&s); 206*287e80b3SSadaf Ebrahimi trace_seq_do_printf(&s); 207*287e80b3SSadaf Ebrahimi trace_seq_destroy(&s); 208*287e80b3SSadaf Ebrahimi} 209*287e80b3SSadaf Ebrahimi 210*287e80b3SSadaf Ebrahimiint main (int argc, char **argv) 211*287e80b3SSadaf Ebrahimi{ 212*287e80b3SSadaf Ebrahimi make_event(); 213*287e80b3SSadaf Ebrahimi 214*287e80b3SSadaf Ebrahimi if (argc > 1) { 215*287e80b3SSadaf Ebrahimi if (!strcmp(argv[1], "create")) { 216*287e80b3SSadaf Ebrahimi /* Create the synthetic event */ 217*287e80b3SSadaf Ebrahimi tracefs_synth_create(synth); 218*287e80b3SSadaf Ebrahimi } else if (!strcmp(argv[1], "delete")) { 219*287e80b3SSadaf Ebrahimi /* Delete the synthetic event */ 220*287e80b3SSadaf Ebrahimi tracefs_synth_destroy(synth); 221*287e80b3SSadaf Ebrahimi } else { 222*287e80b3SSadaf Ebrahimi printf("usage: %s [create|delete]\n", argv[0]); 223*287e80b3SSadaf Ebrahimi exit(-1); 224*287e80b3SSadaf Ebrahimi } 225*287e80b3SSadaf Ebrahimi } else 226*287e80b3SSadaf Ebrahimi show_event(); 227*287e80b3SSadaf Ebrahimi 228*287e80b3SSadaf Ebrahimi tracefs_synth_free(synth); 229*287e80b3SSadaf Ebrahimi 230*287e80b3SSadaf Ebrahimi return 0; 231*287e80b3SSadaf Ebrahimi} 232*287e80b3SSadaf Ebrahimi-- 233*287e80b3SSadaf Ebrahimi 234*287e80b3SSadaf EbrahimiFILES 235*287e80b3SSadaf Ebrahimi----- 236*287e80b3SSadaf Ebrahimi[verse] 237*287e80b3SSadaf Ebrahimi-- 238*287e80b3SSadaf Ebrahimi*tracefs.h* 239*287e80b3SSadaf Ebrahimi Header file to include in order to have access to the library APIs. 240*287e80b3SSadaf Ebrahimi*-ltracefs* 241*287e80b3SSadaf Ebrahimi Linker switch to add when building a program that uses the library. 242*287e80b3SSadaf Ebrahimi-- 243*287e80b3SSadaf Ebrahimi 244*287e80b3SSadaf EbrahimiSEE ALSO 245*287e80b3SSadaf Ebrahimi-------- 246*287e80b3SSadaf Ebrahimi*libtracefs*(3), 247*287e80b3SSadaf Ebrahimi*libtraceevent*(3), 248*287e80b3SSadaf Ebrahimi*trace-cmd*(1), 249*287e80b3SSadaf Ebrahimi*tracefs_hist_alloc*(3), 250*287e80b3SSadaf Ebrahimi*tracefs_hist_alloc_2d*(3), 251*287e80b3SSadaf Ebrahimi*tracefs_hist_alloc_nd*(3), 252*287e80b3SSadaf Ebrahimi*tracefs_hist_free*(3), 253*287e80b3SSadaf Ebrahimi*tracefs_hist_add_key*(3), 254*287e80b3SSadaf Ebrahimi*tracefs_hist_add_value*(3), 255*287e80b3SSadaf Ebrahimi*tracefs_hist_add_name*(3), 256*287e80b3SSadaf Ebrahimi*tracefs_hist_start*(3), 257*287e80b3SSadaf Ebrahimi*tracefs_hist_destory*(3), 258*287e80b3SSadaf Ebrahimi*tracefs_hist_add_sort_key*(3), 259*287e80b3SSadaf Ebrahimi*tracefs_hist_sort_key_direction*(3), 260*287e80b3SSadaf Ebrahimi*tracefs_synth_alloc*(3), 261*287e80b3SSadaf Ebrahimi*tracefs_synth_add_match_field*(3), 262*287e80b3SSadaf Ebrahimi*tracefs_synth_add_compare_field*(3), 263*287e80b3SSadaf Ebrahimi*tracefs_synth_add_start_field*(3), 264*287e80b3SSadaf Ebrahimi*tracefs_synth_add_end_field*(3), 265*287e80b3SSadaf Ebrahimi*tracefs_synth_append_start_filter*(3), 266*287e80b3SSadaf Ebrahimi*tracefs_synth_append_end_filter*(3), 267*287e80b3SSadaf Ebrahimi*tracefs_synth_free*(3), 268*287e80b3SSadaf Ebrahimi*tracefs_synth_create*(3), 269*287e80b3SSadaf Ebrahimi*tracefs_synth_destroy*(3), 270*287e80b3SSadaf Ebrahimi*tracefs_synth_complete*(3), 271*287e80b3SSadaf Ebrahimi*tracefs_synth_trace*(3), 272*287e80b3SSadaf Ebrahimi*tracefs_synth_snapshot*(3), 273*287e80b3SSadaf Ebrahimi*tracefs_synth_save*(3), 274*287e80b3SSadaf Ebrahimi 275*287e80b3SSadaf EbrahimiAUTHOR 276*287e80b3SSadaf Ebrahimi------ 277*287e80b3SSadaf Ebrahimi[verse] 278*287e80b3SSadaf Ebrahimi-- 279*287e80b3SSadaf Ebrahimi*Steven Rostedt* <[email protected]> 280*287e80b3SSadaf Ebrahimi*Tzvetomir Stoyanov* <[email protected]> 281*287e80b3SSadaf Ebrahimi*sameeruddin shaik* <[email protected]> 282*287e80b3SSadaf Ebrahimi-- 283*287e80b3SSadaf EbrahimiREPORTING BUGS 284*287e80b3SSadaf Ebrahimi-------------- 285*287e80b3SSadaf EbrahimiReport bugs to <[email protected]> 286*287e80b3SSadaf Ebrahimi 287*287e80b3SSadaf EbrahimiLICENSE 288*287e80b3SSadaf Ebrahimi------- 289*287e80b3SSadaf Ebrahimilibtracefs is Free Software licensed under the GNU LGPL 2.1 290*287e80b3SSadaf Ebrahimi 291*287e80b3SSadaf EbrahimiRESOURCES 292*287e80b3SSadaf Ebrahimi--------- 293*287e80b3SSadaf Ebrahimihttps://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 294*287e80b3SSadaf Ebrahimi 295*287e80b3SSadaf EbrahimiCOPYING 296*287e80b3SSadaf Ebrahimi------- 297*287e80b3SSadaf EbrahimiCopyright \(C) 2020 VMware, Inc. Free use of this software is granted under 298*287e80b3SSadaf Ebrahimithe terms of the GNU Public License (GPL). 299