linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] perf probe fixes for ppc64le
@ 2016-04-12  9:10 Naveen N. Rao
  2016-04-12  9:10 ` [PATCH v2 1/2] perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le Naveen N. Rao
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Naveen N. Rao @ 2016-04-12  9:10 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: Mark Wielaard, Thiago Jung Bauermann, Arnaldo Carvalho de Melo,
	Masami Hiramatsu, Michael Ellerman, Balbir Singh,
	Ananth N Mavinakayanahalli

This patchset fixes three issues found with perf probe on ppc64le:
1. 'perf test kallsyms' failure on ppc64le (reported by Michael
Ellerman). This was due to the symbols being fixed up during symbol
table load. This is fixed in patch 2 by delaying symbol fixup until
later.
2. perf probe function offset was being calculated from the local entry
point (LEP), which does not match user expectation when trying to look
at function disassembly output (reported by Ananth N). This is fixed for
kallsyms in patch 1 and for symbol table in patch 2.
3. perf probe failure with kretprobe when using kallsyms. This was
failing as we were specifying an offset. This is fixed in patch 1.

A few examples demonstrating the issues and the fix:

Example for issue (2):
--------------------
    # objdump -d vmlinux | grep -A8 \<_do_fork\>:
    c0000000000b6a00 <_do_fork>:
    c0000000000b6a00:	f7 00 4c 3c 	addis   r2,r12,247
    c0000000000b6a04:	00 86 42 38 	addi    r2,r2,-31232
    c0000000000b6a08:	a6 02 08 7c 	mflr    r0
    c0000000000b6a0c:	d0 ff 41 fb 	std     r26,-48(r1)
    c0000000000b6a10:	26 80 90 7d 	mfocrf  r12,8
    c0000000000b6a14:	d8 ff 61 fb 	std     r27,-40(r1)
    c0000000000b6a18:	e0 ff 81 fb 	std     r28,-32(r1)
    c0000000000b6a1c:	e8 ff a1 fb 	std     r29,-24(r1)
    # perf probe -v _do_fork+4
    probe-definition(0): _do_fork+4 
    symbol:_do_fork file:(null) line:0 offset:4 return:0 lazy:(null)
    0 arguments
    Looking at the vmlinux_path (8 entries long)
    Using /proc/kcore for kernel object code
    Using /proc/kallsyms for symbols
    Opening /sys/kernel/debug/tracing//kprobe_events write=1
    Writing event: p:probe/_do_fork _text+748044
    Added new event:
      probe:_do_fork       (on _do_fork+4)

    You can now use it in all perf tools, such as:

	    perf record -e probe:_do_fork -aR sleep 1

    # printf "%x\n" 748044
    b6a0c
    ^^^^^
This is offset from the LEP. With this, there is also no way to ever
probe between the GEP and the LEP.

With this patchset:
    # perf probe -v _do_fork+4
    probe-definition(0): _do_fork+4 
    symbol:_do_fork file:(null) line:0 offset:4 return:0 lazy:(null)
    0 arguments
    Looking at the vmlinux_path (8 entries long)
    Using /proc/kcore for kernel object code
    Using /proc/kallsyms for symbols
    Opening /sys/kernel/debug/tracing//kprobe_events write=1
    Writing event: p:probe/_do_fork _text+748036
    Added new event:
      probe:_do_fork       (on _do_fork+4)

    You can now use it in all perf tools, such as:

	    perf record -e probe:_do_fork -aR sleep 1

    # perf probe -v _do_fork
    probe-definition(0): _do_fork 
    symbol:_do_fork file:(null) line:0 offset:0 return:0 lazy:(null)
    0 arguments
    Looking at the vmlinux_path (8 entries long)
    Using /proc/kcore for kernel object code
    Using /proc/kallsyms for symbols
    Opening /sys/kernel/debug/tracing//kprobe_events write=1
    Writing event: p:probe/_do_fork _text+748040
    Added new event:
      probe:_do_fork       (on _do_fork)

    You can now use it in all perf tools, such as:

	    perf record -e probe:_do_fork -aR sleep 1

We only offset to the LEP if function entry is specified, otherwise, we
offset from the GEP.

Example for issue (3):
---------------------
Before patch:
    # perf probe -v _do_fork:%return
    probe-definition(0): _do_fork:%return 
    symbol:_do_fork file:(null) line:0 offset:0 return:1 lazy:(null)
    0 arguments
    Looking at the vmlinux_path (8 entries long)
    Using /proc/kcore for kernel object code
    Using /proc/kallsyms for symbols
    Opening /sys/kernel/debug/tracing//kprobe_events write=1
    Writing event: r:probe/_do_fork _do_fork+8
    Failed to write event: Invalid argument
      Error: Failed to add events. Reason: Invalid argument (Code: -22)

After patch:
    # perf probe _do_fork:%return
    Added new event:
      probe:_do_fork       (on _do_fork%return)

    You can now use it in all perf tools, such as:

	    perf record -e probe:_do_fork -aR sleep 1


Concept Acked-by: Michael Ellerman <mpe@ellerman.id.au>

Cc: Mark Wielaard <mjw@redhat.com>
Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

Naveen N. Rao (2):
  perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le
  perf tools: Fix kallsyms perf test on ppc64le

 tools/perf/arch/powerpc/util/sym-handling.c | 43 +++++++++++++++++++++--------
 tools/perf/util/probe-event.c               |  5 ++--
 tools/perf/util/probe-event.h               |  3 +-
 tools/perf/util/symbol-elf.c                |  7 +++--
 tools/perf/util/symbol.h                    |  3 +-
 5 files changed, 43 insertions(+), 18 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/2] perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le
  2016-04-12  9:10 [PATCH v2 0/2] perf probe fixes for ppc64le Naveen N. Rao
@ 2016-04-12  9:10 ` Naveen N. Rao
  2016-05-06  6:44   ` [tip:perf/core] perf powerpc: " tip-bot for Naveen N. Rao
  2016-04-12  9:10 ` [PATCH v2 2/2] perf tools: Fix kallsyms perf test " Naveen N. Rao
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Naveen N. Rao @ 2016-04-12  9:10 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: Mark Wielaard, Thiago Jung Bauermann, Arnaldo Carvalho de Melo,
	Masami Hiramatsu, Michael Ellerman, Balbir Singh

