cregit-Linux how code gets into the kernel

Release 4.10 tools/perf/util/record.c

Directory: tools/perf/util
#include "evlist.h"
#include "evsel.h"
#include "cpumap.h"
#include "parse-events.h"
#include <api/fs/fs.h>
#include "util.h"
#include "cloexec.h"


typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel);


static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) { struct perf_evlist *evlist; struct perf_evsel *evsel; unsigned long flags = perf_event_open_cloexec_flag(); int err = -EAGAIN, fd; static pid_t pid = -1; evlist = perf_evlist__new(); if (!evlist) return -ENOMEM; if (parse_events(evlist, str, NULL)) goto out_delete; evsel = perf_evlist__first(evlist); while (1) { fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); if (fd < 0) { if (pid == -1 && errno == EACCES) { pid = 0; continue; } goto out_delete; } break; } close(fd); fn(evsel); fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); if (fd < 0) { if (errno == EINVAL) err = -EINVAL; goto out_delete; } close(fd); err = 0; out_delete: perf_evlist__delete(evlist); return err; }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter19894.74%250.00%
yann droneaudyann droneaud94.31%125.00%
jiri olsajiri olsa20.96%125.00%
Total209100.00%4100.00%


static bool perf_probe_api(setup_probe_fn_t fn) { const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL}; struct cpu_map *cpus; int cpu, ret, i = 0; cpus = cpu_map__new(NULL); if (!cpus) return false; cpu = cpus->map[0]; cpu_map__put(cpus); do { ret = perf_do_probe_api(fn, cpu, try[i++]); if (!ret) return true; } while (ret == -EAGAIN && try[i]); return false; }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter10999.09%266.67%
jiri olsajiri olsa10.91%133.33%
Total110100.00%3100.00%


static void perf_probe_sample_identifier(struct perf_evsel *evsel) { evsel->attr.sample_type |= PERF_SAMPLE_IDENTIFIER; }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter19100.00%1100.00%
Total19100.00%1100.00%


static void perf_probe_comm_exec(struct perf_evsel *evsel) { evsel->attr.comm_exec = 1; }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter19100.00%1100.00%
Total19100.00%1100.00%


static void perf_probe_context_switch(struct perf_evsel *evsel) { evsel->attr.context_switch = 1; }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter19100.00%1100.00%
Total19100.00%1100.00%


bool perf_can_sample_identifier(void) { return perf_probe_api(perf_probe_sample_identifier); }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter13100.00%1100.00%
Total13100.00%1100.00%


static bool perf_can_comm_exec(void) { return perf_probe_api(perf_probe_comm_exec); }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter14100.00%1100.00%
Total14100.00%1100.00%


bool perf_can_record_switch_events(void) { return perf_probe_api(perf_probe_context_switch); }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter13100.00%1100.00%
Total13100.00%1100.00%


bool perf_can_record_cpu_wide(void) { struct perf_event_attr attr = { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_CLOCK, .exclude_kernel = 1, }; struct cpu_map *cpus; int cpu, fd; cpus = cpu_map__new(NULL); if (!cpus) return false; cpu = cpus->map[0]; cpu_map__put(cpus); fd = sys_perf_event_open(&attr, -1, cpu, -1, 0); if (fd < 0) return false; close(fd); return true; }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter102100.00%1100.00%
Total102100.00%1100.00%


