diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-12-08 05:23:09 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-12-08 05:23:09 +0100 |
commit | 803ca41856a26b98150a669290c50adc9bfc648e (patch) | |
tree | 53148198f44c9a68efd82fca60133d0ba4903406 | |
parent | f1ad44884a4c421ceaa9a4a8242aeeee6f686670 (diff) | |
parent | cfef25b8daf7e4b49c84e174a904af9d89dc7c46 (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
User visible changes:
- Fixes and improvements for supporting annotating ARM binaries, support ARM
call and jump instructions, more work needed to have arch specific stuff
separated into tools/perf/arch/*/annotate/ (Russell King)
- Fix several 'perf test' entries broken by recent perf/core changes (Jiri Olsa)
Infrastructure changes:
- Consolidate perf_ev{list,sel}__{enable,disable}() calls (Jiri Olsa)
- Pass correct string to dso__adjust_kmod_long_name() (Wang Nan)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | tools/perf/builtin-stat.c | 44 | ||||
-rw-r--r-- | tools/perf/tests/code-reading.c | 14 | ||||
-rw-r--r-- | tools/perf/tests/dwarf-unwind.c | 8 | ||||
-rw-r--r-- | tools/perf/tests/evsel-roundtrip-name.c | 3 | ||||
-rw-r--r-- | tools/perf/tests/hists_common.c | 5 | ||||
-rw-r--r-- | tools/perf/tests/mmap-thread-lookup.c | 6 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 23 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 32 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 15 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 3 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 2 |
11 files changed, 95 insertions, 60 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index df2fbf046ee2..e74712dee242 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -168,15 +168,25 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) attr->sample_period = 0; attr->sample_type = 0; - 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)) { + /* + * 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 (!initial_delay) + + /* + * 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)); + return perf_evsel__open_per_thread(evsel, evsel_list->threads); } @@ -251,18 +261,18 @@ static void process_interval(void) print_counters(&rs, 0, NULL); } -static void handle_initial_delay(void) +static void enable_counters(void) { - struct perf_evsel *counter; - - if (initial_delay) { - const int ncpus = cpu_map__nr(evsel_list->cpus), - nthreads = thread_map__nr(evsel_list->threads); - + if (initial_delay) usleep(initial_delay * 1000); - evlist__for_each(evsel_list, counter) - perf_evsel__enable(counter, ncpus, nthreads); - } + + /* + * 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; @@ -359,7 +369,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)) { @@ -378,7 +388,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) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 4417b6a079f0..313a48c6b2bc 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) { @@ -549,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; @@ -594,9 +599,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; } 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; } 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; 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; 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; } 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, }, 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; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0a1f4d9e52fc..47f033089349 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -981,13 +981,26 @@ 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); } +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 0e49bd742c63..5ded1fc0341e 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -227,7 +227,8 @@ 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__disable(struct perf_evsel *evsel); int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus); 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, |