mirror of
https://github.com/torvalds/linux.git
synced 2024-11-13 15:41:39 +00:00
perf tools: Enable overwrite settings
This patch allows following config terms and option: Globally setting events to overwrite; # perf record --overwrite ... Set specific events to be overwrite or no-overwrite. # perf record --event cycles/overwrite/ ... # perf record --event cycles/no-overwrite/ ... Add missing config terms and update the config term array size because the longest string length has changed. For overwritable events, it automatically selects attr.write_backward since perf requires it to be backward for reading. Test result: # perf record --overwrite -e syscalls:*enter_nanosleep* usleep 1 [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ] # perf evlist -v syscalls:sys_enter_nanosleep: type: 2, size: 112, config: 0x134, { sample_period, sample_freq }: 1, sample_type: IP|TID|TIME|CPU|PERIOD|RAW, disabled: 1, inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, write_backward: 1 # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events Signed-off-by: Wang Nan <wangnan0@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Nilay Vaish <nilayvaish@gmail.com> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1468485287-33422-14-git-send-email-wangnan0@huawei.com Signed-off-by: He Kuang <hekuang@huawei.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
f6cdff8329
commit
626a6b784e
@ -367,6 +367,20 @@ options.
|
|||||||
'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj
|
'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj
|
||||||
in config file is set to true.
|
in config file is set to true.
|
||||||
|
|
||||||
|
--overwrite::
|
||||||
|
Makes all events use an overwritable ring buffer. An overwritable ring
|
||||||
|
buffer works like a flight recorder: when it gets full, the kernel will
|
||||||
|
overwrite the oldest records, that thus will never make it to the
|
||||||
|
perf.data file.
|
||||||
|
|
||||||
|
When '--overwrite' and '--switch-output' are used perf records and drops
|
||||||
|
events until it receives a signal, meaning that something unusual was
|
||||||
|
detected that warrants taking a snapshot of the most current events,
|
||||||
|
those fitting in the ring buffer at that moment.
|
||||||
|
|
||||||
|
'overwrite' attribute can also be set or canceled for an event using
|
||||||
|
config terms. For example: 'cycles/overwrite/' and 'instructions/no-overwrite/'.
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkperf:perf-stat[1], linkperf:perf-list[1]
|
linkperf:perf-stat[1], linkperf:perf-list[1]
|
||||||
|
@ -1399,6 +1399,7 @@ struct option __record_options[] = {
|
|||||||
OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
|
OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
|
||||||
&record.opts.no_inherit_set,
|
&record.opts.no_inherit_set,
|
||||||
"child tasks do not inherit counters"),
|
"child tasks do not inherit counters"),
|
||||||
|
OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
|
||||||
OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
|
OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
|
||||||
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",
|
||||||
|
@ -59,6 +59,7 @@ struct record_opts {
|
|||||||
bool record_switch_events;
|
bool record_switch_events;
|
||||||
bool all_kernel;
|
bool all_kernel;
|
||||||
bool all_user;
|
bool all_user;
|
||||||
|
bool overwrite;
|
||||||
unsigned int freq;
|
unsigned int freq;
|
||||||
unsigned int mmap_pages;
|
unsigned int mmap_pages;
|
||||||
unsigned int auxtrace_mmap_pages;
|
unsigned int auxtrace_mmap_pages;
|
||||||
|
@ -108,7 +108,11 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bzero(&parse_error, sizeof(parse_error));
|
bzero(&parse_error, sizeof(parse_error));
|
||||||
err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error);
|
/*
|
||||||
|
* Set backward bit, ring buffer should be writing from end. Record
|
||||||
|
* it in aux evlist
|
||||||
|
*/
|
||||||
|
err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_debug("Failed to parse tracepoint event, try use root\n");
|
pr_debug("Failed to parse tracepoint event, try use root\n");
|
||||||
ret = TEST_SKIP;
|
ret = TEST_SKIP;
|
||||||
@ -117,10 +121,6 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
|
|||||||
|
|
||||||
perf_evlist__config(evlist, &opts, NULL);
|
perf_evlist__config(evlist, &opts, NULL);
|
||||||
|
|
||||||
/* Set backward bit, ring buffer should be writing from end */
|
|
||||||
evlist__for_each_entry(evlist, evsel)
|
|
||||||
evsel->attr.write_backward = 1;
|
|
||||||
|
|
||||||
err = perf_evlist__open(evlist);
|
err = perf_evlist__open(evlist);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
pr_debug("perf_evlist__open: %s\n",
|
pr_debug("perf_evlist__open: %s\n",
|
||||||
|
@ -695,6 +695,9 @@ static void apply_config_terms(struct perf_evsel *evsel,
|
|||||||
*/
|
*/
|
||||||
attr->inherit = term->val.inherit ? 1 : 0;
|
attr->inherit = term->val.inherit ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
|
case PERF_EVSEL__CONFIG_TERM_OVERWRITE:
|
||||||
|
attr->write_backward = term->val.overwrite ? 1 : 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -776,6 +779,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
|
|||||||
|
|
||||||
attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
|
attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
|
||||||
attr->inherit = !opts->no_inherit;
|
attr->inherit = !opts->no_inherit;
|
||||||
|
attr->write_backward = opts->overwrite ? 1 : 0;
|
||||||
|
|
||||||
perf_evsel__set_sample_bit(evsel, IP);
|
perf_evsel__set_sample_bit(evsel, IP);
|
||||||
perf_evsel__set_sample_bit(evsel, TID);
|
perf_evsel__set_sample_bit(evsel, TID);
|
||||||
|
@ -45,6 +45,7 @@ enum {
|
|||||||
PERF_EVSEL__CONFIG_TERM_STACK_USER,
|
PERF_EVSEL__CONFIG_TERM_STACK_USER,
|
||||||
PERF_EVSEL__CONFIG_TERM_INHERIT,
|
PERF_EVSEL__CONFIG_TERM_INHERIT,
|
||||||
PERF_EVSEL__CONFIG_TERM_MAX_STACK,
|
PERF_EVSEL__CONFIG_TERM_MAX_STACK,
|
||||||
|
PERF_EVSEL__CONFIG_TERM_OVERWRITE,
|
||||||
PERF_EVSEL__CONFIG_TERM_MAX,
|
PERF_EVSEL__CONFIG_TERM_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ struct perf_evsel_config_term {
|
|||||||
u64 stack_user;
|
u64 stack_user;
|
||||||
int max_stack;
|
int max_stack;
|
||||||
bool inherit;
|
bool inherit;
|
||||||
|
bool overwrite;
|
||||||
} val;
|
} val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -902,6 +902,8 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
|
|||||||
[PARSE_EVENTS__TERM_TYPE_NOINHERIT] = "no-inherit",
|
[PARSE_EVENTS__TERM_TYPE_NOINHERIT] = "no-inherit",
|
||||||
[PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit",
|
[PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit",
|
||||||
[PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack",
|
[PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack",
|
||||||
|
[PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite",
|
||||||
|
[PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool config_term_shrinked;
|
static bool config_term_shrinked;
|
||||||
@ -994,6 +996,12 @@ do { \
|
|||||||
case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
|
case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
|
||||||
CHECK_TYPE_VAL(NUM);
|
CHECK_TYPE_VAL(NUM);
|
||||||
break;
|
break;
|
||||||
|
case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
|
||||||
|
CHECK_TYPE_VAL(NUM);
|
||||||
|
break;
|
||||||
|
case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
|
||||||
|
CHECK_TYPE_VAL(NUM);
|
||||||
|
break;
|
||||||
case PARSE_EVENTS__TERM_TYPE_NAME:
|
case PARSE_EVENTS__TERM_TYPE_NAME:
|
||||||
CHECK_TYPE_VAL(STR);
|
CHECK_TYPE_VAL(STR);
|
||||||
break;
|
break;
|
||||||
@ -1046,6 +1054,8 @@ static int config_term_tracepoint(struct perf_event_attr *attr,
|
|||||||
case PARSE_EVENTS__TERM_TYPE_INHERIT:
|
case PARSE_EVENTS__TERM_TYPE_INHERIT:
|
||||||
case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
|
case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
|
||||||
case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
|
case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
|
||||||
|
case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
|
||||||
|
case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
|
||||||
return config_term_common(attr, term, err);
|
return config_term_common(attr, term, err);
|
||||||
default:
|
default:
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -1118,6 +1128,12 @@ do { \
|
|||||||
case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
|
case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
|
||||||
ADD_CONFIG_TERM(MAX_STACK, max_stack, term->val.num);
|
ADD_CONFIG_TERM(MAX_STACK, max_stack, term->val.num);
|
||||||
break;
|
break;
|
||||||
|
case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
|
||||||
|
ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 1 : 0);
|
||||||
|
break;
|
||||||
|
case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
|
||||||
|
ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2412,9 +2428,9 @@ static void config_terms_list(char *buf, size_t buf_sz)
|
|||||||
char *parse_events_formats_error_string(char *additional_terms)
|
char *parse_events_formats_error_string(char *additional_terms)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
/* "branch_type" is the longest name */
|
/* "no-overwrite" is the longest name */
|
||||||
char static_terms[__PARSE_EVENTS__TERM_TYPE_NR *
|
char static_terms[__PARSE_EVENTS__TERM_TYPE_NR *
|
||||||
(sizeof("branch_type") - 1)];
|
(sizeof("no-overwrite") - 1)];
|
||||||
|
|
||||||
config_terms_list(static_terms, sizeof(static_terms));
|
config_terms_list(static_terms, sizeof(static_terms));
|
||||||
/* valid terms */
|
/* valid terms */
|
||||||
|
@ -69,6 +69,8 @@ enum {
|
|||||||
PARSE_EVENTS__TERM_TYPE_NOINHERIT,
|
PARSE_EVENTS__TERM_TYPE_NOINHERIT,
|
||||||
PARSE_EVENTS__TERM_TYPE_INHERIT,
|
PARSE_EVENTS__TERM_TYPE_INHERIT,
|
||||||
PARSE_EVENTS__TERM_TYPE_MAX_STACK,
|
PARSE_EVENTS__TERM_TYPE_MAX_STACK,
|
||||||
|
PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
|
||||||
|
PARSE_EVENTS__TERM_TYPE_OVERWRITE,
|
||||||
__PARSE_EVENTS__TERM_TYPE_NR,
|
__PARSE_EVENTS__TERM_TYPE_NR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,6 +202,8 @@ stack-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); }
|
|||||||
max-stack { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_MAX_STACK); }
|
max-stack { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_MAX_STACK); }
|
||||||
inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
|
inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
|
||||||
no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
|
no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
|
||||||
|
overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
|
||||||
|
no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
|
||||||
, { return ','; }
|
, { return ','; }
|
||||||
"/" { BEGIN(INITIAL); return '/'; }
|
"/" { BEGIN(INITIAL); return '/'; }
|
||||||
{name_minus} { return str(yyscanner, PE_NAME); }
|
{name_minus} { return str(yyscanner, PE_NAME); }
|
||||||
|
Loading…
Reference in New Issue
Block a user