mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-07 07:08:07 +00:00
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:
commit
9b565a8051
8 changed files with 74 additions and 40 deletions
|
@ -1506,7 +1506,7 @@ static int __init init_hw_perf_events(void)
|
||||||
err = amd_pmu_init();
|
err = amd_pmu_init();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
err = -ENOTSUPP;
|
||||||
}
|
}
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
pr_cont("no PMU driver, software events only.\n");
|
pr_cont("no PMU driver, software events only.\n");
|
||||||
|
|
|
@ -101,7 +101,7 @@ static int setup_cpunode_map(void)
|
||||||
|
|
||||||
dir1 = opendir(PATH_SYS_NODE);
|
dir1 = opendir(PATH_SYS_NODE);
|
||||||
if (!dir1)
|
if (!dir1)
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
while ((dent1 = readdir(dir1)) != NULL) {
|
while ((dent1 = readdir(dir1)) != NULL) {
|
||||||
if (dent1->d_type != DT_DIR ||
|
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.sample = trace__process_sample;
|
||||||
trace->tool.mmap = perf_event__process_mmap;
|
trace->tool.mmap = perf_event__process_mmap;
|
||||||
|
trace->tool.mmap2 = perf_event__process_mmap2;
|
||||||
trace->tool.comm = perf_event__process_comm;
|
trace->tool.comm = perf_event__process_comm;
|
||||||
trace->tool.exit = perf_event__process_exit;
|
trace->tool.exit = perf_event__process_exit;
|
||||||
trace->tool.fork = perf_event__process_fork;
|
trace->tool.fork = perf_event__process_fork;
|
||||||
|
|
|
@ -87,7 +87,7 @@ CFLAGS += -Wall
|
||||||
CFLAGS += -Wextra
|
CFLAGS += -Wextra
|
||||||
CFLAGS += -std=gnu99
|
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)
|
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
|
||||||
CFLAGS += -fstack-protector-all
|
CFLAGS += -fstack-protector-all
|
||||||
|
|
|
@ -792,7 +792,7 @@ static int machine__create_modules(struct machine *machine)
|
||||||
modules = path;
|
modules = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol__restricted_filename(path, "/proc/modules"))
|
if (symbol__restricted_filename(modules, "/proc/modules"))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
file = fopen(modules, "r");
|
file = fopen(modules, "r");
|
||||||
|
|
|
@ -118,7 +118,6 @@ static const Dwfl_Callbacks offline_callbacks = {
|
||||||
static int debuginfo__init_offline_dwarf(struct debuginfo *self,
|
static int debuginfo__init_offline_dwarf(struct debuginfo *self,
|
||||||
const char *path)
|
const char *path)
|
||||||
{
|
{
|
||||||
Dwfl_Module *mod;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
|
@ -129,11 +128,11 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *self,
|
||||||
if (!self->dwfl)
|
if (!self->dwfl)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
mod = dwfl_report_offline(self->dwfl, "", "", fd);
|
self->mod = dwfl_report_offline(self->dwfl, "", "", fd);
|
||||||
if (!mod)
|
if (!self->mod)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
self->dbg = dwfl_module_getdwarf(mod, &self->bias);
|
self->dbg = dwfl_module_getdwarf(self->mod, &self->bias);
|
||||||
if (!self->dbg)
|
if (!self->dbg)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -676,37 +675,42 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert subprogram DIE to trace point */
|
/* Convert subprogram DIE to trace point */
|
||||||
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
|
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
|
||||||
bool retprobe, struct probe_trace_point *tp)
|
Dwarf_Addr paddr, bool retprobe,
|
||||||
|
struct probe_trace_point *tp)
|
||||||
{
|
{
|
||||||
Dwarf_Addr eaddr, highaddr;
|
Dwarf_Addr eaddr, highaddr;
|
||||||
const char *name;
|
GElf_Sym sym;
|
||||||
|
const char *symbol;
|
||||||
|
|
||||||
/* Copy the name of probe point */
|
/* Verify the address is correct */
|
||||||
name = dwarf_diename(sp_die);
|
if (dwarf_entrypc(sp_die, &eaddr) != 0) {
|
||||||
if (name) {
|
pr_warning("Failed to get entry address of %s\n",
|
||||||
if (dwarf_entrypc(sp_die, &eaddr) != 0) {
|
dwarf_diename(sp_die));
|
||||||
pr_warning("Failed to get entry address of %s\n",
|
return -ENOENT;
|
||||||
dwarf_diename(sp_die));
|
}
|
||||||
return -ENOENT;
|
if (dwarf_highpc(sp_die, &highaddr) != 0) {
|
||||||
}
|
pr_warning("Failed to get end address of %s\n",
|
||||||
if (dwarf_highpc(sp_die, &highaddr) != 0) {
|
dwarf_diename(sp_die));
|
||||||
pr_warning("Failed to get end address of %s\n",
|
return -ENOENT;
|
||||||
dwarf_diename(sp_die));
|
}
|
||||||
return -ENOENT;
|
if (paddr > highaddr) {
|
||||||
}
|
pr_warning("Offset specified is greater than size of %s\n",
|
||||||
if (paddr > highaddr) {
|
dwarf_diename(sp_die));
|
||||||
pr_warning("Offset specified is greater than size of %s\n",
|
return -EINVAL;
|
||||||
dwarf_diename(sp_die));
|
}
|
||||||
return -EINVAL;
|
|
||||||
}
|
/* Get an appropriate symbol from symtab */
|
||||||
tp->symbol = strdup(name);
|
symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
|
||||||
if (tp->symbol == NULL)
|
if (!symbol) {
|
||||||
return -ENOMEM;
|
pr_warning("Failed to find symbol at 0x%lx\n",
|
||||||
tp->offset = (unsigned long)(paddr - eaddr);
|
(unsigned long)paddr);
|
||||||
} else
|
return -ENOENT;
|
||||||
/* This function has no name. */
|
}
|
||||||
tp->offset = (unsigned long)paddr;
|
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 */
|
/* Return probe must be on the head of a subprogram */
|
||||||
if (retprobe) {
|
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++];
|
tev = &tf->tevs[tf->ntevs++];
|
||||||
|
|
||||||
/* Trace point should be converted from subprogram DIE */
|
/* 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);
|
pf->pev->point.retprobe, &tev->point);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1181,7 +1185,7 @@ int debuginfo__find_trace_events(struct debuginfo *self,
|
||||||
{
|
{
|
||||||
struct trace_event_finder tf = {
|
struct trace_event_finder tf = {
|
||||||
.pf = {.pev = pev, .callback = add_probe_trace_event},
|
.pf = {.pev = pev, .callback = add_probe_trace_event},
|
||||||
.max_tevs = max_tevs};
|
.mod = self->mod, .max_tevs = max_tevs};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Allocate result tevs array */
|
/* 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++];
|
vl = &af->vls[af->nvls++];
|
||||||
|
|
||||||
/* Trace point should be converted from subprogram DIE */
|
/* 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);
|
pf->pev->point.retprobe, &vl->point);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1289,6 +1293,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self,
|
||||||
{
|
{
|
||||||
struct available_var_finder af = {
|
struct available_var_finder af = {
|
||||||
.pf = {.pev = pev, .callback = add_available_vars},
|
.pf = {.pev = pev, .callback = add_available_vars},
|
||||||
|
.mod = self->mod,
|
||||||
.max_vls = max_vls, .externs = externs};
|
.max_vls = max_vls, .externs = externs};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ static inline int is_c_varname(const char *name)
|
||||||
/* debug information structure */
|
/* debug information structure */
|
||||||
struct debuginfo {
|
struct debuginfo {
|
||||||
Dwarf *dbg;
|
Dwarf *dbg;
|
||||||
|
Dwfl_Module *mod;
|
||||||
Dwfl *dwfl;
|
Dwfl *dwfl;
|
||||||
Dwarf_Addr bias;
|
Dwarf_Addr bias;
|
||||||
};
|
};
|
||||||
|
@ -77,6 +78,7 @@ struct probe_finder {
|
||||||
|
|
||||||
struct trace_event_finder {
|
struct trace_event_finder {
|
||||||
struct probe_finder pf;
|
struct probe_finder pf;
|
||||||
|
Dwfl_Module *mod; /* For solving symbols */
|
||||||
struct probe_trace_event *tevs; /* Found trace events */
|
struct probe_trace_event *tevs; /* Found trace events */
|
||||||
int ntevs; /* Number of trace events */
|
int ntevs; /* Number of trace events */
|
||||||
int max_tevs; /* Max 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 available_var_finder {
|
||||||
struct probe_finder pf;
|
struct probe_finder pf;
|
||||||
|
Dwfl_Module *mod; /* For solving symbols */
|
||||||
struct variable_list *vls; /* Found variable lists */
|
struct variable_list *vls; /* Found variable lists */
|
||||||
int nvls; /* Number of variable lists */
|
int nvls; /* Number of variable lists */
|
||||||
int max_vls; /* Max no. 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...
|
* to it...
|
||||||
*/
|
*/
|
||||||
if (symbol_conf.demangle) {
|
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);
|
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)
|
if (demangled != NULL)
|
||||||
elf_name = demangled;
|
elf_name = demangled;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue