perf/core improvements and fixes
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling, more to come! :-)
- Arnaldo
The following changes since commit ddcd0973fe02aad3d4bdc59dd0f1db90f51105a9:
perf/x86/uncore: Rename IvyTown to IvyBridge-EP (2014-08-13 07:51:18 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to 1c65056c547141a0cb52fb8e6056f63524d2bbf2:
perf evlist: Add perf_evlist__enable_event_idx() (2014-08-13 19:23:48 -0300)
----------------------------------------------------------------
perf/probe fixes and improvements:
User visible changes:
. Do not show +/- callchain expansion when there are no childs (top/report) (Namhyung Kim)
. Fix -z and add respective 'z' hotkey to zero samples before refresh
in 'perf top' (Namhyung Kim)
. Capability probing fixes, improving the detection of
kernel features for non-priviledged users (Adrian Hunter)
. Add beautifier for mremap flags param in 'trace' (Alex Snast)
. Fix --list and --del options to show events when just uprobes is
enabled (Masami Hiramatsu)
. perf script: Allow callchains if any event samples them
. Don't look for kernel idle symbols in all DSOs in 'perf top' (Arnaldo Carvalho de Melo)
. Add cpu_startup_entry to the list of kernel idle symbols (Arnaldo Carvalho de Melo)
. 'perf top' terminal output fixes (Jiri Olsa)
. Fix stdin handling for 'perf kvm stat live' (Jiri Olsa)
. Fix missing label symbols (Adrian Hunter)
. Don't demangle C++ parameters and such by default, only in
--verbose mode (Namhyung Kim)
. Set proper sort__mode for the branch option (Naohiro Aota)
. Check recorded kernel version when finding vmlinux (Namhyung Kim)
Developer Stuff:
. More prep work for intel PT (Adrian Hunter)
. Fix possible memory leaks (Namhyung Kim)
. Fix a memory leak in vmlinux_path__init() (Namhyung Kim)
----------------------------------------------------------------
Adrian Hunter (14):
perf tools: Fix CLOEXEC probe for perf_event_paranoid == 2 perf tools: Fix one of the probe events to exclude kernel perf tools: Fix probing the kernel API with cpu-wide events perf tools: Prefer to use a cpu-wide event for probing CLOEXEC perf symbols: Fix missing label symbols
perf evlist: Add 'system_wide' option
perf evlist: Add perf_evlist__set_tracking_event() perf session: Add perf_session__peek_event()
perf script: Allow callchains if any event samples them perf script python: Add helpers for calling Python objects perf tools: Identify which comms are from exec
perf machine: Add machine__thread_exec_comm()
perf tools: Add flags and insn_len to struct sample perf evlist: Add perf_evlist__enable_event_idx()
Alex Snast (1):
perf trace: Add beautifier for mremap flags param
Arnaldo Carvalho de Melo (2):
perf top: Don't look for kernel idle symbols in all DSOs perf tools: Add cpu_startup_entry to the list of kernel idle symbols
Jiri Olsa (4):
perf top: Join the display thread on exit
perf tools: Introduce set_term_quiet_input helper function perf top: Setup signals for terminal output
perf kvm: Fix stdin handling for 'kvm stat live' command
Masami Hiramatsu (2):
perf probe: Fix --list option to show events only with uprobe events perf probe: Fix --del option to delete events only with uprobe events
Namhyung Kim (17):
perf script: Fix possible memory leaks
perf symbols: Fix a memory leak in vmlinux_path__init() perf annotate: Move session handling out of __cmd_annotate() perf buildid-cache: Move session handling into cmd_buildid_cache() perf inject: Move session handling out of __cmd_inject() perf kmem: Move session handling out of __cmd_kmem() perf kvm: Move call to symbol__init() after creating session perf lock: Move call to symbol__init() after creating session perf sched: Move call to symbol__init() after creating session perf script: Move call to symbol__init() after creating session perf timechart: Move call to symbol__init() after creating session perf trace: Move call to symbol__init() after creating session perf tools: Check recorded kernel version when finding vmlinux perf hists browser: Fix a small callchain display bug perf top: Fix -z option behavior
perf top: Handle 'z' key for toggle zeroing samples in TUI perf symbols: Don't demangle parameters and such by default
[email protected] (1):
perf report: Set proper sort__mode for the branch option
tools/perf/builtin-annotate.c | 75 +++++++------- tools/perf/builtin-buildid-cache.c | 37 ++++--- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-inject.c | 31 +++--- tools/perf/builtin-kmem.c | 49 +++++---- tools/perf/builtin-kvm.c | 24 ++--- tools/perf/builtin-lock.c | 3 +- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 4 +- tools/perf/builtin-sched.c | 3 +- tools/perf/builtin-script.c | 57 +++++++---- tools/perf/builtin-timechart.c | 4 +- tools/perf/builtin-top.c | 59 ++++++++--- tools/perf/builtin-trace.c | 34 +++++- tools/perf/tests/builtin-test.c | 2 +- tools/perf/ui/browsers/hists.c | 13 ++- tools/perf/util/cloexec.c | 23 ++++- tools/perf/util/comm.c | 7 +- tools/perf/util/comm.h | 6 +- tools/perf/util/event.h | 2 + tools/perf/util/evlist.c | 109 ++++++++++++++++++-- tools/perf/util/evlist.h | 5 + tools/perf/util/evsel.c | 34 ++++-- tools/perf/util/evsel.h | 2 + tools/perf/util/hist.c | 22 ++++ tools/perf/util/hist.h | 1 + tools/perf/util/machine.c | 30 +++++- tools/perf/util/machine.h | 4 + tools/perf/util/probe-event.c | 98 ++++++++++++------ tools/perf/util/record.c | 40 ++++++-- .../util/scripting-engines/trace-event-python.c | 114 +++++++++------------ tools/perf/util/session.c | 79 +++++++++++++- tools/perf/util/session.h | 5 + tools/perf/util/symbol-elf.c | 9 +- tools/perf/util/symbol.c | 31 ++++-- tools/perf/util/symbol.h | 4 +- tools/perf/util/thread.c | 24 ++++- tools/perf/util/thread.h | 10 +- tools/perf/util/util.c | 13 +++ tools/perf/util/util.h | 2 + 41 files changed, 770 insertions(+), 305 deletions(-)
Arnaldo Carvalho de Melo
maintainerPATCH 1/41 perf top: Don't look for kernel idle symbols in all DSOs
From: Arnaldo Carvalho de Melo <[email protected]>
The 'top' tool initially supported only kernel symbols, when making it support userspace symbols we forgot to make the symbol filter first check that the DSO is the kernel one. Fix it.
Cc: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Don Zickus <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
c: Stephane Eranian <[email protected]>
--- tools/perf/builtin-top.c | 4 +++- tools/perf/util/symbol.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-)
tools/perf/builtin-top.c +3 -1
@@ -623,10 +623,12 @@ repeat:return NULL ; } -static int symbol_filter (struct map *map__maybe_unused ,struct symbol *sym) +static int symbol_filter (struct map *map,struct symbol *sym) {const char *name = sym->name; +if (!map->dso->kernel) +return 0 ;/* * ppc64 uses function descriptors and appends a '.' to the * start of every instruction address. Remove it.
tools/perf/util/symbol.c +4 -0
@@ -523,6 +523,10 @@ struct process_kallsyms_args {struct dso *dso; }; +/* +* These are symbols in the kernel image, so make sure that +* sym is from a kernel DSO. +*/ bool symbol__is_idle (struct symbol *sym) {const char *const idle_symbols[] = {
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 2/41 perf tools: Add cpu_startup_entry to the list of kernel idle symbols
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
--- tools/perf/util/symbol.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/util/symbol.c +1 -0
@@ -531,6 +531,7 @@ bool symbol__is_idle(struct symbol *sym) {const char *const idle_symbols[] = {"cpu_idle" , +"cpu_startup_entry" ,"intel_idle" ,"default_idle" ,"native_safe_halt" ,
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 3/41 perf top: Join the display thread on exit
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
We create the display thread, but never join it. It gives the display thread a chance to quit and cleanup properly.
--- tools/perf/builtin-top.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/builtin-top.c +3 -1
@@ -965,7 +965,7 @@ static int __cmd_top(struct perf_top *top) param.sched_priority = top->realtime_prio;if (sched_setscheduler (0 ,SCHED_FIFO , ¶m)) {ui__error ("Could not set realtime priority.\n" ); - goto out_delete; + goto out_join; } }
@@ -979,6 +979,8 @@ static int __cmd_top(struct perf_top *top) } ret =0 ; +out_join: +pthread_join (thread,NULL ); out_delete:perf_session__delete (top->session); top->session =NULL ;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 4/41 perf tools: Introduce set_term_quiet_input helper function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding set_term_quiet_input helper to set the terminal quiet, out from 'perf top', used in following patches in 'perf kvm'.
--- tools/perf/builtin-top.c | 10 ++-------- tools/perf/util/util.c | 13 +++++++++++++ tools/perf/util/util.h | 2 ++ 3 files changed, 17 insertions(+), 8 deletions(-)
tools/perf/builtin-top.c +2 -8
@@ -580,20 +580,14 @@ static void *display_thread_tui(void *arg)static void *display_thread (void *arg) {struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; -struct termios tc, save; +struct termios save;struct perf_top *top = arg;int delay_msecs, c; -tcgetattr (0 , &save); - tc = save; - tc.c_lflag &= ~(ICANON |ECHO ); - tc.c_cc[VMIN ] =0 ; - tc.c_cc[VTIME ] =0 ; -pthread__unblock_sigwinch (); repeat: delay_msecs = top->delay_secs *1000 ; -tcsetattr (0 ,TCSANOW , &tc); +set_term_quiet_input (&save);/* trash return*/ getc (stdin);
tools/perf/util/util.c +13 -0
@@ -13,6 +13,7 @@#include <limits.h> #include <byteswap.h> #include <linux/kernel.h> +#include <unistd.h> /* * XXX We need to find a better place for these things...
@@ -282,6 +283,18 @@ void get_term_dimensions(struct winsize *ws) ws->ws_col =80 ; } +void set_term_quiet_input (struct termios *old) +{ +struct termios tc; + +tcgetattr (0 , old); + tc = *old; + tc.c_lflag &= ~(ICANON |ECHO ); + tc.c_cc[VMIN ] =0 ; + tc.c_cc[VTIME ] =0 ; +tcsetattr (0 ,TCSANOW , &tc); +} +static void set_tracing_events_path (const char *mountpoint) { snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
tools/perf/util/util.h +2 -0
@@ -75,6 +75,7 @@#include <api/fs/debugfs.h> #include <termios.h> #include <linux/bitops.h> +#include <termios.h> extern const char *graph_line;extern const char *graph_dotted_line;
@@ -308,6 +309,7 @@ extern unsigned int page_size;extern int cacheline_size;void get_term_dimensions (struct winsize *ws); +void set_term_quiet_input (struct termios *old);struct parse_tag {char tag;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 5/41 perf top: Setup signals for terminal output
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
The TUI code setup standard signals handling, while the stdio display code does not. This leads to premature termination of display thread when signal is received and leaving terminal in wrong state.
Also adding terminal cleanup at the end of display thread, to ensure we get the old terminal state in case of signal interruption.
--- tools/perf/builtin-top.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
tools/perf/builtin-top.c +16 -0
@@ -577,6 +577,20 @@ static void *display_thread_tui(void *arg)return NULL ; } +static void display_sig (int sig__maybe_unused ) +{ + done =1 ; +} + +static void display_setup_sig (void ) +{ +signal (SIGSEGV , display_sig); +signal (SIGFPE , display_sig); +signal (SIGINT , display_sig); +signal (SIGQUIT , display_sig); +signal (SIGTERM , display_sig); +} +static void *display_thread (void *arg) {struct pollfd stdin_poll = { .fd =0 , .events =POLLIN };
@@ -584,6 +598,7 @@ static void *display_thread(void *arg)struct perf_top *top = arg;int delay_msecs, c; +display_setup_sig ();pthread__unblock_sigwinch (); repeat: delay_msecs = top->delay_secs *1000 ;
@@ -614,6 +629,7 @@ repeat: } } +tcsetattr (0 ,TCSAFLUSH , &save);return NULL ; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 6/41 perf kvm: Fix stdin handling for 'kvm stat live' command
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Currently the initial ~(ICANON | ECHO) terminal mode is not set, so we dont get stdin data until we press ENTER.
Fixing this by early setting of the ~(ICANON | ECHO) mode and leaving this mode for whole life of the command, because canonical mode is not needed.
--- tools/perf/builtin-kvm.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-)
tools/perf/builtin-kvm.c +5 -13
@@ -885,15 +885,11 @@ static int fd_set_nonblock(int fd)return 0 ; } -static -int perf_kvm__handle_stdin (struct termios *tc_now,struct termios *tc_save) +static int perf_kvm__handle_stdin (void ) {int c; -tcsetattr (0 ,TCSANOW , tc_now); c =getc (stdin); -tcsetattr (0 ,TCSAFLUSH , tc_save); -if (c =='q' )return 1 ;
@@ -904,7 +900,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) {struct pollfd *pollfds =NULL ;int nr_fds, nr_stdin, ret, err = -EINVAL ; -struct termios tc, save; +struct termios save;/* live flag must be set first */ kvm->live = true;
@@ -919,14 +915,9 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) goto out; } +set_term_quiet_input (&save);init_kvm_event_record (kvm); -tcgetattr (0 , &save); - tc = save; - tc.c_lflag &= ~(ICANON |ECHO ); - tc.c_cc[VMIN ] =0 ; - tc.c_cc[VTIME ] =0 ; -signal (SIGINT , sig_handler);signal (SIGTERM , sig_handler);
@@ -972,7 +963,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) goto out;if (pollfds[nr_stdin].revents &POLLIN ) - done =perf_kvm__handle_stdin (&tc, &save); + done =perf_kvm__handle_stdin ();if (!rc && !done) err =poll (pollfds, nr_fds,100 );
@@ -989,6 +980,7 @@ out:if (kvm->timerfd >=0 )close (kvm->timerfd); +tcsetattr (0 ,TCSAFLUSH , &save);free (pollfds);return err; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 7/41 perf probe: Fix --list option to show events only with uprobe events
In reply to Arnaldo Carvalho de MeloFrom: Masami Hiramatsu <[email protected]>
Current perf probe --list doesn't work if only CONFIG_UPROBE_EVENTS=y because it aborts when it fails to open kprobe_events file before checking uprobe_events file.
This fixes --list option to show dynamic events if it can open either kprobe_events or uprobe_events. Only if it failed to open both of them, it shows an error message and aborts.
Without this patch, if we run perf probe -l on the kernel configured with CONFIG_KPROBE_EVENTS=n and CONFIG_UPROBE_EVENTS=y,
# perf probe -l
/sys/kernel/debug/tracing/kprobe_events file does not exist - please rebuild ker
Error: Failed to show event list.With this patch,
# perf probe -l
probe_perf:alloc_event (on alloc_event@lib/traceevent/event-parse.c in /home/fedora/ksrc/linux-3/tools/perf/perf)Changes in v2:
- Use strerror_r instead of strerror.
--- tools/perf/util/probe-event.c | 89 ++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 30 deletions(-)
tools/perf/util/probe-event.c +59 -30
@@ -1780,10 +1780,11 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)memset (tev,0 ,sizeof (*tev)); } -static void print_warn_msg (const char *file,bool is_kprobe) +static void print_open_warning (int err,bool is_kprobe) { +char sbuf[128 ]; -if (errno ==ENOENT ) { +if (err == -ENOENT ) {const char *config;if (!is_kprobe)
@@ -1791,25 +1792,26 @@ static void print_warn_msg(const char *file, bool is_kprobe)else config ="CONFIG_KPROBE_EVENTS" ; -pr_warning ("%s file does not exist - please rebuild kernel" -" with %s.\n" , file, config); - }else -pr_warning ("Failed to open %s file: %s\n" , file, -strerror (errno)); +pr_warning ("%cprobe_events file does not exist" +" - please rebuild kernel with %s.\n" , + is_kprobe ?'k' :'u' , config); + }else if (err == -ENOTSUP ) +pr_warning ("Debugfs is not mounted.\n" ); +else +pr_warning ("Failed to open %cprobe_events: %s\n" , + is_kprobe ?'k' :'u' , +strerror_r (-err, sbuf,sizeof (sbuf))); } -static int open_probe_events (const char *trace_file,bool readwrite, -bool is_kprobe) +static int open_probe_events (const char *trace_file,bool readwrite) {char buf[PATH_MAX ];const char *__debugfs;int ret; __debugfs =debugfs_find_mountpoint (); -if (__debugfs ==NULL ) { -pr_warning ("Debugfs is not mounted.\n" ); -return -ENOENT ; - } +if (__debugfs ==NULL ) +return -ENOTSUP ; ret =e_snprintf (buf,PATH_MAX ,"%s/%s" , __debugfs, trace_file);if (ret >=0 ) {
@@ -1820,19 +1822,19 @@ static int open_probe_events(const char *trace_file, bool readwrite, ret =open (buf,O_RDONLY ,0 );if (ret <0 ) -print_warn_msg (buf, is_kprobe); + ret = -errno; }return ret; }static int open_kprobe_events (bool readwrite) { -return open_probe_events ("tracing/kprobe_events" , readwrite, true); +return open_probe_events ("tracing/kprobe_events" , readwrite); }static int open_uprobe_events (bool readwrite) { -return open_probe_events ("tracing/uprobe_events" , readwrite, false); +return open_probe_events ("tracing/uprobe_events" , readwrite); }/* Get raw string list of current kprobe_events or uprobe_events */
@@ -1940,27 +1942,47 @@ static int __show_perf_probe_events(int fd, bool is_kprobe)/* List up current perf-probe events */ int show_perf_probe_events (void ) { -int fd, ret; +int kp_fd, up_fd, ret;setup_pager (); - fd =open_kprobe_events (false); - -if (fd <0 ) -return fd; ret =init_symbol_maps (false);if (ret <0 )return ret; - ret =__show_perf_probe_events (fd, true); -close (fd); + kp_fd =open_kprobe_events (false); +if (kp_fd >=0 ) { + ret =__show_perf_probe_events (kp_fd, true); +close (kp_fd); +if (ret <0 ) + goto out; + } - fd =open_uprobe_events (false); -if (fd >=0 ) { - ret =__show_perf_probe_events (fd, false); -close (fd); + up_fd =open_uprobe_events (false); +if (kp_fd <0 && up_fd <0 ) { +/* Both kprobes and uprobes are disabled, warn it. */ +if (kp_fd == -ENOTSUP && up_fd == -ENOTSUP ) +pr_warning ("Debugfs is not mounted.\n" ); +else if (kp_fd == -ENOENT && up_fd == -ENOENT ) +pr_warning ("Please rebuild kernel with " +"CONFIG_KPROBE_EVENTS or/and " +"CONFIG_UPROBE_EVENTS.\n" ); +else { +char sbuf[128 ]; +pr_warning ("Failed to open kprobe events: %s.\n" , +strerror_r (-kp_fd, sbuf,sizeof (sbuf))); +pr_warning ("Failed to open uprobe events: %s.\n" , +strerror_r (-up_fd, sbuf,sizeof (sbuf))); + } + ret = kp_fd; + goto out; } +if (up_fd >=0 ) { + ret =__show_perf_probe_events (up_fd, false); +close (up_fd); + } +out:exit_symbol_maps ();return ret; }
@@ -2075,8 +2097,11 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,else fd =open_kprobe_events (true); -if (fd <0 ) +if (fd <0 ) { +print_open_warning (fd, !pev->uprobes);return fd; + } +/* Get current event names */ namelist =get_probe_trace_event_names (fd, false);if (!namelist) {
@@ -2449,13 +2474,17 @@ int del_perf_probe_events(struct strlist *dellist)/* Get current event names */ kfd =open_kprobe_events (true); -if (kfd <0 ) +if (kfd <0 ) { +print_open_warning (kfd, true);return kfd; + } namelist =get_probe_trace_event_names (kfd, true); ufd =open_uprobe_events (true); -if (ufd >=0 ) +if (ufd <0 ) +print_open_warning (ufd, false); +else unamelist =get_probe_trace_event_names (ufd, true);if (namelist ==NULL && unamelist ==NULL )
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 8/41 perf probe: Fix --del option to delete events only with uprobe events
In reply to Arnaldo Carvalho de MeloFrom: Masami Hiramatsu <[email protected]>
Current perf probe --del doesn't work if only CONFIG_UPROBE_EVENTS=y because it aborts when it fails to open kprobe_events file before checking uprobe_events file.
This fixes --del option to delete dynamic events if it can open either kprobe_events or uprobe_events. Only if it failed to open both of them, it shows an error message and aborts.
Without this patch, if we run perf probe -d on the kernel configured with CONFIG_KPROBE_EVENTS=n and CONFIG_UPROBE_EVENTS=y,
# perf probe -d \*
kprobe_events file does not exist - please rebuild kernel with CONFIG_KPROBE_EVENTS.
Error: Failed to delete events.With this patch,
# perf probe -d \* Removed event: probe_perf:alloc_event
Changes in v2:
- Use strerror_r instead of strerror.
--- tools/perf/util/probe-event.c | 49 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-)
tools/perf/util/probe-event.c +26 -23
@@ -1803,6 +1803,23 @@ static void print_open_warning(int err, bool is_kprobe) strerror_r(-err, sbuf, sizeof(sbuf))); } +static void print_both_open_warning (int kerr,int uerr) +{ +/* Both kprobes and uprobes are disabled, warn it. */ +if (kerr == -ENOTSUP && uerr == -ENOTSUP ) +pr_warning ("Debugfs is not mounted.\n" ); +else if (kerr == -ENOENT && uerr == -ENOENT ) +pr_warning ("Please rebuild kernel with CONFIG_KPROBE_EVENTS " +"or/and CONFIG_UPROBE_EVENTS.\n" ); +else { +char sbuf[128 ]; +pr_warning ("Failed to open kprobe events: %s.\n" , +strerror_r (-kerr, sbuf,sizeof (sbuf))); +pr_warning ("Failed to open uprobe events: %s.\n" , +strerror_r (-uerr, sbuf,sizeof (sbuf))); + } +} +static int open_probe_events (const char *trace_file,bool readwrite) {char buf[PATH_MAX ];
@@ -1960,20 +1977,7 @@ int show_perf_probe_events(void) up_fd =open_uprobe_events (false);if (kp_fd <0 && up_fd <0 ) { -/* Both kprobes and uprobes are disabled, warn it. */ -if (kp_fd == -ENOTSUP && up_fd == -ENOTSUP ) -pr_warning ("Debugfs is not mounted.\n" ); -else if (kp_fd == -ENOENT && up_fd == -ENOENT ) -pr_warning ("Please rebuild kernel with " -"CONFIG_KPROBE_EVENTS or/and " -"CONFIG_UPROBE_EVENTS.\n" ); -else { -char sbuf[128 ]; -pr_warning ("Failed to open kprobe events: %s.\n" , -strerror_r (-kp_fd, sbuf,sizeof (sbuf))); -pr_warning ("Failed to open uprobe events: %s.\n" , -strerror_r (-up_fd, sbuf,sizeof (sbuf))); - } +print_both_open_warning (kp_fd, up_fd); ret = kp_fd; goto out; }
@@ -2474,19 +2478,18 @@ int del_perf_probe_events(struct strlist *dellist)/* Get current event names */ kfd =open_kprobe_events (true); -if (kfd <0 ) { -print_open_warning (kfd, true); -return kfd; - } +if (kfd >=0 ) + namelist =get_probe_trace_event_names (kfd, true); - namelist =get_probe_trace_event_names (kfd, true); ufd =open_uprobe_events (true); - -if (ufd <0 ) -print_open_warning (ufd, false); -else +if (ufd >=0 ) unamelist =get_probe_trace_event_names (ufd, true); +if (kfd <0 && ufd <0 ) { +print_both_open_warning (kfd, ufd); + goto error; + } +if (namelist ==NULL && unamelist ==NULL ) goto error;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 9/41 perf trace: Add beautifier for mremap flags param
In reply to Arnaldo Carvalho de MeloFrom: Alex Snast <[email protected]>
~/devel/kernel/tools/perf(branch:master*) » sudo ./perf trace ~/mremap_test
0.543 ( 0.003 ms): mprotect(start: 0x600000, len: 4096, prot: READ ) = 0
0.550 ( 0.003 ms): mprotect(start: 0x7f441260d000, len: 4096, prot: READ) = 0
0.561 ( 0.010 ms): munmap(addr: 0x7f44125e2000, len: 165572 ) = 0
0.595 ( 0.012 ms): mmap(len: 12288, prot: READ|WRITE, flags: SHARED|ANONYMOUS|LOCKED, fd: -1) = 0x12608000
0.603 ( 0.006 ms): mremap(addr: 0x7f4412608000, old_len: 4096, new_len: 4096, flags: MAYMOVE|FIXED, new_addr: 0x7f16da295000) = 0xda295000
0.608 ( 0.003 ms): mremap(addr: 0x7f441260a000, old_len: 4096, new_len: 4096, flags: MAYMOVE|FIXED, new_addr: 0x7f16da297000) = 0xda297000
0.612 ( 0.003 ms): mremap(addr: 0x7f4412609000, old_len: 4096, new_len: 4096, flags: MAYMOVE|FIXED, new_addr: 0x7f16da296000) = 0xda296000
0.619 ( 0.000 ms): exit_group(--- tools/perf/builtin-trace.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
tools/perf/builtin-trace.c +26 -0
@@ -402,6 +402,31 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags +static size_t syscall_arg__scnprintf_mremap_flags (char *bf,size_t size, +struct syscall_arg *arg) +{ +int printed =0 , flags = arg->val; + +#define P_MREMAP_FLAG (n) \ + if (flags & MREMAP_##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + flags &= ~MREMAP_##n; \ + } + +P_MREMAP_FLAG (MAYMOVE ); +#ifdef MREMAP_FIXED +P_MREMAP_FLAG (FIXED ); +#endif +#undef P_MREMAP_FLAG + +if (flags) + printed +=scnprintf (bf + printed, size - printed,"%s%#x" , printed ?"|" :"" , flags); + +return printed; +} + +#define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags +static size_t syscall_arg__scnprintf_madvise_behavior (char *bf,size_t size,struct syscall_arg *arg) {
@@ -1004,6 +1029,7 @@ static struct syscall_fmt { [2] = SCA_MMAP_PROT, /* prot */ }, }, { .name = "mremap", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ + [3] = SCA_MREMAP_FLAGS, /* flags */ [4] = SCA_HEX, /* new_addr */ }, }, { .name = "munlock", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 10/41 perf tools: Fix CLOEXEC probe for perf_event_paranoid == 2
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
With /proc/sys/kernel/perf_event_paranoid set to 2, the probe of PERF_FLAG_FD_CLOEXEC would fail. Fix by excluding kernel profiling from the probe event.
--- tools/perf/util/cloexec.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/util/cloexec.c +1 -0
@@ -11,6 +11,7 @@ static int perf_flag_probe(void)struct perf_event_attr attr = { .type =PERF_TYPE_SOFTWARE , .config =PERF_COUNT_SW_CPU_CLOCK , + .exclude_kernel =1 , };int fd;int err;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 11/41 perf tools: Fix one of the probe events to exclude kernel
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
When probing the kernel API the kernel should be excluded otherwise the probe will fail for users with insufficient privilege to profile the kernel.
--- tools/perf/util/record.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/record.c +1 -1
@@ -47,7 +47,7 @@ out_delete:static bool perf_probe_api (setup_probe_fn_t fn) { -const char *try[] = {"cycles:u" ,"instructions:u" ,"cpu-clock" ,NULL }; +const char *try[] = {"cycles:u" ,"instructions:u" ,"cpu-clock:u" ,NULL };struct cpu_map *cpus;int cpu, ret, i =0 ;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 12/41 perf tools: Fix probing the kernel API with cpu-wide events
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Fall back to probing with the current pid if cpu-wide probing fails. This primarily affects the setting of comm_exec flag when the user is un-privileged and /proc/sys/kernel/perf_event_paranoid > 0.
The change to comm_exec can be observed by using -vv with perf record and a kernel that supports comm_exec.
--- tools/perf/util/record.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
tools/perf/util/record.c +27 -9
@@ -14,6 +14,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)struct perf_evsel *evsel;unsigned long flags =perf_event_open_cloexec_flag ();int err = -EAGAIN , fd; +static pid_t pid =-1 ; evlist =perf_evlist__new ();if (!evlist)
@@ -24,14 +25,22 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) evsel =perf_evlist__first (evlist); - fd =sys_perf_event_open (&evsel->attr,-1 , cpu,-1 , flags); -if (fd <0 ) - goto out_delete; +while (1 ) { + fd =sys_perf_event_open (&evsel->attr, pid, cpu,-1 , flags); +if (fd <0 ) { +if (pid ==-1 && errno ==EACCES ) { + pid =0 ; +continue ; + } + goto out_delete; + } +break ; + }close (fd);fn (evsel); - fd =sys_perf_event_open (&evsel->attr,-1 , cpu,-1 , flags); + fd =sys_perf_event_open (&evsel->attr, pid, cpu,-1 , flags);if (fd <0 ) {if (errno ==EINVAL ) err = -EINVAL ;
@@ -201,6 +210,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)struct perf_evsel *evsel;int err, fd, cpu;bool ret = false; +pid_t pid =-1 ; temp_evlist =perf_evlist__new ();if (!temp_evlist)
@@ -221,12 +231,20 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) cpu = evlist->cpus->map[0 ]; } - fd =sys_perf_event_open (&evsel->attr,-1 , cpu,-1 , -perf_event_open_cloexec_flag ()); -if (fd >=0 ) { -close (fd); - ret = true; +while (1 ) { + fd =sys_perf_event_open (&evsel->attr, pid, cpu,-1 , +perf_event_open_cloexec_flag ()); +if (fd <0 ) { +if (pid ==-1 && errno ==EACCES ) { + pid =0 ; +continue ; + } + goto out_delete; + } +break ; } +close (fd); + ret = true; out_delete:perf_evlist__delete (temp_evlist);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 13/41 perf tools: Prefer to use a cpu-wide event for probing CLOEXEC
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
When doing a system-wide trace with Intel PT, the jump label set up as a result of probing CLOEXEC gets reset while the trace is running. That causes an Intel PT decoding error because the object code (obtained from /proc/kcore) does not match the running code at that point. While we can't expect there never to be jump label changes, we can avoid cases that the perf tool itself creates.
The problem is avoided by first trying a cpu-wide event (pid = -1) for probing the PERF_FLAG_FD_CLOEXEC flag and falling back to an event for the current process (pid = 0).
--- tools/perf/util/cloexec.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
tools/perf/util/cloexec.c +18 -4
@@ -1,3 +1,4 @@ +#include <sched.h> #include "util.h" #include "../perf.h" #include "cloexec.h"
@@ -15,10 +16,23 @@ static int perf_flag_probe(void) };int fd;int err; +int cpu; +pid_t pid =-1 ; -/* check cloexec flag */ - fd =sys_perf_event_open (&attr,0 ,-1 ,-1 , -PERF_FLAG_FD_CLOEXEC ); + cpu =sched_getcpu (); +if (cpu <0 ) + cpu =0 ; + +while (1 ) { +/* check cloexec flag */ + fd =sys_perf_event_open (&attr, pid, cpu,-1 , +PERF_FLAG_FD_CLOEXEC ); +if (fd <0 && pid ==-1 && errno ==EACCES ) { + pid =0 ; +continue ; + } +break ; + } err = errno;if (fd >=0 ) {
@@ -31,7 +45,7 @@ static int perf_flag_probe(void) err, strerror(err));/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */ - fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); + fd =sys_perf_event_open (&attr, pid, cpu,-1 ,0 ); err = errno; if (WARN_ONCE(fd < 0 && err != EBUSY,
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 14/41 perf script: Fix possible memory leaks
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Some paths in perf script don't call perf_session__delete() after creating a new session.
--- tools/perf/builtin-script.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-)
tools/perf/builtin-script.c +22 -13
@@ -1471,12 +1471,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)bool show_full_info = false;bool header = false;bool header_only = false; +bool script_started = false;char *rec_script_path =NULL ;char *rep_script_path =NULL ;struct perf_session *session;char *script_path =NULL ;const char **__argv; -int i, j, err; +int i, j, err =0 ;struct perf_script script = { .tool = { .sample = process_sample_event,
@@ -1730,14 +1731,15 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)if (header || header_only) {perf_session__fprintf_info (session, stdout, show_full_info);if (header_only) -return 0 ; + goto out_delete; } script.session = session;if (cpu_list) { -if (perf_session__cpu_bitmap (session, cpu_list, cpu_bitmap)) -return -1 ; + err =perf_session__cpu_bitmap (session, cpu_list, cpu_bitmap); +if (err <0 ) + goto out_delete; }if (!no_callchain)
@@ -1752,53 +1754,60 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)if (output_set_by_user ()) {fprintf (stderr,"custom fields not supported for generated scripts" ); -return -1 ; + err = -EINVAL ; + goto out_delete; } input =open (file.path,O_RDONLY );/* input_name */ if (input <0 ) { + err = -errno;perror ("failed to open file" ); -return -1 ; + goto out_delete; } err =fstat (input, &perf_stat);if (err <0 ) {perror ("failed to stat file" ); -return -1 ; + goto out_delete; }if (!perf_stat.st_size) {fprintf (stderr,"zero-sized file, nothing to do!\n" ); -return 0 ; + goto out_delete; } scripting_ops =script_spec__lookup (generate_script_lang);if (!scripting_ops) {fprintf (stderr,"invalid language specifier" ); -return -1 ; + err = -ENOENT ; + goto out_delete; } err = scripting_ops->generate_script (session->tevent.pevent,"perf-script" ); - goto out; + goto out_delete; }if (script_name) { err = scripting_ops->start_script (script_name, argc, argv);if (err) - goto out; + goto out_delete;pr_debug ("perf script started with script %s\n\n" , script_name); + script_started = true; } err =perf_session__check_output_opt (session);if (err <0 ) - goto out; + goto out_delete; err =__cmd_script (&script); +out_delete:perf_session__delete (session); -cleanup_scripting (); + +if (script_started) +cleanup_scripting (); out:return err; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 15/41 perf symbols: Fix a memory leak in vmlinux_path__init()
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
When uname() failed, it should free vmlinux_path.
--- tools/perf/util/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/symbol.c +1 -1
@@ -1772,7 +1772,7 @@ static int vmlinux_path__init(void)return 0 ;if (uname (&uts) <0 ) -return -1 ; + goto out_fail;snprintf (bf,sizeof (bf),"/boot/vmlinux-%s" , uts.release); vmlinux_path[vmlinux_path__nr_entries] =strdup (bf);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 16/41 perf annotate: Move session handling out of __cmd_annotate()
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-annotate.c | 75 +++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 35 deletions(-)
tools/perf/builtin-annotate.c +40 -35
@@ -36,7 +36,8 @@struct perf_annotate {struct perf_tool tool; -bool force, use_tui, use_stdio, use_gtk; +struct perf_session *session; +bool use_tui, use_stdio, use_gtk;bool full_paths;bool print_line;bool skip_missing;
@@ -188,18 +189,9 @@ find_next:static int __cmd_annotate (struct perf_annotate *ann) {int ret; -struct perf_session *session; +struct perf_session *session = ann->session;struct perf_evsel *pos;u64 total_nr_samples; -struct perf_data_file file = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = ann->force, - }; - - session =perf_session__new (&file, false, &ann->tool); -if (session ==NULL ) -return -ENOMEM ;machines__set_symbol_filter (&session->machines, symbol__annotate_init);
@@ -207,22 +199,22 @@ static int __cmd_annotate(struct perf_annotate *ann) ret =perf_session__cpu_bitmap (session, ann->cpu_list, ann->cpu_bitmap);if (ret) - goto out_delete; + goto out; }if (!objdump_path) { ret =perf_session_env__lookup_objdump (&session->header.env);if (ret) - goto out_delete; + goto out; } ret =perf_session__process_events (session, &ann->tool);if (ret) - goto out_delete; + goto out;if (dump_trace) {perf_session__fprintf_nr_events (session, stdout); - goto out_delete; + goto out; }if (verbose >3 )
@@ -250,8 +242,8 @@ static int __cmd_annotate(struct perf_annotate *ann) }if (total_nr_samples ==0 ) { -ui__error ("The %s file has no samples!\n" , file.path); - goto out_delete; +ui__error ("The %s file has no samples!\n" , session->file->path); + goto out; }if (use_browser ==2 ) {
@@ -261,24 +253,12 @@ static int __cmd_annotate(struct perf_annotate *ann) "perf_gtk__show_annotations");if (show_annotations ==NULL ) {ui__error ("GTK browser not found!\n" ); - goto out_delete; + goto out; }show_annotations (); } -out_delete: -/* -* Speed up the exit process, for large files this can -* take quite a while. -* -* XXX Enable this when using valgrind or if we ever -* librarize this command. -* -* Also experiment with obstacks to see how much speed -* up we'll get here. -* -* perf_session__delete(session); -*/ +out:return ret; }
@@ -301,6 +281,10 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) .ordering_requires_timestamps = true, }, }; +struct perf_data_file file = { + .path = input_name, + .mode =PERF_DATA_MODE_READ , + };const struct option options[] = {OPT_STRING ('i' ,"input" , &input_name,"file" , "input file name"),
@@ -308,7 +292,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) "only consider symbols in these dsos"),OPT_STRING ('s' ,"symbol" , &annotate.sym_hist_filter,"symbol" ,"symbol to annotate" ), -OPT_BOOLEAN ('f' ,"force" , &annotate.force,"don't complain, do it" ), +OPT_BOOLEAN ('f' ,"force" , &file.force,"don't complain, do it" ),OPT_INCR ('v' ,"verbose" , &verbose,"be more verbose (show symbol address, etc)" ), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
@@ -341,6 +325,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) "Show event group information together"), OPT_END() }; +int ret; argc =parse_options (argc, argv, options, annotate_usage,0 );
@@ -353,11 +338,16 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)setup_browser (true); + annotate.session =perf_session__new (&file, false, &annotate.tool); +if (annotate.session ==NULL ) +return -ENOMEM ; + symbol_conf.priv_size =sizeof (struct annotation ); symbol_conf.try_vmlinux_path = true; -if (symbol__init () <0 ) -return -1 ; + ret =symbol__init (); +if (ret <0 ) + goto out_delete;if (setup_sorting () <0 )usage_with_options (annotate_usage, options);
@@ -373,5 +363,20 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) annotate.sym_hist_filter = argv[0 ]; } -return __cmd_annotate (&annotate); + ret =__cmd_annotate (&annotate); + +out_delete: +/* +* Speed up the exit process, for large files this can +* take quite a while. +* +* XXX Enable this when using valgrind or if we ever +* librarize this command. +* +* Also experiment with obstacks to see how much speed +* up we'll get here. +* +* perf_session__delete(session); +*/ +return ret; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 17/41 perf buildid-cache: Move session handling into cmd_buildid_cache()
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-buildid-cache.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)
tools/perf/builtin-buildid-cache.c +21 -14
@@ -246,20 +246,9 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)return true; } -static int build_id_cache__fprintf_missing (const char *filename,bool force,FILE *fp) +static int build_id_cache__fprintf_missing (struct perf_session *session,FILE *fp) { -struct perf_data_file file = { - .path = filename, - .mode =PERF_DATA_MODE_READ , - .force = force, - }; -struct perf_session *session =perf_session__new (&file, false,NULL ); -if (session ==NULL ) -return -1 ; -perf_session__fprintf_dsos_buildid (session, fp, dso__missing_buildid_cache,0 ); -perf_session__delete (session); -return 0 ; }
@@ -303,6 +292,11 @@ int cmd_buildid_cache(int argc, const char **argv, *update_name_list_str =NULL , *kcore_filename; +struct perf_data_file file = { + .mode =PERF_DATA_MODE_READ , + }; +struct perf_session *session =NULL ; +const struct option buildid_cache_options[] = {OPT_STRING ('a' ,"add" , &add_name_list_str,"file list" ,"file(s) to add" ),
@@ -326,8 +320,17 @@ int cmd_buildid_cache(int argc, const char **argv, argc =parse_options (argc, argv, buildid_cache_options, buildid_cache_usage,0 ); +if (missing_filename) { + file.path = missing_filename; + file.force = force; + + session =perf_session__new (&file, false,NULL ); +if (session ==NULL ) +return -1 ; + } +if (symbol__init () <0 ) -return -1 ; + goto out;setup_pager ();
@@ -370,7 +373,7 @@ int cmd_buildid_cache(int argc, const char **argv, }if (missing_filename) - ret =build_id_cache__fprintf_missing (missing_filename, force, stdout); + ret =build_id_cache__fprintf_missing (session, stdout);if (update_name_list_str) { list =strlist__new (true, update_name_list_str);
@@ -394,5 +397,9 @@ int cmd_buildid_cache(int argc, const char **argv, build_id_cache__add_kcore(kcore_filename, debugdir, force))pr_warning ("Couldn't add %s\n" , kcore_filename); +out: +if (session) +perf_session__delete (session); +return ret; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 18/41 perf inject: Move session handling out of __cmd_inject()
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-inject.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-)
tools/perf/builtin-inject.c +17 -12
@@ -23,6 +23,7 @@struct perf_inject {struct perf_tool tool; +struct perf_session *session;bool build_ids;bool sched_stat;const char *input_name;
@@ -340,12 +341,8 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel,static int __cmd_inject (struct perf_inject *inject) { -struct perf_session *session;int ret = -EINVAL ; -struct perf_data_file file = { - .path = inject->input_name, - .mode =PERF_DATA_MODE_READ , - }; +struct perf_session *session = inject->session;struct perf_data_file *file_out = &inject->output;signal (SIGINT , sig_handler);
@@ -357,10 +354,6 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.tracing_data = perf_event__repipe_tracing_data; } - session =perf_session__new (&file, true, &inject->tool); -if (session ==NULL ) -return -ENOMEM ; -if (inject->build_ids) { inject->tool.sample = perf_event__inject_buildid; }else if (inject->sched_stat) {
@@ -396,8 +389,6 @@ static int __cmd_inject(struct perf_inject *inject)perf_session__write_header (session, session->evlist, file_out->fd, true); } -perf_session__delete (session); -return ret; }
@@ -427,6 +418,11 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .mode = PERF_DATA_MODE_WRITE, }, }; +struct perf_data_file file = { + .mode =PERF_DATA_MODE_READ , + }; +int ret; +const struct option options[] = {OPT_BOOLEAN ('b' ,"build-ids" , &inject.build_ids, "Inject build-ids into the output stream"),
@@ -461,8 +457,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)return -1 ; } + file.path = inject.input_name; + inject.session =perf_session__new (&file, true, &inject.tool); +if (inject.session ==NULL ) +return -ENOMEM ; +if (symbol__init () <0 )return -1 ; -return __cmd_inject (&inject); + ret =__cmd_inject (&inject); + +perf_session__delete (inject.session); + +return ret; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 19/41 perf kmem: Move session handling out of __cmd_kmem()
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-kmem.c | 49 +++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 21 deletions(-)
tools/perf/builtin-kmem.c +28 -21
@@ -405,10 +405,9 @@ static void sort_result(void)__sort_result (&root_caller_stat, &root_caller_sorted, &caller_sort); } -static int __cmd_kmem (void ) +static int __cmd_kmem (struct perf_session *session) {int err = -EINVAL ; -struct perf_session *session;const struct perf_evsel_str_handler kmem_tracepoints[] = { {"kmem:kmalloc" , perf_evsel__process_alloc_event, }, {"kmem:kmem_cache_alloc" , perf_evsel__process_alloc_event, },
@@ -417,31 +416,22 @@ static int __cmd_kmem(void) { "kmem:kfree", perf_evsel__process_free_event, }, { "kmem:kmem_cache_free", perf_evsel__process_free_event, }, }; -struct perf_data_file file = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - }; - - session =perf_session__new (&file, false, &perf_kmem); -if (session ==NULL ) -return -ENOMEM ;if (!perf_session__has_traces (session,"kmem record" )) - goto out_delete; + goto out;if (perf_session__set_tracepoints_handlers (session, kmem_tracepoints)) {pr_err ("Initializing perf session tracepoint handlers failed\n" ); -return -1 ; + goto out; }setup_pager (); err =perf_session__process_events (session, &perf_kmem);if (err !=0 ) - goto out_delete; + goto out;sort_result ();print_result (session); -out_delete: -perf_session__delete (session); +out:return err; }
@@ -688,29 +678,46 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)NULL ,NULL }; +struct perf_session *session; +struct perf_data_file file = { + .path = input_name, + .mode =PERF_DATA_MODE_READ , + }; +int ret =-1 ; + argc =parse_options_subcommand (argc, argv, kmem_options, kmem_subcommands, kmem_usage,0 );if (!argc)usage_with_options (kmem_usage, kmem_options); -symbol__init (); -if (!strncmp (argv[0 ],"rec" ,3 )) { +symbol__init ();return __cmd_record (argc, argv); - }else if (!strcmp (argv[0 ],"stat" )) { + } + + session =perf_session__new (&file, false, &perf_kmem); +if (session ==NULL ) +return -ENOMEM ; + +symbol__init (); + +if (!strcmp (argv[0 ],"stat" )) {if (cpu__setup_cpunode_map ()) -return -1 ; + goto out_delete;if (list_empty (&caller_sort))setup_sorting (&caller_sort, default_sort_order);if (list_empty (&alloc_sort))setup_sorting (&alloc_sort, default_sort_order); -return __cmd_kmem (); + ret =__cmd_kmem (session); }else usage_with_options (kmem_usage, kmem_options); -return 0 ; +out_delete: +perf_session__delete (session); + +return ret; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 20/41 perf kvm: Move call to symbol__init() after creating session
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-kvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/builtin-kvm.c +2 -2
@@ -1064,6 +1064,8 @@ static int read_events(struct perf_kvm_stat *kvm)return -EINVAL ; } +symbol__init (); +if (!perf_session__has_traces (kvm->session,"kvm record" ))return -EINVAL ;
@@ -1193,8 +1195,6 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)NULL }; -symbol__init (); -if (argc) { argc = parse_options(argc, argv, kvm_events_report_options,
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 21/41 perf lock: Move call to symbol__init() after creating session
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-lock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-lock.c +2 -1
@@ -865,6 +865,8 @@ static int __cmd_report(bool display_info)return -ENOMEM ; } +symbol__init (); +if (!perf_session__has_traces (session,"lock record" )) goto out_delete;
@@ -974,7 +976,6 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)unsigned int i;int rc =0 ; -symbol__init ();for (i =0 ; i <LOCKHASH_SIZE ; i++)INIT_LIST_HEAD (lockhash_table + i);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 22/41 perf sched: Move call to symbol__init() after creating session
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-sched.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-sched.c +2 -1
@@ -1462,6 +1462,8 @@ static int perf_sched__read_events(struct perf_sched *sched,return -1 ; } +symbol__init (); +if (perf_session__set_tracepoints_handlers (session, handlers)) goto out_delete;
@@ -1747,7 +1749,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)if (!strcmp (argv[0 ],"script" ))return cmd_script (argc, argv, prefix); -symbol__init ();if (!strncmp (argv[0 ],"rec" ,3 )) {return __cmd_record (argc, argv); }else if (!strncmp (argv[0 ],"lat" ,3 )) {
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 23/41 perf script: Move call to symbol__init() after creating session
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-script.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/builtin-script.c +3 -2
@@ -1719,8 +1719,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)exit (-1 ); } -if (symbol__init () <0 ) -return -1 ;if (!script_name)setup_pager ();
@@ -1734,6 +1732,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) goto out_delete; } +if (symbol__init () <0 ) + goto out_delete; + script.session = session;if (cpu_list) {
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 24/41 perf timechart: Move call to symbol__init() after creating session
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-timechart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/builtin-timechart.c +2 -2
@@ -1607,6 +1607,8 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)if (session ==NULL )return -ENOMEM ; +symbol__init (); + (void)perf_header__process_sections(&session->header, perf_data_file__fd(session->file), tchart,
@@ -1982,8 +1984,6 @@ int cmd_timechart(int argc, const char **argv,return -1 ; } -symbol__init (); -if (argc && !strncmp (argv[0 ],"rec" ,3 )) { argc =parse_options (argc, argv, record_options, record_usage,PARSE_OPT_STOP_AT_NON_OPTION );
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 25/41 perf trace: Move call to symbol__init() after creating session
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init().
--- tools/perf/builtin-trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-trace.c +3 -3
@@ -2241,13 +2241,13 @@ static int trace__replay(struct trace *trace)/* add tid to output */ trace->multiple_threads = true; -if (symbol__init () <0 ) -return -1 ; - session =perf_session__new (&file, false, &trace->tool);if (session ==NULL )return -ENOMEM ; +if (symbol__init () <0 ) + goto out; + trace->host = &session->machines.host; err =perf_session__set_tracepoints_handlers (session, handlers);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 26/41 perf tools: Check recorded kernel version when finding vmlinux
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Currently vmlinux_path__init() only tries to find vmlinux file from current directory, /boot and some canonical directories with version number of the running kernel. This can be a problem when reporting old data recorded on a kernel version not running currently.
We can use --symfs option for this but it's annoying for user to do it always. As we already have the info in the perf.data file, it can be changed to use it for the search automatically.
Before:
$ perf report
...
# Samples: 4K of event 'cpu-clock'
# Event count (approx.): 1067250000
#
# Overhead Command Shared Object Symbol
# ........ .......... ................. ..............................
71.87% swapper [kernel.kallsyms] [k] recover_probed_instructionAfter:
# Overhead Command Shared Object Symbol
# ........ .......... ................. ....................
71.87% swapper [kernel.kallsyms] [k] native_safe_haltThis requires to change signature of symbol__init() to receive struct perf_session_env *.
--- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-buildid-cache.c | 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-kmem.c | 4 ++-- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 4 ++-- tools/perf/tests/builtin-test.c | 2 +- tools/perf/util/probe-event.c | 2 +- tools/perf/util/symbol.c | 26 +++++++++++++++++--------- tools/perf/util/symbol.h | 3 ++- 19 files changed, 39 insertions(+), 30 deletions(-)
tools/perf/builtin-annotate.c +1 -1
@@ -345,7 +345,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) symbol_conf.priv_size =sizeof (struct annotation ); symbol_conf.try_vmlinux_path = true; - ret =symbol__init (); + ret =symbol__init (&annotate.session->header.env);if (ret <0 ) goto out_delete;
tools/perf/builtin-buildid-cache.c +1 -1
@@ -329,7 +329,7 @@ int cmd_buildid_cache(int argc, const char **argv,return -1 ; } -if (symbol__init () <0 ) +if (symbol__init (session ? &session->header.env :NULL ) <0 ) goto out;setup_pager ();
tools/perf/builtin-diff.c +1 -1
@@ -1143,7 +1143,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) argc =parse_options (argc, argv, options, diff_usage,0 ); -if (symbol__init () <0 ) +if (symbol__init (NULL ) <0 )return -1 ;if (data_init (argc, argv) <0 )
tools/perf/builtin-inject.c +1 -1
@@ -462,7 +462,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)if (inject.session ==NULL )return -ENOMEM ; -if (symbol__init () <0 ) +if (symbol__init (&inject.session->header.env) <0 )return -1 ; ret =__cmd_inject (&inject);
tools/perf/builtin-kmem.c +2 -2
@@ -692,7 +692,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)usage_with_options (kmem_usage, kmem_options);if (!strncmp (argv[0 ],"rec" ,3 )) { -symbol__init (); +symbol__init (NULL );return __cmd_record (argc, argv); }
@@ -700,7 +700,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)if (session ==NULL )return -ENOMEM ; -symbol__init (); +symbol__init (&session->header.env);if (!strcmp (argv[0 ],"stat" )) {if (cpu__setup_cpunode_map ())
tools/perf/builtin-kvm.c +2 -2
@@ -1064,7 +1064,7 @@ static int read_events(struct perf_kvm_stat *kvm)return -EINVAL ; } -symbol__init (); +symbol__init (&kvm->session->header.env);if (!perf_session__has_traces (kvm->session,"kvm record" ))return -EINVAL ;
@@ -1314,7 +1314,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, kvm->opts.target.uid_str =NULL ; kvm->opts.target.uid =UINT_MAX ; -symbol__init (); +symbol__init (NULL );disable_buildid_cache (); use_browser =0 ;
tools/perf/builtin-lock.c +1 -1
@@ -865,7 +865,7 @@ static int __cmd_report(bool display_info)return -ENOMEM ; } -symbol__init (); +symbol__init (&session->header.env);if (!perf_session__has_traces (session,"lock record" )) goto out_delete;
tools/perf/builtin-mem.c +1 -1
@@ -133,7 +133,7 @@ static int report_raw_events(struct perf_mem *mem) goto out_delete; } -if (symbol__init () <0 ) +if (symbol__init (&session->header.env) <0 )return -1 ;printf ("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n" );
tools/perf/builtin-record.c +1 -1
@@ -908,7 +908,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)usage_with_options (record_usage, record_options); } -symbol__init (); +symbol__init (NULL );if (symbol_conf.kptr_restrict) pr_warning(
tools/perf/builtin-report.c +1 -1
@@ -798,7 +798,7 @@ repeat: } } -if (symbol__init () <0 ) +if (symbol__init (&session->header.env) <0 ) goto error;if (argc) {
tools/perf/builtin-sched.c +1 -1
@@ -1462,7 +1462,7 @@ static int perf_sched__read_events(struct perf_sched *sched,return -1 ; } -symbol__init (); +symbol__init (&session->header.env);if (perf_session__set_tracepoints_handlers (session, handlers)) goto out_delete;
tools/perf/builtin-script.c +1 -1
@@ -1732,7 +1732,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) goto out_delete; } -if (symbol__init () <0 ) +if (symbol__init (&session->header.env) <0 ) goto out_delete; script.session = session;
tools/perf/builtin-timechart.c +1 -1
@@ -1607,7 +1607,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)if (session ==NULL )return -ENOMEM ; -symbol__init (); +symbol__init (&session->header.env); (void)perf_header__process_sections(&session->header, perf_data_file__fd(session->file),
tools/perf/builtin-top.c +1 -1
@@ -1234,7 +1234,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) symbol_conf.priv_size =sizeof (struct annotation ); symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name ==NULL ); -if (symbol__init () <0 ) +if (symbol__init (NULL ) <0 )return -1 ;sort__setup_elide (stdout);
tools/perf/builtin-trace.c +2 -2
@@ -1411,7 +1411,7 @@ static int trace__tool_process(struct perf_tool *tool,static int trace__symbols_init (struct trace *trace,struct perf_evlist *evlist) { -int err =symbol__init (); +int err =symbol__init (NULL );if (err)return err;
@@ -2245,7 +2245,7 @@ static int trace__replay(struct trace *trace)if (session ==NULL )return -ENOMEM ; -if (symbol__init () <0 ) +if (symbol__init (&session->header.env) <0 ) goto out; trace->host = &session->machines.host;
tools/perf/tests/builtin-test.c +1 -1
@@ -297,7 +297,7 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) symbol_conf.sort_by_name = true; symbol_conf.try_vmlinux_path = true; -if (symbol__init () <0 ) +if (symbol__init (NULL ) <0 )return -1 ;if (skip !=NULL )
tools/perf/util/probe-event.c +1 -1
@@ -79,7 +79,7 @@ static int init_symbol_maps(bool user_only)int ret; symbol_conf.sort_by_name = true; - ret =symbol__init (); + ret =symbol__init (NULL );if (ret <0 ) {pr_debug ("Failed to init symbol map.\n" ); goto out;
tools/perf/util/symbol.c +17 -9
@@ -15,6 +15,7 @@#include "machine.h" #include "symbol.h" #include "strlist.h" +#include "header.h" #include <elf.h> #include <limits.h>
@@ -1749,10 +1750,11 @@ static void vmlinux_path__exit(void)zfree (&vmlinux_path); } -static int vmlinux_path__init (void ) +static int vmlinux_path__init (struct perf_session_env *env) {struct utsname uts;char bf[PATH_MAX ]; +char *kernel_version; vmlinux_path =malloc (sizeof (char *) *5 );if (vmlinux_path ==NULL )
@@ -1767,25 +1769,31 @@ static int vmlinux_path__init(void) goto out_fail; ++vmlinux_path__nr_entries; -/* only try running kernel version if no symfs was given */ +/* only try kernel version if no symfs was given */ if (symbol_conf.symfs[0 ] !=0 )return 0 ; -if (uname (&uts) <0 ) - goto out_fail; +if (env) { + kernel_version = env->os_release; + }else { +if (uname (&uts) <0 ) + goto out_fail; + + kernel_version = uts.release; + } -snprintf (bf,sizeof (bf),"/boot/vmlinux-%s" , uts.release); +snprintf (bf,sizeof (bf),"/boot/vmlinux-%s" , kernel_version); vmlinux_path[vmlinux_path__nr_entries] =strdup (bf);if (vmlinux_path[vmlinux_path__nr_entries] ==NULL ) goto out_fail; ++vmlinux_path__nr_entries; -snprintf (bf,sizeof (bf),"/lib/modules/%s/build/vmlinux" , uts.release); +snprintf (bf,sizeof (bf),"/lib/modules/%s/build/vmlinux" , kernel_version); vmlinux_path[vmlinux_path__nr_entries] =strdup (bf);if (vmlinux_path[vmlinux_path__nr_entries] ==NULL ) goto out_fail; ++vmlinux_path__nr_entries;snprintf (bf,sizeof (bf),"/usr/lib/debug/lib/modules/%s/vmlinux" , - uts.release); + kernel_version); vmlinux_path[vmlinux_path__nr_entries] =strdup (bf);if (vmlinux_path[vmlinux_path__nr_entries] ==NULL ) goto out_fail;
@@ -1831,7 +1839,7 @@ static bool symbol__read_kptr_restrict(void)return value; } -int symbol__init (void ) +int symbol__init (struct perf_session_env *env) {const char *symfs;
@@ -1846,7 +1854,7 @@ int symbol__init(void) symbol_conf.priv_size += (sizeof (struct symbol_name_rb_node ) -sizeof (struct symbol )); -if (symbol_conf.try_vmlinux_path &&vmlinux_path__init () <0 ) +if (symbol_conf.try_vmlinux_path &&vmlinux_path__init (env) <0 )return -1 ;if (symbol_conf.field_sep && *symbol_conf.field_sep =='.' ) {
tools/perf/util/symbol.h +2 -1
@@ -262,7 +262,8 @@ int modules__parse(const char *filename, void *arg,int filename__read_debuglink (const char *filename,char *debuglink,size_t size); -int symbol__init (void ); +struct perf_session_env ; +int symbol__init (struct perf_session_env *env);void symbol__exit (void );void symbol__elf_init (void );struct symbol *symbol__new (u64 start,u64 len,u8 binding,const char *name);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 27/41 perf hists browser: Fix a small callchain display bug
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The currently when perf TUI report shows callchain, the first level chains have bogus '+' sign even though only the last one has children.
Since they are on a single line of the chain, toggling intermediate entries has no effect. Fix it to show '+' sign at the last entry only. Note that non-first level callchain entries don't have this problem.
Before:
---------------------------------------------------------------------------
Children Self Command Shared Object Symbols - 40.70% 0.00% swapper [kernel.kallsyms] [k] cpuidle_wrap_enter
+ cpuidle_wrap_enter
+ cpuidle_enter_tk
+ cpuidle_idle_call
+ cpu_idle
After:
---------------------------------------------------------------------------
Children Self Command Shared Object Symbols - 40.70% 0.00% swapper [kernel.kallsyms] [k] cpuidle_wrap_enter
cpuidle_wrap_enter
cpuidle_enter_tk
cpuidle_idle_call
+ cpu_idle
--- tools/perf/ui/browsers/hists.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/ui/browsers/hists.c +3 -1
@@ -228,8 +228,10 @@ static void callchain_node__init_have_children(struct callchain_node *node) {struct callchain_list *chain; -list_for_each_entry (chain, &node->val, list) +if (!list_empty (&node->val)) { + chain = list_entry(node->val.prev, struct callchain_list, list); chain->ms.has_children = !RB_EMPTY_ROOT (&node->rb_root); + }callchain_node__init_have_children_rb_tree (node); }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 28/41 perf report: Set proper sort__mode for the branch option
In reply to Arnaldo Carvalho de MeloFrom: "[email protected]" <[email protected]>
When you specify "--branch-stack"("-b" for short) or "--no-branch-stack", "branch_mode" variable is set to 1 or 0 respectively. However, the code is just checking if the variable is -1 or not, ignoring "branch_mode == 1" case. Thus "perf report -b" dose not show its result with the branch sorted mode. This patch fix the problem.
--- tools/perf/builtin-report.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-report.c +1 -1
@@ -730,7 +730,7 @@ repeat: has_br_stack =perf_header__has_feat (&session->header,HEADER_BRANCH_STACK ); -if (branch_mode ==-1 && has_br_stack) { +if ((branch_mode ==-1 && has_br_stack) || branch_mode ==1 ) { sort__mode =SORT_MODE__BRANCH ; symbol_conf.cumulate_callchain = false; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 29/41 perf top: Fix -z option behavior
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The current -z option does almost nothing. It doesn't zero the existing samples so that we can see profiles of exited process after last refresh. It seems it only affects annotation.
This patch clears existing entries before processing if -z option is given. For this original decaying logic also moved before processing.
--- tools/perf/builtin-top.c | 23 +++++++++++++++++------ tools/perf/util/hist.c | 22 ++++++++++++++++++++++ tools/perf/util/hist.h | 1 + 3 files changed, 40 insertions(+), 6 deletions(-)
tools/perf/builtin-top.c +17 -6
@@ -276,11 +276,17 @@ static void perf_top__print_sym_table(struct perf_top *top)return ; } +if (top->zero) { +hists__delete_entries (&top->sym_evsel->hists); + }else { +hists__decay_entries (&top->sym_evsel->hists, + top->hide_user_symbols, + top->hide_kernel_symbols); + } +hists__collapse_resort (&top->sym_evsel->hists,NULL );hists__output_resort (&top->sym_evsel->hists); -hists__decay_entries (&top->sym_evsel->hists, - top->hide_user_symbols, - top->hide_kernel_symbols); +hists__output_recalc_col_len (&top->sym_evsel->hists, top->print_entries - printed);putchar ('\n' );
@@ -542,11 +548,16 @@ static void perf_top__sort_new_samples(void *arg)if (t->evlist->selected !=NULL ) t->sym_evsel = t->evlist->selected; +if (t->zero) { +hists__delete_entries (&t->sym_evsel->hists); + }else { +hists__decay_entries (&t->sym_evsel->hists, + t->hide_user_symbols, + t->hide_kernel_symbols); + } +hists__collapse_resort (&t->sym_evsel->hists,NULL );hists__output_resort (&t->sym_evsel->hists); -hists__decay_entries (&t->sym_evsel->hists, - t->hide_user_symbols, - t->hide_kernel_symbols); }static void *display_thread_tui (void *arg)
tools/perf/util/hist.c +22 -0
@@ -277,6 +277,28 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel) } } +void hists__delete_entries (struct hists *hists) +{ +struct rb_node *next =rb_first (&hists->entries); +struct hist_entry *n; + +while (next) { + n = rb_entry(next, struct hist_entry, rb_node); + next =rb_next (&n->rb_node); + +rb_erase (&n->rb_node, &hists->entries); + +if (sort__need_collapse) +rb_erase (&n->rb_node_in, &hists->entries_collapsed); + + --hists->nr_entries; +if (!n->filtered) + --hists->nr_non_filtered_entries; + +hist_entry__free (n); + } +} +/* * histogram, sorted on item, collects periods */
tools/perf/util/hist.h +1 -0
@@ -152,6 +152,7 @@ void hists__output_resort(struct hists *hists);void hists__collapse_resort (struct hists *hists,struct ui_progress *prog);void hists__decay_entries (struct hists *hists,bool zap_user,bool zap_kernel); +void hists__delete_entries (struct hists *hists);void hists__output_recalc_col_len (struct hists *hists,int max_rows);u64 hists__total_period (struct hists *hists);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 30/41 perf top: Handle 'z' key for toggle zeroing samples in TUI
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The perf top TUI lacks 'z' key support to toggle sample zeroing. Add it.
--- tools/perf/ui/browsers/hists.c | 9 +++++++++ 1 file changed, 9 insertions(+)
tools/perf/ui/browsers/hists.c +9 -0
@@ -10,6 +10,7 @@#include "../../util/pstack.h" #include "../../util/sort.h" #include "../../util/util.h" +#include "../../util/top.h" #include "../../arch/common.h" #include "../browser.h"
@@ -1532,6 +1533,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,"P Print histograms to perf.hist.N\n" "t Zoom into current Thread\n" "V Verbose (DSO names in callchains, etc)\n" +"z Toggle zeroing of samples\n" "/ Filter symbol by name" ;if (browser ==NULL )
@@ -1632,6 +1634,13 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,case 'F' : symbol_conf.filter_relative ^=1 ;continue ; +case 'z' : +if (!is_report_browser (hbt)) { +struct perf_top *top = hbt->arg; + + top->zero = !top->zero; + } +continue ;case K_F1 :case 'h' :case '?' :
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 31/41 perf symbols: Don't demangle parameters and such by default
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Some C++ symbols have very long name and they make column length longer. Most of them are about parameters including templates and we can ignore such info most of time IMHO.
This patch passes DMGL_NO_OPTS by default when calling bfd_demangle(). One can still see full symbols with -v/--verbose option.
before:
JS_CallFunctionValue(JSContext*, JSObject*, JS::Value, unsigned int, JS::Value*, JS::Value*)
after:
JS_CallFunctionValue
--- tools/perf/util/symbol-elf.c | 7 +++++-- tools/perf/util/symbol.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-)
tools/perf/util/symbol-elf.c +5 -2
@@ -939,8 +939,11 @@ new_symbol:* to it... */ if (symbol_conf.demangle) { - demangled =bfd_demangle (NULL , elf_name, -DMGL_PARAMS |DMGL_ANSI ); +int demangle_flags =DMGL_NO_OPTS ; +if (verbose) + demangle_flags =DMGL_PARAMS |DMGL_ANSI ; + + demangled =bfd_demangle (NULL , elf_name, demangle_flags);if (demangled !=NULL ) elf_name = demangled; }
tools/perf/util/symbol.h +1 -0
@@ -60,6 +60,7 @@ extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,#endif #ifndef DMGL_PARAMS +#define DMGL_NO_OPTS 0/* For readability... */ #define DMGL_PARAMS (1 << 0)/* Include function args */ #define DMGL_ANSI (1 << 1)/* Include const, volatile, etc */ #endif
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 32/41 perf symbols: Fix missing label symbols
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Label symbols are missing because elf_sec__is_a() fails to find the section because the section strings do not match the section headers because the sections headers are from the 'runtime' object and the sections strings are from the 'symbol source' object.
Fix by getting the section strings from the 'runtime' object so that they match the section headers.
--- tools/perf/util/symbol-elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/symbol-elf.c +1 -1
@@ -736,7 +736,7 @@ int dso__load_sym(struct dso *dso, struct map *map,if (symstrs ==NULL ) goto out_elf_end; - sec_strndx =elf_getscn (elf, ehdr.e_shstrndx); + sec_strndx =elf_getscn (runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);if (sec_strndx ==NULL ) goto out_elf_end;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 33/41 perf evlist: Add 'system_wide' option
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add an option to cause a selected event to be opened always without a pid when configured by perf_evsel__config().
This is needed when using the sched_switch tracepoint to follow object code execution.
sched_switch occurs before the task switch and so it cannot record it in a context limited to that task. Note that also means that sched_switch is useless when capturing data per-thread, as is the 'context-switches' software event for the same reason.
--- tools/perf/util/evlist.c | 45 +++++++++++++++++++++++++++++++++++++-------- tools/perf/util/evsel.c | 31 ++++++++++++++++++++++++++----- tools/perf/util/evsel.h | 1 + 3 files changed, 64 insertions(+), 13 deletions(-)
tools/perf/util/evlist.c +37 -8
@@ -265,17 +265,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,return 0 ; } +static int perf_evlist__nr_threads (struct perf_evlist *evlist, +struct perf_evsel *evsel) +{ +if (evsel->system_wide) +return 1 ; +else +return thread_map__nr (evlist->threads); +} +void perf_evlist__disable (struct perf_evlist *evlist) {int cpu, thread;struct perf_evsel *pos;int nr_cpus =cpu_map__nr (evlist->cpus); -int nr_threads =thread_map__nr (evlist->threads); +int nr_threads;for (cpu =0 ; cpu < nr_cpus; cpu++) {evlist__for_each (evlist, pos) {if (!perf_evsel__is_group_leader (pos) || !pos->fd)continue ; + nr_threads =perf_evlist__nr_threads (evlist, pos);for (thread =0 ; thread < nr_threads; thread++)ioctl (FD (pos, cpu, thread),PERF_EVENT_IOC_DISABLE ,0 );
@@ -288,12 +298,13 @@ void perf_evlist__enable(struct perf_evlist *evlist)int cpu, thread;struct perf_evsel *pos;int nr_cpus =cpu_map__nr (evlist->cpus); -int nr_threads =thread_map__nr (evlist->threads); +int nr_threads;for (cpu =0 ; cpu < nr_cpus; cpu++) {evlist__for_each (evlist, pos) {if (!perf_evsel__is_group_leader (pos) || !pos->fd)continue ; + nr_threads =perf_evlist__nr_threads (evlist, pos);for (thread =0 ; thread < nr_threads; thread++)ioctl (FD (pos, cpu, thread),PERF_EVENT_IOC_ENABLE ,0 );
@@ -305,12 +316,14 @@ int perf_evlist__disable_event(struct perf_evlist *evlist, struct perf_evsel *evsel) {int cpu, thread, err; +int nr_cpus =cpu_map__nr (evlist->cpus); +int nr_threads =perf_evlist__nr_threads (evlist, evsel);if (!evsel->fd)return 0 ; -for (cpu =0 ; cpu < evlist->cpus->nr; cpu++) { -for (thread =0 ; thread < evlist->threads->nr; thread++) { +for (cpu =0 ; cpu < nr_cpus; cpu++) { +for (thread =0 ; thread < nr_threads; thread++) { err =ioctl (FD (evsel, cpu, thread),PERF_EVENT_IOC_DISABLE ,0 );if (err)
@@ -324,12 +337,14 @@ int perf_evlist__enable_event(struct perf_evlist *evlist, struct perf_evsel *evsel) {int cpu, thread, err; +int nr_cpus =cpu_map__nr (evlist->cpus); +int nr_threads =perf_evlist__nr_threads (evlist, evsel);if (!evsel->fd)return -EINVAL ; -for (cpu =0 ; cpu < evlist->cpus->nr; cpu++) { -for (thread =0 ; thread < evlist->threads->nr; thread++) { +for (cpu =0 ; cpu < nr_cpus; cpu++) { +for (thread =0 ; thread < nr_threads; thread++) { err =ioctl (FD (evsel, cpu, thread),PERF_EVENT_IOC_ENABLE ,0 );if (err)
@@ -343,7 +358,16 @@ static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) {int nr_cpus =cpu_map__nr (evlist->cpus);int nr_threads =thread_map__nr (evlist->threads); -int nfds = nr_cpus * nr_threads * evlist->nr_entries; +int nfds =0 ; +struct perf_evsel *evsel; + +list_for_each_entry (evsel, &evlist->entries, node) { +if (evsel->system_wide) + nfds += nr_cpus; +else + nfds += nr_cpus * nr_threads; + } + evlist->pollfd =malloc (sizeof (struct pollfd ) * nfds);return evlist->pollfd !=NULL ?0 : -ENOMEM ; }
@@ -636,7 +660,12 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,struct perf_evsel *evsel;evlist__for_each (evlist, evsel) { -int fd =FD (evsel, cpu, thread); +int fd; + +if (evsel->system_wide && thread) +continue ; + + fd =FD (evsel, cpu, thread);if (*output ==-1 ) { *output = fd;
tools/perf/util/evsel.c +26 -5
@@ -695,6 +695,10 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)int perf_evsel__alloc_fd (struct perf_evsel *evsel,int ncpus,int nthreads) {int cpu, thread; + +if (evsel->system_wide) + nthreads =1 ; + evsel->fd =xyarray__new (ncpus, nthreads,sizeof (int ));if (evsel->fd) {
@@ -713,6 +717,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea {int cpu, thread; +if (evsel->system_wide) + nthreads =1 ; +for (cpu =0 ; cpu < ncpus; cpu++) {for (thread =0 ; thread < nthreads; thread++) { int fd = FD(evsel, cpu, thread),
@@ -743,6 +750,9 @@ int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads)int perf_evsel__alloc_id (struct perf_evsel *evsel,int ncpus,int nthreads) { +if (evsel->system_wide) + nthreads =1 ; + evsel->sample_id =xyarray__new (ncpus, nthreads,sizeof (struct perf_sample_id ));if (evsel->sample_id ==NULL )return -ENOMEM ;
@@ -787,6 +797,9 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) {int cpu, thread; +if (evsel->system_wide) + nthreads =1 ; +for (cpu =0 ; cpu < ncpus; cpu++)for (thread =0 ; thread < nthreads; ++thread) {close (FD (evsel, cpu, thread));
@@ -875,6 +888,9 @@ int __perf_evsel__read(struct perf_evsel *evsel,int cpu, thread;struct perf_counts_values *aggr = &evsel->counts->aggr, count; +if (evsel->system_wide) + nthreads =1 ; + aggr->val = aggr->ena = aggr->run =0 ;for (cpu =0 ; cpu < ncpus; cpu++) {
@@ -997,13 +1013,18 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)static int __perf_evsel__open (struct perf_evsel *evsel,struct cpu_map *cpus,struct thread_map *threads) { -int cpu, thread; +int cpu, thread, nthreads;unsigned long flags =PERF_FLAG_FD_CLOEXEC ;int pid =-1 , err;enum {NO_CHANGE ,SET_TO_MAX ,INCREASED_MAX } set_rlimit =NO_CHANGE ; +if (evsel->system_wide) + nthreads =1 ; +else + nthreads = threads->nr; +if (evsel->fd ==NULL && -perf_evsel__alloc_fd (evsel, cpus->nr, threads->nr) <0 ) +perf_evsel__alloc_fd (evsel, cpus->nr, nthreads) <0 )return -ENOMEM ;if (evsel->cgrp) {
@@ -1027,10 +1048,10 @@ retry_sample_id:for (cpu =0 ; cpu < cpus->nr; cpu++) { -for (thread =0 ; thread < threads->nr; thread++) { +for (thread =0 ; thread < nthreads; thread++) {int group_fd; -if (!evsel->cgrp) +if (!evsel->cgrp && !evsel->system_wide) pid = threads->map[thread]; group_fd =get_group_fd (evsel, cpu, thread);
@@ -1103,7 +1124,7 @@ out_close:close (FD (evsel, cpu, thread));FD (evsel, cpu, thread) =-1 ; } - thread = threads->nr; + thread = nthreads; }while (--cpu >=0 );return err; }
tools/perf/util/evsel.h +1 -0
@@ -85,6 +85,7 @@ struct perf_evsel {bool needs_swap;bool no_aux_samples;bool immediate; +bool system_wide;/* parse modifier helper */ int exclude_GH;int nr_members;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 34/41 perf evlist: Add perf_evlist__set_tracking_event()
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add a function to change which event is used to track mmap, comm and task events.
This is needed with Instruction Tracing because the Instruction Tracing event must come first but cannot be used for tracking because it will be disabled under some circumstances.
--- tools/perf/util/evlist.c | 17 +++++++++++++++++ tools/perf/util/evlist.h | 3 +++ tools/perf/util/evsel.c | 3 ++- tools/perf/util/evsel.h | 1 + tools/perf/util/record.c | 2 +- 5 files changed, 24 insertions(+), 2 deletions(-)
tools/perf/util/evlist.c +17 -0
@@ -122,6 +122,7 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) {list_add_tail (&entry->node, &evlist->entries); entry->idx = evlist->nr_entries; + entry->tracking = !entry->idx;if (!evlist->nr_entries++)perf_evlist__set_id_pos (evlist);
@@ -1295,3 +1296,19 @@ void perf_evlist__to_front(struct perf_evlist *evlist,list_splice (&move, &evlist->entries); } + +void perf_evlist__set_tracking_event (struct perf_evlist *evlist, +struct perf_evsel *tracking_evsel) +{ +struct perf_evsel *evsel; + +if (tracking_evsel->tracking) +return ; + +evlist__for_each (evlist, evsel) { +if (evsel != tracking_evsel) + evsel->tracking = false; + } + + tracking_evsel->tracking = true; +}
tools/perf/util/evlist.h +3 -0
@@ -262,4 +262,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,#define evlist__for_each_safe (evlist, tmp, evsel) \ __evlist__for_each_safe(&(evlist)->entries, tmp, evsel) +void perf_evlist__set_tracking_event (struct perf_evlist *evlist, +struct perf_evsel *tracking_evsel); +#endif /* __PERF_EVLIST_H */
tools/perf/util/evsel.c +2 -1
@@ -162,6 +162,7 @@ void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr, int idx) { evsel->idx = idx; + evsel->tracking = !idx; evsel->attr = *attr; evsel->leader = evsel; evsel->unit ="" ;
@@ -561,7 +562,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) {struct perf_evsel *leader = evsel->leader;struct perf_event_attr *attr = &evsel->attr; -int track = !evsel->idx;/* only the first counter needs these */ +int track = evsel->tracking;bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread; attr->sample_id_all = perf_missing_features.sample_id_all ?0 :1 ;
tools/perf/util/evsel.h +1 -0
@@ -86,6 +86,7 @@ struct perf_evsel {bool no_aux_samples;bool immediate;bool system_wide; +bool tracking;/* parse modifier helper */ int exclude_GH;int nr_members;
tools/perf/util/record.c +1 -1
@@ -115,7 +115,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)evlist__for_each (evlist, evsel) {perf_evsel__config (evsel, opts); -if (!evsel->idx && use_comm_exec) +if (evsel->tracking && use_comm_exec) evsel->attr.comm_exec =1 ; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 35/41 perf session: Add perf_session__peek_event()
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add a function to peek at other events in the event stream.
--- tools/perf/util/session.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/session.h | 5 +++++ 2 files changed, 60 insertions(+)
tools/perf/util/session.c +55 -0
@@ -897,6 +897,61 @@ static void event_swap(union perf_event *event, bool sample_id_all)swap (event, sample_id_all); } +int perf_session__peek_event (struct perf_session *session,off_t file_offset, +void *buf,size_t buf_sz, +union perf_event **event_ptr, +struct perf_sample *sample) +{ +union perf_event *event; +size_t hdr_sz, rest; +int fd; + +if (session->one_mmap && !session->header.needs_swap) { + event = file_offset - session->one_mmap_offset + + session->one_mmap_addr; + goto out_parse_sample; + } + +if (perf_data_file__is_pipe (session->file)) +return -1 ; + + fd =perf_data_file__fd (session->file); + hdr_sz =sizeof (struct perf_event_header ); + +if (buf_sz < hdr_sz) +return -1 ; + +if (lseek (fd, file_offset,SEEK_SET ) == (off_t)-1 || +readn (fd, &buf, hdr_sz) != (ssize_t )hdr_sz) +return -1 ; + + event = (union perf_event *)buf; + +if (session->header.needs_swap) +perf_event_header__bswap (&event->header); + +if (event->header.size < hdr_sz) +return -1 ; + + rest = event->header.size - hdr_sz; + +if (readn (fd, &buf, rest) != (ssize_t )rest) +return -1 ; + +if (session->header.needs_swap) +event_swap (event,perf_evlist__sample_id_all (session->evlist)); + +out_parse_sample: + +if (sample && event->header.type <PERF_RECORD_USER_TYPE_START && +perf_evlist__parse_sample (session->evlist, event, sample)) +return -1 ; + + *event_ptr = event; + +return 0 ; +} + static s64 perf_session__process_event(struct perf_session *session, union perf_event *event, struct perf_tool *tool,
tools/perf/util/session.h +5 -0
@@ -45,6 +45,11 @@ void perf_session__delete(struct perf_session *session);void perf_event_header__bswap (struct perf_event_header *hdr); +int perf_session__peek_event (struct perf_session *session,off_t file_offset, +void *buf,size_t buf_sz, +union perf_event **event_ptr, +struct perf_sample *sample); +int __perf_session__process_events (struct perf_session *session,u64 data_offset,u64 data_size,u64 size,struct perf_tool *tool);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 36/41 perf script: Allow callchains if any event samples them
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
perf script was not displaying callchains if any selected event did not have PERF_SAMPLE_CALLCHAIN.
Change this to disable callchains only if all selected events do not have PERF_SAMPLE_CALLCHAIN.
--- tools/perf/builtin-script.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
tools/perf/builtin-script.c +13 -4
@@ -184,10 +184,6 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,if (perf_evsel__check_stype (evsel,PERF_SAMPLE_IP ,"IP" ,PERF_OUTPUT_IP ))return -EINVAL ; - -if (!no_callchain && - !(attr->sample_type &PERF_SAMPLE_CALLCHAIN )) - symbol_conf.use_callchain = false; } if (PRINT_FIELD(ADDR) &&
@@ -290,6 +286,19 @@ static int perf_session__check_output_opt(struct perf_session *session)set_print_ip_opts (&evsel->attr); } +if (!no_callchain) { +bool use_callchain = false; + +evlist__for_each (session->evlist, evsel) { +if (evsel->attr.sample_type &PERF_SAMPLE_CALLCHAIN ) { + use_callchain = true; +break ; + } + } +if (!use_callchain) + symbol_conf.use_callchain = false; + } +/* * set default for tracepoints to print symbols only * if callchains are present
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 37/41 perf script python: Add helpers for calling Python objects
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
The Python script API repeatedly uses the same lines of code to get and call objects. Make that into helper functions instead.
A side-effect is that some reference counting bugs disappear because the new call_object() function always decrements the reference count of 'retval'.
--- .../util/scripting-engines/trace-event-python.c | 114 +++++++++------------ 1 file changed, 47 insertions(+), 67 deletions(-)
tools/perf/util/scripting-engines/trace-event-python.c +47 -67
@@ -73,6 +73,35 @@ static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObjPy_DECREF (val); } +static PyObject *get_handler (const char *handler_name) +{ +PyObject *handler; + + handler =PyDict_GetItemString (main_dict, handler_name); +if (handler && !PyCallable_Check (handler)) +return NULL ; +return handler; +} + +static void call_object (PyObject *handler,PyObject *args,const char *die_msg) +{ +PyObject *retval; + + retval =PyObject_CallObject (handler, args); +if (retval ==NULL ) +handler_call_die (die_msg); +Py_DECREF (retval); +} + +static void try_call_object (const char *handler_name,PyObject *args) +{ +PyObject *handler; + + handler =get_handler (handler_name); +if (handler) +call_object (handler, args, handler_name); +} + static void define_value(enum print_arg_type field_type, const char *ev_name, const char *field_name,
@@ -80,7 +109,7 @@ static void define_value(enum print_arg_type field_type, const char *field_str) {const char *handler_name ="define_flag_value" ; -PyObject *handler, *t, *retval; +PyObject *t;unsigned long long value;unsigned n =0 ;
@@ -98,13 +127,7 @@ static void define_value(enum print_arg_type field_type,PyTuple_SetItem (t, n++,PyInt_FromLong (value));PyTuple_SetItem (t, n++,PyString_FromString (field_str)); - handler =PyDict_GetItemString (main_dict, handler_name); -if (handler &&PyCallable_Check (handler)) { - retval =PyObject_CallObject (handler, t); -if (retval ==NULL ) -handler_call_die (handler_name); -Py_DECREF (retval); - } +try_call_object (handler_name, t);Py_DECREF (t); }
@@ -127,7 +150,7 @@ static void define_field(enum print_arg_type field_type, const char *delim) {const char *handler_name ="define_flag_field" ; -PyObject *handler, *t, *retval; +PyObject *t;unsigned n =0 ;if (field_type ==PRINT_SYMBOL )
@@ -145,13 +168,7 @@ static void define_field(enum print_arg_type field_type,if (field_type ==PRINT_FLAGS )PyTuple_SetItem (t, n++,PyString_FromString (delim)); - handler =PyDict_GetItemString (main_dict, handler_name); -if (handler &&PyCallable_Check (handler)) { - retval =PyObject_CallObject (handler, t); -if (retval ==NULL ) -handler_call_die (handler_name); -Py_DECREF (retval); - } +try_call_object (handler_name, t);Py_DECREF (t); }
@@ -362,7 +379,7 @@ static void python_process_tracepoint(struct perf_sample *sample,struct thread *thread, struct addr_location *al) { - PyObject *handler, *retval, *context, *t, *obj, *callchain; + PyObject *handler, *context, *t, *obj, *callchain;PyObject *dict =NULL ;static char handler_name[256 ];struct format_field *field;
@@ -387,9 +404,7 @@ static void python_process_tracepoint(struct perf_sample *sample,sprintf (handler_name,"%s__%s" , event->system, event->name); - handler =PyDict_GetItemString (main_dict, handler_name); -if (handler && !PyCallable_Check (handler)) - handler =NULL ; + handler =get_handler (handler_name);if (!handler) { dict =PyDict_New ();if (!dict)
@@ -450,19 +465,9 @@ static void python_process_tracepoint(struct perf_sample *sample,Py_FatalError ("error resizing Python tuple" );if (handler) { - retval =PyObject_CallObject (handler, t); -if (retval ==NULL ) -handler_call_die (handler_name); -Py_DECREF (retval); +call_object (handler, t, handler_name); }else { - handler =PyDict_GetItemString (main_dict,"trace_unhandled" ); -if (handler &&PyCallable_Check (handler)) { - - retval =PyObject_CallObject (handler, t); -if (retval ==NULL ) -handler_call_die ("trace_unhandled" ); -Py_DECREF (retval); - } +try_call_object ("trace_unhandled" , t);Py_DECREF (dict); }
@@ -474,7 +479,7 @@ static void python_process_general_event(struct perf_sample *sample,struct thread *thread, struct addr_location *al) { - PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample; + PyObject *handler, *t, *dict, *callchain, *dict_sample;static char handler_name[64 ];unsigned n =0 ;
@@ -496,8 +501,8 @@ static void python_process_general_event(struct perf_sample *sample,snprintf (handler_name,sizeof (handler_name),"%s" ,"process_event" ); - handler =PyDict_GetItemString (main_dict, handler_name); -if (!handler || !PyCallable_Check (handler)) + handler =get_handler (handler_name); +if (!handler) goto exit;pydict_set_item_string_decref (dict,"ev_name" ,PyString_FromString (perf_evsel__name (evsel)));
@@ -539,10 +544,7 @@ static void python_process_general_event(struct perf_sample *sample,if (_PyTuple_Resize (&t, n) ==-1 )Py_FatalError ("error resizing Python tuple" ); - retval =PyObject_CallObject (handler, t); -if (retval ==NULL ) -handler_call_die (handler_name); -Py_DECREF (retval); +call_object (handler, t, handler_name); exit:Py_DECREF (dict);Py_DECREF (t);
@@ -566,36 +568,24 @@ static void python_process_event(union perf_event *event __maybe_unused,static int run_start_sub (void ) { -PyObject *handler, *retval; -int err =0 ; - main_module =PyImport_AddModule ("__main__" );if (main_module ==NULL )return -1 ;Py_INCREF (main_module); main_dict =PyModule_GetDict (main_module); -if (main_dict ==NULL ) { - err =-1 ; +if (main_dict ==NULL ) goto error; - }Py_INCREF (main_dict); - handler =PyDict_GetItemString (main_dict,"trace_begin" ); -if (handler ==NULL || !PyCallable_Check (handler)) - goto out; +try_call_object ("trace_begin" ,NULL ); - retval =PyObject_CallObject (handler,NULL ); -if (retval ==NULL ) -handler_call_die ("trace_begin" ); +return 0 ; -Py_DECREF (retval); -return err; error:Py_XDECREF (main_dict);Py_XDECREF (main_module); -out: -return err; +return -1 ; }/*
@@ -654,23 +644,13 @@ error:*/ static int python_stop_script (void ) { -PyObject *handler, *retval; -int err =0 ; +try_call_object ("trace_end" ,NULL ); - handler =PyDict_GetItemString (main_dict,"trace_end" ); -if (handler ==NULL || !PyCallable_Check (handler)) - goto out; - - retval =PyObject_CallObject (handler,NULL ); -if (retval ==NULL ) -handler_call_die ("trace_end" ); -Py_DECREF (retval); -out:Py_XDECREF (main_dict);Py_XDECREF (main_module);Py_Finalize (); -return err; +return 0 ; }static int python_generate_script (struct pevent *pevent,const char *outfile)
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 38/41 perf tools: Identify which comms are from exec
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
For grouping together all the data from a single execution, which is needed for pairing calls and returns e.g. any outstanding calls when a process exec's will never return.
--- tools/perf/util/comm.c | 7 +++++-- tools/perf/util/comm.h | 6 ++++-- tools/perf/util/machine.c | 4 +++- tools/perf/util/thread.c | 24 +++++++++++++++++++----- tools/perf/util/thread.h | 10 +++++++++- 5 files changed, 40 insertions(+), 11 deletions(-)
tools/perf/util/comm.c +5 -2
@@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)return new; } -struct comm *comm__new (const char *str,u64 timestamp) +struct comm *comm__new (const char *str,u64 timestamp,bool exec) {struct comm *comm =zalloc (sizeof (*comm));
@@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp)return NULL ; comm->start = timestamp; + comm->exec = exec; comm->comm_str =comm_str__findnew (str, &comm_str_root);if (!comm->comm_str) {
@@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp)return comm; } -int comm__override (struct comm *comm,const char *str,u64 timestamp) +int comm__override (struct comm *comm,const char *str,u64 timestamp,bool exec) {struct comm_str *new, *old = comm->comm_str;
@@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)comm_str__put (old); comm->comm_str = new; comm->start = timestamp; +if (exec) + comm->exec = true;return 0 ; }
tools/perf/util/comm.h +4 -2
@@ -11,11 +11,13 @@ struct comm {struct comm_str *comm_str;u64 start;struct list_head list; + bool exec; };void comm__free (struct comm *comm); -struct comm *comm__new (const char *str,u64 timestamp); +struct comm *comm__new (const char *str,u64 timestamp,bool exec);const char *comm__str (const struct comm *comm); -int comm__override (struct comm *comm,const char *str,u64 timestamp); +int comm__override (struct comm *comm,const char *str,u64 timestamp, +bool exec);#endif /* __PERF_COMM_H */
tools/perf/util/machine.c +3 -1
@@ -404,11 +404,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *eventstruct thread *thread =machine__findnew_thread (machine, event->comm.pid, event->comm.tid); +bool exec = event->header.misc &PERF_RECORD_MISC_COMM_EXEC ;if (dump_trace)perf_event__fprintf_comm (event, stdout); -if (thread ==NULL ||thread__set_comm (thread, event->comm.comm, sample->time)) { +if (thread ==NULL || +__thread__set_comm (thread, event->comm.comm, sample->time, exec)) {dump_printf ("problem processing PERF_RECORD_COMM, skipping event.\n" );return -1 ; }
tools/perf/util/thread.c +19 -5
@@ -42,7 +42,7 @@ struct thread *thread__new(pid_t pid, pid_t tid) goto err_thread;snprintf (comm_str,32 ,":%d" , tid); - comm =comm__new (comm_str,0 ); + comm =comm__new (comm_str,0 , false);free (comm_str);if (!comm) goto err_thread;
@@ -81,19 +81,33 @@ struct comm *thread__comm(const struct thread *thread) return list_first_entry(&thread->comm_list, struct comm, list); } +struct comm *thread__exec_comm (const struct thread *thread) +{ +struct comm *comm, *last =NULL ; + +list_for_each_entry (comm, &thread->comm_list, list) { +if (comm->exec) +return comm; + last = comm; + } + +return last; +} +/* CHECKME: time should always be 0 if event aren't ordered */ -int thread__set_comm (struct thread *thread,const char *str,u64 timestamp) +int __thread__set_comm (struct thread *thread,const char *str,u64 timestamp, +bool exec) {struct comm *new, *curr =thread__comm (thread);int err;/* Override latest entry if it had no specific time coverage */ -if (!curr->start) { - err =comm__override (curr, str, timestamp); +if (!curr->start && !curr->exec) { + err =comm__override (curr, str, timestamp, exec);if (err)return err; }else { - new =comm__new (str, timestamp); + new =comm__new (str, timestamp, exec);if (!new)return -ENOMEM ;list_add (&new->list, &thread->comm_list);
tools/perf/util/thread.h +9 -1
@@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread) thread->dead = true; } -int thread__set_comm (struct thread *thread,const char *comm,u64 timestamp); +int __thread__set_comm (struct thread *thread,const char *comm,u64 timestamp, +bool exec); +static inline int thread__set_comm (struct thread *thread,const char *comm, +u64 timestamp) +{ +return __thread__set_comm (thread, comm, timestamp, false); +} +int thread__comm_len (struct thread *thread);struct comm *thread__comm (const struct thread *thread); +struct comm *thread__exec_comm (const struct thread *thread);const char *thread__comm_str (const struct thread *thread);void thread__insert_map (struct thread *thread,struct map *map);int thread__fork (struct thread *thread,struct thread *parent,u64 timestamp);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 39/41 perf machine: Add machine__thread_exec_comm()
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add machine__thread_exec_comm() to return the comm that matches the last exec, if the comm_exec flag is present, or the last comm otherwise.
--- tools/perf/util/machine.c | 26 ++++++++++++++++++++++++++ tools/perf/util/machine.h | 4 ++++ tools/perf/util/session.c | 24 +++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-)
tools/perf/util/machine.c +26 -0
@@ -31,6 +31,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) machine->symbol_filter =NULL ; machine->id_hdr_size =0 ; + machine->comm_exec = false; machine->root_dir =strdup (root_dir);if (machine->root_dir ==NULL )
@@ -179,6 +180,19 @@ void machines__set_symbol_filter(struct machines *machines, } } +void machines__set_comm_exec (struct machines *machines,bool comm_exec) +{ +struct rb_node *nd; + + machines->host.comm_exec = comm_exec; + +for (nd =rb_first (&machines->guests); nd; nd =rb_next (nd)) { + struct machine *machine = rb_entry(nd, struct machine, rb_node); + + machine->comm_exec = comm_exec; + } +} +struct machine *machines__find (struct machines *machines,pid_t pid) {struct rb_node **p = &machines->guests.rb_node;
@@ -398,6 +412,15 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid,return __machine__findnew_thread (machine, pid, tid, false); } +struct comm *machine__thread_exec_comm (struct machine *machine, +struct thread *thread) +{ +if (machine->comm_exec) +return thread__exec_comm (thread); +else +return thread__comm (thread); +} +int machine__process_comm_event (struct machine *machine,union perf_event *event,struct perf_sample *sample) {
@@ -406,6 +429,9 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event event->comm.tid);bool exec = event->header.misc &PERF_RECORD_MISC_COMM_EXEC ; +if (exec) + machine->comm_exec = true; +if (dump_trace)perf_event__fprintf_comm (event, stdout);
tools/perf/util/machine.h +4 -0
@@ -26,6 +26,7 @@ struct machine {struct rb_node rb_node;pid_t pid;u16 id_hdr_size; +bool comm_exec;char *root_dir;struct rb_root threads;struct list_head dead_threads;
@@ -47,6 +48,8 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)struct thread *machine__find_thread (struct machine *machine,pid_t pid,pid_t tid); +struct comm *machine__thread_exec_comm (struct machine *machine, +struct thread *thread);int machine__process_comm_event (struct machine *machine,union perf_event *event,struct perf_sample *sample);
@@ -88,6 +91,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);void machines__set_symbol_filter (struct machines *machines,symbol_filter_t symbol_filter); +void machines__set_comm_exec (struct machines *machines,bool comm_exec);struct machine *machine__new_host (void );int machine__init (struct machine *machine,const char *root_dir,pid_t pid);
tools/perf/util/session.c +23 -1
@@ -67,6 +67,25 @@ static void perf_session__destroy_kernel_maps(struct perf_session *session)machines__destroy_kernel_maps (&session->machines); } +static bool perf_session__has_comm_exec (struct perf_session *session) +{ +struct perf_evsel *evsel; + +evlist__for_each (session->evlist, evsel) { +if (evsel->attr.comm_exec) +return true; + } + +return false; +} + +static void perf_session__set_comm_exec (struct perf_session *session) +{ +bool comm_exec =perf_session__has_comm_exec (session); + +machines__set_comm_exec (&session->machines, comm_exec); +} +struct perf_session *perf_session__new (struct perf_data_file *file,bool repipe,struct perf_tool *tool) {
@@ -90,6 +109,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, goto out_close;perf_session__set_id_hdr_size (session); +perf_session__set_comm_exec (session); } }
@@ -866,8 +886,10 @@ static s64 perf_session__process_user_event(struct perf_session *session,switch (event->header.type) {case PERF_RECORD_HEADER_ATTR : err = tool->attr (tool, event, &session->evlist); -if (err ==0 ) +if (err ==0 ) {perf_session__set_id_hdr_size (session); +perf_session__set_comm_exec (session); + }return err;case PERF_RECORD_HEADER_EVENT_TYPE :/*
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 40/41 perf tools: Add flags and insn_len to struct sample
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
The flags will be used to export branch type and transaction status.
insn_len is preparation for pairing calls and returns because the return address equals the call address plus the instruction length (insn_len).
--- tools/perf/util/event.h | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/event.h +2 -0
@@ -156,6 +156,8 @@ struct perf_sample {u32 cpu;u32 raw_size;u64 data_src; +u32 flags; +u16 insn_len;void *raw_data;struct ip_callchain *callchain;struct branch_stack *branch_stack;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 41/41 perf evlist: Add perf_evlist__enable_event_idx()
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add a function to enable a specific event within a specific perf event buffer.
--- tools/perf/util/evlist.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/evlist.h | 2 ++ 2 files changed, 49 insertions(+)
tools/perf/util/evlist.c +47 -0
@@ -355,6 +355,53 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,return 0 ; } +static int perf_evlist__enable_event_cpu (struct perf_evlist *evlist, +struct perf_evsel *evsel,int cpu) +{ +int thread, err; +int nr_threads =perf_evlist__nr_threads (evlist, evsel); + +if (!evsel->fd) +return -EINVAL ; + +for (thread =0 ; thread < nr_threads; thread++) { + err =ioctl (FD (evsel, cpu, thread), +PERF_EVENT_IOC_ENABLE ,0 ); +if (err) +return err; + } +return 0 ; +} + +static int perf_evlist__enable_event_thread (struct perf_evlist *evlist, +struct perf_evsel *evsel, +int thread) +{ +int cpu, err; +int nr_cpus =cpu_map__nr (evlist->cpus); + +if (!evsel->fd) +return -EINVAL ; + +for (cpu =0 ; cpu < nr_cpus; cpu++) { + err =ioctl (FD (evsel, cpu, thread),PERF_EVENT_IOC_ENABLE ,0 ); +if (err) +return err; + } +return 0 ; +} + +int perf_evlist__enable_event_idx (struct perf_evlist *evlist, +struct perf_evsel *evsel,int idx) +{ +bool per_cpu_mmaps = !cpu_map__empty (evlist->cpus); + +if (per_cpu_mmaps) +return perf_evlist__enable_event_cpu (evlist, evsel, idx); +else +return perf_evlist__enable_event_thread (evlist, evsel, idx); +} +static int perf_evlist__alloc_pollfd (struct perf_evlist *evlist) {int nr_cpus =cpu_map__nr (evlist->cpus);
tools/perf/util/evlist.h +2 -0
@@ -122,6 +122,8 @@ int perf_evlist__disable_event(struct perf_evlist *evlist, struct perf_evsel *evsel);int perf_evlist__enable_event (struct perf_evlist *evlist,struct perf_evsel *evsel); +int perf_evlist__enable_event_idx (struct perf_evlist *evlist, +struct perf_evsel *evsel,int idx);void perf_evlist__set_selected (struct perf_evlist *evlist,struct perf_evsel *evsel);
Signature · 1 line
1.9.3
Quoted 155 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling, more to come! :-)
- Arnaldo
The following changes since commit
ddcd0973fe02aad3d4bdc59dd0f1db90f51105a9:perf/x86/uncore: Rename IvyTown to IvyBridge-EP (2014-08-13 07:51:18 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingofor you to fetch changes up to
1c65056c547141a0cb52fb8e6056f63524d2bbf2:perf evlist: Add
perf_evlist__enable_event_idx()(2014-08-13 19:23:48 -0300)----------------------------------------------------------------
perf/probe fixes and improvements:User visible changes:
. Do not show +/- callchain expansion when there are no childs (top/report) (Namhyung Kim)
. Fix -z and add respective 'z' hotkey to zero samples before refresh
in 'perf top' (Namhyung Kim). Capability probing fixes, improving the detection of
kernel features for non-priviledged users (Adrian Hunter). Add beautifier for mremap flags param in 'trace' (Alex Snast)
. Fix --list and --del options to show events when just uprobes is
enabled (Masami Hiramatsu). perf script: Allow callchains if any event samples them
. Don't look for kernel idle symbols in all DSOs in 'perf top' (Arnaldo Carvalho de Melo)
. Add
cpu_startup_entryto the list of kernel idle symbols (Arnaldo Carvalho de Melo). 'perf top' terminal output fixes (Jiri Olsa)
. Fix stdin handling for 'perf kvm stat live' (Jiri Olsa)
. Fix missing label symbols (Adrian Hunter)
. Don't demangle C++ parameters and such by default, only in
--verbose mode (Namhyung Kim). Set proper
sort__modefor the branch option (Naohiro Aota). Check recorded kernel version when finding vmlinux (Namhyung Kim)
Developer Stuff:
. More prep work for intel PT (Adrian Hunter)
. Fix possible memory leaks (Namhyung Kim)
. Fix a memory leak in
vmlinux_path__init()(Namhyung Kim)Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Adrian Hunter (14):
perf tools: Fix CLOEXEC probe forperf_event_paranoid== 2 perf tools: Fix one of the probe events to exclude kernel perf tools: Fix probing the kernel API with cpu-wide events perf tools: Prefer to use a cpu-wide event for probing CLOEXEC perf symbols: Fix missing label symbols
perf evlist: Add 'system_wide' option
perf evlist: Addperf_evlist__set_tracking_event()perf session: Addperf_session__peek_event()
perf script: Allow callchains if any event samples them perf script python: Add helpers for calling Python objects perf tools: Identify which comms are from exec
perf machine: Addmachine__thread_exec_comm()
perf tools: Add flags andinsn_lento struct sample perf evlist: Addperf_evlist__enable_event_idx()Alex Snast (1):
perf trace: Add beautifier for mremap flags paramArnaldo Carvalho de Melo (2):
perf top: Don't look for kernel idle symbols in all DSOs perf tools: Addcpu_startup_entryto the list of kernel idle symbolsJiri Olsa (4):
perf top: Join the display thread on exit
perf tools: Introduceset_term_quiet_inputhelper function perf top: Setup signals for terminal output
perf kvm: Fix stdin handling for 'kvm stat live' commandMasami Hiramatsu (2):
perf probe: Fix --list option to show events only with uprobe events perf probe: Fix --del option to delete events only with uprobe eventsNamhyung Kim (17):
perf script: Fix possible memory leaks
perf symbols: Fix a memory leak invmlinux_path__init()perf annotate: Move session handling out of__cmd_annotate()perf buildid-cache: Move session handling intocmd_buildid_cache()perf inject: Move session handling out of__cmd_inject()perf kmem: Move session handling out of__cmd_kmem()perf kvm: Move call tosymbol__init()after creating session perf lock: Move call tosymbol__init()after creating session perf sched: Move call tosymbol__init()after creating session perf script: Move call tosymbol__init()after creating session perf timechart: Move call tosymbol__init()after creating session perf trace: Move call tosymbol__init()after creating session perf tools: Check recorded kernel version when finding vmlinux perf hists browser: Fix a small callchain display bug perf top: Fix -z option behavior
perf top: Handle 'z' key for toggle zeroing samples in TUI perf symbols: Don't demangle parameters and such by default[email protected] (1):
perf report: Set propersort__modefor the branch optiontools/perf/builtin-annotate.c | 75 +++++++------- tools/perf/builtin-buildid-cache.c | 37 ++++--- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-inject.c | 31 +++--- tools/perf/builtin-kmem.c | 49 +++++---- tools/perf/builtin-kvm.c | 24 ++--- tools/perf/builtin-lock.c | 3 +- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 4 +- tools/perf/builtin-sched.c | 3 +- tools/perf/builtin-script.c | 57 +++++++---- tools/perf/builtin-timechart.c | 4 +- tools/perf/builtin-top.c | 59 ++++++++--- tools/perf/builtin-trace.c | 34 +++++- tools/perf/tests/builtin-test.c | 2 +- tools/perf/ui/browsers/hists.c | 13 ++- tools/perf/util/cloexec.c | 23 ++++- tools/perf/util/comm.c | 7 +- tools/perf/util/comm.h | 6 +- tools/perf/util/event.h | 2 + tools/perf/util/evlist.c | 109 ++++++++++++++++++-- tools/perf/util/evlist.h | 5 + tools/perf/util/evsel.c | 34 ++++-- tools/perf/util/evsel.h | 2 + tools/perf/util/hist.c | 22 ++++ tools/perf/util/hist.h | 1 + tools/perf/util/machine.c | 30 +++++- tools/perf/util/machine.h | 4 + tools/perf/util/probe-event.c | 98 ++++++++++++------ tools/perf/util/record.c | 40 ++++++-- .../util/scripting-engines/trace-event-python.c | 114 +++++++++------------ tools/perf/util/session.c | 79 +++++++++++++- tools/perf/util/session.h | 5 +
Quoted 8 lines
tools/perf/util/symbol-elf.c | 9 +- tools/perf/util/symbol.c | 31 ++++-- tools/perf/util/symbol.h | 4 +- tools/perf/util/thread.c | 24 ++++- tools/perf/util/thread.h | 10 +- tools/perf/util/util.c | 13 +++ tools/perf/util/util.h | 2 + 41 files changed, 770 insertions(+), 305 deletions(-)
Pulled, thanks a lot Arnaldo!
Ingo