Commit 9b565a8051b389e046209a5f68c93eade8de58bd

Authored by Linus Torvalds

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

Showing 8 changed files Side-by-side Diff

arch/x86/kernel/cpu/perf_event.c
... ... @@ -1506,7 +1506,7 @@
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");
tools/perf/builtin-kmem.c
... ... @@ -101,7 +101,7 @@
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 ||
tools/perf/builtin-trace.c
... ... @@ -1055,6 +1055,7 @@
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;
tools/perf/config/Makefile
... ... @@ -87,7 +87,7 @@
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
tools/perf/util/machine.c
... ... @@ -792,7 +792,7 @@
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");
tools/perf/util/probe-finder.c
... ... @@ -118,7 +118,6 @@
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);
125 124  
... ... @@ -129,11 +128,11 @@
129 128 if (!self->dwfl)
130 129 goto error;
131 130  
132   - mod = dwfl_report_offline(self->dwfl, "", "", fd);
133   - if (!mod)
  131 + self->mod = dwfl_report_offline(self->dwfl, "", "", fd);
  132 + if (!self->mod)
134 133 goto error;
135 134  
136   - self->dbg = dwfl_module_getdwarf(mod, &self->bias);
  135 + self->dbg = dwfl_module_getdwarf(self->mod, &self->bias);
137 136 if (!self->dbg)
138 137 goto error;
139 138  
140 139  
141 140  
142 141  
... ... @@ -676,38 +675,43 @@
676 675 }
677 676  
678 677 /* Convert subprogram DIE to trace point */
679   -static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
680   - bool retprobe, struct probe_trace_point *tp)
  678 +static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
  679 + Dwarf_Addr paddr, bool retprobe,
  680 + struct probe_trace_point *tp)
681 681 {
682 682 Dwarf_Addr eaddr, highaddr;
683   - const char *name;
  683 + GElf_Sym sym;
  684 + const char *symbol;
684 685  
685   - /* Copy the name of probe point */
686   - name = dwarf_diename(sp_die);
687   - if (name) {
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   - tp->symbol = strdup(name);
704   - if (tp->symbol == NULL)
705   - return -ENOMEM;
706   - tp->offset = (unsigned long)(paddr - eaddr);
707   - } else
708   - /* This function has no name. */
709   - tp->offset = (unsigned long)paddr;
  686 + /* Verify the address is correct */
  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 + }
710 702  
  703 + /* Get an appropriate symbol from symtab */
  704 + symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
  705 + if (!symbol) {
  706 + pr_warning("Failed to find symbol at 0x%lx\n",
  707 + (unsigned long)paddr);
  708 + return -ENOENT;
  709 + }
  710 + tp->offset = (unsigned long)(paddr - sym.st_value);
  711 + tp->symbol = strdup(symbol);
  712 + if (!tp->symbol)
  713 + return -ENOMEM;
  714 +
711 715 /* Return probe must be on the head of a subprogram */
712 716 if (retprobe) {
713 717 if (eaddr != paddr) {
... ... @@ -1149,7 +1153,7 @@
1149 1153 tev = &tf->tevs[tf->ntevs++];
1150 1154  
1151 1155 /* Trace point should be converted from subprogram DIE */
1152   - ret = convert_to_trace_point(&pf->sp_die, pf->addr,
  1156 + ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
1153 1157 pf->pev->point.retprobe, &tev->point);
1154 1158 if (ret < 0)
1155 1159 return ret;
... ... @@ -1181,7 +1185,7 @@
1181 1185 {
1182 1186 struct trace_event_finder tf = {
1183 1187 .pf = {.pev = pev, .callback = add_probe_trace_event},
1184   - .max_tevs = max_tevs};
  1188 + .mod = self->mod, .max_tevs = max_tevs};
1185 1189 int ret;
1186 1190  
1187 1191 /* Allocate result tevs array */
... ... @@ -1250,7 +1254,7 @@
1250 1254 vl = &af->vls[af->nvls++];
1251 1255  
1252 1256 /* Trace point should be converted from subprogram DIE */
1253   - ret = convert_to_trace_point(&pf->sp_die, pf->addr,
  1257 + ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
1254 1258 pf->pev->point.retprobe, &vl->point);
1255 1259 if (ret < 0)
1256 1260 return ret;
... ... @@ -1289,6 +1293,7 @@
1289 1293 {
1290 1294 struct available_var_finder af = {
1291 1295 .pf = {.pev = pev, .callback = add_available_vars},
  1296 + .mod = self->mod,
1292 1297 .max_vls = max_vls, .externs = externs};
1293 1298 int ret;
1294 1299  
tools/perf/util/probe-finder.h
... ... @@ -23,6 +23,7 @@
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 };
... ... @@ -77,6 +78,7 @@
77 78  
78 79 struct trace_event_finder {
79 80 struct probe_finder pf;
  81 + Dwfl_Module *mod; /* For solving symbols */
80 82 struct probe_trace_event *tevs; /* Found trace events */
81 83 int ntevs; /* Number of trace events */
82 84 int max_tevs; /* Max number of trace events */
... ... @@ -84,6 +86,7 @@
84 86  
85 87 struct available_var_finder {
86 88 struct probe_finder pf;
  89 + Dwfl_Module *mod; /* For solving symbols */
87 90 struct variable_list *vls; /* Found variable lists */
88 91 int nvls; /* Number of variable lists */
89 92 int max_vls; /* Max no. of variable lists */
tools/perf/util/symbol-elf.c
... ... @@ -928,8 +928,33 @@
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 }