Commit 2446042c authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by Ingo Molnar

perf symbols: Capture the running kernel buildid too

[root@doppio linux-2.6-tip]# perf record -a -f sleep 3s ; perf
buildid-list | grep vmlinux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.171 MB perf.data (~7489
samples) ] 18e7cc53db62a7d35e9d6f6c9ddc23017d38ee9a vmlinux
[root@doppio linux-2.6-tip]#

Several refactorings were needed so that we can have symmetry
between dsos__load_modules() and dsos__load_kernel(), i.e. those
functions will respectively create and add to the dsos list the
loaded modules and kernel, with its buildids, but not load its
symbols. That is something the subcomands that need will have to
call dso__load_kernel_sym(), just like we do with modules with
dsos__load_module_sym()/dso__load_module_sym().

Next csets will actually use this info to stop producing bogus
results using mismatched vmlinux and .ko files.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Roland McGrath <roland@redhat.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>
LKML-Reference: <1258582853-8579-4-git-send-email-acme@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent f1617b40
...@@ -948,7 +948,12 @@ static int symbol_filter(struct map *map, struct symbol *sym) ...@@ -948,7 +948,12 @@ static int symbol_filter(struct map *map, struct symbol *sym)
static int parse_symbols(void) static int parse_symbols(void)
{ {
if (dsos__load_kernel(vmlinux_name, symbol_filter, 1) <= 0) struct dso *kernel = dsos__load_kernel();
if (kernel == NULL)
return -1;
if (dso__load_kernel_sym(kernel, symbol_filter, 1) <= 0)
return -1; return -1;
if (dump_symtab) if (dump_symtab)
......
...@@ -241,6 +241,7 @@ perf_header__adds_write(struct perf_header *self, int fd) ...@@ -241,6 +241,7 @@ perf_header__adds_write(struct perf_header *self, int fd)
buildid_sec = &feat_sec[idx++]; buildid_sec = &feat_sec[idx++];
dsos__load_kernel();
/* /*
* Read the list of loaded modules with its build_ids * Read the list of loaded modules with its build_ids
*/ */
......
...@@ -1352,17 +1352,11 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, ...@@ -1352,17 +1352,11 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
return err; return err;
} }
int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, int dso__load_kernel_sym(struct dso *self, symbol_filter_t filter, int use_modules)
int use_modules)
{ {
int err = -1; int err = -1;
struct dso *dso = dso__new(vmlinux);
if (dso == NULL) kernel_map = map__new2(0, self);
return -1;
dso->short_name = "[kernel]";
kernel_map = map__new2(0, dso);
if (kernel_map == NULL) if (kernel_map == NULL)
goto out_delete_dso; goto out_delete_dso;
...@@ -1374,8 +1368,7 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, ...@@ -1374,8 +1368,7 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter,
use_modules = 0; use_modules = 0;
} }
if (vmlinux) { err = dso__load_vmlinux(self, kernel_map, self->name, filter);
err = dso__load_vmlinux(dso, kernel_map, vmlinux, filter);
if (err > 0 && use_modules) { if (err > 0 && use_modules) {
int syms = dsos__load_modules_sym(filter); int syms = dsos__load_modules_sym(filter);
...@@ -1385,28 +1378,26 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, ...@@ -1385,28 +1378,26 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter,
else else
err += syms; err += syms;
} }
}
if (err <= 0) if (err <= 0)
err = kernel_maps__load_kallsyms(filter, use_modules); err = kernel_maps__load_kallsyms(filter, use_modules);
if (err > 0) { if (err > 0) {
struct rb_node *node = rb_first(&dso->syms); struct rb_node *node = rb_first(&self->syms);
struct symbol *sym = rb_entry(node, struct symbol, rb_node); struct symbol *sym = rb_entry(node, struct symbol, rb_node);
kernel_map->start = sym->start; kernel_map->start = sym->start;
node = rb_last(&dso->syms); node = rb_last(&self->syms);
sym = rb_entry(node, struct symbol, rb_node); sym = rb_entry(node, struct symbol, rb_node);
kernel_map->end = sym->end; kernel_map->end = sym->end;
dso->origin = DSO__ORIG_KERNEL; self->origin = DSO__ORIG_KERNEL;
kernel_maps__insert(kernel_map); kernel_maps__insert(kernel_map);
/* /*
* Now that we have all sorted out, just set the ->end of all * Now that we have all sorted out, just set the ->end of all
* maps: * maps:
*/ */
kernel_maps__fixup_end(); kernel_maps__fixup_end();
dsos__add(dso);
if (verbose) if (verbose)
kernel_maps__fprintf(stderr); kernel_maps__fprintf(stderr);
...@@ -1415,7 +1406,7 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, ...@@ -1415,7 +1406,7 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter,
return err; return err;
out_delete_dso: out_delete_dso:
dso__delete(dso); dso__delete(self);
return -1; return -1;
} }
...@@ -1475,18 +1466,36 @@ size_t dsos__fprintf_buildid(FILE *fp) ...@@ -1475,18 +1466,36 @@ size_t dsos__fprintf_buildid(FILE *fp)
return ret; return ret;
} }
int load_kernel(symbol_filter_t filter) struct dso *dsos__load_kernel(void)
{ {
if (dsos__load_kernel(vmlinux_name, filter, modules) <= 0) struct dso *kernel = dso__new(vmlinux_name);
return -1;
if (kernel == NULL)
return NULL;
kernel->short_name = "[kernel]";
vdso = dso__new("[vdso]"); vdso = dso__new("[vdso]");
if (!vdso) if (!vdso)
return -1; return NULL;
if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
sizeof(kernel->build_id)) == 0)
kernel->has_build_id = true;
dsos__add(kernel);
dsos__add(vdso); dsos__add(vdso);
return 0; return kernel;
}
int load_kernel(symbol_filter_t filter)
{
struct dso *kernel = dsos__load_kernel();
if (kernel == NULL)
return -1;
return dso__load_kernel_sym(kernel, filter, modules);
} }
void symbol__init(unsigned int priv_size) void symbol__init(unsigned int priv_size)
......
...@@ -77,10 +77,10 @@ void dso__delete(struct dso *self); ...@@ -77,10 +77,10 @@ void dso__delete(struct dso *self);
struct symbol *dso__find_symbol(struct dso *self, u64 ip); struct symbol *dso__find_symbol(struct dso *self, u64 ip);
int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, int modules);
int dsos__load_modules(void); int dsos__load_modules(void);
struct dso *dsos__findnew(const char *name); struct dso *dsos__findnew(const char *name);
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
int dso__load_kernel_sym(struct dso *self, symbol_filter_t filter, int modules);
void dsos__fprintf(FILE *fp); void dsos__fprintf(FILE *fp);
size_t dsos__fprintf_buildid(FILE *fp); size_t dsos__fprintf_buildid(FILE *fp);
...@@ -94,6 +94,7 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size); ...@@ -94,6 +94,7 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
bool dsos__read_build_ids(void); bool dsos__read_build_ids(void);
int build_id__sprintf(u8 *self, int len, char *bf); int build_id__sprintf(u8 *self, int len, char *bf);
struct dso *dsos__load_kernel(void);
int load_kernel(symbol_filter_t filter); int load_kernel(symbol_filter_t filter);
void symbol__init(unsigned int priv_size); void symbol__init(unsigned int priv_size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment