Path: blob/master/tools/lib/perf/Documentation/libperf-sampling.txt
26298 views
libperf-sampling(7)1===================23NAME4----5libperf-sampling - sampling interface678DESCRIPTION9-----------10The sampling interface provides API to measure and get count for specific perf events.1112The following test tries to explain count on `sampling.c` example.1314It is by no means complete guide to sampling, but shows libperf basic API for sampling.1516The `sampling.c` comes with libperf package and can be compiled and run like:1718[source,bash]19--20$ gcc -o sampling sampling.c -lperf21$ sudo ./sampling22cpu 0, pid 0, tid 0, ip ffffffffad06c4e6, period 123cpu 0, pid 4465, tid 4469, ip ffffffffad118748, period 1832295924cpu 0, pid 0, tid 0, ip ffffffffad115722, period 3354484625cpu 0, pid 4465, tid 4470, ip 7f84fe0cdad6, period 2368747426cpu 0, pid 0, tid 0, ip ffffffffad9e0349, period 3425579027cpu 0, pid 4465, tid 4469, ip ffffffffad136581, period 3866406928cpu 0, pid 0, tid 0, ip ffffffffad9e55e2, period 2192238429cpu 0, pid 4465, tid 4470, ip 7f84fe0ebebf, period 1765517530...31--3233It requires root access, because it uses hardware cycles event.3435The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a36nutshell it:3738- creates events39- adds them to the event list40- opens and enables events through the event list41- sleeps for 3 seconds42- disables events43- reads and displays recorded samples44- destroys the event list4546The first thing you need to do before using libperf is to call init function:4748[source,c]49--5012 static int libperf_print(enum libperf_print_level level,5113 const char *fmt, va_list ap)5214 {5315 return vfprintf(stderr, fmt, ap);5416 }555623 int main(int argc, char **argv)5724 {58...5940 libperf_init(libperf_print);60--6162It will setup the library and sets function for debug output from library.6364The `libperf_print` callback will receive any message with its debug level,65defined as:6667[source,c]68--69enum libperf_print_level {70LIBPERF_ERR,71LIBPERF_WARN,72LIBPERF_INFO,73LIBPERF_DEBUG,74LIBPERF_DEBUG2,75LIBPERF_DEBUG3,76};77--7879Once the setup is complete we start by defining cycles event using the `struct perf_event_attr`:8081[source,c]82--8329 struct perf_event_attr attr = {8430 .type = PERF_TYPE_HARDWARE,8531 .config = PERF_COUNT_HW_CPU_CYCLES,8632 .disabled = 1,8733 .freq = 1,8834 .sample_freq = 10,8935 .sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD,9036 };91--9293Next step is to prepare CPUs map.9495In this case we will monitor all the available CPUs:9697[source,c]98--9942 cpus = perf_cpu_map__new_online_cpus();10043 if (!cpus) {10144 fprintf(stderr, "failed to create cpus\n");10245 return -1;10346 }104--105106Now we create libperf's event list, which will serve as holder for the cycles event:107108[source,c]109--11048 evlist = perf_evlist__new();11149 if (!evlist) {11250 fprintf(stderr, "failed to create evlist\n");11351 goto out_cpus;11452 }115--116117We create libperf's event for the cycles attribute we defined earlier and add it to the list:118119[source,c]120--12154 evsel = perf_evsel__new(&attr);12255 if (!evsel) {12356 fprintf(stderr, "failed to create cycles\n");12457 goto out_cpus;12558 }1265912760 perf_evlist__add(evlist, evsel);128--129130Configure event list with the cpus map and open event:131132[source,c]133--13462 perf_evlist__set_maps(evlist, cpus, NULL);1356313664 err = perf_evlist__open(evlist);13765 if (err) {13866 fprintf(stderr, "failed to open evlist\n");13967 goto out_evlist;14068 }141--142143Once the events list is open, we can create memory maps AKA perf ring buffers:144145[source,c]146--14770 err = perf_evlist__mmap(evlist, 4);14871 if (err) {14972 fprintf(stderr, "failed to mmap evlist\n");15073 goto out_evlist;15174 }152--153154The event is created as disabled (note the `disabled = 1` assignment above),155so we need to enable the events list explicitly.156157From this moment the cycles event is sampling.158159We will sleep for 3 seconds while the ring buffers get data from all CPUs, then we disable the events list.160161[source,c]162--16376 perf_evlist__enable(evlist);16477 sleep(3);16578 perf_evlist__disable(evlist);166--167168Following code walks through the ring buffers and reads stored events/samples:169170[source,c]171--17280 perf_evlist__for_each_mmap(evlist, map, false) {17381 if (perf_mmap__read_init(map) < 0)17482 continue;1758317684 while ((event = perf_mmap__read_event(map)) != NULL) {177178/* process event */179180108 perf_mmap__consume(map);181109 }182110 perf_mmap__read_done(map);183111 }184185--186187Each sample needs to get parsed:188189[source,c]190--19185 int cpu, pid, tid;19286 __u64 ip, period, *array;19387 union u64_swap u;1948819589 array = event->sample.array;1969019791 ip = *array;19892 array++;1999320094 u.val64 = *array;20195 pid = u.val32[0];20296 tid = u.val32[1];20397 array++;2049820599 u.val64 = *array;206100 cpu = u.val32[0];207101 array++;208102209103 period = *array;210104211105 fprintf(stdout, "cpu %3d, pid %6d, tid %6d, ip %20llx, period %20llu\n",212106 cpu, pid, tid, ip, period);213--214215And finally cleanup.216217We close the whole events list (both events) and remove it together with the threads map:218219[source,c]220--221113 out_evlist:222114 perf_evlist__delete(evlist);223115 out_cpus:224116 perf_cpu_map__put(cpus);225117 return err;226118 }227--228229REPORTING BUGS230--------------231Report bugs to <[email protected]>.232233LICENSE234-------235libperf is Free Software licensed under the GNU LGPL 2.1236237RESOURCES238---------239https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git240241SEE ALSO242--------243libperf(3), libperf-counting(7)244245246