Skip to content

Commit

Permalink
perf symbols: Remove perf_session usage in symbols layer
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Arnaldo Carvalho de Melo <acme@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: <1265223128-11786-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Feb 4, 2010
1 parent b8f46c5 commit 9de89fe
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 121 deletions.
2 changes: 1 addition & 1 deletion tools/perf/builtin-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
5 changes: 2 additions & 3 deletions tools/perf/builtin-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
6 changes: 2 additions & 4 deletions tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
20 changes: 12 additions & 8 deletions tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,15 @@ 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;

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];
Expand Down Expand Up @@ -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))
Expand Down
22 changes: 16 additions & 6 deletions tools/perf/util/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -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);

#endif /* __PERF_MAP_H */
35 changes: 24 additions & 11 deletions tools/perf/util/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ static int perf_session__open(struct perf_session *self, bool force)
return -1;
}

static inline int perf_session__create_kernel_maps(struct perf_session *self)
{
return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
}

struct perf_session *perf_session__new(const char *filename, int mode, bool force)
{
size_t len = filename ? strlen(filename) + 1 : 0;
Expand Down Expand Up @@ -507,6 +512,7 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
u64 addr)
{
char *bracket;
enum map_type i;

self->ref_reloc_sym.name = strdup(symbol_name);
if (self->ref_reloc_sym.name == NULL)
Expand All @@ -517,6 +523,12 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
*bracket = '\0';

self->ref_reloc_sym.addr = addr;

for (i = 0; i < MAP__NR_TYPES; ++i) {
struct kmap *kmap = map__kmap(self->vmlinux_maps[i]);
kmap->ref_reloc_sym = &self->ref_reloc_sym;
}

return 0;
}

Expand All @@ -530,20 +542,21 @@ static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
return ip - (s64)map->pgoff;
}

void perf_session__reloc_vmlinux_maps(struct perf_session *self,
u64 unrelocated_addr)
void map__reloc_vmlinux(struct map *self)
{
enum map_type type;
s64 reloc = unrelocated_addr - self->ref_reloc_sym.addr;
struct kmap *kmap = map__kmap(self);
s64 reloc;

if (!reloc)
if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
return;

for (type = 0; type < MAP__NR_TYPES; ++type) {
struct map *map = self->vmlinux_maps[type];
reloc = (kmap->ref_reloc_sym->unrelocated_addr -
kmap->ref_reloc_sym->addr);

map->map_ip = map__reloc_map_ip;
map->unmap_ip = map__reloc_unmap_ip;
map->pgoff = reloc;
}
if (!reloc)
return;

self->map_ip = map__reloc_map_ip;
self->unmap_ip = map__reloc_unmap_ip;
self->pgoff = reloc;
}
22 changes: 15 additions & 7 deletions tools/perf/util/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

#include "event.h"
#include "header.h"
#include "symbol.h"
#include "thread.h"
#include <linux/rbtree.h>
#include "../../../include/linux/perf_event.h"

struct ip_callchain;
struct thread;
struct symbol;

struct perf_session {
struct perf_header header;
Expand All @@ -24,10 +24,7 @@ struct perf_session {
unsigned long unknown_events;
struct rb_root hists;
u64 sample_type;
struct {
const char *name;
u64 addr;
} ref_reloc_sym;
struct ref_reloc_sym ref_reloc_sym;
int fd;
int cwdlen;
char *cwd;
Expand Down Expand Up @@ -69,9 +66,20 @@ int perf_header__read_build_ids(struct perf_header *self, int input,
int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
const char *symbol_name,
u64 addr);
void perf_session__reloc_vmlinux_maps(struct perf_session *self,
u64 unrelocated_addr);

void mem_bswap_64(void *src, int byte_size);

static inline int __perf_session__create_kernel_maps(struct perf_session *self,
struct dso *kernel)
{
return __map_groups__create_kernel_maps(&self->kmaps,
self->vmlinux_maps, kernel);
}

static inline struct map *
perf_session__new_module_map(struct perf_session *self,
u64 start, const char *filename)
{
return map_groups__new_module(&self->kmaps, start, filename);
}
#endif /* __PERF_SESSION_H */
Loading

0 comments on commit 9de89fe

Please sign in to comment.