From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Clark Williams <williams@redhat.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>,
Adrian Hunter <adrian.hunter@intel.com>
Subject: [PATCH 12/12] perf maps: Set maps pointer in the kmap area for kernel maps
Date: Tue, 17 Dec 2019 11:48:28 -0300 [thread overview]
Message-ID: <20191217144828.2460-13-acme@kernel.org> (raw)
In-Reply-To: <20191217144828.2460-1-acme@kernel.org>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
When kernel maps are created with map__new2() we allocate an extra area
to store a pointer to the 'struct maps' for the kernel maps, and this
ends up being used in places like __map__is_kernel() to figure out if a
map is the main kernel one.
We were setting this up only in __machine__create_kernel_maps() and
machine__create_extra_kernel_map(), but not when splitting kallsyms,
kcore address ranges in new kernel maps such as
"[kernel.vmlinux].init.text", leading to assertion failures in
__map__is_kernel().
So make map__new2() receive the kernel 'struct maps' pointer so that all
kernel maps point back to it in its 'struct kmap' area.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/n/tip-z4qrek7y7s7sjnczremjdn1z@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/tests/maps.c | 8 ++++----
tools/perf/util/auxtrace.c | 2 +-
tools/perf/util/dso.c | 4 ++--
tools/perf/util/dso.h | 4 +++-
tools/perf/util/machine.c | 10 ++++------
tools/perf/util/map.c | 15 ++++++++++++++-
tools/perf/util/map.h | 2 +-
tools/perf/util/probe-event.c | 10 ++++++----
tools/perf/util/symbol-elf.c | 2 +-
tools/perf/util/symbol.c | 6 ++++--
10 files changed, 40 insertions(+), 23 deletions(-)
diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c
index edcbc70ff9d6..7e32b4df8ff1 100644
--- a/tools/perf/tests/maps.c
+++ b/tools/perf/tests/maps.c
@@ -69,7 +69,7 @@ int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unus
for (i = 0; i < ARRAY_SIZE(bpf_progs); i++) {
struct map *map;
- map = dso__new_map(bpf_progs[i].name);
+ map = dso__new_map(bpf_progs[i].name, &maps);
TEST_ASSERT_VAL("failed to create map", map);
map->start = bpf_progs[i].start;
@@ -78,13 +78,13 @@ int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unus
map__put(map);
}
- map_kcore1 = dso__new_map("kcore1");
+ map_kcore1 = dso__new_map("kcore1", &maps);
TEST_ASSERT_VAL("failed to create map", map_kcore1);
- map_kcore2 = dso__new_map("kcore2");
+ map_kcore2 = dso__new_map("kcore2", &maps);
TEST_ASSERT_VAL("failed to create map", map_kcore2);
- map_kcore3 = dso__new_map("kcore3");
+ map_kcore3 = dso__new_map("kcore3", &maps);
TEST_ASSERT_VAL("failed to create map", map_kcore3);
/* kcore1 map overlaps over all bpf maps */
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index eb087e7df6f4..c5be6eeff069 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -2250,7 +2250,7 @@ static struct dso *load_dso(const char *name)
struct map *map;
struct dso *dso;
- map = dso__new_map(name);
+ map = dso__new_map(name, NULL);
if (!map)
return NULL;
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 91f21239608b..dd5c2e71d8d7 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -1118,13 +1118,13 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
return dso__data_write_cache_offs(dso, machine, offset, data, size);
}
-struct map *dso__new_map(const char *name)
+struct map *dso__new_map(const char *name, struct maps *kmaps)
{
struct map *map = NULL;
struct dso *dso = dso__new(name);
if (dso)
- map = map__new2(0, dso);
+ map = map__new2(0, dso, kmaps);
return map;
}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 2db64b79617a..3b4f690c67e0 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -353,7 +353,9 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
struct machine *machine, u64 addr,
const u8 *data, ssize_t size);
-struct map *dso__new_map(const char *name);
+struct maps;
+
+struct map *dso__new_map(const char *name, struct maps *kmaps);
struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
const char *short_name, int dso_type);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index c8c5410315e8..7ee14963edc9 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -726,7 +726,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
struct map *map = maps__find(&machine->kmaps, event->ksymbol.addr);
if (!map) {
- map = dso__new_map(event->ksymbol.name);
+ map = dso__new_map(event->ksymbol.name, &machine->kmaps);
if (!map)
return -ENOMEM;
@@ -784,7 +784,7 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start
if (dso == NULL)
goto out;
- map = map__new2(start, dso);
+ map = map__new2(start, dso, &machine->kmaps);
if (map == NULL)
goto out;
@@ -963,7 +963,7 @@ int machine__create_extra_kernel_map(struct machine *machine,
struct kmap *kmap;
struct map *map;
- map = map__new2(xm->start, kernel);
+ map = map__new2(xm->start, kernel, &machine->kmaps);
if (!map)
return -1;
@@ -972,7 +972,6 @@ int machine__create_extra_kernel_map(struct machine *machine,
kmap = map__kmap(map);
- kmap->kmaps = &machine->kmaps;
strlcpy(kmap->name, xm->name, KMAP_NAME_LEN);
maps__insert(&machine->kmaps, map);
@@ -1088,7 +1087,7 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
/* In case of renewal the kernel map, destroy previous one */
machine__destroy_kernel_maps(machine);
- machine->vmlinux_map = map__new2(0, kernel);
+ machine->vmlinux_map = map__new2(0, kernel, &machine->kmaps);
if (machine->vmlinux_map == NULL)
return -1;
@@ -1098,7 +1097,6 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
if (!kmap)
return -1;
- kmap->kmaps = &machine->kmaps;
maps__insert(&machine->kmaps, map);
return 0;
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index fdd5bddb3075..a2cdfe62df94 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -223,7 +223,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
* they are loaded) and for vmlinux, where only after we load all the
* symbols we'll know where it starts and ends.
*/
-struct map *map__new2(u64 start, struct dso *dso)
+struct map *map__new2(u64 start, struct dso *dso, struct maps *kmaps)
{
struct map *map = calloc(1, (sizeof(*map) +
(dso->kernel ? sizeof(struct kmap) : 0)));
@@ -232,6 +232,19 @@ struct map *map__new2(u64 start, struct dso *dso)
* ->end will be filled after we load all the symbols
*/
map__init(map, start, 0, 0, dso);
+ if (dso->kernel) {
+ /*
+ * __map__is_kernel() Needs this for in-kernel map ranges
+ * such as:
+ * (gdb) print map->dso->name
+ * $8 = 0x1232d6c "[kernel.vmlinux].init.text"
+ * (gdb) print map->dso->kernel
+ * $9 = DSO_TYPE_KERNEL
+ * (gdb)
+ */
+ struct kmap *kmap = map__kmap(map);
+ kmap->kmaps = kmaps;
+ }
}
return map;
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 067036e8970c..b4531876cd66 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -108,7 +108,7 @@ struct dso_id;
struct map *map__new(struct machine *machine, u64 start, u64 len,
u64 pgoff, struct dso_id *id, u32 prot, u32 flags,
char *filename, struct thread *thread);
-struct map *map__new2(u64 start, struct dso *dso);
+struct map *map__new2(u64 start, struct dso *dso, struct maps *kmaps);
void map__delete(struct map *map);
struct map *map__clone(struct map *map);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index eea132f512b0..b123a800d260 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -146,7 +146,7 @@ static struct map *kernel_get_module_map(const char *module)
/* A file path -- this is an offline module */
if (module && strchr(module, '/'))
- return dso__new_map(module);
+ return dso__new_map(module, maps);
if (!module) {
pos = machine__kernel_map(host_machine);
@@ -170,7 +170,7 @@ struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user)
if (user) {
struct map *map;
- map = dso__new_map(target);
+ map = dso__new_map(target, NULL);
if (map && map->dso)
map->dso->nsinfo = nsinfo__get(nsi);
return map;
@@ -651,12 +651,13 @@ static int
post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
int ntevs, const char *pathname)
{
+ struct maps *maps = machine__kernel_maps(host_machine);
struct map *map;
unsigned long stext = 0;
int i, ret = 0;
/* Prepare a map for offline binary */
- map = dso__new_map(pathname);
+ map = dso__new_map(pathname, maps);
if (!map || get_text_start_address(pathname, &stext, NULL) < 0) {
pr_warning("Failed to get ELF symbols for %s\n", pathname);
return -EINVAL;
@@ -2111,7 +2112,8 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
int ret = -ENOENT;
if (!is_kprobe) {
- map = dso__new_map(tp->module);
+ struct maps *maps = machine__kernel_maps(host_machine);
+ map = dso__new_map(tp->module, maps);
if (!map)
goto out;
sym = map__find_symbol(map, addr);
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 6658fbf196e6..cc896ba85a99 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -915,7 +915,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
curr_dso->kernel = dso->kernel;
curr_dso->long_name = dso->long_name;
curr_dso->long_name_len = dso->long_name_len;
- curr_map = map__new2(start, curr_dso);
+ curr_map = map__new2(start, curr_dso, kmaps);
dso__put(curr_dso);
if (curr_map == NULL)
return -1;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 3b379b1296f1..d166f0fb258c 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -856,7 +856,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
ndso->kernel = dso->kernel;
- curr_map = map__new2(pos->start, ndso);
+ curr_map = map__new2(pos->start, ndso, kmaps);
if (curr_map == NULL) {
dso__put(ndso);
return -1;
@@ -1144,6 +1144,7 @@ static int validate_kcore_addresses(const char *kallsyms_filename,
struct kcore_mapfn_data {
struct dso *dso;
+ struct maps *kmaps;
struct list_head maps;
};
@@ -1152,7 +1153,7 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
struct kcore_mapfn_data *md = data;
struct map *map;
- map = map__new2(start, md->dso);
+ map = map__new2(start, md->dso, md->kmaps);
if (map == NULL)
return -ENOMEM;
@@ -1271,6 +1272,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
return -EINVAL;
md.dso = dso;
+ md.kmaps = kmaps;
INIT_LIST_HEAD(&md.maps);
fd = open(kcore_filename, O_RDONLY);
--
2.21.0
next prev parent reply other threads:[~2019-12-17 14:48 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-17 14:48 [RFC] perf report/top with callchain fixes improvements Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 01/12] perf hists browser: Restore ESC as "Zoom out" of DSO/thread/etc Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 02/12] perf report/top: Make ENTER consistently bring up menu Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 03/12] perf report/top: Add menu entry for toggling callchain expansion Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 04/12] perf report/top: Improve toggle callchain menu option Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 05/12] perf hists browser: Generalize the do_zoom_dso() function Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 06/12] perf report/top: Add 'k' hotkey to zoom directly into the kernel map Arnaldo Carvalho de Melo
2019-12-20 6:48 ` Namhyung Kim
2019-12-20 12:17 ` Arnaldo Carvalho de Melo
2019-12-21 7:20 ` Namhyung Kim
2019-12-17 14:48 ` [PATCH 07/12] perf hists browser: Allow passing an initial hotkey Arnaldo Carvalho de Melo
2019-12-18 8:08 ` Jiri Olsa
2019-12-18 14:08 ` Arnaldo Carvalho de Melo
2019-12-18 14:23 ` Jiri Olsa
2019-12-19 17:26 ` Arnaldo Carvalho de Melo
2019-12-19 21:44 ` Jiri Olsa
2019-12-17 14:48 ` [PATCH 08/12] tools ui popup: Allow returning hotkeys Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 09/12] perf report/top: Allow pressing hotkeys in the options popup menu Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 10/12] perf report/top: Do not offer annotation for symbols without samples Arnaldo Carvalho de Melo
2019-12-17 14:48 ` [PATCH 11/12] perf report/top: Make 'e' visible in the help and make it toggle showing callchains Arnaldo Carvalho de Melo
2019-12-17 14:48 ` Arnaldo Carvalho de Melo [this message]
2019-12-18 9:05 ` [PATCH 12/12] perf maps: Set maps pointer in the kmap area for kernel maps Jiri Olsa
2019-12-18 14:24 ` Arnaldo Carvalho de Melo
2019-12-18 18:22 ` Arnaldo Carvalho de Melo
2019-12-18 19:01 ` Arnaldo Carvalho de Melo
2019-12-19 9:24 ` Jiri Olsa
2019-12-18 9:07 ` Jiri Olsa
2019-12-18 14:20 ` Arnaldo Carvalho de Melo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191217144828.2460-13-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=tglx@linutronix.de \
--cc=williams@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.