xref: /openbmc/linux/tools/perf/util/record.c (revision 7af6fbdd)
1 // SPDX-License-Identifier: GPL-2.0
2 #include "debug.h"
3 #include "evlist.h"
4 #include "evsel.h"
5 #include "evsel_config.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 "cloexec.h"
14 #include "util/perf_api_probe.h"
15 #include "record.h"
16 #include "../perf-sys.h"
17 
18 /*
19  * evsel__config_leader_sampling() uses special rules for leader sampling.
20  * However, if the leader is an AUX area event, then assume the event to sample
21  * is the next event.
22  */
23 static struct evsel *evsel__read_sampler(struct evsel *evsel, struct evlist *evlist)
24 {
25 	struct evsel *leader = evsel->leader;
26 
27 	if (evsel__is_aux_event(leader)) {
28 		evlist__for_each_entry(evlist, evsel) {
29 			if (evsel->leader == leader && evsel != evsel->leader)
30 				return evsel;
31 		}
32 	}
33 
34 	return leader;
35 }
36 
37 static u64 evsel__config_term_mask(struct evsel *evsel)
38 {
39 	struct evsel_config_term *term;
40 	struct list_head *config_terms = &evsel->config_terms;
41 	u64 term_types = 0;
42 
43 	list_for_each_entry(term, config_terms, list) {
44 		term_types |= 1 << term->type;
45 	}
46 	return term_types;
47 }
48 
49 static void evsel__config_leader_sampling(struct evsel *evsel, struct evlist *evlist)
50 {
51 	struct perf_event_attr *attr = &evsel->core.attr;
52 	struct evsel *leader = evsel->leader;
53 	struct evsel *read_sampler;
54 	u64 term_types, freq_mask;
55 
56 	if (!leader->sample_read)
57 		return;
58 
59 	read_sampler = evsel__read_sampler(evsel, evlist);
60 
61 	if (evsel == read_sampler)
62 		return;
63 
64 	term_types = evsel__config_term_mask(evsel);
65 	/*
66 	 * Disable sampling for all group members except those with explicit
67 	 * config terms or the leader. In the case of an AUX area event, the 2nd
68 	 * event in the group is the one that 'leads' the sampling.
69 	 */
70 	freq_mask = (1 << EVSEL__CONFIG_TERM_FREQ) | (1 << EVSEL__CONFIG_TERM_PERIOD);
71 	if ((term_types & freq_mask) == 0) {
72 		attr->freq           = 0;
73 		attr->sample_freq    = 0;
74 		attr->sample_period  = 0;
75 	}
76 	if ((term_types & (1 << EVSEL__CONFIG_TERM_OVERWRITE)) == 0)
77 		attr->write_backward = 0;
78 
79 	/*
80 	 * We don't get a sample for slave events, we make them when delivering
81 	 * the group leader sample. Set the slave event to follow the master
82 	 * sample_type to ease up reporting.
83 	 * An AUX area event also has sample_type requirements, so also include
84 	 * the sample type bits from the leader's sample_type to cover that
85 	 * case.
86 	 */
87 	attr->sample_type = read_sampler->core.attr.sample_type |
88 			    leader->core.attr.sample_type;
89 }
90 
91 void perf_evlist__config(struct evlist *evlist, struct record_opts *opts,
92 			 struct callchain_param *callchain)
93 {
94 	struct evsel *evsel;
95 	bool use_sample_identifier = false;
96 	bool use_comm_exec;
97 	bool sample_id = opts->sample_id;
98 
99 	/*
100 	 * Set the evsel leader links before we configure attributes,
101 	 * since some might depend on this info.
102 	 */
103 	if (opts->group)
104 		perf_evlist__set_leader(evlist);
105 
106 	if (evlist->core.cpus->map[0] < 0)
107 		opts->no_inherit = true;
108 
109 	use_comm_exec = perf_can_comm_exec();
110 
111 	evlist__for_each_entry(evlist, evsel) {
112 		evsel__config(evsel, opts, callchain);
113 		if (evsel->tracking && use_comm_exec)
114 			evsel->core.attr.comm_exec = 1;
115 	}
116 
117 	/* Configure leader sampling here now that the sample type is known */
118 	evlist__for_each_entry(evlist, evsel)
119 		evsel__config_leader_sampling(evsel, evlist);
120 
121 	if (opts->full_auxtrace) {
122 		/*
123 		 * Need to be able to synthesize and parse selected events with
124 		 * arbitrary sample types, which requires always being able to
125 		 * match the id.
126 		 */
127 		use_sample_identifier = perf_can_sample_identifier();
128 		sample_id = true;
129 	} else if (evlist->core.nr_entries > 1) {
130 		struct evsel *first = evlist__first(evlist);
131 
132 		evlist__for_each_entry(evlist, evsel) {
133 			if (evsel->core.attr.sample_type == first->core.attr.sample_type)
134 				continue;
135 			use_sample_identifier = perf_can_sample_identifier();
136 			break;
137 		}
138 		sample_id = true;
139 	}
140 
141 	if (sample_id) {
142 		evlist__for_each_entry(evlist, evsel)
143 			evsel__set_sample_id(evsel, use_sample_identifier);
144 	}
145 
146 	perf_evlist__set_id_pos(evlist);
147 }
148 
149 static int get_max_rate(unsigned int *rate)
150 {
151 	return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate);
152 }
153 
154 static int record_opts__config_freq(struct record_opts *opts)
155 {
156 	bool user_freq = opts->user_freq != UINT_MAX;
157 	unsigned int max_rate;
158 
159 	if (opts->user_interval != ULLONG_MAX)
160 		opts->default_interval = opts->user_interval;
161 	if (user_freq)
162 		opts->freq = opts->user_freq;
163 
164 	/*
165 	 * User specified count overrides default frequency.
166 	 */
167 	if (opts->default_interval)
168 		opts->freq = 0;
169 	else if (opts->freq) {
170 		opts->default_interval = opts->freq;
171 	} else {
172 		pr_err("frequency and count are zero, aborting\n");
173 		return -1;
174 	}
175 
176 	if (get_max_rate(&max_rate))
177 		return 0;
178 
179 	/*
180 	 * User specified frequency is over current maximum.
181 	 */
182 	if (user_freq && (max_rate < opts->freq)) {
183 		if (opts->strict_freq) {
184 			pr_err("error: Maximum frequency rate (%'u Hz) exceeded.\n"
185 			       "       Please use -F freq option with a lower value or consider\n"
186 			       "       tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
187 			       max_rate);
188 			return -1;
189 		} else {
190 			pr_warning("warning: Maximum frequency rate (%'u Hz) exceeded, throttling from %'u Hz to %'u Hz.\n"
191 				   "         The limit can be raised via /proc/sys/kernel/perf_event_max_sample_rate.\n"
192 				   "         The kernel will lower it when perf's interrupts take too long.\n"
193 				   "         Use --strict-freq to disable this throttling, refusing to record.\n",
194 				   max_rate, opts->freq, max_rate);
195 
196 			opts->freq = max_rate;
197 		}
198 	}
199 
200 	/*
201 	 * Default frequency is over current maximum.
202 	 */
203 	if (max_rate < opts->freq) {
204 		pr_warning("Lowering default frequency rate to %u.\n"
205 			   "Please consider tweaking "
206 			   "/proc/sys/kernel/perf_event_max_sample_rate.\n",
207 			   max_rate);
208 		opts->freq = max_rate;
209 	}
210 
211 	return 0;
212 }
213 
214 int record_opts__config(struct record_opts *opts)
215 {
216 	return record_opts__config_freq(opts);
217 }
218 
219 bool perf_evlist__can_select_event(struct evlist *evlist, const char *str)
220 {
221 	struct evlist *temp_evlist;
222 	struct evsel *evsel;
223 	int err, fd, cpu;
224 	bool ret = false;
225 	pid_t pid = -1;
226 
227 	temp_evlist = evlist__new();
228 	if (!temp_evlist)
229 		return false;
230 
231 	err = parse_events(temp_evlist, str, NULL);
232 	if (err)
233 		goto out_delete;
234 
235 	evsel = evlist__last(temp_evlist);
236 
237 	if (!evlist || perf_cpu_map__empty(evlist->core.cpus)) {
238 		struct perf_cpu_map *cpus = perf_cpu_map__new(NULL);
239 
240 		cpu =  cpus ? cpus->map[0] : 0;
241 		perf_cpu_map__put(cpus);
242 	} else {
243 		cpu = evlist->core.cpus->map[0];
244 	}
245 
246 	while (1) {
247 		fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1,
248 					 perf_event_open_cloexec_flag());
249 		if (fd < 0) {
250 			if (pid == -1 && errno == EACCES) {
251 				pid = 0;
252 				continue;
253 			}
254 			goto out_delete;
255 		}
256 		break;
257 	}
258 	close(fd);
259 	ret = true;
260 
261 out_delete:
262 	evlist__delete(temp_evlist);
263 	return ret;
264 }
265 
266 int record__parse_freq(const struct option *opt, const char *str, int unset __maybe_unused)
267 {
268 	unsigned int freq;
269 	struct record_opts *opts = opt->value;
270 
271 	if (!str)
272 		return -EINVAL;
273 
274 	if (strcasecmp(str, "max") == 0) {
275 		if (get_max_rate(&freq)) {
276 			pr_err("couldn't read /proc/sys/kernel/perf_event_max_sample_rate\n");
277 			return -1;
278 		}
279 		pr_info("info: Using a maximum frequency rate of %'d Hz\n", freq);
280 	} else {
281 		freq = atoi(str);
282 	}
283 
284 	opts->user_freq = freq;
285 	return 0;
286 }
287