diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-31 22:49:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-31 22:49:05 -0400 |
commit | 41d859a83c567a9c9f50a34082cc64aab0abb0cd (patch) | |
tree | ab911ea521701401413d041e1b92225f3dbdab41 /tools/perf/builtin-script.c | |
parent | 4658000955d1864b54890214434e171949c7f1c5 (diff) | |
parent | bac2e4a96d1c0bcce5e9654dcc902f75576b9b03 (diff) |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar:
"Main perf kernel side changes:
- uprobes updates/fixes. (Oleg Nesterov)
- Add PERF_RECORD_SWITCH to indicate context switches and use it in
tooling. (Adrian Hunter)
- Support BPF programs attached to uprobes and first steps for BPF
tooling support. (Wang Nan)
- x86 generic x86 MSR-to-perf PMU driver. (Andy Lutomirski)
- x86 Intel PT, LBR and BTS updates. (Alexander Shishkin)
- x86 Intel Skylake support. (Andi Kleen)
- x86 Intel Knights Landing (KNL) RAPL support. (Dasaratharaman
Chandramouli)
- x86 Intel Broadwell-DE uncore support. (Kan Liang)
- x86 hw breakpoints robustization (Andy Lutomirski)
Main perf tooling side changes:
- Support Intel PT in several tools, enabling the use of the
processor trace feature introduced in Intel Broadwell processors:
(Adrian Hunter)
# dmesg | grep Performance
# [0.188477] Performance Events: PEBS fmt2+, 16-deep LBR, Broadwell events, full-width counters, Intel PMU driver.
# perf record -e intel_pt//u -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.216 MB perf.data ]
# perf script # then navigate in the tool output to some area, like this one:
184 1030 dl_main (/usr/lib64/ld-2.17.so) => 7f21ba661440 dl_main (/usr/lib64/ld-2.17.so)
185 1457 dl_main (/usr/lib64/ld-2.17.so) => 7f21ba669f10 _dl_new_object (/usr/lib64/ld-2.17.so)
186 9f37 _dl_new_object (/usr/lib64/ld-2.17.so) => 7f21ba677b90 strlen (/usr/lib64/ld-2.17.so)
187 7ba3 strlen (/usr/lib64/ld-2.17.so) => 7f21ba677c75 strlen (/usr/lib64/ld-2.17.so)
188 7c78 strlen (/usr/lib64/ld-2.17.so) => 7f21ba669f3c _dl_new_object (/usr/lib64/ld-2.17.so)
189 9f8a _dl_new_object (/usr/lib64/ld-2.17.so) => 7f21ba65fab0 calloc@plt (/usr/lib64/ld-2.17.so)
190 fab0 calloc@plt (/usr/lib64/ld-2.17.so) => 7f21ba675e70 calloc (/usr/lib64/ld-2.17.so)
191 5e87 calloc (/usr/lib64/ld-2.17.so) => 7f21ba65fa90 malloc@plt (/usr/lib64/ld-2.17.so)
192 fa90 malloc@plt (/usr/lib64/ld-2.17.so) => 7f21ba675e60 malloc (/usr/lib64/ld-2.17.so)
193 5e68 malloc (/usr/lib64/ld-2.17.so) => 7f21ba65fa80 __libc_memalign@plt (/usr/lib64/ld-2.17.so)
194 fa80 __libc_memalign@plt (/usr/lib64/ld-2.17.so) => 7f21ba675d50 __libc_memalign (/usr/lib64/ld-2.17.so)
195 5d63 __libc_memalign (/usr/lib64/ld-2.17.so) => 7f21ba675e20 __libc_memalign (/usr/lib64/ld-2.17.so)
196 5e40 __libc_memalign (/usr/lib64/ld-2.17.so) => 7f21ba675d73 __libc_memalign (/usr/lib64/ld-2.17.so)
197 5d97 __libc_memalign (/usr/lib64/ld-2.17.so) => 7f21ba675e18 __libc_memalign (/usr/lib64/ld-2.17.so)
198 5e1e __libc_memalign (/usr/lib64/ld-2.17.so) => 7f21ba675df9 __libc_memalign (/usr/lib64/ld-2.17.so)
199 5e10 __libc_memalign (/usr/lib64/ld-2.17.so) => 7f21ba669f8f _dl_new_object (/usr/lib64/ld-2.17.so)
200 9fc2 _dl_new_object (/usr/lib64/ld-2.17.so) => 7f21ba678e70 memcpy (/usr/lib64/ld-2.17.so)
201 8e8c memcpy (/usr/lib64/ld-2.17.so) => 7f21ba678ea0 memcpy (/usr/lib64/ld-2.17.so)
- Add support for using several Intel PT features (CYC, MTC packets),
the relevant documentation was updated in:
tools/perf/Documentation/intel-pt.txt
briefly describing those packets, its purposes, how to configure
them in the event config terms and relevant external documentation
for further reading. (Adrian Hunter)
- Introduce support for probing at an absolute address, for user and
kernel 'perf probe's, useful when one have the symbol maps on a
developer machine but not on an embedded system. (Wang Nan)
- Add Intel BTS support, with a call-graph script to show it and PT
in use in a GUI using 'perf script' python scripting with
postgresql and Qt. (Adrian Hunter)
- Allow selecting the type of callchains per event, including
disabling callchains in all but one entry in an event list, to save
space, and also to ask for the callchains collected in one event to
be used in other events. (Kan Liang)
- Beautify more syscall arguments in 'perf trace': (Arnaldo Carvalho
de Melo)
* A bunch more translate file/pathnames from pointers to strings.
* Convert numbers to strings for the 'keyctl' syscall 'option'
arg.
* Add missing 'clockid' entries.
- Introduce 'srcfile' sort key: (Andi Kleen)
# perf record -F 10000 usleep 1
# perf report --stdio --dsos '[kernel.vmlinux]' -s srcfile
<SNIP>
# Overhead Source File
26.49% copy_page_64.S
5.49% signal.c
0.51% msr.h
#
It can be combined with other fields, for instance, experiment with
'-s srcfile,symbol'.
There are some oddities in some distros and with some specific
DSOs, being investigated, so your mileage may vary.
- Support per-event 'freq' term: (Namhyung Kim)
$ perf record -e 'cpu/instructions,freq=1234/',cycles -c 1000 sleep 1
$ perf evlist -F
cpu/instructions,freq=1234/: sample_freq=1234
cycles: sample_period=1000
$
- Deref sys_enter pointer args with contents from probe:vfs_getname,
showing pathnames instead of pointers in many syscalls in 'perf
trace'. (Arnaldo Carvalho de Melo)
- Stop collecting /proc/kallsyms in perf.data files, saving about
4.5MB on a typical x86-64 system, use the the symbol resolution
routines used in all the other tools (report, top, etc) now that we
can ask libtraceevent to use perf's symbol resolution code.
(Arnaldo Carvalho de Melo)
- Allow filtering out of perf's PID via 'perf record --exclude-perf'.
(Wang Nan)
- 'perf trace' now supports syscall groups, like strace, i.e:
$ trace -e file touch file
Will expand 'file' into multiple, file related, syscalls. More
work needed to add extra groups for other syscall groups, and also
to complement what was added for the 'file' group, included as a
proof of concept. (Arnaldo Carvalho de Melo)
- Add lock_pi stresser to 'perf bench futex', to test the kernel code
related to FUTEX_(UN)LOCK_PI. (Davidlohr Bueso)
- Let user have timestamps with per-thread recording in 'perf record'
(Adrian Hunter)
- ... and tons of other changes, see the shortlog and the Git log for
details"
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (240 commits)
perf evlist: Add backpointer for perf_env to evlist
perf tools: Rename perf_session_env to perf_env
perf tools: Do not change lib/api/fs/debugfs directly
perf tools: Add tracing_path and remove unneeded functions
perf buildid: Introduce sysfs/filename__sprintf_build_id
perf evsel: Add a backpointer to the evlist a evsel is in
perf trace: Add header with copyright and background info
perf scripts python: Add new compaction-times script
perf stat: Get correct cpu id for print_aggr
tools lib traceeveent: Allow for negative numbers in print format
perf script: Add --[no-]-demangle/--[no-]-demangle-kernel
tracing/uprobes: Do not print '0x (null)' when offset is 0
perf probe: Support probing at absolute address
perf probe: Fix error reported when offset without function
perf probe: Fix list result when address is zero
perf probe: Fix list result when symbol can't be found
tools build: Allow duplicate objects in the object list
perf tools: Remove export.h from MANIFEST
perf probe: Prevent segfault when reading probe point with absolute address
perf tools: Update Intel PT documentation
...
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 24809787369f..4430340292c0 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -623,6 +623,7 @@ struct perf_script { | |||
623 | struct perf_session *session; | 623 | struct perf_session *session; |
624 | bool show_task_events; | 624 | bool show_task_events; |
625 | bool show_mmap_events; | 625 | bool show_mmap_events; |
626 | bool show_switch_events; | ||
626 | }; | 627 | }; |
627 | 628 | ||
628 | static int process_attr(struct perf_tool *tool, union perf_event *event, | 629 | static int process_attr(struct perf_tool *tool, union perf_event *event, |
@@ -661,7 +662,7 @@ static int process_comm_event(struct perf_tool *tool, | |||
661 | struct thread *thread; | 662 | struct thread *thread; |
662 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 663 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
663 | struct perf_session *session = script->session; | 664 | struct perf_session *session = script->session; |
664 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 665 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
665 | int ret = -1; | 666 | int ret = -1; |
666 | 667 | ||
667 | thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); | 668 | thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); |
@@ -695,7 +696,7 @@ static int process_fork_event(struct perf_tool *tool, | |||
695 | struct thread *thread; | 696 | struct thread *thread; |
696 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 697 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
697 | struct perf_session *session = script->session; | 698 | struct perf_session *session = script->session; |
698 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 699 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
699 | 700 | ||
700 | if (perf_event__process_fork(tool, event, sample, machine) < 0) | 701 | if (perf_event__process_fork(tool, event, sample, machine) < 0) |
701 | return -1; | 702 | return -1; |
@@ -727,7 +728,7 @@ static int process_exit_event(struct perf_tool *tool, | |||
727 | struct thread *thread; | 728 | struct thread *thread; |
728 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 729 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
729 | struct perf_session *session = script->session; | 730 | struct perf_session *session = script->session; |
730 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 731 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
731 | 732 | ||
732 | thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); | 733 | thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); |
733 | if (thread == NULL) { | 734 | if (thread == NULL) { |
@@ -759,7 +760,7 @@ static int process_mmap_event(struct perf_tool *tool, | |||
759 | struct thread *thread; | 760 | struct thread *thread; |
760 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 761 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
761 | struct perf_session *session = script->session; | 762 | struct perf_session *session = script->session; |
762 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 763 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
763 | 764 | ||
764 | if (perf_event__process_mmap(tool, event, sample, machine) < 0) | 765 | if (perf_event__process_mmap(tool, event, sample, machine) < 0) |
765 | return -1; | 766 | return -1; |
@@ -790,7 +791,7 @@ static int process_mmap2_event(struct perf_tool *tool, | |||
790 | struct thread *thread; | 791 | struct thread *thread; |
791 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 792 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
792 | struct perf_session *session = script->session; | 793 | struct perf_session *session = script->session; |
793 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 794 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
794 | 795 | ||
795 | if (perf_event__process_mmap2(tool, event, sample, machine) < 0) | 796 | if (perf_event__process_mmap2(tool, event, sample, machine) < 0) |
796 | return -1; | 797 | return -1; |
@@ -813,6 +814,32 @@ static int process_mmap2_event(struct perf_tool *tool, | |||
813 | return 0; | 814 | return 0; |
814 | } | 815 | } |
815 | 816 | ||
817 | static int process_switch_event(struct perf_tool *tool, | ||
818 | union perf_event *event, | ||
819 | struct perf_sample *sample, | ||
820 | struct machine *machine) | ||
821 | { | ||
822 | struct thread *thread; | ||
823 | struct perf_script *script = container_of(tool, struct perf_script, tool); | ||
824 | struct perf_session *session = script->session; | ||
825 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); | ||
826 | |||
827 | if (perf_event__process_switch(tool, event, sample, machine) < 0) | ||
828 | return -1; | ||
829 | |||
830 | thread = machine__findnew_thread(machine, sample->pid, | ||
831 | sample->tid); | ||
832 | if (thread == NULL) { | ||
833 | pr_debug("problem processing SWITCH event, skipping it.\n"); | ||
834 | return -1; | ||
835 | } | ||
836 | |||
837 | print_sample_start(sample, thread, evsel); | ||
838 | perf_event__fprintf(event, stdout); | ||
839 | thread__put(thread); | ||
840 | return 0; | ||
841 | } | ||
842 | |||
816 | static void sig_handler(int sig __maybe_unused) | 843 | static void sig_handler(int sig __maybe_unused) |
817 | { | 844 | { |
818 | session_done = 1; | 845 | session_done = 1; |
@@ -834,6 +861,8 @@ static int __cmd_script(struct perf_script *script) | |||
834 | script->tool.mmap = process_mmap_event; | 861 | script->tool.mmap = process_mmap_event; |
835 | script->tool.mmap2 = process_mmap2_event; | 862 | script->tool.mmap2 = process_mmap2_event; |
836 | } | 863 | } |
864 | if (script->show_switch_events) | ||
865 | script->tool.context_switch = process_switch_event; | ||
837 | 866 | ||
838 | ret = perf_session__process_events(script->session); | 867 | ret = perf_session__process_events(script->session); |
839 | 868 | ||
@@ -1532,6 +1561,22 @@ static int have_cmd(int argc, const char **argv) | |||
1532 | return 0; | 1561 | return 0; |
1533 | } | 1562 | } |
1534 | 1563 | ||
1564 | static void script__setup_sample_type(struct perf_script *script) | ||
1565 | { | ||
1566 | struct perf_session *session = script->session; | ||
1567 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); | ||
1568 | |||
1569 | if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { | ||
1570 | if ((sample_type & PERF_SAMPLE_REGS_USER) && | ||
1571 | (sample_type & PERF_SAMPLE_STACK_USER)) | ||
1572 | callchain_param.record_mode = CALLCHAIN_DWARF; | ||
1573 | else if (sample_type & PERF_SAMPLE_BRANCH_STACK) | ||
1574 | callchain_param.record_mode = CALLCHAIN_LBR; | ||
1575 | else | ||
1576 | callchain_param.record_mode = CALLCHAIN_FP; | ||
1577 | } | ||
1578 | } | ||
1579 | |||
1535 | int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | 1580 | int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) |
1536 | { | 1581 | { |
1537 | bool show_full_info = false; | 1582 | bool show_full_info = false; |
@@ -1618,10 +1663,19 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1618 | "Show the fork/comm/exit events"), | 1663 | "Show the fork/comm/exit events"), |
1619 | OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, | 1664 | OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, |
1620 | "Show the mmap events"), | 1665 | "Show the mmap events"), |
1666 | OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events, | ||
1667 | "Show context switch events (if recorded)"), | ||
1621 | OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), | 1668 | OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), |
1622 | OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", | 1669 | OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", |
1623 | "Instruction Tracing options", | 1670 | "Instruction Tracing options", |
1624 | itrace_parse_synth_opts), | 1671 | itrace_parse_synth_opts), |
1672 | OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename, | ||
1673 | "Show full source file name path for source lines"), | ||
1674 | OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, | ||
1675 | "Enable symbol demangling"), | ||
1676 | OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, | ||
1677 | "Enable kernel symbol demangling"), | ||
1678 | |||
1625 | OPT_END() | 1679 | OPT_END() |
1626 | }; | 1680 | }; |
1627 | const char * const script_subcommands[] = { "record", "report", NULL }; | 1681 | const char * const script_subcommands[] = { "record", "report", NULL }; |
@@ -1816,6 +1870,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1816 | goto out_delete; | 1870 | goto out_delete; |
1817 | 1871 | ||
1818 | script.session = session; | 1872 | script.session = session; |
1873 | script__setup_sample_type(&script); | ||
1819 | 1874 | ||
1820 | session->itrace_synth_opts = &itrace_synth_opts; | 1875 | session->itrace_synth_opts = &itrace_synth_opts; |
1821 | 1876 | ||
@@ -1830,6 +1885,14 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1830 | else | 1885 | else |
1831 | symbol_conf.use_callchain = false; | 1886 | symbol_conf.use_callchain = false; |
1832 | 1887 | ||
1888 | if (session->tevent.pevent && | ||
1889 | pevent_set_function_resolver(session->tevent.pevent, | ||
1890 | machine__resolve_kernel_addr, | ||
1891 | &session->machines.host) < 0) { | ||
1892 | pr_err("%s: failed to set libtraceevent function resolver\n", __func__); | ||
1893 | return -1; | ||
1894 | } | ||
1895 | |||
1833 | if (generate_script_lang) { | 1896 | if (generate_script_lang) { |
1834 | struct stat perf_stat; | 1897 | struct stat perf_stat; |
1835 | int input; | 1898 | int input; |