perf record: Allow asking for the maximum allowed sample rate
Add the handy '-F max' shortcut to reading and using the kernel.perf_event_max_sample_rate value as the user supplied sampling frequency: # perf record -F max sleep 1 info: Using a maximum frequency rate of 15,000 Hz [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.019 MB perf.data (14 samples) ] # sysctl kernel.perf_event_max_sample_rate kernel.perf_event_max_sample_rate = 15000 # perf evlist -v cycles:ppp: size: 112, { sample_period, sample_freq }: 15000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1 # perf record -F 10 sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.019 MB perf.data (4 samples) ] # perf evlist -v cycles:ppp: size: 112, { sample_period, sample_freq }: 10, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1 # Suggested-by: Ingo Molnar <mingo@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Link: https://lkml.kernel.org/n/tip-4y0tiuws62c64gp4cf0hme0m@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
4f67336870
commit
67230479b2
|
@ -193,7 +193,9 @@ OPTIONS
|
||||||
Child tasks do not inherit counters.
|
Child tasks do not inherit counters.
|
||||||
-F::
|
-F::
|
||||||
--freq=::
|
--freq=::
|
||||||
Profile at this frequency.
|
Profile at this frequency. Use 'max' to use the currently maximum
|
||||||
|
allowed frequency, i.e. the value in the kernel.perf_event_max_sample_rate
|
||||||
|
sysctl.
|
||||||
|
|
||||||
-m::
|
-m::
|
||||||
--mmap-pages=::
|
--mmap-pages=::
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <locale.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
@ -1542,7 +1543,9 @@ static struct option __record_options[] = {
|
||||||
OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
|
OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
|
||||||
"synthesize non-sample events at the end of output"),
|
"synthesize non-sample events at the end of output"),
|
||||||
OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
|
OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
|
||||||
OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
|
OPT_CALLBACK('F', "freq", &record.opts, "freq or 'max'",
|
||||||
|
"profile at this frequency",
|
||||||
|
record__parse_freq),
|
||||||
OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
|
OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
|
||||||
"number of mmap data pages and AUX area tracing mmap pages",
|
"number of mmap data pages and AUX area tracing mmap pages",
|
||||||
record__parse_mmap_pages),
|
record__parse_mmap_pages),
|
||||||
|
@ -1651,6 +1654,8 @@ int cmd_record(int argc, const char **argv)
|
||||||
struct record *rec = &record;
|
struct record *rec = &record;
|
||||||
char errbuf[BUFSIZ];
|
char errbuf[BUFSIZ];
|
||||||
|
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
#ifndef HAVE_LIBBPF_SUPPORT
|
#ifndef HAVE_LIBBPF_SUPPORT
|
||||||
# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
|
# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
|
||||||
set_nobuild('\0', "clang-path", true);
|
set_nobuild('\0', "clang-path", true);
|
||||||
|
|
|
@ -82,4 +82,6 @@ struct record_opts {
|
||||||
struct option;
|
struct option;
|
||||||
extern const char * const *record_usage;
|
extern const char * const *record_usage;
|
||||||
extern struct option *record_options;
|
extern struct option *record_options;
|
||||||
|
|
||||||
|
int record__parse_freq(const struct option *opt, const char *str, int unset);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "parse-events.h"
|
#include "parse-events.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <api/fs/fs.h>
|
#include <api/fs/fs.h>
|
||||||
|
#include <subcmd/parse-options.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cloexec.h"
|
#include "cloexec.h"
|
||||||
|
|
||||||
|
@ -287,3 +288,25 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
|
||||||
perf_evlist__delete(temp_evlist);
|
perf_evlist__delete(temp_evlist);
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue