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

Commit ba92732e authored by Wang Nan's avatar Wang Nan Committed by Arnaldo Carvalho de Melo
Browse files

perf kmaps: Check kmaps to make code more robust



This patch add checks in places where map__kmap is used to get kmaps
from struct kmap.

Error messages are added at map__kmap to warn invalid accessing of kmap
(for the case of !map->dso->kernel, kmap(map) does not exists at all).

Also, introduces map__kmaps() to warn uninitialized kmaps.

Reviewed-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarWang Nan <wangnan0@huawei.com>
Cc: pi3orama@163.com
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Link: http://lkml.kernel.org/r/1428394966-131044-2-git-send-email-wangnan0@huawei.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 8ea92ceb
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -679,6 +679,9 @@ int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
			machine->vmlinux_maps[type]->unmap_ip =
				identity__map_ip;
		kmap = map__kmap(machine->vmlinux_maps[type]);
		if (!kmap)
			return -1;

		kmap->kmaps = &machine->kmaps;
		map_groups__insert(&machine->kmaps,
				   machine->vmlinux_maps[type]);
@@ -700,7 +703,7 @@ void machine__destroy_kernel_maps(struct machine *machine)
		kmap = map__kmap(machine->vmlinux_maps[type]);
		map_groups__remove(&machine->kmaps,
				   machine->vmlinux_maps[type]);
		if (kmap->ref_reloc_sym) {
		if (kmap && kmap->ref_reloc_sym) {
			/*
			 * ref_reloc_sym is shared among all maps, so free just
			 * on one of them.
+20 −0
Original line number Diff line number Diff line
@@ -778,3 +778,23 @@ struct map *maps__next(struct map *map)
		return rb_entry(next, struct map, rb_node);
	return NULL;
}

struct kmap *map__kmap(struct map *map)
{
	if (!map->dso || !map->dso->kernel) {
		pr_err("Internal error: map__kmap with a non-kernel map\n");
		return NULL;
	}
	return (struct kmap *)(map + 1);
}

struct map_groups *map__kmaps(struct map *map)
{
	struct kmap *kmap = map__kmap(map);

	if (!kmap || !kmap->kmaps) {
		pr_err("Internal error: map__kmaps with a non-kernel map\n");
		return NULL;
	}
	return kmap->kmaps;
}
+2 −4
Original line number Diff line number Diff line
@@ -76,10 +76,8 @@ static inline struct map_groups *map_groups__get(struct map_groups *mg)

void map_groups__put(struct map_groups *mg);

static inline struct kmap *map__kmap(struct map *map)
{
	return (struct kmap *)(map + 1);
}
struct kmap *map__kmap(struct map *map);
struct map_groups *map__kmaps(struct map *map);

static inline u64 map__map_ip(struct map *map, u64 ip)
{
+2 −0
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
		return NULL;

	kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]);
	if (!kmap)
		return NULL;
	return kmap->ref_reloc_sym;
}

+3 −0
Original line number Diff line number Diff line
@@ -1466,6 +1466,9 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,

	for (i = 0; i < MAP__NR_TYPES; ++i) {
		struct kmap *kmap = map__kmap(maps[i]);

		if (!kmap)
			continue;
		kmap->ref_reloc_sym = ref;
	}

Loading