Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c24b67a authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

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 <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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 35a23ff9
Loading
Loading
Loading
Loading
+22 −15
Original line number Diff line number Diff line
@@ -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);
	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);
+2 −56
Original line number Diff line number Diff line
@@ -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,12 +671,6 @@ 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);

		if (err)
+8 −2
Original line number Diff line number Diff line
@@ -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);