So far, we used to treat probe point offsets as being offset from the
LEP. However, userspace applications (objdump/readelf) always show
disassembly and offsets from the function GEP. This is confusing to the
user as we will end up probing at an address different from what the
user expects when looking at the function disassembly with
readelf/objdump. Fix this by changing how we modify probe address with
perf.

If only the function name is provided, we assume the user needs the LEP.
Otherwise, if an offset is specified, we assume that the user knows the
exact address to probe based on function disassembly, and so we just
place the probe from the GEP offset.

Finally, kretprobe was also broken with kallsyms as we were trying to
specify an offset. This patch also fixes that issue.

Cc: Mark Wielaard <mjw@redhat.com>
Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Balbir Singh <bsingharora@gmail.com>
Reported-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
v2: Removed un-necessary check for uprobes

 tools/perf/arch/powerpc/util/sym-handling.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c
index bbc1a50..6974ba0 100644
--- a/tools/perf/arch/powerpc/util/sym-handling.c
+++ b/tools/perf/arch/powerpc/util/sym-handling.c
@@ -71,12 +71,21 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
 			     struct probe_trace_event *tev, struct map *map)
 {
 	/*
-	 * ppc64 ABIv2 local entry point is currently always 2 instructions
-	 * (8 bytes) after the global entry point.
+	 * When probing at a function entry point, we normally always want the
+	 * LEP since that catches calls to the function through both the GEP and
+	 * the LEP. Hence, we would like to probe at an offset of 8 bytes if
+	 * the user only specified the function entry.
+	 *
+	 * However, if the user specifies an offset, we fall back to using the
+	 * GEP since all userspace applications (objdump/readelf) show function
+	 * disassembly with offsets from the GEP.
+	 *
+	 * In addition, we shouldn't specify an offset for kretprobes.
 	 */
-	if (!pev->uprobes && map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
-		tev->point.address += PPC64LE_LEP_OFFSET;
+	if (pev->point.offset || pev->point.retprobe || !map)
+		return;
+
+	if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
 		tev->point.offset += PPC64LE_LEP_OFFSET;
-	}
 }
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/2] perf tools: Fix kallsyms perf test on ppc64le
  2016-04-12  9:10 [PATCH v2 0/2] perf probe fixes for ppc64le Naveen N. Rao
  2016-04-12  9:10 ` [PATCH v2 1/2] perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le Naveen N. Rao
@ 2016-04-12  9:10 ` Naveen N. Rao
  2016-05-06  6:45   ` [tip:perf/core] perf symbols: " tip-bot for Naveen N. Rao
  2016-04-14  1:16 ` [PATCH v2 0/2] perf probe fixes for ppc64le Balbir Singh
  2016-04-27 16:20 ` Naveen N. Rao
  3 siblings, 1 reply; 7+ messages in thread
From: Naveen N. Rao @ 2016-04-12  9:10 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: Mark Wielaard, Thiago Jung Bauermann, Arnaldo Carvalho de Melo,
	Masami Hiramatsu, Balbir Singh

ppc64le functions have a Global Entry Point (GEP) and a Local Entry
Point (LEP). While placing a probe, we always prefer the LEP since it
catches function calls through both the GEP and the LEP. In order to do
this, we fixup the function entry points during elf symbol table lookup
to point to the LEPs. This works, but breaks 'perf test kallsyms' since
the symbols loaded from the symbol table (pointing to the LEP) do not
match the symbols in kallsyms.

To fix this, we do not adjust all the symbols during symbol table load.
Instead, we note down st_other in a newly introduced arch-specific
member of perf symbol structure, and later use this to adjust the probe
trace point.

Cc: Mark Wielaard <mjw@redhat.com>
Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Balbir Singh <bsingharora@gmail.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Reported-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
v2: Added uprobes handling -- we modify the probe address, rather than
the offset.

 tools/perf/arch/powerpc/util/sym-handling.c | 28 ++++++++++++++++++++--------
 tools/perf/util/probe-event.c               |  5 +++--
 tools/perf/util/probe-event.h               |  3 ++-
 tools/perf/util/symbol-elf.c                |  7 ++++---
 tools/perf/util/symbol.h                    |  3 ++-
 5 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c
index 6974ba0..c6d0f91 100644
--- a/tools/perf/arch/powerpc/util/sym-handling.c
+++ b/tools/perf/arch/powerpc/util/sym-handling.c
@@ -19,12 +19,6 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
 	       ehdr.e_type == ET_DYN;
 }
 
-#if defined(_CALL_ELF) && _CALL_ELF == 2
-void arch__elf_sym_adjust(GElf_Sym *sym)
-{
-	sym->st_value += PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
-}
-#endif
 #endif
 
 #if !defined(_CALL_ELF) || _CALL_ELF != 2
@@ -65,11 +59,21 @@ bool arch__prefers_symtab(void)
 	return true;
 }
 
+#ifdef HAVE_LIBELF_SUPPORT
+void arch__sym_update(struct symbol *s, GElf_Sym *sym)
+{
+	s->arch_sym = sym->st_other;
+}
+#endif
+
 #define PPC64LE_LEP_OFFSET	8
 
 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
-			     struct probe_trace_event *tev, struct map *map)
+			     struct probe_trace_event *tev, struct map *map,
+			     struct symbol *sym)
 {
+	int lep_offset;
+
 	/*
 	 * When probing at a function entry point, we normally always want the
 	 * LEP since that catches calls to the function through both the GEP and
@@ -82,10 +86,18 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
 	 *
 	 * In addition, we shouldn't specify an offset for kretprobes.
 	 */
-	if (pev->point.offset || pev->point.retprobe || !map)
+	if (pev->point.offset || pev->point.retprobe || !map || !sym)
 		return;
 
+	lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
+
 	if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
 		tev->point.offset += PPC64LE_LEP_OFFSET;
+	else if (lep_offset) {
+		if (pev->uprobes)
+			tev->point.address += lep_offset;
+		else
+			tev->point.offset += lep_offset;
+	}
 }
 #endif
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 8319fbb..d786a49 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2498,7 +2498,8 @@ static int find_probe_functions(struct map *map, char *name,
 
 void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
 				struct probe_trace_event *tev __maybe_unused,
-				struct map *map __maybe_unused) { }
+				struct map *map __maybe_unused,
+				struct symbol *sym __maybe_unused) { }
 
 /*
  * Find probe function addresses from map.
@@ -2624,7 +2625,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
 					strdup_or_goto(pev->args[i].type,
 							nomem_out);
 		}
-		arch__fix_tev_from_maps(pev, tev, map);
+		arch__fix_tev_from_maps(pev, tev, map, sym);
 	}
 	if (ret == skipped) {
 		ret = -ENOENT;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index e54e7b0..9bbc0c1 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -154,7 +154,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
 int show_available_funcs(const char *module, struct strfilter *filter, bool user);
 bool arch__prefers_symtab(void);
 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
-			     struct probe_trace_event *tev, struct map *map);
+			     struct probe_trace_event *tev, struct map *map,
+			     struct symbol *sym);
 
 /* If there is no space to write, returns -E2BIG. */
 int e_snprintf(char *str, size_t size, const char *format, ...)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index bc229a7..e6c032e 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -777,7 +777,8 @@ static bool want_demangle(bool is_kernel_sym)
 	return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
 }
 
-void __weak arch__elf_sym_adjust(GElf_Sym *sym __maybe_unused) { }
+void __weak arch__sym_update(struct symbol *s __maybe_unused,
+		GElf_Sym *sym __maybe_unused) { }
 
 int dso__load_sym(struct dso *dso, struct map *map,
 		  struct symsrc *syms_ss, struct symsrc *runtime_ss,
@@ -954,8 +955,6 @@ int dso__load_sym(struct dso *dso, struct map *map,
 		    (sym.st_value & 1))
 			--sym.st_value;
 
-		arch__elf_sym_adjust(&sym);
-
 		if (dso->kernel || kmodule) {
 			char dso_name[PATH_MAX];
 
@@ -1089,6 +1088,8 @@ new_symbol:
 		if (!f)
 			goto out_elf_end;
 
+		arch__sym_update(f, &sym);
+
 		if (filter && filter(curr_map, f))
 			symbol__delete(f);
 		else {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index c8b7544..f0e62e8 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -55,6 +55,7 @@ struct symbol {
 	u16		namelen;
 	u8		binding;
 	bool		ignore;
+	u8		arch_sym;
 	char		name[0];
 };
 
@@ -310,7 +311,7 @@ int setup_intlist(struct intlist **list, const char *list_str,
 
 #ifdef HAVE_LIBELF_SUPPORT
 bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
-void arch__elf_sym_adjust(GElf_Sym *sym);
+void arch__sym_update(struct symbol *s, GElf_Sym *sym);
 #endif
 
 #define SYMBOL_A 0
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/2] perf probe fixes for ppc64le
  2016-04-12  9:10 [PATCH v2 0/2] perf probe fixes for ppc64le Naveen N. Rao
  2016-04-12  9:10 ` [PATCH v2 1/2] perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le Naveen N. Rao
  2016-04-12  9:10 ` [PATCH v2 2/2] perf tools: Fix kallsyms perf test " Naveen N. Rao
@ 2016-04-14  1:16 ` Balbir Singh
  2016-04-27 16:20 ` Naveen N. Rao
  3 siblings, 0 replies; 7+ messages in thread
From: Balbir Singh @ 2016-04-14  1:16 UTC (permalink / raw)
  To: Naveen N. Rao, linux-kernel, linuxppc-dev
  Cc: Mark Wielaard, Thiago Jung Bauermann, Arnaldo Carvalho de Melo,
	Masami Hiramatsu, Michael Ellerman, Ananth N Mavinakayanahalli



On 12/04/16 19:10, Naveen N. Rao wrote:
> This patchset fixes three issues found with perf probe on ppc64le:
> 1. 'perf test kallsyms' failure on ppc64le (reported by Michael
> Ellerman). This was due to the symbols being fixed up during symbol
> table load. This is fixed in patch 2 by delaying symbol fixup until
> later.
> 2. perf probe function offset was being calculated from the local entry
> point (LEP), which does not match user expectation when trying to look
> at function disassembly output (reported by Ananth N). This is fixed for
> kallsyms in patch 1 and for symbol table in patch 2.
> 3. perf probe failure with kretprobe when using kallsyms. This was
> failing as we were specifying an offset. This is fixed in patch 1.
> 
> A few examples demonstrating the issues and the fix:
> 

Given the choices, I think this makes sense

Acked-by: Balbir Singh <bsingharora@gmail.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/2] perf probe fixes for ppc64le
  2016-04-12  9:10 [PATCH v2 0/2] perf probe fixes for ppc64le Naveen N. Rao
                   ` (2 preceding siblings ...)
  2016-04-14  1:16 ` [PATCH v2 0/2] perf probe fixes for ppc64le Balbir Singh
@ 2016-04-27 16:20 ` Naveen N. Rao
  3 siblings, 0 replies; 7+ messages in thread
