diff options
| author | Jiri Olsa <jolsa@redhat.com> | 2013-11-05 09:14:47 -0500 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-11-05 13:15:08 -0500 |
| commit | 714647bdc516330e4405b39677d7f763e016c685 (patch) | |
| tree | 13aaae6374601031ff2393d11ee8a28d37072a6d /tools/perf | |
| parent | a9862418547e818aa5842840aecfa81d733b97e9 (diff) | |
perf tools: Check maximum frequency rate for record/top
Adding the check for maximum allowed frequency rate defined in following
file:
/proc/sys/kernel/perf_event_max_sample_rate
When we cross the maximum value we fail and display detailed error
message with advise.
$ perf record -F 3000 ls
Maximum frequency rate (2000) reached.
Please use -F freq option with lower value or consider
tweaking /proc/sys/kernel/perf_event_max_sample_rate.
In case user does not specify the frequency and the default value cross
the maximum, we display warning and set the frequency value to the
current maximum.
$ perf record ls
Lowering default frequency rate to 2000.
Please consider tweaking /proc/sys/kernel/perf_event_max_sample_rate.
Same messages are used for 'perf top'.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1383660887-1734-4-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/builtin-record.c | 15 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 15 | ||||
| -rw-r--r-- | tools/perf/util/evlist.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/record.c | 71 |
4 files changed, 74 insertions, 28 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 8b45fcead5f6..ea4c04f7437e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -958,20 +958,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 958 | if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) | 958 | if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) |
| 959 | usage_with_options(record_usage, record_options); | 959 | usage_with_options(record_usage, record_options); |
| 960 | 960 | ||
| 961 | if (rec->opts.user_interval != ULLONG_MAX) | 961 | if (perf_record_opts__config(&rec->opts)) { |
| 962 | rec->opts.default_interval = rec->opts.user_interval; | ||
| 963 | if (rec->opts.user_freq != UINT_MAX) | ||
| 964 | rec->opts.freq = rec->opts.user_freq; | ||
| 965 | |||
| 966 | /* | ||
| 967 | * User specified count overrides default frequency. | ||
| 968 | */ | ||
| 969 | if (rec->opts.default_interval) | ||
| 970 | rec->opts.freq = 0; | ||
| 971 | else if (rec->opts.freq) { | ||
| 972 | rec->opts.default_interval = rec->opts.freq; | ||
| 973 | } else { | ||
| 974 | ui__error("frequency and count are zero, aborting\n"); | ||
| 975 | err = -EINVAL; | 962 | err = -EINVAL; |
| 976 | goto out_free_fd; | 963 | goto out_free_fd; |
| 977 | } | 964 | } |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 21897f0ffcd3..9acca8856ccb 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -1209,20 +1209,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1209 | if (top.delay_secs < 1) | 1209 | if (top.delay_secs < 1) |
| 1210 | top.delay_secs = 1; | 1210 | top.delay_secs = 1; |
| 1211 | 1211 | ||
| 1212 | if (opts->user_interval != ULLONG_MAX) | 1212 | if (perf_record_opts__config(opts)) { |
| 1213 | opts->default_interval = opts->user_interval; | ||
| 1214 | if (opts->user_freq != UINT_MAX) | ||
| 1215 | opts->freq = opts->user_freq; | ||
| 1216 | |||
| 1217 | /* | ||
| 1218 | * User specified count overrides default frequency. | ||
| 1219 | */ | ||
| 1220 | if (opts->default_interval) | ||
| 1221 | opts->freq = 0; | ||
| 1222 | else if (opts->freq) { | ||
| 1223 | opts->default_interval = opts->freq; | ||
| 1224 | } else { | ||
| 1225 | ui__error("frequency and count are zero, aborting\n"); | ||
| 1226 | status = -EINVAL; | 1213 | status = -EINVAL; |
| 1227 | goto out_delete_maps; | 1214 | goto out_delete_maps; |
| 1228 | } | 1215 | } |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 6e8acc9abe38..0617ce2a0679 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -99,6 +99,7 @@ void perf_evlist__set_id_pos(struct perf_evlist *evlist); | |||
| 99 | bool perf_can_sample_identifier(void); | 99 | bool perf_can_sample_identifier(void); |
| 100 | void perf_evlist__config(struct perf_evlist *evlist, | 100 | void perf_evlist__config(struct perf_evlist *evlist, |
| 101 | struct perf_record_opts *opts); | 101 | struct perf_record_opts *opts); |
| 102 | int perf_record_opts__config(struct perf_record_opts *opts); | ||
| 102 | 103 | ||
| 103 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, | 104 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, |
| 104 | struct perf_target *target, | 105 | struct perf_target *target, |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 18d73aa2f0f8..c8845b107f60 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | #include "evsel.h" | 2 | #include "evsel.h" |
| 3 | #include "cpumap.h" | 3 | #include "cpumap.h" |
| 4 | #include "parse-events.h" | 4 | #include "parse-events.h" |
| 5 | #include "fs.h" | ||
| 6 | #include "util.h" | ||
| 5 | 7 | ||
| 6 | typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel); | 8 | typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel); |
| 7 | 9 | ||
| @@ -106,3 +108,72 @@ void perf_evlist__config(struct perf_evlist *evlist, | |||
| 106 | 108 | ||
| 107 | perf_evlist__set_id_pos(evlist); | 109 | perf_evlist__set_id_pos(evlist); |
| 108 | } | 110 | } |
| 111 | |||
| 112 | static int get_max_rate(unsigned int *rate) | ||
| 113 | { | ||
| 114 | char path[PATH_MAX]; | ||
| 115 | const char *procfs = procfs__mountpoint(); | ||
| 116 | |||
| 117 | if (!procfs) | ||
| 118 | return -1; | ||
| 119 | |||
| 120 | snprintf(path, PATH_MAX, | ||
| 121 | "%s/sys/kernel/perf_event_max_sample_rate", procfs); | ||
| 122 | |||
| 123 | return filename__read_int(path, (int *) rate); | ||
| 124 | } | ||
| 125 | |||
| 126 | static int perf_record_opts__config_freq(struct perf_record_opts *opts) | ||
| 127 | { | ||
| 128 | bool user_freq = opts->user_freq != UINT_MAX; | ||
| 129 | unsigned int max_rate; | ||
| 130 | |||
| 131 | if (opts->user_interval != ULLONG_MAX) | ||
| 132 | opts->default_interval = opts->user_interval; | ||
| 133 | if (user_freq) | ||
| 134 | opts->freq = opts->user_freq; | ||
| 135 | |||
| 136 | /* | ||
| 137 | * User specified count overrides default frequency. | ||
| 138 | */ | ||
| 139 | if (opts->default_interval) | ||
| 140 | opts->freq = 0; | ||
| 141 | else if (opts->freq) { | ||
| 142 | opts->default_interval = opts->freq; | ||
| 143 | } else { | ||
| 144 | pr_err("frequency and count are zero, aborting\n"); | ||
| 145 | return -1; | ||
| 146 | } | ||
| 147 | |||
| 148 | if (get_max_rate(&max_rate)) | ||
| 149 | return 0; | ||
| 150 | |||
| 151 | /* | ||
| 152 | * User specified frequency is over current maximum. | ||
| 153 | */ | ||
| 154 | if (user_freq && (max_rate < opts->freq)) { | ||
| 155 | pr_err("Maximum frequency rate (%u) reached.\n" | ||
| 156 | "Please use -F freq option with lower value or consider\n" | ||
| 157 | "tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n", | ||
| 158 | max_rate); | ||
| 159 | return -1; | ||
| 160 | } | ||
| 161 | |||
| 162 | /* | ||
| 163 | * Default frequency is over current maximum. | ||
| 164 | */ | ||
| 165 | if (max_rate < opts->freq) { | ||
| 166 | pr_warning("Lowering default frequency rate to %u.\n" | ||
| 167 | "Please consider tweaking " | ||
| 168 | "/proc/sys/kernel/perf_event_max_sample_rate.\n", | ||
| 169 | max_rate); | ||
| 170 | opts->freq = max_rate; | ||
| 171 | } | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | int perf_record_opts__config(struct perf_record_opts *opts) | ||
| 177 | { | ||
| 178 | return perf_record_opts__config_freq(opts); | ||
| 179 | } | ||
