io_uring: fix sequence logic for timeout requests
[linux-2.6-microblaze.git] / tools / perf / util / record.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include "debug.h"
3 #include "evlist.h"
4 #include "evsel.h"
5 #include "cpumap.h"
6 #include "parse-events.h"
7 #include <errno.h>
8 #include <limits.h>
9 #include <stdlib.h>
10 #include <api/fs/fs.h>
11 #include <subcmd/parse-options.h>
12 #include <perf/cpumap.h>
13 #include "util.h"
14 #include "cloexec.h"
15 #include "record.h"
16 #include "../perf-sys.h"
17
18 typedef void (*setup_probe_fn_t)(struct evsel *evsel);
19
20 static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
21 {
22         struct evlist *evlist;
23         struct evsel *evsel;
24         unsigned long flags = perf_event_open_cloexec_flag();
25         int err = -EAGAIN, fd;
26         static pid_t pid = -1;
27
28         evlist = evlist__new();
29         if (!evlist)
30                 return -ENOMEM;
31
32         if (parse_events(evlist, str, NULL))
33                 goto out_delete;
34
35         evsel = perf_evlist__first(evlist);
36
37         while (1) {
38                 fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
39                 if (fd < 0) {
40                         if (pid == -1 && errno == EACCES) {
41                                 pid = 0;
42                                 continue;
43                         }
44                         goto out_delete;
45                 }
46                 break;
47         }
48         close(fd);
49
50         fn(evsel);
51
52         fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
53         if (fd < 0) {
54                 if (errno == EINVAL)
55                         err = -EINVAL;
56                 goto out_delete;
57         }
58         close(fd);
59         err = 0;
60
61 out_delete:
62         evlist__delete(evlist);
63         return err;
64 }
65
66 static bool perf_probe_api(setup_probe_fn_t fn)
67 {
68         const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL};
69         struct perf_cpu_map *cpus;
70         int cpu, ret, i = 0;
71
72         cpus = perf_cpu_map__new(NULL);
73         if (!cpus)
74                 return false;
75         cpu = cpus->map[0];
76         perf_cpu_map__put(cpus);
77
78         do {
79                 ret = perf_do_probe_api(fn, cpu, try[i++]);
80                 if (!ret)
81                         return true;
82         } while (ret == -EAGAIN && try[i]);
83
84         return false;
85 }
86
87 static void perf_probe_sample_identifier(struct evsel *evsel)
88 {
89         evsel->core.attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
90 }
91
92 static void perf_probe_comm_exec(struct evsel *evsel)
93 {
94         evsel->core.attr.comm_exec = 1;
95 }
96
97 static void perf_probe_context_switch(struct evsel *evsel)
98 {
99         evsel->core.attr.context_switch = 1;
100 }
101
102 bool perf_can_sample_identifier(void)
103 {
104         return perf_probe_api(perf_probe_sample_identifier);
105 }
106
107 static bool perf_can_comm_exec(void)
108 {
109         return perf_probe_api(perf_probe_comm_exec);
110 }
111
112 bool perf_can_record_switch_events(void)
113 {
114         return perf_probe_api(perf_probe_context_switch);
115 }
116
117 bool perf_can_record_cpu_wide(void)
118 {
119         struct perf_event_attr attr = {
120                 .type = PERF_TYPE_SOFTWARE,
121                 .config = PERF_COUNT_SW_CPU_CLOCK,
122                 .exclude_kernel = 1,
123         };
124         struct perf_cpu_map *cpus;
125         int cpu, fd;
126
127         cpus = perf_cpu_map__new(NULL);
128         if (!cpus)
129                 return false;
130         cpu = cpus->map[0];
131         perf_cpu_map__put(cpus);
132
133         fd = sys_perf_event_open(&attr, -1, cpu, -1, 0);
134         if (fd < 0)
135                 return false;
136         close(fd);
137
138         return true;
139 }
140
141 void perf_evlist__config(struct evlist *evlist, struct record_opts *opts,
142                          struct callchain_param *callchain)
143 {
144         struct evsel *evsel;
145         bool use_sample_identifier = false;
146         bool use_comm_exec;
147         bool sample_id = opts->sample_id;
148
149         /*
150          * Set the evsel leader links before we configure attributes,
151          * since some might depend on this info.
152          */
153         if (opts->group)
154                 perf_evlist__set_leader(evlist);
155
156         if (evlist->core.cpus->map[0] < 0)
157                 opts->no_inherit = true;
158
159         use_comm_exec = perf_can_comm_exec();
160
161         evlist__for_each_entry(evlist, evsel) {
162                 perf_evsel__config(evsel, opts, callchain);
163                 if (evsel->tracking && use_comm_exec)
164                         evsel->core.attr.comm_exec = 1;
165         }
166
167         if (opts->full_auxtrace) {
168                 /*
169                  * Need to be able to synthesize and parse selected events with
170                  * arbitrary sample types, which requires always being able to
171                  * match the id.
172                  */
173                 use_sample_identifier = perf_can_sample_identifier();
174                 sample_id = true;
175         } else if (evlist->core.nr_entries > 1) {
176                 struct evsel *first = perf_evlist__first(evlist);
177
178                 evlist__for_each_entry(evlist, evsel) {
179                         if (evsel->core.attr.sample_type == first->core.attr.sample_type)
180                                 continue;
181                         use_sample_identifier = perf_can_sample_identifier();
182                         break;
183                 }
184                 sample_id = true;
185         }
186
187         if (sample_id) {
188                 evlist__for_each_entry(evlist, evsel)
189                         perf_evsel__set_sample_id(evsel, use_sample_identifier);
190         }
191
192         perf_evlist__set_id_pos(evlist);
193 }
194
195 static int get_max_rate(unsigned int *rate)
196 {
197         return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate);
198 }
199
200 static int record_opts__config_freq(struct record_opts *opts)
201 {
202         bool user_freq = opts->user_freq != UINT_MAX;
203         unsigned int max_rate;
204
205         if (opts->user_interval != ULLONG_MAX)
206                 opts->default_interval = opts->user_interval;
207         if (user_freq)
208                 opts->freq = opts->user_freq;
209
210         /*
211          * User specified count overrides default frequency.
212          */
213         if (opts->default_interval)
214                 opts->freq = 0;
215         else if (opts->freq) {
216                 opts->default_interval = opts->freq;
217         } else {
218                 pr_err("frequency and count are zero, aborting\n");
219                 return -1;
220         }
221
222         if (get_max_rate(&max_rate))
223                 return 0;
224
225         /*
226          * User specified frequency is over current maximum.
227          */
228         if (user_freq && (max_rate < opts->freq)) {
229                 if (opts->strict_freq) {
230                         pr_err("error: Maximum frequency rate (%'u Hz) exceeded.\n"
231                                "       Please use -F freq option with a lower value or consider\n"
232                                "       tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
233                                max_rate);
234                         return -1;
235                 } else {
236                         pr_warning("warning: Maximum frequency rate (%'u Hz) exceeded, throttling from %'u Hz to %'u Hz.\n"
237                                    "         The limit can be raised via /proc/sys/kernel/perf_event_max_sample_rate.\n"
238                                    "         The kernel will lower it when perf's interrupts take too long.\n"
239                                    "         Use --strict-freq to disable this throttling, refusing to record.\n",
240                                    max_rate, opts->freq, max_rate);
241
242                         opts->freq = max_rate;
243                 }
244         }
245
246         /*
247          * Default frequency is over current maximum.
248          */
249         if (max_rate < opts->freq) {
250                 pr_warning("Lowering default frequency rate to %u.\n"
251                            "Please consider tweaking "
252                            "/proc/sys/kernel/perf_event_max_sample_rate.\n",
253                            max_rate);
254                 opts->freq = max_rate;
255         }
256
257         return 0;
258 }
259
260 int record_opts__config(struct record_opts *opts)
261 {
262         return record_opts__config_freq(opts);
263 }
264
265 bool perf_evlist__can_select_event(struct evlist *evlist, const char *str)
266 {
267         struct evlist *temp_evlist;
268         struct evsel *evsel;
269         int err, fd, cpu;
270         bool ret = false;
271         pid_t pid = -1;
272
273         temp_evlist = evlist__new();
274         if (!temp_evlist)
275                 return false;
276
277         err = parse_events(temp_evlist, str, NULL);
278         if (err)
279                 goto out_delete;
280
281         evsel = perf_evlist__last(temp_evlist);
282
283         if (!evlist || perf_cpu_map__empty(evlist->core.cpus)) {
284                 struct perf_cpu_map *cpus = perf_cpu_map__new(NULL);
285
286                 cpu =  cpus ? cpus->map[0] : 0;
287                 perf_cpu_map__put(cpus);
288         } else {
289                 cpu = evlist->core.cpus->map[0];
290         }
291
292         while (1) {
293                 fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1,
294                                          perf_event_open_cloexec_flag());
295                 if (fd < 0) {
296                         if (pid == -1 && errno == EACCES) {
297                                 pid = 0;
298                                 continue;
299                         }
300                         goto out_delete;
301                 }
302                 break;
303         }
304         close(fd);
305         ret = true;
306
307 out_delete:
308         evlist__delete(temp_evlist);
309         return ret;
310 }
311
312 int record__parse_freq(const struct option *opt, const char *str, int unset __maybe_unused)
313 {
314         unsigned int freq;
315         struct record_opts *opts = opt->value;
316
317         if (!str)
318                 return -EINVAL;
319
320         if (strcasecmp(str, "max") == 0) {
321                 if (get_max_rate(&freq)) {
322                         pr_err("couldn't read /proc/sys/kernel/perf_event_max_sample_rate\n");
323                         return -1;
324                 }
325                 pr_info("info: Using a maximum frequency rate of %'d Hz\n", freq);
326         } else {
327                 freq = atoi(str);
328         }
329
330         opts->user_freq = freq;
331         return 0;
332 }