From: Naveen N. Rao @ 2016-04-27 16:20 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, Arnaldo Carvalho de Melo
  Cc: Mark Wielaard, Thiago Jung Bauermann, Masami Hiramatsu,
	Michael Ellerman, Balbir Singh, Ananth N Mavinakayanahalli

On 2016/04/12 02:40PM, Naveen N Rao wrote:
> This patchset fixes three issues found with perf probe on ppc64le:
> 1. 'perf test kallsyms' failure on ppc64le (reported by Michael
> Ellerman). This was due to the symbols being fixed up during symbol
> table load. This is fixed in patch 2 by delaying symbol fixup until
> later.
> 2. perf probe function offset was being calculated from the local entry
> point (LEP), which does not match user expectation when trying to look
> at function disassembly output (reported by Ananth N). This is fixed for
> kallsyms in patch 1 and for symbol table in patch 2.
> 3. perf probe failure with kretprobe when using kallsyms. This was
> failing as we were specifying an offset. This is fixed in patch 1.
> 
> A few examples demonstrating the issues and the fix:
> 
> Example for issue (2):
> --------------------
>     # objdump -d vmlinux | grep -A8 \<_do_fork\>:
>     c0000000000b6a00 <_do_fork>:
>     c0000000000b6a00:	f7 00 4c 3c 	addis   r2,r12,247
>     c0000000000b6a04:	00 86 42 38 	addi    r2,r2,-31232
>     c0000000000b6a08:	a6 02 08 7c 	mflr    r0
>     c0000000000b6a0c:	d0 ff 41 fb 	std     r26,-48(r1)
>     c0000000000b6a10:	26 80 90 7d 	mfocrf  r12,8
>     c0000000000b6a14:	d8 ff 61 fb 	std     r27,-40(r1)
>     c0000000000b6a18:	e0 ff 81 fb 	std     r28,-32(r1)
>     c0000000000b6a1c:	e8 ff a1 fb 	std     r29,-24(r1)
>     # perf probe -v _do_fork+4
>     probe-definition(0): _do_fork+4 
>     symbol:_do_fork file:(null) line:0 offset:4 return:0 lazy:(null)
>     0 arguments
>     Looking at the vmlinux_path (8 entries long)
>     Using /proc/kcore for kernel object code
>     Using /proc/kallsyms for symbols
>     Opening /sys/kernel/debug/tracing//kprobe_events write=1
>     Writing event: p:probe/_do_fork _text+748044
>     Added new event:
>       probe:_do_fork       (on _do_fork+4)
> 
>     You can now use it in all perf tools, such as:
> 
> 	    perf record -e probe:_do_fork -aR sleep 1
> 
>     # printf "%x\n" 748044
>     b6a0c
>     ^^^^^
> This is offset from the LEP. With this, there is also no way to ever
> probe between the GEP and the LEP.
> 
> With this patchset:
>     # perf probe -v _do_fork+4
>     probe-definition(0): _do_fork+4 
>     symbol:_do_fork file:(null) line:0 offset:4 return:0 lazy:(null)
>     0 arguments
>     Looking at the vmlinux_path (8 entries long)
>     Using /proc/kcore for kernel object code
>     Using /proc/kallsyms for symbols
>     Opening /sys/kernel/debug/tracing//kprobe_events write=1
>     Writing event: p:probe/_do_fork _text+748036
>     Added new event:
>       probe:_do_fork       (on _do_fork+4)
> 
>     You can now use it in all perf tools, such as:
> 
> 	    perf record -e probe:_do_fork -aR sleep 1
> 
>     # perf probe -v _do_fork
>     probe-definition(0): _do_fork 
>     symbol:_do_fork file:(null) line:0 offset:0 return:0 lazy:(null)
>     0 arguments
>     Looking at the vmlinux_path (8 entries long)
>     Using /proc/kcore for kernel object code
>     Using /proc/kallsyms for symbols
>     Opening /sys/kernel/debug/tracing//kprobe_events write=1
>     Writing event: p:probe/_do_fork _text+748040
>     Added new event:
>       probe:_do_fork       (on _do_fork)
> 
>     You can now use it in all perf tools, such as:
> 
> 	    perf record -e probe:_do_fork -aR sleep 1
> 
> We only offset to the LEP if function entry is specified, otherwise, we
> offset from the GEP.
> 
> Example for issue (3):
> ---------------------
> Before patch:
>     # perf probe -v _do_fork:%return
>     probe-definition(0): _do_fork:%return 
>     symbol:_do_fork file:(null) line:0 offset:0 return:1 lazy:(null)
>     0 arguments
>     Looking at the vmlinux_path (8 entries long)
>     Using /proc/kcore for kernel object code
>     Using /proc/kallsyms for symbols
>     Opening /sys/kernel/debug/tracing//kprobe_events write=1
>     Writing event: r:probe/_do_fork _do_fork+8
>     Failed to write event: Invalid argument
>       Error: Failed to add events. Reason: Invalid argument (Code: -22)
> 
> After patch:
>     # perf probe _do_fork:%return
>     Added new event:
>       probe:_do_fork       (on _do_fork%return)
> 
>     You can now use it in all perf tools, such as:
> 
> 	    perf record -e probe:_do_fork -aR sleep 1
> 
> 
> Concept Acked-by: Michael Ellerman <mpe@ellerman.id.au>
> 
> Cc: Mark Wielaard <mjw@redhat.com>
> Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Masami Hiramatsu <mhiramat@kernel.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Balbir Singh <bsingharora@gmail.com>
> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

