Skip to content

Commit 50e36c2

Browse files
kmjohansengregkh
authored andcommitted
perf symbols: Symbol lookup with kcore can fail if multiple segments match stext
commit 1c24956 upstream. This problem was encountered on an arm64 system with a lot of memory. Without kernel debug symbols installed, and with both kcore and kallsyms available, perf managed to get confused and returned "unknown" for all of the kernel symbols that it tried to look up. On this system, stext fell within the vmalloc segment. The kcore symbol matching code tries to find the first segment that contains stext and uses that to replace the segment generated from just the kallsyms information. In this case, however, there were two: a very large vmalloc segment, and the text segment. This caused perf to get confused because multiple overlapping segments were inserted into the RB tree that holds the discovered segments. However, that alone wasn't sufficient to cause the problem. Even when we could find the segment, the offsets were adjusted in such a way that the newly generated symbols didn't line up with the instruction addresses in the trace. The most obvious solution would be to consult which segment type is text from kcore, but this information is not exposed to users. Instead, select the smallest matching segment that contains stext instead of the first matching segment. This allows us to match the text segment instead of vmalloc, if one is contained within the other. Reviewed-by: Adrian Hunter <[email protected]> Signed-off-by: Krister Johansen <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: David Reaver <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Michael Petlan <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lore.kernel.org/lkml/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Krister Johansen <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 67e3b52 commit 50e36c2

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

tools/perf/util/symbol.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,10 +1368,23 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
13681368

13691369
/* Find the kernel map using the '_stext' symbol */
13701370
if (!kallsyms__get_function_start(kallsyms_filename, "_stext", &stext)) {
1371+
u64 replacement_size = 0;
1372+
13711373
list_for_each_entry(new_map, &md.maps, node) {
1372-
if (stext >= new_map->start && stext < new_map->end) {
1374+
u64 new_size = new_map->end - new_map->start;
1375+
1376+
if (!(stext >= new_map->start && stext < new_map->end))
1377+
continue;
1378+
1379+
/*
1380+
* On some architectures, ARM64 for example, the kernel
1381+
* text can get allocated inside of the vmalloc segment.
1382+
* Select the smallest matching segment, in case stext
1383+
* falls within more than one in the list.
1384+
*/
1385+
if (!replacement_map || new_size < replacement_size) {
13731386
replacement_map = new_map;
1374-
break;
1387+
replacement_size = new_size;
13751388
}
13761389
}
13771390
}

0 commit comments

Comments
 (0)