diff options
Diffstat (limited to 'tools/perf/util/record.c')
-rw-r--r-- | tools/perf/util/record.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 1e97937b03a9..9cfc7bf16531 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -5,6 +5,7 @@ #include "parse-events.h" #include <errno.h> #include <api/fs/fs.h> +#include <subcmd/parse-options.h> #include "util.h" #include "cloexec.h" @@ -137,6 +138,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct perf_evsel *evsel; bool use_sample_identifier = false; bool use_comm_exec; + bool sample_id = opts->sample_id; /* * Set the evsel leader links before we configure attributes, @@ -163,8 +165,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, * 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); + sample_id = true; } else if (evlist->nr_entries > 1) { struct perf_evsel *first = perf_evlist__first(evlist); @@ -174,6 +175,10 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, use_sample_identifier = perf_can_sample_identifier(); break; } + sample_id = true; + } + + if (sample_id) { evlist__for_each_entry(evlist, evsel) perf_evsel__set_sample_id(evsel, use_sample_identifier); } @@ -215,11 +220,21 @@ static int record_opts__config_freq(struct record_opts *opts) * 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; + if (opts->strict_freq) { + pr_err("error: Maximum frequency rate (%'u Hz) exceeded.\n" + " Please use -F freq option with a lower value or consider\n" + " tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n", + max_rate); + return -1; + } else { + pr_warning("warning: Maximum frequency rate (%'u Hz) exceeded, throttling from %'u Hz to %'u Hz.\n" + " The limit can be raised via /proc/sys/kernel/perf_event_max_sample_rate.\n" + " The kernel will lower it when perf's interrupts take too long.\n" + " Use --strict-freq to disable this throttling, refusing to record.\n", + max_rate, opts->freq, max_rate); + + opts->freq = max_rate; + } } /* @@ -287,3 +302,25 @@ out_delete: perf_evlist__delete(temp_evlist); return ret; } + +int record__parse_freq(const struct option *opt, const char *str, int unset __maybe_unused) +{ + unsigned int freq; + struct record_opts *opts = opt->value; + + if (!str) + return -EINVAL; + + if (strcasecmp(str, "max") == 0) { + if (get_max_rate(&freq)) { + pr_err("couldn't read /proc/sys/kernel/perf_event_max_sample_rate\n"); + return -1; + } + pr_info("info: Using a maximum frequency rate of %'d Hz\n", freq); + } else { + freq = atoi(str); + } + + opts->user_freq = freq; + return 0; +} |