aboutsummaryrefslogtreecommitdiff
path: root/tools/perf/util/record.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/record.c')
-rw-r--r--tools/perf/util/record.c51
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;
+}