Arnaldo,
Can you please pick this up if you're ok with the changes?

- Naveen

> 
> Naveen N. Rao (2):
>   perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le
>   perf tools: Fix kallsyms perf test on ppc64le
> 
>  tools/perf/arch/powerpc/util/sym-handling.c | 43 +++++++++++++++++++++--------
>  tools/perf/util/probe-event.c               |  5 ++--
>  tools/perf/util/probe-event.h               |  3 +-
>  tools/perf/util/symbol-elf.c                |  7 +++--
>  tools/perf/util/symbol.h                    |  3 +-
>  5 files changed, 43 insertions(+), 18 deletions(-)
> 
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [tip:perf/core] perf powerpc: Fix kprobe and kretprobe handling with kallsyms on ppc64le
  2016-04-12  9:10 ` [PATCH v2 1/2] perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le Naveen N. Rao
@ 2016-05-06  6:44   ` tip-bot for Naveen N. Rao
  0 siblings, 0 replies; 7+ messages in thread
From: tip-bot for Naveen N. Rao @ 2016-05-06  6:44 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mpe, linux-kernel, mingo, hpa, naveen.n.rao, bsingharora, acme,
	bauerman, ananth, mjw, tglx, mhiramat

Commit-ID:  239aeba764092b29dd7cab177cd47f472390622e
Gitweb:     http://git.kernel.org/tip/239aeba764092b29dd7cab177cd47f472390622e
Author:     Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
AuthorDate: Tue, 12 Apr 2016 14:40:49 +0530
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 5 May 2016 21:04:02 -0300

