Skip to content

Commit d94f395

Browse files
committed
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
2 parents bc1abb9 + 219d720 commit d94f395

File tree

7 files changed

+100
-51
lines changed

7 files changed

+100
-51
lines changed

tools/lib/perf/evsel.c

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)
4343
free(evsel);
4444
}
4545

46-
#define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y))
46+
#define FD(e, x, y) ((int *) xyarray__entry(e->fd, x, y))
4747
#define MMAP(e, x, y) (e->mmap ? ((struct perf_mmap *) xyarray__entry(e->mmap, x, y)) : NULL)
4848

4949
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)
5454
int cpu, thread;
5555
for (cpu = 0; cpu < ncpus; cpu++) {
5656
for (thread = 0; thread < nthreads; thread++) {
57-
FD(evsel, cpu, thread) = -1;
57+
int *fd = FD(evsel, cpu, thread);
58+
59+
if (fd)
60+
*fd = -1;
5861
}
5962
}
6063
}
@@ -80,7 +83,7 @@ sys_perf_event_open(struct perf_event_attr *attr,
8083
static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *group_fd)
8184
{
8285
struct perf_evsel *leader = evsel->leader;
83-
int fd;
86+
int *fd;
8487

8588
if (evsel == leader) {
8689
*group_fd = -1;
@@ -95,10 +98,10 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *grou
9598
return -ENOTCONN;
9699

97100
fd = FD(leader, cpu, thread);
98-
if (fd == -1)
101+
if (fd == NULL || *fd == -1)
99102
return -EBADF;
100103

101-
*group_fd = fd;
104+
*group_fd = *fd;
102105

103106
return 0;
104107
}
@@ -138,7 +141,11 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
138141

139142
for (cpu = 0; cpu < cpus->nr; cpu++) {
140143
for (thread = 0; thread < threads->nr; thread++) {
141-
int fd, group_fd;
144+
int fd, group_fd, *evsel_fd;
145+
146+
evsel_fd = FD(evsel, cpu, thread);
147+
if (evsel_fd == NULL)
148+
return -EINVAL;
142149

143150
err = get_group_fd(evsel, cpu, thread, &group_fd);
144151
if (err < 0)
@@ -151,7 +158,7 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
151158
if (fd < 0)
152159
return -errno;
153160

154-
FD(evsel, cpu, thread) = fd;
161+
*evsel_fd = fd;
155162
}
156163
}
157164

@@ -163,9 +170,12 @@ static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu)
163170
int thread;
164171

165172
for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
166-
if (FD(evsel, cpu, thread) >= 0)
167-
close(FD(evsel, cpu, thread));
168-
FD(evsel, cpu, thread) = -1;
173+
int *fd = FD(evsel, cpu, thread);
174+
175+
if (fd && *fd >= 0) {
176+
close(*fd);
177+
*fd = -1;
178+
}
169179
}
170180
}
171181

@@ -209,13 +219,12 @@ void perf_evsel__munmap(struct perf_evsel *evsel)
209219

210220
for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) {
211221
for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
212-
int fd = FD(evsel, cpu, thread);
213-
struct perf_mmap *map = MMAP(evsel, cpu, thread);
222+
int *fd = FD(evsel, cpu, thread);
214223

215-
if (fd < 0)
224+
if (fd == NULL || *fd < 0)
216225
continue;
217226

218-
perf_mmap__munmap(map);
227+
perf_mmap__munmap(MMAP(evsel, cpu, thread));
219228
}
220229
}
221230

@@ -239,15 +248,16 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
239248

