aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-08-03 01:45:00 -0400
committerIngo Molnar <mingo@elte.hu>2010-08-03 01:45:00 -0400
commit43d7383bbec1878f838060d6bbd214f6d0485478 (patch)
tree64869524fc8e9fe23a9712993c608ccdcecfc2a1
parent69e77a8b0426ded5d924eea7dbe4eca51e09f530 (diff)
parent0a1eae391d0d92b60cff9f55cdaf3861b4e33922 (diff)
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/map.c49
-rw-r--r--tools/perf/util/map.h10
-rw-r--r--tools/perf/util/session.c8
-rw-r--r--tools/perf/util/symbol.c43
-rw-r--r--tools/perf/util/symbol.h2
6 files changed, 96 insertions, 18 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index a6cea2894d12..e7263d49bcf0 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -93,6 +93,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
93 if (self != NULL) { 93 if (self != NULL) {
94 *self = *template; 94 *self = *template;
95 self->nr_events = 1; 95 self->nr_events = 1;
96 if (self->ms.map)
97 self->ms.map->referenced = true;
96 if (symbol_conf.use_callchain) 98 if (symbol_conf.use_callchain)
97 callchain_init(self->callchain); 99 callchain_init(self->callchain);
98 } 100 }
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 15d6a6dd50c5..3a7eb6ec0eec 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -29,6 +29,7 @@ void map__init(struct map *self, enum map_type type,
29 self->unmap_ip = map__unmap_ip; 29 self->unmap_ip = map__unmap_ip;
30 RB_CLEAR_NODE(&self->rb_node); 30 RB_CLEAR_NODE(&self->rb_node);
31 self->groups = NULL; 31 self->groups = NULL;
32 self->referenced = false;
32} 33}
33 34
34struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, 35struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
@@ -387,6 +388,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
387{ 388{
388 struct rb_root *root = &self->maps[map->type]; 389 struct rb_root *root = &self->maps[map->type];
389 struct rb_node *next = rb_first(root); 390 struct rb_node *next = rb_first(root);
391 int err = 0;
390 392
391 while (next) { 393 while (next) {
392 struct map *pos = rb_entry(next, struct map, rb_node); 394 struct map *pos = rb_entry(next, struct map, rb_node);
@@ -403,20 +405,16 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
403 405
404 rb_erase(&pos->rb_node, root); 406 rb_erase(&pos->rb_node, root);
405 /* 407 /*
406 * We may have references to this map, for instance in some
407 * hist_entry instances, so just move them to a separate
408 * list.
409 */
410 list_add_tail(&pos->node, &self->removed_maps[map->type]);
411 /*
412 * Now check if we need to create new maps for areas not 408 * Now check if we need to create new maps for areas not
413 * overlapped by the new map: 409 * overlapped by the new map:
414 */ 410 */
415 if (map->start > pos->start) { 411 if (map->start > pos->start) {
416 struct map *before = map__clone(pos); 412 struct map *before = map__clone(pos);
417 413
418 if (before == NULL) 414 if (before == NULL) {
419 return -ENOMEM; 415 err = -ENOMEM;
416 goto move_map;
417 }
420 418
421 before->end = map->start - 1; 419 before->end = map->start - 1;
422 map_groups__insert(self, before); 420 map_groups__insert(self, before);
@@ -427,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
427 if (map->end < pos->end) { 425 if (map->end < pos->end) {
428 struct map *after = map__clone(pos); 426 struct map *after = map__clone(pos);
429 427
430 if (after == NULL) 428 if (after == NULL) {
431 return -ENOMEM; 429 err = -ENOMEM;
430 goto move_map;
431 }
432 432
433 after->start = map->end + 1; 433 after->start = map->end + 1;
434 map_groups__insert(self, after); 434 map_groups__insert(self, after);
435 if (verbose >= 2) 435 if (verbose >= 2)
436 map__fprintf(after, fp); 436 map__fprintf(after, fp);
437 } 437 }
438move_map:
439 /*
440 * If we have references, just move them to a separate list.
441 */
442 if (pos->referenced)
443 list_add_tail(&pos->node, &self->removed_maps[map->type]);
444 else
445 map__delete(pos);
446
447 if (err)
448 return err;
438 } 449 }
439 450
440 return 0; 451 return 0;
@@ -506,6 +517,11 @@ void maps__insert(struct rb_root *maps, struct map *map)
506 rb_insert_color(&map->rb_node, maps); 517 rb_insert_color(&map->rb_node, maps);
507} 518}
508 519
520void maps__remove(struct rb_root *self, struct map *map)
521{
522 rb_erase(&map->rb_node, self);
523}
524
509struct map *maps__find(struct rb_root *maps, u64 ip) 525struct map *maps__find(struct rb_root *maps, u64 ip)
510{ 526{
511 struct rb_node **p = &maps->rb_node; 527 struct rb_node **p = &maps->rb_node;
@@ -551,13 +567,6 @@ static void dsos__delete(struct list_head *self)
551 567
552void machine__exit(struct machine *self) 568void machine__exit(struct machine *self)
553{ 569{
554 struct kmap *kmap = map__kmap(self->vmlinux_maps[MAP__FUNCTION]);
555
556 if (kmap->ref_reloc_sym) {
557 free((char *)kmap->ref_reloc_sym->name);
558 free(kmap->ref_reloc_sym);
559 }
560
561 map_groups__exit(&self->kmaps); 570 map_groups__exit(&self->kmaps);
562 dsos__delete(&self->user_dsos); 571 dsos__delete(&self->user_dsos);
563 dsos__delete(&self->kernel_dsos); 572 dsos__delete(&self->kernel_dsos);
@@ -565,6 +574,12 @@ void machine__exit(struct machine *self)
565 self->root_dir = NULL; 574 self->root_dir = NULL;
566} 575}
567 576
577void machine__delete(struct machine *self)
578{
579 machine__exit(self);
580 free(self);
581}
582
568struct machine *machines__add(struct rb_root *self, pid_t pid, 583struct machine *machines__add(struct rb_root *self, pid_t pid,
569 const char *root_dir) 584 const char *root_dir)
570{ 585{
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 0e0984e86fce..78575796d5f3 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -29,7 +29,8 @@ struct map {
29 }; 29 };
30 u64 start; 30 u64 start;
31 u64 end; 31 u64 end;
32 enum map_type type; 32 u8 /* enum map_type */ type;
33 bool referenced;
33 u32 priv; 34 u32 priv;
34 u64 pgoff; 35 u64 pgoff;
35 36
@@ -125,6 +126,7 @@ void map__reloc_vmlinux(struct map *self);
125size_t __map_groups__fprintf_maps(struct map_groups *self, 126size_t __map_groups__fprintf_maps(struct map_groups *self,
126 enum map_type type, int verbose, FILE *fp); 127 enum map_type type, int verbose, FILE *fp);
127void maps__insert(struct rb_root *maps, struct map *map); 128void maps__insert(struct rb_root *maps, struct map *map);
129void maps__remove(struct rb_root *self, struct map *map);
128struct map *maps__find(struct rb_root *maps, u64 addr); 130struct map *maps__find(struct rb_root *maps, u64 addr);
129void map_groups__init(struct map_groups *self); 131void map_groups__init(struct map_groups *self);
130void map_groups__exit(struct map_groups *self); 132void map_groups__exit(struct map_groups *self);
@@ -144,6 +146,7 @@ struct machine *machines__findnew(struct rb_root *self, pid_t pid);
144char *machine__mmap_name(struct machine *self, char *bf, size_t size); 146char *machine__mmap_name(struct machine *self, char *bf, size_t size);
145int machine__init(struct machine *self, const char *root_dir, pid_t pid); 147int machine__init(struct machine *self, const char *root_dir, pid_t pid);
146void machine__exit(struct machine *self); 148void machine__exit(struct machine *self);
149void machine__delete(struct machine *self);
147 150
148/* 151/*
149 * Default guest kernel is defined by parameter --guestkallsyms 152 * Default guest kernel is defined by parameter --guestkallsyms
@@ -165,6 +168,11 @@ static inline void map_groups__insert(struct map_groups *self, struct map *map)
165 map->groups = self; 168 map->groups = self;
166} 169}
167 170
171static inline void map_groups__remove(struct map_groups *self, struct map *map)
172{
173 maps__remove(&self->maps[map->type], map);
174}
175
168static inline struct map *map_groups__find(struct map_groups *self, 176static inline struct map *map_groups__find(struct map_groups *self,
169 enum map_type type, u64 addr) 177 enum map_type type, u64 addr)
170{ 178{
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 04a3b3db9e90..fa9d652c2dc3 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -79,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self)
79 return ret; 79 return ret;
80} 80}
81 81
82static void perf_session__destroy_kernel_maps(struct perf_session *self)
83{
84 machine__destroy_kernel_maps(&self->host_machine);
85 machines__destroy_guest_kernel_maps(&self->machines);
86}
87
82struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) 88struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe)
83{ 89{
84 size_t len = filename ? strlen(filename) + 1 : 0; 90 size_t len = filename ? strlen(filename) + 1 : 0;
@@ -150,6 +156,7 @@ static void perf_session__delete_threads(struct perf_session *self)
150void perf_session__delete(struct perf_session *self) 156void perf_session__delete(struct perf_session *self)
151{ 157{
152 perf_header__exit(&self->header); 158 perf_header__exit(&self->header);
159 perf_session__destroy_kernel_maps(self);
153 perf_session__delete_dead_threads(self); 160 perf_session__delete_dead_threads(self);
154 perf_session__delete_threads(self); 161 perf_session__delete_threads(self);
155 machine__exit(&self->host_machine); 162 machine__exit(&self->host_machine);
@@ -159,6 +166,7 @@ void perf_session__delete(struct perf_session *self)
159 166
160void perf_session__remove_thread(struct perf_session *self, struct thread *th) 167void perf_session__remove_thread(struct perf_session *self, struct thread *th)
161{ 168{
169 self->last_match = NULL;
162 rb_erase(&th->rb_node, &self->threads); 170 rb_erase(&th->rb_node, &self->threads);
163 /* 171 /*
164 * We may have references to this thread, for instance in some hist_entry 172 * We may have references to this thread, for instance in some hist_entry
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 3b8c00506672..6f0dd90c36ce 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2107,6 +2107,36 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
2107 return 0; 2107 return 0;
2108} 2108}
2109 2109
2110void machine__destroy_kernel_maps(struct machine *self)
2111{
2112 enum map_type type;
2113
2114 for (type = 0; type < MAP__NR_TYPES; ++type) {
2115 struct kmap *kmap;
2116
2117 if (self->vmlinux_maps[type] == NULL)
2118 continue;
2119
2120 kmap = map__kmap(self->vmlinux_maps[type]);
2121 map_groups__remove(&self->kmaps, self->vmlinux_maps[type]);
2122 if (kmap->ref_reloc_sym) {
2123 /*
2124 * ref_reloc_sym is shared among all maps, so free just
2125 * on one of them.
2126 */
2127 if (type == MAP__FUNCTION) {
2128 free((char *)kmap->ref_reloc_sym->name);
2129 kmap->ref_reloc_sym->name = NULL;
2130 free(kmap->ref_reloc_sym);
2131 }
2132 kmap->ref_reloc_sym = NULL;
2133 }
2134
2135 map__delete(self->vmlinux_maps[type]);
2136 self->vmlinux_maps[type] = NULL;
2137 }
2138}
2139
2110int machine__create_kernel_maps(struct machine *self) 2140int machine__create_kernel_maps(struct machine *self)
2111{ 2141{
2112 struct dso *kernel = machine__create_kernel(self); 2142 struct dso *kernel = machine__create_kernel(self);
@@ -2351,6 +2381,19 @@ failure:
2351 return ret; 2381 return ret;
2352} 2382}
2353 2383
2384void machines__destroy_guest_kernel_maps(struct rb_root *self)
2385{
2386 struct rb_node *next = rb_first(self);
2387
2388 while (next) {
2389 struct machine *pos = rb_entry(next, struct machine, rb_node);
2390
2391 next = rb_next(&pos->rb_node);
2392 rb_erase(&pos->rb_node, self);
2393 machine__delete(pos);
2394 }
2395}
2396
2354int machine__load_kallsyms(struct machine *self, const char *filename, 2397int machine__load_kallsyms(struct machine *self, const char *filename,
2355 enum map_type type, symbol_filter_t filter) 2398 enum map_type type, symbol_filter_t filter)
2356{ 2399{
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 33d53ce28958..906be20011d9 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -212,11 +212,13 @@ int kallsyms__parse(const char *filename, void *arg,
212 int (*process_symbol)(void *arg, const char *name, 212 int (*process_symbol)(void *arg, const char *name,
213 char type, u64 start)); 213 char type, u64 start));
214 214
215void machine__destroy_kernel_maps(struct machine *self);
215int __machine__create_kernel_maps(struct machine *self, struct dso *kernel); 216int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
216int machine__create_kernel_maps(struct machine *self); 217int machine__create_kernel_maps(struct machine *self);
217 218
218int machines__create_kernel_maps(struct rb_root *self, pid_t pid); 219int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
219int machines__create_guest_kernel_maps(struct rb_root *self); 220int machines__create_guest_kernel_maps(struct rb_root *self);
221void machines__destroy_guest_kernel_maps(struct rb_root *self);
220 222
221int symbol__init(void); 223int symbol__init(void);
222void symbol__exit(void); 224void symbol__exit(void);