xref: /linux/tools/perf/util/record.c (revision 36ec807b627b4c0a0a382f0ae48eac7187d14b2b)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2b4209025SArnaldo Carvalho de Melo #include "debug.h"
3faf96706SAdrian Hunter #include "evlist.h"
4faf96706SAdrian Hunter #include "evsel.h"
53b0a18c1SIan Rogers #include "evsel_config.h"
675562573SAdrian Hunter #include "parse-events.h"
7a43783aeSArnaldo Carvalho de Melo #include <errno.h>
8f2a39fe8SArnaldo Carvalho de Melo #include <limits.h>
9f2a39fe8SArnaldo Carvalho de Melo #include <stdlib.h>
10cd0cfad7SBorislav Petkov #include <api/fs/fs.h>
1167230479SArnaldo Carvalho de Melo #include <subcmd/parse-options.h>
129c3516d1SJiri Olsa #include <perf/cpumap.h>
1357480d2cSYann Droneaud #include "cloexec.h"
1440c7d246SArnaldo Carvalho de Melo #include "util/perf_api_probe.h"
15aeb00b1aSArnaldo Carvalho de Melo #include "record.h"
1691854f9aSArnaldo Carvalho de Melo #include "../perf-sys.h"
17acb65150SKan Liang #include "topdown.h"
182a57d408SKan Liang #include "map_symbol.h"
192a57d408SKan Liang #include "mem-events.h"
2075562573SAdrian Hunter 
21e3459979SAdrian Hunter /*
226ec17b4eSArnaldo Carvalho de Melo  * evsel__config_leader_sampling() uses special rules for leader sampling.
23e3459979SAdrian Hunter  * However, if the leader is an AUX area event, then assume the event to sample
24e3459979SAdrian Hunter  * is the next event.
25e3459979SAdrian Hunter  */
26ea089692SArnaldo Carvalho de Melo static struct evsel *evsel__read_sampler(struct evsel *evsel, struct evlist *evlist)
27e3459979SAdrian Hunter {
28fba7c866SJiri Olsa 	struct evsel *leader = evsel__leader(evsel);
29e3459979SAdrian Hunter 
302a57d408SKan Liang 	if (evsel__is_aux_event(leader) || arch_topdown_sample_read(leader) ||
312a57d408SKan Liang 	    is_mem_loads_aux_event(leader)) {
32e3459979SAdrian Hunter 		evlist__for_each_entry(evlist, evsel) {
33fba7c866SJiri Olsa 			if (evsel__leader(evsel) == leader && evsel != evsel__leader(evsel))
34e3459979SAdrian Hunter 				return evsel;
35e3459979SAdrian Hunter 		}
36e3459979SAdrian Hunter 	}
37e3459979SAdrian Hunter 
38e3459979SAdrian Hunter 	return leader;
39e3459979SAdrian Hunter }
40e3459979SAdrian Hunter 
413b0a18c1SIan Rogers static u64 evsel__config_term_mask(struct evsel *evsel)
423b0a18c1SIan Rogers {
433b0a18c1SIan Rogers 	struct evsel_config_term *term;
443b0a18c1SIan Rogers 	struct list_head *config_terms = &evsel->config_terms;
453b0a18c1SIan Rogers 	u64 term_types = 0;
463b0a18c1SIan Rogers 
473b0a18c1SIan Rogers 	list_for_each_entry(term, config_terms, list) {
483b0a18c1SIan Rogers 		term_types |= 1 << term->type;
493b0a18c1SIan Rogers 	}
503b0a18c1SIan Rogers 	return term_types;
513b0a18c1SIan Rogers }
523b0a18c1SIan Rogers 
536ec17b4eSArnaldo Carvalho de Melo static void evsel__config_leader_sampling(struct evsel *evsel, struct evlist *evlist)
545f342788SAdrian Hunter {
555f342788SAdrian Hunter 	struct perf_event_attr *attr = &evsel->core.attr;
56fba7c866SJiri Olsa 	struct evsel *leader = evsel__leader(evsel);
57e3459979SAdrian Hunter 	struct evsel *read_sampler;
583b0a18c1SIan Rogers 	u64 term_types, freq_mask;
595f342788SAdrian Hunter 
60e3459979SAdrian Hunter 	if (!leader->sample_read)
61e3459979SAdrian Hunter 		return;
62e3459979SAdrian Hunter 
63ea089692SArnaldo Carvalho de Melo 	read_sampler = evsel__read_sampler(evsel, evlist);
64e3459979SAdrian Hunter 
65e3459979SAdrian Hunter 	if (evsel == read_sampler)
663713eb37SAdrian Hunter 		return;
673713eb37SAdrian Hunter 
683b0a18c1SIan Rogers 	term_types = evsel__config_term_mask(evsel);
695f342788SAdrian Hunter 	/*
703b0a18c1SIan Rogers 	 * Disable sampling for all group members except those with explicit
713b0a18c1SIan Rogers 	 * config terms or the leader. In the case of an AUX area event, the 2nd
723b0a18c1SIan Rogers 	 * event in the group is the one that 'leads' the sampling.
735f342788SAdrian Hunter 	 */
743b0a18c1SIan Rogers 	freq_mask = (1 << EVSEL__CONFIG_TERM_FREQ) | (1 << EVSEL__CONFIG_TERM_PERIOD);
753b0a18c1SIan Rogers 	if ((term_types & freq_mask) == 0) {
765f342788SAdrian Hunter 		attr->freq           = 0;
775f342788SAdrian Hunter 		attr->sample_freq    = 0;
785f342788SAdrian Hunter 		attr->sample_period  = 0;
793b0a18c1SIan Rogers 	}
803b0a18c1SIan Rogers 	if ((term_types & (1 << EVSEL__CONFIG_TERM_OVERWRITE)) == 0)
815f342788SAdrian Hunter 		attr->write_backward = 0;
825f342788SAdrian Hunter 
835f342788SAdrian Hunter 	/*
843713eb37SAdrian Hunter 	 * We don't get a sample for slave events, we make them when delivering
853713eb37SAdrian Hunter 	 * the group leader sample. Set the slave event to follow the master
863713eb37SAdrian Hunter 	 * sample_type to ease up reporting.
87e3459979SAdrian Hunter 	 * An AUX area event also has sample_type requirements, so also include
88e3459979SAdrian Hunter 	 * the sample type bits from the leader's sample_type to cover that
89e3459979SAdrian Hunter 	 * case.
905f342788SAdrian Hunter 	 */
91e3459979SAdrian Hunter 	attr->sample_type = read_sampler->core.attr.sample_type |
92e3459979SAdrian Hunter 			    leader->core.attr.sample_type;
935f342788SAdrian Hunter }
945f342788SAdrian Hunter 
9578e1bc25SArnaldo Carvalho de Melo void evlist__config(struct evlist *evlist, struct record_opts *opts, struct callchain_param *callchain)
96faf96706SAdrian Hunter {
9732dcd021SJiri Olsa 	struct evsel *evsel;
9875562573SAdrian Hunter 	bool use_sample_identifier = false;
9939e09d40SAdrian Hunter 	bool use_comm_exec;
100ad46e48cSJiri Olsa 	bool sample_id = opts->sample_id;
10175562573SAdrian Hunter 
1020df6ade7SIan Rogers 	if (perf_cpu_map__cpu(evlist->core.user_requested_cpus, 0).cpu < 0)
103faf96706SAdrian Hunter 		opts->no_inherit = true;
104faf96706SAdrian Hunter 
10539e09d40SAdrian Hunter 	use_comm_exec = perf_can_comm_exec();
10639e09d40SAdrian Hunter 
107e5cadb93SArnaldo Carvalho de Melo 	evlist__for_each_entry(evlist, evsel) {
1086ec17b4eSArnaldo Carvalho de Melo 		evsel__config(evsel, opts, callchain);
10960b0896cSAdrian Hunter 		if (evsel->tracking && use_comm_exec)
1101fc632ceSJiri Olsa 			evsel->core.attr.comm_exec = 1;
11139e09d40SAdrian Hunter 	}
112faf96706SAdrian Hunter 
1135f342788SAdrian Hunter 	/* Configure leader sampling here now that the sample type is known */
1145f342788SAdrian Hunter 	evlist__for_each_entry(evlist, evsel)
1156ec17b4eSArnaldo Carvalho de Melo 		evsel__config_leader_sampling(evsel, evlist);
1165f342788SAdrian Hunter 
11761110883SAdrian Hunter 	if (opts->full_auxtrace || opts->sample_identifier) {
1189e0cc4feSAdrian Hunter 		/*
1199e0cc4feSAdrian Hunter 		 * Need to be able to synthesize and parse selected events with
1209e0cc4feSAdrian Hunter 		 * arbitrary sample types, which requires always being able to
1219e0cc4feSAdrian Hunter 		 * match the id.
1229e0cc4feSAdrian Hunter 		 */
1239e0cc4feSAdrian Hunter 		use_sample_identifier = perf_can_sample_identifier();
124ad46e48cSJiri Olsa 		sample_id = true;
1256484d2f9SJiri Olsa 	} else if (evlist->core.nr_entries > 1) {
126515dbe48SJiri Olsa 		struct evsel *first = evlist__first(evlist);
12775562573SAdrian Hunter 
128e5cadb93SArnaldo Carvalho de Melo 		evlist__for_each_entry(evlist, evsel) {
1291fc632ceSJiri Olsa 			if (evsel->core.attr.sample_type == first->core.attr.sample_type)
13075562573SAdrian Hunter 				continue;
13175562573SAdrian Hunter 			use_sample_identifier = perf_can_sample_identifier();
13275562573SAdrian Hunter 			break;
133faf96706SAdrian Hunter 		}
134ad46e48cSJiri Olsa 		sample_id = true;
135ad46e48cSJiri Olsa 	}
136ad46e48cSJiri Olsa 
137ad46e48cSJiri Olsa 	if (sample_id) {
138e5cadb93SArnaldo Carvalho de Melo 		evlist__for_each_entry(evlist, evsel)
139862b2f8fSArnaldo Carvalho de Melo 			evsel__set_sample_id(evsel, use_sample_identifier);
14075562573SAdrian Hunter 	}
14175562573SAdrian Hunter 
1420a7e7ec9SArnaldo Carvalho de Melo 	evlist__set_id_pos(evlist);
143faf96706SAdrian Hunter }
144714647bdSJiri Olsa 
145714647bdSJiri Olsa static int get_max_rate(unsigned int *rate)
146714647bdSJiri Olsa {
147ce27309fSArnaldo Carvalho de Melo 	return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate);
148714647bdSJiri Olsa }
149714647bdSJiri Olsa 
150b4006796SArnaldo Carvalho de Melo static int record_opts__config_freq(struct record_opts *opts)
151714647bdSJiri Olsa {
152714647bdSJiri Olsa 	bool user_freq = opts->user_freq != UINT_MAX;
153e8c11676SNamhyung Kim 	bool user_interval = opts->user_interval != ULLONG_MAX;
154714647bdSJiri Olsa 	unsigned int max_rate;
155714647bdSJiri Olsa 
156e8c11676SNamhyung Kim 	if (user_interval && user_freq) {
157e8c11676SNamhyung Kim 		pr_err("cannot set frequency and period at the same time\n");
158e8c11676SNamhyung Kim 		return -1;
159e8c11676SNamhyung Kim 	}
160e8c11676SNamhyung Kim 
161e8c11676SNamhyung Kim 	if (user_interval)
162714647bdSJiri Olsa 		opts->default_interval = opts->user_interval;
163714647bdSJiri Olsa 	if (user_freq)
164714647bdSJiri Olsa 		opts->freq = opts->user_freq;
165714647bdSJiri Olsa 
166714647bdSJiri Olsa 	/*
167714647bdSJiri Olsa 	 * User specified count overrides default frequency.
168714647bdSJiri Olsa 	 */
169714647bdSJiri Olsa 	if (opts->default_interval)
170714647bdSJiri Olsa 		opts->freq = 0;
171714647bdSJiri Olsa 	else if (opts->freq) {
172714647bdSJiri Olsa 		opts->default_interval = opts->freq;
173714647bdSJiri Olsa 	} else {
174714647bdSJiri Olsa 		pr_err("frequency and count are zero, aborting\n");
175714647bdSJiri Olsa 		return -1;
176714647bdSJiri Olsa 	}
177714647bdSJiri Olsa 
178714647bdSJiri Olsa 	if (get_max_rate(&max_rate))
179714647bdSJiri Olsa 		return 0;
180714647bdSJiri Olsa 
181714647bdSJiri Olsa 	/*
182714647bdSJiri Olsa 	 * User specified frequency is over current maximum.
183714647bdSJiri Olsa 	 */
184714647bdSJiri Olsa 	if (user_freq && (max_rate < opts->freq)) {
185b09c2364SArnaldo Carvalho de Melo 		if (opts->strict_freq) {
186b09c2364SArnaldo Carvalho de Melo 			pr_err("error: Maximum frequency rate (%'u Hz) exceeded.\n"
187b09c2364SArnaldo Carvalho de Melo 			       "       Please use -F freq option with a lower value or consider\n"
188714647bdSJiri Olsa 			       "       tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
189714647bdSJiri Olsa 			       max_rate);
190714647bdSJiri Olsa 			return -1;
191b09c2364SArnaldo Carvalho de Melo 		} else {
192b09c2364SArnaldo Carvalho de Melo 			pr_warning("warning: Maximum frequency rate (%'u Hz) exceeded, throttling from %'u Hz to %'u Hz.\n"
193b09c2364SArnaldo Carvalho de Melo 				   "         The limit can be raised via /proc/sys/kernel/perf_event_max_sample_rate.\n"
194b09c2364SArnaldo Carvalho de Melo 				   "         The kernel will lower it when perf's interrupts take too long.\n"
195b09c2364SArnaldo Carvalho de Melo 				   "         Use --strict-freq to disable this throttling, refusing to record.\n",
196b09c2364SArnaldo Carvalho de Melo 				   max_rate, opts->freq, max_rate);
197b09c2364SArnaldo Carvalho de Melo 
198b09c2364SArnaldo Carvalho de Melo 			opts->freq = max_rate;
199b09c2364SArnaldo Carvalho de Melo 		}
200714647bdSJiri Olsa 	}
201714647bdSJiri Olsa 
202714647bdSJiri Olsa 	/*
203714647bdSJiri Olsa 	 * Default frequency is over current maximum.
204714647bdSJiri Olsa 	 */
205714647bdSJiri Olsa 	if (max_rate < opts->freq) {
206c07b45a3SHans-Peter Nilsson 		pr_warning("Lowering default frequency rate from %u to %u.\n"
207714647bdSJiri Olsa 			   "Please consider tweaking "
208714647bdSJiri Olsa 			   "/proc/sys/kernel/perf_event_max_sample_rate.\n",
209c07b45a3SHans-Peter Nilsson 			   opts->freq, max_rate);
210714647bdSJiri Olsa 		opts->freq = max_rate;
211714647bdSJiri Olsa 	}
212714647bdSJiri Olsa 
213714647bdSJiri Olsa 	return 0;
214714647bdSJiri Olsa }
215714647bdSJiri Olsa 
216b4006796SArnaldo Carvalho de Melo int record_opts__config(struct record_opts *opts)
217714647bdSJiri Olsa {
218b4006796SArnaldo Carvalho de Melo 	return record_opts__config_freq(opts);
219714647bdSJiri Olsa }
220c09ec622SAdrian Hunter 
221900c8eadSArnaldo Carvalho de Melo bool evlist__can_select_event(struct evlist *evlist, const char *str)
222c09ec622SAdrian Hunter {
22363503dbaSJiri Olsa 	struct evlist *temp_evlist;
22432dcd021SJiri Olsa 	struct evsel *evsel;
2256d18804bSIan Rogers 	int err, fd;
2266d18804bSIan Rogers 	struct perf_cpu cpu = { .cpu = 0 };
227c09ec622SAdrian Hunter 	bool ret = false;
22846ec69adSAdrian Hunter 	pid_t pid = -1;
229c09ec622SAdrian Hunter 
2300f98b11cSJiri Olsa 	temp_evlist = evlist__new();
231c09ec622SAdrian Hunter 	if (!temp_evlist)
232c09ec622SAdrian Hunter 		return false;
233c09ec622SAdrian Hunter 
234806731a9SAdrian Hunter 	err = parse_event(temp_evlist, str);
235c09ec622SAdrian Hunter 	if (err)
236c09ec622SAdrian Hunter 		goto out_delete;
237c09ec622SAdrian Hunter 
238515dbe48SJiri Olsa 	evsel = evlist__last(temp_evlist);
239c09ec622SAdrian Hunter 
240*3e5deb70SIan Rogers 	if (!evlist || perf_cpu_map__is_any_cpu_or_is_empty(evlist->core.user_requested_cpus)) {
241effe957cSIan Rogers 		struct perf_cpu_map *cpus = perf_cpu_map__new_online_cpus();
242c09ec622SAdrian Hunter 
2436d18804bSIan Rogers 		if (cpus)
24444028699SIan Rogers 			cpu =  perf_cpu_map__cpu(cpus, 0);
2456d18804bSIan Rogers 
24638f01d8dSJiri Olsa 		perf_cpu_map__put(cpus);
247c09ec622SAdrian Hunter 	} else {
2480df6ade7SIan Rogers 		cpu = perf_cpu_map__cpu(evlist->core.user_requested_cpus, 0);
249c09ec622SAdrian Hunter 	}
250c09ec622SAdrian Hunter 
25146ec69adSAdrian Hunter 	while (1) {
2526d18804bSIan Rogers 		fd = sys_perf_event_open(&evsel->core.attr, pid, cpu.cpu, -1,
25357480d2cSYann Droneaud 					 perf_event_open_cloexec_flag());
25446ec69adSAdrian Hunter 		if (fd < 0) {
25546ec69adSAdrian Hunter 			if (pid == -1 && errno == EACCES) {
25646ec69adSAdrian Hunter 				pid = 0;
25746ec69adSAdrian Hunter 				continue;
25846ec69adSAdrian Hunter 			}
25946ec69adSAdrian Hunter 			goto out_delete;
26046ec69adSAdrian Hunter 		}
26146ec69adSAdrian Hunter 		break;
26246ec69adSAdrian Hunter 	}
263c09ec622SAdrian Hunter 	close(fd);
264c09ec622SAdrian Hunter 	ret = true;
265c09ec622SAdrian Hunter 
266c09ec622SAdrian Hunter out_delete:
267c12995a5SJiri Olsa 	evlist__delete(temp_evlist);
268c09ec622SAdrian Hunter 	return ret;
269c09ec622SAdrian Hunter }
27067230479SArnaldo Carvalho de Melo 
27167230479SArnaldo Carvalho de Melo int record__parse_freq(const struct option *opt, const char *str, int unset __maybe_unused)
27267230479SArnaldo Carvalho de Melo {
27367230479SArnaldo Carvalho de Melo 	unsigned int freq;
27467230479SArnaldo Carvalho de Melo 	struct record_opts *opts = opt->value;
27567230479SArnaldo Carvalho de Melo 
27667230479SArnaldo Carvalho de Melo 	if (!str)
27767230479SArnaldo Carvalho de Melo 		return -EINVAL;
27867230479SArnaldo Carvalho de Melo 
27967230479SArnaldo Carvalho de Melo 	if (strcasecmp(str, "max") == 0) {
28067230479SArnaldo Carvalho de Melo 		if (get_max_rate(&freq)) {
28167230479SArnaldo Carvalho de Melo 			pr_err("couldn't read /proc/sys/kernel/perf_event_max_sample_rate\n");
28267230479SArnaldo Carvalho de Melo 			return -1;
28367230479SArnaldo Carvalho de Melo 		}
28467230479SArnaldo Carvalho de Melo 		pr_info("info: Using a maximum frequency rate of %'d Hz\n", freq);
28567230479SArnaldo Carvalho de Melo 	} else {
28667230479SArnaldo Carvalho de Melo 		freq = atoi(str);
28767230479SArnaldo Carvalho de Melo 	}
28867230479SArnaldo Carvalho de Melo 
28967230479SArnaldo Carvalho de Melo 	opts->user_freq = freq;
29067230479SArnaldo Carvalho de Melo 	return 0;
29167230479SArnaldo Carvalho de Melo }
292