From b5c2161cc415babb84d2b49599df8bd03b2b9b69 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 27 Nov 2018 10:46:34 +0200 Subject: perf dso: Export data_file_size() method there are no symbols Will be used outside dso.c in a followup patch, so rename it and make it non-static. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Link: http://lkml.kernel.org/r/20181127084634.12469-1-adrian.hunter@intel.com [ split from a larger patch ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.c | 6 +++--- tools/perf/util/dso.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index cee717a3794f..62c8cf622607 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -894,7 +894,7 @@ static ssize_t cached_read(struct dso *dso, struct machine *machine, return r; } -static int data_file_size(struct dso *dso, struct machine *machine) +int dso__data_file_size(struct dso *dso, struct machine *machine) { int ret = 0; struct stat st; @@ -943,7 +943,7 @@ out: */ off_t dso__data_size(struct dso *dso, struct machine *machine) { - if (data_file_size(dso, machine)) + if (dso__data_file_size(dso, machine)) return -1; /* For now just estimate dso data size is close to file size */ @@ -953,7 +953,7 @@ off_t dso__data_size(struct dso *dso, struct machine *machine) static ssize_t data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size) { - if (data_file_size(dso, machine)) + if (dso__data_file_size(dso, machine)) return -1; /* Check the offset sanity. */ diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index c5380500bed4..8c8a7abe809d 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -322,6 +322,7 @@ int dso__data_get_fd(struct dso *dso, struct machine *machine); void dso__data_put_fd(struct dso *dso); void dso__data_close(struct dso *dso); +int dso__data_file_size(struct dso *dso, struct machine *machine); off_t dso__data_size(struct dso *dso, struct machine *machine); ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size); -- cgit From 571766010ea6bf9726b288eb2db1abb59b1841af Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 27 Nov 2018 10:46:34 +0200 Subject: perf auxtrace: Alter addr_filter__entire_dso() to work if there are no symbols addr_filter__entire_dso() uses the first and last symbols from a dso, and so does not work when there are no symbols. Alter it to filter the whole file instead. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Mathieu Poirier Fixes: 1b36c03e3569 ("perf record: Add support for using symbols in address filters") Link: http://lkml.kernel.org/r/20181127084634.12469-1-adrian.hunter@intel.com [ split from a larger patch ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/auxtrace.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 72d5ba2479bf..f69961c4a4f3 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -1983,17 +1983,14 @@ static int find_dso_sym(struct dso *dso, const char *sym_name, u64 *start, static int addr_filter__entire_dso(struct addr_filter *filt, struct dso *dso) { - struct symbol *first_sym = dso__first_symbol(dso); - struct symbol *last_sym = dso__last_symbol(dso); - - if (!first_sym || !last_sym) { - pr_err("Failed to determine filter for %s\nNo symbols found.\n", + if (dso__data_file_size(dso, NULL)) { + pr_err("Failed to determine filter for %s\nCannot determine file size.\n", filt->filename); return -EINVAL; } - filt->addr = first_sym->start; - filt->size = last_sym->end - first_sym->start; + filt->addr = 0; + filt->size = dso->data.file_size; return 0; } -- cgit From 4eaf97e8c5b13d01dd3c3b00181b6eed208aec01 Mon Sep 17 00:00:00 2001 From: Michael Petlan Date: Wed, 21 Nov 2018 16:39:18 -0500 Subject: perf tests: Use shebangs in the shell scripts Since the first line was used as a test identification, it needs to be skipped by shell_test__description() function now. Further notes from Hendrik: It might be worth to note that adding the shebang is necessary to spot them as scripts. Using /bin/sh looks fine to. Just briefly checked whether the scripts contains some bash-specifics, which is not the case. Signed-off-by: Michael Petlan Reviewed-by: Hendrik Brueckner Cc: Jiri Olsa LPU-Reference: 2127419430.57657104.1542836358464.JavaMail.zimbra@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 3 +++ tools/perf/tests/shell/probe_vfs_getname.sh | 1 + tools/perf/tests/shell/record+probe_libc_inet_pton.sh | 1 + tools/perf/tests/shell/record+script_probe_vfs_getname.sh | 1 + tools/perf/tests/shell/trace+probe_vfs_getname.sh | 1 + 5 files changed, 7 insertions(+) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 12c09e0ece71..9852b5d624a5 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -424,6 +424,9 @@ static const char *shell_test__description(char *description, size_t size, if (!fp) return NULL; + /* Skip shebang */ + while (fgetc(fp) != '\n'); + description = fgets(description, size, fp); fclose(fp); diff --git a/tools/perf/tests/shell/probe_vfs_getname.sh b/tools/perf/tests/shell/probe_vfs_getname.sh index 9b7635184dc2..46e076e3c537 100755 --- a/tools/perf/tests/shell/probe_vfs_getname.sh +++ b/tools/perf/tests/shell/probe_vfs_getname.sh @@ -1,3 +1,4 @@ +#!/bin/sh # Add vfs_getname probe to get syscall args filenames # # Arnaldo Carvalho de Melo , 2017 diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh index cab7b0aea6ea..61c9f8fc6fa1 100755 --- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh +++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh @@ -1,3 +1,4 @@ +#!/bin/sh # probe libc's inet_pton & backtrace it with ping # Installs a probe on libc's inet_pton function, that will use uprobes, diff --git a/tools/perf/tests/shell/record+script_probe_vfs_getname.sh b/tools/perf/tests/shell/record+script_probe_vfs_getname.sh index ba29535b8580..9b073e7fa88c 100755 --- a/tools/perf/tests/shell/record+script_probe_vfs_getname.sh +++ b/tools/perf/tests/shell/record+script_probe_vfs_getname.sh @@ -1,3 +1,4 @@ +#!/bin/sh # Use vfs_getname probe to get syscall args filenames # Uses the 'perf test shell' library to add probe:vfs_getname to the system diff --git a/tools/perf/tests/shell/trace+probe_vfs_getname.sh b/tools/perf/tests/shell/trace+probe_vfs_getname.sh index 4ce276efe6b4..50109f27ca07 100755 --- a/tools/perf/tests/shell/trace+probe_vfs_getname.sh +++ b/tools/perf/tests/shell/trace+probe_vfs_getname.sh @@ -1,3 +1,4 @@ +#!/bin/sh # Check open filename arg using perf trace + vfs_getname # Uses the 'perf test shell' library to add probe:vfs_getname to the system -- cgit From 51433ead1460fb3f46e1c34f68bb22fd2dd0f5d0 Mon Sep 17 00:00:00 2001 From: Michael Petlan Date: Mon, 10 Dec 2018 11:00:04 -0500 Subject: perf stat: Avoid segfaults caused by negated options Some 'perf stat' options do not make sense to be negated (event, cgroup), some do not have negated path implemented (metrics). Due to that, it is better to disable the "no-" prefix for them, since otherwise, the later opt-parsing segfaults. Before: $ perf stat --no-metrics -- ls Segmentation fault (core dumped) After: $ perf stat --no-metrics -- ls Error: option `no-metrics' isn't available Usage: perf stat [] [] Signed-off-by: Michael Petlan Tested-by: Arnaldo Carvalho de Melo LPU-Reference: 1485912065.62416880.1544457604340.JavaMail.zimbra@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index a635abfa77b6..1410d66192f7 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -709,7 +709,7 @@ static int parse_metric_groups(const struct option *opt, return metricgroup__parse_groups(opt, str, &stat_config.metric_events); } -static const struct option stat_options[] = { +static struct option stat_options[] = { OPT_BOOLEAN('T', "transaction", &transaction_run, "hardware transaction statistics"), OPT_CALLBACK('e', "event", &evsel_list, "event", @@ -1599,6 +1599,12 @@ int cmd_stat(int argc, const char **argv) return -ENOMEM; parse_events__shrink_config_terms(); + + /* String-parsing callback-based options would segfault when negated */ + set_option_flag(stat_options, 'e', "event", PARSE_OPT_NONEG); + set_option_flag(stat_options, 'M', "metrics", PARSE_OPT_NONEG); + set_option_flag(stat_options, 'G', "cgroup", PARSE_OPT_NONEG); + argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands, (const char **) stat_usage, PARSE_OPT_STOP_AT_NON_OPTION); -- cgit From f024cf085c423bac7512479f45c34ee9a24af7ce Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Mon, 10 Dec 2018 13:45:22 -0500 Subject: tools lib traceevent: Fix processing of dereferenced args in bprintk events In the case that a bprintk event has a dereferenced pointer that is stored as a string, and there's more values to process (more args), the arg was not updated to point to the next arg after processing the dereferenced pointer, and it screwed up what was to be displayed. Signed-off-by: Steven Rostedt (VMware) Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Cc: stable@vger.kernel.org Fixes: 37db96bb49629 ("tools lib traceevent: Handle new pointer processing of bprint strings") Link: http://lkml.kernel.org/r/20181210134522.3f71e2ca@gandalf.local.home Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index a5ed291b8a9f..69a96e39f0ab 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -4973,6 +4973,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_e if (arg->type == TEP_PRINT_BSTRING) { trace_seq_puts(s, arg->string.string); + arg = arg->next; break; } -- cgit From 7ba61524fa0337a919b2ec5fcce26db23c611ca7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 10 Dec 2018 16:09:51 -0300 Subject: perf trace: Rename delivery functions to ease making ordered_events selectable Just hide a bit more how events gets delivered, hiding ordered_events details from the main loop. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-lxwwf3238ta4neq2zh1y1h45@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 366ec3c8f580..1ff5603db940 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2641,7 +2641,7 @@ static int trace__set_filter_pids(struct trace *trace) return err; } -static int trace__deliver_event(struct trace *trace, union perf_event *event) +static int __trace__deliver_event(struct trace *trace, union perf_event *event) { struct perf_evlist *evlist = trace->evlist; struct perf_sample sample; @@ -2656,7 +2656,7 @@ static int trace__deliver_event(struct trace *trace, union perf_event *event) return 0; } -static int trace__flush_ordered_events(struct trace *trace) +static int trace__flush_events(struct trace *trace) { u64 first = ordered_events__first_time(&trace->oe.data); u64 flush = trace->oe.last - NSEC_PER_SEC; @@ -2668,7 +2668,7 @@ static int trace__flush_ordered_events(struct trace *trace) return 0; } -static int trace__deliver_ordered_event(struct trace *trace, union perf_event *event) +static int trace__deliver_event(struct trace *trace, union perf_event *event) { struct perf_evlist *evlist = trace->evlist; int err; @@ -2681,7 +2681,7 @@ static int trace__deliver_ordered_event(struct trace *trace, union perf_event *e if (err) return err; - return trace__flush_ordered_events(trace); + return trace__flush_events(trace); } static int ordered_events__deliver_event(struct ordered_events *oe, @@ -2689,7 +2689,7 @@ static int ordered_events__deliver_event(struct ordered_events *oe, { struct trace *trace = container_of(oe, struct trace, oe.data); - return trace__deliver_event(trace, event->event); + return __trace__deliver_event(trace, event->event); } static int trace__run(struct trace *trace, int argc, const char **argv) @@ -2859,7 +2859,7 @@ again: while ((event = perf_mmap__read_event(md)) != NULL) { ++trace->nr_events; - err = trace__deliver_ordered_event(trace, event); + err = trace__deliver_event(trace, event); if (err) goto out_disable; @@ -2885,7 +2885,7 @@ again: goto again; } else { - if (trace__flush_ordered_events(trace)) + if (trace__flush_events(trace)) goto out_disable; } } else { -- cgit From a761a8d102e2a6edfef3ad5bb22baeb715f93abd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 10 Dec 2018 16:27:33 -0300 Subject: perf trace: Allow selecting use the use of the ordered_events code I was trigger happy on this one, as using ordered_events as implemented by Jiri for use with the --block code under discussion on lkml incurs in delaying processing to form batches that then get ordered and then printed. With 'perf trace' we want to process the events as they go, without that delay, and doing it that way works well for the common case which is to trace a thread or a workload started by 'perf trace'. So revert back to not using ordered_events but add an option to select that mode so that users can experiment with their particular use case to see if works better, i.e. if the added delay is not a problem and the ordering helps. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-8ki7sld6rusnjhhtaly26i5o@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-trace.txt | 6 ++++++ tools/perf/builtin-trace.c | 25 +++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index e113450503d2..631e687be4eb 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -205,6 +205,12 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. because the file may be huge. A time out is needed in such cases. This option sets the time out limit. The default value is 500 ms. +--sort-events:: + Do sorting on batches of events, use when noticing out of order events that + may happen, for instance, when a thread gets migrated to a different CPU + while processing a syscall. + + PAGEFAULTS ---------- diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 1ff5603db940..406bceda6a2b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -110,6 +110,7 @@ struct trace { } stats; unsigned int max_stack; unsigned int min_stack; + bool sort_events; bool raw_augmented_syscalls; bool not_ev_qualifier; bool live; @@ -2656,7 +2657,7 @@ static int __trace__deliver_event(struct trace *trace, union perf_event *event) return 0; } -static int trace__flush_events(struct trace *trace) +static int __trace__flush_events(struct trace *trace) { u64 first = ordered_events__first_time(&trace->oe.data); u64 flush = trace->oe.last - NSEC_PER_SEC; @@ -2668,12 +2669,19 @@ static int trace__flush_events(struct trace *trace) return 0; } +static int trace__flush_events(struct trace *trace) +{ + return !trace->sort_events ? 0 : __trace__flush_events(trace); +} + static int trace__deliver_event(struct trace *trace, union perf_event *event) { - struct perf_evlist *evlist = trace->evlist; int err; - err = perf_evlist__parse_sample_timestamp(evlist, event, &trace->oe.last); + if (!trace->sort_events) + return __trace__deliver_event(trace, event); + + err = perf_evlist__parse_sample_timestamp(trace->evlist, event, &trace->oe.last); if (err && err != -1) return err; @@ -2897,7 +2905,8 @@ out_disable: perf_evlist__disable(evlist); - ordered_events__flush(&trace->oe.data, OE_FLUSH__FINAL); + if (trace->sort_events) + ordered_events__flush(&trace->oe.data, OE_FLUSH__FINAL); if (!err) { if (trace->summary) @@ -3516,6 +3525,8 @@ int cmd_trace(int argc, const char **argv) "Set the maximum stack depth when parsing the callchain, " "anything beyond the specified depth will be ignored. " "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), + OPT_BOOLEAN(0, "sort-events", &trace.sort_events, + "Sort batch of events before processing, use if getting out of order events"), OPT_BOOLEAN(0, "print-sample", &trace.print_sample, "print the PERF_RECORD_SAMPLE PERF_SAMPLE_ info, for debugging"), OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout, @@ -3609,8 +3620,10 @@ int cmd_trace(int argc, const char **argv) } } - ordered_events__init(&trace.oe.data, ordered_events__deliver_event, &trace); - ordered_events__set_copy_on_queue(&trace.oe.data, true); + if (trace.sort_events) { + ordered_events__init(&trace.oe.data, ordered_events__deliver_event, &trace); + ordered_events__set_copy_on_queue(&trace.oe.data, true); + } /* * If we are augmenting syscalls, then combine what we put in the -- cgit From 84a835412cdc36f3821a1daa10853f9c9aa3fc7c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 09:53:21 -0300 Subject: perf trace beauty: Beautify renameat2's fd arg wrt AT_FDCWD Just like is done with the 'renameat' syscall. # strace -e renameat2 -f perf trace -e rename* mv c /tmp [pid 12334] renameat2(AT_FDCWD, "c", AT_FDCWD, "/tmp", RENAME_NOREPLACE) = -1 EXDEV (Invalid cross-device link) [pid 12334] renameat2(AT_FDCWD, "c", AT_FDCWD, "/tmp/c", RENAME_NOREPLACE) = -1 EEXIST (File exists) 1.947 ( 0.007 ms): mv/12334 renameat2(olddfd: CWD, oldname: 0x7ffce8b7fd81, newdfd: CWD, newname: 0x7ffce8b7fd83, flags: 1) = -1 EXDEV Invalid cross-device link 2.073 ( 0.009 ms): mv/12334 renameat2(olddfd: CWD, oldname: 0x7ffce8b7fd81, newdfd: CWD, newname: 0x55ce7f0a1cc0, flags: 1mv: ) = -1 EEXIST File exists'c' and '/tmp/c' are the same file # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-8q9l92eh9eee3y2bwyqku3tc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 406bceda6a2b..60c61a89436f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -799,6 +799,9 @@ static struct syscall_fmt { .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "renameat", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "renameat2", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, + [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "rt_sigaction", .arg = { [0] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, { .name = "rt_sigprocmask", -- cgit From bdc2a9d64a4c4c77c63ce2561bd644d233fcb1fc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 10:16:42 -0300 Subject: perf beauty: Add a string table generator for renameat2's flags constants Using the already copied tools/include/uapi/linux/fs.h file: $ tools/perf/trace/beauty/rename_flags.sh static const char *rename_flags[] = { [0 + 1] = "NOREPLACE", [1 + 1] = "EXCHANGE", [2 + 1] = "WHITEOUT", }; $ Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ta2jbh03spkymp4sbdh489g8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/rename_flags.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 tools/perf/trace/beauty/rename_flags.sh diff --git a/tools/perf/trace/beauty/rename_flags.sh b/tools/perf/trace/beauty/rename_flags.sh new file mode 100755 index 000000000000..54c87c782ab2 --- /dev/null +++ b/tools/perf/trace/beauty/rename_flags.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo +# SPDX-License-Identifier: LGPL-2.1 + +[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ + +fs_header=${header_dir}/fs.h + +printf "static const char *rename_flags[] = {\n" +regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+RENAME_([[:alnum:]_]+)[[:space:]]+\(1[[:space:]]*<<[[:space:]]*([[:xdigit:]]+)[[:space:]]*\)[[:space:]]*.*' +egrep -q $regex ${fs_header} && \ +(egrep $regex ${fs_header} | \ + sed -r "s/$regex/\2 \1/g" | \ + xargs printf "\t[%d + 1] = \"%s\",\n") +printf "};\n" -- cgit From 5a1cb7edfbf6ee8087b75d32461775501213a8e9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 10:26:13 -0300 Subject: perf beauty: Wire up the renameat flags table generator to the Makefile Now when we run 'make -C tools/perf O=/tmp/build/perf' we end up with: $ cat /tmp/build/perf/trace/beauty/generated/rename_flags_array.c static const char *rename_flags[] = { [0 + 1] = "NOREPLACE", [1 + 1] = "EXCHANGE", [2 + 1] = "WHITEOUT", }; $ Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-4fad4xahrn04y06o0lc49clm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index bfdaefd500ab..22956a85e4c6 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -490,6 +490,12 @@ prctl_option_tbl := $(srctree)/tools/perf/trace/beauty/prctl_option.sh $(prctl_option_array): $(prctl_hdr_dir)/prctl.h $(prctl_option_tbl) $(Q)$(SHELL) '$(prctl_option_tbl)' $(prctl_hdr_dir) > $@ +rename_flags_array := $(beauty_outdir)/rename_flags_array.c +rename_flags_tbl := $(srctree)/tools/perf/trace/beauty/rename_flags.sh + +$(rename_flags_array): $(linux_uapi_dir)/fs.h $(rename_flags_tbl) + $(Q)$(SHELL) '$(rename_flags_tbl)' $(linux_uapi_dir) > $@ + arch_errno_name_array := $(beauty_outdir)/arch_errno_name_array.c arch_errno_hdr_dir := $(srctree)/tools arch_errno_tbl := $(srctree)/tools/perf/trace/beauty/arch_errno_names.sh @@ -604,6 +610,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc $(mount_flags_array) \ $(perf_ioctl_array) \ $(prctl_option_array) \ + $(rename_flags_array) \ $(arch_errno_name_array) $(OUTPUT)%.o: %.c prepare FORCE @@ -900,6 +907,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(OUTPUT)$(vhost_virtio_ioctl_array) \ $(OUTPUT)$(perf_ioctl_array) \ $(OUTPUT)$(prctl_option_array) \ + $(OUTPUT)$(rename_flags_array) \ $(OUTPUT)$(arch_errno_name_array) $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean -- cgit From ca7ff2c8e7add62b661c414257e7ef12cd40a950 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 10:39:30 -0300 Subject: perf trace: Beautify renameat2's flags argument # strace -e renameat2 -f perf trace -e rename* mv c /tmp strace: Process 10824 attached [pid 10824] renameat2(AT_FDCWD, "c", AT_FDCWD, "/tmp", RENAME_NOREPLACE) = -1 EXDEV (Invalid cross-device link) [pid 10824] renameat2(AT_FDCWD, "c", AT_FDCWD, "/tmp/c", RENAME_NOREPLACE) = -1 EEXIST (File exists) 1.857 ( 0.008 ms): mv/10824 renameat2(olddfd: CWD, oldname: 0x7ffc72ff3d81, newdfd: CWD, newname: 0x7ffc72ff3d83, flags: NOREPLACE) = -1 EXDEV Invalid cross-device link 2.002 ( 0.006 ms): mv/10824 renameat2(olddfd: CWD, oldname: 0x7ffc72ff3d81, newdfd: CWD, newname: 0x55ad609efcc0, flags: NOREPLACE) = -1 EEXIST File exists mv: 'c' and '/tmp/c' are the same file [pid 10824] +++ exited with 1 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=10824, si_uid=0, si_status=1, si_utime=0, si_stime=0} --- +++ exited with 0 +++ # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-glyt6nzlt1yx56m5bshy6g83@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 ++- tools/perf/trace/beauty/Build | 1 + tools/perf/trace/beauty/beauty.h | 3 +++ tools/perf/trace/beauty/renameat.c | 19 +++++++++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tools/perf/trace/beauty/renameat.c diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 60c61a89436f..4b3f8407f8d5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -801,7 +801,8 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, { .name = "renameat2", .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, - [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, + [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, + [4] = { .scnprintf = SCA_RENAMEAT2_FLAGS, /* flags */ }, }, }, { .name = "rt_sigaction", .arg = { [0] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, { .name = "rt_sigprocmask", diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index 304313073242..10c85cd3eb4f 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build @@ -8,6 +8,7 @@ libperf-y += kcmp.o libperf-y += mount_flags.o libperf-y += pkey_alloc.o libperf-y += prctl.o +libperf-y += renameat.o libperf-y += sockaddr.o libperf-y += socket.o libperf-y += statx.o diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 039c29039b2c..48ff3ce05325 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -144,6 +144,9 @@ size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_a size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg); #define SCA_PRCTL_ARG3 syscall_arg__scnprintf_prctl_arg3 +size_t syscall_arg__scnprintf_renameat2_flags(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_RENAMEAT2_FLAGS syscall_arg__scnprintf_renameat2_flags + size_t syscall_arg__scnprintf_sockaddr(char *bf, size_t size, struct syscall_arg *arg); #define SCA_SOCKADDR syscall_arg__scnprintf_sockaddr diff --git a/tools/perf/trace/beauty/renameat.c b/tools/perf/trace/beauty/renameat.c new file mode 100644 index 000000000000..02c7207faee6 --- /dev/null +++ b/tools/perf/trace/beauty/renameat.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: LGPL-2.1 +// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo + +#include "trace/beauty/beauty.h" +#include + +static size_t renameat2__scnprintf_flags(unsigned long flags, char *bf, size_t size) +{ +#include "trace/beauty/generated/rename_flags_array.c" + static DEFINE_STRARRAY(rename_flags); + + return strarray__scnprintf_flags(&strarray__rename_flags, bf, size, flags); +} + +size_t syscall_arg__scnprintf_renameat2_flags(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long flags = arg->val; + return renameat2__scnprintf_flags(flags, bf, size); +} -- cgit From 436651caa1ca3fd1d61e8daaff57453881f35a14 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 11:19:23 -0300 Subject: perf trace beauty: renameat's newdirfd may also be AT_FDCWD Noticed while working on renameat2. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-8omchrcjcvlwoxxv6wrjehfh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4b3f8407f8d5..a14ee4ed2c9f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -798,7 +798,8 @@ static struct syscall_fmt { { .name = "recvmsg", .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "renameat", - .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, + [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "renameat2", .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, -- cgit From ece9804985b57e1ccd83b1fb6288520955a29d51 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 15:00:52 -0300 Subject: tools lib subcmd: Don't add the kernel sources to the include path At some point we decided not to directly include kernel sources files when building tools/perf/, but when tools/lib/subcmd/ was forked from tools/perf it somehow ended up adding it via these two lines in its Makefile: CFLAGS += -I$(srctree)/include/uapi CFLAGS += -I$(srctree)/include As $(srctree) points to the kernel sources. Removing those lines and keeping just: CFLAGS += -I$(srctree)/tools/include/ Is enough to build tools/perf and tools/objtool. This fixes the build when building from the sources in environments such as the Android NDK crossbuilding from a fedora:26 system: subcmd-util.h:11:15: error: expected ',' or ';' before 'void' static inline void report(const char *prefix, const char *err, va_list params) ^ In file included from /git/perf/include/uapi/linux/stddef.h:2:0, from /git/perf/include/uapi/linux/posix_types.h:5, from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/sys/types.h:36, from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/unistd.h:33, from run-command.c:2: subcmd-util.h:18:17: error: '__no_instrument_function__' attribute applies only to functions The /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/sys/types.h file that includes linux/posix_types.h ends up getting the one in the kernel sources causing the breakage. Fix it. Test built tools/objtool/ too. Reported-by: Jiri Olsa Tested-by: Jiri Olsa Cc: Adrian Hunter Cc: Josh Poimboeuf Cc: Namhyung Kim Fixes: 4b6ab94eabe4 ("perf subcmd: Create subcmd library") Link: https://lkml.kernel.org/n/tip-5lhaoecrj12t0bqwvpiu14sm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/subcmd/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index 95563b8e1ad7..ed61fb3a46c0 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -36,8 +36,6 @@ endif CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE CFLAGS += -I$(srctree)/tools/include/ -CFLAGS += -I$(srctree)/include/uapi -CFLAGS += -I$(srctree)/include SUBCMD_IN := $(OUTPUT)libsubcmd-in.o -- cgit From 748fe0889c1ff12d378946bd5326e8ee8eacf5cf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 15:48:47 -0300 Subject: perf tools: Add missing sigqueue() prototype for systems lacking it There are systems such as the Android NDK API level 24 has the sigqueue() function but doesn't provide a prototype, adding noise to the build: util/evlist.c: In function 'perf_evlist__prepare_workload': util/evlist.c:1494:4: warning: implicit declaration of function 'sigqueue' [-Wimplicit-function-declaration] if (sigqueue(getppid(), SIGUSR1, val)) ^ util/evlist.c:1494:4: warning: nested extern declaration of 'sigqueue' [-Wnested-externs] Define a LACKS_SIGQUEUE_PROTOTYPE define so that code needing that can get a prototype. Checked in the bionic git repo to be available since level 23: https://android.googlesource.com/platform/bionic/+/master/libc/include/signal.h#123 int sigqueue(pid_t __pid, int __signal, const union sigval __value) __INTRODUCED_IN(23); Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-lmhpev1uni9kdrv7j29glyov@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 1 + tools/perf/util/evlist.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index b66f97a04b12..265a9225e5fc 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -294,6 +294,7 @@ ifndef NO_BIONIC $(call feature_check,bionic) ifeq ($(feature-bionic), 1) BIONIC := 1 + CFLAGS += -DLACKS_SIGQUEUE_PROTOTYPE EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) endif diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e90575192209..8c902276d4b4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -34,6 +34,10 @@ #include #include +#ifdef LACKS_SIGQUEUE_PROTOTYPE +int sigqueue(pid_t pid, int sig, const union sigval value); +#endif + #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) -- cgit From 0afcf29bab35d3785204cd9bd51693b231ad7181 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 16:11:54 -0300 Subject: perf header: Fix up argument to ctime() Reducing this noise when cross building to the Android NDK: util/header.c: In function 'perf_header__fprintf_info': util/header.c:2710:45: warning: pointer targets in passing argument 1 of 'ctime' differ in signedness [-Wpointer-sign] fprintf(fp, "# captured on : %s", ctime(&st.st_ctime)); ^ In file included from util/../perf.h:5:0, from util/evlist.h:11, from util/header.c:22: /opt/android-ndk-r15c/platforms/android-26/arch-arm/usr/include/time.h:81:14: note: expected 'const time_t *' but argument is of type 'long unsigned int *' extern char* ctime(const time_t*) __LIBC_ABI_PUBLIC__; ^ Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6bz74zp080yhmtiwb36enso9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 1171d8400bf4..dec6d218c31c 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2698,6 +2698,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) struct perf_header *header = &session->header; int fd = perf_data__fd(session->data); struct stat st; + time_t stctime; int ret, bit; hd.fp = fp; @@ -2707,7 +2708,8 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) if (ret == -1) return -1; - fprintf(fp, "# captured on : %s", ctime(&st.st_ctime)); + stctime = st.st_ctime; + fprintf(fp, "# captured on : %s", ctime(&stctime)); fprintf(fp, "# header version : %u\n", header->version); fprintf(fp, "# data offset : %" PRIu64 "\n", header->data_offset); -- cgit From d7a8c4a6a055097a67ccfa3ca7c9ff1b64603a70 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 16:31:19 -0300 Subject: perf tools: Add missing open_memstream() prototype for systems lacking it There are systems such as the Android NDK API level 24 has the open_memstream() function but doesn't provide a prototype, adding noise to the build: builtin-timechart.c: In function 'cat_backtrace': builtin-timechart.c:486:2: warning: implicit declaration of function 'open_memstream' [-Wimplicit-function-declaration] FILE *f = open_memstream(&p, &p_len); ^ builtin-timechart.c:486:2: warning: nested extern declaration of 'open_memstream' [-Wnested-externs] builtin-timechart.c:486:12: warning: initialization makes pointer from integer without a cast FILE *f = open_memstream(&p, &p_len); ^ Define a LACKS_OPEN_MEMSTREAM_PROTOTYPE define so that code needing that can get a prototype. Checked in the bionic git repo to be available since level 23: https://android.googlesource.com/platform/bionic/+/master/libc/include/stdio.h#241 FILE* open_memstream(char** __ptr, size_t* __size_ptr) __INTRODUCED_IN(23); Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-343ashae97e5bq6vizusyfno@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 1 + tools/perf/builtin-timechart.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 265a9225e5fc..07c1857c3d7a 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -295,6 +295,7 @@ ifndef NO_BIONIC ifeq ($(feature-bionic), 1) BIONIC := 1 CFLAGS += -DLACKS_SIGQUEUE_PROTOTYPE + CFLAGS += -DLACKS_OPEN_MEMSTREAM_PROTOTYPE EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) endif diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index a827919c6263..775b99833e51 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -43,6 +43,10 @@ #include "util/data.h" #include "util/debug.h" +#ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE +FILE *open_memstream(char **ptr, size_t *sizeloc); +#endif + #define SUPPORT_OLD_POWER_EVENTS 1 #define PWR_EVENT_EXIT -1 -- cgit From 866053bb644f754d1a93aaa9db9998fecf7a8978 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 11 Dec 2018 16:43:40 -0300 Subject: perf tools: Cast off_t to s64 to avoid warning on bionic libc To avoid this warning: CC /tmp/build/perf/util/s390-cpumsf.o util/s390-cpumsf.c: In function 's390_cpumsf_samples': util/s390-cpumsf.c:508:3: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 4 has type 'off_t' [-Wformat=] pr_err("[%#08" PRIx64 "] Invalid AUX trailer entry TOD clock base\n", ^ Now the various Android cross toolchains used in the perf tools container test builds are all clean and we can remove this: export EXTRA_MAKE_ARGS="WERROR=0" Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Thomas Richter Link: https://lkml.kernel.org/n/tip-5rav4ccyb0sjciysz2i4p3sx@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/s390-cpumsf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index a2eeebbfb25f..68b2570304ec 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -506,7 +506,7 @@ static int s390_cpumsf_samples(struct s390_cpumsf_queue *sfq, u64 *ts) aux_ts = get_trailer_time(buf); if (!aux_ts) { pr_err("[%#08" PRIx64 "] Invalid AUX trailer entry TOD clock base\n", - sfq->buffer->data_offset); + (s64)sfq->buffer->data_offset); aux_ts = ~0ULL; goto out; } -- cgit From 41fa483aeee567cc34f9fc4c2e7035f2df25299d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 12 Dec 2018 10:12:14 +0100 Subject: tools lib traceevent: Use LDFLAGS in the build commands So that the user can specify outside LDFLAGS values. Keeping the CFLAGS in there as well, so we don't break existing scripts. Signed-off-by: Jiri Olsa Acked-by: Steven Rostedt (VMware) Cc: Herton Krzesinski Cc: Tzvetomir Stoyanov (VMware) Link: http://lkml.kernel.org/r/20181212091214.GC17489@krava Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 67fe5d7ef190..941761d9923d 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -177,7 +177,7 @@ $(TE_IN): force $(Q)$(MAKE) $(build)=libtraceevent $(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN) - $(QUIET_LINK)$(CC) --shared $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@ + $(QUIET_LINK)$(CC) --shared $(LDFLAGS) $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@ @ln -sf $(@F) $(OUTPUT)libtraceevent.so @ln -sf $(@F) $(OUTPUT)libtraceevent.so.$(EP_VERSION) @@ -196,7 +196,7 @@ $(PLUGINS_IN): force $(Q)$(MAKE) $(build)=$(plugin_obj) $(OUTPUT)%.so: $(OUTPUT)%-in.o - $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $^ + $(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^ define make_version.h (echo '/* This file is automatically generated. Do not modify. */'; \ -- cgit From 3f643937aaab04881236b5aabec00f9802c1eda8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 12 Dec 2018 14:29:40 +0100 Subject: perf tools: Link libperf-jvmti.so with LDFLAGS variable So we could propagate distro flags into libperf-jvmti.so library. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20181212132940.840-1-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 22956a85e4c6..8c1350c591f2 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -654,7 +654,7 @@ $(LIBJVMTI_IN): FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=jvmti obj=jvmti $(OUTPUT)$(LIBJVMTI): $(LIBJVMTI_IN) - $(QUIET_LINK)$(CC) -shared -Wl,-soname -Wl,$(LIBJVMTI) -o $@ $< + $(QUIET_LINK)$(CC) $(LDFLAGS) -shared -Wl,-soname -Wl,$(LIBJVMTI) -o $@ $< endif $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) -- cgit From 246fbe03edaab9dfa5bd1f0e223c7c960d987982 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Dec 2018 11:06:53 -0300 Subject: perf trace: Rename set_ev_qualifier_filter to clarify its a tracepoint filter Rename it to trace__set_ev_qualifier_tp_filter(), as this just sets up tracepoint filters on the raw_syscalls:sys_{enter,exit} tracepoints, and since we're going to do the same for the augmented_raw_syscalls codepath, when used, rename it to clarify. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-8bjsul8x7osw7nxjodnyfn14@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a14ee4ed2c9f..76e4fa04d824 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2553,7 +2553,7 @@ out_delete_sys_enter: goto out; } -static int trace__set_ev_qualifier_filter(struct trace *trace) +static int trace__set_ev_qualifier_tp_filter(struct trace *trace) { int err = -1; struct perf_evsel *sys_exit; @@ -2578,6 +2578,11 @@ out_enomem: goto out; } +static int trace__set_ev_qualifier_filter(struct trace *trace) +{ + return trace__set_ev_qualifier_tp_filter(trace); +} + static int bpf_map__set_filter_pids(struct bpf_map *map __maybe_unused, size_t npids __maybe_unused, pid_t *pids __maybe_unused) { -- cgit From 0df50e0b0e0f315c0d5e2ce8556aafe1403b4a4b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Dec 2018 13:47:40 -0300 Subject: perf trace: Avoid using raw_syscalls in duplicity with eBPF augmentation So when we do something like: # perf trace -e open*,augmented_raw_syscalls.o We need to set trace->trace_syscalls because there is logic that use that when mixing strace-like output with other events, such as scheduler tracepoints, but with that set we ended up having multiple raw_syscalls:sys_{enter,exit} setup, which garbled the output, so check if trace->augmented_raw_syscalls is set and avoid the two extra tracepoints. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-kjmnbrlgu0c38co1ye8egbsb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 76e4fa04d824..f9eb5bc4fefb 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2721,11 +2721,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv) trace->live = true; - if (trace->trace_syscalls && trace__add_syscall_newtp(trace)) - goto out_error_raw_syscalls; + if (!trace->raw_augmented_syscalls) { + if (trace->trace_syscalls && trace__add_syscall_newtp(trace)) + goto out_error_raw_syscalls; - if (trace->trace_syscalls) - trace->vfs_getname = perf_evlist__add_vfs_getname(evlist); + if (trace->trace_syscalls) + trace->vfs_getname = perf_evlist__add_vfs_getname(evlist); + } if ((trace->trace_pgfaults & TRACE_PFMAJ)) { pgfault_maj = perf_evsel__new_pgfault(PERF_COUNT_SW_PAGE_FAULTS_MAJ); @@ -2825,8 +2827,10 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_errno; - pr_debug("event qualifier tracepoint filter: %s\n", - trace->syscalls.events.sys_exit->filter); + if (trace->syscalls.events.sys_exit) { + pr_debug("event qualifier tracepoint filter: %s\n", + trace->syscalls.events.sys_exit->filter); + } } err = perf_evlist__apply_filters(evlist, &evsel); -- cgit From b27b38ed9427b32e0194e03281e3a79dd49887b2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Dec 2018 13:39:24 -0300 Subject: perf trace: Implement syscall filtering in augmented_syscalls Just another map, this time an BPF_MAP_TYPE_ARRAY, stating with one bool per syscall, stating if it should be filtered or not. So, with a pre-built augmented_raw_syscalls.o file, we use: # perf trace -e open*,augmented_raw_syscalls.o 0.000 ( 0.016 ms): DNS Res~er #37/29652 openat(dfd: CWD, filename: /etc/hosts, flags: CLOEXEC ) = 138 187.039 ( 0.048 ms): gsd-housekeepi/2436 openat(dfd: CWD, filename: /etc/fstab, flags: CLOEXEC ) = 11 187.348 ( 0.041 ms): gsd-housekeepi/2436 openat(dfd: CWD, filename: /proc/self/mountinfo, flags: CLOEXEC ) = 11 188.793 ( 0.036 ms): gsd-housekeepi/2436 openat(dfd: CWD, filename: /proc/self/mountinfo, flags: CLOEXEC ) = 11 189.803 ( 0.029 ms): gsd-housekeepi/2436 openat(dfd: CWD, filename: /proc/self/mountinfo, flags: CLOEXEC ) = 11 190.774 ( 0.027 ms): gsd-housekeepi/2436 openat(dfd: CWD, filename: /proc/self/mountinfo, flags: CLOEXEC ) = 11 284.620 ( 0.149 ms): DataStorage/3076 openat(dfd: CWD, filename: /home/acme/.mozilla/firefox/ina67tev.default/SiteSecurityServiceState.txt, flags: CREAT|TRUNC|WRONLY, mode: IRUGO|IWUSR|IWGRP) = 167 ^C# What is it that this gsd-housekeeping thingy needs to open /proc/self/mountinfo four times periodically? :-) This map will be extended to tell per-syscall parameters, i.e. how many bytes to copy per arg, using the function signature to get the types and then the size of those types, via BTF. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-cy222g9ucvnym3raqvxp0hpg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 66 ++++++++++++++++++++++++ tools/perf/examples/bpf/augmented_raw_syscalls.c | 26 +++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index f9eb5bc4fefb..de81918c7ad4 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -76,6 +76,7 @@ struct trace { struct { int max; struct syscall *table; + struct bpf_map *map; struct { struct perf_evsel *sys_enter, *sys_exit, @@ -2578,8 +2579,64 @@ out_enomem: goto out; } +#ifdef HAVE_LIBBPF_SUPPORT +static int trace__set_ev_qualifier_bpf_filter(struct trace *trace) +{ + int fd = bpf_map__fd(trace->syscalls.map); + bool value = !trace->not_ev_qualifier; + int err = 0; + size_t i; + + for (i = 0; i < trace->ev_qualifier_ids.nr; ++i) { + int key = trace->ev_qualifier_ids.entries[i]; + + err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); + if (err) + break; + } + + return err; +} + +static int __trace__init_syscalls_bpf_map(struct trace *trace, bool enabled) +{ + int fd = bpf_map__fd(trace->syscalls.map); + int err = 0, key; + + for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { + err = bpf_map_update_elem(fd, &key, &enabled, BPF_ANY); + if (err) + break; + } + + return err; +} + +static int trace__init_syscalls_bpf_map(struct trace *trace) +{ + bool enabled = true; + + if (trace->ev_qualifier_ids.nr) + enabled = trace->not_ev_qualifier; + + return __trace__init_syscalls_bpf_map(trace, enabled); +} +#else +static int trace__set_ev_qualifier_bpf_filter(struct trace *trace __maybe_unused) +{ + return 0; +} + +static int trace__init_syscalls_bpf_map(struct trace *trace __maybe_unused) +{ + return 0; +} +#endif // HAVE_LIBBPF_SUPPORT + static int trace__set_ev_qualifier_filter(struct trace *trace) { + if (trace->syscalls.map) + return trace__set_ev_qualifier_bpf_filter(trace); return trace__set_ev_qualifier_tp_filter(trace); } @@ -2822,6 +2879,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_mem; + if (trace->syscalls.map) + trace__init_syscalls_bpf_map(trace); + if (trace->ev_qualifier_ids.nr > 0) { err = trace__set_ev_qualifier_filter(trace); if (err < 0) @@ -3449,6 +3509,11 @@ static void trace__set_bpf_map_filtered_pids(struct trace *trace) trace->filter_pids.map = bpf__find_map_by_name("pids_filtered"); } +static void trace__set_bpf_map_syscalls(struct trace *trace) +{ + trace->syscalls.map = bpf__find_map_by_name("syscalls"); +} + int cmd_trace(int argc, const char **argv) { const char *trace_usage[] = { @@ -3589,6 +3654,7 @@ int cmd_trace(int argc, const char **argv) if (evsel) { trace.syscalls.events.augmented = evsel; trace__set_bpf_map_filtered_pids(&trace); + trace__set_bpf_map_syscalls(&trace); } err = bpf__setup_stdout(trace.evlist); diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 74ce7574073d..bb3dcc4ec256 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -26,6 +26,13 @@ struct bpf_map SEC("maps") __augmented_syscalls__ = { .max_entries = __NR_CPUS__, }; +struct bpf_map SEC("maps") syscalls = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(bool), + .max_entries = 512, +}; + struct syscall_enter_args { unsigned long long common_tp_fields; long syscall_nr; @@ -56,6 +63,7 @@ int sys_enter(struct syscall_enter_args *args) struct syscall_enter_args args; struct augmented_filename filename; } augmented_args; + bool *enabled; unsigned int len = sizeof(augmented_args); const void *filename_arg = NULL; @@ -63,6 +71,10 @@ int sys_enter(struct syscall_enter_args *args) return 0; probe_read(&augmented_args.args, sizeof(augmented_args.args), args); + + enabled = bpf_map_lookup_elem(&syscalls, &augmented_args.args.syscall_nr); + if (enabled == NULL || !*enabled) + return 0; /* * Yonghong and Edward Cree sayz: * @@ -131,7 +143,19 @@ int sys_enter(struct syscall_enter_args *args) SEC("raw_syscalls:sys_exit") int sys_exit(struct syscall_exit_args *args) { - return !pid_filter__has(&pids_filtered, getpid()); + struct syscall_exit_args exit_args; + bool *enabled; + + if (pid_filter__has(&pids_filtered, getpid())) + return 0; + + probe_read(&exit_args, sizeof(exit_args), args); + + enabled = bpf_map_lookup_elem(&syscalls, &exit_args.syscall_nr); + if (enabled == NULL || !*enabled) + return 0; + + return 1; } license(GPL); -- cgit From 61d007138a44dc69265cf948eadd1759edbd3875 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Dec 2018 15:31:28 -0300 Subject: perf bpf: Move perf_event_output() from stdio.h to bpf.h So that we don't always carry that __bpf_output__ map, leaving that to the scripts wanting to use that facility. 'perf trace' will be changed to look if that map is present and only setup the bpf-output events if so. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-azwys8irxqx9053vpajr0k5h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/include/bpf/bpf.h | 2 ++ tools/perf/include/bpf/stdio.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/include/bpf/bpf.h b/tools/perf/include/bpf/bpf.h index bd5d7b4d7760..e667577207dc 100644 --- a/tools/perf/include/bpf/bpf.h +++ b/tools/perf/include/bpf/bpf.h @@ -55,4 +55,6 @@ int _version SEC("version") = LINUX_VERSION_CODE; static int (*probe_read)(void *dst, int size, const void *unsafe_addr) = (void *)BPF_FUNC_probe_read; static int (*probe_read_str)(void *dst, int size, const void *unsafe_addr) = (void *)BPF_FUNC_probe_read_str; +static int (*perf_event_output)(void *, struct bpf_map *, int, void *, unsigned long) = (void *)BPF_FUNC_perf_event_output; + #endif /* _PERF_BPF_H */ diff --git a/tools/perf/include/bpf/stdio.h b/tools/perf/include/bpf/stdio.h index 2899cb7bfed8..316af5b2ff35 100644 --- a/tools/perf/include/bpf/stdio.h +++ b/tools/perf/include/bpf/stdio.h @@ -9,9 +9,6 @@ struct bpf_map SEC("maps") __bpf_stdout__ = { .max_entries = __NR_CPUS__, }; -static int (*perf_event_output)(void *, struct bpf_map *, int, void *, unsigned long) = - (void *)BPF_FUNC_perf_event_output; - #define puts(from) \ ({ const int __len = sizeof(from); \ char __from[__len] = from; \ -- cgit From 27f2992e7bb12ca28e886e48838ba740d2eb95f4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Dec 2018 16:46:13 -0300 Subject: perf augmented_syscalls: Switch to using a struct for the syscalls map values We'll start adding more perf-syscall stuff, so lets do this prep step so that the next ones are just about adding more fields. Run it with the .c file once to cache the .o file: # trace --filter-pids 2834,2199 -e openat,augmented_raw_syscalls.c LLVM: dumping augmented_raw_syscalls.o 0.000 ( 0.021 ms): tmux: server/4952 openat(dfd: CWD, filename: /proc/5691/cmdline ) = 11 349.807 ( 0.040 ms): DNS Res~er #39/11082 openat(dfd: CWD, filename: /etc/hosts, flags: CLOEXEC ) = 44 4988.759 ( 0.052 ms): gsd-color/2431 openat(dfd: CWD, filename: /etc/localtime ) = 18 4988.976 ( 0.029 ms): gsd-color/2431 openat(dfd: CWD, filename: /etc/localtime ) = 18 ^C[root@quaco bpf]# From now on, we can use just the newly built .o file, skipping the compilation step for a faster startup: # trace --filter-pids 2834,2199 -e openat,augmented_raw_syscalls.o 0.000 ( 0.046 ms): DNS Res~er #39/11088 openat(dfd: CWD, filename: /etc/hosts, flags: CLOEXEC ) = 44 1946.408 ( 0.190 ms): systemd/1 openat(dfd: CWD, filename: /proc/1071/cgroup, flags: CLOEXEC ) = 20 1946.792 ( 0.215 ms): systemd/1 openat(dfd: CWD, filename: /proc/954/cgroup, flags: CLOEXEC ) = 20 ^C# Now on to do the same in the builtin-trace.c side of things. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-k8mwu04l8es29rje5loq9vg7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index bb3dcc4ec256..a91c5874433e 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -26,10 +26,14 @@ struct bpf_map SEC("maps") __augmented_syscalls__ = { .max_entries = __NR_CPUS__, }; +struct syscall { + bool enabled; +}; + struct bpf_map SEC("maps") syscalls = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), - .value_size = sizeof(bool), + .value_size = sizeof(struct syscall), .max_entries = 512, }; @@ -63,7 +67,7 @@ int sys_enter(struct syscall_enter_args *args) struct syscall_enter_args args; struct augmented_filename filename; } augmented_args; - bool *enabled; + struct syscall *syscall; unsigned int len = sizeof(augmented_args); const void *filename_arg = NULL; @@ -72,8 +76,8 @@ int sys_enter(struct syscall_enter_args *args) probe_read(&augmented_args.args, sizeof(augmented_args.args), args); - enabled = bpf_map_lookup_elem(&syscalls, &augmented_args.args.syscall_nr); - if (enabled == NULL || !*enabled) + syscall = bpf_map_lookup_elem(&syscalls, &augmented_args.args.syscall_nr); + if (syscall == NULL || !syscall->enabled) return 0; /* * Yonghong and Edward Cree sayz: @@ -144,15 +148,15 @@ SEC("raw_syscalls:sys_exit") int sys_exit(struct syscall_exit_args *args) { struct syscall_exit_args exit_args; - bool *enabled; + struct syscall *syscall; if (pid_filter__has(&pids_filtered, getpid())) return 0; probe_read(&exit_args, sizeof(exit_args), args); - enabled = bpf_map_lookup_elem(&syscalls, &exit_args.syscall_nr); - if (enabled == NULL || !*enabled) + syscall = bpf_map_lookup_elem(&syscalls, &exit_args.syscall_nr); + if (syscall == NULL || !syscall->enabled) return 0; return 1; -- cgit From bbab50dda724309eccec92132d3f36cb262e8728 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Dec 2018 16:54:09 -0300 Subject: perf trace: Switch to using a struct for the aumented_raw_syscalls syscalls map values We'll start adding more perf-syscall stuff, so lets do this prep step so that the next ones are just about adding more fields. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-vac4sn1ns1vj4y07lzj7y4b8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index de81918c7ad4..096380e8c213 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -908,6 +908,10 @@ struct syscall { struct syscall_arg_fmt *arg_fmt; }; +struct bpf_map_syscall_entry { + bool enabled; +}; + /* * We need to have this 'calculated' boolean because in some cases we really * don't know what is the duration of a syscall, for instance, when we start @@ -2583,7 +2587,9 @@ out_enomem: static int trace__set_ev_qualifier_bpf_filter(struct trace *trace) { int fd = bpf_map__fd(trace->syscalls.map); - bool value = !trace->not_ev_qualifier; + struct bpf_map_syscall_entry value = { + .enabled = !trace->not_ev_qualifier, + }; int err = 0; size_t i; @@ -2601,10 +2607,13 @@ static int trace__set_ev_qualifier_bpf_filter(struct trace *trace) static int __trace__init_syscalls_bpf_map(struct trace *trace, bool enabled) { int fd = bpf_map__fd(trace->syscalls.map); + struct bpf_map_syscall_entry value = { + .enabled = enabled, + }; int err = 0, key; for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { - err = bpf_map_update_elem(fd, &key, &enabled, BPF_ANY); + err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); if (err) break; } -- cgit From 43fd56669c28cd354e9228bdb58e4bca1c1a8b66 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:21 +0800 Subject: perf cs-etm: Correct packets swapping in cs_etm__flush() The structure cs_etm_queue uses 'prev_packet' to point to previous packet, this can be used to combine with new coming packet to generate samples. In function cs_etm__flush() it swaps packets only when the flag 'etm->synth_opts.last_branch' is true, this means that it will not swap packets if without option '--itrace=il' to generate last branch entries; thus for this case the 'prev_packet' doesn't point to the correct previous packet and the stale packet still will be used to generate sequential sample. Thus if dump trace with 'perf script' command we can see the incorrect flow with the stale packet's address info. This patch corrects packets swapping in cs_etm__flush(); except using the flag 'etm->synth_opts.last_branch' it also checks the another flag 'etm->sample_branches', if any flag is true then it swaps packets so can save correct content to 'prev_packet'. Finally this can fix the wrong program flow dumping issue. The patch has a minor refactoring to use 'etm->synth_opts.last_branch' instead of 'etmq->etm->synth_opts.last_branch' for condition checking, this is consistent with that is done in cs_etm__sample(). Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-2-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 23159c33db2a..789707bc4e9e 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1042,7 +1042,7 @@ static int cs_etm__flush(struct cs_etm_queue *etmq) } swap_packet: - if (etmq->etm->synth_opts.last_branch) { + if (etm->sample_branches || etm->synth_opts.last_branch) { /* * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for * the next incoming packet. -- cgit From 24fff5eb2b937951af5dce6cdb7a1e679ac8e751 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:22 +0800 Subject: perf cs-etm: Avoid stale branch samples when flush packet At the end of trace buffer handling, function cs_etm__flush() is invoked to flush any remaining branch stack entries. As a side effect, it also generates branch sample, because the 'etmq->packet' doesn't contains any new coming packet but point to one stale packet after packets swapping, so it wrongly makes synthesize branch samples with stale packet info. We could review below detailed flow which causes issue: Packet1: start_addr=0xffff000008b1fbf0 end_addr=0xffff000008b1fbfc Packet2: start_addr=0xffff000008b1fb5c end_addr=0xffff000008b1fb6c step 1: cs_etm__sample(): sample: ip=(0xffff000008b1fbfc-4) addr=0xffff000008b1fb5c step 2: flush packet in cs_etm__run_decoder(): cs_etm__run_decoder() `-> err = cs_etm__flush(etmq, false); sample: ip=(0xffff000008b1fb6c-4) addr=0xffff000008b1fbf0 Packet1 and packet2 are two continuous packets, when packet2 is the new coming packet, cs_etm__sample() generates branch sample for these two packets and use [packet1::end_addr - 4 => packet2::start_addr] as branch jump flow, thus we can see the first generated branch sample in step 1. At the end of cs_etm__sample() it swaps packets so 'etm->prev_packet'= packet2 and 'etm->packet'=packet1, so far it's okay for branch sample. If packet2 is the last one packet in trace buffer, even there have no any new coming packet, cs_etm__run_decoder() invokes cs_etm__flush() to flush branch stack entries as expected, but it also generates branch samples by taking 'etm->packet' as a new coming packet, thus the branch jump flow is as [packet2::end_addr - 4 => packet1::start_addr]; this is the second sample which is generated in step 2. So actually the second sample is a stale sample and we should not generate it. This patch introduces a new function cs_etm__end_block(), at the end of trace block this function is invoked to only flush branch stack entries and thus can avoid to generate branch sample for stale packet. Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-3-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 789707bc4e9e..ffc4fe5c0b7e 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1055,6 +1055,39 @@ swap_packet: return err; } +static int cs_etm__end_block(struct cs_etm_queue *etmq) +{ + int err; + + /* + * It has no new packet coming and 'etmq->packet' contains the stale + * packet which was set at the previous time with packets swapping; + * so skip to generate branch sample to avoid stale packet. + * + * For this case only flush branch stack and generate a last branch + * event for the branches left in the circular buffer at the end of + * the trace. + */ + if (etmq->etm->synth_opts.last_branch && + etmq->prev_packet->sample_type == CS_ETM_RANGE) { + /* + * Use the address of the end of the last reported execution + * range. + */ + u64 addr = cs_etm__last_executed_instr(etmq->prev_packet); + + err = cs_etm__synth_instruction_sample( + etmq, addr, + etmq->period_instructions); + if (err) + return err; + + etmq->period_instructions = 0; + } + + return 0; +} + static int cs_etm__run_decoder(struct cs_etm_queue *etmq) { struct cs_etm_auxtrace *etm = etmq->etm; @@ -1137,7 +1170,7 @@ static int cs_etm__run_decoder(struct cs_etm_queue *etmq) if (err == 0) /* Flush any remaining branch stack entries */ - err = cs_etm__flush(etmq); + err = cs_etm__end_block(etmq); } return err; -- cgit From cee7a6a212ddb514d6e2ac1f9733501c43d63d0a Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:23 +0800 Subject: perf cs-etm: Remove unused 'trace_on' in cs_etm_decoder cs_etm_decoder::trace_on is being assigned when TRACE_ON or NO_SYNC element is coming, but it is never used hence it is redundant and can be removed. So let's remove 'trace_on' field from cs_etm_decoder struct. Suggested-by: Mathieu Poirier Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-4-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 0b4c8629f578..97b39b1f5759 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -36,7 +36,6 @@ struct cs_etm_decoder { void *data; void (*packet_printer)(const char *msg); - bool trace_on; dcd_tree_handle_t dcd_tree; cs_etm_mem_cb_type mem_access; ocsd_datapath_resp_t prev_return; @@ -411,12 +410,10 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( case OCSD_GEN_TRC_ELEM_UNKNOWN: break; case OCSD_GEN_TRC_ELEM_NO_SYNC: - decoder->trace_on = false; break; case OCSD_GEN_TRC_ELEM_TRACE_ON: resp = cs_etm_decoder__buffer_trace_on(decoder, trace_chan_id); - decoder->trace_on = true; break; case OCSD_GEN_TRC_ELEM_INSTR_RANGE: resp = cs_etm_decoder__buffer_range(decoder, elem, -- cgit From cfc1d4276b0453a752d8b31daf34f7f2dbd55e82 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:24 +0800 Subject: perf cs-etm: Refactor enumeration cs_etm_sample_type The values in enumeration cs_etm_sample_type are defined with setting bit N for each packet type, this is not suggested in the usual case. This patch refactor cs_etm_sample_type by converting from bit shifting values to continuous numbers. Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-5-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h index b295dd2b8292..3819a04a2c27 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -23,9 +23,9 @@ struct cs_etm_buffer { }; enum cs_etm_sample_type { - CS_ETM_EMPTY = 0, - CS_ETM_RANGE = 1 << 0, - CS_ETM_TRACE_ON = 1 << 1, + CS_ETM_EMPTY, + CS_ETM_RANGE, + CS_ETM_TRACE_ON, }; enum cs_etm_isa { -- cgit From 49ccf87bfb9e8517ab2f019e95845760c4c3a562 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:25 +0800 Subject: perf cs-etm: Rename CS_ETM_TRACE_ON to CS_ETM_DISCONTINUITY TRACE_ON element is used at the beginning of trace, it also can be appeared in the middle of trace data to indicate discontinuity; for example, it's possible to see multiple TRACE_ON elements in the trace stream if the trace is being limited by address range filtering. Furthermore, except TRACE_ON element is for discontinuity, NO_SYNC and EO_TRACE also can be used to indicate discontinuity, though they are used for different scenarios for which the trace is interrupted. This patch renames sample type CS_ETM_TRACE_ON to CS_ETM_DISCONTINUITY, firstly the new name describes more closely the purpose of the packet; secondly this is a preparation for other output elements which also cause the trace discontinuity thus they can share the same one packet type. Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-6-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 10 +++++----- tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 2 +- tools/perf/util/cs-etm.c | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 97b39b1f5759..1039f364f4cc 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -390,11 +390,11 @@ cs_etm_decoder__buffer_range(struct cs_etm_decoder *decoder, } static ocsd_datapath_resp_t -cs_etm_decoder__buffer_trace_on(struct cs_etm_decoder *decoder, - const uint8_t trace_chan_id) +cs_etm_decoder__buffer_discontinuity(struct cs_etm_decoder *decoder, + const uint8_t trace_chan_id) { return cs_etm_decoder__buffer_packet(decoder, trace_chan_id, - CS_ETM_TRACE_ON); + CS_ETM_DISCONTINUITY); } static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( @@ -412,8 +412,8 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( case OCSD_GEN_TRC_ELEM_NO_SYNC: break; case OCSD_GEN_TRC_ELEM_TRACE_ON: - resp = cs_etm_decoder__buffer_trace_on(decoder, - trace_chan_id); + resp = cs_etm_decoder__buffer_discontinuity(decoder, + trace_chan_id); break; case OCSD_GEN_TRC_ELEM_INSTR_RANGE: resp = cs_etm_decoder__buffer_range(decoder, elem, diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h index 3819a04a2c27..a27231722e27 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -25,7 +25,7 @@ struct cs_etm_buffer { enum cs_etm_sample_type { CS_ETM_EMPTY, CS_ETM_RANGE, - CS_ETM_TRACE_ON, + CS_ETM_DISCONTINUITY, }; enum cs_etm_isa { diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index ffc4fe5c0b7e..cea3158915d3 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -562,8 +562,8 @@ static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq, static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packet) { - /* Returns 0 for the CS_ETM_TRACE_ON packet */ - if (packet->sample_type == CS_ETM_TRACE_ON) + /* Returns 0 for the CS_ETM_DISCONTINUITY packet */ + if (packet->sample_type == CS_ETM_DISCONTINUITY) return 0; return packet->start_addr; @@ -572,8 +572,8 @@ static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packet) static inline u64 cs_etm__last_executed_instr(const struct cs_etm_packet *packet) { - /* Returns 0 for the CS_ETM_TRACE_ON packet */ - if (packet->sample_type == CS_ETM_TRACE_ON) + /* Returns 0 for the CS_ETM_DISCONTINUITY packet */ + if (packet->sample_type == CS_ETM_DISCONTINUITY) return 0; return packet->end_addr - packet->last_instr_size; @@ -972,7 +972,7 @@ static int cs_etm__sample(struct cs_etm_queue *etmq) bool generate_sample = false; /* Generate sample for tracing on packet */ - if (etmq->prev_packet->sample_type == CS_ETM_TRACE_ON) + if (etmq->prev_packet->sample_type == CS_ETM_DISCONTINUITY) generate_sample = true; /* Generate sample for branch taken packet */ @@ -1148,7 +1148,7 @@ static int cs_etm__run_decoder(struct cs_etm_queue *etmq) */ cs_etm__sample(etmq); break; - case CS_ETM_TRACE_ON: + case CS_ETM_DISCONTINUITY: /* * Discontinuity in trace, flush * previous branch stack -- cgit From 37bb37168dc1b1f5e3ac791aeecd14ef980764fd Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:26 +0800 Subject: perf cs-etm: Treat NO_SYNC element as trace discontinuity The CoreSight tracer driver might insert barrier packets between different buffers, thus the decoder can spot the boundaries based on the barrier packet; it is possible for the decoder to hit a barrier packet and emit a NO_SYNC element, then the decoder will find a periodic synchronisation point inside that next trace block that starts the trace again but does not have the TRACE_ON element as indicator - usually because this trace block has wrapped the buffer so we have lost the original point when the trace was enabled. In the first case it causes the insertion of a OCSD_GEN_TRC_ELEM_NO_SYNC in the middle of the tracing stream, but as we were not handling the NO_SYNC element properly this ends up making users miss the discontinuity indications. Though OCSD_GEN_TRC_ELEM_NO_SYNC is different from CS_ETM_TRACE_ON when output from the decoder, both indicate that the trace data is discontinuous; this patch treats OCSD_GEN_TRC_ELEM_NO_SYNC as a trace discontinuity and generates a CS_ETM_DISCONTINUITY packet for it, so cs-etm can handle the discontinuity for this case, finally it saves the last trace data for the previous trace block and restart samples for the new block. Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight ml Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-7-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 1039f364f4cc..bee026e76a4c 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -410,7 +410,6 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( case OCSD_GEN_TRC_ELEM_UNKNOWN: break; case OCSD_GEN_TRC_ELEM_NO_SYNC: - break; case OCSD_GEN_TRC_ELEM_TRACE_ON: resp = cs_etm_decoder__buffer_discontinuity(decoder, trace_chan_id); -- cgit From 02e7e2509e939b50f4f1b14c08b97f60256df3ea Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:27 +0800 Subject: perf cs-etm: Treat EO_TRACE element as trace discontinuity If the decoder outputs an EO_TRACE element, it means the end of the trace buffer; this is a discontinuity and in this case the end of trace data needs to be saved. This patch generates a CS_ETM_DISCONTINUITY packet for the EO_TRACE element hereby flushing the end of trace data in cs-etm.c. Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-8-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index bee026e76a4c..cda6f074bd03 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -409,6 +409,7 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( switch (elem->elem_type) { case OCSD_GEN_TRC_ELEM_UNKNOWN: break; + case OCSD_GEN_TRC_ELEM_EO_TRACE: case OCSD_GEN_TRC_ELEM_NO_SYNC: case OCSD_GEN_TRC_ELEM_TRACE_ON: resp = cs_etm_decoder__buffer_discontinuity(decoder, @@ -425,7 +426,6 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( decoder->packet_buffer[decoder->tail].exc_ret = true; break; case OCSD_GEN_TRC_ELEM_PE_CONTEXT: - case OCSD_GEN_TRC_ELEM_EO_TRACE: case OCSD_GEN_TRC_ELEM_ADDR_NACC: case OCSD_GEN_TRC_ELEM_TIMESTAMP: case OCSD_GEN_TRC_ELEM_CYCLE_COUNT: -- cgit From 7100b12cf474f575658e6e4a834f0e8a0b3c9867 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 11 Dec 2018 15:38:28 +0800 Subject: perf cs-etm: Generate branch sample for exception packet The exception packet appears as one element with 'elem_type' == OCSD_GEN_TRC_ELEM_EXCEPTION or OCSD_GEN_TRC_ELEM_EXCEPTION_RET, which is present for exception entry and exit respectively. The decoder sets the packet fields 'packet->exc' and 'packet->exc_ret' to indicate the exception packets; but exception packets don't have a dedicated sample type and shares the same sample type CS_ETM_RANGE with normal instruction packets. As a result, the exception packets are taken as normal instruction packets and this introduces confusion in mixing different packet types. Furthermore, these instruction range packets will be processed for branch samples only when 'packet->last_instr_taken_branch' is true, otherwise they will be omitted, this can introduce a mess for exception and exception returning due to not having the complete address range info for context switching. To process exception packets properly, this patch introduces two new sample types: CS_ETM_EXCEPTION and CS_ETM_EXCEPTION_RET; these two types of packets will be handled by cs_etm__exception(). The function cs_etm__exception() forces setting the previous CS_ETM_RANGE packet flag 'prev_packet->last_instr_taken_branch' to true, this matches well with the program flow when the exception is trapped from user space to kernel space, no matter if the most recent flow has branch taken or not; this is also safe for returning to user space after exception handling. After exception packets have their own sample type, the packet fields 'packet->exc' and 'packet->exc_ret' aren't needed anymore, so remove them. Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: coresight ml Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-9-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 26 +++++++++++++++++------ tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 4 ++-- tools/perf/util/cs-etm.c | 28 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index cda6f074bd03..8c155575c6c5 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -290,8 +290,6 @@ static void cs_etm_decoder__clear_buffer(struct cs_etm_decoder *decoder) decoder->packet_buffer[i].instr_count = 0; decoder->packet_buffer[i].last_instr_taken_branch = false; decoder->packet_buffer[i].last_instr_size = 0; - decoder->packet_buffer[i].exc = false; - decoder->packet_buffer[i].exc_ret = false; decoder->packet_buffer[i].cpu = INT_MIN; } } @@ -319,8 +317,6 @@ cs_etm_decoder__buffer_packet(struct cs_etm_decoder *decoder, decoder->packet_buffer[et].sample_type = sample_type; decoder->packet_buffer[et].isa = CS_ETM_ISA_UNKNOWN; - decoder->packet_buffer[et].exc = false; - decoder->packet_buffer[et].exc_ret = false; decoder->packet_buffer[et].cpu = *((int *)inode->priv); decoder->packet_buffer[et].start_addr = CS_ETM_INVAL_ADDR; decoder->packet_buffer[et].end_addr = CS_ETM_INVAL_ADDR; @@ -397,6 +393,22 @@ cs_etm_decoder__buffer_discontinuity(struct cs_etm_decoder *decoder, CS_ETM_DISCONTINUITY); } +static ocsd_datapath_resp_t +cs_etm_decoder__buffer_exception(struct cs_etm_decoder *decoder, + const uint8_t trace_chan_id) +{ + return cs_etm_decoder__buffer_packet(decoder, trace_chan_id, + CS_ETM_EXCEPTION); +} + +static ocsd_datapath_resp_t +cs_etm_decoder__buffer_exception_ret(struct cs_etm_decoder *decoder, + const uint8_t trace_chan_id) +{ + return cs_etm_decoder__buffer_packet(decoder, trace_chan_id, + CS_ETM_EXCEPTION_RET); +} + static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( const void *context, const ocsd_trc_index_t indx __maybe_unused, @@ -420,10 +432,12 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer( trace_chan_id); break; case OCSD_GEN_TRC_ELEM_EXCEPTION: - decoder->packet_buffer[decoder->tail].exc = true; + resp = cs_etm_decoder__buffer_exception(decoder, + trace_chan_id); break; case OCSD_GEN_TRC_ELEM_EXCEPTION_RET: - decoder->packet_buffer[decoder->tail].exc_ret = true; + resp = cs_etm_decoder__buffer_exception_ret(decoder, + trace_chan_id); break; case OCSD_GEN_TRC_ELEM_PE_CONTEXT: case OCSD_GEN_TRC_ELEM_ADDR_NACC: diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h index a27231722e27..a6407d41598f 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -26,6 +26,8 @@ enum cs_etm_sample_type { CS_ETM_EMPTY, CS_ETM_RANGE, CS_ETM_DISCONTINUITY, + CS_ETM_EXCEPTION, + CS_ETM_EXCEPTION_RET, }; enum cs_etm_isa { @@ -43,8 +45,6 @@ struct cs_etm_packet { u32 instr_count; u8 last_instr_taken_branch; u8 last_instr_size; - u8 exc; - u8 exc_ret; int cpu; }; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index cea3158915d3..27a374ddf661 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1000,6 +1000,25 @@ static int cs_etm__sample(struct cs_etm_queue *etmq) return 0; } +static int cs_etm__exception(struct cs_etm_queue *etmq) +{ + /* + * When the exception packet is inserted, whether the last instruction + * in previous range packet is taken branch or not, we need to force + * to set 'prev_packet->last_instr_taken_branch' to true. This ensures + * to generate branch sample for the instruction range before the + * exception is trapped to kernel or before the exception returning. + * + * The exception packet includes the dummy address values, so don't + * swap PACKET with PREV_PACKET. This keeps PREV_PACKET to be useful + * for generating instruction and branch samples. + */ + if (etmq->prev_packet->sample_type == CS_ETM_RANGE) + etmq->prev_packet->last_instr_taken_branch = true; + + return 0; +} + static int cs_etm__flush(struct cs_etm_queue *etmq) { int err = 0; @@ -1148,6 +1167,15 @@ static int cs_etm__run_decoder(struct cs_etm_queue *etmq) */ cs_etm__sample(etmq); break; + case CS_ETM_EXCEPTION: + case CS_ETM_EXCEPTION_RET: + /* + * If the exception packet is coming, + * make sure the previous instruction + * range packet to be handled properly. + */ + cs_etm__exception(etmq); + break; case CS_ETM_DISCONTINUITY: /* * Discontinuity in trace, flush -- cgit From 4623ce405d0871e648ba72fdb9c561016e2cc41d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 13 Dec 2018 15:05:43 -0300 Subject: perf augmented_raw_syscalls: Do not include stdio.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're not using that puts() thing, and thus we don't need to define the __bpf_stdout__ map, reducing the setup time. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-3452xgatncpil7v22minkwbo@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index a91c5874433e..6c5db6baeb3a 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -14,7 +14,6 @@ * code that will combine entry/exit in a strace like way. */ -#include #include #include -- cgit From ac96287cae0851797262da37347b83797db931b3 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 13 Dec 2018 17:30:20 -0300 Subject: perf trace: Allow specifying a set of events to add in perfconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To add augmented_raw_syscalls to the events speficied by the user, or be the only one if no events were specified by the user, one can add this to perfconfig: # cat ~/.perfconfig [trace] add_events = /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o # I.e. pre-compile the augmented_raw_syscalls.c BPF program and make it always load, this way: # perf trace -e open* cat /etc/passwd > /dev/null 0.000 ( 0.013 ms): cat/31557 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC) = 3 0.035 ( 0.007 ms): cat/31557 openat(dfd: CWD, filename: /lib64/libc.so.6, flags: CLOEXEC) = 3 0.353 ( 0.009 ms): cat/31557 openat(dfd: CWD, filename: /usr/lib/locale/locale-archive, flags: CLOEXEC) = 3 0.424 ( 0.006 ms): cat/31557 openat(dfd: CWD, filename: /etc/passwd) = 3 # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-0lgj7vh64hg3ce44gsmvj7ud@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 8 ++++++++ tools/perf/builtin-trace.c | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 661b1fb3f8ba..423cb41f6e3f 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -521,6 +521,14 @@ diff.*:: Possible values are 'delta', 'delta-abs', 'ratio' and 'wdiff'. Default is 'delta'. +trace.*:: + trace.add_events:: + Allows adding a set of events to add to the ones specified + by the user, or use as a default one if none was specified. + The initial use case is to add augmented_raw_syscalls.o to + activate the 'perf trace' logic that looks for syscall + pointer contents after the normal tracepoint payload. + SEE ALSO -------- linkperf:perf[1] diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 096380e8c213..d754a74aef46 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -22,6 +22,7 @@ #include "builtin.h" #include "util/cgroup.h" #include "util/color.h" +#include "util/config.h" #include "util/debug.h" #include "util/env.h" #include "util/event.h" @@ -3523,6 +3524,21 @@ static void trace__set_bpf_map_syscalls(struct trace *trace) trace->syscalls.map = bpf__find_map_by_name("syscalls"); } +static int trace__config(const char *var, const char *value, void *arg) +{ + int err = 0; + + if (!strcmp(var, "trace.add_events")) { + struct trace *trace = arg; + struct option o = OPT_CALLBACK('e', "event", &trace->evlist, "event", + "event selector. use 'perf list' to list available events", + parse_events_option); + err = parse_events_option(&o, value, 0); + } + + return err; +} + int cmd_trace(int argc, const char **argv) { const char *trace_usage[] = { @@ -3645,6 +3661,10 @@ int cmd_trace(int argc, const char **argv) goto out; } + err = perf_config(trace__config, &trace); + if (err) + goto out; + argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands, trace_usage, PARSE_OPT_STOP_AT_NON_OPTION); -- cgit From e7c634fcc6ff921d725ba988cdb198ca8b59a39f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 10:12:09 -0300 Subject: perf trace: Allow configuring if zeroed syscall args should be printed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default so far, since we show argument names followed by its values, was to make the output more compact by suppressing most zeroed args. Make this configurable so that users can choose what best suit their needs. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-q0gxws02ygodh94o0hzim5xd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 2 ++ tools/perf/builtin-trace.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 423cb41f6e3f..b55bd16c77fe 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -528,6 +528,8 @@ trace.*:: The initial use case is to add augmented_raw_syscalls.o to activate the 'perf trace' logic that looks for syscall pointer contents after the normal tracepoint payload. + trace.show_zeros:: + Do not suppress syscall arguments that are equal to zero. SEE ALSO -------- diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d754a74aef46..4d97bdac205c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -127,6 +127,7 @@ struct trace { bool show_tool_stats; bool trace_syscalls; bool kernel_syscallchains; + bool show_zeros; bool force; bool vfs_getname; int trace_pgfaults; @@ -1598,6 +1599,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, * strarray for it. */ if (val == 0 && + !trace->show_zeros && !(sc->arg_fmt && (sc->arg_fmt[arg.idx].show_zero || sc->arg_fmt[arg.idx].scnprintf == SCA_STRARRAY || @@ -3526,14 +3528,16 @@ static void trace__set_bpf_map_syscalls(struct trace *trace) static int trace__config(const char *var, const char *value, void *arg) { + struct trace *trace = arg; int err = 0; if (!strcmp(var, "trace.add_events")) { - struct trace *trace = arg; struct option o = OPT_CALLBACK('e', "event", &trace->evlist, "event", "event selector. use 'perf list' to list available events", parse_events_option); err = parse_events_option(&o, value, 0); + } else if (!strcmp(var, "trace.show_zeros")) { + trace->show_zeros = perf_config_bool(var, value); } return err; -- cgit From 42e4a52d01d087e7ce069049799e3e336eaec101 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 10:22:18 -0300 Subject: perf trace: Allow configuring if the syscall duration should be printed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # perf config trace.show_duration=no # perf config -l | grep trace trace.default_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o trace.show_zeros=true trace.show_duration=no # trace -e *sleep sleep 1 0.000 sleep/8729 nanosleep(rqtp: 0x7ffcb0b4c940, rmtp: 0) = 0 # perf config trace.show_duration=yes # trace -e *sleep sleep 1 0.000 (1000.212 ms): sleep/8735 nanosleep(rqtp: 0x7ffca15fa770, rmtp: 0) = 0 # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-2c7h1m8fhzb9puxtj9nlevi8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 4 ++++ tools/perf/builtin-trace.c | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index b55bd16c77fe..0d641b0d15ae 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -528,6 +528,10 @@ trace.*:: The initial use case is to add augmented_raw_syscalls.o to activate the 'perf trace' logic that looks for syscall pointer contents after the normal tracepoint payload. + + trace.show_duration:: + Show syscall duration. + trace.show_zeros:: Do not suppress syscall arguments that are equal to zero. diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4d97bdac205c..4355dadad232 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -127,6 +127,7 @@ struct trace { bool show_tool_stats; bool trace_syscalls; bool kernel_syscallchains; + bool show_duration; bool show_zeros; bool force; bool vfs_getname; @@ -1215,7 +1216,8 @@ static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thre u64 duration, bool duration_calculated, u64 tstamp, FILE *fp) { size_t printed = trace__fprintf_tstamp(trace, tstamp, fp); - printed += fprintf_duration(duration, duration_calculated, fp); + if (trace->show_duration) + printed += fprintf_duration(duration, duration_calculated, fp); return printed + trace__fprintf_comm_tid(trace, thread, fp); } @@ -2190,7 +2192,7 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, trace__printf_interrupted_entry(trace); trace__fprintf_tstamp(trace, sample->time, trace->output); - if (trace->trace_syscalls) + if (trace->trace_syscalls && trace->show_duration) fprintf(trace->output, "( ): "); if (thread) @@ -3536,6 +3538,8 @@ static int trace__config(const char *var, const char *value, void *arg) "event selector. use 'perf list' to list available events", parse_events_option); err = parse_events_option(&o, value, 0); + } else if (!strcmp(var, "trace.show_duration")) { + trace->show_duration = perf_config_bool(var, value); } else if (!strcmp(var, "trace.show_zeros")) { trace->show_zeros = perf_config_bool(var, value); } @@ -3568,6 +3572,7 @@ int cmd_trace(int argc, const char **argv) }, .output = stderr, .show_comm = true, + .show_duration = true, .trace_syscalls = false, .kernel_syscallchains = false, .max_stack = UINT_MAX, -- cgit From 41e0d040c475251eea14c8b92ea3a01c5e269856 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 10:29:44 -0300 Subject: perf config: Show the configuration when no arguments are provided MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More convenient thah having to recall what letter is about showing/listing/dumping the configuration, i.e. no arguments means -l/--list: # perf config llvm.dump-obj=true trace.default_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o trace.show_zeros=yes trace.show_duration=no # perf config -l llvm.dump-obj=true trace.default_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o trace.show_zeros=yes trace.show_duration=no # perf config -h Usage: perf config [] [options] [section.name[=value] ...] -l, --list show current config variables --system use system config file --user use user config file # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Taeung Song Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-z2n63avz6tliqb5gmu4l1dti@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-config.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 514f70f95b57..d76f831f94c7 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -196,6 +196,7 @@ int cmd_config(int argc, const char **argv) pr_err("Error: takes no arguments\n"); parse_options_usage(config_usage, config_options, "l", 1); } else { +do_action_list: if (show_config(set) < 0) { pr_err("Nothing configured, " "please check your %s \n", config_filename); @@ -204,10 +205,8 @@ int cmd_config(int argc, const char **argv) } break; default: - if (!argc) { - usage_with_options(config_usage, config_options); - break; - } + if (!argc) + goto do_action_list; for (i = 0; argv[i]; i++) { char *var, *value; -- cgit From d32de87e734191698dd1834146ee65ebd0f5e240 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 11:06:16 -0300 Subject: perf trace: Allow configuring default for perf_event_attr.inherit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I.f. if children should inherit the parent perf_event configuration, i.e. if we should trace children as well or just the parent. The default is to follow children, to disable this and have a behaviour similar to strace, set this config option or use the --no_inherit 'perf trace' option. E.g.: Default: # perf config trace.no_inherit # trace -e clone,*sleep time sleep 1 0.000 time/21107 clone(clone_flags: CHILD_CLEARTID|CHILD_SETTID|0x11, newsp: 0, child_tidptr: 0x7f7b8f9ae810) = 21108 (time) ? time/21108 ... [continued]: clone() 0.691 sleep/21108 nanosleep(rqtp: 0x7ffed01d0540, rmtp: 0 ) = 0 0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 1988maxresident)k 0inputs+0outputs (0major+76minor)pagefaults 0swaps # Disable it: # trace -e clone,*sleep time sleep 1 0.000 clone(clone_flags: CHILD_CLEARTID|CHILD_SETTID|0x11, newsp: 0, child_tidptr: 0x7ff41e100810) = 21414 (time) 0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 1964maxresident)k 0inputs+0outputs (0major+76minor)pagefaults 0swaps # Notice that since there is just one thread, the "comm/TID" column is suppressed. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-thd8s16pagyza71ufi5vjlan@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 3 +++ tools/perf/builtin-trace.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 0d641b0d15ae..cd9bf12fb255 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -529,6 +529,9 @@ trace.*:: activate the 'perf trace' logic that looks for syscall pointer contents after the normal tracepoint payload. + trace.no_inherit:: + Do not follow children threads. + trace.show_duration:: Show syscall duration. diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4355dadad232..a4e2290e57e0 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3542,6 +3542,8 @@ static int trace__config(const char *var, const char *value, void *arg) trace->show_duration = perf_config_bool(var, value); } else if (!strcmp(var, "trace.show_zeros")) { trace->show_zeros = perf_config_bool(var, value); + } else if (!strcmp(var, "trace.no_inherit")) { + trace->opts.no_inherit = perf_config_bool(var, value); } return err; -- cgit From b036146fd0f99209e87877115d090c69da2ab747 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 11:17:19 -0300 Subject: perf trace: Allow configuring if the syscall start timestamp should be printed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # trace -e open*,close,*sleep sleep 1 0.000 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC ) = 3 0.016 close(fd: 3 ) = 0 0.024 openat(dfd: CWD, filename: /lib64/libc.so.6, flags: CLOEXEC ) = 3 0.074 close(fd: 3 ) = 0 0.235 openat(dfd: CWD, filename: /usr/lib/locale/locale-archive, flags: CLOEXEC) = 3 0.251 close(fd: 3 ) = 0 0.285 nanosleep(rqtp: 0x7ffd68e6d620, rmtp: 0 ) = 0 1000.386 close(fd: 1 ) = 0 1000.395 close(fd: 2 ) = 0 # # perf config trace.show_timestamp=no # trace -e open*,close,*sleep sleep 1 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC ) = 3 close(fd: 3 ) = 0 openat(dfd: CWD, filename: /lib64/libc.so.6, flags: CLOEXEC ) = 3 close(fd: 3 ) = 0 openat(dfd: CWD, filename: , flags: CLOEXEC ) = 3 close(fd: 3 ) = 0 nanosleep(rqtp: 0x7fffa79c38e0, rmtp: 0 ) = 0 close(fd: 1 ) = 0 close(fd: 2 ) = 0 # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-mjjnicy48367jah6ls4k0nk8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 3 +++ tools/perf/builtin-trace.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index cd9bf12fb255..ecd1e9514925 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -535,6 +535,9 @@ trace.*:: trace.show_duration:: Show syscall duration. + trace.show_timestamp:: + Show syscall start timestamp. + trace.show_zeros:: Do not suppress syscall arguments that are equal to zero. diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a4e2290e57e0..e978ce034863 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -127,6 +127,7 @@ struct trace { bool show_tool_stats; bool trace_syscalls; bool kernel_syscallchains; + bool show_tstamp; bool show_duration; bool show_zeros; bool force; @@ -1215,7 +1216,10 @@ static size_t trace__fprintf_comm_tid(struct trace *trace, struct thread *thread static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread, u64 duration, bool duration_calculated, u64 tstamp, FILE *fp) { - size_t printed = trace__fprintf_tstamp(trace, tstamp, fp); + size_t printed = 0; + + if (trace->show_tstamp) + printed = trace__fprintf_tstamp(trace, tstamp, fp); if (trace->show_duration) printed += fprintf_duration(duration, duration_calculated, fp); return printed + trace__fprintf_comm_tid(trace, thread, fp); @@ -3538,6 +3542,8 @@ static int trace__config(const char *var, const char *value, void *arg) "event selector. use 'perf list' to list available events", parse_events_option); err = parse_events_option(&o, value, 0); + } else if (!strcmp(var, "trace.show_timestamp")) { + trace->show_tstamp = perf_config_bool(var, value); } else if (!strcmp(var, "trace.show_duration")) { trace->show_duration = perf_config_bool(var, value); } else if (!strcmp(var, "trace.show_zeros")) { @@ -3574,6 +3580,7 @@ int cmd_trace(int argc, const char **argv) }, .output = stderr, .show_comm = true, + .show_tstamp = true, .show_duration = true, .trace_syscalls = false, .kernel_syscallchains = false, -- cgit From 9d6dc178f0c9e40e61f45d2ac86baa8ad77cb052 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 11:32:02 -0300 Subject: perf trace: Allow suppressing the syscall argument names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To show just the values: Default: # trace -e open*,close,*sleep sleep 1 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC ) = 3 close(fd: 3 ) = 0 openat(dfd: CWD, filename: /lib64/libc.so.6, flags: CLOEXEC ) = 3 close(fd: 3 ) = 0 openat(dfd: CWD, filename: /usr/lib/locale/locale-archive, flags: CLOEXEC) = 3 close(fd: 3 ) = 0 nanosleep(rqtp: 0x7ffc0c4ea0d0, rmtp: 0 ) = 0 close(fd: 1 ) = 0 close(fd: 2 ) = 0 # Remove it: # perf config trace.show_arg_names=no # trace -e open*,close,*sleep sleep 1 openat(CWD, /etc/ld.so.cache, CLOEXEC ) = 3 close(3 ) = 0 openat(CWD, /lib64/libc.so.6, CLOEXEC ) = 3 close(3 ) = 0 openat(CWD, /usr/lib/locale/locale-archive, CLOEXEC ) = 3 close(3 ) = 0 nanosleep(0x7ffced3a8c40, 0 ) = 0 close(1 ) = 0 close(2 ) = 0 # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-ta9tbdwgodpw719sr2bjm8eb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 4 ++++ tools/perf/builtin-trace.c | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index ecd1e9514925..35108fd61fa6 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -532,6 +532,10 @@ trace.*:: trace.no_inherit:: Do not follow children threads. + trace.show_arg_names:: + Should syscall argument names be printed? If not then trace.show_zeros + will be set. + trace.show_duration:: Show syscall duration. diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index e978ce034863..95dfcb851604 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -130,6 +130,7 @@ struct trace { bool show_tstamp; bool show_duration; bool show_zeros; + bool show_arg_names; bool force; bool vfs_getname; int trace_pgfaults; @@ -1613,8 +1614,11 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, sc->arg_fmt[arg.idx].parm)) continue; - printed += scnprintf(bf + printed, size - printed, - "%s%s: ", printed ? ", " : "", field->name); + printed += scnprintf(bf + printed, size - printed, "%s", printed ? ", " : ""); + + if (trace->show_arg_names) + printed += scnprintf(bf + printed, size - printed, "%s: ", field->name); + printed += syscall__scnprintf_val(sc, bf + printed, size - printed, &arg, val); } } else if (IS_ERR(sc->tp_format)) { @@ -3546,12 +3550,21 @@ static int trace__config(const char *var, const char *value, void *arg) trace->show_tstamp = perf_config_bool(var, value); } else if (!strcmp(var, "trace.show_duration")) { trace->show_duration = perf_config_bool(var, value); + } else if (!strcmp(var, "trace.show_arg_names")) { + trace->show_arg_names = perf_config_bool(var, value); + if (!trace->show_arg_names) + trace->show_zeros = true; } else if (!strcmp(var, "trace.show_zeros")) { - trace->show_zeros = perf_config_bool(var, value); + bool new_show_zeros = perf_config_bool(var, value); + if (!trace->show_arg_names && !new_show_zeros) { + pr_warning("trace.show_zeros has to be set when trace.show_arg_names=no\n"); + goto out; + } + trace->show_zeros = new_show_zeros; } else if (!strcmp(var, "trace.no_inherit")) { trace->opts.no_inherit = perf_config_bool(var, value); } - +out: return err; } @@ -3582,6 +3595,7 @@ int cmd_trace(int argc, const char **argv) .show_comm = true, .show_tstamp = true, .show_duration = true, + .show_arg_names = true, .trace_syscalls = false, .kernel_syscallchains = false, .max_stack = UINT_MAX, -- cgit From 9ed45d59aeae2211933b032acc4e5b40a1a2fcd3 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 13:40:49 -0300 Subject: perf trace: Make the alignment of the syscall args be configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the start 'perf trace' aligns the parens enclosing the list of syscall args to align the syscall results, allow this to be configurable, keeping the default of 70. Using: # perf config llvm.dump-obj=true trace.add_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o trace.show_zeros=yes trace.show_duration=no trace.no_inherit=yes trace.show_timestamp=no trace.show_arg_names=no trace.args_alignment=0 # trace -e open*,close,*sleep sleep 1 openat(CWD, /etc/ld.so.cache, CLOEXEC) = 3 close(3) = 0 openat(CWD, /lib64/libc.so.6, CLOEXEC) = 3 close(3) = 0 openat(CWD, /usr/lib/locale/locale-archive, CLOEXEC) = 3 close(3) = 0 nanosleep(0x7ffc00de66f0, 0) = 0 close(1) = 0 close(2) = 0 # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-r8cbhoz1lr5npq9tutpvoigr@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 4 ++++ tools/perf/builtin-trace.c | 12 +++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 35108fd61fa6..0098eab8e5b1 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -529,6 +529,10 @@ trace.*:: activate the 'perf trace' logic that looks for syscall pointer contents after the normal tracepoint payload. + trace.args_alignment:: + Number of columns to align the argument list, default is 70, + use 40 for the strace default, zero to no alignment. + trace.no_inherit:: Do not follow children threads. diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 95dfcb851604..2d8fd48a4727 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -127,6 +127,7 @@ struct trace { bool show_tool_stats; bool trace_syscalls; bool kernel_syscallchains; + s16 args_alignment; bool show_tstamp; bool show_duration; bool show_zeros; @@ -1731,7 +1732,7 @@ static int trace__printf_interrupted_entry(struct trace *trace) return 0; printed = trace__fprintf_entry_head(trace, trace->current, 0, false, ttrace->entry_time, trace->output); - printed += fprintf(trace->output, "%-70s) ...\n", ttrace->entry_str); + printed += fprintf(trace->output, "%-*s) ...\n", trace->args_alignment, ttrace->entry_str); ttrace->entry_pending = false; ++trace->nr_events_printed; @@ -1838,7 +1839,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, if (sc->is_exit) { if (!(trace->duration_filter || trace->summary_only || trace->failure_only || trace->min_stack)) { trace__fprintf_entry_head(trace, thread, 0, false, ttrace->entry_time, trace->output); - fprintf(trace->output, "%-70s)\n", ttrace->entry_str); + fprintf(trace->output, "%-*s)\n", trace->args_alignment, ttrace->entry_str); } } else { ttrace->entry_pending = true; @@ -1981,7 +1982,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, trace__fprintf_entry_head(trace, thread, duration, duration_calculated, ttrace->entry_time, trace->output); if (ttrace->entry_pending) { - fprintf(trace->output, "%-70s", ttrace->entry_str); + fprintf(trace->output, "%-*s", trace->args_alignment, ttrace->entry_str); } else { fprintf(trace->output, " ... ["); color_fprintf(trace->output, PERF_COLOR_YELLOW, "continued"); @@ -3563,6 +3564,10 @@ static int trace__config(const char *var, const char *value, void *arg) trace->show_zeros = new_show_zeros; } else if (!strcmp(var, "trace.no_inherit")) { trace->opts.no_inherit = perf_config_bool(var, value); + } else if (!strcmp(var, "trace.args_alignment")) { + int args_alignment = 0; + if (perf_config_int(&args_alignment, var, value) == 0) + trace->args_alignment = args_alignment; } out: return err; @@ -3596,6 +3601,7 @@ int cmd_trace(int argc, const char **argv) .show_tstamp = true, .show_duration = true, .show_arg_names = true, + .args_alignment = 70, .trace_syscalls = false, .kernel_syscallchains = false, .max_stack = UINT_MAX, -- cgit From 721f5326fb35dcba18ee4d9ef2b32394f86d403e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 14:02:03 -0300 Subject: perf trace: Enclose strings with double quotes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To match 'strace' output, helping with upcoming regression tests comparing both outputs. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-jab52t1dcuh6vlztqle9g7u9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2d8fd48a4727..dc8cadeb3fa5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1149,7 +1149,7 @@ static size_t syscall_arg__scnprintf_augmented_string(struct syscall_arg *arg, c { struct augmented_arg *augmented_arg = arg->augmented.args; - return scnprintf(bf, size, "%.*s", augmented_arg->size, augmented_arg->value); + return scnprintf(bf, size, "\"%.*s\"", augmented_arg->size, augmented_arg->value); } static size_t syscall_arg__scnprintf_filename(char *bf, size_t size, -- cgit From 2e3d7fac9db5e80d1cc26bb1453b85245c26d657 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 15:08:40 -0300 Subject: perf trace: Add a prefix member to the strarray class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that the user, in an upcoming patch, can select printing it to get the full string as used in the source code, not one with a common prefix chopped off so as to make the output more compact. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-zypczc88gzbmeqx7b372s138@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 21 +++++++++++---------- tools/perf/trace/beauty/beauty.h | 7 +++++-- tools/perf/trace/beauty/fcntl.c | 2 +- tools/perf/trace/beauty/ioctl.c | 16 ++++++++-------- tools/perf/trace/beauty/kcmp.c | 2 +- tools/perf/trace/beauty/mmap.c | 4 ++-- tools/perf/trace/beauty/mount_flags.c | 2 +- tools/perf/trace/beauty/pkey_alloc.c | 2 +- tools/perf/trace/beauty/prctl.c | 4 ++-- tools/perf/trace/beauty/renameat.c | 2 +- tools/perf/trace/beauty/sockaddr.c | 2 +- tools/perf/trace/beauty/socket.c | 2 +- 12 files changed, 35 insertions(+), 31 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index dc8cadeb3fa5..02bc5da5cfa7 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -423,6 +423,7 @@ static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size, struct syscall_arg *arg) { int fd = arg->val; + /* char fd_at_prefix = "AT_FD"; */ if (fd == AT_FDCWD) return scnprintf(bf, size, "CWD"); @@ -456,13 +457,13 @@ static const char *bpf_cmd[] = { "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM", "MAP_GET_NEXT_KEY", "PROG_LOAD", }; -static DEFINE_STRARRAY(bpf_cmd); +static DEFINE_STRARRAY(bpf_cmd, "BPF_"); static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", }; -static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1); +static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, "EPOLL_CTL_", 1); static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", }; -static DEFINE_STRARRAY(itimers); +static DEFINE_STRARRAY(itimers, "ITIMER_"); static const char *keyctl_options[] = { "GET_KEYRING_ID", "JOIN_SESSION_KEYRING", "UPDATE", "REVOKE", "CHOWN", @@ -471,7 +472,7 @@ static const char *keyctl_options[] = { "ASSUME_AUTHORITY", "GET_SECURITY", "SESSION_TO_PARENT", "REJECT", "INSTANTIATE_IOV", "INVALIDATE", "GET_PERSISTENT", }; -static DEFINE_STRARRAY(keyctl_options); +static DEFINE_STRARRAY(keyctl_options, "KEYCTL_"); static const char *whences[] = { "SET", "CUR", "END", #ifdef SEEK_DATA @@ -481,7 +482,7 @@ static const char *whences[] = { "SET", "CUR", "END", "HOLE", #endif }; -static DEFINE_STRARRAY(whences); +static DEFINE_STRARRAY(whences, "SEEK_"); static const char *fcntl_cmds[] = { "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK", @@ -489,7 +490,7 @@ static const char *fcntl_cmds[] = { "SETLK64", "SETLKW64", "SETOWN_EX", "GETOWN_EX", "GETOWNER_UIDS", }; -static DEFINE_STRARRAY(fcntl_cmds); +static DEFINE_STRARRAY(fcntl_cmds, "F_"); static const char *fcntl_linux_specific_cmds[] = { "SETLEASE", "GETLEASE", "NOTIFY", [5] = "CANCELLK", "DUPFD_CLOEXEC", @@ -497,7 +498,7 @@ static const char *fcntl_linux_specific_cmds[] = { "GET_RW_HINT", "SET_RW_HINT", "GET_FILE_RW_HINT", "SET_FILE_RW_HINT", }; -static DEFINE_STRARRAY_OFFSET(fcntl_linux_specific_cmds, F_LINUX_SPECIFIC_BASE); +static DEFINE_STRARRAY_OFFSET(fcntl_linux_specific_cmds, "F_", F_LINUX_SPECIFIC_BASE); static struct strarray *fcntl_cmds_arrays[] = { &strarray__fcntl_cmds, @@ -511,17 +512,17 @@ static const char *rlimit_resources[] = { "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO", "RTTIME", }; -static DEFINE_STRARRAY(rlimit_resources); +static DEFINE_STRARRAY(rlimit_resources, "RLIMIT_"); static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", }; -static DEFINE_STRARRAY(sighow); +static DEFINE_STRARRAY(sighow, "SIG_"); static const char *clockid[] = { "REALTIME", "MONOTONIC", "PROCESS_CPUTIME_ID", "THREAD_CPUTIME_ID", "MONOTONIC_RAW", "REALTIME_COARSE", "MONOTONIC_COARSE", "BOOTTIME", "REALTIME_ALARM", "BOOTTIME_ALARM", "SGI_CYCLE", "TAI" }; -static DEFINE_STRARRAY(clockid); +static DEFINE_STRARRAY(clockid, "CLOCK_"); static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size, struct syscall_arg *arg) diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 48ff3ce05325..452e9c006d4f 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -9,18 +9,21 @@ struct strarray { int offset; int nr_entries; + const char *prefix; const char **entries; }; -#define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \ +#define DEFINE_STRARRAY(array, _prefix) struct strarray strarray__##array = { \ .nr_entries = ARRAY_SIZE(array), \ .entries = array, \ + .prefix = _prefix, \ } -#define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \ +#define DEFINE_STRARRAY_OFFSET(array, _prefix, off) struct strarray strarray__##array = { \ .offset = off, \ .nr_entries = ARRAY_SIZE(array), \ .entries = array, \ + .prefix = _prefix, \ } size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val); diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c index e6de31674e24..15d669087e0a 100644 --- a/tools/perf/trace/beauty/fcntl.c +++ b/tools/perf/trace/beauty/fcntl.c @@ -22,7 +22,7 @@ static size_t syscall_arg__scnprintf_fcntl_getfd(char *bf, size_t size, struct s static size_t fcntl__scnprintf_getlease(unsigned long val, char *bf, size_t size) { static const char *fcntl_setlease[] = { "RDLCK", "WRLCK", "UNLCK", }; - static DEFINE_STRARRAY(fcntl_setlease); + static DEFINE_STRARRAY(fcntl_setlease, "F_"); return strarray__scnprintf(&strarray__fcntl_setlease, bf, size, "%x", val); } diff --git a/tools/perf/trace/beauty/ioctl.c b/tools/perf/trace/beauty/ioctl.c index eae59ad15ce3..ea243f6167d7 100644 --- a/tools/perf/trace/beauty/ioctl.c +++ b/tools/perf/trace/beauty/ioctl.c @@ -36,7 +36,7 @@ static size_t ioctl__scnprintf_tty_cmd(int nr, int dir, char *bf, size_t size) "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS", "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI", "TIOCMIWAIT", "TIOCGICOUNT", }; - static DEFINE_STRARRAY(ioctl_tty_cmd); + static DEFINE_STRARRAY(ioctl_tty_cmd, ""); if (nr < strarray__ioctl_tty_cmd.nr_entries && strarray__ioctl_tty_cmd.entries[nr] != NULL) return scnprintf(bf, size, "%s", strarray__ioctl_tty_cmd.entries[nr]); @@ -47,7 +47,7 @@ static size_t ioctl__scnprintf_tty_cmd(int nr, int dir, char *bf, size_t size) static size_t ioctl__scnprintf_drm_cmd(int nr, int dir, char *bf, size_t size) { #include "trace/beauty/generated/ioctl/drm_ioctl_array.c" - static DEFINE_STRARRAY(drm_ioctl_cmds); + static DEFINE_STRARRAY(drm_ioctl_cmds, ""); if (nr < strarray__drm_ioctl_cmds.nr_entries && strarray__drm_ioctl_cmds.entries[nr] != NULL) return scnprintf(bf, size, "DRM_%s", strarray__drm_ioctl_cmds.entries[nr]); @@ -58,7 +58,7 @@ static size_t ioctl__scnprintf_drm_cmd(int nr, int dir, char *bf, size_t size) static size_t ioctl__scnprintf_sndrv_pcm_cmd(int nr, int dir, char *bf, size_t size) { #include "trace/beauty/generated/ioctl/sndrv_pcm_ioctl_array.c" - static DEFINE_STRARRAY(sndrv_pcm_ioctl_cmds); + static DEFINE_STRARRAY(sndrv_pcm_ioctl_cmds, ""); if (nr < strarray__sndrv_pcm_ioctl_cmds.nr_entries && strarray__sndrv_pcm_ioctl_cmds.entries[nr] != NULL) return scnprintf(bf, size, "SNDRV_PCM_%s", strarray__sndrv_pcm_ioctl_cmds.entries[nr]); @@ -69,7 +69,7 @@ static size_t ioctl__scnprintf_sndrv_pcm_cmd(int nr, int dir, char *bf, size_t s static size_t ioctl__scnprintf_sndrv_ctl_cmd(int nr, int dir, char *bf, size_t size) { #include "trace/beauty/generated/ioctl/sndrv_ctl_ioctl_array.c" - static DEFINE_STRARRAY(sndrv_ctl_ioctl_cmds); + static DEFINE_STRARRAY(sndrv_ctl_ioctl_cmds, ""); if (nr < strarray__sndrv_ctl_ioctl_cmds.nr_entries && strarray__sndrv_ctl_ioctl_cmds.entries[nr] != NULL) return scnprintf(bf, size, "SNDRV_CTL_%s", strarray__sndrv_ctl_ioctl_cmds.entries[nr]); @@ -80,7 +80,7 @@ static size_t ioctl__scnprintf_sndrv_ctl_cmd(int nr, int dir, char *bf, size_t s static size_t ioctl__scnprintf_kvm_cmd(int nr, int dir, char *bf, size_t size) { #include "trace/beauty/generated/ioctl/kvm_ioctl_array.c" - static DEFINE_STRARRAY(kvm_ioctl_cmds); + static DEFINE_STRARRAY(kvm_ioctl_cmds, ""); if (nr < strarray__kvm_ioctl_cmds.nr_entries && strarray__kvm_ioctl_cmds.entries[nr] != NULL) return scnprintf(bf, size, "KVM_%s", strarray__kvm_ioctl_cmds.entries[nr]); @@ -91,8 +91,8 @@ static size_t ioctl__scnprintf_kvm_cmd(int nr, int dir, char *bf, size_t size) static size_t ioctl__scnprintf_vhost_virtio_cmd(int nr, int dir, char *bf, size_t size) { #include "trace/beauty/generated/ioctl/vhost_virtio_ioctl_array.c" - static DEFINE_STRARRAY(vhost_virtio_ioctl_cmds); - static DEFINE_STRARRAY(vhost_virtio_ioctl_read_cmds); + static DEFINE_STRARRAY(vhost_virtio_ioctl_cmds, ""); + static DEFINE_STRARRAY(vhost_virtio_ioctl_read_cmds, ""); struct strarray *s = (dir & _IOC_READ) ? &strarray__vhost_virtio_ioctl_read_cmds : &strarray__vhost_virtio_ioctl_cmds; if (nr < s->nr_entries && s->entries[nr] != NULL) @@ -104,7 +104,7 @@ static size_t ioctl__scnprintf_vhost_virtio_cmd(int nr, int dir, char *bf, size_ static size_t ioctl__scnprintf_perf_cmd(int nr, int dir, char *bf, size_t size) { #include "trace/beauty/generated/ioctl/perf_ioctl_array.c" - static DEFINE_STRARRAY(perf_ioctl_cmds); + static DEFINE_STRARRAY(perf_ioctl_cmds, ""); if (nr < strarray__perf_ioctl_cmds.nr_entries && strarray__perf_ioctl_cmds.entries[nr] != NULL) return scnprintf(bf, size, "PERF_%s", strarray__perf_ioctl_cmds.entries[nr]); diff --git a/tools/perf/trace/beauty/kcmp.c b/tools/perf/trace/beauty/kcmp.c index b276a274f203..56f1e50a6012 100644 --- a/tools/perf/trace/beauty/kcmp.c +++ b/tools/perf/trace/beauty/kcmp.c @@ -28,7 +28,7 @@ size_t syscall_arg__scnprintf_kcmp_idx(char *bf, size_t size, struct syscall_arg static size_t kcmp__scnprintf_type(int type, char *bf, size_t size) { - static DEFINE_STRARRAY(kcmp_types); + static DEFINE_STRARRAY(kcmp_types, "KCMP_"); return strarray__scnprintf(&strarray__kcmp_types, bf, size, "%d", type); } diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index c534bd96ef5c..1a7bd716057a 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c @@ -34,7 +34,7 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, static size_t mmap__scnprintf_flags(unsigned long flags, char *bf, size_t size) { #include "trace/beauty/generated/mmap_flags_array.c" - static DEFINE_STRARRAY(mmap_flags); + static DEFINE_STRARRAY(mmap_flags, "MAP_"); return strarray__scnprintf_flags(&strarray__mmap_flags, bf, size, flags); } @@ -78,7 +78,7 @@ static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size, static size_t madvise__scnprintf_behavior(int behavior, char *bf, size_t size) { #include "trace/beauty/generated/madvise_behavior_array.c" - static DEFINE_STRARRAY(madvise_advices); + static DEFINE_STRARRAY(madvise_advices, "MADV_"); if (behavior < strarray__madvise_advices.nr_entries && strarray__madvise_advices.entries[behavior] != NULL) return scnprintf(bf, size, "MADV_%s", strarray__madvise_advices.entries[behavior]); diff --git a/tools/perf/trace/beauty/mount_flags.c b/tools/perf/trace/beauty/mount_flags.c index 712935c6620a..7129106bf797 100644 --- a/tools/perf/trace/beauty/mount_flags.c +++ b/tools/perf/trace/beauty/mount_flags.c @@ -14,7 +14,7 @@ static size_t mount__scnprintf_flags(unsigned long flags, char *bf, size_t size) { #include "trace/beauty/generated/mount_flags_array.c" - static DEFINE_STRARRAY(mount_flags); + static DEFINE_STRARRAY(mount_flags, "MS_"); return strarray__scnprintf_flags(&strarray__mount_flags, bf, size, flags); } diff --git a/tools/perf/trace/beauty/pkey_alloc.c b/tools/perf/trace/beauty/pkey_alloc.c index 1b8ed4cac815..f4818e05a48b 100644 --- a/tools/perf/trace/beauty/pkey_alloc.c +++ b/tools/perf/trace/beauty/pkey_alloc.c @@ -41,7 +41,7 @@ size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, uns static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, size_t size) { #include "trace/beauty/generated/pkey_alloc_access_rights_array.c" - static DEFINE_STRARRAY(pkey_alloc_access_rights); + static DEFINE_STRARRAY(pkey_alloc_access_rights, "PKEY_"); return strarray__scnprintf_flags(&strarray__pkey_alloc_access_rights, bf, size, access_rights); } diff --git a/tools/perf/trace/beauty/prctl.c b/tools/perf/trace/beauty/prctl.c index be7a5d395975..7b6466b0856d 100644 --- a/tools/perf/trace/beauty/prctl.c +++ b/tools/perf/trace/beauty/prctl.c @@ -13,13 +13,13 @@ static size_t prctl__scnprintf_option(int option, char *bf, size_t size) { - static DEFINE_STRARRAY(prctl_options); + static DEFINE_STRARRAY(prctl_options, "PR_"); return strarray__scnprintf(&strarray__prctl_options, bf, size, "%d", option); } static size_t prctl__scnprintf_set_mm(int option, char *bf, size_t size) { - static DEFINE_STRARRAY(prctl_set_mm_options); + static DEFINE_STRARRAY(prctl_set_mm_options, "PR_SET_MM_"); return strarray__scnprintf(&strarray__prctl_set_mm_options, bf, size, "%d", option); } diff --git a/tools/perf/trace/beauty/renameat.c b/tools/perf/trace/beauty/renameat.c index 02c7207faee6..910695aff979 100644 --- a/tools/perf/trace/beauty/renameat.c +++ b/tools/perf/trace/beauty/renameat.c @@ -7,7 +7,7 @@ static size_t renameat2__scnprintf_flags(unsigned long flags, char *bf, size_t size) { #include "trace/beauty/generated/rename_flags_array.c" - static DEFINE_STRARRAY(rename_flags); + static DEFINE_STRARRAY(rename_flags, "RENAME_"); return strarray__scnprintf_flags(&strarray__rename_flags, bf, size, flags); } diff --git a/tools/perf/trace/beauty/sockaddr.c b/tools/perf/trace/beauty/sockaddr.c index 9410ad230f10..95cc82a9967f 100644 --- a/tools/perf/trace/beauty/sockaddr.c +++ b/tools/perf/trace/beauty/sockaddr.c @@ -15,7 +15,7 @@ static const char *socket_families[] = { "BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF", "ALG", "NFC", "VSOCK", }; -DEFINE_STRARRAY(socket_families); +DEFINE_STRARRAY(socket_families, "PF_"); static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size) { diff --git a/tools/perf/trace/beauty/socket.c b/tools/perf/trace/beauty/socket.c index d971a2596417..eacbfb930fe4 100644 --- a/tools/perf/trace/beauty/socket.c +++ b/tools/perf/trace/beauty/socket.c @@ -12,7 +12,7 @@ static size_t socket__scnprintf_ipproto(int protocol, char *bf, size_t size) { #include "trace/beauty/generated/socket_ipproto_array.c" - static DEFINE_STRARRAY(socket_ipproto); + static DEFINE_STRARRAY(socket_ipproto, "IPPROTO_"); return strarray__scnprintf(&strarray__socket_ipproto, bf, size, "%d", protocol); } -- cgit From c65c83ffe904590162bd762be185ac4d53ce5a85 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Dec 2018 17:06:47 -0300 Subject: perf trace: Allow asking for not suppressing common string prefixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far we've been suppressing common stuff such as "MAP_" in the mmap flags, showing "SHARED" instead of "MAP_SHARED", allow for those prefixes (and a few suffixes) to be shown: # trace -e *map,open*,*seek sleep 1 openat("/etc/ld.so.cache", CLOEXEC) = 3 mmap(0, 109093, READ, PRIVATE, 3, 0) = 0x7ff61c695000 openat("/lib64/libc.so.6", CLOEXEC) = 3 lseek(3, 792, SET) = 792 mmap(0, 8192, READ|WRITE, PRIVATE|ANONYMOUS) = 0x7ff61c693000 lseek(3, 792, SET) = 792 lseek(3, 864, SET) = 864 mmap(0, 1857568, READ, PRIVATE|DENYWRITE, 3, 0) = 0x7ff61c4cd000 mmap(0x7ff61c4ef000, 1363968, EXEC|READ, PRIVATE|FIXED|DENYWRITE, 3, 139264) = 0x7ff61c4ef000 mmap(0x7ff61c63c000, 311296, READ, PRIVATE|FIXED|DENYWRITE, 3, 1503232) = 0x7ff61c63c000 mmap(0x7ff61c689000, 24576, READ|WRITE, PRIVATE|FIXED|DENYWRITE, 3, 1814528) = 0x7ff61c689000 mmap(0x7ff61c68f000, 14368, READ|WRITE, PRIVATE|FIXED|ANONYMOUS) = 0x7ff61c68f000 munmap(0x7ff61c695000, 109093) = 0 openat("/usr/lib/locale/locale-archive", CLOEXEC) = 3 mmap(0, 217749968, READ, PRIVATE, 3, 0) = 0x7ff60f523000 # # vim ~/.perfconfig # # perf config llvm.dump-obj=true trace.add_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o trace.show_zeros=yes trace.show_duration=no trace.no_inherit=yes trace.show_timestamp=no trace.show_arg_names=no trace.args_alignment=0 trace.string_quote=" trace.show_prefix=yes # # # trace -e *map,open*,*seek sleep 1 openat(AT_FDCWD, "/etc/ld.so.cache", O_CLOEXEC) = 3 mmap(0, 109093, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7ebbe59000 openat(AT_FDCWD, "/lib64/libc.so.6", O_CLOEXEC) = 3 lseek(3, 792, SEEK_SET) = 792 mmap(0, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS) = 0x7f7ebbe57000 lseek(3, 792, SEEK_SET) = 792 lseek(3, 864, SEEK_SET) = 864 mmap(0, 1857568, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7ebbc91000 mmap(0x7f7ebbcb3000, 1363968, PROT_EXEC|PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 139264) = 0x7f7ebbcb3000 mmap(0x7f7ebbe00000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 1503232) = 0x7f7ebbe00000 mmap(0x7f7ebbe4d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 1814528) = 0x7f7ebbe4d000 mmap(0x7f7ebbe53000, 14368, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS) = 0x7f7ebbe53000 munmap(0x7f7ebbe59000, 109093) = 0 openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_CLOEXEC) = 3 mmap(0, 217749968, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7eaece7000 # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-mtn1i4rjowjl72trtnbmvjd4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 4 ++++ tools/perf/builtin-trace.c | 30 ++++++++++++++++++++---------- tools/perf/trace/beauty/beauty.h | 8 +++++--- tools/perf/trace/beauty/clone.c | 7 ++++--- tools/perf/trace/beauty/eventfd.c | 4 +++- tools/perf/trace/beauty/fcntl.c | 20 +++++++++++--------- tools/perf/trace/beauty/flock.c | 4 +++- tools/perf/trace/beauty/futex_op.c | 8 +++++--- tools/perf/trace/beauty/futex_val3.c | 3 ++- tools/perf/trace/beauty/ioctl.c | 15 +++++++++------ tools/perf/trace/beauty/kcmp.c | 6 +++--- tools/perf/trace/beauty/mmap.c | 16 ++++++++++------ tools/perf/trace/beauty/mode_t.c | 4 +++- tools/perf/trace/beauty/mount_flags.c | 6 +++--- tools/perf/trace/beauty/msg_flags.c | 4 +++- tools/perf/trace/beauty/open_flags.c | 11 ++++++----- tools/perf/trace/beauty/perf_event_open.c | 4 +++- tools/perf/trace/beauty/pkey_alloc.c | 12 ++++++------ tools/perf/trace/beauty/prctl.c | 12 ++++++------ tools/perf/trace/beauty/renameat.c | 6 +++--- tools/perf/trace/beauty/sched_policy.c | 6 ++++-- tools/perf/trace/beauty/seccomp.c | 8 ++++++-- tools/perf/trace/beauty/signum.c | 4 +++- tools/perf/trace/beauty/sockaddr.c | 2 +- tools/perf/trace/beauty/socket.c | 6 +++--- tools/perf/trace/beauty/socket_type.c | 4 +++- tools/perf/trace/beauty/statx.c | 10 +++++++--- tools/perf/trace/beauty/waitid_options.c | 4 +++- 28 files changed, 142 insertions(+), 86 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 0098eab8e5b1..4ac7775fbc11 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -543,6 +543,10 @@ trace.*:: trace.show_duration:: Show syscall duration. + trace.show_prefix:: + If set to 'yes' will show common string prefixes in tables. The default + is to remove the common prefix in things like "MAP_SHARED", showing just "SHARED". + trace.show_timestamp:: Show syscall start timestamp. diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 02bc5da5cfa7..8a176ab2bd8e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -132,6 +132,7 @@ struct trace { bool show_duration; bool show_zeros; bool show_arg_names; + bool show_string_prefix; bool force; bool vfs_getname; int trace_pgfaults; @@ -360,21 +361,21 @@ out_delete: ({ struct syscall_tp *fields = evsel->priv; \ fields->name.pointer(&fields->name, sample); }) -size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val) +size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, bool show_prefix, int val) { int idx = val - sa->offset; if (idx < 0 || idx >= sa->nr_entries || sa->entries[idx] == NULL) return scnprintf(bf, size, intfmt, val); - return scnprintf(bf, size, "%s", sa->entries[idx]); + return scnprintf(bf, size, "%s%s", show_prefix ? sa->prefix : "", sa->entries[idx]); } static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size, const char *intfmt, struct syscall_arg *arg) { - return strarray__scnprintf(arg->parm, bf, size, intfmt, arg->val); + return strarray__scnprintf(arg->parm, bf, size, intfmt, arg->show_string_prefix, arg->val); } static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, @@ -408,7 +409,7 @@ size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, if (idx >= 0 && idx < sa->nr_entries) { if (sa->entries[idx] == NULL) break; - return scnprintf(bf, size, "%s", sa->entries[idx]); + return scnprintf(bf, size, "%s%s", arg->show_string_prefix ? sa->prefix : "", sa->entries[idx]); } } @@ -423,10 +424,10 @@ static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size, struct syscall_arg *arg) { int fd = arg->val; - /* char fd_at_prefix = "AT_FD"; */ + const char *prefix = "AT_FD"; if (fd == AT_FDCWD) - return scnprintf(bf, size, "CWD"); + return scnprintf(bf, size, "%s%s", arg->show_string_prefix ? prefix : "", "CWD"); return syscall_arg__scnprintf_fd(bf, size, arg); } @@ -527,14 +528,16 @@ static DEFINE_STRARRAY(clockid, "CLOCK_"); static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *suffix = "_OK"; size_t printed = 0; int mode = arg->val; if (mode == F_OK) /* 0 */ - return scnprintf(bf, size, "F"); + return scnprintf(bf, size, "F%s", show_prefix ? suffix : ""); #define P_MODE(n) \ if (mode & n##_OK) { \ - printed += scnprintf(bf + printed, size - printed, "%s", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s", #n, show_prefix ? suffix : ""); \ mode &= ~n##_OK; \ } @@ -559,11 +562,13 @@ static size_t syscall_arg__scnprintf_filename(char *bf, size_t size, static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "O_"; int printed = 0, flags = arg->val; #define P_FLAG(n) \ if (flags & O_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~O_##n; \ } @@ -589,11 +594,13 @@ static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "GRND_"; int printed = 0, flags = arg->val; #define P_FLAG(n) \ if (flags & GRND_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~GRND_##n; \ } @@ -1577,6 +1584,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, .mask = 0, .trace = trace, .thread = thread, + .show_string_prefix = trace->show_string_prefix, }; struct thread_trace *ttrace = thread__priv(thread); @@ -3563,6 +3571,8 @@ static int trace__config(const char *var, const char *value, void *arg) goto out; } trace->show_zeros = new_show_zeros; + } else if (!strcmp(var, "trace.show_prefix")) { + trace->show_string_prefix = perf_config_bool(var, value); } else if (!strcmp(var, "trace.no_inherit")) { trace->opts.no_inherit = perf_config_bool(var, value); } else if (!strcmp(var, "trace.args_alignment")) { diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 452e9c006d4f..ac25b6410bc8 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -26,8 +26,8 @@ struct strarray { .prefix = _prefix, \ } -size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val); -size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, unsigned long flags); +size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, bool show_prefix, int val); +size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, bool show_prefix, unsigned long flags); struct trace; struct thread; @@ -69,6 +69,7 @@ struct augmented_arg { * @parm: private area, may be an strarray, for instance * @idx: syscall arg idx (is this the first?) * @mask: a syscall arg may mask another arg, see syscall_arg__scnprintf_futex_op + * @show_string_prefix: When there is a common prefix in a string table, show it or not */ struct syscall_arg { @@ -83,6 +84,7 @@ struct syscall_arg { void *parm; u8 idx; u8 mask; + bool show_string_prefix; }; unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx); @@ -162,7 +164,7 @@ size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_ size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_MASK syscall_arg__scnprintf_statx_mask -size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size); +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix); void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg)); diff --git a/tools/perf/trace/beauty/clone.c b/tools/perf/trace/beauty/clone.c index 010406500c30..6eb9a6636171 100644 --- a/tools/perf/trace/beauty/clone.c +++ b/tools/perf/trace/beauty/clone.c @@ -10,13 +10,14 @@ #include #include -static size_t clone__scnprintf_flags(unsigned long flags, char *bf, size_t size) +static size_t clone__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix) { + const char *prefix = "CLONE_"; int printed = 0; #define P_FLAG(n) \ if (flags & CLONE_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~CLONE_##n; \ } @@ -70,5 +71,5 @@ size_t syscall_arg__scnprintf_clone_flags(char *bf, size_t size, struct syscall_ if (!(flags & CLONE_SETTLS)) arg->mask |= SCC_TLS; - return clone__scnprintf_flags(flags, bf, size); + return clone__scnprintf_flags(flags, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/eventfd.c b/tools/perf/trace/beauty/eventfd.c index db5b9b492113..4bab106213c6 100644 --- a/tools/perf/trace/beauty/eventfd.c +++ b/tools/perf/trace/beauty/eventfd.c @@ -13,13 +13,15 @@ static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "EFD_"; int printed = 0, flags = arg->val; if (flags == 0) return scnprintf(bf, size, "NONE"); #define P_FLAG(n) \ if (flags & EFD_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~EFD_##n; \ } diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c index 15d669087e0a..56ef83b3d130 100644 --- a/tools/perf/trace/beauty/fcntl.c +++ b/tools/perf/trace/beauty/fcntl.c @@ -9,27 +9,28 @@ #include #include -static size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size) +static size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size, bool show_prefix) { - return scnprintf(bf, size, "%s", val ? "CLOEXEC" : "0"); + return val ? scnprintf(bf, size, "%s", "0") : + scnprintf(bf, size, "%s%s", show_prefix ? "FD_" : "", "CLOEXEC"); } static size_t syscall_arg__scnprintf_fcntl_getfd(char *bf, size_t size, struct syscall_arg *arg) { - return fcntl__scnprintf_getfd(arg->val, bf, size); + return fcntl__scnprintf_getfd(arg->val, bf, size, arg->show_string_prefix); } -static size_t fcntl__scnprintf_getlease(unsigned long val, char *bf, size_t size) +static size_t fcntl__scnprintf_getlease(unsigned long val, char *bf, size_t size, bool show_prefix) { static const char *fcntl_setlease[] = { "RDLCK", "WRLCK", "UNLCK", }; static DEFINE_STRARRAY(fcntl_setlease, "F_"); - return strarray__scnprintf(&strarray__fcntl_setlease, bf, size, "%x", val); + return strarray__scnprintf(&strarray__fcntl_setlease, bf, size, "%x", show_prefix, val); } static size_t syscall_arg__scnprintf_fcntl_getlease(char *bf, size_t size, struct syscall_arg *arg) { - return fcntl__scnprintf_getlease(arg->val, bf, size); + return fcntl__scnprintf_getlease(arg->val, bf, size, arg->show_string_prefix); } size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg) @@ -68,22 +69,23 @@ out: size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; int cmd = syscall_arg__val(arg, 1); if (cmd == F_DUPFD) return syscall_arg__scnprintf_fd(bf, size, arg); if (cmd == F_SETFD) - return fcntl__scnprintf_getfd(arg->val, bf, size); + return fcntl__scnprintf_getfd(arg->val, bf, size, show_prefix); if (cmd == F_SETFL) - return open__scnprintf_flags(arg->val, bf, size); + return open__scnprintf_flags(arg->val, bf, size, show_prefix); if (cmd == F_SETOWN) return syscall_arg__scnprintf_pid(bf, size, arg); if (cmd == F_SETLEASE) - return fcntl__scnprintf_getlease(arg->val, bf, size); + return fcntl__scnprintf_getlease(arg->val, bf, size, show_prefix); /* * We still don't grab the contents of pointers on entry or exit, * so just print them as hex numbers diff --git a/tools/perf/trace/beauty/flock.c b/tools/perf/trace/beauty/flock.c index cf02ae5f0ba6..c14274edd6d9 100644 --- a/tools/perf/trace/beauty/flock.c +++ b/tools/perf/trace/beauty/flock.c @@ -22,13 +22,15 @@ size_t syscall_arg__scnprintf_flock(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "LOCK_"; int printed = 0, op = arg->val; if (op == 0) return scnprintf(bf, size, "NONE"); #define P_CMD(cmd) \ if ((op & LOCK_##cmd) == LOCK_##cmd) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #cmd); \ op &= ~LOCK_##cmd; \ } diff --git a/tools/perf/trace/beauty/futex_op.c b/tools/perf/trace/beauty/futex_op.c index 1136bde56406..00365156782b 100644 --- a/tools/perf/trace/beauty/futex_op.c +++ b/tools/perf/trace/beauty/futex_op.c @@ -19,6 +19,8 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "FUTEX_"; enum syscall_futex_args { SCF_UADDR = (1 << 0), SCF_OP = (1 << 1), @@ -32,7 +34,7 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc size_t printed = 0; switch (cmd) { -#define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n); +#define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", #n); P_FUTEX_OP(WAIT); arg->mask |= SCF_VAL3|SCF_UADDR2; break; P_FUTEX_OP(WAKE); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; P_FUTEX_OP(FD); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; @@ -50,10 +52,10 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc } if (op & FUTEX_PRIVATE_FLAG) - printed += scnprintf(bf + printed, size - printed, "|PRIV"); + printed += scnprintf(bf + printed, size - printed, "|%s%s", show_prefix ? prefix : "", "PRIVATE_FLAG"); if (op & FUTEX_CLOCK_REALTIME) - printed += scnprintf(bf + printed, size - printed, "|CLKRT"); + printed += scnprintf(bf + printed, size - printed, "|%s%s", show_prefix ? prefix : "", "CLOCK_REALTIME"); return printed; } diff --git a/tools/perf/trace/beauty/futex_val3.c b/tools/perf/trace/beauty/futex_val3.c index 138b7d588a70..9114f7620571 100644 --- a/tools/perf/trace/beauty/futex_val3.c +++ b/tools/perf/trace/beauty/futex_val3.c @@ -7,10 +7,11 @@ static size_t syscall_arg__scnprintf_futex_val3(char *bf, size_t size, struct syscall_arg *arg) { + const char *prefix = "FUTEX_BITSET_"; unsigned int bitset = arg->val; if (bitset == FUTEX_BITSET_MATCH_ANY) - return scnprintf(bf, size, "MATCH_ANY"); + return scnprintf(bf, size, "%s%s", arg->show_string_prefix ? prefix : "", "MATCH_ANY"); return scnprintf(bf, size, "%#xd", bitset); } diff --git a/tools/perf/trace/beauty/ioctl.c b/tools/perf/trace/beauty/ioctl.c index ea243f6167d7..9efeb6a936c2 100644 --- a/tools/perf/trace/beauty/ioctl.c +++ b/tools/perf/trace/beauty/ioctl.c @@ -112,8 +112,9 @@ static size_t ioctl__scnprintf_perf_cmd(int nr, int dir, char *bf, size_t size) return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAE, nr, dir); } -static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size) +static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size, bool show_prefix) { + const char *prefix = "_IOC_"; int dir = _IOC_DIR(cmd), type = _IOC_TYPE(cmd), nr = _IOC_NR(cmd), @@ -143,12 +144,14 @@ static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size) printed += scnprintf(bf + printed, size - printed, "%c", '('); if (dir == _IOC_NONE) { - printed += scnprintf(bf + printed, size - printed, "%s", "NONE"); + printed += scnprintf(bf + printed, size - printed, "%s%s", show_prefix ? prefix : "", "NONE"); } else { if (dir & _IOC_READ) - printed += scnprintf(bf + printed, size - printed, "%s", "READ"); - if (dir & _IOC_WRITE) - printed += scnprintf(bf + printed, size - printed, "%s%s", dir & _IOC_READ ? "|" : "", "WRITE"); + printed += scnprintf(bf + printed, size - printed, "%s%s", show_prefix ? prefix : "", "READ"); + if (dir & _IOC_WRITE) { + printed += scnprintf(bf + printed, size - printed, "%s%s%s", dir & _IOC_READ ? "|" : "", + show_prefix ? prefix : "", "WRITE"); + } } return printed + scnprintf(bf + printed, size - printed, ", %#x, %#x, %#x)", type, nr, sz); @@ -158,5 +161,5 @@ size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_ar { unsigned long cmd = arg->val; - return ioctl__scnprintf_cmd(cmd, bf, size); + return ioctl__scnprintf_cmd(cmd, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/kcmp.c b/tools/perf/trace/beauty/kcmp.c index 56f1e50a6012..9351f84390a1 100644 --- a/tools/perf/trace/beauty/kcmp.c +++ b/tools/perf/trace/beauty/kcmp.c @@ -26,10 +26,10 @@ size_t syscall_arg__scnprintf_kcmp_idx(char *bf, size_t size, struct syscall_arg return pid__scnprintf_fd(arg->trace, pid, fd, bf, size); } -static size_t kcmp__scnprintf_type(int type, char *bf, size_t size) +static size_t kcmp__scnprintf_type(int type, char *bf, size_t size, bool show_prefix) { static DEFINE_STRARRAY(kcmp_types, "KCMP_"); - return strarray__scnprintf(&strarray__kcmp_types, bf, size, "%d", type); + return strarray__scnprintf(&strarray__kcmp_types, bf, size, "%d", show_prefix, type); } size_t syscall_arg__scnprintf_kcmp_type(char *bf, size_t size, struct syscall_arg *arg) @@ -39,5 +39,5 @@ size_t syscall_arg__scnprintf_kcmp_type(char *bf, size_t size, struct syscall_ar if (type != KCMP_FILE) arg->mask |= (1 << 3) | (1 << 4); /* Ignore idx1 and idx2 */ - return kcmp__scnprintf_type(type, bf, size); + return kcmp__scnprintf_type(type, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index 1a7bd716057a..138f36a47fb1 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c @@ -5,13 +5,15 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, struct syscall_arg *arg) { + const char *prot_prefix = "PROT_"; int printed = 0, prot = arg->val; + bool show_prefix = arg->show_string_prefix; if (prot == PROT_NONE) - return scnprintf(bf, size, "NONE"); + return scnprintf(bf, size, "%sNONE", show_prefix ? prot_prefix : ""); #define P_MMAP_PROT(n) \ if (prot & PROT_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prot_prefix :"", #n); \ prot &= ~PROT_##n; \ } @@ -31,12 +33,12 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, #define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot -static size_t mmap__scnprintf_flags(unsigned long flags, char *bf, size_t size) +static size_t mmap__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix) { #include "trace/beauty/generated/mmap_flags_array.c" static DEFINE_STRARRAY(mmap_flags, "MAP_"); - return strarray__scnprintf_flags(&strarray__mmap_flags, bf, size, flags); + return strarray__scnprintf_flags(&strarray__mmap_flags, bf, size, show_prefix, flags); } static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, @@ -47,7 +49,7 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, if (flags & MAP_ANONYMOUS) arg->mask |= (1 << 4) | (1 << 5); /* Mask 4th ('fd') and 5th ('offset') args, ignored */ - return mmap__scnprintf_flags(flags, bf, size); + return mmap__scnprintf_flags(flags, bf, size, arg->show_string_prefix); } #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags @@ -55,11 +57,13 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size, struct syscall_arg *arg) { + const char *flags_prefix = "MREMAP_"; + bool show_prefix = arg->show_string_prefix; int printed = 0, flags = arg->val; #define P_MREMAP_FLAG(n) \ if (flags & MREMAP_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? flags_prefix : "", #n); \ flags &= ~MREMAP_##n; \ } diff --git a/tools/perf/trace/beauty/mode_t.c b/tools/perf/trace/beauty/mode_t.c index 6879d36d3004..29a8fadfb7f9 100644 --- a/tools/perf/trace/beauty/mode_t.c +++ b/tools/perf/trace/beauty/mode_t.c @@ -22,11 +22,13 @@ static size_t syscall_arg__scnprintf_mode_t(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "S_"; int printed = 0, mode = arg->val; #define P_MODE(n) \ if ((mode & S_##n) == S_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ mode &= ~S_##n; \ } diff --git a/tools/perf/trace/beauty/mount_flags.c b/tools/perf/trace/beauty/mount_flags.c index 7129106bf797..10fb14cfaf8f 100644 --- a/tools/perf/trace/beauty/mount_flags.c +++ b/tools/perf/trace/beauty/mount_flags.c @@ -11,12 +11,12 @@ #include #include -static size_t mount__scnprintf_flags(unsigned long flags, char *bf, size_t size) +static size_t mount__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix) { #include "trace/beauty/generated/mount_flags_array.c" static DEFINE_STRARRAY(mount_flags, "MS_"); - return strarray__scnprintf_flags(&strarray__mount_flags, bf, size, flags); + return strarray__scnprintf_flags(&strarray__mount_flags, bf, size, show_prefix, flags); } unsigned long syscall_arg__mask_val_mount_flags(struct syscall_arg *arg __maybe_unused, unsigned long flags) @@ -39,5 +39,5 @@ size_t syscall_arg__scnprintf_mount_flags(char *bf, size_t size, struct syscall_ { unsigned long flags = arg->val; - return mount__scnprintf_flags(flags, bf, size); + return mount__scnprintf_flags(flags, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/msg_flags.c b/tools/perf/trace/beauty/msg_flags.c index 1b9d6306d274..d66c66315987 100644 --- a/tools/perf/trace/beauty/msg_flags.c +++ b/tools/perf/trace/beauty/msg_flags.c @@ -21,13 +21,15 @@ static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "MSG_"; int printed = 0, flags = arg->val; if (flags == 0) return scnprintf(bf, size, "NONE"); #define P_MSG_FLAG(n) \ if (flags & MSG_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~MSG_##n; \ } diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index cc673fec9184..6da48893a1bb 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -22,15 +22,16 @@ #undef O_LARGEFILE #define O_LARGEFILE 00100000 -size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix) { + const char *prefix = "O_"; int printed = 0; if (flags == 0) - return scnprintf(bf, size, "RDONLY"); + return scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", "RDONLY"); #define P_FLAG(n) \ if (flags & O_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~O_##n; \ } @@ -57,7 +58,7 @@ size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) #endif #ifdef O_DSYNC if ((flags & O_SYNC) == O_SYNC) - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC"); + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", "SYNC"); else { P_FLAG(DSYNC); } @@ -81,5 +82,5 @@ size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_a if (!(flags & O_CREAT)) arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ - return open__scnprintf_flags(flags, bf, size); + return open__scnprintf_flags(flags, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/perf_event_open.c b/tools/perf/trace/beauty/perf_event_open.c index 981185c1974b..11d47dbe63bd 100644 --- a/tools/perf/trace/beauty/perf_event_open.c +++ b/tools/perf/trace/beauty/perf_event_open.c @@ -18,6 +18,8 @@ static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "PERF_"; int printed = 0, flags = arg->val; if (flags == 0) @@ -25,7 +27,7 @@ static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size, #define P_FLAG(n) \ if (flags & PERF_FLAG_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~PERF_FLAG_##n; \ } diff --git a/tools/perf/trace/beauty/pkey_alloc.c b/tools/perf/trace/beauty/pkey_alloc.c index f4818e05a48b..f9596ed02cc4 100644 --- a/tools/perf/trace/beauty/pkey_alloc.c +++ b/tools/perf/trace/beauty/pkey_alloc.c @@ -9,14 +9,14 @@ #include #include -size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, unsigned long flags) +size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, bool show_prefix, unsigned long flags) { int i, printed = 0; if (flags == 0) { const char *s = sa->entries[0]; if (s) - return scnprintf(bf, size, "%s", s); + return scnprintf(bf, size, "%s%s", show_prefix ? sa->prefix : "", s); return scnprintf(bf, size, "%d", 0); } @@ -30,7 +30,7 @@ size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, uns printed += scnprintf(bf + printed, size - printed, "|"); if (sa->entries[i] != NULL) - printed += scnprintf(bf + printed, size - printed, "%s", sa->entries[i]); + printed += scnprintf(bf + printed, size - printed, "%s%s", show_prefix ? sa->prefix : "", sa->entries[i]); else printed += scnprintf(bf + printed, size - printed, "0x%#", bit); } @@ -38,17 +38,17 @@ size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, uns return printed; } -static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, size_t size) +static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, size_t size, bool show_prefix) { #include "trace/beauty/generated/pkey_alloc_access_rights_array.c" static DEFINE_STRARRAY(pkey_alloc_access_rights, "PKEY_"); - return strarray__scnprintf_flags(&strarray__pkey_alloc_access_rights, bf, size, access_rights); + return strarray__scnprintf_flags(&strarray__pkey_alloc_access_rights, bf, size, show_prefix, access_rights); } size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg) { unsigned long cmd = arg->val; - return pkey_alloc__scnprintf_access_rights(cmd, bf, size); + return pkey_alloc__scnprintf_access_rights(cmd, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/prctl.c b/tools/perf/trace/beauty/prctl.c index 7b6466b0856d..ba2179abed00 100644 --- a/tools/perf/trace/beauty/prctl.c +++ b/tools/perf/trace/beauty/prctl.c @@ -11,16 +11,16 @@ #include "trace/beauty/generated/prctl_option_array.c" -static size_t prctl__scnprintf_option(int option, char *bf, size_t size) +static size_t prctl__scnprintf_option(int option, char *bf, size_t size, bool show_prefix) { static DEFINE_STRARRAY(prctl_options, "PR_"); - return strarray__scnprintf(&strarray__prctl_options, bf, size, "%d", option); + return strarray__scnprintf(&strarray__prctl_options, bf, size, "%d", show_prefix, option); } -static size_t prctl__scnprintf_set_mm(int option, char *bf, size_t size) +static size_t prctl__scnprintf_set_mm(int option, char *bf, size_t size, bool show_prefix) { static DEFINE_STRARRAY(prctl_set_mm_options, "PR_SET_MM_"); - return strarray__scnprintf(&strarray__prctl_set_mm_options, bf, size, "%d", option); + return strarray__scnprintf(&strarray__prctl_set_mm_options, bf, size, "%d", show_prefix, option); } size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_arg *arg) @@ -28,7 +28,7 @@ size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_a int option = syscall_arg__val(arg, 0); if (option == PR_SET_MM) - return prctl__scnprintf_set_mm(arg->val, bf, size); + return prctl__scnprintf_set_mm(arg->val, bf, size, arg->show_string_prefix); /* * We still don't grab the contents of pointers on entry or exit, * so just print them as hex numbers @@ -77,5 +77,5 @@ size_t syscall_arg__scnprintf_prctl_option(char *bf, size_t size, struct syscall if (option < ARRAY_SIZE(masks)) arg->mask |= masks[option]; - return prctl__scnprintf_option(option, bf, size); + return prctl__scnprintf_option(option, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/renameat.c b/tools/perf/trace/beauty/renameat.c index 910695aff979..6dab340cc506 100644 --- a/tools/perf/trace/beauty/renameat.c +++ b/tools/perf/trace/beauty/renameat.c @@ -4,16 +4,16 @@ #include "trace/beauty/beauty.h" #include -static size_t renameat2__scnprintf_flags(unsigned long flags, char *bf, size_t size) +static size_t renameat2__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix) { #include "trace/beauty/generated/rename_flags_array.c" static DEFINE_STRARRAY(rename_flags, "RENAME_"); - return strarray__scnprintf_flags(&strarray__rename_flags, bf, size, flags); + return strarray__scnprintf_flags(&strarray__rename_flags, bf, size, show_prefix, flags); } size_t syscall_arg__scnprintf_renameat2_flags(char *bf, size_t size, struct syscall_arg *arg) { unsigned long flags = arg->val; - return renameat2__scnprintf_flags(flags, bf, size); + return renameat2__scnprintf_flags(flags, bf, size, arg->show_string_prefix); } diff --git a/tools/perf/trace/beauty/sched_policy.c b/tools/perf/trace/beauty/sched_policy.c index 48f2b5c9aa3e..68aa59eeed8d 100644 --- a/tools/perf/trace/beauty/sched_policy.c +++ b/tools/perf/trace/beauty/sched_policy.c @@ -17,6 +17,8 @@ static size_t syscall_arg__scnprintf_sched_policy(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "SCHED_"; const char *policies[] = { "NORMAL", "FIFO", "RR", "BATCH", "ISO", "IDLE", "DEADLINE", }; @@ -26,13 +28,13 @@ static size_t syscall_arg__scnprintf_sched_policy(char *bf, size_t size, policy &= SCHED_POLICY_MASK; if (policy <= SCHED_DEADLINE) - printed = scnprintf(bf, size, "%s", policies[policy]); + printed = scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", policies[policy]); else printed = scnprintf(bf, size, "%#x", policy); #define P_POLICY_FLAG(n) \ if (flags & SCHED_##n) { \ - printed += scnprintf(bf + printed, size - printed, "|%s", #n); \ + printed += scnprintf(bf + printed, size - printed, "|%s%s", show_prefix ? prefix : "", #n); \ flags &= ~SCHED_##n; \ } diff --git a/tools/perf/trace/beauty/seccomp.c b/tools/perf/trace/beauty/seccomp.c index e36156b19c70..4600c28a3cfe 100644 --- a/tools/perf/trace/beauty/seccomp.c +++ b/tools/perf/trace/beauty/seccomp.c @@ -8,11 +8,13 @@ static size_t syscall_arg__scnprintf_seccomp_op(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "SECOMP_SET_MODE_"; int op = arg->val; size_t printed = 0; switch (op) { -#define P_SECCOMP_SET_MODE_OP(n) case SECCOMP_SET_MODE_##n: printed = scnprintf(bf, size, #n); break +#define P_SECCOMP_SET_MODE_OP(n) case SECCOMP_SET_MODE_##n: printed = scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", #n); break P_SECCOMP_SET_MODE_OP(STRICT); P_SECCOMP_SET_MODE_OP(FILTER); #undef P_SECCOMP_SET_MODE_OP @@ -31,11 +33,13 @@ static size_t syscall_arg__scnprintf_seccomp_op(char *bf, size_t size, struct sy static size_t syscall_arg__scnprintf_seccomp_flags(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "SECOMP_FILTER_FLAG_"; int printed = 0, flags = arg->val; #define P_FLAG(n) \ if (flags & SECCOMP_FILTER_FLAG_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~SECCOMP_FILTER_FLAG_##n; \ } diff --git a/tools/perf/trace/beauty/signum.c b/tools/perf/trace/beauty/signum.c index 587fec545b8a..21220c56500a 100644 --- a/tools/perf/trace/beauty/signum.c +++ b/tools/perf/trace/beauty/signum.c @@ -3,10 +3,12 @@ static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "SIG"; int sig = arg->val; switch (sig) { -#define P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n) +#define P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", #n) P_SIGNUM(HUP); P_SIGNUM(INT); P_SIGNUM(QUIT); diff --git a/tools/perf/trace/beauty/sockaddr.c b/tools/perf/trace/beauty/sockaddr.c index 95cc82a9967f..173c8f760763 100644 --- a/tools/perf/trace/beauty/sockaddr.c +++ b/tools/perf/trace/beauty/sockaddr.c @@ -58,7 +58,7 @@ static size_t syscall_arg__scnprintf_augmented_sockaddr(struct syscall_arg *arg, char family[32]; size_t printed; - strarray__scnprintf(&strarray__socket_families, family, sizeof(family), "%d", sa->sa_family); + strarray__scnprintf(&strarray__socket_families, family, sizeof(family), "%d", arg->show_string_prefix, sa->sa_family); printed = scnprintf(bf, size, "{ .family: %s", family); if (sa->sa_family < ARRAY_SIZE(af_scnprintfs) && af_scnprintfs[sa->sa_family]) diff --git a/tools/perf/trace/beauty/socket.c b/tools/perf/trace/beauty/socket.c index eacbfb930fe4..f23a3dda2902 100644 --- a/tools/perf/trace/beauty/socket.c +++ b/tools/perf/trace/beauty/socket.c @@ -9,12 +9,12 @@ #include #include -static size_t socket__scnprintf_ipproto(int protocol, char *bf, size_t size) +static size_t socket__scnprintf_ipproto(int protocol, char *bf, size_t size, bool show_prefix) { #include "trace/beauty/generated/socket_ipproto_array.c" static DEFINE_STRARRAY(socket_ipproto, "IPPROTO_"); - return strarray__scnprintf(&strarray__socket_ipproto, bf, size, "%d", protocol); + return strarray__scnprintf(&strarray__socket_ipproto, bf, size, "%d", show_prefix, protocol); } size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct syscall_arg *arg) @@ -22,7 +22,7 @@ size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct sysc int domain = syscall_arg__val(arg, 0); if (domain == AF_INET || domain == AF_INET6) - return socket__scnprintf_ipproto(arg->val, bf, size); + return socket__scnprintf_ipproto(arg->val, bf, size, arg->show_string_prefix); return syscall_arg__scnprintf_int(bf, size, arg); } diff --git a/tools/perf/trace/beauty/socket_type.c b/tools/perf/trace/beauty/socket_type.c index a63a9a332aa0..bed8d5761ca8 100644 --- a/tools/perf/trace/beauty/socket_type.c +++ b/tools/perf/trace/beauty/socket_type.c @@ -20,6 +20,8 @@ static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "SOCK_"; size_t printed; int type = arg->val, flags = type & ~SOCK_TYPE_MASK; @@ -29,7 +31,7 @@ static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, struct s * Can't use a strarray, MIPS may override for ABI reasons. */ switch (type) { -#define P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break; +#define P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", #n); break; P_SK_TYPE(STREAM); P_SK_TYPE(DGRAM); P_SK_TYPE(RAW); diff --git a/tools/perf/trace/beauty/statx.c b/tools/perf/trace/beauty/statx.c index 630f2760dd66..811cc0eeb2d5 100644 --- a/tools/perf/trace/beauty/statx.c +++ b/tools/perf/trace/beauty/statx.c @@ -13,13 +13,15 @@ size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "AT_"; int printed = 0, flags = arg->val; if (flags == 0) - return scnprintf(bf, size, "SYNC_AS_STAT"); + return scnprintf(bf, size, "%s%s", show_prefix ? "AT_STATX_" : "", "SYNC_AS_STAT"); #define P_FLAG(n) \ if (flags & AT_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~AT_##n; \ } @@ -41,11 +43,13 @@ size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_ size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "STATX_"; int printed = 0, flags = arg->val; #define P_FLAG(n) \ if (flags & STATX_##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ flags &= ~STATX_##n; \ } diff --git a/tools/perf/trace/beauty/waitid_options.c b/tools/perf/trace/beauty/waitid_options.c index 42ff58ad613b..6897fab40dcc 100644 --- a/tools/perf/trace/beauty/waitid_options.c +++ b/tools/perf/trace/beauty/waitid_options.c @@ -5,11 +5,13 @@ static size_t syscall_arg__scnprintf_waitid_options(char *bf, size_t size, struct syscall_arg *arg) { + bool show_prefix = arg->show_string_prefix; + const char *prefix = "W"; int printed = 0, options = arg->val; #define P_OPTION(n) \ if (options & W##n) { \ - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : #n); \ options &= ~W##n; \ } -- cgit From 601d66d43309534eb7a268bdc42c205521014645 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 11:55:57 -0300 Subject: perf trace beauty: Print O_RDONLY when (flags & O_ACCMODE) == 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And there are more flags, to match strace's output. openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 Also to help with regression tests. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-ofovpmvdli3bwch30936xn7t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/open_flags.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index 6da48893a1bb..78f6566ef110 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -27,8 +27,10 @@ size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool sh const char *prefix = "O_"; int printed = 0; + if ((flags & O_ACCMODE) == O_RDONLY) + printed = scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", "RDONLY"); if (flags == 0) - return scnprintf(bf, size, "%s%s", show_prefix ? prefix : "", "RDONLY"); + return printed; #define P_FLAG(n) \ if (flags & O_##n) { \ printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ -- cgit From 4b8a240ed5e0a4e6b53c994ddfcff86a06879a66 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 11:48:46 -0300 Subject: perf trace: Add alignment spaces after the closing parens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To use strace's style, helping in comparing the output of 'perf trace' with the one from 'strace', to help in upcoming regression tests. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-mw6peotz4n84rga0fk78buff@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8a176ab2bd8e..226e994ac638 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1741,7 +1741,7 @@ static int trace__printf_interrupted_entry(struct trace *trace) return 0; printed = trace__fprintf_entry_head(trace, trace->current, 0, false, ttrace->entry_time, trace->output); - printed += fprintf(trace->output, "%-*s) ...\n", trace->args_alignment, ttrace->entry_str); + printed += fprintf(trace->output, ")%-*s ...\n", trace->args_alignment, ttrace->entry_str); ttrace->entry_pending = false; ++trace->nr_events_printed; @@ -1798,7 +1798,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, { char *msg; void *args; - size_t printed = 0; + int printed = 0; struct thread *thread; int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1; int augmented_args_size = 0; @@ -1847,8 +1847,13 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, if (sc->is_exit) { if (!(trace->duration_filter || trace->summary_only || trace->failure_only || trace->min_stack)) { + int alignment = 0; + trace__fprintf_entry_head(trace, thread, 0, false, ttrace->entry_time, trace->output); - fprintf(trace->output, "%-*s)\n", trace->args_alignment, ttrace->entry_str); + printed = fprintf(trace->output, "%s)", ttrace->entry_str); + if (trace->args_alignment > printed) + alignment = trace->args_alignment - printed; + fprintf(trace->output, "%*s= ?\n", alignment, " "); } } else { ttrace->entry_pending = true; @@ -1943,7 +1948,8 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, u64 duration = 0; bool duration_calculated = false; struct thread *thread; - int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0; + int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0; + int alignment = trace->args_alignment; struct syscall *sc = trace__syscall_info(trace, evsel, id); struct thread_trace *ttrace; @@ -1991,28 +1997,37 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, trace__fprintf_entry_head(trace, thread, duration, duration_calculated, ttrace->entry_time, trace->output); if (ttrace->entry_pending) { - fprintf(trace->output, "%-*s", trace->args_alignment, ttrace->entry_str); + printed = fprintf(trace->output, "%s", ttrace->entry_str); } else { fprintf(trace->output, " ... ["); color_fprintf(trace->output, PERF_COLOR_YELLOW, "continued"); fprintf(trace->output, "]: %s()", sc->name); } + printed++; /* the closing ')' */ + + if (alignment > printed) + alignment -= printed; + else + alignment = 0; + + fprintf(trace->output, ")%*s= ", alignment, " "); + if (sc->fmt == NULL) { if (ret < 0) goto errno_print; signed_print: - fprintf(trace->output, ") = %ld", ret); + fprintf(trace->output, "%ld", ret); } else if (ret < 0) { errno_print: { char bf[STRERR_BUFSIZE]; const char *emsg = str_error_r(-ret, bf, sizeof(bf)), *e = errno_to_name(evsel, -ret); - fprintf(trace->output, ") = -1 %s %s", e, emsg); + fprintf(trace->output, "-1 %s %s", e, emsg); } } else if (ret == 0 && sc->fmt->timeout) - fprintf(trace->output, ") = 0 Timeout"); + fprintf(trace->output, "0 Timeout"); else if (ttrace->ret_scnprintf) { char bf[1024]; struct syscall_arg arg = { @@ -2022,14 +2037,14 @@ errno_print: { }; ttrace->ret_scnprintf(bf, sizeof(bf), &arg); ttrace->ret_scnprintf = NULL; - fprintf(trace->output, ") = %s", bf); + fprintf(trace->output, "%s", bf); } else if (sc->fmt->hexret) - fprintf(trace->output, ") = %#lx", ret); + fprintf(trace->output, "%#lx", ret); else if (sc->fmt->errpid) { struct thread *child = machine__find_thread(trace->host, ret, ret); if (child != NULL) { - fprintf(trace->output, ") = %ld", ret); + fprintf(trace->output, "%ld", ret); if (child->comm_set) fprintf(trace->output, " (%s)", thread__comm_str(child)); thread__put(child); -- cgit From c48ee107bb387f76b089e0c30e1fed26e8d921f0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 11:59:35 -0300 Subject: perf augmented_raw_syscalls: Copy 'access' arg as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will all come from userspace, but to test the changes to make 'perf trace' output similar to strace's, do this one more now manually. To update the precompiled augmented_raw_syscalls.o binary I just run: # perf record -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c sleep 1 LLVM: dumping /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.022 MB perf.data ] # Because to have augmented_raw_syscalls to be always used and a fast startup and remove the need to have the llvm toolchain installed, I'm using: # perf config | grep add_events trace.add_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o # So when doing changes to augmented_raw_syscals.c one needs to rebuild the .o file. This will be done automagically later, i.e. have a 'make' behaviour of recompiling when the .c gets changed. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-lw3i2atyq8549fpqwmszn3qp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 6c5db6baeb3a..53c233370fae 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -55,6 +55,7 @@ struct augmented_filename { }; #define SYS_OPEN 2 +#define SYS_ACCESS 21 #define SYS_OPENAT 257 pid_filter(pids_filtered); @@ -119,6 +120,7 @@ int sys_enter(struct syscall_enter_args *args) * after the ctx memory access to prevent their down stream merging. */ switch (augmented_args.args.syscall_nr) { + case SYS_ACCESS: case SYS_OPEN: filename_arg = (const void *)args->args[0]; __asm__ __volatile__("": : :"memory"); break; -- cgit From 2c83dfae021306d528b21dceb8d128ca16524c5a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 12:06:34 -0300 Subject: perf trace: Enclose the errno strings with () MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To match strace, now both emit the same line for calls like: access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-krxl6klsqc9qyktoaxyih942@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 226e994ac638..35d8fbe47ee4 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2024,10 +2024,10 @@ errno_print: { const char *emsg = str_error_r(-ret, bf, sizeof(bf)), *e = errno_to_name(evsel, -ret); - fprintf(trace->output, "-1 %s %s", e, emsg); + fprintf(trace->output, "-1 %s (%s)", e, emsg); } } else if (ret == 0 && sc->fmt->timeout) - fprintf(trace->output, "0 Timeout"); + fprintf(trace->output, "0 (Timeout)"); else if (ttrace->ret_scnprintf) { char bf[1024]; struct syscall_arg arg = { -- cgit From ce05539f20b337221d3310baf73b45317dab067c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 12:21:09 -0300 Subject: perf trace: Show NULL when syscall pointer args are 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Matching strace's output format. The 'format' file for the syscall tracepoints have an indication if the arg is a pointer, with some exceptions like 'mmap' that has its first arg as an 'unsigned long', so use a heuristic using the argument name, i.e. if it contains the 'addr' substring, format it with the pointer formatter. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-ddghemr8qrm6i0sb8awznbze@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 28 ++++++++++++---------------- tools/perf/trace/beauty/beauty.h | 3 +++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 35d8fbe47ee4..6ba8290a0794 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -444,6 +444,13 @@ size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg return scnprintf(bf, size, "%#lx", arg->val); } +size_t syscall_arg__scnprintf_ptr(char *bf, size_t size, struct syscall_arg *arg) +{ + if (arg->val == 0) + return scnprintf(bf, size, "NULL"); + return syscall_arg__scnprintf_hex(bf, size, arg); +} + size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg) { return scnprintf(bf, size, "%d", arg->val); @@ -660,7 +667,7 @@ static struct syscall_fmt { { .name = "bpf", .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, { .name = "brk", .hexret = true, - .arg = { [0] = { .scnprintf = SCA_HEX, /* brk */ }, }, }, + .arg = { [0] = { .scnprintf = SCA_PTR, /* brk */ }, }, }, { .name = "clock_gettime", .arg = { [0] = STRARRAY(clk_id, clockid), }, }, { .name = "clone", .errpid = true, .nr_args = 5, @@ -738,17 +745,12 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, { .name = "mknodat", .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, - { .name = "mlock", - .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, - { .name = "mlockall", - .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, { .name = "mmap", .hexret = true, /* The standard mmap maps to old_mmap on s390x */ #if defined(__s390x__) .alias = "old_mmap", #endif - .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, - [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, + .arg = { [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, [3] = { .scnprintf = SCA_MMAP_FLAGS, /* flags */ }, }, }, { .name = "mount", .arg = { [0] = { .scnprintf = SCA_FILENAME, /* dev_name */ }, @@ -760,13 +762,7 @@ static struct syscall_fmt { { .name = "mq_unlink", .arg = { [0] = { .scnprintf = SCA_FILENAME, /* u_name */ }, }, }, { .name = "mremap", .hexret = true, - .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, - [3] = { .scnprintf = SCA_MREMAP_FLAGS, /* flags */ }, - [4] = { .scnprintf = SCA_HEX, /* new_addr */ }, }, }, - { .name = "munlock", - .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, - { .name = "munmap", - .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, + .arg = { [3] = { .scnprintf = SCA_MREMAP_FLAGS, /* flags */ }, }, }, { .name = "name_to_handle_at", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, { .name = "newfstatat", @@ -1350,8 +1346,8 @@ static int syscall__set_arg_fmts(struct syscall *sc) strcmp(field->name, "path") == 0 || strcmp(field->name, "pathname") == 0)) sc->arg_fmt[idx].scnprintf = SCA_FILENAME; - else if (field->flags & TEP_FIELD_IS_POINTER) - sc->arg_fmt[idx].scnprintf = syscall_arg__scnprintf_hex; + else if ((field->flags & TEP_FIELD_IS_POINTER) || strstr(field->name, "addr")) + sc->arg_fmt[idx].scnprintf = SCA_PTR; else if (strcmp(field->type, "pid_t") == 0) sc->arg_fmt[idx].scnprintf = SCA_PID; else if (strcmp(field->type, "umode_t") == 0) diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index ac25b6410bc8..1a93d9c626ef 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -98,6 +98,9 @@ size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg) size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg); #define SCA_HEX syscall_arg__scnprintf_hex +size_t syscall_arg__scnprintf_ptr(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_PTR syscall_arg__scnprintf_ptr + size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg); #define SCA_INT syscall_arg__scnprintf_int -- cgit From c22e2683c0cbfb8dcac84529d29386b094cd78cf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 16:15:27 -0300 Subject: tools include arch: Grab a copy of x86's prctl.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need it to generate the tables for the 'code' arch_prctl's syscall argument. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-vu890pi18fpd4eyz61cazckj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/uapi/asm/prctl.h | 17 +++++++++++++++++ tools/perf/check-headers.sh | 1 + 2 files changed, 18 insertions(+) create mode 100644 tools/arch/x86/include/uapi/asm/prctl.h diff --git a/tools/arch/x86/include/uapi/asm/prctl.h b/tools/arch/x86/include/uapi/asm/prctl.h new file mode 100644 index 000000000000..5a6aac9fa41f --- /dev/null +++ b/tools/arch/x86/include/uapi/asm/prctl.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _ASM_X86_PRCTL_H +#define _ASM_X86_PRCTL_H + +#define ARCH_SET_GS 0x1001 +#define ARCH_SET_FS 0x1002 +#define ARCH_GET_FS 0x1003 +#define ARCH_GET_GS 0x1004 + +#define ARCH_GET_CPUID 0x1011 +#define ARCH_SET_CPUID 0x1012 + +#define ARCH_MAP_VDSO_X32 0x2001 +#define ARCH_MAP_VDSO_32 0x2002 +#define ARCH_MAP_VDSO_64 0x2003 + +#endif /* _ASM_X86_PRCTL_H */ diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 9531f7bd7d9b..10d97dc632da 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -21,6 +21,7 @@ include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h arch/x86/include/asm/required-features.h arch/x86/include/asm/cpufeatures.h +arch/x86/include/uapi/asm/prctl.h arch/arm/include/uapi/asm/perf_regs.h arch/arm64/include/uapi/asm/perf_regs.h arch/powerpc/include/uapi/asm/perf_regs.h -- cgit From ff4cb769bc2dcc9a74a1c29e403bcfaf789365ef Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 16:11:37 -0300 Subject: perf beauty: Add a string table generator for x86's 'arch_prctl' codes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $ tools/perf/trace/beauty/x86_arch_prctl.sh #define x86_arch_prctl_codes_1_offset 0x1001 static const char *x86_arch_prctl_codes_1[] = { [0x1001 - 0x1001]= "SET_GS", [0x1002 - 0x1001]= "SET_FS", [0x1003 - 0x1001]= "GET_FS", [0x1004 - 0x1001]= "GET_GS", [0x1011 - 0x1001]= "GET_CPUID", [0x1012 - 0x1001]= "SET_CPUID", }; #define x86_arch_prctl_codes_2_offset 0x2001 static const char *x86_arch_prctl_codes_2[] = { [0x2001 - 0x2001]= "MAP_VDSO_X32", [0x2002 - 0x2001]= "MAP_VDSO_32", [0x2003 - 0x2001]= "MAP_VDSO_64", }; $ Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-w0fux1psivphhx6rve8kn3vq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/x86_arch_prctl.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 tools/perf/trace/beauty/x86_arch_prctl.sh diff --git a/tools/perf/trace/beauty/x86_arch_prctl.sh b/tools/perf/trace/beauty/x86_arch_prctl.sh new file mode 100755 index 000000000000..7372d3cab959 --- /dev/null +++ b/tools/perf/trace/beauty/x86_arch_prctl.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo +# SPDX-License-Identifier: LGPL-2.1 + +[ $# -eq 1 ] && x86_header_dir=$1 || x86_header_dir=tools/arch/x86/include/uapi/asm/ + +prctl_arch_header=${x86_header_dir}/prctl.h + +print_range () { + local idx=$1 + local prefix=$2 + local first_entry=$3 + + printf "#define x86_arch_prctl_codes_%d_offset %s\n" $idx $first_entry + printf "static const char *x86_arch_prctl_codes_%d[] = {\n" $idx + regex=`printf '^[[:space:]]*#[[:space:]]*define[[:space:]]+ARCH_([[:alnum:]_]+)[[:space:]]+(%s[[:xdigit:]]+).*' ${prefix}` + fmt="\t[%#x - ${first_entry}]= \"%s\",\n" + egrep -q $regex ${prctl_arch_header} && \ + (egrep $regex ${prctl_arch_header} | \ + sed -r "s/$regex/\2 \1/g" | \ + xargs printf "$fmt") + printf "};\n\n" +} + +print_range 1 0x1 0x1001 +print_range 2 0x2 0x2001 -- cgit From 40714e8b37723c31aa1b48dd2f346c3827059957 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Dec 2018 17:00:14 -0300 Subject: perf beauty: Wire up the x86_arch prctl code table generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $ cat /tmp/build/perf/trace/beauty/generated/x86_arch_prctl_code_array.c #define x86_arch_prctl_codes_1_offset 0x1001 static const char *x86_arch_prctl_codes_1[] = { [0x1001 - 0x1001]= "SET_GS", [0x1002 - 0x1001]= "SET_FS", [0x1003 - 0x1001]= "GET_FS", [0x1004 - 0x1001]= "GET_GS", [0x1011 - 0x1001]= "GET_CPUID", [0x1012 - 0x1001]= "SET_CPUID", }; #define x86_arch_prctl_codes_2_offset 0x2001 static const char *x86_arch_prctl_codes_2[] = { [0x2001 - 0x2001]= "MAP_VDSO_X32", [0x2002 - 0x2001]= "MAP_VDSO_32", [0x2003 - 0x2001]= "MAP_VDSO_64", }; $ Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-3r9blij6n8wdlsyd5dujx86r@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 8c1350c591f2..3af432bccd3e 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -396,6 +396,7 @@ SHELL = $(SHELL_PATH) linux_uapi_dir := $(srctree)/tools/include/uapi/linux asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic arch_asm_uapi_dir := $(srctree)/tools/arch/$(SRCARCH)/include/uapi/asm/ +x86_arch_asm_uapi_dir := $(srctree)/tools/arch/x86/include/uapi/asm/ beauty_outdir := $(OUTPUT)trace/beauty/generated beauty_ioctl_outdir := $(beauty_outdir)/ioctl @@ -490,6 +491,12 @@ prctl_option_tbl := $(srctree)/tools/perf/trace/beauty/prctl_option.sh $(prctl_option_array): $(prctl_hdr_dir)/prctl.h $(prctl_option_tbl) $(Q)$(SHELL) '$(prctl_option_tbl)' $(prctl_hdr_dir) > $@ +x86_arch_prctl_code_array := $(beauty_outdir)/x86_arch_prctl_code_array.c +x86_arch_prctl_code_tbl := $(srctree)/tools/perf/trace/beauty/x86_arch_prctl.sh + +$(x86_arch_prctl_code_array): $(x86_arch_asm_uapi_dir)/prctl.h $(x86_arch_prctl_code_tbl) + $(Q)$(SHELL) '$(x86_arch_prctl_code_tbl)' $(x86_arch_asm_uapi_dir) > $@ + rename_flags_array := $(beauty_outdir)/rename_flags_array.c rename_flags_tbl := $(srctree)/tools/perf/trace/beauty/rename_flags.sh @@ -610,6 +617,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc $(mount_flags_array) \ $(perf_ioctl_array) \ $(prctl_option_array) \ + $(x86_arch_prctl_code_array) \ $(rename_flags_array) \ $(arch_errno_name_array) @@ -907,6 +915,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(OUTPUT)$(vhost_virtio_ioctl_array) \ $(OUTPUT)$(perf_ioctl_array) \ $(OUTPUT)$(prctl_option_array) \ + $(OUTPUT)$(x86_arch_prctl_code_array) \ $(OUTPUT)$(rename_flags_array) \ $(OUTPUT)$(arch_errno_name_array) $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean -- cgit From 1f2d085e0f25a40eeb0ac032fd399be94f866adb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 10:25:28 -0300 Subject: perf trace: Move strarrays to beauty.h for further reuse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We'll use it in the upcoming arch_prctl() 'code' arg beautifier. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-6e4tj2fjen8qa73gy4u49vav@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 26 ++++++++++---------------- tools/perf/trace/beauty/beauty.h | 12 ++++++++++++ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6ba8290a0794..9d30e0f3b7ea 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -386,34 +386,28 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, #define SCA_STRARRAY syscall_arg__scnprintf_strarray -struct strarrays { - int nr_entries; - struct strarray **entries; -}; - -#define DEFINE_STRARRAYS(array) struct strarrays strarrays__##array = { \ - .nr_entries = ARRAY_SIZE(array), \ - .entries = array, \ -} - -size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, - struct syscall_arg *arg) +size_t strarrays__scnprintf(struct strarrays *sas, char *bf, size_t size, const char *intfmt, bool show_prefix, int val) { - struct strarrays *sas = arg->parm; int i; for (i = 0; i < sas->nr_entries; ++i) { struct strarray *sa = sas->entries[i]; - int idx = arg->val - sa->offset; + int idx = val - sa->offset; if (idx >= 0 && idx < sa->nr_entries) { if (sa->entries[idx] == NULL) break; - return scnprintf(bf, size, "%s%s", arg->show_string_prefix ? sa->prefix : "", sa->entries[idx]); + return scnprintf(bf, size, "%s%s", show_prefix ? sa->prefix : "", sa->entries[idx]); } } - return scnprintf(bf, size, "%d", arg->val); + return scnprintf(bf, size, intfmt, val); +} + +size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, + struct syscall_arg *arg) +{ + return strarrays__scnprintf(arg->parm, bf, size, "%d", arg->show_string_prefix, arg->val); } #ifndef AT_FDCWD diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 1a93d9c626ef..58e734b27958 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -32,6 +32,18 @@ size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, boo struct trace; struct thread; +struct strarrays { + int nr_entries; + struct strarray **entries; +}; + +#define DEFINE_STRARRAYS(array) struct strarrays strarrays__##array = { \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + +size_t strarrays__scnprintf(struct strarrays *sas, char *bf, size_t size, const char *intfmt, bool show_prefix, int val); + size_t pid__scnprintf_fd(struct trace *trace, pid_t pid, int fd, char *bf, size_t size); extern struct strarray strarray__socket_families; -- cgit From 9614b8d697350d529743702f095b3db3f6d5a889 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 10:54:19 -0300 Subject: perf trace: When showing string prefixes show prefix + ??? for unknown entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To match 'strace' output, like in: arch_prctl(0x3001 /* ARCH_??? */, 0x7ffc8a92dc80) = -1 EINVAL (Invalid argument) Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-kx59j2dk5l1x04ou57mt99ck@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9d30e0f3b7ea..6d9be952e3a7 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -365,8 +365,12 @@ size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const cha { int idx = val - sa->offset; - if (idx < 0 || idx >= sa->nr_entries || sa->entries[idx] == NULL) - return scnprintf(bf, size, intfmt, val); + if (idx < 0 || idx >= sa->nr_entries || sa->entries[idx] == NULL) { + size_t printed = scnprintf(bf, size, intfmt, val); + if (show_prefix) + printed += scnprintf(bf + printed, size - printed, " /* %s??? */", sa->prefix); + return printed; + } return scnprintf(bf, size, "%s%s", show_prefix ? sa->prefix : "", sa->entries[idx]); } @@ -388,6 +392,7 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, size_t strarrays__scnprintf(struct strarrays *sas, char *bf, size_t size, const char *intfmt, bool show_prefix, int val) { + size_t printed; int i; for (i = 0; i < sas->nr_entries; ++i) { @@ -401,7 +406,10 @@ size_t strarrays__scnprintf(struct strarrays *sas, char *bf, size_t size, const } } - return scnprintf(bf, size, intfmt, val); + printed = scnprintf(bf, size, intfmt, val); + if (show_prefix) + printed += scnprintf(bf + printed, size - printed, " /* %s??? */", sas->entries[0]->prefix); + return printed; } size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, -- cgit From fb7068e73d2c24ba381938004ed0f285341ef1ba Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 11:05:56 -0300 Subject: perf trace beauty: Beautify arch_prctl()'s arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This actually so far, AFAIK is available only in x86, so the code was put in place with x86 prefixes, in arches where it is not available it will just not be called, so no further mechanisms are needed at this time. Later, when other arches wire this up, we'll just look at the uname (live sessions) or perf_env data in the perf.data header to auto-wire the right beautifier. With this the output is the same as produced by 'strace' when used with the following ~/.perfconfig: # cat ~/.perfconfig [llvm] dump-obj = true [trace] add_events = /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o show_zeros = yes show_duration = no no_inherit = yes show_timestamp = no show_arg_names = no args_alignment = -40 show_prefix = yes # And, on fedora 29, since the string tables are generated from the kernel sources, we don't know about 0x3001, just like strace: --- /tmp/strace 2018-12-17 11:22:08.707586721 -0300 +++ /tmp/trace 2018-12-18 11:11:32.037512729 -0300 @@ -1,49 +1,49 @@ -arch_prctl(0x3001 /* ARCH_??? */, 0x7ffc8a92dc80) = -1 EINVAL (Invalid argument) +arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe4eb93ae0) = -1 EINVAL (Invalid argument) -arch_prctl(ARCH_SET_FS, 0x7faf6700f540) = 0 +arch_prctl(ARCH_SET_FS, 0x7fb507364540) = 0 And that seems to be related to the CET/Shadow Stack feature, that userland in Fedora 29 (glibc 2.28) are querying the kernel about, that 0x3001 seems to be ARCH_CET_STATUS, I'll check the situation and test with a fedora 29 kernel to see if the other codes are used. A diff that ignores the different pointers for different runs needs to be put in place in the upcoming regression tests comparing 'perf trace's output to strace's. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-73a9prs8ktkrt97trtdmdjs8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 5 ++++- tools/perf/trace/beauty/Build | 1 + tools/perf/trace/beauty/arch_prctl.c | 33 +++++++++++++++++++++++++++++++++ tools/perf/trace/beauty/beauty.h | 3 +++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tools/perf/trace/beauty/arch_prctl.c diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6d9be952e3a7..2cc62ca75b2e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -664,6 +664,9 @@ static struct syscall_fmt { } syscall_fmts[] = { { .name = "access", .arg = { [1] = { .scnprintf = SCA_ACCMODE, /* mode */ }, }, }, + { .name = "arch_prctl", + .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ }, + [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, }, { .name = "bind", .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, }, }, { .name = "bpf", @@ -793,7 +796,7 @@ static struct syscall_fmt { [3] = { .scnprintf = SCA_INT, /* pkey */ }, }, }, { .name = "poll", .timeout = true, }, { .name = "ppoll", .timeout = true, }, - { .name = "prctl", .alias = "arch_prctl", + { .name = "prctl", .arg = { [0] = { .scnprintf = SCA_PRCTL_OPTION, /* option */ }, [1] = { .scnprintf = SCA_PRCTL_ARG2, /* arg2 */ }, [2] = { .scnprintf = SCA_PRCTL_ARG3, /* arg3 */ }, }, }, diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index 10c85cd3eb4f..637365099b7d 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build @@ -7,6 +7,7 @@ endif libperf-y += kcmp.o libperf-y += mount_flags.o libperf-y += pkey_alloc.o +libperf-y += arch_prctl.o libperf-y += prctl.o libperf-y += renameat.o libperf-y += sockaddr.o diff --git a/tools/perf/trace/beauty/arch_prctl.c b/tools/perf/trace/beauty/arch_prctl.c new file mode 100644 index 000000000000..fe022ca67e60 --- /dev/null +++ b/tools/perf/trace/beauty/arch_prctl.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: LGPL-2.1 +/* + * trace/beauty/arch_prctl.c + * + * Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo + */ + +#include "trace/beauty/beauty.h" +#include + +#include "trace/beauty/generated/x86_arch_prctl_code_array.c" + +static DEFINE_STRARRAY_OFFSET(x86_arch_prctl_codes_1, "ARCH_", x86_arch_prctl_codes_1_offset); +static DEFINE_STRARRAY_OFFSET(x86_arch_prctl_codes_2, "ARCH_", x86_arch_prctl_codes_2_offset); + +static struct strarray *x86_arch_prctl_codes[] = { + &strarray__x86_arch_prctl_codes_1, + &strarray__x86_arch_prctl_codes_2, +}; + +static DEFINE_STRARRAYS(x86_arch_prctl_codes); + +static size_t x86_arch_prctl__scnprintf_code(int option, char *bf, size_t size, bool show_prefix) +{ + return strarrays__scnprintf(&strarrays__x86_arch_prctl_codes, bf, size, "%#x", show_prefix, option); +} + +size_t syscall_arg__scnprintf_x86_arch_prctl_code(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long code = arg->val; + + return x86_arch_prctl__scnprintf_code(code, bf, size, arg->show_string_prefix); +} diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 58e734b27958..83c5b202e00e 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -155,6 +155,9 @@ size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, st size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags +size_t syscall_arg__scnprintf_x86_arch_prctl_code(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_X86_ARCH_PRCTL_CODE syscall_arg__scnprintf_x86_arch_prctl_code + size_t syscall_arg__scnprintf_prctl_option(char *bf, size_t size, struct syscall_arg *arg); #define SCA_PRCTL_OPTION syscall_arg__scnprintf_prctl_option -- cgit From 1355e09ab04bc583df9c4b2b68d445c535c8b66b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 11:22:34 -0300 Subject: perf beauty mmap: Print PROT_READ before PROT_EXEC to match strace output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helps with comparing 'strace' and 'perf trace' output, for mutual regression testing. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-va0qe95xbhep5hy52aq5qe0v@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/mmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index 138f36a47fb1..eb31089790e3 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c @@ -17,8 +17,8 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, prot &= ~PROT_##n; \ } - P_MMAP_PROT(EXEC); P_MMAP_PROT(READ); + P_MMAP_PROT(EXEC); P_MMAP_PROT(WRITE); P_MMAP_PROT(SEM); P_MMAP_PROT(GROWSDOWN); -- cgit From a66313408a08a9758e3007fe9a6cfe47b0dec88b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 11:25:08 -0300 Subject: perf beauty mmap: Print mmap's 'offset' arg in hexadecimal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also to make it match 'strace' output, for regression testing. Both now produce this option, when 'perf trace' uses a .perfconfig asking for the strace like output: mmap(0x7faf66e6a000, 1363968, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7faf66e6a000 Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-27qhouo1kaac2iyl85nfnsf5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2cc62ca75b2e..ebde59e61133 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -756,7 +756,8 @@ static struct syscall_fmt { .alias = "old_mmap", #endif .arg = { [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, - [3] = { .scnprintf = SCA_MMAP_FLAGS, /* flags */ }, }, }, + [3] = { .scnprintf = SCA_MMAP_FLAGS, /* flags */ }, + [5] = { .scnprintf = SCA_HEX, /* offset */ }, }, }, { .name = "mount", .arg = { [0] = { .scnprintf = SCA_FILENAME, /* dev_name */ }, [3] = { .scnprintf = SCA_MOUNT_FLAGS, /* flags */ -- cgit From f9cdd63e79946d2f635d5c23d76811c2d710aa5c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 16:15:53 -0300 Subject: tools headers uapi: Grab a copy of fadvise.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Will be used to generate the string table for fadvise64's 'advice' argument. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-muswpnft8q9krktv052yrgsc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/fadvise.h | 22 ++++++++++++++++++++++ tools/perf/check-headers.sh | 1 + 2 files changed, 23 insertions(+) create mode 100644 tools/include/uapi/linux/fadvise.h diff --git a/tools/include/uapi/linux/fadvise.h b/tools/include/uapi/linux/fadvise.h new file mode 100644 index 000000000000..0862b87434c2 --- /dev/null +++ b/tools/include/uapi/linux/fadvise.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef FADVISE_H_INCLUDED +#define FADVISE_H_INCLUDED + +#define POSIX_FADV_NORMAL 0 /* No further special treatment. */ +#define POSIX_FADV_RANDOM 1 /* Expect random page references. */ +#define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ + +/* + * The advise values for POSIX_FADV_DONTNEED and POSIX_ADV_NOREUSE + * for s390-64 differ from the values for the rest of the world. + */ +#if defined(__s390x__) +#define POSIX_FADV_DONTNEED 6 /* Don't need these pages. */ +#define POSIX_FADV_NOREUSE 7 /* Data will be accessed once. */ +#else +#define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ +#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ +#endif + +#endif /* FADVISE_H_INCLUDED */ diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 10d97dc632da..8e811ea0cf85 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -4,6 +4,7 @@ HEADERS=' include/uapi/drm/drm.h include/uapi/drm/i915_drm.h +include/uapi/linux/fadvise.h include/uapi/linux/fcntl.h include/uapi/linux/fs.h include/uapi/linux/kcmp.h -- cgit From 069c1c6cc3646454f9c8e83084a25f8eb8cab7ae Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 11:49:58 -0300 Subject: perf beauty: Add generator for fadvise64's 'advice' arg constants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $ tools/perf/trace/beauty/fadvise.sh static const char *fadvise_advices[] = { [0] = "NORMAL", [1] = "RANDOM", [2] = "SEQUENTIAL", [3] = "WILLNEED", [4] = "DONTNEED", [5] = "NOREUSE", }; $ This has a hack wrt the s390 difference. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-tb7jguv01u8p570piq13eioh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/fadvise.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 tools/perf/trace/beauty/fadvise.sh diff --git a/tools/perf/trace/beauty/fadvise.sh b/tools/perf/trace/beauty/fadvise.sh new file mode 100755 index 000000000000..b15ae3875167 --- /dev/null +++ b/tools/perf/trace/beauty/fadvise.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: LGPL-2.1 + +[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ + +printf "static const char *fadvise_advices[] = {\n" +regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+POSIX_FADV_(\w+)[[:space:]]+([[:digit:]]+)[[:space:]]+.*' + +egrep $regex ${header_dir}/fadvise.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" | \ + grep -v "[6].*DONTNEED" | grep -v "[7].*NOREUSE" +printf "};\n" + +# XXX Fix this properly: + +# The grep 6/7 DONTNEED/NOREUSE are a hack to filter out the s/390 oddity See +# tools/include/uapi/linux/fadvise.h for details. + +# Probably fix this when generating the string tables per arch so that We can +# reliably process on arch FOO a perf.data file collected by 'perf trace +# record' on arch BAR, e.g. collect on s/390 and process on x86. -- cgit From 42337cb768ad9536150603b206acd6bbd320e75e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 11:54:31 -0300 Subject: perf trace: Wire up the fadvise 'advice' table generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That ends up generating this: $ cat /tmp/build/perf/trace/beauty/generated/fadvise_advice_array.c static const char *fadvise_advices[] = { [0] = "NORMAL", [1] = "RANDOM", [2] = "SEQUENTIAL", [3] = "WILLNEED", [4] = "DONTNEED", [5] = "NOREUSE", }; $ Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-zwbslubagram8a8zdc003u8h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 3af432bccd3e..bd23e3f30895 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -410,6 +410,12 @@ _dummy := $(shell [ -d '$(beauty_ioctl_outdir)' ] || mkdir -p '$(beauty_ioctl_ou $(drm_ioctl_array): $(drm_hdr_dir)/drm.h $(drm_hdr_dir)/i915_drm.h $(drm_ioctl_tbl) $(Q)$(SHELL) '$(drm_ioctl_tbl)' $(drm_hdr_dir) > $@ +fadvise_advice_array := $(beauty_outdir)/fadvise_advice_array.c +fadvise_advice_tbl := $(srctree)/tools/perf/trace/beauty/fadvise.sh + +$(fadvise_advice_array): $(linux_uapi_dir)/in.h $(fadvise_advice_tbl) + $(Q)$(SHELL) '$(fadvise_advice_tbl)' $(linux_uapi_dir) > $@ + pkey_alloc_access_rights_array := $(beauty_outdir)/pkey_alloc_access_rights_array.c asm_generic_hdr_dir := $(srctree)/tools/include/uapi/asm-generic/ pkey_alloc_access_rights_tbl := $(srctree)/tools/perf/trace/beauty/pkey_alloc_access_rights.sh @@ -605,6 +611,7 @@ __build-dir = $(subst $(OUTPUT),,$(dir $@)) build-dir = $(if $(__build-dir),$(__build-dir),.) prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioctl_array) \ + $(fadvise_advice_array) \ $(pkey_alloc_access_rights_array) \ $(sndrv_pcm_ioctl_array) \ $(sndrv_ctl_ioctl_array) \ @@ -902,6 +909,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(OUTPUT)util/intel-pt-decoder/inat-tables.c \ $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ $(OUTPUT)pmu-events/pmu-events.c \ + $(OUTPUT)$(fadvise_advice_array) \ $(OUTPUT)$(madvise_behavior_array) \ $(OUTPUT)$(mmap_flags_array) \ $(OUTPUT)$(mount_flags_array) \ -- cgit From bc055c54b887961bc3545c54e61c844fd4499c2b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 12:39:08 -0300 Subject: perf symbols: Relax checks on perf-PID.map ownership MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those are simple enough, and usually not produced by root, instead by whatever user is running java, rust, Node.js JIT code that end up generating those /tmp/perf-PID.map for resolution of symbols in the anonymous executable maps. Having to use --force to resolve symbols in 'perf top' is a distraction, as recently I experienced when node.js symbols were not being resolved by 'perf top'. Acked-by: Ingo Molnar Cc: Adrian Hunter Cc: Frederic Weisbecker Cc: Hítalo Silva Cc: Jiri Olsa Cc: Namhyung Kim Cc: Pekka Enberg Cc: Peter Zijlstra Link: https://lkml.kernel.org/n/tip-tk2jgo2v4v2yjuj28axbpppo@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index dcce74bae6de..01f2c7385e38 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1537,17 +1537,6 @@ int dso__load(struct dso *dso, struct map *map) dso->adjust_symbols = 0; if (perfmap) { - struct stat st; - - if (lstat(map_path, &st) < 0) - goto out; - - if (!symbol_conf.force && st.st_uid && (st.st_uid != geteuid())) { - pr_warning("File %s not owned by current user or root, " - "ignoring it (use -f to override).\n", map_path); - goto out; - } - ret = dso__load_perf_map(map_path, dso); dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : DSO_BINARY_TYPE__NOT_FOUND; -- cgit From 89a0948984896352cac1ebe079cb3d64d6c3adc6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Dec 2018 12:53:06 -0300 Subject: tools uapi asm: Update asm-generic/unistd.h copy To get the change in: b7d624ab4312 ("asm-generic: unistd.h: fixup broken macro include.") That doesn't imply in any changes in the tools. This silences the following perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/asm-generic/unistd.h' differs from latest version at 'include/uapi/asm-generic/unistd.h' diff -u tools/include/uapi/asm-generic/unistd.h include/uapi/asm-generic/unistd.h Cc: Adrian Hunter Cc: Arnd Bergmann Cc: Guo Ren Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-2e7xwm5i2qcc88jp2lyawdyd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/asm-generic/unistd.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h index 538546edbfbd..c7f3321fbe43 100644 --- a/tools/include/uapi/asm-generic/unistd.h +++ b/tools/include/uapi/asm-generic/unistd.h @@ -760,8 +760,10 @@ __SYSCALL(__NR_rseq, sys_rseq) #define __NR_ftruncate __NR3264_ftruncate #define __NR_lseek __NR3264_lseek #define __NR_sendfile __NR3264_sendfile +#if defined(__ARCH_WANT_NEW_STAT) || defined(__ARCH_WANT_STAT64) #define __NR_newfstatat __NR3264_fstatat #define __NR_fstat __NR3264_fstat +#endif #define __NR_mmap __NR3264_mmap #define __NR_fadvise64 __NR3264_fadvise64 #ifdef __NR3264_stat @@ -776,8 +778,10 @@ __SYSCALL(__NR_rseq, sys_rseq) #define __NR_ftruncate64 __NR3264_ftruncate #define __NR_llseek __NR3264_lseek #define __NR_sendfile64 __NR3264_sendfile +#if defined(__ARCH_WANT_NEW_STAT) || defined(__ARCH_WANT_STAT64) #define __NR_fstatat64 __NR3264_fstatat #define __NR_fstat64 __NR3264_fstat +#endif #define __NR_mmap2 __NR3264_mmap #define __NR_fadvise64_64 __NR3264_fadvise64 #ifdef __NR3264_stat -- cgit