From 44848cdbbd1bacbac2a825920b699adc000d51c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Li=C5=A1ka?= Date: Fri, 29 May 2015 14:06:44 +0200 Subject: [PATCH 01/14] perf annotate: Fix -i option, which is currently ignored. Assign input_name, received from program arguments, to file data structure. Signed-off-by: Martin Liska Tested-by: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/55685654.2010209@suse.cz Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index c434e1264087..4e08c2d2090e 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -289,7 +289,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) }, }; struct perf_data_file file = { - .path = input_name, .mode = PERF_DATA_MODE_READ, }; const struct option options[] = { @@ -346,6 +345,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) else if (annotate.use_gtk) use_browser = 2; + file.path = input_name; + setup_browser(true); annotate.session = perf_session__new(&file, false, &annotate.tool); From 60fb7742928dab3c6a0fec7f2d2cce26d9366a3c Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Thu, 28 May 2015 02:25:05 +0000 Subject: [PATCH 02/14] perf probe: Fix 'function unused' warning By 'make build-test' a warning is found in probe-event.c that, after commit 419e873828 (perf probe: Show the error reason comes from invalid DSO) the only user of kernel_get_module_dso() is open_debuginfo(). Which is not compiled if HAVE_DWARF_SUPPORT not set. 'make build-test' found this problem when make_minimal. This patch moves kernel_get_module_dso() to HAVE_DWARF_SUPPORT ifdef section. Signed-off-by: Wang Nan Acked-by: Masami Hiramatsu Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1432779905-206143-1-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 65 ++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index b0b8a8080009..e6a02b1ffd6d 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -200,38 +200,6 @@ static void put_target_map(struct map *map, bool user) } -static int kernel_get_module_dso(const char *module, struct dso **pdso) -{ - struct dso *dso; - struct map *map; - const char *vmlinux_name; - int ret = 0; - - if (module) { - list_for_each_entry(dso, &host_machine->kernel_dsos.head, - node) { - if (strncmp(dso->short_name + 1, module, - dso->short_name_len - 2) == 0) - goto found; - } - pr_debug("Failed to find module %s.\n", module); - return -ENOENT; - } - - map = host_machine->vmlinux_maps[MAP__FUNCTION]; - dso = map->dso; - - vmlinux_name = symbol_conf.vmlinux_name; - dso->load_errno = 0; - if (vmlinux_name) - ret = dso__load_vmlinux(dso, map, vmlinux_name, false, NULL); - else - ret = dso__load_vmlinux_path(dso, map, NULL); -found: - *pdso = dso; - return ret; -} - static int convert_exec_to_group(const char *exec, char **result) { char *ptr1, *ptr2, *exec_copy; @@ -279,6 +247,39 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) } #ifdef HAVE_DWARF_SUPPORT + +static int kernel_get_module_dso(const char *module, struct dso **pdso) +{ + struct dso *dso; + struct map *map; + const char *vmlinux_name; + int ret = 0; + + if (module) { + list_for_each_entry(dso, &host_machine->kernel_dsos.head, + node) { + if (strncmp(dso->short_name + 1, module, + dso->short_name_len - 2) == 0) + goto found; + } + pr_debug("Failed to find module %s.\n", module); + return -ENOENT; + } + + map = host_machine->vmlinux_maps[MAP__FUNCTION]; + dso = map->dso; + + vmlinux_name = symbol_conf.vmlinux_name; + dso->load_errno = 0; + if (vmlinux_name) + ret = dso__load_vmlinux(dso, map, vmlinux_name, false, NULL); + else + ret = dso__load_vmlinux_path(dso, map, NULL); +found: + *pdso = dso; + return ret; +} + /* * Some binaries like glibc have special symbols which are on the symbol * table, but not in the debuginfo. If we can find the address of the From 427cde3287f2c6349f308d0e22c9223f9ea05ef1 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 29 May 2015 16:33:29 +0300 Subject: [PATCH 03/14] perf db-export: Fix thread ref-counting Thread ref-counting was not done for get_main_thread() meaning that there was a thread__get() from machine__find_thread() that was not being paired with thread__put(). Fix that. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1432906425-9911-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/db-export.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index eb7a2acb973b..1c9689e4cc17 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -234,7 +234,7 @@ int db_export__symbol(struct db_export *dbe, struct symbol *sym, static struct thread *get_main_thread(struct machine *machine, struct thread *thread) { if (thread->pid_ == thread->tid) - return thread; + return thread__get(thread); if (thread->pid_ == -1) return NULL; @@ -308,19 +308,18 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, if (err) return err; - /* FIXME: check refcounting for get_main_thread, that calls machine__find_thread... */ main_thread = get_main_thread(al->machine, thread); if (main_thread) comm = machine__thread_exec_comm(al->machine, main_thread); err = db_export__thread(dbe, thread, al->machine, comm); if (err) - return err; + goto out_put; if (comm) { err = db_export__comm(dbe, comm, main_thread); if (err) - return err; + goto out_put; es.comm_db_id = comm->db_id; } @@ -328,7 +327,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, err = db_ids_from_al(dbe, al, &es.dso_db_id, &es.sym_db_id, &es.offset); if (err) - return err; + goto out_put; if ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && sample_addr_correlates_sym(&evsel->attr)) { @@ -338,20 +337,22 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id, &es.addr_sym_db_id, &es.addr_offset); if (err) - return err; + goto out_put; if (dbe->crp) { err = thread_stack__process(thread, comm, sample, al, &addr_al, es.db_id, dbe->crp); if (err) - return err; + goto out_put; } } if (dbe->export_sample) - return dbe->export_sample(dbe, &es); + err = dbe->export_sample(dbe, &es); - return 0; +out_put: + thread__put(main_thread); + return err; } static struct { From b236512280fb96dcca45a3f5bbae1839bd673e58 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 29 May 2015 09:48:13 -0300 Subject: [PATCH 04/14] perf kmem: Fix compiler warning about may be accessing uninitialized variable The last argument to strtok_r doesn't need to be initialized, its just a placeholder to make this routine reentrant, but gcc doesn't know about that and complains, breaking the build, fix it by setting it to NULL. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/n/tip-8e8rgbg3aom9uarsyqjrsctg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 254614b10c4a..950f296dfcf7 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -644,7 +644,7 @@ static char *compact_gfp_flags(char *gfp_flags) { char *orig_flags = strdup(gfp_flags); char *new_flags = NULL; - char *str, *pos; + char *str, *pos = NULL; size_t len = 0; if (orig_flags == NULL) From 3237f28188c3e41a938781a369652772a23e97a9 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Fri, 27 Mar 2015 13:08:01 +0000 Subject: [PATCH 05/14] perf tools: Add ARM64 perf_regs_load to support libunwind and enable testing Newest libunwind does support ARM64, and perf is able to utilize it also. This patch enables the perf test dwarf unwind for arm64. Test result: # ./perf test unwind 25: Test dwarf unwind : Ok Signed-off-by: Wang Nan Acked-by: Jiri Olsa Cc: Namhyung Kim Cc: Zefan Li Link: http://lkml.kernel.org/r/1427461681-72971-1-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/Build | 1 + tools/perf/arch/arm64/include/perf_regs.h | 3 ++ tools/perf/arch/arm64/tests/Build | 2 + tools/perf/arch/arm64/tests/dwarf-unwind.c | 61 ++++++++++++++++++++++ tools/perf/arch/arm64/tests/regs_load.S | 46 ++++++++++++++++ tools/perf/tests/Build | 2 +- tools/perf/tests/builtin-test.c | 2 +- tools/perf/tests/tests.h | 2 +- 8 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 tools/perf/arch/arm64/tests/Build create mode 100644 tools/perf/arch/arm64/tests/dwarf-unwind.c create mode 100644 tools/perf/arch/arm64/tests/regs_load.S diff --git a/tools/perf/arch/arm64/Build b/tools/perf/arch/arm64/Build index 54afe4a467e7..41bf61da476a 100644 --- a/tools/perf/arch/arm64/Build +++ b/tools/perf/arch/arm64/Build @@ -1 +1,2 @@ libperf-y += util/ +libperf-$(CONFIG_DWARF_UNWIND) += tests/ diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h index 1d3f39c3aa56..4e5af27e3fbf 100644 --- a/tools/perf/arch/arm64/include/perf_regs.h +++ b/tools/perf/arch/arm64/include/perf_regs.h @@ -5,8 +5,11 @@ #include #include +void perf_regs_load(u64 *regs); + #define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1) #define PERF_REGS_MAX PERF_REG_ARM64_MAX +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 #define PERF_REG_IP PERF_REG_ARM64_PC #define PERF_REG_SP PERF_REG_ARM64_SP diff --git a/tools/perf/arch/arm64/tests/Build b/tools/perf/arch/arm64/tests/Build new file mode 100644 index 000000000000..b30eff9bcc83 --- /dev/null +++ b/tools/perf/arch/arm64/tests/Build @@ -0,0 +1,2 @@ +libperf-y += regs_load.o +libperf-y += dwarf-unwind.o diff --git a/tools/perf/arch/arm64/tests/dwarf-unwind.c b/tools/perf/arch/arm64/tests/dwarf-unwind.c new file mode 100644 index 000000000000..cf04a4c91c59 --- /dev/null +++ b/tools/perf/arch/arm64/tests/dwarf-unwind.c @@ -0,0 +1,61 @@ +#include +#include "perf_regs.h" +#include "thread.h" +#include "map.h" +#include "event.h" +#include "debug.h" +#include "tests/tests.h" + +#define STACK_SIZE 8192 + +static int sample_ustack(struct perf_sample *sample, + struct thread *thread, u64 *regs) +{ + struct stack_dump *stack = &sample->user_stack; + struct map *map; + unsigned long sp; + u64 stack_size, *buf; + + buf = malloc(STACK_SIZE); + if (!buf) { + pr_debug("failed to allocate sample uregs data\n"); + return -1; + } + + sp = (unsigned long) regs[PERF_REG_ARM64_SP]; + + map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp); + if (!map) { + pr_debug("failed to get stack map\n"); + free(buf); + return -1; + } + + stack_size = map->end - sp; + stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; + + memcpy(buf, (void *) sp, stack_size); + stack->data = (char *) buf; + stack->size = stack_size; + return 0; +} + +int test__arch_unwind_sample(struct perf_sample *sample, + struct thread *thread) +{ + struct regs_dump *regs = &sample->user_regs; + u64 *buf; + + buf = calloc(1, sizeof(u64) * PERF_REGS_MAX); + if (!buf) { + pr_debug("failed to allocate sample uregs data\n"); + return -1; + } + + perf_regs_load(buf); + regs->abi = PERF_SAMPLE_REGS_ABI; + regs->regs = buf; + regs->mask = PERF_REGS_MASK; + + return sample_ustack(sample, thread, buf); +} diff --git a/tools/perf/arch/arm64/tests/regs_load.S b/tools/perf/arch/arm64/tests/regs_load.S new file mode 100644 index 000000000000..025b46e579a6 --- /dev/null +++ b/tools/perf/arch/arm64/tests/regs_load.S @@ -0,0 +1,46 @@ +#include + +.text +.type perf_regs_load,%function +#define STR_REG(r) str x##r, [x0, 8 * r] +#define LDR_REG(r) ldr x##r, [x0, 8 * r] +#define SP (8 * 31) +#define PC (8 * 32) +ENTRY(perf_regs_load) + STR_REG(0) + STR_REG(1) + STR_REG(2) + STR_REG(3) + STR_REG(4) + STR_REG(5) + STR_REG(6) + STR_REG(7) + STR_REG(8) + STR_REG(9) + STR_REG(10) + STR_REG(11) + STR_REG(12) + STR_REG(13) + STR_REG(14) + STR_REG(15) + STR_REG(16) + STR_REG(17) + STR_REG(18) + STR_REG(19) + STR_REG(20) + STR_REG(21) + STR_REG(22) + STR_REG(23) + STR_REG(24) + STR_REG(25) + STR_REG(26) + STR_REG(27) + STR_REG(28) + STR_REG(29) + STR_REG(30) + mov x1, sp + str x1, [x0, #SP] + str x30, [x0, #PC] + LDR_REG(1) + ret +ENDPROC(perf_regs_load) diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 6a8801b32017..67f48e6620e1 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -34,7 +34,7 @@ perf-y += kmod-path.o perf-$(CONFIG_X86) += perf-time-to-tsc.o -ifeq ($(ARCH),$(filter $(ARCH),x86 arm)) +ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64)) perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o endif diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index f42af98a5c16..b5b87a24a9e7 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -126,7 +126,7 @@ static struct test { .desc = "Test parsing with no sample_id_all bit set", .func = test__parse_no_sample_id_all, }, -#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) +#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__) #ifdef HAVE_DWARF_UNWIND_SUPPORT { .desc = "Test dwarf unwind", diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index a10eaf5c4767..87bcaf16ae99 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -62,7 +62,7 @@ int test__fdarray__filter(void); int test__fdarray__add(void); int test__kmod_path__parse(void); -#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) +#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__) #ifdef HAVE_DWARF_UNWIND_SUPPORT struct thread; struct perf_sample; From 43f322b4ab3f203d8eefbdad6e58e1637221e4a7 Mon Sep 17 00:00:00 2001 From: Riku Voipio Date: Thu, 16 Apr 2015 16:52:53 +0300 Subject: [PATCH 06/14] perf tests: Switch from open to openat Multiple perf tests fail on arm64 due to missing open syscall: 2: detect open syscall event : FAILED! open(2) is a legacy syscall, replaced with openat(2) since 2.6.16. Thus new architectures in kernel, such as arm64, don't implement these legacy syscalls. The patch replaces all sys_enter_open events with sys_enter_openat, renames the related tests and test output to avoid confusion. Signed-off-by: Riku Voipio Reviewed-by: Ingo Molnar Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1429192375-13706-2-git-send-email-riku.voipio@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 12 ++++++------ tools/perf/tests/open-syscall-all-cpus.c | 12 ++++++------ tools/perf/tests/open-syscall-tp-fields.c | 6 +++--- tools/perf/tests/open-syscall.c | 14 +++++++------- tools/perf/tests/parse-events.c | 12 ++++++------ tools/perf/tests/tests.h | 6 +++--- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index b5b87a24a9e7..87b9961646e4 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -23,12 +23,12 @@ static struct test { .func = test__vmlinux_matches_kallsyms, }, { - .desc = "detect open syscall event", - .func = test__open_syscall_event, + .desc = "detect openat syscall event", + .func = test__openat_syscall_event, }, { - .desc = "detect open syscall event on all cpus", - .func = test__open_syscall_event_on_all_cpus, + .desc = "detect openat syscall event on all cpus", + .func = test__openat_syscall_event_on_all_cpus, }, { .desc = "read samples using the mmap interface", @@ -73,8 +73,8 @@ static struct test { .func = test__perf_evsel__tp_sched_test, }, { - .desc = "Generate and check syscalls:sys_enter_open event fields", - .func = test__syscall_open_tp_fields, + .desc = "Generate and check syscalls:sys_enter_openat event fields", + .func = test__syscall_openat_tp_fields, }, { .desc = "struct perf_event_attr setup", diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/open-syscall-all-cpus.c index 3ec885c48f8f..e34dfdf96b5a 100644 --- a/tools/perf/tests/open-syscall-all-cpus.c +++ b/tools/perf/tests/open-syscall-all-cpus.c @@ -4,12 +4,12 @@ #include "cpumap.h" #include "debug.h" -int test__open_syscall_event_on_all_cpus(void) +int test__openat_syscall_event_on_all_cpus(void) { int err = -1, fd, cpu; struct cpu_map *cpus; struct perf_evsel *evsel; - unsigned int nr_open_calls = 111, i; + unsigned int nr_openat_calls = 111, i; cpu_set_t cpu_set; struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); char sbuf[STRERR_BUFSIZE]; @@ -27,7 +27,7 @@ int test__open_syscall_event_on_all_cpus(void) CPU_ZERO(&cpu_set); - evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); + evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); if (evsel == NULL) { if (tracefs_configured()) pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); @@ -46,7 +46,7 @@ int test__open_syscall_event_on_all_cpus(void) } for (cpu = 0; cpu < cpus->nr; ++cpu) { - unsigned int ncalls = nr_open_calls + cpu; + unsigned int ncalls = nr_openat_calls + cpu; /* * XXX eventually lift this restriction in a way that * keeps perf building on older glibc installations @@ -66,7 +66,7 @@ int test__open_syscall_event_on_all_cpus(void) goto out_close_fd; } for (i = 0; i < ncalls; ++i) { - fd = open("/etc/passwd", O_RDONLY); + fd = openat(0, "/etc/passwd", O_RDONLY); close(fd); } CPU_CLR(cpus->map[cpu], &cpu_set); @@ -96,7 +96,7 @@ int test__open_syscall_event_on_all_cpus(void) break; } - expected = nr_open_calls + cpu; + expected = nr_openat_calls + cpu; if (evsel->counts->cpu[cpu].val != expected) { pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index 127dcae0b760..6245221479d7 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c @@ -5,7 +5,7 @@ #include "tests.h" #include "debug.h" -int test__syscall_open_tp_fields(void) +int test__syscall_openat_tp_fields(void) { struct record_opts opts = { .target = { @@ -29,7 +29,7 @@ int test__syscall_open_tp_fields(void) goto out; } - evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); + evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); if (evsel == NULL) { pr_debug("%s: perf_evsel__newtp\n", __func__); goto out_delete_evlist; @@ -66,7 +66,7 @@ int test__syscall_open_tp_fields(void) /* * Generate the event: */ - open(filename, flags); + openat(AT_FDCWD, filename, flags); while (1) { int before = nr_events; diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/open-syscall.c index 07aa319bf334..9f9491bb8e48 100644 --- a/tools/perf/tests/open-syscall.c +++ b/tools/perf/tests/open-syscall.c @@ -3,11 +3,11 @@ #include "debug.h" #include "tests.h" -int test__open_syscall_event(void) +int test__openat_syscall_event(void) { int err = -1, fd; struct perf_evsel *evsel; - unsigned int nr_open_calls = 111, i; + unsigned int nr_openat_calls = 111, i; struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); char sbuf[STRERR_BUFSIZE]; @@ -16,7 +16,7 @@ int test__open_syscall_event(void) return -1; } - evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); + evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); if (evsel == NULL) { if (tracefs_configured()) pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); @@ -34,8 +34,8 @@ int test__open_syscall_event(void) goto out_evsel_delete; } - for (i = 0; i < nr_open_calls; ++i) { - fd = open("/etc/passwd", O_RDONLY); + for (i = 0; i < nr_openat_calls; ++i) { + fd = openat(0, "/etc/passwd", O_RDONLY); close(fd); } @@ -44,9 +44,9 @@ int test__open_syscall_event(void) goto out_close_fd; } - if (evsel->counts->cpu[0].val != nr_open_calls) { + if (evsel->counts->cpu[0].val != nr_openat_calls) { pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", - nr_open_calls, evsel->counts->cpu[0].val); + nr_openat_calls, evsel->counts->cpu[0].val); goto out_close_fd; } diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 82d2a1636f7f..d76963f7ad3d 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -427,7 +427,7 @@ static int test__checkevent_list(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - /* syscalls:sys_enter_open:k */ + /* syscalls:sys_enter_openat:k */ evsel = perf_evsel__next(evsel); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", @@ -665,7 +665,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); - /* group1 syscalls:sys_enter_open:H */ + /* group1 syscalls:sys_enter_openat:H */ evsel = leader = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", @@ -1293,7 +1293,7 @@ struct evlist_test { static struct evlist_test test__events[] = { { - .name = "syscalls:sys_enter_open", + .name = "syscalls:sys_enter_openat", .check = test__checkevent_tracepoint, .id = 0, }, @@ -1353,7 +1353,7 @@ static struct evlist_test test__events[] = { .id = 11, }, { - .name = "syscalls:sys_enter_open:k", + .name = "syscalls:sys_enter_openat:k", .check = test__checkevent_tracepoint_modifier, .id = 12, }, @@ -1408,7 +1408,7 @@ static struct evlist_test test__events[] = { .id = 22, }, { - .name = "r1,syscalls:sys_enter_open:k,1:1:hp", + .name = "r1,syscalls:sys_enter_openat:k,1:1:hp", .check = test__checkevent_list, .id = 23, }, @@ -1443,7 +1443,7 @@ static struct evlist_test test__events[] = { .id = 29, }, { - .name = "group1{syscalls:sys_enter_open:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u", + .name = "group1{syscalls:sys_enter_openat:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u", .check = test__group3, .id = 30, }, diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 87bcaf16ae99..8e5038b48ba8 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -26,14 +26,14 @@ enum { /* Tests */ int test__vmlinux_matches_kallsyms(void); -int test__open_syscall_event(void); -int test__open_syscall_event_on_all_cpus(void); +int test__openat_syscall_event(void); +int test__openat_syscall_event_on_all_cpus(void); int test__basic_mmap(void); int test__PERF_RECORD(void); int test__rdpmc(void); int test__perf_evsel__roundtrip_name_test(void); int test__perf_evsel__tp_sched_test(void); -int test__syscall_open_tp_fields(void); +int test__syscall_openat_tp_fields(void); int test__pmu(void); int test__attr(void); int test__dso_data(void); From fbb2df231e11d8086dc51df73376b16407463de1 Mon Sep 17 00:00:00 2001 From: Riku Voipio Date: Fri, 29 May 2015 12:36:11 -0300 Subject: [PATCH 07/14] perf tests: Aename open*.c to openat*.c Since the test being tested is now openat rather than open, rename the files to make it explicit. The patch is separeted from the first to make it simpler to deal with any potential conflicts in the Makefile Signed-off-by: Riku Voipio Reviewed-by: Ingo Molnar Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1429192375-13706-3-git-send-email-riku.voipio@linaro.org [ Fixed it up wrt Build files ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/Build | 6 +++--- .../{open-syscall-all-cpus.c => openat-syscall-all-cpus.c} | 0 ...{open-syscall-tp-fields.c => openat-syscall-tp-fields.c} | 0 tools/perf/tests/{open-syscall.c => openat-syscall.c} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename tools/perf/tests/{open-syscall-all-cpus.c => openat-syscall-all-cpus.c} (100%) rename tools/perf/tests/{open-syscall-tp-fields.c => openat-syscall-tp-fields.c} (100%) rename tools/perf/tests/{open-syscall.c => openat-syscall.c} (100%) diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 67f48e6620e1..ee41e705b2eb 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -3,9 +3,9 @@ perf-y += parse-events.o perf-y += dso-data.o perf-y += attr.o perf-y += vmlinux-kallsyms.o -perf-y += open-syscall.o -perf-y += open-syscall-all-cpus.o -perf-y += open-syscall-tp-fields.o +perf-y += openat-syscall.o +perf-y += openat-syscall-all-cpus.o +perf-y += openat-syscall-tp-fields.o perf-y += mmap-basic.o perf-y += perf-record.o perf-y += rdpmc.o diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c similarity index 100% rename from tools/perf/tests/open-syscall-all-cpus.c rename to tools/perf/tests/openat-syscall-all-cpus.c diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c similarity index 100% rename from tools/perf/tests/open-syscall-tp-fields.c rename to tools/perf/tests/openat-syscall-tp-fields.c diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/openat-syscall.c similarity index 100% rename from tools/perf/tests/open-syscall.c rename to tools/perf/tests/openat-syscall.c From cec83938707a7055c1f9decd81f2741420518e64 Mon Sep 17 00:00:00 2001 From: Riku Voipio Date: Thu, 16 Apr 2015 16:52:55 +0300 Subject: [PATCH 08/14] perf tests: Remove getpgrp from mmap-basic mmap-basic fails on arm64. 4: read samples using the mmap interface: read samples using the mmap interface: FAILED! This is because arm64 doesn't come with getpgrp() syscall. The syscall is a BSD compatibility wrapper, Archs that don't define __ARCH_WANT_SYS_GETPGRP do not have this. Remove it, since getpgid is already used in the testcase. Signed-off-by: Riku Voipio Reviewed-by: Ingo Molnar Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1429192375-13706-4-git-send-email-riku.voipio@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/mmap-basic.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 9b9622a33932..5855cf471210 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -23,10 +23,8 @@ int test__basic_mmap(void) struct cpu_map *cpus; struct perf_evlist *evlist; cpu_set_t cpu_set; - const char *syscall_names[] = { "getsid", "getppid", "getpgrp", - "getpgid", }; - pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp, - (void*)getpgid }; + const char *syscall_names[] = { "getsid", "getppid", "getpgid", }; + pid_t (*syscalls[])(void) = { (void *)getsid, getppid, (void*)getpgid }; #define nsyscalls ARRAY_SIZE(syscall_names) unsigned int nr_events[nsyscalls], expected_nr_events[nsyscalls], i, j; From 459ce518d9b563a99faa73aa340b764e0b3fb143 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 28 May 2015 12:40:55 -0300 Subject: [PATCH 09/14] perf machine: Adopt findnew_kernel method It never was a 'struct dso' method, so fix that by rename dso__kernel_findnew() to machine__findnew_kernel(). At some point I'll move it all to the machine.[ch] files, for now lets ease patch review by not moving too much stuff. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-zrxmblgsg5vx0iv4rhvq2f6l@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.c | 4 ++-- tools/perf/util/dso.h | 4 ++-- tools/perf/util/machine.c | 11 +++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 7e11a700303f..fe5236833164 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -827,8 +827,8 @@ struct map *dso__new_map(const char *name) return map; } -struct dso *dso__kernel_findnew(struct machine *machine, const char *name, - const char *short_name, int dso_type) +struct dso *machine__findnew_kernel(struct machine *machine, const char *name, + const char *short_name, int dso_type) { /* * The kernel dso could be created by build_id processing. diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index bcec06ad73a2..24a507a54147 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -294,8 +294,8 @@ ssize_t dso__data_read_addr(struct dso *dso, struct map *map, bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by); struct map *dso__new_map(const char *name); -struct dso *dso__kernel_findnew(struct machine *machine, const char *name, - const char *short_name, int dso_type); +struct dso *machine__findnew_kernel(struct machine *machine, const char *name, + const char *short_name, int dso_type); void dsos__add(struct dsos *dsos, struct dso *dso); struct dso *dsos__addnew(struct dsos *dsos, const char *name); diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 0c0e61cce577..8934dc4345fe 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -640,9 +640,8 @@ static struct dso *machine__get_kernel(struct machine *machine) if (!vmlinux_name) vmlinux_name = "[kernel.kallsyms]"; - kernel = dso__kernel_findnew(machine, vmlinux_name, - "[kernel]", - DSO_TYPE_KERNEL); + kernel = machine__findnew_kernel(machine, vmlinux_name, + "[kernel]", DSO_TYPE_KERNEL); } else { char bf[PATH_MAX]; @@ -652,9 +651,9 @@ static struct dso *machine__get_kernel(struct machine *machine) vmlinux_name = machine__mmap_name(machine, bf, sizeof(bf)); - kernel = dso__kernel_findnew(machine, vmlinux_name, - "[guest.kernel]", - DSO_TYPE_GUEST_KERNEL); + kernel = machine__findnew_kernel(machine, vmlinux_name, + "[guest.kernel]", + DSO_TYPE_GUEST_KERNEL); } if (kernel != NULL && (!kernel->has_build_id)) From 3d39ac538629e4f00a6e1c38d46346f1b8e69505 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 28 May 2015 13:06:42 -0300 Subject: [PATCH 10/14] perf machine: No need to have two DSOs lists We can, given a DSO, figure out if it is a kernel, a kernel module or a userlevel DSO, so stop having to process two lists in several functions. If searching becomes an issue at some point, we can have them in a rbtree, etc. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-s4yb0onpdywu6dj2xl9lxi4t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/hists_common.c | 2 +- tools/perf/util/build-id.c | 59 +++++++++------------------------ tools/perf/util/dso.c | 2 +- tools/perf/util/header.c | 6 +--- tools/perf/util/machine.c | 28 ++++++---------- tools/perf/util/machine.h | 3 +- tools/perf/util/map.c | 2 +- tools/perf/util/probe-event.c | 5 +-- tools/perf/util/symbol-elf.c | 6 +--- tools/perf/util/vdso.c | 6 ++-- 10 files changed, 39 insertions(+), 80 deletions(-) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index 456f884eb27b..bcde1d27919c 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -121,7 +121,7 @@ struct machine *setup_fake_machine(struct machines *machines) size_t k; struct dso *dso; - dso = __dsos__findnew(&machine->user_dsos, + dso = __dsos__findnew(&machine->dsos, fake_symbols[i].dso_name); if (dso == NULL) goto out; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index ad8cfcbaa25d..1f6fc2323ef9 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -162,15 +162,20 @@ static int write_buildid(const char *name, size_t name_len, u8 *build_id, return write_padded(fd, name, name_len + 1, len); } -static int __dsos__write_buildid_table(struct list_head *head, - struct machine *machine, - pid_t pid, u16 misc, int fd) +static int machine__write_buildid_table(struct machine *machine, int fd) { + int err = 0; char nm[PATH_MAX]; struct dso *pos; + u16 kmisc = PERF_RECORD_MISC_KERNEL, + umisc = PERF_RECORD_MISC_USER; - dsos__for_each_with_build_id(pos, head) { - int err; + if (!machine__is_host(machine)) { + kmisc = PERF_RECORD_MISC_GUEST_KERNEL; + umisc = PERF_RECORD_MISC_GUEST_USER; + } + + dsos__for_each_with_build_id(pos, &machine->dsos.head) { const char *name; size_t name_len; @@ -189,32 +194,12 @@ static int __dsos__write_buildid_table(struct list_head *head, name_len = pos->long_name_len + 1; } - err = write_buildid(name, name_len, pos->build_id, - pid, misc, fd); + err = write_buildid(name, name_len, pos->build_id, machine->pid, + pos->kernel ? kmisc : umisc, fd); if (err) - return err; + break; } - return 0; -} - -static int machine__write_buildid_table(struct machine *machine, int fd) -{ - int err; - u16 kmisc = PERF_RECORD_MISC_KERNEL, - umisc = PERF_RECORD_MISC_USER; - - if (!machine__is_host(machine)) { - kmisc = PERF_RECORD_MISC_GUEST_KERNEL; - umisc = PERF_RECORD_MISC_GUEST_USER; - } - - err = __dsos__write_buildid_table(&machine->kernel_dsos.head, machine, - machine->pid, kmisc, fd); - if (err == 0) - err = __dsos__write_buildid_table(&machine->user_dsos.head, - machine, machine->pid, umisc, - fd); return err; } @@ -247,13 +232,7 @@ static int __dsos__hit_all(struct list_head *head) static int machine__hit_all_dsos(struct machine *machine) { - int err; - - err = __dsos__hit_all(&machine->kernel_dsos.head); - if (err) - return err; - - return __dsos__hit_all(&machine->user_dsos.head); + return __dsos__hit_all(&machine->dsos.head); } int dsos__hit_all(struct perf_session *session) @@ -493,9 +472,7 @@ static int __dsos__cache_build_ids(struct list_head *head, static int machine__cache_build_ids(struct machine *machine) { - int ret = __dsos__cache_build_ids(&machine->kernel_dsos.head, machine); - ret |= __dsos__cache_build_ids(&machine->user_dsos.head, machine); - return ret; + return __dsos__cache_build_ids(&machine->dsos.head, machine); } int perf_session__cache_build_ids(struct perf_session *session) @@ -520,11 +497,7 @@ int perf_session__cache_build_ids(struct perf_session *session) static bool machine__read_build_ids(struct machine *machine, bool with_hits) { - bool ret; - - ret = __dsos__read_build_ids(&machine->kernel_dsos.head, with_hits); - ret |= __dsos__read_build_ids(&machine->user_dsos.head, with_hits); - return ret; + return __dsos__read_build_ids(&machine->dsos.head, with_hits); } bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index fe5236833164..ff040b0569d6 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -833,7 +833,7 @@ struct dso *machine__findnew_kernel(struct machine *machine, const char *name, /* * The kernel dso could be created by build_id processing. */ - struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); + struct dso *dso = __dsos__findnew(&machine->dsos, name); /* * We need to run this in all cases, since during the build_id diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3f0d809d853a..a900e9441fb5 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1238,7 +1238,6 @@ static int __event_process_build_id(struct build_id_event *bev, struct perf_session *session) { int err = -1; - struct dsos *dsos; struct machine *machine; u16 misc; struct dso *dso; @@ -1253,22 +1252,19 @@ static int __event_process_build_id(struct build_id_event *bev, switch (misc) { case PERF_RECORD_MISC_KERNEL: dso_type = DSO_TYPE_KERNEL; - dsos = &machine->kernel_dsos; break; case PERF_RECORD_MISC_GUEST_KERNEL: dso_type = DSO_TYPE_GUEST_KERNEL; - dsos = &machine->kernel_dsos; break; case PERF_RECORD_MISC_USER: case PERF_RECORD_MISC_GUEST_USER: dso_type = DSO_TYPE_USER; - dsos = &machine->user_dsos; break; default: goto out; } - dso = __dsos__findnew(dsos, filename); + dso = __dsos__findnew(&machine->dsos, filename); if (dso != NULL) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 8934dc4345fe..ffd31079d447 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -26,8 +26,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) { map_groups__init(&machine->kmaps, machine); RB_CLEAR_NODE(&machine->rb_node); - dsos__init(&machine->user_dsos); - dsos__init(&machine->kernel_dsos); + dsos__init(&machine->dsos); machine->threads = RB_ROOT; pthread_rwlock_init(&machine->threads_lock, NULL); @@ -111,8 +110,7 @@ void machine__delete_threads(struct machine *machine) void machine__exit(struct machine *machine) { map_groups__exit(&machine->kmaps); - dsos__delete(&machine->user_dsos); - dsos__delete(&machine->kernel_dsos); + dsos__delete(&machine->dsos); vdso__exit(machine); zfree(&machine->root_dir); zfree(&machine->current_tid); @@ -490,9 +488,9 @@ machine__module_dso(struct machine *machine, struct kmod_path *m, { struct dso *dso; - dso = dsos__find(&machine->kernel_dsos, m->name, true); + dso = dsos__find(&machine->dsos, m->name, true); if (!dso) { - dso = dsos__addnew(&machine->kernel_dsos, m->name); + dso = dsos__addnew(&machine->dsos, m->name); if (dso == NULL) return NULL; @@ -561,13 +559,11 @@ out: size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) { struct rb_node *nd; - size_t ret = __dsos__fprintf(&machines->host.kernel_dsos.head, fp) + - __dsos__fprintf(&machines->host.user_dsos.head, fp); + size_t ret = __dsos__fprintf(&machines->host.dsos.head, fp); for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { struct machine *pos = rb_entry(nd, struct machine, rb_node); - ret += __dsos__fprintf(&pos->kernel_dsos.head, fp); - ret += __dsos__fprintf(&pos->user_dsos.head, fp); + ret += __dsos__fprintf(&pos->dsos.head, fp); } return ret; @@ -576,8 +572,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) size_t machine__fprintf_dsos_buildid(struct machine *m, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm) { - return __dsos__fprintf_buildid(&m->kernel_dsos.head, fp, skip, parm) + - __dsos__fprintf_buildid(&m->user_dsos.head, fp, skip, parm); + return __dsos__fprintf_buildid(&m->dsos.head, fp, skip, parm); } size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, @@ -1106,7 +1101,7 @@ static bool machine__uses_kcore(struct machine *machine) { struct dso *dso; - list_for_each_entry(dso, &machine->kernel_dsos.head, node) { + list_for_each_entry(dso, &machine->dsos.head, node) { if (dso__is_kcore(dso)) return true; } @@ -1153,8 +1148,8 @@ static int machine__process_kernel_mmap_event(struct machine *machine, struct dso *kernel = NULL; struct dso *dso; - list_for_each_entry(dso, &machine->kernel_dsos.head, node) { - if (is_kernel_module(dso->long_name)) + list_for_each_entry(dso, &machine->dsos.head, node) { + if (dso->kernel && is_kernel_module(dso->long_name)) continue; kernel = dso; @@ -1162,8 +1157,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, } if (kernel == NULL) - kernel = __dsos__findnew(&machine->kernel_dsos, - kmmap_prefix); + kernel = __dsos__findnew(&machine->dsos, kmmap_prefix); if (kernel == NULL) goto out_problem; diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index c7963c63c474..aabca583e655 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -34,8 +34,7 @@ struct machine { struct list_head dead_threads; struct thread *last_match; struct vdso_info *vdso_info; - struct dsos user_dsos; - struct dsos kernel_dsos; + struct dsos dsos; struct map_groups kmaps; struct map *vmlinux_maps[MAP__NR_TYPES]; u64 kernel_start; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index af572322586d..57ff0256c22c 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -180,7 +180,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, pgoff = 0; dso = vdso__dso_findnew(machine, thread); } else - dso = __dsos__findnew(&machine->user_dsos, filename); + dso = __dsos__findnew(&machine->dsos, filename); if (dso == NULL) goto out_delete; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index e6a02b1ffd6d..d27edef5eb5b 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -256,8 +256,9 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) int ret = 0; if (module) { - list_for_each_entry(dso, &host_machine->kernel_dsos.head, - node) { + list_for_each_entry(dso, &host_machine->dsos.head, node) { + if (!dso->kernel) + continue; if (strncmp(dso->short_name + 1, module, dso->short_name_len - 2) == 0) goto found; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index fa10116a12ab..a93ba85509b2 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1031,11 +1031,7 @@ int dso__load_sym(struct dso *dso, struct map *map, } curr_dso->symtab_type = dso->symtab_type; map_groups__insert(kmaps, curr_map); - /* - * The new DSO should go to the kernel DSOS - */ - dsos__add(&map->groups->machine->kernel_dsos, - curr_dso); + dsos__add(&map->groups->machine->dsos, curr_dso); dso__set_loaded(curr_dso, map->type); } else curr_dso = curr_map->dso; diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 5c7dd796979d..d3651b43e945 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -127,7 +127,7 @@ static struct dso *vdso__new(struct machine *machine, const char *short_name, dso = dso__new(short_name); if (dso != NULL) { - dsos__add(&machine->user_dsos, dso); + dsos__add(&machine->dsos, dso); dso__set_long_name(dso, long_name, false); } @@ -236,7 +236,7 @@ static struct dso *vdso__findnew_compat(struct machine *machine, const char *file_name; struct dso *dso; - dso = dsos__find(&machine->user_dsos, vdso_file->dso_name, true); + dso = dsos__find(&machine->dsos, vdso_file->dso_name, true); if (dso) return dso; @@ -299,7 +299,7 @@ struct dso *vdso__dso_findnew(struct machine *machine, return dso; #endif - dso = dsos__find(&machine->user_dsos, DSO__NAME_VDSO, true); + dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, true); if (!dso) { char *file; From aa7cc2ae5ae69aff555793fbfcff514141bb23f3 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 29 May 2015 11:31:12 -0300 Subject: [PATCH 11/14] perf machine: Introduce machine__findnew_dso() method Similar to machine__findnew_thread(), also prepping for refcounting and locking, this time for struct dso instances. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/n/tip-fv3tshv5o1413coh147lszjc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/hists_common.c | 3 +-- tools/perf/util/dso.c | 2 +- tools/perf/util/header.c | 2 +- tools/perf/util/machine.c | 7 ++++++- tools/perf/util/machine.h | 2 ++ tools/perf/util/map.c | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index bcde1d27919c..915f60af6a0e 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -121,8 +121,7 @@ struct machine *setup_fake_machine(struct machines *machines) size_t k; struct dso *dso; - dso = __dsos__findnew(&machine->dsos, - fake_symbols[i].dso_name); + dso = machine__findnew_dso(machine, fake_symbols[i].dso_name); if (dso == NULL) goto out; diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index ff040b0569d6..b335db3532a2 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -833,7 +833,7 @@ struct dso *machine__findnew_kernel(struct machine *machine, const char *name, /* * The kernel dso could be created by build_id processing. */ - struct dso *dso = __dsos__findnew(&machine->dsos, name); + struct dso *dso = machine__findnew_dso(machine, name); /* * We need to run this in all cases, since during the build_id diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index a900e9441fb5..851143a7988d 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1264,7 +1264,7 @@ static int __event_process_build_id(struct build_id_event *bev, goto out; } - dso = __dsos__findnew(&machine->dsos, filename); + dso = machine__findnew_dso(machine, filename); if (dso != NULL) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index ffd31079d447..698da1da5168 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1157,7 +1157,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, } if (kernel == NULL) - kernel = __dsos__findnew(&machine->dsos, kmmap_prefix); + kernel = machine__findnew_dso(machine, kmmap_prefix); if (kernel == NULL) goto out_problem; @@ -1915,3 +1915,8 @@ int machine__get_kernel_start(struct machine *machine) } return err; } + +struct dso *machine__findnew_dso(struct machine *machine, const char *filename) +{ + return __dsos__findnew(&machine->dsos, filename); +} diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index aabca583e655..39a0ca06cbd8 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -154,6 +154,8 @@ static inline bool machine__is_host(struct machine *machine) struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); +struct dso *machine__findnew_dso(struct machine *machine, const char *filename); + size_t machine__fprintf(struct machine *machine, FILE *fp); static inline diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 57ff0256c22c..d15e1e9dd2ae 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -180,7 +180,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, pgoff = 0; dso = vdso__dso_findnew(machine, thread); } else - dso = __dsos__findnew(&machine->dsos, filename); + dso = machine__findnew_dso(machine, filename); if (dso == NULL) goto out_delete; From 9a4388c711d07889217b19eaf63485122dec8817 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 29 May 2015 11:54:08 -0300 Subject: [PATCH 12/14] perf machine: Fix up vdso methods names To make it consistent with the other dso lifetime routines. For instance: struct dso *vdso__new(struct machine *machine, const char *short_name, const char *long_name) Becomes: struct dso *machine__addnew_vdso(struct machine *machine, const char *short_name, const char *long_name) Because: 1) There is no 'struct vdso' for us to have vdso__ prefixed routines. 2) Because it will not really just create a new instance of 'struct dso', it'll call dso__new() but it will also insert it into the DSO's list/rbtree, and we have a method name for that: 'addnew', just like we have dsos__addnew(). 3) So it is really a 'struct machine' operation, it is the first argument, etc. This way the place where this is used gets consistent: if (vdso) { pgoff = 0; - dso = vdso__dso_findnew(machine, thread); + dso = machine__findnew_vdso(machine, thread); } else dso = machine__findnew_dso(machine, filename); Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/n/tip-r3w3tvh8exm9xfz3p4tz9qbz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 2 +- tools/perf/util/map.c | 2 +- tools/perf/util/vdso.c | 18 +++++++++--------- tools/perf/util/vdso.h | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 698da1da5168..2ed61f59d415 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -111,7 +111,7 @@ void machine__exit(struct machine *machine) { map_groups__exit(&machine->kmaps); dsos__delete(&machine->dsos); - vdso__exit(machine); + machine__exit_vdso(machine); zfree(&machine->root_dir); zfree(&machine->current_tid); pthread_rwlock_destroy(&machine->threads_lock); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index d15e1e9dd2ae..365011c233a6 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -178,7 +178,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (vdso) { pgoff = 0; - dso = vdso__dso_findnew(machine, thread); + dso = machine__findnew_vdso(machine, thread); } else dso = machine__findnew_dso(machine, filename); diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index d3651b43e945..2e8f6886ca72 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -101,7 +101,7 @@ static char *get_file(struct vdso_file *vdso_file) return vdso; } -void vdso__exit(struct machine *machine) +void machine__exit_vdso(struct machine *machine) { struct vdso_info *vdso_info = machine->vdso_info; @@ -120,8 +120,8 @@ void vdso__exit(struct machine *machine) zfree(&machine->vdso_info); } -static struct dso *vdso__new(struct machine *machine, const char *short_name, - const char *long_name) +static struct dso *machine__addnew_vdso(struct machine *machine, const char *short_name, + const char *long_name) { struct dso *dso; @@ -244,10 +244,10 @@ static struct dso *vdso__findnew_compat(struct machine *machine, if (!file_name) return NULL; - return vdso__new(machine, vdso_file->dso_name, file_name); + return machine__addnew_vdso(machine, vdso_file->dso_name, file_name); } -static int vdso__dso_findnew_compat(struct machine *machine, +static int machine__findnew_vdso_compat(struct machine *machine, struct thread *thread, struct vdso_info *vdso_info, struct dso **dso) @@ -281,8 +281,8 @@ static int vdso__dso_findnew_compat(struct machine *machine, #endif -struct dso *vdso__dso_findnew(struct machine *machine, - struct thread *thread __maybe_unused) +struct dso *machine__findnew_vdso(struct machine *machine, + struct thread *thread __maybe_unused) { struct vdso_info *vdso_info; struct dso *dso; @@ -295,7 +295,7 @@ struct dso *vdso__dso_findnew(struct machine *machine, return NULL; #if BITS_PER_LONG == 64 - if (vdso__dso_findnew_compat(machine, thread, vdso_info, &dso)) + if (machine__findnew_vdso_compat(machine, thread, vdso_info, &dso)) return dso; #endif @@ -307,7 +307,7 @@ struct dso *vdso__dso_findnew(struct machine *machine, if (!file) return NULL; - dso = vdso__new(machine, DSO__NAME_VDSO, file); + dso = machine__addnew_vdso(machine, DSO__NAME_VDSO, file); } return dso; diff --git a/tools/perf/util/vdso.h b/tools/perf/util/vdso.h index d97da1616f0c..cdc4fabfc212 100644 --- a/tools/perf/util/vdso.h +++ b/tools/perf/util/vdso.h @@ -23,7 +23,7 @@ bool dso__is_vdso(struct dso *dso); struct machine; struct thread; -struct dso *vdso__dso_findnew(struct machine *machine, struct thread *thread); -void vdso__exit(struct machine *machine); +struct dso *machine__findnew_vdso(struct machine *machine, struct thread *thread); +void machine__exit_vdso(struct machine *machine); #endif /* __PERF_VDSO__ */ From d7a3d85e08477a979933a2bb3b525a8de99543c2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 29 May 2015 17:42:58 +0200 Subject: [PATCH 13/14] perf build: Do not fail on missing Build file Allow nesting into directories without Build file. Currently we force include of the Build file, which fails the build when the Build file is missing. We already support empty *-in.o' objects if there's nothing in the directory to be compiled, so we can just use it for missing Build file cases. Also adding this case under tests. Reported-by: Rabin Vincent Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Rabin Vincent Link: http://lkml.kernel.org/r/1432914178-24086-1-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.build | 2 +- tools/build/tests/ex/Build | 1 + tools/build/tests/ex/empty2/README | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 tools/build/tests/ex/empty2/README diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index 10df57237a66..69c35cf09cad 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -37,7 +37,7 @@ subdir-obj-y := # Build definitions build-file := $(dir)/Build -include $(build-file) +-include $(build-file) quiet_cmd_flex = FLEX $@ quiet_cmd_bison = BISON $@ diff --git a/tools/build/tests/ex/Build b/tools/build/tests/ex/Build index 0e6c3e6767e6..70d876237c57 100644 --- a/tools/build/tests/ex/Build +++ b/tools/build/tests/ex/Build @@ -2,6 +2,7 @@ ex-y += ex.o ex-y += a.o ex-y += b.o ex-y += empty/ +ex-y += empty2/ libex-y += c.o libex-y += d.o diff --git a/tools/build/tests/ex/empty2/README b/tools/build/tests/ex/empty2/README new file mode 100644 index 000000000000..2107cc5bf5a9 --- /dev/null +++ b/tools/build/tests/ex/empty2/README @@ -0,0 +1,2 @@ +This directory is left intentionally without Build file +to test proper nesting into Build-less directories. From ed426915900db3c58c410b8b38f6ff0e46bf6c96 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 29 May 2015 21:53:44 +0900 Subject: [PATCH 14/14] perf tools: Make Ctrl-C stop processing on TUI It was inconvenient that perf cannot be quit with SIGINT during processing samples on TUI especially for large data files. This was because the first argument of SLang_init_tty(), abort_char, being 0. The manual says it's the ascii value of the control character that will be used to generate the interrupt signal [1]. Passing -1 means to use the default value (Ctrl-C). However, after processing samples, Ctrl-C was used to in other cases as well - like stepping back from annotate. So recover the original behavior after processing. [1] http://jedsoft.org/slang/doc/html/cslang-6.html#ss6.1 Signed-off-by: Namhyung Kim Tested-by: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1432904024-13170-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/annotate.c | 4 ++++ tools/perf/ui/browsers/hists.c | 4 ++++ tools/perf/ui/tui/setup.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index e5250eb2dd57..acb0e23b138e 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -838,6 +838,10 @@ int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, struct hist_browser_timer *hbt) { + /* reset abort key so that it can get Ctrl-C as a key */ + SLang_reset_tty(); + SLang_init_tty(0, 0, 0); + return map_symbol__tui_annotate(&he->ms, evsel, hbt); } diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index f981cb8f0158..e64893f2fd7f 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1741,6 +1741,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, if (browser == NULL) return -1; + /* reset abort key so that it can get Ctrl-C as a key */ + SLang_reset_tty(); + SLang_init_tty(0, 0, 0); + if (min_pcnt) { browser->min_pcnt = min_pcnt; hist_browser__update_nr_entries(browser); diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index b77e1d771363..60d1f29b4b50 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -129,7 +129,7 @@ int ui__init(void) err = SLsmg_init_smg(); if (err < 0) goto out; - err = SLang_init_tty(0, 0, 0); + err = SLang_init_tty(-1, 0, 0); if (err < 0) goto out;