perf powerpc: Fix kprobe and kretprobe handling with kallsyms on ppc64le

So far, we used to treat probe point offsets as being offset from the
LEP. However, userspace applications (objdump/readelf) always show
disassembly and offsets from the function GEP. This is confusing to the
user as we will end up probing at an address different from what the
user expects when looking at the function disassembly with
readelf/objdump. Fix this by changing how we modify probe address with
perf.

If only the function name is provided, we assume the user needs the LEP.
Otherwise, if an offset is specified, we assume that the user knows the
exact address to probe based on function disassembly, and so we just
place the probe from the GEP offset.

Finally, kretprobe was also broken with kallsyms as we were trying to
specify an offset. This patch also fixes that issue.

Reported-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Balbir Singh <bsingharora@gmail.com>
Cc: Mark Wielaard <mjw@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/75df860aad8216bf4b9bcd10c6351ecc0e3dee54.1460451721.git.naveen.n.rao@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/powerpc/util/sym-handling.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c
index bbc1a50..6974ba0 100644
--- a/tools/perf/arch/powerpc/util/sym-handling.c
+++ b/tools/perf/arch/powerpc/util/sym-handling.c
@@ -71,12 +71,21 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
 			     struct probe_trace_event *tev, struct map *map)
 {
 	/*
-	 * ppc64 ABIv2 local entry point is currently always 2 instructions
-	 * (8 bytes) after the global entry point.
+	 * When probing at a function entry point, we normally always want the
+	 * LEP since that catches calls to the function through both the GEP and
+	 * the LEP. Hence, we would like to probe at an offset of 8 bytes if
+	 * the user only specified the function entry.
+	 *
+	 * However, if the user specifies an offset, we fall back to using the
+	 * GEP since all userspace applications (objdump/readelf) show function
+	 * disassembly with offsets from the GEP.
+	 *
+	 * In addition, we shouldn't specify an offset for kretprobes.
 	 */
-	if (!pev->uprobes && map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
-		tev->point.address += PPC64LE_LEP_OFFSET;
+	if (pev->point.offset || pev->point.retprobe || !map)
+		return;
+
+	if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
 		tev->point.offset += PPC64LE_LEP_OFFSET;
-	}
 }
 #endif

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [tip:perf/core] perf symbols: Fix kallsyms perf test on ppc64le
  2016-04-12  9:10 ` [PATCH v2 2/2] perf tools: Fix kallsyms perf test " Naveen N. Rao
@ 2016-05-06  6:45   ` tip-bot for Naveen N. Rao
  0 siblings, 0 replies; 7+ messages in thread
