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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"A couple of tooling fixlets and a PMU detection printout fix"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86: Fix PMU detection printout when no PMU is detected
perf symbols: Demangle cloned functions
perf machine: Fix path unpopulated in machine__create_modules()
perf tools: Explicitly add libdl dependency
perf probe: Fix probing symbols with optimization suffix
perf trace: Add mmap2 handler
perf kmem: Make it work again on non NUMA machines

+74 -40
+1 -1
arch/x86/kernel/cpu/perf_event.c
··· 1506 1506 err = amd_pmu_init(); 1507 1507 break; 1508 1508 default: 1509 - return 0; 1509 + err = -ENOTSUPP; 1510 1510 } 1511 1511 if (err != 0) { 1512 1512 pr_cont("no PMU driver, software events only.\n");
+1 -1
tools/perf/builtin-kmem.c
··· 101 101 102 102 dir1 = opendir(PATH_SYS_NODE); 103 103 if (!dir1) 104 - return -1; 104 + return 0; 105 105 106 106 while ((dent1 = readdir(dir1)) != NULL) { 107 107 if (dent1->d_type != DT_DIR ||
+1
tools/perf/builtin-trace.c
··· 1055 1055 1056 1056 trace->tool.sample = trace__process_sample; 1057 1057 trace->tool.mmap = perf_event__process_mmap; 1058 + trace->tool.mmap2 = perf_event__process_mmap2; 1058 1059 trace->tool.comm = perf_event__process_comm; 1059 1060 trace->tool.exit = perf_event__process_exit; 1060 1061 trace->tool.fork = perf_event__process_fork;
+1 -1
tools/perf/config/Makefile
··· 87 87 CFLAGS += -Wextra 88 88 CFLAGS += -std=gnu99 89 89 90 - EXTLIBS = -lelf -lpthread -lrt -lm 90 + EXTLIBS = -lelf -lpthread -lrt -lm -ldl 91 91 92 92 ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) 93 93 CFLAGS += -fstack-protector-all
+1 -1
tools/perf/util/machine.c
··· 792 792 modules = path; 793 793 } 794 794 795 - if (symbol__restricted_filename(path, "/proc/modules")) 795 + if (symbol__restricted_filename(modules, "/proc/modules")) 796 796 return -1; 797 797 798 798 file = fopen(modules, "r");
+40 -35
tools/perf/util/probe-finder.c
··· 118 118 static int debuginfo__init_offline_dwarf(struct debuginfo *self, 119 119 const char *path) 120 120 { 121 - Dwfl_Module *mod; 122 121 int fd; 123 122 124 123 fd = open(path, O_RDONLY); ··· 128 129 if (!self->dwfl) 129 130 goto error; 130 131 131 - mod = dwfl_report_offline(self->dwfl, "", "", fd); 132 - if (!mod) 132 + self->mod = dwfl_report_offline(self->dwfl, "", "", fd); 133 + if (!self->mod) 133 134 goto error; 134 135 135 - self->dbg = dwfl_module_getdwarf(mod, &self->bias); 136 + self->dbg = dwfl_module_getdwarf(self->mod, &self->bias); 136 137 if (!self->dbg) 137 138 goto error; 138 139 ··· 675 676 } 676 677 677 678 /* Convert subprogram DIE to trace point */ 678 - static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr, 679 - bool retprobe, struct probe_trace_point *tp) 679 + static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, 680 + Dwarf_Addr paddr, bool retprobe, 681 + struct probe_trace_point *tp) 680 682 { 681 683 Dwarf_Addr eaddr, highaddr; 682 - const char *name; 684 + GElf_Sym sym; 685 + const char *symbol; 683 686 684 - /* Copy the name of probe point */ 685 - name = dwarf_diename(sp_die); 686 - if (name) { 687 - if (dwarf_entrypc(sp_die, &eaddr) != 0) { 688 - pr_warning("Failed to get entry address of %s\n", 689 - dwarf_diename(sp_die)); 690 - return -ENOENT; 691 - } 692 - if (dwarf_highpc(sp_die, &highaddr) != 0) { 693 - pr_warning("Failed to get end address of %s\n", 694 - dwarf_diename(sp_die)); 695 - return -ENOENT; 696 - } 697 - if (paddr > highaddr) { 698 - pr_warning("Offset specified is greater than size of %s\n", 699 - dwarf_diename(sp_die)); 700 - return -EINVAL; 701 - } 702 - tp->symbol = strdup(name); 703 - if (tp->symbol == NULL) 704 - return -ENOMEM; 705 - tp->offset = (unsigned long)(paddr - eaddr); 706 - } else 707 - /* This function has no name. */ 708 - tp->offset = (unsigned long)paddr; 687 + /* Verify the address is correct */ 688 + if (dwarf_entrypc(sp_die, &eaddr) != 0) { 689 + pr_warning("Failed to get entry address of %s\n", 690 + dwarf_diename(sp_die)); 691 + return -ENOENT; 692 + } 693 + if (dwarf_highpc(sp_die, &highaddr) != 0) { 694 + pr_warning("Failed to get end address of %s\n", 695 + dwarf_diename(sp_die)); 696 + return -ENOENT; 697 + } 698 + if (paddr > highaddr) { 699 + pr_warning("Offset specified is greater than size of %s\n", 700 + dwarf_diename(sp_die)); 701 + return -EINVAL; 702 + } 703 + 704 + /* Get an appropriate symbol from symtab */ 705 + symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); 706 + if (!symbol) { 707 + pr_warning("Failed to find symbol at 0x%lx\n", 708 + (unsigned long)paddr); 709 + return -ENOENT; 710 + } 711 + tp->offset = (unsigned long)(paddr - sym.st_value); 712 + tp->symbol = strdup(symbol); 713 + if (!tp->symbol) 714 + return -ENOMEM; 709 715 710 716 /* Return probe must be on the head of a subprogram */ 711 717 if (retprobe) { ··· 1153 1149 tev = &tf->tevs[tf->ntevs++]; 1154 1150 1155 1151 /* Trace point should be converted from subprogram DIE */ 1156 - ret = convert_to_trace_point(&pf->sp_die, pf->addr, 1152 + ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, 1157 1153 pf->pev->point.retprobe, &tev->point); 1158 1154 if (ret < 0) 1159 1155 return ret; ··· 1185 1181 { 1186 1182 struct trace_event_finder tf = { 1187 1183 .pf = {.pev = pev, .callback = add_probe_trace_event}, 1188 - .max_tevs = max_tevs}; 1184 + .mod = self->mod, .max_tevs = max_tevs}; 1189 1185 int ret; 1190 1186 1191 1187 /* Allocate result tevs array */ ··· 1254 1250 vl = &af->vls[af->nvls++]; 1255 1251 1256 1252 /* Trace point should be converted from subprogram DIE */ 1257 - ret = convert_to_trace_point(&pf->sp_die, pf->addr, 1253 + ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr, 1258 1254 pf->pev->point.retprobe, &vl->point); 1259 1255 if (ret < 0) 1260 1256 return ret; ··· 1293 1289 { 1294 1290 struct available_var_finder af = { 1295 1291 .pf = {.pev = pev, .callback = add_available_vars}, 1292 + .mod = self->mod, 1296 1293 .max_vls = max_vls, .externs = externs}; 1297 1294 int ret; 1298 1295
+3
tools/perf/util/probe-finder.h
··· 23 23 /* debug information structure */ 24 24 struct debuginfo { 25 25 Dwarf *dbg; 26 + Dwfl_Module *mod; 26 27 Dwfl *dwfl; 27 28 Dwarf_Addr bias; 28 29 }; ··· 78 77 79 78 struct trace_event_finder { 80 79 struct probe_finder pf; 80 + Dwfl_Module *mod; /* For solving symbols */ 81 81 struct probe_trace_event *tevs; /* Found trace events */ 82 82 int ntevs; /* Number of trace events */ 83 83 int max_tevs; /* Max number of trace events */ ··· 86 84 87 85 struct available_var_finder { 88 86 struct probe_finder pf; 87 + Dwfl_Module *mod; /* For solving symbols */ 89 88 struct variable_list *vls; /* Found variable lists */ 90 89 int nvls; /* Number of variable lists */ 91 90 int max_vls; /* Max no. of variable lists */
+26 -1
tools/perf/util/symbol-elf.c
··· 928 928 * to it... 929 929 */ 930 930 if (symbol_conf.demangle) { 931 - demangled = bfd_demangle(NULL, elf_name, 931 + /* 932 + * The demangler doesn't deal with cloned functions. 933 + * XXXX.clone.NUM or similar 934 + * Strip the dot part and readd it later. 935 + */ 936 + char *p = (char *)elf_name, *dot; 937 + dot = strchr(elf_name, '.'); 938 + if (dot) { 939 + p = strdup(elf_name); 940 + if (!p) 941 + goto new_symbol; 942 + dot = strchr(p, '.'); 943 + *dot = 0; 944 + } 945 + 946 + demangled = bfd_demangle(NULL, p, 932 947 DMGL_PARAMS | DMGL_ANSI); 948 + if (dot) 949 + *dot = '.'; 950 + if (demangled && dot) { 951 + demangled = realloc(demangled, strlen(demangled) + strlen(dot) + 1); 952 + if (!demangled) 953 + goto new_symbol; 954 + strcpy(demangled + (dot - p), dot); 955 + } 956 + if (p != elf_name) 957 + free(p); 933 958 if (demangled != NULL) 934 959 elf_name = demangled; 935 960 }