Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Wang Nan and committed by
Arnaldo Carvalho de Melo
626a6b78 f6cdff83

+49 -7
+14
tools/perf/Documentation/perf-record.txt
··· 367 367 'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj 368 368 in config file is set to true. 369 369 370 + --overwrite:: 371 + Makes all events use an overwritable ring buffer. An overwritable ring 372 + buffer works like a flight recorder: when it gets full, the kernel will 373 + overwrite the oldest records, that thus will never make it to the 374 + perf.data file. 375 + 376 + When '--overwrite' and '--switch-output' are used perf records and drops 377 + events until it receives a signal, meaning that something unusual was 378 + detected that warrants taking a snapshot of the most current events, 379 + those fitting in the ring buffer at that moment. 380 + 381 + 'overwrite' attribute can also be set or canceled for an event using 382 + config terms. For example: 'cycles/overwrite/' and 'instructions/no-overwrite/'. 383 + 370 384 SEE ALSO 371 385 -------- 372 386 linkperf:perf-stat[1], linkperf:perf-list[1]
+1
tools/perf/builtin-record.c
··· 1399 1399 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, 1400 1400 &record.opts.no_inherit_set, 1401 1401 "child tasks do not inherit counters"), 1402 + OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"), 1402 1403 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"), 1403 1404 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]", 1404 1405 "number of mmap data pages and AUX area tracing mmap pages",
+1
tools/perf/perf.h
··· 59 59 bool record_switch_events; 60 60 bool all_kernel; 61 61 bool all_user; 62 + bool overwrite; 62 63 unsigned int freq; 63 64 unsigned int mmap_pages; 64 65 unsigned int auxtrace_mmap_pages;
+5 -5
tools/perf/tests/backward-ring-buffer.c
··· 108 108 } 109 109 110 110 bzero(&parse_error, sizeof(parse_error)); 111 - err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error); 111 + /* 112 + * Set backward bit, ring buffer should be writing from end. Record 113 + * it in aux evlist 114 + */ 115 + err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error); 112 116 if (err) { 113 117 pr_debug("Failed to parse tracepoint event, try use root\n"); 114 118 ret = TEST_SKIP; ··· 120 116 } 121 117 122 118 perf_evlist__config(evlist, &opts, NULL); 123 - 124 - /* Set backward bit, ring buffer should be writing from end */ 125 - evlist__for_each_entry(evlist, evsel) 126 - evsel->attr.write_backward = 1; 127 119 128 120 err = perf_evlist__open(evlist); 129 121 if (err < 0) {
+4
tools/perf/util/evsel.c
··· 695 695 */ 696 696 attr->inherit = term->val.inherit ? 1 : 0; 697 697 break; 698 + case PERF_EVSEL__CONFIG_TERM_OVERWRITE: 699 + attr->write_backward = term->val.overwrite ? 1 : 0; 700 + break; 698 701 default: 699 702 break; 700 703 } ··· 779 776 780 777 attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1; 781 778 attr->inherit = !opts->no_inherit; 779 + attr->write_backward = opts->overwrite ? 1 : 0; 782 780 783 781 perf_evsel__set_sample_bit(evsel, IP); 784 782 perf_evsel__set_sample_bit(evsel, TID);
+2
tools/perf/util/evsel.h
··· 45 45 PERF_EVSEL__CONFIG_TERM_STACK_USER, 46 46 PERF_EVSEL__CONFIG_TERM_INHERIT, 47 47 PERF_EVSEL__CONFIG_TERM_MAX_STACK, 48 + PERF_EVSEL__CONFIG_TERM_OVERWRITE, 48 49 PERF_EVSEL__CONFIG_TERM_MAX, 49 50 }; 50 51 ··· 60 59 u64 stack_user; 61 60 int max_stack; 62 61 bool inherit; 62 + bool overwrite; 63 63 } val; 64 64 }; 65 65
+18 -2
tools/perf/util/parse-events.c
··· 902 902 [PARSE_EVENTS__TERM_TYPE_NOINHERIT] = "no-inherit", 903 903 [PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit", 904 904 [PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack", 905 + [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite", 906 + [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite", 905 907 }; 906 908 907 909 static bool config_term_shrinked; ··· 996 994 case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 997 995 CHECK_TYPE_VAL(NUM); 998 996 break; 997 + case PARSE_EVENTS__TERM_TYPE_OVERWRITE: 998 + CHECK_TYPE_VAL(NUM); 999 + break; 1000 + case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: 1001 + CHECK_TYPE_VAL(NUM); 1002 + break; 999 1003 case PARSE_EVENTS__TERM_TYPE_NAME: 1000 1004 CHECK_TYPE_VAL(STR); 1001 1005 break; ··· 1054 1046 case PARSE_EVENTS__TERM_TYPE_INHERIT: 1055 1047 case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 1056 1048 case PARSE_EVENTS__TERM_TYPE_MAX_STACK: 1049 + case PARSE_EVENTS__TERM_TYPE_OVERWRITE: 1050 + case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: 1057 1051 return config_term_common(attr, term, err); 1058 1052 default: 1059 1053 if (err) { ··· 1127 1117 break; 1128 1118 case PARSE_EVENTS__TERM_TYPE_MAX_STACK: 1129 1119 ADD_CONFIG_TERM(MAX_STACK, max_stack, term->val.num); 1120 + break; 1121 + case PARSE_EVENTS__TERM_TYPE_OVERWRITE: 1122 + ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 1 : 0); 1123 + break; 1124 + case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: 1125 + ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1); 1130 1126 break; 1131 1127 default: 1132 1128 break; ··· 2428 2412 char *parse_events_formats_error_string(char *additional_terms) 2429 2413 { 2430 2414 char *str; 2431 - /* "branch_type" is the longest name */ 2415 + /* "no-overwrite" is the longest name */ 2432 2416 char static_terms[__PARSE_EVENTS__TERM_TYPE_NR * 2433 - (sizeof("branch_type") - 1)]; 2417 + (sizeof("no-overwrite") - 1)]; 2434 2418 2435 2419 config_terms_list(static_terms, sizeof(static_terms)); 2436 2420 /* valid terms */
+2
tools/perf/util/parse-events.h
··· 69 69 PARSE_EVENTS__TERM_TYPE_NOINHERIT, 70 70 PARSE_EVENTS__TERM_TYPE_INHERIT, 71 71 PARSE_EVENTS__TERM_TYPE_MAX_STACK, 72 + PARSE_EVENTS__TERM_TYPE_NOOVERWRITE, 73 + PARSE_EVENTS__TERM_TYPE_OVERWRITE, 72 74 __PARSE_EVENTS__TERM_TYPE_NR, 73 75 }; 74 76
+2
tools/perf/util/parse-events.l
··· 202 202 max-stack { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_MAX_STACK); } 203 203 inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); } 204 204 no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); } 205 + overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); } 206 + no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); } 205 207 , { return ','; } 206 208 "/" { BEGIN(INITIAL); return '/'; } 207 209 {name_minus} { return str(yyscanner, PE_NAME); }