From: tip-bot for Naveen N. Rao @ 2016-05-06  6:45 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, naveen.n.rao, hpa, mingo, bsingharora, mjw, acme,
	mhiramat, ananth, bauerman, mpe, tglx

Commit-ID:  0b3c2264ae30ed692fd1ffd2b84c5fbdf737cb0d
Gitweb:     http://git.kernel.org/tip/0b3c2264ae30ed692fd1ffd2b84c5fbdf737cb0d
Author:     Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
AuthorDate: Tue, 12 Apr 2016 14:40:50 +0530
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 5 May 2016 21:04:03 -0300

perf symbols: Fix kallsyms perf test on ppc64le

ppc64le functions have a Global Entry Point (GEP) and a Local Entry
Point (LEP). While placing a probe, we always prefer the LEP since it
catches function calls through both the GEP and the LEP. In order to do
this, we fixup the function entry points during elf symbol table lookup
to point to the LEPs. This works, but breaks 'perf test kallsyms' since
the symbols loaded from the symbol table (pointing to the LEP) do not
match the symbols in kallsyms.

To fix this, we do not adjust all the symbols during symbol table load.
Instead, we note down st_other in a newly introduced arch-specific
member of perf symbol structure, and later use this to adjust the probe
trace point.

Reported-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Acked-by: Balbir Singh <bsingharora@gmail.com>
Cc: Mark Wielaard <mjw@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/6be7c2b17e370100c2f79dd444509df7929bdd3e.1460451721.git.naveen.n.rao@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/powerpc/util/sym-handling.c | 28 ++++++++++++++++++++--------
 tools/perf/util/probe-event.c               |  5 +++--
 tools/perf/util/probe-event.h               |  3 ++-
 tools/perf/util/symbol-elf.c                |  7 ++++---
 tools/perf/util/symbol.h                    |  3 ++-
 5 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c
