1*287e80b3SSadaf Ebrahimilibtracefs(3) 2*287e80b3SSadaf Ebrahimi============= 3*287e80b3SSadaf Ebrahimi 4*287e80b3SSadaf EbrahimiNAME 5*287e80b3SSadaf Ebrahimi---- 6*287e80b3SSadaf Ebrahimitracefs_iterate_raw_events, tracefs_iterate_stop, tracefs_follow_event, tracefs_follow_missed_events - Iterate over events in the ring buffer 7*287e80b3SSadaf Ebrahimi 8*287e80b3SSadaf EbrahimiSYNOPSIS 9*287e80b3SSadaf Ebrahimi-------- 10*287e80b3SSadaf Ebrahimi[verse] 11*287e80b3SSadaf Ebrahimi-- 12*287e80b3SSadaf Ebrahimi*#include <tracefs.h>* 13*287e80b3SSadaf Ebrahimi 14*287e80b3SSadaf Ebrahimiint *tracefs_iterate_raw_events*(struct tep_handle pass:[*]_tep_, struct tracefs_instance pass:[*]_instance_, 15*287e80b3SSadaf Ebrahimi cpu_set_t pass:[*]_cpus_, int _cpu_size_, 16*287e80b3SSadaf Ebrahimi int (pass:[*]_callback_)(struct tep_event pass:[*], struct tep_record pass:[*], int, void pass:[*]), 17*287e80b3SSadaf Ebrahimi void pass:[*]_callback_context_); 18*287e80b3SSadaf Ebrahimivoid *tracefs_iterate_stop*(struct tracefs_instance pass:[*]_instance_); 19*287e80b3SSadaf Ebrahimi 20*287e80b3SSadaf Ebrahimiint *tracefs_follow_event*(struct tep_handle pass:[*]_tep_, struct tracefs_instance pass:[*]_instance_, 21*287e80b3SSadaf Ebrahimi const char pass:[*]_system_, const char pass:[*]_event_name_, 22*287e80b3SSadaf Ebrahimi int (pass:[*]_callback_)(struct tep_event pass:[*], 23*287e80b3SSadaf Ebrahimi struct tep_record pass:[*], 24*287e80b3SSadaf Ebrahimi int, void pass:[*]), 25*287e80b3SSadaf Ebrahimi void pass:[*]_callback_data_); 26*287e80b3SSadaf Ebrahimiint *tracefs_follow_missed_events*(struct tracefs_instance pass:[*]_instance_, 27*287e80b3SSadaf Ebrahimi int (pass:[*]_callback_)(struct tep_event pass:[*], 28*287e80b3SSadaf Ebrahimi struct tep_record pass:[*], 29*287e80b3SSadaf Ebrahimi int, void pass:[*]), 30*287e80b3SSadaf Ebrahimi void pass:[*]_callback_data_); 31*287e80b3SSadaf Ebrahimi-- 32*287e80b3SSadaf Ebrahimi 33*287e80b3SSadaf EbrahimiDESCRIPTION 34*287e80b3SSadaf Ebrahimi----------- 35*287e80b3SSadaf EbrahimiTrace iterator over raw events. 36*287e80b3SSadaf Ebrahimi 37*287e80b3SSadaf EbrahimiThe *tracefs_iterate_raw_events()* function will read the tracefs raw 38*287e80b3SSadaf Ebrahimidata buffers and call the specified _callback_ function for every event it 39*287e80b3SSadaf Ebrahimiencounters. Events are iterated in sorted order: oldest first. An initialized 40*287e80b3SSadaf Ebrahimi_tep_ handler is required (See *tracefs_local_events*(3)). If _instance_ is 41*287e80b3SSadaf EbrahimiNULL, then the toplevel tracefs buffer is used, otherwise the buffer for 42*287e80b3SSadaf Ebrahimithe corresponding _instance_ is read. To filter only on a subset of CPUs, 43*287e80b3SSadaf Ebrahimi_cpus_ and _cpu_size_ may be set to only call _callback_ with events that 44*287e80b3SSadaf Ebrahimioccurred on the CPUs specified, otherwise if _cpus_ is NULL then the _callback_ 45*287e80b3SSadaf Ebrahimifunction will be called for all events, and _cpu_size_ is ignored. The 46*287e80b3SSadaf Ebrahimi_callback_ function will be called with the following parameters: A 47*287e80b3SSadaf Ebrahimipointer to a struct tep_event that corresponds to the type of event the 48*287e80b3SSadaf Ebrahimirecord is; The record representing the event; The CPU that the event 49*287e80b3SSadaf Ebrahimioccurred on; and a pointer to user specified _callback_context_. If the _callback_ 50*287e80b3SSadaf Ebrahimireturns non-zero, the iteration stops. 51*287e80b3SSadaf Ebrahimi 52*287e80b3SSadaf EbrahimiUse *tracefs_iterate_stop()* to force a executing *tracefs_iterate_raw_events()* 53*287e80b3SSadaf Ebrahimito halt. This can be called from either a callback that is called by 54*287e80b3SSadaf Ebrahimithe iterator (even though a return of non-zero will stop it), or from another 55*287e80b3SSadaf Ebrahimithread. 56*287e80b3SSadaf Ebrahimi 57*287e80b3SSadaf EbrahimiThe *tracefs_follow_event()* is used with *tracefs_iterate_raw_events()* but 58*287e80b3SSadaf Ebrahimiintead of the callback being called for every event, it is only called for the 59*287e80b3SSadaf Ebrahimispecified _system_ / _event_name_ given to the function. The _callback_ is the 60*287e80b3SSadaf Ebrahimisame as for *tracefs_iterate_raw_events()*, and the passed in _callback_context_ 61*287e80b3SSadaf Ebrahimiwill be passed to the _callback_ as well. Note, if it returns something other 62*287e80b3SSadaf Ebrahimithan 0, it will stop the loop before the _callback_ of *tracefs_iterate_raw_events()* 63*287e80b3SSadaf Ebrahimiis called. 64*287e80b3SSadaf Ebrahimi 65*287e80b3SSadaf EbrahimiThe *tracefs_follow_missed_events()* will call the _callback_ when missed 66*287e80b3SSadaf Ebrahimievents are detected. It will set the _record_ parameter of the callback to the 67*287e80b3SSadaf Ebrahimirecord that came after the missed events and _event_ will be of the type of 68*287e80b3SSadaf Ebrahimievent _record_ is. _cpu_ will be set to the CPU that missed the events, and 69*287e80b3SSadaf Ebrahimi_callback_data_ will be the content that was passed in to the function. 70*287e80b3SSadaf Ebrahimi 71*287e80b3SSadaf EbrahimiRETURN VALUE 72*287e80b3SSadaf Ebrahimi------------ 73*287e80b3SSadaf EbrahimiThe *tracefs_iterate_raw_events()* function returns -1 in case of an error or 74*287e80b3SSadaf Ebrahimi0 otherwise. 75*287e80b3SSadaf Ebrahimi 76*287e80b3SSadaf EbrahimiEXAMPLE 77*287e80b3SSadaf Ebrahimi------- 78*287e80b3SSadaf Ebrahimi[source,c] 79*287e80b3SSadaf Ebrahimi-- 80*287e80b3SSadaf Ebrahimi#include <unistd.h> 81*287e80b3SSadaf Ebrahimi#include <tracefs.h> 82*287e80b3SSadaf Ebrahimi#include <stdbool.h> 83*287e80b3SSadaf Ebrahimi#include <signal.h> 84*287e80b3SSadaf Ebrahimi 85*287e80b3SSadaf Ebrahimistruct my_struct { 86*287e80b3SSadaf Ebrahimi bool stopped; 87*287e80b3SSadaf Ebrahimi}; 88*287e80b3SSadaf Ebrahimi 89*287e80b3SSadaf Ebrahimi#define MAX_COUNT 500000 90*287e80b3SSadaf Ebrahimistatic int counter; 91*287e80b3SSadaf Ebrahimi 92*287e80b3SSadaf Ebrahimistatic int callback(struct tep_event *event, struct tep_record *record, 93*287e80b3SSadaf Ebrahimi int cpu, void *data) 94*287e80b3SSadaf Ebrahimi{ 95*287e80b3SSadaf Ebrahimi struct my_struct *my_data = data; 96*287e80b3SSadaf Ebrahimi static struct trace_seq seq; 97*287e80b3SSadaf Ebrahimi 98*287e80b3SSadaf Ebrahimi if (counter++ > MAX_COUNT) { 99*287e80b3SSadaf Ebrahimi my_data->stopped = true; 100*287e80b3SSadaf Ebrahimi return 1; 101*287e80b3SSadaf Ebrahimi } 102*287e80b3SSadaf Ebrahimi 103*287e80b3SSadaf Ebrahimi if (!seq.buffer) 104*287e80b3SSadaf Ebrahimi trace_seq_init(&seq); 105*287e80b3SSadaf Ebrahimi 106*287e80b3SSadaf Ebrahimi tep_print_event(event->tep, &seq, record, "%16s-%-5d [%03d] %6.1000d %s: %s\n", 107*287e80b3SSadaf Ebrahimi TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU, 108*287e80b3SSadaf Ebrahimi TEP_PRINT_TIME, TEP_PRINT_NAME, TEP_PRINT_INFO); 109*287e80b3SSadaf Ebrahimi trace_seq_terminate(&seq); 110*287e80b3SSadaf Ebrahimi trace_seq_do_printf(&seq); 111*287e80b3SSadaf Ebrahimi trace_seq_reset(&seq); 112*287e80b3SSadaf Ebrahimi return 0; 113*287e80b3SSadaf Ebrahimi} 114*287e80b3SSadaf Ebrahimi 115*287e80b3SSadaf Ebrahimistatic int sched_callback(struct tep_event *event, struct tep_record *record, 116*287e80b3SSadaf Ebrahimi int cpu, void *data) 117*287e80b3SSadaf Ebrahimi{ 118*287e80b3SSadaf Ebrahimi static struct tep_format_field *prev_pid; 119*287e80b3SSadaf Ebrahimi static struct tep_format_field *next_pid; 120*287e80b3SSadaf Ebrahimi unsigned long long pid; 121*287e80b3SSadaf Ebrahimi int this_pid = *(int *)data; 122*287e80b3SSadaf Ebrahimi 123*287e80b3SSadaf Ebrahimi if (!prev_pid) { 124*287e80b3SSadaf Ebrahimi prev_pid = tep_find_field(event, "prev_pid"); 125*287e80b3SSadaf Ebrahimi next_pid = tep_find_field(event, "next_pid"); 126*287e80b3SSadaf Ebrahimi if (!prev_pid || !next_pid) { 127*287e80b3SSadaf Ebrahimi fprintf(stderr, "No pid fields??\n"); 128*287e80b3SSadaf Ebrahimi return -1; 129*287e80b3SSadaf Ebrahimi } 130*287e80b3SSadaf Ebrahimi } 131*287e80b3SSadaf Ebrahimi 132*287e80b3SSadaf Ebrahimi tep_read_number_field(prev_pid, record->data, &pid); 133*287e80b3SSadaf Ebrahimi if (pid == this_pid) 134*287e80b3SSadaf Ebrahimi printf("WE ARE LEAVING!\n"); 135*287e80b3SSadaf Ebrahimi tep_read_number_field(next_pid, record->data, &pid); 136*287e80b3SSadaf Ebrahimi if (pid == this_pid) 137*287e80b3SSadaf Ebrahimi printf("WE ARE ARRIVING!\n"); 138*287e80b3SSadaf Ebrahimi return 0; 139*287e80b3SSadaf Ebrahimi} 140*287e80b3SSadaf Ebrahimi 141*287e80b3SSadaf Ebrahimistatic int missed_callback(struct tep_event *event, struct tep_record *record, 142*287e80b3SSadaf Ebrahimi int cpu, void *data) 143*287e80b3SSadaf Ebrahimi{ 144*287e80b3SSadaf Ebrahimi printf("OOPS! cpu %d dropped ", cpu); 145*287e80b3SSadaf Ebrahimi if (record->missed_events > 0) 146*287e80b3SSadaf Ebrahimi printf("%lld ", record->missed_events); 147*287e80b3SSadaf Ebrahimi printf("events\n"); 148*287e80b3SSadaf Ebrahimi return 0; 149*287e80b3SSadaf Ebrahimi} 150*287e80b3SSadaf Ebrahimi 151*287e80b3SSadaf Ebrahimistatic struct tracefs_instance *instance; 152*287e80b3SSadaf Ebrahimistatic struct my_struct my_data; 153*287e80b3SSadaf Ebrahimi 154*287e80b3SSadaf Ebrahimistatic void sig(int s) 155*287e80b3SSadaf Ebrahimi{ 156*287e80b3SSadaf Ebrahimi tracefs_iterate_stop(instance); 157*287e80b3SSadaf Ebrahimi my_data.stopped = true; 158*287e80b3SSadaf Ebrahimi} 159*287e80b3SSadaf Ebrahimi 160*287e80b3SSadaf Ebrahimiint main (int argc, char **argv, char **env) 161*287e80b3SSadaf Ebrahimi{ 162*287e80b3SSadaf Ebrahimi struct tep_handle *tep; 163*287e80b3SSadaf Ebrahimi int this_pid = getpid(); 164*287e80b3SSadaf Ebrahimi 165*287e80b3SSadaf Ebrahimi instance = tracefs_instance_create("my-buffer"); 166*287e80b3SSadaf Ebrahimi if (!instance) 167*287e80b3SSadaf Ebrahimi return -1; 168*287e80b3SSadaf Ebrahimi 169*287e80b3SSadaf Ebrahimi signal(SIGINT, sig); 170*287e80b3SSadaf Ebrahimi 171*287e80b3SSadaf Ebrahimi tracefs_event_enable(instance, NULL, NULL); 172*287e80b3SSadaf Ebrahimi sleep(1); 173*287e80b3SSadaf Ebrahimi tracefs_event_disable(instance, NULL, NULL); 174*287e80b3SSadaf Ebrahimi tep = tracefs_local_events(NULL); 175*287e80b3SSadaf Ebrahimi tep_load_plugins(tep); 176*287e80b3SSadaf Ebrahimi tracefs_follow_missed_events(instance, missed_callback, NULL); 177*287e80b3SSadaf Ebrahimi tracefs_follow_event(tep, instance, "sched", "sched_switch", sched_callback, &this_pid); 178*287e80b3SSadaf Ebrahimi tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, &my_data); 179*287e80b3SSadaf Ebrahimi tracefs_instance_destroy(instance); 180*287e80b3SSadaf Ebrahimi 181*287e80b3SSadaf Ebrahimi if (my_data.stopped) { 182*287e80b3SSadaf Ebrahimi if (counter > MAX_COUNT) 183*287e80b3SSadaf Ebrahimi printf("Finished max count\n"); 184*287e80b3SSadaf Ebrahimi else 185*287e80b3SSadaf Ebrahimi printf("Finished via signal\n"); 186*287e80b3SSadaf Ebrahimi } 187*287e80b3SSadaf Ebrahimi 188*287e80b3SSadaf Ebrahimi return 0; 189*287e80b3SSadaf Ebrahimi} 190*287e80b3SSadaf Ebrahimi-- 191*287e80b3SSadaf EbrahimiFILES 192*287e80b3SSadaf Ebrahimi----- 193*287e80b3SSadaf Ebrahimi[verse] 194*287e80b3SSadaf Ebrahimi-- 195*287e80b3SSadaf Ebrahimi*tracefs.h* 196*287e80b3SSadaf Ebrahimi Header file to include in order to have access to the library APIs. 197*287e80b3SSadaf Ebrahimi*-ltracefs* 198*287e80b3SSadaf Ebrahimi Linker switch to add when building a program that uses the library. 199*287e80b3SSadaf Ebrahimi-- 200*287e80b3SSadaf Ebrahimi 201*287e80b3SSadaf EbrahimiSEE ALSO 202*287e80b3SSadaf Ebrahimi-------- 203*287e80b3SSadaf Ebrahimi*libtracefs*(3), 204*287e80b3SSadaf Ebrahimi*libtraceevent*(3), 205*287e80b3SSadaf Ebrahimi*trace-cmd*(1) 206*287e80b3SSadaf Ebrahimi 207*287e80b3SSadaf EbrahimiAUTHOR 208*287e80b3SSadaf Ebrahimi------ 209*287e80b3SSadaf Ebrahimi[verse] 210*287e80b3SSadaf Ebrahimi-- 211*287e80b3SSadaf Ebrahimi*Steven Rostedt* <[email protected]> 212*287e80b3SSadaf Ebrahimi*Tzvetomir Stoyanov* <[email protected]> 213*287e80b3SSadaf Ebrahimi-- 214*287e80b3SSadaf EbrahimiREPORTING BUGS 215*287e80b3SSadaf Ebrahimi-------------- 216*287e80b3SSadaf EbrahimiReport bugs to <[email protected]> 217*287e80b3SSadaf Ebrahimi 218*287e80b3SSadaf EbrahimiLICENSE 219*287e80b3SSadaf Ebrahimi------- 220*287e80b3SSadaf Ebrahimilibtracefs is Free Software licensed under the GNU LGPL 2.1 221*287e80b3SSadaf Ebrahimi 222*287e80b3SSadaf EbrahimiRESOURCES 223*287e80b3SSadaf Ebrahimi--------- 224*287e80b3SSadaf Ebrahimihttps://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 225*287e80b3SSadaf Ebrahimi 226*287e80b3SSadaf EbrahimiCOPYING 227*287e80b3SSadaf Ebrahimi------- 228*287e80b3SSadaf EbrahimiCopyright \(C) 2020 VMware, Inc. Free use of this software is granted under 229*287e80b3SSadaf Ebrahimithe terms of the GNU Public License (GPL). 230