Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Automatically use guest kcore_dir if present

When registering a guest machine using machine_pid from the id index,
check perf.data for a matching kcore_dir subdirectory and set the
kallsyms file name accordingly. If set, use it to find the machine's
kernel symbols and object code (from kcore).

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: kvm@vger.kernel.org
Link: https://lore.kernel.org/r/20220711093218.10967-23-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
a5367ecb 65691e9f

+27 -2
+19
tools/perf/util/data.c
··· 518 518 return kallsyms_name; 519 519 } 520 520 521 + char *perf_data__guest_kallsyms_name(struct perf_data *data, pid_t machine_pid) 522 + { 523 + char *kallsyms_name; 524 + struct stat st; 525 + 526 + if (!data->is_dir) 527 + return NULL; 528 + 529 + if (asprintf(&kallsyms_name, "%s/kcore_dir__%d/kallsyms", data->path, machine_pid) < 0) 530 + return NULL; 531 + 532 + if (stat(kallsyms_name, &st)) { 533 + free(kallsyms_name); 534 + return NULL; 535 + } 536 + 537 + return kallsyms_name; 538 + } 539 + 521 540 bool is_perf_data(const char *path) 522 541 { 523 542 bool ret = false;
+1
tools/perf/util/data.h
··· 101 101 int perf_data__make_kcore_dir(struct perf_data *data, char *buf, size_t buf_sz); 102 102 bool has_kcore_dir(const char *path); 103 103 char *perf_data__kallsyms_name(struct perf_data *data); 104 + char *perf_data__guest_kallsyms_name(struct perf_data *data, pid_t machine_pid); 104 105 bool is_perf_data(const char *path); 105 106 #endif /* __PERF_DATA_H */
+1
tools/perf/util/machine.h
··· 48 48 bool single_address_space; 49 49 char *root_dir; 50 50 char *mmap_name; 51 + char *kallsyms_filename; 51 52 struct threads threads[THREADS__TABLE_SIZE]; 52 53 struct vdso_info *vdso_info; 53 54 struct perf_env *env;
+2
tools/perf/util/session.c
··· 2772 2772 return -ENOMEM; 2773 2773 thread__put(thread); 2774 2774 2775 + machine->kallsyms_filename = perf_data__guest_kallsyms_name(session->data, machine_pid); 2776 + 2775 2777 return 0; 2776 2778 } 2777 2779
+4 -2
tools/perf/util/symbol.c
··· 2300 2300 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map) 2301 2301 { 2302 2302 int err; 2303 - const char *kallsyms_filename = NULL; 2303 + const char *kallsyms_filename; 2304 2304 struct machine *machine = map__kmaps(map)->machine; 2305 2305 char path[PATH_MAX]; 2306 2306 2307 - if (machine__is_default_guest(machine)) { 2307 + if (machine->kallsyms_filename) { 2308 + kallsyms_filename = machine->kallsyms_filename; 2309 + } else if (machine__is_default_guest(machine)) { 2308 2310 /* 2309 2311 * if the user specified a vmlinux filename, use it and only 2310 2312 * it, reporting errors to the user if it cannot be used.