index 6974ba0..c6d0f91 100644
--- a/tools/perf/arch/powerpc/util/sym-handling.c
+++ b/tools/perf/arch/powerpc/util/sym-handling.c
@@ -19,12 +19,6 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
 	       ehdr.e_type == ET_DYN;
 }
 
-#if defined(_CALL_ELF) && _CALL_ELF == 2
-void arch__elf_sym_adjust(GElf_Sym *sym)
-{
-	sym->st_value += PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
-}
-#endif
 #endif
 
 #if !defined(_CALL_ELF) || _CALL_ELF != 2
@@ -65,11 +59,21 @@ bool arch__prefers_symtab(void)
 	return true;
 }
 
+#ifdef HAVE_LIBELF_SUPPORT
+void arch__sym_update(struct symbol *s, GElf_Sym *sym)
+{
+	s->arch_sym = sym->st_other;
+}
+#endif
+
 #define PPC64LE_LEP_OFFSET	8
 
 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
-			     struct probe_trace_event *tev, struct map *map)
+			     struct probe_trace_event *tev, struct map *map,
+			     struct symbol *sym)
 {
+	int lep_offset;
+
 	/*
 	 * When probing at a function entry point, we normally always want the
 	 * LEP since that catches calls to the function through both the GEP and
@@ -82,10 +86,18 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
 	 *
 	 * In addition, we shouldn't specify an offset for kretprobes.
 	 */
-	if (pev->point.offset || pev->point.retprobe || !map)
+	if (pev->point.offset || pev->point.retprobe || !map || !sym)
 		return;
 
+	lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
+
 	if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
 		tev->point.offset += PPC64LE_LEP_OFFSET;
+	else if (lep_offset) {
+		if (pev->uprobes)
+			tev->point.address += lep_offset;
+		else
+			tev->point.offset += lep_offset;
+	}
 }
 #endif
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 85d82f4..c82c625 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2477,7 +2477,8 @@ static int find_probe_functions(struct map *map, char *name,
 
 void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
 				struct probe_trace_event *tev __maybe_unused,
-				struct map *map __maybe_unused) { }
+				struct map *map __maybe_unused,
+				struct symbol *sym __maybe_unused) { }
 
 /*
  * Find probe function addresses from map.
@@ -2614,7 +2615,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
 					strdup_or_goto(pev->args[i].type,
 							nomem_out);
 		}
-		arch__fix_tev_from_maps(pev, tev, map);
+		arch__fix_tev_from_maps(pev, tev, map, sym);
 	}
 	if (ret == skipped) {
 		ret = -ENOENT;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index e220962..5a27eb4 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -154,7 +154,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
 int show_available_funcs(const char *module, struct strfilter *filter, bool user);
 bool arch__prefers_symtab(void);
 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
-			     struct probe_trace_event *tev, struct map *map);
+			     struct probe_trace_event *tev, struct map *map,
+			     struct symbol *sym);
 
 /* If there is no space to write, returns -E2BIG. */
 int e_snprintf(char *str, size_t size, const char *format, ...)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 3f9d679..87a297d 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -770,7 +770,8 @@ static bool want_demangle(bool is_kernel_sym)
 	return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
 }
 
