perf tools: Replace map->referenced & maps->removed_maps with map->refcnt
authorArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 16 Jun 2015 02:29:51 +0000 (23:29 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 16 Jun 2015 13:34:38 +0000 (10:34 -0300)
Use just reference counts, so that when no more hist_entry instances
references a map and the thread instance goes away by processing a
PERF_RECORD_EXIT, we can delete the maps.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-oym7lfhcc7ss6xpz44h7nbxs@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/hist.c
tools/perf/util/map.c
tools/perf/util/map.h

index f53d017c7c22eabc70c270f6b6c999ab85a40686..6f28d53d4e46093293e71363d9aa5e7c1e0b23f5 100644 (file)
@@ -313,8 +313,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
                                memset(&he->stat, 0, sizeof(he->stat));
                }
 
-               if (he->ms.map)
-                       he->ms.map->referenced = true;
+               map__get(he->ms.map);
 
                if (he->branch_info) {
                        /*
@@ -324,6 +323,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
                         */
                        he->branch_info = malloc(sizeof(*he->branch_info));
                        if (he->branch_info == NULL) {
+                               map__zput(he->ms.map);
                                free(he->stat_acc);
                                free(he);
                                return NULL;
@@ -332,17 +332,13 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
                        memcpy(he->branch_info, template->branch_info,
                               sizeof(*he->branch_info));
 
-                       if (he->branch_info->from.map)
-                               he->branch_info->from.map->referenced = true;
-                       if (he->branch_info->to.map)
-                               he->branch_info->to.map->referenced = true;
+                       map__get(he->branch_info->from.map);
+                       map__get(he->branch_info->to.map);
                }
 
                if (he->mem_info) {
-                       if (he->mem_info->iaddr.map)
-                               he->mem_info->iaddr.map->referenced = true;
-                       if (he->mem_info->daddr.map)
-                               he->mem_info->daddr.map->referenced = true;
+                       map__get(he->mem_info->iaddr.map);
+                       map__get(he->mem_info->daddr.map);
                }
 
                if (symbol_conf.use_callchain)
@@ -407,9 +403,8 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
                         * the history counter to increment.
                         */
                        if (he->ms.map != entry->ms.map) {
-                               he->ms.map = entry->ms.map;
-                               if (he->ms.map)
-                                       he->ms.map->referenced = true;
+                               map__put(he->ms.map);
+                               he->ms.map = map__get(entry->ms.map);
                        }
                        goto out;
                }
@@ -933,8 +928,20 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 void hist_entry__delete(struct hist_entry *he)
 {
        thread__zput(he->thread);
-       zfree(&he->branch_info);
-       zfree(&he->mem_info);
+       map__zput(he->ms.map);
+
+       if (he->branch_info) {
+               map__zput(he->branch_info->from.map);
+               map__zput(he->branch_info->to.map);
+               zfree(&he->branch_info);
+       }
+
+       if (he->mem_info) {
+               map__zput(he->mem_info->iaddr.map);
+               map__zput(he->mem_info->daddr.map);
+               zfree(&he->mem_info);
+       }
+
        zfree(&he->stat_acc);
        free_srcline(he->srcline);
        free_callchain(he->callchain);
index 1241ab989cf5d72d46b0f9493770c837d557f32e..b5a5e9c024379652fccd722d7da2739169e0ab5d 100644 (file)
@@ -137,7 +137,6 @@ void map__init(struct map *map, enum map_type type,
        map->unmap_ip = map__unmap_ip;
        RB_CLEAR_NODE(&map->rb_node);
        map->groups   = NULL;
-       map->referenced = false;
        map->erange_warned = false;
        atomic_set(&map->refcnt, 1);
 }
@@ -439,7 +438,6 @@ static void maps__init(struct maps *maps)
 {
        maps->entries = RB_ROOT;
        pthread_rwlock_init(&maps->lock, NULL);
-       INIT_LIST_HEAD(&maps->removed_maps);
 }
 
 void map_groups__init(struct map_groups *mg, struct machine *machine)
@@ -466,21 +464,10 @@ static void __maps__purge(struct maps *maps)
        }
 }
 
