Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+100 -51
+41 -23
tools/lib/perf/evsel.c
··· 43 43 free(evsel); 44 44 } 45 45 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)) 47 47 #define MMAP(e, x, y) (e->mmap ? ((struct perf_mmap *) xyarray__entry(e->mmap, x, y)) : NULL) 48 48 49 49 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) ··· 54 54 int cpu, thread; 55 55 for (cpu = 0; cpu < ncpus; cpu++) { 56 56 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; 58 61 } 59 62 } 60 63 } ··· 83 80 static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *group_fd) 84 81 { 85 82 struct perf_evsel *leader = evsel->leader; 86 - int fd; 83 + int *fd; 87 84 88 85 if (evsel == leader) { 89 86 *group_fd = -1; ··· 98 95 return -ENOTCONN; 99 96 100 97 fd = FD(leader, cpu, thread); 101 - if (fd == -1) 98 + if (fd == NULL || *fd == -1) 102 99 return -EBADF; 103 100 104 - *group_fd = fd; 101 + *group_fd = *fd; 105 102 106 103 return 0; 107 104 } ··· 141 138 142 139 for (cpu = 0; cpu < cpus->nr; cpu++) { 143 140 for (thread = 0; thread < threads->nr; thread++) { 144 - int fd, group_fd; 141 + int fd, group_fd, *evsel_fd; 142 + 143 + evsel_fd = FD(evsel, cpu, thread); 144 + if (evsel_fd == NULL) 145 + return -EINVAL; 145 146 146 147 err = get_group_fd(evsel, cpu, thread, &group_fd); 147 148 if (err < 0) ··· 158 151 if (fd < 0) 159 152 return -errno; 160 153 161 - FD(evsel, cpu, thread) = fd; 154 + *evsel_fd = fd; 162 155 } 163 156 } 164 157 ··· 170 163 int thread; 171 164 172 165 for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) { 173 - if (FD(evsel, cpu, thread) >= 0) 174 - close(FD(evsel, cpu, thread)); 175 - FD(evsel, cpu, thread) = -1; 166 + int *fd = FD(evsel, cpu, thread); 167 + 168 + if (fd && *fd >= 0) { 169 + close(*fd); 170 + *fd = -1; 171 + } 176 172 } 177 173 } 178 174 ··· 219 209 220 210 for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { 221 211 for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { 222 - int fd = FD(evsel, cpu, thread); 223 - struct perf_mmap *map = MMAP(evsel, cpu, thread); 212 + int *fd = FD(evsel, cpu, thread); 224 213 225 - if (fd < 0) 214 + if (fd == NULL || *fd < 0) 226 215 continue; 227 216 228 - perf_mmap__munmap(map); 217 + perf_mmap__munmap(MMAP(evsel, cpu, thread)); 229 218 } 230 219 } 231 220 ··· 248 239 249 240 for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { 250 241 for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { 251 - int fd = FD(evsel, cpu, thread); 252 - struct perf_mmap *map = MMAP(evsel, cpu, thread); 242 + int *fd = FD(evsel, cpu, thread); 243 + struct perf_mmap *map; 253 244 254 - if (fd < 0) 245 + if (fd == NULL || *fd < 0) 255 246 continue; 256 247 248 + map = MMAP(evsel, cpu, thread); 257 249 perf_mmap__init(map, NULL, false, NULL); 258 250 259 - ret = perf_mmap__mmap(map, &mp, fd, cpu); 251 + ret = perf_mmap__mmap(map, &mp, *fd, cpu); 260 252 if (ret) { 261 253 perf_evsel__munmap(evsel); 262 254 return ret; ··· 270 260 271 261 void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread) 272 262 { 273 - if (FD(evsel, cpu, thread) < 0 || MMAP(evsel, cpu, thread) == NULL) 263 + int *fd = FD(evsel, cpu, thread); 264 + 265 + if (fd == NULL || *fd < 0 || MMAP(evsel, cpu, thread) == NULL) 274 266 return NULL; 275 267 276 268 return MMAP(evsel, cpu, thread)->base; ··· 307 295 struct perf_counts_values *count) 308 296 { 309 297 size_t size = perf_evsel__read_size(evsel); 298 + int *fd = FD(evsel, cpu, thread); 310 299 311 300 memset(count, 0, sizeof(*count)); 312 301 313 - if (FD(evsel, cpu, thread) < 0) 302 + if (fd == NULL || *fd < 0) 314 303 return -EINVAL; 315 304 316 305 if (MMAP(evsel, cpu, thread) && 317 306 !perf_mmap__read_self(MMAP(evsel, cpu, thread), count)) 318 307 return 0; 319 308 320 - if (readn(FD(evsel, cpu, thread), count->values, size) <= 0) 309 + if (readn(*fd, count->values, size) <= 0) 321 310 return -errno; 322 311 323 312 return 0; ··· 331 318 int thread; 332 319 333 320 for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { 334 - int fd = FD(evsel, cpu, thread), 335 - err = ioctl(fd, ioc, arg); 321 + int err; 322 + int *fd = FD(evsel, cpu, thread); 323 + 324 + if (fd == NULL || *fd < 0) 325 + return -1; 326 + 327 + err = ioctl(*fd, ioc, arg); 336 328 337 329 if (err) 338 330 return err;
+13 -11
tools/perf/builtin-script.c
··· 368 368 return OUTPUT_TYPE_OTHER; 369 369 } 370 370 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 - 381 371 static bool output_set_by_user(void) 382 372 { 383 373 int j; ··· 546 556 output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE; 547 557 } 548 558 559 + static struct evsel *find_first_output_type(struct evlist *evlist, 560 + unsigned int type) 561 + { 562 + struct evsel *evsel; 563 + 564 + evlist__for_each_entry(evlist, evsel) { 565 + if (output_type(evsel->core.attr.type) == (int)type) 566 + return evsel; 567 + } 568 + return NULL; 569 + } 570 + 549 571 /* 550 572 * verify all user requested events exist and the samples 551 573 * have the expected data ··· 569 567 struct evsel *evsel; 570 568 571 569 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) { 572 - evsel = perf_session__find_first_evtype(session, attr_type(j)); 570 + evsel = find_first_output_type(session->evlist, j); 573 571 574 572 /* 575 573 * even if fields is set to 0 (ie., show nothing) event must
+24 -9
tools/perf/ui/browser.c
··· 757 757 } 758 758 759 759 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) 761 761 { 762 - unsigned int end_row; 762 + int end_row; 763 763 764 - if (row >= browser->top_idx) 765 - end_row = row - browser->top_idx; 766 - else 764 + if (diff <= 0) 767 765 return; 768 766 769 767 SLsmg_set_char_set(1); 770 768 771 769 if (arrow_down) { 770 + if (row + diff <= browser->top_idx) 771 + return; 772 + 773 + end_row = row + diff - browser->top_idx; 772 774 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); 777 775 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 + } 778 789 } else { 790 + if (row < browser->top_idx) 791 + return; 792 + 793 + end_row = row - browser->top_idx; 779 794 ui_browser__gotorc(browser, end_row, column - 1); 780 795 SLsmg_write_char(SLSMG_LTEE_CHAR); 781 796 ui_browser__gotorc(browser, end_row, column);
+1 -1
tools/perf/ui/browser.h
··· 51 51 void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, 52 52 u64 start, u64 end); 53 53 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); 55 55 void __ui_browser__show_title(struct ui_browser *browser, const char *title); 56 56 void ui_browser__show_title(struct ui_browser *browser, const char *title); 57 57 int ui_browser__show(struct ui_browser *browser, const char *title,
+17 -7
tools/perf/ui/browsers/annotate.c
··· 125 125 ab->selection = al; 126 126 } 127 127 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) 129 129 { 130 130 struct disasm_line *pos = list_prev_entry(cursor, al.node); 131 131 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 + } 132 139 133 140 if (!pos) 134 - return false; 141 + return 0; 135 142 136 143 if (ins__is_lock(&pos->ins)) 137 144 name = pos->ops.locked.ins.name; ··· 146 139 name = pos->ins.name; 147 140 148 141 if (!name || !cursor->ins.name) 149 - return false; 142 + return 0; 150 143 151 - return ins__is_fused(ab->arch, name, cursor->ins.name); 144 + if (ins__is_fused(ab->arch, name, cursor->ins.name)) 145 + return diff; 146 + return 0; 152 147 } 153 148 154 149 static void annotate_browser__draw_current_jump(struct ui_browser *browser) ··· 164 155 struct annotation *notes = symbol__annotation(sym); 165 156 u8 pcnt_width = annotation__pcnt_width(notes); 166 157 int width; 158 + int diff = 0; 167 159 168 160 /* PLT symbols contain external offsets */ 169 161 if (strstr(sym->name, "@plt")) ··· 215 205 pcnt_width + 2 + notes->widths.addr + width, 216 206 from, to); 217 207 218 - if (is_fused(ab, cursor)) { 208 + diff = is_fused(ab, cursor); 209 + if (diff > 0) { 219 210 ui_browser__mark_fused(browser, 220 211 pcnt_width + 3 + notes->widths.addr + width, 221 - from - 1, 222 - to > from); 212 + from - diff, diff, to > from); 223 213 } 224 214 } 225 215
+3
tools/perf/util/bpf-event.c
··· 24 24 struct btf * __weak btf__load_from_kernel_by_id(__u32 id) 25 25 { 26 26 struct btf *btf; 27 + #pragma GCC diagnostic push 28 + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 27 29 int err = btf__get_from_id(id, &btf); 30 + #pragma GCC diagnostic pop 28 31 29 32 return err ? ERR_PTR(err) : btf; 30 33 }
+1
tools/perf/util/machine.c
··· 2149 2149 2150 2150 al.filtered = 0; 2151 2151 al.sym = NULL; 2152 + al.srcline = NULL; 2152 2153 if (!cpumode) { 2153 2154 thread__find_cpumode_addr_location(thread, ip, &al); 2154 2155 } else {