This is a note to let you know that I've just added the patch titled perf symbols: Symbol lookup with kcore can fail if multiple segments match stext to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: perf-symbols-symbol-lookup-with-kcore-can-fail-if-multiple-segments-match-stext.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 1c249565426e3a9940102c0ba9f63914f7cda73d Mon Sep 17 00:00:00 2001 From: Krister Johansen <kjlx@xxxxxxxxxxxxxxxxxx> Date: Wed, 25 Jan 2023 10:34:18 -0800 Subject: perf symbols: Symbol lookup with kcore can fail if multiple segments match stext From: Krister Johansen <kjlx@xxxxxxxxxxxxxxxxxx> commit 1c249565426e3a9940102c0ba9f63914f7cda73d 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 <adrian.hunter@xxxxxxxxx> Signed-off-by: Krister Johansen <kjlx@xxxxxxxxxxxxxxxxxx> Cc: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx> Cc: David Reaver <me@xxxxxxxxxxxxxxx> Cc: Ian Rogers <irogers@xxxxxxxxxx> Cc: Jiri Olsa <jolsa@xxxxxxxxxx> Cc: Mark Rutland <mark.rutland@xxxxxxx> Cc: Michael Petlan <mpetlan@xxxxxxxxxx> Cc: Namhyung Kim <namhyung@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Link: http://lore.kernel.org/lkml/20230125183418.GD1963@xxxxxxxxxxxxxxxxxx Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> Signed-off-by: Krister Johansen <kjlx@xxxxxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- tools/perf/util/symbol.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1368,10 +1368,23 @@ static int dso__load_kcore(struct dso *d /* Find the kernel map using the '_stext' symbol */ if (!kallsyms__get_function_start(kallsyms_filename, "_stext", &stext)) { + u64 replacement_size = 0; + list_for_each_entry(new_map, &md.maps, node) { - if (stext >= new_map->start && stext < new_map->end) { + u64 new_size = new_map->end - new_map->start; + + if (!(stext >= new_map->start && stext < new_map->end)) + continue; + + /* + * On some architectures, ARM64 for example, the kernel + * text can get allocated inside of the vmalloc segment. + * Select the smallest matching segment, in case stext + * falls within more than one in the list. + */ + if (!replacement_map || new_size < replacement_size) { replacement_map = new_map; - break; + replacement_size = new_size; } } } Patches currently in stable-queue which might be from kjlx@xxxxxxxxxxxxxxxxxx are queue-6.1/perf-symbols-symbol-lookup-with-kcore-can-fail-if-multiple-segments-match-stext.patch