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
This commit is contained in:
Коммит
9b565a8051
|
@ -1506,7 +1506,7 @@ static int __init init_hw_perf_events(void)
|
|||
err = amd_pmu_init();
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
err = -ENOTSUPP;
|
||||
}
|
||||
if (err != 0) {
|
||||
pr_cont("no PMU driver, software events only.\n");
|
||||
|
|
|
@ -101,7 +101,7 @@ static int setup_cpunode_map(void)
|
|||
|
||||
dir1 = opendir(PATH_SYS_NODE);
|
||||
if (!dir1)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
while ((dent1 = readdir(dir1)) != NULL) {
|
||||
if (dent1->d_type != DT_DIR ||
|
||||
|
|
|
@ -1055,6 +1055,7 @@ static int trace__replay(struct trace *trace)
|
|||
|
||||
trace->tool.sample = trace__process_sample;
|
||||
trace->tool.mmap = perf_event__process_mmap;
|
||||
trace->tool.mmap2 = perf_event__process_mmap2;
|
||||
trace->tool.comm = perf_event__process_comm;
|
||||
trace->tool.exit = perf_event__process_exit;
|
||||
trace->tool.fork = perf_event__process_fork;
|
||||
|
|
|
@ -87,7 +87,7 @@ CFLAGS += -Wall
|
|||
CFLAGS += -Wextra
|
||||
CFLAGS += -std=gnu99
|
||||
|
||||
EXTLIBS = -lelf -lpthread -lrt -lm
|
||||
EXTLIBS = -lelf -lpthread -lrt -lm -ldl
|
||||
|
||||
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
|
||||
CFLAGS += -fstack-protector-all
|
||||
|
|
|
@ -792,7 +792,7 @@ static int machine__create_modules(struct machine *machine)
|
|||
modules = path;
|
||||
}
|
||||
|
||||
if (symbol__restricted_filename(path, "/proc/modules"))
|
||||
if (symbol__restricted_filename(modules, "/proc/modules"))
|
||||
return -1;
|
||||
|
||||
file = fopen(modules, "r");
|
||||
|
|
|
@ -118,7 +118,6 @@ static const Dwfl_Callbacks offline_callbacks = {
|
|||
static int debuginfo__init_offline_dwarf(struct debuginfo *self,
|
||||
const char *path)
|
||||
{
|
||||
Dwfl_Module *mod;
|
||||
int fd;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
|
@ -129,11 +128,11 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *self,
|
|||
if (!self->dwfl)
|
||||
goto error;
|
||||
|
||||
mod = dwfl_report_offline(self->dwfl, "", "", fd);
|
||||
if (!mod)
|
||||
self->mod = dwfl_report_offline(self->dwfl, "", "", fd);
|
||||
if (!self->mod)
|
||||
goto error;
|
||||
|
||||
self->dbg = dwfl_module_getdwarf(mod, &self->bias);
|
||||
self->dbg = dwfl_module_getdwarf(self->mod, &self->bias);
|
||||
if (!self->dbg)
|
||||
goto error;
|
||||
|
||||
|
@ -676,37 +675,42 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
|
|||
}
|
||||
|
||||
/* Convert subprogram DIE to trace point */
|
||||
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
|
||||
bool retprobe, struct probe_trace_point *tp)
|
||||
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
|
||||
Dwarf_Addr paddr, bool retprobe,
|
||||
struct probe_trace_point *tp)
|
||||
{
|
||||
Dwarf_Addr eaddr, highaddr;
|
||||
const char *name;
|
||||
GElf_Sym sym;
|
||||
const char *symbol;
|
||||
|
||||
/* Copy the name of probe point */
|
||||
name = dwarf_diename(sp_die);
|
||||
if (name) {
|
||||
if (dwarf_entrypc(sp_die, &eaddr) != 0) {
|
||||
pr_warning("Failed to get entry address of %s\n",
|
||||
dwarf_diename(sp_die));
|
||||
return -ENOENT;
|
||||
}
|
||||
if (dwarf_highpc(sp_die, &highaddr) != 0) {
|
||||
pr_warning("Failed to get end address of %s\n",
|
||||
dwarf_diename(sp_die));
|
||||
return -ENOENT;
|
||||
}
|
||||
if (paddr > highaddr) {
|
||||
pr_warning("Offset specified is greater than size of %s\n",
|
||||
dwarf_diename(sp_die));
|
||||
return -EINVAL;
|
||||
}
|
||||
tp->symbol = strdup(name);
|
||||
if (tp->symbol == NULL)
|
||||
return -ENOMEM;
|
||||
tp->offset = (unsigned long)(paddr - eaddr);
|
||||
} else
|
||||
/* This function has no name. */
|
||||
tp->offset = (unsigned long)paddr;
|
||||
/* Verify the address is correct */
|
||||
if (dwarf_entrypc(sp_die, &eaddr) != 0) {
|
||||
pr_warning("Failed to get entry address of %s\n",
|
||||
dwarf_diename(sp_die));
|
||||
return -ENOENT;
|
||||
}
|
||||
if (dwarf_highpc(sp_die, &highaddr) != 0) {
|
||||
pr_warning("Failed to get end address of %s\n",
|
||||
dwarf_diename(sp_die));
|
||||
return -ENOENT;
|
||||
}
|
||||
if (paddr > highaddr) {
|
||||
pr_warning("Offset specified is greater than size of %s\n",
|
||||
dwarf_diename(sp_die));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get an appropriate symbol from symtab */
|
||||
symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
|
||||
if (!symbol) {
|
||||
pr_warning("Failed to find symbol at 0x%lx\n",
|
||||
(unsigned long)paddr);
|
||||
return -ENOENT;
|
||||
}
|
||||
tp->offset = (unsigned long)(paddr - sym.st_value);
|
||||
tp->symbol = strdup(symbol);
|
||||
if (!tp->symbol)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Return probe must be on the head of a subprogram */
|
||||
if (retprobe) {
|
||||
|
@ -1149,7 +1153,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
|
|||
tev = &tf->tevs[tf->ntevs++];
|
||||
|
||||
/* Trace point should be converted from subprogram DIE */
|
||||
ret = convert_to_trace_point(&pf->sp_die, pf->addr,
|
||||
ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
|
||||
pf->pev->point.retprobe, &tev->point);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -1181,7 +1185,7 @@ int debuginfo__find_trace_events(struct debuginfo *self,
|
|||
{
|
||||
struct trace_event_finder tf = {
|
||||
.pf = {.pev = pev, .callback = add_probe_trace_event},
|
||||
.max_tevs = max_tevs};
|
||||
.mod = self->mod, .max_tevs = max_tevs};
|
||||
int ret;
|
||||
|
||||
/* Allocate result tevs array */
|
||||
|
@ -1250,7 +1254,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
|
|||
vl = &af->vls[af->nvls++];
|
||||
|
||||
/* Trace point should be converted from subprogram DIE */
|
||||
ret = convert_to_trace_point(&pf->sp_die, pf->addr,
|
||||
ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
|
||||
pf->pev->point.retprobe, &vl->point);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -1289,6 +1293,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self,
|
|||
{
|
||||
struct available_var_finder af = {
|
||||
.pf = {.pev = pev, .callback = add_available_vars},
|
||||
.mod = self->mod,
|
||||
.max_vls = max_vls, .externs = externs};
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ static inline int is_c_varname(const char *name)
|
|||
/* debug information structure */
|
||||
struct debuginfo {
|
||||
Dwarf *dbg;
|
||||
Dwfl_Module *mod;
|
||||
Dwfl *dwfl;
|
||||
Dwarf_Addr bias;
|
||||
};
|
||||
|
@ -77,6 +78,7 @@ struct probe_finder {
|
|||
|
||||
struct trace_event_finder {
|
||||
struct probe_finder pf;
|
||||
Dwfl_Module *mod; /* For solving symbols */
|
||||
struct probe_trace_event *tevs; /* Found trace events */
|
||||
int ntevs; /* Number of trace events */
|
||||
int max_tevs; /* Max number of trace events */
|
||||
|
@ -84,6 +86,7 @@ struct trace_event_finder {
|
|||
|
||||
struct available_var_finder {
|
||||
struct probe_finder pf;
|
||||
Dwfl_Module *mod; /* For solving symbols */
|
||||
struct variable_list *vls; /* Found variable lists */
|
||||
int nvls; /* Number of variable lists */
|
||||
int max_vls; /* Max no. of variable lists */
|
||||
|
|
|
@ -928,8 +928,33 @@ int dso__load_sym(struct dso *dso, struct map *map,
|
|||
* to it...
|
||||
*/
|
||||
if (symbol_conf.demangle) {
|
||||
demangled = bfd_demangle(NULL, elf_name,
|
||||
/*
|
||||
* The demangler doesn't deal with cloned functions.
|
||||
* XXXX.clone.NUM or similar
|
||||
* Strip the dot part and readd it later.
|
||||
*/
|
||||
char *p = (char *)elf_name, *dot;
|
||||
dot = strchr(elf_name, '.');
|
||||
if (dot) {
|
||||
p = strdup(elf_name);
|
||||
if (!p)
|
||||
goto new_symbol;
|
||||
dot = strchr(p, '.');
|
||||
*dot = 0;
|
||||
}
|
||||
|
||||
demangled = bfd_demangle(NULL, p,
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
if (dot)
|
||||
*dot = '.';
|
||||
if (demangled && dot) {
|
||||
demangled = realloc(demangled, strlen(demangled) + strlen(dot) + 1);
|
||||
if (!demangled)
|
||||
goto new_symbol;
|
||||
strcpy(demangled + (dot - p), dot);
|
||||
}
|
||||
if (p != elf_name)
|
||||
free(p);
|
||||
if (demangled != NULL)
|
||||
elf_name = demangled;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче