aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-04-29 15:25:23 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-04-29 15:25:23 -0300
commit5c0541d53ef3897494768decb09eb8f1087953a5 (patch)
tree38b8eab8e45a2d2265db64b131320e6baa43b984
parent18acde52b83bd1c8e1d007db519f46d344aa13ed (diff)
downloadkernel_samsung_espresso10-5c0541d53ef3897494768decb09eb8f1087953a5.zip
kernel_samsung_espresso10-5c0541d53ef3897494768decb09eb8f1087953a5.tar.gz
kernel_samsung_espresso10-5c0541d53ef3897494768decb09eb8f1087953a5.tar.bz2
perf symbols: Add machine helper routines
Created when writing the first 'perf test' regression testing routine. Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/util/map.h25
-rw-r--r--tools/perf/util/symbol.c77
-rw-r--r--tools/perf/util/symbol.h7
4 files changed, 86 insertions, 25 deletions
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 1563561..ee05dba 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -377,7 +377,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
if (is_caller) {
addr = data->call_site;
if (!raw_ip)
- sym = machine__find_function(machine, addr, &map, NULL);
+ sym = machine__find_kernel_function(machine, addr, &map, NULL);
} else
addr = data->ptr;
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 881dba4..f391345 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -30,6 +30,7 @@ struct map {
u64 start;
u64 end;
enum map_type type;
+ u32 priv;
u64 pgoff;
/* ip -> dso rip */
@@ -66,6 +67,12 @@ struct machine {
struct map *vmlinux_maps[MAP__NR_TYPES];
};
+static inline
+struct map *machine__kernel_map(struct machine *self, enum map_type type)
+{
+ return self->vmlinux_maps[type];
+}
+
static inline struct kmap *map__kmap(struct map *self)
{
return (struct kmap *)(self + 1);
@@ -173,11 +180,21 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
struct map **mapp,
symbol_filter_t filter);
-static inline struct symbol *machine__find_function(struct machine *self,
- u64 addr, struct map **mapp,
- symbol_filter_t filter)
+static inline
+struct symbol *machine__find_kernel_symbol(struct machine *self,
+ enum map_type type, u64 addr,
+ struct map **mapp,
+ symbol_filter_t filter)
+{
+ return map_groups__find_symbol(&self->kmaps, type, addr, mapp, filter);
+}
+
+static inline
+struct symbol *machine__find_kernel_function(struct machine *self, u64 addr,
+ struct map **mapp,
+ symbol_filter_t filter)
{
- return map_groups__find_symbol(&self->kmaps, MAP__FUNCTION, addr, mapp, filter);
+ return machine__find_kernel_symbol(self, MAP__FUNCTION, addr, mapp, filter);
}
static inline
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index caa890f..4c0146a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1983,23 +1983,23 @@ void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine
self->has_build_id = true;
}
-static struct dso *dsos__create_kernel(struct machine *machine)
+static struct dso *machine__create_kernel(struct machine *self)
{
const char *vmlinux_name = NULL;
struct dso *kernel;
- if (machine__is_host(machine)) {
+ if (machine__is_host(self)) {
vmlinux_name = symbol_conf.vmlinux_name;
kernel = dso__new_kernel(vmlinux_name);
} else {
- if (machine__is_default_guest(machine))
+ if (machine__is_default_guest(self))
vmlinux_name = symbol_conf.default_guest_vmlinux_name;
- kernel = dso__new_guest_kernel(machine, vmlinux_name);
+ kernel = dso__new_guest_kernel(self, vmlinux_name);
}
if (kernel != NULL) {
- dso__read_running_kernel_build_id(kernel, machine);
- dsos__add(&machine->kernel_dsos, kernel);
+ dso__read_running_kernel_build_id(kernel, self);
+ dsos__add(&self->kernel_dsos, kernel);
}
return kernel;
}
@@ -2026,6 +2026,23 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
return 0;
}
+int machine__create_kernel_maps(struct machine *self)
+{
+ struct dso *kernel = machine__create_kernel(self);
+
+ if (kernel == NULL ||
+ __machine__create_kernel_maps(self, kernel) < 0)
+ return -1;
+
+ if (symbol_conf.use_modules && machine__create_modules(self) < 0)
+ pr_debug("Problems creating module maps, continuing anyway...\n");
+ /*
+ * Now that we have all the maps created, just set the ->end of them:
+ */
+ map_groups__fixup_end(&self->kmaps);
+ return 0;
+}
+
static void vmlinux_path__exit(void)
{
while (--vmlinux_path__nr_entries >= 0) {
@@ -2144,25 +2161,12 @@ out_free_comm_list:
int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
{
- struct dso *kernel;
struct machine *machine = machines__findnew(self, pid);
if (machine == NULL)
return -1;
- kernel = dsos__create_kernel(machine);
- if (kernel == NULL)
- return -1;
-
- if (__machine__create_kernel_maps(machine, kernel) < 0)
- return -1;
- if (symbol_conf.use_modules && machine__create_modules(machine) < 0)
- pr_debug("Problems creating module maps, continuing anyway...\n");
- /*
- * Now that we have all the maps created, just set the ->end of them:
- */
- map_groups__fixup_end(&machine->kmaps);
- return 0;
+ return machine__create_kernel_maps(machine);
}
static int hex(char ch)
@@ -2248,3 +2252,36 @@ failure:
return ret;
}
+
+int machine__load_kallsyms(struct machine *self, const char *filename,
+ enum map_type type, symbol_filter_t filter)
+{
+ struct map *map = self->vmlinux_maps[type];
+ int ret = dso__load_kallsyms(map->dso, filename, map, filter);
+
+ if (ret > 0) {
+ dso__set_loaded(map->dso, type);
+ /*
+ * Since /proc/kallsyms will have multiple sessions for the
+ * kernel, with modules between them, fixup the end of all
+ * sections.
+ */
+ __map_groups__fixup_end(&self->kmaps, type);
+ }
+
+ return ret;
+}
+
+int machine__load_vmlinux_path(struct machine *self, enum map_type type,
+ symbol_filter_t filter)
+{
+ struct map *map = self->vmlinux_maps[type];
+ int ret = dso__load_vmlinux_path(map->dso, map, filter);
+
+ if (ret > 0) {
+ dso__set_loaded(map->dso, type);
+ map__reloc_vmlinux(map);
+ }
+
+ return ret;
+}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 2cec6a1..a517c17 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -162,6 +162,11 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
symbol_filter_t filter);
int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
symbol_filter_t filter);
+int machine__load_kallsyms(struct machine *self, const char *filename,
+ enum map_type type, symbol_filter_t filter);
+int machine__load_vmlinux_path(struct machine *self, enum map_type type,
+ symbol_filter_t filter);
+
size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
@@ -199,6 +204,8 @@ int kallsyms__parse(const char *filename, void *arg,
char type, u64 start));
int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
+int machine__create_kernel_maps(struct machine *self);
+
int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
int machines__create_guest_kernel_maps(struct rb_root *self);