forked from mirrors/linux
		
	Fix various typos and inconsistent capitalization of CPU in the libperf man pages. Signed-off-by: Rob Herring <robh@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lore.kernel.org/lkml/20200807193241.3904545-1-robh@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
		
			
				
	
	
		
			213 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
libperf-counting(7)
 | 
						|
===================
 | 
						|
 | 
						|
NAME
 | 
						|
----
 | 
						|
libperf-counting - counting interface
 | 
						|
 | 
						|
DESCRIPTION
 | 
						|
-----------
 | 
						|
The counting interface provides API to measure and get count for specific perf events.
 | 
						|
 | 
						|
The following test tries to explain count on `counting.c` example.
 | 
						|
 | 
						|
It is by no means complete guide to counting, but shows libperf basic API for counting.
 | 
						|
 | 
						|
The `counting.c` comes with libperf package and can be compiled and run like:
 | 
						|
 | 
						|
[source,bash]
 | 
						|
--
 | 
						|
$ gcc -o counting counting.c -lperf
 | 
						|
$ sudo ./counting
 | 
						|
count 176792, enabled 176944, run 176944
 | 
						|
count 176242, enabled 176242, run 176242
 | 
						|
--
 | 
						|
 | 
						|
It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event,
 | 
						|
which is available only for root.
 | 
						|
 | 
						|
The `counting.c` example monitors two events on the current process and displays
 | 
						|
their count, in a nutshell it:
 | 
						|
 | 
						|
* creates events
 | 
						|
* adds them to the event list
 | 
						|
* opens and enables events through the event list
 | 
						|
* does some workload
 | 
						|
* disables events
 | 
						|
* reads and displays event counts
 | 
						|
* destroys the event list
 | 
						|
 | 
						|
