2013-09-25 17:20:51

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [GIT PULL 0/6] perf/urgent fixes

From: Arnaldo Carvalho de Melo <[email protected]>

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit cf3b425dd8d99e01214515a6754f9e69ecc6dce8:

perf/x86/intel: Add model number for Avoton Silvermont (2013-09-23 10:22:00 +0200)

are available in the git repository at:

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

for you to fetch changes up to de95ab53645a2f0015e0f68ee723f18dce2b8b51:

perf symbols: Demangle cloned functions (2013-09-25 12:58:21 -0300)

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

. It was possible to use an uninitialized buffer when reading
kernel modules information and checking if the file was a
/proc/sys/kernel/kptr_restrict'ed one, fix for this from
Adrian Hunter.

. The libbfd demangler doesn't handle cloned functions (e.g. symbol.clone.NUM),
feed it unsuffixed symbol names, workaround from Andi Kleen.

. Fix segfault in 'perf trace' when processing perf.data files with PERF_RECORD_MMAP2
records, recently added but not handled in this tool, from David Ahern.

. Fix libdl related build in old systems like Fedora 12, from David Ahern.

. Make 'perf kmem' work again on non NUMA machines, fix from Jiri Olsa.

. Fix probing symbols with optimization suffix in 'perf probe' where some
operations that are entirely user level and involves vmlinux/DWARF were working
but when the symbol name was fed to the kprobes tracer, the in kernel code
would use /proc/kallsyms where the name had the suffix, from Masami Hiramatsu.

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>

----------------------------------------------------------------
Adrian Hunter (1):
perf machine: Fix path unpopulated in machine__create_modules()

Andi Kleen (1):
perf symbols: Demangle cloned functions

David Ahern (2):
perf trace: Add mmap2 handler
perf tools: Explicitly add libdl dependency

Jiri Olsa (1):
perf kmem: Make it work again on non NUMA machines

Masami Hiramatsu (1):
perf probe: Fix probing symbols with optimization suffix

tools/perf/builtin-kmem.c | 2 +-
tools/perf/builtin-trace.c | 1 +
tools/perf/config/Makefile | 2 +-
tools/perf/util/machine.c | 2 +-
tools/perf/util/probe-finder.c | 77 ++++++++++++++++++++++--------------------
tools/perf/util/probe-finder.h | 3 ++
tools/perf/util/symbol-elf.c | 27 ++++++++++++++-
7 files changed, 74 insertions(+), 40 deletions(-)


2013-09-25 17:20:39

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 2/6] perf trace: Add mmap2 handler

From: David Ahern <[email protected]>

5c5e854b changed perf_event__synthesize_mmap_events to generate MMAP2
events. Since perf-trace does not have a handler for it it dies with a
segfault when trying to process files:

perf trace -i /tmp/perf.data
Segmentation fault

Signed-off-by: David Ahern <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-trace.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index fd48534..71aa3e3 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1055,6 +1055,7 @@ static int trace__replay(struct trace *trace)

trace->tool.sample = trace__process_sample;
trace->tool.mmap = perf_event__process_mmap;
+ trace->tool.mmap2 = perf_event__process_mmap2;
trace->tool.comm = perf_event__process_comm;
trace->tool.exit = perf_event__process_exit;
trace->tool.fork = perf_event__process_fork;
--
1.8.1.4

2013-09-25 17:20:44

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 6/6] perf symbols: Demangle cloned functions

From: Andi Kleen <[email protected]>

The libbfd C++ demangler doesn't seem to deal with cloned functions,
like symbol.clone.NUM.

Just strip the dot part before demangling and add it back later.

