Skip to content

Commit 5c24b67

Browse files
committed
perf tools: Replace map->referenced & maps->removed_maps with map->refcnt
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 <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: David Ahern <[email protected]> Cc: Don Zickus <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Stephane Eranian <[email protected]> Link: http://lkml.kernel.org/n/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 35a23ff commit 5c24b67

File tree

3 files changed

+32
-73
lines changed

3 files changed

+32
-73
lines changed

tools/perf/util/hist.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
313313
memset(&he->stat, 0, sizeof(he->stat));
314314
}
315315

316-
if (he->ms.map)
317-
he->ms.map->referenced = true;
316+
map__get(he->ms.map);
318317

319318
if (he->branch_info) {
320319
/*
@@ -324,6 +323,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
324323
*/
325324
he->branch_info = malloc(sizeof(*he->branch_info));
326325
if (he->branch_info == NULL) {
326+
map__zput(he->ms.map);
327327
free(he->stat_acc);
328328
free(he);
329329
return NULL;
@@ -332,17 +332,13 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
332332
memcpy(he->branch_info, template->branch_info,
333333
sizeof(*he->branch_info));
334334

335-
if (he->branch_info->from.map)
336-
he->branch_info->from.map->referenced = true;
337-
if (he->branch_info->to.map)
338-
he->branch_info->to.map->referenced = true;
335+
map__get(he->branch_info->from.map);
336+
map__get(he->branch_info->to.map);
339337
}
340338

341339
if (he->mem_info) {
342-
if (he->mem_info->iaddr.map)
343-
he->mem_info->iaddr.map->referenced = true;
344-
if (he->mem_info->daddr.map)
345-
he->mem_info->daddr.map->referenced = true;
340+
map__get(he->mem_info->iaddr.map);
341+
map__get(he->mem_info->daddr.map);
346342
}
347343

348344
if (symbol_conf.use_callchain)
@@ -407,9 +403,8 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
407403
* the history counter to increment.
408404
*/
409405
if (he->ms.map != entry->ms.map) {
410-
he->ms.map = entry->ms.map;
411-
if (he->ms.map)
412-
he->ms.map->referenced = true;
406+
map__put(he->ms.map);
407+
he->ms.map = map__get(entry->ms.map);
413408
}
414409
goto out;
415410
}
@@ -933,8 +928,20 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
933928
void hist_entry__delete(struct hist_entry *he)
934929
{
935930
thread__zput(he->thread);
936-
zfree(&he->branch_info);
937-
zfree(&he->mem_info);
931+
map__zput(he->ms.map);
932+
933+
if (he->branch_info) {
934+
map__zput(he->branch_info->from.map);
935+
map__zput(he->branch_info->to.map);
936+
zfree(&he->branch_info);
937+
}
938+
939+
if (he->mem_info) {
940+
map__zput(he->mem_info->iaddr.map);
941+
map__zput(he->mem_info->daddr.map);
942+
zfree(&he->mem_info);
943+
}
944+
938945
zfree(&he->stat_acc);
939946
free_srcline(he->srcline);
940947
free_callchain(he->callchain);

tools/perf/util/map.c

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ void map__init(struct map *map, enum map_type type,
137137
map->unmap_ip = map__unmap_ip;
138138
RB_CLEAR_NODE(&map->rb_node);
139139
map->groups = NULL;
140-
map->referenced = false;
141140
map->erange_warned = false;
142141
atomic_set(&map->refcnt, 1);
143142
}
@@ -439,7 +438,6 @@ static void maps__init(struct maps *maps)
439438
{
440439
maps->entries = RB_ROOT;
441440
pthread_rwlock_init(&maps->lock, NULL);
442-
INIT_LIST_HEAD(&maps->removed_maps);
443441
}
444442

445443
void map_groups__init(struct map_groups *mg, struct machine *machine)
@@ -466,21 +464,10 @@ static void __maps__purge(struct maps *maps)
466464
}
467465
}
468466

