Commit d94f3957 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'perf-tools-fixes-for-v5.15-2021-09-18' of...

Merge tag 'perf-tools-fixes-for-v5.15-2021-09-18' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:

 - Fix ip display in 'perf script' when output type != attr->type.

 - Ignore deprecation warning when using libbpf'sg btf__get_from_id(),
   fixing the build with libbpf v0.6+.

 - Make use of FD() robust in libperf, fixing a segfault with 'perf stat
   --iostat list'.

 - Initialize addr_location:srcline pointer to NULL when resolving
   callchain addresses.

 - Fix fused instruction logic for assembly functions in 'perf
   annotate'.

* tag 'perf-tools-fixes-for-v5.15-2021-09-18' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
  perf bpf: Ignore deprecation warning when using libbpf's btf__get_from_id()
  libperf evsel: Make use of FD robust.
  perf machine: Initialize srcline string member in add_location struct
  perf script: Fix ip display when type != attr->type
  perf annotate: Fix fused instr logic for assembly functions
parents bc1abb9e 219d720e
...@@ -43,7 +43,7 @@ void perf_evsel__delete(struct perf_evsel *evsel) ...@@ -43,7 +43,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)
free(evsel); free(evsel);
} }
#define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y)) #define FD(e, x, y) ((int *) xyarray__entry(e->fd, x, y))
#define MMAP(e, x, y) (e->mmap ? ((struct perf_mmap *) xyarray__entry(e->mmap, x, y)) : NULL) #define MMAP(e, x, y) (e->mmap ? ((struct perf_mmap *) xyarray__entry(e->mmap, x, y)) : NULL)
int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
...@@ -54,7 +54,10 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) ...@@ -54,7 +54,10 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
int cpu, thread; int cpu, thread;
for (cpu = 0; cpu < ncpus; cpu++) { for (cpu = 0; cpu < ncpus; cpu++) {
for (thread = 0; thread < nthreads; thread++) { for (thread = 0; thread < nthreads; thread++) {
FD(evsel, cpu, thread) = -1; int *fd = FD(evsel, cpu, thread);
if (fd)
*fd = -1;
} }
} }
} }
...@@ -80,7 +83,7 @@ sys_perf_event_open(struct perf_event_attr *attr, ...@@ -80,7 +83,7 @@ sys_perf_event_open(struct perf_event_attr *attr,
static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *group_fd) static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *group_fd)
{ {
struct perf_evsel *leader = evsel->leader; struct perf_evsel *leader = evsel->leader;
int fd; int *fd;
if (evsel == leader) { if (evsel == leader) {
*group_fd = -1; *group_fd = -1;
...@@ -95,10 +98,10 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *grou ...@@ -95,10 +98,10 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *grou
return -ENOTCONN; return -ENOTCONN;
fd = FD(leader, cpu, thread); fd = FD(leader, cpu, thread);
if (fd == -1) if (fd == NULL || *fd == -1)
return -EBADF; return -EBADF;
*group_fd = fd; *group_fd = *fd;
return 0; return 0;
} }
...@@ -138,7 +141,11 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, ...@@ -138,7 +141,11 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
for (cpu = 0; cpu < cpus->nr; cpu++) { for (cpu = 0; cpu < cpus->nr; cpu++) {
for (thread = 0; thread < threads->nr; thread++) { for (thread = 0; thread < threads->nr; thread++) {
int fd, group_fd; int fd, group_fd, *evsel_fd;
evsel_fd = FD(evsel, cpu, thread);
if (evsel_fd == NULL)
return -EINVAL;
err = get_group_fd(evsel, cpu, thread, &group_fd); err = get_group_fd(evsel, cpu, thread, &group_fd);
if (err < 0) if (err < 0)
...@@ -151,7 +158,7 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, ...@@ -151,7 +158,7 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
if (fd < 0) if (fd < 0)
return -errno; return -errno;
FD(evsel, cpu, thread) = fd; *evsel_fd = fd;
} }
} }
...@@ -163,9 +170,12 @@ static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu) ...@@ -163,9 +170,12 @@ static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu)
int thread; int thread;
for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) { for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
if (FD(evsel, cpu, thread) >= 0) int *fd = FD(evsel, cpu, thread);
close(FD(evsel, cpu, thread));
FD(evsel, cpu, thread) = -1; if (fd && *fd >= 0) {
close(*fd);
*fd = -1;
}
} }
} }
...@@ -209,13 +219,12 @@ void perf_evsel__munmap(struct perf_evsel *evsel) ...@@ -209,13 +219,12 @@ void perf_evsel__munmap(struct perf_evsel *evsel)
for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) {
for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
int fd = FD(evsel, cpu, thread); int *fd = FD(evsel, cpu, thread);
struct perf_mmap *map = MMAP(evsel, cpu, thread);
if (fd < 0) if (fd == NULL || *fd < 0)
continue; continue;
perf_mmap__munmap(map); perf_mmap__munmap(MMAP(evsel, cpu, thread));
} }
} }
...@@ -239,15 +248,16 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages) ...@@ -239,15 +248,16 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) {
for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
int fd = FD(evsel, cpu, thread); int *fd = FD(evsel, cpu, thread);
struct perf_mmap *map = MMAP(evsel, cpu, thread); struct perf_mmap *map;
if (fd < 0) if (fd == NULL || *fd < 0)
continue; continue;
map = MMAP(evsel, cpu, thread);
perf_mmap__init(map, NULL, false, NULL); perf_mmap__init(map, NULL, false, NULL);
ret = perf_mmap__mmap(map, &mp, fd, cpu); ret = perf_mmap__mmap(map, &mp, *fd, cpu);
if (ret) { if (ret) {
perf_evsel__munmap(evsel); perf_evsel__munmap(evsel);
return ret; return ret;
...@@ -260,7 +270,9 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages) ...@@ -260,7 +270,9 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread) void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread)
{ {
if (FD(evsel, cpu, thread) < 0 || MMAP(evsel, cpu, thread) == NULL) int *fd = FD(evsel, cpu, thread);
if (fd == NULL || *fd < 0 || MMAP(evsel, cpu, thread) == NULL)
return NULL; return NULL;
return MMAP(evsel, cpu, thread)->base; return MMAP(evsel, cpu, thread)->base;
...@@ -295,17 +307,18 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, ...@@ -295,17 +307,18 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
struct perf_counts_values *count) struct perf_counts_values *count)
{ {
size_t size = perf_evsel__read_size(evsel); size_t size = perf_evsel__read_size(evsel);
int *fd = FD(evsel, cpu, thread);
memset(count, 0, sizeof(*count)); memset(count, 0, sizeof(*count));
if (FD(evsel, cpu, thread) < 0) if (fd == NULL || *fd < 0)
return -EINVAL; return -EINVAL;
if (MMAP(evsel, cpu, thread) && if (MMAP(evsel, cpu, thread) &&
!perf_mmap__read_self(MMAP(evsel, cpu, thread), count)) !perf_mmap__read_self(MMAP(evsel, cpu, thread), count))
return 0; return 0;
if (readn(FD(evsel, cpu, thread), count->values, size) <= 0) if (readn(*fd, count->values, size) <= 0)
return -errno; return -errno;
return 0; return 0;
...@@ -318,8 +331,13 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, ...@@ -318,8 +331,13 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
int thread; int thread;
for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
int fd = FD(evsel, cpu, thread), int err;
err = ioctl(fd, ioc, arg); int *fd = FD(evsel, cpu, thread);
if (fd == NULL || *fd < 0)
return -1;
err = ioctl(*fd, ioc, arg);
if (err) if (err)
return err; return err;
......
...@@ -368,16 +368,6 @@ static inline int output_type(unsigned int type) ...@@ -368,16 +368,6 @@ static inline int output_type(unsigned int type)
return OUTPUT_TYPE_OTHER; return OUTPUT_TYPE_OTHER;
} }
static inline unsigned int attr_type(unsigned int type)
{
switch (type) {
case OUTPUT_TYPE_SYNTH:
return PERF_TYPE_SYNTH;
default:
return type;
}
}
static bool output_set_by_user(void) static bool output_set_by_user(void)
{ {
int j; int j;
...@@ -556,6 +546,18 @@ static void set_print_ip_opts(struct perf_event_attr *attr) ...@@ -556,6 +546,18 @@ static void set_print_ip_opts(struct perf_event_attr *attr)
output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE; output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
} }
static struct evsel *find_first_output_type(struct evlist *evlist,
unsigned int type)
{
struct evsel *evsel;
evlist__for_each_entry(evlist, evsel) {
if (output_type(evsel->core.attr.type) == (int)type)
return evsel;
}
return NULL;
}
/* /*
* verify all user requested events exist and the samples * verify all user requested events exist and the samples
* have the expected data * have the expected data
...@@ -567,7 +569,7 @@ static int perf_session__check_output_opt(struct perf_session *session) ...@@ -567,7 +569,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
struct evsel *evsel; struct evsel *evsel;
for (j = 0; j < OUTPUT_TYPE_MAX; ++j) { for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
evsel = perf_session__find_first_evtype(session, attr_type(j)); evsel = find_first_output_type(session->evlist, j);
/* /*
* even if fields is set to 0 (ie., show nothing) event must * even if fields is set to 0 (ie., show nothing) event must
......
...@@ -757,25 +757,40 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, ...@@ -757,25 +757,40 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
} }
void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column,
unsigned int row, bool arrow_down) unsigned int row, int diff, bool arrow_down)
{ {
unsigned int end_row; int end_row;
if (row >= browser->top_idx) if (diff <= 0)
end_row = row - browser->top_idx;
else
return; return;
SLsmg_set_char_set(1); SLsmg_set_char_set(1);
if (arrow_down) { if (arrow_down) {
if (row + diff <= browser->top_idx)
return;
end_row = row + diff - browser->top_idx;
ui_browser__gotorc(browser, end_row, column - 1); ui_browser__gotorc(browser, end_row, column - 1);
SLsmg_write_char(SLSMG_ULCORN_CHAR);
ui_browser__gotorc(browser, end_row, column);
SLsmg_draw_hline(2);
ui_browser__gotorc(browser, end_row + 1, column - 1);
SLsmg_write_char(SLSMG_LTEE_CHAR); SLsmg_write_char(SLSMG_LTEE_CHAR);
while (--end_row >= 0 && end_row > (int)(row - browser->top_idx)) {
ui_browser__gotorc(browser, end_row, column - 1);
SLsmg_draw_vline(1);
}
end_row = (int)(row - browser->top_idx);
if (end_row >= 0) {
ui_browser__gotorc(browser, end_row, column - 1);
SLsmg_write_char(SLSMG_ULCORN_CHAR);
ui_browser__gotorc(browser, end_row, column);
SLsmg_draw_hline(2);
}
} else { } else {
if (row < browser->top_idx)
return;
end_row = row - browser->top_idx;
ui_browser__gotorc(browser, end_row, column - 1); ui_browser__gotorc(browser, end_row, column - 1);
SLsmg_write_char(SLSMG_LTEE_CHAR); SLsmg_write_char(SLSMG_LTEE_CHAR);
ui_browser__gotorc(browser, end_row, column); ui_browser__gotorc(browser, end_row, column);
......
...@@ -51,7 +51,7 @@ void ui_browser__write_graph(struct ui_browser *browser, int graph); ...@@ -51,7 +51,7 @@ void ui_browser__write_graph(struct ui_browser *browser, int graph);
void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
u64 start, u64 end); u64 start, u64 end);
void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column,
unsigned int row, bool arrow_down); unsigned int row, int diff, bool arrow_down);
void __ui_browser__show_title(struct ui_browser *browser, const char *title); void __ui_browser__show_title(struct ui_browser *browser, const char *title);
void ui_browser__show_title(struct ui_browser *browser, const char *title); void ui_browser__show_title(struct ui_browser *browser, const char *title);
int ui_browser__show(struct ui_browser *browser, const char *title, int ui_browser__show(struct ui_browser *browser, const char *title,
......
...@@ -125,13 +125,20 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int ...@@ -125,13 +125,20 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
ab->selection = al; ab->selection = al;
} }
static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) static int is_fused(struct annotate_browser *ab, struct disasm_line *cursor)
{ {
struct disasm_line *pos = list_prev_entry(cursor, al.node); struct disasm_line *pos = list_prev_entry(cursor, al.node);
const char *name; const char *name;
int diff = 1;
while (pos && pos->al.offset == -1) {
pos = list_prev_entry(pos, al.node);
if (!ab->opts->hide_src_code)
diff++;
}
if (!pos) if (!pos)
return false; return 0;
if (ins__is_lock(&pos->ins)) if (ins__is_lock(&pos->ins))
name = pos->ops.locked.ins.name; name = pos->ops.locked.ins.name;
...@@ -139,9 +146,11 @@ static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) ...@@ -139,9 +146,11 @@ static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor)
name = pos->ins.name; name = pos->ins.name;
if (!name || !cursor->ins.name) if (!name || !cursor->ins.name)
return false; return 0;
return ins__is_fused(ab->arch, name, cursor->ins.name); if (ins__is_fused(ab->arch, name, cursor->ins.name))
return diff;
return 0;
} }
static void annotate_browser__draw_current_jump(struct ui_browser *browser) static void annotate_browser__draw_current_jump(struct ui_browser *browser)
...@@ -155,6 +164,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) ...@@ -155,6 +164,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
struct annotation *notes = symbol__annotation(sym); struct annotation *notes = symbol__annotation(sym);
u8 pcnt_width = annotation__pcnt_width(notes); u8 pcnt_width = annotation__pcnt_width(notes);
int width; int width;
int diff = 0;
/* PLT symbols contain external offsets */ /* PLT symbols contain external offsets */
if (strstr(sym->name, "@plt")) if (strstr(sym->name, "@plt"))
...@@ -205,11 +215,11 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) ...@@ -205,11 +215,11 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
pcnt_width + 2 + notes->widths.addr + width, pcnt_width + 2 + notes->widths.addr + width,
from, to); from, to);
if (is_fused(ab, cursor)) { diff = is_fused(ab, cursor);
if (diff > 0) {
ui_browser__mark_fused(browser, ui_browser__mark_fused(browser,
pcnt_width + 3 + notes->widths.addr + width, pcnt_width + 3 + notes->widths.addr + width,
from - 1, from - diff, diff, to > from);
to > from);
} }
} }
......
...@@ -24,7 +24,10 @@ ...@@ -24,7 +24,10 @@
struct btf * __weak btf__load_from_kernel_by_id(__u32 id) struct btf * __weak btf__load_from_kernel_by_id(__u32 id)
{ {
struct btf *btf; struct btf *btf;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
int err = btf__get_from_id(id, &btf); int err = btf__get_from_id(id, &btf);
#pragma GCC diagnostic pop
return err ? ERR_PTR(err) : btf; return err ? ERR_PTR(err) : btf;
} }
......
...@@ -2149,6 +2149,7 @@ static int add_callchain_ip(struct thread *thread, ...@@ -2149,6 +2149,7 @@ static int add_callchain_ip(struct thread *thread,
al.filtered = 0; al.filtered = 0;
al.sym = NULL; al.sym = NULL;
al.srcline = NULL;
if (!cpumode) { if (!cpumode) {
thread__find_cpumode_addr_location(thread, ip, &al); thread__find_cpumode_addr_location(thread, ip, &al);
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment