diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-06-05 08:04:59 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-05 08:46:41 -0400 |
commit | fc54db5105d01ad691a7d747064c7890e17f936c (patch) | |
tree | 324d0c7ab589203329098c1eba1b763c29df14dd | |
parent | 089dd79db9264dc0da602bad45d42f1b3e7d1e07 (diff) |
perf report: Deal with maps
In order to deal with [vdso] maps generalize the ip->symbol path
a bit and allow to override some bits with custom functions.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | Documentation/perf_counter/builtin-report.c | 37 | ||||
-rw-r--r-- | Documentation/perf_counter/util/symbol.c | 1 | ||||
-rw-r--r-- | Documentation/perf_counter/util/symbol.h | 1 |
3 files changed, 37 insertions, 2 deletions
diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c index eb5424fcbd62..9783d1e493c4 100644 --- a/Documentation/perf_counter/builtin-report.c +++ b/Documentation/perf_counter/builtin-report.c | |||
@@ -79,6 +79,7 @@ typedef union event_union { | |||
79 | 79 | ||
80 | static LIST_HEAD(dsos); | 80 | static LIST_HEAD(dsos); |
81 | static struct dso *kernel_dso; | 81 | static struct dso *kernel_dso; |
82 | static struct dso *vdso; | ||
82 | 83 | ||
83 | static void dsos__add(struct dso *dso) | 84 | static void dsos__add(struct dso *dso) |
84 | { | 85 | { |
@@ -136,6 +137,11 @@ static void dsos__fprintf(FILE *fp) | |||
136 | dso__fprintf(pos, fp); | 137 | dso__fprintf(pos, fp); |
137 | } | 138 | } |
138 | 139 | ||
140 | static struct symbol *vdso__find_symbol(struct dso *dso, uint64_t ip) | ||
141 | { | ||
142 | return dso__find_symbol(kernel_dso, ip); | ||
143 | } | ||
144 | |||
139 | static int load_kernel(void) | 145 | static int load_kernel(void) |
140 | { | 146 | { |
141 | int err; | 147 | int err; |
@@ -151,6 +157,14 @@ static int load_kernel(void) | |||
151 | } else | 157 | } else |
152 | dsos__add(kernel_dso); | 158 | dsos__add(kernel_dso); |
153 | 159 | ||
160 | vdso = dso__new("[vdso]", 0); | ||
161 | if (!vdso) | ||
162 | return -1; | ||
163 | |||
164 | vdso->find_symbol = vdso__find_symbol; | ||
165 | |||
166 | dsos__add(vdso); | ||
167 | |||
154 | return err; | 168 | return err; |
155 | } | 169 | } |
156 | 170 | ||
@@ -173,9 +187,20 @@ struct map { | |||
173 | uint64_t start; | 187 | uint64_t start; |
174 | uint64_t end; | 188 | uint64_t end; |
175 | uint64_t pgoff; | 189 | uint64_t pgoff; |
190 | uint64_t (*map_ip)(struct map *, uint64_t); | ||
176 | struct dso *dso; | 191 | struct dso *dso; |
177 | }; | 192 | }; |
178 | 193 | ||
194 | static uint64_t map__map_ip(struct map *map, uint64_t ip) | ||
195 | { | ||
196 | return ip - map->start + map->pgoff; | ||
197 | } | ||
198 | |||
199 | static uint64_t vdso__map_ip(struct map *map, uint64_t ip) | ||
200 | { | ||
201 | return ip; | ||
202 | } | ||
203 | |||
179 | static struct map *map__new(struct mmap_event *event) | 204 | static struct map *map__new(struct mmap_event *event) |
180 | { | 205 | { |
181 | struct map *self = malloc(sizeof(*self)); | 206 | struct map *self = malloc(sizeof(*self)); |
@@ -201,6 +226,11 @@ static struct map *map__new(struct mmap_event *event) | |||
201 | self->dso = dsos__findnew(filename); | 226 | self->dso = dsos__findnew(filename); |
202 | if (self->dso == NULL) | 227 | if (self->dso == NULL) |
203 | goto out_delete; | 228 | goto out_delete; |
229 | |||
230 | if (self->dso == vdso) | ||
231 | self->map_ip = vdso__map_ip; | ||
232 | else | ||
233 | self->map_ip = map__map_ip; | ||
204 | } | 234 | } |
205 | return self; | 235 | return self; |
206 | out_delete: | 236 | out_delete: |
@@ -917,8 +947,8 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head) | |||
917 | 947 | ||
918 | map = thread__find_map(thread, ip); | 948 | map = thread__find_map(thread, ip); |
919 | if (map != NULL) { | 949 | if (map != NULL) { |
950 | ip = map->map_ip(map, ip); | ||
920 | dso = map->dso; | 951 | dso = map->dso; |
921 | ip -= map->start + map->pgoff; | ||
922 | } else { | 952 | } else { |
923 | /* | 953 | /* |
924 | * If this is outside of all known maps, | 954 | * If this is outside of all known maps, |
@@ -938,7 +968,10 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head) | |||
938 | } | 968 | } |
939 | 969 | ||
940 | if (show & show_mask) { | 970 | if (show & show_mask) { |
941 | struct symbol *sym = dso__find_symbol(dso, ip); | 971 | struct symbol *sym = NULL; |
972 | |||
973 | if (dso) | ||
974 | sym = dso->find_symbol(dso, ip); | ||
942 | 975 | ||
943 | if (hist_entry__add(thread, map, dso, sym, ip, level)) { | 976 | if (hist_entry__add(thread, map, dso, sym, ip, level)) { |
944 | fprintf(stderr, | 977 | fprintf(stderr, |
diff --git a/Documentation/perf_counter/util/symbol.c b/Documentation/perf_counter/util/symbol.c index 15d5cf9abfac..a06bbfba8350 100644 --- a/Documentation/perf_counter/util/symbol.c +++ b/Documentation/perf_counter/util/symbol.c | |||
@@ -45,6 +45,7 @@ struct dso *dso__new(const char *name, unsigned int sym_priv_size) | |||
45 | strcpy(self->name, name); | 45 | strcpy(self->name, name); |
46 | self->syms = RB_ROOT; | 46 | self->syms = RB_ROOT; |
47 | self->sym_priv_size = sym_priv_size; | 47 | self->sym_priv_size = sym_priv_size; |
48 | self->find_symbol = dso__find_symbol; | ||
48 | } | 49 | } |
49 | 50 | ||
50 | return self; | 51 | return self; |
diff --git a/Documentation/perf_counter/util/symbol.h b/Documentation/perf_counter/util/symbol.h index 8dd8522a0a0c..e23cc3126684 100644 --- a/Documentation/perf_counter/util/symbol.h +++ b/Documentation/perf_counter/util/symbol.h | |||
@@ -16,6 +16,7 @@ struct dso { | |||
16 | struct list_head node; | 16 | struct list_head node; |
17 | struct rb_root syms; | 17 | struct rb_root syms; |
18 | unsigned int sym_priv_size; | 18 | unsigned int sym_priv_size; |
19 | struct symbol *(*find_symbol)(struct dso *, uint64_t ip); | ||
19 | char name[0]; | 20 | char name[0]; |
20 | }; | 21 | }; |
21 | 22 | ||