The first thing you need to do before using libperf is to call init function:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
  8 static int libperf_print(enum libperf_print_level level,
 | 
						|
  9                          const char *fmt, va_list ap)
 | 
						|
 10 {
 | 
						|
 11         return vfprintf(stderr, fmt, ap);
 | 
						|
 12 }
 | 
						|
 | 
						|
 14 int main(int argc, char **argv)
 | 
						|
 15 {
 | 
						|
 ...
 | 
						|
 35         libperf_init(libperf_print);
 | 
						|
--
 | 
						|
 | 
						|
It will setup the library and sets function for debug output from library.
 | 
						|
 | 
						|
The `libperf_print` callback will receive any message with its debug level,
 | 
						|
defined as:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
enum libperf_print_level {
 | 
						|
        LIBPERF_ERR,
 | 
						|
        LIBPERF_WARN,
 | 
						|
        LIBPERF_INFO,
 | 
						|
        LIBPERF_DEBUG,
 | 
						|
        LIBPERF_DEBUG2,
 | 
						|
        LIBPERF_DEBUG3,
 | 
						|
};
 | 
						|
--
 | 
						|
 | 
						|
Once the setup is complete we start by defining specific events using the `struct perf_event_attr`.
 | 
						|
 | 
						|
We create software events for cpu and task:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 20         struct perf_event_attr attr1 = {
 | 
						|
 21                 .type        = PERF_TYPE_SOFTWARE,
 | 
						|
 22                 .config      = PERF_COUNT_SW_CPU_CLOCK,
 | 
						|
 23                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
 | 
						|
 24                 .disabled    = 1,
 | 
						|
 25         };
 | 
						|
 26         struct perf_event_attr attr2 = {
 | 
						|
 27                 .type        = PERF_TYPE_SOFTWARE,
 | 
						|
 28                 .config      = PERF_COUNT_SW_TASK_CLOCK,
 | 
						|
 29                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
 | 
						|
 30                 .disabled    = 1,
 | 
						|
 31         };
 | 
						|
--
 | 
						|
 | 
						|
The `read_format` setup tells perf to include timing details together with each count.
 | 
						|
 | 
						|
Next step is to prepare threads map.
 | 
						|
 | 
						|
In this case we will monitor current process, so we create threads map with single pid (0):
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 37         threads = perf_thread_map__new_dummy();
 | 
						|
 38         if (!threads) {
 | 
						|
 39                 fprintf(stderr, "failed to create threads\n");
 | 
						|
 40                 return -1;
 | 
						|
 41         }
 | 
						|
 42
 | 
						|
 43         perf_thread_map__set_pid(threads, 0, 0);
 | 
						|
--
 | 
						|
 | 
						|
Now we create libperf's event list, which will serve as holder for the events we want:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 45         evlist = perf_evlist__new();
 | 
						|
 46         if (!evlist) {
 | 
						|
 47                 fprintf(stderr, "failed to create evlist\n");
 | 
						|
 48                 goto out_threads;
 | 
						|
 49         }
 | 
						|
--
 | 
						|
 | 
						|
We create libperf's events for the attributes we defined earlier and add them to the list:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 51         evsel = perf_evsel__new(&attr1);
 | 
						|
 52         if (!evsel) {
 | 
						|
 53                 fprintf(stderr, "failed to create evsel1\n");
 | 
						|
 54                 goto out_evlist;
 | 
						|
 55         }
 | 
						|
 56
 | 
						|
 57         perf_evlist__add(evlist, evsel);
 | 
						|
 58
 | 
						|
 59         evsel = perf_evsel__new(&attr2);
 | 
						|
 60         if (!evsel) {
 | 
						|
 61                 fprintf(stderr, "failed to create evsel2\n");
 | 
						|
 62                 goto out_evlist;
 | 
						|
 63         }
 | 
						|
 64
 | 
						|
 65         perf_evlist__add(evlist, evsel);
 | 
						|
--
 | 
						|
 | 
						|
Configure event list with the thread map and open events:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 67         perf_evlist__set_maps(evlist, NULL, threads);
 | 
						|
 68
 | 
						|
 69         err = perf_evlist__open(evlist);
 | 
						|
 70         if (err) {
 | 
						|
 71                 fprintf(stderr, "failed to open evsel\n");
 | 
						|
 72                 goto out_evlist;
 | 
						|
 73         }
 | 
						|
--
 | 
						|
 | 
						|
Both events are created as disabled (note the `disabled = 1` assignment above),
 | 
						|
so we need to enable the whole list explicitly (both events).
 | 
						|
 | 
						|
From this moment events are counting and we can do our workload.
 | 
						|
 | 
						|
When we are done we disable the events list.
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 75         perf_evlist__enable(evlist);
 | 
						|
 76
 | 
						|
 77         while (count--);
 | 
						|
 78
 | 
						|
 79         perf_evlist__disable(evlist);
 | 
						|
--
 | 
						|
 | 
						|
Now we need to get the counts from events, following code iterates through the
 | 
						|
events list and read counts:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 81         perf_evlist__for_each_evsel(evlist, evsel) {
 | 
						|
 82                 perf_evsel__read(evsel, 0, 0, &counts);
 | 
						|
 83                 fprintf(stdout, "count %llu, enabled %llu, run %llu\n",
 | 
						|
 84                         counts.val, counts.ena, counts.run);
 | 
						|
 85         }
 | 
						|
--
 | 
						|
 | 
						|
And finally cleanup.
 | 
						|
 | 
						|
We close the whole events list (both events) and remove it together with the threads map:
 | 
						|
 | 
						|
[source,c]
 | 
						|
--
 | 
						|
 87         perf_evlist__close(evlist);
 | 
						|
 88
 | 
						|
 89 out_evlist:
 | 
						|
 90         perf_evlist__delete(evlist);
 | 
						|
 91 out_threads:
 | 
						|
 92         perf_thread_map__put(threads);
 | 
						|
 93         return err;
 | 
						|
 94 }
 | 
						|
--
 | 
						|
 | 
						|
REPORTING BUGS
 | 
						|
--------------
 | 
						|
Report bugs to <linux-perf-users@vger.kernel.org>.
 | 
						|
 | 
						|
LICENSE
 | 
						|
-------
 | 
						|
libperf is Free Software licensed under the GNU LGPL 2.1
 | 
						|
 | 
						|
RESOURCES
 | 
						|
---------
 | 
						|
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 | 
						|
 | 
						|
SEE ALSO
 | 
						|
--------
 | 
						|
libperf(3), libperf-sampling(7)
 |