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

perf buildid-cache: Add guestmount'd files to the build ID cache

When the guestmount option is used, a guest machine's file system mount
point is recorded in machine->root_dir.

perf already iterates guest machines when adding files to the build ID
cache, but does not take machine->root_dir into account.

Use machine->root_dir to find files for guest build IDs, and add them to
the build ID cache using the "proper" name i.e. relative to the guest root
directory not the host root directory.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Andi Kleen <ak@linux.intel.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-9-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
15fe0362 57190e38

+64 -21
+52 -17
tools/perf/util/build-id.c
··· 625 625 #endif 626 626 627 627 static char *build_id_cache__find_debug(const char *sbuild_id, 628 - struct nsinfo *nsi) 628 + struct nsinfo *nsi, 629 + const char *root_dir) 629 630 { 631 + const char *dirname = "/usr/lib/debug/.build-id/"; 630 632 char *realname = NULL; 633 + char dirbuf[PATH_MAX]; 631 634 char *debugfile; 632 635 struct nscookie nsc; 633 636 size_t len = 0; ··· 639 636 if (!debugfile) 640 637 goto out; 641 638 642 - len = __symbol__join_symfs(debugfile, PATH_MAX, 643 - "/usr/lib/debug/.build-id/"); 639 + if (root_dir) { 640 + path__join(dirbuf, PATH_MAX, root_dir, dirname); 641 + dirname = dirbuf; 642 + } 643 + 644 + len = __symbol__join_symfs(debugfile, PATH_MAX, dirname); 644 645 snprintf(debugfile + len, PATH_MAX - len, "%.2s/%s.debug", sbuild_id, 645 646 sbuild_id + 2); 646 647 ··· 675 668 676 669 int 677 670 build_id_cache__add(const char *sbuild_id, const char *name, const char *realname, 678 - struct nsinfo *nsi, bool is_kallsyms, bool is_vdso) 671 + struct nsinfo *nsi, bool is_kallsyms, bool is_vdso, 672 + const char *proper_name, const char *root_dir) 679 673 { 680 674 const size_t size = PATH_MAX; 681 675 char *filename = NULL, *dir_name = NULL, *linkname = zalloc(size), *tmp; 682 676 char *debugfile = NULL; 683 677 int err = -1; 684 678 685 - dir_name = build_id_cache__cachedir(sbuild_id, name, nsi, is_kallsyms, 679 + if (!proper_name) 680 + proper_name = name; 681 + 682 + dir_name = build_id_cache__cachedir(sbuild_id, proper_name, nsi, is_kallsyms, 686 683 is_vdso); 687 684 if (!dir_name) 688 685 goto out_free; ··· 726 715 */ 727 716 if (!is_kallsyms && !is_vdso && 728 717 strncmp(".ko", name + strlen(name) - 3, 3)) { 729 - debugfile = build_id_cache__find_debug(sbuild_id, nsi); 718 + debugfile = build_id_cache__find_debug(sbuild_id, nsi, root_dir); 730 719 if (debugfile) { 731 720 zfree(&filename); 732 721 if (asprintf(&filename, "%s/%s", dir_name, ··· 792 781 return err; 793 782 } 794 783 795 - int build_id_cache__add_s(const char *sbuild_id, const char *name, 796 - struct nsinfo *nsi, bool is_kallsyms, bool is_vdso) 784 + int __build_id_cache__add_s(const char *sbuild_id, const char *name, 785 + struct nsinfo *nsi, bool is_kallsyms, bool is_vdso, 786 + const char *proper_name, const char *root_dir) 797 787 { 798 788 char *realname = NULL; 799 789 int err = -1; ··· 808 796 goto out_free; 809 797 } 810 798 811 - err = build_id_cache__add(sbuild_id, name, realname, nsi, is_kallsyms, is_vdso); 812 - 799 + err = build_id_cache__add(sbuild_id, name, realname, nsi, 800 + is_kallsyms, is_vdso, proper_name, root_dir); 813 801 out_free: 814 802 if (!is_kallsyms) 815 803 free(realname); ··· 818 806 819 807 static int build_id_cache__add_b(const struct build_id *bid, 820 808 const char *name, struct nsinfo *nsi, 821 - bool is_kallsyms, bool is_vdso) 809 + bool is_kallsyms, bool is_vdso, 810 + const char *proper_name, 811 + const char *root_dir) 822 812 { 823 813 char sbuild_id[SBUILD_ID_SIZE]; 824 814 825 815 build_id__sprintf(bid, sbuild_id); 826 816 827 - return build_id_cache__add_s(sbuild_id, name, nsi, is_kallsyms, 828 - is_vdso); 817 + return __build_id_cache__add_s(sbuild_id, name, nsi, is_kallsyms, 818 + is_vdso, proper_name, root_dir); 829 819 } 830 820 831 821 bool build_id_cache__cached(const char *sbuild_id) ··· 910 896 bool is_kallsyms = dso__is_kallsyms(dso); 911 897 bool is_vdso = dso__is_vdso(dso); 912 898 const char *name = dso->long_name; 899 + const char *proper_name = NULL; 900 + const char *root_dir = NULL; 901 + char *allocated_name = NULL; 902 + int ret = 0; 913 903 914 904 if (!dso->has_build_id) 915 905 return 0; ··· 923 905 name = machine->mmap_name; 924 906 } 925 907 926 - if (!is_kallsyms && dso__build_id_mismatch(dso, name)) 927 - return 0; 908 + if (!machine__is_host(machine)) { 909 + if (*machine->root_dir) { 910 + root_dir = machine->root_dir; 911 + ret = asprintf(&allocated_name, "%s/%s", root_dir, name); 912 + if (ret < 0) 913 + return ret; 914 + proper_name = name; 915 + name = allocated_name; 916 + } else if (is_kallsyms) { 917 + /* Cannot get guest kallsyms */ 918 + return 0; 919 + } 920 + } 928 921 929 - return build_id_cache__add_b(&dso->bid, name, dso->nsinfo, 930 - is_kallsyms, is_vdso); 922 + if (!is_kallsyms && dso__build_id_mismatch(dso, name)) 923 + goto out_free; 924 + 925 + ret = build_id_cache__add_b(&dso->bid, name, dso->nsinfo, 926 + is_kallsyms, is_vdso, proper_name, root_dir); 927 + out_free: 928 + free(allocated_name); 929 + return ret; 931 930 } 932 931 933 932 static int
+12 -4
tools/perf/util/build-id.h
··· 66 66 struct strlist **result); 67 67 bool build_id_cache__cached(const char *sbuild_id); 68 68 int build_id_cache__add(const char *sbuild_id, const char *name, const char *realname, 69 - struct nsinfo *nsi, bool is_kallsyms, bool is_vdso); 70 - int build_id_cache__add_s(const char *sbuild_id, 71 - const char *name, struct nsinfo *nsi, 72 - bool is_kallsyms, bool is_vdso); 69 + struct nsinfo *nsi, bool is_kallsyms, bool is_vdso, 70 + const char *proper_name, const char *root_dir); 71 + int __build_id_cache__add_s(const char *sbuild_id, 72 + const char *name, struct nsinfo *nsi, 73 + bool is_kallsyms, bool is_vdso, 74 + const char *proper_name, const char *root_dir); 75 + static inline int build_id_cache__add_s(const char *sbuild_id, 76 + const char *name, struct nsinfo *nsi, 77 + bool is_kallsyms, bool is_vdso) 78 + { 79 + return __build_id_cache__add_s(sbuild_id, name, nsi, is_kallsyms, is_vdso, NULL, NULL); 80 + } 73 81 int build_id_cache__remove_s(const char *sbuild_id); 74 82 75 83 extern char buildid_dir[];