void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct callchain_param *callchain) { struct perf_evsel *evsel; bool use_sample_identifier = false; bool use_comm_exec; /* * Set the evsel leader links before we configure attributes, * since some might depend on this info. */ if (opts->group) perf_evlist__set_leader(evlist); if (evlist->cpus->map[0] < 0) opts->no_inherit = true; use_comm_exec = perf_can_comm_exec(); evlist__for_each_entry(evlist, evsel) { perf_evsel__config(evsel, opts, callchain); if (evsel->tracking && use_comm_exec) evsel->attr.comm_exec = 1; } if (opts->full_auxtrace) { /* * Need to be able to synthesize and parse selected events with * arbitrary sample types, which requires always being able to * match the id. */ use_sample_identifier = perf_can_sample_identifier(); evlist__for_each_entry(evlist, evsel) perf_evsel__set_sample_id(evsel, use_sample_identifier); } else if (evlist->nr_entries > 1) { struct perf_evsel *first = perf_evlist__first(evlist); evlist__for_each_entry(evlist, evsel) { if (evsel->attr.sample_type == first->attr.sample_type) continue; use_sample_identifier = perf_can_sample_identifier(); break; } evlist__for_each_entry(evlist, evsel) perf_evsel__set_sample_id(evsel, use_sample_identifier); } perf_evlist__set_id_pos(evlist); }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter17990.86%555.56%
arnaldo carvalho de meloarnaldo carvalho de melo189.14%444.44%
Total197100.00%9100.00%


static int get_max_rate(unsigned int *rate) { return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate); }

Contributors

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa2191.30%150.00%
arnaldo carvalho de meloarnaldo carvalho de melo28.70%150.00%
Total23100.00%2100.00%


static int record_opts__config_freq(struct record_opts *opts) { bool user_freq = opts->user_freq != UINT_MAX; unsigned int max_rate; if (opts->user_interval != ULLONG_MAX) opts->default_interval = opts->user_interval; if (user_freq) opts->freq = opts->user_freq; /* * User specified count overrides default frequency. */ if (opts->default_interval) opts->freq = 0; else if (opts->freq) { opts->default_interval = opts->freq; } else { pr_err("frequency and count are zero, aborting\n"); return -1; } if (get_max_rate(&max_rate)) return 0; /* * User specified frequency is over current maximum. */ if (user_freq && (max_rate < opts->freq)) { pr_err("Maximum frequency rate (%u) reached.\n" "Please use -F freq option with lower value or consider\n" "tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n", max_rate); return -1; } /* * Default frequency is over current maximum. */ if (max_rate < opts->freq) { pr_warning("Lowering default frequency rate to %u.\n" "Please consider tweaking " "/proc/sys/kernel/perf_event_max_sample_rate.\n", max_rate); opts->freq = max_rate; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa16098.77%150.00%
arnaldo carvalho de meloarnaldo carvalho de melo21.23%150.00%
Total162100.00%2100.00%


int record_opts__config(struct record_opts *opts) { return record_opts__config_freq(opts); }

Contributors

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa1381.25%150.00%
arnaldo carvalho de meloarnaldo carvalho de melo318.75%150.00%
Total16100.00%2100.00%


bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) { struct perf_evlist *temp_evlist; struct perf_evsel *evsel; int err, fd, cpu; bool ret = false; pid_t pid = -1; temp_evlist = perf_evlist__new(); if (!temp_evlist) return false; err = parse_events(temp_evlist, str, NULL); if (err) goto out_delete; evsel = perf_evlist__last(temp_evlist); if (!evlist || cpu_map__empty(evlist->cpus)) { struct cpu_map *cpus = cpu_map__new(NULL); cpu = cpus ? cpus->map[0] : 0; cpu_map__put(cpus); } else { cpu = evlist->cpus->map[0]; } while (1) { fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, perf_event_open_cloexec_flag()); if (fd < 0) { if (pid == -1 && errno == EACCES) { pid = 0; continue; } goto out_delete; } break; } close(fd); ret = true; out_delete: perf_evlist__delete(temp_evlist); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter20797.64%240.00%
jiri olsajiri olsa31.42%240.00%
yann droneaudyann droneaud20.94%120.00%
Total212100.00%5100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
adrian hunteradrian hunter91778.92%1050.00%
jiri olsajiri olsa20517.64%315.00%
arnaldo carvalho de meloarnaldo carvalho de melo252.15%525.00%
yann droneaudyann droneaud141.20%15.00%
borislav petkovborislav petkov10.09%15.00%
Total1162100.00%20100.00%
Directory: tools/perf/util
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.