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