From 0a8cb85c200c4082ed7e57efd90dd9d18c8d40b6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 6 Jul 2014 14:18:21 +0200 Subject: perf tools: Rename ordered_samples bool to ordered_events The time ordering is generic for all kinds of events, so using generic name 'ordered_events' for ordered_samples bool in perf_tool struct. No functional change was intended. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-07mrqzcuhsks9wfmxrzsvemz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 9a5a035cb426..c10cc44bae19 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -360,7 +360,7 @@ static struct perf_tool tool = { .exit = perf_event__process_exit, .fork = perf_event__process_fork, .lost = perf_event__process_lost, - .ordered_samples = true, + .ordered_events = true, .ordering_requires_timestamps = true, }; -- cgit v1.2.3 From 0a7e6d1b6844bec2d6817615a693c7fce447b80d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:45 +0900 Subject: perf tools: Check recorded kernel version when finding vmlinux 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_instruction After: # Overhead Command Shared Object Symbol # ........ .......... ................. .................... 71.87% swapper [kernel.kallsyms] [k] native_safe_halt This requires to change signature of symbol__init() to receive struct perf_session_env *. Reported-by: Minchan Kim Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407825645-24586-14-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- 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(-) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index c0464dc38057..d4da6929597f 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -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; diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index d91bfa6632e8..ac5838e0b1bd 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -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(); diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index c10cc44bae19..190d0b6b28cc 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -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) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 18eaefd3cd0c..3a62b6b3c8fd 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -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); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 349d9b46098e..23762187a219 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -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()) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 7f2b55513863..14d03edc81c2 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -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; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index d73580b39908..92790ed7af45 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -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; diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 80e57c84adef..8b4a87fe3858 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -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"); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ca0251e8470d..4db670d4b8da 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -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( diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 041e93da13e4..b9e0fcac4d71 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -798,7 +798,7 @@ repeat: } } - if (symbol__init() < 0) + if (symbol__init(&session->header.env) < 0) goto error; if (argc) { diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index dcd9ebf5a7df..f5874a27b346 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -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; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9ca7a2d03f17..37d2b608d388 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -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; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index df3b1c5ae7b9..48eea6cd2f5b 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -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), diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0ab3ea7f7525..4b0e15c2b2a8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -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); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8a83bd835327..d080b9cf0354 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -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; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 6f8b01bc6033..c6796d22423a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -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) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 443225cb62f7..784ea42ad8cb 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -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; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 009a9d064f11..ac098a3c2a31 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -15,6 +15,7 @@ #include "machine.h" #include "symbol.h" #include "strlist.h" +#include "header.h" #include #include @@ -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 == '.') { diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 196b29104276..b95e3a36d654 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -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); -- cgit v1.2.3 From 52e0283497ccb1e675d56c9499cc2cc5ec271094 Mon Sep 17 00:00:00 2001 From: Taeung Song Date: Wed, 24 Sep 2014 10:33:37 +0900 Subject: perf tools: Modify error code for when perf_session__new() fails Because perf_session__new() can fail for more reasons than just ENOMEM, modify error code(ENOMEM or EINVAL) to -1. Signed-off-by: Taeung Song Acked-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/r/1411522417-9917-1-git-send-email-treeze.taeung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-evlist.c | 2 +- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-report.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 | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index d4da6929597f..be5939418425 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -340,7 +340,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) annotate.session = perf_session__new(&file, false, &annotate.tool); if (annotate.session == NULL) - return -ENOMEM; + return -1; symbol_conf.priv_size = sizeof(struct annotation); symbol_conf.try_vmlinux_path = true; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 190d0b6b28cc..a3ce19f7aebd 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -683,7 +683,7 @@ static int __cmd_diff(void) d->session = perf_session__new(&d->file, false, &tool); if (!d->session) { pr_err("Failed to open %s\n", d->file.path); - ret = -ENOMEM; + ret = -1; goto out_delete; } diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 66e12f55c052..0f93f859b782 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -28,7 +28,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details session = perf_session__new(&file, 0, NULL); if (session == NULL) - return -ENOMEM; + return -1; evlist__for_each(session->evlist, pos) perf_evsel__fprintf(pos, details, stdout); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 3a62b6b3c8fd..de99ca1bb942 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -460,7 +460,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) file.path = inject.input_name; inject.session = perf_session__new(&file, true, &inject.tool); if (inject.session == NULL) - return -ENOMEM; + return -1; if (symbol__init(&inject.session->header.env) < 0) return -1; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 23762187a219..f295141025bc 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -698,7 +698,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) session = perf_session__new(&file, false, &perf_kmem); if (session == NULL) - return -ENOMEM; + return -1; symbol__init(&session->header.env); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 1e639d6265cc..d8bf2271f4ea 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1058,7 +1058,7 @@ static int read_events(struct perf_kvm_stat *kvm) kvm->session = perf_session__new(&file, false, &kvm->tool); if (!kvm->session) { pr_err("Initializing perf session failed\n"); - return -EINVAL; + return -1; } symbol__init(&kvm->session->header.env); @@ -1361,7 +1361,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, */ kvm->session = perf_session__new(&file, false, &kvm->tool); if (kvm->session == NULL) { - err = -ENOMEM; + err = -1; goto out; } kvm->session->evlist = kvm->evlist; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 92790ed7af45..e7ec71589da6 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -862,7 +862,7 @@ static int __cmd_report(bool display_info) session = perf_session__new(&file, false, &eops); if (!session) { pr_err("Initializing perf session failed\n"); - return -ENOMEM; + return -1; } symbol__init(&session->header.env); diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 8b4a87fe3858..24db6ffe2957 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -124,7 +124,7 @@ static int report_raw_events(struct perf_mem *mem) &mem->tool); if (session == NULL) - return -ENOMEM; + return -1; if (mem->cpu_list) { ret = perf_session__cpu_bitmap(session, mem->cpu_list, diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 8c0b3f22412a..ac145fae0521 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -720,7 +720,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) repeat: session = perf_session__new(&file, false, &report.tool); if (session == NULL) - return -ENOMEM; + return -1; if (report.queue_size) { ordered_events__set_alloc_size(&session->ordered_events, diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 02dce9295e2c..b9b9e58a6c39 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1744,7 +1744,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) session = perf_session__new(&file, false, &script.tool); if (session == NULL) - return -ENOMEM; + return -1; if (header || header_only) { perf_session__fprintf_info(session, stdout, show_full_info); diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 48eea6cd2f5b..35b425b6293f 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1605,7 +1605,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) int ret = -EINVAL; if (session == NULL) - return -ENOMEM; + return -1; symbol__init(&session->header.env); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 832fb527ed90..5c16ba2dcf08 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -929,7 +929,7 @@ static int __cmd_top(struct perf_top *top) top->session = perf_session__new(NULL, false, NULL); if (top->session == NULL) - return -ENOMEM; + return -1; machines__set_symbol_filter(&top->session->machines, symbol_filter); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fe39dc620179..c70e69ea1c5d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2250,7 +2250,7 @@ static int trace__replay(struct trace *trace) session = perf_session__new(&file, false, &trace->tool); if (session == NULL) - return -ENOMEM; + return -1; if (symbol__init(&session->header.env) < 0) goto out; -- cgit v1.2.3 From 4ea062ed431d00153af0ac370cb6fef0620e5fa1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 9 Oct 2014 13:13:41 -0300 Subject: perf evsel: Add hists helper Not all tools need a hists instance per perf_evsel, so lets pave the way to remove evsel->hists while leaving a way to access the hists from a specially allocated evsel, one that comes with space at the end where lives the evsel. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jean Pihet Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-qlktkhe31w4mgtbd84035sr2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 8 +++--- tools/perf/builtin-diff.c | 21 ++++++++------- tools/perf/builtin-report.c | 18 +++++++------ tools/perf/builtin-top.c | 55 +++++++++++++++++++++------------------ tools/perf/tests/hists_cumulate.c | 8 +++--- tools/perf/tests/hists_filter.c | 23 ++++++++-------- tools/perf/tests/hists_link.c | 23 ++++++++++------ tools/perf/tests/hists_output.c | 20 +++++++------- tools/perf/ui/browsers/hists.c | 20 ++++++++------ tools/perf/ui/gtk/hists.c | 2 +- tools/perf/util/evsel.h | 5 ++++ tools/perf/util/hist.c | 22 +++++++++------- tools/perf/util/session.c | 4 +-- tools/perf/util/sort.c | 4 +-- 14 files changed, 132 insertions(+), 101 deletions(-) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index be5939418425..c9a119e2113d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -51,6 +51,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, struct addr_location *al, struct perf_annotate *ann) { + struct hists *hists = evsel__hists(evsel); struct hist_entry *he; int ret; @@ -66,13 +67,12 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, return 0; } - he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0, - true); + he = __hists__add_entry(hists, al, NULL, NULL, NULL, 1, 1, 0, true); if (he == NULL) return -ENOMEM; ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); - hists__inc_nr_samples(&evsel->hists, true); + hists__inc_nr_samples(hists, true); return ret; } @@ -225,7 +225,7 @@ static int __cmd_annotate(struct perf_annotate *ann) total_nr_samples = 0; evlist__for_each(session->evlist, pos) { - struct hists *hists = &pos->hists; + struct hists *hists = evsel__hists(pos); u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; if (nr_samples > 0) { diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index a3ce19f7aebd..8c5c11ca8c53 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -327,6 +327,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, struct machine *machine) { struct addr_location al; + struct hists *hists = evsel__hists(evsel); if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { pr_warning("problem processing %d event, skipping it.\n", @@ -334,7 +335,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, return -1; } - if (hists__add_entry(&evsel->hists, &al, sample->period, + if (hists__add_entry(hists, &al, sample->period, sample->weight, sample->transaction)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; @@ -346,9 +347,9 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, * hists__output_resort() and precompute needs the total * period in order to sort entries by percentage delta. */ - evsel->hists.stats.total_period += sample->period; + hists->stats.total_period += sample->period; if (!al.filtered) - evsel->hists.stats.total_non_filtered_period += sample->period; + hists->stats.total_non_filtered_period += sample->period; return 0; } @@ -382,7 +383,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist) struct perf_evsel *evsel; evlist__for_each(evlist, evsel) { - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); hists__collapse_resort(hists, NULL); } @@ -631,24 +632,26 @@ static void data_process(void) bool first = true; evlist__for_each(evlist_base, evsel_base) { + struct hists *hists_base = evsel__hists(evsel_base); struct data__file *d; int i; data__for_each_file_new(i, d) { struct perf_evlist *evlist = d->session->evlist; struct perf_evsel *evsel; + struct hists *hists; evsel = evsel_match(evsel_base, evlist); if (!evsel) continue; - d->hists = &evsel->hists; + hists = evsel__hists(evsel); + d->hists = hists; - hists__match(&evsel_base->hists, &evsel->hists); + hists__match(hists_base, hists); if (!show_baseline_only) - hists__link(&evsel_base->hists, - &evsel->hists); + hists__link(hists_base, hists); } fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", @@ -659,7 +662,7 @@ static void data_process(void) if (verbose || data__files_cnt > 2) data__fprintf(); - hists__process(&evsel_base->hists); + hists__process(hists_base); } } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index ac145fae0521..3750d635f0f7 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -288,12 +288,14 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report evname = buf; for_each_group_member(pos, evsel) { + const struct hists *pos_hists = evsel__hists(pos); + if (symbol_conf.filter_relative) { - nr_samples += pos->hists.stats.nr_non_filtered_samples; - nr_events += pos->hists.stats.total_non_filtered_period; + nr_samples += pos_hists->stats.nr_non_filtered_samples; + nr_events += pos_hists->stats.total_non_filtered_period; } else { - nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; - nr_events += pos->hists.stats.total_period; + nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; + nr_events += pos_hists->stats.total_period; } } } @@ -318,7 +320,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, struct perf_evsel *pos; evlist__for_each(evlist, pos) { - struct hists *hists = &pos->hists; + struct hists *hists = evsel__hists(pos); const char *evname = perf_evsel__name(pos); if (symbol_conf.event_group && @@ -427,7 +429,7 @@ static void report__collapse_hists(struct report *rep) ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); evlist__for_each(rep->session->evlist, pos) { - struct hists *hists = &pos->hists; + struct hists *hists = evsel__hists(pos); if (pos->idx == 0) hists->symbol_filter_str = rep->symbol_filter_str; @@ -437,7 +439,7 @@ static void report__collapse_hists(struct report *rep) /* Non-group events are considered as leader */ if (symbol_conf.event_group && !perf_evsel__is_group_leader(pos)) { - struct hists *leader_hists = &pos->leader->hists; + struct hists *leader_hists = evsel__hists(pos->leader); hists__match(leader_hists, hists); hists__link(leader_hists, hists); @@ -500,7 +502,7 @@ static int __cmd_report(struct report *rep) } evlist__for_each(session->evlist, pos) - hists__output_resort(&pos->hists); + hists__output_resort(evsel__hists(pos)); return report__browse_hists(rep); } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index fc3d55f832ac..8ab9716db593 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -251,6 +251,7 @@ static void perf_top__print_sym_table(struct perf_top *top) char bf[160]; int printed = 0; const int win_width = top->winsize.ws_col - 1; + struct hists *hists = evsel__hists(top->sym_evsel); puts(CONSOLE_CLEAR); @@ -261,13 +262,13 @@ static void perf_top__print_sym_table(struct perf_top *top) printf("%-*.*s\n", win_width, win_width, graph_dotted_line); - if (top->sym_evsel->hists.stats.nr_lost_warned != - top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]) { - top->sym_evsel->hists.stats.nr_lost_warned = - top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]; + if (hists->stats.nr_lost_warned != + hists->stats.nr_events[PERF_RECORD_LOST]) { + hists->stats.nr_lost_warned = + hists->stats.nr_events[PERF_RECORD_LOST]; color_fprintf(stdout, PERF_COLOR_RED, "WARNING: LOST %d chunks, Check IO/CPU overload", - top->sym_evsel->hists.stats.nr_lost_warned); + hists->stats.nr_lost_warned); ++printed; } @@ -277,21 +278,18 @@ static void perf_top__print_sym_table(struct perf_top *top) } if (top->zero) { - hists__delete_entries(&top->sym_evsel->hists); + hists__delete_entries(hists); } else { - hists__decay_entries(&top->sym_evsel->hists, - top->hide_user_symbols, + hists__decay_entries(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__collapse_resort(hists, NULL); + hists__output_resort(hists); - hists__output_recalc_col_len(&top->sym_evsel->hists, - top->print_entries - printed); + hists__output_recalc_col_len(hists, top->print_entries - printed); putchar('\n'); - hists__fprintf(&top->sym_evsel->hists, false, - top->print_entries - printed, win_width, + hists__fprintf(hists, false, top->print_entries - printed, win_width, top->min_percent, stdout); } @@ -334,6 +332,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg) { char *buf = malloc(0), *p; struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL; + struct hists *hists = evsel__hists(top->sym_evsel); struct rb_node *next; size_t dummy = 0; @@ -351,7 +350,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg) if (p) *p = 0; - next = rb_first(&top->sym_evsel->hists.entries); + next = rb_first(&hists->entries); while (next) { n = rb_entry(next, struct hist_entry, rb_node); if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) { @@ -538,21 +537,24 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) static void perf_top__sort_new_samples(void *arg) { struct perf_top *t = arg; + struct hists *hists; + perf_top__reset_sample_counters(t); if (t->evlist->selected != NULL) t->sym_evsel = t->evlist->selected; + hists = evsel__hists(t->sym_evsel); + if (t->zero) { - hists__delete_entries(&t->sym_evsel->hists); + hists__delete_entries(hists); } else { - hists__decay_entries(&t->sym_evsel->hists, - t->hide_user_symbols, + hists__decay_entries(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__collapse_resort(hists, NULL); + hists__output_resort(hists); } static void *display_thread_tui(void *arg) @@ -573,8 +575,10 @@ static void *display_thread_tui(void *arg) * Zooming in/out UIDs. For now juse use whatever the user passed * via --uid. */ - evlist__for_each(top->evlist, pos) - pos->hists.uid_filter_str = top->record_opts.target.uid_str; + evlist__for_each(top->evlist, pos) { + struct hists *hists = evsel__hists(pos); + hists->uid_filter_str = top->record_opts.target.uid_str; + } perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent, &top->session->header.env); @@ -768,6 +772,7 @@ static void perf_event__process_sample(struct perf_tool *tool, } if (al.sym == NULL || !al.sym->ignore) { + struct hists *hists = evsel__hists(evsel); struct hist_entry_iter iter = { .add_entry_cb = hist_iter__top_callback, }; @@ -777,14 +782,14 @@ static void perf_event__process_sample(struct perf_tool *tool, else iter.ops = &hist_iter_normal; - pthread_mutex_lock(&evsel->hists.lock); + pthread_mutex_lock(&hists->lock); err = hist_entry_iter__add(&iter, &al, evsel, sample, top->max_stack, top); if (err < 0) pr_err("Problem incrementing symbol period, skipping event\n"); - pthread_mutex_unlock(&evsel->hists.lock); + pthread_mutex_unlock(&hists->lock); } return; @@ -849,7 +854,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) perf_event__process_sample(&top->tool, event, evsel, &sample, machine); } else if (event->header.type < PERF_RECORD_MAX) { - hists__inc_nr_events(&evsel->hists, event->header.type); + hists__inc_nr_events(evsel__hists(evsel), event->header.type); machine__process_event(machine, event, &sample); } else ++session->stats.nr_unknown_events; diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 0ac240db2e24..614d5c4978ab 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -245,7 +245,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec static int test1(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); /* * expected output: * @@ -295,7 +295,7 @@ out: static int test2(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); /* * expected output: * @@ -442,7 +442,7 @@ out: static int test3(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); /* * expected output: * @@ -498,7 +498,7 @@ out: static int test4(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); /* * expected output: * diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 821f581fd930..5a31787cc6b9 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -66,11 +66,12 @@ static int add_hist_entries(struct perf_evlist *evlist, .ops = &hist_iter_normal, .hide_unresolved = false, }; + struct hists *hists = evsel__hists(evsel); /* make sure it has no filter at first */ - evsel->hists.thread_filter = NULL; - evsel->hists.dso_filter = NULL; - evsel->hists.symbol_filter_str = NULL; + hists->thread_filter = NULL; + hists->dso_filter = NULL; + hists->symbol_filter_str = NULL; sample.pid = fake_samples[i].pid; sample.tid = fake_samples[i].pid; @@ -134,7 +135,7 @@ int test__hists_filter(void) goto out; evlist__for_each(evlist, evsel) { - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); hists__collapse_resort(hists, NULL); hists__output_resort(hists); @@ -160,7 +161,7 @@ int test__hists_filter(void) hists->stats.total_non_filtered_period); /* now applying thread filter for 'bash' */ - evsel->hists.thread_filter = fake_samples[9].thread; + hists->thread_filter = fake_samples[9].thread; hists__filter_by_thread(hists); if (verbose > 2) { @@ -185,11 +186,11 @@ int test__hists_filter(void) hists->stats.total_non_filtered_period == 400); /* remove thread filter first */ - evsel->hists.thread_filter = NULL; + hists->thread_filter = NULL; hists__filter_by_thread(hists); /* now applying dso filter for 'kernel' */ - evsel->hists.dso_filter = fake_samples[0].map->dso; + hists->dso_filter = fake_samples[0].map->dso; hists__filter_by_dso(hists); if (verbose > 2) { @@ -214,7 +215,7 @@ int test__hists_filter(void) hists->stats.total_non_filtered_period == 300); /* remove dso filter first */ - evsel->hists.dso_filter = NULL; + hists->dso_filter = NULL; hists__filter_by_dso(hists); /* @@ -224,7 +225,7 @@ int test__hists_filter(void) * be counted as a separate entry but the sample count and * total period will be remained. */ - evsel->hists.symbol_filter_str = "main"; + hists->symbol_filter_str = "main"; hists__filter_by_symbol(hists); if (verbose > 2) { @@ -249,8 +250,8 @@ int test__hists_filter(void) hists->stats.total_non_filtered_period == 300); /* now applying all filters at once. */ - evsel->hists.thread_filter = fake_samples[1].thread; - evsel->hists.dso_filter = fake_samples[1].map->dso; + hists->thread_filter = fake_samples[1].thread; + hists->dso_filter = fake_samples[1].map->dso; hists__filter_by_thread(hists); hists__filter_by_dso(hists); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index d4b34b0f50a2..278ba8344c23 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -73,6 +73,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) * "bash [libc] malloc" so total 9 entries will be in the tree. */ evlist__for_each(evlist, evsel) { + struct hists *hists = evsel__hists(evsel); + for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { const union perf_event event = { .header = { @@ -87,7 +89,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) &sample) < 0) goto out; - he = __hists__add_entry(&evsel->hists, &al, NULL, + he = __hists__add_entry(hists, &al, NULL, NULL, NULL, 1, 1, 0, true); if (he == NULL) goto out; @@ -111,7 +113,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) &sample) < 0) goto out; - he = __hists__add_entry(&evsel->hists, &al, NULL, + he = __hists__add_entry(hists, &al, NULL, NULL, NULL, 1, 1, 0, true); if (he == NULL) goto out; @@ -271,6 +273,7 @@ static int validate_link(struct hists *leader, struct hists *other) int test__hists_link(void) { int err = -1; + struct hists *hists, *first_hists; struct machines machines; struct machine *machine = NULL; struct perf_evsel *evsel, *first; @@ -306,24 +309,28 @@ int test__hists_link(void) goto out; evlist__for_each(evlist, evsel) { - hists__collapse_resort(&evsel->hists, NULL); + hists = evsel__hists(evsel); + hists__collapse_resort(hists, NULL); if (verbose > 2) - print_hists_in(&evsel->hists); + print_hists_in(hists); } first = perf_evlist__first(evlist); evsel = perf_evlist__last(evlist); + first_hists = evsel__hists(first); + hists = evsel__hists(evsel); + /* match common entries */ - hists__match(&first->hists, &evsel->hists); - err = validate_match(&first->hists, &evsel->hists); + hists__match(first_hists, hists); + err = validate_match(first_hists, hists); if (err) goto out; /* link common and/or dummy entries */ - hists__link(&first->hists, &evsel->hists); - err = validate_link(&first->hists, &evsel->hists); + hists__link(first_hists, hists); + err = validate_link(first_hists, hists); if (err) goto out; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index e3bbd6c54c1b..a748f2be1222 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -122,7 +122,7 @@ typedef int (*test_fn_t)(struct perf_evsel *, struct machine *); static int test1(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); struct hist_entry *he; struct rb_root *root; struct rb_node *node; @@ -159,7 +159,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine) print_hists_out(hists); } - root = &evsel->hists.entries; + root = &hists->entries; node = rb_first(root); he = rb_entry(node, struct hist_entry, rb_node); TEST_ASSERT_VAL("Invalid hist entry", @@ -224,7 +224,7 @@ out: static int test2(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); struct hist_entry *he; struct rb_root *root; struct rb_node *node; @@ -259,7 +259,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine) print_hists_out(hists); } - root = &evsel->hists.entries; + root = &hists->entries; node = rb_first(root); he = rb_entry(node, struct hist_entry, rb_node); TEST_ASSERT_VAL("Invalid hist entry", @@ -280,7 +280,7 @@ out: static int test3(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); struct hist_entry *he; struct rb_root *root; struct rb_node *node; @@ -313,7 +313,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) print_hists_out(hists); } - root = &evsel->hists.entries; + root = &hists->entries; node = rb_first(root); he = rb_entry(node, struct hist_entry, rb_node); TEST_ASSERT_VAL("Invalid hist entry", @@ -354,7 +354,7 @@ out: static int test4(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); struct hist_entry *he; struct rb_root *root; struct rb_node *node; @@ -391,7 +391,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) print_hists_out(hists); } - root = &evsel->hists.entries; + root = &hists->entries; node = rb_first(root); he = rb_entry(node, struct hist_entry, rb_node); TEST_ASSERT_VAL("Invalid hist entry", @@ -456,7 +456,7 @@ out: static int test5(struct perf_evsel *evsel, struct machine *machine) { int err; - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); struct hist_entry *he; struct rb_root *root; struct rb_node *node; @@ -494,7 +494,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine) print_hists_out(hists); } - root = &evsel->hists.entries; + root = &hists->entries; node = rb_first(root); he = rb_entry(node, struct hist_entry, rb_node); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 8f60a970404f..68eab9ea1634 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1229,12 +1229,14 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) ev_name = buf; for_each_group_member(pos, evsel) { + struct hists *pos_hists = evsel__hists(pos); + if (symbol_conf.filter_relative) { - nr_samples += pos->hists.stats.nr_non_filtered_samples; - nr_events += pos->hists.stats.total_non_filtered_period; + nr_samples += pos_hists->stats.nr_non_filtered_samples; + nr_events += pos_hists->stats.total_non_filtered_period; } else { - nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; - nr_events += pos->hists.stats.total_period; + nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; + nr_events += pos_hists->stats.total_period; } } } @@ -1387,7 +1389,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, float min_pcnt, struct perf_session_env *env) { - struct hists *hists = &evsel->hists; + struct hists *hists = evsel__hists(evsel); struct hist_browser *browser = hist_browser__new(hists); struct branch_info *bi; struct pstack *fstack; @@ -1802,8 +1804,9 @@ static void perf_evsel_menu__write(struct ui_browser *browser, struct perf_evsel_menu *menu = container_of(browser, struct perf_evsel_menu, b); struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); + struct hists *hists = evsel__hists(evsel); bool current_entry = ui_browser__is_current_entry(browser, row); - unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; + unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE]; const char *ev_name = perf_evsel__name(evsel); char bf[256], unit; const char *warn = " "; @@ -1818,7 +1821,8 @@ static void perf_evsel_menu__write(struct ui_browser *browser, ev_name = perf_evsel__group_name(evsel); for_each_group_member(pos, evsel) { - nr_events += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; + struct hists *pos_hists = evsel__hists(pos); + nr_events += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; } } @@ -1827,7 +1831,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, unit, unit == ' ' ? "" : " ", ev_name); slsmg_printf("%s", bf); - nr_events = evsel->hists.stats.nr_events[PERF_RECORD_LOST]; + nr_events = hists->stats.nr_events[PERF_RECORD_LOST]; if (nr_events != 0) { menu->lost_events = true; if (!current_entry) diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index f3fa4258b256..fc654fb77ace 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -319,7 +319,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, gtk_container_add(GTK_CONTAINER(window), vbox); evlist__for_each(evlist, pos) { - struct hists *hists = &pos->hists; + struct hists *hists = evsel__hists(pos); const char *evname = perf_evsel__name(pos); GtkWidget *scrolled_window; GtkWidget *tab_label; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 7bc314be6a7b..ff72ce058724 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -102,6 +102,11 @@ union u64_swap { #define hists_to_evsel(h) container_of(h, struct perf_evsel, hists) +static inline struct hists *evsel__hists(struct perf_evsel *evsel) +{ + return &evsel->hists; +} + struct cpu_map; struct thread_map; struct perf_evlist; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index b47595697140..f72ad9c36e39 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -509,6 +509,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al { u64 cost; struct mem_info *mi = iter->priv; + struct hists *hists = evsel__hists(iter->evsel); struct hist_entry *he; if (mi == NULL) @@ -525,7 +526,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al * and this is indirectly achieved by passing period=weight here * and the he_stat__add_period() function. */ - he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi, + he = __hists__add_entry(hists, al, iter->parent, NULL, mi, cost, cost, 0, true); if (!he) return -ENOMEM; @@ -539,13 +540,14 @@ iter_finish_mem_entry(struct hist_entry_iter *iter, struct addr_location *al __maybe_unused) { struct perf_evsel *evsel = iter->evsel; + struct hists *hists = evsel__hists(evsel); struct hist_entry *he = iter->he; int err = -EINVAL; if (he == NULL) goto out; - hists__inc_nr_samples(&evsel->hists, he->filtered); + hists__inc_nr_samples(hists, he->filtered); err = hist_entry__append_callchain(he, iter->sample); @@ -611,6 +613,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a { struct branch_info *bi; struct perf_evsel *evsel = iter->evsel; + struct hists *hists = evsel__hists(evsel); struct hist_entry *he = NULL; int i = iter->curr; int err = 0; @@ -624,12 +627,12 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a * The report shows the percentage of total branches captured * and not events sampled. Thus we use a pseudo period of 1. */ - he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL, + he = __hists__add_entry(hists, al, iter->parent, &bi[i], NULL, 1, 1, 0, true); if (he == NULL) return -ENOMEM; - hists__inc_nr_samples(&evsel->hists, he->filtered); + hists__inc_nr_samples(hists, he->filtered); out: iter->he = he; @@ -661,7 +664,7 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location struct perf_sample *sample = iter->sample; struct hist_entry *he; - he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, + he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL, sample->period, sample->weight, sample->transaction, true); if (he == NULL) @@ -684,7 +687,7 @@ iter_finish_normal_entry(struct hist_entry_iter *iter, iter->he = NULL; - hists__inc_nr_samples(&evsel->hists, he->filtered); + hists__inc_nr_samples(evsel__hists(evsel), he->filtered); return hist_entry__append_callchain(he, sample); } @@ -717,12 +720,13 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter, struct addr_location *al) { struct perf_evsel *evsel = iter->evsel; + struct hists *hists = evsel__hists(evsel); struct perf_sample *sample = iter->sample; struct hist_entry **he_cache = iter->priv; struct hist_entry *he; int err = 0; - he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, + he = __hists__add_entry(hists, al, iter->parent, NULL, NULL, sample->period, sample->weight, sample->transaction, true); if (he == NULL) @@ -739,7 +743,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter, */ callchain_cursor_commit(&callchain_cursor); - hists__inc_nr_samples(&evsel->hists, he->filtered); + hists__inc_nr_samples(hists, he->filtered); return err; } @@ -795,7 +799,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter, } } - he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, + he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL, sample->period, sample->weight, sample->transaction, false); if (he == NULL) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 883406f4b381..1d423548862f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -827,7 +827,7 @@ int perf_session__deliver_event(struct perf_session *session, * future probably it'll be a good idea to restrict event * processing via perf_session to files with both set. */ - hists__inc_nr_events(&evsel->hists, event->header.type); + hists__inc_nr_events(evsel__hists(evsel), event->header.type); } machine = perf_session__find_machine_for_cpumode(session, event, @@ -1398,7 +1398,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) evlist__for_each(session->evlist, pos) { ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); - ret += events_stats__fprintf(&pos->hists.stats, fp); + ret += events_stats__fprintf(&evsel__hists(pos)->stats, fp); } return ret; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 289df9d1e65a..4906cd81cb56 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1218,7 +1218,7 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, hse = container_of(fmt, struct hpp_sort_entry, hpp); if (!len) - len = hists__col_len(&evsel->hists, hse->se->se_width_idx); + len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx); return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name); } @@ -1233,7 +1233,7 @@ static int __sort__hpp_width(struct perf_hpp_fmt *fmt, hse = container_of(fmt, struct hpp_sort_entry, hpp); if (!len) - len = hists__col_len(&evsel->hists, hse->se->se_width_idx); + len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx); return len; } -- cgit v1.2.3 From 9ab1f50876dbb8b962db058259be7aae920d4c25 Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Wed, 22 Oct 2014 15:02:41 -0400 Subject: perf diff: Add missing hists__init() call at tool start It also uses hists/hist_entries, hists__init() should be called before creating any evsels. Otherwise no extra space will be allocated per perf_evsel nor this space will be initialized when allocating a new perf_evsel instance, resulting in reads/writes to non allocated space, oops. Fix it. Signed-off-by: Kan Liang Link: http://lkml.kernel.org/r/1414004561-22096-1-git-send-email-kan.liang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 8c5c11ca8c53..25114c9a6801 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -1142,6 +1142,11 @@ static int data_init(int argc, const char **argv) int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) { + int ret = hists__init(); + + if (ret < 0) + return ret; + perf_config(perf_default_config, NULL); argc = parse_options(argc, argv, options, diff_usage, 0); -- cgit v1.2.3 From 68ca9d65b88420c2c97948a0640bad13405129e7 Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Tue, 18 Nov 2014 11:38:18 -0500 Subject: perf diff: Add missing handler for PERF_RECORD_MMAP2 events Without mmap2, perf diff fails to find the symbol name. The default symbol sort key doesn't work well. Signed-off-by: Kan Liang Acked-by: Namhyung Kim Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/r/1416328700-1836-2-git-send-email-kan.liang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 25114c9a6801..1ce425d101a9 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -357,6 +357,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, static struct perf_tool tool = { .sample = diff__process_sample_event, .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, .exit = perf_event__process_exit, .fork = perf_event__process_fork, -- cgit v1.2.3 From 740b97f9509ac5a015278940747178af4eb0900d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 22 Dec 2014 13:44:10 +0900 Subject: perf report: Show progress bar for output resorting Sometimes it takes a long time to resort hist entries for output in case of a large data file. Show a progress bar window and inform user. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1419223455-4362-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-report.c | 24 ++++++++++++++++++++++-- tools/perf/builtin-top.c | 4 ++-- tools/perf/tests/hists_cumulate.c | 2 +- tools/perf/tests/hists_filter.c | 2 +- tools/perf/tests/hists_output.c | 10 +++++----- tools/perf/util/hist.c | 10 +++++++++- tools/perf/util/hist.h | 2 +- 9 files changed, 43 insertions(+), 15 deletions(-) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e7417fe97a97..747f86103599 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -232,7 +232,7 @@ static int __cmd_annotate(struct perf_annotate *ann) if (nr_samples > 0) { total_nr_samples += nr_samples; hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (symbol_conf.event_group && !perf_evsel__is_group_leader(pos)) diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 1ce425d101a9..303c1e151dcf 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -605,7 +605,7 @@ static void hists__process(struct hists *hists) hists__precompute(hists); hists__compute_resort(hists); } else { - hists__output_resort(hists); + hists__output_resort(hists, NULL); } hists__fprintf(hists, true, 0, 0, 0, stdout); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 39367609c707..072ae8ad67fc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -457,6 +457,19 @@ static void report__collapse_hists(struct report *rep) ui_progress__finish(); } +static void report__output_resort(struct report *rep) +{ + struct ui_progress prog; + struct perf_evsel *pos; + + ui_progress__init(&prog, rep->nr_entries, "Sorting events for output..."); + + evlist__for_each(rep->session->evlist, pos) + hists__output_resort(evsel__hists(pos), &prog); + + ui_progress__finish(); +} + static int __cmd_report(struct report *rep) { int ret; @@ -505,13 +518,20 @@ static int __cmd_report(struct report *rep) if (session_done()) return 0; + /* + * recalculate number of entries after collapsing since it + * might be changed during the collapse phase. + */ + rep->nr_entries = 0; + evlist__for_each(session->evlist, pos) + rep->nr_entries += evsel__hists(pos)->nr_entries; + if (rep->nr_entries == 0) { ui__error("The %s file has no samples!\n", file->path); return 0; } - evlist__for_each(session->evlist, pos) - hists__output_resort(evsel__hists(pos)); + report__output_resort(rep); return report__browse_hists(rep); } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0aa7747ff139..961cea183a83 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -285,7 +285,7 @@ static void perf_top__print_sym_table(struct perf_top *top) } hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); hists__output_recalc_col_len(hists, top->print_entries - printed); putchar('\n'); @@ -554,7 +554,7 @@ static void perf_top__sort_new_samples(void *arg) } hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); } static void *display_thread_tui(void *arg) diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 614d5c4978ab..4b8226e19a91 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -187,7 +187,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec * function since TEST_ASSERT_VAL() returns in case of failure. */ hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (verbose > 2) { pr_info("use callchain: %d, cumulate callchain: %d\n", diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 74f257a81265..59e53db7914c 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -138,7 +138,7 @@ int test__hists_filter(void) struct hists *hists = evsel__hists(evsel); hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (verbose > 2) { pr_info("Normal histogram\n"); diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index a748f2be1222..f5547610da02 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -152,7 +152,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine) goto out; hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (verbose > 2) { pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); @@ -252,7 +252,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine) goto out; hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (verbose > 2) { pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); @@ -306,7 +306,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) goto out; hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (verbose > 2) { pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); @@ -384,7 +384,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) goto out; hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (verbose > 2) { pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); @@ -487,7 +487,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine) goto out; hists__collapse_resort(hists, NULL); - hists__output_resort(hists); + hists__output_resort(hists, NULL); if (verbose > 2) { pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6e88b9e395df..1cc6ea4b7065 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -6,6 +6,7 @@ #include "evlist.h" #include "evsel.h" #include "annotate.h" +#include "ui/progress.h" #include static bool hists__filter_entry_by_dso(struct hists *hists, @@ -987,6 +988,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused, else p = &(*p)->rb_right; } + hists->nr_entries++; rb_link_node(&he->rb_node_in, parent, p); rb_insert_color(&he->rb_node_in, root); @@ -1024,7 +1026,10 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) if (!sort__need_collapse) return; + hists->nr_entries = 0; + root = hists__get_rotate_entries_in(hists); + next = rb_first(root); while (next) { @@ -1119,7 +1124,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, rb_insert_color(&he->rb_node, entries); } -void hists__output_resort(struct hists *hists) +void hists__output_resort(struct hists *hists, struct ui_progress *prog) { struct rb_root *root; struct rb_node *next; @@ -1148,6 +1153,9 @@ void hists__output_resort(struct hists *hists) if (!n->filtered) hists__calc_col_len(hists, n); + + if (prog) + ui_progress__update(prog, 1); } } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index d0ef9a19a744..46bd50344f85 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -121,7 +121,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size, struct hists *hists); void hist_entry__free(struct hist_entry *); -void hists__output_resort(struct hists *hists); +void hists__output_resort(struct hists *hists, struct ui_progress *prog); void hists__collapse_resort(struct hists *hists, struct ui_progress *prog); void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); -- cgit v1.2.3 From e7024fc3783317608b8e07048116a72a7d1cd26d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sat, 27 Dec 2014 14:06:29 +0900 Subject: perf diff: Fix to sort by baseline field by default The currently perf diff didn't add the baseline and delta (or other compute) fields to the sort list so output will be sorted by other fields like alphabetical order of DSO or symbol as below example. Fix it by adding hpp formats for the fields and provides default compare functions. Before: $ perf diff # Event 'cycles' # # Baseline Delta Shared Object Symbol # ........ ....... .................. ............................... # [bridge] [k] ip_sabotage_in [btrfs] [k] __etree_search.constprop.47 0.01% [btrfs] [k] btrfs_file_mmap 0.01% -0.01% [btrfs] [k] btrfs_getattr [e1000e] [k] e1000_watchdog 0.00% [kernel.vmlinux] [k] PageHuge 0.00% [kernel.vmlinux] [k] __acct_update_integrals 0.00% [kernel.vmlinux] [k] __activate_page [kernel.vmlinux] [k] __alloc_fd 0.02% +0.02% [kernel.vmlinux] [k] __alloc_pages_nodemask ... After: # Baseline Delta Shared Object Symbol # ........ ....... .................. ................................ # 24.73% -4.62% perf [.] append_chain_children 7.96% -1.29% perf [.] dso__find_symbol 6.97% -2.07% libc-2.20.so [.] vfprintf 4.61% +0.88% libc-2.20.so [.] __fprintf_chk 4.41% +2.43% perf [.] sort__comm_cmp 4.10% -0.16% perf [.] comm__str 4.03% -0.93% perf [.] machine__findnew_thread_time 3.82% +3.09% perf [.] __hists__add_entry 2.95% -0.18% perf [.] sort__dso_cmp ... Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1419656793-32756-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'tools/perf/builtin-diff.c') diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 303c1e151dcf..1fd96c13f199 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -545,6 +545,42 @@ hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right, return __hist_entry__cmp_compute(p_left, p_right, c); } +static int64_t +hist_entry__cmp_nop(struct hist_entry *left __maybe_unused, + struct hist_entry *right __maybe_unused) +{ + return 0; +} + +static int64_t +hist_entry__cmp_baseline(struct hist_entry *left, struct hist_entry *right) +{ + if (sort_compute) + return 0; + + if (left->stat.period == right->stat.period) + return 0; + return left->stat.period > right->stat.period ? 1 : -1; +} + +static int64_t +hist_entry__cmp_delta(struct hist_entry *left, struct hist_entry *right) +{ + return hist_entry__cmp_compute(right, left, COMPUTE_DELTA); +} + +static int64_t +hist_entry__cmp_ratio(struct hist_entry *left, struct hist_entry *right) +{ + return hist_entry__cmp_compute(right, left, COMPUTE_RATIO); +} + +static int64_t +hist_entry__cmp_wdiff(struct hist_entry *left, struct hist_entry *right) +{ + return hist_entry__cmp_compute(right, left, COMPUTE_WEIGHTED_DIFF); +} + static void insert_hist_entry_by_compute(struct rb_root *root, struct hist_entry *he, int c) @@ -1038,27 +1074,35 @@ static void data__hpp_register(struct data__file *d, int idx) fmt->header = hpp__header; fmt->width = hpp__width; fmt->entry = hpp__entry_global; + fmt->cmp = hist_entry__cmp_nop; + fmt->collapse = hist_entry__cmp_nop; /* TODO more colors */ switch (idx) { case PERF_HPP_DIFF__BASELINE: fmt->color = hpp__color_baseline; + fmt->sort = hist_entry__cmp_baseline; break; case PERF_HPP_DIFF__DELTA: fmt->color = hpp__color_delta; + fmt->sort = hist_entry__cmp_delta; break; case PERF_HPP_DIFF__RATIO: fmt->color = hpp__color_ratio; + fmt->sort = hist_entry__cmp_ratio; break; case PERF_HPP_DIFF__WEIGHTED_DIFF: fmt->color = hpp__color_wdiff; + fmt->sort = hist_entry__cmp_wdiff; break; default: + fmt->sort = hist_entry__cmp_nop; break; } init_header(d, dfmt); perf_hpp__column_register(fmt); + perf_hpp__register_sort_field(fmt); } static void ui_init(void) -- cgit v1.2.3