Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf tooling fixes from Thomas Gleixner: "Perf tooling fixes all over the place: - Fix the selection of the main thread COMM in db-export - Fix the disassemmbly display for BPF in annotate - Fix cpumap mask setup in perf ftrace when only one CPU is present - Add the missing 'cpu_clk_unhalted.core' event - Fix CPU 0 bindings in NUMA benchmarks - Fix the module size calculations for s390 - Handle the gap between kernel end and module start on s390 correctly - Build and typo fixes" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf pmu-events: Fix missing "cpu_clk_unhalted.core" event perf annotate: Fix s390 gap between kernel end and module start perf record: Fix module size on s390 perf tools: Fix include paths in ui directory perf tools: Fix a typo in a variable name in the Documentation Makefile perf cpumap: Fix writing to illegal memory in handling cpumap mask perf ftrace: Fix failure to set cpumask when only one cpu is present perf db-export: Fix thread__exec_comm() perf annotate: Fix printing of unaugmented disassembled instructions from BPF perf bench numa: Fix cpu0 binding
This commit is contained in:
commit
d2359a5153
|
@ -242,7 +242,7 @@ $(OUTPUT)doc.dep : $(wildcard *.txt) build-docdep.perl
|
||||||
$(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \
|
$(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
-include $(OUPTUT)doc.dep
|
-include $(OUTPUT)doc.dep
|
||||||
|
|
||||||
_cmds_txt = cmds-ancillaryinterrogators.txt \
|
_cmds_txt = cmds-ancillaryinterrogators.txt \
|
||||||
cmds-ancillarymanipulators.txt \
|
cmds-ancillarymanipulators.txt \
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "api/fs/fs.h"
|
#include "api/fs/fs.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "symbol.h"
|
||||||
|
|
||||||
int arch__fix_module_text_start(u64 *start, const char *name)
|
int arch__fix_module_text_start(u64 *start, u64 *size, const char *name)
|
||||||
{
|
{
|
||||||
u64 m_start = *start;
|
u64 m_start = *start;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
@ -17,7 +18,35 @@ int arch__fix_module_text_start(u64 *start, const char *name)
|
||||||
if (sysfs__read_ull(path, (unsigned long long *)start) < 0) {
|
if (sysfs__read_ull(path, (unsigned long long *)start) < 0) {
|
||||||
pr_debug2("Using module %s start:%#lx\n", path, m_start);
|
pr_debug2("Using module %s start:%#lx\n", path, m_start);
|
||||||
*start = m_start;
|
*start = m_start;
|
||||||
|
} else {
|
||||||
|
/* Successful read of the modules segment text start address.
|
||||||
|
* Calculate difference between module start address
|
||||||
|
* in memory and module text segment start address.
|
||||||
|
* For example module load address is 0x3ff8011b000
|
||||||
|
* (from /proc/modules) and module text segment start
|
||||||
|
* address is 0x3ff8011b870 (from file above).
|
||||||
|
*
|
||||||
|
* Adjust the module size and subtract the GOT table
|
||||||
|
* size located at the beginning of the module.
|
||||||
|
*/
|
||||||
|
*size -= (*start - m_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On s390 kernel text segment start is located at very low memory addresses,
|
||||||
|
* for example 0x10000. Modules are located at very high memory addresses,
|
||||||
|
* for example 0x3ff xxxx xxxx. The gap between end of kernel text segment
|
||||||
|
* and beginning of first module's text segment is very big.
|
||||||
|
* Therefore do not fill this gap and do not assign it to the kernel dso map.
|
||||||
|
*/
|
||||||
|
void arch__symbols__fixup_end(struct symbol *p, struct symbol *c)
|
||||||
|
{
|
||||||
|
if (strchr(p->name, '[') == NULL && strchr(c->name, '['))
|
||||||
|
/* Last kernel symbol mapped to end of page */
|
||||||
|
p->end = roundup(p->end, page_size);
|
||||||
|
else
|
||||||
|
p->end = c->start;
|
||||||
|
pr_debug4("%s sym:%s end:%#lx\n", __func__, p->name, p->end);
|
||||||
|
}
|
||||||
|
|
|
@ -379,8 +379,10 @@ static u8 *alloc_data(ssize_t bytes0, int map_flags,
|
||||||
|
|
||||||
/* Allocate and initialize all memory on CPU#0: */
|
/* Allocate and initialize all memory on CPU#0: */
|
||||||
if (init_cpu0) {
|
if (init_cpu0) {
|
||||||
orig_mask = bind_to_node(0);
|
int node = numa_node_of_cpu(0);
|
||||||
bind_to_memnode(0);
|
|
||||||
|
orig_mask = bind_to_node(node);
|
||||||
|
bind_to_memnode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = bytes0 + HPSIZE;
|
bytes = bytes0 + HPSIZE;
|
||||||
|
|
|
@ -173,7 +173,7 @@ static int set_tracing_cpumask(struct cpu_map *cpumap)
|
||||||
int last_cpu;
|
int last_cpu;
|
||||||
|
|
||||||
last_cpu = cpu_map__cpu(cpumap, cpumap->nr - 1);
|
last_cpu = cpu_map__cpu(cpumap, cpumap->nr - 1);
|
||||||
mask_size = (last_cpu + 3) / 4 + 1;
|
mask_size = last_cpu / 4 + 2; /* one more byte for EOS */
|
||||||
mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */
|
mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */
|
||||||
|
|
||||||
cpumask = malloc(mask_size);
|
cpumask = malloc(mask_size);
|
||||||
|
|
|
@ -453,6 +453,7 @@ static struct fixed {
|
||||||
{ "inst_retired.any_p", "event=0xc0" },
|
{ "inst_retired.any_p", "event=0xc0" },
|
||||||
{ "cpu_clk_unhalted.ref", "event=0x0,umask=0x03" },
|
{ "cpu_clk_unhalted.ref", "event=0x0,umask=0x03" },
|
||||||
{ "cpu_clk_unhalted.thread", "event=0x3c" },
|
{ "cpu_clk_unhalted.thread", "event=0x3c" },
|
||||||
|
{ "cpu_clk_unhalted.core", "event=0x3c" },
|
||||||
{ "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" },
|
{ "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" },
|
||||||
{ NULL, NULL},
|
{ NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include "../string2.h"
|
#include "../util/util.h"
|
||||||
#include "../config.h"
|
#include "../util/string2.h"
|
||||||
#include "../../perf.h"
|
#include "../util/config.h"
|
||||||
|
#include "../perf.h"
|
||||||
#include "libslang.h"
|
#include "libslang.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
#include "browser.h"
|
#include "browser.h"
|
||||||
#include "helpline.h"
|
#include "helpline.h"
|
||||||
#include "keysyms.h"
|
#include "keysyms.h"
|
||||||
#include "../color.h"
|
#include "../util/color.h"
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include "../cache.h"
|
#include "../../util/cache.h"
|
||||||
#include "../progress.h"
|
#include "../progress.h"
|
||||||
#include "../libslang.h"
|
#include "../libslang.h"
|
||||||
#include "../ui.h"
|
#include "../ui.h"
|
||||||
|
|
|
@ -1122,7 +1122,7 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
(*rawp)[0] = tmp;
|
(*rawp)[0] = tmp;
|
||||||
*rawp = skip_spaces(*rawp);
|
*rawp = strim(*rawp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -751,7 +751,10 @@ size_t cpu_map__snprint_mask(struct cpu_map *map, char *buf, size_t size)
|
||||||
unsigned char *bitmap;
|
unsigned char *bitmap;
|
||||||
int last_cpu = cpu_map__cpu(map, map->nr - 1);
|
int last_cpu = cpu_map__cpu(map, map->nr - 1);
|
||||||
|
|
||||||
bitmap = zalloc((last_cpu + 7) / 8);
|
if (buf == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bitmap = zalloc(last_cpu / 8 + 1);
|
||||||
if (bitmap == NULL) {
|
if (bitmap == NULL) {
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1378,6 +1378,7 @@ static int machine__set_modules_path(struct machine *machine)
|
||||||
return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
|
return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
|
||||||
}
|
}
|
||||||
int __weak arch__fix_module_text_start(u64 *start __maybe_unused,
|
int __weak arch__fix_module_text_start(u64 *start __maybe_unused,
|
||||||
|
u64 *size __maybe_unused,
|
||||||
const char *name __maybe_unused)
|
const char *name __maybe_unused)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1389,7 +1390,7 @@ static int machine__create_module(void *arg, const char *name, u64 start,
|
||||||
struct machine *machine = arg;
|
struct machine *machine = arg;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
|
||||||
if (arch__fix_module_text_start(&start, name) < 0)
|
if (arch__fix_module_text_start(&start, &size, name) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
map = machine__findnew_module_map(machine, start, name);
|
map = machine__findnew_module_map(machine, start, name);
|
||||||
|
|
|
@ -222,7 +222,7 @@ struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine,
|
||||||
|
|
||||||
struct map *machine__findnew_module_map(struct machine *machine, u64 start,
|
struct map *machine__findnew_module_map(struct machine *machine, u64 start,
|
||||||
const char *filename);
|
const char *filename);
|
||||||
int arch__fix_module_text_start(u64 *start, const char *name);
|
int arch__fix_module_text_start(u64 *start, u64 *size, const char *name);
|
||||||
|
|
||||||
int machine__load_kallsyms(struct machine *machine, const char *filename);
|
int machine__load_kallsyms(struct machine *machine, const char *filename);
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,11 @@ static int prefix_underscores_count(const char *str)
|
||||||
return tail - str;
|
return tail - str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __weak arch__symbols__fixup_end(struct symbol *p, struct symbol *c)
|
||||||
|
{
|
||||||
|
p->end = c->start;
|
||||||
|
}
|
||||||
|
|
||||||
const char * __weak arch__normalize_symbol_name(const char *name)
|
const char * __weak arch__normalize_symbol_name(const char *name)
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
|
@ -218,7 +223,7 @@ void symbols__fixup_end(struct rb_root_cached *symbols)
|
||||||
curr = rb_entry(nd, struct symbol, rb_node);
|
curr = rb_entry(nd, struct symbol, rb_node);
|
||||||
|
|
||||||
if (prev->end == prev->start && prev->end != curr->start)
|
if (prev->end == prev->start && prev->end != curr->start)
|
||||||
prev->end = curr->start;
|
arch__symbols__fixup_end(prev, curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last entry */
|
/* Last entry */
|
||||||
|
|
|
@ -288,6 +288,7 @@ const char *arch__normalize_symbol_name(const char *name);
|
||||||
#define SYMBOL_A 0
|
#define SYMBOL_A 0
|
||||||
#define SYMBOL_B 1
|
#define SYMBOL_B 1
|
||||||
|
|
||||||
|
void arch__symbols__fixup_end(struct symbol *p, struct symbol *c);
|
||||||
int arch__compare_symbol_names(const char *namea, const char *nameb);
|
int arch__compare_symbol_names(const char *namea, const char *nameb);
|
||||||
int arch__compare_symbol_names_n(const char *namea, const char *nameb,
|
int arch__compare_symbol_names_n(const char *namea, const char *nameb,
|
||||||
unsigned int n);
|
unsigned int n);
|
||||||
|
|
|
@ -214,14 +214,24 @@ struct comm *thread__comm(const struct thread *thread)
|
||||||
|
|
||||||
struct comm *thread__exec_comm(const struct thread *thread)
|
struct comm *thread__exec_comm(const struct thread *thread)
|
||||||
{
|
{
|
||||||
struct comm *comm, *last = NULL;
|
struct comm *comm, *last = NULL, *second_last = NULL;
|
||||||
|
|
||||||
list_for_each_entry(comm, &thread->comm_list, list) {
|
list_for_each_entry(comm, &thread->comm_list, list) {
|
||||||
if (comm->exec)
|
if (comm->exec)
|
||||||
return comm;
|
return comm;
|
||||||
|
second_last = last;
|
||||||
last = comm;
|
last = comm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'last' with no start time might be the parent's comm of a synthesized
|
||||||
|
* thread (created by processing a synthesized fork event). For a main
|
||||||
|
* thread, that is very probably wrong. Prefer a later comm to avoid
|
||||||
|
* that case.
|
||||||
|
*/
|
||||||
|
if (second_last && !last->start && thread->pid_ == thread->tid)
|
||||||
|
return second_last;
|
||||||
|
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue