Skip to contentSkip to conversation

perf/urgent fixes

GIT PULL New Arnaldo Carvalho de Melo 2 participants 13 messages Jun 6, 2017 – Jun 7, 2017 perf events

lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 6e30437bd42c4d4e9cfc4c40efda00eb83a11cde:

tools/include: Sync kernel ABI headers with tooling headers (2017-05-24 09:00:21 +0200)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-urgent-for-mingo-4.12-20170606

for you to fetch changes up to 2538b9e2450ae255337c04356e9e0f8cb9ec48d9:

perf report: Ensure the perf DSO mapping matches what libdw sees (2017-06-05 14:18:05 -0300)

----------------------------------------------------------------
perf/urgent fixes:

- 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)

----------------------------------------------------------------
Andi Kleen (1):
perf stat: Only print NMI watchdog hint when enabled

Jiri Olsa (2):
perf trace: Add mmap alias for s390
perf test: Disable breakpoint signal tests for powerpc

Kim Phillips (2):
perf annotate: Fix branch instruction with multiple operands perf annotate: Add missing powerpc triplet

Milian Wolff (2):
perf report: Include partial stacks unwound with libdw perf report: Ensure the perf DSO mapping matches what libdw sees

Namhyung Kim (3):
perf header: Set proper module name when build-id event found perf symbols: Set module info when build-id event found
perf symbols: Use correct filename for compressed modules in build-id cache

Ravi Bangoria (1):
perf annotate: Fix failure when filename has special chars

 tools/perf/arch/common.c        |  1 +
 tools/perf/builtin-stat.c       |  5 ++++-
 tools/perf/builtin-trace.c      |  4 ++++
 tools/perf/tests/bp_signal.c    | 14 ++++++++++++++
 tools/perf/tests/builtin-test.c |  7 +++++++
 tools/perf/tests/tests.h        |  3 +++
 tools/perf/util/annotate.c      | 35 +++++++++++++++++++++++++++++++----
 tools/perf/util/dso.c           | 15 +++++++++++++++
 tools/perf/util/dso.h           |  3 +++
 tools/perf/util/header.c        | 12 ++++++++++--
 tools/perf/util/machine.c       | 11 +----------
 tools/perf/util/symbol-elf.c    |  5 +----
 tools/perf/util/unwind-libdw.c  | 10 +++++++++-
 13 files changed, 103 insertions(+), 22 deletions(-)
author maintainer
#1 lore raw

PATCH 1/11 perf annotate: Fix failure when filename has special chars

From: Ravi Bangoria <[email protected]>

When filename contains special chars, perf annotate fails with an error:

  $ perf annotate --vmlinux ./vmlinux\(test\) --stdio native_safe_halt
    sh: -c: line 0: syntax error near unexpected token `('
    sh: -c: line 0: `objdump  --start-address=0xffffffff8184e840
    --stop-address=0xffffffff8184e848 -l -d --no-show-raw -S -C
    ./vmlinux(test) 2>/dev/null|grep -v ./vmlinux(test):|expand'

Fix it by surrounding filename in double quotes.

---
 tools/perf/util/annotate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/annotate.c +1 -1
index 683f8340460c..07d5608a675f 100644
@@ -1429,7 +1429,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
 	snprintf(command, sizeof(command),
 		 "%s %s%s --start-address=0x%016" PRIx64
 		 " --stop-address=0x%016" PRIx64
-		 " -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand",
+		 " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
 		 objdump_path ? objdump_path : "objdump",
 		 disassembler_style ? "-M " : "",
 		 disassembler_style ? disassembler_style : "",
Signature · 1 line
2.9.4
author maintainer
#2 lore raw

PATCH 2/11 perf trace: Add mmap alias for s390

In reply to Arnaldo Carvalho de Melo

From: Jiri Olsa <[email protected]>

The s390 architecture maps sys_mmap (nr 90) into sys_old_mmap. For this reason perf trace can't find the proper syscall event to get args format from and displays it wrongly as 'continued'.

To fix that fill the "alias" field with "old_mmap" for trace's mmap record to get the correct translation.

Before:

     0.042 ( 0.011 ms): vest/43052 fstat(statbuf: 0x3ffff89fd90                ) = 0
     0.042 ( 0.028 ms): vest/43052  ... [continued]: mmap()) = 0x3fffd6e2000
     0.072 ( 0.025 ms): vest/43052 read(buf: 0x3fffd6e2000, count: 4096        ) = 6

