linux.kernel - 25 new messages in 14 topics - digest
linux.kernel
http://groups.google.com/group/linux.kernel?hl=en
Today's topics:
* perf probe: Don't use a perf_session instance just to resolve symbols - 4
messages, 1 author
http://groups.google.com/group/linux.kernel/t/05460a1ee6308f2b?hl=en
* perf symbols: Remove perf_session usage in symbols layer - 1 messages, 1
author
http://groups.google.com/group/linux.kernel/t/83c5928b604579c9?hl=en
* remove EXPERIMENTAL from NFS_FSCACHE - 1 messages, 1 author
http://groups.google.com/group/linux.kernel/t/b40d800a6c2462e3?hl=en
* OF Device tree merge patches - 4 messages, 1 author
http://groups.google.com/group/linux.kernel/t/95890bc885fee525?hl=en
* Input: serio - re-add thaw (and add freeze) - 2 messages, 2 authors
http://groups.google.com/group/linux.kernel/t/01a55687b4d83506?hl=en
* reiserfs deadlock - 2 messages, 1 author
http://groups.google.com/group/linux.kernel/t/8725f85be3262cd6?hl=en
* syslog: distinguish between /proc/kmsg and syscalls - 2 messages, 1 author
http://groups.google.com/group/linux.kernel/t/e1594790606b7db6?hl=en
* drivers/ata: Fix continuation line formats - 1 messages, 1 author
http://groups.google.com/group/linux.kernel/t/d822eba66af5e806?hl=en
* MX1/MX2: -EINVAL overwritten in second iteration in mxc_gpio_setup_multiple_
pins() - 1 messages, 1 author
http://groups.google.com/group/linux.kernel/t/7de8eb855916e1be?hl=en
* netfilter: per netns nf_conntrack_cachep - 1 messages, 1 author
http://groups.google.com/group/linux.kernel/t/8498db207556ff69?hl=en
* 2.6.33-rc6: ext4 triggers warning about high order allocations - 1 messages,
1 author
http://groups.google.com/group/linux.kernel/t/fd864bd824fcba2c?hl=en
* avr32: use generic ptrace_resume code - 3 messages, 3 authors
http://groups.google.com/group/linux.kernel/t/5497cb48daecd717?hl=en
* ohci1394_dma=early crash since 2.6.32 (was Re: [Bug #14487] PANIC: early
exception 08 rip 246:10 error ffffffff810251b5 cr2 0) - 1 messages, 1 author
http://groups.google.com/group/linux.kernel/t/42f60222e13dd142?hl=en
* x86: fix race in create_irq_nr on irq_desc - 1 messages, 1 author
http://groups.google.com/group/linux.kernel/t/8d79051b75e0b2aa?hl=en
==============================================================================
TOPIC: perf probe: Don't use a perf_session instance just to resolve symbols
http://groups.google.com/group/linux.kernel/t/05460a1ee6308f2b?hl=en
==============================================================================
== 1 of 4 ==
Date: Wed, Feb 3 2010 11:00 am
From: Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <acme@redhat.com>
With the recent modifications done to untie the session and symbol layers,
'perf probe' now can use just the symbols layer.
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Acked-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-probe.c | 26 +++++++++++++-------------
1 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 4fa73ec..ad47bd4 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -41,7 +41,6 @@
#include "util/debugfs.h"
#include "util/symbol.h"
#include "util/thread.h"
-#include "util/session.h"
#include "util/parse-options.h"
#include "util/parse-events.h" /* For debugfs_path */
#include "util/probe-finder.h"
@@ -59,8 +58,8 @@ static struct {
int nr_probe;
struct probe_point probes[MAX_PROBES];
struct strlist *dellist;
- struct perf_session *psession;
- struct map *kmap;
+ struct map_groups kmap_groups;
+ struct map *kmaps[MAP__NR_TYPES];
struct line_range line_range;
} session;
@@ -122,7 +121,8 @@ static int opt_del_probe_event(const struct option *opt __used,
static void evaluate_probe_point(struct probe_point *pp)
{
struct symbol *sym;
- sym = map__find_symbol_by_name(session.kmap, pp->function, NULL);
+ sym = map__find_symbol_by_name(session.kmaps[MAP__FUNCTION],
+ pp->function, NULL);
if (!sym)
die("Kernel symbol \'%s\' not found - probe not added.",
pp->function);
@@ -131,12 +131,13 @@ static void evaluate_probe_point(struct probe_point *pp)
#ifndef NO_LIBDWARF
static int open_vmlinux(void)
{
- if (map__load(session.kmap, NULL) < 0) {
+ if (map__load(session.kmaps[MAP__FUNCTION], NULL) < 0) {
pr_debug("Failed to load kernel map.\n");
return -EINVAL;
}
- pr_debug("Try to open %s\n", session.kmap->dso->long_name);
- return open(session.kmap->dso->long_name, O_RDONLY);
+ pr_debug("Try to open %s\n",
+ session.kmaps[MAP__FUNCTION]->dso->long_name);
+ return open(session.kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
}
static int opt_show_lines(const struct option *opt __used,
@@ -212,12 +213,11 @@ static void init_vmlinux(void)
pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
if (symbol__init() < 0)
die("Failed to init symbol map.");
- session.psession = perf_session__new(NULL, O_WRONLY, false);
- if (session.psession == NULL)
- die("Failed to init perf_session.");
- session.kmap = session.psession->vmlinux_maps[MAP__FUNCTION];
- if (!session.kmap)
- die("Could not find kernel map.\n");
+
+ map_groups__init(&session.kmap_groups);
+ if (map_groups__create_kernel_maps(&session.kmap_groups,
+ session.kmaps) < 0)
+ die("Failed to create kernel maps.");
}
int cmd_probe(int argc, const char **argv, const char *prefix __used)
--
1.6.2.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
== 2 of 4 ==
Date: Wed, Feb 3 2010 11:00 am
From: Arnaldo Carvalho de Melo
From: Kirill Smelkov <kirr@landau.phys.spbu.ru>
The problem was we were incorrectly calculating objdump addresses for
sym->start and sym->end, look:
For simple ET_DYN type DSO (*.so) with one function, objdump -dS output
is something like this:
000004ac <my_strlen>:
int my_strlen(const char *s)
4ac: 55 push %ebp
4ad: 89 e5 mov %esp,%ebp
4af: 83 ec 10 sub $0x10,%esp
{
i.e. we have relative-to-dso-mapping IPs (=RIP) there.
For ET_EXEC type and probably for prelinked libs as well (sorry can't
test - I don't use prelink) objdump outputs absolute IPs, e.g.
08048604 <zz_strlen>:
extern "C"
int zz_strlen(const char *s)
8048604: 55 push %ebp
8048605: 89 e5 mov %esp,%ebp
8048607: 83 ec 10 sub $0x10,%esp
{
So, if sym->start is always relative to dso mapping(*), we'll have to
unmap it for ET_EXEC like cases, and leave as is for ET_DYN cases.
(*) and it is - we've explicitely made it relative. Look for
adjust_symbols handling in dso__load_sym()
Previously we were always unmapping sym->start and for ET_DYN dsos
resulting addresses were wrong, and so objdump output was empty.
The end result was that perf annotate output for symbols from
non-prelinked *.so had always 0.00% percents only, which is wrong.
To fix it, let's introduce a helper for converting rip to objdump
address, and also let's document what map_ip() and unmap_ip() do -- I
had to study sources for several hours to understand it.
Cc: Mike Galbraith <efault@gmx.de>
Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-annotate.c | 5 +++--
tools/perf/util/map.c | 12 ++++++++++++
tools/perf/util/map.h | 9 +++++++++
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 4fc3899..28ea4e0 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -189,7 +189,7 @@ static int parse_line(FILE *file, struct hist_entry *he, u64 len)
line_ip = -1;
}
- start = he->map->unmap_ip(he->map, sym->start);
+ start = map__rip_2objdump(he->map, sym->start);
if (line_ip != -1) {
const char *path = NULL;
@@ -397,7 +397,8 @@ static void annotate_sym(struct hist_entry *he)
dso, dso->long_name, sym, sym->name);
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
- map->unmap_ip(map, sym->start), map->unmap_ip(map, sym->end),
+ map__rip_2objdump(map, sym->start),
+ map__rip_2objdump(map, sym->end),
filename, filename);
if (verbose >= 3)
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index f6626cc..af5805f 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -210,3 +210,15 @@ size_t map__fprintf(struct map *self, FILE *fp)
return fprintf(fp, " %Lx-%Lx %Lx %s\n",
self->start, self->end, self->pgoff, self->dso->name);
}
+
+/*
+ * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
+ * map->dso->adjust_symbols==1 for ET_EXEC-like cases.
+ */
+u64 map__rip_2objdump(struct map *map, u64 rip)
+{
+ u64 addr = map->dso->adjust_symbols ?
+ map->unmap_ip(map, rip) : /* RIP -> IP */
+ rip;
+ return addr;
+}
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index de04839..9cee9c7 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -26,8 +26,12 @@ struct map {
u64 end;
enum map_type type;
u64 pgoff;
+
+ /* ip -> dso rip */
u64 (*map_ip)(struct map *, u64);
+ /* dso rip -> ip */
u64 (*unmap_ip)(struct map *, u64);
+
struct dso *dso;
};
@@ -56,6 +60,11 @@ static inline u64 identity__map_ip(struct map *map __used, u64 ip)
return ip;
}
+
+/* rip -> addr suitable for passing to `objdump --start-address=` */
+u64 map__rip_2objdump(struct map *map, u64 rip);
+
+
struct symbol;
struct mmap_event;
--
1.6.2.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
== 3 of 4 ==
Date: Wed, Feb 3 2010 11:00 am
From: Arnaldo Carvalho de Melo
From: Kirill Smelkov <kirr@landau.phys.spbu.ru>
By relying on logic in dso__load_kernel_sym(), we can automatically load
vmlinux.
The only thing which needs to be adjusted, is how --sym-annotate option
is handled - now we can't rely on vmlinux been loaded until full
successful pass of dso__load_vmlinux(), but that's not the case if we'll
do sym_filter_entry setup in symbol_filter().
So move this step right after event__process_sample() where we know the
whole dso__load_kernel_sym() pass is done.
By the way, though conceptually similar `perf top` still can't annotate
userspace - see next patches with fixes.
Cc: Mike Galbraith <efault@gmx.de>
Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/Documentation/perf-top.txt | 2 +-
tools/perf/builtin-top.c | 39 +++++++++++++++++++-------------
2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 4a7d558..785b9fc 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -74,7 +74,7 @@ OPTIONS
-s <symbol>::
--sym-annotate=<symbol>::
- Annotate this symbol. Requires -k option.
+ Annotate this symbol.
-v::
--verbose::
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 1fc018e..83c09c8 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -94,6 +94,7 @@ struct source_line {
static char *sym_filter = NULL;
struct sym_entry *sym_filter_entry = NULL;
+struct sym_entry *sym_filter_entry_sched = NULL;
static int sym_pcnt_filter = 5;
static int sym_counter = 0;
static int display_weighted = -1;
@@ -695,11 +696,9 @@ static void print_mapped_keys(void)
fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter);
- if (symbol_conf.vmlinux_name) {
- fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter);
- fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
- fprintf(stdout, "\t[S] stop annotation.\n");
- }
+ fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter);
+ fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
+ fprintf(stdout, "\t[S] stop annotation.\n");
if (nr_counters > 1)
fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0);
@@ -725,14 +724,13 @@ static int key_mapped(int c)
case 'Q':
case 'K':
case 'U':
+ case 'F':
+ case 's':
+ case 'S':
return 1;
case 'E':
case 'w':
return nr_counters > 1 ? 1 : 0;
- case 'F':
- case 's':
- case 'S':
- return symbol_conf.vmlinux_name ? 1 : 0;
default:
break;
}
@@ -910,8 +908,12 @@ static int symbol_filter(struct map *map, struct symbol *sym)
syme = symbol__priv(sym);
syme->map = map;
syme->src = NULL;
- if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter))
- sym_filter_entry = syme;
+
+ if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) {
+ /* schedule initial sym_filter_entry setup */
+ sym_filter_entry_sched = syme;
+ sym_filter = NULL;
+ }
for (i = 0; skip_symbols[i]; i++) {
if (!strcmp(skip_symbols[i], name)) {
@@ -976,6 +978,13 @@ static void event__process_sample(const event_t *self,
return;
}
+ /* let's see, whether we need to install initial sym_filter_entry */
+ if (sym_filter_entry_sched) {
+ sym_filter_entry = sym_filter_entry_sched;
+ sym_filter_entry_sched = NULL;
+ parse_source(sym_filter_entry);
+ }
+
syme = symbol__priv(al.sym);
if (!syme->skip) {
syme->count[counter]++;
@@ -1270,7 +1279,7 @@ static const struct option options[] = {
OPT_BOOLEAN('i', "inherit", &inherit,
"child tasks inherit counters"),
OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name",
- "symbol to annotate - requires -k option"),
+ "symbol to annotate"),
OPT_BOOLEAN('z', "zero", &zero,
"zero history across updates"),
OPT_INTEGER('F', "freq", &freq,
@@ -1306,16 +1315,14 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
symbol_conf.priv_size = (sizeof(struct sym_entry) +
(nr_counters + 1) * sizeof(unsigned long));
- if (symbol_conf.vmlinux_name == NULL)
- symbol_conf.try_vmlinux_path = true;
+
+ symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
if (symbol__init() < 0)
return -1;
if (delay_secs < 1)
delay_secs = 1;
- parse_source(sym_filter_entry);
-
/*
* User specified count overrides default frequency.
*/
--
1.6.2.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
== 4 of 4 ==
Date: Wed, Feb 3 2010 11:00 am
From: Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <acme@redhat.com>
We want to stream events as fast as possible to perf.data, and also in the
future we want to have splice working, when no interception will be possible.
Using build_id__mark_dso_hit_ops to create the list of DSOs that back MMAPs we
also optimize disk usage in the build-id cache by only caching DSOs that had
hits.
Suggested-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-record.c | 37 ++++++++++++-------------
tools/perf/util/header.c | 7 +++-
tools/perf/util/session.c | 64 +++++++++++++++++++++++++-----------------
tools/perf/util/session.h | 3 ++
tools/perf/util/symbol.c | 13 +++++---
tools/perf/util/symbol.h | 2 +-
6 files changed, 73 insertions(+), 53 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 949167e..706f001 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -12,6 +12,7 @@
#include "perf.h"
+#include "util/build-id.h"
#include "util/util.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
@@ -65,6 +66,7 @@ static int nr_poll = 0;
static int nr_cpu = 0;
static int file_new = 1;
+static off_t post_processing_offset;
static struct perf_session *session;
@@ -114,26 +116,10 @@ static void write_output(void *buf, size_t size)
}
}
-static void write_event(event_t *buf, size_t size)
-{
- /*
- * Add it to the list of DSOs, so that when we finish this
- * record session we can pick the available build-ids.
- */
- if (buf->header.type == PERF_RECORD_MMAP) {
- struct list_head *head = &dsos__user;
- if (buf->mmap.header.misc == 1)
- head = &dsos__kernel;
- __dsos__findnew(head, buf->mmap.filename);
- }
-
- write_output(buf, size);
-}
-
static int process_synthesized_event(event_t *event,
struct perf_session *self __used)
{
- write_event(event, event->header.size);
+ write_output(event, event->header.size);
return 0;
}
@@ -185,14 +171,14 @@ static void mmap_read(struct mmap_data *md)
size = md->mask + 1 - (old & md->mask);
old += size;
- write_event(buf, size);
+ write_output(buf, size);
}
buf = &data[old & md->mask];
size = head - old;
old += size;
- write_event(buf, size);
+ write_output(buf, size);
md->prev = old;
mmap_write_tail(md, old);
@@ -402,10 +388,21 @@ static void open_counters(int cpu, pid_t pid)
nr_cpu++;
}
+static int process_buildids(void)
+{
+ u64 size = lseek(output, 0, SEEK_CUR);
+
+ session->fd = output;
+ return __perf_session__process_events(session, post_processing_offset,
+ size - post_processing_offset,
+ size, &build_id__mark_dso_hit_ops);
+}
+
static void atexit_header(void)
{
session->header.data_size += bytes_written;
+ process_buildids();
perf_header__write(&session->header, output, true);
}
@@ -558,6 +555,8 @@ static int __cmd_record(int argc, const char **argv)
return err;
}
+ post_processing_offset = lseek(output, 0, SEEK_CUR);
+
err = event__synthesize_kernel_mmap(process_synthesized_event,
session, "_text");
if (err < 0) {
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ed3efd7..d5facd5 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -205,8 +205,11 @@ static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
dsos__for_each_with_build_id(pos, head) {
int err;
struct build_id_event b;
- size_t len = pos->long_name_len + 1;
+ size_t len;
+ if (!pos->hit)
+ continue;
+ len = pos->long_name_len + 1;
len = ALIGN(len, NAME_ALIGN);
memset(&b, 0, sizeof(b));
memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
@@ -371,7 +374,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
u64 sec_start;
int idx = 0, err;
- if (dsos__read_build_ids())
+ if (dsos__read_build_ids(true))
perf_header__set_feat(self, HEADER_BUILD_ID);
nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index aa8a031..74cbc64 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -385,8 +385,9 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
return thread;
}
-int perf_session__process_events(struct perf_session *self,
- struct perf_event_ops *ops)
+int __perf_session__process_events(struct perf_session *self,
+ u64 data_offset, u64 data_size,
+ u64 file_size, struct perf_event_ops *ops)
{
int err, mmap_prot, mmap_flags;
u64 head, shift;
@@ -396,32 +397,11 @@ int perf_session__process_events(struct perf_session *self,
uint32_t size;
char *buf;
- if (perf_session__register_idle_thread(self) == NULL)
- return -ENOMEM;
-
perf_event_ops__fill_defaults(ops);
page_size = sysconf(_SC_PAGESIZE);
- head = self->header.data_offset;
-
- if (!symbol_conf.full_paths) {
- char bf[PATH_MAX];
-
- if (getcwd(bf, sizeof(bf)) == NULL) {
- err = -errno;
-out_getcwd_err:
- pr_err("failed to get the current directory\n");
- goto out_err;
- }
- self->cwd = strdup(bf);
- if (self->cwd == NULL) {
- err = -ENOMEM;
- goto out_getcwd_err;
- }
- self->cwdlen = strlen(self->cwd);
- }
-
+ head = data_offset;
shift = page_size * (head / page_size);
offset += shift;
head -= shift;
@@ -486,10 +466,10 @@ more:
head += size;
- if (offset + head >= self->header.data_offset + self->header.data_size)
+ if (offset + head >= data_offset + data_size)
goto done;
- if (offset + head < self->size)
+ if (offset + head < file_size)
goto more;
done:
err = 0;
@@ -497,6 +477,38 @@ out_err:
return err;
}
+int perf_session__process_events(struct perf_session *self,
+ struct perf_event_ops *ops)
+{
+ int err;
+
+ if (perf_session__register_idle_thread(self) == NULL)
+ return -ENOMEM;
+
+ if (!symbol_conf.full_paths) {
+ char bf[PATH_MAX];
+
+ if (getcwd(bf, sizeof(bf)) == NULL) {
+ err = -errno;
+out_getcwd_err:
+ pr_err("failed to get the current directory\n");
+ goto out_err;
+ }
+ self->cwd = strdup(bf);
+ if (self->cwd == NULL) {
+ err = -ENOMEM;
+ goto out_getcwd_err;
+ }
+ self->cwdlen = strlen(self->cwd);
+ }
+
+ err = __perf_session__process_events(self, self->header.data_offset,
+ self->header.data_size,
+ self->size, ops);
+out_err:
+ return err;
+}
+
bool perf_session__has_traces(struct perf_session *self, const char *msg)
{
if (!(self->sample_type & PERF_SAMPLE_RAW)) {
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 752d75a..31950fc 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -50,6 +50,9 @@ void perf_session__delete(struct perf_session *self);
void perf_event_header__bswap(struct perf_event_header *self);
+int __perf_session__process_events(struct perf_session *self,
+ u64 data_offset, u64 data_size, u64 size,
+ struct perf_event_ops *ops);
int perf_session__process_events(struct perf_session *self,
struct perf_event_ops *event_ops);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e752837..bfb0554 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1076,25 +1076,28 @@ static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
}
-static bool __dsos__read_build_ids(struct list_head *head)
+static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
{
bool have_build_id = false;
struct dso *pos;
- list_for_each_entry(pos, head, node)
+ list_for_each_entry(pos, head, node) {
+ if (with_hits && !pos->hit)
+ continue;
if (filename__read_build_id(pos->long_name, pos->build_id,
sizeof(pos->build_id)) > 0) {
have_build_id = true;
pos->has_build_id = true;
}
+ }
return have_build_id;
}
-bool dsos__read_build_ids(void)
+bool dsos__read_build_ids(bool with_hits)
{
- bool kbuildids = __dsos__read_build_ids(&dsos__kernel),
- ubuildids = __dsos__read_build_ids(&dsos__user);
+ bool kbuildids = __dsos__read_build_ids(&dsos__kernel, with_hits),
+ ubuildids = __dsos__read_build_ids(&dsos__user, with_hits);
return kbuildids || ubuildids;
}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index e90568a..1b4192e 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -157,7 +157,7 @@ struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
-bool dsos__read_build_ids(void);
+bool dsos__read_build_ids(bool with_hits);
int build_id__sprintf(const u8 *self, int len, char *bf);
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
--
1.6.2.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
==============================================================================
TOPIC: perf symbols: Remove perf_session usage in symbols layer
http://groups.google.com/group/linux.kernel/t/83c5928b604579c9?hl=en
==============================================================================
== 1 of 1 ==
Date: Wed, Feb 3 2010 11:00 am
From: Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <acme@redhat.com>
I noticed while writing the first test in 'perf regtest' that to just test the
symbol handling routines one needs to create a perf session, that is a layer
centered on a perf.data file, events, etc, so I untied these layers.
This reduces the complexity for the users as the number of parameters to most
of the symbols and session APIs now was reduced while not adding more state to
all the map instances by only having data that is needed to split the kernel
(kallsyms and ELF symtab sections) maps and do vmlinux relocation on the main
kernel map.
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-kmem.c | 2 +-
tools/perf/builtin-probe.c | 5 +-
tools/perf/util/event.c | 6 +--
tools/perf/util/map.c | 20 ++++---
tools/perf/util/map.h | 22 ++++++--
tools/perf/util/session.c | 35 +++++++++----
tools/perf/util/session.h | 22 +++++---
tools/perf/util/symbol.c | 122 ++++++++++++++++++++-----------------------
tools/perf/util/symbol.h | 19 ++++---
tools/perf/util/thread.c | 3 +-
tools/perf/util/thread.h | 14 +++--
11 files changed, 149 insertions(+), 121 deletions(-)
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 5d5dc6b..924a951 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -369,7 +369,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
if (is_caller) {
addr = data->call_site;
if (!raw_ip)
- sym = map_groups__find_function(&session->kmaps, session, addr, NULL);
+ sym = map_groups__find_function(&session->kmaps, addr, NULL);
} else
addr = data->ptr;
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 34f2acb..4fa73ec 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -122,8 +122,7 @@ static int opt_del_probe_event(const struct option *opt __used,
static void evaluate_probe_point(struct probe_point *pp)
{
struct symbol *sym;
- sym = map__find_symbol_by_name(session.kmap, pp->function,
- session.psession, NULL);
+ sym = map__find_symbol_by_name(session.kmap, pp->function, NULL);
if (!sym)
die("Kernel symbol \'%s\' not found - probe not added.",
pp->function);
@@ -132,7 +131,7 @@ static void evaluate_probe_point(struct probe_point *pp)
#ifndef NO_LIBDWARF
static int open_vmlinux(void)
{
- if (map__load(session.kmap, session.psession, NULL) < 0) {
+ if (map__load(session.kmap, NULL) < 0) {
pr_debug("Failed to load kernel map.\n");
return -EINVAL;
}
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index bbaee61..c3831f6 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -374,9 +374,7 @@ int event__process_mmap(event_t *self, struct perf_session *session)
goto out_problem;
kernel->kernel = 1;
- if (__map_groups__create_kernel_maps(&session->kmaps,
- session->vmlinux_maps,
- kernel) < 0)
+ if (__perf_session__create_kernel_maps(session, kernel) < 0)
goto out_problem;
session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start;
@@ -476,7 +474,7 @@ void thread__find_addr_location(struct thread *self,
{
thread__find_addr_map(self, session, cpumode, type, addr, al);
if (al->map != NULL)
- al->sym = map__find_symbol(al->map, session, al->addr, filter);
+ al->sym = map__find_symbol(al->map, al->addr, filter);
else
al->sym = NULL;
}
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index c4d55a0..36ff0bf 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -104,8 +104,7 @@ void map__fixup_end(struct map *self)
#define DSO__DELETED "(deleted)"
-int map__load(struct map *self, struct perf_session *session,
- symbol_filter_t filter)
+int map__load(struct map *self, symbol_filter_t filter)
{
const char *name = self->dso->long_name;
int nr;
@@ -113,7 +112,7 @@ int map__load(struct map *self, struct perf_session *session,
if (dso__loaded(self->dso, self->type))
return 0;
- nr = dso__load(self->dso, self, session, filter);
+ nr = dso__load(self->dso, self, filter);
if (nr < 0) {
if (self->dso->has_build_id) {
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
@@ -144,24 +143,29 @@ int map__load(struct map *self, struct perf_session *session,
return -1;
}
+ /*
+ * Only applies to the kernel, as its symtabs aren't relative like the
+ * module ones.
+ */
+ if (self->dso->kernel)
+ map__reloc_vmlinux(self);
return 0;
}
-struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
- u64 addr, symbol_filter_t filter)
+struct symbol *map__find_symbol(struct map *self, u64 addr,
+ symbol_filter_t filter)
{
- if (map__load(self, session, filter) < 0)
+ if (map__load(self, filter) < 0)
return NULL;
return dso__find_symbol(self->dso, self->type, addr);
}
struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
- struct perf_session *session,
symbol_filter_t filter)
{
- if (map__load(self, session, filter) < 0)
+ if (map__load(self, filter) < 0)
return NULL;
if (!dso__sorted_by_name(self->dso, self->type))
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 72f0b6a..de04839 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -14,6 +14,8 @@ enum map_type {
#define MAP__NR_TYPES (MAP__VARIABLE + 1)
struct dso;
+struct ref_reloc_sym;
+struct map_groups;
struct map {
union {
@@ -29,6 +31,16 @@ struct map {
struct dso *dso;
};
+struct kmap {
+ struct ref_reloc_sym *ref_reloc_sym;
+ struct map_groups *kmaps;
+};
+
+static inline struct kmap *map__kmap(struct map *self)
+{
+ return (struct kmap *)(self + 1);
+}
+
static inline u64 map__map_ip(struct map *map, u64 ip)
{
return ip - map->start + map->pgoff;
@@ -58,16 +70,14 @@ struct map *map__clone(struct map *self);
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *self, FILE *fp);
-struct perf_session;
-
-int map__load(struct map *self, struct perf_session *session,
- symbol_filter_t filter);
-struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
+int map__load(struct map *self, symbol_filter_t filter);
+struct symbol *map__find_symbol(struct map *self,
u64 addr, symbol_filter_t filter);
struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
- struct perf_session *session,
symbol_filter_t filter);
void map__fixup_start(struct map *self);
void map__fixup_end(struct map *self);
+void map__reloc_vmlinux(struct map *self);
+

0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home