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

Commit 43d7383b authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'perf/core' of...

Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
parents 69e77a8b 0a1eae39
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -93,6 +93,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
	if (self != NULL) {
		*self = *template;
		self->nr_events = 1;
		if (self->ms.map)
			self->ms.map->referenced = true;
		if (symbol_conf.use_callchain)
			callchain_init(self->callchain);
	}
+32 −17
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ void map__init(struct map *self, enum map_type type,
	self->unmap_ip = map__unmap_ip;
	RB_CLEAR_NODE(&self->rb_node);
	self->groups   = NULL;
	self->referenced = false;
}

struct 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,
{
	struct rb_root *root = &self->maps[map->type];
	struct rb_node *next = rb_first(root);
	int err = 0;

	while (next) {
		struct map *pos = rb_entry(next, struct map, rb_node);
@@ -402,12 +404,6 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
		}

		rb_erase(&pos->rb_node, root);
		/*
		 * We may have references to this map, for instance in some
		 * hist_entry instances, so just move them to a separate
		 * list.
		 */
		list_add_tail(&pos->node, &self->removed_maps[map->type]);
		/*
		 * Now check if we need to create new maps for areas not
		 * overlapped by the new map:
@@ -415,8 +411,10 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
		if (map->start > pos->start) {
			struct map *before = map__clone(pos);

			if (before == NULL)
				return -ENOMEM;
			if (before == NULL) {
				err = -ENOMEM;
				goto move_map;
			}

			before->end = map->start - 1;
			map_groups__insert(self, before);
@@ -427,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
		if (map->end < pos->end) {
			struct map *after = map__clone(pos);

			if (after == NULL)
				return -ENOMEM;
			if (after == NULL) {
				err = -ENOMEM;
				goto move_map;
			}

			after->start = map->end + 1;
			map_groups__insert(self, after);
			if (verbose >= 2)
				map__fprintf(after, fp);
		}
move_map:
		/*
		 * If we have references, just move them to a separate list.
		 */
		if (pos->referenced)
			list_add_tail(&pos->node, &self->removed_maps[map->type]);
		else
			map__delete(pos);

		if (err)
			return err;
	}

	return 0;
@@ -506,6 +517,11 @@ void maps__insert(struct rb_root *maps, struct map *map)
	rb_insert_color(&map->rb_node, maps);
}

void maps__remove(struct rb_root *self, struct map *map)
{
	rb_erase(&map->rb_node, self);
}

struct map *maps__find(struct rb_root *maps, u64 ip)
{
	struct rb_node **p = &maps->rb_node;
@@ -551,13 +567,6 @@ static void dsos__delete(struct list_head *self)

void machine__exit(struct machine *self)
{
	struct kmap *kmap = map__kmap(self->vmlinux_maps[MAP__FUNCTION]);

	if (kmap->ref_reloc_sym) {
		free((char *)kmap->ref_reloc_sym->name);
		free(kmap->ref_reloc_sym);
	}

	map_groups__exit(&self->kmaps);
	dsos__delete(&self->user_dsos);
	dsos__delete(&self->kernel_dsos);
@@ -565,6 +574,12 @@ void machine__exit(struct machine *self)
	self->root_dir = NULL;
}

void machine__delete(struct machine *self)
{
	machine__exit(self);
	free(self);
}

struct machine *machines__add(struct rb_root *self, pid_t pid,
			      const char *root_dir)
{
+9 −1
Original line number Diff line number Diff line
@@ -29,7 +29,8 @@ struct map {
	};
	u64			start;
	u64			end;
	enum map_type		type;
	u8 /* enum map_type */	type;
	bool			referenced;
	u32			priv;
	u64			pgoff;

@@ -125,6 +126,7 @@ void map__reloc_vmlinux(struct map *self);
size_t __map_groups__fprintf_maps(struct map_groups *self,
				  enum map_type type, int verbose, FILE *fp);
void maps__insert(struct rb_root *maps, struct map *map);
void maps__remove(struct rb_root *self, struct map *map);
struct map *maps__find(struct rb_root *maps, u64 addr);
void map_groups__init(struct map_groups *self);
void map_groups__exit(struct map_groups *self);
@@ -144,6 +146,7 @@ struct machine *machines__findnew(struct rb_root *self, pid_t pid);
char *machine__mmap_name(struct machine *self, char *bf, size_t size);
int machine__init(struct machine *self, const char *root_dir, pid_t pid);
void machine__exit(struct machine *self);
void machine__delete(struct machine *self);

/*
 * 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)
	map->groups = self;
}

static inline void map_groups__remove(struct map_groups *self, struct map *map)
{
	maps__remove(&self->maps[map->type], map);
}

static inline struct map *map_groups__find(struct map_groups *self,
					   enum map_type type, u64 addr)
{
+8 −0
Original line number Diff line number Diff line
@@ -79,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self)
	return ret;
}

static void perf_session__destroy_kernel_maps(struct perf_session *self)
{
	machine__destroy_kernel_maps(&self->host_machine);
	machines__destroy_guest_kernel_maps(&self->machines);
}

struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe)
{
	size_t len = filename ? strlen(filename) + 1 : 0;
@@ -150,6 +156,7 @@ static void perf_session__delete_threads(struct perf_session *self)
void perf_session__delete(struct perf_session *self)
{
	perf_header__exit(&self->header);
	perf_session__destroy_kernel_maps(self);
	perf_session__delete_dead_threads(self);
	perf_session__delete_threads(self);
	machine__exit(&self->host_machine);
@@ -159,6 +166,7 @@ void perf_session__delete(struct perf_session *self)

void perf_session__remove_thread(struct perf_session *self, struct thread *th)
{
	self->last_match = NULL;
	rb_erase(&th->rb_node, &self->threads);
	/*
	 * We may have references to this thread, for instance in some hist_entry
+43 −0
Original line number Diff line number Diff line
@@ -2107,6 +2107,36 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
	return 0;
}

void machine__destroy_kernel_maps(struct machine *self)
{
	enum map_type type;

	for (type = 0; type < MAP__NR_TYPES; ++type) {
		struct kmap *kmap;

		if (self->vmlinux_maps[type] == NULL)
			continue;

		kmap = map__kmap(self->vmlinux_maps[type]);
		map_groups__remove(&self->kmaps, self->vmlinux_maps[type]);
		if (kmap->ref_reloc_sym) {
			/*
			 * ref_reloc_sym is shared among all maps, so free just
			 * on one of them.
			 */
			if (type == MAP__FUNCTION) {
				free((char *)kmap->ref_reloc_sym->name);
				kmap->ref_reloc_sym->name = NULL;
				free(kmap->ref_reloc_sym);
			}
			kmap->ref_reloc_sym = NULL;
		}

		map__delete(self->vmlinux_maps[type]);
		self->vmlinux_maps[type] = NULL;
	}
}

int machine__create_kernel_maps(struct machine *self)
{
	struct dso *kernel = machine__create_kernel(self);
@@ -2351,6 +2381,19 @@ int machines__create_guest_kernel_maps(struct rb_root *self)
	return ret;
}

void machines__destroy_guest_kernel_maps(struct rb_root *self)
{
	struct rb_node *next = rb_first(self);

	while (next) {
		struct machine *pos = rb_entry(next, struct machine, rb_node);

		next = rb_next(&pos->rb_node);
		rb_erase(&pos->rb_node, self);
		machine__delete(pos);
	}
}

int machine__load_kallsyms(struct machine *self, const char *filename,
			   enum map_type type, symbol_filter_t filter)
{
Loading