240249
for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) {
241250
for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
242-
int fd = FD(evsel, cpu, thread);
243-
struct perf_mmap *map = MMAP(evsel, cpu, thread);
251+
int *fd = FD(evsel, cpu, thread);
252+
struct perf_mmap *map;
244253

245-
if (fd < 0)
254+
if (fd == NULL || *fd < 0)
246255
continue;
247256

257+
map = MMAP(evsel, cpu, thread);
248258
perf_mmap__init(map, NULL, false, NULL);
249259

250-
ret = perf_mmap__mmap(map, &mp, fd, cpu);
260+
ret = perf_mmap__mmap(map, &mp, *fd, cpu);
251261
if (ret) {
252262
perf_evsel__munmap(evsel);
253263
return ret;
@@ -260,7 +270,9 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
260270

261271
void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread)
262272
{
263-
if (FD(evsel, cpu, thread) < 0 || MMAP(evsel, cpu, thread) == NULL)
273+
int *fd = FD(evsel, cpu, thread);
274+
275+
if (fd == NULL || *fd < 0 || MMAP(evsel, cpu, thread) == NULL)
264276
return NULL;
265277

266278
return MMAP(evsel, cpu, thread)->base;
@@ -295,17 +307,18 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
295307
struct perf_counts_values *count)
296308
{
297309
size_t size = perf_evsel__read_size(evsel);
310+
int *fd = FD(evsel, cpu, thread);
298311

299312
memset(count, 0, sizeof(*count));
300313

301-
if (FD(evsel, cpu, thread) < 0)
314+
if (fd == NULL || *fd < 0)
302315
return -EINVAL;
303316

304317
if (MMAP(evsel, cpu, thread) &&
305318
!perf_mmap__read_self(MMAP(evsel, cpu, thread), count))
306319
return 0;
307320

308-
if (readn(FD(evsel, cpu, thread), count->values, size) <= 0)
321+
if (readn(*fd, count->values, size) <= 0)
309322
return -errno;
310323

311324
return 0;
@@ -318,8 +331,13 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
318331
int thread;
319332

320333
for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
321-
int fd = FD(evsel, cpu, thread),
322-
err = ioctl(fd, ioc, arg);
334+
int err;
335+
int *fd = FD(evsel, cpu, thread);
336+
337+
if (fd == NULL || *fd < 0)
338+
return -1;
339+
340+
err = ioctl(*fd, ioc, arg);
323341

324342
if (err)
325343
return err;

tools/perf/builtin-script.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -368,16 +368,6 @@ static inline int output_type(unsigned int type)
368368
return OUTPUT_TYPE_OTHER;
369369
}
370370

371-
static inline unsigned int attr_type(unsigned int type)
372-
{
373-
switch (type) {
374-
case OUTPUT_TYPE_SYNTH:
375-
return PERF_TYPE_SYNTH;
376-
default:
377-
return type;
378-
}
379-
}
380-
381371
static bool output_set_by_user(void)
382372
{
383373
int j;
@@ -556,6 +546,18 @@ static void set_print_ip_opts(struct perf_event_attr *attr)
556546
output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
557547
}
558548

549+
static struct evsel *find_first_output_type(struct evlist *evlist,
550+
unsigned int type)
551+
{
552+
struct evsel *evsel;
553+
554+
evlist__for_each_entry(evlist, evsel) {
555+
if (output_type(evsel->core.attr.type) == (int)type)
556+
return evsel;
557+
}
558+
return NULL;
559+
}
560+
559561
/*
560562
* verify all user requested events exist and the samples
561563
* have the expected data
@@ -567,7 +569,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
567569
struct evsel *evsel;
568570

569571
for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
570-
evsel = perf_session__find_first_evtype(session, attr_type(j));
572+
evsel = find_first_output_type(session->evlist, j);
571573

572574
/*
573575
* even if fields is set to 0 (ie., show nothing) event must

tools/perf/ui/browser.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -757,25 +757,40 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
757757
}
758758

759759
void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column,
760-
unsigned int row, bool arrow_down)
760+
unsigned int row, int diff, bool arrow_down)
761761
{
762-
unsigned int end_row;
762+
int end_row;
763763

764-
if (row >= browser->top_idx)
765-
end_row = row - browser->top_idx;
766-
else
764+
if (diff <= 0)
767765
return;
768766

769767
SLsmg_set_char_set(1);
770768

771769
if (arrow_down) {
770+
if (row + diff <= browser->top_idx)
771+
return;
772+
773+
end_row = row + diff - browser->top_idx;
772774
ui_browser__gotorc(browser, end_row, column - 1);
773-
SLsmg_write_char(SLSMG_ULCORN_CHAR);
774-
ui_browser__gotorc(browser, end_row, column);
775-
SLsmg_draw_hline(2);
776-
ui_browser__gotorc(browser, end_row + 1, column - 1);
777775
SLsmg_write_char(SLSMG_LTEE_CHAR);
776+
777+
while (--end_row >= 0 && end_row > (int)(row - browser->top_idx)) {
778+
ui_browser__gotorc(browser, end_row, column - 1);
779+
SLsmg_draw_vline(1);
780+
}
781+
782+
end_row = (int)(row - browser->top_idx);
783+
if (end_row >= 0) {
784+
ui_browser__gotorc(browser, end_row, column - 1);
785+
SLsmg_write_char(SLSMG_ULCORN_CHAR);
786+
ui_browser__gotorc(browser, end_row, column);
787+
SLsmg_draw_hline(2);
788+
}
778789
} else {
790+
if (row < browser->top_idx)
791+
return;
792+
793+
end_row = row - browser->top_idx;
779794
ui_browser__gotorc(browser, end_row, column - 1);
780795
SLsmg_write_char(SLSMG_LTEE_CHAR);
781796
ui_browser__gotorc(browser, end_row, column);

tools/perf/ui/browser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void ui_browser__write_graph(struct ui_browser *browser, int graph);
5151
void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
5252
u64 start, u64 end);
5353
void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column,
54-
unsigned int row, bool arrow_down);
54+
unsigned int row, int diff, bool arrow_down);
5555
void __ui_browser__show_title(struct ui_browser *browser, const char *title);
5656
void ui_browser__show_title(struct ui_browser *browser, const char *title);
5757
int ui_browser__show(struct ui_browser *browser, const char *title,

tools/perf/ui/browsers/annotate.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,23 +125,32 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
125125
ab->selection = al;
126126
}
127127

128-
static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor)
128+
static int is_fused(struct annotate_browser *ab, struct disasm_line *cursor)
129129
{
130130
struct disasm_line *pos = list_prev_entry(cursor, al.node);
131131
const char *name;
132+
int diff = 1;
133+
134+
while (pos && pos->al.offset == -1) {
135+
pos = list_prev_entry(pos, al.node);
136+
if (!ab->opts->hide_src_code)
137+
diff++;
138+
}
132139

133140
if (!pos)
134-
return false;
141+
return 0;
135142

136143
if (ins__is_lock(&pos->ins))
137144
name = pos->ops.locked.ins.name;
138145
else
139146
name = pos->ins.name;
140147

141148
if (!name || !cursor->ins.name)
142-
return false;
149+
return 0;
143150

144-
return ins__is_fused(ab->arch, name, cursor->ins.name);
151+
if (ins__is_fused(ab->arch, name, cursor->ins.name))
152+
return diff;
153+
return 0;
145154
}
146155

147156
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)
155164
struct annotation *notes = symbol__annotation(sym);
156165
u8 pcnt_width = annotation__pcnt_width(notes);
157166
int width;
167+
int diff = 0;
158168

159169
/* PLT symbols contain external offsets */
160170
if (strstr(sym->name, "@plt"))
@@ -205,11 +215,11 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
205215
pcnt_width + 2 + notes->widths.addr + width,
206216
from, to);
207217

208-
if (is_fused(ab, cursor)) {
218+
diff = is_fused(ab, cursor);
219+
if (diff > 0) {
209220
ui_browser__mark_fused(browser,
210221
pcnt_width + 3 + notes->widths.addr + width,
211-
from - 1,
212-
to > from);
222+
from - diff, diff, to > from);
213223
}
214224
}
215225

tools/perf/util/bpf-event.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
struct btf * __weak btf__load_from_kernel_by_id(__u32 id)
2525
{
2626
struct btf *btf;
27+
#pragma GCC diagnostic push
28+
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2729
int err = btf__get_from_id(id, &btf);
30+
#pragma GCC diagnostic pop
2831

2932
return err ? ERR_PTR(err) : btf;
3033
}

tools/perf/util/machine.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,7 @@ static int add_callchain_ip(struct thread *thread,
21492149

21502150
al.filtered = 0;
21512151
al.sym = NULL;
2152+
al.srcline = NULL;
21522153
if (!cpumode) {
21532154
thread__find_cpumode_addr_location(thread, ip, &al);
21542155
} else {

0 commit comments

Comments
 (0)