Commit 626a6b78 authored by Wang Nan's avatar Wang Nan Committed by Arnaldo Carvalho de Melo

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: default avatarWang Nan <wangnan0@huawei.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: default avatarJiri 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.comSigned-off-by: default avatarHe Kuang <hekuang@huawei.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f6cdff83
...@@ -367,6 +367,20 @@ options. ...@@ -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[] = { ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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 { ...@@ -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] = { ...@@ -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 { \ ...@@ -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, ...@@ -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 { \ ...@@ -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) ...@@ -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 { ...@@ -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); } ...@@ -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); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment