From 5dcf16df3ce48b2e4f798b1a11b5de2fc3cfd73a Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 7 Dec 2015 02:36:25 +0000 Subject: [PATCH 01/14] perf machine: Pass correct string to dso__adjust_kmod_long_name There's a mistake in dso__adjust_kmod_long_name() that it use strdup() to dup the new long_name of a dso, but passes the original string to dso__set_long_name(). Which causes random crash during cleanup. Signed-off-by: Wang Nan Reviewed-by: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com Fixes: c03d5184f0e9 ("perf machine: Adjust dso->long_name for offline module") Link: http://lkml.kernel.org/r/1449455785-42020-1-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 95a7f6087346..bfc289c73c22 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -576,7 +576,7 @@ static void dso__adjust_kmod_long_name(struct dso *dso, const char *filename) if (!dup_filename) return; - dso__set_long_name(dso, filename, true); + dso__set_long_name(dso, dup_filename, true); } struct map *machine__findnew_module_map(struct machine *machine, u64 start, From bdaba8aee5c3806d78ee4f130048b2238c636d47 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 09:34:12 +0100 Subject: [PATCH 02/14] perf test: Use machine__new_host in dwarf unwind test This is more straightforward than what we have now. It also fixes a segfault within machine__exit, that's caused by not creating kernel maps for machine.. We're calling machine__destroy_kernel_maps in machine__exit since commit: ebe9729c8c31 perf machine: Fix to destroy kernel maps when machine exits Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1449131658-1841-2-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/dwarf-unwind.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 3cce13b19cbb..1c5c0221cea2 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -160,14 +160,11 @@ static int krava_1(struct thread *thread) int test__dwarf_unwind(int subtest __maybe_unused) { - struct machines machines; struct machine *machine; struct thread *thread; int err = -1; - machines__init(&machines); - - machine = machines__find(&machines, HOST_KERNEL_ID); + machine = machine__new_host(); if (!machine) { pr_err("Could not get machine\n"); return -1; @@ -199,7 +196,6 @@ int test__dwarf_unwind(int subtest __maybe_unused) out: machine__delete_threads(machine); - machine__exit(machine); - machines__exit(&machines); + machine__delete(machine); return err; } From 046847935754f27c2e8334ff15abda0b733a1fd4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 09:34:13 +0100 Subject: [PATCH 03/14] perf test: Use machine__new_host in mmap thread lookup test This is more straightforward than what we have now. It also fixes a segfault within machine__exit, that's caused by not creating kernel maps for machine.. We're calling machine__destroy_kernel_maps in machine__exit since commit: ebe9729c8c31 perf machine: Fix to destroy kernel maps when machine exits Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: David Ahern Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1449131658-1841-3-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/mmap-thread-lookup.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 6cdb97579c45..0c5ce44f723f 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -149,7 +149,6 @@ static int synth_process(struct machine *machine) static int mmap_events(synth_cb synth) { - struct machines machines; struct machine *machine; int err, i; @@ -162,8 +161,7 @@ static int mmap_events(synth_cb synth) */ TEST_ASSERT_VAL("failed to create threads", !threads_create()); - machines__init(&machines); - machine = &machines.host; + machine = machine__new_host(); dump_trace = verbose > 1 ? 1 : 0; @@ -203,7 +201,7 @@ static int mmap_events(synth_cb synth) } machine__delete_threads(machine); - machines__exit(&machines); + machine__delete(machine); return err; } From 0fd4008ed755c52d85117302a3c2c108b2958420 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 09:34:14 +0100 Subject: [PATCH 04/14] perf test: Use machine__new_host in mmap thread code reading test This is more straightforward than what we have now. It also fixes a segfault within machine__exit, that's caused by not creating kernel maps for machine.. We're calling machine__destroy_kernel_maps in machine__exit since commit: ebe9729c8c31 perf machine: Fix to destroy kernel maps when machine exits Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1449131658-1841-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 4417b6a079f0..26182ffcea75 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -433,7 +433,6 @@ enum { static int do_test_code_reading(bool try_kcore) { - struct machines machines; struct machine *machine; struct thread *thread; struct record_opts opts = { @@ -459,8 +458,7 @@ static int do_test_code_reading(bool try_kcore) pid = getpid(); - machines__init(&machines); - machine = &machines.host; + machine = machine__new_host(); ret = machine__create_kernel_maps(machine); if (ret < 0) { @@ -594,9 +592,8 @@ out_err: cpu_map__put(cpus); thread_map__put(threads); } - machines__destroy_kernel_maps(&machines); machine__delete_threads(machine); - machines__exit(&machines); + machine__delete(machine); return err; } From 7320b1b3d9e6af30adcbead64568be3c40b50e59 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 09:34:15 +0100 Subject: [PATCH 05/14] perf test: Fix cpus and thread maps reference in error path In error path to try user space event, both cpus and threads map now owned by evlist and freed by perf_evlist__set_maps call. Getting reference to keep them alive. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1449131658-1841-5-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 26182ffcea75..313a48c6b2bc 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -547,6 +547,13 @@ static int do_test_code_reading(bool try_kcore) if (ret < 0) { if (!excl_kernel) { excl_kernel = true; + /* + * Both cpus and threads are now owned by evlist + * and will be freed by following perf_evlist__set_maps + * call. Getting refference to keep them alive. + */ + cpu_map__get(cpus); + thread_map__get(threads); perf_evlist__set_maps(evlist, NULL, NULL); perf_evlist__delete(evlist); evlist = NULL; From c0651c41e45dee1d6abb83fd5b25e7097aeac141 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 09:34:16 +0100 Subject: [PATCH 06/14] perf test: Prevent using bpf-output event in round trip name test The bpf-output is added under software events, but is not parse-able within parse_events, which is what round trip test is expecting. Checking software events only until dummy event. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: David Ahern Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1449131658-1841-6-git-send-email-jolsa@kernel.org [ Make it a one liner by keeping __perf_evsel__name_array_test() around ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/evsel-roundtrip-name.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 1da92e1159ee..2de4a4f2c3ed 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -103,7 +103,8 @@ int test__perf_evsel__roundtrip_name_test(int subtest __maybe_unused) if (err) ret = err; - err = perf_evsel__name_array_test(perf_evsel__sw_names); + err = __perf_evsel__name_array_test(perf_evsel__sw_names, + PERF_COUNT_SW_DUMMY + 1); if (err) ret = err; From d6e94fa6b6dab4668e46665bbe766142af32cc15 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 2 Dec 2015 22:08:29 +0100 Subject: [PATCH 07/14] perf test: Create kernel maps properly for hist entries test It fixes segfault within machine__exit, that's caused but not creating kernel maps for machine.. We're calling machine__destroy_kernel_maps in machine__exit since commit: ebe9729c8c31 perf machine: Fix to destroy kernel maps when machine exits Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: David Ahern Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/tip-k4snzv5t4dvdckggzwdzyljo@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/hists_common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index ce80b274b097..46f453b1de60 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -87,6 +87,11 @@ struct machine *setup_fake_machine(struct machines *machines) return NULL; } + if (machine__create_kernel_maps(machine)) { + pr_debug("Not enough memory for machine setup\n"); + goto out; + } + for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { struct thread *thread; From 5cd95fc3f8d84a8bb256838fa3b6b59e9095eaa2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 10:06:40 +0100 Subject: [PATCH 08/14] perf evsel: Use event maps directly in perf_evsel__enable All events now share proper cpu and thread maps. There's no need to pass those maps from evlist, it's safe to use evsel maps for enabling event. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1449133606-14429-2-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 5 +---- tools/perf/util/evsel.c | 5 ++++- tools/perf/util/evsel.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index df2fbf046ee2..813c52ad9303 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -256,12 +256,9 @@ static void handle_initial_delay(void) struct perf_evsel *counter; if (initial_delay) { - const int ncpus = cpu_map__nr(evsel_list->cpus), - nthreads = thread_map__nr(evsel_list->threads); - usleep(initial_delay * 1000); evlist__for_each(evsel_list, counter) - perf_evsel__enable(counter, ncpus, nthreads); + perf_evsel__enable(counter); } } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0a1f4d9e52fc..3a9b5068667d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -981,8 +981,11 @@ int perf_evsel__append_filter(struct perf_evsel *evsel, return -1; } -int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads) +int perf_evsel__enable(struct perf_evsel *evsel) { + int nthreads = thread_map__nr(evsel->threads); + int ncpus = cpu_map__nr(evsel->cpus); + return perf_evsel__run_ioctl(evsel, ncpus, nthreads, PERF_EVENT_IOC_ENABLE, 0); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 0e49bd742c63..a721592a3200 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -227,7 +227,7 @@ int perf_evsel__append_filter(struct perf_evsel *evsel, const char *op, const char *filter); int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads, const char *filter); -int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads); +int perf_evsel__enable(struct perf_evsel *evsel); int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus); From e98a4cbb01e0ba1110eba5166a425b3eab9b2244 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 10:06:41 +0100 Subject: [PATCH 09/14] perf evsel: Introduce disable() method Adding perf_evsel__disable function to have complement for perf_evsel__enable function. Both will be used in following patch to factor perf_evlist__(enable|disable). Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1449133606-14429-3-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 10 ++++++++++ tools/perf/util/evsel.h | 1 + 2 files changed, 11 insertions(+) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 3a9b5068667d..47f033089349 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -991,6 +991,16 @@ int perf_evsel__enable(struct perf_evsel *evsel) 0); } +int perf_evsel__disable(struct perf_evsel *evsel) +{ + int nthreads = thread_map__nr(evsel->threads); + int ncpus = cpu_map__nr(evsel->cpus); + + return perf_evsel__run_ioctl(evsel, ncpus, nthreads, + PERF_EVENT_IOC_DISABLE, + 0); +} + int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads) { if (ncpus == 0 || nthreads == 0) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a721592a3200..5ded1fc0341e 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -228,6 +228,7 @@ int perf_evsel__append_filter(struct perf_evsel *evsel, int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads, const char *filter); int perf_evsel__enable(struct perf_evsel *evsel); +int perf_evsel__disable(struct perf_evsel *evsel); int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus); From 3e27c92081131738fa4d7dd71673aa6e8c24866d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 10:06:42 +0100 Subject: [PATCH 10/14] perf evlist: Factor perf_evlist__(enable|disable) functions Use perf_evsel__(enable|disable) functions in perf_evlist__(enable|disable) functions in order to centralize ioctl enable/disable calls. This way we eliminate 2 places calling directly ioctl. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1449133606-14429-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d1392194a9a9..d1b6c206bb93 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -336,20 +336,12 @@ static int perf_evlist__nr_threads(struct perf_evlist *evlist, 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; - 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); - } + evlist__for_each(evlist, pos) { + if (!perf_evsel__is_group_leader(pos) || !pos->fd) + continue; + perf_evsel__disable(pos); } evlist->enabled = false; @@ -357,20 +349,12 @@ void perf_evlist__disable(struct perf_evlist *evlist) 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; - 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); - } + evlist__for_each(evlist, pos) { + if (!perf_evsel__is_group_leader(pos) || !pos->fd) + continue; + perf_evsel__enable(pos); } evlist->enabled = true; From ab46db0a3325a064bb24e826b12995d157565efb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 10:06:43 +0100 Subject: [PATCH 11/14] perf stat: Use perf_evlist__enable in handle_initial_delay No need to mimic the behaviour of perf_evlist__enable, we can use it directly. Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1449133606-14429-5-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 813c52ad9303..8ca40deaa728 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -253,12 +253,9 @@ static void process_interval(void) static void handle_initial_delay(void) { - struct perf_evsel *counter; - if (initial_delay) { usleep(initial_delay * 1000); - evlist__for_each(evsel_list, counter) - perf_evsel__enable(counter); + perf_evlist__enable(evsel_list); } } From 67ccdecd09cac818146b1e153ff901cb67570012 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 10:06:44 +0100 Subject: [PATCH 12/14] perf stat: Create events as disabled Currently we have 2 kinds of stat counters based on when the event is enabled: 1) tracee command events, which are enable once the tracee executes exec syscall (enable_on_exec bit) 2) all other events which get alive within the perf_event_open syscall And 2) case could raise a problem in case we want additional filter to be attached for event. In this case we want the event to be enabled after it's configured with filter. Changing the behaviour of 2) events, so they all are created as disabled (disabled bit). Adding extra enable call to make them alive once they finish setup. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1449133606-14429-6-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 8ca40deaa728..2e70610649a1 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -168,11 +168,18 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) attr->sample_period = 0; attr->sample_type = 0; + /* + * Disabling all counters initially, they will be enabled + * either manually by us or by kernel via enable_on_exec + * set later. + */ + if (perf_evsel__is_group_leader(evsel)) + attr->disabled = 1; + if (target__has_cpu(&target)) return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) { - attr->disabled = 1; if (!initial_delay) attr->enable_on_exec = 1; } @@ -251,12 +258,18 @@ static void process_interval(void) print_counters(&rs, 0, NULL); } -static void handle_initial_delay(void) +static void enable_counters(void) { - if (initial_delay) { + if (initial_delay) usleep(initial_delay * 1000); + + /* + * We need to enable counters only if: + * - we don't have tracee (attaching to task or cpu) + * - we have initial delay configured + */ + if (!target__none(&target) || initial_delay) perf_evlist__enable(evsel_list); - } } static volatile int workload_exec_errno; @@ -353,7 +366,7 @@ static int __run_perf_stat(int argc, const char **argv) if (forks) { perf_evlist__start_workload(evsel_list); - handle_initial_delay(); + enable_counters(); if (interval) { while (!waitpid(child_pid, &status, WNOHANG)) { @@ -372,7 +385,7 @@ static int __run_perf_stat(int argc, const char **argv) if (WIFSIGNALED(status)) psignal(WTERMSIG(status), argv[0]); } else { - handle_initial_delay(); + enable_counters(); while (!done) { nanosleep(&ts, NULL); if (interval) From c8280cec2a196f2ffea83dd755b17eb020ca1b83 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 3 Dec 2015 10:06:45 +0100 Subject: [PATCH 13/14] perf stat: Move enable_on_exec setup under earlier code It's more readable this way and we can save one perf_evsel__is_group_leader condition in current code. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1449133606-14429-7-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2e70610649a1..e74712dee242 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -173,17 +173,20 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) * either manually by us or by kernel via enable_on_exec * set later. */ - if (perf_evsel__is_group_leader(evsel)) + if (perf_evsel__is_group_leader(evsel)) { attr->disabled = 1; + /* + * In case of initial_delay we enable tracee + * events manually. + */ + if (target__none(&target) && !initial_delay) + attr->enable_on_exec = 1; + } + if (target__has_cpu(&target)) return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); - if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) { - if (!initial_delay) - attr->enable_on_exec = 1; - } - return perf_evsel__open_per_thread(evsel, evsel_list->threads); } From cfef25b8daf7e4b49c84e174a904af9d89dc7c46 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 6 Dec 2015 23:07:13 +0000 Subject: [PATCH 14/14] perf annotate: ARM support Add basic support to parse ARM assembly. This: * enables perf to correctly show the disassembly, rather than chopping some constants off at the '#' (which is not a comment character on ARM). * allows perf to identify ARM instructions that branch to other parts within the same function, thereby properly annotating them. * allows perf to identify function calls, allowing called functions to be followed in the annotated view. Signed-off-by: Russell King Cc: Peter Zijlstra Cc: Will Deacon Link: http://lkml.kernel.org/n/tip-owp1uj0nmcgfrlppfyeetuyf@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 1dd1949b0e79..b795b6994144 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -65,6 +65,11 @@ static int call__parse(struct ins_operands *ops) name++; +#ifdef __arm__ + if (strchr(name, '+')) + return -1; +#endif + tok = strchr(name, '>'); if (tok == NULL) return -1; @@ -246,7 +251,11 @@ static int mov__parse(struct ins_operands *ops) return -1; target = ++s; +#ifdef __arm__ + comment = strchr(s, ';'); +#else comment = strchr(s, '#'); +#endif if (comment != NULL) s = comment - 1; @@ -354,6 +363,20 @@ static struct ins instructions[] = { { .name = "addq", .ops = &mov_ops, }, { .name = "addw", .ops = &mov_ops, }, { .name = "and", .ops = &mov_ops, }, +#ifdef __arm__ + { .name = "b", .ops = &jump_ops, }, // might also be a call + { .name = "bcc", .ops = &jump_ops, }, + { .name = "bcs", .ops = &jump_ops, }, + { .name = "beq", .ops = &jump_ops, }, + { .name = "bge", .ops = &jump_ops, }, + { .name = "bgt", .ops = &jump_ops, }, + { .name = "bhi", .ops = &jump_ops, }, + { .name = "bl", .ops = &call_ops, }, + { .name = "blt", .ops = &jump_ops, }, + { .name = "bls", .ops = &jump_ops, }, + { .name = "blx", .ops = &call_ops, }, + { .name = "bne", .ops = &jump_ops, }, +#endif { .name = "bts", .ops = &mov_ops, }, { .name = "call", .ops = &call_ops, }, { .name = "callq", .ops = &call_ops, },