~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/lib/perf/Documentation/libperf-sampling.txt

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 libperf-sampling(7)
  2 ===================
  3 
  4 NAME
  5 ----
  6 libperf-sampling - sampling interface
  7 
  8 
  9 DESCRIPTION
 10 -----------
 11 The sampling interface provides API to measure and get count for specific perf events.
 12 
 13 The following test tries to explain count on `sampling.c` example.
 14 
 15 It is by no means complete guide to sampling, but shows libperf basic API for sampling.
 16 
 17 The `sampling.c` comes with libperf package and can be compiled and run like:
 18 
 19 [source,bash]
 20 --
 21 $ gcc -o sampling sampling.c -lperf
 22 $ sudo ./sampling
 23 cpu   0, pid      0, tid      0, ip     ffffffffad06c4e6, period                    1
 24 cpu   0, pid   4465, tid   4469, ip     ffffffffad118748, period             18322959
 25 cpu   0, pid      0, tid      0, ip     ffffffffad115722, period             33544846
 26 cpu   0, pid   4465, tid   4470, ip         7f84fe0cdad6, period             23687474
 27 cpu   0, pid      0, tid      0, ip     ffffffffad9e0349, period             34255790
 28 cpu   0, pid   4465, tid   4469, ip     ffffffffad136581, period             38664069
 29 cpu   0, pid      0, tid      0, ip     ffffffffad9e55e2, period             21922384
 30 cpu   0, pid   4465, tid   4470, ip         7f84fe0ebebf, period             17655175
 31 ...
 32 --
 33 
 34 It requires root access, because it uses hardware cycles event.
 35 
 36 The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a
 37 nutshell it:
 38 
 39 - creates events
 40 - adds them to the event list
 41 - opens and enables events through the event list
 42 - sleeps for 3 seconds
 43 - disables events
 44 - reads and displays recorded samples
 45 - destroys the event list
 46 
 47 The first thing you need to do before using libperf is to call init function:
 48 
 49 [source,c]
 50 --
 51  12 static int libperf_print(enum libperf_print_level level,
 52  13                          const char *fmt, va_list ap)
 53  14 {
 54  15         return vfprintf(stderr, fmt, ap);
 55  16 }
 56 
 57  23 int main(int argc, char **argv)
 58  24 {
 59  ...
 60  40         libperf_init(libperf_print);
 61 --
 62 
 63 It will setup the library and sets function for debug output from library.
 64 
 65 The `libperf_print` callback will receive any message with its debug level,
 66 defined as:
 67 
 68 [source,c]
 69 --
 70 enum libperf_print_level {
 71         LIBPERF_ERR,
 72         LIBPERF_WARN,
 73         LIBPERF_INFO,
 74         LIBPERF_DEBUG,
 75         LIBPERF_DEBUG2,
 76         LIBPERF_DEBUG3,
 77 };
 78 --
 79 
 80 Once the setup is complete we start by defining cycles event using the `struct perf_event_attr`:
 81 
 82 [source,c]
 83 --
 84  29         struct perf_event_attr attr = {
 85  30                 .type        = PERF_TYPE_HARDWARE,
 86  31                 .config      = PERF_COUNT_HW_CPU_CYCLES,
 87  32                 .disabled    = 1,
 88  33                 .freq        = 1,
 89  34                 .sample_freq = 10,
 90  35                 .sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD,
 91  36         };
 92 --
 93 
 94 Next step is to prepare CPUs map.
 95 
 96 In this case we will monitor all the available CPUs:
 97 
 98 [source,c]
 99 --
100  42         cpus = perf_cpu_map__new_online_cpus();
101  43         if (!cpus) {
102  44                 fprintf(stderr, "failed to create cpus\n");
103  45                 return -1;
104  46         }
105 --
106 
107 Now we create libperf's event list, which will serve as holder for the cycles event:
108 
109 [source,c]
110 --
111  48         evlist = perf_evlist__new();
112  49         if (!evlist) {
113  50                 fprintf(stderr, "failed to create evlist\n");
114  51                 goto out_cpus;
115  52         }
116 --
117 
118 We create libperf's event for the cycles attribute we defined earlier and add it to the list:
119 
120 [source,c]
121 --
122  54         evsel = perf_evsel__new(&attr);
123  55         if (!evsel) {
124  56                 fprintf(stderr, "failed to create cycles\n");
125  57                 goto out_cpus;
126  58         }
127  59
128  60         perf_evlist__add(evlist, evsel);
129 --
130 
131 Configure event list with the cpus map and open event:
132 
133 [source,c]
134 --
135  62         perf_evlist__set_maps(evlist, cpus, NULL);
136  63
137  64         err = perf_evlist__open(evlist);
138  65         if (err) {
139  66                 fprintf(stderr, "failed to open evlist\n");
140  67                 goto out_evlist;
141  68         }
142 --
143 
144 Once the events list is open, we can create memory maps AKA perf ring buffers:
145 
146 [source,c]
147 --
148  70         err = perf_evlist__mmap(evlist, 4);
149  71         if (err) {
150  72                 fprintf(stderr, "failed to mmap evlist\n");
151  73                 goto out_evlist;
152  74         }
153 --
154 
155 The event is created as disabled (note the `disabled = 1` assignment above),
156 so we need to enable the events list explicitly.
157 
158 From this moment the cycles event is sampling.
159 
160 We will sleep for 3 seconds while the ring buffers get data from all CPUs, then we disable the events list.
161 
162 [source,c]
163 --
164  76         perf_evlist__enable(evlist);
165  77         sleep(3);
166  78         perf_evlist__disable(evlist);
167 --
168 
169 Following code walks through the ring buffers and reads stored events/samples:
170 
171 [source,c]
172 --
173  80         perf_evlist__for_each_mmap(evlist, map, false) {
174  81                 if (perf_mmap__read_init(map) < 0)
175  82                         continue;
176  83
177  84                 while ((event = perf_mmap__read_event(map)) != NULL) {
178 
179                             /* process event */
180 
181 108                         perf_mmap__consume(map);
182 109                 }
183 110                 perf_mmap__read_done(map);
184 111         }
185 
186 --
187 
188 Each sample needs to get parsed:
189 
190 [source,c]
191 --
192  85                         int cpu, pid, tid;
193  86                         __u64 ip, period, *array;
194  87                         union u64_swap u;
195  88
196  89                         array = event->sample.array;
197  90
198  91                         ip = *array;
199  92                         array++;
200  93
201  94                         u.val64 = *array;
202  95                         pid = u.val32[0];
203  96                         tid = u.val32[1];
204  97                         array++;
205  98
206  99                         u.val64 = *array;
207 100                         cpu = u.val32[0];
208 101                         array++;
209 102
210 103                         period = *array;
211 104
212 105                         fprintf(stdout, "cpu %3d, pid %6d, tid %6d, ip %20llx, period %20llu\n",
213 106                                 cpu, pid, tid, ip, period);
214 --
215 
216 And finally cleanup.
217 
218 We close the whole events list (both events) and remove it together with the threads map:
219 
220 [source,c]
221 --
222 113 out_evlist:
223 114         perf_evlist__delete(evlist);
224 115 out_cpus:
225 116         perf_cpu_map__put(cpus);
226 117         return err;
227 118 }
228 --
229 
230 REPORTING BUGS
231 --------------
232 Report bugs to <linux-perf-users@vger.kernel.org>.
233 
234 LICENSE
235 -------
236 libperf is Free Software licensed under the GNU LGPL 2.1
237 
238 RESOURCES
239 ---------
240 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
241 
242 SEE ALSO
243 --------
244 libperf(3), libperf-counting(7)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php