-void __weak arch__elf_sym_adjust(GElf_Sym *sym __maybe_unused) { }
+void __weak arch__sym_update(struct symbol *s __maybe_unused,
+		GElf_Sym *sym __maybe_unused) { }
 
 int dso__load_sym(struct dso *dso, struct map *map,
 		  struct symsrc *syms_ss, struct symsrc *runtime_ss,
@@ -947,8 +948,6 @@ int dso__load_sym(struct dso *dso, struct map *map,
 		    (sym.st_value & 1))
 			--sym.st_value;
 
-		arch__elf_sym_adjust(&sym);
-
 		if (dso->kernel || kmodule) {
 			char dso_name[PATH_MAX];
 
@@ -1082,6 +1081,8 @@ new_symbol:
 		if (!f)
 			goto out_elf_end;
 
+		arch__sym_update(f, &sym);
+
 		if (filter && filter(curr_map, f))
 			symbol__delete(f);
 		else {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index c8e4397..07211c2 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -55,6 +55,7 @@ struct symbol {
 	u16		namelen;
 	u8		binding;
 	bool		ignore;
+	u8		arch_sym;
 	char		name[0];
 };
 
@@ -323,7 +324,7 @@ int setup_intlist(struct intlist **list, const char *list_str,
 
 #ifdef HAVE_LIBELF_SUPPORT
 bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
-void arch__elf_sym_adjust(GElf_Sym *sym);
+void arch__sym_update(struct symbol *s, GElf_Sym *sym);
 #endif
 
 #define SYMBOL_A 0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-05-06  6:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-12  9:10 [PATCH v2 0/2] perf probe fixes for ppc64le Naveen N. Rao
2016-04-12  9:10 ` [PATCH v2 1/2] perf tools: Fix kprobe and kretprobe handling with kallsyms on ppc64le Naveen N. Rao
2016-05-06  6:44   ` [tip:perf/core] perf powerpc: " tip-bot for Naveen N. Rao
2016-04-12  9:10 ` [PATCH v2 2/2] perf tools: Fix kallsyms perf test " Naveen N. Rao
2016-05-06  6:45   ` [tip:perf/core] perf symbols: " tip-bot for Naveen N. Rao
2016-04-14  1:16 ` [PATCH v2 0/2] perf probe fixes for ppc64le Balbir Singh
2016-04-27 16:20 ` Naveen N. Rao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).