469-
static void __maps__purge_removed_maps(struct maps *maps)
470-
{
471-
struct map *pos, *n;
472-
473-
list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
474-
list_del_init(&pos->node);
475-
map__put(pos);
476-
}
477-
}
478-
479467
static void maps__exit(struct maps *maps)
480468
{
481469
pthread_rwlock_wrlock(&maps->lock);
482470
__maps__purge(maps);
483-
__maps__purge_removed_maps(maps);
484471
pthread_rwlock_unlock(&maps->lock);
485472
}
486473

@@ -499,8 +486,6 @@ bool map_groups__empty(struct map_groups *mg)
499486
for (i = 0; i < MAP__NR_TYPES; ++i) {
500487
if (maps__first(&mg->maps[i]))
501488
return false;
502-
if (!list_empty(&mg->maps[i].removed_maps))
503-
return false;
504489
}
505490

506491
return true;
@@ -621,47 +606,14 @@ size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
621606
return printed += maps__fprintf(&mg->maps[type], fp);
622607
}
623608

624-
static size_t map_groups__fprintf_maps(struct map_groups *mg, FILE *fp)
609+
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
625610
{
626611
size_t printed = 0, i;
627612
for (i = 0; i < MAP__NR_TYPES; ++i)
628613
printed += __map_groups__fprintf_maps(mg, i, fp);
629614
return printed;
630615
}
631616

632-
static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
633-
enum map_type type, FILE *fp)
634-
{
635-
struct map *pos;
636-
size_t printed = 0;
637-
638-
list_for_each_entry(pos, &mg->maps[type].removed_maps, node) {
639-
printed += fprintf(fp, "Map:");
640-
printed += map__fprintf(pos, fp);
641-
if (verbose > 1) {
642-
printed += dso__fprintf(pos->dso, type, fp);
643-
printed += fprintf(fp, "--\n");
644-
}
645-
}
646-
return printed;
647-
}
648-
649-
static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
650-
FILE *fp)
651-
{
652-
size_t printed = 0, i;
653-
for (i = 0; i < MAP__NR_TYPES; ++i)
654-
printed += __map_groups__fprintf_removed_maps(mg, i, fp);
655-
return printed;
656-
}
657-
658-
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
659-
{
660-
size_t printed = map_groups__fprintf_maps(mg, fp);
661-
printed += fprintf(fp, "Removed maps:\n");
662-
return printed + map_groups__fprintf_removed_maps(mg, fp);
663-
}
664-
665617
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
666618
{
667619
struct rb_root *root;
@@ -719,13 +671,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
719671
map__fprintf(after, fp);
720672
}
721673
put_map:
722-
/*
723-
* If we have references, just move them to a separate list.
724-
*/
725-
if (pos->referenced)
726-
list_add_tail(&pos->node, &maps->removed_maps);
727-
else
728-
map__put(pos);
674+
map__put(pos);
729675

730676
if (err)
731677
goto out;

tools/perf/util/map.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ struct map {
3434
u64 start;
3535
u64 end;
3636
u8 /* enum map_type */ type;
37-
bool referenced;
3837
bool erange_warned;
3938
u32 priv;
4039
u32 prot;
@@ -63,7 +62,6 @@ struct kmap {
6362
struct maps {
6463
struct rb_root entries;
6564
pthread_rwlock_t lock;
66-
struct list_head removed_maps;
6765
};
6866

6967
struct map_groups {
@@ -161,6 +159,14 @@ static inline struct map *map__get(struct map *map)
161159

162160
void map__put(struct map *map);
163161

162+
static inline void __map__zput(struct map **map)
163+
{
164+
map__put(*map);
165+
*map = NULL;
166+
}
167+
168+
#define map__zput(map) __map__zput(&map)
169+
164170
int map__overlap(struct map *l, struct map *r);
165171
size_t map__fprintf(struct map *map, FILE *fp);
166172
size_t map__fprintf_dsoname(struct map *map, FILE *fp);

0 commit comments

Comments
 (0)