mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 09:01:34 +00:00
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>
This commit is contained in:
parent
a986241854
commit
714647bdc5
@ -958,20 +958,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
|
|||||||
if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
|
if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
|
||||||
usage_with_options(record_usage, record_options);
|
usage_with_options(record_usage, record_options);
|
||||||
|
|
||||||
if (rec->opts.user_interval != ULLONG_MAX)
|
if (perf_record_opts__config(&rec->opts)) {
|
||||||
rec->opts.default_interval = rec->opts.user_interval;
|
|
||||||
if (rec->opts.user_freq != UINT_MAX)
|
|
||||||
rec->opts.freq = rec->opts.user_freq;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User specified count overrides default frequency.
|
|
||||||
*/
|
|
||||||
if (rec->opts.default_interval)
|
|
||||||
rec->opts.freq = 0;
|
|
||||||
else if (rec->opts.freq) {
|
|
||||||
rec->opts.default_interval = rec->opts.freq;
|
|
||||||
} else {
|
|
||||||
ui__error("frequency and count are zero, aborting\n");
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_free_fd;
|
goto out_free_fd;
|
||||||
}
|
}
|
||||||
|
@ -1209,20 +1209,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
|
|||||||
if (top.delay_secs < 1)
|
if (top.delay_secs < 1)
|
||||||
top.delay_secs = 1;
|
top.delay_secs = 1;
|
||||||
|
|
||||||
if (opts->user_interval != ULLONG_MAX)
|
if (perf_record_opts__config(opts)) {
|
||||||
opts->default_interval = opts->user_interval;
|
|
||||||
if (opts->user_freq != UINT_MAX)
|
|
||||||
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 {
|
|
||||||
ui__error("frequency and count are zero, aborting\n");
|
|
||||||
status = -EINVAL;
|
status = -EINVAL;
|
||||||
goto out_delete_maps;
|
goto out_delete_maps;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@ void perf_evlist__set_id_pos(struct perf_evlist *evlist);
|
|||||||
bool perf_can_sample_identifier(void);
|
bool perf_can_sample_identifier(void);
|
||||||
void perf_evlist__config(struct perf_evlist *evlist,
|
void perf_evlist__config(struct perf_evlist *evlist,
|
||||||
struct perf_record_opts *opts);
|
struct perf_record_opts *opts);
|
||||||
|
int perf_record_opts__config(struct perf_record_opts *opts);
|
||||||
|
|
||||||
int perf_evlist__prepare_workload(struct perf_evlist *evlist,
|
int perf_evlist__prepare_workload(struct perf_evlist *evlist,
|
||||||
struct perf_target *target,
|
struct perf_target *target,
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include "evsel.h"
|
#include "evsel.h"
|
||||||
#include "cpumap.h"
|
#include "cpumap.h"
|
||||||
#include "parse-events.h"
|
#include "parse-events.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel);
|
typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel);
|
||||||
|
|
||||||
@ -106,3 +108,72 @@ void perf_evlist__config(struct perf_evlist *evlist,
|
|||||||
|
|
||||||
perf_evlist__set_id_pos(evlist);
|
perf_evlist__set_id_pos(evlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_max_rate(unsigned int *rate)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
const char *procfs = procfs__mountpoint();
|
||||||
|
|
||||||
|
if (!procfs)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX,
|
||||||
|
"%s/sys/kernel/perf_event_max_sample_rate", procfs);
|
||||||
|
|
||||||
|
return filename__read_int(path, (int *) rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int perf_record_opts__config_freq(struct perf_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int perf_record_opts__config(struct perf_record_opts *opts)
|
||||||
|
{
|
||||||
|
return perf_record_opts__config_freq(opts);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user