Signed-off-by: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/symbol-elf.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index a9c829b..d2a888e 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -928,8 +928,33 @@ int dso__load_sym(struct dso *dso, struct map *map,
* to it...
*/
if (symbol_conf.demangle) {
- demangled = bfd_demangle(NULL, elf_name,
+ /*
+ * The demangler doesn't deal with cloned functions.
+ * XXXX.clone.NUM or similar
+ * Strip the dot part and readd it later.
+ */
+ char *p = (char *)elf_name, *dot;
+ dot = strchr(elf_name, '.');
+ if (dot) {
+ p = strdup(elf_name);
+ if (!p)
+ goto new_symbol;
+ dot = strchr(p, '.');
+ *dot = 0;
+ }
+
+ demangled = bfd_demangle(NULL, p,
DMGL_PARAMS | DMGL_ANSI);
+ if (dot)
+ *dot = '.';
+ if (demangled && dot) {
+ demangled = realloc(demangled, strlen(demangled) + strlen(dot) + 1);
+ if (!demangled)
+ goto new_symbol;
+ strcpy(demangled + (dot - p), dot);
+ }
+ if (p != elf_name)
+ free(p);
if (demangled != NULL)
elf_name = demangled;
}
--
1.8.1.4

2013-09-25 17:20:49

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 1/6] perf kmem: Make it work again on non NUMA machines

From: Jiri Olsa <[email protected]>

The commit '2814eb0 perf kmem: Remove die() calls' disabled 'perf kmem'
command for machines without numa support. It made the command fail if
'/sys/devices/system/node' dir wasn't found.

Skipping the numa based initialization in case the directory is not
found and continue execution.

Signed-off-by: Jiri Olsa <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
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 c2dff9c..9b5f077 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -101,7 +101,7 @@ static int setup_cpunode_map(void)

dir1 = opendir(PATH_SYS_NODE);
if (!dir1)
- return -1;
+ return 0;

while ((dent1 = readdir(dir1)) != NULL) {
if (dent1->d_type != DT_DIR ||
--
1.8.1.4

2013-09-25 17:20:47

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 3/6] perf probe: Fix probing symbols with optimization suffix

From: Masami Hiramatsu <[email protected]>

Fix perf probe to probe on some symbols which have some optimzation
suffixes, e.g. ".part", ".isra", and ".constprop".

To fix this issue, instead of using the DIE name, perf probe uses the
symbol name found by dwfl_module_addrsym().

This also involves a perf probe --vars operation update which now shows
the symbol name instead of the DIE name.

Without this patch, putting a probe on an inlined function which was
compiled with a suffixed symbol will fail like this:

$ perf probe -v getname_flags
probe-definition(0): getname_flags
symbol:getname_flags file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
Looking at the vmlinux_path (6 entries long)
Using /lib/modules/3.11.0+/build/vmlinux for symbols
found inline addr: 0xffffffff8119bb70
Probe point found: getname_flags+0
found inline addr: 0xffffffff8119bcb6
Probe point found: getname+6
found inline addr: 0xffffffff811a06a6
Probe point found: user_path_at_empty+6
find 3 probe_trace_events.
Opening /sys/kernel/debug//tracing/kprobe_events write=1
Added new events:
Writing event: p:probe/getname_flags getname_flags+0
Failed to write event: No such file or directory
Error: Failed to add events. (-1)

Because the debuginfo knows only the original (non suffix) symbol name,
it uses the original symbol for probe address but the kernel (kallsyms)
knows only suffixed symbol. Then, the kernel rejects that original
symbol.

This patch uses dwfl_module_addrsym() to get the correct (suffixed)
symbol from symtab when a probe point is found.

Reported-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Masami Hiramatsu <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/probe-finder.c | 77 ++++++++++++++++++++++--------------------
tools/perf/util/probe-finder.h | 3 ++
2 files changed, 44 insertions(+), 36 deletions(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 20c7299..371476c 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -118,7 +118,6 @@ static const Dwfl_Callbacks offline_callbacks = {
static int debuginfo__init_offline_dwarf(struct debuginfo *self,
const char *path)
{
- Dwfl_Module *mod;
int fd;

fd = open(path, O_RDONLY);
@@ -129,11 +128,11 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *self,
if (!self->dwfl)
goto error;

- mod = dwfl_report_offline(self->dwfl, "", "", fd);
- if (!mod)
+ self->mod = dwfl_report_offline(self->dwfl, "", "", fd);
+ if (!self->mod)
goto error;

- self->dbg = dwfl_module_getdwarf(mod, &self->bias);
+ self->dbg = dwfl_module_getdwarf(self->mod, &self->bias);
if (!self->dbg)
goto error;

@@ -676,37 +675,42 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
}

/* Convert subprogram DIE to trace point */
-static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
- bool retprobe, struct probe_trace_point *tp)
+static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
+ Dwarf_Addr paddr, bool retprobe,
+ struct probe_trace_point *tp)
{
Dwarf_Addr eaddr, highaddr;
- const char *name;
-
- /* Copy the name of probe point */
- name = dwarf_diename(sp_die);
- if (name) {
- if (dwarf_entrypc(sp_die, &eaddr) != 0) {
- pr_warning("Failed to get entry address of %s\n",
- dwarf_diename(sp_die));
- return -ENOENT;
- }
- if (dwarf_highpc(sp_die, &highaddr) != 0) {
- pr_warning("Failed to get end address of %s\n",
- dwarf_diename(sp_die));
- return -ENOENT;
- }
- if (paddr > highaddr) {
- pr_warning("Offset specified is greater than size of %s\n",
- dwarf_diename(sp_die));
- return -EINVAL;
- }
- tp->symbol = strdup(name);
- if (tp->symbol == NULL)
- return -ENOMEM;
- tp->offset = (unsigned long)(paddr - eaddr);
- } else
- /* This function has no name. */
- tp->offset = (unsigned long)paddr;
+ GElf_Sym sym;
+ const char *symbol;
+
+ /* Verify the address is correct */
+ if (dwarf_entrypc(sp_die, &eaddr) != 0) {
+ pr_warning("Failed to get entry address of %s\n",
+ dwarf_diename(sp_die));
+ return -ENOENT;
+ }
+ if (dwarf_highpc(sp_die, &highaddr) != 0) {
+ pr_warning("Failed to get end address of %s\n",
+ dwarf_diename(sp_die));
+ return -ENOENT;
+ }
+ if (paddr > highaddr) {
+ pr_warning("Offset specified is greater than size of %s\n",
+ dwarf_diename(sp_die));
+ return -EINVAL;
+ }
+
+ /* Get an appropriate symbol from symtab */
+ symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
+ if (!symbol) {
+ pr_warning("Failed to find symbol at 0x%lx\n",
+ (unsigned long)paddr);
+ return -ENOENT;
+ }
+ tp->offset = (unsigned long)(paddr - sym.st_value);
+ tp->symbol = strdup(symbol);
+ if (!tp->symbol)
+ return -ENOMEM;

/* Return probe must be on the head of a subprogram */
if (retprobe) {
@@ -1149,7 +1153,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
tev = &tf->tevs[tf->ntevs++];

/* Trace point should be converted from subprogram DIE */
- ret = convert_to_trace_point(&pf->sp_die, pf->addr,
+ ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
pf->pev->point.retprobe, &tev->point);
if (ret < 0)
return ret;
@@ -1181,7 +1185,7 @@ int debuginfo__find_trace_events(struct debuginfo *self,
{
struct trace_event_finder tf = {
.pf = {.pev = pev, .callback = add_probe_trace_event},
- .max_tevs = max_tevs};
+ .mod = self->mod, .max_tevs = max_tevs};
int ret;

/* Allocate result tevs array */
@@ -1250,7 +1254,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
vl = &af->vls[af->nvls++];

/* Trace point should be converted from subprogram DIE */
- ret = convert_to_trace_point(&pf->sp_die, pf->addr,
+ ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
pf->pev->point.retprobe, &vl->point);
if (ret < 0)
return ret;
@@ -1289,6 +1293,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self,
{
struct available_var_finder af = {
.pf = {.pev = pev, .callback = add_available_vars},
+ .mod = self->mod,
.max_vls = max_vls, .externs = externs};
int ret;

diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 17e94d0..3b7d630 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -23,6 +23,7 @@ static inline int is_c_varname(const char *name)
/* debug information structure */
struct debuginfo {
Dwarf *dbg;
+ Dwfl_Module *mod;
Dwfl *dwfl;
Dwarf_Addr bias;
};
@@ -77,6 +78,7 @@ struct probe_finder {

struct trace_event_finder {
struct probe_finder pf;
+ Dwfl_Module *mod; /* For solving symbols */
struct probe_trace_event *tevs; /* Found trace events */
int ntevs; /* Number of trace events */
int max_tevs; /* Max number of trace events */
@@ -84,6 +86,7 @@ struct trace_event_finder {

struct available_var_finder {
struct probe_finder pf;
+ Dwfl_Module *mod; /* For solving symbols */
struct variable_list *vls; /* Found variable lists */
int nvls; /* Number of variable lists */
int max_vls; /* Max no. of variable lists */
--
1.8.1.4

2013-09-25 17:21:34

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 5/6] perf machine: Fix path unpopulated in machine__create_modules()

From: Adrian Hunter <[email protected]>

In machine__create_modules() the 'path' char array was used in a call to
symbol__restricted_filename() without always being populated.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
[ Split patch removing unrelated conversion of sprintf to snprintf to perf/core ]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/machine.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 933d14f..6188d28 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -792,7 +792,7 @@ static int machine__create_modules(struct machine *machine)
modules = path;
}

- if (symbol__restricted_filename(path, "/proc/modules"))
+ if (symbol__restricted_filename(modules, "/proc/modules"))
return -1;

file = fopen(modules, "r");
--
1.8.1.4

2013-09-25 17:20:38

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 4/6] perf tools: Explicitly add libdl dependency

From: David Ahern <[email protected]>

Fixes compile failure on Fedora 12.

Signed-off-by: David Ahern <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/config/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 346ee92..5f6f9b3 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -87,7 +87,7 @@ CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -std=gnu99

-EXTLIBS = -lelf -lpthread -lrt -lm
+EXTLIBS = -lelf -lpthread -lrt -lm -ldl

ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
CFLAGS += -fstack-protector-all
--
1.8.1.4

2013-09-25 18:28:59

by Ingo Molnar

[permalink] [raw]
Subject: Re: [GIT PULL 0/6] perf/urgent fixes


* Arnaldo Carvalho de Melo <[email protected]> wrote:

> From: Arnaldo Carvalho de Melo <[email protected]>
>
> Hi Ingo,
>
> Please consider pulling,
>
> - Arnaldo
>
> The following changes since commit cf3b425dd8d99e01214515a6754f9e69ecc6dce8:
>
> perf/x86/intel: Add model number for Avoton Silvermont (2013-09-23 10:22:00 +0200)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux tags/perf-urgent-for-mingo
>
> for you to fetch changes up to de95ab53645a2f0015e0f68ee723f18dce2b8b51:
>
> perf symbols: Demangle cloned functions (2013-09-25 12:58:21 -0300)
>
> ----------------------------------------------------------------
> perf/urgent fixes:
>
> . It was possible to use an uninitialized buffer when reading
> kernel modules information and checking if the file was a
> /proc/sys/kernel/kptr_restrict'ed one, fix for this from
> Adrian Hunter.
>
> . The libbfd demangler doesn't handle cloned functions (e.g. symbol.clone.NUM),
> feed it unsuffixed symbol names, workaround from Andi Kleen.
>
> . Fix segfault in 'perf trace' when processing perf.data files with PERF_RECORD_MMAP2
> records, recently added but not handled in this tool, from David Ahern.
>
> . Fix libdl related build in old systems like Fedora 12, from David Ahern.
>
> . Make 'perf kmem' work again on non NUMA machines, fix from Jiri Olsa.
>
> . Fix probing symbols with optimization suffix in 'perf probe' where some
> operations that are entirely user level and involves vmlinux/DWARF were working
> but when the symbol name was fed to the kprobes tracer, the in kernel code
> would use /proc/kallsyms where the name had the suffix, from Masami Hiramatsu.
>
> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
>
> ----------------------------------------------------------------
> Adrian Hunter (1):
> perf machine: Fix path unpopulated in machine__create_modules()
>
> Andi Kleen (1):
> perf symbols: Demangle cloned functions
>
> David Ahern (2):
> perf trace: Add mmap2 handler
> perf tools: Explicitly add libdl dependency
>
> Jiri Olsa (1):
> perf kmem: Make it work again on non NUMA machines
>
> Masami Hiramatsu (1):
> perf probe: Fix probing symbols with optimization suffix
>
> tools/perf/builtin-kmem.c | 2 +-
> tools/perf/builtin-trace.c | 1 +
> tools/perf/config/Makefile | 2 +-
> tools/perf/util/machine.c | 2 +-
> tools/perf/util/probe-finder.c | 77 ++++++++++++++++++++++--------------------
> tools/perf/util/probe-finder.h | 3 ++
> tools/perf/util/symbol-elf.c | 27 ++++++++++++++-
> 7 files changed, 74 insertions(+), 40 deletions(-)

Pulled, thanks a lot Arnaldo!

Ingo