After:

     0.045 ( 0.011 ms): fstat(statbuf: 0x3ffff8a0930                           ) = 0
     0.057 ( 0.018 ms): mmap(arg: 0x3ffff8a0858                                ) = 0x3fffd14a000
     0.076 ( 0.025 ms): read(buf: 0x3fffd14a000, count: 4096                   ) = 6
---
 tools/perf/builtin-trace.c | 4 ++++
 1 file changed, 4 insertions(+)
tools/perf/builtin-trace.c +4 -0
index d014350adc52..4b2a5d298197 100644
@@ -681,6 +681,10 @@ static struct syscall_fmt {
 	{ .name	    = "mlockall",   .errmsg = true,
 	  .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
 	{ .name	    = "mmap",	    .hexret = true,
+/* The standard mmap maps to old_mmap on s390x */
+#if defined(__s390x__)
+	.alias = "old_mmap",
+#endif
 	  .arg_scnprintf = { [0] = SCA_HEX,	  /* addr */
 			     [2] = SCA_MMAP_PROT, /* prot */
 			     [3] = SCA_MMAP_FLAGS, /* flags */ }, },
Signature · 1 line
2.9.4
author maintainer
#3 lore raw

PATCH 3/11 perf annotate: Fix branch instruction with multiple operands

In reply to Arnaldo Carvalho de Melo

From: Kim Phillips <[email protected]>

'perf annotate' is dropping the cr* fields from branch instructions.

Fix it by adding support to display branch instructions having multiple operands.

Power Arch objdump of int_sqrt:

 20.36 | c0000000004d2694:   subf   r10,r10,r3
       | c0000000004d2698: v bgt    cr6,c0000000004d26a0 <int_sqrt+0x40>
  1.82 | c0000000004d269c:   mr     r3,r10
 29.18 | c0000000004d26a0:   mr     r10,r8
       | c0000000004d26a4: v bgt    cr7,c0000000004d26ac <int_sqrt+0x4c>
       | c0000000004d26a8:   mr     r10,r7

Power Arch Before Patch:

 20.36 |       subf   r10,r10,r3
       |     v bgt    40
  1.82 |       mr     r3,r10
 29.18 | 40:   mr     r10,r8
       |     v bgt    4c
       |       mr     r10,r7

Power Arch After patch:

 20.36 |       subf   r10,r10,r3
       |     v bgt    cr6,40
  1.82 |       mr     r3,r10
 29.18 | 40:   mr     r10,r8
       |     v bgt    cr7,4c
       |       mr     r10,r7

Also support AArch64 conditional branch instructions, which can have up to three operands:

Aarch64 Non-simplified (raw objdump) view:

       │ffff0000083cd11c: ↑ cbz    w0, ffff0000083cd100 <security_fil▒
...
  4.44 │ffff000│083cd134: ↓ tbnz   w0, #26, ffff0000083cd190 <securit▒
...
  1.37 │ffff000│083cd144: ↓ tbnz   w22, #5, ffff0000083cd1a4 <securit▒
       │ffff000│083cd148:   mov    w19, #0x20000                   //▒
  1.02 │ffff000│083cd14c: ↓ tbz    w22, #2, ffff0000083cd1ac <securit▒

...
0.68 │ffff000└──3cd16c: ↑ cbnz w0, ffff0000083cd120 <security_fil▒

Aarch64 Simplified, before this patch:

│ ↑ cbz 40
...
4.44 │ │↓ tbnz w0, #26, ffff0000083cd190 <security_file_permiss▒
...

  1.37 │   │↓ tbnz   w22, #5, ffff0000083cd1a4 <security_file_permiss▒
       │   │  mov    w19, #0x20000                   // #131072
  1.02 │   │↓ tbz    w22, #2, ffff0000083cd1ac <security_file_permiss▒

...
0.68 │ └──cbnz 60

the cbz operand is missing, and the tbz doesn't get simplified processing at all because the parsing function failed to match an address.

Aarch64 Simplified, After this patch applied:

│ ↑ cbz w0, 40
...
4.44 │ │↓ tbnz w0, #26, d0
...

  1.37 │   │↓ tbnz   w22, #5, e4
       │   │  mov    w19, #0x20000                   // #131072
  1.02 │   │↓ tbz    w22, #2, ec

...
0.68 │ └──cbnz w0, 60

---
 tools/perf/util/annotate.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)
tools/perf/util/annotate.c +30 -3
index 07d5608a675f..1367d7e35242 100644
@@ -239,10 +239,20 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 	const char *s = strchr(ops->raw, '+');
 	const char *c = strchr(ops->raw, ',');
 
-	if (c++ != NULL)
+	/*
+	 * skip over possible up to 2 operands to get to address, e.g.:
+	 * tbnz	 w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
+	 */
+	if (c++ != NULL) {
 		ops->target.addr = strtoull(c, NULL, 16);
-	else
+		if (!ops->target.addr) {
+			c = strchr(c, ',');
+			if (c++ != NULL)
+				ops->target.addr = strtoull(c, NULL, 16);
+		}
+	} else {
 		ops->target.addr = strtoull(ops->raw, NULL, 16);
+	}
 
 	if (s++ != NULL) {
 		ops->target.offset = strtoull(s, NULL, 16);
@@ -257,10 +267,27 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
 			   struct ins_operands *ops)
 {
+	const char *c = strchr(ops->raw, ',');
+
 	if (!ops->target.addr || ops->target.offset < 0)
 		return ins__raw_scnprintf(ins, bf, size, ops);
 
-	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
+	if (c != NULL) {
+		const char *c2 = strchr(c + 1, ',');
+
+		/* check for 3-op insn */
+		if (c2 != NULL)
+			c = c2;
+		c++;
+
+		/* mirror arch objdump's space-after-comma style */
+		if (*c == ' ')
+			c++;
+	}
+
+	return scnprintf(bf, size, "%-6.6s %.*s%" PRIx64,
+			 ins->name, c ? c - ops->raw : 0, ops->raw,
+			 ops->target.offset);
 }
 
 static struct ins_ops jump_ops = {
Signature · 1 line
2.9.4
author maintainer
#4 lore raw

PATCH 4/11 perf stat: Only print NMI watchdog hint when enabled

In reply to Arnaldo Carvalho de Melo

From: Andi Kleen <[email protected]>

Only print the NMI watchdog hint when that watchdog it actually enabled.

This avoids printing these unnecessarily.

---
 tools/perf/builtin-stat.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-stat.c +4 -1
index a935b5023732..ad9324d1daf9 100644
@@ -1578,6 +1578,7 @@ static void print_header(int argc, const char **argv)
 static void print_footer(void)
 {
 	FILE *output = stat_config.output;
+	int n;
 
 	if (!null_run)
 		fprintf(output, "\n");
@@ -1590,7 +1591,9 @@ static void print_footer(void)
 	}
 	fprintf(output, "\n\n");
 
-	if (print_free_counters_hint)
+	if (print_free_counters_hint &&
+	    sysctl__read_int("kernel/nmi_watchdog", &n) >= 0 &&
+	    n > 0)
 		fprintf(output,
 "Some events weren't counted. Try disabling the NMI watchdog:\n"
 "	echo 0 > /proc/sys/kernel/nmi_watchdog\n"
Signature · 1 line
2.9.4
author maintainer
#5 lore raw

PATCH 5/11 perf header: Set proper module name when build-id event found

In reply to Arnaldo Carvalho de Melo

From: Namhyung Kim <[email protected]>

When perf processes build-id event, it creates DSOs with the build-id. But it didn't set the module short name (like '[module-name]') so when processing a kernel mmap event of the module, it cannot found the DSO as it only checks the short names.

That leads for perf to create a same DSO without the build-id info and it'll lookup the system path even if the DSO is already in the build-id cache. After kernel was updated, perf cannot find the DSO and cannot show symbols in it anymore.

You can see this if you have an old data file (w/ old kernel version):

  $ perf report -i perf.data.old -v |& grep scsi_mod
  build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz : cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1
  Failed to open /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz, continuing without symbols
  ...

The second message didn't show the build-id. With this patch:

  $ perf report -i perf.data.old -v |& grep scsi_mod
  build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz: cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1
  /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz with build id cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 not found, continuing without symbols
  ...

Now it shows the build-id but still cannot load the symbol table. This is a different problem which will be fixed in the next patch.

Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Peter Zijlstra <[email protected]>
[ Fix the build on older compilers (debian <= 8, fedora <= 21, etc) wrt kmod_path var init ]
---
 tools/perf/util/header.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
tools/perf/util/header.c +10 -2
index 314a07151fb7..c40a4d8acf8b 100644
@@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,
 
 		dso__set_build_id(dso, &bev->build_id);
 
-		if (!is_kernel_module(filename, cpumode))
-			dso->kernel = dso_type;
+		if (dso_type != DSO_TYPE_USER) {
+			struct kmod_path m = { .name = NULL, };
+
+			if (!kmod_path__parse_name(&m, filename) && m.kmod)
+				dso__set_short_name(dso, strdup(m.name), true);
+			else
+				dso->kernel = dso_type;
+
+			free(m.name);
+		}
 
 		build_id__sprintf(dso->build_id, sizeof(dso->build_id),
 				  sbuild_id);
Signature · 1 line
2.9.4
author maintainer
#6 lore raw

PATCH 6/11 perf symbols: Set module info when build-id event found

In reply to Arnaldo Carvalho de Melo

From: Namhyung Kim <[email protected]>

Like machine__findnew_module_dso(), it should set necessary info for kernel modules to find symbol info from the file. Factor out dso__set_module_info() to do it.

This is needed for dso__needs_decompress() to detect such DSOs.

---
 tools/perf/util/dso.c     | 15 +++++++++++++++
 tools/perf/util/dso.h     |  3 +++
 tools/perf/util/header.c  |  2 +-
 tools/perf/util/machine.c | 11 +----------
 4 files changed, 20 insertions(+), 11 deletions(-)
tools/perf/util/dso.c +15 -0
index a96a99d2369f..b27d127cdf68 100644
@@ -335,6 +335,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
 	return 0;
 }
 
+void dso__set_module_info(struct dso *dso, struct kmod_path *m,
+			  struct machine *machine)
+{
+	if (machine__is_host(machine))
+		dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
+	else
+		dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
+
+	/* _KMODULE_COMP should be next to _KMODULE */
+	if (m->kmod && m->comp)
+		dso->symtab_type++;
+
+	dso__set_short_name(dso, strdup(m->name), true);
+}
+
 /*
  * Global list of open DSOs and the counter.
  */
tools/perf/util/dso.h +3 -0
index 12350b171727..5fe2ab5877bd 100644
@@ -259,6 +259,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
 #define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
 #define kmod_path__parse_ext(__m, __p)  __kmod_path__parse(__m, __p, false, true)
 
+void dso__set_module_info(struct dso *dso, struct kmod_path *m,
+			  struct machine *machine);
+
 /*
  * The dso__data_* external interface provides following functions:
  *   dso__data_get_fd
tools/perf/util/header.c +1 -1
index c40a4d8acf8b..5cac8d5e009a 100644
@@ -1473,7 +1473,7 @@ static int __event_process_build_id(struct build_id_event *bev,
 			struct kmod_path m = { .name = NULL, };
 
 			if (!kmod_path__parse_name(&m, filename) && m.kmod)
-				dso__set_short_name(dso, strdup(m.name), true);
+				dso__set_module_info(dso, &m, machine);
 			else
 				dso->kernel = dso_type;
 
tools/perf/util/machine.c +1 -10
index d97e014c3df3..d7f31cb0a4cb 100644
@@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
 		if (dso == NULL)
 			goto out_unlock;
 
-		if (machine__is_host(machine))
-			dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
-		else
-			dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
-
-		/* _KMODULE_COMP should be next to _KMODULE */
-		if (m->kmod && m->comp)
-			dso->symtab_type++;
-
-		dso__set_short_name(dso, strdup(m->name), true);
+		dso__set_module_info(dso, m, machine);
 		dso__set_long_name(dso, strdup(filename), true);
 	}
 
Signature · 1 line
2.9.4
author maintainer
#7 lore raw

PATCH 7/11 perf symbols: Use correct filename for compressed modules in build-id cache

In reply to Arnaldo Carvalho de Melo

From: Namhyung Kim <[email protected]>

The decompress_kmodule() decompresses kernel modules in order to load symbols from it. In the DSO_BINARY_TYPE__BUILD_ID_CACHE case, it needs the full file path to extract the file extension to determine the decompression method. But overwriting 'name' will fail the decompression since it might point to a non-existing old file.

Instead, use dso->long_name for having the correct extension and use the real filename to decompress.

In the DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP case, both names should be the same. This allows resolving symbols in the old modules.

Before:

  $ perf report -i perf.data.old | grep scsi_mod
     0.00%  cc1      [scsi_mod]    [k] 0x0000000000004aa6
     0.00%  as       [scsi_mod]    [k] 0x00000000000099e1
     0.00%  cc1      [scsi_mod]    [k] 0x0000000000009830
     0.00%  cc1      [scsi_mod]    [k] 0x0000000000001b8f

After:

     0.00%  cc1      [scsi_mod]    [k] scsi_handle_queue_ramp_up
     0.00%  as       [scsi_mod]    [k] scsi_sg_alloc
     0.00%  cc1      [scsi_mod]    [k] scsi_setup_cmnd
     0.00%  cc1      [scsi_mod]    [k] scsi_get_command
---
 tools/perf/util/symbol-elf.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/util/symbol-elf.c +1 -4
index e7ee47f7377a..1fb2efae4f02 100644
@@ -649,10 +649,7 @@ static int decompress_kmodule(struct dso *dso, const char *name,
 	    type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
 		return -1;
 
-	if (type == DSO_BINARY_TYPE__BUILD_ID_CACHE)
-		name = dso->long_name;
-
-	if (kmod_path__parse_ext(&m, name) || !m.comp)
+	if (kmod_path__parse_ext(&m, dso->long_name) || !m.comp)
 		return -1;
 
 	fd = mkstemp(tmpbuf);
Signature · 1 line
2.9.4
author maintainer
#8 lore raw

PATCH 8/11 perf test: Disable breakpoint signal tests for powerpc

In reply to Arnaldo Carvalho de Melo

From: Jiri Olsa <[email protected]>

The following tests are failing on powerpc:

  # perf test break
  18: Breakpoint overflow signal handler  : FAILED!
  19: Breakpoint overflow sampling        : FAILED!

The powerpc kenel so far does not have support to even create instruction breakpoints using the perf event interface, so those tests fail early in the config phase.

I added a '->is_supported()' callback to test struct to be able to disable specific tests. It seems better than putting ifdefs directly to the test array.

---
 tools/perf/tests/bp_signal.c    | 14 ++++++++++++++
 tools/perf/tests/builtin-test.c |  7 +++++++
 tools/perf/tests/tests.h        |  3 +++
 3 files changed, 24 insertions(+)
tools/perf/tests/bp_signal.c +14 -0
index e7664fe3bd33..8ba2c4618fe9 100644
@@ -288,3 +288,17 @@ int test__bp_signal(int subtest __maybe_unused)
 	return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
 		TEST_OK : TEST_FAIL;
 }
+
+bool test__bp_signal_is_supported(void)
+{
+/*
+ * The powerpc so far does not have support to even create
+ * instruction breakpoint using the perf event interface.
+ * Once it's there we can release this.
+ */
+#ifdef __powerpc__
+	return false;
+#else
+	return true;
+#endif
+}
tools/perf/tests/builtin-test.c +7 -0
index 9e08d297f1a9..3ccfd58a8c3c 100644
@@ -97,10 +97,12 @@ static struct test generic_tests[] = {
 	{
 		.desc = "Breakpoint overflow signal handler",
 		.func = test__bp_signal,
+		.is_supported = test__bp_signal_is_supported,
 	},
 	{
 		.desc = "Breakpoint overflow sampling",
 		.func = test__bp_signal_overflow,
+		.is_supported = test__bp_signal_is_supported,
 	},
 	{
 		.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)
 		if (!perf_test__matches(t, curr, argc, argv))
 			continue;
 
+		if (t->is_supported && !t->is_supported()) {
+			pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc);
+			continue;
+		}
+
 		pr_info("%2d: %-*s:", i, width, t->desc);
 
 		if (intlist__find(skiplist, i)) {
tools/perf/tests/tests.h +3 -0
index 631859629403..577363809c9b 100644
@@ -34,6 +34,7 @@ struct test {
 		int (*get_nr)(void);
 		const char *(*get_desc)(int subtest);
 	} subtest;
+	bool (*is_supported)(void);
 };
 
 /* Tests */
@@ -99,6 +100,8 @@ const char *test__clang_subtest_get_desc(int subtest);
 int test__clang_subtest_get_nr(void);
 int test__unit_number__scnprint(int subtest);
 
+bool test__bp_signal_is_supported(void);
+
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
 struct thread;
Signature · 1 line
2.9.4
author maintainer
#9 lore raw

PATCH 9/11 perf annotate: Add missing powerpc triplet

In reply to Arnaldo Carvalho de Melo

From: Kim Phillips <[email protected]>

On an Ubuntu xenial system, 'perf annotate' says to install powerpc objdump on a system that already has binutils-powerpc-linux-gnu installed. Make perf aware of the missing triplet for the powerpc-linux-gnu target.

---
 tools/perf/arch/common.c | 1 +
 1 file changed, 1 insertion(+)
tools/perf/arch/common.c +1 -0
index 837067f48a4c..6b40e9f01740 100644
@@ -26,6 +26,7 @@ const char *const arm64_triplets[] = {
 
 const char *const powerpc_triplets[] = {
 	"powerpc-unknown-linux-gnu-",
+	"powerpc-linux-gnu-",
 	"powerpc64-unknown-linux-gnu-",
 	"powerpc64-linux-gnu-",
 	"powerpc64le-linux-gnu-",
Signature · 1 line
2.9.4
author maintainer
#10 lore raw

PATCH 10/11 perf report: Include partial stacks unwound with libdw

In reply to Arnaldo Carvalho de Melo

From: Milian Wolff <[email protected]>

So far the whole stack was thrown away when any error occurred before the maximum stack depth was unwound. This is actually a very common scenario though. The stacks that got unwound so far are still interesting. This removes a large chunk of differences when comparing perf script output for libunwind and libdw perf unwinding.

E.g. with libunwind:

~~~~~
heaptrack_gui 2228 135073.388524: 479408 cycles:

        ffffffff811749ed perf_iterate_ctx ([kernel.kallsyms])
        ffffffff81181662 perf_event_mmap ([kernel.kallsyms])
        ffffffff811cf5ed mmap_region ([kernel.kallsyms])
        ffffffff811cfe6b do_mmap ([kernel.kallsyms])
        ffffffff811b0dca vm_mmap_pgoff ([kernel.kallsyms])
        ffffffff811cdb0c sys_mmap_pgoff ([kernel.kallsyms])
        ffffffff81033acb sys_mmap ([kernel.kallsyms])
        ffffffff81631d37 entry_SYSCALL_64_fastpath ([kernel.kallsyms])
                   192ca mmap64 (/usr/lib/ld-2.25.so)
                    59a9 _dl_map_object_from_fd (/usr/lib/ld-2.25.so)
                    83d0 _dl_map_object (/usr/lib/ld-2.25.so)
                    cda1 openaux (/usr/lib/ld-2.25.so)
                   1834f _dl_catch_error (/usr/lib/ld-2.25.so)
                    cfe2 _dl_map_object_deps (/usr/lib/ld-2.25.so)
                    3481 dl_main (/usr/lib/ld-2.25.so)
                   17387 _dl_sysdep_start (/usr/lib/ld-2.25.so)
                    4d37 _dl_start (/usr/lib/ld-2.25.so)
                     d87 _start (/usr/lib/ld-2.25.so)

heaptrack_gui 2228 135073.388677: 611329 cycles:

                   1a3e0 strcmp (/usr/lib/ld-2.25.so)
                    82b2 _dl_map_object (/usr/lib/ld-2.25.so)
                    cda1 openaux (/usr/lib/ld-2.25.so)
                   1834f _dl_catch_error (/usr/lib/ld-2.25.so)
                    cfe2 _dl_map_object_deps (/usr/lib/ld-2.25.so)
                    3481 dl_main (/usr/lib/ld-2.25.so)
                   17387 _dl_sysdep_start (/usr/lib/ld-2.25.so)
                    4d37 _dl_start (/usr/lib/ld-2.25.so)
                     d87 _start (/usr/lib/ld-2.25.so)

~~~~~

With libdw without this patch:

~~~~~
heaptrack_gui 2228 135073.388524: 479408 cycles:
ffffffff811749ed perf_iterate_ctx ([kernel.kallsyms]) ffffffff81181662 perf_event_mmap ([kernel.kallsyms]) ffffffff811cf5ed mmap_region ([kernel.kallsyms]) ffffffff811cfe6b do_mmap ([kernel.kallsyms]) ffffffff811b0dca vm_mmap_pgoff ([kernel.kallsyms]) ffffffff811cdb0c sys_mmap_pgoff ([kernel.kallsyms]) ffffffff81033acb sys_mmap ([kernel.kallsyms]) ffffffff81631d37 entry_SYSCALL_64_fastpath ([kernel.kallsyms])

heaptrack_gui 2228 135073.388677: 611329 cycles:
~~~~~

With this patch applied, the libdw unwinder will produce the same output as the libunwind unwinder.

---
 tools/perf/util/unwind-libdw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/unwind-libdw.c +1 -1
index 943a06291587..b4c20124d2ee 100644
@@ -224,7 +224,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
 
 	err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui);
 
-	if (err && !ui->max_stack)
+	if (err && ui->max_stack != max_stack)
 		err = 0;
 
 	/*
Signature · 1 line
2.9.4
author maintainer
#11 lore raw

PATCH 11/11 perf report: Ensure the perf DSO mapping matches what libdw sees

In reply to Arnaldo Carvalho de Melo

From: Milian Wolff <[email protected]>

In some situations the libdw unwinder stopped working properly. I.e. with libunwind we see:

~~~~~
heaptrack_gui 2228 135073.400112: 641314 cycles:

	            e8ed _dl_fixup (/usr/lib/ld-2.25.so)
	           15f06 _dl_runtime_resolve_sse_vex (/usr/lib/ld-2.25.so)
	           ed94c KDynamicJobTracker::KDynamicJobTracker (/home/milian/projects/compiled/kf5/lib64/libKF5KIOWidgets.so.5.35.0)
	           608f3 _GLOBAL__sub_I_kdynamicjobtracker.cpp (/home/milian/projects/compiled/kf5/lib64/libKF5KIOWidgets.so.5.35.0)
	            f199 call_init.part.0 (/usr/lib/ld-2.25.so)
	            f2a5 _dl_init (/usr/lib/ld-2.25.so)
	             db9 _dl_start_user (/usr/lib/ld-2.25.so)

~~~~~

But with libdw and without this patch this sample is not properly unwound:

~~~~~
heaptrack_gui 2228 135073.400112: 641314 cycles:

	            e8ed _dl_fixup (/usr/lib/ld-2.25.so)
	           15f06 _dl_runtime_resolve_sse_vex (/usr/lib/ld-2.25.so)
	           ed94c KDynamicJobTracker::KDynamicJobTracker (/home/milian/projects/compiled/kf5/lib64/libKF5KIOWidgets.so.5.35.0)

~~~~~

Debug output showed me that libdw found a module for the last frame address, but it thinks it belongs to /usr/lib/ld-2.25.so. This patch double-checks what libdw sees and what perf knows. If the mappings mismatch, we now report the elf known to perf. This fixes the situation above, and the libdw unwinder produces the same stack as libunwind.

---
 tools/perf/util/unwind-libdw.c | 8 ++++++++
 1 file changed, 8 insertions(+)
tools/perf/util/unwind-libdw.c +8 -0
index b4c20124d2ee..da45c4be5fb3 100644
@@ -39,6 +39,14 @@ static int __report_module(struct addr_location *al, u64 ip,
 		return 0;
 
 	mod = dwfl_addrmodule(ui->dwfl, ip);
+	if (mod) {
+		Dwarf_Addr s;
+
+		dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
+		if (s != al->map->start)
+			mod = 0;
+	}
+
 	if (!mod)
 		mod = dwfl_report_elf(ui->dwfl, dso->short_name,
 				      dso->long_name, -1, al->map->start,
Signature · 1 line
2.9.4
#12 lore raw
In reply to Arnaldo Carvalho de Melo
Quoted 70 lines · Arnaldo Carvalho de Melo

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 6e30437bd42c4d4e9cfc4c40efda00eb83a11cde:

tools/include: Sync kernel ABI headers with tooling headers (2017-05-24 09:00:21 +0200)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-urgent-for-mingo-4.12-20170606

for you to fetch changes up to 2538b9e2450ae255337c04356e9e0f8cb9ec48d9:

perf report: Ensure the perf DSO mapping matches what libdw sees (2017-06-05 14:18:05 -0300)

----------------------------------------------------------------
perf/urgent fixes:

- 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)

----------------------------------------------------------------
Andi Kleen (1):
perf stat: Only print NMI watchdog hint when enabled

Jiri Olsa (2):
perf trace: Add mmap alias for s390
perf test: Disable breakpoint signal tests for powerpc

Kim Phillips (2):
perf annotate: Fix branch instruction with multiple operands perf annotate: Add missing powerpc triplet

Milian Wolff (2):
perf report: Include partial stacks unwound with libdw perf report: Ensure the perf DSO mapping matches what libdw sees

Namhyung Kim (3):
perf header: Set proper module name when build-id event found perf symbols: Set module info when build-id event found
perf symbols: Use correct filename for compressed modules in build-id cache

Ravi Bangoria (1):
perf annotate: Fix failure when filename has special chars

Quoted 14 lines
 tools/perf/arch/common.c        |  1 +
 tools/perf/builtin-stat.c       |  5 ++++-
 tools/perf/builtin-trace.c      |  4 ++++
 tools/perf/tests/bp_signal.c    | 14 ++++++++++++++
 tools/perf/tests/builtin-test.c |  7 +++++++
 tools/perf/tests/tests.h        |  3 +++
 tools/perf/util/annotate.c      | 35 +++++++++++++++++++++++++++++++----
 tools/perf/util/dso.c           | 15 +++++++++++++++
 tools/perf/util/dso.h           |  3 +++
 tools/perf/util/header.c        | 12 ++++++++++--
 tools/perf/util/machine.c       | 11 +----------
 tools/perf/util/symbol-elf.c    |  5 +----
 tools/perf/util/unwind-libdw.c  | 10 +++++++++-
 13 files changed, 103 insertions(+), 22 deletions(-)

Pulled, thanks a lot Arnaldo!

Ingo