[tip:perf/core] perf report: Add --switch-on/--switch-off events
Commit-ID: ef4b1a539f4b8776701752c5a09ee741a4232ae6 Gitweb: https://git.kernel.org/tip/ef4b1a539f4b8776701752c5a09ee741a4232ae6 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 18:18:58 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Fri, 16 Aug 2019 12:14:33 -0300 perf report: Add --switch-on/--switch-off events Since 'perf top' shares the histogram browser with 'perf report', then the same explanation in the previous cset applies. An additional example uses a pair of SDT events available for systemtap: # perf probe --exec=/usr/bin/stap '%*:*' Added new events: sdt_stap:benchmark__thread__start (on %* in /usr/bin/stap) sdt_stap:benchmark (on %* in /usr/bin/stap) sdt_stap:benchmark__thread__end (on %* in /usr/bin/stap) sdt_stap:pass6__start (on %* in /usr/bin/stap) sdt_stap:pass6__end (on %* in /usr/bin/stap) sdt_stap:pass5__start (on %* in /usr/bin/stap) sdt_stap:pass5__end (on %* in /usr/bin/stap) sdt_stap:pass0__start (on %* in /usr/bin/stap) sdt_stap:pass0__end (on %* in /usr/bin/stap) sdt_stap:pass1a__start (on %* in /usr/bin/stap) sdt_stap:pass1b__start (on %* in /usr/bin/stap) sdt_stap:pass1__end (on %* in /usr/bin/stap) sdt_stap:pass2__start (on %* in /usr/bin/stap) sdt_stap:pass2__end (on %* in /usr/bin/stap) sdt_stap:pass3__start (on %* in /usr/bin/stap) sdt_stap:pass3__end (on %* in /usr/bin/stap) sdt_stap:pass4__start (on %* in /usr/bin/stap) sdt_stap:pass4__end (on %* in /usr/bin/stap) sdt_stap:benchmark__start (on %* in /usr/bin/stap) sdt_stap:benchmark__end (on %* in /usr/bin/stap) sdt_stap:cache__get (on %* in /usr/bin/stap) sdt_stap:cache__clean (on %* in /usr/bin/stap) sdt_stap:cache__add__module (on %* in /usr/bin/stap) sdt_stap:cache__add__source (on %* in /usr/bin/stap) sdt_stap:stap_system__complete (on %* in /usr/bin/stap) sdt_stap:stap_system__start (on %* in /usr/bin/stap) sdt_stap:stap_system__spawn (on %* in /usr/bin/stap) sdt_stap:stap_system__fork (on %* in /usr/bin/stap) sdt_stap:intern_string (on %* in /usr/bin/stap) sdt_stap:client__start (on %* in /usr/bin/stap) sdt_stap:client__end (on %* in /usr/bin/stap) You can now use it in all perf tools, such as: perf record -e sdt_stap:client__end -aR sleep 1 # >From these we're use the two below to run systemtap's test suite: # perf record -e sdt_stap:pass2__*,cycles:P make installcheck > /dev/null ^C[ perf record: Woken up 8 times to write data ] [ perf record: Captured and wrote 2.691 MB perf.data (39638 samples) ] Terminated # perf script | grep sdt_stap stap 28979 [000] 19424.302660: sdt_stap:pass2__start: (561b9a537de3) arg1=140730364262544 stap 28979 [000] 19424.333083: sdt_stap:pass2__end: (561b9a53a9e1) arg1=140730364262544 stap 29045 [006] 19424.933460: sdt_stap:pass2__start: (563edddcede3) arg1=140722674883152 stap 29045 [006] 19424.963794: sdt_stap:pass2__end: (563e19e1) arg1=140722674883152 # perf script | grep cycles | wc -l 39634 # Looking at the whole perf.data file: [root@quaco testsuite]# perf report | grep cycles:P -A25 # Samples: 39K of event 'cycles:P' # Event count (approx.): 34044267368 # # Overhead Command Shared Object Symbol # ... # 3.50% cc1 cc1 [.] ht_lookup_with_hash 3.04% cc1 cc1 [.] _cpp_lex_token 2.11% cc1 cc1 [.] ggc_internal_alloc 1.83% cc1 cc1 [.] cpp_get_token_with_location 1.68% cc1 libc-2.29.so [.] _int_malloc 1.41% cc1 cc1 [.] linemap_position_for_column 1.25% cc1 cc1 [.] ggc_internal_cleared_alloc 1.20% cc1 cc1 [.] c_lex_with_flags 1.18% cc1 cc1 [.] get_combined_adhoc_loc 1.05% cc1 libc-2.29.so [.] malloc 1.01% cc1 libc-2.29.so [.] _int_free 0.96% stap stap [.] std::_Hashtable, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::allocator, std::allocator > >, std::__detail::_Identity, std::equal_to, std::allocator > >, stringtable_hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits >::_M_insert, std::allocator > const&, std::__detail::_AllocNode, std::allocator >, true> > > > 0.78% stap stap [.] lexer::scan 0.74% cc1 cc1 [.] _cpp_lex_direct 0.70% cc1 cc1 [.] pop_scope 0.70% cc1 cc1 [.] c_parser_declspecs 0.69% stap libc-2.29.so
[tip:perf/core] perf top: Add --switch-on/--switch-off events
Commit-ID: 2f53ae347f597842683c4bde5b9ce76f5efae247 Gitweb: https://git.kernel.org/tip/2f53ae347f597842683c4bde5b9ce76f5efae247 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 16:03:26 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 16:03:26 -0300 perf top: Add --switch-on/--switch-off events Just like 'perf trace' and 'perf script', should be useful for instance to only consider samples after the initialization phase of some workload. The man page has some examples and considerations about its current interface, that still doesn't handle the on/off events in a special way, behaving just like when multiple events are specified, i.e.: - In non-group mode (when the event list is not enclosed in {}) show a a menu to allow choosing which event the user wants to see in the histograms browser - In group mode, be it using {} or asking for --group, show one column per event. Try for instance: # perf top -e '{cycles,instructions,probe:icmp_rcv}' --switch-on=probe:icmp_rcv Replace probe:icmp_rcv, that I put in place using: # perf probe icmp_rcv:59 To hit when broadcast packets arrive, with a probe installed after an initialization phase is over or after some other point of interest, some garbage collection, etc, and also use --switch-off, for instance, on a probe installed after said garbage collection is over. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-c7q7qjeqtyvc9mkeipxza...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-top.txt | 38 +++ tools/perf/builtin-top.c | 10 - tools/perf/util/top.h | 2 ++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index cfea87c6f38e..5596129a71cf 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -266,6 +266,44 @@ Default is to monitor all CPUS. Record events of type PERF_RECORD_NAMESPACES and display it with the 'cgroup_id' sort key. +--switch-on EVENT_NAME:: + Only consider events after this event is found. + + E.g.: + + Find out where broadcast packets are handled + + perf probe -L icmp_rcv + + Insert a probe there: + + perf probe icmp_rcv:59 + + Start perf top and ask it to only consider the cycles events when a + broadcast packet arrives This will show a menu with two entries and + will start counting when a broadcast packet arrives: + + perf top -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv + + Alternatively one can ask for --group and then two overhead columns + will appear, the first for cycles and the second for the switch-on event. + + perf top --group -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv + + This may be interesting to measure a workload only after some initialization + phase is over, i.e. insert a perf probe at that point and use the above + examples replacing probe:icmp_rcv with the just-after-init probe. + +--switch-off EVENT_NAME:: + Stop considering events after this event is found. + +--show-on-off-events:: + Show the --switch-on/off events too. This has no effect in 'perf top' now + but probably we'll make the default not to show the switch-on/off events +on the --group mode and if there is only one event besides the off/on ones, + go straight to the histogram browser, just like 'perf top' with no events + explicitely specified does. + INTERACTIVE PROMPTING KEYS -- diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 78e7efc597a6..5970723cd55a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1148,8 +1148,11 @@ static int deliver_event(struct ordered_events *qe, evsel = perf_evlist__id2evsel(session->evlist, sample.id); assert(evsel != NULL); - if (event->header.type == PERF_RECORD_SAMPLE) + if (event->header.type == PERF_RECORD_SAMPLE) { + if (evswitch__discard(>evswitch, evsel)) + return 0; ++top->samples; + } switch (sample.cpumode) { case PERF_RECORD_MISC_USER: @@ -1534,6 +1537,7 @@ int cmd_top(int argc, const char **argv) "number of thread to run event synthesize"), OPT_BOOLEAN(0, "namespaces", >record_namespaces, "Record namespaces events"), + OPTS_EVSWITCH(), OPT_END() }; struct evlist *sb_evlist = NULL; @@ -1567,6 +1571,10 @@ int cmd_top(int argc, const char **argv) goto out_delete_evlist; } + status = evswitch__init(, top.evlist,
[tip:perf/core] perf trace: Add --switch-on/--switch-off events
Commit-ID: 22ac4318ad95847797de99dccaf059c76cd74efe Gitweb: https://git.kernel.org/tip/22ac4318ad95847797de99dccaf059c76cd74efe Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 12:15:39 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:26:21 -0300 perf trace: Add --switch-on/--switch-off events Just like with 'perf script': # perf trace -e sched:*,syscalls:*sleep* sleep 1 0.000 :28345/28345 sched:sched_waking:comm=perf pid=28346 prio=120 target_cpu=005 0.005 :28345/28345 sched:sched_wakeup:perf:28346 [120] success=1 CPU:005 0.383 sleep/28346 sched:sched_process_exec:filename=/usr/bin/sleep pid=28346 old_pid=28346 0.613 sleep/28346 sched:sched_stat_runtime:comm=sleep pid=28346 runtime=607375 [ns] vruntime=23289041218 [ns] 0.689 sleep/28346 syscalls:sys_enter_nanosleep:rqtp: 0x7ffc491789b0 0.693 sleep/28346 sched:sched_stat_runtime:comm=sleep pid=28346 runtime=72021 [ns] vruntime=23289113239 [ns] 0.694 sleep/28346 sched:sched_switch:sleep:28346 [120] S ==> swapper/5:0 [120] 1000.787 :0/0 sched:sched_waking:comm=sleep pid=28346 prio=120 target_cpu=005 1000.824 :0/0 sched:sched_wakeup:sleep:28346 [120] success=1 CPU:005 1000.908 sleep/28346 syscalls:sys_exit_nanosleep:0x0 1001.218 sleep/28346 sched:sched_process_exit:comm=sleep pid=28346 prio=120 # perf trace -e sched:*,syscalls:*sleep* --switch-on=syscalls:sys_enter_nanosleep sleep 1 0.000 sleep/28349 sched:sched_stat_runtime:comm=sleep pid=28349 runtime=603036 [ns] vruntime=23873537697 [ns] 0.001 sleep/28349 sched:sched_switch:sleep:28349 [120] S ==> swapper/4:0 [120] 1000.392 :0/0 sched:sched_waking:comm=sleep pid=28349 prio=120 target_cpu=004 1000.443 :0/0 sched:sched_wakeup:sleep:28349 [120] success=1 CPU:004 1000.540 sleep/28349 syscalls:sys_exit_nanosleep:0x0 1000.852 sleep/28349 sched:sched_process_exit:comm=sleep pid=28349 prio=120 # perf trace -e sched:*,syscalls:*sleep* --switch-on=syscalls:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep sleep 1 0.000 sleep/28352 sched:sched_stat_runtime:comm=sleep pid=28352 runtime=610543 [ns] vruntime=24811686681 [ns] 0.001 sleep/28352 sched:sched_switch:sleep:28352 [120] S ==> swapper/0:0 [120] 1000.397 :0/0 sched:sched_waking:comm=sleep pid=28352 prio=120 target_cpu=000 1000.440 :0/0 sched:sched_wakeup:sleep:28352 [120] success=1 CPU:000 # # perf trace -e sched:*,syscalls:*sleep* --switch-on=syscalls:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep --show-on-off sleep 1 0.000 sleep/28367 syscalls:sys_enter_nanosleep:rqtp: 0x7fffd1a25fc0 0.004 sleep/28367 sched:sched_stat_runtime:comm=sleep pid=28367 runtime=628760 [ns] vruntime=22170052672 [ns] 0.005 sleep/28367 sched:sched_switch:sleep:28367 [120] S ==> swapper/2:0 [120] 1000.367 :0/0 sched:sched_waking:comm=sleep pid=28367 prio=120 target_cpu=002 1000.412 :0/0 sched:sched_wakeup:sleep:28367 [120] success=1 CPU:002 1000.512 sleep/28367 syscalls:sys_exit_nanosleep:0x0 # Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-t3ngpt1brcc1fm9gep9gx...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-trace.txt | 9 + tools/perf/builtin-trace.c | 10 ++ 2 files changed, 19 insertions(+) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index fc6e43262c41..25b74fdb36fa 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -176,6 +176,15 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. only at exit time or when a syscall is interrupted, i.e. in those cases this option is equivalent to the number of lines printed. +--switch-on EVENT_NAME:: + Only consider events after this event is found. + +--switch-off EVENT_NAME:: + Stop considering events after this event is found. + +--show-on-off-events:: + Show the --switch-on/off events too. + --max-stack:: Set the stack depth limit when parsing the callchain, anything beyond the specified depth will be ignored. Note that at this point diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d553d06a9aeb..bc44ed29e05a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -27,6 +27,7 @@ #include "util/env.h" #include "util/event.h" #include "util/evlist.h" +#include "util/evswitch.h" #include #include "util/machine.h" #include "util/map.h" @@ -106,6 +107,7 @@ struct trace { unsigned long nr_events; unsigned long nr_events_printed; unsigned long max_events; + struct evswitch evswitch; struct strlist *ev_qualifier;
[tip:perf/core] perf evswitch: Add hint when not finding specified on/off events
Commit-ID: 8b3c9ea7bf8f50ead6787c084cfc6d3a0b1e38aa Gitweb: https://git.kernel.org/tip/8b3c9ea7bf8f50ead6787c084cfc6d3a0b1e38aa Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 12:02:13 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:26:13 -0300 perf evswitch: Add hint when not finding specified on/off events If the user specifies a on or off switch event and it isn't in the perf.data file, provide a hint about how to see the events in the perf.data evlist: # perf script --switch-on=syscall:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep ERROR: event_on event not found (syscall:sys_enter_nanosleep) HINT: use 'perf evlist' to see the available event names # # perf evlist sched:sched_kthread_stop sched:sched_kthread_stop_ret sched:sched_waking sched:sched_wakeup sched:sched_wakeup_new sched:sched_switch sched:sched_migrate_task sched:sched_process_free sched:sched_process_exit sched:sched_wait_task sched:sched_process_wait sched:sched_process_fork sched:sched_process_exec sched:sched_stat_wait sched:sched_stat_sleep sched:sched_stat_iowait sched:sched_stat_blocked sched:sched_stat_runtime sched:sched_pi_setprio sched:sched_move_numa sched:sched_stick_numa sched:sched_swap_numa sched:sched_wake_idle_without_ipi syscalls:sys_enter_clock_nanosleep syscalls:sys_exit_clock_nanosleep syscalls:sys_enter_nanosleep syscalls:sys_exit_nanosleep # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events # # perf script --switch-on=syscalls:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [ns] sleep 20919 [001] 109866.144412:sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568:sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586:sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 # Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-iijjvdlyad973oskdq8gm...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evswitch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c index 71daed615a2c..3ba72f743d3c 100644 --- a/tools/perf/util/evswitch.c +++ b/tools/perf/util/evswitch.c @@ -33,7 +33,9 @@ bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) static int evswitch__fprintf_enoent(FILE *fp, const char *evtype, const char *evname) { - return fprintf(fp, "ERROR: switch-%s event not found (%s)\n", evtype, evname); + int printed = fprintf(fp, "ERROR: switch-%s event not found (%s)\n", evtype, evname); + + return printed += fprintf(fp, "HINT: use 'perf evlist' to see the available event names\n"); } int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp)
[tip:perf/core] perf evswitch: Move enoent error message printing to separate function
Commit-ID: c9a4269930dada68971a4a97f3abf079af8cde4e Gitweb: https://git.kernel.org/tip/c9a4269930dada68971a4a97f3abf079af8cde4e Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 11:35:56 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:26:04 -0300 perf evswitch: Move enoent error message printing to separate function Allows adding hints there, will be done in followup patch. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-1kvrdi7weuz3hxycwvarc...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evswitch.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c index b57b5f0816f5..71daed615a2c 100644 --- a/tools/perf/util/evswitch.c +++ b/tools/perf/util/evswitch.c @@ -31,12 +31,17 @@ bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) return false; } +static int evswitch__fprintf_enoent(FILE *fp, const char *evtype, const char *evname) +{ + return fprintf(fp, "ERROR: switch-%s event not found (%s)\n", evtype, evname); +} + int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp) { if (evswitch->on_name) { evswitch->on = perf_evlist__find_evsel_by_str(evlist, evswitch->on_name); if (evswitch->on == NULL) { - fprintf(fp, "switch-on event not found (%s)\n", evswitch->on_name); + evswitch__fprintf_enoent(fp, "on", evswitch->on_name); return -ENOENT; } evswitch->discarding = true; @@ -45,7 +50,7 @@ int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp) if (evswitch->off_name) { evswitch->off = perf_evlist__find_evsel_by_str(evlist, evswitch->off_name); if (evswitch->off == NULL) { - fprintf(fp, "switch-off event not found (%s)\n", evswitch->off_name); + evswitch__fprintf_enoent(fp, "off", evswitch->off_name); return -ENOENT; } }
[tip:perf/core] perf evswitch: Introduce init() method to set the on/off evsels from the command line
Commit-ID: 124e02be72fdff05ab5d7f004a3c0d4061569380 Gitweb: https://git.kernel.org/tip/124e02be72fdff05ab5d7f004a3c0d4061569380 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 11:31:29 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:25:55 -0300 perf evswitch: Introduce init() method to set the on/off evsels from the command line Another step in having all the boilerplate in just one place to then use in the other tools. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-snreb1wmwyjei3eefwotx...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 21 +++-- tools/perf/util/evswitch.c | 23 +++ tools/perf/util/evswitch.h | 4 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 2a5b8af80e6b..1764efd16cd4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3868,24 +3868,9 @@ int cmd_script(int argc, const char **argv) script.range_num); } - if (script.evswitch.on_name) { - script.evswitch.on = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.on_name); - if (script.evswitch.on == NULL) { - fprintf(stderr, "switch-on event not found (%s)\n", script.evswitch.on_name); - err = -ENOENT; - goto out_delete; - } - script.evswitch.discarding = true; - } - - if (script.evswitch.off_name) { - script.evswitch.off = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.off_name); - if (script.evswitch.off == NULL) { - fprintf(stderr, "switch-off event not found (%s)\n", script.evswitch.off_name); - err = -ENOENT; - goto out_delete; - } - } + err = evswitch__init(, session->evlist, stderr); + if (err) + goto out_delete; err = __cmd_script(); diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c index c87f988d81c8..b57b5f0816f5 100644 --- a/tools/perf/util/evswitch.c +++ b/tools/perf/util/evswitch.c @@ -2,6 +2,7 @@ // Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo #include "evswitch.h" +#include "evlist.h" bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) { @@ -29,3 +30,25 @@ bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) return false; } + +int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp) +{ + if (evswitch->on_name) { + evswitch->on = perf_evlist__find_evsel_by_str(evlist, evswitch->on_name); + if (evswitch->on == NULL) { + fprintf(fp, "switch-on event not found (%s)\n", evswitch->on_name); + return -ENOENT; + } + evswitch->discarding = true; + } + + if (evswitch->off_name) { + evswitch->off = perf_evlist__find_evsel_by_str(evlist, evswitch->off_name); + if (evswitch->off == NULL) { + fprintf(fp, "switch-off event not found (%s)\n", evswitch->off_name); + return -ENOENT; + } + } + + return 0; +} diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index 94220d1bb479..fd30460b6218 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -4,8 +4,10 @@ #define __PERF_EVSWITCH_H 1 #include +#include struct evsel; +struct evlist; struct evswitch { struct evsel *on, *off; @@ -14,6 +16,8 @@ struct evswitch { bool show_on_off_events; }; +int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp); + bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel); #define OPTS_EVSWITCH(evswitch) \
[tip:perf/core] perf evswitch: Introduce OPTS_EVSWITCH() for cmd line processing
Commit-ID: add3a719c95f0443d563889b4af255b78ba54521 Gitweb: https://git.kernel.org/tip/add3a719c95f0443d563889b4af255b78ba54521 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 11:21:21 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:25:47 -0300 perf evswitch: Introduce OPTS_EVSWITCH() for cmd line processing All tools will want those, so provide a convenient way to get them. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-v16pe3sbf3wjmn152u18f...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 7 +-- tools/perf/util/evswitch.h | 8 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 177e4e91b199..2a5b8af80e6b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3543,12 +3543,7 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/kallsyms"), OPT_STRING(0, "guestmodules", _conf.default_guest_modules, "file", "file saving guest os /proc/modules"), - OPT_STRING(0, "switch-on", _name, - "event", "Consider events after the ocurrence of this event"), - OPT_STRING(0, "switch-off", _name, - "event", "Stop considering events after the ocurrence of this event"), - OPT_BOOLEAN(0, "show-on-off-events", _on_off_events, - "Show the on/off switch events, used with --switch-on"), + OPTS_EVSWITCH(), OPT_END() }; const char * const script_subcommands[] = { "record", "report", NULL }; diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index 891164504080..94220d1bb479 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -16,4 +16,12 @@ struct evswitch { bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel); +#define OPTS_EVSWITCH(evswitch) \ + OPT_STRING(0, "switch-on", &(evswitch)->on_name, \ + "event", "Consider events after the ocurrence of this event"), \ + OPT_STRING(0, "switch-off", &(evswitch)->off_name, \ + "event", "Stop considering events after the ocurrence of this event"), \ + OPT_BOOLEAN(0, "show-on-off-events", &(evswitch)->show_on_off_events, \ + "Show the on/off switch events, used with --switch-on and --switch-off") + #endif /* __PERF_EVSWITCH_H */
[tip:perf/core] perf evswitch: Add the names of on/off events
Commit-ID: 0b495b121585a1b6ca120fe13f950e2f86ca8197 Gitweb: https://git.kernel.org/tip/0b495b121585a1b6ca120fe13f950e2f86ca8197 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 11:11:14 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:24:42 -0300 perf evswitch: Add the names of on/off events So that we can have macros for the OPT_ entries and also for finding those in an evlist, this way other tools will use this very easily. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-q0og1xoqqi0w38ve5u0a4...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 18 -- tools/perf/util/evswitch.h | 1 + 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e7b950e977a9..177e4e91b199 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3400,8 +3400,6 @@ int cmd_script(int argc, const char **argv) struct utsname uts; char *script_path = NULL; const char **__argv; - const char *event_switch_on = NULL, - *event_switch_off = NULL; int i, j, err = 0; struct perf_script script = { .tool = { @@ -3545,9 +3543,9 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/kallsyms"), OPT_STRING(0, "guestmodules", _conf.default_guest_modules, "file", "file saving guest os /proc/modules"), - OPT_STRING(0, "switch-on", _switch_on, + OPT_STRING(0, "switch-on", _name, "event", "Consider events after the ocurrence of this event"), - OPT_STRING(0, "switch-off", _switch_off, + OPT_STRING(0, "switch-off", _name, "event", "Stop considering events after the ocurrence of this event"), OPT_BOOLEAN(0, "show-on-off-events", _on_off_events, "Show the on/off switch events, used with --switch-on"), @@ -3875,20 +3873,20 @@ int cmd_script(int argc, const char **argv) script.range_num); } - if (event_switch_on) { - script.evswitch.on = perf_evlist__find_evsel_by_str(session->evlist, event_switch_on); + if (script.evswitch.on_name) { + script.evswitch.on = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.on_name); if (script.evswitch.on == NULL) { - fprintf(stderr, "switch-on event not found (%s)\n", event_switch_on); + fprintf(stderr, "switch-on event not found (%s)\n", script.evswitch.on_name); err = -ENOENT; goto out_delete; } script.evswitch.discarding = true; } - if (event_switch_off) { - script.evswitch.off = perf_evlist__find_evsel_by_str(session->evlist, event_switch_off); + if (script.evswitch.off_name) { + script.evswitch.off = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.off_name); if (script.evswitch.off == NULL) { - fprintf(stderr, "switch-off event not found (%s)\n", event_switch_off); + fprintf(stderr, "switch-off event not found (%s)\n", script.evswitch.off_name); err = -ENOENT; goto out_delete; } diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index bae3a22ad719..891164504080 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -9,6 +9,7 @@ struct evsel; struct evswitch { struct evsel *on, *off; + const char *on_name, *off_name; bool discarding; bool show_on_off_events; };
[tip:perf/core] perf evswitch: Move switch logic to use in other tools
Commit-ID: 8829e56fa050998164e496d380cd69186ae9b8d0 Gitweb: https://git.kernel.org/tip/8829e56fa050998164e496d380cd69186ae9b8d0 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 11:00:11 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:24:31 -0300 perf evswitch: Move switch logic to use in other tools Now other tools that want switching can use an evswitch for that, just set it up and add it to the PERF_RECORD_SAMPLE processing function. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-b1trj1q97qwfv251l66q3...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 23 ++- tools/perf/util/Build | 1 + tools/perf/util/evswitch.c | 31 +++ tools/perf/util/evswitch.h | 2 ++ 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index fff02e0d70c4..e7b950e977a9 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1807,28 +1807,9 @@ static void process_event(struct perf_script *script, if (!show_event(sample, evsel, thread, al)) return; - if (script->evswitch.on && script->evswitch.discarding) { - if (script->evswitch.on != evsel) - return; - - script->evswitch.discarding = false; - - if (!script->evswitch.show_on_off_events) - return; - - goto print_it; - } - - if (script->evswitch.off && !script->evswitch.discarding) { - if (script->evswitch.off != evsel) - goto print_it; - - script->evswitch.discarding = true; + if (evswitch__discard(>evswitch, evsel)) + return; - if (!script->evswitch.show_on_off_events) - return; - } -print_it: ++es->samples; perf_sample__fprintf_start(sample, thread, evsel, diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 7cda749059a9..b922c8c297ca 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -9,6 +9,7 @@ perf-y += event.o perf-y += evlist.o perf-y += evsel.o perf-y += evsel_fprintf.o +perf-y += evswitch.o perf-y += find_bit.o perf-y += get_current_dir_name.o perf-y += kallsyms.o diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c new file mode 100644 index ..c87f988d81c8 --- /dev/null +++ b/tools/perf/util/evswitch.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo + +#include "evswitch.h" + +bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) +{ + if (evswitch->on && evswitch->discarding) { + if (evswitch->on != evsel) + return true; + + evswitch->discarding = false; + + if (!evswitch->show_on_off_events) + return true; + + return false; + } + + if (evswitch->off && !evswitch->discarding) { + if (evswitch->off != evsel) + return false; + + evswitch->discarding = true; + + if (!evswitch->show_on_off_events) + return true; + } + + return false; +} diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index bb88e8002f39..bae3a22ad719 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -13,4 +13,6 @@ struct evswitch { bool show_on_off_events; }; +bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel); + #endif /* __PERF_EVSWITCH_H */
[tip:perf/core] perf evswitch: Move struct to a separate header to use in other tools
Commit-ID: d2360442725fd29b3189887476c57059854a398c Gitweb: https://git.kernel.org/tip/d2360442725fd29b3189887476c57059854a398c Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 15 Aug 2019 10:37:24 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:24:24 -0300 perf evswitch: Move struct to a separate header to use in other tools Now that we see that the simple userspace-based "slicing" of events using delimiter events ("markers") works, lets move it to a separate header to make it available to other tools, next step will be having the switch on/off check done at the PERF_RECORD_SAMPLE processing function moved too. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-z0cyi9ifzlr37cedr9xzt...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 8 +--- tools/perf/util/evswitch.h | 16 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index b6eed0f7e835..fff02e0d70c4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -16,6 +16,7 @@ #include "util/trace-event.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/evswitch.h" #include "util/sort.h" #include "util/data.h" #include "util/auxtrace.h" @@ -1616,13 +1617,6 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample, return 0; } -struct evswitch { - struct evsel *on, -*off; - bool discarding; - bool show_on_off_events; -}; - struct perf_script { struct perf_tooltool; struct perf_session *session; diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h new file mode 100644 index ..bb88e8002f39 --- /dev/null +++ b/tools/perf/util/evswitch.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo +#ifndef __PERF_EVSWITCH_H +#define __PERF_EVSWITCH_H 1 + +#include + +struct evsel; + +struct evswitch { + struct evsel *on, *off; + bool discarding; + bool show_on_off_events; +}; + +#endif /* __PERF_EVSWITCH_H */
[tip:perf/core] perf script: Allow specifying event to switch off processing of other events
Commit-ID: dd41f660c03a6d8f2c2f3b2cccf50d8c4e06dd42 Gitweb: https://git.kernel.org/tip/dd41f660c03a6d8f2c2f3b2cccf50d8c4e06dd42 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 14 Aug 2019 16:51:28 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:24:16 -0300 perf script: Allow specifying event to switch off processing of other events Counterpart of --switch-on: # perf record -e sched:*,syscalls:sys_*_nanosleep sleep 1 [ perf record: Woken up 36 times to write data ] [ perf record: Captured and wrote 0.032 MB perf.data (10 samples) ] # # perf script :20918 20918 [002] 109866.143696:sched:sched_waking: comm=perf pid=20919 prio=120 target_cpu=001 :20918 20918 [002] 109866.143702:sched:sched_wakeup: perf:20919 [120] success=1 CPU:001 sleep 20919 [001] 109866.144081: sched:sched_process_exec: filename=/usr/bin/sleep pid=20919 old_pid=20919 sleep 20919 [001] 109866.144408: syscalls:sys_enter_nanosleep: rqtp: 0x7ffc2384fef0, rmtp: 0x sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412:sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568:sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586:sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 sleep 20919 [001] 109867.144614: syscalls:sys_exit_nanosleep: 0x0 sleep 20919 [001] 109867.144753: sched:sched_process_exit: comm=sleep pid=20919 prio=120 # # perf script --switch-off syscalls:sys_exit_nanosleep :20918 20918 [002] 109866.143696:sched:sched_waking: comm=perf pid=20919 prio=120 target_cpu=001 :20918 20918 [002] 109866.143702:sched:sched_wakeup: perf:20919 [120] success=1 CPU:001 sleep 20919 [001] 109866.144081: sched:sched_process_exec: filename=/usr/bin/sleep pid=20919 old_pid=20919 sleep 20919 [001] 109866.144408: syscalls:sys_enter_nanosleep: rqtp: 0x7ffc2384fef0, rmtp: 0x sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412:sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568:sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586:sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 sleep 20919 [001] 109867.144753: sched:sched_process_exit: comm=sleep pid=20919 prio=120 # # perf script --switch-on syscalls:sys_enter_nanosleep --switch-off syscalls:sys_exit_nanosleep sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412:sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568:sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586:sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 # # perf script --switch-on syscalls:sys_enter_nanosleep --switch-off syscalls:sys_exit_nanosleep --show-on-off sleep 20919 [001] 109866.144408: syscalls:sys_enter_nanosleep: rqtp: 0x7ffc2384fef0, rmtp: 0x sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412:sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568:sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586:sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 sleep 20919 [001] 109867.144614: syscalls:sys_exit_nanosleep: 0x0 # Now think about using this together with 'perf probe' to create custom on/off events in your app :-) Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-li3j01c4tmj9kw6ydsl8s...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 5 - tools/perf/builtin-script.c | 31 --- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 24eea68ee829..2599b057e47b 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -420,8 +420,11 @@ include::itrace.txt[] --switch-on EVENT_NAME:: Only consider
[tip:perf/core] perf script: Allow showing the --switch-on event
Commit-ID: 6469eb6dffeb44edfa3d4ca496b044b4a9c643b9 Gitweb: https://git.kernel.org/tip/6469eb6dffeb44edfa3d4ca496b044b4a9c643b9 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 14 Aug 2019 16:40:58 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:24:08 -0300 perf script: Allow showing the --switch-on event One may want to see the --switch-on event as well, allow for that, using the previous cset example: # perf script --switch-on syscalls:sys_enter_nanosleep --show-on-off sleep 13638 [001] 108237.582286: syscalls:sys_enter_nanosleep: rqtp: 0x7fff1948ac40, rmtp: 0x sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291: sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428: sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458: sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # # perf script --switch-on syscalls:sys_enter_nanosleep sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291: sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428: sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458: sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # Signed-off-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Cc: Florian Weimer Link: https://lkml.kernel.org/n/tip-0omwwoywj1v63gu8cz0tr...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 3 +++ tools/perf/builtin-script.c | 6 ++ 2 files changed, 9 insertions(+) diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 9936819aae1c..24eea68ee829 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -420,6 +420,9 @@ include::itrace.txt[] --switch-on EVENT_NAME:: Only consider events after this event is found. +--show-on-off-events:: + Show the --switch-on event too. + SEE ALSO linkperf:perf-record[1], linkperf:perf-script-perl[1], diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d0bc7ccaf7bf..fa0cc8b0eccc 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1619,6 +1619,7 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample, struct evswitch { struct evsel *on; bool discarding; + bool show_on_off_events; }; struct perf_script { @@ -1816,6 +1817,9 @@ static void process_event(struct perf_script *script, return; script->evswitch.discarding = false; + + if (!script->evswitch.show_on_off_events) + return; } ++es->samples; @@ -3554,6 +3558,8 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/modules"), OPT_STRING(0, "switch-on", _switch_on, "event", "Consider events from the first ocurrence of this event"), + OPT_BOOLEAN(0, "show-on-off-events", _on_off_events, + "Show the on/off switch events, used with --switch-on"), OPT_END() }; const char * const script_subcommands[] = { "record", "report", NULL };
[tip:perf/core] perf script: Allow specifying event to switch on processing of other events
Commit-ID: f90a24171a8179a29e5e1532fd5bb94e59b5380e Gitweb: https://git.kernel.org/tip/f90a24171a8179a29e5e1532fd5bb94e59b5380e Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 14 Aug 2019 16:20:13 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 15 Aug 2019 12:23:58 -0300 perf script: Allow specifying event to switch on processing of other events Sometime we want to only consider events after something happens, so allow discarding events till such events is found, e.g.: Record all scheduler tracepoints and the sys_enter_nanosleep syscall event for the 'sleep 1' workload: # perf record -e sched:*,syscalls:sys_enter_nanosleep sleep 1 [ perf record: Woken up 31 times to write data ] [ perf record: Captured and wrote 0.032 MB perf.data (10 samples) ] # So we have these events in the generated perf data file: # perf evlist sched:sched_kthread_stop sched:sched_kthread_stop_ret sched:sched_waking sched:sched_wakeup sched:sched_wakeup_new sched:sched_switch sched:sched_migrate_task sched:sched_process_free sched:sched_process_exit sched:sched_wait_task sched:sched_process_wait sched:sched_process_fork sched:sched_process_exec sched:sched_stat_wait sched:sched_stat_sleep sched:sched_stat_iowait sched:sched_stat_blocked sched:sched_stat_runtime sched:sched_pi_setprio sched:sched_move_numa sched:sched_stick_numa sched:sched_swap_numa sched:sched_wake_idle_without_ipi syscalls:sys_enter_nanosleep # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events # Then show all of the events that actually took place in this 'perf record' session: # perf script :13637 13637 [002] 108237.581529:sched:sched_waking: comm=perf pid=13638 prio=120 target_cpu=001 :13637 13637 [002] 108237.581537:sched:sched_wakeup: perf:13638 [120] success=1 CPU:001 sleep 13638 [001] 108237.581992: sched:sched_process_exec: filename=/usr/bin/sleep pid=13638 old_pid=13638 sleep 13638 [001] 108237.582286: syscalls:sys_enter_nanosleep: rqtp: 0x7fff1948ac40, rmtp: 0x sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291:sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428:sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458:sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # Now lets see only the ones that took place after a certain "marker": # perf script --switch-on syscalls:sys_enter_nanosleep sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291:sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428:sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458:sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-f1oo0ufdhrkx6nhy2lj1i...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 3 +++ tools/perf/builtin-script.c | 26 ++ 2 files changed, 29 insertions(+) diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index caaab28f8400..9936819aae1c 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -417,6 +417,9 @@ include::itrace.txt[] For itrace only show specified functions and their callees for itrace. Multiple functions can be separated by comma. +--switch-on EVENT_NAME:: + Only consider events after this event is found. + SEE ALSO linkperf:perf-record[1], linkperf:perf-script-perl[1], diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 31a529ec139f..d0bc7ccaf7bf 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1616,6 +1616,11 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample,
[tip:perf/core] perf ui: No need to set ui_browser to 1 twice
Commit-ID: 1cd8fa288eb83c1fe0dfa492b09d228a8d802fbf Gitweb: https://git.kernel.org/tip/1cd8fa288eb83c1fe0dfa492b09d228a8d802fbf Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 13 Aug 2019 12:07:14 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 14 Aug 2019 11:00:00 -0300 perf ui: No need to set ui_browser to 1 twice We need to do it only when fallbacking from GTK to the TUI. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-dda0acxqef1k72n9z4myj...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 44fe824e96cd..3bc7c9a6fae9 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -89,9 +89,9 @@ void setup_browser(bool fallback_to_pager) printf("GTK browser requested but could not find %s\n", PERF_GTK_DSO); sleep(1); + use_browser = 1; /* fall through */ case 1: - use_browser = 1; if (ui__init() == 0) break; /* fall through */
[tip:perf/core] perf evsel: Provide meaningful warning when trying to use 'aux_output' on older kernels
Commit-ID: acb9f2d4755a70e31343f99791aa43b05401b996 Gitweb: https://git.kernel.org/tip/acb9f2d4755a70e31343f99791aa43b05401b996 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 13 Aug 2019 11:06:38 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 14 Aug 2019 10:59:59 -0300 perf evsel: Provide meaningful warning when trying to use 'aux_output' on older kernels Just like we do with the 'write_backwards' feature: Before: # perf record -e {intel_pt/branch=0/,cycles/aux-output/ppp} uname Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (cycles/aux-output/ppp). /bin/dmesg | grep -i perf may provide additional information. # After: # perf record -e {intel_pt/branch=0/,cycles/aux-output/ppp} uname Error: The 'aux_output' feature is not supported, update the kernel. # Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lkml.kernel.org/n/tip-wgjsjroe1e150c0metgwm...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 11 +-- tools/perf/util/evsel.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 5da40511546b..0a33f7322ecc 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1738,7 +1738,8 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, int pid = -1, err; enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE; - if (perf_missing_features.write_backward && evsel->core.attr.write_backward) + if ((perf_missing_features.write_backward && evsel->core.attr.write_backward) || + (perf_missing_features.aux_output && evsel->core.attr.aux_output)) return -EINVAL; if (cpus == NULL) { @@ -1912,7 +1913,11 @@ try_fallback: * Must probe features in the order they were added to the * perf_event_attr interface. */ - if (!perf_missing_features.bpf_event && evsel->core.attr.bpf_event) { + if (!perf_missing_features.aux_output && evsel->core.attr.aux_output) { + perf_missing_features.aux_output = true; + pr_debug2("Kernel has no attr.aux_output support, bailing out\n"); + goto out_close; + } else if (!perf_missing_features.bpf_event && evsel->core.attr.bpf_event) { perf_missing_features.bpf_event = true; pr_debug2("switching off bpf_event\n"); goto fallback_missing_features; @@ -2926,6 +2931,8 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target, return scnprintf(msg, size, "clockid feature not supported."); if (perf_missing_features.clockid_wrong) return scnprintf(msg, size, "wrong clockid (%d).", clockid); + if (perf_missing_features.aux_output) + return scnprintf(msg, size, "The 'aux_output' feature is not supported, update the kernel."); break; default: break; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 8a316dd54cd0..9cd6e3ae479a 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -184,6 +184,7 @@ struct perf_missing_features { bool group_read; bool ksymbol; bool bpf_event; + bool aux_output; }; extern struct perf_missing_features perf_missing_features;
[tip:perf/core] perf ftrace: Improve error message about capability to use ftrace
Commit-ID: 73e5de70dca00344cb48e018131a4cadec0fabf0 Gitweb: https://git.kernel.org/tip/73e5de70dca00344cb48e018131a4cadec0fabf0 Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 12 Aug 2019 17:27:11 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 14 Aug 2019 10:59:59 -0300 perf ftrace: Improve error message about capability to use ftrace If we link against libcap, then we can state that CAP_SYS_ADMIN is needed, if not, fallback to telling the user it needs to be root, as was before linking against libcap. Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Igor Lubashev Cc: James Morris Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Link: https://lkml.kernel.org/n/tip-hhnbjdo8r67054of9zm2k...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-ftrace.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 01a5bb58eb04..1367bb5046a7 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -284,7 +284,13 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) }; if (!perf_cap__capable(CAP_SYS_ADMIN)) { - pr_err("ftrace only works for root!\n"); + pr_err("ftrace only works for %s!\n", +#ifdef HAVE_LIBCAP_SUPPORT + "users with the SYS_ADMIN capability" +#else + "root" +#endif + ); return -1; }
[tip:perf/core] perf tools: Add CAP_SYSLOG define for older systems
Commit-ID: 083c1359b0e03867a8c7effd21d4c0be3639f336 Gitweb: https://git.kernel.org/tip/083c1359b0e03867a8c7effd21d4c0be3639f336 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 13 Aug 2019 11:38:19 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 14 Aug 2019 10:59:59 -0300 perf tools: Add CAP_SYSLOG define for older systems Some of the systems I test don't have that define, provide it conditionally since we'll use it in the kptr_restrict checks in the next patch. Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Igor Lubashev Cc: James Morris Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Link: https://lkml.kernel.org/n/tip-dcize2v6jjab7tds5ngz9...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cap.h | 5 + 1 file changed, 5 insertions(+) diff --git a/tools/perf/util/cap.h b/tools/perf/util/cap.h index 10af94e473da..051dc590ceee 100644 --- a/tools/perf/util/cap.h +++ b/tools/perf/util/cap.h @@ -24,4 +24,9 @@ static inline bool perf_cap__capable(int cap __maybe_unused) #endif /* HAVE_LIBCAP_SUPPORT */ +/* For older systems */ +#ifndef CAP_SYSLOG +#define CAP_SYSLOG 34 +#endif + #endif /* __PERF_CAP_H */
[tip:perf/core] perf tools: Add NO_LIBCAP=1 to the minimal build test
Commit-ID: 97993bd6eb89bf08649c01d4d57453feca4314f8 Gitweb: https://git.kernel.org/tip/97993bd6eb89bf08649c01d4d57453feca4314f8 Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 12 Aug 2019 16:43:08 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 14 Aug 2019 10:59:59 -0300 perf tools: Add NO_LIBCAP=1 to the minimal build test We need to add these so that we test building without all selectable features. Acked-by: Igor Lubashev Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Link: https://lkml.kernel.org/n/tip-eknnvp22elznj0cl5a39h...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/make | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 5363a12a8b9b..70c48475896d 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -108,6 +108,7 @@ make_minimal+= NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 make_minimal+= NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 make_minimal+= NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 make_minimal+= NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1 +make_minimal+= NO_LIBCAP=1 # $(run) contains all available tests run := make_pure
[tip:perf/core] perf top: Collapse and resort all evsels in a group
Commit-ID: 40d81772dac45643cecc7add0e95356072265754 Gitweb: https://git.kernel.org/tip/40d81772dac45643cecc7add0e95356072265754 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 9 Aug 2019 16:44:34 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf top: Collapse and resort all evsels in a group And link them, i.e. find the hist entries in the non-leader events and link them to the ones in the leader. This should be the same thing already done for the 'perf report' case, but now we do it periodically. With this in place we get percentages in from the second overhead column on, not just on the first (the leader). Try it using: perf top --stdio -e '{cycles,instructions}' You should see something like: PerfTop: 20776 irqs/sec kernel:68.7% exact: 0.0% lost: 0/0 drop: 0/0 [cycles], (all, 8 CPUs) --- 4.44% 0.44% [kernel] [k] do_syscall_64 2.27% 0.17% [kernel] [k] entry_SYSCALL_64 1.73% 0.27% [kernel] [k] syscall_return_via_sysret 1.60% 0.91% [kernel] [k] _raw_spin_lock_irqsave 1.45% 3.53% libglib-2.0.so.0.6000.4 [.] g_string_insert_unichar 1.39% 0.21% [kernel] [k] copy_user_enhanced_fast_string 1.26% 1.15% [kernel] [k] psi_task_change 1.16% 0.14% libpixman-1.so.0.38.0[.] 0x0006f403 1.00% 0.32% [kernel] [k] __sched_text_start 0.97% 2.11% [kernel] [k] n_tty_write 0.96% 0.04% [kernel] [k] queued_spin_lock_slowpath 0.93% 0.88% [kernel] [k] menu_select 0.87% 0.14% [kernel] [k] try_to_wake_up 0.77% 0.10% libpixman-1.so.0.38.0[.] 0x0006f40b 0.73% 0.09% libpixman-1.so.0.38.0[.] 0x0006f413 0.69% 0.48% libc-2.29.so [.] __memmove_avx_unaligned_erms 0.68% 0.29% [kernel] [k] _raw_spin_lock_irq 0.61% 0.04% libpixman-1.so.0.38.0[.] 0x0006f423 0.60% 0.37% [kernel] [k] native_sched_clock 0.57% 0.23% [kernel] [k] do_idle 0.57% 0.23% [kernel] [k] __fget 0.56% 0.30% [kernel] [k] __switch_to_asm 0.56% 0.00% libc-2.29.so [.] __memset_avx2_erms 0.52% 0.32% [kernel] [k] _raw_spin_lock 0.49% 0.24% [kernel] [k] n_tty_poll 0.49% 0.54% libglib-2.0.so.0.6000.4 [.] g_mutex_lock 0.48% 0.62% [kernel] [k] _raw_spin_unlock_irqrestore 0.47% 0.27% [kernel] [k] __switch_to 0.47% 0.25% [kernel] [k] pick_next_task_fair 0.45% 0.17% [kernel] [k] filldir64 0.40% 0.16% [kernel] [k] update_rq_clock 0.39% 0.19% [kernel] [k] enqueue_task_fair # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-uw8cjeifxvjpkjp6x2iil...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 30 ++ 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 94e34853a238..78e7efc597a6 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -264,6 +264,30 @@ out_unlock: pthread_mutex_unlock(>lock); } +static void evlist__resort_hists(struct evlist *evlist) +{ + struct evsel *pos; + + evlist__for_each_entry(evlist, pos) { + struct hists *hists = evsel__hists(pos); + + hists__collapse_resort(hists, NULL); + + /* Non-group events are considered as leader */ + if (symbol_conf.event_group && + !perf_evsel__is_group_leader(pos)) { + struct hists *leader_hists = evsel__hists(pos->leader); + + hists__match(leader_hists, hists); + hists__link(leader_hists, hists); + } + } + + evlist__for_each_entry(evlist, pos) { + perf_evsel__output_resort(pos, NULL); + } +} + static void perf_top__print_sym_table(struct perf_top *top) { char bf[160]; @@ -304,8 +328,7 @@ static void perf_top__print_sym_table(struct perf_top *top) } } - hists__collapse_resort(hists, NULL); - perf_evsel__output_resort(evsel, NULL); + evlist__resort_hists(top->evlist); hists__output_recalc_col_len(hists, top->print_entries - printed); putchar('\n'); @@ -570,8 +593,7 @@ static void perf_top__sort_new_samples(void *arg) } } - hists__collapse_resort(hists, NULL); -
[tip:perf/core] perf hist: Remove dummy entries when finding real ones.
Commit-ID: 5f8b4d5d237a3e2e35509da4e63769ae5c82c085 Gitweb: https://git.kernel.org/tip/5f8b4d5d237a3e2e35509da4e63769ae5c82c085 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 9 Aug 2019 17:56:06 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf hist: Remove dummy entries when finding real ones. When he have an event group we have multiple struct hist instances, one per evsel, and in each of these hists we may have hist_entries that point to the same thing being observed, say a symbol, i.e. if we're looking at instructions and cycles, then we'll have one hist_entry in the "instructions" evsel and another in the "cycles" evsel. We need to link those to then show one column for each. When we're looking at some other pair of events, say instructions and cache misses, we may have just the "instructions" hist entry and not one for "cache misses", as instructions not necessarily generate cache misses, as the logic expects one hist_entry per evsel, we end up adding "dummy" hist_entries. This is enough for 'perf report', that does this matching operation (hists__match()) just once after processing all events, but for 'perf top', we do this at each refresh, so we may finally find events matching and then we need to trow away the dummies and link with the real events. So if we find a match, traverse the link of matches and trow away dummies for that hists. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-dwvtjqqifsbsczeb35q6m...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index d923a5bb7b48..8efbf58dc3d0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2436,7 +2436,7 @@ void hists__match(struct hists *leader, struct hists *other) { struct rb_root_cached *root; struct rb_node *nd; - struct hist_entry *pos, *pair; + struct hist_entry *pos, *pair, *pos_pair, *tmp_pair; if (symbol_conf.report_hierarchy) { /* hierarchy report always collapses entries */ @@ -2453,8 +2453,24 @@ void hists__match(struct hists *leader, struct hists *other) pos = rb_entry(nd, struct hist_entry, rb_node_in); pair = hists__find_entry(other, pos); - if (pair && list_empty(>pairs.node)) + if (pair && list_empty(>pairs.node)) { + list_for_each_entry_safe(pos_pair, tmp_pair, >pairs.head, pairs.node) { + if (pos_pair->hists == other) { + /* +* XXX maybe decayed entries can appear +* here? but then we would have use +* after free, as decayed entries are +* freed see hists__delete_entry +*/ + BUG_ON(!pos_pair->dummy); + list_del_init(_pair->pairs.node); + hist_entry__delete(pos_pair); + break; + } + } + hist_entry__add_pair(pair, pos); + } } }
[tip:perf/core] perf hists: Do not link a pair if already linked
Commit-ID: 7d1a5efa20dbfea97cb93b99c67ce5cd5c4a4dbc Gitweb: https://git.kernel.org/tip/7d1a5efa20dbfea97cb93b99c67ce5cd5c4a4dbc Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 7 Aug 2019 10:45:30 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf hists: Do not link a pair if already linked When we have multiple events in a group we link hist_entries in the non-leader evsel hists to the one in the leader that points to the same sorting criteria, in hists__match(). For 'perf report' we do this just once and then print the results, but for 'perf top' we need to look if this was already done in the previous refresh of the screen, so check for that and don't try to link again. This is part of having 'perf top' using the hists browser for showing multiple events in multiple columns. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-iwvb37rgb7upswhruwpcd...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 4297f56b1e05..d923a5bb7b48 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2453,7 +2453,7 @@ void hists__match(struct hists *leader, struct hists *other) pos = rb_entry(nd, struct hist_entry, rb_node_in); pair = hists__find_entry(other, pos); - if (pair) + if (pair && list_empty(>pairs.node)) hist_entry__add_pair(pair, pos); } }
[tip:perf/core] perf top: Set display thread COMM to help with debugging
Commit-ID: 1205a2719e52b6b52e0f9c0011554419da0377a0 Gitweb: https://git.kernel.org/tip/1205a2719e52b6b52e0f9c0011554419da0377a0 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 6 Aug 2019 11:20:42 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf top: Set display thread COMM to help with debugging When we want to attach just to the thread that updates the display it helps having its COMM stand out, so change it from the default "perf" to "perf-top-UI". Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-5w0hmlk3zfvysxvpsh763...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 4 1 file changed, 4 insertions(+) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1a4615a5f6c9..94e34853a238 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -601,6 +601,8 @@ static void *display_thread_tui(void *arg) */ unshare(CLONE_FS); + prctl(PR_SET_NAME, "perf-top-UI", 0, 0, 0); + perf_top__sort_new_samples(top); /* @@ -651,6 +653,8 @@ static void *display_thread(void *arg) */ unshare(CLONE_FS); + prctl(PR_SET_NAME, "perf-top-UI", 0, 0, 0); + display_setup_sig(); pthread__unblock_sigwinch(); repeat:
[tip:perf/core] perf test vfs_getname: Disable ~/.perfconfig to get default output
Commit-ID: 4fe94ce1c6ba678b5f12b94bb9996eea4fc99e85 Gitweb: https://git.kernel.org/tip/4fe94ce1c6ba678b5f12b94bb9996eea4fc99e85 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 30 Jul 2019 11:37:44 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf test vfs_getname: Disable ~/.perfconfig to get default output To get the expected output we have to ignore whatever changes the user has in its ~/.perfconfig file, so set PERF_CONFIG to /dev/null to achieve that. Before: # egrep 'trace|show_' ~/.perfconfig [trace] show_zeros = yes show_duration = no show_timestamp = no show_arg_names = no show_prefix = yes # echo $PERF_CONFIG # perf test "trace + vfs_getname" 70: Check open filename arg using perf trace + vfs_getname: FAILED! # export PERF_CONFIG=/dev/null # perf test "trace + vfs_getname" 70: Check open filename arg using perf trace + vfs_getname: Ok # After: # egrep 'trace|show_' ~/.perfconfig [trace] show_zeros = yes show_duration = no show_timestamp = no show_arg_names = no show_prefix = yes # echo $PERF_CONFIG # perf test "trace + vfs_getname" 70: Check open filename arg using perf trace + vfs_getname: Ok # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Taeung Song Link: https://lkml.kernel.org/n/tip-3up27pexg5i3exuzqrvt4...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/trace+probe_vfs_getname.sh | 4 1 file changed, 4 insertions(+) diff --git a/tools/perf/tests/shell/trace+probe_vfs_getname.sh b/tools/perf/tests/shell/trace+probe_vfs_getname.sh index 45d269b0157e..11cc2af13f2b 100755 --- a/tools/perf/tests/shell/trace+probe_vfs_getname.sh +++ b/tools/perf/tests/shell/trace+probe_vfs_getname.sh @@ -32,6 +32,10 @@ if [ $err -ne 0 ] ; then exit $err fi +# Do not use whatever ~/.perfconfig file, it may change the output +# via trace.{show_timestamp,show_prefix,etc} +export PERF_CONFIG=/dev/null + trace_open_vfs_getname err=$? rm -f ${file}
[tip:perf/core] perf config: Document the PERF_CONFIG environment variable
Commit-ID: 5de9e5fda05b580c036e1fec6e2d8bf78eb2ac9d Gitweb: https://git.kernel.org/tip/5de9e5fda05b580c036e1fec6e2d8bf78eb2ac9d Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 30 Jul 2019 11:30:37 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf config: Document the PERF_CONFIG environment variable There was a provision for setting this variable, but not the getenv("PERF_CONFIG") call to set it, as this was fixed in the previous cset, document that it can be used to ask for using an alternative .perfconfig file or to disable reading whatever file exists in the system or home directory, i.e. using: export PERF_CONFIG=/dev/null Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Taeung Song Link: https://lkml.kernel.org/n/tip-0u4o967hsk7j0o50zp9ct...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 4 1 file changed, 4 insertions(+) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index e4aa268d2e38..c599623a1f3d 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -40,6 +40,10 @@ The '$HOME/.perfconfig' file is used to store a per-user configuration. The file '$(sysconfdir)/perfconfig' can be used to store a system-wide default configuration. +One an disable reading config files by setting the PERF_CONFIG environment +variable to /dev/null, or provide an alternate config file by setting that +variable. + When reading or writing, the values are read from the system and user configuration files by default, and options '--system' and '--user' can be used to tell the command to read from or write to only that location.
[tip:perf/core] perf config: Honour $PERF_CONFIG env var to specify alternate .perfconfig
Commit-ID: 61a461fcbd62d42c29a1ea6a9cc3838ad9f49401 Gitweb: https://git.kernel.org/tip/61a461fcbd62d42c29a1ea6a9cc3838ad9f49401 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 30 Jul 2019 11:20:55 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf config: Honour $PERF_CONFIG env var to specify alternate .perfconfig We had this comment in Documentation/perf_counter/config.c, i.e. since when we got this from the git sources, but never really did that getenv("PERF_CONFIG"), do it now as I need to disable whatever ~/.perfconfig root has so that tests parsing tool output are done for the expected default output or that we specify an alternate config file that when read will make the tools produce expected output. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Taeung Song Fixes: 078006012401 ("perf_counter tools: add in basic glue from Git") Link: https://lkml.kernel.org/n/tip-jo209zac9rut0dz1rqvbd...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 97e2628ea5dd..d4e4d53e8b44 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -441,6 +441,9 @@ int main(int argc, const char **argv) srandom(time(NULL)); + /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ + config_exclusive_filename = getenv("PERF_CONFIG"); + err = perf_config(perf_default_config, NULL); if (err) return err;
[tip:perf/core] perf session: Avoid infinite loop when seeing invalid header.size
Commit-ID: 57fc032ad643ffd018d66bd4c1bd3a91de4841e8 Gitweb: https://git.kernel.org/tip/57fc032ad643ffd018d66bd4c1bd3a91de4841e8 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 30 Jul 2019 10:58:41 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 12 Aug 2019 16:26:02 -0300 perf session: Avoid infinite loop when seeing invalid header.size Vince reported that when fuzzing the userland perf tool with a bogus perf.data file he got into a infinite loop in 'perf report'. Changing the return of fetch_mmaped_event() to ERR_PTR(-EINVAL) for that case gets us out of that infinite loop. Reported-by: Vince Weaver Tested-by: Vince Weaver Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lkml.kernel.org/r/20190726211415.ge24...@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 11e6093c941b..b9fe71d11bf6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include @@ -1955,7 +1956,9 @@ fetch_mmaped_event(struct perf_session *session, /* We're not fetching the event so swap back again */ if (session->header.needs_swap) perf_event_header__bswap(>header); - return NULL; + pr_debug("%s: head=%#" PRIx64 " event->header_size=%#x, mmap_size=%#zx: fuzzed perf.data?\n", +__func__, head, event->header.size, mmap_size); + return ERR_PTR(-EINVAL); } return event; @@ -1973,6 +1976,9 @@ static int __perf_session__process_decomp_events(struct perf_session *session) while (decomp->head < decomp->size && !session_done()) { union perf_event *event = fetch_mmaped_event(session, decomp->head, decomp->size, decomp->data); + if (IS_ERR(event)) + return PTR_ERR(event); + if (!event) break; @@ -2072,6 +2078,9 @@ remap: more: event = fetch_mmaped_event(session, head, mmap_size, buf); + if (IS_ERR(event)) + return PTR_ERR(event); + if (!event) { if (mmaps[map_idx]) { munmap(mmaps[map_idx], mmap_size);
[tip:perf/urgent] perf annotate: Fix printing of unaugmented disassembled instructions from BPF
Commit-ID: 85127775a65fc58e69af0c44513937d471ccbe7b Gitweb: https://git.kernel.org/tip/85127775a65fc58e69af0c44513937d471ccbe7b Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 6 Aug 2019 11:24:09 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 8 Aug 2019 15:40:56 -0300 perf annotate: Fix printing of unaugmented disassembled instructions from BPF The code to disassemble BPF programs uses binutil's disassembling routines, and those use in turn fprintf to print to a memstream FILE, adding a newline at the end of each line, which ends up confusing the TUI routines called from: annotate_browser__write() annotate_line__write() annotate_browser__printf() ui_browser__vprintf() SLsmg_vprintf() The SLsmg_vprintf() function in the slang library gets confused with the terminating newline, so make the disasm_line__parse() function that parses the lines produced by the BPF specific disassembler (that uses binutil's libopcodes) and the lines produced by the objdump based disassembler used for everything else (and that doesn't adds this terminating newline) trim the end of the line in addition of the beginning. This way when disasm_line->ops.raw, i.e. for instructions without a special scnprintf() method, we'll not have that \n getting in the way of filling the screen right after the instruction with spaces to avoid leaving what was on the screen before and thus garbling the annotation screen, breaking scrolling, etc. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Song Liu Fixes: 6987561c9e86 ("perf annotate: Enable annotation of BPF programs") Link: https://lkml.kernel.org/n/tip-unbr5a5efakobfr6rhxq9...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index ac9ad2330f93..163536720149 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1122,7 +1122,7 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) goto out; (*rawp)[0] = tmp; - *rawp = skip_spaces(*rawp); + *rawp = strim(*rawp); return 0;
[tip:perf/core] perf trace: Put the per-syscall entry/exit prog_array BPF map infrastructure in place
Commit-ID: 3803a229312de539d2878f2fc5c6ee0202ce6728 Gitweb: https://git.kernel.org/tip/3803a229312de539d2878f2fc5c6ee0202ce6728 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 11:27:03 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Put the per-syscall entry/exit prog_array BPF map infrastructure in place I.e. look for "syscalls_sys_enter" and "syscalls_sys_exit" BPF maps of type PROG_ARRAY and populate it with the handlers as specified per syscall, for now only 'open' is wiring it to something, in time all syscalls that need to copy arguments entering a syscall or returning from one will set these to the right handlers, reusing when possible pre-existing ones. Next step is to use bpf_tail_call() into that. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-t0p4u43i9vbpzs1xtowna...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 76 ++-- tools/perf/examples/bpf/augmented_raw_syscalls.c | 14 + 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6cc696edf24a..fb8b8e78d7b5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0-only /* * builtin-trace.c * @@ -83,6 +82,10 @@ struct trace { int max; struct syscall *table; struct bpf_map *map; + struct { // per syscall BPF_MAP_TYPE_PROG_ARRAY + struct bpf_map *sys_enter, + *sys_exit; + } prog_array; struct { struct perf_evsel *sys_enter, *sys_exit, @@ -1619,6 +1622,22 @@ out_free: goto out; } +static __maybe_unused bool trace__syscall_enabled(struct trace *trace, int id) +{ + bool in_ev_qualifier; + + if (trace->ev_qualifier_ids.nr == 0) + return true; + + in_ev_qualifier = bsearch(, trace->ev_qualifier_ids.entries, + trace->ev_qualifier_ids.nr, sizeof(int), intcmp) != NULL; + + if (in_ev_qualifier) + return !trace->not_ev_qualifier; + + return trace->not_ev_qualifier; +} + /* * args is to be interpreted as a series of longs but we need to handle * 8-byte unaligned accesses. args points to raw_data within the event @@ -2784,6 +2803,18 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id) } } +static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id) +{ + struct syscall *sc = trace__syscall_info(trace, NULL, id); + return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->syscalls.unaugmented_prog); +} + +static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id) +{ + struct syscall *sc = trace__syscall_info(trace, NULL, id); + return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->syscalls.unaugmented_prog); +} + static void trace__init_bpf_map_syscall_args(struct trace *trace, int id, struct bpf_map_syscall_entry *entry) { struct syscall *sc = trace__syscall_info(trace, NULL, id); @@ -2837,10 +2868,8 @@ static int __trace__init_syscalls_bpf_map(struct trace *trace, bool enabled) int err = 0, key; for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { - if (enabled) { + if (enabled) trace__init_bpf_map_syscall_args(trace, key, ); - trace__init_syscall_bpf_progs(trace, key); - } err = bpf_map_update_elem(fd, , , BPF_ANY); if (err) @@ -2859,6 +2888,34 @@ static int trace__init_syscalls_bpf_map(struct trace *trace) return __trace__init_syscalls_bpf_map(trace, enabled); } + +static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace) +{ + int map_enter_fd = bpf_map__fd(trace->syscalls.prog_array.sys_enter), + map_exit_fd = bpf_map__fd(trace->syscalls.prog_array.sys_exit); + int err = 0, key; + + for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { + int prog_fd; + + if (!trace__syscall_enabled(trace, key)) + continue; + + trace__init_syscall_bpf_progs(trace, key); + + // It'll get at least the "!raw_syscalls:unaugmented" + prog_fd = trace__bpf_prog_sys_enter_fd(trace, key); + err = bpf_map_update_elem(map_enter_fd, , _fd, BPF_ANY); + if (err) + break; + prog_fd = trace__bpf_prog_sys_exit_fd(trace, key); + err =
[tip:perf/core] perf trace: Allow specifying the bpf prog to augment specific syscalls
Commit-ID: 6ff8fff45611e0b5ff4c0979cd0470b5cbc0a031 Gitweb: https://git.kernel.org/tip/6ff8fff45611e0b5ff4c0979cd0470b5cbc0a031 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 10:59:19 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Allow specifying the bpf prog to augment specific syscalls This is a step in the direction of being able to use a BPF_MAP_TYPE_PROG_ARRAY to handle syscalls that need to copy pointer payloads in addition to the raw tracepoint syscall args. There is a first example in tools/perf/examples/bpf/augmented_raw_syscalls.c for the 'open' syscall. Next step is to introduce the prog array map and use this 'open' augmenter, then use that augmenter in other syscalls that also only copy the first arg as a string, and then show how to use with a syscall that reads more than one filename, like 'rename', etc. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-pys4v57x5qqrybb4cery2...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 50 +++- tools/perf/examples/bpf/augmented_raw_syscalls.c | 23 +++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 07df952a0d7f..6cc696edf24a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -690,6 +690,10 @@ struct syscall_arg_fmt { static struct syscall_fmt { const char *name; const char *alias; + struct { + const char *sys_enter, + *sys_exit; + } bpf_prog_name; struct syscall_arg_fmt arg[6]; u8 nr_args; bool errpid; @@ -823,6 +827,7 @@ static struct syscall_fmt { { .name = "newfstatat", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, { .name = "open", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_open", }, .arg = { [1] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "open_by_handle_at", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, @@ -967,6 +972,10 @@ struct syscall { struct tep_event*tp_format; int nr_args; int args_size; + struct { + struct bpf_program *sys_enter, + *sys_exit; + } bpf_prog; boolis_exit; boolis_open; struct tep_format_field *args; @@ -2742,6 +2751,39 @@ static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, return bpf_object__find_program_by_title(trace->bpf_obj, name); } +static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, struct syscall *sc, + const char *prog_name, const char *type) +{ + struct bpf_program *prog; + + if (prog_name == NULL) + goto out_unaugmented; + + prog = trace__find_bpf_program_by_title(trace, prog_name); + if (prog != NULL) + return prog; + + pr_debug("Couldn't find BPF prog \"%s\" to associate with syscalls:sys_%s_%s, not augmenting it\n", +prog_name, type, sc->name); +out_unaugmented: + return trace->syscalls.unaugmented_prog; +} + +static void trace__init_syscall_bpf_progs(struct trace *trace, int id) +{ + struct syscall *sc = trace__syscall_info(trace, NULL, id); + + if (sc == NULL) + return; + + if (sc->fmt != NULL) { + sc->bpf_prog.sys_enter = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_enter, "enter"); + sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_exit, "exit"); + } else { + sc->bpf_prog.sys_enter = sc->bpf_prog.sys_exit = trace->syscalls.unaugmented_prog; + } +} + static void trace__init_bpf_map_syscall_args(struct trace *trace, int id, struct bpf_map_syscall_entry *entry) { struct syscall *sc = trace__syscall_info(trace, NULL, id); @@ -2773,8 +2815,10 @@ static int trace__set_ev_qualifier_bpf_filter(struct trace *trace) for (i = 0; i < trace->ev_qualifier_ids.nr; ++i) { int key = trace->ev_qualifier_ids.entries[i]; - if (value.enabled) + if (value.enabled) { trace__init_bpf_map_syscall_args(trace, key, ); + trace__init_syscall_bpf_progs(trace, key); + } err = bpf_map_update_elem(fd, , , BPF_EXIST); if (err) @@ -2793,8 +2837,10 @@ static int __trace__init_syscalls_bpf_map(struct trace *trace, bool enabled) int err = 0, key;
[tip:perf/core] perf trace: Add "sendfile64" alias to the "sendfile" syscall
Commit-ID: e4b00e930bf71ef32189716e6cb6b0565592f078 Gitweb: https://git.kernel.org/tip/e4b00e930bf71ef32189716e6cb6b0565592f078 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 17 Jul 2019 20:32:13 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:42 -0300 perf trace: Add "sendfile64" alias to the "sendfile" syscall We were looking in tracefs for: /sys/kernel/debug/tracing/events/syscalls/sys_enter_sendfile/format when what is there is just /sys/kernel/debug/tracing/events/syscalls/sys_enter_sendfile/format Its the same id, 40 in x86_64, so just add an alias and let the existing logic take care of that. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-km2hmg7hru6u4pawi5fi9...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 200fbe33d5de..ca28c48f812e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -895,6 +895,7 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_SECCOMP_OP,/* op */ }, [1] = { .scnprintf = SCA_SECCOMP_FLAGS, /* flags */ }, }, }, { .name = "select", .timeout = true, }, + { .name = "sendfile", .alias = "sendfile64", }, { .name = "sendmmsg", .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "sendmsg",
[tip:perf/core] perf trace: Reuse BPF augmenters from syscalls with similar args signature
Commit-ID: ad4153f964ebb756617e1586ba372156db0efeed Gitweb: https://git.kernel.org/tip/ad4153f964ebb756617e1586ba372156db0efeed Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 17 Jul 2019 18:27:33 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:42 -0300 perf trace: Reuse BPF augmenters from syscalls with similar args signature We have an augmenter for the "open" syscall, which has just one pointer, in the first argument, a "const char *", so any other syscall that has just one pointer and that is the first can reuse the "open" BPF augmenter program. Even more, syscalls that get two pointers with the first being a string can reuse "open"'s BPF augmenter till we have an augmenter that better matches that syscall with two pointers. With this the few augmenters we have, for open (first arg is a string), openat (2nd arg is a string), renameat (2nd and 4th are strings) can be reused by a lot of syscalls, ditto for "bind" reusing "connect" because both have the 2nd argument as a sockaddr and the 3rd as its len. Lets see how this makes the "bind" syscall reuse the "connect" BPF prog augmenter found in tools/perf/examples/bpf/augmented_raw_syscalls.c: # perf trace -e bind,connect systemctl restart sshd connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0 # Oh, it just connects to some daemon, so we better do it system wide and then stop/start sshd: # perf trace -e bind,connect systemctl/10124 connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0 sshd/10102 connect(7, { .family: PF_LOCAL, path: /dev/log }, 110) = 0 systemctl/10126 connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0 systemd/10128 ... [continued]: connect())= 0 (sshd)/10128 connect(3, { .family: PF_LOCAL, path: /run/systemd/journal/stdout }, 30) ... sshd/10128 bind(3, { .family: PF_NETLINK }, 12)= 0 sshd/10128 connect(4, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(3, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0 sshd/10128 connect(3, { .family: PF_UNSPEC }, 16) = 0 sshd/10128 connect(3, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0 sshd/10128 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 bind(4, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0 sshd/10128 connect(6, { .family: PF_LOCAL, path: /dev/log }, 110) = 0 sshd/10128 bind(6, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0 sshd/10128 connect(7, { .family: PF_LOCAL, path: /dev/log }, 110) = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-zfley2ghs4nim1uq4nu6e...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 154 - 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d8565c9a18a2..200fbe33d5de 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -709,7 +709,6 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ }, [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, }, { .name = "bind", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_connect", }, .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, @@ -879,7 +878,6 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "renameat2", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, [4] = { .scnprintf = SCA_RENAMEAT2_FLAGS, /* flags */ }, }, }, @@ -2910,6 +2908,94 @@ static int trace__init_syscalls_bpf_map(struct trace *trace) return __trace__init_syscalls_bpf_map(trace, enabled); } +static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace, struct syscall *sc) +{ + struct tep_format_field *field, *candidate_field; + int id; + + /* +* We're only interested in syscalls that have a pointer: +
[tip:perf/core] perf trace: Preallocate the syscall table
Commit-ID: 30a910d7d3e04dd920e4ca3e8dcabf10c67fb03e Gitweb: https://git.kernel.org/tip/30a910d7d3e04dd920e4ca3e8dcabf10c67fb03e Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 18 Jul 2019 20:19:30 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:42 -0300 perf trace: Preallocate the syscall table We'll continue reading its details from tracefs as we need it, but preallocate the whole thing otherwise we may realloc and end up with pointers to the previous buffer. I.e. in an upcoming algorithm we'll look for syscalls that have function signatures that are similar to a given syscall to see if we can reuse its BPF augmenter, so we may be at syscall 42, having a 'struct syscall' pointing to that slot in trace->syscalls.table[] and try to read the slot for an yet unread syscall, which would realloc that table to read the info for syscall 43, say, which would trigger a realoc of trace->syscalls.table[], and then the pointer we had for syscall 42 would be pointing to the previous block of memory. b00m. Cc: Adrian Hunter Cc: Brendan Gregg Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-m3cjzzifibs13imafhkk7...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 29 +++-- tools/perf/util/syscalltbl.c | 1 + tools/perf/util/syscalltbl.h | 1 + 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 765b998755ce..d8565c9a18a2 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -79,7 +79,6 @@ struct trace { struct perf_tooltool; struct syscalltbl *sctbl; struct { - int max; struct syscall *table; struct bpf_map *map; struct { // per syscall BPF_MAP_TYPE_PROG_ARRAY @@ -1493,21 +1492,10 @@ static int trace__read_syscall_info(struct trace *trace, int id) struct syscall *sc; const char *name = syscalltbl__name(trace->sctbl, id); - if (id > trace->syscalls.max) { - struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); - - if (nsyscalls == NULL) + if (trace->syscalls.table == NULL) { + trace->syscalls.table = calloc(trace->sctbl->syscalls.nr_entries, sizeof(*sc)); + if (trace->syscalls.table == NULL) return -ENOMEM; - - if (trace->syscalls.max != -1) { - memset(nsyscalls + trace->syscalls.max + 1, 0, - (id - trace->syscalls.max) * sizeof(*sc)); - } else { - memset(nsyscalls, 0, (id + 1) * sizeof(*sc)); - } - - trace->syscalls.table = nsyscalls; - trace->syscalls.max = id; } sc = trace->syscalls.table + id; @@ -1819,11 +1807,11 @@ static struct syscall *trace__syscall_info(struct trace *trace, err = -EINVAL; - if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) && - (err = trace__read_syscall_info(trace, id)) != 0) + if (id > trace->sctbl->syscalls.max_id) goto out_cant_read; - if (id > trace->syscalls.max) + if ((trace->syscalls.table == NULL || trace->syscalls.table[id].name == NULL) && + (err = trace__read_syscall_info(trace, id)) != 0) goto out_cant_read; if (trace->syscalls.table[id].name == NULL) { @@ -1838,7 +1826,7 @@ out_cant_read: if (verbose > 0) { char sbuf[STRERR_BUFSIZE]; fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err, str_error_r(-err, sbuf, sizeof(sbuf))); - if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) + if (id <= trace->sctbl->syscalls.max_id && trace->syscalls.table[id].name != NULL) fprintf(trace->output, "(%s)", trace->syscalls.table[id].name); fputs(" information\n", trace->output); } @@ -3922,9 +3910,6 @@ int cmd_trace(int argc, const char **argv) NULL }; struct trace trace = { - .syscalls = { - . max = -1, - }, .opts = { .target = { .uid = UINT_MAX, diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index 022a9c670338..820fceeb19a9 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c @@ -79,6 +79,7 @@ static int syscalltbl__init_native(struct syscalltbl *tbl) qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp); tbl->syscalls.nr_entries = nr_entries; + tbl->syscalls.max_id =
[tip:perf/core] perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages
Commit-ID: b8b1033fcaa091d82289698d7179e84e28cbd92a Gitweb: https://git.kernel.org/tip/b8b1033fcaa091d82289698d7179e84e28cbd92a Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 17 Jul 2019 20:21:37 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:42 -0300 perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages There are holes in syscall tables with IDs not associated with any syscall, mark those when trying to read information for syscalls, which could happen when iterating thru all syscalls from 0 to the highest numbered syscall id. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-cku9mpcrcsqaiq0jepu86...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5dae7b172291..765b998755ce 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -976,6 +976,7 @@ static struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias) * is_exit: is this "exit" or "exit_group"? * is_open: is this "open" or "openat"? To associate the fd returned in sys_exit with the pathname in sys_enter. * args_size: sum of the sizes of the syscall arguments, anything after that is augmented stuff: pathname for openat, etc. + * nonexistent: Just a hole in the syscall table, syscall id not allocated */ struct syscall { struct tep_event*tp_format; @@ -987,6 +988,7 @@ struct syscall { } bpf_prog; boolis_exit; boolis_open; + boolnonexistent; struct tep_format_field *args; const char *name; struct syscall_fmt *fmt; @@ -1491,9 +1493,6 @@ static int trace__read_syscall_info(struct trace *trace, int id) struct syscall *sc; const char *name = syscalltbl__name(trace->sctbl, id); - if (name == NULL) - return -EINVAL; - if (id > trace->syscalls.max) { struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); @@ -1512,8 +1511,15 @@ static int trace__read_syscall_info(struct trace *trace, int id) } sc = trace->syscalls.table + id; - sc->name = name; + if (sc->nonexistent) + return 0; + if (name == NULL) { + sc->nonexistent = true; + return 0; + } + + sc->name = name; sc->fmt = syscall_fmt__find(sc->name); snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); @@ -1811,14 +1817,21 @@ static struct syscall *trace__syscall_info(struct trace *trace, return NULL; } + err = -EINVAL; + if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) && (err = trace__read_syscall_info(trace, id)) != 0) goto out_cant_read; - err = -EINVAL; - if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL)) + if (id > trace->syscalls.max) goto out_cant_read; + if (trace->syscalls.table[id].name == NULL) { + if (trace->syscalls.table[id].nonexistent) + return NULL; + goto out_cant_read; + } + return >syscalls.table[id]; out_cant_read:
[tip:perf/core] perf trace: Forward error codes when trying to read syscall info
Commit-ID: 5d2bd88975117062766a48b5f36ce31d2c1a8269 Gitweb: https://git.kernel.org/tip/5d2bd88975117062766a48b5f36ce31d2c1a8269 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 17 Jul 2019 19:53:51 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:42 -0300 perf trace: Forward error codes when trying to read syscall info We iterate thru the syscall table produced from the kernel syscall tables reading info, propagate the error and add to the debug message. This helps in fixing further bugs, such as failing to read the "sendfile" syscall info when it really should try the aliasm "sendfile64". Problems reading syscall 40: 2 (No such file or directory)(sendfile) information # grep sendfile /tmp/build/perf/arch/x86/include/generated/asm/syscalls_64.c [40] = "sendfile", # I.e. in the tracefs format file for the syscall tracepoints we have it as sendfile64: # find /sys -type f -name format | grep sendfile /sys/kernel/debug/tracing/events/syscalls/sys_enter_sendfile64/format /sys/kernel/debug/tracing/events/syscalls/sys_exit_sendfile64/format # But as "sendfile" in the file used to build the syscall table used in perf: $ grep sendfile arch/x86/entry/syscalls/syscall_64.tbl 40common sendfile__x64_sys_sendfile64 $ So we need to add, in followup patches, aliases in 'perf trace' syscall data structures to cope with thie. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-w3eluap63x9je0bb8o3t7...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d403b09812d1..5dae7b172291 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1492,13 +1492,13 @@ static int trace__read_syscall_info(struct trace *trace, int id) const char *name = syscalltbl__name(trace->sctbl, id); if (name == NULL) - return -1; + return -EINVAL; if (id > trace->syscalls.max) { struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); if (nsyscalls == NULL) - return -1; + return -ENOMEM; if (trace->syscalls.max != -1) { memset(nsyscalls + trace->syscalls.max + 1, 0, @@ -1525,10 +1525,10 @@ static int trace__read_syscall_info(struct trace *trace, int id) } if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields)) - return -1; + return -ENOMEM; if (IS_ERR(sc->tp_format)) - return -1; + return PTR_ERR(sc->tp_format); sc->args = sc->tp_format->format.fields; /* @@ -1789,6 +1789,7 @@ typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel, static struct syscall *trace__syscall_info(struct trace *trace, struct perf_evsel *evsel, int id) { + int err = 0; if (id < 0) { @@ -1811,9 +1812,10 @@ static struct syscall *trace__syscall_info(struct trace *trace, } if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) && - trace__read_syscall_info(trace, id)) + (err = trace__read_syscall_info(trace, id)) != 0) goto out_cant_read; + err = -EINVAL; if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL)) goto out_cant_read; @@ -1821,7 +1823,8 @@ static struct syscall *trace__syscall_info(struct trace *trace, out_cant_read: if (verbose > 0) { - fprintf(trace->output, "Problems reading syscall %d", id); + char sbuf[STRERR_BUFSIZE]; + fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err, str_error_r(-err, sbuf, sizeof(sbuf))); if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) fprintf(trace->output, "(%s)", trace->syscalls.table[id].name); fputs(" information\n", trace->output);
[tip:perf/core] perf trace beauty: Add BPF augmenter for the 'rename' syscall
Commit-ID: cfa9ac73d6f9790f569959a729cbc9d52bff4270 Gitweb: https://git.kernel.org/tip/cfa9ac73d6f9790f569959a729cbc9d52bff4270 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 17 Jul 2019 11:47:37 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:42 -0300 perf trace beauty: Add BPF augmenter for the 'rename' syscall I.e. two strings: # perf trace -e rename systemd/1 rename("/run/systemd/units/.#invocation:dnf-makecache.service970761b7f2840dcc", "/run/systemd/units/invocation:dnf-makecache.service") = 0 systemd-journa/715 rename("/run/systemd/journal/streams/.#9:17539785BJDblc", "/run/systemd/journal/streams/9:17539785") = 0 mv/1936 rename("/tmp/build/perf/fd/.array.o.tmp", "/tmp/build/perf/fd/.array.o.cmd") = 0 sh/1949 rename("/tmp/build/perf/.cpu.o.tmp", "/tmp/build/perf/.cpu.o.cmd") = 0 mv/1954 rename("/tmp/build/perf/fs/.tracing_path.o.tmp", "/tmp/build/perf/fs/.tracing_path.o.cmd") = 0 mv/1963 rename("/tmp/build/perf/common-cmds.h+", "/tmp/build/perf/common-cmds.h") = 0 :1975/1975 rename("/tmp/build/perf/.exec-cmd.o.tmp", "/tmp/build/perf/.exec-cmd.o.cmd") = 0 mv/1979 rename("/tmp/build/perf/fs/.fs.o.tmp", "/tmp/build/perf/fs/.fs.o.cmd") = 0 mv/2005 rename("/tmp/build/perf/.debug.o.tmp", "/tmp/build/perf/.debug.o.cmd") = 0 mv/2012 rename("/tmp/build/perf/.str_error_r.o.tmp", "/tmp/build/perf/.str_error_r.o.cmd") = 0 mv/2019 rename("/tmp/build/perf/.help.o.tmp", "/tmp/build/perf/.help.o.cmd") = 0 mv/2031 rename("/tmp/build/perf/.trace-seq.o.tmp", "/tmp/build/perf/.trace-seq.o.cmd") = 0 make/2038 ... [continued]: rename()) = 0 :2038/2038 rename("/tmp/build/perf/.event-plugin.o.tmp", "/tmp/build/perf/.event-plugin.o.cmd") ... ar/2035 rename("/tmp/build/perf/stzwBX3a", "/tmp/build/perf/libapi.a") = 0 mv/2051 rename("/tmp/build/perf/.parse-utils.o.tmp", "/tmp/build/perf/.parse-utils.o.cmd") = 0 mv/2069 rename("/tmp/build/perf/.subcmd-config.o.tmp", "/tmp/build/perf/.subcmd-config.o.cmd") = 0 make/2080 rename("/tmp/build/perf/.parse-filter.o.tmp", "/tmp/build/perf/.parse-filter.o.cmd") = 0 mv/2099 rename("/tmp/build/perf/.pager.o.tmp", "/tmp/build/perf/.pager.o.cmd") = 0 :2124/2124 rename("/tmp/build/perf/.sigchain.o.tmp", "/tmp/build/perf/.sigchain.o.cmd") = 0 make/2140 rename("/tmp/build/perf/.event-parse.o.tmp", "/tmp/build/perf/.event-parse.o.cmd") = 0 mv/2164 rename("/tmp/build/perf/.kbuffer-parse.o.tmp", "/tmp/build/perf/.kbuffer-parse.o.cmd") = 0 sh/2174 rename("/tmp/build/perf/.run-command.o.tmp", "/tmp/build/perf/.run-command.o.cmd") = 0 mv/2190 rename("/tmp/build/perf/.tep_strerror.o.tmp", "/tmp/build/perf/.tep_strerror.o.cmd") = 0 :2261/2261 rename("/tmp/build/perf/.event-parse-api.o.tmp", "/tmp/build/perf/.event-parse-api.o.cmd") = 0 :2480/2480 rename("/tmp/build/perf/stLv3kG2", "/tmp/build/perf/libtraceevent.a") = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6hh2rl27uri6gsxhmk6q3...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 9c2228b01ee6..79787cf4fce9 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -197,6 +197,25 @@ int sys_enter_openat(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); } +SEC("!syscalls:sys_enter_rename") +int sys_enter_rename(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(_args_tmp, ); + const void *oldpath_arg = (const void *)args->args[0], + *newpath_arg = (const void *)args->args[1]; + unsigned int len = sizeof(augmented_args->args), oldpath_len; + +if (augmented_args == NULL) +return 1; /* Failure: don't filter */ + + oldpath_len = augmented_filename__read(_args->filename, oldpath_arg, sizeof(augmented_args->filename.value)); + len += oldpath_len + augmented_filename__read((void *)(_args->filename) + oldpath_len, newpath_arg, sizeof(augmented_args->filename.value)); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); +} + SEC("!syscalls:sys_enter_renameat") int sys_enter_renameat(struct syscall_enter_args *args) {
[tip:perf/core] perf trace beauty: Beautify bind's sockaddr arg
Commit-ID: 247dd65b909f1cd62a178febe3f6f8d5efdd7dd2 Gitweb: https://git.kernel.org/tip/247dd65b909f1cd62a178febe3f6f8d5efdd7dd2 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 17:38:26 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:42 -0300 perf trace beauty: Beautify bind's sockaddr arg By reusing the "connect" BPF collector. Testing it system wide and stopping/starting sshd: # perf trace -e bind LLVM: dumping /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o DNS Res~er #18/15132 bind(243, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(247, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(238, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/15132 bind(243, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/10327 bind(258, { .family: PF_NETLINK }, 12) = 0 :6507/6507 bind(24, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(238, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/15132 bind(242, { .family: PF_NETLINK }, 12) = 0 sshd/6514 bind(3, { .family: PF_NETLINK }, 12)= 0 sshd/6514 bind(5, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0 sshd/6514 bind(7, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0 DNS Res~er #18/10327 bind(229, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/15132 bind(231, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(229, { .family: PF_NETLINK }, 12) = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-m2hmxqrckxxw2ciki0tu8...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 010aa9e9a561..d403b09812d1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -710,8 +710,10 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ }, [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, }, { .name = "bind", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_connect", }, .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, - [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, }, }, + [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, + [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, { .name = "bpf", .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, { .name = "brk",.hexret = true,
[tip:perf/core] perf trace beauty: Beautify 'sendto's sockaddr arg
Commit-ID: 3c475bc021be1f5e0a00dc1a13dc85ce7924a7d6 Gitweb: https://git.kernel.org/tip/3c475bc021be1f5e0a00dc1a13dc85ce7924a7d6 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 17:33:39 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace beauty: Beautify 'sendto's sockaddr arg By just writing the collector in the augmented_raw_syscalls.c BPF program: # perf trace -e sendto ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 Socket Thread/3573 sendto(247, 0x7fb32d49c000, 120, NONE, { .family: PF_UNSPEC }, NULL) = 120 DNS Res~er #18/11374 sendto(242, 0x7fb342cfe420, 20, NONE, { .family: PF_NETLINK }, 0xc) = 20 DNS Res~er #18/11374 sendto(242, 0x7fb342cfcca0, 42, MSG_NOSIGNAL, { .family: PF_UNSPEC }, NULL) = 42 DNS Res~er #18/11374 sendto(242, 0x7fb342cf, 42, MSG_NOSIGNAL, { .family: PF_UNSPEC }, NULL) = 42 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 Socket Thread/3573 sendto(242, 0x7fb308bb1c08, 296, NONE, { .family: PF_UNSPEC }, NULL) = 296 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ^C # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-p0l0rlvq19v5zf8qc2x2i...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 21 + 1 file changed, 21 insertions(+) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index d7a292d7ee2f..9c2228b01ee6 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -142,6 +142,27 @@ int sys_enter_connect(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); } +SEC("!syscalls:sys_enter_sendto") +int sys_enter_sendto(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(_args_tmp, ); + const void *sockaddr_arg = (const void *)args->args[4]; + unsigned int socklen = args->args[5]; + unsigned int len = sizeof(augmented_args->args); + +if (augmented_args == NULL) +return 1; /* Failure: don't filter */ + + if (socklen > sizeof(augmented_args->saddr)) + socklen = sizeof(augmented_args->saddr); + + probe_read(_args->saddr, socklen, sockaddr_arg); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); +} + SEC("!syscalls:sys_enter_open") int sys_enter_open(struct syscall_enter_args *args) {
[tip:perf/core] perf trace beauty: Do not try to use the fd->pathname beautifier for bind/connect fd arg
Commit-ID: ef969ca64d04161ccbde2aaf8b0767f91a6d32ff Gitweb: https://git.kernel.org/tip/ef969ca64d04161ccbde2aaf8b0767f91a6d32ff Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 17:21:09 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace beauty: Do not try to use the fd->pathname beautifier for bind/connect fd arg Doesn't make sense and also we now beautify the sockaddr, which provides enough info: # trace -e close,socket,connec* ssh www.bla.com close(5)= 0 socket(PF_INET, SOCK_DGRAM|CLOEXEC|NONBLOCK, IPPROTO_IP) = 5 connect(5, { .family: PF_INET, port: 53, addr: 192.168.44.1 }, 16) = 0 close(5)= 0 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-h9drpb7ail808d2mh4n7t...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 94c33bb573c1..010aa9e9a561 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -710,7 +710,8 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ }, [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, }, { .name = "bind", - .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, }, }, + .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, + [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, }, }, { .name = "bpf", .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, { .name = "brk",.hexret = true, @@ -726,7 +727,8 @@ static struct syscall_fmt { { .name = "close", .arg = { [0] = { .scnprintf = SCA_CLOSE_FD, /* fd */ }, }, }, { .name = "connect", - .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, + .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, + [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, { .name = "epoll_ctl", .arg = { [1] = STRARRAY(op, epoll_ctl_ops), }, },
[tip:perf/core] perf trace beauty: Disable fd->pathname when close() not enabled
Commit-ID: 79d725cdf24dec7bfe7ad27b107f5cb06cd3785a Gitweb: https://git.kernel.org/tip/79d725cdf24dec7bfe7ad27b107f5cb06cd3785a Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 16:56:49 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace beauty: Disable fd->pathname when close() not enabled As we invalidate the fd->pathname table in the SCA_CLOSE_FD beautifier, if we don't have it we may end up keeping an fd->pathname association that then gets misprinted. The previous behaviour continues when the close() syscall is enabled, which may still be a a problem if we lose records (i.e. we may lose a 'close' record and then get that fd reused by socket()) but then the tool will notify that records are being lost and the user will be warned that some of the heuristics will fall apart. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-b7t6h8sq9lebemvfy2zh3...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 123d7efc12e8..94c33bb573c1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -127,6 +127,7 @@ struct trace { unsigned intmin_stack; int raw_augmented_syscalls_args_size; boolraw_augmented_syscalls; + boolfd_path_disabled; boolsort_events; boolnot_ev_qualifier; boollive; @@ -1178,7 +1179,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, { struct thread_trace *ttrace = thread__priv(thread); - if (ttrace == NULL) + if (ttrace == NULL || trace->fd_path_disabled) return NULL; if (fd < 0) @@ -2097,7 +2098,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, ret = perf_evsel__sc_tp_uint(evsel, ret, sample); - if (sc->is_open && ret >= 0 && ttrace->filename.pending_open) { + if (!trace->fd_path_disabled && sc->is_open && ret >= 0 && ttrace->filename.pending_open) { trace__set_fd_pathname(thread, ret, ttrace->filename.name); ttrace->filename.pending_open = false; ++trace->stats.vfs_getname; @@ -3206,7 +3207,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (trace->syscalls.prog_array.sys_enter) trace__init_syscalls_bpf_prog_array_maps(trace); - if (trace->ev_qualifier_ids.nr > 0) { err = trace__set_ev_qualifier_filter(trace); if (err < 0) @@ -3218,6 +3218,19 @@ static int trace__run(struct trace *trace, int argc, const char **argv) } } + /* +* If the "close" syscall is not traced, then we will not have the +* opportunity to, in syscall_arg__scnprintf_close_fd() invalidate the +* fd->pathname table and were ending up showing the last value set by +* syscalls opening a pathname and associating it with a descriptor or +* reading it from /proc/pid/fd/ in cases where that doesn't make +* sense. +* +* So just disable this beautifier (SCA_FD, SCA_FDAT) when 'close' is +* not in use. +*/ + trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(trace->sctbl, "close")); + err = perf_evlist__apply_filters(evlist, ); if (err < 0) goto out_error_apply_filters;
[tip:perf/core] perf trace beauty: Make connect's addrlen be printed as an int, not hex
Commit-ID: 1d86275225b4c9db3fb426e992886df5051f0047 Gitweb: https://git.kernel.org/tip/1d86275225b4c9db3fb426e992886df5051f0047 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 16:34:27 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace beauty: Make connect's addrlen be printed as an int, not hex # perf trace -e connec* ssh www.bla.com connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(4, { .family: PF_LOCAL, path: /var/lib/sss/pipes/nss }, 110) = 0 connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_INET, port: 53, addr: 192.168.44.1 }, 16) = 0 connect(5, { .family: PF_INET, port: 22, addr: 146.112.61.108 }, 16) = 0 connect(5, { .family: PF_INET6, port: 22, addr: :::146.112.61.108 }, 28) = 0 ^Cconnect(5, { .family: PF_INET, port: 22, addr: 146.112.61.108 }, 16) = -1 (unknown) (INTERNAL ERROR: strerror_r(512, [buf], 128)=22) # Argh, the SCA_FD needs to invalidate its cache when close is done... It works if the 'close' syscall is not filtered out ;-\ # perf trace -e close,connec* ssh www.bla.com close(3)= 0 close(3) = 0 close(3)= 0 close(3) = 0 close(3) = 0 close(3)= 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3)= 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3)= 0 close(3)= 0 close(3)= 0 close(3)= 0 close(4)= 0 close(3)= 0 close(3)= 0 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) close(3)= 0 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) close(3)= 0 close(3)= 0 close(3)= 0 close(3)= 0 connect(4, { .family: PF_LOCAL, path: /var/lib/sss/pipes/nss }, 110) = 0 ^C # Will disable this beautifier when 'close' is filtered out... Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ekuiciyx4znchvy95c8p1...@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 5258399a1c94..123d7efc12e8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -725,7 +725,8 @@ static struct syscall_fmt { { .name = "close", .arg = { [0] = { .scnprintf = SCA_CLOSE_FD, /* fd */ }, }, }, { .name = "connect", - .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, }, }, + .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, + [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, { .name = "epoll_ctl", .arg = { [1] = STRARRAY(op, epoll_ctl_ops), }, }, { .name = "eventfd2",
[tip:perf/core] perf augmented_raw_syscalls: Augment sockaddr arg in 'connect'
Commit-ID: 212b9ab6775b5f340de848b5b6eef6968ccf7f20 Gitweb: https://git.kernel.org/tip/212b9ab6775b5f340de848b5b6eef6968ccf7f20 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 16:28:14 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf augmented_raw_syscalls: Augment sockaddr arg in 'connect' We already had a beautifier for an augmented sockaddr payload, but that was when we were hooking on each syscalls:sys_enter_foo tracepoints, since now we're almost doing that by doing a tail call from raw_syscalls:sys_enter, its almost the same, we can reuse it straight away. # perf trace -e connec* ssh www.bla.com connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(4, { .family: PF_LOCAL, path: /var/lib/sss/pipes/nss }, 0x6e) = 0 connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_INET, port: 53, addr: 192.168.44.1 }, 0x10) = 0 connect(5, { .family: PF_INET, port: 22, addr: 146.112.61.108 }, 0x10) = 0 connect(5, { .family: PF_INET6, port: 22, addr: :::146.112.61.108 }, 0x1c) = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-5xkrbcpjsgnr3zt1aqdd7...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 35 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 77bb6a0edce3..d7a292d7ee2f 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -16,6 +16,7 @@ #include #include +#include #include /* bpf-output associated map */ @@ -69,10 +70,13 @@ pid_filter(pids_filtered); struct augmented_args_payload { struct syscall_enter_args args; - struct { - struct augmented_filename filename; - struct augmented_filename filename2; - }; + union { + struct { + struct augmented_filename filename, + filename2; + }; + struct sockaddr_storage saddr; + }; }; bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1); @@ -112,11 +116,32 @@ int syscall_unaugmented(struct syscall_enter_args *args) } /* - * This will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in + * These will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in * augmented_args_tmp what was read by that raw_syscalls:sys_enter and go * on from there, reading the first syscall arg as a string, i.e. open's * filename. */ +SEC("!syscalls:sys_enter_connect") +int sys_enter_connect(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(_args_tmp, ); + const void *sockaddr_arg = (const void *)args->args[1]; + unsigned int socklen = args->args[2]; + unsigned int len = sizeof(augmented_args->args); + +if (augmented_args == NULL) +return 1; /* Failure: don't filter */ + + if (socklen > sizeof(augmented_args->saddr)) + socklen = sizeof(augmented_args->saddr); + + probe_read(_args->saddr, socklen, sockaddr_arg); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); +} + SEC("!syscalls:sys_enter_open") int sys_enter_open(struct syscall_enter_args *args) {
[tip:perf/core] perf augmented_raw_syscalls: Rename augmented_args_filename to augmented_args_payload
Commit-ID: 6f563674935e6dc9e2190ce798c1917f51af6eed Gitweb: https://git.kernel.org/tip/6f563674935e6dc9e2190ce798c1917f51af6eed Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 15:33:20 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf augmented_raw_syscalls: Rename augmented_args_filename to augmented_args_payload It'll get other stuff in there than just filenames, starting with sockaddr for 'connect' and 'bind'. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-bsexidtsn91ehdpzcd6n5...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index df52d92e1c69..77bb6a0edce3 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -67,13 +67,15 @@ struct augmented_filename { pid_filter(pids_filtered); -struct augmented_args_filename { +struct augmented_args_payload { struct syscall_enter_args args; - struct augmented_filename filename; - struct augmented_filename filename2; + struct { + struct augmented_filename filename; + struct augmented_filename filename2; + }; }; -bpf_map(augmented_filename_map, PERCPU_ARRAY, int, struct augmented_args_filename, 1); +bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1); static inline unsigned int augmented_filename__read(struct augmented_filename *augmented_filename, @@ -111,7 +113,7 @@ int syscall_unaugmented(struct syscall_enter_args *args) /* * This will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in - * augmented_filename_map what was read by that raw_syscalls:sys_enter and go + * augmented_args_tmp what was read by that raw_syscalls:sys_enter and go * on from there, reading the first syscall arg as a string, i.e. open's * filename. */ @@ -119,7 +121,7 @@ SEC("!syscalls:sys_enter_open") int sys_enter_open(struct syscall_enter_args *args) { int key = 0; - struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(_filename_map, ); + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(_args_tmp, ); const void *filename_arg = (const void *)args->args[0]; unsigned int len = sizeof(augmented_args->args); @@ -136,7 +138,7 @@ SEC("!syscalls:sys_enter_openat") int sys_enter_openat(struct syscall_enter_args *args) { int key = 0; - struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(_filename_map, ); + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(_args_tmp, ); const void *filename_arg = (const void *)args->args[1]; unsigned int len = sizeof(augmented_args->args); @@ -153,7 +155,7 @@ SEC("!syscalls:sys_enter_renameat") int sys_enter_renameat(struct syscall_enter_args *args) { int key = 0; - struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(_filename_map, ); + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(_args_tmp, ); const void *oldpath_arg = (const void *)args->args[1], *newpath_arg = (const void *)args->args[3]; unsigned int len = sizeof(augmented_args->args), oldpath_len; @@ -171,7 +173,7 @@ int sys_enter_renameat(struct syscall_enter_args *args) SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { - struct augmented_args_filename *augmented_args; + struct augmented_args_payload *augmented_args; /* * We start len, the amount of data that will be in the perf ring * buffer, if this is not filtered out by one of pid_filter__has(), @@ -185,7 +187,7 @@ int sys_enter(struct syscall_enter_args *args) struct syscall *syscall; int key = 0; -augmented_args = bpf_map_lookup_elem(_filename_map, ); +augmented_args = bpf_map_lookup_elem(_args_tmp, ); if (augmented_args == NULL) return 1;
[tip:perf/core] perf trace: Look for default name for entries in the syscalls prog array
Commit-ID: 8b8044e5c9527cdfff3b0937f2d17470cc4acf9e Gitweb: https://git.kernel.org/tip/8b8044e5c9527cdfff3b0937f2d17470cc4acf9e Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 15:24:58 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Look for default name for entries in the syscalls prog array I.e. just look for "!syscalls:sys_enter_" or "exit_" plus the syscall name, that way we need just to add entries to the augmented_raw_syscalls.c BPF source to add handlers. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6xavwddruokp6ohs7tf4q...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c64f7c99db15..5258399a1c94 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -830,13 +830,11 @@ static struct syscall_fmt { { .name = "newfstatat", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, { .name = "open", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_open", }, .arg = { [1] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "open_by_handle_at", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "openat", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_openat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "perf_event_open", @@ -873,7 +871,6 @@ static struct syscall_fmt { { .name = "recvmsg", .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "renameat", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "renameat2", @@ -2778,12 +2775,27 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str { struct bpf_program *prog; - if (prog_name == NULL) + if (prog_name == NULL) { + char default_prog_name[256]; + scnprintf(default_prog_name, sizeof(default_prog_name), "!syscalls:sys_%s_%s", type, sc->name); + prog = trace__find_bpf_program_by_title(trace, default_prog_name); + if (prog != NULL) + goto out_found; + if (sc->fmt && sc->fmt->alias) { + scnprintf(default_prog_name, sizeof(default_prog_name), "!syscalls:sys_%s_%s", type, sc->fmt->alias); + prog = trace__find_bpf_program_by_title(trace, default_prog_name); + if (prog != NULL) + goto out_found; + } goto out_unaugmented; + } prog = trace__find_bpf_program_by_title(trace, prog_name); - if (prog != NULL) + + if (prog != NULL) { +out_found: return prog; + } pr_debug("Couldn't find BPF prog \"%s\" to associate with syscalls:sys_%s_%s, not augmenting it\n", prog_name, type, sc->name); @@ -2798,12 +2810,8 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id) if (sc == NULL) return; - if (sc->fmt != NULL) { - sc->bpf_prog.sys_enter = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_enter, "enter"); - sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_exit, "exit"); - } else { - sc->bpf_prog.sys_enter = sc->bpf_prog.sys_exit = trace->syscalls.unaugmented_prog; - } + sc->bpf_prog.sys_enter = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_enter : NULL, "enter"); + sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_exit : NULL, "exit"); } static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id)
[tip:perf/core] perf augmented_raw_syscalls: Support copying two string syscall args
Commit-ID: 8d5da2649d8211e63c5f65ccf8945f2c46a9c0b8 Gitweb: https://git.kernel.org/tip/8d5da2649d8211e63c5f65ccf8945f2c46a9c0b8 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 14:55:57 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf augmented_raw_syscalls: Support copying two string syscall args Starting with the renameat and renameat2 syscall, that both receive as second and fourth parameters a pathname: # perf trace -e rename* mv one ANOTHER LLVM: dumping /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o mv: cannot stat 'one': No such file or directory renameat2(AT_FDCWD, "one", AT_FDCWD, "ANOTHER", RENAME_NOREPLACE) = -1 ENOENT (No such file or directory) # Since the per CPU scratch buffer map has space for two maximum sized pathnames, the verifier is satisfied that there will be no overrun. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-x2uboyg5kx2wqeru28820...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 ++ tools/perf/examples/bpf/augmented_raw_syscalls.c | 20 2 files changed, 22 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a681b8c2ee4e..c64f7c99db15 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -873,9 +873,11 @@ static struct syscall_fmt { { .name = "recvmsg", .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "renameat", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "renameat2", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, [4] = { .scnprintf = SCA_RENAMEAT2_FLAGS, /* flags */ }, }, }, diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index ce308b9a317c..df52d92e1c69 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -70,6 +70,7 @@ pid_filter(pids_filtered); struct augmented_args_filename { struct syscall_enter_args args; struct augmented_filename filename; + struct augmented_filename filename2; }; bpf_map(augmented_filename_map, PERCPU_ARRAY, int, struct augmented_args_filename, 1); @@ -148,6 +149,25 @@ int sys_enter_openat(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); } +SEC("!syscalls:sys_enter_renameat") +int sys_enter_renameat(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(_filename_map, ); + const void *oldpath_arg = (const void *)args->args[1], + *newpath_arg = (const void *)args->args[3]; + unsigned int len = sizeof(augmented_args->args), oldpath_len; + +if (augmented_args == NULL) +return 1; /* Failure: don't filter */ + + oldpath_len = augmented_filename__read(_args->filename, oldpath_arg, sizeof(augmented_args->filename.value)); + len += oldpath_len + augmented_filename__read((void *)(_args->filename) + oldpath_len, newpath_arg, sizeof(augmented_args->filename.value)); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) {
[tip:perf/core] perf augmented_raw_syscalls: Switch to using BPF_MAP_TYPE_PROG_ARRAY
Commit-ID: bf134ca6c8eafd7ddc28840f767259b97e950bac Gitweb: https://git.kernel.org/tip/bf134ca6c8eafd7ddc28840f767259b97e950bac Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 12:34:59 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf augmented_raw_syscalls: Switch to using BPF_MAP_TYPE_PROG_ARRAY Trying to control what arguments to copy, which ones were strings, etc all from userspace via maps went nowhere, lots of difficulties to get the verifier satisfied, so use what the fine BPF guys designed for such a syscall handling mechanism: bpf_tail_call + BPF_MAP_TYPE_PROG_ARRAY. The series leading to this should have explained it thoroughly, but the end result, explained via gdb should help understand this: Breakpoint 1, syscall_arg__scnprintf_filename (bf=0xc002b1 "", size=2031, arg=0x7fff7970) at builtin-trace.c:1268 1268 { (gdb) n 1269 unsigned long ptr = arg->val; (gdb) n 1271 if (arg->augmented.args) (gdb) n 1272 return syscall_arg__scnprintf_augmented_string(arg, bf, size); (gdb) s syscall_arg__scnprintf_augmented_string (arg=0x7fff7970, bf=0xc002b1 "", size=2031) at builtin-trace.c:1251 1251 { (gdb) n 1252 struct augmented_arg *augmented_arg = arg->augmented.args; (gdb) n 1253 size_t printed = scnprintf(bf, size, "\"%.*s\"", augmented_arg->size, augmented_arg->value); (gdb) n 1258 int consumed = sizeof(*augmented_arg) + augmented_arg->size; (gdb) p bf $1 = 0xc002b1 "\"/etc/ld.so.cache\"" (gdb) bt #0 syscall_arg__scnprintf_augmented_string (arg=0x7fff7970, bf=0xc002b1 "\"/etc/ld.so.cache\"", size=2031) at builtin-trace.c:1258 #1 0x00492634 in syscall_arg__scnprintf_filename (bf=0xc002b1 "\"/etc/ld.so.cache\"", size=2031, arg=0x7fff7970) at builtin-trace.c:1272 #2 0x00493cd7 in syscall__scnprintf_val (sc=0xc0de68, bf=0xc002b1 "\"/etc/ld.so.cache\"", size=2031, arg=0x7fff7970, val=140737354091036) at builtin-trace.c:1689 #3 0x0049404f in syscall__scnprintf_args (sc=0xc0de68, bf=0xc002a7 "AT_FDCWD, \"/etc/ld.so.cache\"", size=2041, args=0x76cbf1ec "\234\377\377\377", augmented_args=0x76cbf21c, augmented_args_size=28, trace=0x7fffa170, thread=0xbff940) at builtin-trace.c:1756 #4 0x00494a97 in trace__sys_enter (trace=0x7fffa170, evsel=0xbe1900, event=0x76cbf1a0, sample=0x7fff7b00) at builtin-trace.c:1975 #5 0x00496ff1 in trace__handle_event (trace=0x7fffa170, event=0x76cbf1a0, sample=0x7fff7b00) at builtin-trace.c:2685 #6 0x00497edb in __trace__deliver_event (trace=0x7fffa170, event=0x76cbf1a0) at builtin-trace.c:3029 #7 0x0049801e in trace__deliver_event (trace=0x7fffa170, event=0x76cbf1a0) at builtin-trace.c:3056 #8 0x004988de in trace__run (trace=0x7fffa170, argc=2, argv=0x7fffd660) at builtin-trace.c:3258 #9 0x0049c2d3 in cmd_trace (argc=2, argv=0x7fffd660) at builtin-trace.c:4220 #10 0x004dcb6c in run_builtin (p=0xa18e00 , argc=5, argv=0x7fffd660) at perf.c:304 #11 0x004dcdd9 in handle_internal_command (argc=5, argv=0x7fffd660) at perf.c:356 #12 0x004dcf20 in run_argv (argcp=0x7fffd4bc, argv=0x7fffd4b0) at perf.c:400 #13 0x004dd28c in main (argc=5, argv=0x7fffd660) at perf.c:522 (gdb) (gdb) continue Continuing. openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 Now its a matter of automagically assigning the BPF programs copying syscall arg pointers to functions that are "open"-like (i.e. that need only the first syscall arg copied as a string), or "openat"-like (2nd arg, etc). End result in tool output: # perf trace -e open* ls /tmp/notthere LLVM: dumping /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = ls: cannot access '/tmp/notthere'-1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD,
[tip:perf/core] perf augmented_raw_syscalls: Add handler for "openat"
Commit-ID: 236dd5838871024d58d354ff8d0dab00ee59a867 Gitweb: https://git.kernel.org/tip/236dd5838871024d58d354ff8d0dab00ee59a867 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 12:31:10 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf augmented_raw_syscalls: Add handler for "openat" I.e. for a syscall that has its second argument being a string, its difficult these days to find 'open' being used in the wild :-) Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-yf3kbzirqrukd3fb2sp5q...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 1 + tools/perf/examples/bpf/augmented_raw_syscalls.c | 17 + 2 files changed, 18 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 872c9cc982a5..a681b8c2ee4e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -836,6 +836,7 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "openat", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_openat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "perf_event_open", diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index c66474a6ccf4..661936f90fe0 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -131,6 +131,23 @@ int sys_enter_open(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); } +SEC("!syscalls:sys_enter_openat") +int sys_enter_openat(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(_filename_map, ); + const void *filename_arg = (const void *)args->args[1]; + unsigned int len = sizeof(augmented_args->args); + +if (augmented_args == NULL) +return 1; /* Failure: don't filter */ + + len += augmented_filename__read(_args->filename, filename_arg, sizeof(augmented_args->filename.value)); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) {
[tip:perf/core] perf trace: Handle raw_syscalls:sys_enter just like the BPF_OUTPUT augmented event
Commit-ID: b119970aa541091e405373399690c24ead9d2920 Gitweb: https://git.kernel.org/tip/b119970aa541091e405373399690c24ead9d2920 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 16 Jul 2019 11:53:03 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Handle raw_syscalls:sys_enter just like the BPF_OUTPUT augmented event So, we use a PERF_COUNT_SW_BPF_OUTPUT to output the augmented sys_enter payload, i.e. to output more than just the raw syscall args, and if something goes wrong when handling an unfiltered syscall, we bail out and just return 1 in the bpf program associated with raw_syscalls:sys_enter, meaning, don't filter that tracepoint, in which case what will appear in the perf ring buffer isn't the BPF_OUTPUT event, but the original raw_syscalls:sys_enter event with its normal payload. Now that we're switching to using a bpf_tail_call + BPF_MAP_TYPE_PROG_ARRAY we're going to use this in the common case, so a bug where raw_syscalls:sys_enter wasn't being handled by trace__sys_enter() surfaced and for that case, instead of using the strace-like augmenter (trace__sys_enter()), we continued to use the normal generic tracepoint handler: (gdb) p evsel $2 = (struct perf_evsel *) 0xc03e40 (gdb) p evsel->name $3 = 0xbc56c0 "raw_syscalls:sys_enter" (gdb) p ((struct perf_evsel *) 0xc03e40)->name $4 = 0xbc56c0 "raw_syscalls:sys_enter" (gdb) p ((struct perf_evsel *) 0xc03e40)->handler $5 = (void *) 0x495eb3 This resulted in this: 0.027 raw_syscalls:sys_enter:NR 12 (0, 7fcfcac64c9b, 4d, 7fcfcac64c9b, 7fcfcac6ce00, 19) ... [continued]: brk())= 0x563b88677000 I.e. only the sys_exit tracepoint was being properly handled, but since the sys_enter went to the generic trace__event_handler() we printed it using libtraceevent's formatter instead of 'perf trace's strace-like one. Fix it by setting trace__sys_enter() as the handler for raw_syscalls:sys_enter and setup the tp_field tracepoint field accessors. Now, to test it we just make raw_syscalls:sys_enter return 1 right after checking if the pid is filtered, making it not use bpf_perf_output_event() but rather ask for the tracepoint not to be filtered and the result is the expected one: brk(NULL) = 0x556f42d6e000 I.e. raw_syscalls:sys_enter returns 1, gets handled by trace__sys_enter() and gets it combined with the raw_syscalls:sys_exit in a strace-like way. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-0mkocgk31nmy0odknegcb...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fb8b8e78d7b5..872c9cc982a5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4128,7 +4128,22 @@ int cmd_trace(int argc, const char **argv) if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) || perf_evsel__init_augmented_syscall_tp_args(augmented)) goto out; + /* +* Augmented is __augmented_syscalls__ BPF_OUTPUT event +* Above we made sure we can get from the payload the tp fields +* that we get from syscalls:sys_enter tracefs format file. +*/ augmented->handler = trace__sys_enter; + /* +* Now we do the same for the *syscalls:sys_enter event so that +* if we handle it directly, i.e. if the BPF prog returns 0 so +* as not to filter it, then we'll handle it just like we would +* for the BPF_OUTPUT one: +*/ + if (perf_evsel__init_augmented_syscall_tp(evsel, evsel) || + perf_evsel__init_augmented_syscall_tp_args(evsel)) + goto out; + evsel->handler = trace__sys_enter; } if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) {
[tip:perf/core] perf trace: Add BPF handler for unaugmented syscalls
Commit-ID: 5834da7f10917245d191032f76f132e62e57197c Gitweb: https://git.kernel.org/tip/5834da7f10917245d191032f76f132e62e57197c Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 15 Jul 2019 17:51:43 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Add BPF handler for unaugmented syscalls Will be used to assign to syscalls that don't need augmentation, i.e. those with just integer args. All syscalls will be in a BPF_MAP_TYPE_PROG_ARRAY, and the bpf_tail_call() keyed by the syscall id will either find nothing in place, which means the syscall is being filtered, or a function that will either add things like filenames to the ring buffer, right after the raw syscall args, or be this unaugmented handler that will just return 1, meaning don't filter the original raw_syscalls:sys_{enter,exit} tracepoint. For now it is not really being used, this is just leg work to break the patch into smaller pieces. It introduces a trace__find_bpf_program_by_title() helper that in turn uses libbpf's bpf_object__find_program_by_title() on the BPF object with the __augmented_syscalls__ map. "title" is how libbpf calls the SEC() argument for functions, i.e. the ELF section that follows a convention to specify what BPF program (a function with this SEC() marking) should be connected to which tracepoint, kprobes, etc. In perf anything that is of the form SEC("sys:event_name") will be connected to that tracepoint by perf's BPF loader. In this case its something that will be bpf_tail_call()ed from either the "raw_syscalls:sys_enter" or "raw_syscall:sys_exit" tracepoints, so its named "!raw_syscalls:unaugmented" to convey that idea, i.e. its not going to be directly attached to a tracepoint, thus it starts with a "!". Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-meucpjx2u0slpkayx56lx...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 16 tools/perf/examples/bpf/augmented_raw_syscalls.c | 6 ++ 2 files changed, 22 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9bd5ecd6a8dd..07df952a0d7f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -88,6 +88,7 @@ struct trace { *sys_exit, *augmented; } events; + struct bpf_program *unaugmented_prog; } syscalls; struct { struct bpf_map *map; @@ -2733,6 +2734,14 @@ out_enomem: } #ifdef HAVE_LIBBPF_SUPPORT +static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, const char *name) +{ + if (trace->bpf_obj == NULL) + return NULL; + + return bpf_object__find_program_by_title(trace->bpf_obj, name); +} + static void trace__init_bpf_map_syscall_args(struct trace *trace, int id, struct bpf_map_syscall_entry *entry) { struct syscall *sc = trace__syscall_info(trace, NULL, id); @@ -2814,6 +2823,12 @@ static int trace__init_syscalls_bpf_map(struct trace *trace __maybe_unused) { return 0; } + +static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace __maybe_unused, + const char *name __maybe_unused) +{ + return NULL; +} #endif // HAVE_LIBBPF_SUPPORT static int trace__set_ev_qualifier_filter(struct trace *trace) @@ -3914,6 +3929,7 @@ int cmd_trace(int argc, const char **argv) trace__set_bpf_map_filtered_pids(); trace__set_bpf_map_syscalls(); + trace.syscalls.unaugmented_prog = trace__find_bpf_program_by_title(, "!raw_syscalls:unaugmented"); } 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 2f822bb51717..48a536b1be6d 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -88,6 +88,12 @@ unsigned int augmented_filename__read(struct augmented_filename *augmented_filen return len; } +SEC("!raw_syscalls:unaugmented") +int syscall_unaugmented(struct syscall_enter_args *args) +{ + return 1; +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) {
[tip:perf/core] perf trace: Order -e syscalls table
Commit-ID: 83e69b92b10c2a8b75e1919b7074338f8bdbacaf Gitweb: https://git.kernel.org/tip/83e69b92b10c2a8b75e1919b7074338f8bdbacaf Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 15 Jul 2019 17:28:25 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Order -e syscalls table The ev_qualifier is an array with the syscall ids passed via -e on the command line, sort it as we'll search it when setting up the BPF_MAP_TYPE_PROG_ARRAY. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-c8hprylp3ai6e0z9burn2...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 8 1 file changed, 8 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index bfd739a321d1..9bd5ecd6a8dd 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1528,6 +1528,13 @@ static int trace__read_syscall_info(struct trace *trace, int id) return syscall__set_arg_fmts(sc); } +static int intcmp(const void *a, const void *b) +{ + const int *one = a, *another = b; + + return *one - *another; +} + static int trace__validate_ev_qualifier(struct trace *trace) { int err = 0; @@ -1591,6 +1598,7 @@ matches: } trace->ev_qualifier_ids.nr = nr_used; + qsort(trace->ev_qualifier_ids.entries, nr_used, sizeof(int), intcmp); out: if (printed_invalid_prefix) pr_debug("\n");
[tip:perf/core] perf trace: Look up maps just on the __augmented_syscalls__ BPF object
Commit-ID: 5ca0b7f5004a5f1a35c1cb47894790ad98e34ed1 Gitweb: https://git.kernel.org/tip/5ca0b7f5004a5f1a35c1cb47894790ad98e34ed1 Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 15 Jul 2019 17:03:10 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Look up maps just on the __augmented_syscalls__ BPF object We can conceivably have multiple BPF object files for other purposes, so better look just on the BPF object containing the __augmented_syscalls__ map for all things augmented_syscalls related. Cc: Adrian Hunter Cc: Brendan Gregg Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-3jt8knkuae9lt705r1lns...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 20 +++- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6aa080845a84..bfd739a321d1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3669,28 +3669,22 @@ static int trace__parse_cgroups(const struct option *opt, const char *str, int u return 0; } -static struct bpf_map *bpf__find_map_by_name(const char *name) +static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace, const char *name) { - struct bpf_object *obj, *tmp; - - bpf_object__for_each_safe(obj, tmp) { - struct bpf_map *map = bpf_object__find_map_by_name(obj, name); - if (map) - return map; - - } + if (trace->bpf_obj == NULL) + return NULL; - return NULL; + return bpf_object__find_map_by_name(trace->bpf_obj, name); } static void trace__set_bpf_map_filtered_pids(struct trace *trace) { - trace->filter_pids.map = bpf__find_map_by_name("pids_filtered"); + trace->filter_pids.map = trace__find_bpf_map_by_name(trace, "pids_filtered"); } static void trace__set_bpf_map_syscalls(struct trace *trace) { - trace->syscalls.map = bpf__find_map_by_name("syscalls"); + trace->syscalls.map = trace__find_bpf_map_by_name(trace, "syscalls"); } static int trace__config(const char *var, const char *value, void *arg) @@ -3924,7 +3918,7 @@ int cmd_trace(int argc, const char **argv) err = -1; if (map_dump_str) { - trace.dump.map = bpf__find_map_by_name(map_dump_str); + trace.dump.map = trace__find_bpf_map_by_name(, map_dump_str); if (trace.dump.map == NULL) { pr_err("ERROR: BPF map \"%s\" not found\n", map_dump_str); goto out;
[tip:perf/core] perf trace: Add pointer to BPF object containing __augmented_syscalls__
Commit-ID: c8c805707ed4c5d976210821da3242af8610a533 Gitweb: https://git.kernel.org/tip/c8c805707ed4c5d976210821da3242af8610a533 Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 15 Jul 2019 16:58:23 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf trace: Add pointer to BPF object containing __augmented_syscalls__ So that we can use it when looking for other components of that object file, such as other programs to add to the BPF_MAP_TYPE_PROG_ARRAY and use with bpf_tail_call(). Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-1ibmz7ouv6llqxajy7m8i...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4f0bbffee05f..6aa080845a84 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -96,6 +96,7 @@ struct trace { struct perf_evlist *evlist; struct machine *host; struct thread *current; + struct bpf_object *bpf_obj; struct cgroup *cgroup; u64 base_time; FILE*output; @@ -3895,6 +3896,20 @@ int cmd_trace(int argc, const char **argv) if (evsel) { trace.syscalls.events.augmented = evsel; + + evsel = perf_evlist__find_tracepoint_by_name(trace.evlist, "raw_syscalls:sys_enter"); + if (evsel == NULL) { + pr_err("ERROR: raw_syscalls:sys_enter not found in the augmented BPF object\n"); + goto out; + } + + if (evsel->bpf_obj == NULL) { + pr_err("ERROR: raw_syscalls:sys_enter not associated to a BPF object\n"); + goto out; + } + + trace.bpf_obj = evsel->bpf_obj; + trace__set_bpf_map_filtered_pids(); trace__set_bpf_map_syscalls(); }
[tip:perf/core] perf evsel: Store backpointer to attached bpf_object
Commit-ID: af4a0991f40a1e50e5caff0317f152df2c82bdeb Gitweb: https://git.kernel.org/tip/af4a0991f40a1e50e5caff0317f152df2c82bdeb Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 15 Jul 2019 16:22:57 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:41 -0300 perf evsel: Store backpointer to attached bpf_object We may want to get to this bpf_object, to search for other BPF programs, etc. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-3y8hrb6lszjfi23vjlic3...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-loader.c | 4 ++-- tools/perf/util/bpf-loader.h | 2 +- tools/perf/util/evsel.c| 1 + tools/perf/util/evsel.h| 3 +++ tools/perf/util/parse-events.c | 3 ++- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index c61974a50aa5..6d0dfb777a79 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -763,7 +763,7 @@ int bpf__foreach_event(struct bpf_object *obj, if (priv->is_tp) { fd = bpf_program__fd(prog); - err = (*func)(priv->sys_name, priv->evt_name, fd, arg); + err = (*func)(priv->sys_name, priv->evt_name, fd, obj, arg); if (err) { pr_debug("bpf: tracepoint call back failed, stop iterate\n"); return err; @@ -788,7 +788,7 @@ int bpf__foreach_event(struct bpf_object *obj, return fd; } - err = (*func)(tev->group, tev->event, fd, arg); + err = (*func)(tev->group, tev->event, fd, obj, arg); if (err) { pr_debug("bpf: call back failed, stop iterate\n"); return err; diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h index 3f46856e3330..8c3441a4b72c 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -46,7 +46,7 @@ struct parse_events_term; #define PERF_BPF_PROBE_GROUP "perf_bpf_probe" typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event, - int fd, void *arg); + int fd, struct bpf_object *obj, void *arg); #ifdef HAVE_LIBBPF_SUPPORT struct bpf_object *bpf__prepare_load(const char *filename, bool source); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 52459dd5ad0c..7d1757a2ec46 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -234,6 +234,7 @@ void perf_evsel__init(struct perf_evsel *evsel, evsel->scale = 1.0; evsel->max_events = ULONG_MAX; evsel->evlist = NULL; + evsel->bpf_obj = NULL; evsel->bpf_fd = -1; INIT_LIST_HEAD(>node); INIT_LIST_HEAD(>config_terms); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index cad54e8ba522..b27935a6d36c 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -82,6 +82,8 @@ enum perf_tool_event { PERF_TOOL_DURATION_TIME = 1, }; +struct bpf_object; + /** struct perf_evsel - event selector * * @evlist - evlist this evsel is in, if it is in one. @@ -152,6 +154,7 @@ struct perf_evsel { char*group_name; boolcmdline_group_boundary; struct list_headconfig_terms; + struct bpf_object *bpf_obj; int bpf_fd; boolauto_merge_stats; boolmerged_stat; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index fac6b32ef94a..0540303e5e97 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -630,7 +630,7 @@ struct __add_bpf_event_param { struct list_head *head_config; }; -static int add_bpf_event(const char *group, const char *event, int fd, +static int add_bpf_event(const char *group, const char *event, int fd, struct bpf_object *obj, void *_param) { LIST_HEAD(new_evsels); @@ -672,6 +672,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, pr_debug("adding %s:%s to %p\n", group, event, pos); pos->bpf_fd = fd; + pos->bpf_obj = obj; } list_splice(_evsels, list); return 0;
[tip:perf/core] perf bpf: Do not attach a BPF prog to a tracepoint if its name starts with !
Commit-ID: 2620b7e3696a9470c7cda0a08e55813fd5e57e5c Gitweb: https://git.kernel.org/tip/2620b7e3696a9470c7cda0a08e55813fd5e57e5c Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 15 Jul 2019 15:29:34 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:40 -0300 perf bpf: Do not attach a BPF prog to a tracepoint if its name starts with ! With BPF_MAP_TYPE_PROG_ARRAY + bpf_tail_call() we want to have BPF programs, i.e. functions in a object file that perf's BPF loader shouldn't try to attach to anything, i.e. "!syscalls:sys_enter_open" should just stay there, not be attached to a tracepoint with that name, it'll be used by, for instance, 'perf trace' to associate with syscalls that copy, in addition to the syscall raw args, a filename pointed by the first arg, i.e. multiple syscalls that need copying the same pointer arg in the same way, as a filename, for instance, will share the same BPF program/function. Right now when perf's BPF loader sees a function with a name "sys:name" it'll look for a tracepoint and will associate that BPF program with it, say: SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { //SNIP } Will crate a perf_evsel tracepoint event and then associate with it that BPF program. This convention at some point will switch to the one used by the BPF loader in libbpf, but to experiment with BPF_MAP_TYPE_PROG_ARRAY in 'perf trace' lets do this, that will not require changing too much stuff. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-lk6dasjr1yf9rtvl292b2...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events.c | 9 + 1 file changed, 9 insertions(+) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 371ff3aee769..fac6b32ef94a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -639,6 +639,15 @@ static int add_bpf_event(const char *group, const char *event, int fd, struct list_head *list = param->list; struct perf_evsel *pos; int err; + /* +* Check if we should add the event, i.e. if it is a TP but starts with a '!', +* then don't add the tracepoint, this will be used for something else, like +* adding to a BPF_MAP_TYPE_PROG_ARRAY. +* +* See tools/perf/examples/bpf/augmented_raw_syscalls.c +*/ + if (group[0] == '!') + return 0; pr_debug("add bpf event %s:%s and attach bpf program %d\n", group, event, fd);
[tip:perf/core] perf include bpf: Add bpf_tail_call() prototype
Commit-ID: 941a7658e065e339ebdaf27b9a7702f9935d1d4a Gitweb: https://git.kernel.org/tip/941a7658e065e339ebdaf27b9a7702f9935d1d4a Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 15 Jul 2019 15:25:41 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:40 -0300 perf include bpf: Add bpf_tail_call() prototype Will be used together with BPF_MAP_TYPE_PROG_ARRAY in tools/perf/examples/bpf/augmented_raw_syscalls.c. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-pd1bpy8i31nta6jqwdex8...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/include/bpf/bpf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/include/bpf/bpf.h b/tools/perf/include/bpf/bpf.h index 2eac6d804b2d..b422aeef5339 100644 --- a/tools/perf/include/bpf/bpf.h +++ b/tools/perf/include/bpf/bpf.h @@ -45,6 +45,8 @@ struct btf_map_##name __attribute__((section(".maps." #name), used)) \ static int (*bpf_map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags) = (void *)BPF_FUNC_map_update_elem; static void *(*bpf_map_lookup_elem)(struct bpf_map *map, void *key) = (void *)BPF_FUNC_map_lookup_elem; +static void (*bpf_tail_call)(void *ctx, void *map, int index) = (void *)BPF_FUNC_tail_call; + #define SEC(NAME) __attribute__((section(NAME), used)) #define probe(function, vars) \
[tip:perf/urgent] tools headers UAPI: Sync if_link.h with the kernel
Commit-ID: e54599c93dbf487ef80ba2833c5760c22bd20c32 Gitweb: https://git.kernel.org/tip/e54599c93dbf487ef80ba2833c5760c22bd20c32 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 15:44:41 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 09:03:43 -0300 tools headers UAPI: Sync if_link.h with the kernel To pick the changes in: 07a4ddec3ce9 ("bonding: add an option to specify a delay between peer notifications") And silence this build warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h' differs from latest version at 'include/uapi/linux/if_link.h' Cc: Adrian Hunter Cc: David S. Miller Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Vincent Bernat Link: https://lkml.kernel.org/n/tip-3liw4exxh8goc0rq9xryl...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/if_link.h | 5 + 1 file changed, 5 insertions(+) diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h index 7d113a9602f0..4a8c02cafa9a 100644 --- a/tools/include/uapi/linux/if_link.h +++ b/tools/include/uapi/linux/if_link.h @@ -695,6 +695,7 @@ enum { IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */ IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */ IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */ + IFLA_VF_BROADCAST, /* VF broadcast */ __IFLA_VF_MAX, }; @@ -705,6 +706,10 @@ struct ifla_vf_mac { __u8 mac[32]; /* MAX_ADDR_LEN */ }; +struct ifla_vf_broadcast { + __u8 broadcast[32]; +}; + struct ifla_vf_vlan { __u32 vf; __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
[tip:perf/urgent] tools headers UAPI: Sync sched.h with the kernel
Commit-ID: c093de6bd3c50d3dd597ff9fa5cf7a30acbb3eb7 Gitweb: https://git.kernel.org/tip/c093de6bd3c50d3dd597ff9fa5cf7a30acbb3eb7 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 15:41:09 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 09:03:43 -0300 tools headers UAPI: Sync sched.h with the kernel To get the changes in: a509a7cd7974 ("sched/uclamp: Extend sched_setattr() to support utilization clamping") 1d6362fa0cfc ("sched/core: Allow sched_setattr() to use the current policy") 7f192e3cd316 ("fork: add clone3") And silence this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/sched.h' differs from latest version at 'include/uapi/linux/sched.h' diff -u tools/include/uapi/linux/sched.h include/uapi/linux/sched.h No changes in tools/ due to the above. Cc: Adrian Hunter Cc: Christian Brauner Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Patrick Bellasi Link: https://lkml.kernel.org/n/tip-mtrpsjrux5hgyr5uf8l1a...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/sched.h | 30 +- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h index ed4ee170bee2..b3105ac1381a 100644 --- a/tools/include/uapi/linux/sched.h +++ b/tools/include/uapi/linux/sched.h @@ -2,6 +2,8 @@ #ifndef _UAPI_LINUX_SCHED_H #define _UAPI_LINUX_SCHED_H +#include + /* * cloning flags: */ @@ -31,6 +33,20 @@ #define CLONE_NEWNET 0x4000 /* New network namespace */ #define CLONE_IO 0x8000 /* Clone io context */ +/* + * Arguments for the clone3 syscall + */ +struct clone_args { + __aligned_u64 flags; + __aligned_u64 pidfd; + __aligned_u64 child_tid; + __aligned_u64 parent_tid; + __aligned_u64 exit_signal; + __aligned_u64 stack; + __aligned_u64 stack_size; + __aligned_u64 tls; +}; + /* * Scheduling policies */ @@ -51,9 +67,21 @@ #define SCHED_FLAG_RESET_ON_FORK 0x01 #define SCHED_FLAG_RECLAIM 0x02 #define SCHED_FLAG_DL_OVERRUN 0x04 +#define SCHED_FLAG_KEEP_POLICY 0x08 +#define SCHED_FLAG_KEEP_PARAMS 0x10 +#define SCHED_FLAG_UTIL_CLAMP_MIN 0x20 +#define SCHED_FLAG_UTIL_CLAMP_MAX 0x40 + +#define SCHED_FLAG_KEEP_ALL(SCHED_FLAG_KEEP_POLICY | \ +SCHED_FLAG_KEEP_PARAMS) + +#define SCHED_FLAG_UTIL_CLAMP (SCHED_FLAG_UTIL_CLAMP_MIN | \ +SCHED_FLAG_UTIL_CLAMP_MAX) #define SCHED_FLAG_ALL (SCHED_FLAG_RESET_ON_FORK | \ SCHED_FLAG_RECLAIM | \ -SCHED_FLAG_DL_OVERRUN) +SCHED_FLAG_DL_OVERRUN | \ +SCHED_FLAG_KEEP_ALL| \ +SCHED_FLAG_UTIL_CLAMP) #endif /* _UAPI_LINUX_SCHED_H */
[tip:perf/urgent] tools headers UAPI: Sync usbdevice_fs.h with the kernels to get new ioctl
Commit-ID: 0f58163c9d5702efbc242d144fd038e54b4c6ad0 Gitweb: https://git.kernel.org/tip/0f58163c9d5702efbc242d144fd038e54b4c6ad0 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 15:31:25 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 09:03:43 -0300 tools headers UAPI: Sync usbdevice_fs.h with the kernels to get new ioctl To get the changes in: 6d101f24f1dd ("USB: add usbfs ioctl to retrieve the connection parameters") And address this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/usbdevice_fs.h' differs from latest version at 'include/uapi/linux/usbdevice_fs.h' diff -u tools/include/uapi/linux/usbdevice_fs.h include/uapi/linux/usbdevice_fs.h Which ends up autogenerating a ioctl_cmd->string table used by 'perf trace': $ tools/perf/trace/beauty/usbdevfs_ioctl.sh > before $ cp include/uapi/linux/usbdevice_fs.h tools/include/uapi/linux/usbdevice_fs.h $ tools/perf/trace/beauty/usbdevfs_ioctl.sh > after $ diff -u before after --- before 2019-07-26 15:26:55.513636844 -0300 +++ after 2019-07-26 15:29:11.650518677 -0300 @@ -23,6 +23,7 @@ [2] = "BULK", [30] = "DROP_PRIVILEGES", [31] = "GET_SPEED", + [32] = "CONNINFO_EX", [3] = "RESETEP", [4] = "SETINTERFACE", [5] = "SETCONFIGURATION", $ Now 'perf trace' ioctl beautifier will translate this new ioctl to a string and at some point will allow filtering the 'ioctl' syscall with something like this in a system wide strace-like sessin: # perf trace -e ioctl/cmd=USBDEVFS_CONNINFO_EX/ Cc: Adrian Hunter Cc: Dmitry Torokhov Cc: Greg Kroah-Hartman Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-tkdfbgzqypwco96b309c0...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/usbdevice_fs.h | 26 ++ 1 file changed, 26 insertions(+) diff --git a/tools/include/uapi/linux/usbdevice_fs.h b/tools/include/uapi/linux/usbdevice_fs.h index 964e87217be4..78efe870c2b7 100644 --- a/tools/include/uapi/linux/usbdevice_fs.h +++ b/tools/include/uapi/linux/usbdevice_fs.h @@ -76,6 +76,26 @@ struct usbdevfs_connectinfo { unsigned char slow; }; +struct usbdevfs_conninfo_ex { + __u32 size; /* Size of the structure from the kernel's */ + /* point of view. Can be used by userspace */ + /* to determine how much data can be */ + /* used/trusted. */ + __u32 busnum; /* USB bus number, as enumerated by the*/ + /* kernel, the device is connected to. */ + __u32 devnum; /* Device address on the bus. */ + __u32 speed;/* USB_SPEED_* constants from ch9.h*/ + __u8 num_ports; /* Number of ports the device is connected */ + /* to on the way to the root hub. It may */ + /* be bigger than size of 'ports' array so */ + /* userspace can detect overflows. */ + __u8 ports[7]; /* List of ports on the way from the root */ + /* hub to the device. Current limit in */ + /* USB specification is 7 tiers (root hub, */ + /* 5 intermediate hubs, device), which */ + /* gives at most 6 port entries. */ +}; + #define USBDEVFS_URB_SHORT_NOT_OK 0x01 #define USBDEVFS_URB_ISO_ASAP 0x02 #define USBDEVFS_URB_BULK_CONTINUATION 0x04 @@ -137,6 +157,7 @@ struct usbdevfs_hub_portinfo { #define USBDEVFS_CAP_REAP_AFTER_DISCONNECT 0x10 #define USBDEVFS_CAP_MMAP 0x20 #define USBDEVFS_CAP_DROP_PRIVILEGES 0x40 +#define USBDEVFS_CAP_CONNINFO_EX 0x80 /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ @@ -197,5 +218,10 @@ struct usbdevfs_streams { #define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams) #define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32) #define USBDEVFS_GET_SPEED _IO('U', 31) +/* + * Returns struct usbdevfs_conninfo_ex; length is variable to allow + * extending size of the data returned. + */ +#define USBDEVFS_CONNINFO_EX(len) _IOC(_IOC_READ, 'U', 32, len) #endif /* _UAPI_LINUX_USBDEVICE_FS_H */
[tip:perf/urgent] tools perf beauty: Fix usbdevfs_ioctl table generator to handle _IOC()
Commit-ID: 7ee526152db7a75d7b8713346dac76ffc3662b29 Gitweb: https://git.kernel.org/tip/7ee526152db7a75d7b8713346dac76ffc3662b29 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 15:29:56 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 09:03:42 -0300 tools perf beauty: Fix usbdevfs_ioctl table generator to handle _IOC() In addition to _IOW() and _IOR(), to handle this case: #define USBDEVFS_CONNINFO_EX(len) _IOC(_IOC_READ, 'U', 32, len) That will happen in the next sync of this header file. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-3br5e4t64e4lp0goo84ch...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/usbdevfs_ioctl.sh | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/perf/trace/beauty/usbdevfs_ioctl.sh b/tools/perf/trace/beauty/usbdevfs_ioctl.sh index 930b80f422e8..aa597ae53747 100755 --- a/tools/perf/trace/beauty/usbdevfs_ioctl.sh +++ b/tools/perf/trace/beauty/usbdevfs_ioctl.sh @@ -3,10 +3,13 @@ [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ +# also as: +# #define USBDEVFS_CONNINFO_EX(len) _IOC(_IOC_READ, 'U', 32, len) + printf "static const char *usbdevfs_ioctl_cmds[] = {\n" -regex="^#[[:space:]]*define[[:space:]]+USBDEVFS_(\w+)[[:space:]]+_IO[WR]{0,2}\([[:space:]]*'U'[[:space:]]*,[[:space:]]*([[:digit:]]+).*" -egrep $regex ${header_dir}/usbdevice_fs.h | egrep -v 'USBDEVFS_\w+32[[:space:]]' | \ - sed -r "s/$regex/\2 \1/g" | \ +regex="^#[[:space:]]*define[[:space:]]+USBDEVFS_(\w+)(\(\w+\))?[[:space:]]+_IO[CWR]{0,2}\([[:space:]]*(_IOC_\w+,[[:space:]]*)?'U'[[:space:]]*,[[:space:]]*([[:digit:]]+).*" +egrep "$regex" ${header_dir}/usbdevice_fs.h | egrep -v 'USBDEVFS_\w+32[[:space:]]' | \ + sed -r "s/$regex/\4 \1/g" | \ sort | xargs printf "\t[%s] = \"%s\",\n" printf "};\n\n" printf "#if 0\n"
[tip:perf/urgent] tools headers UAPI: Update tools's copy of drm.h headers
Commit-ID: 95dc663aa6382fec92674e748682cefeeb2bfc22 Gitweb: https://git.kernel.org/tip/95dc663aa6382fec92674e748682cefeeb2bfc22 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 15:00:24 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 09:03:42 -0300 tools headers UAPI: Update tools's copy of drm.h headers Picking the changes from: c5d3e39caa45 ("drm/i915: Engine discovery query") a88b6e4cbafd ("drm/i915: Allow specification of parallel execbuf") ee1136908e9b ("drm/i915/execlists: Virtual engine bonding") 6d06779e8672 ("drm/i915: Load balancing across a virtual engine") b81dde719439 ("drm/i915: Allow userspace to clone contexts on creation") 8319f44c0525 ("drm/i915: Re-expose SINGLE_TIMELINE flags for context creation") e620f7b3a263 ("drm/i915: Extend I915_CONTEXT_PARAM_SSEU to support local ctx->engine[]") 976b55f0e1db ("drm/i915: Allow a context to define its set of engines") 7f3f317a66ca ("drm/i915: Restore control over ppgtt for context creation ABI") 75b3f1cb50bd ("drm: Fix drm.h uapi header for GNU/kFreeBSD") Silencing these perf build warnings: Warning: Kernel ABI header at 'tools/include/uapi/drm/drm.h' differs from latest version at 'include/uapi/drm/drm.h' diff -u tools/include/uapi/drm/drm.h include/uapi/drm/drm.h Warning: Kernel ABI header at 'tools/include/uapi/drm/i915_drm.h' differs from latest version at 'include/uapi/drm/i915_drm.h' diff -u tools/include/uapi/drm/i915_drm.h include/uapi/drm/i915_drm.h Now 'perf trace' and other code that might use the tools/perf/trace/beauty autogenerated tables will be able to translate this new ioctl code into a string: $ tools/perf/trace/beauty/drm_ioctl.sh > before $ cp include/uapi/drm/i915_drm.h tools/include/uapi/drm/i915_drm.h $ tools/perf/trace/beauty/drm_ioctl.sh > after $ diff -u before after --- before 2019-07-26 13:02:22.052723640 -0300 +++ after 2019-07-26 13:02:35.354906036 -0300 @@ -163,4 +163,6 @@ [DRM_COMMAND_BASE + 0x37] = "I915_PERF_ADD_CONFIG", [DRM_COMMAND_BASE + 0x38] = "I915_PERF_REMOVE_CONFIG", [DRM_COMMAND_BASE + 0x39] = "I915_QUERY", + [DRM_COMMAND_BASE + 0x3a] = "I915_GEM_VM_CREATE", + [DRM_COMMAND_BASE + 0x3b] = "I915_GEM_VM_DESTROY", }; $ Cc: Adrian Hunter Cc: Chris Wilson Cc: Eric Anholt Cc: James Clarke Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Tvrtko Ursulin Link: https://lkml.kernel.org/n/tip-a9173whgu3h1vo24jgdg5...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/drm/drm.h | 1 + tools/include/uapi/drm/i915_drm.h | 209 +- 2 files changed, 207 insertions(+), 3 deletions(-) diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h index 661d73f9a919..8a5b2f8f8eb9 100644 --- a/tools/include/uapi/drm/drm.h +++ b/tools/include/uapi/drm/drm.h @@ -50,6 +50,7 @@ typedef unsigned int drm_handle_t; #else /* One of the BSDs */ +#include #include #include typedef int8_t __s8; diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h index 3a73f5316766..328d05e77d9f 100644 --- a/tools/include/uapi/drm/i915_drm.h +++ b/tools/include/uapi/drm/i915_drm.h @@ -136,6 +136,8 @@ enum drm_i915_gem_engine_class { struct i915_engine_class_instance { __u16 engine_class; /* see enum drm_i915_gem_engine_class */ __u16 engine_instance; +#define I915_ENGINE_CLASS_INVALID_NONE -1 +#define I915_ENGINE_CLASS_INVALID_VIRTUAL -2 }; /** @@ -355,6 +357,8 @@ typedef struct _drm_i915_sarea { #define DRM_I915_PERF_ADD_CONFIG 0x37 #define DRM_I915_PERF_REMOVE_CONFIG0x38 #define DRM_I915_QUERY 0x39 +#define DRM_I915_GEM_VM_CREATE 0x3a +#define DRM_I915_GEM_VM_DESTROY0x3b /* Must be kept compact -- no holes */ #define DRM_IOCTL_I915_INITDRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) @@ -415,6 +419,8 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config) #define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64) #define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query) +#define DRM_IOCTL_I915_GEM_VM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_CREATE, struct drm_i915_gem_vm_control) +#define DRM_IOCTL_I915_GEM_VM_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_VM_DESTROY, struct drm_i915_gem_vm_control) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -598,6 +604,12 @@ typedef struct drm_i915_irq_wait { */ #define I915_PARAM_MMAP_GTT_COHERENT 52 +/* + * Query whether DRM_I915_GEM_EXECBUFFER2 supports coordination of parallel + * execution
[tip:perf/urgent] tools headers UAPI: Update tools's copy of mman.h headers
Commit-ID: b830f94f7303a49d509d5b1bb34ecb2e648b23c4 Gitweb: https://git.kernel.org/tip/b830f94f7303a49d509d5b1bb34ecb2e648b23c4 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 12:49:00 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 09:02:58 -0300 tools headers UAPI: Update tools's copy of mman.h headers To pick up the changes from: 8aa3c927ec10 ("mm/mmap: move common defines to mman-common.h") 22fcea6f85f2 ("mm: move MAP_SYNC to asm-generic/mman-common.h") 0bf5f9492389 ("mm: fix the MAP_UNINITIALIZED flag") To address the following perf build warnings: Warning: Kernel ABI header at 'tools/include/uapi/asm-generic/mman-common.h' differs from latest version at 'include/uapi/asm-generic/mman-common.h' diff -u tools/include/uapi/asm-generic/mman-common.h include/uapi/asm-generic/mman-common.h Warning: Kernel ABI header at 'tools/include/uapi/asm-generic/mman.h' differs from latest version at 'include/uapi/asm-generic/mman.h' diff -u tools/include/uapi/asm-generic/mman.h include/uapi/asm-generic/mman.h That ends up just moving a bit the auto-generated code->string tables: $ tools/perf/trace/beauty/mmap_flags.sh > before $ cp include/uapi/asm-generic/mman.h tools/include/uapi/asm-generic/mman.h $ cp include/uapi/asm-generic/mman-common.h tools/include/uapi/asm-generic/mman-common.h $ tools/perf/trace/beauty/mmap_flags.sh > after $ diff -u before after --- before 2019-07-26 12:45:02.948335904 -0300 +++ after 2019-07-26 12:48:05.342893539 -0300 @@ -4,15 +4,15 @@ [ilog2(0x02) + 1] = "PRIVATE", [ilog2(0x10) + 1] = "FIXED", [ilog2(0x20) + 1] = "ANONYMOUS", + [ilog2(0x008000) + 1] = "POPULATE", + [ilog2(0x01) + 1] = "NONBLOCK", + [ilog2(0x02) + 1] = "STACK", + [ilog2(0x04) + 1] = "HUGETLB", + [ilog2(0x08) + 1] = "SYNC", [ilog2(0x10) + 1] = "FIXED_NOREPLACE", [ilog2(0x0100) + 1] = "GROWSDOWN", [ilog2(0x0800) + 1] = "DENYWRITE", [ilog2(0x1000) + 1] = "EXECUTABLE", [ilog2(0x2000) + 1] = "LOCKED", [ilog2(0x4000) + 1] = "NORESERVE", - [ilog2(0x8000) + 1] = "POPULATE", - [ilog2(0x1) + 1] = "NONBLOCK", - [ilog2(0x2) + 1] = "STACK", - [ilog2(0x4) + 1] = "HUGETLB", - [ilog2(0x8) + 1] = "SYNC", }; $ Cc: Adrian Hunter Cc: Aneesh Kumar K.V Cc: Christoph Hellwig Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-fzqvzni9megaurmsp0k4v...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/powerpc/include/uapi/asm/mman.h | 4 tools/arch/sparc/include/uapi/asm/mman.h | 4 tools/include/uapi/asm-generic/mman-common.h | 15 +-- tools/include/uapi/asm-generic/mman.h| 10 -- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/tools/arch/powerpc/include/uapi/asm/mman.h b/tools/arch/powerpc/include/uapi/asm/mman.h index f33105bc5ca6..8601d824a9c6 100644 --- a/tools/arch/powerpc/include/uapi/asm/mman.h +++ b/tools/arch/powerpc/include/uapi/asm/mman.h @@ -4,12 +4,8 @@ #define MAP_DENYWRITE 0x0800 #define MAP_EXECUTABLE 0x1000 #define MAP_GROWSDOWN 0x0100 -#define MAP_HUGETLB0x4 #define MAP_LOCKED 0x80 -#define MAP_NONBLOCK 0x1 #define MAP_NORESERVE 0x40 -#define MAP_POPULATE 0x8000 -#define MAP_STACK 0x2 #include /* MAP_32BIT is undefined on powerpc, fix it for perf */ #define MAP_32BIT 0 diff --git a/tools/arch/sparc/include/uapi/asm/mman.h b/tools/arch/sparc/include/uapi/asm/mman.h index 38920eed8cbf..7b94dccc843d 100644 --- a/tools/arch/sparc/include/uapi/asm/mman.h +++ b/tools/arch/sparc/include/uapi/asm/mman.h @@ -4,12 +4,8 @@ #define MAP_DENYWRITE 0x0800 #define MAP_EXECUTABLE 0x1000 #define MAP_GROWSDOWN 0x0200 -#define MAP_HUGETLB0x4 #define MAP_LOCKED 0x100 -#define MAP_NONBLOCK 0x1 #define MAP_NORESERVE 0x40 -#define MAP_POPULATE 0x8000 -#define MAP_STACK 0x2 #include /* MAP_32BIT is undefined on sparc, fix it for perf */ #define MAP_32BIT 0 diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h index abd238d0f7a4..63b1f506ea67 100644 --- a/tools/include/uapi/asm-generic/mman-common.h +++ b/tools/include/uapi/asm-generic/mman-common.h @@ -19,15 +19,18 @@ #define MAP_TYPE 0x0f/* Mask for type of mapping */ #define MAP_FIXED 0x10/* Interpret addr exactly */ #define MAP_ANONYMOUS 0x20/* don't use a file */ -#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED -# define MAP_UNINITIALIZED 0x400 /* For anonymous mmap, memory could be uninitialized */ -#else -# define MAP_UNINITIALIZED 0x0 /* Don't support this flag */ -#endif -/* 0x0100 - 0x8 flags are defined in asm-generic/mman.h */ +/* 0x0100 - 0x4000 flags
[tip:perf/urgent] tools headers UAPI: Update tools's copy of kvm.h headers
Commit-ID: e0d99c4d24fd8861da724b88ebd18a9fae8a2260 Gitweb: https://git.kernel.org/tip/e0d99c4d24fd8861da724b88ebd18a9fae8a2260 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 12:43:23 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Fri, 26 Jul 2019 12:43:23 -0300 tools headers UAPI: Update tools's copy of kvm.h headers Picking the changes from: 66bb8a065f5a ("KVM: x86: PMU Event Filter") f087a02941fe ("KVM: nVMX: Stash L1's CR3 in vmcs01.GUEST_CR3 on nested entry w/o EPT") 99adb567632b ("KVM: arm/arm64: Add save/restore support for firmware workaround state") Silencing this perf build warning: Warning: Kernel ABI header at 'tools/arch/arm/include/uapi/asm/kvm.h' differs from latest version at 'arch/arm/include/uapi/asm/kvm.h' diff -u tools/arch/arm/include/uapi/asm/kvm.h arch/arm/include/uapi/asm/kvm.h Warning: Kernel ABI header at 'tools/arch/arm64/include/uapi/asm/kvm.h' differs from latest version at 'arch/arm64/include/uapi/asm/kvm.h' diff -u tools/arch/arm64/include/uapi/asm/kvm.h arch/arm64/include/uapi/asm/kvm.h Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/vmx.h' differs from latest version at 'arch/x86/include/uapi/asm/vmx.h' diff -u tools/arch/x86/include/uapi/asm/vmx.h arch/x86/include/uapi/asm/vmx.h Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/kvm.h' differs from latest version at 'arch/x86/include/uapi/asm/kvm.h' diff -u tools/arch/x86/include/uapi/asm/kvm.h arch/x86/include/uapi/asm/kvm.h Warning: Kernel ABI header at 'tools/include/uapi/linux/kvm.h' differs from latest version at 'include/uapi/linux/kvm.h' diff -u tools/include/uapi/linux/kvm.h include/uapi/linux/kvm.h Now 'perf trace' and other code that might use the tools/perf/trace/beauty autogenerated tables will be able to translate this new ioctl code into a string: $ tools/perf/trace/beauty/kvm_ioctl.sh > before $ $ cp include/uapi/linux/kvm.h tools/include/uapi/linux/kvm.h $ tools/perf/trace/beauty/kvm_ioctl.sh > after $ diff -u before after --- before 2019-07-26 12:32:47.959220236 -0300 +++ after 2019-07-26 12:33:05.766464871 -0300 @@ -79,6 +79,7 @@ [0xac] = "SET_ONE_REG", [0xad] = "KVMCLOCK_CTRL", [0xb0] = "GET_REG_LIST", + [0xb2] = "SET_PMU_EVENT_FILTER", [0xb7] = "SMI", [0xba] = "MEMORY_ENCRYPT_OP", [0xbb] = "MEMORY_ENCRYPT_REG_REGION", $ Cc: Adrian Hunter Cc: Andre Przywara Cc: Brendan Gregg Cc: Eric Hankland Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Marc Zyngier Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Sean Christopherson Link: https://lkml.kernel.org/n/tip-py1gcmt6rboehlwg6zvag...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/arm/include/uapi/asm/kvm.h | 12 tools/arch/arm64/include/uapi/asm/kvm.h | 10 ++ tools/arch/x86/include/uapi/asm/kvm.h | 22 ++ tools/arch/x86/include/uapi/asm/vmx.h | 1 - tools/include/uapi/linux/kvm.h | 3 +++ 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h index 4602464ebdfb..a4217c1a5d01 100644 --- a/tools/arch/arm/include/uapi/asm/kvm.h +++ b/tools/arch/arm/include/uapi/asm/kvm.h @@ -214,6 +214,18 @@ struct kvm_vcpu_events { #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \ KVM_REG_ARM_FW | ((r) & 0x)) #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1KVM_REG_ARM_FW_REG(1) + /* Higher values mean better protection. */ +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL 0 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL 1 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED 2 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2KVM_REG_ARM_FW_REG(2) + /* Higher values mean better protection. */ +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL 0 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN1 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL 2 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED(1U << 4) /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index d819a3e8b552..9a507716ae2f 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -229,6 +229,16 @@ struct kvm_vcpu_events { #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ KVM_REG_ARM_FW | ((r) & 0x)) #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1KVM_REG_ARM_FW_REG(1) +#define
[tip:perf/urgent] tools include UAPI: Sync x86's syscalls_64.tbl and generic unistd.h to pick up clone3 and pidfd_open
Commit-ID: 820571af721990e354649368e641313f85a29976 Gitweb: https://git.kernel.org/tip/820571af721990e354649368e641313f85a29976 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 26 Jul 2019 12:31:28 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Fri, 26 Jul 2019 12:31:28 -0300 tools include UAPI: Sync x86's syscalls_64.tbl and generic unistd.h to pick up clone3 and pidfd_open 05a70a8ec287 ("unistd: protect clone3 via __ARCH_WANT_SYS_CLONE3") 8f3220a80654 ("arch: wire-up clone3() syscall") 7615d9e1780e ("arch: wire-up pidfd_open()") Silencing the following tools/perf build warnings 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 Warning: Kernel ABI header at 'tools/perf/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl' diff -u tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl Now 'perf trace -e pidfd*,clone*' will trace those syscalls as well as the others with those prefixes. $ diff -u /tmp/build/perf/arch/x86/include/generated/asm/syscalls_64.c.before /tmp/build/perf/arch/x86/include/generated/asm/syscalls_64.c --- /tmp/build/perf/arch/x86/include/generated/asm/syscalls_64.c.before 2019-07-26 12:24:55.020944201 -0300 +++ /tmp/build/perf/arch/x86/include/generated/asm/syscalls_64.c 2019-07-26 12:25:03.919047217 -0300 @@ -344,5 +344,7 @@ [431] = "fsconfig", [432] = "fsmount", [433] = "fspick", + [434] = "pidfd_open", + [435] = "clone3", }; -#define SYSCALLTBL_x86_64_MAX_ID 433 +#define SYSCALLTBL_x86_64_MAX_ID 435 $ Cc: Adrian Hunter Cc: Brendan Gregg Cc: Christian Brauner Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-0isnnqxtr1ihz6p8wzjiy...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/asm-generic/unistd.h | 8 +++- tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h index a87904daf103..1be0e798e362 100644 --- a/tools/include/uapi/asm-generic/unistd.h +++ b/tools/include/uapi/asm-generic/unistd.h @@ -844,9 +844,15 @@ __SYSCALL(__NR_fsconfig, sys_fsconfig) __SYSCALL(__NR_fsmount, sys_fsmount) #define __NR_fspick 433 __SYSCALL(__NR_fspick, sys_fspick) +#define __NR_pidfd_open 434 +__SYSCALL(__NR_pidfd_open, sys_pidfd_open) +#ifdef __ARCH_WANT_SYS_CLONE3 +#define __NR_clone3 435 +__SYSCALL(__NR_clone3, sys_clone3) +#endif #undef __NR_syscalls -#define __NR_syscalls 434 +#define __NR_syscalls 436 /* * 32 bit systems traditionally used different diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index b4e6f9e6204a..c29976eca4a8 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -355,6 +355,8 @@ 431common fsconfig__x64_sys_fsconfig 432common fsmount __x64_sys_fsmount 433common fspick __x64_sys_fspick +434common pidfd_open __x64_sys_pidfd_open +435common clone3 __x64_sys_clone3/ptregs # # x32-specific system call numbers start at 512 to avoid cache impact
[tip:perf/urgent] perf build: Do not use -Wshadow on gcc < 4.8
Commit-ID: 39e7317e37f7f0be366d1201c283f968c17268da Gitweb: https://git.kernel.org/tip/39e7317e37f7f0be366d1201c283f968c17268da Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 19 Jul 2019 15:34:30 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 23 Jul 2019 09:04:54 -0300 perf build: Do not use -Wshadow on gcc < 4.8 As it is too strict, see https://lkml.org/lkml/2006/11/28/253 and https://gcc.gnu.org/gcc-4.8/changes.html, that takes into account Linus's comments (search for Wshadow) for the reasoning about -Wshadow not being interesting before gcc 4.8. Acked-by: Andrii Nakryiko Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/r/20190719183417.gq3...@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/scripts/Makefile.include | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 495066bafbe3..ded7a950dc40 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -32,7 +32,6 @@ EXTRA_WARNINGS += -Wno-system-headers EXTRA_WARNINGS += -Wold-style-definition EXTRA_WARNINGS += -Wpacked EXTRA_WARNINGS += -Wredundant-decls -EXTRA_WARNINGS += -Wshadow EXTRA_WARNINGS += -Wstrict-prototypes EXTRA_WARNINGS += -Wswitch-default EXTRA_WARNINGS += -Wswitch-enum @@ -69,8 +68,16 @@ endif # will do for now and keep the above -Wstrict-aliasing=3 in place # in newer systems. # Needed for the __raw_cmpxchg in tools/arch/x86/include/asm/cmpxchg.h +# +# See https://lkml.org/lkml/2006/11/28/253 and https://gcc.gnu.org/gcc-4.8/changes.html, +# that takes into account Linus's comments (search for Wshadow) for the reasoning about +# -Wshadow not being interesting before gcc 4.8. + ifneq ($(filter 3.%,$(MAKE_VERSION)),) # make-3 EXTRA_WARNINGS += -fno-strict-aliasing +EXTRA_WARNINGS += -Wno-shadow +else +EXTRA_WARNINGS += -Wshadow endif ifneq ($(findstring $(MAKEFLAGS), w),w)
[tip:perf/urgent] perf probe: Avoid calling freeing routine multiple times for same pointer
Commit-ID: d95daf5accf4a72005daa13fbb1d1bd8709f2861 Gitweb: https://git.kernel.org/tip/d95daf5accf4a72005daa13fbb1d1bd8709f2861 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 18 Jul 2019 11:28:37 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 23 Jul 2019 09:04:41 -0300 perf probe: Avoid calling freeing routine multiple times for same pointer When perf_add_probe_events() we call cleanup_perf_probe_events() for the pev pointer it receives, then, as part of handling this failure the main 'perf probe' goes on and calls cleanup_params() and that will again call cleanup_perf_probe_events()for the same pointer, so just set nevents to zero when handling the failure of perf_add_probe_events() to avoid the double free. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-x8qgma4g813z96dvtw9w2...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-probe.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 6418782951a4..3d0ffd41fb55 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -698,6 +698,16 @@ __cmd_probe(int argc, const char **argv) ret = perf_add_probe_events(params.events, params.nevents); if (ret < 0) { + + /* +* When perf_add_probe_events() fails it calls +* cleanup_perf_probe_events(pevs, npevs), i.e. +* cleanup_perf_probe_events(params.events, params.nevents), which +* will call clear_perf_probe_event(), so set nevents to zero +* to avoid cleanup_params() to call clear_perf_probe_event() again +* on the same pevs. +*/ + params.nevents = 0; pr_err_with_code(" Error: Failed to add events.", ret); return ret; }
[tip:perf/urgent] perf probe: Set pev->nargs to zero after freeing pev->args entries
Commit-ID: df8350ed56a26f502a9636f37faf699a12ee906e Gitweb: https://git.kernel.org/tip/df8350ed56a26f502a9636f37faf699a12ee906e Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 18 Jul 2019 11:22:58 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 23 Jul 2019 09:04:25 -0300 perf probe: Set pev->nargs to zero after freeing pev->args entries So that, when perf_add_probe_events() fails, like in: # perf probe icmp_rcv:64 "type=icmph->type" Failed to find 'icmph' in this function. Error: Failed to add events. Segmentation fault (core dumped) # We don't segfault. clear_perf_probe_event() was zeroing the whole pev, and since the switch to zfree() for the members in the pev, that memset() was removed, which left nargs with its original value, in the above case 1. With the memset the same pev could be passed to clear_perf_probe_event() multiple times, since all it would have would be zeroes, and free() accepts zero, the loop would not happen and we would just memset it again to zeroes. Without it we got that segfault, so zero nargs to keep it like it was, next cset will avoid calling clear_perf_probe_event() for the same pevs in case of failure. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Fixes: d8f9da240495 ("perf tools: Use zfree() where applicable") Link: https://lkml.kernel.org/n/tip-802f2jypnwqsvyavvivs8...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 0c3b55d0617d..4acd3457d39d 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2219,6 +2219,7 @@ void clear_perf_probe_event(struct perf_probe_event *pev) field = next; } } + pev->nargs = 0; zfree(>args); }
[tip:perf/urgent] perf trace: Auto bump rlimit(MEMLOCK) for eBPF maps sake
Commit-ID: c3e78a3403dabcb7115c2fb7b538a1095d168cd5 Gitweb: https://git.kernel.org/tip/c3e78a3403dabcb7115c2fb7b538a1095d168cd5 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 9 Jul 2019 16:36:45 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 16:36:45 -0300 perf trace: Auto bump rlimit(MEMLOCK) for eBPF maps sake Circa v5.2 this started to fail: # perf trace -e /wb/augmented_raw_syscalls.o event syntax error: '/wb/augmented_raw_syscalls.o' \___ Operation not permitted (add -v to see detail) Run 'perf list' for a list of valid events Usage: perf trace [] [] or: perf trace [] -- [] or: perf trace record [] [] or: perf trace record [] -- [] -e, --eventevent/syscall selector. use 'perf list' to list available events # In verbose mode we some -EPERM when creating a BPF map: # perf trace -v -e /wb/augmented_raw_syscalls.o libbpf: failed to create map (name: '__augmented_syscalls__'): Operation not permitted libbpf: failed to load object '/wb/augmented_raw_syscalls.o' bpf: load objects failed: err=-1: (Operation not permitted) event syntax error: '/wb/augmented_raw_syscalls.o' \___ Operation not permitted (add -v to see detail) Run 'perf list' for a list of valid events Usage: perf trace [] [] or: perf trace [] -- [] or: perf trace record [] [] or: perf trace record [] -- [] -e, --eventevent/syscall selector. use 'perf list' to list available events # If we bumped 'ulimit -l 128' to get it from the 64k default to double that, it worked, so use the recently added rlimit__bump_memlock() helper: # perf trace -e /wb/augmented_raw_syscalls.o -e open*,*sleep sleep 1 0.000 ( 0.007 ms): sleep/28042 openat(dfd: CWD, filename: "/etc/ld.so.cache", flags: RDONLY|CLOEXEC) = 3 0.022 ( 0.004 ms): sleep/28042 openat(dfd: CWD, filename: "/lib64/libc.so.6", flags: RDONLY|CLOEXEC) = 3 0.201 ( 0.007 ms): sleep/28042 openat(dfd: CWD, filename: "", flags: RDONLY|CLOEXEC) = 3 0.241 (1000.421 ms): sleep/28042 nanosleep(rqtp: 0x7ffd6c3e6ed0) = 0 # Cc: Adrian Hunter Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-j6f2ioa6hj9dinzpjvlhc...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 1aa2ed096f65..4f0bbffee05f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -19,6 +19,7 @@ #include #include #include "util/bpf_map.h" +#include "util/rlimit.h" #include "builtin.h" #include "util/cgroup.h" #include "util/color.h" @@ -3864,6 +3865,15 @@ int cmd_trace(int argc, const char **argv) goto out; } + /* +* Parsing .perfconfig may entail creating a BPF event, that may need +* to create BPF maps, so bump RLIM_MEMLOCK as the default 64K setting +* is too small. This affects just this process, not touching the +* global setting. If it fails we'll get something in 'perf trace -v' +* to help diagnose the problem. +*/ + rlimit__bump_memlock(); + err = perf_config(trace__config, ); if (err) goto out;
[tip:perf/urgent] perf test: Auto bump rlimit(MEMLOCK) for BPF test sake
Commit-ID: d3280ce01e21a827daa50b0e9bdc8588c6f855d8 Gitweb: https://git.kernel.org/tip/d3280ce01e21a827daa50b0e9bdc8588c6f855d8 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 9 Jul 2019 16:27:01 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 16:27:01 -0300 perf test: Auto bump rlimit(MEMLOCK) for BPF test sake I noticed that the 'perf test bpf' was failing: # perf test bpf 41: BPF filter: 41.1: Basic BPF filtering : Skip 41.2: BPF pinning : Skip 41.3: BPF prologue generation : Skip 41.4: BPF relocation checker : Skip # ulimit -l 64 # Using verbose mode we get just a line bout -EPERF being returned from libbpf's bpf_load_program_xattr(), that ends up being used in 'perf test bpf' initial program loading capability query: Missing basic BPF support, skip this test: Operation not permitted Not that informative, but on a separate problem when creating BPF maps bumping rlimit(MEMLOCK) helped, so I tried it here as well, works: # ulimit -l 128 # perf test bpf 41: BPF filter: 41.1: Basic BPF filtering : Ok 41.2: BPF pinning : Ok 41.3: BPF prologue generation : Ok 41.4: BPF relocation checker : Ok # So use the recently added rlimit__bump_memlock() helper: # ulimit -l 64 # perf test bpf 41: BPF filter: 41.1: Basic BPF filtering : Ok 41.2: BPF pinning : Ok 41.3: BPF prologue generation : Ok 41.4: BPF relocation checker : Ok # ulimit -l 64 # I.e. the bumping of memlock is restricted to the 'perf test' instance, not changing the global value. Cc: Adrian Hunter Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-b9fubkhr4jm192lu7y8hg...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 66a82badc1d1..c3bec9d2c201 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -21,6 +21,7 @@ #include #include "string2.h" #include "symbol.h" +#include "util/rlimit.h" #include #include #include @@ -727,6 +728,11 @@ int cmd_test(int argc, const char **argv) if (skip != NULL) skiplist = intlist__new(skip); + /* +* Tests that create BPF maps, for instance, need more than the 64K +* default: +*/ + rlimit__bump_memlock(); return __cmd_test(argc, argv, skiplist); }
[tip:perf/urgent] perf tools: Introduce rlimit__bump_memlock() helper
Commit-ID: 4975223b8156c14f0537dcde1554f050fb4d29bf Gitweb: https://git.kernel.org/tip/4975223b8156c14f0537dcde1554f050fb4d29bf Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 9 Jul 2019 14:49:26 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 14:59:11 -0300 perf tools: Introduce rlimit__bump_memlock() helper Just like the BPF guys did when faced with failures with map creation, etc, i.e. their solution is: tools/testing/selftests/bpf/bpf_rlimit.h For perf use this function in 'perf test' and in 'perf trace'. Make it bump to 4 times the current value, if it fails twice the current value and if it still fails, warn that things like BPF map creation may fail, to help in diagnosing the problem. Cc: Adrian Hunter Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-muvqef2i7n6pzqbmu7tn2...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/Build| 1 + tools/perf/util/rlimit.c | 29 + tools/perf/util/rlimit.h | 6 ++ 3 files changed, 36 insertions(+) diff --git a/tools/perf/util/Build b/tools/perf/util/Build index d7e3b008a613..14f812bb07a7 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -20,6 +20,7 @@ perf-y += parse-events.o perf-y += perf_regs.o perf-y += path.o perf-y += print_binary.o +perf-y += rlimit.o perf-y += argv_split.o perf-y += rbtree.o perf-y += libstring.o diff --git a/tools/perf/util/rlimit.c b/tools/perf/util/rlimit.c new file mode 100644 index ..13521d392a22 --- /dev/null +++ b/tools/perf/util/rlimit.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: LGPL-2.1 */ + +#include "util/debug.h" +#include "util/rlimit.h" +#include +#include + +/* + * Bump the memlock so that we can get bpf maps of a reasonable size, + * like the ones used with 'perf trace' and with 'perf test bpf', + * improve this to some specific request if needed. + */ +void rlimit__bump_memlock(void) +{ + struct rlimit rlim; + + if (getrlimit(RLIMIT_MEMLOCK, ) == 0) { + rlim.rlim_cur *= 4; + rlim.rlim_max *= 4; + + if (setrlimit(RLIMIT_MEMLOCK, ) < 0) { + rlim.rlim_cur /= 2; + rlim.rlim_max /= 2; + + if (setrlimit(RLIMIT_MEMLOCK, ) < 0) + pr_debug("Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc\n"); + } + } +} diff --git a/tools/perf/util/rlimit.h b/tools/perf/util/rlimit.h new file mode 100644 index ..9f59d8e710a3 --- /dev/null +++ b/tools/perf/util/rlimit.h @@ -0,0 +1,6 @@ +#ifndef __PERF_RLIMIT_H_ +#define __PERF_RLIMIT_H_ +/* SPDX-License-Identifier: LGPL-2.1 */ + +void rlimit__bump_memlock(void); +#endif // __PERF_RLIMIT_H_
[tip:perf/urgent] perf metricgroup: Add missing list_del_init() when flushing egroups list
Commit-ID: acc7bfb3db9744c4a18c96fd6536069e8647cb11 Gitweb: https://git.kernel.org/tip/acc7bfb3db9744c4a18c96fd6536069e8647cb11 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 4 Jul 2019 12:20:21 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 10:13:27 -0300 perf metricgroup: Add missing list_del_init() when flushing egroups list So that at the end each of the entries have its list node struct cleared and the egroup list head ends emptied. Cc: Adrian Hunter Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-dxzj1ah350fy9ec0xbhb1...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/metricgroup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 0d8c840f88c0..416a9015405e 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -492,6 +492,7 @@ static void metricgroup__free_egroups(struct list_head *group_list) for (i = 0; i < eg->idnum; i++) zfree(>ids[i]); zfree(>ids); + list_del_init(>nd); free(eg); } }
[tip:perf/urgent] perf tools: Use list_del_init() more thorougly
Commit-ID: e56fbc9dc79ce0fdc49ffadd062214ddd02f65b6 Gitweb: https://git.kernel.org/tip/e56fbc9dc79ce0fdc49ffadd062214ddd02f65b6 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 4 Jul 2019 12:13:46 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 10:13:27 -0300 perf tools: Use list_del_init() more thorougly To allow for destructors to check if they're operating on a object still in a list, and to avoid going from use after free list entries into still valid, or even also other already removed from list entries. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-deh17ub44atyox3j90e6r...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-ftrace.c| 2 +- tools/perf/builtin-lock.c | 8 tools/perf/pmu-events/jevents.c| 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/ui/gtk/annotate.c | 2 +- tools/perf/util/annotate.c | 4 ++-- tools/perf/util/auxtrace.c | 4 ++-- tools/perf/util/bpf-loader.c | 2 +- tools/perf/util/call-path.c| 2 +- tools/perf/util/callchain.c| 10 +- tools/perf/util/db-export.c| 4 ++-- tools/perf/util/dso.c | 2 +- tools/perf/util/evsel.c| 2 +- tools/perf/util/hist.c | 4 ++-- tools/perf/util/ordered-events.c | 6 +++--- tools/perf/util/parse-events.c | 2 +- tools/perf/util/pmu.c | 2 +- tools/perf/util/probe-event.c | 2 +- tools/perf/util/s390-cpumsf.c | 2 +- tools/perf/util/srccode.c | 2 +- tools/perf/util/symbol-elf.c | 6 +++--- tools/perf/util/thread.c | 4 ++-- 22 files changed, 38 insertions(+), 38 deletions(-) diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 9c228c55e1fb..66d5a6658daf 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -431,7 +431,7 @@ static void delete_filter_func(struct list_head *head) struct filter_entry *pos, *tmp; list_for_each_entry_safe(pos, tmp, head, list) { - list_del(>list); + list_del_init(>list); free(pos); } } diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index c0be44e65e9d..574e30ec6d7c 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -454,7 +454,7 @@ broken: /* broken lock sequence, discard it */ ls->discard = 1; bad_hist[BROKEN_ACQUIRE]++; - list_del(>list); + list_del_init(>list); free(seq); goto end; default: @@ -515,7 +515,7 @@ static int report_lock_acquired_event(struct perf_evsel *evsel, /* broken lock sequence, discard it */ ls->discard = 1; bad_hist[BROKEN_ACQUIRED]++; - list_del(>list); + list_del_init(>list); free(seq); goto end; default: @@ -570,7 +570,7 @@ static int report_lock_contended_event(struct perf_evsel *evsel, /* broken lock sequence, discard it */ ls->discard = 1; bad_hist[BROKEN_CONTENDED]++; - list_del(>list); + list_del_init(>list); free(seq); goto end; default: @@ -639,7 +639,7 @@ static int report_lock_release_event(struct perf_evsel *evsel, ls->nr_release++; free_seq: - list_del(>list); + list_del_init(>list); free(seq); end: return 0; diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 287a6f10ca48..1a91a197cafb 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -407,7 +407,7 @@ static void free_arch_std_events(void) list_for_each_entry_safe(es, next, _std_events, list) { FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD); - list_del(>list); + list_del_init(>list); free(es); } } diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 744409dce65f..6cdab5f4812a 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -238,7 +238,7 @@ static void free_event_nodes(struct list_head *events) while (!list_empty(events)) { node = list_entry(events->next, struct event_node, list); - list_del(>list); + list_del_init(>list); free(node); } } diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index df49c9ba1785..3af87c18a914 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -152,7 +152,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym, gtk_container_add(GTK_CONTAINER(window), view);
[tip:perf/urgent] perf tools: Use zfree() where applicable
Commit-ID: d8f9da240495b50766239410f9b0c715ca506a67 Gitweb: https://git.kernel.org/tip/d8f9da240495b50766239410f9b0c715ca506a67 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 4 Jul 2019 12:06:20 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 10:13:27 -0300 perf tools: Use zfree() where applicable In places where the equivalent was already being done, i.e.: free(a); a = NULL; And in placs where struct members are being freed so that if we have some erroneous reference to its struct, then accesses to freed members will result in segfaults, which we can detect faster than use after free to areas that may still have something seemingly valid. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-jatyoofo5boc1bsvoig6b...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex-hash.c| 3 +- tools/perf/bench/futex-lock-pi.c | 3 +- tools/perf/builtin-record.c | 4 +-- tools/perf/builtin-stat.c| 4 +-- tools/perf/tests/dwarf-unwind.c | 5 ++-- tools/perf/tests/expr.c | 3 +- tools/perf/tests/mem2node.c | 3 +- tools/perf/tests/thread-map.c| 3 +- tools/perf/ui/browsers/res_sample.c | 6 ++-- tools/perf/ui/browsers/scripts.c | 4 +-- tools/perf/util/annotate.c | 3 +- tools/perf/util/auxtrace.c | 5 ++-- tools/perf/util/cgroup.c | 2 +- tools/perf/util/cputopo.c| 2 +- tools/perf/util/cs-etm.c | 5 ++-- tools/perf/util/data-convert-bt.c| 2 +- tools/perf/util/data.c | 2 +- tools/perf/util/env.c| 8 ++--- tools/perf/util/event.c | 2 +- tools/perf/util/header.c | 6 ++-- tools/perf/util/hist.c | 14 - tools/perf/util/jitdump.c| 7 ++--- tools/perf/util/llvm-utils.c | 3 +- tools/perf/util/machine.c| 4 +-- tools/perf/util/metricgroup.c| 9 +++--- tools/perf/util/probe-event.c| 51 +++- tools/perf/util/s390-cpumsf.c| 7 ++--- tools/perf/util/srccode.c| 9 +++--- tools/perf/util/stat-shadow.c| 3 +- tools/perf/util/stat.c | 2 +- tools/perf/util/symbol-elf.c | 10 +++ tools/perf/util/thread_map.c | 2 +- tools/perf/util/unwind-libunwind-local.c | 3 +- 33 files changed, 100 insertions(+), 99 deletions(-) diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index 9aa3a674829b..a80797763e1f 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "../util/stat.h" @@ -214,7 +215,7 @@ int bench_futex_hash(int argc, const char **argv) [i].futex[nfutexes-1], t); } - free(worker[i].futex); + zfree([i].futex); } print_summary(); diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 8e9c4753e304..d02330a69745 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "bench.h" #include "futex.h" @@ -217,7 +218,7 @@ int bench_futex_lock_pi(int argc, const char **argv) worker[i].tid, worker[i].futex, t); if (multi) - free(worker[i].futex); + zfree([i].futex); } print_summary(); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index dca55997934e..8779cee58185 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -11,7 +11,6 @@ #include "perf.h" #include "util/build-id.h" -#include "util/util.h" #include #include "util/parse-events.h" #include "util/config.h" @@ -54,6 +53,7 @@ #include #include #include +#include struct switch_output { bool enabled; @@ -1110,7 +1110,7 @@ record__switch_output(struct record *rec, bool at_exit) rec->switch_output.cur_file = n; if (rec->switch_output.filenames[n]) { remove(rec->switch_output.filenames[n]); - free(rec->switch_output.filenames[n]); + zfree(>switch_output.filenames[n]); } rec->switch_output.filenames[n] = new_filename; } else { diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index c72f4a0831a8..b55a534b4de0 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1586,7 +1586,7 @@ static void runtime_stat_delete(struct perf_stat_config *config)
[tip:perf/urgent] tools lib: Adopt zalloc()/zfree() from tools/perf
Commit-ID: 7f7c536f23e6afaa5d5d4b0e0958b0be8922491f Gitweb: https://git.kernel.org/tip/7f7c536f23e6afaa5d5d4b0e0958b0be8922491f Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 4 Jul 2019 11:32:27 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 10:13:26 -0300 tools lib: Adopt zalloc()/zfree() from tools/perf Eroding a bit more the tools/perf/util/util.h hodpodge header. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-natazosyn9rwjka25tvcn...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/zalloc.h| 12 tools/lib/zalloc.c | 15 +++ tools/perf/MANIFEST | 1 + tools/perf/arch/arm/annotate/instructions.c | 1 + tools/perf/arch/arm/util/auxtrace.c | 1 + tools/perf/arch/arm/util/cs-etm.c | 1 + tools/perf/arch/arm64/util/arm-spe.c| 1 + tools/perf/arch/common.c| 2 +- tools/perf/arch/powerpc/util/perf_regs.c| 2 +- tools/perf/arch/s390/util/auxtrace.c| 1 + tools/perf/arch/s390/util/header.c | 2 +- tools/perf/arch/x86/util/event.c| 2 +- tools/perf/arch/x86/util/intel-bts.c| 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/arch/x86/util/perf_regs.c| 2 +- tools/perf/bench/mem-functions.c| 2 +- tools/perf/bench/numa.c | 2 +- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-bench.c | 2 +- tools/perf/builtin-c2c.c| 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-help.c | 1 + tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-kvm.c| 2 +- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-probe.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-timechart.c | 4 +--- tools/perf/builtin-trace.c | 1 + tools/perf/perf.c | 2 +- tools/perf/tests/switch-tracking.c | 1 + tools/perf/ui/browser.c | 2 +- tools/perf/ui/browsers/annotate.c | 2 +- tools/perf/ui/browsers/hists.c | 2 +- tools/perf/ui/gtk/util.c| 3 +-- tools/perf/ui/stdio/hist.c | 2 +- tools/perf/util/Build | 5 + tools/perf/util/arm-spe.c | 2 +- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/bpf-loader.c| 1 + tools/perf/util/build-id.c | 1 + tools/perf/util/call-path.c | 3 ++- tools/perf/util/callchain.c | 2 +- tools/perf/util/cgroup.c| 2 +- tools/perf/util/comm.c | 2 +- tools/perf/util/config.c| 3 +-- tools/perf/util/counts.c| 2 +- tools/perf/util/cpumap.c| 2 +- tools/perf/util/cputopo.c | 2 +- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 1 + tools/perf/util/cs-etm.c| 1 + tools/perf/util/data-convert-bt.c | 2 +- tools/perf/util/data.c | 1 + tools/perf/util/db-export.c | 2 +- tools/perf/util/dso.c | 3 ++- tools/perf/util/env.c | 2 +- tools/perf/util/event.c | 1 + tools/perf/util/evlist.c| 2 +- tools/perf/util/evsel.c | 2 +- tools/perf/util/header.c| 2 +- tools/perf/util/help-unknown-cmd.c | 2 ++ tools/perf/util/hist.c | 2 +- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 2 +- tools/perf/util/intel-pt.c | 2 +- tools/perf/util/llvm-utils.c| 1 + tools/perf/util/machine.c | 2 +- tools/perf/util/map.c | 2 +- tools/perf/util/mem2node.c | 2 +-
[tip:perf/urgent] perf tools: Move get_current_dir_name() cond prototype out of util.h
Commit-ID: e5653eb82ddc71ad8ffcbb3c74dd6f0c0230ab4c Gitweb: https://git.kernel.org/tip/e5653eb82ddc71ad8ffcbb3c74dd6f0c0230ab4c Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 5 Jul 2019 14:16:15 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 10:13:26 -0300 perf tools: Move get_current_dir_name() cond prototype out of util.h And in a separate header, so that we erode util.h a bit more. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-xpzvuu9d0gei9jl9bkzgo...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/get_current_dir_name.c | 6 +++--- tools/perf/util/get_current_dir_name.h | 8 tools/perf/util/namespaces.c | 1 + tools/perf/util/util.h | 4 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/get_current_dir_name.c b/tools/perf/util/get_current_dir_name.c index 267aa609a582..01f32f26552d 100644 --- a/tools/perf/util/get_current_dir_name.c +++ b/tools/perf/util/get_current_dir_name.c @@ -1,8 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo +// SPDX-License-Identifier: LGPL-2.1 +// Copyright (C) 2018, 2019 Red Hat Inc, Arnaldo Carvalho de Melo // #ifndef HAVE_GET_CURRENT_DIR_NAME -#include "util.h" +#include "get_current_dir_name.h" #include #include #include diff --git a/tools/perf/util/get_current_dir_name.h b/tools/perf/util/get_current_dir_name.h new file mode 100644 index ..69f7d5537d32 --- /dev/null +++ b/tools/perf/util/get_current_dir_name.h @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: LGPL-2.1 +// Copyright (C) 2018, 2019 Red Hat Inc, Arnaldo Carvalho de Melo +// +#ifndef __PERF_GET_CURRENT_DIR_NAME_H +#ifndef HAVE_GET_CURRENT_DIR_NAME +char *get_current_dir_name(void); +#endif // HAVE_GET_CURRENT_DIR_NAME +#endif // __PERF_GET_CURRENT_DIR_NAME_H diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index 023c4efd788d..fda2fa1e8819 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -7,6 +7,7 @@ #include "namespaces.h" #include "util.h" #include "event.h" +#include "get_current_dir_name.h" #include #include #include diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 59fe33708090..cfc4d85bbd42 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -59,10 +59,6 @@ int fetch_kernel_version(unsigned int *puint, const char *perf_tip(const char *dirpath); -#ifndef HAVE_GET_CURRENT_DIR_NAME -char *get_current_dir_name(void); -#endif - #ifndef HAVE_SCHED_GETCPU_SUPPORT int sched_getcpu(void); #endif
[tip:perf/urgent] perf namespaces: Move the conditional setns() prototype to namespaces.h
Commit-ID: 245aec7f7f4ca95b924f005d604bab9d838b5eb1 Gitweb: https://git.kernel.org/tip/245aec7f7f4ca95b924f005d604bab9d838b5eb1 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 5 Jul 2019 13:59:06 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 10:13:26 -0300 perf namespaces: Move the conditional setns() prototype to namespaces.h Out of util.h, to reduce its scope, and since we have a namespaces.h header, much better to have it there, where it is related to. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-zlu81bbtccuzygh7m8nmg...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/namespaces.h | 4 tools/perf/util/setns.c | 4 +++- tools/perf/util/util.h | 4 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 15a5a276c478..004430c0de93 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -13,6 +13,10 @@ #include #include +#ifndef HAVE_SETNS_SUPPORT +int setns(int fd, int nstype); +#endif + struct namespaces_event; struct namespaces { diff --git a/tools/perf/util/setns.c b/tools/perf/util/setns.c index ce8fc290fce8..48f9c0af63b2 100644 --- a/tools/perf/util/setns.c +++ b/tools/perf/util/setns.c @@ -1,4 +1,6 @@ -#include "util.h" +// SPDX-License-Identifier: LGPL-2.1 + +#include "namespaces.h" #include #include diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 125e215dd3d8..59fe33708090 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -67,10 +67,6 @@ char *get_current_dir_name(void); int sched_getcpu(void); #endif -#ifndef HAVE_SETNS_SUPPORT -int setns(int fd, int nstype); -#endif - extern bool perf_singlethreaded; void perf_set_singlethreaded(void);
[tip:perf/urgent] perf tools: Add missing headers, mostly stdlib.h
Commit-ID: 215a0d305c5651928eb67c96bcedd0a6c297dfce Gitweb: https://git.kernel.org/tip/215a0d305c5651928eb67c96bcedd0a6c297dfce Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 4 Jul 2019 11:21:24 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 10:13:22 -0300 perf tools: Add missing headers, mostly stdlib.h Part of the erosion of util/util.h, that will lose its include stdlib.h, we need to add it to places where it is needed but was getting it indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-1imnqezw99ahc07fjeb51...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/common.c | 1 + tools/perf/arch/powerpc/util/perf_regs.c | 2 ++ tools/perf/arch/s390/util/header.c | 1 + tools/perf/builtin-config.c | 1 + tools/perf/builtin-help.c| 1 + tools/perf/tests/llvm.c | 1 + tools/perf/tests/sample-parsing.c| 1 + tools/perf/tests/vmlinux-kallsyms.c | 1 + tools/perf/ui/browser.h | 1 + tools/perf/ui/browsers/map.c | 1 + tools/perf/ui/tui/setup.c| 1 + tools/perf/ui/tui/util.c | 2 +- tools/perf/util/cputopo.c| 1 + tools/perf/util/db-export.c | 1 + tools/perf/util/debug.c | 1 + tools/perf/util/demangle-java.c | 3 ++- tools/perf/util/dwarf-aux.c | 2 +- tools/perf/util/env.c| 1 + tools/perf/util/parse-branch-options.c | 2 +- tools/perf/util/parse-regs-options.c | 8 ++-- tools/perf/util/strbuf.c | 1 + tools/perf/util/symbol-elf.c | 1 + tools/perf/util/symbol-minimal.c | 1 + tools/perf/util/target.c | 2 +- tools/perf/util/thread-stack.c | 1 + tools/perf/util/usage.c | 3 +++ 26 files changed, 35 insertions(+), 7 deletions(-) diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index f3824ca7c20b..1bc329412bcf 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include "common.h" #include "../util/env.h" #include "../util/util.h" diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c index 34d5134681d9..64f65c296d3e 100644 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ b/tools/perf/arch/powerpc/util/perf_regs.c @@ -8,6 +8,8 @@ #include "../../util/perf_regs.h" #include "../../util/debug.h" +#include + const struct sample_reg sample_reg_masks[] = { SMPL_REG(r0, PERF_REG_POWERPC_R0), SMPL_REG(r1, PERF_REG_POWERPC_R1), diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c index a25896135abe..165c51435e72 100644 --- a/tools/perf/arch/s390/util/header.c +++ b/tools/perf/arch/s390/util/header.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "../../util/header.h" #include "../../util/util.h" diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index d76f831f94c7..6c1284c87aaa 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -15,6 +15,7 @@ #include "util/debug.h" #include "util/config.h" #include +#include static bool use_system_config, use_user_config; diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 3d29d0524a89..6a1cab547043 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index a039f93199e5..ca5a5f94ce79 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 236ce0d6c826..361714e2583c 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index f101576d1c72..5e8834fc7dec 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "map.h" #include "symbol.h" #include "util.h" diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index aa5932e1d62e..dc1444136658 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -4,6 +4,7 @@ #include #include +#include #define HE_COLORSET_TOP50 #define HE_COLORSET_MEDIUM 51 diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index
[tip:perf/urgent] perf evsel: perf_evsel__name(NULL) is valid, no need to check evsel
Commit-ID: fc50e0ba9bcac92ff177ff3ac64644108b6d8dd8 Gitweb: https://git.kernel.org/tip/fc50e0ba9bcac92ff177ff3ac64644108b6d8dd8 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 3 Jul 2019 16:12:51 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 09:33:55 -0300 perf evsel: perf_evsel__name(NULL) is valid, no need to check evsel It'll return "unknown", no need to open code it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Leo Yan Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-4okvjmm18arjrcyfhuahg...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 2 +- tools/perf/util/session.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index aef59f318a67..93d4b12e248e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -298,7 +298,7 @@ static int process_read_event(struct perf_tool *tool, struct report *rep = container_of(tool, struct report, tool); if (rep->show_threads) { - const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; + const char *name = perf_evsel__name(evsel); int err = perf_read_values_add_value(>show_threads_values, event->read.pid, event->read.tid, evsel->idx, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2e61dd6a3574..e3463df18493 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1246,7 +1246,7 @@ static void dump_read(struct perf_evsel *evsel, union perf_event *event) return; printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, - evsel ? perf_evsel__name(evsel) : "FAIL", + perf_evsel__name(evsel), event->read.value); if (!evsel)
[tip:perf/urgent] perf inject: The tool->read() call may pass a NULL evsel, handle it
Commit-ID: 40978e9bf2137223993e70921de2731201788049 Gitweb: https://git.kernel.org/tip/40978e9bf2137223993e70921de2731201788049 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 3 Jul 2019 16:02:09 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 9 Jul 2019 09:33:55 -0300 perf inject: The tool->read() call may pass a NULL evsel, handle it Check first, as machines__deliver_event() may have perf_evlist__id2evsel() returning NULL. This was found while checking a report from Leo Yan that used the smatch tool to find places where a pointer is checked before use and then, later in the same function gets used without checking. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Leo Yan Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-muvb8xqyh0gysgfjfq35w...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 8e0e06d3edfc..f4591a1438b4 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -224,7 +224,7 @@ static int perf_event__repipe_sample(struct perf_tool *tool, struct perf_evsel *evsel, struct machine *machine) { - if (evsel->handler) { + if (evsel && evsel->handler) { inject_handler f = evsel->handler; return f(tool, event, sample, evsel, machine); }
[tip:perf/core] tools arch x86: Sync asm/cpufeatures.h with the with the kernel
Commit-ID: 686cbe9e5d88ad639bbe26d963e7d5dafa1c1c28 Gitweb: https://git.kernel.org/tip/686cbe9e5d88ad639bbe26d963e7d5dafa1c1c28 Author: Arnaldo Carvalho de Melo AuthorDate: Mon, 8 Jul 2019 13:47:14 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 8 Jul 2019 13:47:14 -0300 tools arch x86: Sync asm/cpufeatures.h with the with the kernel To pick up the changes in: 6dbbf5ec9e1e ("x86/cpufeatures: Enumerate user wait instructions") b302e4b176d0 ("x86/cpufeatures: Enumerate the new AVX512 BFLOAT16 instructions") acec0ce081de ("x86/cpufeatures: Combine word 11 and 12 into a new scattered features word") cbb99c0f5887 ("x86/cpufeatures: Add FDP_EXCPTN_ONLY and ZERO_FCS_FDS") That don't affect anything in tools/. This silences this perf build warning: Warning: Kernel ABI header at 'tools/arch/x86/include/asm/cpufeatures.h' differs from latest version at 'arch/x86/include/asm/cpufeatures.h' diff -u tools/arch/x86/include/asm/cpufeatures.h arch/x86/include/asm/cpufeatures.h Cc: Aaron Lewis Cc: Adrian Hunter Cc: Borislav Petkov Cc: Fenghua Yu Cc: Jiri Olsa Cc: Namhyung Kim Cc: Thomas Gleixner Link: https://lkml.kernel.org/n/tip-y60wnyg2fuxi0hx7icruo...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/asm/cpufeatures.h | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 75f27ee2c263..998c2cc08363 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -239,12 +239,14 @@ #define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ #define X86_FEATURE_HLE( 9*32+ 4) /* Hardware Lock Elision */ #define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ +#define X86_FEATURE_FDP_EXCPTN_ONLY( 9*32+ 6) /* "" FPU data pointer updated only on x87 exceptions */ #define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */ #define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ #define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB instructions */ #define X86_FEATURE_INVPCID( 9*32+10) /* Invalidate Processor Context ID */ #define X86_FEATURE_RTM( 9*32+11) /* Restricted Transactional Memory */ #define X86_FEATURE_CQM( 9*32+12) /* Cache QoS Monitoring */ +#define X86_FEATURE_ZERO_FCS_FDS ( 9*32+13) /* "" Zero out FPU CS and FPU DS */ #define X86_FEATURE_MPX( 9*32+14) /* Memory Protection Extension */ #define X86_FEATURE_RDT_A ( 9*32+15) /* Resource Director Technology Allocation */ #define X86_FEATURE_AVX512F( 9*32+16) /* AVX-512 Foundation */ @@ -269,13 +271,19 @@ #define X86_FEATURE_XGETBV1(10*32+ 2) /* XGETBV with ECX = 1 instruction */ #define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS instructions */ -/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x000F:0 (EDX), word 11 */ -#define X86_FEATURE_CQM_LLC(11*32+ 1) /* LLC QoS if 1 */ +/* + * Extended auxiliary flags: Linux defined - for features scattered in various + * CPUID levels like 0xf, etc. + * + * Reuse free bits when adding new feature flags! + */ +#define X86_FEATURE_CQM_LLC(11*32+ 0) /* LLC QoS if 1 */ +#define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */ +#define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */ +#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */ -/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x000F:1 (EDX), word 12 */ -#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring */ -#define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */ -#define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */ +/* Intel-defined CPU features, CPUID level 0x0007:1 (EAX), word 12 */ +#define X86_FEATURE_AVX512_BF16(12*32+ 5) /* AVX512 BFLOAT16 instructions */ /* AMD-defined CPU features, CPUID level 0x8008 (EBX), word 13 */ #define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */ @@ -322,6 +330,7 @@ #define X86_FEATURE_UMIP (16*32+ 2) /* User Mode Instruction Protection */ #define X86_FEATURE_PKU(16*32+ 3) /* Protection Keys for Userspace */ #define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */ +#define X86_FEATURE_WAITPKG(16*32+ 5) /* UMONITOR/UMWAIT/TPAUSE Instructions */ #define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* Additional AVX512 Vector Bit Manipulation Instructions */ #define X86_FEATURE_GFNI (16*32+ 8) /* Galois Field New
[tip:perf/core] tools build: Check if gettid() is available before providing helper
Commit-ID: 05c78468a60f2fd961cd0a0c01c27f288bf81204 Gitweb: https://git.kernel.org/tip/05c78468a60f2fd961cd0a0c01c27f288bf81204 Author: Arnaldo Carvalho de Melo AuthorDate: Thu, 13 Jun 2019 12:04:19 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Sun, 7 Jul 2019 17:53:09 -0300 tools build: Check if gettid() is available before providing helper Laura reported that the perf build failed in fedora when we got a glibc that provides gettid(), which I reproduced using fedora rawhide with the glibc-devel-2.29.9000-26.fc31.x86_64 package. Add a feature check to avoid providing a gettid() helper in such systems. On a fedora rawhide system with this patch applied we now get: [root@7a5f55352234 perf]# grep gettid /tmp/build/perf/FEATURE-DUMP feature-gettid=1 [root@7a5f55352234 perf]# cat /tmp/build/perf/feature/test-gettid.make.output [root@7a5f55352234 perf]# ldd /tmp/build/perf/feature/test-gettid.bin linux-vdso.so.1 (0x7ffc6b1f6000) libc.so.6 => /lib64/libc.so.6 (0x7f04e0a74000) /lib64/ld-linux-x86-64.so.2 (0x7f04e0c47000) [root@7a5f55352234 perf]# nm /tmp/build/perf/feature/test-gettid.bin | grep -w gettid U gettid@@GLIBC_2.30 [root@7a5f55352234 perf]# While on a fedora:29 system: [acme@quaco perf]$ grep gettid /tmp/build/perf/FEATURE-DUMP feature-gettid=0 [acme@quaco perf]$ cat /tmp/build/perf/feature/test-gettid.make.output test-gettid.c: In function ‘main’: test-gettid.c:8:9: error: implicit declaration of function ‘gettid’; did you mean ‘getgid’? [-Werror=implicit-function-declaration] return gettid(); ^~ getgid cc1: all warnings being treated as errors [acme@quaco perf]$ Reported-by: Laura Abbott Tested-by: Laura Abbott Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Florian Weimer Cc: Namhyung Kim Cc: Stephane Eranian Link: https://lkml.kernel.org/n/tip-yfy3ch53agmklwu9o7rlg...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.feature | 1 + tools/build/feature/Makefile | 4 tools/build/feature/test-all.c | 5 + tools/build/feature/{test-get_current_dir_name.c => test-gettid.c} | 6 +++--- tools/perf/Makefile.config | 4 tools/perf/jvmti/jvmti_agent.c | 2 ++ 6 files changed, 19 insertions(+), 3 deletions(-) diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 3b24231c58a2..50377cc2f5f9 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -36,6 +36,7 @@ FEATURE_TESTS_BASIC := \ fortify-source \ sync-compare-and-swap \ get_current_dir_name\ +gettid \ glibc \ gtk2\ gtk2-infobar\ diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 4b8244ee65ce..523ee42db0c8 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -54,6 +54,7 @@ FILES= \ test-get_cpuid.bin \ test-sdt.bin \ test-cxx.bin \ + test-gettid.bin \ test-jvmti.bin\ test-jvmti-cmlr.bin \ test-sched_getcpu.bin \ @@ -267,6 +268,9 @@ $(OUTPUT)test-sdt.bin: $(OUTPUT)test-cxx.bin: $(BUILDXX) -std=gnu++11 +$(OUTPUT)test-gettid.bin: + $(BUILD) + $(OUTPUT)test-jvmti.bin: $(BUILD) diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index a59c53705093..3b3d5d72124a 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c @@ -38,6 +38,10 @@ # include "test-get_current_dir_name.c" #undef main +#define main main_test_gettid +# include "test-gettid.c" +#undef main + #define main main_test_glibc # include "test-glibc.c" #undef main @@ -195,6 +199,7 @@ int main(int argc, char *argv[]) main_test_libelf(); main_test_libelf_mmap(); main_test_get_current_dir_name(); + main_test_gettid(); main_test_glibc(); main_test_dwarf(); main_test_dwarf_getlocations(); diff --git a/tools/build/feature/test-get_current_dir_name.c b/tools/build/feature/test-gettid.c similarity index 53% copy from tools/build/feature/test-get_current_dir_name.c copy to tools/build/feature/test-gettid.c index c3c201691b4f..ef24e42d3f1b 100644 --- a/tools/build/feature/test-get_current_dir_name.c +++ b/tools/build/feature/test-gettid.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2019, Red Hat
[tip:perf/core] perf python: Remove -fstack-protector-strong if clang doesn't have it
Commit-ID: c18ae6327a13a6d707f6139c31597057103aa85b Gitweb: https://git.kernel.org/tip/c18ae6327a13a6d707f6139c31597057103aa85b Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 28 May 2019 17:36:46 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Sun, 7 Jul 2019 12:32:46 -0300 perf python: Remove -fstack-protector-strong if clang doesn't have it Some distros put -fstack-protector-strong in the compiler flags to be used to build python extensions, but then, the clang version in that distro doesn't know about that, only gcc does. Check if that is the case and remove it from the set of options used to build the python binding with clang. Case at hand: oraclelinux:7 $ head -2 /etc/os-release NAME="Oracle Linux Server" VERSION="7.6" $ grep stack-protector /usr/lib64/python2.7/_sysconfigdata.py | head -1 | cut -c-120 'CFLAGS': '-fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --para $ gcc version 4.8.5 20150623 (Red Hat 4.8.5-36.0.1) (GCC) clang version 3.4.2 (tags/RELEASE_34/dot2-final) clang: error: unknown argument: '-fstack-protector-strong' clang: error: unknown argument: '-fstack-protector-strong' error: command 'clang' failed with exit status 1 cp: cannot stat '/tmp/build/perf/python_ext_build/lib/perf*.so': No such file or directory make[2]: *** [/tmp/build/perf/python/perf.so] Error 1 Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-brmp2415zxpbhz45etkgj...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index 5b5a167b43ce..a1a68a2fa917 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -17,6 +17,8 @@ if cc == "clang": vars[var] = sub("-fcf-protection", "", vars[var]) if not clang_has_option("-fstack-clash-protection"): vars[var] = sub("-fstack-clash-protection", "", vars[var]) +if not clang_has_option("-fstack-protector-strong"): +vars[var] = sub("-fstack-protector-strong", "", vars[var]) from distutils.core import setup, Extension
[tip:perf/core] perf annotate TUI browser: Do not use member from variable within its own initialization
Commit-ID: d5b2179d6a675ee8cdbd3250d42f1e32d5a45fb1 Gitweb: https://git.kernel.org/tip/d5b2179d6a675ee8cdbd3250d42f1e32d5a45fb1 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 28 May 2019 16:02:56 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Sat, 6 Jul 2019 16:59:11 -0300 perf annotate TUI browser: Do not use member from variable within its own initialization Some compilers will complain when using a member of a struct to initialize another member, in the same struct initialization. For instance: debian:8 Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0) oraclelinux:7 clang version 3.4.2 (tags/RELEASE_34/dot2-final) Produce: ui/browsers/annotate.c:104:12: error: variable 'ops' is uninitialized when used within its own initialization [-Werror,-Wuninitialized] (!ops.current_entry || ^~~ 1 error generated. So use an extra variable, initialized just before that struct, to have the value used in the expressions used to init two of the struct members. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Fixes: c298304bd747 ("perf annotate: Use a ops table for annotation_line__write()") Link: https://lkml.kernel.org/n/tip-f9nexro58q62l3o9hez8h...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/annotate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 98d934a36d86..b0d089a95dac 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -97,11 +97,12 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); struct annotation *notes = browser__annotation(browser); struct annotation_line *al = list_entry(entry, struct annotation_line, node); + const bool is_current_entry = ui_browser__is_current_entry(browser, row); struct annotation_write_ops ops = { .first_line = row == 0, - .current_entry = ui_browser__is_current_entry(browser, row), + .current_entry = is_current_entry, .change_color= (!notes->options->hide_src_code && - (!ops.current_entry || + (!is_current_entry || (browser->use_navkeypressed && !browser->navkeypressed))), .width = browser->width,
[tip:perf/core] perf thread: Allow references to thread objects after machine__exit()
Commit-ID: 4c00af0e94cd01b8c5a5e6b3323d34677b04e192 Gitweb: https://git.kernel.org/tip/4c00af0e94cd01b8c5a5e6b3323d34677b04e192 Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 5 Jul 2019 12:11:35 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Sat, 6 Jul 2019 14:29:32 -0300 perf thread: Allow references to thread objects after machine__exit() Threads are created when we either synthesize PERF_RECORD_FORK events for pre-existing threads or when we receive PERF_RECORD_FORK events from the kernel as new threads get created. We then keep them in machine->threads[].entries rb trees till when we receive a PERF_RECORD_EXIT, i.e. that thread terminated. The thread object has a reference count that is grabbed when, for instance, we keep that thread referenced in struct hist_entry, in 'perf report' and 'perf top'. When we receive a PERF_RECORD_EXIT we remove the thread object from the rb tree and move it to the corresponding machine->threads[].dead list, then we do a thread__put(), dropping the reference we had for keeping it in the rb tree. In thread__put() we were assuming that when the reference count hit zero we should remove it from the dead list by simply doing a list_del_init(>node). That works well when all the thread lifetime is during the machine that has the list heads lifetime, since we know that we can do the list_del_init() and it will update the 'dead' list_head. But in 'perf sched lat' we were doing: machine__new() (via perf_session__new) process events, grabbing refcounts to keep those thread objects in 'perf sched' local data structures. machine__exit() (via perf_session__delete) which would delete the 'dead' list heads. And then doing the final thread__put() for the refcounts 'perf sched' rightfully obtained for keeping those thread object references. b00m, since thread__put() would do the list_del_init() touching a dead dead list head. Fix it by removing all the dead threads from machine->threads[].dead at machine__exit(), since whatever is there should have refcounts taken by things like 'perf sched lat', and make thread__put() check if the thread is in a linked list before removing it from that list. Reported-by: Wei Li Link: https://lkml.kernel.org/r/20190508143648.8153-1-liwei...@huawei.com Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Zhipeng Xie Link: https://lkml.kernel.org/r/20190704194355.gi10...@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 25 +++-- tools/perf/util/thread.c | 23 --- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index dc7aafe45a2b..e00dc413652d 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -209,6 +209,18 @@ void machine__exit(struct machine *machine) for (i = 0; i < THREADS__TABLE_SIZE; i++) { struct threads *threads = >threads[i]; + struct thread *thread, *n; + /* +* Forget about the dead, at this point whatever threads were +* left in the dead lists better have a reference count taken +* by who is using them, and then, when they drop those references +* and it finally hits zero, thread__put() will check and see that +* its not in the dead threads list and will not try to remove it +* from there, just calling thread__delete() straight away. +*/ + list_for_each_entry_safe(thread, n, >dead, node) + list_del_init(>node); + exit_rwsem(>lock); } } @@ -1758,9 +1770,11 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th, if (threads->last_match == th) threads__set_last_match(threads, NULL); - BUG_ON(refcount_read(>refcnt) == 0); if (lock) down_write(>lock); + + BUG_ON(refcount_read(>refcnt) == 0); + rb_erase_cached(>rb_node, >entries); RB_CLEAR_NODE(>rb_node); --threads->nr; @@ -1770,9 +1784,16 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th, * will be called and we will remove it from the dead_threads list. */ list_add_tail(>node, >dead); + + /* +* We need to do the put here because if this is the last refcount, +* then we will be touching the threads->dead head when removing the +* thread. +*/ + thread__put(th); + if (lock) up_write(>lock); - thread__put(th); } void machine__remove_thread(struct machine *machine, struct thread *th) diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index b413ba5b9835..7bfb740d2ede 100644 --- a/tools/perf/util/thread.c +++
[tip:perf/core] tools arch kvm: Sync kvm headers with the kernel sources
Commit-ID: c499d1f483a99e86a5f712277de7c8fa33a9ec0a Gitweb: https://git.kernel.org/tip/c499d1f483a99e86a5f712277de7c8fa33a9ec0a Author: Arnaldo Carvalho de Melo AuthorDate: Sat, 6 Jul 2019 14:26:40 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Sat, 6 Jul 2019 14:26:40 -0300 tools arch kvm: Sync kvm headers with the kernel sources To pick up the changes from: 41040cf7c5f0 ("arm64/sve: Fix missing SVE/FPSIMD endianness conversions") 6ca00dfafda7 ("KVM: x86: Modify struct kvm_nested_state to have explicit fields for data") None entail changes in tooling. This silences these tools/perf build warnings: Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/kvm.h' differs from latest version at 'arch/x86/include/uapi/asm/kvm.h' diff -u tools/arch/x86/include/uapi/asm/kvm.h arch/x86/include/uapi/asm/kvm.h Warning: Kernel ABI header at 'tools/arch/arm64/include/uapi/asm/kvm.h' differs from latest version at 'arch/arm64/include/uapi/asm/kvm.h' diff -u tools/arch/arm64/include/uapi/asm/kvm.h arch/arm64/include/uapi/asm/kvm.h Cc: Adrian Hunter Cc: Dave Martin Cc: Jiri Olsa Cc: Liran Alon Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-1cdbq5ulr4d6cx3iv2ye5...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/arm64/include/uapi/asm/kvm.h | 7 +++ tools/arch/x86/include/uapi/asm/kvm.h | 31 +-- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index 7b7ac0f6cec9..d819a3e8b552 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -260,6 +260,13 @@ struct kvm_vcpu_events { KVM_REG_SIZE_U256 |\ ((i) & (KVM_ARM64_SVE_MAX_SLICES - 1))) +/* + * Register values for KVM_REG_ARM64_SVE_ZREG(), KVM_REG_ARM64_SVE_PREG() and + * KVM_REG_ARM64_SVE_FFR() are represented in memory in an endianness- + * invariant layout which differs from the layout used for the FPSIMD + * V-registers on big-endian systems: see sigcontext.h for more explanation. + */ + #define KVM_ARM64_SVE_VQ_MIN __SVE_VQ_MIN #define KVM_ARM64_SVE_VQ_MAX __SVE_VQ_MAX diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h index 24a8cd229df6..d6ab5b4d15e5 100644 --- a/tools/arch/x86/include/uapi/asm/kvm.h +++ b/tools/arch/x86/include/uapi/asm/kvm.h @@ -383,6 +383,9 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) #define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) +#define KVM_STATE_NESTED_FORMAT_VMX0 +#define KVM_STATE_NESTED_FORMAT_SVM1 /* unused */ + #define KVM_STATE_NESTED_GUEST_MODE0x0001 #define KVM_STATE_NESTED_RUN_PENDING 0x0002 #define KVM_STATE_NESTED_EVMCS 0x0004 @@ -390,7 +393,14 @@ struct kvm_sync_regs { #define KVM_STATE_NESTED_SMM_GUEST_MODE0x0001 #define KVM_STATE_NESTED_SMM_VMXON 0x0002 -struct kvm_vmx_nested_state { +#define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 + +struct kvm_vmx_nested_state_data { + __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; + __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; +}; + +struct kvm_vmx_nested_state_hdr { __u64 vmxon_pa; __u64 vmcs12_pa; @@ -401,24 +411,25 @@ struct kvm_vmx_nested_state { /* for KVM_CAP_NESTED_STATE */ struct kvm_nested_state { - /* KVM_STATE_* flags */ __u16 flags; - - /* 0 for VMX, 1 for SVM. */ __u16 format; - - /* 128 for SVM, 128 + VMCS size for VMX. */ __u32 size; union { - /* VMXON, VMCS */ - struct kvm_vmx_nested_state vmx; + struct kvm_vmx_nested_state_hdr vmx; /* Pad the header to 128 bytes. */ __u8 pad[120]; - }; + } hdr; - __u8 data[0]; + /* +* Define data region as 0 bytes to preserve backwards-compatability +* to old definition of kvm_nested_state in order to avoid changing +* KVM_{GET,PUT}_NESTED_STATE ioctl values. +*/ + union { + struct kvm_vmx_nested_state_data vmx[0]; + } data; }; #endif /* _ASM_X86_KVM_H */
[tip:perf/core] perf script: Allow specifying the files to process guest samples
Commit-ID: 15a108af1a18b597bfbd7f7b3c7b4823bfbaf8df Gitweb: https://git.kernel.org/tip/15a108af1a18b597bfbd7f7b3c7b4823bfbaf8df Author: Arnaldo Carvalho de Melo AuthorDate: Fri, 28 Jun 2019 17:16:58 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 3 Jul 2019 00:13:25 -0300 perf script: Allow specifying the files to process guest samples The 'perf kvm' command set up things so that we can record, report, top, etc, but not 'script', so make 'perf script' be able to process samples by allowing to pass guest kallsyms, vmlinux, modules, etc, and if at least one of those is provided, set perf_guest to true so that guest samples get properly resolved. Testing it: # perf kvm --guest --guestkallsyms /wb/rhel6.kallsyms --guestmodules /wb/rhel6.modules record -e cycles:Gk ^C[ perf record: Woken up 7 times to write data ] [ perf record: Captured and wrote 3.602 MB perf.data.guest (10492 samples) ] # # perf evlist -i perf.data.guest cycles:Gk # perf evlist -v -i perf.data.guest cycles:Gk: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|CPU|PERIOD, read_format: ID, disabled: 1, inherit: 1, exclude_user: 1, exclude_hv: 1, mmap: 1, comm: 1, freq: 1, task: 1, sample_id_all: 1, exclude_host: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1 # # perf kvm --guestkallsyms /wb/rhel6.kallsyms --guestmodules /wb/rhel6.modules report --stdio -s sym | head -30 # To display the perf.data header info, please use --header/--header-only options. # # # Total Lost Samples: 0 # # Samples: 10K of event 'cycles:Gk' # Event count (approx.): 2434201408 # # Overhead Symbol # .. # 11.93% [g] avtab_search_node 3.95% [g] sidtab_context_to_sid 2.41% [g] n_tty_write 2.20% [g] _spin_unlock_irqrestore 1.37% [g] _aesni_dec4 1.33% [g] kmem_cache_alloc 1.07% [g] native_write_cr0 0.99% [g] kfree 0.95% [g] _spin_lock 0.91% [g] __memset 0.87% [g] schedule 0.83% [g] _spin_lock_irqsave 0.76% [g] __kmalloc 0.67% [g] avc_has_perm_noaudit 0.66% [g] kmem_cache_free 0.65% [g] glue_xts_crypt_128bit 0.59% [g] __d_lookup 0.59% [g] __audit_syscall_exit 0.56% [g] __memcpy # Then, when trying to use perf script to generate a python script and then process the events after adding a python hook for non-tracepoint events: # perf script -i perf.data.guest -g python generated Python script: perf-script.py # vim perf-script.py # tail -2 perf-script.py def process_event(param_dict): print(param_dict["symbol"]) # # perf script -i perf.data.guest -s perf-script.py | head in trace_begin vmx_vmexit vmx_vmexit vmx_vmexit vmx_vmexit vmx_vmexit vmx_vmexit vmx_vmexit vmx_vmexit vmx_vmexit 231 # We'd see just the vmx_vmexit, i.e. the samples from the guest don't show up. After this patch: # perf script --guestkallsyms /wb/rhel6.kallsyms --guestmodules /wb/rhel6.modules -i perf.data.guest -s perf-script.py 2> /dev/null | head -30 in trace_begin apic_timer_interrupt apic_timer_interrupt apic_timer_interrupt apic_timer_interrupt apic_timer_interrupt save_args do_timer drain_array inode_permission avc_has_perm_noaudit run_timer_softirq apic_timer_interrupt apic_timer_interrupt apic_timer_interrupt apic_timer_interrupt apic_timer_interrupt kvm_guest_apic_eoi_write run_posix_cpu_timers _spin_lock handle_pte_fault rcu_irq_enter delay_tsc delay_tsc native_read_tsc apic_timer_interrupt sys_open internal_add_timer list_del rcu_exit_nohz # Jiri Olsa noticed we need to set 'perf_guest' to true if we want to process guest samples and I made it be set if one of the guest files settings get set via the command line options added in this patch, that match those present in the 'perf kvm' command. We probably want to have 'perf record', 'perf report' etc to notice that there are guest samples and do the right thing, which is to look for files with some suffix that make it be associated with the guest used to collect the samples, i.e. if a vmlinux file is passed, we can get the build-id from it, if not some other identifier or simply looking for "kallsyms.guest", for instance, in the current directory. Reported-by: Mariano Pache Tested-by: Mariano Pache Cc: Adrian Hunter Cc: Alexander Yarygin Cc: Ali Raza Cc: Christian Borntraeger Cc: Jiri Olsa Cc: Joe Mario Cc: Larry Woodman Cc: Namhyung Kim Cc: Orran Krieger Cc: Ramkumar Ramachandra Cc: Yunlong Song Link: https://lkml.kernel.org/n/tip-d54gj64rerlxcqsrod05b...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 520e5b6b9ef9..2f6232f1bfdc 100644 ---
[tip:perf/core] tools lib: Move argv_{split,free} from tools/perf/util/
Commit-ID: 9c10548c42219e961279826c2763a0e32dc056b9 Gitweb: https://git.kernel.org/tip/9c10548c42219e961279826c2763a0e32dc056b9 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 15:27:58 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 1 Jul 2019 22:50:40 -0300 tools lib: Move argv_{split,free} from tools/perf/util/ This came from the kernel lib/argv_split.c, so move it to tools/lib/argv_split.c, to get it closer to the kernel structure. We need to audit the usage of argv_split() to figure out if it is really necessary to do have one allocation per argv[] entry, looking at one of its users I guess that is not the case and we probably are even leaking those allocations by not using argv_free() judiciously, for later. With this we further remove stuff from tools/perf/util/, reducing the perf specific codebase and encouraging other tools/ code to use these routines so as to keep the style and constructs used with the kernel. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-j479s1ive9h75w5lfg16j...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/string.h | 3 ++ tools/lib/argv_split.c | 100 +++ tools/perf/MANIFEST | 1 + tools/perf/util/Build| 5 +++ tools/perf/util/string.c | 91 --- tools/perf/util/string2.h| 2 - 6 files changed, 109 insertions(+), 93 deletions(-) diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index a76d4df10435..980cb9266718 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -7,6 +7,9 @@ void *memdup(const void *src, size_t len); +char **argv_split(const char *str, int *argcp); +void argv_free(char **argv); + int strtobool(const char *s, bool *res); /* diff --git a/tools/lib/argv_split.c b/tools/lib/argv_split.c new file mode 100644 index ..0a58ccf3f761 --- /dev/null +++ b/tools/lib/argv_split.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Helper function for splitting a string into an argv-like array. + */ + +#include +#include +#include +#include + +static const char *skip_arg(const char *cp) +{ + while (*cp && !isspace(*cp)) + cp++; + + return cp; +} + +static int count_argc(const char *str) +{ + int count = 0; + + while (*str) { + str = skip_spaces(str); + if (*str) { + count++; + str = skip_arg(str); + } + } + + return count; +} + +/** + * argv_free - free an argv + * @argv - the argument vector to be freed + * + * Frees an argv and the strings it points to. + */ +void argv_free(char **argv) +{ + char **p; + for (p = argv; *p; p++) { + free(*p); + *p = NULL; + } + + free(argv); +} + +/** + * argv_split - split a string at whitespace, returning an argv + * @str: the string to be split + * @argcp: returned argument count + * + * Returns an array of pointers to strings which are split out from + * @str. This is performed by strictly splitting on white-space; no + * quote processing is performed. Multiple whitespace characters are + * considered to be a single argument separator. The returned array + * is always NULL-terminated. Returns NULL on memory allocation + * failure. + */ +char **argv_split(const char *str, int *argcp) +{ + int argc = count_argc(str); + char **argv = calloc(argc + 1, sizeof(*argv)); + char **argvp; + + if (argv == NULL) + goto out; + + if (argcp) + *argcp = argc; + + argvp = argv; + + while (*str) { + str = skip_spaces(str); + + if (*str) { + const char *p = str; + char *t; + + str = skip_arg(str); + + t = strndup(p, str-p); + if (t == NULL) + goto fail; + *argvp++ = t; + } + } + *argvp = NULL; + +out: + return argv; + +fail: + argv_free(argv); + return NULL; +} diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index aac4c755d81b..6a5de44b2de9 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -7,6 +7,7 @@ tools/lib/traceevent tools/lib/api tools/lib/bpf tools/lib/subcmd +tools/lib/argv_split.c tools/lib/ctype.c tools/lib/hweight.c tools/lib/rbtree.c diff --git a/tools/perf/util/Build b/tools/perf/util/Build index b4dc6112138f..d3408a463060 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -20,6 +20,7 @@ perf-y += parse-events.o perf-y += perf_regs.o perf-y += path.o perf-y += print_binary.o +perf-y += argv_split.o perf-y += rbtree.o perf-y += libstring.o perf-y += bitmap.o @@ -209,6 +210,10
[tip:perf/core] perf tools: Drop strxfrchar(), use strreplace() equivalent from kernel
Commit-ID: af0de0c5f060b1d4eae6033043eb9eafd15aa738 Gitweb: https://git.kernel.org/tip/af0de0c5f060b1d4eae6033043eb9eafd15aa738 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 12:45:09 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 1 Jul 2019 22:50:40 -0300 perf tools: Drop strxfrchar(), use strreplace() equivalent from kernel No change in behaviour intended, just reducing the codebase and using something available in tools/lib/. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-oyi6zif3810nwi4uu85od...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.c | 3 ++- tools/perf/util/string.c | 18 -- tools/perf/util/string2.h | 1 - 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 1fb18292c2d3..c7fde04400f7 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include @@ -394,7 +395,7 @@ int __kmod_path__parse(struct kmod_path *m, const char *path, return -ENOMEM; } - strxfrchar(m->name, '-', '_'); + strreplace(m->name, '-', '_'); } return 0; diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 93a5340424df..9b7fbb0cbecd 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -300,24 +300,6 @@ int strtailcmp(const char *s1, const char *s2) return 0; } -/** - * strxfrchar - Locate and replace character in @s - * @s:The string to be searched/changed. - * @from: Source character to be replaced. - * @to: Destination character. - * - * Return pointer to the changed string. - */ -char *strxfrchar(char *s, char from, char to) -{ - char *p = s; - - while ((p = strchr(p, from)) != NULL) - *p++ = to; - - return s; -} - char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints) { /* diff --git a/tools/perf/util/string2.h b/tools/perf/util/string2.h index 6da835ad8f5b..2696c3fcd780 100644 --- a/tools/perf/util/string2.h +++ b/tools/perf/util/string2.h @@ -21,7 +21,6 @@ static inline bool strisglob(const char *str) return strpbrk(str, "*?[") != NULL; } int strtailcmp(const char *s1, const char *s2); -char *strxfrchar(char *s, char from, char to); char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints);
[tip:perf/core] tools lib: Adopt strreplace() from the kernel
Commit-ID: 2a60689a33a61f000bd90596b1289babcb861cd9 Gitweb: https://git.kernel.org/tip/2a60689a33a61f000bd90596b1289babcb861cd9 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 12:24:03 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 1 Jul 2019 22:50:40 -0300 tools lib: Adopt strreplace() from the kernel We'll use it to further reduce the size of tools/perf/util/string.c, replacing the strxfrchar() equivalent function we have there. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-x3r61ikjrso1buygxwke8...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/string.h | 2 ++ tools/lib/string.c | 16 2 files changed, 18 insertions(+) diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index e436f8037c87..a76d4df10435 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -19,6 +19,8 @@ extern size_t strlcpy(char *dest, const char *src, size_t size); char *str_error_r(int errnum, char *buf, size_t buflen); +char *strreplace(char *s, char old, char new); + /** * strstarts - does @str start with @prefix? * @str: string to examine diff --git a/tools/lib/string.c b/tools/lib/string.c index 80472e6b3829..f2ae1b87c719 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c @@ -145,3 +145,19 @@ char *strim(char *s) return skip_spaces(s); } + +/** + * strreplace - Replace all occurrences of character in string. + * @s: The string to operate on. + * @old: The character being replaced. + * @new: The character @old is replaced with. + * + * Returns pointer to the nul byte at the end of @s. + */ +char *strreplace(char *s, char old, char new) +{ + for (; *s; ++s) + if (*s == old) + *s = new; + return s; +}
[tip:perf/core] perf tools: Ditch rtrim(), use strim() from tools/lib
Commit-ID: 13c230ab6e56c6ae3a968f01f4c6505b794cecad Gitweb: https://git.kernel.org/tip/13c230ab6e56c6ae3a968f01f4c6505b794cecad Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 12:13:13 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 1 Jul 2019 22:50:33 -0300 perf tools: Ditch rtrim(), use strim() from tools/lib Cleaning up a bit more tools/perf/util/ by using things we got from the kernel and have in tools/lib/ Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-7hluuoveryoicvkclshzj...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 3 ++- tools/perf/util/annotate.c | 3 ++- tools/perf/util/header.c | 6 +++--- tools/perf/util/pmu.c | 2 +- tools/perf/util/python-ext-sources | 1 + tools/perf/util/srcline.c | 3 ++- tools/perf/util/string.c | 23 --- tools/perf/util/string2.h | 2 -- tools/perf/util/thread_map.c | 3 ++- 9 files changed, 13 insertions(+), 33 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 10243408f3dc..33e67aa91347 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2071,7 +2071,8 @@ static int hist_browser__fprintf_hierarchy_entry(struct hist_browser *browser, advance_hpp(, ret); } - printed += fprintf(fp, "%s\n", rtrim(s)); + strim(s); + printed += fprintf(fp, "%s\n", s); if (he->leaf && folded_sign == '-') { printed += hist_browser__fprintf_callchain(browser, he, fp, diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 783e2628cc8e..2d08c4b62c63 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -35,6 +35,7 @@ #include #include #include +#include #include /* FIXME: For the HE_COLORSET */ @@ -1495,7 +1496,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, return -1; line_ip = -1; - parsed_line = rtrim(line); + parsed_line = strim(line); /* /filename:linenr ? Save line number and ignore. */ if (regexec(_lineno, parsed_line, 2, match, 0) == 0) { diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 1eb15f7517b0..bf26dc85eaaa 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1048,7 +1048,7 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev return -1; cache->type[len] = 0; - cache->type = rtrim(cache->type); + cache->type = strim(cache->type); scnprintf(file, PATH_MAX, "%s/size", path); if (sysfs__read_str(file, >size, )) { @@ -1057,7 +1057,7 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev } cache->size[len] = 0; - cache->size = rtrim(cache->size); + cache->size = strim(cache->size); scnprintf(file, PATH_MAX, "%s/shared_cpu_list", path); if (sysfs__read_str(file, >map, )) { @@ -1067,7 +1067,7 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev } cache->map[len] = 0; - cache->map = rtrim(cache->map); + cache->map = strim(cache->map); return 0; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 38dc0c6e28b8..8139a1f3ed39 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -395,7 +395,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI buf[ret] = 0; /* Remove trailing newline from sysfs file */ - rtrim(buf); + strim(buf); return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 648bcd80b475..2237bac9fadb 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -16,6 +16,7 @@ util/namespaces.c ../lib/bitmap.c ../lib/find_bit.c ../lib/hweight.c +../lib/string.c ../lib/vsprintf.c util/thread_map.c util/util.c diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 10ca1533937e..1824cabe3512 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -5,6 +5,7 @@ #include #include +#include #include "util/dso.h" #include "util/util.h" @@ -464,7 +465,7 @@ static struct inline_node *addr2inlines(const char *dso_name, u64 addr, char *srcline; struct symbol *inline_sym; - rtrim(funcname); + strim(funcname); if (getline(, , fp) == -1) goto out; diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 99a555ea4a9f..93a5340424df 100644 ---
[tip:perf/core] perf tools: Remove trim() implementation, use tools/lib's strim()
Commit-ID: 3ca43b6053c9a5dbbffb02aa010c1ccf8eb460a8 Gitweb: https://git.kernel.org/tip/3ca43b6053c9a5dbbffb02aa010c1ccf8eb460a8 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 12:06:20 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 26 Jun 2019 12:06:20 -0300 perf tools: Remove trim() implementation, use tools/lib's strim() Moving more stuff out of tools/perf/util/ and using the kernel idiom. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-wpj8rktj62yse5dq6ckny...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 3 ++- tools/perf/ui/browsers/hists.c | 3 ++- tools/perf/ui/gtk/hists.c | 5 +++-- tools/perf/ui/stdio/hist.c | 2 +- tools/perf/util/string2.h | 5 - 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index cd72ff0f7658..66a82badc1d1 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -22,6 +22,7 @@ #include "string2.h" #include "symbol.h" #include +#include #include static bool dont_fork; @@ -438,7 +439,7 @@ static const char *shell_test__description(char *description, size_t size, description = fgets(description, size, fp); fclose(fp); - return description ? trim(description + 1) : NULL; + return description ? strim(description + 1) : NULL; } #define for_each_shell_test(dir, base, ent)\ diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 04a56114df92..10243408f3dc 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -1686,7 +1687,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows ret = fmt->header(fmt, _hpp, hists, 0, NULL); dummy_hpp.buf[ret] = '\0'; - start = trim(dummy_hpp.buf); + start = strim(dummy_hpp.buf); ret = strlen(start); if (start != dummy_hpp.buf) diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 6341c421a8f7..3955ed1d1bd9 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -9,6 +9,7 @@ #include "../string2.h" #include "gtk.h" #include +#include #define MAX_COLUMNS32 @@ -459,7 +460,7 @@ static void perf_gtk__add_hierarchy_entries(struct hists *hists, advance_hpp(hpp, ret + 2); } - gtk_tree_store_set(store, , col_idx, trim(bf), -1); + gtk_tree_store_set(store, , col_idx, strim(bf), -1); if (!he->leaf) { hpp->buf = bf; @@ -555,7 +556,7 @@ static void perf_gtk__show_hierarchy(GtkWidget *window, struct hists *hists, first_col = false; fmt->header(fmt, , hists, 0, NULL); - strcat(buf, trim(hpp.buf)); + strcat(buf, strim(hpp.buf)); } } diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 594e56628904..9eb0131c3ade 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -620,7 +620,7 @@ static int hists__fprintf_hierarchy_headers(struct hists *hists, fmt->header(fmt, hpp, hists, 0, NULL); - header_width += fprintf(fp, "%s", trim(hpp->buf)); + header_width += fprintf(fp, "%s", strim(hpp->buf)); } } diff --git a/tools/perf/util/string2.h b/tools/perf/util/string2.h index db02059e31c5..5bc3fea52cdc 100644 --- a/tools/perf/util/string2.h +++ b/tools/perf/util/string2.h @@ -25,11 +25,6 @@ char *strxfrchar(char *s, char from, char to); char *rtrim(char *s); -static inline char *trim(char *s) -{ - return skip_spaces(rtrim(s)); -} - char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints); static inline char *asprintf_expr_in_ints(const char *var, size_t nints, int *ints)
[tip:perf/core] perf report: Use skip_spaces()
Commit-ID: 526bbbdd442ce143b52cd6a8b4ee424f9930be0d Gitweb: https://git.kernel.org/tip/526bbbdd442ce143b52cd6a8b4ee424f9930be0d Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 11:24:37 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 26 Jun 2019 11:31:43 -0300 perf report: Use skip_spaces() No change in behaviour intended. Cc: Adrian Hunter Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-lcywlfqbi37nhegmhl1ar...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 91a3762b4211..aef59f318a67 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -941,8 +941,7 @@ parse_time_quantum(const struct option *opt, const char *arg, pr_err("time quantum cannot be 0"); return -1; } - while (isspace(*end)) - end++; + end = skip_spaces(end); if (*end == 0) return 0; if (!strcmp(end, "s")) {
[tip:perf/core] tools lib: Adopt strim() from the kernel
Commit-ID: 45bfd0ac7bd2afa83600df9c1286a1642bb15c55 Gitweb: https://git.kernel.org/tip/45bfd0ac7bd2afa83600df9c1286a1642bb15c55 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 11:50:16 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 26 Jun 2019 11:50:16 -0300 tools lib: Adopt strim() from the kernel Since we're working on moving stuff out of tools/perf/util/ to tools/lib/, take the opportunity to adopt routines from the kernel that are equivalent, so that tools/ code look more like the kernel. Cc: Adrian Hunter Cc: André Goddard Rosa Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-zqy1zdu2ok17qvi0ytk8z...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/string.h | 2 ++ tools/lib/string.c | 25 + 2 files changed, 27 insertions(+) diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index cee239350a6b..e436f8037c87 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -31,4 +31,6 @@ static inline bool strstarts(const char *str, const char *prefix) extern char * __must_check skip_spaces(const char *); +extern char *strim(char *); + #endif /* _TOOLS_LINUX_STRING_H_ */ diff --git a/tools/lib/string.c b/tools/lib/string.c index 50d400822bb3..80472e6b3829 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c @@ -120,3 +120,28 @@ char *skip_spaces(const char *str) ++str; return (char *)str; } + +/** + * strim - Removes leading and trailing whitespace from @s. + * @s: The string to be stripped. + * + * Note that the first trailing whitespace is replaced with a %NUL-terminator + * in the given string @s. Returns a pointer to the first non-whitespace + * character in @s. + */ +char *strim(char *s) +{ + size_t size; + char *end; + + size = strlen(s); + if (!size) + return s; + + end = s + size - 1; + while (end >= s && isspace(*end)) + end--; + *(end + 1) = '\0'; + + return skip_spaces(s); +}
[tip:perf/core] perf tools: Ditch rtrim(), use skip_spaces() to get closer to the kernel
Commit-ID: 328584804edc950fb4608c9a38e396ac71ef22b6 Gitweb: https://git.kernel.org/tip/328584804edc950fb4608c9a38e396ac71ef22b6 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 11:42:03 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 26 Jun 2019 11:42:03 -0300 perf tools: Ditch rtrim(), use skip_spaces() to get closer to the kernel No change in behaviour, just using the same kernel idiom for such operation. Cc: Adrian Hunter Cc: André Goddard Rosa Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-a85lkptkt0ru40irpga8y...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c| 12 ++-- tools/perf/ui/browser.c| 2 +- tools/perf/ui/browsers/hists.c | 2 +- tools/perf/ui/gtk/hists.c | 4 ++-- tools/perf/ui/stdio/hist.c | 2 +- tools/perf/util/annotate.c | 10 +- tools/perf/util/event.c| 4 +--- tools/perf/util/pmu.c | 3 ++- tools/perf/util/stat-display.c | 4 ++-- tools/perf/util/string.c | 14 -- tools/perf/util/string2.h | 4 ++-- 11 files changed, 23 insertions(+), 38 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 0131f7a0d48d..520e5b6b9ef9 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2880,7 +2880,7 @@ static int read_script_info(struct script_desc *desc, const char *filename) return -1; while (fgets(line, sizeof(line), fp)) { - p = ltrim(line); + p = skip_spaces(line); if (strlen(p) == 0) continue; if (*p != '#') @@ -2889,19 +2889,19 @@ static int read_script_info(struct script_desc *desc, const char *filename) if (strlen(p) && *p == '!') continue; - p = ltrim(p); + p = skip_spaces(p); if (strlen(p) && p[strlen(p) - 1] == '\n') p[strlen(p) - 1] = '\0'; if (!strncmp(p, "description:", strlen("description:"))) { p += strlen("description:"); - desc->half_liner = strdup(ltrim(p)); + desc->half_liner = strdup(skip_spaces(p)); continue; } if (!strncmp(p, "args:", strlen("args:"))) { p += strlen("args:"); - desc->args = strdup(ltrim(p)); + desc->args = strdup(skip_spaces(p)); continue; } } @@ -3008,7 +3008,7 @@ static int check_ev_match(char *dir_name, char *scriptname, return -1; while (fgets(line, sizeof(line), fp)) { - p = ltrim(line); + p = skip_spaces(line); if (*p == '#') continue; @@ -3018,7 +3018,7 @@ static int check_ev_match(char *dir_name, char *scriptname, break; p += 2; - p = ltrim(p); + p = skip_spaces(p); len = strcspn(p, " \t"); if (!len) break; diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 8812c1564995..55ff05a46e0b 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -594,7 +594,7 @@ static int ui_browser__color_config(const char *var, const char *value, break; *bg = '\0'; - bg = ltrim(++bg); + bg = skip_spaces(bg + 1); ui_browser__colorsets[i].bg = bg; ui_browser__colorsets[i].fg = fg; return 0; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 59483bdb0027..04a56114df92 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1470,7 +1470,7 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser, int i = 0; width -= fmt->entry(fmt, , entry); - ui_browser__printf(>b, "%s", ltrim(s)); + ui_browser__printf(>b, "%s", skip_spaces(s)); while (isspace(s[i++])) width++; diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 0c08890f006a..6341c421a8f7 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -459,7 +459,7 @@ static void perf_gtk__add_hierarchy_entries(struct hists *hists, advance_hpp(hpp, ret + 2); } - gtk_tree_store_set(store, , col_idx, ltrim(rtrim(bf)), -1); + gtk_tree_store_set(store, , col_idx, trim(bf), -1); if
[tip:perf/core] perf metricgroup: Use strsep()
Commit-ID: 80e9073f1f4473639d585b89ebc9130bb47920e8 Gitweb: https://git.kernel.org/tip/80e9073f1f4473639d585b89ebc9130bb47920e8 Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 11:21:47 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 26 Jun 2019 11:31:43 -0300 perf metricgroup: Use strsep() No change in behaviour intended, trivial optimization done by avoiding looking for spaces in 'g' right after setting it to "No_group". Cc: Adrian Hunter Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-f2siadtp3hb5o0l1w7bvd...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/metricgroup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index a0cf3cd95ced..90cd84e2a503 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -308,10 +308,9 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter, struct mep *me; char *s; + g = skip_spaces(g); if (*g == 0) g = "No_group"; - while (isspace(*g)) - g++; if (filter && !strstr(g, filter)) continue; if (raw)
[tip:perf/core] perf strfilter: Use skip_spaces()
Commit-ID: c1fc14cbdcc9455507e5f54109199bfea3af185f Gitweb: https://git.kernel.org/tip/c1fc14cbdcc9455507e5f54109199bfea3af185f Author: Arnaldo Carvalho de Melo AuthorDate: Wed, 26 Jun 2019 11:08:10 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 26 Jun 2019 11:31:43 -0300 perf strfilter: Use skip_spaces() No change in behaviour. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-p9rtamq7lvre9zhti70az...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/strfilter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c index 2c3a2904ebcd..90ea2b209cbb 100644 --- a/tools/perf/util/strfilter.c +++ b/tools/perf/util/strfilter.c @@ -5,6 +5,7 @@ #include #include +#include /* Operators */ static const char *OP_and = "&"; /* Logical AND */ @@ -37,8 +38,7 @@ static const char *get_token(const char *s, const char **e) { const char *p; - while (isspace(*s)) /* Skip spaces */ - s++; + s = skip_spaces(s); if (*s == '\0') { p = s;
[tip:perf/core] perf probe: Use skip_spaces() for argv handling
Commit-ID: ee44b5b51f37727f57962b2cdccd548c62045252 Gitweb: https://git.kernel.org/tip/ee44b5b51f37727f57962b2cdccd548c62045252 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 25 Jun 2019 21:46:39 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 26 Jun 2019 11:31:37 -0300 perf probe: Use skip_spaces() for argv handling The skip_sep() routine has the same implementation as skip_spaces(), recently adopted from the kernel, sources, switch to it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-0ix211a81z2016dl5nmtd...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/string.c | 16 ++-- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 084c3e4e9400..d28e723e2790 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -69,18 +69,6 @@ out_err: return -1; } -/* - * Helper function for splitting a string into an argv-like array. - * originally copied from lib/argv_split.c - */ -static const char *skip_sep(const char *cp) -{ - while (*cp && isspace(*cp)) - cp++; - - return cp; -} - static const char *skip_arg(const char *cp) { while (*cp && !isspace(*cp)) @@ -94,7 +82,7 @@ static int count_argc(const char *str) int count = 0; while (*str) { - str = skip_sep(str); + str = skip_spaces(str); if (*str) { count++; str = skip_arg(str); @@ -148,7 +136,7 @@ char **argv_split(const char *str, int *argcp) argvp = argv; while (*str) { - str = skip_sep(str); + str = skip_spaces(str); if (*str) { const char *p = str;
[tip:perf/core] perf time-utils: Use skip_spaces()
Commit-ID: 9bb5a27ac7958ce11cb02463b5a5f7f160d60916 Gitweb: https://git.kernel.org/tip/9bb5a27ac7958ce11cb02463b5a5f7f160d60916 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 25 Jun 2019 21:39:18 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 25 Jun 2019 21:39:18 -0300 perf time-utils: Use skip_spaces() No change in behaviour intended. Cc: Adrian Hunter Cc: David Ahern Cc: Jin Yao Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-cpugv7qd5vzhbtvnlydo9...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/time-utils.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c index 369fa19dd596..c2abc259b51d 100644 --- a/tools/perf/util/time-utils.c +++ b/tools/perf/util/time-utils.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include @@ -141,10 +142,7 @@ static int perf_time__parse_strs(struct perf_time_interval *ptime, for (i = 0, p = str; i < num - 1; i++) { arg = p; /* Find next comma, there must be one */ - p = strchr(p, ',') + 1; - /* Skip white space */ - while (isspace(*p)) - p++; + p = skip_spaces(strchr(p, ',') + 1); /* Skip the value, must not contain space or comma */ while (*p && !isspace(*p)) { if (*p++ == ',') {
[tip:perf/core] perf header: Use skip_spaces() in __write_cpudesc()
Commit-ID: fc6a172600cd54e9b4efeb684daa8464991b6c26 Gitweb: https://git.kernel.org/tip/fc6a172600cd54e9b4efeb684daa8464991b6c26 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 25 Jun 2019 21:33:14 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 25 Jun 2019 21:34:31 -0300 perf header: Use skip_spaces() in __write_cpudesc() No change in behaviour. Cc: Stephane Eranian Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-0dbfpi70aa66s6mtd8z6p...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index fca9dbaf61ae..1eb15f7517b0 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -416,10 +417,8 @@ static int __write_cpudesc(struct feat_fd *ff, const char *cpuinfo_proc) while (*p) { if (isspace(*p)) { char *r = p + 1; - char *q = r; + char *q = skip_spaces(r); *p = ' '; - while (*q && isspace(*q)) - q++; if (q != (p+1)) while ((*r++ = *q++)); }
[tip:perf/core] perf stat: Use recently introduced skip_spaces()
Commit-ID: 810826acd122ed859e238bf1555a09b326c8fe23 Gitweb: https://git.kernel.org/tip/810826acd122ed859e238bf1555a09b326c8fe23 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 25 Jun 2019 21:28:49 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 25 Jun 2019 21:28:49 -0300 perf stat: Use recently introduced skip_spaces() No change in behaviour. Cc: Andi Kleen Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ncpvp4eelf8fqhuy29uv5...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 992e327bce85..ce993d29cca5 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include "color.h" @@ -215,9 +216,7 @@ static void print_metric_csv(struct perf_stat_config *config __maybe_unused, while (isdigit(*ends) || *ends == '.') ends++; *ends = 0; - while (isspace(*unit)) - unit++; - fprintf(out, "%s%s%s%s", config->csv_sep, vals, config->csv_sep, unit); + fprintf(out, "%s%s%s%s", config->csv_sep, vals, config->csv_sep, skip_spaces(unit)); } /* Filter out some columns that don't work well in metrics only mode */
[tip:perf/core] tools lib: Adopt skip_spaces() from the kernel sources
Commit-ID: 7bd330de43fd5693e90be13dac7fbd9af3b6335d Gitweb: https://git.kernel.org/tip/7bd330de43fd5693e90be13dac7fbd9af3b6335d Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 25 Jun 2019 21:23:18 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 25 Jun 2019 21:23:18 -0300 tools lib: Adopt skip_spaces() from the kernel sources Same implementation, will be used to replace ad-hoc equivalent code in tools/. Cc: Adrian Hunter Cc: André Goddard Rosa Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-dig691cg9ripvoiprpidt...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/string.h | 4 +++- tools/lib/string.c | 14 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index 6c3e2cc274c5..cee239350a6b 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -29,4 +29,6 @@ static inline bool strstarts(const char *str, const char *prefix) return strncmp(str, prefix, strlen(prefix)) == 0; } -#endif /* _LINUX_STRING_H_ */ +extern char * __must_check skip_spaces(const char *); + +#endif /* _TOOLS_LINUX_STRING_H_ */ diff --git a/tools/lib/string.c b/tools/lib/string.c index 93b3d4b6feac..50d400822bb3 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c @@ -17,6 +17,7 @@ #include #include #include +#include #include /** @@ -106,3 +107,16 @@ size_t __weak strlcpy(char *dest, const char *src, size_t size) } return ret; } + +/** + * skip_spaces - Removes leading whitespace from @str. + * @str: The string to be stripped. + * + * Returns a pointer to the first non-whitespace character in @str. + */ +char *skip_spaces(const char *str) +{ + while (isspace(*str)) + ++str; + return (char *)str; +}
[tip:perf/core] perf tools: Use linux/ctype.h in more places
Commit-ID: bd9860bf050f77c4e260a9ae10a5587009ad6e07 Gitweb: https://git.kernel.org/tip/bd9860bf050f77c4e260a9ae10a5587009ad6e07 Author: Arnaldo Carvalho de Melo AuthorDate: Tue, 25 Jun 2019 21:13:51 -0300 Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 25 Jun 2019 21:13:51 -0300 perf tools: Use linux/ctype.h in more places There were a few places where we still were using the libc version of ctype.h, switch to the one in tools/lib/ctype.c that the rest of perf uses. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-wa4nz4kt61eze88eprk20...@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/s390/util/header.c | 2 +- tools/perf/util/metricgroup.c | 2 +- tools/perf/util/time-utils.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c index 3db85cd2069e..a25896135abe 100644 --- a/tools/perf/arch/s390/util/header.c +++ b/tools/perf/arch/s390/util/header.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "../../util/header.h" #include "../../util/util.h" diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 699e020737d9..a0cf3cd95ced 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -17,7 +17,7 @@ #include "pmu-events/pmu-events.h" #include "strlist.h" #include -#include +#include struct metric_event *metricgroup__lookup(struct rblist *metric_events, struct perf_evsel *evsel, diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c index 2b48816a2d2e..369fa19dd596 100644 --- a/tools/perf/util/time-utils.c +++ b/tools/perf/util/time-utils.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "perf.h" #include "debug.h"