]> Git Repo - linux.git/blob - tools/lib/perf/Documentation/libperf-counting.txt
enetc: Migrate to PHYLINK and PCS_LYNX
[linux.git] / tools / lib / perf / Documentation / libperf-counting.txt
1 libperf-counting(7)
2 ===================
3
4 NAME
5 ----
6 libperf-counting - counting interface
7
8 DESCRIPTION
9 -----------
10 The counting interface provides API to measure and get count for specific perf events.
11
12 The following test tries to explain count on `counting.c` example.
13
14 It is by no means complete guide to counting, but shows libperf basic API for counting.
15
16 The `counting.c` comes with libperf package and can be compiled and run like:
17
18 [source,bash]
19 --
20 $ gcc -o counting counting.c -lperf
21 $ sudo ./counting
22 count 176792, enabled 176944, run 176944
23 count 176242, enabled 176242, run 176242
24 --
25
26 It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event,
27 which is available only for root.
28
29 The `counting.c` example monitors two events on the current process and displays
30 their count, in a nutshell it:
31
32 * creates events
33 * adds them to the event list
34 * opens and enables events through the event list
35 * does some workload
36 * disables events
37 * reads and displays event counts
38 * destroys the event list
39
40 The first thing you need to do before using libperf is to call init function:
41
42 [source,c]
43 --
44   8 static int libperf_print(enum libperf_print_level level,
45   9                          const char *fmt, va_list ap)
46  10 {
47  11         return vfprintf(stderr, fmt, ap);
48  12 }
49
50  14 int main(int argc, char **argv)
51  15 {
52  ...
53  35         libperf_init(libperf_print);
54 --
55
56 It will setup the library and sets function for debug output from library.
57
58 The `libperf_print` callback will receive any message with its debug level,
59 defined as:
60
61 [source,c]
62 --
63 enum libperf_print_level {
64         LIBPERF_ERR,
65         LIBPERF_WARN,
66         LIBPERF_INFO,
67         LIBPERF_DEBUG,
68         LIBPERF_DEBUG2,
69         LIBPERF_DEBUG3,
70 };
71 --
72
73 Once the setup is complete we start by defining specific events using the `struct perf_event_attr`.
74
75 We create software events for cpu and task:
76
77 [source,c]
78 --
79  20         struct perf_event_attr attr1 = {
80  21                 .type        = PERF_TYPE_SOFTWARE,
81  22                 .config      = PERF_COUNT_SW_CPU_CLOCK,
82  23                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
83  24                 .disabled    = 1,
84  25         };
85  26         struct perf_event_attr attr2 = {
86  27                 .type        = PERF_TYPE_SOFTWARE,
87  28                 .config      = PERF_COUNT_SW_TASK_CLOCK,
88  29                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
89  30                 .disabled    = 1,
90  31         };
91 --
92
93 The `read_format` setup tells perf to include timing details together with each count.
94
95 Next step is to prepare threads map.
96
97 In this case we will monitor current process, so we create threads map with single pid (0):
98
99 [source,c]
100 --
101  37         threads = perf_thread_map__new_dummy();
102  38         if (!threads) {
103  39                 fprintf(stderr, "failed to create threads\n");
104  40                 return -1;
105  41         }
106  42
107  43         perf_thread_map__set_pid(threads, 0, 0);
108 --
109
110 Now we create libperf's event list, which will serve as holder for the events we want:
111
112 [source,c]
113 --
114  45         evlist = perf_evlist__new();
115  46         if (!evlist) {
116  47                 fprintf(stderr, "failed to create evlist\n");
117  48                 goto out_threads;
118  49         }
119 --
120
121 We create libperf's events for the attributes we defined earlier and add them to the list:
122
123 [source,c]
124 --
125  51         evsel = perf_evsel__new(&attr1);
126  52         if (!evsel) {
127  53                 fprintf(stderr, "failed to create evsel1\n");
128  54                 goto out_evlist;
129  55         }
130  56
131  57         perf_evlist__add(evlist, evsel);
132  58
133  59         evsel = perf_evsel__new(&attr2);
134  60         if (!evsel) {
135  61                 fprintf(stderr, "failed to create evsel2\n");
136  62                 goto out_evlist;
137  63         }
138  64
139  65         perf_evlist__add(evlist, evsel);
140 --
141
142 Configure event list with the thread map and open events:
143
144 [source,c]
145 --
146  67         perf_evlist__set_maps(evlist, NULL, threads);
147  68
148  69         err = perf_evlist__open(evlist);
149  70         if (err) {
150  71                 fprintf(stderr, "failed to open evsel\n");
151  72                 goto out_evlist;
152  73         }
153 --
154
155 Both events are created as disabled (note the `disabled = 1` assignment above),
156 so we need to enable the whole list explicitly (both events).
157
158 From this moment events are counting and we can do our workload.
159
160 When we are done we disable the events list.
161
162 [source,c]
163 --
164  75         perf_evlist__enable(evlist);
165  76
166  77         while (count--);
167  78
168  79         perf_evlist__disable(evlist);
169 --
170
171 Now we need to get the counts from events, following code iterates through the
172 events list and read counts:
173
174 [source,c]
175 --
176  81         perf_evlist__for_each_evsel(evlist, evsel) {
177  82                 perf_evsel__read(evsel, 0, 0, &counts);
178  83                 fprintf(stdout, "count %llu, enabled %llu, run %llu\n",
179  84                         counts.val, counts.ena, counts.run);
180  85         }
181 --
182
183 And finally cleanup.
184
185 We close the whole events list (both events) and remove it together with the threads map:
186
187 [source,c]
188 --
189  87         perf_evlist__close(evlist);
190  88
191  89 out_evlist:
192  90         perf_evlist__delete(evlist);
193  91 out_threads:
194  92         perf_thread_map__put(threads);
195  93         return err;
196  94 }
197 --
198
199 REPORTING BUGS
200 --------------
201 Report bugs to <[email protected]>.
202
203 LICENSE
204 -------
205 libperf is Free Software licensed under the GNU LGPL 2.1
206
207 RESOURCES
208 ---------
209 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
210
211 SEE ALSO
212 --------
213 libperf(3), libperf-sampling(7)
This page took 0.047192 seconds and 4 git commands to generate.