aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-06-07 11:50:19 -0400
committerIngo Molnar <mingo@kernel.org>2017-06-07 11:50:19 -0400
commit3e411b0ee7c7bf0cbe2bd5961f84a02f0451ad57 (patch)
tree271e81558067f046f2104b2cfc0c35d6ecf11ee5
parentba7b2387ad239a519041f2a2d35a1902bdd03dfb (diff)
parent2538b9e2450ae255337c04356e9e0f8cb9ec48d9 (diff)
Merge tag 'perf-urgent-for-mingo-4.12-20170606' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/urgent fixes from Arnaldo Carvalho de Melo: - Only print NMI watchdog hint in 'perf stat' when it is enabled (Andi Kleen) - Fix sys_mmap/sys_old_mmap shandling in s390 in 'perf trace' (Jiri Olsa) - Disable breakpoint signal tests in powerpc, that lacks the perf kernel glue to set breakpoint events and makes 'perf test' always fail (Jiri Olsa) - Fix 'perf annotate' for branch instruction with multiple operands (Kim Phillips) - Add missing powerpc triplet when disassembling with 'objdump' in 'perf annotate' (Kim Phillips) - Do not trow away partial unwound stacks when using libdw, making callchains produced with it similar to those produced when linked with the other DWARF unwind library supported in perf, libunwind (Milian Wolff) - Fixes to properly handle kernel modules when processing build-id meta events (Namhyung Kim) - Fix handling of compressed modules in the build-id cache (Namhyung Kim) - Fix 'perf annotate' failure when filename has special chars (Ravi Bangoria) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/perf/arch/common.c1
-rw-r--r--tools/perf/builtin-stat.c5
-rw-r--r--tools/perf/builtin-trace.c4
-rw-r--r--tools/perf/tests/bp_signal.c14
-rw-r--r--tools/perf/tests/builtin-test.c7
-rw-r--r--tools/perf/tests/tests.h3
-rw-r--r--tools/perf/util/annotate.c35
-rw-r--r--tools/perf/util/dso.c15
-rw-r--r--tools/perf/util/dso.h3
-rw-r--r--tools/perf/util/header.c12
-rw-r--r--tools/perf/util/machine.c11
-rw-r--r--tools/perf/util/symbol-elf.c5
-rw-r--r--tools/perf/util/unwind-libdw.c10
13 files changed, 103 insertions, 22 deletions
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index 837067f48a4c..6b40e9f01740 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -26,6 +26,7 @@ const char *const arm64_triplets[] = {
26 26
27const char *const powerpc_triplets[] = { 27const char *const powerpc_triplets[] = {
28 "powerpc-unknown-linux-gnu-", 28 "powerpc-unknown-linux-gnu-",
29 "powerpc-linux-gnu-",
29 "powerpc64-unknown-linux-gnu-", 30 "powerpc64-unknown-linux-gnu-",
30 "powerpc64-linux-gnu-", 31 "powerpc64-linux-gnu-",
31 "powerpc64le-linux-gnu-", 32 "powerpc64le-linux-gnu-",
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a935b5023732..ad9324d1daf9 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1578,6 +1578,7 @@ static void print_header(int argc, const char **argv)
1578static void print_footer(void) 1578static void print_footer(void)
1579{ 1579{
1580 FILE *output = stat_config.output; 1580 FILE *output = stat_config.output;
1581 int n;
1581 1582
1582 if (!null_run) 1583 if (!null_run)
1583 fprintf(output, "\n"); 1584 fprintf(output, "\n");
@@ -1590,7 +1591,9 @@ static void print_footer(void)
1590 } 1591 }
1591 fprintf(output, "\n\n"); 1592 fprintf(output, "\n\n");
1592 1593
1593 if (print_free_counters_hint) 1594 if (print_free_counters_hint &&
1595 sysctl__read_int("kernel/nmi_watchdog", &n) >= 0 &&
1596 n > 0)
1594 fprintf(output, 1597 fprintf(output,
1595"Some events weren't counted. Try disabling the NMI watchdog:\n" 1598"Some events weren't counted. Try disabling the NMI watchdog:\n"
1596" echo 0 > /proc/sys/kernel/nmi_watchdog\n" 1599" echo 0 > /proc/sys/kernel/nmi_watchdog\n"
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d014350adc52..4b2a5d298197 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -681,6 +681,10 @@ static struct syscall_fmt {
681 { .name = "mlockall", .errmsg = true, 681 { .name = "mlockall", .errmsg = true,
682 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, 682 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
683 { .name = "mmap", .hexret = true, 683 { .name = "mmap", .hexret = true,
684/* The standard mmap maps to old_mmap on s390x */
685#if defined(__s390x__)
686 .alias = "old_mmap",
687#endif
684 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ 688 .arg_scnprintf = { [0] = SCA_HEX, /* addr */
685 [2] = SCA_MMAP_PROT, /* prot */ 689 [2] = SCA_MMAP_PROT, /* prot */
686 [3] = SCA_MMAP_FLAGS, /* flags */ }, }, 690 [3] = SCA_MMAP_FLAGS, /* flags */ }, },
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index e7664fe3bd33..8ba2c4618fe9 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -288,3 +288,17 @@ int test__bp_signal(int subtest __maybe_unused)
288 return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ? 288 return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
289 TEST_OK : TEST_FAIL; 289 TEST_OK : TEST_FAIL;
290} 290}
291
292bool test__bp_signal_is_supported(void)
293{
294/*
295 * The powerpc so far does not have support to even create
296 * instruction breakpoint using the perf event interface.
297 * Once it's there we can release this.
298 */
299#ifdef __powerpc__
300 return false;
301#else
302 return true;
303#endif
304}
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 9e08d297f1a9..3ccfd58a8c3c 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -97,10 +97,12 @@ static struct test generic_tests[] = {
97 { 97 {
98 .desc = "Breakpoint overflow signal handler", 98 .desc = "Breakpoint overflow signal handler",
99 .func = test__bp_signal, 99 .func = test__bp_signal,
100 .is_supported = test__bp_signal_is_supported,
100 }, 101 },
101 { 102 {
102 .desc = "Breakpoint overflow sampling", 103 .desc = "Breakpoint overflow sampling",
103 .func = test__bp_signal_overflow, 104 .func = test__bp_signal_overflow,
105 .is_supported = test__bp_signal_is_supported,
104 }, 106 },
105 { 107 {
106 .desc = "Number of exit events of a simple workload", 108 .desc = "Number of exit events of a simple workload",
@@ -401,6 +403,11 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
401 if (!perf_test__matches(t, curr, argc, argv)) 403 if (!perf_test__matches(t, curr, argc, argv))
402 continue; 404 continue;
403 405
406 if (t->is_supported && !t->is_supported()) {
407 pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc);
408 continue;
409 }
410
404 pr_info("%2d: %-*s:", i, width, t->desc); 411 pr_info("%2d: %-*s:", i, width, t->desc);
405 412
406 if (intlist__find(skiplist, i)) { 413 if (intlist__find(skiplist, i)) {
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 631859629403..577363809c9b 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -34,6 +34,7 @@ struct test {
34 int (*get_nr)(void); 34 int (*get_nr)(void);
35 const char *(*get_desc)(int subtest); 35 const char *(*get_desc)(int subtest);
36 } subtest; 36 } subtest;
37 bool (*is_supported)(void);
37}; 38};
38 39
39/* Tests */ 40/* Tests */
@@ -99,6 +100,8 @@ const char *test__clang_subtest_get_desc(int subtest);
99int test__clang_subtest_get_nr(void); 100int test__clang_subtest_get_nr(void);
100int test__unit_number__scnprint(int subtest); 101int test__unit_number__scnprint(int subtest);
101 102
103bool test__bp_signal_is_supported(void);
104
102#if defined(__arm__) || defined(__aarch64__) 105#if defined(__arm__) || defined(__aarch64__)
103#ifdef HAVE_DWARF_UNWIND_SUPPORT 106#ifdef HAVE_DWARF_UNWIND_SUPPORT
104struct thread; 107struct thread;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 683f8340460c..1367d7e35242 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -239,10 +239,20 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
239 const char *s = strchr(ops->raw, '+'); 239 const char *s = strchr(ops->raw, '+');
240 const char *c = strchr(ops->raw, ','); 240 const char *c = strchr(ops->raw, ',');
241 241
242 if (c++ != NULL) 242 /*
243 * skip over possible up to 2 operands to get to address, e.g.:
244 * tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
245 */
246 if (c++ != NULL) {
243 ops->target.addr = strtoull(c, NULL, 16); 247 ops->target.addr = strtoull(c, NULL, 16);
244 else 248 if (!ops->target.addr) {
249 c = strchr(c, ',');
250 if (c++ != NULL)
251 ops->target.addr = strtoull(c, NULL, 16);
252 }
253 } else {
245 ops->target.addr = strtoull(ops->raw, NULL, 16); 254 ops->target.addr = strtoull(ops->raw, NULL, 16);
255 }
246 256
247 if (s++ != NULL) { 257 if (s++ != NULL) {
248 ops->target.offset = strtoull(s, NULL, 16); 258 ops->target.offset = strtoull(s, NULL, 16);
@@ -257,10 +267,27 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
257static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 267static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
258 struct ins_operands *ops) 268 struct ins_operands *ops)
259{ 269{
270 const char *c = strchr(ops->raw, ',');
271
260 if (!ops->target.addr || ops->target.offset < 0) 272 if (!ops->target.addr || ops->target.offset < 0)
261 return ins__raw_scnprintf(ins, bf, size, ops); 273 return ins__raw_scnprintf(ins, bf, size, ops);
262 274
263 return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset); 275 if (c != NULL) {
276 const char *c2 = strchr(c + 1, ',');
277
278 /* check for 3-op insn */
279 if (c2 != NULL)
280 c = c2;
281 c++;
282
283 /* mirror arch objdump's space-after-comma style */
284 if (*c == ' ')
285 c++;
286 }
287
288 return scnprintf(bf, size, "%-6.6s %.*s%" PRIx64,
289 ins->name, c ? c - ops->raw : 0, ops->raw,
290 ops->target.offset);
264} 291}
265 292
266static struct ins_ops jump_ops = { 293static struct ins_ops jump_ops = {
@@ -1429,7 +1456,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
1429 snprintf(command, sizeof(command), 1456 snprintf(command, sizeof(command),
1430 "%s %s%s --start-address=0x%016" PRIx64 1457 "%s %s%s --start-address=0x%016" PRIx64
1431 " --stop-address=0x%016" PRIx64 1458 " --stop-address=0x%016" PRIx64
1432 " -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand", 1459 " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
1433 objdump_path ? objdump_path : "objdump", 1460 objdump_path ? objdump_path : "objdump",
1434 disassembler_style ? "-M " : "", 1461 disassembler_style ? "-M " : "",
1435 disassembler_style ? disassembler_style : "", 1462 disassembler_style ? disassembler_style : "",
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index a96a99d2369f..b27d127cdf68 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -335,6 +335,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
335 return 0; 335 return 0;
336} 336}
337 337
338void dso__set_module_info(struct dso *dso, struct kmod_path *m,
339 struct machine *machine)
340{
341 if (machine__is_host(machine))
342 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
343 else
344 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
345
346 /* _KMODULE_COMP should be next to _KMODULE */
347 if (m->kmod && m->comp)
348 dso->symtab_type++;
349
350 dso__set_short_name(dso, strdup(m->name), true);
351}
352
338/* 353/*
339 * Global list of open DSOs and the counter. 354 * Global list of open DSOs and the counter.
340 */ 355 */
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 12350b171727..5fe2ab5877bd 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -259,6 +259,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
259#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false) 259#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
260#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true) 260#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
261 261
262void dso__set_module_info(struct dso *dso, struct kmod_path *m,
263 struct machine *machine);
264
262/* 265/*
263 * The dso__data_* external interface provides following functions: 266 * The dso__data_* external interface provides following functions:
264 * dso__data_get_fd 267 * dso__data_get_fd
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 314a07151fb7..5cac8d5e009a 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,
1469 1469
1470 dso__set_build_id(dso, &bev->build_id); 1470 dso__set_build_id(dso, &bev->build_id);
1471 1471
1472 if (!is_kernel_module(filename, cpumode)) 1472 if (dso_type != DSO_TYPE_USER) {
1473 dso->kernel = dso_type; 1473 struct kmod_path m = { .name = NULL, };
1474
1475 if (!kmod_path__parse_name(&m, filename) && m.kmod)
1476 dso__set_module_info(dso, &m, machine);
1477 else
1478 dso->kernel = dso_type;
1479
1480 free(m.name);
1481 }
1474 1482
1475 build_id__sprintf(dso->build_id, sizeof(dso->build_id), 1483 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1476 sbuild_id); 1484 sbuild_id);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index d97e014c3df3..d7f31cb0a4cb 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
572 if (dso == NULL) 572 if (dso == NULL)
573 goto out_unlock; 573 goto out_unlock;
574 574
575 if (machine__is_host(machine)) 575 dso__set_module_info(dso, m, machine);
576 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
577 else
578 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
579
580 /* _KMODULE_COMP should be next to _KMODULE */
581 if (m->kmod && m->comp)
582 dso->symtab_type++;
583
584 dso__set_short_name(dso, strdup(m->name), true);
585 dso__set_long_name(dso, strdup(filename), true); 576 dso__set_long_name(dso, strdup(filename), true);
586 } 577 }
587 578
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index e7ee47f7377a..1fb2efae4f02 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -649,10 +649,7 @@ static int decompress_kmodule(struct dso *dso, const char *name,
649 type != DSO_BINARY_TYPE__BUILD_ID_CACHE) 649 type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
650 return -1; 650 return -1;
651 651
652 if (type == DSO_BINARY_TYPE__BUILD_ID_CACHE) 652 if (kmod_path__parse_ext(&m, dso->long_name) || !m.comp)
653 name = dso->long_name;
654
655 if (kmod_path__parse_ext(&m, name) || !m.comp)
656 return -1; 653 return -1;
657 654
658 fd = mkstemp(tmpbuf); 655 fd = mkstemp(tmpbuf);
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 943a06291587..da45c4be5fb3 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -39,6 +39,14 @@ static int __report_module(struct addr_location *al, u64 ip,
39 return 0; 39 return 0;
40 40
41 mod = dwfl_addrmodule(ui->dwfl, ip); 41 mod = dwfl_addrmodule(ui->dwfl, ip);
42 if (mod) {
43 Dwarf_Addr s;
44
45 dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
46 if (s != al->map->start)
47 mod = 0;
48 }
49
42 if (!mod) 50 if (!mod)
43 mod = dwfl_report_elf(ui->dwfl, dso->short_name, 51 mod = dwfl_report_elf(ui->dwfl, dso->short_name,
44 dso->long_name, -1, al->map->start, 52 dso->long_name, -1, al->map->start,
@@ -224,7 +232,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
224 232
225 err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui); 233 err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui);
226 234
227 if (err && !ui->max_stack) 235 if (err && ui->max_stack != max_stack)
228 err = 0; 236 err = 0;
229 237
230 /* 238 /*