-static void __maps__purge_removed_maps(struct maps *maps)
-{
-       struct map *pos, *n;
-
-       list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
-               list_del_init(&pos->node);
-               map__put(pos);
-       }
-}
-
 static void maps__exit(struct maps *maps)
 {
        pthread_rwlock_wrlock(&maps->lock);
        __maps__purge(maps);
-       __maps__purge_removed_maps(maps);
        pthread_rwlock_unlock(&maps->lock);
 }
 
@@ -499,8 +486,6 @@ bool map_groups__empty(struct map_groups *mg)
        for (i = 0; i < MAP__NR_TYPES; ++i) {
                if (maps__first(&mg->maps[i]))
                        return false;
-               if (!list_empty(&mg->maps[i].removed_maps))
-                       return false;
        }
 
        return true;
@@ -621,7 +606,7 @@ size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
        return printed += maps__fprintf(&mg->maps[type], fp);
 }
 
-static size_t map_groups__fprintf_maps(struct map_groups *mg, FILE *fp)
+size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
 {
        size_t printed = 0, i;
        for (i = 0; i < MAP__NR_TYPES; ++i)
@@ -629,39 +614,6 @@ static size_t map_groups__fprintf_maps(struct map_groups *mg, FILE *fp)
        return printed;
 }
 
-static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
-                                                enum map_type type, FILE *fp)
-{
-       struct map *pos;
-       size_t printed = 0;
-
-       list_for_each_entry(pos, &mg->maps[type].removed_maps, node) {
-               printed += fprintf(fp, "Map:");
-               printed += map__fprintf(pos, fp);
-               if (verbose > 1) {
-                       printed += dso__fprintf(pos->dso, type, fp);
-                       printed += fprintf(fp, "--\n");
-               }
-       }
-       return printed;
-}
-
-static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
-                                              FILE *fp)
-{
-       size_t printed = 0, i;
-       for (i = 0; i < MAP__NR_TYPES; ++i)
-               printed += __map_groups__fprintf_removed_maps(mg, i, fp);
-       return printed;
-}
-
-size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
-{
-       size_t printed = map_groups__fprintf_maps(mg, fp);
-       printed += fprintf(fp, "Removed maps:\n");
-       return printed + map_groups__fprintf_removed_maps(mg, fp);
-}
-
 static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
 {
        struct rb_root *root;
@@ -719,13 +671,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
                                map__fprintf(after, fp);
                }
 put_map:
-               /*
-                * If we have references, just move them to a separate list.
-                */
-               if (pos->referenced)
-                       list_add_tail(&pos->node, &maps->removed_maps);
-               else
-                       map__put(pos);
+               map__put(pos);
 
                if (err)
                        goto out;
index b8df09d94aca5072347f2b9af488a4799bce08d4..d73e687b224e4e0d3b427f1244695ea4e19c4fcb 100644 (file)
@@ -34,7 +34,6 @@ struct map {
        u64                     start;
        u64                     end;
        u8 /* enum map_type */  type;
-       bool                    referenced;
        bool                    erange_warned;
        u32                     priv;
        u32                     prot;
@@ -63,7 +62,6 @@ struct kmap {
 struct maps {
        struct rb_root   entries;
        pthread_rwlock_t lock;
-       struct list_head removed_maps;
 };
 
 struct map_groups {
@@ -161,6 +159,14 @@ static inline struct map *map__get(struct map *map)
 
 void map__put(struct map *map);
 
+static inline void __map__zput(struct map **map)
+{
+       map__put(*map);
+       *map = NULL;
+}
+
+#define map__zput(map) __map__zput(&map)
+
 int map__overlap(struct map *l, struct map *r);
 size_t map__fprintf(struct map *map, FILE *fp);
 size_t map__fprintf_dsoname(struct map *map, FILE *fp);