]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - tools/perf/util/record.c
perf evlist: Move leader-sampling configuration
[mirror_ubuntu-hirsute-kernel.git] / tools / perf / util / record.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
b4209025 2#include "debug.h"
faf96706
AH
3#include "evlist.h"
4#include "evsel.h"
75562573 5#include "parse-events.h"
a43783ae 6#include <errno.h>
f2a39fe8
ACM
7#include <limits.h>
8#include <stdlib.h>
cd0cfad7 9#include <api/fs/fs.h>
67230479 10#include <subcmd/parse-options.h>
9c3516d1 11#include <perf/cpumap.h>
57480d2c 12#include "cloexec.h"
aeb00b1a 13#include "record.h"
91854f9a 14#include "../perf-sys.h"
75562573 15
32dcd021 16typedef void (*setup_probe_fn_t)(struct evsel *evsel);
75562573
AH
17
18static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
19{
63503dba 20 struct evlist *evlist;
32dcd021 21 struct evsel *evsel;
57480d2c 22 unsigned long flags = perf_event_open_cloexec_flag();
75562573 23 int err = -EAGAIN, fd;
46ec69ad 24 static pid_t pid = -1;
75562573 25
0f98b11c 26 evlist = evlist__new();
75562573
AH
27 if (!evlist)
28 return -ENOMEM;
29
b39b8393 30 if (parse_events(evlist, str, NULL))
75562573
AH
31 goto out_delete;
32
515dbe48 33 evsel = evlist__first(evlist);
75562573 34
46ec69ad 35 while (1) {
1fc632ce 36 fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
46ec69ad
AH
37 if (fd < 0) {
38 if (pid == -1 && errno == EACCES) {
39 pid = 0;
40 continue;
41 }
42 goto out_delete;
43 }
44 break;
45 }
75562573
AH
46 close(fd);
47
48 fn(evsel);
49
1fc632ce 50 fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
75562573
AH
51 if (fd < 0) {
52 if (errno == EINVAL)
53 err = -EINVAL;
54 goto out_delete;
55 }
56 close(fd);
57 err = 0;
58
59out_delete:
c12995a5 60 evlist__delete(evlist);
75562573
AH
61 return err;
62}
63
64static bool perf_probe_api(setup_probe_fn_t fn)
65{
c6fa3565 66 const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL};
f854839b 67 struct perf_cpu_map *cpus;
75562573
AH
68 int cpu, ret, i = 0;
69
9c3516d1 70 cpus = perf_cpu_map__new(NULL);
75562573
AH
71 if (!cpus)
72 return false;
73 cpu = cpus->map[0];
38f01d8d 74 perf_cpu_map__put(cpus);
75562573
AH
75
76 do {
77 ret = perf_do_probe_api(fn, cpu, try[i++]);
78 if (!ret)
79 return true;
80 } while (ret == -EAGAIN && try[i]);
81
82 return false;
83}
84
32dcd021 85static void perf_probe_sample_identifier(struct evsel *evsel)
75562573 86{
1fc632ce 87 evsel->core.attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
75562573
AH
88}
89
32dcd021 90static void perf_probe_comm_exec(struct evsel *evsel)
39e09d40 91{
1fc632ce 92 evsel->core.attr.comm_exec = 1;
39e09d40
AH
93}
94
32dcd021 95static void perf_probe_context_switch(struct evsel *evsel)
b757bb09 96{
1fc632ce 97 evsel->core.attr.context_switch = 1;
b757bb09
AH
98}
99
75562573
AH
100bool perf_can_sample_identifier(void)
101{
102 return perf_probe_api(perf_probe_sample_identifier);
103}
faf96706 104
39e09d40
AH
105static bool perf_can_comm_exec(void)
106{
107 return perf_probe_api(perf_probe_comm_exec);
108}
109
b757bb09
AH
110bool perf_can_record_switch_events(void)
111{
112 return perf_probe_api(perf_probe_context_switch);
113}
114
83509565
AH
115bool perf_can_record_cpu_wide(void)
116{
117 struct perf_event_attr attr = {
118 .type = PERF_TYPE_SOFTWARE,
119 .config = PERF_COUNT_SW_CPU_CLOCK,
120 .exclude_kernel = 1,
121 };
f854839b 122 struct perf_cpu_map *cpus;
83509565
AH
123 int cpu, fd;
124
9c3516d1 125 cpus = perf_cpu_map__new(NULL);
83509565
AH
126 if (!cpus)
127 return false;
128 cpu = cpus->map[0];
38f01d8d 129 perf_cpu_map__put(cpus);
83509565
AH
130
131 fd = sys_perf_event_open(&attr, -1, cpu, -1, 0);
132 if (fd < 0)
133 return false;
134 close(fd);
135
136 return true;
137}
138
9bca1a4e
AH
139/*
140 * Architectures are expected to know if AUX area sampling is supported by the
141 * hardware. Here we check for kernel support.
142 */
143bool perf_can_aux_sample(void)
144{
145 struct perf_event_attr attr = {
146 .size = sizeof(struct perf_event_attr),
147 .exclude_kernel = 1,
148 /*
149 * Non-zero value causes the kernel to calculate the effective
150 * attribute size up to that byte.
151 */
152 .aux_sample_size = 1,
153 };
154 int fd;
155
156 fd = sys_perf_event_open(&attr, -1, 0, -1, 0);
157 /*
158 * If the kernel attribute is big enough to contain aux_sample_size
159 * then we assume that it is supported. We are relying on the kernel to
160 * validate the attribute size before anything else that could be wrong.
161 */
162 if (fd < 0 && errno == E2BIG)
163 return false;
164 if (fd >= 0)
165 close(fd);
166
167 return true;
168}
169
5f342788
AH
170static void perf_evsel__config_leader_sampling(struct evsel *evsel)
171{
172 struct perf_event_attr *attr = &evsel->core.attr;
173 struct evsel *leader = evsel->leader;
174
175 /*
176 * Disable sampling for all group members other
177 * than leader in case leader 'leads' the sampling.
178 */
179 if (leader != evsel && leader->sample_read) {
180 attr->freq = 0;
181 attr->sample_freq = 0;
182 attr->sample_period = 0;
183 attr->write_backward = 0;
184
185 /*
186 * We don't get sample for slave events, we make them
187 * when delivering group leader sample. Set the slave
188 * event to follow the master sample_type to ease up
189 * report.
190 */
191 attr->sample_type = leader->core.attr.sample_type;
192 }
193}
194
63503dba 195void perf_evlist__config(struct evlist *evlist, struct record_opts *opts,
e68ae9cf 196 struct callchain_param *callchain)
faf96706 197{
32dcd021 198 struct evsel *evsel;
75562573 199 bool use_sample_identifier = false;
39e09d40 200 bool use_comm_exec;
ad46e48c 201 bool sample_id = opts->sample_id;
75562573 202
faf96706
AH
203 /*
204 * Set the evsel leader links before we configure attributes,
205 * since some might depend on this info.
206 */
207 if (opts->group)
208 perf_evlist__set_leader(evlist);
209
f72f901d 210 if (evlist->core.cpus->map[0] < 0)
faf96706
AH
211 opts->no_inherit = true;
212
39e09d40
AH
213 use_comm_exec = perf_can_comm_exec();
214
e5cadb93 215 evlist__for_each_entry(evlist, evsel) {
e68ae9cf 216 perf_evsel__config(evsel, opts, callchain);
60b0896c 217 if (evsel->tracking && use_comm_exec)
1fc632ce 218 evsel->core.attr.comm_exec = 1;
39e09d40 219 }
faf96706 220
5f342788
AH
221 /* Configure leader sampling here now that the sample type is known */
222 evlist__for_each_entry(evlist, evsel)
223 perf_evsel__config_leader_sampling(evsel);
224
9e0cc4fe
AH
225 if (opts->full_auxtrace) {
226 /*
227 * Need to be able to synthesize and parse selected events with
228 * arbitrary sample types, which requires always being able to
229 * match the id.
230 */
231 use_sample_identifier = perf_can_sample_identifier();
ad46e48c 232 sample_id = true;
6484d2f9 233 } else if (evlist->core.nr_entries > 1) {
515dbe48 234 struct evsel *first = evlist__first(evlist);
75562573 235
e5cadb93 236 evlist__for_each_entry(evlist, evsel) {
1fc632ce 237 if (evsel->core.attr.sample_type == first->core.attr.sample_type)
75562573
AH
238 continue;
239 use_sample_identifier = perf_can_sample_identifier();
240 break;
241 }
ad46e48c
JO
242 sample_id = true;
243 }
244
245 if (sample_id) {
e5cadb93 246 evlist__for_each_entry(evlist, evsel)
75562573 247 perf_evsel__set_sample_id(evsel, use_sample_identifier);
faf96706 248 }
75562573
AH
249
250 perf_evlist__set_id_pos(evlist);
faf96706 251}
714647bd
JO
252
253static int get_max_rate(unsigned int *rate)
254{
ce27309f 255 return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate);
714647bd
JO
256}
257
b4006796 258static int record_opts__config_freq(struct record_opts *opts)
714647bd
JO
259{
260 bool user_freq = opts->user_freq != UINT_MAX;
261 unsigned int max_rate;
262
263 if (opts->user_interval != ULLONG_MAX)
264 opts->default_interval = opts->user_interval;
265 if (user_freq)
266 opts->freq = opts->user_freq;
267
268 /*
269 * User specified count overrides default frequency.
270 */
271 if (opts->default_interval)
272 opts->freq = 0;
273 else if (opts->freq) {
274 opts->default_interval = opts->freq;
275 } else {
276 pr_err("frequency and count are zero, aborting\n");
277 return -1;
278 }
279
280 if (get_max_rate(&max_rate))
281 return 0;
282
283 /*
284 * User specified frequency is over current maximum.
285 */
286 if (user_freq && (max_rate < opts->freq)) {
b09c2364
ACM
287 if (opts->strict_freq) {
288 pr_err("error: Maximum frequency rate (%'u Hz) exceeded.\n"
289 " Please use -F freq option with a lower value or consider\n"
290 " tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
291 max_rate);
292 return -1;
293 } else {
294 pr_warning("warning: Maximum frequency rate (%'u Hz) exceeded, throttling from %'u Hz to %'u Hz.\n"
295 " The limit can be raised via /proc/sys/kernel/perf_event_max_sample_rate.\n"
296 " The kernel will lower it when perf's interrupts take too long.\n"
297 " Use --strict-freq to disable this throttling, refusing to record.\n",
298 max_rate, opts->freq, max_rate);
299
300 opts->freq = max_rate;
301 }
714647bd
JO
302 }
303
304 /*
305 * Default frequency is over current maximum.
306 */
307 if (max_rate < opts->freq) {
308 pr_warning("Lowering default frequency rate to %u.\n"
309 "Please consider tweaking "
310 "/proc/sys/kernel/perf_event_max_sample_rate.\n",
311 max_rate);
312 opts->freq = max_rate;
313 }
314
315 return 0;
316}
317
b4006796 318int record_opts__config(struct record_opts *opts)
714647bd 319{
b4006796 320 return record_opts__config_freq(opts);
714647bd 321}
c09ec622 322
63503dba 323bool perf_evlist__can_select_event(struct evlist *evlist, const char *str)
c09ec622 324{
63503dba 325 struct evlist *temp_evlist;
32dcd021 326 struct evsel *evsel;
c09ec622
AH
327 int err, fd, cpu;
328 bool ret = false;
46ec69ad 329 pid_t pid = -1;
c09ec622 330
0f98b11c 331 temp_evlist = evlist__new();
c09ec622
AH
332 if (!temp_evlist)
333 return false;
334
b39b8393 335 err = parse_events(temp_evlist, str, NULL);
c09ec622
AH
336 if (err)
337 goto out_delete;
338
515dbe48 339 evsel = evlist__last(temp_evlist);
c09ec622 340
315c0a1f 341 if (!evlist || perf_cpu_map__empty(evlist->core.cpus)) {
9c3516d1 342 struct perf_cpu_map *cpus = perf_cpu_map__new(NULL);
c09ec622
AH
343
344 cpu = cpus ? cpus->map[0] : 0;
38f01d8d 345 perf_cpu_map__put(cpus);
c09ec622 346 } else {
f72f901d 347 cpu = evlist->core.cpus->map[0];
c09ec622
AH
348 }
349
46ec69ad 350 while (1) {
1fc632ce 351 fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1,
46ec69ad
AH
352 perf_event_open_cloexec_flag());
353 if (fd < 0) {
354 if (pid == -1 && errno == EACCES) {
355 pid = 0;
356 continue;
357 }
358 goto out_delete;
359 }
360 break;
c09ec622 361 }
46ec69ad
AH
362 close(fd);
363 ret = true;
c09ec622
AH
364
365out_delete:
c12995a5 366 evlist__delete(temp_evlist);
c09ec622
AH
367 return ret;
368}
67230479
ACM
369
370int record__parse_freq(const struct option *opt, const char *str, int unset __maybe_unused)
371{
372 unsigned int freq;
373 struct record_opts *opts = opt->value;
374
375 if (!str)
376 return -EINVAL;
377
378 if (strcasecmp(str, "max") == 0) {
379 if (get_max_rate(&freq)) {
380 pr_err("couldn't read /proc/sys/kernel/perf_event_max_sample_rate\n");
381 return -1;
382 }
383 pr_info("info: Using a maximum frequency rate of %'d Hz\n", freq);
384 } else {
385 freq = atoi(str);
386 }
387
388 opts->user_freq = freq;
389 return 0;
390}