Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"Tooling changes only: it includes the ARM tooling fixlets, various
other fixes, smaller updates, minor cleanups"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf record: Add an option to force per-cpu mmaps
perf probe: Add '--demangle'/'--no-demangle'
perf ui browser: Fix segfault caused by off by one handling END key
perf symbols: Limit max callchain using max_stack on DWARF unwinding too
perf evsel: Introduce perf_evsel__prev() method
perf tools: Use perf_evlist__{first,last}, perf_evsel__next
perf tools: Synthesize anon MMAP records again
perf top: Add missing newline if the 'uid' is invalid
perf tools: Remove trivial extra semincolon
perf trace: Tweak summary output
tools/perf/build: Fix feature-libunwind-debug-frame handling
tools/perf/build: Fix timerfd feature check

+63 -38
+6
tools/perf/Documentation/perf-record.txt
··· 201 --transaction:: 202 Record transaction flags for transaction related events. 203 204 SEE ALSO 205 -------- 206 linkperf:perf-stat[1], linkperf:perf-list[1]
··· 201 --transaction:: 202 Record transaction flags for transaction related events. 203 204 + --force-per-cpu:: 205 + Force the use of per-cpu mmaps. By default, when tasks are specified (i.e. -p, 206 + -t or -u options) per-thread mmaps are created. This option overrides that and 207 + forces per-cpu mmaps. A side-effect of that is that inheritance is 208 + automatically enabled. Add the -i option also to disable inheritance. 209 + 210 SEE ALSO 211 -------- 212 linkperf:perf-stat[1], linkperf:perf-list[1]
+2
tools/perf/builtin-probe.c
··· 325 opt_set_filter), 326 OPT_CALLBACK('x', "exec", NULL, "executable|path", 327 "target executable name or path", opt_set_target), 328 OPT_END() 329 }; 330 int ret;
··· 325 opt_set_filter), 326 OPT_CALLBACK('x', "exec", NULL, "executable|path", 327 "target executable name or path", opt_set_target), 328 + OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 329 + "Disable symbol demangling"), 330 OPT_END() 331 }; 332 int ret;
+2
tools/perf/builtin-record.c
··· 888 "sample by weight (on special events only)"), 889 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction, 890 "sample transaction flags (special events only)"), 891 OPT_END() 892 }; 893
··· 888 "sample by weight (on special events only)"), 889 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction, 890 "sample transaction flags (special events only)"), 891 + OPT_BOOLEAN(0, "force-per-cpu", &record.opts.target.force_per_cpu, 892 + "force the use of per-cpu mmaps"), 893 OPT_END() 894 }; 895
+2 -2
tools/perf/builtin-top.c
··· 1172 status = target__validate(target); 1173 if (status) { 1174 target__strerror(target, status, errbuf, BUFSIZ); 1175 - ui__warning("%s", errbuf); 1176 } 1177 1178 status = target__parse_uid(target); ··· 1180 int saved_errno = errno; 1181 1182 target__strerror(target, status, errbuf, BUFSIZ); 1183 - ui__error("%s", errbuf); 1184 1185 status = -saved_errno; 1186 goto out_delete_evlist;
··· 1172 status = target__validate(target); 1173 if (status) { 1174 target__strerror(target, status, errbuf, BUFSIZ); 1175 + ui__warning("%s\n", errbuf); 1176 } 1177 1178 status = target__parse_uid(target); ··· 1180 int saved_errno = errno; 1181 1182 target__strerror(target, status, errbuf, BUFSIZ); 1183 + ui__error("%s\n", errbuf); 1184 1185 status = -saved_errno; 1186 goto out_delete_evlist;
+5 -5
tools/perf/builtin-trace.c
··· 2112 2113 printed += fprintf(fp, "\n"); 2114 2115 - printed += fprintf(fp, " msec/call\n"); 2116 - printed += fprintf(fp, " syscall calls min avg max stddev\n"); 2117 - printed += fprintf(fp, " --------------- -------- -------- -------- -------- ------\n"); 2118 2119 /* each int_node is a syscall */ 2120 while (inode) { ··· 2131 2132 sc = &trace->syscalls.table[inode->i]; 2133 printed += fprintf(fp, " %-15s", sc->name); 2134 - printed += fprintf(fp, " %8" PRIu64 " %8.3f %8.3f", 2135 n, min, avg); 2136 - printed += fprintf(fp, " %8.3f %6.2f\n", max, pct); 2137 } 2138 2139 inode = intlist__next(inode);
··· 2112 2113 printed += fprintf(fp, "\n"); 2114 2115 + printed += fprintf(fp, " syscall calls min avg max stddev\n"); 2116 + printed += fprintf(fp, " (msec) (msec) (msec) (%%)\n"); 2117 + printed += fprintf(fp, " --------------- -------- --------- --------- --------- ------\n"); 2118 2119 /* each int_node is a syscall */ 2120 while (inode) { ··· 2131 2132 sc = &trace->syscalls.table[inode->i]; 2133 printed += fprintf(fp, " %-15s", sc->name); 2134 + printed += fprintf(fp, " %8" PRIu64 " %9.3f %9.3f", 2135 n, min, avg); 2136 + printed += fprintf(fp, " %9.3f %9.2f%%\n", max, pct); 2137 } 2138 2139 inode = intlist__next(inode);
+10 -4
tools/perf/config/Makefile
··· 142 libunwind \ 143 on-exit \ 144 stackprotector \ 145 - stackprotector-all 146 147 # 148 # So here we detect whether test-all was rebuilt, to be able ··· 329 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1); 330 NO_LIBUNWIND := 1 331 else 332 - ifneq ($(feature-libunwind-debug-frame), 1) 333 - msg := $(warning No debug_frame support found in libunwind); 334 CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME 335 endif 336 endif ··· 412 endif 413 endif 414 415 - $(call feature_check,timerfd) 416 ifeq ($(feature-timerfd), 1) 417 CFLAGS += -DHAVE_TIMERFD_SUPPORT 418 else
··· 142 libunwind \ 143 on-exit \ 144 stackprotector \ 145 + stackprotector-all \ 146 + timerfd 147 148 # 149 # So here we detect whether test-all was rebuilt, to be able ··· 328 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1); 329 NO_LIBUNWIND := 1 330 else 331 + ifeq ($(ARCH),arm) 332 + $(call feature_check,libunwind-debug-frame) 333 + ifneq ($(feature-libunwind-debug-frame), 1) 334 + msg := $(warning No debug_frame support found in libunwind); 335 + CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME 336 + endif 337 + else 338 + # non-ARM has no dwarf_find_debug_frame() function: 339 CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME 340 endif 341 endif ··· 405 endif 406 endif 407 408 ifeq ($(feature-timerfd), 1) 409 CFLAGS += -DHAVE_TIMERFD_SUPPORT 410 else
+3
tools/perf/config/feature-checks/Makefile
··· 76 test-libunwind: 77 $(BUILD) $(LIBUNWIND_LIBS) -lelf 78 79 test-libaudit: 80 $(BUILD) -laudit 81
··· 76 test-libunwind: 77 $(BUILD) $(LIBUNWIND_LIBS) -lelf 78 79 + test-libunwind-debug-frame: 80 + $(BUILD) $(LIBUNWIND_LIBS) -lelf 81 + 82 test-libaudit: 83 $(BUILD) -laudit 84
-4
tools/perf/config/feature-checks/test-all.c
··· 49 # include "test-libunwind.c" 50 #undef main 51 52 - #define main main_test_libunwind_debug_frame 53 - # include "test-libunwind-debug-frame.c" 54 - #undef main 55 - 56 #define main main_test_libaudit 57 # include "test-libaudit.c" 58 #undef main
··· 49 # include "test-libunwind.c" 50 #undef main 51 52 #define main main_test_libaudit 53 # include "test-libaudit.c" 54 #undef main
+1 -2
tools/perf/tests/parse-events.c
··· 441 442 static int test__checkevent_pmu_events(struct perf_evlist *evlist) 443 { 444 - struct perf_evsel *evsel; 445 446 - evsel = list_entry(evlist->entries.next, struct perf_evsel, node); 447 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); 448 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); 449 TEST_ASSERT_VAL("wrong exclude_user",
··· 441 442 static int test__checkevent_pmu_events(struct perf_evlist *evlist) 443 { 444 + struct perf_evsel *evsel = perf_evlist__first(evlist); 445 446 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); 447 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); 448 TEST_ASSERT_VAL("wrong exclude_user",
+2 -2
tools/perf/ui/browser.c
··· 569 browser->top = browser->top + browser->top_idx + offset; 570 break; 571 case SEEK_END: 572 - browser->top = browser->top + browser->nr_entries + offset; 573 break; 574 default: 575 return; ··· 680 if (end >= browser->top_idx + browser->height) 681 end_row = browser->height - 1; 682 else 683 - end_row = end - browser->top_idx;; 684 685 ui_browser__gotorc(browser, row, column); 686 SLsmg_draw_vline(end_row - row + 1);
··· 569 browser->top = browser->top + browser->top_idx + offset; 570 break; 571 case SEEK_END: 572 + browser->top = browser->top + browser->nr_entries - 1 + offset; 573 break; 574 default: 575 return; ··· 680 if (end >= browser->top_idx + browser->height) 681 end_row = browser->height - 1; 682 else 683 + end_row = end - browser->top_idx; 684 685 ui_browser__gotorc(browser, row, column); 686 SLsmg_draw_vline(end_row - row + 1);
+5 -6
tools/perf/ui/browsers/hists.c
··· 1847 switch (key) { 1848 case K_TAB: 1849 if (pos->node.next == &evlist->entries) 1850 - pos = list_entry(evlist->entries.next, struct perf_evsel, node); 1851 else 1852 - pos = list_entry(pos->node.next, struct perf_evsel, node); 1853 goto browse_hists; 1854 case K_UNTAB: 1855 if (pos->node.prev == &evlist->entries) 1856 - pos = list_entry(evlist->entries.prev, struct perf_evsel, node); 1857 else 1858 - pos = list_entry(pos->node.prev, struct perf_evsel, node); 1859 goto browse_hists; 1860 case K_ESC: 1861 if (!ui_browser__dialog_yesno(&menu->b, ··· 1943 1944 single_entry: 1945 if (nr_entries == 1) { 1946 - struct perf_evsel *first = list_entry(evlist->entries.next, 1947 - struct perf_evsel, node); 1948 const char *ev_name = perf_evsel__name(first); 1949 1950 return perf_evsel__hists_browse(first, nr_entries, help,
··· 1847 switch (key) { 1848 case K_TAB: 1849 if (pos->node.next == &evlist->entries) 1850 + pos = perf_evlist__first(evlist); 1851 else 1852 + pos = perf_evsel__next(pos); 1853 goto browse_hists; 1854 case K_UNTAB: 1855 if (pos->node.prev == &evlist->entries) 1856 + pos = perf_evlist__last(evlist); 1857 else 1858 + pos = perf_evsel__prev(pos); 1859 goto browse_hists; 1860 case K_ESC: 1861 if (!ui_browser__dialog_yesno(&menu->b, ··· 1943 1944 single_entry: 1945 if (nr_entries == 1) { 1946 + struct perf_evsel *first = perf_evlist__first(evlist); 1947 const char *ev_name = perf_evsel__name(first); 1948 1949 return perf_evsel__hists_browse(first, nr_entries, help,
+4 -2
tools/perf/util/event.c
··· 209 &event->mmap.start, &event->mmap.len, prot, 210 &event->mmap.pgoff, 211 execname); 212 - 213 - if (n != 5) 214 continue; 215 /* 216 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
··· 209 &event->mmap.start, &event->mmap.len, prot, 210 &event->mmap.pgoff, 211 execname); 212 + /* 213 + * Anon maps don't have the execname. 214 + */ 215 + if (n < 4) 216 continue; 217 /* 218 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
+4 -2
tools/perf/util/evlist.c
··· 819 if (evlist->threads == NULL) 820 return -1; 821 822 - if (target__has_task(target)) 823 evlist->cpus = cpu_map__dummy_new(); 824 else if (!target__has_cpu(target) && !target->uses_mmap) 825 evlist->cpus = cpu_map__dummy_new(); ··· 1150 perf_evsel__name(evsel)); 1151 } 1152 1153 - return printed + fprintf(fp, "\n");; 1154 } 1155 1156 int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused,
··· 819 if (evlist->threads == NULL) 820 return -1; 821 822 + if (target->force_per_cpu) 823 + evlist->cpus = cpu_map__new(target->cpu_list); 824 + else if (target__has_task(target)) 825 evlist->cpus = cpu_map__dummy_new(); 826 else if (!target__has_cpu(target) && !target->uses_mmap) 827 evlist->cpus = cpu_map__dummy_new(); ··· 1148 perf_evsel__name(evsel)); 1149 } 1150 1151 + return printed + fprintf(fp, "\n"); 1152 } 1153 1154 int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused,
+2 -2
tools/perf/util/evsel.c
··· 645 } 646 } 647 648 - if (target__has_cpu(&opts->target)) 649 perf_evsel__set_sample_bit(evsel, CPU); 650 651 if (opts->period) ··· 653 654 if (!perf_missing_features.sample_id_all && 655 (opts->sample_time || !opts->no_inherit || 656 - target__has_cpu(&opts->target))) 657 perf_evsel__set_sample_bit(evsel, TIME); 658 659 if (opts->raw_samples) {
··· 645 } 646 } 647 648 + if (target__has_cpu(&opts->target) || opts->target.force_per_cpu) 649 perf_evsel__set_sample_bit(evsel, CPU); 650 651 if (opts->period) ··· 653 654 if (!perf_missing_features.sample_id_all && 655 (opts->sample_time || !opts->no_inherit || 656 + target__has_cpu(&opts->target) || opts->target.force_per_cpu)) 657 perf_evsel__set_sample_bit(evsel, TIME); 658 659 if (opts->raw_samples) {
+5
tools/perf/util/evsel.h
··· 279 return list_entry(evsel->node.next, struct perf_evsel, node); 280 } 281 282 /** 283 * perf_evsel__is_group_leader - Return whether given evsel is a leader event 284 *
··· 279 return list_entry(evsel->node.next, struct perf_evsel, node); 280 } 281 282 + static inline struct perf_evsel *perf_evsel__prev(struct perf_evsel *evsel) 283 + { 284 + return list_entry(evsel->node.prev, struct perf_evsel, node); 285 + } 286 + 287 /** 288 * perf_evsel__is_group_leader - Return whether given evsel is a leader event 289 *
+1 -1
tools/perf/util/machine.c
··· 1368 1369 return unwind__get_entries(unwind_entry, &callchain_cursor, machine, 1370 thread, evsel->attr.sample_regs_user, 1371 - sample); 1372 1373 } 1374
··· 1368 1369 return unwind__get_entries(unwind_entry, &callchain_cursor, machine, 1370 thread, evsel->attr.sample_regs_user, 1371 + sample, max_stack); 1372 1373 } 1374
+1
tools/perf/util/target.h
··· 12 uid_t uid; 13 bool system_wide; 14 bool uses_mmap; 15 }; 16 17 enum target_errno {
··· 12 uid_t uid; 13 bool system_wide; 14 bool uses_mmap; 15 + bool force_per_cpu; 16 }; 17 18 enum target_errno {
+5 -4
tools/perf/util/unwind.c
··· 559 }; 560 561 static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, 562 - void *arg) 563 { 564 unw_addr_space_t addr_space; 565 unw_cursor_t c; ··· 575 if (ret) 576 display_error(ret); 577 578 - while (!ret && (unw_step(&c) > 0)) { 579 unw_word_t ip; 580 581 unw_get_reg(&c, UNW_REG_IP, &ip); ··· 588 589 int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 590 struct machine *machine, struct thread *thread, 591 - u64 sample_uregs, struct perf_sample *data) 592 { 593 unw_word_t ip; 594 struct unwind_info ui = { ··· 611 if (ret) 612 return -ENOMEM; 613 614 - return get_entries(&ui, cb, arg); 615 }
··· 559 }; 560 561 static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, 562 + void *arg, int max_stack) 563 { 564 unw_addr_space_t addr_space; 565 unw_cursor_t c; ··· 575 if (ret) 576 display_error(ret); 577 578 + while (!ret && (unw_step(&c) > 0) && max_stack--) { 579 unw_word_t ip; 580 581 unw_get_reg(&c, UNW_REG_IP, &ip); ··· 588 589 int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 590 struct machine *machine, struct thread *thread, 591 + u64 sample_uregs, struct perf_sample *data, 592 + int max_stack) 593 { 594 unw_word_t ip; 595 struct unwind_info ui = { ··· 610 if (ret) 611 return -ENOMEM; 612 613 + return get_entries(&ui, cb, arg, max_stack); 614 }
+3 -2
tools/perf/util/unwind.h
··· 18 struct machine *machine, 19 struct thread *thread, 20 u64 sample_uregs, 21 - struct perf_sample *data); 22 int unwind__arch_reg_id(int regnum); 23 #else 24 static inline int ··· 27 struct machine *machine __maybe_unused, 28 struct thread *thread __maybe_unused, 29 u64 sample_uregs __maybe_unused, 30 - struct perf_sample *data __maybe_unused) 31 { 32 return 0; 33 }
··· 18 struct machine *machine, 19 struct thread *thread, 20 u64 sample_uregs, 21 + struct perf_sample *data, int max_stack); 22 int unwind__arch_reg_id(int regnum); 23 #else 24 static inline int ··· 27 struct machine *machine __maybe_unused, 28 struct thread *thread __maybe_unused, 29 u64 sample_uregs __maybe_unused, 30 + struct perf_sample *data __maybe_unused, 31 + int max_stack __maybe_unused) 32 { 33 return 0; 34 }