History

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

Pull perf updates from Ingo Molnar: "Bigger kernel side changes: - Add backwards writing capability to the perf ring-buffer code, which is preparation for future advanced features like robust 'overwrite support' and snapshot mode. (Wang Nan) - Add pause and resume ioctls for the perf ringbuffer (Wang Nan) - x86 Intel cstate code cleanups and reorgnization (Thomas Gleixner) - x86 Intel uncore and CPU PMU driver updates (Kan Liang, Peter Zijlstra) - x86 AUX (Intel PT) related enhancements and updates (Alexander Shishkin) - x86 MSR PMU driver enhancements and updates (Huang Rui) - ... and lots of other changes spread out over 40+ commits. Biggest tooling side changes: - 'perf trace' features and enhancements. (Arnaldo Carvalho de Melo) - BPF tooling updates (Wang Nan) - 'perf sched' updates (Jiri Olsa) - 'perf probe' updates (Masami Hiramatsu) - ... plus 200+ other enhancements, fixes and cleanups to tools/ The merge commits, the shortlog and the changelogs contain a lot more details" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (249 commits) perf/core: Disable the event on a truncated AUX record perf/x86/intel/pt: Generate PMI in the STOP region as well perf buildid-cache: Use lsdir() for looking up buildid caches perf symbols: Use lsdir() for the search in kcore cache directory perf tools: Use SBUILD_ID_SIZE where applicable perf tools: Fix lsdir to set errno correctly perf trace: Move seccomp args beautifiers to tools/perf/trace/beauty/ perf trace: Move flock op beautifier to tools/perf/trace/beauty/ perf build: Add build-test for debug-frame on arm/arm64 perf build: Add build-test for libunwind cross-platforms support perf script: Fix export of callchains with recursion in db-export perf script: Fix callchain addresses in db-export perf script: Fix symbol insertion behavior in db-export perf symbols: Add dso__insert_symbol function perf scripting python: Use Py_FatalError instead of die() perf tools: Remove xrealloc and ALLOC_GROW perf help: Do not use ALLOC_GROW in add_cmd_list perf pmu: Make pmu_formats_string to check return value of strbuf perf header: Make topology checkers to check return value of strbuf perf tools: Make alias handler to check return value of strbuf ...

Linus Torvalds committed 10 years ago

Commit 36db1712 parents 3469d26 3f56e68217 files · +8328 −2731Browse files

Unified · Split

217 files
  1. Documentation/sysctl/kernel.txt +14 −0
  2. arch/arm/kernel/hw_breakpoint.c +2 −2
  3. arch/arm/kernel/perf_callchain.c +1 −1
  4. arch/arm64/kernel/hw_breakpoint.c +2 −2
  5. arch/arm64/kernel/perf_callchain.c +2 −2
  6. arch/metag/kernel/perf_callchain.c +1 −1
  7. arch/mips/kernel/perf_event.c +2 −2
  8. arch/powerpc/perf/callchain.c +2 −2
  9. arch/sparc/kernel/perf_event.c +3 −3
  10. arch/x86/Kconfig +2 −13
  11. arch/x86/events/Kconfig +36 −0
  12. arch/x86/events/Makefile +3 −6
  13. arch/x86/events/amd/uncore.c +2 −0
  14. arch/x86/events/core.c +8 −2
  15. arch/x86/events/intel/Makefile +9 −0
  16. arch/x86/events/intel/bts.c +48 −57
  17. arch/x86/events/intel/core.c +159 −1
  18. arch/x86/events/intel/cstate.c +256 −291
  19. arch/x86/events/intel/ds.c +6 −0
  20. arch/x86/events/intel/lbr.c +30 −1
  21. arch/x86/events/intel/pt.c +250 −68
  22. arch/x86/events/intel/pt.h +68 −0
  23. arch/x86/events/intel/rapl.c +141 −42
  24. arch/x86/events/intel/uncore.c +126 −90
  25. arch/x86/events/msr.c +26 −10
  26. arch/x86/events/perf_event.h +5 −0
  27. arch/x86/include/asm/cpufeatures.h +2 −0
  28. arch/x86/include/asm/msr-index.h +15 −20
  29. arch/x86/kernel/uprobes.c +2 −2
  30. arch/xtensa/kernel/perf_event.c +2 −2
  31. drivers/perf/arm_pmu.c +8 −0
  32. drivers/powercap/intel_rapl.c +69 −0
  33. include/linux/perf_event.h +135 −4
  34. include/uapi/linux/perf_event.h +3 −1
  35. kernel/bpf/stackmap.c +4 −4
  36. kernel/events/callchain.c +33 −2
  37. kernel/events/core.c +857 −54
  38. kernel/events/internal.h +9 −1
  39. kernel/events/ring_buffer.c +87 −31
  40. kernel/sysctl.c +12 −0
  41. kernel/trace/trace_event_perf.c +3 −0
  42. tools/Makefile +2 −1
  43. tools/build/Makefile.feature +7 −1
  44. tools/build/feature/Makefile +23 −0
  45. tools/build/feature/test-bpf.c +1 −2
  46. tools/build/feature/test-libunwind-aarch64.c +26 −0
  47. tools/build/feature/test-libunwind-arm.c +27 −0
  48. tools/build/feature/test-libunwind-debug-frame-aarch64.c +16 −0
  49. tools/build/feature/test-libunwind-debug-frame-arm.c +16 −0
  50. tools/build/feature/test-libunwind-x86.c +27 −0
  51. tools/build/feature/test-libunwind-x86_64.c +27 −0
  52. tools/lib/api/fs/fs.c +13 −0
  53. tools/lib/api/fs/fs.h +2 −0
  54. tools/perf/Documentation/intel-pt.txt +7 −0
  55. tools/perf/Documentation/itrace.txt +8 −0
  56. tools/perf/Documentation/perf-annotate.txt +1 −1
  57. tools/perf/Documentation/perf-diff.txt +1 −1
  58. tools/perf/Documentation/perf-list.txt +106 −1
  59. tools/perf/Documentation/perf-mem.txt +8 −0
  60. tools/perf/Documentation/perf-record.txt +13 −0
  61. tools/perf/Documentation/perf-report.txt +2 −2
  62. tools/perf/Documentation/perf-sched.txt +16 −0
  63. tools/perf/Documentation/perf-script.txt +14 −0
  64. tools/perf/Documentation/perf-top.txt +1 −1
  65. tools/perf/Documentation/perf-trace.txt +32 −0
  66. tools/perf/Makefile.perf +9 −6
  67. tools/perf/arch/powerpc/Makefile +1 −0
  68. tools/perf/arch/powerpc/util/dwarf-regs.c +28 −12
  69. tools/perf/arch/powerpc/util/sym-handling.c +32 −11
  70. tools/perf/arch/x86/Makefile +23 −0
  71. tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +376 −0
  72. tools/perf/arch/x86/entry/syscalls/syscalltbl.sh +39 −0
  73. tools/perf/arch/x86/tests/perf-time-to-tsc.c +1 −1
  74. tools/perf/arch/x86/util/intel-bts.c +5 −0
  75. tools/perf/arch/x86/util/intel-pt.c +5 −0
  76. tools/perf/arch/x86/util/tsc.c +31 −1
  77. tools/perf/arch/x86/util/tsc.h +0 −17
  78. tools/perf/bench/futex-lock-pi.c +1 −1
  79. tools/perf/bench/futex.h +2 −4
  80. tools/perf/bench/mem-functions.c +15 −7
  81. tools/perf/builtin-config.c +32 −7
  82. tools/perf/builtin-diff.c +2 −2
  83. tools/perf/builtin-help.c +10 −8
  84. tools/perf/builtin-inject.c +1 −0
  85. tools/perf/builtin-kmem.c +1 −1
  86. tools/perf/builtin-kvm.c +1 −1
  87. tools/perf/builtin-mem.c +10 −1
  88. tools/perf/builtin-record.c +220 −47
  89. tools/perf/builtin-report.c +10 −9
  90. tools/perf/builtin-sched.c +186 −12
  91. tools/perf/builtin-script.c +35 −21
  92. tools/perf/builtin-stat.c +8 −0
  93. tools/perf/builtin-top.c +19 −20
  94. tools/perf/builtin-trace.c +416 −669
  95. tools/perf/config/Makefile +1 −4
  96. tools/perf/jvmti/jvmti_agent.c +41 −2
  97. tools/perf/perf.c +11 −5
  98. tools/perf/perf.h +0 −1
  99. tools/perf/scripts/python/export-to-postgresql.py +32 −20
  100. tools/perf/tests/Build +2 −0
  101. tools/perf/tests/backward-ring-buffer.c +151 −0
  102. tools/perf/tests/bpf.c +1 −1
  103. tools/perf/tests/builtin-test.c +8 −0
  104. tools/perf/tests/code-reading.c +1 −1
  105. tools/perf/tests/dso-data.c +1 −1
  106. tools/perf/tests/event-times.c +236 −0
  107. tools/perf/tests/event_update.c +1 −1
  108. tools/perf/tests/hists_common.c +1 −1
  109. tools/perf/tests/hists_cumulate.c +2 −2
  110. tools/perf/tests/hists_filter.c +1 −1
  111. tools/perf/tests/hists_link.c +2 −2
  112. tools/perf/tests/hists_output.c +2 −2
  113. tools/perf/tests/keep-tracking.c +1 −1
  114. tools/perf/tests/openat-syscall-tp-fields.c +1 −1
  115. tools/perf/tests/perf-record.c +1 −1
  116. tools/perf/tests/switch-tracking.c +1 −1
  117. tools/perf/tests/tests.h +2 −0
  118. tools/perf/tests/vmlinux-kallsyms.c +10 −1
  119. tools/perf/trace/beauty/eventfd.c +38 −0
  120. tools/perf/trace/beauty/flock.c +31 −0
  121. tools/perf/trace/beauty/futex_op.c +44 −0
  122. tools/perf/trace/beauty/mmap.c +158 −0
  123. tools/perf/trace/beauty/mode_t.c +68 −0
  124. tools/perf/trace/beauty/msg_flags.c +62 −0
  125. tools/perf/trace/beauty/open_flags.c +56 −0
  126. tools/perf/trace/beauty/perf_event_open.c +43 −0
  127. tools/perf/trace/beauty/pid.c +21 −0
  128. tools/perf/trace/beauty/sched_policy.c +44 −0
  129. tools/perf/trace/beauty/seccomp.c +52 −0
  130. tools/perf/trace/beauty/signum.c +53 −0
  131. tools/perf/trace/beauty/socket_type.c +60 −0
  132. tools/perf/trace/beauty/waitid_options.c +26 −0
  133. tools/perf/ui/browsers/hists.c +20 −20
  134. tools/perf/ui/gtk/hists.c +1 −1
  135. tools/perf/ui/hist.c +1 −1
  136. tools/perf/ui/stdio/hist.c +1 −2
  137. tools/perf/util/Build +5 −3
  138. tools/perf/util/annotate.c +2 −2
  139. tools/perf/util/auxtrace.c +7 −0
  140. tools/perf/util/auxtrace.h +2 −0
  141. tools/perf/util/bpf-loader.c +143 −0
  142. tools/perf/util/bpf-loader.h +19 −0
  143. tools/perf/util/build-id.c +7 −29
  144. tools/perf/util/cache.h +0 −19
  145. tools/perf/util/call-path.c +122 −0
  146. tools/perf/util/call-path.h +77 −0
  147. tools/perf/util/callchain.c +6 −3
  148. tools/perf/util/callchain.h +8 −1
  149. tools/perf/util/config.c +191 −31
  150. tools/perf/util/config.h +26 −0
  151. tools/perf/util/cpumap.c +12 −0
  152. tools/perf/util/cpumap.h +2 −0
  153. tools/perf/util/data.c +41 −0
  154. tools/perf/util/data.h +10 −1
  155. tools/perf/util/db-export.c +87 −2
  156. tools/perf/util/db-export.h +3 −0
  157. tools/perf/util/dso.c +2 −2
  158. tools/perf/util/dwarf-aux.c +24 −28
  159. tools/perf/util/event.c +1 −0
  160. tools/perf/util/event.h +9 −0
  161. tools/perf/util/evlist.c +134 −40
  162. tools/perf/util/evlist.h +21 −1
  163. tools/perf/util/evsel.c +38 −101
  164. tools/perf/util/evsel.h +26 −2
  165. tools/perf/util/evsel_fprintf.c +212 −0
  166. tools/perf/util/header.c +21 −12
  167. tools/perf/util/help-unknown-cmd.c +22 −8
  168. tools/perf/util/hist.c +13 −10
  169. tools/perf/util/hist.h +10 −2
  170. tools/perf/util/intel-bts.c +5 −0
  171. tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +1 −1
  172. tools/perf/util/intel-pt.c +20 −2
  173. tools/perf/util/jitdump.c +34 −7
  174. tools/perf/util/jitdump.h +3 −0
  175. tools/perf/util/machine.c +73 −32
  176. tools/perf/util/machine.h +7 −0
  177. tools/perf/util/map.c +15 −1
  178. tools/perf/util/ordered-events.c +9 −0
  179. tools/perf/util/ordered-events.h +1 −0
  180. tools/perf/util/pmu.c +11 −12
  181. tools/perf/util/probe-event.c +215 −191
  182. tools/perf/util/probe-event.h +3 −2
  183. tools/perf/util/probe-file.c +1 −2
  184. tools/perf/util/probe-finder.c +21 −15
  185. tools/perf/util/python-ext-sources +1 −0
  186. tools/perf/util/quote.c +20 −16
  187. tools/perf/util/quote.h +1 −1
  188. tools/perf/util/rb_resort.h +149 −0
  189. tools/perf/util/record.c +3 −2
  190. tools/perf/util/scripting-engines/trace-event-perl.c +118 −8
  191. tools/perf/util/scripting-engines/trace-event-python.c +41 −6
  192. tools/perf/util/session.c +13 −102
  193. tools/perf/util/session.h +1 −11
  194. tools/perf/util/sort.c +14 −21
  195. tools/perf/util/sort.h +0 −7
  196. tools/perf/util/stat.c +3 −1
  197. tools/perf/util/strbuf.c +67 −26
  198. tools/perf/util/strbuf.h +15 −10
  199. tools/perf/util/symbol-elf.c +7 −13
  200. tools/perf/util/symbol.c +37 −71
  201. tools/perf/util/symbol.h +18 −1
  202. tools/perf/util/symbol_fprintf.c +71 −0
  203. tools/perf/util/syscalltbl.c +134 −0
  204. tools/perf/util/syscalltbl.h +20 −0
  205. tools/perf/util/thread-stack.c +1 −138
  206. tools/perf/util/thread-stack.h +10 −21
  207. tools/perf/util/thread.c +20 −1
  208. tools/perf/util/thread.h +8 −0
  209. tools/perf/util/thread_map.c +13 −1
  210. tools/perf/util/thread_map.h +3 −0
  211. tools/perf/util/tool.h +1 −0
  212. tools/perf/util/trigger.h +94 −0
  213. tools/perf/util/tsc.h +20 −1
  214. tools/perf/util/unwind-libunwind.c +9 −16
  215. tools/perf/util/util.c +36 −2
  216. tools/perf/util/util.h +9 −6
  217. tools/perf/util/wrapper.c +0 −29
Documentation/sysctl/kernel.txt+14−0
@@ -60,6 +60,7 @@ show up in /proc/sys/kernel: · 59 unmodified lines
6060 - panic_on_warn
6161 - perf_cpu_time_max_percent
6262 - perf_event_paranoid
63+- perf_event_max_stack
6364 - pid_max
6465 - powersave-nap [ PPC only ]
6566 - printk
@@ -654,6 +655,19 @@ users (without CAP_SYS_ADMIN). The default value is 2. · 588 unmodified lines
654655
655656 ==============================================================
656657
658+perf_event_max_stack:
659+
660+Controls maximum number of stack frames to copy for (attr.sample_type &
661+PERF_SAMPLE_CALLCHAIN) configured events, for instance, when using
662+'perf record -g' or 'perf trace --call-graph fp'.
663+
664+This can only be done when no events are in use that have callchains
665+enabled, otherwise writing to this file will return -EBUSY.
666+
667+The default value is 127.
668+
669+==============================================================
670+
657671 pid_max:
658672
659673 PID allocation wrap value. When the kernel's next PID value
arch/arm/kernel/hw_breakpoint.c+2−2
@@ -631,7 +631,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) · 630 unmodified lines
631631 info->address &= ~alignment_mask;
632632 info->ctrl.len <<= offset;
633633
634− if (!bp->overflow_handler) {
634+ if (is_default_overflow_handler(bp)) {
635635 /*
636636 * Mismatch breakpoints are required for single-stepping
637637 * breakpoints.
@@ -754,7 +754,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, · 116 unmodified lines
754754 * mismatch breakpoint so we can single-step over the
755755 * watchpoint trigger.
756756 */
757− if (!wp->overflow_handler)
757+ if (is_default_overflow_handler(wp))
758758 enable_single_step(wp, instruction_pointer(regs));
759759
760760 unlock:
arch/arm/kernel/perf_callchain.c+1−1
@@ -75,7 +75,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) · 74 unmodified lines
7575
7676 tail = (struct frame_tail __user *)regs->ARM_fp - 1;
7777
78− while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
78+ while ((entry->nr < sysctl_perf_event_max_stack) &&
7979 tail && !((unsigned long)tail & 0x3))
8080 tail = user_backtrace(tail, entry);
8181 }
arch/arm64/kernel/hw_breakpoint.c+2−2
@@ -616,7 +616,7 @@ static int breakpoint_handler(unsigned long unused, unsigned int esr, · 615 unmodified lines
616616 perf_bp_event(bp, regs);
617617
618618 /* Do we need to handle the stepping? */
619− if (!bp->overflow_handler)
619+ if (is_default_overflow_handler(bp))
620620 step = 1;
621621 unlock:
622622 rcu_read_unlock();
@@ -712,7 +712,7 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, · 89 unmodified lines
712712 perf_bp_event(wp, regs);
713713
714714 /* Do we need to handle the stepping? */
715− if (!wp->overflow_handler)
715+ if (is_default_overflow_handler(wp))
716716 step = 1;
717717
718718 unlock:
arch/arm64/kernel/perf_callchain.c+2−2
@@ -122,7 +122,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry, · 121 unmodified lines
122122
123123 tail = (struct frame_tail __user *)regs->regs[29];
124124
125− while (entry->nr < PERF_MAX_STACK_DEPTH &&
125+ while (entry->nr < sysctl_perf_event_max_stack &&
126126 tail && !((unsigned long)tail & 0xf))
127127 tail = user_backtrace(tail, entry);
128128 } else {
@@ -132,7 +132,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry, · 3 unmodified lines
132132
133133 tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
134134
135− while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
135+ while ((entry->nr < sysctl_perf_event_max_stack) &&
136136 tail && !((unsigned long)tail & 0x3))
137137 tail = compat_user_backtrace(tail, entry);
138138 #endif
arch/metag/kernel/perf_callchain.c+1−1
@@ -65,7 +65,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) · 64 unmodified lines
6565
6666 --frame;
6767
68− while ((entry->nr < PERF_MAX_STACK_DEPTH) && frame)
68+ while ((entry->nr < sysctl_perf_event_max_stack) && frame)
6969 frame = user_backtrace(frame, entry);
7070 }
7171
arch/mips/kernel/perf_event.c+2−2
@@ -35,7 +35,7 @@ static void save_raw_perf_callchain(struct perf_callchain_entry *entry, · 34 unmodified lines
3535 addr = *sp++;
3636 if (__kernel_text_address(addr)) {
3737 perf_callchain_store(entry, addr);
38− if (entry->nr >= PERF_MAX_STACK_DEPTH)
38+ if (entry->nr >= sysctl_perf_event_max_stack)
3939 break;
4040 }
4141 }
@@ -59,7 +59,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, · 17 unmodified lines
5959 }
6060 do {
6161 perf_callchain_store(entry, pc);
62− if (entry->nr >= PERF_MAX_STACK_DEPTH)
62+ if (entry->nr >= sysctl_perf_event_max_stack)
6363 break;
6464 pc = unwind_stack(current, &sp, pc, &ra);
6565 } while (pc);
arch/powerpc/perf/callchain.c+2−2
@@ -247,7 +247,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, · 246 unmodified lines
247247 sp = regs->gpr[1];
248248 perf_callchain_store(entry, next_ip);
249249
250− while (entry->nr < PERF_MAX_STACK_DEPTH) {
250+ while (entry->nr < sysctl_perf_event_max_stack) {
251251 fp = (unsigned long __user *) sp;
252252 if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
253253 return;
@@ -453,7 +453,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, · 199 unmodified lines
453453 sp = regs->gpr[1];
454454 perf_callchain_store(entry, next_ip);
455455
456− while (entry->nr < PERF_MAX_STACK_DEPTH) {
456+ while (entry->nr < sysctl_perf_event_max_stack) {
457457 fp = (unsigned int __user *) (unsigned long) sp;
458458 if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
459459 return;
arch/sparc/kernel/perf_event.c+3−3
@@ -1756,7 +1756,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, · 1755 unmodified lines
17561756 }
17571757 }
17581758 #endif
1759− } while (entry->nr < PERF_MAX_STACK_DEPTH);
1759+ } while (entry->nr < sysctl_perf_event_max_stack);
17601760 }
17611761
17621762 static inline int
@@ -1790,7 +1790,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, · 27 unmodified lines
17901790 pc = sf.callers_pc;
17911791 ufp = (unsigned long)sf.fp + STACK_BIAS;
17921792 perf_callchain_store(entry, pc);
1793− } while (entry->nr < PERF_MAX_STACK_DEPTH);
1793+ } while (entry->nr < sysctl_perf_event_max_stack);
17941794 }
17951795
17961796 static void perf_callchain_user_32(struct perf_callchain_entry *entry,
@@ -1822,7 +1822,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, · 25 unmodified lines
18221822 ufp = (unsigned long)sf.fp;
18231823 }
18241824 perf_callchain_store(entry, pc);
1825− } while (entry->nr < PERF_MAX_STACK_DEPTH);
1825+ } while (entry->nr < sysctl_perf_event_max_stack);
18261826 }
18271827
18281828 void
arch/x86/Kconfig+2−13
@@ -164,10 +164,6 @@ config INSTRUCTION_DECODER · 163 unmodified lines
164164 def_bool y
165165 depends on KPROBES || PERF_EVENTS || UPROBES
166166
167−config PERF_EVENTS_INTEL_UNCORE
168− def_bool y
169− depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
170−
171167 config OUTPUT_FORMAT
172168 string
173169 default "elf32-i386" if X86_32
@@ -1046,6 +1042,8 @@ config X86_THERMAL_VECTOR · 872 unmodified lines
10461042 def_bool y
10471043 depends on X86_MCE_INTEL
10481044
1045+source "arch/x86/events/Kconfig"
1046+
10491047 config X86_LEGACY_VM86
10501048 bool "Legacy VM86 support"
10511049 default n
@@ -1210,15 +1208,6 @@ config MICROCODE_OLD_INTERFACE · 158 unmodified lines
12101208 def_bool y
12111209 depends on MICROCODE
12121210
1213−config PERF_EVENTS_AMD_POWER
1214− depends on PERF_EVENTS && CPU_SUP_AMD
1215− tristate "AMD Processor Power Reporting Mechanism"
1216− ---help---
1217− Provide power reporting mechanism support for AMD processors.
1218− Currently, it leverages X86_FEATURE_ACC_POWER
1219− (CPUID Fn8000_0007_EDX[12]) interface to calculate the
1220− average power consumption on Family 15h processors.
1221−
12221211 config X86_MSR
12231212 tristate "/dev/cpu/*/msr - Model-specific register support"
12241213 ---help---
arch/x86/events/Kconfig+36−0
@@ -0,0 +1,36 @@
1+menu "Performance monitoring"
2+
3+config PERF_EVENTS_INTEL_UNCORE
4+ tristate "Intel uncore performance events"
5+ depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
6+ default y
7+ ---help---
8+ Include support for Intel uncore performance events. These are
9+ available on NehalemEX and more modern processors.
10+
11+config PERF_EVENTS_INTEL_RAPL
12+ tristate "Intel rapl performance events"
13+ depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
14+ default y
15+ ---help---
16+ Include support for Intel rapl performance events for power
17+ monitoring on modern processors.
18+
19+config PERF_EVENTS_INTEL_CSTATE
20+ tristate "Intel cstate performance events"
21+ depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
22+ default y
23+ ---help---
24+ Include support for Intel cstate performance events for power
25+ monitoring on modern processors.
26+
27+config PERF_EVENTS_AMD_POWER
28+ depends on PERF_EVENTS && CPU_SUP_AMD
29+ tristate "AMD Processor Power Reporting Mechanism"
30+ ---help---
31+ Provide power reporting mechanism support for AMD processors.
32+ Currently, it leverages X86_FEATURE_ACC_POWER
33+ (CPUID Fn8000_0007_EDX[12]) interface to calculate the
34+ average power consumption on Family 15h processors.
35+
36+endmenu
arch/x86/events/Makefile+3−6
@@ -6,9 +6,6 @@ obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o · 5 unmodified lines
66 ifdef CONFIG_AMD_IOMMU
77 obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o
88 endif
9−obj-$(CONFIG_CPU_SUP_INTEL) += intel/core.o intel/bts.o intel/cqm.o
10−obj-$(CONFIG_CPU_SUP_INTEL) += intel/cstate.o intel/ds.o intel/knc.o
11−obj-$(CONFIG_CPU_SUP_INTEL) += intel/lbr.o intel/p4.o intel/p6.o intel/pt.o
12−obj-$(CONFIG_CPU_SUP_INTEL) += intel/rapl.o msr.o
13−obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore.o intel/uncore_nhmex.o
14−obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore_snb.o intel/uncore_snbep.o
9+
10+obj-$(CONFIG_CPU_SUP_INTEL) += msr.o
11+obj-$(CONFIG_CPU_SUP_INTEL) += intel/
arch/x86/events/amd/uncore.c+2−0
@@ -263,6 +263,7 @@ static const struct attribute_group *amd_uncore_attr_groups[] = { · 262 unmodified lines
263263 };
264264
265265 static struct pmu amd_nb_pmu = {
266+ .task_ctx_nr = perf_invalid_context,
266267 .attr_groups = amd_uncore_attr_groups,
267268 .name = "amd_nb",
268269 .event_init = amd_uncore_event_init,
@@ -274,6 +275,7 @@ static struct pmu amd_nb_pmu = { · 5 unmodified lines
274275 };
275276
276277 static struct pmu amd_l2_pmu = {
278+ .task_ctx_nr = perf_invalid_context,
277279 .attr_groups = amd_uncore_attr_groups,
278280 .name = "amd_l2",
279281 .event_init = amd_uncore_event_init,
arch/x86/events/core.c+8−2
@@ -360,6 +360,9 @@ int x86_add_exclusive(unsigned int what) · 359 unmodified lines
360360 {
361361 int i;
362362
363+ if (x86_pmu.lbr_pt_coexist)
364+ return 0;
365+
363366 if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
364367 mutex_lock(&pmc_reserve_mutex);
365368 for (i = 0; i < ARRAY_SIZE(x86_pmu.lbr_exclusive); i++) {
@@ -380,6 +383,9 @@ fail_unlock: · 14 unmodified lines
380383
381384 void x86_del_exclusive(unsigned int what)
382385 {
386+ if (x86_pmu.lbr_pt_coexist)
387+ return;
388+
383389 atomic_dec(&x86_pmu.lbr_exclusive[what]);
384390 atomic_dec(&active_events);
385391 }
@@ -2277,7 +2283,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) · 1891 unmodified lines
22772283
22782284 fp = compat_ptr(ss_base + regs->bp);
22792285 pagefault_disable();
2280− while (entry->nr < PERF_MAX_STACK_DEPTH) {
2286+ while (entry->nr < sysctl_perf_event_max_stack) {
22812287 unsigned long bytes;
22822288 frame.next_frame = 0;
22832289 frame.return_address = 0;
@@ -2337,7 +2343,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) · 53 unmodified lines
23372343 return;
23382344
23392345 pagefault_disable();
2340− while (entry->nr < PERF_MAX_STACK_DEPTH) {
2346+ while (entry->nr < sysctl_perf_event_max_stack) {
23412347 unsigned long bytes;
23422348 frame.next_frame = NULL;
23432349 frame.return_address = 0;
arch/x86/events/intel/Makefile+9−0
@@ -0,0 +1,9 @@
1+obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o
2+obj-$(CONFIG_CPU_SUP_INTEL) += ds.o knc.o
3+obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o
4+obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += intel-rapl.o
5+intel-rapl-objs := rapl.o
6+obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o
7+intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o
8+obj-$(CONFIG_PERF_EVENTS_INTEL_CSTATE) += intel-cstate.o
9+intel-cstate-objs := cstate.o
arch/x86/events/intel/bts.c+48−57
@@ -171,18 +171,6 @@ static void bts_buffer_pad_out(struct bts_phys *phys, unsigned long head) · 170 unmodified lines
171171 memset(page_address(phys->page) + index, 0, phys->size - index);
172172 }
173173
174−static bool bts_buffer_is_full(struct bts_buffer *buf, struct bts_ctx *bts)
175−{
176− if (buf->snapshot)
177− return false;
178−
179− if (local_read(&buf->data_size) >= bts->handle.size ||
180− bts->handle.size - local_read(&buf->data_size) < BTS_RECORD_SIZE)
181− return true;
182−
183− return false;
184−}
185−
186174 static void bts_update(struct bts_ctx *bts)
187175 {
188176 int cpu = raw_smp_processor_id();
@@ -213,18 +201,15 @@ static void bts_update(struct bts_ctx *bts) · 24 unmodified lines
213201 }
214202 }
215203
204+static int
205+bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle);
206+
216207 static void __bts_event_start(struct perf_event *event)
217208 {
218209 struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
219210 struct bts_buffer *buf = perf_get_aux(&bts->handle);
220211 u64 config = 0;
221212
222− if (!buf || bts_buffer_is_full(buf, bts))
223− return;
224−
225− event->hw.itrace_started = 1;
226− event->hw.state = 0;
227−
228213 if (!buf->snapshot)
229214 config |= ARCH_PERFMON_EVENTSEL_INT;
230215 if (!event->attr.exclude_kernel)
@@ -241,16 +226,41 @@ static void __bts_event_start(struct perf_event *event) · 10 unmodified lines
241226 wmb();
242227
243228 intel_pmu_enable_bts(config);
229+
244230 }
245231
246232 static void bts_event_start(struct perf_event *event, int flags)
247233 {
234+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
248235 struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
236+ struct bts_buffer *buf;
237+
238+ buf = perf_aux_output_begin(&bts->handle, event);
239+ if (!buf)
240+ goto fail_stop;
241+
242+ if (bts_buffer_reset(buf, &bts->handle))
243+ goto fail_end_stop;
244+
245+ bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
246+ bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
247+ bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
248+
249+ event->hw.itrace_started = 1;
250+ event->hw.state = 0;
249251
250252 __bts_event_start(event);
251253
252254 /* PMI handler: this counter is running and likely generating PMIs */
253255 ACCESS_ONCE(bts->started) = 1;
256+
257+ return;
258+
259+fail_end_stop:
260+ perf_aux_output_end(&bts->handle, 0, false);
261+
262+fail_stop:
263+ event->hw.state = PERF_HES_STOPPED;
254264 }
255265
256266 static void __bts_event_stop(struct perf_event *event)
@@ -269,15 +279,32 @@ static void __bts_event_stop(struct perf_event *event) · 12 unmodified lines
269279
270280 static void bts_event_stop(struct perf_event *event, int flags)
271281 {
282+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
272283 struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
284+ struct bts_buffer *buf = perf_get_aux(&bts->handle);
273285
274286 /* PMI handler: don't restart this counter */
275287 ACCESS_ONCE(bts->started) = 0;
276288
277289 __bts_event_stop(event);
278290
279− if (flags & PERF_EF_UPDATE)
291+ if (flags & PERF_EF_UPDATE) {
280292 bts_update(bts);
293+
294+ if (buf) {
295+ if (buf->snapshot)
296+ bts->handle.head =
297+ local_xchg(&buf->data_size,
298+ buf->nr_pages << PAGE_SHIFT);
299+ perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
300+ !!local_xchg(&buf->lost, 0));
301+ }
302+
303+ cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
304+ cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
305+ cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
306+ cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
307+ }
281308 }
282309
283310 void intel_bts_enable_local(void)
@@ -417,34 +444,14 @@ int intel_bts_interrupt(void) · 133 unmodified lines
417444
418445 static void bts_event_del(struct perf_event *event, int mode)
419446 {
420− struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
421− struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
422− struct bts_buffer *buf = perf_get_aux(&bts->handle);
423−
424447 bts_event_stop(event, PERF_EF_UPDATE);
425−
426− if (buf) {
427− if (buf->snapshot)
428− bts->handle.head =
429− local_xchg(&buf->data_size,
430− buf->nr_pages << PAGE_SHIFT);
431− perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
432− !!local_xchg(&buf->lost, 0));
433− }
434−
435− cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
436− cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
437− cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
438− cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
439448 }
440449
441450 static int bts_event_add(struct perf_event *event, int mode)
442451 {
443− struct bts_buffer *buf;
444452 struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
445453 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
446454 struct hw_perf_event *hwc = &event->hw;
447− int ret = -EBUSY;
448455
449456 event->hw.state = PERF_HES_STOPPED;
450457
@@ -454,26 +461,10 @@ static int bts_event_add(struct perf_event *event, int mode) · 3 unmodified lines
454461 if (bts->handle.event)
455462 return -EBUSY;
456463
457− buf = perf_aux_output_begin(&bts->handle, event);
458− if (!buf)
459− return -EINVAL;
460−
461− ret = bts_buffer_reset(buf, &bts->handle);
462− if (ret) {
463− perf_aux_output_end(&bts->handle, 0, false);
464− return ret;
465− }
466−
467− bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
468− bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
469− bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
470−
471464 if (mode & PERF_EF_START) {
472465 bts_event_start(event, 0);
473− if (hwc->state & PERF_HES_STOPPED) {
474− bts_event_del(event, 0);
475− return -EBUSY;
476− }
466+ if (hwc->state & PERF_HES_STOPPED)
467+ return -EINVAL;
477468 }
478469
479470 return 0;
arch/x86/events/intel/core.c+159−1
@@ -1465,6 +1465,140 @@ static __initconst const u64 slm_hw_cache_event_ids · 1464 unmodified lines
14651465 },
14661466 };
14671467
1468+static struct extra_reg intel_glm_extra_regs[] __read_mostly = {
1469+ /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
1470+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x760005ffbfull, RSP_0),
1471+ INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x360005ffbfull, RSP_1),
1472+ EVENT_EXTRA_END
1473+};
1474+
1475+#define GLM_DEMAND_DATA_RD BIT_ULL(0)
1476+#define GLM_DEMAND_RFO BIT_ULL(1)
1477+#define GLM_ANY_RESPONSE BIT_ULL(16)
1478+#define GLM_SNP_NONE_OR_MISS BIT_ULL(33)
1479+#define GLM_DEMAND_READ GLM_DEMAND_DATA_RD
1480+#define GLM_DEMAND_WRITE GLM_DEMAND_RFO
1481+#define GLM_DEMAND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO)
1482+#define GLM_LLC_ACCESS GLM_ANY_RESPONSE
1483+#define GLM_SNP_ANY (GLM_SNP_NONE_OR_MISS|SNB_NO_FWD|SNB_HITM)
1484+#define GLM_LLC_MISS (GLM_SNP_ANY|SNB_NON_DRAM)
1485+
1486+static __initconst const u64 glm_hw_cache_event_ids
1487+ [PERF_COUNT_HW_CACHE_MAX]
1488+ [PERF_COUNT_HW_CACHE_OP_MAX]
1489+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
1490+ [C(L1D)] = {
1491+ [C(OP_READ)] = {
1492+ [C(RESULT_ACCESS)] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
1493+ [C(RESULT_MISS)] = 0x0,
1494+ },
1495+ [C(OP_WRITE)] = {
1496+ [C(RESULT_ACCESS)] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
1497+ [C(RESULT_MISS)] = 0x0,
1498+ },
1499+ [C(OP_PREFETCH)] = {
1500+ [C(RESULT_ACCESS)] = 0x0,
1501+ [C(RESULT_MISS)] = 0x0,
1502+ },
1503+ },
1504+ [C(L1I)] = {
1505+ [C(OP_READ)] = {
1506+ [C(RESULT_ACCESS)] = 0x0380, /* ICACHE.ACCESSES */
1507+ [C(RESULT_MISS)] = 0x0280, /* ICACHE.MISSES */
1508+ },
1509+ [C(OP_WRITE)] = {
1510+ [C(RESULT_ACCESS)] = -1,
1511+ [C(RESULT_MISS)] = -1,
1512+ },
1513+ [C(OP_PREFETCH)] = {
1514+ [C(RESULT_ACCESS)] = 0x0,
1515+ [C(RESULT_MISS)] = 0x0,
1516+ },
1517+ },
1518+ [C(LL)] = {
1519+ [C(OP_READ)] = {
1520+ [C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
1521+ [C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
1522+ },
1523+ [C(OP_WRITE)] = {
1524+ [C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
1525+ [C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
1526+ },
1527+ [C(OP_PREFETCH)] = {
1528+ [C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
1529+ [C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
1530+ },
1531+ },
1532+ [C(DTLB)] = {
1533+ [C(OP_READ)] = {
1534+ [C(RESULT_ACCESS)] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
1535+ [C(RESULT_MISS)] = 0x0,
1536+ },
1537+ [C(OP_WRITE)] = {
1538+ [C(RESULT_ACCESS)] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
1539+ [C(RESULT_MISS)] = 0x0,
1540+ },
1541+ [C(OP_PREFETCH)] = {
1542+ [C(RESULT_ACCESS)] = 0x0,
1543+ [C(RESULT_MISS)] = 0x0,
1544+ },
1545+ },
1546+ [C(ITLB)] = {
1547+ [C(OP_READ)] = {
1548+ [C(RESULT_ACCESS)] = 0x00c0, /* INST_RETIRED.ANY_P */
1549+ [C(RESULT_MISS)] = 0x0481, /* ITLB.MISS */
1550+ },
1551+ [C(OP_WRITE)] = {
1552+ [C(RESULT_ACCESS)] = -1,
1553+ [C(RESULT_MISS)] = -1,
1554+ },
1555+ [C(OP_PREFETCH)] = {
1556+ [C(RESULT_ACCESS)] = -1,
1557+ [C(RESULT_MISS)] = -1,
1558+ },
1559+ },
1560+ [C(BPU)] = {
1561+ [C(OP_READ)] = {
1562+ [C(RESULT_ACCESS)] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
1563+ [C(RESULT_MISS)] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
1564+ },
1565+ [C(OP_WRITE)] = {
1566+ [C(RESULT_ACCESS)] = -1,
1567+ [C(RESULT_MISS)] = -1,
1568+ },
1569+ [C(OP_PREFETCH)] = {
1570+ [C(RESULT_ACCESS)] = -1,
1571+ [C(RESULT_MISS)] = -1,
1572+ },
1573+ },
1574+};
1575+
1576+static __initconst const u64 glm_hw_cache_extra_regs
1577+ [PERF_COUNT_HW_CACHE_MAX]
1578+ [PERF_COUNT_HW_CACHE_OP_MAX]
1579+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
1580+ [C(LL)] = {
1581+ [C(OP_READ)] = {
1582+ [C(RESULT_ACCESS)] = GLM_DEMAND_READ|
1583+ GLM_LLC_ACCESS,
1584+ [C(RESULT_MISS)] = GLM_DEMAND_READ|
1585+ GLM_LLC_MISS,
1586+ },
1587+ [C(OP_WRITE)] = {
1588+ [C(RESULT_ACCESS)] = GLM_DEMAND_WRITE|
1589+ GLM_LLC_ACCESS,
1590+ [C(RESULT_MISS)] = GLM_DEMAND_WRITE|
1591+ GLM_LLC_MISS,
1592+ },
1593+ [C(OP_PREFETCH)] = {
1594+ [C(RESULT_ACCESS)] = GLM_DEMAND_PREFETCH|
1595+ GLM_LLC_ACCESS,
1596+ [C(RESULT_MISS)] = GLM_DEMAND_PREFETCH|
1597+ GLM_LLC_MISS,
1598+ },
1599+ },
1600+};
1601+
14681602 #define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */
14691603 #define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */
14701604 #define KNL_MCDRAM_LOCAL BIT_ULL(21)
@@ -3447,7 +3581,7 @@ __init int intel_pmu_init(void) · 1976 unmodified lines
34473581 memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
34483582 sizeof(hw_cache_extra_regs));
34493583
3450− intel_pmu_lbr_init_atom();
3584+ intel_pmu_lbr_init_slm();
34513585
34523586 x86_pmu.event_constraints = intel_slm_event_constraints;
34533587 x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
@@ -3456,6 +3590,30 @@ __init int intel_pmu_init(void) · 2 unmodified lines
34563590 pr_cont("Silvermont events, ");
34573591 break;
34583592
3593+ case 92: /* 14nm Atom "Goldmont" */
3594+ case 95: /* 14nm Atom "Goldmont Denverton" */
3595+ memcpy(hw_cache_event_ids, glm_hw_cache_event_ids,
3596+ sizeof(hw_cache_event_ids));
3597+ memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs,
3598+ sizeof(hw_cache_extra_regs));
3599+
3600+ intel_pmu_lbr_init_skl();
3601+
3602+ x86_pmu.event_constraints = intel_slm_event_constraints;
3603+ x86_pmu.pebs_constraints = intel_glm_pebs_event_constraints;
3604+ x86_pmu.extra_regs = intel_glm_extra_regs;
3605+ /*
3606+ * It's recommended to use CPU_CLK_UNHALTED.CORE_P + NPEBS
3607+ * for precise cycles.
3608+ * :pp is identical to :ppp
3609+ */
3610+ x86_pmu.pebs_aliases = NULL;
3611+ x86_pmu.pebs_prec_dist = true;
3612+ x86_pmu.lbr_pt_coexist = true;
3613+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
3614+ pr_cont("Goldmont events, ");
3615+ break;
3616+
34593617 case 37: /* 32nm Westmere */
34603618 case 44: /* 32nm Westmere-EP */
34613619 case 47: /* 32nm Westmere-EX */
arch/x86/events/intel/cstate.c+256−291
@@ -91,6 +91,8 @@ · 90 unmodified lines
9191 #include <asm/cpu_device_id.h>
9292 #include "../perf_event.h"
9393
94+MODULE_LICENSE("GPL");
95+
9496 #define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \
9597 static ssize_t __cstate_##_var##_show(struct kobject *kobj, \
9698 struct kobj_attribute *attr, \
@@ -106,22 +108,27 @@ static ssize_t cstate_get_attr_cpumask(struct device *dev, · 9 unmodified lines
106108 struct device_attribute *attr,
107109 char *buf);
108110
111+/* Model -> events mapping */
112+struct cstate_model {
113+ unsigned long core_events;
114+ unsigned long pkg_events;
115+ unsigned long quirks;
116+};
117+
118+/* Quirk flags */
119+#define SLM_PKG_C6_USE_C7_MSR (1UL << 0)
120+
109121 struct perf_cstate_msr {
110122 u64 msr;
111123 struct perf_pmu_events_attr *attr;
112− bool (*test)(int idx);
113124 };
114125
115126
116127 /* cstate_core PMU */
117−
118128 static struct pmu cstate_core_pmu;
119129 static bool has_cstate_core;
120130
121−enum perf_cstate_core_id {
122− /*
123− * cstate_core events
124− */
131+enum perf_cstate_core_events {
125132 PERF_CSTATE_CORE_C1_RES = 0,
126133 PERF_CSTATE_CORE_C3_RES,
127134 PERF_CSTATE_CORE_C6_RES,
@@ -130,69 +137,16 @@ enum perf_cstate_core_id { · 2 unmodified lines
130137 PERF_CSTATE_CORE_EVENT_MAX,
131138 };
132139
133−bool test_core(int idx)
134−{
135− if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
136− boot_cpu_data.x86 != 6)
137− return false;
138−
139− switch (boot_cpu_data.x86_model) {
140− case 30: /* 45nm Nehalem */
141− case 26: /* 45nm Nehalem-EP */
142− case 46: /* 45nm Nehalem-EX */
143−
144− case 37: /* 32nm Westmere */
145− case 44: /* 32nm Westmere-EP */
146− case 47: /* 32nm Westmere-EX */
147− if (idx == PERF_CSTATE_CORE_C3_RES ||
148− idx == PERF_CSTATE_CORE_C6_RES)
149− return true;
150− break;
151− case 42: /* 32nm SandyBridge */
152− case 45: /* 32nm SandyBridge-E/EN/EP */
153−
154− case 58: /* 22nm IvyBridge */
155− case 62: /* 22nm IvyBridge-EP/EX */
156−
157− case 60: /* 22nm Haswell Core */
158− case 63: /* 22nm Haswell Server */
159− case 69: /* 22nm Haswell ULT */
160− case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
161−
162− case 61: /* 14nm Broadwell Core-M */
163− case 86: /* 14nm Broadwell Xeon D */
164− case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
165− case 79: /* 14nm Broadwell Server */
166−
167− case 78: /* 14nm Skylake Mobile */
168− case 94: /* 14nm Skylake Desktop */
169− if (idx == PERF_CSTATE_CORE_C3_RES ||
170− idx == PERF_CSTATE_CORE_C6_RES ||
171− idx == PERF_CSTATE_CORE_C7_RES)
172− return true;
173− break;
174− case 55: /* 22nm Atom "Silvermont" */
175− case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
176− case 76: /* 14nm Atom "Airmont" */
177− if (idx == PERF_CSTATE_CORE_C1_RES ||
178− idx == PERF_CSTATE_CORE_C6_RES)
179− return true;
180− break;
181− }
182−
183− return false;
184−}
185−
186140 PMU_EVENT_ATTR_STRING(c1-residency, evattr_cstate_core_c1, "event=0x00");
187141 PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_core_c3, "event=0x01");
188142 PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_core_c6, "event=0x02");
189143 PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_core_c7, "event=0x03");
190144
191145 static struct perf_cstate_msr core_msr[] = {
192− [PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES, &evattr_cstate_core_c1, test_core, },
193− [PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY, &evattr_cstate_core_c3, test_core, },
194− [PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY, &evattr_cstate_core_c6, test_core, },
195− [PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY, &evattr_cstate_core_c7, test_core, },
146+ [PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES, &evattr_cstate_core_c1 },
147+ [PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY, &evattr_cstate_core_c3 },
148+ [PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY, &evattr_cstate_core_c6 },
149+ [PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY, &evattr_cstate_core_c7 },
196150 };
197151
198152 static struct attribute *core_events_attrs[PERF_CSTATE_CORE_EVENT_MAX + 1] = {
@@ -234,18 +188,11 @@ static const struct attribute_group *core_attr_groups[] = { · 35 unmodified lines
234188 NULL,
235189 };
236190
237−/* cstate_core PMU end */
238−
239−
240191 /* cstate_pkg PMU */
241−
242192 static struct pmu cstate_pkg_pmu;
243193 static bool has_cstate_pkg;
244194
245−enum perf_cstate_pkg_id {
246− /*
247− * cstate_pkg events
248− */
195+enum perf_cstate_pkg_events {
249196 PERF_CSTATE_PKG_C2_RES = 0,
250197 PERF_CSTATE_PKG_C3_RES,
251198 PERF_CSTATE_PKG_C6_RES,
@@ -257,69 +204,6 @@ enum perf_cstate_pkg_id { · 5 unmodified lines
257204 PERF_CSTATE_PKG_EVENT_MAX,
258205 };
259206
260−bool test_pkg(int idx)
261−{
262− if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
263− boot_cpu_data.x86 != 6)
264− return false;
265−
266− switch (boot_cpu_data.x86_model) {
267− case 30: /* 45nm Nehalem */
268− case 26: /* 45nm Nehalem-EP */
269− case 46: /* 45nm Nehalem-EX */
270−
271− case 37: /* 32nm Westmere */
272− case 44: /* 32nm Westmere-EP */
273− case 47: /* 32nm Westmere-EX */
274− if (idx == PERF_CSTATE_CORE_C3_RES ||
275− idx == PERF_CSTATE_CORE_C6_RES ||
276− idx == PERF_CSTATE_CORE_C7_RES)
277− return true;
278− break;
279− case 42: /* 32nm SandyBridge */
280− case 45: /* 32nm SandyBridge-E/EN/EP */
281−
282− case 58: /* 22nm IvyBridge */
283− case 62: /* 22nm IvyBridge-EP/EX */
284−
285− case 60: /* 22nm Haswell Core */
286− case 63: /* 22nm Haswell Server */
287− case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
288−
289− case 61: /* 14nm Broadwell Core-M */
290− case 86: /* 14nm Broadwell Xeon D */
291− case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
292− case 79: /* 14nm Broadwell Server */
293−
294− case 78: /* 14nm Skylake Mobile */
295− case 94: /* 14nm Skylake Desktop */
296− if (idx == PERF_CSTATE_PKG_C2_RES ||
297− idx == PERF_CSTATE_PKG_C3_RES ||
298− idx == PERF_CSTATE_PKG_C6_RES ||
299− idx == PERF_CSTATE_PKG_C7_RES)
300− return true;
301− break;
302− case 55: /* 22nm Atom "Silvermont" */
303− case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
304− case 76: /* 14nm Atom "Airmont" */
305− if (idx == PERF_CSTATE_CORE_C6_RES)
306− return true;
307− break;
308− case 69: /* 22nm Haswell ULT */
309− if (idx == PERF_CSTATE_PKG_C2_RES ||
310− idx == PERF_CSTATE_PKG_C3_RES ||
311− idx == PERF_CSTATE_PKG_C6_RES ||
312− idx == PERF_CSTATE_PKG_C7_RES ||
313− idx == PERF_CSTATE_PKG_C8_RES ||
314− idx == PERF_CSTATE_PKG_C9_RES ||
315− idx == PERF_CSTATE_PKG_C10_RES)
316− return true;
317− break;
318− }
319−
320− return false;
321−}
322−
323207 PMU_EVENT_ATTR_STRING(c2-residency, evattr_cstate_pkg_c2, "event=0x00");
324208 PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_pkg_c3, "event=0x01");
325209 PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_pkg_c6, "event=0x02");
@@ -329,13 +213,13 @@ PMU_EVENT_ATTR_STRING(c9-residency, evattr_cstate_pkg_c9, "event=0x05"); · 3 unmodified lines
329213 PMU_EVENT_ATTR_STRING(c10-residency, evattr_cstate_pkg_c10, "event=0x06");
330214
331215 static struct perf_cstate_msr pkg_msr[] = {
332− [PERF_CSTATE_PKG_C2_RES] = { MSR_PKG_C2_RESIDENCY, &evattr_cstate_pkg_c2, test_pkg, },
333− [PERF_CSTATE_PKG_C3_RES] = { MSR_PKG_C3_RESIDENCY, &evattr_cstate_pkg_c3, test_pkg, },
334− [PERF_CSTATE_PKG_C6_RES] = { MSR_PKG_C6_RESIDENCY, &evattr_cstate_pkg_c6, test_pkg, },
335− [PERF_CSTATE_PKG_C7_RES] = { MSR_PKG_C7_RESIDENCY, &evattr_cstate_pkg_c7, test_pkg, },
336− [PERF_CSTATE_PKG_C8_RES] = { MSR_PKG_C8_RESIDENCY, &evattr_cstate_pkg_c8, test_pkg, },
337− [PERF_CSTATE_PKG_C9_RES] = { MSR_PKG_C9_RESIDENCY, &evattr_cstate_pkg_c9, test_pkg, },
338− [PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY, &evattr_cstate_pkg_c10, test_pkg, },
216+ [PERF_CSTATE_PKG_C2_RES] = { MSR_PKG_C2_RESIDENCY, &evattr_cstate_pkg_c2 },
217+ [PERF_CSTATE_PKG_C3_RES] = { MSR_PKG_C3_RESIDENCY, &evattr_cstate_pkg_c3 },
218+ [PERF_CSTATE_PKG_C6_RES] = { MSR_PKG_C6_RESIDENCY, &evattr_cstate_pkg_c6 },
219+ [PERF_CSTATE_PKG_C7_RES] = { MSR_PKG_C7_RESIDENCY, &evattr_cstate_pkg_c7 },
220+ [PERF_CSTATE_PKG_C8_RES] = { MSR_PKG_C8_RESIDENCY, &evattr_cstate_pkg_c8 },
221+ [PERF_CSTATE_PKG_C9_RES] = { MSR_PKG_C9_RESIDENCY, &evattr_cstate_pkg_c9 },
222+ [PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY, &evattr_cstate_pkg_c10 },
339223 };
340224
341225 static struct attribute *pkg_events_attrs[PERF_CSTATE_PKG_EVENT_MAX + 1] = {
@@ -366,8 +250,6 @@ static const struct attribute_group *pkg_attr_groups[] = { · 24 unmodified lines
366250 NULL,
367251 };
368252
369−/* cstate_pkg PMU end*/
370−
371253 static ssize_t cstate_get_attr_cpumask(struct device *dev,
372254 struct device_attribute *attr,
373255 char *buf)
@@ -385,7 +267,7 @@ static ssize_t cstate_get_attr_cpumask(struct device *dev, · 11 unmodified lines
385267 static int cstate_pmu_event_init(struct perf_event *event)
386268 {
387269 u64 cfg = event->attr.config;
388− int ret = 0;
270+ int cpu;
389271
390272 if (event->attr.type != event->pmu->type)
391273 return -ENOENT;
@@ -400,26 +282,36 @@ static int cstate_pmu_event_init(struct perf_event *event) · 8 unmodified lines
400282 event->attr.sample_period) /* no sampling */
401283 return -EINVAL;
402284
285+ if (event->cpu < 0)
286+ return -EINVAL;
287+
403288 if (event->pmu == &cstate_core_pmu) {
404289 if (cfg >= PERF_CSTATE_CORE_EVENT_MAX)
405290 return -EINVAL;
406291 if (!core_msr[cfg].attr)
407292 return -EINVAL;
408293 event->hw.event_base = core_msr[cfg].msr;
294+ cpu = cpumask_any_and(&cstate_core_cpu_mask,
295+ topology_sibling_cpumask(event->cpu));
409296 } else if (event->pmu == &cstate_pkg_pmu) {
410297 if (cfg >= PERF_CSTATE_PKG_EVENT_MAX)
411298 return -EINVAL;
412299 if (!pkg_msr[cfg].attr)
413300 return -EINVAL;
414301 event->hw.event_base = pkg_msr[cfg].msr;
415− } else
302+ cpu = cpumask_any_and(&cstate_pkg_cpu_mask,
303+ topology_core_cpumask(event->cpu));
304+ } else {
416305 return -ENOENT;
306+ }
307+
308+ if (cpu >= nr_cpu_ids)
309+ return -ENODEV;
417310
418− /* must be done before validate_group */
311+ event->cpu = cpu;
419312 event->hw.config = cfg;
420313 event->hw.idx = -1;
421−
422− return ret;
314+ return 0;
423315 }
424316
425317 static inline u64 cstate_pmu_read_counter(struct perf_event *event)
@@ -469,172 +361,91 @@ static int cstate_pmu_event_add(struct perf_event *event, int mode) · 43 unmodified lines
469361 return 0;
470362 }
471363
364+/*
365+ * Check if exiting cpu is the designated reader. If so migrate the
366+ * events when there is a valid target available
367+ */
472368 static void cstate_cpu_exit(int cpu)
473369 {
474− int i, id, target;
370+ unsigned int target;
475371
476− /* cpu exit for cstate core */
477− if (has_cstate_core) {
478− id = topology_core_id(cpu);
479− target = -1;
480−
481− for_each_online_cpu(i) {
482− if (i == cpu)
483− continue;
484− if (id == topology_core_id(i)) {
485− target = i;
486− break;
487− }
488− }
489− if (cpumask_test_and_clear_cpu(cpu, &cstate_core_cpu_mask) && target >= 0)
372+ if (has_cstate_core &&
373+ cpumask_test_and_clear_cpu(cpu, &cstate_core_cpu_mask)) {
374+
375+ target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
376+ /* Migrate events if there is a valid target */
377+ if (target < nr_cpu_ids) {
490378 cpumask_set_cpu(target, &cstate_core_cpu_mask);
491− WARN_ON(cpumask_empty(&cstate_core_cpu_mask));
492− if (target >= 0)
493379 perf_pmu_migrate_context(&cstate_core_pmu, cpu, target);
380+ }
494381 }
495382
496− /* cpu exit for cstate pkg */
497− if (has_cstate_pkg) {
498− id = topology_physical_package_id(cpu);
499− target = -1;
500−
501− for_each_online_cpu(i) {
502− if (i == cpu)
503− continue;
504− if (id == topology_physical_package_id(i)) {
505− target = i;
506− break;
507− }
508− }
509− if (cpumask_test_and_clear_cpu(cpu, &cstate_pkg_cpu_mask) && target >= 0)
383+ if (has_cstate_pkg &&
384+ cpumask_test_and_clear_cpu(cpu, &cstate_pkg_cpu_mask)) {
385+
386+ target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
387+ /* Migrate events if there is a valid target */
388+ if (target < nr_cpu_ids) {
510389 cpumask_set_cpu(target, &cstate_pkg_cpu_mask);
511− WARN_ON(cpumask_empty(&cstate_pkg_cpu_mask));
512− if (target >= 0)
513390 perf_pmu_migrate_context(&cstate_pkg_pmu, cpu, target);
391+ }
514392 }
515393 }
516394
517395 static void cstate_cpu_init(int cpu)
518396 {
519− int i, id;
397+ unsigned int target;
520398
521− /* cpu init for cstate core */
522− if (has_cstate_core) {
523− id = topology_core_id(cpu);
524− for_each_cpu(i, &cstate_core_cpu_mask) {
525− if (id == topology_core_id(i))
526− break;
527− }
528− if (i >= nr_cpu_ids)
529− cpumask_set_cpu(cpu, &cstate_core_cpu_mask);
530− }
399+ /*
400+ * If this is the first online thread of that core, set it in
401+ * the core cpu mask as the designated reader.
402+ */
403+ target = cpumask_any_and(&cstate_core_cpu_mask,
404+ topology_sibling_cpumask(cpu));
531405
532− /* cpu init for cstate pkg */
533− if (has_cstate_pkg) {
534− id = topology_physical_package_id(cpu);
535− for_each_cpu(i, &cstate_pkg_cpu_mask) {
536− if (id == topology_physical_package_id(i))
537− break;
538− }
539− if (i >= nr_cpu_ids)
540− cpumask_set_cpu(cpu, &cstate_pkg_cpu_mask);
541− }
406+ if (has_cstate_core && target >= nr_cpu_ids)
407+ cpumask_set_cpu(cpu, &cstate_core_cpu_mask);
408+
409+ /*
410+ * If this is the first online thread of that package, set it
411+ * in the package cpu mask as the designated reader.
412+ */
413+ target = cpumask_any_and(&cstate_pkg_cpu_mask,
414+ topology_core_cpumask(cpu));
415+ if (has_cstate_pkg && target >= nr_cpu_ids)
416+ cpumask_set_cpu(cpu, &cstate_pkg_cpu_mask);
542417 }
543418
544419 static int cstate_cpu_notifier(struct notifier_block *self,
545− unsigned long action, void *hcpu)
420+ unsigned long action, void *hcpu)
546421 {
547422 unsigned int cpu = (long)hcpu;
548423
549424 switch (action & ~CPU_TASKS_FROZEN) {
550− case CPU_UP_PREPARE:
551− break;
552425 case CPU_STARTING:
553426 cstate_cpu_init(cpu);
554427 break;
555− case CPU_UP_CANCELED:
556− case CPU_DYING:
557− break;
558− case CPU_ONLINE:
559− case CPU_DEAD:
560− break;
561428 case CPU_DOWN_PREPARE:
562429 cstate_cpu_exit(cpu);
563430 break;
564431 default:
565432 break;
566433 }
567−
568434 return NOTIFY_OK;
569435 }
570436
571−/*
572− * Probe the cstate events and insert the available one into sysfs attrs
573− * Return false if there is no available events.
574− */
575−static bool cstate_probe_msr(struct perf_cstate_msr *msr,
576− struct attribute **events_attrs,
577− int max_event_nr)
578−{
579− int i, j = 0;
580− u64 val;
581−
582− /* Probe the cstate events. */
583− for (i = 0; i < max_event_nr; i++) {
584− if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
585− msr[i].attr = NULL;
586− }
587−
588− /* List remaining events in the sysfs attrs. */
589− for (i = 0; i < max_event_nr; i++) {
590− if (msr[i].attr)
591− events_attrs[j++] = &msr[i].attr->attr.attr;
592− }
593− events_attrs[j] = NULL;
594−
595− return (j > 0) ? true : false;
596−}
597−
598−static int __init cstate_init(void)
599−{
600− /* SLM has different MSR for PKG C6 */
601− switch (boot_cpu_data.x86_model) {
602− case 55:
603− case 76:
604− case 77:
605− pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY;
606− }
607−
608− if (cstate_probe_msr(core_msr, core_events_attrs, PERF_CSTATE_CORE_EVENT_MAX))
609− has_cstate_core = true;
610−
611− if (cstate_probe_msr(pkg_msr, pkg_events_attrs, PERF_CSTATE_PKG_EVENT_MAX))
612− has_cstate_pkg = true;
613−
614− return (has_cstate_core || has_cstate_pkg) ? 0 : -ENODEV;
615−}
616−
617−static void __init cstate_cpumask_init(void)
618−{
619− int cpu;
620−
621− cpu_notifier_register_begin();
622−
623− for_each_online_cpu(cpu)
624− cstate_cpu_init(cpu);
625−
626− __perf_cpu_notifier(cstate_cpu_notifier);
627−
628− cpu_notifier_register_done();
629−}
437+static struct notifier_block cstate_cpu_nb = {
438+ .notifier_call = cstate_cpu_notifier,
439+ .priority = CPU_PRI_PERF + 1,
440+};
630441
631442 static struct pmu cstate_core_pmu = {
632443 .attr_groups = core_attr_groups,
633444 .name = "cstate_core",
634445 .task_ctx_nr = perf_invalid_context,
635446 .event_init = cstate_pmu_event_init,
636− .add = cstate_pmu_event_add, /* must have */
637− .del = cstate_pmu_event_del, /* must have */
447+ .add = cstate_pmu_event_add,
448+ .del = cstate_pmu_event_del,
638449 .start = cstate_pmu_event_start,
639450 .stop = cstate_pmu_event_stop,
640451 .read = cstate_pmu_event_update,
@@ -646,49 +457,203 @@ static struct pmu cstate_pkg_pmu = { · 5 unmodified lines
646457 .name = "cstate_pkg",
647458 .task_ctx_nr = perf_invalid_context,
648459 .event_init = cstate_pmu_event_init,
649− .add = cstate_pmu_event_add, /* must have */
650− .del = cstate_pmu_event_del, /* must have */
460+ .add = cstate_pmu_event_add,
461+ .del = cstate_pmu_event_del,
651462 .start = cstate_pmu_event_start,
652463 .stop = cstate_pmu_event_stop,
653464 .read = cstate_pmu_event_update,
654465 .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
655466 };
656467
657−static void __init cstate_pmus_register(void)
468+static const struct cstate_model nhm_cstates __initconst = {
469+ .core_events = BIT(PERF_CSTATE_CORE_C3_RES) |
470+ BIT(PERF_CSTATE_CORE_C6_RES),
471+
472+ .pkg_events = BIT(PERF_CSTATE_PKG_C3_RES) |
473+ BIT(PERF_CSTATE_PKG_C6_RES) |
474+ BIT(PERF_CSTATE_PKG_C7_RES),
475+};
476+
477+static const struct cstate_model snb_cstates __initconst = {
478+ .core_events = BIT(PERF_CSTATE_CORE_C3_RES) |
479+ BIT(PERF_CSTATE_CORE_C6_RES) |
480+ BIT(PERF_CSTATE_CORE_C7_RES),
481+
482+ .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
483+ BIT(PERF_CSTATE_PKG_C3_RES) |
484+ BIT(PERF_CSTATE_PKG_C6_RES) |
485+ BIT(PERF_CSTATE_PKG_C7_RES),
486+};
487+
488+static const struct cstate_model hswult_cstates __initconst = {
489+ .core_events = BIT(PERF_CSTATE_CORE_C3_RES) |
490+ BIT(PERF_CSTATE_CORE_C6_RES) |
491+ BIT(PERF_CSTATE_CORE_C7_RES),
492+
493+ .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
494+ BIT(PERF_CSTATE_PKG_C3_RES) |
495+ BIT(PERF_CSTATE_PKG_C6_RES) |
496+ BIT(PERF_CSTATE_PKG_C7_RES) |
497+ BIT(PERF_CSTATE_PKG_C8_RES) |
498+ BIT(PERF_CSTATE_PKG_C9_RES) |
499+ BIT(PERF_CSTATE_PKG_C10_RES),
500+};
501+
502+static const struct cstate_model slm_cstates __initconst = {
503+ .core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
504+ BIT(PERF_CSTATE_CORE_C6_RES),
505+
506+ .pkg_events = BIT(PERF_CSTATE_PKG_C6_RES),
507+ .quirks = SLM_PKG_C6_USE_C7_MSR,
508+};
509+
510+#define X86_CSTATES_MODEL(model, states) \
511+ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long) &(states) }
512+
513+static const struct x86_cpu_id intel_cstates_match[] __initconst = {
514+ X86_CSTATES_MODEL(30, nhm_cstates), /* 45nm Nehalem */
515+ X86_CSTATES_MODEL(26, nhm_cstates), /* 45nm Nehalem-EP */
516+ X86_CSTATES_MODEL(46, nhm_cstates), /* 45nm Nehalem-EX */
517+
518+ X86_CSTATES_MODEL(37, nhm_cstates), /* 32nm Westmere */
519+ X86_CSTATES_MODEL(44, nhm_cstates), /* 32nm Westmere-EP */
520+ X86_CSTATES_MODEL(47, nhm_cstates), /* 32nm Westmere-EX */
521+
522+ X86_CSTATES_MODEL(42, snb_cstates), /* 32nm SandyBridge */
523+ X86_CSTATES_MODEL(45, snb_cstates), /* 32nm SandyBridge-E/EN/EP */
524+
525+ X86_CSTATES_MODEL(58, snb_cstates), /* 22nm IvyBridge */
526+ X86_CSTATES_MODEL(62, snb_cstates), /* 22nm IvyBridge-EP/EX */
527+
528+ X86_CSTATES_MODEL(60, snb_cstates), /* 22nm Haswell Core */
529+ X86_CSTATES_MODEL(63, snb_cstates), /* 22nm Haswell Server */
530+ X86_CSTATES_MODEL(70, snb_cstates), /* 22nm Haswell + GT3e */
531+
532+ X86_CSTATES_MODEL(69, hswult_cstates), /* 22nm Haswell ULT */
533+
534+ X86_CSTATES_MODEL(55, slm_cstates), /* 22nm Atom Silvermont */
535+ X86_CSTATES_MODEL(77, slm_cstates), /* 22nm Atom Avoton/Rangely */
536+ X86_CSTATES_MODEL(76, slm_cstates), /* 22nm Atom Airmont */
537+
538+ X86_CSTATES_MODEL(61, snb_cstates), /* 14nm Broadwell Core-M */
539+ X86_CSTATES_MODEL(86, snb_cstates), /* 14nm Broadwell Xeon D */
540+ X86_CSTATES_MODEL(71, snb_cstates), /* 14nm Broadwell + GT3e */
541+ X86_CSTATES_MODEL(79, snb_cstates), /* 14nm Broadwell Server */
542+
543+ X86_CSTATES_MODEL(78, snb_cstates), /* 14nm Skylake Mobile */
544+ X86_CSTATES_MODEL(94, snb_cstates), /* 14nm Skylake Desktop */
545+ { },
546+};
547+MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
548+
549+/*
550+ * Probe the cstate events and insert the available one into sysfs attrs
551+ * Return false if there are no available events.
552+ */
553+static bool __init cstate_probe_msr(const unsigned long evmsk, int max,
554+ struct perf_cstate_msr *msr,
555+ struct attribute **attrs)
658556 {
659− int err;
557+ bool found = false;
558+ unsigned int bit;
559+ u64 val;
560+
561+ for (bit = 0; bit < max; bit++) {
562+ if (test_bit(bit, &evmsk) && !rdmsrl_safe(msr[bit].msr, &val)) {
563+ *attrs++ = &msr[bit].attr->attr.attr;
564+ found = true;
565+ } else {
566+ msr[bit].attr = NULL;
567+ }
568+ }
569+ *attrs = NULL;
570+
571+ return found;
572+}
573+
574+static int __init cstate_probe(const struct cstate_model *cm)
575+{
576+ /* SLM has different MSR for PKG C6 */
577+ if (cm->quirks & SLM_PKG_C6_USE_C7_MSR)
578+ pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY;
579+
580+ has_cstate_core = cstate_probe_msr(cm->core_events,
581+ PERF_CSTATE_CORE_EVENT_MAX,
582+ core_msr, core_events_attrs);
583+
584+ has_cstate_pkg = cstate_probe_msr(cm->pkg_events,
585+ PERF_CSTATE_PKG_EVENT_MAX,
586+ pkg_msr, pkg_events_attrs);
587+
588+ return (has_cstate_core || has_cstate_pkg) ? 0 : -ENODEV;
589+}
590+
591+static inline void cstate_cleanup(void)
592+{
593+ if (has_cstate_core)
594+ perf_pmu_unregister(&cstate_core_pmu);
595+
596+ if (has_cstate_pkg)
597+ perf_pmu_unregister(&cstate_pkg_pmu);
598+}
599+
600+static int __init cstate_init(void)
601+{
602+ int cpu, err;
603+
604+ cpu_notifier_register_begin();
605+ for_each_online_cpu(cpu)
606+ cstate_cpu_init(cpu);
660607
661608 if (has_cstate_core) {
662609 err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1);
663− if (WARN_ON(err))
664− pr_info("Failed to register PMU %s error %d\n",
665− cstate_core_pmu.name, err);
610+ if (err) {
611+ has_cstate_core = false;
612+ pr_info("Failed to register cstate core pmu\n");
613+ goto out;
614+ }
666615 }
667616
668617 if (has_cstate_pkg) {
669618 err = perf_pmu_register(&cstate_pkg_pmu, cstate_pkg_pmu.name, -1);
670− if (WARN_ON(err))
671− pr_info("Failed to register PMU %s error %d\n",
672− cstate_pkg_pmu.name, err);
619+ if (err) {
620+ has_cstate_pkg = false;
621+ pr_info("Failed to register cstate pkg pmu\n");
622+ cstate_cleanup();
623+ goto out;
624+ }
673625 }
626+ __register_cpu_notifier(&cstate_cpu_nb);
627+out:
628+ cpu_notifier_register_done();
629+ return err;
674630 }
675631
676632 static int __init cstate_pmu_init(void)
677633 {
634+ const struct x86_cpu_id *id;
678635 int err;
679636
680− if (cpu_has_hypervisor)
637+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
638+ return -ENODEV;
639+
640+ id = x86_match_cpu(intel_cstates_match);
641+ if (!id)
681642 return -ENODEV;
682643
683− err = cstate_init();
644+ err = cstate_probe((const struct cstate_model *) id->driver_data);
684645 if (err)
685646 return err;
686647
687− cstate_cpumask_init();
688−
689− cstate_pmus_register();
690−
691− return 0;
648+ return cstate_init();
692649 }
650+module_init(cstate_pmu_init);
693651
694−device_initcall(cstate_pmu_init);
652+static void __exit cstate_pmu_exit(void)
653+{
654+ cpu_notifier_register_begin();
655+ __unregister_cpu_notifier(&cstate_cpu_nb);
656+ cstate_cleanup();
657+ cpu_notifier_register_done();
658+}
659+module_exit(cstate_pmu_exit);
arch/x86/events/intel/ds.c+6−0
@@ -645,6 +645,12 @@ struct event_constraint intel_slm_pebs_event_constraints[] = { · 644 unmodified lines
645645 EVENT_CONSTRAINT_END
646646 };
647647
648+struct event_constraint intel_glm_pebs_event_constraints[] = {
649+ /* Allow all events as PEBS with no flags */
650+ INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
651+ EVENT_CONSTRAINT_END
652+};
653+
648654 struct event_constraint intel_nehalem_pebs_event_constraints[] = {
649655 INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
650656 INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
arch/x86/events/intel/lbr.c+30−1
@@ -14,7 +14,8 @@ enum { · 13 unmodified lines
1414 LBR_FORMAT_EIP_FLAGS = 0x03,
1515 LBR_FORMAT_EIP_FLAGS2 = 0x04,
1616 LBR_FORMAT_INFO = 0x05,
17− LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_INFO,
17+ LBR_FORMAT_TIME = 0x06,
18+ LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_TIME,
1819 };
1920
2021 static enum {
@@ -464,6 +465,16 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) · 443 unmodified lines
464465 abort = !!(info & LBR_INFO_ABORT);
465466 cycles = (info & LBR_INFO_CYCLES);
466467 }
468+
469+ if (lbr_format == LBR_FORMAT_TIME) {
470+ mis = !!(from & LBR_FROM_FLAG_MISPRED);
471+ pred = !mis;
472+ skip = 1;
473+ cycles = ((to >> 48) & LBR_INFO_CYCLES);
474+
475+ to = (u64)((((s64)to) << 16) >> 16);
476+ }
477+
467478 if (lbr_flags & LBR_EIP_FLAGS) {
468479 mis = !!(from & LBR_FROM_FLAG_MISPRED);
469480 pred = !mis;
@@ -1049,6 +1060,24 @@ void __init intel_pmu_lbr_init_atom(void) · 579 unmodified lines
10491060 pr_cont("8-deep LBR, ");
10501061 }
10511062
1063+/* slm */
1064+void __init intel_pmu_lbr_init_slm(void)
1065+{
1066+ x86_pmu.lbr_nr = 8;
1067+ x86_pmu.lbr_tos = MSR_LBR_TOS;
1068+ x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
1069+ x86_pmu.lbr_to = MSR_LBR_CORE_TO;
1070+
1071+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
1072+ x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
1073+
1074+ /*
1075+ * SW branch filter usage:
1076+ * - compensate for lack of HW filter
1077+ */
1078+ pr_cont("8-deep LBR, ");
1079+}
1080+
10521081 /* Knights Landing */
10531082 void intel_pmu_lbr_init_knl(void)
10541083 {
arch/x86/events/intel/pt.c+250−68
@@ -67,11 +67,13 @@ static struct pt_cap_desc { · 66 unmodified lines
6767 PT_CAP(max_subleaf, 0, CR_EAX, 0xffffffff),
6868 PT_CAP(cr3_filtering, 0, CR_EBX, BIT(0)),
6969 PT_CAP(psb_cyc, 0, CR_EBX, BIT(1)),
70+ PT_CAP(ip_filtering, 0, CR_EBX, BIT(2)),
7071 PT_CAP(mtc, 0, CR_EBX, BIT(3)),
7172 PT_CAP(topa_output, 0, CR_ECX, BIT(0)),
7273 PT_CAP(topa_multiple_entries, 0, CR_ECX, BIT(1)),
7374 PT_CAP(single_range_output, 0, CR_ECX, BIT(2)),
7475 PT_CAP(payloads_lip, 0, CR_ECX, BIT(31)),
76+ PT_CAP(num_address_ranges, 1, CR_EAX, 0x3),
7577 PT_CAP(mtc_periods, 1, CR_EAX, 0xffff0000),
7678 PT_CAP(cycle_thresholds, 1, CR_EBX, 0xffff),
7779 PT_CAP(psb_periods, 1, CR_EBX, 0xffff0000),
@@ -125,9 +127,46 @@ static struct attribute_group pt_format_group = { · 47 unmodified lines
125127 .attrs = pt_formats_attr,
126128 };
127129
130+static ssize_t
131+pt_timing_attr_show(struct device *dev, struct device_attribute *attr,
132+ char *page)
133+{
134+ struct perf_pmu_events_attr *pmu_attr =
135+ container_of(attr, struct perf_pmu_events_attr, attr);
136+
137+ switch (pmu_attr->id) {
138+ case 0:
139+ return sprintf(page, "%lu\n", pt_pmu.max_nonturbo_ratio);
140+ case 1:
141+ return sprintf(page, "%u:%u\n",
142+ pt_pmu.tsc_art_num,
143+ pt_pmu.tsc_art_den);
144+ default:
145+ break;
146+ }
147+
148+ return -EINVAL;
149+}
150+
151+PMU_EVENT_ATTR(max_nonturbo_ratio, timing_attr_max_nonturbo_ratio, 0,
152+ pt_timing_attr_show);
153+PMU_EVENT_ATTR(tsc_art_ratio, timing_attr_tsc_art_ratio, 1,
154+ pt_timing_attr_show);
155+
156+static struct attribute *pt_timing_attr[] = {
157+ &timing_attr_max_nonturbo_ratio.attr.attr,
158+ &timing_attr_tsc_art_ratio.attr.attr,
159+ NULL,
160+};
161+
162+static struct attribute_group pt_timing_group = {
163+ .attrs = pt_timing_attr,
164+};
165+
128166 static const struct attribute_group *pt_attr_groups[] = {
129167 &pt_cap_group,
130168 &pt_format_group,
169+ &pt_timing_group,
131170 NULL,
132171 };
133172
@@ -140,6 +179,23 @@ static int __init pt_pmu_hw_init(void) · 6 unmodified lines
140179 int ret;
141180 long i;
142181
182+ rdmsrl(MSR_PLATFORM_INFO, reg);
183+ pt_pmu.max_nonturbo_ratio = (reg & 0xff00) >> 8;
184+
185+ /*
186+ * if available, read in TSC to core crystal clock ratio,
187+ * otherwise, zero for numerator stands for "not enumerated"
188+ * as per SDM
189+ */
190+ if (boot_cpu_data.cpuid_level >= CPUID_TSC_LEAF) {
191+ u32 eax, ebx, ecx, edx;
192+
193+ cpuid(CPUID_TSC_LEAF, &eax, &ebx, &ecx, &edx);
194+
195+ pt_pmu.tsc_art_num = ebx;
196+ pt_pmu.tsc_art_den = eax;
197+ }
198+
143199 if (boot_cpu_has(X86_FEATURE_VMX)) {
144200 /*
145201 * Intel SDM, 36.5 "Tracing post-VMXON" says that
@@ -263,6 +319,75 @@ static bool pt_event_valid(struct perf_event *event) · 117 unmodified lines
263319 * These all are cpu affine and operate on a local PT
264320 */
265321
322+/* Address ranges and their corresponding msr configuration registers */
323+static const struct pt_address_range {
324+ unsigned long msr_a;
325+ unsigned long msr_b;
326+ unsigned int reg_off;
327+} pt_address_ranges[] = {
328+ {
329+ .msr_a = MSR_IA32_RTIT_ADDR0_A,
330+ .msr_b = MSR_IA32_RTIT_ADDR0_B,
331+ .reg_off = RTIT_CTL_ADDR0_OFFSET,
332+ },
333+ {
334+ .msr_a = MSR_IA32_RTIT_ADDR1_A,
335+ .msr_b = MSR_IA32_RTIT_ADDR1_B,
336+ .reg_off = RTIT_CTL_ADDR1_OFFSET,
337+ },
338+ {
339+ .msr_a = MSR_IA32_RTIT_ADDR2_A,
340+ .msr_b = MSR_IA32_RTIT_ADDR2_B,
341+ .reg_off = RTIT_CTL_ADDR2_OFFSET,
342+ },
343+ {
344+ .msr_a = MSR_IA32_RTIT_ADDR3_A,
345+ .msr_b = MSR_IA32_RTIT_ADDR3_B,
346+ .reg_off = RTIT_CTL_ADDR3_OFFSET,
347+ }
348+};
349+
350+static u64 pt_config_filters(struct perf_event *event)
351+{
352+ struct pt_filters *filters = event->hw.addr_filters;
353+ struct pt *pt = this_cpu_ptr(&pt_ctx);
354+ unsigned int range = 0;
355+ u64 rtit_ctl = 0;
356+
357+ if (!filters)
358+ return 0;
359+
360+ perf_event_addr_filters_sync(event);
361+
362+ for (range = 0; range < filters->nr_filters; range++) {
363+ struct pt_filter *filter = &filters->filter[range];
364+
365+ /*
366+ * Note, if the range has zero start/end addresses due
367+ * to its dynamic object not being loaded yet, we just
368+ * go ahead and program zeroed range, which will simply
369+ * produce no data. Note^2: if executable code at 0x0
370+ * is a concern, we can set up an "invalid" configuration
371+ * such as msr_b < msr_a.
372+ */
373+
374+ /* avoid redundant msr writes */
375+ if (pt->filters.filter[range].msr_a != filter->msr_a) {
376+ wrmsrl(pt_address_ranges[range].msr_a, filter->msr_a);
377+ pt->filters.filter[range].msr_a = filter->msr_a;
378+ }
379+
380+ if (pt->filters.filter[range].msr_b != filter->msr_b) {
381+ wrmsrl(pt_address_ranges[range].msr_b, filter->msr_b);
382+ pt->filters.filter[range].msr_b = filter->msr_b;
383+ }
384+
385+ rtit_ctl |= filter->config << pt_address_ranges[range].reg_off;
386+ }
387+
388+ return rtit_ctl;
389+}
390+
266391 static void pt_config(struct perf_event *event)
267392 {
268393 u64 reg;
@@ -272,7 +397,8 @@ static void pt_config(struct perf_event *event) · 3 unmodified lines
272397 wrmsrl(MSR_IA32_RTIT_STATUS, 0);
273398 }
274399
275− reg = RTIT_CTL_TOPA | RTIT_CTL_BRANCH_EN | RTIT_CTL_TRACEEN;
400+ reg = pt_config_filters(event);
401+ reg |= RTIT_CTL_TOPA | RTIT_CTL_BRANCH_EN | RTIT_CTL_TRACEEN;
276402
277403 if (!event->attr.exclude_kernel)
278404 reg |= RTIT_CTL_OS;
@@ -921,24 +1047,80 @@ static void pt_buffer_free_aux(void *data) · 642 unmodified lines
9211047 kfree(buf);
9221048 }
9231049
924−/**
925− * pt_buffer_is_full() - check if the buffer is full
926− * @buf: PT buffer.
927− * @pt: Per-cpu pt handle.
928− *
929− * If the user hasn't read data from the output region that aux_head
930− * points to, the buffer is considered full: the user needs to read at
931− * least this region and update aux_tail to point past it.
932− */
933−static bool pt_buffer_is_full(struct pt_buffer *buf, struct pt *pt)
1050+static int pt_addr_filters_init(struct perf_event *event)
9341051 {
935− if (buf->snapshot)
936− return false;
1052+ struct pt_filters *filters;
1053+ int node = event->cpu == -1 ? -1 : cpu_to_node(event->cpu);
1054+
1055+ if (!pt_cap_get(PT_CAP_num_address_ranges))
1056+ return 0;
1057+
1058+ filters = kzalloc_node(sizeof(struct pt_filters), GFP_KERNEL, node);
1059+ if (!filters)
1060+ return -ENOMEM;
1061+
1062+ if (event->parent)
1063+ memcpy(filters, event->parent->hw.addr_filters,
1064+ sizeof(*filters));
1065+
1066+ event->hw.addr_filters = filters;
1067+
1068+ return 0;
1069+}
1070+
1071+static void pt_addr_filters_fini(struct perf_event *event)
1072+{
1073+ kfree(event->hw.addr_filters);
1074+ event->hw.addr_filters = NULL;
1075+}
1076+
1077+static int pt_event_addr_filters_validate(struct list_head *filters)
1078+{
1079+ struct perf_addr_filter *filter;
1080+ int range = 0;
1081+
1082+ list_for_each_entry(filter, filters, entry) {
1083+ /* PT doesn't support single address triggers */
1084+ if (!filter->range)
1085+ return -EOPNOTSUPP;
1086+
1087+ if (!filter->inode && !kernel_ip(filter->offset))
1088+ return -EINVAL;
1089+
1090+ if (++range > pt_cap_get(PT_CAP_num_address_ranges))
1091+ return -EOPNOTSUPP;
1092+ }
1093+
1094+ return 0;
1095+}
1096+
1097+static void pt_event_addr_filters_sync(struct perf_event *event)
1098+{
1099+ struct perf_addr_filters_head *head = perf_event_addr_filters(event);
1100+ unsigned long msr_a, msr_b, *offs = event->addr_filters_offs;
1101+ struct pt_filters *filters = event->hw.addr_filters;
1102+ struct perf_addr_filter *filter;
1103+ int range = 0;
1104+
1105+ if (!filters)
1106+ return;
9371107
938− if (local_read(&buf->data_size) >= pt->handle.size)
939− return true;
1108+ list_for_each_entry(filter, &head->list, entry) {
1109+ if (filter->inode && !offs[range]) {
1110+ msr_a = msr_b = 0;
1111+ } else {
1112+ /* apply the offset */
1113+ msr_a = filter->offset + offs[range];
1114+ msr_b = filter->size + msr_a;
1115+ }
1116+
1117+ filters->filter[range].msr_a = msr_a;
1118+ filters->filter[range].msr_b = msr_b;
1119+ filters->filter[range].config = filter->filter ? 1 : 2;
1120+ range++;
1121+ }
9401122
941− return false;
1123+ filters->nr_filters = range;
9421124 }
9431125
9441126 /**
@@ -955,7 +1137,7 @@ void intel_pt_interrupt(void) · 10 unmodified lines
9551137 * after PT has been disabled by pt_event_stop(). Make sure we don't
9561138 * do anything (particularly, re-enable) for this event here.
9571139 */
958− if (!ACCESS_ONCE(pt->handle_nmi))
1140+ if (!READ_ONCE(pt->handle_nmi))
9591141 return;
9601142
9611143 /*
@@ -1040,23 +1222,36 @@ EXPORT_SYMBOL_GPL(intel_pt_handle_vmx); · 78 unmodified lines
10401222
10411223 static void pt_event_start(struct perf_event *event, int mode)
10421224 {
1225+ struct hw_perf_event *hwc = &event->hw;
10431226 struct pt *pt = this_cpu_ptr(&pt_ctx);
1044− struct pt_buffer *buf = perf_get_aux(&pt->handle);
1227+ struct pt_buffer *buf;
10451228
10461229 if (READ_ONCE(pt->vmx_on))
10471230 return;
10481231
1049− if (!buf || pt_buffer_is_full(buf, pt)) {
1050− event->hw.state = PERF_HES_STOPPED;
1051− return;
1232+ buf = perf_aux_output_begin(&pt->handle, event);
1233+ if (!buf)
1234+ goto fail_stop;
1235+
1236+ pt_buffer_reset_offsets(buf, pt->handle.head);
1237+ if (!buf->snapshot) {
1238+ if (pt_buffer_reset_markers(buf, &pt->handle))
1239+ goto fail_end_stop;
10521240 }
10531241
1054− ACCESS_ONCE(pt->handle_nmi) = 1;
1055− event->hw.state = 0;
1242+ WRITE_ONCE(pt->handle_nmi, 1);
1243+ hwc->state = 0;
10561244
10571245 pt_config_buffer(buf->cur->table, buf->cur_idx,
10581246 buf->output_off);
10591247 pt_config(event);
1248+
1249+ return;
1250+
1251+fail_end_stop:
1252+ perf_aux_output_end(&pt->handle, 0, true);
1253+fail_stop:
1254+ hwc->state = PERF_HES_STOPPED;
10601255 }
10611256
10621257 static void pt_event_stop(struct perf_event *event, int mode)
@@ -1067,7 +1262,7 @@ static void pt_event_stop(struct perf_event *event, int mode) · 4 unmodified lines
10671262 * Protect against the PMI racing with disabling wrmsr,
10681263 * see comment in intel_pt_interrupt().
10691264 */
1070− ACCESS_ONCE(pt->handle_nmi) = 0;
1265+ WRITE_ONCE(pt->handle_nmi, 0);
10711266
10721267 pt_config_stop(event);
10731268
@@ -1090,19 +1285,7 @@ static void pt_event_stop(struct perf_event *event, int mode) · 16 unmodified lines
10901285 pt_handle_status(pt);
10911286
10921287 pt_update_head(pt);
1093− }
1094−}
1095−
1096−static void pt_event_del(struct perf_event *event, int mode)
1097−{
1098− struct pt *pt = this_cpu_ptr(&pt_ctx);
1099− struct pt_buffer *buf;
11001288
1101− pt_event_stop(event, PERF_EF_UPDATE);
1102−
1103− buf = perf_get_aux(&pt->handle);
1104−
1105− if (buf) {
11061289 if (buf->snapshot)
11071290 pt->handle.head =
11081291 local_xchg(&buf->data_size,
@@ -1112,9 +1295,13 @@ static void pt_event_del(struct perf_event *event, int mode) · 3 unmodified lines
11121295 }
11131296 }
11141297
1298+static void pt_event_del(struct perf_event *event, int mode)
1299+{
1300+ pt_event_stop(event, PERF_EF_UPDATE);
1301+}
1302+
11151303 static int pt_event_add(struct perf_event *event, int mode)
11161304 {
1117− struct pt_buffer *buf;
11181305 struct pt *pt = this_cpu_ptr(&pt_ctx);
11191306 struct hw_perf_event *hwc = &event->hw;
11201307 int ret = -EBUSY;
@@ -1122,34 +1309,18 @@ static int pt_event_add(struct perf_event *event, int mode) · 1 unmodified line
11221309 if (pt->handle.event)
11231310 goto fail;
11241311
1125− buf = perf_aux_output_begin(&pt->handle, event);
1126− ret = -EINVAL;
1127− if (!buf)
1128− goto fail_stop;
1129−
1130− pt_buffer_reset_offsets(buf, pt->handle.head);
1131− if (!buf->snapshot) {
1132− ret = pt_buffer_reset_markers(buf, &pt->handle);
1133− if (ret)
1134− goto fail_end_stop;
1135− }
1136−
11371312 if (mode & PERF_EF_START) {
11381313 pt_event_start(event, 0);
1139− ret = -EBUSY;
1314+ ret = -EINVAL;
11401315 if (hwc->state == PERF_HES_STOPPED)
1141− goto fail_end_stop;
1316+ goto fail;
11421317 } else {
11431318 hwc->state = PERF_HES_STOPPED;
11441319 }
11451320
1146− return 0;
1147−
1148−fail_end_stop:
1149− perf_aux_output_end(&pt->handle, 0, true);
1150−fail_stop:
1151− hwc->state = PERF_HES_STOPPED;
1321+ ret = 0;
11521322 fail:
1323+
11531324 return ret;
11541325 }
11551326
@@ -1159,6 +1330,7 @@ static void pt_event_read(struct perf_event *event) · 3 unmodified lines
11591330
11601331 static void pt_event_destroy(struct perf_event *event)
11611332 {
1333+ pt_addr_filters_fini(event);
11621334 x86_del_exclusive(x86_lbr_exclusive_pt);
11631335 }
11641336
@@ -1173,6 +1345,11 @@ static int pt_event_init(struct perf_event *event) · 8 unmodified lines
11731345 if (x86_add_exclusive(x86_lbr_exclusive_pt))
11741346 return -EBUSY;
11751347
1348+ if (pt_addr_filters_init(event)) {
1349+ x86_del_exclusive(x86_lbr_exclusive_pt);
1350+ return -ENOMEM;
1351+ }
1352+
11761353 event->destroy = pt_event_destroy;
11771354
11781355 return 0;
@@ -1192,7 +1369,7 @@ static __init int pt_init(void) · 13 unmodified lines
11921369
11931370 BUILD_BUG_ON(sizeof(struct topa) > PAGE_SIZE);
11941371
1195− if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
1372+ if (!boot_cpu_has(X86_FEATURE_INTEL_PT))
11961373 return -ENODEV;
11971374
11981375 get_online_cpus();
@@ -1226,16 +1403,21 @@ static __init int pt_init(void) · 27 unmodified lines
12261403 PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_AUX_SW_DOUBLEBUF;
12271404
12281405 pt_pmu.pmu.capabilities |= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
1229− pt_pmu.pmu.attr_groups = pt_attr_groups;
1230− pt_pmu.pmu.task_ctx_nr = perf_sw_context;
1231− pt_pmu.pmu.event_init = pt_event_init;
1232− pt_pmu.pmu.add = pt_event_add;
1233− pt_pmu.pmu.del = pt_event_del;
1234− pt_pmu.pmu.start = pt_event_start;
1235− pt_pmu.pmu.stop = pt_event_stop;
1236− pt_pmu.pmu.read = pt_event_read;
1237− pt_pmu.pmu.setup_aux = pt_buffer_setup_aux;
1238− pt_pmu.pmu.free_aux = pt_buffer_free_aux;
1406+ pt_pmu.pmu.attr_groups = pt_attr_groups;
1407+ pt_pmu.pmu.task_ctx_nr = perf_sw_context;
1408+ pt_pmu.pmu.event_init = pt_event_init;
1409+ pt_pmu.pmu.add = pt_event_add;
1410+ pt_pmu.pmu.del = pt_event_del;
1411+ pt_pmu.pmu.start = pt_event_start;
1412+ pt_pmu.pmu.stop = pt_event_stop;
1413+ pt_pmu.pmu.read = pt_event_read;
1414+ pt_pmu.pmu.setup_aux = pt_buffer_setup_aux;
1415+ pt_pmu.pmu.free_aux = pt_buffer_free_aux;
1416+ pt_pmu.pmu.addr_filters_sync = pt_event_addr_filters_sync;
1417+ pt_pmu.pmu.addr_filters_validate = pt_event_addr_filters_validate;
1418+ pt_pmu.pmu.nr_addr_filters =
1419+ pt_cap_get(PT_CAP_num_address_ranges);
1420+
12391421 ret = perf_pmu_register(&pt_pmu.pmu, "intel_pt", -1);
12401422
12411423 return ret;
arch/x86/events/intel/pt.h+68−0
@@ -19,6 +19,40 @@ · 18 unmodified lines
1919 #ifndef __INTEL_PT_H__
2020 #define __INTEL_PT_H__
2121
22+/*
23+ * PT MSR bit definitions
24+ */
25+#define RTIT_CTL_TRACEEN BIT(0)
26+#define RTIT_CTL_CYCLEACC BIT(1)
27+#define RTIT_CTL_OS BIT(2)
28+#define RTIT_CTL_USR BIT(3)
29+#define RTIT_CTL_CR3EN BIT(7)
30+#define RTIT_CTL_TOPA BIT(8)
31+#define RTIT_CTL_MTC_EN BIT(9)
32+#define RTIT_CTL_TSC_EN BIT(10)
33+#define RTIT_CTL_DISRETC BIT(11)
34+#define RTIT_CTL_BRANCH_EN BIT(13)
35+#define RTIT_CTL_MTC_RANGE_OFFSET 14
36+#define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET)
37+#define RTIT_CTL_CYC_THRESH_OFFSET 19
38+#define RTIT_CTL_CYC_THRESH (0x0full << RTIT_CTL_CYC_THRESH_OFFSET)
39+#define RTIT_CTL_PSB_FREQ_OFFSET 24
40+#define RTIT_CTL_PSB_FREQ (0x0full << RTIT_CTL_PSB_FREQ_OFFSET)
41+#define RTIT_CTL_ADDR0_OFFSET 32
42+#define RTIT_CTL_ADDR0 (0x0full << RTIT_CTL_ADDR0_OFFSET)
43+#define RTIT_CTL_ADDR1_OFFSET 36
44+#define RTIT_CTL_ADDR1 (0x0full << RTIT_CTL_ADDR1_OFFSET)
45+#define RTIT_CTL_ADDR2_OFFSET 40
46+#define RTIT_CTL_ADDR2 (0x0full << RTIT_CTL_ADDR2_OFFSET)
47+#define RTIT_CTL_ADDR3_OFFSET 44
48+#define RTIT_CTL_ADDR3 (0x0full << RTIT_CTL_ADDR3_OFFSET)
49+#define RTIT_STATUS_FILTEREN BIT(0)
50+#define RTIT_STATUS_CONTEXTEN BIT(1)
51+#define RTIT_STATUS_TRIGGEREN BIT(2)
52+#define RTIT_STATUS_BUFFOVF BIT(3)
53+#define RTIT_STATUS_ERROR BIT(4)
54+#define RTIT_STATUS_STOPPED BIT(5)
55+
2256 /*
2357 * Single-entry ToPA: when this close to region boundary, switch
2458 * buffers to avoid losing data.
@@ -48,15 +82,20 @@ struct topa_entry { · 23 unmodified lines
4882 #define PT_CPUID_LEAVES 2
4983 #define PT_CPUID_REGS_NUM 4 /* number of regsters (eax, ebx, ecx, edx) */
5084
85+/* TSC to Core Crystal Clock Ratio */
86+#define CPUID_TSC_LEAF 0x15
87+
5188 enum pt_capabilities {
5289 PT_CAP_max_subleaf = 0,
5390 PT_CAP_cr3_filtering,
5491 PT_CAP_psb_cyc,
92+ PT_CAP_ip_filtering,
5593 PT_CAP_mtc,
5694 PT_CAP_topa_output,
5795 PT_CAP_topa_multiple_entries,
5896 PT_CAP_single_range_output,
5997 PT_CAP_payloads_lip,
98+ PT_CAP_num_address_ranges,
6099 PT_CAP_mtc_periods,
61100 PT_CAP_cycle_thresholds,
62101 PT_CAP_psb_periods,
@@ -66,6 +105,9 @@ struct pt_pmu { · 3 unmodified lines
66105 struct pmu pmu;
67106 u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES];
68107 bool vmx;
108+ unsigned long max_nonturbo_ratio;
109+ unsigned int tsc_art_num;
110+ unsigned int tsc_art_den;
69111 };
70112
71113 /**
@@ -104,14 +146,40 @@ struct pt_buffer { · 32 unmodified lines
104146 struct topa_entry *topa_index[0];
105147 };
106148
149+#define PT_FILTERS_NUM 4
150+
151+/**
152+ * struct pt_filter - IP range filter configuration
153+ * @msr_a: range start, goes to RTIT_ADDRn_A
154+ * @msr_b: range end, goes to RTIT_ADDRn_B
155+ * @config: 4-bit field in RTIT_CTL
156+ */
157+struct pt_filter {
158+ unsigned long msr_a;
159+ unsigned long msr_b;
160+ unsigned long config;
161+};
162+
163+/**
164+ * struct pt_filters - IP range filtering context
165+ * @filter: filters defined for this context
166+ * @nr_filters: number of defined filters in the @filter array
167+ */
168+struct pt_filters {
169+ struct pt_filter filter[PT_FILTERS_NUM];
170+ unsigned int nr_filters;
171+};
172+
107173 /**
108174 * struct pt - per-cpu pt context
109175 * @handle: perf output handle
176+ * @filters: last configured filters
110177 * @handle_nmi: do handle PT PMI on this cpu, there's an active event
111178 * @vmx_on: 1 if VMX is ON on this cpu
112179 */
113180 struct pt {
114181 struct perf_output_handle handle;
182+ struct pt_filters filters;
115183 int handle_nmi;
116184 int vmx_on;
117185 };
arch/x86/events/intel/rapl.c+141−42
@@ -27,10 +27,14 @@ · 26 unmodified lines
2727 * event: rapl_energy_dram
2828 * perf code: 0x3
2929 *
30− * dram counter: consumption of the builtin-gpu domain (client only)
30+ * gpu counter: consumption of the builtin-gpu domain (client only)
3131 * event: rapl_energy_gpu
3232 * perf code: 0x4
3333 *
34+ * psys counter: consumption of the builtin-psys domain (client only)
35+ * event: rapl_energy_psys
36+ * perf code: 0x5
37+ *
3438 * We manage those counters as free running (read-only). They may be
3539 * use simultaneously by other tools, such as turbostat.
3640 *
@@ -53,6 +57,8 @@ · 16 unmodified lines
5357 #include <asm/cpu_device_id.h>
5458 #include "../perf_event.h"
5559
60+MODULE_LICENSE("GPL");
61+
5662 /*
5763 * RAPL energy status counters
5864 */
@@ -64,13 +70,16 @@ · 5 unmodified lines
6470 #define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
6571 #define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */
6672 #define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
73+#define RAPL_IDX_PSYS_NRG_STAT 4 /* psys */
74+#define INTEL_RAPL_PSYS 0x5 /* pseudo-encoding */
6775
68−#define NR_RAPL_DOMAINS 0x4
76+#define NR_RAPL_DOMAINS 0x5
6977 static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
7078 "pp0-core",
7179 "package",
7280 "dram",
7381 "pp1-gpu",
82+ "psys",
7483 };
7584
7685 /* Clients have PP0, PKG */
@@ -89,6 +98,13 @@ static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = { · 12 unmodified lines
8998 1<<RAPL_IDX_RAM_NRG_STAT|\
9099 1<<RAPL_IDX_PP1_NRG_STAT)
91100
101+/* SKL clients have PP0, PKG, RAM, PP1, PSYS */
102+#define RAPL_IDX_SKL_CLN (1<<RAPL_IDX_PP0_NRG_STAT|\
103+ 1<<RAPL_IDX_PKG_NRG_STAT|\
104+ 1<<RAPL_IDX_RAM_NRG_STAT|\
105+ 1<<RAPL_IDX_PP1_NRG_STAT|\
106+ 1<<RAPL_IDX_PSYS_NRG_STAT)
107+
92108 /* Knights Landing has PKG, RAM */
93109 #define RAPL_IDX_KNL (1<<RAPL_IDX_PKG_NRG_STAT|\
94110 1<<RAPL_IDX_RAM_NRG_STAT)
@@ -360,6 +376,10 @@ static int rapl_pmu_event_init(struct perf_event *event) · 265 unmodified lines
360376 bit = RAPL_IDX_PP1_NRG_STAT;
361377 msr = MSR_PP1_ENERGY_STATUS;
362378 break;
379+ case INTEL_RAPL_PSYS:
380+ bit = RAPL_IDX_PSYS_NRG_STAT;
381+ msr = MSR_PLATFORM_ENERGY_STATUS;
382+ break;
363383 default:
364384 return -EINVAL;
365385 }
@@ -414,11 +434,13 @@ RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); · 48 unmodified lines
414434 RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02");
415435 RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03");
416436 RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04");
437+RAPL_EVENT_ATTR_STR(energy-psys, rapl_psys, "event=0x05");
417438
418439 RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
419440 RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules");
420441 RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules");
421442 RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules");
443+RAPL_EVENT_ATTR_STR(energy-psys.unit, rapl_psys_unit, "Joules");
422444
423445 /*
424446 * we compute in 0.23 nJ increments regardless of MSR
@@ -427,6 +449,7 @@ RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890 · 2 unmodified lines
427449 RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10");
428450 RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10");
429451 RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10");
452+RAPL_EVENT_ATTR_STR(energy-psys.scale, rapl_psys_scale, "2.3283064365386962890625e-10");
430453
431454 static struct attribute *rapl_events_srv_attr[] = {
432455 EVENT_PTR(rapl_cores),
@@ -476,6 +499,27 @@ static struct attribute *rapl_events_hsw_attr[] = { · 43 unmodified lines
476499 NULL,
477500 };
478501
502+static struct attribute *rapl_events_skl_attr[] = {
503+ EVENT_PTR(rapl_cores),
504+ EVENT_PTR(rapl_pkg),
505+ EVENT_PTR(rapl_gpu),
506+ EVENT_PTR(rapl_ram),
507+ EVENT_PTR(rapl_psys),
508+
509+ EVENT_PTR(rapl_cores_unit),
510+ EVENT_PTR(rapl_pkg_unit),
511+ EVENT_PTR(rapl_gpu_unit),
512+ EVENT_PTR(rapl_ram_unit),
513+ EVENT_PTR(rapl_psys_unit),
514+
515+ EVENT_PTR(rapl_cores_scale),
516+ EVENT_PTR(rapl_pkg_scale),
517+ EVENT_PTR(rapl_gpu_scale),
518+ EVENT_PTR(rapl_ram_scale),
519+ EVENT_PTR(rapl_psys_scale),
520+ NULL,
521+};
522+
479523 static struct attribute *rapl_events_knl_attr[] = {
480524 EVENT_PTR(rapl_pkg),
481525 EVENT_PTR(rapl_ram),
@@ -592,6 +636,11 @@ static int rapl_cpu_notifier(struct notifier_block *self, · 110 unmodified lines
592636 return NOTIFY_OK;
593637 }
594638
639+static struct notifier_block rapl_cpu_nb = {
640+ .notifier_call = rapl_cpu_notifier,
641+ .priority = CPU_PRI_PERF + 1,
642+};
643+
595644 static int rapl_check_hw_unit(bool apply_quirk)
596645 {
597646 u64 msr_rapl_power_unit_bits;
@@ -660,7 +709,7 @@ static int __init rapl_prepare_cpus(void) · 62 unmodified lines
660709 return 0;
661710 }
662711
663−static void __init cleanup_rapl_pmus(void)
712+static void cleanup_rapl_pmus(void)
664713 {
665714 int i;
666715
@@ -691,52 +740,92 @@ static int __init init_rapl_pmus(void) · 24 unmodified lines
691740 return 0;
692741 }
693742
743+#define X86_RAPL_MODEL_MATCH(model, init) \
744+ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init }
745+
746+struct intel_rapl_init_fun {
747+ bool apply_quirk;
748+ int cntr_mask;
749+ struct attribute **attrs;
750+};
751+
752+static const struct intel_rapl_init_fun snb_rapl_init __initconst = {
753+ .apply_quirk = false,
754+ .cntr_mask = RAPL_IDX_CLN,
755+ .attrs = rapl_events_cln_attr,
756+};
757+
758+static const struct intel_rapl_init_fun hsx_rapl_init __initconst = {
759+ .apply_quirk = true,
760+ .cntr_mask = RAPL_IDX_SRV,
761+ .attrs = rapl_events_srv_attr,
762+};
763+
764+static const struct intel_rapl_init_fun hsw_rapl_init __initconst = {
765+ .apply_quirk = false,
766+ .cntr_mask = RAPL_IDX_HSW,
767+ .attrs = rapl_events_hsw_attr,
768+};
769+
770+static const struct intel_rapl_init_fun snbep_rapl_init __initconst = {
771+ .apply_quirk = false,
772+ .cntr_mask = RAPL_IDX_SRV,
773+ .attrs = rapl_events_srv_attr,
774+};
775+
776+static const struct intel_rapl_init_fun knl_rapl_init __initconst = {
777+ .apply_quirk = true,
778+ .cntr_mask = RAPL_IDX_KNL,
779+ .attrs = rapl_events_knl_attr,
780+};
781+
782+static const struct intel_rapl_init_fun skl_rapl_init __initconst = {
783+ .apply_quirk = false,
784+ .cntr_mask = RAPL_IDX_SKL_CLN,
785+ .attrs = rapl_events_skl_attr,
786+};
787+
694788 static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
695− [0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
696− [1] = {},
789+ X86_RAPL_MODEL_MATCH(42, snb_rapl_init), /* Sandy Bridge */
790+ X86_RAPL_MODEL_MATCH(45, snbep_rapl_init), /* Sandy Bridge-EP */
791+
792+ X86_RAPL_MODEL_MATCH(58, snb_rapl_init), /* Ivy Bridge */
793+ X86_RAPL_MODEL_MATCH(62, snbep_rapl_init), /* IvyTown */
794+
795+ X86_RAPL_MODEL_MATCH(60, hsw_rapl_init), /* Haswell */
796+ X86_RAPL_MODEL_MATCH(63, hsx_rapl_init), /* Haswell-Server */
797+ X86_RAPL_MODEL_MATCH(69, hsw_rapl_init), /* Haswell-Celeron */
798+ X86_RAPL_MODEL_MATCH(70, hsw_rapl_init), /* Haswell GT3e */
799+
800+ X86_RAPL_MODEL_MATCH(61, hsw_rapl_init), /* Broadwell */
801+ X86_RAPL_MODEL_MATCH(71, hsw_rapl_init), /* Broadwell-H */
802+ X86_RAPL_MODEL_MATCH(79, hsx_rapl_init), /* Broadwell-Server */
803+ X86_RAPL_MODEL_MATCH(86, hsx_rapl_init), /* Broadwell Xeon D */
804+
805+ X86_RAPL_MODEL_MATCH(87, knl_rapl_init), /* Knights Landing */
806+
807+ X86_RAPL_MODEL_MATCH(78, skl_rapl_init), /* Skylake */
808+ X86_RAPL_MODEL_MATCH(94, skl_rapl_init), /* Skylake H/S */
809+ {},
697810 };
698811
812+MODULE_DEVICE_TABLE(x86cpu, rapl_cpu_match);
813+
699814 static int __init rapl_pmu_init(void)
700815 {
701− bool apply_quirk = false;
816+ const struct x86_cpu_id *id;
817+ struct intel_rapl_init_fun *rapl_init;
818+ bool apply_quirk;
702819 int ret;
703820
704− if (!x86_match_cpu(rapl_cpu_match))
821+ id = x86_match_cpu(rapl_cpu_match);
822+ if (!id)
705823 return -ENODEV;
706824
707− switch (boot_cpu_data.x86_model) {
708− case 42: /* Sandy Bridge */
709− case 58: /* Ivy Bridge */
710− rapl_cntr_mask = RAPL_IDX_CLN;
711− rapl_pmu_events_group.attrs = rapl_events_cln_attr;
712− break;
713− case 63: /* Haswell-Server */
714− case 79: /* Broadwell-Server */
715− apply_quirk = true;
716− rapl_cntr_mask = RAPL_IDX_SRV;
717− rapl_pmu_events_group.attrs = rapl_events_srv_attr;
718− break;
719− case 60: /* Haswell */
720− case 69: /* Haswell-Celeron */
721− case 70: /* Haswell GT3e */
722− case 61: /* Broadwell */
723− case 71: /* Broadwell-H */
724− rapl_cntr_mask = RAPL_IDX_HSW;
725− rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
726− break;
727− case 45: /* Sandy Bridge-EP */
728− case 62: /* IvyTown */
729− rapl_cntr_mask = RAPL_IDX_SRV;
730− rapl_pmu_events_group.attrs = rapl_events_srv_attr;
731− break;
732− case 87: /* Knights Landing */
733− apply_quirk = true;
734− rapl_cntr_mask = RAPL_IDX_KNL;
735− rapl_pmu_events_group.attrs = rapl_events_knl_attr;
736− break;
737− default:
738− return -ENODEV;
739− }
825+ rapl_init = (struct intel_rapl_init_fun *)id->driver_data;
826+ apply_quirk = rapl_init->apply_quirk;
827+ rapl_cntr_mask = rapl_init->cntr_mask;
828+ rapl_pmu_events_group.attrs = rapl_init->attrs;
740829
741830 ret = rapl_check_hw_unit(apply_quirk);
742831 if (ret)
@@ -756,7 +845,7 @@ static int __init rapl_pmu_init(void) · 13 unmodified lines
756845 if (ret)
757846 goto out;
758847
759− __perf_cpu_notifier(rapl_cpu_notifier);
848+ __register_cpu_notifier(&rapl_cpu_nb);
760849 cpu_notifier_register_done();
761850 rapl_advertise();
762851 return 0;
@@ -767,4 +856,14 @@ out: · 4 unmodified lines
767856 cpu_notifier_register_done();
768857 return ret;
769858 }
770−device_initcall(rapl_pmu_init);
859+module_init(rapl_pmu_init);
860+
861+static void __exit intel_rapl_exit(void)
862+{
863+ cpu_notifier_register_begin();
864+ __unregister_cpu_notifier(&rapl_cpu_nb);
865+ perf_pmu_unregister(&rapl_pmus->pmu);
866+ cleanup_rapl_pmus();
867+ cpu_notifier_register_done();
868+}
869+module_exit(intel_rapl_exit);
arch/x86/events/intel/uncore.c+126−90
@@ -1,3 +1,4 @@
1+#include <asm/cpu_device_id.h>
12 #include "uncore.h"
23
34 static struct intel_uncore_type *empty_uncore[] = { NULL, };
@@ -21,6 +22,8 @@ static struct event_constraint uncore_constraint_fixed = · 17 unmodified lines
2122 struct event_constraint uncore_constraint_empty =
2223 EVENT_CONSTRAINT(0, 0, 0);
2324
25+MODULE_LICENSE("GPL");
26+
2427 static int uncore_pcibus_to_physid(struct pci_bus *bus)
2528 {
2629 struct pci2phy_map *map;
@@ -754,7 +757,7 @@ static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu) · 727 unmodified lines
754757 pmu->registered = false;
755758 }
756759
757−static void __init __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
760+static void __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
758761 {
759762 struct intel_uncore_pmu *pmu = type->pmus;
760763 struct intel_uncore_box *box;
@@ -770,7 +773,7 @@ static void __init __uncore_exit_boxes(struct intel_uncore_type *type, int cpu) · 9 unmodified lines
770773 }
771774 }
772775
773−static void __init uncore_exit_boxes(void *dummy)
776+static void uncore_exit_boxes(void *dummy)
774777 {
775778 struct intel_uncore_type **types;
776779
@@ -787,7 +790,7 @@ static void uncore_free_boxes(struct intel_uncore_pmu *pmu) · 10 unmodified lines
787790 kfree(pmu->boxes);
788791 }
789792
790−static void __init uncore_type_exit(struct intel_uncore_type *type)
793+static void uncore_type_exit(struct intel_uncore_type *type)
791794 {
792795 struct intel_uncore_pmu *pmu = type->pmus;
793796 int i;
@@ -804,7 +807,7 @@ static void __init uncore_type_exit(struct intel_uncore_type *type) · 10 unmodified lines
804807 type->events_group = NULL;
805808 }
806809
807−static void __init uncore_types_exit(struct intel_uncore_type **types)
810+static void uncore_types_exit(struct intel_uncore_type **types)
808811 {
809812 for (; *types; types++)
810813 uncore_type_exit(*types);
@@ -989,46 +992,6 @@ static int __init uncore_pci_init(void) · 178 unmodified lines
989992 size_t size;
990993 int ret;
991994
992− switch (boot_cpu_data.x86_model) {
993− case 45: /* Sandy Bridge-EP */
994− ret = snbep_uncore_pci_init();
995− break;
996− case 62: /* Ivy Bridge-EP */
997− ret = ivbep_uncore_pci_init();
998− break;
999− case 63: /* Haswell-EP */
1000− ret = hswep_uncore_pci_init();
1001− break;
1002− case 79: /* BDX-EP */
1003− case 86: /* BDX-DE */
1004− ret = bdx_uncore_pci_init();
1005− break;
1006− case 42: /* Sandy Bridge */
1007− ret = snb_uncore_pci_init();
1008− break;
1009− case 58: /* Ivy Bridge */
1010− ret = ivb_uncore_pci_init();
1011− break;
1012− case 60: /* Haswell */
1013− case 69: /* Haswell Celeron */
1014− ret = hsw_uncore_pci_init();
1015− break;
1016− case 61: /* Broadwell */
1017− ret = bdw_uncore_pci_init();
1018− break;
1019− case 87: /* Knights Landing */
1020− ret = knl_uncore_pci_init();
1021− break;
1022− case 94: /* SkyLake */
1023− ret = skl_uncore_pci_init();
1024− break;
1025− default:
1026− return -ENODEV;
1027− }
1028−
1029− if (ret)
1030− return ret;
1031−
1032995 size = max_packages * sizeof(struct pci_extra_dev);
1033996 uncore_extra_pci_dev = kzalloc(size, GFP_KERNEL);
1034997 if (!uncore_extra_pci_dev) {
@@ -1060,7 +1023,7 @@ err: · 25 unmodified lines
10601023 return ret;
10611024 }
10621025
1063−static void __init uncore_pci_exit(void)
1026+static void uncore_pci_exit(void)
10641027 {
10651028 if (pcidrv_registered) {
10661029 pcidrv_registered = false;
@@ -1287,46 +1250,6 @@ static int __init uncore_cpu_init(void) · 220 unmodified lines
12871250 {
12881251 int ret;
12891252
1290− switch (boot_cpu_data.x86_model) {
1291− case 26: /* Nehalem */
1292− case 30:
1293− case 37: /* Westmere */
1294− case 44:
1295− nhm_uncore_cpu_init();
1296− break;
1297− case 42: /* Sandy Bridge */
1298− case 58: /* Ivy Bridge */
1299− case 60: /* Haswell */
1300− case 69: /* Haswell */
1301− case 70: /* Haswell */
1302− case 61: /* Broadwell */
1303− case 71: /* Broadwell */
1304− snb_uncore_cpu_init();
1305− break;
1306− case 45: /* Sandy Bridge-EP */
1307− snbep_uncore_cpu_init();
1308− break;
1309− case 46: /* Nehalem-EX */
1310− case 47: /* Westmere-EX aka. Xeon E7 */
1311− nhmex_uncore_cpu_init();
1312− break;
1313− case 62: /* Ivy Bridge-EP */
1314− ivbep_uncore_cpu_init();
1315− break;
1316− case 63: /* Haswell-EP */
1317− hswep_uncore_cpu_init();
1318− break;
1319− case 79: /* BDX-EP */
1320− case 86: /* BDX-DE */
1321− bdx_uncore_cpu_init();
1322− break;
1323− case 87: /* Knights Landing */
1324− knl_uncore_cpu_init();
1325− break;
1326− default:
1327− return -ENODEV;
1328− }
1329−
13301253 ret = uncore_types_init(uncore_msr_uncores, true);
13311254 if (ret)
13321255 goto err;
@@ -1376,11 +1299,105 @@ static int __init uncore_cpumask_init(bool msr) · 43 unmodified lines
13761299 return 0;
13771300 }
13781301
1302+#define X86_UNCORE_MODEL_MATCH(model, init) \
1303+ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init }
1304+
1305+struct intel_uncore_init_fun {
1306+ void (*cpu_init)(void);
1307+ int (*pci_init)(void);
1308+};
1309+
1310+static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
1311+ .cpu_init = nhm_uncore_cpu_init,
1312+};
1313+
1314+static const struct intel_uncore_init_fun snb_uncore_init __initconst = {
1315+ .cpu_init = snb_uncore_cpu_init,
1316+ .pci_init = snb_uncore_pci_init,
1317+};
1318+
1319+static const struct intel_uncore_init_fun ivb_uncore_init __initconst = {
1320+ .cpu_init = snb_uncore_cpu_init,
1321+ .pci_init = ivb_uncore_pci_init,
1322+};
1323+
1324+static const struct intel_uncore_init_fun hsw_uncore_init __initconst = {
1325+ .cpu_init = snb_uncore_cpu_init,
1326+ .pci_init = hsw_uncore_pci_init,
1327+};
1328+
1329+static const struct intel_uncore_init_fun bdw_uncore_init __initconst = {
1330+ .cpu_init = snb_uncore_cpu_init,
1331+ .pci_init = bdw_uncore_pci_init,
1332+};
1333+
1334+static const struct intel_uncore_init_fun snbep_uncore_init __initconst = {
1335+ .cpu_init = snbep_uncore_cpu_init,
1336+ .pci_init = snbep_uncore_pci_init,
1337+};
1338+
1339+static const struct intel_uncore_init_fun nhmex_uncore_init __initconst = {
1340+ .cpu_init = nhmex_uncore_cpu_init,
1341+};
1342+
1343+static const struct intel_uncore_init_fun ivbep_uncore_init __initconst = {
1344+ .cpu_init = ivbep_uncore_cpu_init,
1345+ .pci_init = ivbep_uncore_pci_init,
1346+};
1347+
1348+static const struct intel_uncore_init_fun hswep_uncore_init __initconst = {
1349+ .cpu_init = hswep_uncore_cpu_init,
1350+ .pci_init = hswep_uncore_pci_init,
1351+};
1352+
1353+static const struct intel_uncore_init_fun bdx_uncore_init __initconst = {
1354+ .cpu_init = bdx_uncore_cpu_init,
1355+ .pci_init = bdx_uncore_pci_init,
1356+};
1357+
1358+static const struct intel_uncore_init_fun knl_uncore_init __initconst = {
1359+ .cpu_init = knl_uncore_cpu_init,
1360+ .pci_init = knl_uncore_pci_init,
1361+};
1362+
1363+static const struct intel_uncore_init_fun skl_uncore_init __initconst = {
1364+ .pci_init = skl_uncore_pci_init,
1365+};
1366+
1367+static const struct x86_cpu_id intel_uncore_match[] __initconst = {
1368+ X86_UNCORE_MODEL_MATCH(26, nhm_uncore_init), /* Nehalem */
1369+ X86_UNCORE_MODEL_MATCH(30, nhm_uncore_init),
1370+ X86_UNCORE_MODEL_MATCH(37, nhm_uncore_init), /* Westmere */
1371+ X86_UNCORE_MODEL_MATCH(44, nhm_uncore_init),
1372+ X86_UNCORE_MODEL_MATCH(42, snb_uncore_init), /* Sandy Bridge */
1373+ X86_UNCORE_MODEL_MATCH(58, ivb_uncore_init), /* Ivy Bridge */
1374+ X86_UNCORE_MODEL_MATCH(60, hsw_uncore_init), /* Haswell */
1375+ X86_UNCORE_MODEL_MATCH(69, hsw_uncore_init), /* Haswell Celeron */
1376+ X86_UNCORE_MODEL_MATCH(70, hsw_uncore_init), /* Haswell */
1377+ X86_UNCORE_MODEL_MATCH(61, bdw_uncore_init), /* Broadwell */
1378+ X86_UNCORE_MODEL_MATCH(71, bdw_uncore_init), /* Broadwell */
1379+ X86_UNCORE_MODEL_MATCH(45, snbep_uncore_init), /* Sandy Bridge-EP */
1380+ X86_UNCORE_MODEL_MATCH(46, nhmex_uncore_init), /* Nehalem-EX */
1381+ X86_UNCORE_MODEL_MATCH(47, nhmex_uncore_init), /* Westmere-EX aka. Xeon E7 */
1382+ X86_UNCORE_MODEL_MATCH(62, ivbep_uncore_init), /* Ivy Bridge-EP */
1383+ X86_UNCORE_MODEL_MATCH(63, hswep_uncore_init), /* Haswell-EP */
1384+ X86_UNCORE_MODEL_MATCH(79, bdx_uncore_init), /* BDX-EP */
1385+ X86_UNCORE_MODEL_MATCH(86, bdx_uncore_init), /* BDX-DE */
1386+ X86_UNCORE_MODEL_MATCH(87, knl_uncore_init), /* Knights Landing */
1387+ X86_UNCORE_MODEL_MATCH(94, skl_uncore_init), /* SkyLake */
1388+ {},
1389+};
1390+
1391+MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
1392+
13791393 static int __init intel_uncore_init(void)
13801394 {
1381− int pret, cret, ret;
1395+ const struct x86_cpu_id *id;
1396+ struct intel_uncore_init_fun *uncore_init;
1397+ int pret = 0, cret = 0, ret;
13821398
1383− if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
1399+ id = x86_match_cpu(intel_uncore_match);
1400+ if (!id)
13841401 return -ENODEV;
13851402
13861403 if (cpu_has_hypervisor)
@@ -1388,8 +1405,17 @@ static int __init intel_uncore_init(void) · 1 unmodified line
13881405
13891406 max_packages = topology_max_packages();
13901407
1391− pret = uncore_pci_init();
1392− cret = uncore_cpu_init();
1408+ uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
1409+ if (uncore_init->pci_init) {
1410+ pret = uncore_init->pci_init();
1411+ if (!pret)
1412+ pret = uncore_pci_init();
1413+ }
1414+
1415+ if (uncore_init->cpu_init) {
1416+ uncore_init->cpu_init();
1417+ cret = uncore_cpu_init();
1418+ }
13931419
13941420 if (cret && pret)
13951421 return -ENODEV;
@@ -1409,4 +1435,14 @@ err: · 13 unmodified lines
14091435 cpu_notifier_register_done();
14101436 return ret;
14111437 }
1412−device_initcall(intel_uncore_init);
1438+module_init(intel_uncore_init);
1439+
1440+static void __exit intel_uncore_exit(void)
1441+{
1442+ cpu_notifier_register_begin();
1443+ __unregister_cpu_notifier(&uncore_cpu_nb);
1444+ uncore_types_exit(uncore_msr_uncores);
1445+ uncore_pci_exit();
1446+ cpu_notifier_register_done();
1447+}
1448+module_exit(intel_uncore_exit);
arch/x86/events/msr.c+26−10
@@ -6,6 +6,8 @@ enum perf_msr_id { · 5 unmodified lines
66 PERF_MSR_MPERF = 2,
77 PERF_MSR_PPERF = 3,
88 PERF_MSR_SMI = 4,
9+ PERF_MSR_PTSC = 5,
10+ PERF_MSR_IRPERF = 6,
911
1012 PERF_MSR_EVENT_MAX,
1113 };
@@ -15,6 +17,16 @@ static bool test_aperfmperf(int idx) · 3 unmodified lines
1517 return boot_cpu_has(X86_FEATURE_APERFMPERF);
1618 }
1719
20+static bool test_ptsc(int idx)
21+{
22+ return boot_cpu_has(X86_FEATURE_PTSC);
23+}
24+
25+static bool test_irperf(int idx)
26+{
27+ return boot_cpu_has(X86_FEATURE_IRPERF);
28+}
29+
1830 static bool test_intel(int idx)
1931 {
2032 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
@@ -69,18 +81,22 @@ struct perf_msr { · 48 unmodified lines
6981 bool (*test)(int idx);
7082 };
7183
72−PMU_EVENT_ATTR_STRING(tsc, evattr_tsc, "event=0x00");
73−PMU_EVENT_ATTR_STRING(aperf, evattr_aperf, "event=0x01");
74−PMU_EVENT_ATTR_STRING(mperf, evattr_mperf, "event=0x02");
75−PMU_EVENT_ATTR_STRING(pperf, evattr_pperf, "event=0x03");
76−PMU_EVENT_ATTR_STRING(smi, evattr_smi, "event=0x04");
84+PMU_EVENT_ATTR_STRING(tsc, evattr_tsc, "event=0x00");
85+PMU_EVENT_ATTR_STRING(aperf, evattr_aperf, "event=0x01");
86+PMU_EVENT_ATTR_STRING(mperf, evattr_mperf, "event=0x02");
87+PMU_EVENT_ATTR_STRING(pperf, evattr_pperf, "event=0x03");
88+PMU_EVENT_ATTR_STRING(smi, evattr_smi, "event=0x04");
89+PMU_EVENT_ATTR_STRING(ptsc, evattr_ptsc, "event=0x05");
90+PMU_EVENT_ATTR_STRING(irperf, evattr_irperf, "event=0x06");
7791
7892 static struct perf_msr msr[] = {
79− [PERF_MSR_TSC] = { 0, &evattr_tsc, NULL, },
80− [PERF_MSR_APERF] = { MSR_IA32_APERF, &evattr_aperf, test_aperfmperf, },
81− [PERF_MSR_MPERF] = { MSR_IA32_MPERF, &evattr_mperf, test_aperfmperf, },
82− [PERF_MSR_PPERF] = { MSR_PPERF, &evattr_pperf, test_intel, },
83− [PERF_MSR_SMI] = { MSR_SMI_COUNT, &evattr_smi, test_intel, },
93+ [PERF_MSR_TSC] = { 0, &evattr_tsc, NULL, },
94+ [PERF_MSR_APERF] = { MSR_IA32_APERF, &evattr_aperf, test_aperfmperf, },
95+ [PERF_MSR_MPERF] = { MSR_IA32_MPERF, &evattr_mperf, test_aperfmperf, },
96+ [PERF_MSR_PPERF] = { MSR_PPERF, &evattr_pperf, test_intel, },
97+ [PERF_MSR_SMI] = { MSR_SMI_COUNT, &evattr_smi, test_intel, },
98+ [PERF_MSR_PTSC] = { MSR_F15H_PTSC, &evattr_ptsc, test_ptsc, },
99+ [PERF_MSR_IRPERF] = { MSR_F17H_IRPERF, &evattr_irperf, test_irperf, },
84100 };
85101
86102 static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
arch/x86/events/perf_event.h+5−0
@@ -601,6 +601,7 @@ struct x86_pmu { · 600 unmodified lines
601601 u64 lbr_sel_mask; /* LBR_SELECT valid bits */
602602 const int *lbr_sel_map; /* lbr_select mappings */
603603 bool lbr_double_abort; /* duplicated lbr aborts */
604+ bool lbr_pt_coexist; /* LBR may coexist with PT */
604605
605606 /*
606607 * Intel PT/LBR/BTS are exclusive
@@ -859,6 +860,8 @@ extern struct event_constraint intel_atom_pebs_event_constraints[]; · 252 unmodified lines
859860
860861 extern struct event_constraint intel_slm_pebs_event_constraints[];
861862
863+extern struct event_constraint intel_glm_pebs_event_constraints[];
864+
862865 extern struct event_constraint intel_nehalem_pebs_event_constraints[];
863866
864867 extern struct event_constraint intel_westmere_pebs_event_constraints[];
@@ -907,6 +910,8 @@ void intel_pmu_lbr_init_nhm(void); · 42 unmodified lines
907910
908911 void intel_pmu_lbr_init_atom(void);
909912
913+void intel_pmu_lbr_init_slm(void);
914+
910915 void intel_pmu_lbr_init_snb(void);
911916
912917 void intel_pmu_lbr_init_hsw(void);
arch/x86/include/asm/cpufeatures.h+2−0
@@ -177,6 +177,7 @@ · 176 unmodified lines
177177 #define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
178178 #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */
179179 #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */
180+#define X86_FEATURE_PTSC ( 6*32+27) /* performance time-stamp counter */
180181 #define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */
181182 #define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
182183
@@ -250,6 +251,7 @@ · 67 unmodified lines
250251
251252 /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
252253 #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
254+#define X86_FEATURE_IRPERF (13*32+1) /* Instructions Retired Count */
253255
254256 /* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
255257 #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
arch/x86/include/asm/msr-index.h+15−20
@@ -89,27 +89,16 @@ · 88 unmodified lines
8989 #define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6
9090
9191 #define MSR_IA32_RTIT_CTL 0x00000570
92−#define RTIT_CTL_TRACEEN BIT(0)
93−#define RTIT_CTL_CYCLEACC BIT(1)
94−#define RTIT_CTL_OS BIT(2)
95−#define RTIT_CTL_USR BIT(3)
96−#define RTIT_CTL_CR3EN BIT(7)
97−#define RTIT_CTL_TOPA BIT(8)
98−#define RTIT_CTL_MTC_EN BIT(9)
99−#define RTIT_CTL_TSC_EN BIT(10)
100−#define RTIT_CTL_DISRETC BIT(11)
101−#define RTIT_CTL_BRANCH_EN BIT(13)
102−#define RTIT_CTL_MTC_RANGE_OFFSET 14
103−#define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET)
104−#define RTIT_CTL_CYC_THRESH_OFFSET 19
105−#define RTIT_CTL_CYC_THRESH (0x0full << RTIT_CTL_CYC_THRESH_OFFSET)
106−#define RTIT_CTL_PSB_FREQ_OFFSET 24
107−#define RTIT_CTL_PSB_FREQ (0x0full << RTIT_CTL_PSB_FREQ_OFFSET)
10892 #define MSR_IA32_RTIT_STATUS 0x00000571
109−#define RTIT_STATUS_CONTEXTEN BIT(1)
110−#define RTIT_STATUS_TRIGGEREN BIT(2)
111−#define RTIT_STATUS_ERROR BIT(4)
112−#define RTIT_STATUS_STOPPED BIT(5)
93+#define MSR_IA32_RTIT_STATUS 0x00000571
94+#define MSR_IA32_RTIT_ADDR0_A 0x00000580
95+#define MSR_IA32_RTIT_ADDR0_B 0x00000581
96+#define MSR_IA32_RTIT_ADDR1_A 0x00000582
97+#define MSR_IA32_RTIT_ADDR1_B 0x00000583
98+#define MSR_IA32_RTIT_ADDR2_A 0x00000584
99+#define MSR_IA32_RTIT_ADDR2_B 0x00000585
100+#define MSR_IA32_RTIT_ADDR3_A 0x00000586
101+#define MSR_IA32_RTIT_ADDR3_B 0x00000587
113102 #define MSR_IA32_RTIT_CR3_MATCH 0x00000572
114103 #define MSR_IA32_RTIT_OUTPUT_BASE 0x00000560
115104 #define MSR_IA32_RTIT_OUTPUT_MASK 0x00000561
@@ -205,6 +194,8 @@ · 89 unmodified lines
205194 #define MSR_CONFIG_TDP_CONTROL 0x0000064B
206195 #define MSR_TURBO_ACTIVATION_RATIO 0x0000064C
207196
197+#define MSR_PLATFORM_ENERGY_STATUS 0x0000064D
198+
208199 #define MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
209200 #define MSR_PKG_ANY_CORE_C0_RES 0x00000659
210201 #define MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
@@ -315,6 +306,9 @@ · 104 unmodified lines
315306 #define MSR_AMD64_IBSOPDATA4 0xc001103d
316307 #define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
317308
309+/* Fam 17h MSRs */
310+#define MSR_F17H_IRPERF 0xc00000e9
311+
318312 /* Fam 16h MSRs */
319313 #define MSR_F16H_L2I_PERF_CTL 0xc0010230
320314 #define MSR_F16H_L2I_PERF_CTR 0xc0010231
@@ -328,6 +322,7 @@ · 7 unmodified lines
328322 #define MSR_F15H_PERF_CTR 0xc0010201
329323 #define MSR_F15H_NB_PERF_CTL 0xc0010240
330324 #define MSR_F15H_NB_PERF_CTR 0xc0010241
325+#define MSR_F15H_PTSC 0xc0010280
331326 #define MSR_F15H_IC_CFG 0xc0011021
332327
333328 /* Fam 10h MSRs */
arch/x86/kernel/uprobes.c+2−2
@@ -578,7 +578,7 @@ static void default_abort_op(struct arch_uprobe *auprobe, struct pt_regs *regs) · 577 unmodified lines
578578 riprel_post_xol(auprobe, regs);
579579 }
580580
581−static struct uprobe_xol_ops default_xol_ops = {
581+static const struct uprobe_xol_ops default_xol_ops = {
582582 .pre_xol = default_pre_xol_op,
583583 .post_xol = default_post_xol_op,
584584 .abort = default_abort_op,
@@ -695,7 +695,7 @@ static void branch_clear_offset(struct arch_uprobe *auprobe, struct insn *insn) · 110 unmodified lines
695695 0, insn->immediate.nbytes);
696696 }
697697
698−static struct uprobe_xol_ops branch_xol_ops = {
698+static const struct uprobe_xol_ops branch_xol_ops = {
699699 .emulate = branch_emulate_op,
700700 .post_xol = branch_post_xol_op,
701701 };
arch/xtensa/kernel/perf_event.c+2−2
@@ -332,14 +332,14 @@ static int callchain_trace(struct stackframe *frame, void *data) · 331 unmodified lines
332332 void perf_callchain_kernel(struct perf_callchain_entry *entry,
333333 struct pt_regs *regs)
334334 {
335− xtensa_backtrace_kernel(regs, PERF_MAX_STACK_DEPTH,
335+ xtensa_backtrace_kernel(regs, sysctl_perf_event_max_stack,
336336 callchain_trace, NULL, entry);
337337 }
338338
339339 void perf_callchain_user(struct perf_callchain_entry *entry,
340340 struct pt_regs *regs)
341341 {
342− xtensa_backtrace_user(regs, PERF_MAX_STACK_DEPTH,
342+ xtensa_backtrace_user(regs, sysctl_perf_event_max_stack,
343343 callchain_trace, entry);
344344 }
345345
drivers/perf/arm_pmu.c+8−0
@@ -847,6 +847,14 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu) · 846 unmodified lines
847847 if (!platform_get_irq(cpu_pmu->plat_device, 0))
848848 cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
849849
850+ /*
851+ * This is a CPU PMU potentially in a heterogeneous configuration (e.g.
852+ * big.LITTLE). This is not an uncore PMU, and we have taken ctx
853+ * sharing into account (e.g. with our pmu::filter_match callback and
854+ * pmu::event_init group validation).
855+ */
856+ cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_HETEROGENEOUS_CPUS;
857+
850858 return 0;
851859
852860 out_unregister:
drivers/powercap/intel_rapl.c+69−0
@@ -34,6 +34,9 @@ · 33 unmodified lines
3434 #include <asm/processor.h>
3535 #include <asm/cpu_device_id.h>
3636
37+/* Local defines */
38+#define MSR_PLATFORM_POWER_LIMIT 0x0000065C
39+
3740 /* bitmasks for RAPL MSRs, used by primitive access functions */
3841 #define ENERGY_STATUS_MASK 0xffffffff
3942
@@ -86,6 +89,7 @@ enum rapl_domain_type { · 46 unmodified lines
8689 RAPL_DOMAIN_PP0, /* core power plane */
8790 RAPL_DOMAIN_PP1, /* graphics uncore */
8891 RAPL_DOMAIN_DRAM,/* DRAM control_type */
92+ RAPL_DOMAIN_PLATFORM, /* PSys control_type */
8993 RAPL_DOMAIN_MAX,
9094 };
9195
@@ -251,9 +255,11 @@ static const char * const rapl_domain_names[] = { · 159 unmodified lines
251255 "core",
252256 "uncore",
253257 "dram",
258+ "psys",
254259 };
255260
256261 static struct powercap_control_type *control_type; /* PowerCap Controller */
262+static struct rapl_domain *platform_rapl_domain; /* Platform (PSys) domain */
257263
258264 /* caller to ensure CPU hotplug lock is held */
259265 static struct rapl_package *find_package_by_id(int id)
@@ -409,6 +415,14 @@ static const struct powercap_zone_ops zone_ops[] = { · 149 unmodified lines
409415 .set_enable = set_domain_enable,
410416 .get_enable = get_domain_enable,
411417 },
418+ /* RAPL_DOMAIN_PLATFORM */
419+ {
420+ .get_energy_uj = get_energy_counter,
421+ .get_max_energy_range_uj = get_max_energy_counter,
422+ .release = release_zone,
423+ .set_enable = set_domain_enable,
424+ .get_enable = get_domain_enable,
425+ },
412426 };
413427
414428 static int set_power_limit(struct powercap_zone *power_zone, int id,
@@ -1160,6 +1174,13 @@ static int rapl_unregister_powercap(void) · 745 unmodified lines
11601174 powercap_unregister_zone(control_type,
11611175 &rd_package->power_zone);
11621176 }
1177+
1178+ if (platform_rapl_domain) {
1179+ powercap_unregister_zone(control_type,
1180+ &platform_rapl_domain->power_zone);
1181+ kfree(platform_rapl_domain);
1182+ }
1183+
11631184 powercap_unregister_control_type(control_type);
11641185
11651186 return 0;
@@ -1239,6 +1260,47 @@ err_cleanup: · 73 unmodified lines
12391260 return ret;
12401261 }
12411262
1263+static int rapl_register_psys(void)
1264+{
1265+ struct rapl_domain *rd;
1266+ struct powercap_zone *power_zone;
1267+ u64 val;
1268+
1269+ if (rdmsrl_safe_on_cpu(0, MSR_PLATFORM_ENERGY_STATUS, &val) || !val)
1270+ return -ENODEV;
1271+
1272+ if (rdmsrl_safe_on_cpu(0, MSR_PLATFORM_POWER_LIMIT, &val) || !val)
1273+ return -ENODEV;
1274+
1275+ rd = kzalloc(sizeof(*rd), GFP_KERNEL);
1276+ if (!rd)
1277+ return -ENOMEM;
1278+
1279+ rd->name = rapl_domain_names[RAPL_DOMAIN_PLATFORM];
1280+ rd->id = RAPL_DOMAIN_PLATFORM;
1281+ rd->msrs[0] = MSR_PLATFORM_POWER_LIMIT;
1282+ rd->msrs[1] = MSR_PLATFORM_ENERGY_STATUS;
1283+ rd->rpl[0].prim_id = PL1_ENABLE;
1284+ rd->rpl[0].name = pl1_name;
1285+ rd->rpl[1].prim_id = PL2_ENABLE;
1286+ rd->rpl[1].name = pl2_name;
1287+ rd->rp = find_package_by_id(0);
1288+
1289+ power_zone = powercap_register_zone(&rd->power_zone, control_type,
1290+ "psys", NULL,
1291+ &zone_ops[RAPL_DOMAIN_PLATFORM],
1292+ 2, &constraint_ops);
1293+
1294+ if (IS_ERR(power_zone)) {
1295+ kfree(rd);
1296+ return PTR_ERR(power_zone);
1297+ }
1298+
1299+ platform_rapl_domain = rd;
1300+
1301+ return 0;
1302+}
1303+
12421304 static int rapl_register_powercap(void)
12431305 {
12441306 struct rapl_domain *rd;
@@ -1255,6 +1317,10 @@ static int rapl_register_powercap(void) · 10 unmodified lines
12551317 list_for_each_entry(rp, &rapl_packages, plist)
12561318 if (rapl_package_register_powercap(rp))
12571319 goto err_cleanup_package;
1320+
1321+ /* Don't bail out if PSys is not supported */
1322+ rapl_register_psys();
1323+
12581324 return ret;
12591325
12601326 err_cleanup_package:
@@ -1289,6 +1355,9 @@ static int rapl_check_domain(int cpu, int domain) · 28 unmodified lines
12891355 case RAPL_DOMAIN_DRAM:
12901356 msr = MSR_DRAM_ENERGY_STATUS;
12911357 break;
1358+ case RAPL_DOMAIN_PLATFORM:
1359+ /* PSYS(PLATFORM) is not a CPU domain, so avoid printng error */
1360+ return -EINVAL;
12921361 default:
12931362 pr_err("invalid domain id %d\n", domain);
12941363 return -EINVAL;
include/linux/perf_event.h+135−4
@@ -58,7 +58,7 @@ struct perf_guest_info_callbacks { · 57 unmodified lines
5858
5959 struct perf_callchain_entry {
6060 __u64 nr;
61− __u64 ip[PERF_MAX_STACK_DEPTH];
61+ __u64 ip[0]; /* /proc/sys/kernel/perf_event_max_stack */
6262 };
6363
6464 struct perf_raw_record {
@@ -151,6 +151,15 @@ struct hw_perf_event { · 86 unmodified lines
151151 */
152152 struct task_struct *target;
153153
154+ /*
155+ * PMU would store hardware filter configuration
156+ * here.
157+ */
158+ void *addr_filters;
159+
160+ /* Last sync'ed generation of filters */
161+ unsigned long addr_filters_gen;
162+
154163 /*
155164 * hw_perf_event::state flags; used to track the PERF_EF_* state.
156165 */
@@ -216,6 +225,7 @@ struct perf_event; · 59 unmodified lines
216225 #define PERF_PMU_CAP_AUX_SW_DOUBLEBUF 0x08
217226 #define PERF_PMU_CAP_EXCLUSIVE 0x10
218227 #define PERF_PMU_CAP_ITRACE 0x20
228+#define PERF_PMU_CAP_HETEROGENEOUS_CPUS 0x40
219229
220230 /**
221231 * struct pmu - generic performance monitoring unit
@@ -240,6 +250,9 @@ struct pmu { · 18 unmodified lines
240250 int task_ctx_nr;
241251 int hrtimer_interval_ms;
242252
253+ /* number of address filters this PMU can do */
254+ unsigned int nr_addr_filters;
255+
243256 /*
244257 * Fully disable/enable this PMU, can be used to protect from the PMI
245258 * as well as for lazy/batch writing of the MSRs.
@@ -392,12 +405,71 @@ struct pmu { · 146 unmodified lines
392405 */
393406 void (*free_aux) (void *aux); /* optional */
394407
408+ /*
409+ * Validate address range filters: make sure the HW supports the
410+ * requested configuration and number of filters; return 0 if the
411+ * supplied filters are valid, -errno otherwise.
412+ *
413+ * Runs in the context of the ioctl()ing process and is not serialized
414+ * with the rest of the PMU callbacks.
415+ */
416+ int (*addr_filters_validate) (struct list_head *filters);
417+ /* optional */
418+
419+ /*
420+ * Synchronize address range filter configuration:
421+ * translate hw-agnostic filters into hardware configuration in
422+ * event::hw::addr_filters.
423+ *
424+ * Runs as a part of filter sync sequence that is done in ->start()
425+ * callback by calling perf_event_addr_filters_sync().
426+ *
427+ * May (and should) traverse event::addr_filters::list, for which its
428+ * caller provides necessary serialization.
429+ */
430+ void (*addr_filters_sync) (struct perf_event *event);
431+ /* optional */
432+
395433 /*
396434 * Filter events for PMU-specific reasons.
397435 */
398436 int (*filter_match) (struct perf_event *event); /* optional */
399437 };
400438
439+/**
440+ * struct perf_addr_filter - address range filter definition
441+ * @entry: event's filter list linkage
442+ * @inode: object file's inode for file-based filters
443+ * @offset: filter range offset
444+ * @size: filter range size
445+ * @range: 1: range, 0: address
446+ * @filter: 1: filter/start, 0: stop
447+ *
448+ * This is a hardware-agnostic filter configuration as specified by the user.
449+ */
450+struct perf_addr_filter {
451+ struct list_head entry;
452+ struct inode *inode;
453+ unsigned long offset;
454+ unsigned long size;
455+ unsigned int range : 1,
456+ filter : 1;
457+};
458+
459+/**
460+ * struct perf_addr_filters_head - container for address range filters
461+ * @list: list of filters for this event
462+ * @lock: spinlock that serializes accesses to the @list and event's
463+ * (and its children's) filter generations.
464+ *
465+ * A child event will use parent's @list (and therefore @lock), so they are
466+ * bundled together; see perf_event_addr_filters().
467+ */
468+struct perf_addr_filters_head {
469+ struct list_head list;
470+ raw_spinlock_t lock;
471+};
472+
401473 /**
402474 * enum perf_event_active_state - the states of a event
403475 */
@@ -566,6 +638,12 @@ struct perf_event { · 162 unmodified lines
566638
567639 atomic_t event_limit;
568640
641+ /* address range filters */
642+ struct perf_addr_filters_head addr_filters;
643+ /* vma address array for file-based filders */
644+ unsigned long *addr_filters_offs;
645+ unsigned long addr_filters_gen;
646+
569647 void (*destroy)(struct perf_event *);
570648 struct rcu_head rcu_head;
571649
@@ -834,9 +912,25 @@ extern int perf_event_overflow(struct perf_event *event, · 262 unmodified lines
834912 struct perf_sample_data *data,
835913 struct pt_regs *regs);
836914
915+extern void perf_event_output_forward(struct perf_event *event,
916+ struct perf_sample_data *data,
917+ struct pt_regs *regs);
918+extern void perf_event_output_backward(struct perf_event *event,
919+ struct perf_sample_data *data,
920+ struct pt_regs *regs);
837921 extern void perf_event_output(struct perf_event *event,
838− struct perf_sample_data *data,
839− struct pt_regs *regs);
922+ struct perf_sample_data *data,
923+ struct pt_regs *regs);
924+
925+static inline bool
926+is_default_overflow_handler(struct perf_event *event)
927+{
928+ if (likely(event->overflow_handler == perf_event_output_forward))
929+ return true;
930+ if (unlikely(event->overflow_handler == perf_event_output_backward))
931+ return true;
932+ return false;
933+}
840934
841935 extern void
842936 perf_event_header__init_id(struct perf_event_header *header,
@@ -977,9 +1071,11 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, · 134 unmodified lines
9771071 extern int get_callchain_buffers(void);
9781072 extern void put_callchain_buffers(void);
9791073
1074+extern int sysctl_perf_event_max_stack;
1075+
9801076 static inline int perf_callchain_store(struct perf_callchain_entry *entry, u64 ip)
9811077 {
982− if (entry->nr < PERF_MAX_STACK_DEPTH) {
1078+ if (entry->nr < sysctl_perf_event_max_stack) {
9831079 entry->ip[entry->nr++] = ip;
9841080 return 0;
9851081 } else {
@@ -1001,6 +1097,8 @@ extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, · 15 unmodified lines
10011097 void __user *buffer, size_t *lenp,
10021098 loff_t *ppos);
10031099
1100+int perf_event_max_stack_handler(struct ctl_table *table, int write,
1101+ void __user *buffer, size_t *lenp, loff_t *ppos);
10041102
10051103 static inline bool perf_paranoid_tracepoint_raw(void)
10061104 {
@@ -1045,8 +1143,41 @@ static inline bool has_aux(struct perf_event *event) · 38 unmodified lines
10451143 return event->pmu->setup_aux;
10461144 }
10471145
1146+static inline bool is_write_backward(struct perf_event *event)
1147+{
1148+ return !!event->attr.write_backward;
1149+}
1150+
1151+static inline bool has_addr_filter(struct perf_event *event)
1152+{
1153+ return event->pmu->nr_addr_filters;
1154+}
1155+
1156+/*
1157+ * An inherited event uses parent's filters
1158+ */
1159+static inline struct perf_addr_filters_head *
1160+perf_event_addr_filters(struct perf_event *event)
1161+{
1162+ struct perf_addr_filters_head *ifh = &event->addr_filters;
1163+
1164+ if (event->parent)
1165+ ifh = &event->parent->addr_filters;
1166+
1167+ return ifh;
1168+}
1169+
1170+extern void perf_event_addr_filters_sync(struct perf_event *event);
1171+
10481172 extern int perf_output_begin(struct perf_output_handle *handle,
10491173 struct perf_event *event, unsigned int size);
1174+extern int perf_output_begin_forward(struct perf_output_handle *handle,
1175+ struct perf_event *event,
1176+ unsigned int size);
1177+extern int perf_output_begin_backward(struct perf_output_handle *handle,
1178+ struct perf_event *event,
1179+ unsigned int size);
1180+
10501181 extern void perf_output_end(struct perf_output_handle *handle);
10511182 extern unsigned int perf_output_copy(struct perf_output_handle *handle,
10521183 const void *buf, unsigned int len);
include/uapi/linux/perf_event.h+3−1
@@ -340,7 +340,8 @@ struct perf_event_attr { · 339 unmodified lines
340340 comm_exec : 1, /* flag comm events that are due to an exec */
341341 use_clockid : 1, /* use @clockid for time fields */
342342 context_switch : 1, /* context switch data */
343− __reserved_1 : 37;
343+ write_backward : 1, /* Write ring buffer from end to beginning */
344+ __reserved_1 : 36;
344345
345346 union {
346347 __u32 wakeup_events; /* wakeup every n events */
@@ -401,6 +402,7 @@ struct perf_event_attr { · 54 unmodified lines
401402 #define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
402403 #define PERF_EVENT_IOC_ID _IOR('$', 7, __u64 *)
403404 #define PERF_EVENT_IOC_SET_BPF _IOW('$', 8, __u32)
405+#define PERF_EVENT_IOC_PAUSE_OUTPUT _IOW('$', 9, __u32)
404406
405407 enum perf_event_ioc_flags {
406408 PERF_IOC_FLAG_GROUP = 1U << 0,
kernel/bpf/stackmap.c+4−4
@@ -66,7 +66,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) · 65 unmodified lines
6666 /* check sanity of attributes */
6767 if (attr->max_entries == 0 || attr->key_size != 4 ||
6868 value_size < 8 || value_size % 8 ||
69− value_size / 8 > PERF_MAX_STACK_DEPTH)
69+ value_size / 8 > sysctl_perf_event_max_stack)
7070 return ERR_PTR(-EINVAL);
7171
7272 /* hash table size must be power of 2 */
@@ -124,8 +124,8 @@ static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5) · 51 unmodified lines
124124 struct perf_callchain_entry *trace;
125125 struct stack_map_bucket *bucket, *new_bucket, *old_bucket;
126126 u32 max_depth = map->value_size / 8;
127− /* stack_map_alloc() checks that max_depth <= PERF_MAX_STACK_DEPTH */
128− u32 init_nr = PERF_MAX_STACK_DEPTH - max_depth;
127+ /* stack_map_alloc() checks that max_depth <= sysctl_perf_event_max_stack */
128+ u32 init_nr = sysctl_perf_event_max_stack - max_depth;
129129 u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
130130 u32 hash, id, trace_nr, trace_len;
131131 bool user = flags & BPF_F_USER_STACK;
@@ -143,7 +143,7 @@ static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5) · 11 unmodified lines
143143 return -EFAULT;
144144
145145 /* get_perf_callchain() guarantees that trace->nr >= init_nr
146− * and trace-nr <= PERF_MAX_STACK_DEPTH, so trace_nr <= max_depth
146+ * and trace-nr <= sysctl_perf_event_max_stack, so trace_nr <= max_depth
147147 */
148148 trace_nr = trace->nr - init_nr;
149149
kernel/events/callchain.c+33−2
@@ -18,6 +18,14 @@ struct callchain_cpus_entries { · 17 unmodified lines
1818 struct perf_callchain_entry *cpu_entries[0];
1919 };
2020
21+int sysctl_perf_event_max_stack __read_mostly = PERF_MAX_STACK_DEPTH;
22+
23+static inline size_t perf_callchain_entry__sizeof(void)
24+{
25+ return (sizeof(struct perf_callchain_entry) +
26+ sizeof(__u64) * sysctl_perf_event_max_stack);
27+}
28+
2129 static DEFINE_PER_CPU(int, callchain_recursion[PERF_NR_CONTEXTS]);
2230 static atomic_t nr_callchain_events;
2331 static DEFINE_MUTEX(callchain_mutex);
@@ -73,7 +81,7 @@ static int alloc_callchain_buffers(void) · 49 unmodified lines
7381 if (!entries)
7482 return -ENOMEM;
7583
76− size = sizeof(struct perf_callchain_entry) * PERF_NR_CONTEXTS;
84+ size = perf_callchain_entry__sizeof() * PERF_NR_CONTEXTS;
7785
7886 for_each_possible_cpu(cpu) {
7987 entries->cpu_entries[cpu] = kmalloc_node(size, GFP_KERNEL,
@@ -147,7 +155,8 @@ static struct perf_callchain_entry *get_callchain_entry(int *rctx) · 67 unmodified lines
147155
148156 cpu = smp_processor_id();
149157
150− return &entries->cpu_entries[cpu][*rctx];
158+ return (((void *)entries->cpu_entries[cpu]) +
159+ (*rctx * perf_callchain_entry__sizeof()));
151160 }
152161
153162 static void
@@ -215,3 +224,25 @@ exit_put: · 61 unmodified lines
215224
216225 return entry;
217226 }
227+
228+int perf_event_max_stack_handler(struct ctl_table *table, int write,
229+ void __user *buffer, size_t *lenp, loff_t *ppos)
230+{
231+ int new_value = sysctl_perf_event_max_stack, ret;
232+ struct ctl_table new_table = *table;
233+
234+ new_table.data = &new_value;
235+ ret = proc_dointvec_minmax(&new_table, write, buffer, lenp, ppos);
236+ if (ret || !write)
237+ return ret;
238+
239+ mutex_lock(&callchain_mutex);
240+ if (atomic_read(&nr_callchain_events))
241+ ret = -EBUSY;
242+ else
243+ sysctl_perf_event_max_stack = new_value;
244+
245+ mutex_unlock(&callchain_mutex);
246+
247+ return ret;
248+}
kernel/events/core.c+857−54
@@ -44,6 +44,8 @@ · 43 unmodified lines
4444 #include <linux/compat.h>
4545 #include <linux/bpf.h>
4646 #include <linux/filter.h>
47+#include <linux/namei.h>
48+#include <linux/parser.h>
4749
4850 #include "internal.h"
4951
@@ -1927,8 +1929,13 @@ event_sched_in(struct perf_event *event, · 1877 unmodified lines
19271929 if (event->state <= PERF_EVENT_STATE_OFF)
19281930 return 0;
19291931
1930− event->state = PERF_EVENT_STATE_ACTIVE;
1931− event->oncpu = smp_processor_id();
1932+ WRITE_ONCE(event->oncpu, smp_processor_id());
1933+ /*
1934+ * Order event::oncpu write to happen before the ACTIVE state
1935+ * is visible.
1936+ */
1937+ smp_wmb();
1938+ WRITE_ONCE(event->state, PERF_EVENT_STATE_ACTIVE);
19321939
19331940 /*
19341941 * Unthrottle events, since we scheduled we might have missed several
@@ -2360,6 +2367,112 @@ void perf_event_enable(struct perf_event *event) · 425 unmodified lines
23602367 }
23612368 EXPORT_SYMBOL_GPL(perf_event_enable);
23622369
2370+struct stop_event_data {
2371+ struct perf_event *event;
2372+ unsigned int restart;
2373+};
2374+
2375+static int __perf_event_stop(void *info)
2376+{
2377+ struct stop_event_data *sd = info;
2378+ struct perf_event *event = sd->event;
2379+
2380+ /* if it's already INACTIVE, do nothing */
2381+ if (READ_ONCE(event->state) != PERF_EVENT_STATE_ACTIVE)
2382+ return 0;
2383+
2384+ /* matches smp_wmb() in event_sched_in() */
2385+ smp_rmb();
2386+
2387+ /*
2388+ * There is a window with interrupts enabled before we get here,
2389+ * so we need to check again lest we try to stop another CPU's event.
2390+ */
2391+ if (READ_ONCE(event->oncpu) != smp_processor_id())
2392+ return -EAGAIN;
2393+
2394+ event->pmu->stop(event, PERF_EF_UPDATE);
2395+
2396+ /*
2397+ * May race with the actual stop (through perf_pmu_output_stop()),
2398+ * but it is only used for events with AUX ring buffer, and such
2399+ * events will refuse to restart because of rb::aux_mmap_count==0,
2400+ * see comments in perf_aux_output_begin().
2401+ *
2402+ * Since this is happening on a event-local CPU, no trace is lost
2403+ * while restarting.
2404+ */
2405+ if (sd->restart)
2406+ event->pmu->start(event, PERF_EF_START);
2407+
2408+ return 0;
2409+}
2410+
2411+static int perf_event_restart(struct perf_event *event)
2412+{
2413+ struct stop_event_data sd = {
2414+ .event = event,
2415+ .restart = 1,
2416+ };
2417+ int ret = 0;
2418+
2419+ do {
2420+ if (READ_ONCE(event->state) != PERF_EVENT_STATE_ACTIVE)
2421+ return 0;
2422+
2423+ /* matches smp_wmb() in event_sched_in() */
2424+ smp_rmb();
2425+
2426+ /*
2427+ * We only want to restart ACTIVE events, so if the event goes
2428+ * inactive here (event->oncpu==-1), there's nothing more to do;
2429+ * fall through with ret==-ENXIO.
2430+ */
2431+ ret = cpu_function_call(READ_ONCE(event->oncpu),
2432+ __perf_event_stop, &sd);
2433+ } while (ret == -EAGAIN);
2434+
2435+ return ret;
2436+}
2437+
2438+/*
2439+ * In order to contain the amount of racy and tricky in the address filter
2440+ * configuration management, it is a two part process:
2441+ *
2442+ * (p1) when userspace mappings change as a result of (1) or (2) or (3) below,
2443+ * we update the addresses of corresponding vmas in
2444+ * event::addr_filters_offs array and bump the event::addr_filters_gen;
2445+ * (p2) when an event is scheduled in (pmu::add), it calls
2446+ * perf_event_addr_filters_sync() which calls pmu::addr_filters_sync()
2447+ * if the generation has changed since the previous call.
2448+ *
2449+ * If (p1) happens while the event is active, we restart it to force (p2).
2450+ *
2451+ * (1) perf_addr_filters_apply(): adjusting filters' offsets based on
2452+ * pre-existing mappings, called once when new filters arrive via SET_FILTER
2453+ * ioctl;
2454+ * (2) perf_addr_filters_adjust(): adjusting filters' offsets based on newly
2455+ * registered mapping, called for every new mmap(), with mm::mmap_sem down
2456+ * for reading;
2457+ * (3) perf_event_addr_filters_exec(): clearing filters' offsets in the process
2458+ * of exec.
2459+ */
2460+void perf_event_addr_filters_sync(struct perf_event *event)
2461+{
2462+ struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
2463+
2464+ if (!has_addr_filter(event))
2465+ return;
2466+
2467+ raw_spin_lock(&ifh->lock);
2468+ if (event->addr_filters_gen != event->hw.addr_filters_gen) {
2469+ event->pmu->addr_filters_sync(event);
2470+ event->hw.addr_filters_gen = event->addr_filters_gen;
2471+ }
2472+ raw_spin_unlock(&ifh->lock);
2473+}
2474+EXPORT_SYMBOL_GPL(perf_event_addr_filters_sync);
2475+
23632476 static int _perf_event_refresh(struct perf_event *event, int refresh)
23642477 {
23652478 /*
@@ -3209,16 +3322,6 @@ out: · 843 unmodified lines
32093322 put_ctx(clone_ctx);
32103323 }
32113324
3212−void perf_event_exec(void)
3213−{
3214− int ctxn;
3215−
3216− rcu_read_lock();
3217− for_each_task_context_nr(ctxn)
3218− perf_event_enable_on_exec(ctxn);
3219− rcu_read_unlock();
3220−}
3221−
32223325 struct perf_read_data {
32233326 struct perf_event *event;
32243327 bool group;
@@ -3720,6 +3823,9 @@ static bool exclusive_event_installable(struct perf_event *event, · 495 unmodified lines
37203823 return true;
37213824 }
37223825
3826+static void perf_addr_filters_splice(struct perf_event *event,
3827+ struct list_head *head);
3828+
37233829 static void _free_event(struct perf_event *event)
37243830 {
37253831 irq_work_sync(&event->pending);
@@ -3747,6 +3853,8 @@ static void _free_event(struct perf_event *event) · 21 unmodified lines
37473853 }
37483854
37493855 perf_event_free_bpf_prog(event);
3856+ perf_addr_filters_splice(event, NULL);
3857+ kfree(event->addr_filters_offs);
37503858
37513859 if (event->destroy)
37523860 event->destroy(event);
@@ -4343,6 +4451,19 @@ static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned lon · 590 unmodified lines
43434451 case PERF_EVENT_IOC_SET_BPF:
43444452 return perf_event_set_bpf_prog(event, arg);
43454453
4454+ case PERF_EVENT_IOC_PAUSE_OUTPUT: {
4455+ struct ring_buffer *rb;
4456+
4457+ rcu_read_lock();
4458+ rb = rcu_dereference(event->rb);
4459+ if (!rb || !rb->nr_pages) {
4460+ rcu_read_unlock();
4461+ return -EINVAL;
4462+ }
4463+ rb_toggle_paused(rb, !!arg);
4464+ rcu_read_unlock();
4465+ return 0;
4466+ }
43464467 default:
43474468 return -ENOTTY;
43484469 }
@@ -4659,6 +4780,8 @@ static void perf_mmap_open(struct vm_area_struct *vma) · 310 unmodified lines
46594780 event->pmu->event_mapped(event);
46604781 }
46614782
4783+static void perf_pmu_output_stop(struct perf_event *event);
4784+
46624785 /*
46634786 * A buffer can be mmap()ed multiple times; either directly through the same
46644787 * event, or through other events by use of perf_event_set_output().
@@ -4686,10 +4809,22 @@ static void perf_mmap_close(struct vm_area_struct *vma) · 21 unmodified lines
46864809 */
46874810 if (rb_has_aux(rb) && vma->vm_pgoff == rb->aux_pgoff &&
46884811 atomic_dec_and_mutex_lock(&rb->aux_mmap_count, &event->mmap_mutex)) {
4812+ /*
4813+ * Stop all AUX events that are writing to this buffer,
4814+ * so that we can free its AUX pages and corresponding PMU
4815+ * data. Note that after rb::aux_mmap_count dropped to zero,
4816+ * they won't start any more (see perf_aux_output_begin()).
4817+ */
4818+ perf_pmu_output_stop(event);
4819+
4820+ /* now it's safe to free the pages */
46894821 atomic_long_sub(rb->aux_nr_pages, &mmap_user->locked_vm);
46904822 vma->vm_mm->pinned_vm -= rb->aux_mmap_locked;
46914823
4824+ /* this has to be the last one */
46924825 rb_free_aux(rb);
4826+ WARN_ON_ONCE(atomic_read(&rb->aux_refcount));
4827+
46934828 mutex_unlock(&event->mmap_mutex);
46944829 }
46954830
@@ -5630,9 +5765,13 @@ void perf_prepare_sample(struct perf_event_header *header, · 934 unmodified lines
56305765 }
56315766 }
56325767
5633−void perf_event_output(struct perf_event *event,
5634− struct perf_sample_data *data,
5635− struct pt_regs *regs)
5768+static void __always_inline
5769+__perf_event_output(struct perf_event *event,
5770+ struct perf_sample_data *data,
5771+ struct pt_regs *regs,
5772+ int (*output_begin)(struct perf_output_handle *,
5773+ struct perf_event *,
5774+ unsigned int))
56365775 {
56375776 struct perf_output_handle handle;
56385777 struct perf_event_header header;
@@ -5642,7 +5781,7 @@ void perf_event_output(struct perf_event *event, · 3 unmodified lines
56425781
56435782 perf_prepare_sample(&header, data, event, regs);
56445783
5645− if (perf_output_begin(&handle, event, header.size))
5784+ if (output_begin(&handle, event, header.size))
56465785 goto exit;
56475786
56485787 perf_output_sample(&handle, &header, data, event);
@@ -5653,6 +5792,30 @@ exit: · 4 unmodified lines
56535792 rcu_read_unlock();
56545793 }
56555794
5795+void
5796+perf_event_output_forward(struct perf_event *event,
5797+ struct perf_sample_data *data,
5798+ struct pt_regs *regs)
5799+{
5800+ __perf_event_output(event, data, regs, perf_output_begin_forward);
5801+}
5802+
5803+void
5804+perf_event_output_backward(struct perf_event *event,
5805+ struct perf_sample_data *data,
5806+ struct pt_regs *regs)
5807+{
5808+ __perf_event_output(event, data, regs, perf_output_begin_backward);
5809+}
5810+
5811+void
5812+perf_event_output(struct perf_event *event,
5813+ struct perf_sample_data *data,
5814+ struct pt_regs *regs)
5815+{
5816+ __perf_event_output(event, data, regs, perf_output_begin);
5817+}
5818+
56565819 /*
56575820 * read event_id
56585821 */
@@ -5698,15 +5861,18 @@ typedef void (perf_event_aux_output_cb)(struct perf_event *event, void *data); · 39 unmodified lines
56985861 static void
56995862 perf_event_aux_ctx(struct perf_event_context *ctx,
57005863 perf_event_aux_output_cb output,
5701− void *data)
5864+ void *data, bool all)
57025865 {
57035866 struct perf_event *event;
57045867
57055868 list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
5706− if (event->state < PERF_EVENT_STATE_INACTIVE)
5707− continue;
5708− if (!event_filter_match(event))
5709− continue;
5869+ if (!all) {
5870+ if (event->state < PERF_EVENT_STATE_INACTIVE)
5871+ continue;
5872+ if (!event_filter_match(event))
5873+ continue;
5874+ }
5875+
57105876 output(event, data);
57115877 }
57125878 }
@@ -5717,7 +5883,7 @@ perf_event_aux_task_ctx(perf_event_aux_output_cb output, void *data, · 4 unmodified lines
57175883 {
57185884 rcu_read_lock();
57195885 preempt_disable();
5720− perf_event_aux_ctx(task_ctx, output, data);
5886+ perf_event_aux_ctx(task_ctx, output, data, false);
57215887 preempt_enable();
57225888 rcu_read_unlock();
57235889 }
@@ -5747,19 +5913,147 @@ perf_event_aux(perf_event_aux_output_cb output, void *data, · 23 unmodified lines
57475913 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
57485914 if (cpuctx->unique_pmu != pmu)
57495915 goto next;
5750− perf_event_aux_ctx(&cpuctx->ctx, output, data);
5916+ perf_event_aux_ctx(&cpuctx->ctx, output, data, false);
57515917 ctxn = pmu->task_ctx_nr;
57525918 if (ctxn < 0)
57535919 goto next;
57545920 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
57555921 if (ctx)
5756− perf_event_aux_ctx(ctx, output, data);
5922+ perf_event_aux_ctx(ctx, output, data, false);
57575923 next:
57585924 put_cpu_ptr(pmu->pmu_cpu_context);
57595925 }
57605926 rcu_read_unlock();
57615927 }
57625928
5929+/*
5930+ * Clear all file-based filters at exec, they'll have to be
5931+ * re-instated when/if these objects are mmapped again.
5932+ */
5933+static void perf_event_addr_filters_exec(struct perf_event *event, void *data)
5934+{
5935+ struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
5936+ struct perf_addr_filter *filter;
5937+ unsigned int restart = 0, count = 0;
5938+ unsigned long flags;
5939+
5940+ if (!has_addr_filter(event))
5941+ return;
5942+
5943+ raw_spin_lock_irqsave(&ifh->lock, flags);
5944+ list_for_each_entry(filter, &ifh->list, entry) {
5945+ if (filter->inode) {
5946+ event->addr_filters_offs[count] = 0;
5947+ restart++;
5948+ }
5949+
5950+ count++;
5951+ }
5952+
5953+ if (restart)
5954+ event->addr_filters_gen++;
5955+ raw_spin_unlock_irqrestore(&ifh->lock, flags);
5956+
5957+ if (restart)
5958+ perf_event_restart(event);
5959+}
5960+
5961+void perf_event_exec(void)
5962+{
5963+ struct perf_event_context *ctx;
5964+ int ctxn;
5965+
5966+ rcu_read_lock();
5967+ for_each_task_context_nr(ctxn) {
5968+ ctx = current->perf_event_ctxp[ctxn];
5969+ if (!ctx)
5970+ continue;
5971+
5972+ perf_event_enable_on_exec(ctxn);
5973+
5974+ perf_event_aux_ctx(ctx, perf_event_addr_filters_exec, NULL,
5975+ true);
5976+ }
5977+ rcu_read_unlock();
5978+}
5979+
5980+struct remote_output {
5981+ struct ring_buffer *rb;
5982+ int err;
5983+};
5984+
5985+static void __perf_event_output_stop(struct perf_event *event, void *data)
5986+{
5987+ struct perf_event *parent = event->parent;
5988+ struct remote_output *ro = data;
5989+ struct ring_buffer *rb = ro->rb;
5990+ struct stop_event_data sd = {
5991+ .event = event,
5992+ };
5993+
5994+ if (!has_aux(event))
5995+ return;
5996+
5997+ if (!parent)
5998+ parent = event;
5999+
6000+ /*
6001+ * In case of inheritance, it will be the parent that links to the
6002+ * ring-buffer, but it will be the child that's actually using it:
6003+ */
6004+ if (rcu_dereference(parent->rb) == rb)
6005+ ro->err = __perf_event_stop(&sd);
6006+}
6007+
6008+static int __perf_pmu_output_stop(void *info)
6009+{
6010+ struct perf_event *event = info;
6011+ struct pmu *pmu = event->pmu;
6012+ struct perf_cpu_context *cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
6013+ struct remote_output ro = {
6014+ .rb = event->rb,
6015+ };
6016+
6017+ rcu_read_lock();
6018+ perf_event_aux_ctx(&cpuctx->ctx, __perf_event_output_stop, &ro, false);
6019+ if (cpuctx->task_ctx)
6020+ perf_event_aux_ctx(cpuctx->task_ctx, __perf_event_output_stop,
6021+ &ro, false);
6022+ rcu_read_unlock();
6023+
6024+ return ro.err;
6025+}
6026+
6027+static void perf_pmu_output_stop(struct perf_event *event)
6028+{
6029+ struct perf_event *iter;
6030+ int err, cpu;
6031+
6032+restart:
6033+ rcu_read_lock();
6034+ list_for_each_entry_rcu(iter, &event->rb->event_list, rb_entry) {
6035+ /*
6036+ * For per-CPU events, we need to make sure that neither they
6037+ * nor their children are running; for cpu==-1 events it's
6038+ * sufficient to stop the event itself if it's active, since
6039+ * it can't have children.
6040+ */
6041+ cpu = iter->cpu;
6042+ if (cpu == -1)
6043+ cpu = READ_ONCE(iter->oncpu);
6044+
6045+ if (cpu == -1)
6046+ continue;
6047+
6048+ err = cpu_function_call(cpu, __perf_pmu_output_stop, event);
6049+ if (err == -EAGAIN) {
6050+ rcu_read_unlock();
6051+ goto restart;
6052+ }
6053+ }
6054+ rcu_read_unlock();
6055+}
6056+
57636057 /*
57646058 * task tracking -- fork/exit
57656059 *
@@ -6169,6 +6463,87 @@ got_name: · 403 unmodified lines
61696463 kfree(buf);
61706464 }
61716465
6466+/*
6467+ * Whether this @filter depends on a dynamic object which is not loaded
6468+ * yet or its load addresses are not known.
6469+ */
6470+static bool perf_addr_filter_needs_mmap(struct perf_addr_filter *filter)
6471+{
6472+ return filter->filter && filter->inode;
6473+}
6474+
6475+/*
6476+ * Check whether inode and address range match filter criteria.
6477+ */
6478+static bool perf_addr_filter_match(struct perf_addr_filter *filter,
6479+ struct file *file, unsigned long offset,
6480+ unsigned long size)
6481+{
6482+ if (filter->inode != file->f_inode)
6483+ return false;
6484+
6485+ if (filter->offset > offset + size)
6486+ return false;
6487+
6488+ if (filter->offset + filter->size < offset)
6489+ return false;
6490+
6491+ return true;
6492+}
6493+
6494+static void __perf_addr_filters_adjust(struct perf_event *event, void *data)
6495+{
6496+ struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
6497+ struct vm_area_struct *vma = data;
6498+ unsigned long off = vma->vm_pgoff << PAGE_SHIFT, flags;
6499+ struct file *file = vma->vm_file;
6500+ struct perf_addr_filter *filter;
6501+ unsigned int restart = 0, count = 0;
6502+
6503+ if (!has_addr_filter(event))
6504+ return;
6505+
6506+ if (!file)
6507+ return;
6508+
6509+ raw_spin_lock_irqsave(&ifh->lock, flags);
6510+ list_for_each_entry(filter, &ifh->list, entry) {
6511+ if (perf_addr_filter_match(filter, file, off,
6512+ vma->vm_end - vma->vm_start)) {
6513+ event->addr_filters_offs[count] = vma->vm_start;
6514+ restart++;
6515+ }
6516+
6517+ count++;
6518+ }
6519+
6520+ if (restart)
6521+ event->addr_filters_gen++;
6522+ raw_spin_unlock_irqrestore(&ifh->lock, flags);
6523+
6524+ if (restart)
6525+ perf_event_restart(event);
6526+}
6527+
6528+/*
6529+ * Adjust all task's events' filters to the new vma
6530+ */
6531+static void perf_addr_filters_adjust(struct vm_area_struct *vma)
6532+{
6533+ struct perf_event_context *ctx;
6534+ int ctxn;
6535+
6536+ rcu_read_lock();
6537+ for_each_task_context_nr(ctxn) {
6538+ ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
6539+ if (!ctx)
6540+ continue;
6541+
6542+ perf_event_aux_ctx(ctx, __perf_addr_filters_adjust, vma, true);
6543+ }
6544+ rcu_read_unlock();
6545+}
6546+
61726547 void perf_event_mmap(struct vm_area_struct *vma)
61736548 {
61746549 struct perf_mmap_event mmap_event;
@@ -6200,6 +6575,7 @@ void perf_event_mmap(struct vm_area_struct *vma) · 25 unmodified lines
62006575 /* .flags (attr_mmap2 only) */
62016576 };
62026577
6578+ perf_addr_filters_adjust(vma);
62036579 perf_event_mmap_event(&mmap_event);
62046580 }
62056581
@@ -6491,10 +6867,7 @@ static int __perf_event_overflow(struct perf_event *event, · 285 unmodified lines
64916867 irq_work_queue(&event->pending);
64926868 }
64936869
6494− if (event->overflow_handler)
6495− event->overflow_handler(event, data, regs);
6496− else
6497− perf_event_output(event, data, regs);
6870+ event->overflow_handler(event, data, regs);
64986871
64996872 if (*perf_event_fasync(event) && event->pending_kill) {
65006873 event->pending_wakeup = 1;
@@ -7081,24 +7454,6 @@ static inline void perf_tp_register(void) · 580 unmodified lines
70817454 perf_pmu_register(&perf_tracepoint, "tracepoint", PERF_TYPE_TRACEPOINT);
70827455 }
70837456
7084−static int perf_event_set_filter(struct perf_event *event, void __user *arg)
7085−{
7086− char *filter_str;
7087− int ret;
7088−
7089− if (event->attr.type != PERF_TYPE_TRACEPOINT)
7090− return -EINVAL;
7091−
7092− filter_str = strndup_user(arg, PAGE_SIZE);
7093− if (IS_ERR(filter_str))
7094− return PTR_ERR(filter_str);
7095−
7096− ret = ftrace_profile_set_filter(event, event->attr.config, filter_str);
7097−
7098− kfree(filter_str);
7099− return ret;
7100−}
7101−
71027457 static void perf_event_free_filter(struct perf_event *event)
71037458 {
71047459 ftrace_profile_free_filter(event);
@@ -7153,11 +7508,6 @@ static inline void perf_tp_register(void) · 48 unmodified lines
71537508 {
71547509 }
71557510
7156−static int perf_event_set_filter(struct perf_event *event, void __user *arg)
7157−{
7158− return -ENOENT;
7159−}
7160−
71617511 static void perf_event_free_filter(struct perf_event *event)
71627512 {
71637513 }
@@ -7185,6 +7535,387 @@ void perf_bp_event(struct perf_event *bp, void *data) · 21 unmodified lines
71857535 }
71867536 #endif
71877537
7538+/*
7539+ * Allocate a new address filter
7540+ */
7541+static struct perf_addr_filter *
7542+perf_addr_filter_new(struct perf_event *event, struct list_head *filters)
7543+{
7544+ int node = cpu_to_node(event->cpu == -1 ? 0 : event->cpu);
7545+ struct perf_addr_filter *filter;
7546+
7547+ filter = kzalloc_node(sizeof(*filter), GFP_KERNEL, node);
7548+ if (!filter)
7549+ return NULL;
7550+
7551+ INIT_LIST_HEAD(&filter->entry);
7552+ list_add_tail(&filter->entry, filters);
7553+
7554+ return filter;
7555+}
7556+
7557+static void free_filters_list(struct list_head *filters)
7558+{
7559+ struct perf_addr_filter *filter, *iter;
7560+
7561+ list_for_each_entry_safe(filter, iter, filters, entry) {
7562+ if (filter->inode)
7563+ iput(filter->inode);
7564+ list_del(&filter->entry);
7565+ kfree(filter);
7566+ }
7567+}
7568+
7569+/*
7570+ * Free existing address filters and optionally install new ones
7571+ */
7572+static void perf_addr_filters_splice(struct perf_event *event,
7573+ struct list_head *head)
7574+{
7575+ unsigned long flags;
7576+ LIST_HEAD(list);
7577+
7578+ if (!has_addr_filter(event))
7579+ return;
7580+
7581+ /* don't bother with children, they don't have their own filters */
7582+ if (event->parent)
7583+ return;
7584+
7585+ raw_spin_lock_irqsave(&event->addr_filters.lock, flags);
7586+
7587+ list_splice_init(&event->addr_filters.list, &list);
7588+ if (head)
7589+ list_splice(head, &event->addr_filters.list);
7590+
7591+ raw_spin_unlock_irqrestore(&event->addr_filters.lock, flags);
7592+
7593+ free_filters_list(&list);
7594+}
7595+
7596+/*
7597+ * Scan through mm's vmas and see if one of them matches the
7598+ * @filter; if so, adjust filter's address range.
7599+ * Called with mm::mmap_sem down for reading.
7600+ */
7601+static unsigned long perf_addr_filter_apply(struct perf_addr_filter *filter,
7602+ struct mm_struct *mm)
7603+{
7604+ struct vm_area_struct *vma;
7605+
7606+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
7607+ struct file *file = vma->vm_file;
7608+ unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
7609+ unsigned long vma_size = vma->vm_end - vma->vm_start;
7610+
7611+ if (!file)
7612+ continue;
7613+
7614+ if (!perf_addr_filter_match(filter, file, off, vma_size))
7615+ continue;
7616+
7617+ return vma->vm_start;
7618+ }
7619+
7620+ return 0;
7621+}
7622+
7623+/*
7624+ * Update event's address range filters based on the
7625+ * task's existing mappings, if any.
7626+ */
7627+static void perf_event_addr_filters_apply(struct perf_event *event)
7628+{
7629+ struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
7630+ struct task_struct *task = READ_ONCE(event->ctx->task);
7631+ struct perf_addr_filter *filter;
7632+ struct mm_struct *mm = NULL;
7633+ unsigned int count = 0;
7634+ unsigned long flags;
7635+
7636+ /*
7637+ * We may observe TASK_TOMBSTONE, which means that the event tear-down
7638+ * will stop on the parent's child_mutex that our caller is also holding
7639+ */
7640+ if (task == TASK_TOMBSTONE)
7641+ return;
7642+
7643+ mm = get_task_mm(event->ctx->task);
7644+ if (!mm)
7645+ goto restart;
7646+
7647+ down_read(&mm->mmap_sem);
7648+
7649+ raw_spin_lock_irqsave(&ifh->lock, flags);
7650+ list_for_each_entry(filter, &ifh->list, entry) {
7651+ event->addr_filters_offs[count] = 0;
7652+
7653+ if (perf_addr_filter_needs_mmap(filter))
7654+ event->addr_filters_offs[count] =
7655+ perf_addr_filter_apply(filter, mm);
7656+
7657+ count++;
7658+ }
7659+
7660+ event->addr_filters_gen++;
7661+ raw_spin_unlock_irqrestore(&ifh->lock, flags);
7662+
7663+ up_read(&mm->mmap_sem);
7664+
7665+ mmput(mm);
7666+
7667+restart:
7668+ perf_event_restart(event);
7669+}
7670+
7671+/*
7672+ * Address range filtering: limiting the data to certain
7673+ * instruction address ranges. Filters are ioctl()ed to us from
7674+ * userspace as ascii strings.
7675+ *
7676+ * Filter string format:
7677+ *
7678+ * ACTION RANGE_SPEC
7679+ * where ACTION is one of the
7680+ * * "filter": limit the trace to this region
7681+ * * "start": start tracing from this address
7682+ * * "stop": stop tracing at this address/region;
7683+ * RANGE_SPEC is
7684+ * * for kernel addresses: <start address>[/<size>]
7685+ * * for object files: <start address>[/<size>]@</path/to/object/file>
7686+ *
7687+ * if <size> is not specified, the range is treated as a single address.
7688+ */
7689+enum {
7690+ IF_ACT_FILTER,
7691+ IF_ACT_START,
7692+ IF_ACT_STOP,
7693+ IF_SRC_FILE,
7694+ IF_SRC_KERNEL,
7695+ IF_SRC_FILEADDR,
7696+ IF_SRC_KERNELADDR,
7697+};
7698+
7699+enum {
7700+ IF_STATE_ACTION = 0,
7701+ IF_STATE_SOURCE,
7702+ IF_STATE_END,
7703+};
7704+
7705+static const match_table_t if_tokens = {
7706+ { IF_ACT_FILTER, "filter" },
7707+ { IF_ACT_START, "start" },
7708+ { IF_ACT_STOP, "stop" },
7709+ { IF_SRC_FILE, "%u/%u@%s" },
7710+ { IF_SRC_KERNEL, "%u/%u" },
7711+ { IF_SRC_FILEADDR, "%u@%s" },
7712+ { IF_SRC_KERNELADDR, "%u" },
7713+};
7714+
7715+/*
7716+ * Address filter string parser
7717+ */
7718+static int
7719+perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
7720+ struct list_head *filters)
7721+{
7722+ struct perf_addr_filter *filter = NULL;
7723+ char *start, *orig, *filename = NULL;
7724+ struct path path;
7725+ substring_t args[MAX_OPT_ARGS];
7726+ int state = IF_STATE_ACTION, token;
7727+ unsigned int kernel = 0;
7728+ int ret = -EINVAL;
7729+
7730+ orig = fstr = kstrdup(fstr, GFP_KERNEL);
7731+ if (!fstr)
7732+ return -ENOMEM;
7733+
7734+ while ((start = strsep(&fstr, " ,\n")) != NULL) {
7735+ ret = -EINVAL;
7736+
7737+ if (!*start)
7738+ continue;
7739+
7740+ /* filter definition begins */
7741+ if (state == IF_STATE_ACTION) {
7742+ filter = perf_addr_filter_new(event, filters);
7743+ if (!filter)
7744+ goto fail;
7745+ }
7746+
7747+ token = match_token(start, if_tokens, args);
7748+ switch (token) {
7749+ case IF_ACT_FILTER:
7750+ case IF_ACT_START:
7751+ filter->filter = 1;
7752+
7753+ case IF_ACT_STOP:
7754+ if (state != IF_STATE_ACTION)
7755+ goto fail;
7756+
7757+ state = IF_STATE_SOURCE;
7758+ break;
7759+
7760+ case IF_SRC_KERNELADDR:
7761+ case IF_SRC_KERNEL:
7762+ kernel = 1;
7763+
7764+ case IF_SRC_FILEADDR:
7765+ case IF_SRC_FILE:
7766+ if (state != IF_STATE_SOURCE)
7767+ goto fail;
7768+
7769+ if (token == IF_SRC_FILE || token == IF_SRC_KERNEL)
7770+ filter->range = 1;
7771+
7772+ *args[0].to = 0;
7773+ ret = kstrtoul(args[0].from, 0, &filter->offset);
7774+ if (ret)
7775+ goto fail;
7776+
7777+ if (filter->range) {
7778+ *args[1].to = 0;
7779+ ret = kstrtoul(args[1].from, 0, &filter->size);
7780+ if (ret)
7781+ goto fail;
7782+ }
7783+
7784+ if (token == IF_SRC_FILE) {
7785+ filename = match_strdup(&args[2]);
7786+ if (!filename) {
7787+ ret = -ENOMEM;
7788+ goto fail;
7789+ }
7790+ }
7791+
7792+ state = IF_STATE_END;
7793+ break;
7794+
7795+ default:
7796+ goto fail;
7797+ }
7798+
7799+ /*
7800+ * Filter definition is fully parsed, validate and install it.
7801+ * Make sure that it doesn't contradict itself or the event's
7802+ * attribute.
7803+ */
7804+ if (state == IF_STATE_END) {
7805+ if (kernel && event->attr.exclude_kernel)
7806+ goto fail;
7807+
7808+ if (!kernel) {
7809+ if (!filename)
7810+ goto fail;
7811+
7812+ /* look up the path and grab its inode */
7813+ ret = kern_path(filename, LOOKUP_FOLLOW, &path);
7814+ if (ret)
7815+ goto fail_free_name;
7816+
7817+ filter->inode = igrab(d_inode(path.dentry));
7818+ path_put(&path);
7819+ kfree(filename);
7820+ filename = NULL;
7821+
7822+ ret = -EINVAL;
7823+ if (!filter->inode ||
7824+ !S_ISREG(filter->inode->i_mode))
7825+ /* free_filters_list() will iput() */
7826+ goto fail;
7827+ }
7828+
7829+ /* ready to consume more filters */
7830+ state = IF_STATE_ACTION;
7831+ filter = NULL;
7832+ }
7833+ }
7834+
7835+ if (state != IF_STATE_ACTION)
7836+ goto fail;
7837+
7838+ kfree(orig);
7839+
7840+ return 0;
7841+
7842+fail_free_name:
7843+ kfree(filename);
7844+fail:
7845+ free_filters_list(filters);
7846+ kfree(orig);
7847+
7848+ return ret;
7849+}
7850+
7851+static int
7852+perf_event_set_addr_filter(struct perf_event *event, char *filter_str)
7853+{
7854+ LIST_HEAD(filters);
7855+ int ret;
7856+
7857+ /*
7858+ * Since this is called in perf_ioctl() path, we're already holding
7859+ * ctx::mutex.
7860+ */
7861+ lockdep_assert_held(&event->ctx->mutex);
7862+
7863+ if (WARN_ON_ONCE(event->parent))
7864+ return -EINVAL;
7865+
7866+ /*
7867+ * For now, we only support filtering in per-task events; doing so
7868+ * for CPU-wide events requires additional context switching trickery,
7869+ * since same object code will be mapped at different virtual
7870+ * addresses in different processes.
7871+ */
7872+ if (!event->ctx->task)
7873+ return -EOPNOTSUPP;
7874+
7875+ ret = perf_event_parse_addr_filter(event, filter_str, &filters);
7876+ if (ret)
7877+ return ret;
7878+
7879+ ret = event->pmu->addr_filters_validate(&filters);
7880+ if (ret) {
7881+ free_filters_list(&filters);
7882+ return ret;
7883+ }
7884+
7885+ /* remove existing filters, if any */
7886+ perf_addr_filters_splice(event, &filters);
7887+
7888+ /* install new filters */
7889+ perf_event_for_each_child(event, perf_event_addr_filters_apply);
7890+
7891+ return ret;
7892+}
7893+
7894+static int perf_event_set_filter(struct perf_event *event, void __user *arg)
7895+{
7896+ char *filter_str;
7897+ int ret = -EINVAL;
7898+
7899+ if ((event->attr.type != PERF_TYPE_TRACEPOINT ||
7900+ !IS_ENABLED(CONFIG_EVENT_TRACING)) &&
7901+ !has_addr_filter(event))
7902+ return -EINVAL;
7903+
7904+ filter_str = strndup_user(arg, PAGE_SIZE);
7905+ if (IS_ERR(filter_str))
7906+ return PTR_ERR(filter_str);
7907+
7908+ if (IS_ENABLED(CONFIG_EVENT_TRACING) &&
7909+ event->attr.type == PERF_TYPE_TRACEPOINT)
7910+ ret = ftrace_profile_set_filter(event, event->attr.config,
7911+ filter_str);
7912+ else if (has_addr_filter(event))
7913+ ret = perf_event_set_addr_filter(event, filter_str);
7914+
7915+ kfree(filter_str);
7916+ return ret;
7917+}
7918+
71887919 /*
71897920 * hrtimer based swevent callback
71907921 */
@@ -7542,6 +8273,20 @@ static void free_pmu_context(struct pmu *pmu) · 351 unmodified lines
75428273 out:
75438274 mutex_unlock(&pmus_lock);
75448275 }
8276+
8277+/*
8278+ * Let userspace know that this PMU supports address range filtering:
8279+ */
8280+static ssize_t nr_addr_filters_show(struct device *dev,
8281+ struct device_attribute *attr,
8282+ char *page)
8283+{
8284+ struct pmu *pmu = dev_get_drvdata(dev);
8285+
8286+ return snprintf(page, PAGE_SIZE - 1, "%d\n", pmu->nr_addr_filters);
8287+}
8288+DEVICE_ATTR_RO(nr_addr_filters);
8289+
75458290 static struct idr pmu_idr;
75468291
75478292 static ssize_t
@@ -7643,9 +8388,19 @@ static int pmu_dev_alloc(struct pmu *pmu) · 95 unmodified lines
76438388 if (ret)
76448389 goto free_dev;
76458390
8391+ /* For PMUs with address filters, throw in an extra attribute: */
8392+ if (pmu->nr_addr_filters)
8393+ ret = device_create_file(pmu->dev, &dev_attr_nr_addr_filters);
8394+
8395+ if (ret)
8396+ goto del_dev;
8397+
76468398 out:
76478399 return ret;
76488400
8401+del_dev:
8402+ device_del(pmu->dev);
8403+
76498404 free_dev:
76508405 put_device(pmu->dev);
76518406 goto out;
@@ -7685,6 +8440,21 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type) · 33 unmodified lines
76858440 }
76868441
76878442 skip_type:
8443+ if (pmu->task_ctx_nr == perf_hw_context) {
8444+ static int hw_context_taken = 0;
8445+
8446+ /*
8447+ * Other than systems with heterogeneous CPUs, it never makes
8448+ * sense for two PMUs to share perf_hw_context. PMUs which are
8449+ * uncore must use perf_invalid_context.
8450+ */
8451+ if (WARN_ON_ONCE(hw_context_taken &&
8452+ !(pmu->capabilities & PERF_PMU_CAP_HETEROGENEOUS_CPUS)))
8453+ pmu->task_ctx_nr = perf_invalid_context;
8454+
8455+ hw_context_taken = 1;
8456+ }
8457+
76888458 pmu->pmu_cpu_context = find_pmu_context(pmu->task_ctx_nr);
76898459 if (pmu->pmu_cpu_context)
76908460 goto got_cpu_context;
@@ -7772,6 +8542,8 @@ void perf_pmu_unregister(struct pmu *pmu) · 81 unmodified lines
77728542 free_percpu(pmu->pmu_disable_count);
77738543 if (pmu->type >= PERF_TYPE_MAX)
77748544 idr_remove(&pmu_idr, pmu->type);
8545+ if (pmu->nr_addr_filters)
8546+ device_remove_file(pmu->dev, &dev_attr_nr_addr_filters);
77758547 device_del(pmu->dev);
77768548 put_device(pmu->dev);
77778549 free_pmu_context(pmu);
@@ -7965,6 +8737,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, · 187 unmodified lines
79658737 INIT_LIST_HEAD(&event->sibling_list);
79668738 INIT_LIST_HEAD(&event->rb_entry);
79678739 INIT_LIST_HEAD(&event->active_entry);
8740+ INIT_LIST_HEAD(&event->addr_filters.list);
79688741 INIT_HLIST_NODE(&event->hlist_entry);
79698742
79708743
@@ -7972,6 +8745,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, · 1 unmodified line
79728745 init_irq_work(&event->pending, perf_pending_event);
79738746
79748747 mutex_init(&event->mmap_mutex);
8748+ raw_spin_lock_init(&event->addr_filters.lock);
79758749
79768750 atomic_long_set(&event->refcount, 1);
79778751 event->cpu = cpu;
@@ -8006,8 +8780,16 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, · 28 unmodified lines
80068780 context = parent_event->overflow_handler_context;
80078781 }
80088782
8009− event->overflow_handler = overflow_handler;
8010− event->overflow_handler_context = context;
8783+ if (overflow_handler) {
8784+ event->overflow_handler = overflow_handler;
8785+ event->overflow_handler_context = context;
8786+ } else if (is_write_backward(event)){
8787+ event->overflow_handler = perf_event_output_backward;
8788+ event->overflow_handler_context = NULL;
8789+ } else {
8790+ event->overflow_handler = perf_event_output_forward;
8791+ event->overflow_handler_context = NULL;
8792+ }
80118793
80128794 perf_event__state_init(event);
80138795
@@ -8048,11 +8830,22 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, · 34 unmodified lines
80488830 if (err)
80498831 goto err_pmu;
80508832
8833+ if (has_addr_filter(event)) {
8834+ event->addr_filters_offs = kcalloc(pmu->nr_addr_filters,
8835+ sizeof(unsigned long),
8836+ GFP_KERNEL);
8837+ if (!event->addr_filters_offs)
8838+ goto err_per_task;
8839+
8840+ /* force hw sync on the address filters */
8841+ event->addr_filters_gen = 1;
8842+ }
8843+
80518844 if (!event->parent) {
80528845 if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
80538846 err = get_callchain_buffers();
80548847 if (err)
8055− goto err_per_task;
8848+ goto err_addr_filters;
80568849 }
80578850 }
80588851
@@ -8061,6 +8854,9 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, · 2 unmodified lines
80618854
80628855 return event;
80638856
8857+err_addr_filters:
8858+ kfree(event->addr_filters_offs);
8859+
80648860 err_per_task:
80658861 exclusive_event_destroy(event);
80668862
@@ -8239,6 +9035,13 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event) · 172 unmodified lines
82399035 if (output_event->clock != event->clock)
82409036 goto out;
82419037
9038+ /*
9039+ * Either writing ring buffer from beginning or from end.
9040+ * Mixing is not allowed.
9041+ */
9042+ if (is_write_backward(output_event) != is_write_backward(event))
9043+ goto out;
9044+
82429045 /*
82439046 * If both events generate aux data, they must be on the same PMU
82449047 */
kernel/events/internal.h+9−1
@@ -11,13 +11,13 @@ · 10 unmodified lines
1111 struct ring_buffer {
1212 atomic_t refcount;
1313 struct rcu_head rcu_head;
14− struct irq_work irq_work;
1514 #ifdef CONFIG_PERF_USE_VMALLOC
1615 struct work_struct work;
1716 int page_order; /* allocation order */
1817 #endif
1918 int nr_pages; /* nr of data pages */
2019 int overwrite; /* can overwrite itself */
20+ int paused; /* can write into ring buffer */
2121
2222 atomic_t poll; /* POLL_ for wakeups */
2323
@@ -65,6 +65,14 @@ static inline void rb_free_rcu(struct rcu_head *rcu_head) · 41 unmodified lines
6565 rb_free(rb);
6666 }
6767
68+static inline void rb_toggle_paused(struct ring_buffer *rb, bool pause)
69+{
70+ if (!pause && rb->nr_pages)
71+ rb->paused = 0;
72+ else
73+ rb->paused = 1;
74+}
75+
6876 extern struct ring_buffer *
6977 rb_alloc(int nr_pages, long watermark, int cpu, int flags);
7078 extern void perf_event_wakeup(struct perf_event *event);
kernel/events/ring_buffer.c+87−31
@@ -102,8 +102,21 @@ out: · 101 unmodified lines
102102 preempt_enable();
103103 }
104104
105−int perf_output_begin(struct perf_output_handle *handle,
106− struct perf_event *event, unsigned int size)
105+static bool __always_inline
106+ring_buffer_has_space(unsigned long head, unsigned long tail,
107+ unsigned long data_size, unsigned int size,
108+ bool backward)
109+{
110+ if (!backward)
111+ return CIRC_SPACE(head, tail, data_size) >= size;
112+ else
113+ return CIRC_SPACE(tail, head, data_size) >= size;
114+}
115+
116+static int __always_inline
117+__perf_output_begin(struct perf_output_handle *handle,
118+ struct perf_event *event, unsigned int size,
119+ bool backward)
107120 {
108121 struct ring_buffer *rb;
109122 unsigned long tail, offset, head;
@@ -125,8 +138,11 @@ int perf_output_begin(struct perf_output_handle *handle, · 15 unmodified lines
125138 if (unlikely(!rb))
126139 goto out;
127140
128− if (unlikely(!rb->nr_pages))
141+ if (unlikely(rb->paused)) {
142+ if (rb->nr_pages)
143+ local_inc(&rb->lost);
129144 goto out;
145+ }
130146
131147 handle->rb = rb;
132148 handle->event = event;
@@ -143,9 +159,12 @@ int perf_output_begin(struct perf_output_handle *handle, · 10 unmodified lines
143159 do {
144160 tail = READ_ONCE(rb->user_page->data_tail);
145161 offset = head = local_read(&rb->head);
146− if (!rb->overwrite &&
147− unlikely(CIRC_SPACE(head, tail, perf_data_size(rb)) < size))
148− goto fail;
162+ if (!rb->overwrite) {
163+ if (unlikely(!ring_buffer_has_space(head, tail,
164+ perf_data_size(rb),
165+ size, backward)))
166+ goto fail;
167+ }
149168
150169 /*
151170 * The above forms a control dependency barrier separating the
@@ -159,9 +178,17 @@ int perf_output_begin(struct perf_output_handle *handle, · 7 unmodified lines
159178 * See perf_output_put_handle().
160179 */
161180
162− head += size;
181+ if (!backward)
182+ head += size;
183+ else
184+ head -= size;
163185 } while (local_cmpxchg(&rb->head, offset, head) != offset);
164186
187+ if (backward) {
188+ offset = head;
189+ head = (u64)(-head);
190+ }
191+
165192 /*
166193 * We rely on the implied barrier() by local_cmpxchg() to ensure
167194 * none of the data stores below can be lifted up by the compiler.
@@ -203,6 +230,26 @@ out: · 35 unmodified lines
203230 return -ENOSPC;
204231 }
205232
233+int perf_output_begin_forward(struct perf_output_handle *handle,
234+ struct perf_event *event, unsigned int size)
235+{
236+ return __perf_output_begin(handle, event, size, false);
237+}
238+
239+int perf_output_begin_backward(struct perf_output_handle *handle,
240+ struct perf_event *event, unsigned int size)
241+{
242+ return __perf_output_begin(handle, event, size, true);
243+}
244+
245+int perf_output_begin(struct perf_output_handle *handle,
246+ struct perf_event *event, unsigned int size)
247+{
248+
249+ return __perf_output_begin(handle, event, size,
250+ unlikely(is_write_backward(event)));
251+}
252+
206253 unsigned int perf_output_copy(struct perf_output_handle *handle,
207254 const void *buf, unsigned int len)
208255 {
@@ -221,8 +268,6 @@ void perf_output_end(struct perf_output_handle *handle) · 12 unmodified lines
221268 rcu_read_unlock();
222269 }
223270
224−static void rb_irq_work(struct irq_work *work);
225−
226271 static void
227272 ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
228273 {
@@ -243,16 +288,13 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags) · 14 unmodified lines
243288
244289 INIT_LIST_HEAD(&rb->event_list);
245290 spin_lock_init(&rb->event_lock);
246− init_irq_work(&rb->irq_work, rb_irq_work);
247−}
248291
249−static void ring_buffer_put_async(struct ring_buffer *rb)
250−{
251− if (!atomic_dec_and_test(&rb->refcount))
252− return;
253−
254− rb->rcu_head.next = (void *)rb;
255− irq_work_queue(&rb->irq_work);
292+ /*
293+ * perf_output_begin() only checks rb->paused, therefore
294+ * rb->paused must be true if we have no pages for output.
295+ */
296+ if (!rb->nr_pages)
297+ rb->paused = 1;
256298 }
257299
258300 /*
@@ -264,6 +306,10 @@ static void ring_buffer_put_async(struct ring_buffer *rb) · 5 unmodified lines
264306 * The ordering is similar to that of perf_output_{begin,end}, with
265307 * the exception of (B), which should be taken care of by the pmu
266308 * driver, since ordering rules will differ depending on hardware.
309+ *
310+ * Call this from pmu::start(); see the comment in perf_aux_output_end()
311+ * about its use in pmu callbacks. Both can also be called from the PMI
312+ * handler if needed.
267313 */
268314 void *perf_aux_output_begin(struct perf_output_handle *handle,
269315 struct perf_event *event)
@@ -287,6 +333,13 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, · 17 unmodified lines
287333 if (!rb_has_aux(rb) || !atomic_inc_not_zero(&rb->aux_refcount))
288334 goto err;
289335
336+ /*
337+ * If rb::aux_mmap_count is zero (and rb_has_aux() above went through),
338+ * the aux buffer is in perf_mmap_close(), about to get freed.
339+ */
340+ if (!atomic_read(&rb->aux_mmap_count))
341+ goto err_put;
342+
290343 /*
291344 * Nesting is not supported for AUX area, make sure nested
292345 * writers are caught early
@@ -328,10 +381,11 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, · 35 unmodified lines
328381 return handle->rb->aux_priv;
329382
330383 err_put:
384+ /* can't be last */
331385 rb_free_aux(rb);
332386
333387 err:
334− ring_buffer_put_async(rb);
388+ ring_buffer_put(rb);
335389 handle->event = NULL;
336390
337391 return NULL;
@@ -342,6 +396,10 @@ err: · 4 unmodified lines
342396 * aux_head and posting a PERF_RECORD_AUX into the perf buffer. It is the
343397 * pmu driver's responsibility to observe ordering rules of the hardware,
344398 * so that all the data is externally visible before this is called.
399+ *
400+ * Note: this has to be called from pmu::stop() callback, as the assumption
401+ * of the AUX buffer management code is that after pmu::stop(), the AUX
402+ * transaction must be stopped and therefore drop the AUX reference count.
345403 */
346404 void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
347405 bool truncated)
@@ -389,8 +447,9 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size, · 41 unmodified lines
389447 handle->event = NULL;
390448
391449 local_set(&rb->aux_nest, 0);
450+ /* can't be last */
392451 rb_free_aux(rb);
393− ring_buffer_put_async(rb);
452+ ring_buffer_put(rb);
394453 }
395454
396455 /*
@@ -471,6 +530,14 @@ static void __rb_free_aux(struct ring_buffer *rb) · 74 unmodified lines
471530 {
472531 int pg;
473532
533+ /*
534+ * Should never happen, the last reference should be dropped from
535+ * perf_mmap_close() path, which first stops aux transactions (which
536+ * in turn are the atomic holders of aux_refcount) and then does the
537+ * last rb_free_aux().
538+ */
539+ WARN_ON_ONCE(in_atomic());
540+
474541 if (rb->aux_priv) {
475542 rb->free_aux(rb->aux_priv);
476543 rb->free_aux = NULL;
@@ -582,18 +649,7 @@ out: · 105 unmodified lines
582649 void rb_free_aux(struct ring_buffer *rb)
583650 {
584651 if (atomic_dec_and_test(&rb->aux_refcount))
585− irq_work_queue(&rb->irq_work);
586−}
587−
588−static void rb_irq_work(struct irq_work *work)
589−{
590− struct ring_buffer *rb = container_of(work, struct ring_buffer, irq_work);
591−
592− if (!atomic_read(&rb->aux_refcount))
593652 __rb_free_aux(rb);
594−
595− if (rb->rcu_head.next == (void *)rb)
596− call_rcu(&rb->rcu_head, rb_free_rcu);
597653 }
598654
599655 #ifndef CONFIG_PERF_USE_VMALLOC
kernel/sysctl.c+12−0
@@ -130,6 +130,9 @@ static int one_thousand = 1000; · 129 unmodified lines
130130 #ifdef CONFIG_PRINTK
131131 static int ten_thousand = 10000;
132132 #endif
133+#ifdef CONFIG_PERF_EVENTS
134+static int six_hundred_forty_kb = 640 * 1024;
135+#endif
133136
134137 /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
135138 static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
@@ -1144,6 +1147,15 @@ static struct ctl_table kern_table[] = { · 1008 unmodified lines
11441147 .extra1 = &zero,
11451148 .extra2 = &one_hundred,
11461149 },
1150+ {
1151+ .procname = "perf_event_max_stack",
1152+ .data = NULL, /* filled in by handler */
1153+ .maxlen = sizeof(sysctl_perf_event_max_stack),
1154+ .mode = 0644,
1155+ .proc_handler = perf_event_max_stack_handler,
1156+ .extra1 = &zero,
1157+ .extra2 = &six_hundred_forty_kb,
1158+ },
11471159 #endif
11481160 #ifdef CONFIG_KMEMCHECK
11491161 {
kernel/trace/trace_event_perf.c+3−0
@@ -47,6 +47,9 @@ static int perf_trace_event_perm(struct trace_event_call *tp_event, · 46 unmodified lines
4747 if (perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN))
4848 return -EPERM;
4949
50+ if (!is_sampling_event(p_event))
51+ return 0;
52+
5053 /*
5154 * We don't allow user space callchains for function trace
5255 * event, due to issues with page faults while tracing page
tools/Makefile+2−1
@@ -137,7 +137,8 @@ libsubcmd_clean: · 136 unmodified lines
137137 $(call descend,lib/subcmd,clean)
138138
139139 perf_clean:
140− $(call descend,$(@:_clean=),clean)
140+ $(Q)mkdir -p $(PERF_O) .
141+ $(Q)$(MAKE) --no-print-directory -C perf O=$(PERF_O) subdir= clean
141142
142143 selftests_clean:
143144 $(call descend,testing/$(@:_clean=),clean)
tools/build/Makefile.feature+7−1
@@ -49,6 +49,10 @@ FEATURE_TESTS_BASIC := \ · 48 unmodified lines
4949 libslang \
5050 libcrypto \
5151 libunwind \
52+ libunwind-x86 \
53+ libunwind-x86_64 \
54+ libunwind-arm \
55+ libunwind-aarch64 \
5256 pthread-attr-setaffinity-np \
5357 stackprotector-all \
5458 timerfd \
@@ -69,7 +73,9 @@ FEATURE_TESTS_EXTRA := \ · 14 unmodified lines
6973 libbabeltrace \
7074 liberty \
7175 liberty-z \
72− libunwind-debug-frame
76+ libunwind-debug-frame \
77+ libunwind-debug-frame-arm \
78+ libunwind-debug-frame-aarch64
7379
7480 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
7581
tools/build/feature/Makefile+23−0
@@ -27,6 +27,12 @@ FILES= \ · 26 unmodified lines
2727 test-libcrypto.bin \
2828 test-libunwind.bin \
2929 test-libunwind-debug-frame.bin \
30+ test-libunwind-x86.bin \
31+ test-libunwind-x86_64.bin \
32+ test-libunwind-arm.bin \
33+ test-libunwind-aarch64.bin \
34+ test-libunwind-debug-frame-arm.bin \
35+ test-libunwind-debug-frame-aarch64.bin \
3036 test-pthread-attr-setaffinity-np.bin \
3137 test-stackprotector-all.bin \
3238 test-timerfd.bin \
@@ -103,6 +109,23 @@ $(OUTPUT)test-libunwind.bin: · 70 unmodified lines
103109
104110 $(OUTPUT)test-libunwind-debug-frame.bin:
105111 $(BUILD) -lelf
112+$(OUTPUT)test-libunwind-x86.bin:
113+ $(BUILD) -lelf -lunwind-x86
114+
115+$(OUTPUT)test-libunwind-x86_64.bin:
116+ $(BUILD) -lelf -lunwind-x86_64
117+
118+$(OUTPUT)test-libunwind-arm.bin:
119+ $(BUILD) -lelf -lunwind-arm
120+
121+$(OUTPUT)test-libunwind-aarch64.bin:
122+ $(BUILD) -lelf -lunwind-aarch64
123+
124+$(OUTPUT)test-libunwind-debug-frame-arm.bin:
125+ $(BUILD) -lelf -lunwind-arm
126+
127+$(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
128+ $(BUILD) -lelf -lunwind-aarch64
106129
107130 $(OUTPUT)test-libaudit.bin:
108131 $(BUILD) -laudit
tools/build/feature/test-bpf.c+1−2
@@ -27,10 +27,9 @@ int main(void) · 26 unmodified lines
2727 attr.log_level = 0;
2828 attr.kern_version = 0;
2929
30− attr = attr;
3130 /*
3231 * Test existence of __NR_bpf and BPF_PROG_LOAD.
3332 * This call should fail if we run the testcase.
3433 */
35− return syscall(__NR_bpf, BPF_PROG_LOAD, attr, sizeof(attr));
34+ return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
3635 }
tools/build/feature/test-libunwind-aarch64.c+26−0
@@ -0,0 +1,26 @@
1+#include <libunwind-aarch64.h>
2+#include <stdlib.h>
3+
4+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
5+ unw_word_t ip,
6+ unw_dyn_info_t *di,
7+ unw_proc_info_t *pi,
8+ int need_unwind_info, void *arg);
9+
10+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
11+
12+static unw_accessors_t accessors;
13+
14+int main(void)
15+{
16+ unw_addr_space_t addr_space;
17+
18+ addr_space = unw_create_addr_space(&accessors, 0);
19+ if (addr_space)
20+ return 0;
21+
22+ unw_init_remote(NULL, addr_space, NULL);
23+ dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
24+
25+ return 0;
26+}
tools/build/feature/test-libunwind-arm.c+27−0
@@ -0,0 +1,27 @@
1+#include <libunwind-arm.h>
2+#include <stdlib.h>
3+
4+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
5+ unw_word_t ip,
6+ unw_dyn_info_t *di,
7+ unw_proc_info_t *pi,
8+ int need_unwind_info, void *arg);
9+
10+
11+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
12+
13+static unw_accessors_t accessors;
14+
15+int main(void)
16+{
17+ unw_addr_space_t addr_space;
18+
19+ addr_space = unw_create_addr_space(&accessors, 0);
20+ if (addr_space)
21+ return 0;
22+
23+ unw_init_remote(NULL, addr_space, NULL);
24+ dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
25+
26+ return 0;
27+}
tools/build/feature/test-libunwind-debug-frame-aarch64.c+16−0
@@ -0,0 +1,16 @@
1+#include <libunwind-aarch64.h>
2+#include <stdlib.h>
3+
4+extern int
5+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
6+ unw_word_t ip, unw_word_t segbase,
7+ const char *obj_name, unw_word_t start,
8+ unw_word_t end);
9+
10+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
11+
12+int main(void)
13+{
14+ dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
15+ return 0;
16+}
tools/build/feature/test-libunwind-debug-frame-arm.c+16−0
@@ -0,0 +1,16 @@
1+#include <libunwind-arm.h>
2+#include <stdlib.h>
3+
4+extern int
5+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
6+ unw_word_t ip, unw_word_t segbase,
7+ const char *obj_name, unw_word_t start,
8+ unw_word_t end);
9+
10+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
11+
12+int main(void)
13+{
14+ dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
15+ return 0;
16+}
tools/build/feature/test-libunwind-x86.c+27−0
@@ -0,0 +1,27 @@
1+#include <libunwind-x86.h>
2+#include <stdlib.h>
3+
4+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
5+ unw_word_t ip,
6+ unw_dyn_info_t *di,
7+ unw_proc_info_t *pi,
8+ int need_unwind_info, void *arg);
9+
10+
11+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
12+
13+static unw_accessors_t accessors;
14+
15+int main(void)
16+{
17+ unw_addr_space_t addr_space;
18+
19+ addr_space = unw_create_addr_space(&accessors, 0);
20+ if (addr_space)
21+ return 0;
22+
23+ unw_init_remote(NULL, addr_space, NULL);
24+ dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
25+
26+ return 0;
27+}
tools/build/feature/test-libunwind-x86_64.c+27−0
@@ -0,0 +1,27 @@
1+#include <libunwind-x86_64.h>
2+#include <stdlib.h>
3+
4+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
5+ unw_word_t ip,
6+ unw_dyn_info_t *di,
7+ unw_proc_info_t *pi,
8+ int need_unwind_info, void *arg);
9+
10+
11+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
12+
13+static unw_accessors_t accessors;
14+
15+int main(void)
16+{
17+ unw_addr_space_t addr_space;
18+
19+ addr_space = unw_create_addr_space(&accessors, 0);
20+ if (addr_space)
21+ return 0;
22+
23+ unw_init_remote(NULL, addr_space, NULL);
24+ dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
25+
26+ return 0;
27+}
tools/lib/api/fs/fs.c+13−0
@@ -351,6 +351,19 @@ int filename__read_str(const char *filename, char **buf, size_t *sizep) · 350 unmodified lines
351351 return err;
352352 }
353353
354+int procfs__read_str(const char *entry, char **buf, size_t *sizep)
355+{
356+ char path[PATH_MAX];
357+ const char *procfs = procfs__mountpoint();
358+
359+ if (!procfs)
360+ return -1;
361+
362+ snprintf(path, sizeof(path), "%s/%s", procfs, entry);
363+
364+ return filename__read_str(path, buf, sizep);
365+}
366+
354367 int sysfs__read_ull(const char *entry, unsigned long long *value)
355368 {
356369 char path[PATH_MAX];
tools/lib/api/fs/fs.h+2−0
@@ -29,6 +29,8 @@ int filename__read_int(const char *filename, int *value); · 28 unmodified lines
2929 int filename__read_ull(const char *filename, unsigned long long *value);
3030 int filename__read_str(const char *filename, char **buf, size_t *sizep);
3131
32+int procfs__read_str(const char *entry, char **buf, size_t *sizep);
33+
3234 int sysctl__read_int(const char *sysctl, int *value);
3335 int sysfs__read_int(const char *entry, int *value);
3436 int sysfs__read_ull(const char *entry, unsigned long long *value);
tools/perf/Documentation/intel-pt.txt+7−0
@@ -672,6 +672,7 @@ The letters are: · 671 unmodified lines
672672 d create a debug log
673673 g synthesize a call chain (use with i or x)
674674 l synthesize last branch entries (use with i or x)
675+ s skip initial number of events
675676
676677 "Instructions" events look like they were recorded by "perf record -e
677678 instructions".
@@ -730,6 +731,12 @@ from one sample to the next. · 52 unmodified lines
730731
731732 To disable trace decoding entirely, use the option --no-itrace.
732733
734+It is also possible to skip events generated (instructions, branches, transactions)
735+at the beginning. This is useful to ignore initialization code.
736+
737+ --itrace=i0nss1000000
738+
739+skips the first million instructions.
733740
734741 dump option
735742 -----------
tools/perf/Documentation/itrace.txt+8−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 d create a debug log
88 g synthesize a call chain (use with i or x)
99 l synthesize last branch entries (use with i or x)
10+ s skip initial number of events
1011
1112 The default is all events i.e. the same as --itrace=ibxe
1213
@@ -24,3 +25,10 @@ · 11 unmodified lines
2425
2526 Also the number of last branch entries (default 64, max. 1024) for
2627 instructions or transactions events can be specified.
28+
29+ It is also possible to skip events generated (instructions, branches, transactions)
30+ at the beginning. This is useful to ignore initialization code.
31+
32+ --itrace=i0nss1000000
33+
34+ skips the first million instructions.
tools/perf/Documentation/perf-annotate.txt+1−1
@@ -33,7 +33,7 @@ OPTIONS · 32 unmodified lines
3333
3434 -f::
3535 --force::
36− Don't complain, do it.
36+ Don't do ownership validation.
3737
3838 -v::
3939 --verbose::
tools/perf/Documentation/perf-diff.txt+1−1
@@ -75,7 +75,7 @@ OPTIONS · 74 unmodified lines
7575
7676 -f::
7777 --force::
78− Don't complain, do it.
78+ Don't do ownership validation.
7979
8080 --symfs=<directory>::
8181 Look for files with symbols relative to this directory.
tools/perf/Documentation/perf-list.txt+106−1
@@ -93,6 +93,67 @@ raw encoding of 0x1A8 can be used: · 92 unmodified lines
9393 You should refer to the processor specific documentation for getting these
9494 details. Some of them are referenced in the SEE ALSO section below.
9595
96+ARBITRARY PMUS
97+--------------
98+
99+perf also supports an extended syntax for specifying raw parameters
100+to PMUs. Using this typically requires looking up the specific event
101+in the CPU vendor specific documentation.
102+
103+The available PMUs and their raw parameters can be listed with
104+
105+ ls /sys/devices/*/format
106+
107+For example the raw event "LSD.UOPS" core pmu event above could
108+be specified as
109+
110+ perf stat -e cpu/event=0xa8,umask=0x1,name=LSD.UOPS_CYCLES,cmask=1/ ...
111+
112+PER SOCKET PMUS
113+---------------
114+
115+Some PMUs are not associated with a core, but with a whole CPU socket.
116+Events on these PMUs generally cannot be sampled, but only counted globally
117+with perf stat -a. They can be bound to one logical CPU, but will measure
118+all the CPUs in the same socket.
119+
120+This example measures memory bandwidth every second
121+on the first memory controller on socket 0 of a Intel Xeon system
122+
123+ perf stat -C 0 -a uncore_imc_0/cas_count_read/,uncore_imc_0/cas_count_write/ -I 1000 ...
124+
125+Each memory controller has its own PMU. Measuring the complete system
126+bandwidth would require specifying all imc PMUs (see perf list output),
127+and adding the values together.
128+
129+This example measures the combined core power every second
130+
131+ perf stat -I 1000 -e power/energy-cores/ -a
132+
133+ACCESS RESTRICTIONS
134+-------------------
135+
136+For non root users generally only context switched PMU events are available.
137+This is normally only the events in the cpu PMU, the predefined events
138+like cycles and instructions and some software events.
139+
140+Other PMUs and global measurements are normally root only.
141+Some event qualifiers, such as "any", are also root only.
142+
143+This can be overriden by setting the kernel.perf_event_paranoid
144+sysctl to -1, which allows non root to use these events.
145+
146+For accessing trace point events perf needs to have read access to
147+/sys/kernel/debug/tracing, even when perf_event_paranoid is in a relaxed
148+setting.
149+
150+TRACING
151+-------
152+
153+Some PMUs control advanced hardware tracing capabilities, such as Intel PT,
154+that allows low overhead execution tracing. These are described in a separate
155+intel-pt.txt document.
156+
96157 PARAMETERIZED EVENTS
97158 --------------------
98159
@@ -106,6 +167,50 @@ also be supplied. For example: · 7 unmodified lines
106167
107168 perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ...
108169
170+EVENT GROUPS
171+------------
172+
173+Perf supports time based multiplexing of events, when the number of events
174+active exceeds the number of hardware performance counters. Multiplexing
175+can cause measurement errors when the workload changes its execution
176+profile.
177+
178+When metrics are computed using formulas from event counts, it is useful to
179+ensure some events are always measured together as a group to minimize multiplexing
180+errors. Event groups can be specified using { }.
181+
182+ perf stat -e '{instructions,cycles}' ...
183+
184+The number of available performance counters depend on the CPU. A group
185+cannot contain more events than available counters.
186+For example Intel Core CPUs typically have four generic performance counters
187+for the core, plus three fixed counters for instructions, cycles and
188+ref-cycles. Some special events have restrictions on which counter they
189+can schedule, and may not support multiple instances in a single group.
190+When too many events are specified in the group none of them will not
191+be measured.
192+
193+Globally pinned events can limit the number of counters available for
194+other groups. On x86 systems, the NMI watchdog pins a counter by default.
195+The nmi watchdog can be disabled as root with
196+
197+ echo 0 > /proc/sys/kernel/nmi_watchdog
198+
199+Events from multiple different PMUs cannot be mixed in a group, with
200+some exceptions for software events.
201+
202+LEADER SAMPLING
203+---------------
204+
205+perf also supports group leader sampling using the :S specifier.
206+
207+ perf record -e '{cycles,instructions}:S' ...
208+ perf report --group
209+
210+Normally all events in a event group sample, but with :S only
211+the first event (the leader) samples, and it only reads the values of the
212+other events in the group.
213+
109214 OPTIONS
110215 -------
111216
@@ -143,5 +248,5 @@ SEE ALSO · 31 unmodified lines
143248 --------
144249 linkperf:perf-stat[1], linkperf:perf-top[1],
145250 linkperf:perf-record[1],
146−http://www.intel.com/Assets/PDF/manual/253669.pdf[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide],
251+http://www.intel.com/sdm/[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide],
147252 http://support.amd.com/us/Processor_TechDocs/24593_APM_v2.pdf[AMD64 Architecture Programmer’s Manual Volume 2: System Programming]
tools/perf/Documentation/perf-mem.txt+8−0
@@ -48,6 +48,14 @@ OPTIONS · 47 unmodified lines
4848 option can be passed in record mode. It will be interpreted the same way as perf
4949 record.
5050
51+-K::
52+--all-kernel::
53+ Configure all used events to run in kernel space.
54+
55+-U::
56+--all-user::
57+ Configure all used events to run in user space.
58+
5159 SEE ALSO
5260 --------
5361 linkperf:perf-record[1], linkperf:perf-report[1]
tools/perf/Documentation/perf-record.txt+13−0
@@ -347,6 +347,19 @@ Configure all used events to run in kernel space. · 346 unmodified lines
347347 --all-user::
348348 Configure all used events to run in user space.
349349
350+--timestamp-filename
351+Append timestamp to output file name.
352+
353+--switch-output::
354+Generate multiple perf.data files, timestamp prefixed, switching to a new one
355+when receiving a SIGUSR2.
356+
357+A possible use case is to, given an external event, slice the perf.data file
358+that gets then processed, possibly via a perf script, to decide if that
359+particular perf.data snapshot should be kept or not.
360+
361+Implies --timestamp-filename, --no-buildid and --no-buildid-cache.
362+
350363 SEE ALSO
351364 --------
352365 linkperf:perf-stat[1], linkperf:perf-list[1]
tools/perf/Documentation/perf-report.txt+2−2
@@ -248,7 +248,7 @@ OPTIONS · 247 unmodified lines
248248 Note that when using the --itrace option the synthesized callchain size
249249 will override this value if the synthesized callchain size is bigger.
250250
251− Default: 127
251+ Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise.
252252
253253 -G::
254254 --inverted::
@@ -285,7 +285,7 @@ OPTIONS · 30 unmodified lines
285285
286286 -f::
287287 --force::
288− Don't complain, do it.
288+ Don't do ownership validation.
289289
290290 --symfs=<directory>::
291291 Look for files with symbols relative to this directory.
tools/perf/Documentation/perf-sched.txt+16−0
@@ -50,6 +50,22 @@ OPTIONS · 49 unmodified lines
5050 --dump-raw-trace=::
5151 Display verbose dump of the sched data.
5252
53+OPTIONS for 'perf sched map'
54+----------------------------
55+
56+--compact::
57+ Show only CPUs with activity. Helps visualizing on high core
58+ count systems.
59+
60+--cpus::
61+ Show just entries with activities for the given CPUs.
62+
63+--color-cpus::
64+ Highlight the given cpus.
65+
66+--color-pids::
67+ Highlight the given pids.
68+
5369 SEE ALSO
5470 --------
5571 linkperf:perf-record[1]
tools/perf/Documentation/perf-script.txt+14−0
@@ -259,9 +259,23 @@ include::itrace.txt[] · 258 unmodified lines
259259 --full-source-path::
260260 Show the full path for source files for srcline output.
261261
262+--max-stack::
263+ Set the stack depth limit when parsing the callchain, anything
264+ beyond the specified depth will be ignored. This is a trade-off
265+ between information loss and faster processing especially for
266+ workloads that can have a very long callchain stack.
267+ Note that when using the --itrace option the synthesized callchain size
268+ will override this value if the synthesized callchain size is bigger.
269+
270+ Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise.
271+
262272 --ns::
263273 Use 9 decimal places when displaying time (i.e. show the nanoseconds)
264274
275+-f::
276+--force::
277+ Don't do ownership validation.
278+
265279 SEE ALSO
266280 --------
267281 linkperf:perf-record[1], linkperf:perf-script-perl[1],
tools/perf/Documentation/perf-top.txt+1−1
@@ -177,7 +177,7 @@ Default is to monitor all CPUS. · 176 unmodified lines
177177 between information loss and faster processing especially for
178178 workloads that can have a very long callchain stack.
179179
180− Default: 127
180+ Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise.
181181
182182 --ignore-callees=<regex>::
183183 Ignore callees of the function(s) matching the given regex.
tools/perf/Documentation/perf-trace.txt+32−0
@@ -117,9 +117,41 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. · 116 unmodified lines
117117 --syscalls::
118118 Trace system calls. This options is enabled by default.
119119
120+--call-graph [mode,type,min[,limit],order[,key][,branch]]::
121+ Setup and enable call-graph (stack chain/backtrace) recording.
122+ See `--call-graph` section in perf-record and perf-report
123+ man pages for details. The ones that are most useful in 'perf trace'
124+ are 'dwarf' and 'lbr', where available, try: 'perf trace --call-graph dwarf'.
125+
126+ Using this will, for the root user, bump the value of --mmap-pages to 4
127+ times the maximum for non-root users, based on the kernel.perf_event_mlock_kb
128+ sysctl. This is done only if the user doesn't specify a --mmap-pages value.
129+
130+--kernel-syscall-graph::
131+ Show the kernel callchains on the syscall exit path.
132+
120133 --event::
121134 Trace other events, see 'perf list' for a complete list.
122135
136+--max-stack::
137+ Set the stack depth limit when parsing the callchain, anything
138+ beyond the specified depth will be ignored. Note that at this point
139+ this is just about the presentation part, i.e. the kernel is still
140+ not limiting, the overhead of callchains needs to be set via the
141+ knobs in --call-graph dwarf.
142+
143+ Implies '--call-graph dwarf' when --call-graph not present on the
144+ command line, on systems where DWARF unwinding was built in.
145+
146+ Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise.
147+
148+--min-stack::
149+ Set the stack depth limit when parsing the callchain, anything
150+ below the specified depth will be ignored. Disabled by default.
151+
152+ Implies '--call-graph dwarf' when --call-graph not present on the
153+ command line, on systems where DWARF unwinding was built in.
154+
123155 --proc-map-timeout::
124156 When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
125157 because the file may be huge. A time out is needed in such cases.
tools/perf/Makefile.perf+9−6
@@ -183,6 +183,11 @@ endif · 182 unmodified lines
183183 include config/Makefile
184184 endif
185185
186+ifeq ($(config),0)
187+include $(srctree)/tools/scripts/Makefile.arch
188+-include arch/$(ARCH)/Makefile
189+endif
190+
186191 # The FEATURE_DUMP_EXPORT holds location of the actual
187192 # FEATURE_DUMP file to be used to bypass feature detection
188193 # (for bpf or any other subproject)
@@ -297,8 +302,6 @@ endif · 108 unmodified lines
297302 # because maintaining the nesting to match is a pain. If
298303 # we had "elif" things would have been much nicer...
299304
300−-include arch/$(ARCH)/Makefile
301−
302305 ifneq ($(OUTPUT),)
303306 CFLAGS += -I$(OUTPUT)
304307 endif
@@ -390,7 +393,7 @@ endif · 85 unmodified lines
390393 __build-dir = $(subst $(OUTPUT),,$(dir $@))
391394 build-dir = $(if $(__build-dir),$(__build-dir),.)
392395
393−prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep
396+prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep archheaders
394397
395398 $(OUTPUT)%.o: %.c prepare FORCE
396399 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -430,7 +433,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) · 33 unmodified lines
430433
431434 LIBPERF_IN := $(OUTPUT)libperf-in.o
432435
433−$(LIBPERF_IN): fixdep FORCE
436+$(LIBPERF_IN): prepare fixdep FORCE
434437 $(Q)$(MAKE) $(build)=libperf
435438
436439 $(LIB_FILE): $(LIBPERF_IN)
@@ -625,7 +628,7 @@ config-clean: · 188 unmodified lines
625628 $(call QUIET_CLEAN, config)
626629 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null
627630
628−clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean
631+clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean
629632 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
630633 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
631634 $(Q)$(RM) $(OUTPUT).config-detected
@@ -662,5 +665,5 @@ FORCE: · 30 unmodified lines
662665 .PHONY: all install clean config-clean strip install-gtk
663666 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
664667 .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
665−.PHONY: libtraceevent_plugins
668+.PHONY: libtraceevent_plugins archheaders
666669
tools/perf/arch/powerpc/Makefile+1−0
@@ -3,4 +3,5 @@ PERF_HAVE_DWARF_REGS := 1 · 2 unmodified lines
33 endif
44
55 HAVE_KVM_STAT_SUPPORT := 1
6+PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
67 PERF_HAVE_JITDUMP := 1
tools/perf/arch/powerpc/util/dwarf-regs.c+28−12
@@ -10,19 +10,26 @@ · 9 unmodified lines
1010 */
1111
1212 #include <stddef.h>
13+#include <errno.h>
14+#include <string.h>
1315 #include <dwarf-regs.h>
14−
16+#include <linux/ptrace.h>
17+#include <linux/kernel.h>
18+#include "util.h"
1519
1620 struct pt_regs_dwarfnum {
1721 const char *name;
1822 unsigned int dwarfnum;
23+ unsigned int ptregs_offset;
1924 };
2025
21−#define STR(s) #s
22−#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
23−#define GPR_DWARFNUM_NAME(num) \
24− {.name = STR(%gpr##num), .dwarfnum = num}
25−#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
26+#define REG_DWARFNUM_NAME(r, num) \
27+ {.name = STR(%)STR(r), .dwarfnum = num, \
28+ .ptregs_offset = offsetof(struct pt_regs, r)}
29+#define GPR_DWARFNUM_NAME(num) \
30+ {.name = STR(%gpr##num), .dwarfnum = num, \
31+ .ptregs_offset = offsetof(struct pt_regs, gpr[num])}
32+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0, .ptregs_offset = 0}
2633
2734 /*
2835 * Reference:
@@ -61,12 +68,12 @@ static const struct pt_regs_dwarfnum regdwarfnum_table[] = { · 32 unmodified lines
6168 GPR_DWARFNUM_NAME(29),
6269 GPR_DWARFNUM_NAME(30),
6370 GPR_DWARFNUM_NAME(31),
64− REG_DWARFNUM_NAME("%msr", 66),
65− REG_DWARFNUM_NAME("%ctr", 109),
66− REG_DWARFNUM_NAME("%link", 108),
67− REG_DWARFNUM_NAME("%xer", 101),
68− REG_DWARFNUM_NAME("%dar", 119),
69− REG_DWARFNUM_NAME("%dsisr", 118),
71+ REG_DWARFNUM_NAME(msr, 66),
72+ REG_DWARFNUM_NAME(ctr, 109),
73+ REG_DWARFNUM_NAME(link, 108),
74+ REG_DWARFNUM_NAME(xer, 101),
75+ REG_DWARFNUM_NAME(dar, 119),
76+ REG_DWARFNUM_NAME(dsisr, 118),
7077 REG_DWARFNUM_END,
7178 };
7279
@@ -86,3 +93,12 @@ const char *get_arch_regstr(unsigned int n) · 13 unmodified lines
8693 return roff->name;
8794 return NULL;
8895 }
96+
97+int regs_query_register_offset(const char *name)
98+{
99+ const struct pt_regs_dwarfnum *roff;
100+ for (roff = regdwarfnum_table; roff->name != NULL; roff++)
101+ if (!strcmp(roff->name, name))
102+ return roff->ptregs_offset;
103+ return -EINVAL;
104+}
tools/perf/arch/powerpc/util/sym-handling.c+32−11
@@ -19,12 +19,6 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr) · 18 unmodified lines
1919 ehdr.e_type == ET_DYN;
2020 }
2121
22−#if defined(_CALL_ELF) && _CALL_ELF == 2
23−void arch__elf_sym_adjust(GElf_Sym *sym)
24−{
25− sym->st_value += PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
26−}
27−#endif
2822 #endif
2923
3024 #if !defined(_CALL_ELF) || _CALL_ELF != 2
@@ -65,18 +59,45 @@ bool arch__prefers_symtab(void) · 34 unmodified lines
6559 return true;
6660 }
6761
62+#ifdef HAVE_LIBELF_SUPPORT
63+void arch__sym_update(struct symbol *s, GElf_Sym *sym)
64+{
65+ s->arch_sym = sym->st_other;
66+}
67+#endif
68+
6869 #define PPC64LE_LEP_OFFSET 8
6970
7071 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
71− struct probe_trace_event *tev, struct map *map)
72+ struct probe_trace_event *tev, struct map *map,
73+ struct symbol *sym)
7274 {
75+ int lep_offset;
76+
7377 /*
74− * ppc64 ABIv2 local entry point is currently always 2 instructions
75− * (8 bytes) after the global entry point.
78+ * When probing at a function entry point, we normally always want the
79+ * LEP since that catches calls to the function through both the GEP and
80+ * the LEP. Hence, we would like to probe at an offset of 8 bytes if
81+ * the user only specified the function entry.
82+ *
83+ * However, if the user specifies an offset, we fall back to using the
84+ * GEP since all userspace applications (objdump/readelf) show function
85+ * disassembly with offsets from the GEP.
86+ *
87+ * In addition, we shouldn't specify an offset for kretprobes.
7688 */
77− if (!pev->uprobes && map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
78− tev->point.address += PPC64LE_LEP_OFFSET;
89+ if (pev->point.offset || pev->point.retprobe || !map || !sym)
90+ return;
91+
92+ lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
93+
94+ if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
7995 tev->point.offset += PPC64LE_LEP_OFFSET;
96+ else if (lep_offset) {
97+ if (pev->uprobes)
98+ tev->point.address += lep_offset;
99+ else
100+ tev->point.offset += lep_offset;
80101 }
81102 }
82103 #endif
tools/perf/arch/x86/Makefile+23−0
@@ -4,3 +4,26 @@ endif · 3 unmodified lines
44 HAVE_KVM_STAT_SUPPORT := 1
55 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
66 PERF_HAVE_JITDUMP := 1
7+
8+###
9+# Syscall table generation
10+#
11+
12+out := $(OUTPUT)arch/x86/include/generated/asm
13+header := $(out)/syscalls_64.c
14+sys := $(srctree)/tools/perf/arch/x86/entry/syscalls
15+systbl := $(sys)/syscalltbl.sh
16+
17+# Create output directory if not already present
18+_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
19+
20+$(header): $(sys)/syscall_64.tbl $(systbl)
21+ @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \
22+ (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \
23+ || echo "Warning: x86_64's syscall_64.tbl differs from kernel" >&2 )) || true
24+ $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
25+
26+clean::
27+ $(call QUIET_CLEAN, x86) $(RM) $(header)
28+
29+archheaders: $(header)
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl+376−0
@@ -0,0 +1,376 @@
1+#
2+# 64-bit system call numbers and entry vectors
3+#
4+# The format is:
5+# <number> <abi> <name> <entry point>
6+#
7+# The abi is "common", "64" or "x32" for this file.
8+#
9+0 common read sys_read
10+1 common write sys_write
11+2 common open sys_open
12+3 common close sys_close
13+4 common stat sys_newstat
14+5 common fstat sys_newfstat
15+6 common lstat sys_newlstat
16+7 common poll sys_poll
17+8 common lseek sys_lseek
18+9 common mmap sys_mmap
19+10 common mprotect sys_mprotect
20+11 common munmap sys_munmap
21+12 common brk sys_brk
22+13 64 rt_sigaction sys_rt_sigaction
23+14 common rt_sigprocmask sys_rt_sigprocmask
24+15 64 rt_sigreturn sys_rt_sigreturn/ptregs
25+16 64 ioctl sys_ioctl
26+17 common pread64 sys_pread64
27+18 common pwrite64 sys_pwrite64
28+19 64 readv sys_readv
29+20 64 writev sys_writev
30+21 common access sys_access
31+22 common pipe sys_pipe
32+23 common select sys_select
33+24 common sched_yield sys_sched_yield
34+25 common mremap sys_mremap
35+26 common msync sys_msync
36+27 common mincore sys_mincore
37+28 common madvise sys_madvise
38+29 common shmget sys_shmget
39+30 common shmat sys_shmat
40+31 common shmctl sys_shmctl
41+32 common dup sys_dup
42+33 common dup2 sys_dup2
43+34 common pause sys_pause
44+35 common nanosleep sys_nanosleep
45+36 common getitimer sys_getitimer
46+37 common alarm sys_alarm
47+38 common setitimer sys_setitimer
48+39 common getpid sys_getpid
49+40 common sendfile sys_sendfile64
50+41 common socket sys_socket
51+42 common connect sys_connect
52+43 common accept sys_accept
53+44 common sendto sys_sendto
54+45 64 recvfrom sys_recvfrom
55+46 64 sendmsg sys_sendmsg
56+47 64 recvmsg sys_recvmsg
57+48 common shutdown sys_shutdown
58+49 common bind sys_bind
59+50 common listen sys_listen
60+51 common getsockname sys_getsockname
61+52 common getpeername sys_getpeername
62+53 common socketpair sys_socketpair
63+54 64 setsockopt sys_setsockopt
64+55 64 getsockopt sys_getsockopt
65+56 common clone sys_clone/ptregs
66+57 common fork sys_fork/ptregs
67+58 common vfork sys_vfork/ptregs
68+59 64 execve sys_execve/ptregs
69+60 common exit sys_exit
70+61 common wait4 sys_wait4
71+62 common kill sys_kill
72+63 common uname sys_newuname
73+64 common semget sys_semget
74+65 common semop sys_semop
75+66 common semctl sys_semctl
76+67 common shmdt sys_shmdt
77+68 common msgget sys_msgget
78+69 common msgsnd sys_msgsnd
79+70 common msgrcv sys_msgrcv
80+71 common msgctl sys_msgctl
81+72 common fcntl sys_fcntl
82+73 common flock sys_flock
83+74 common fsync sys_fsync
84+75 common fdatasync sys_fdatasync
85+76 common truncate sys_truncate
86+77 common ftruncate sys_ftruncate
87+78 common getdents sys_getdents
88+79 common getcwd sys_getcwd
89+80 common chdir sys_chdir
90+81 common fchdir sys_fchdir
91+82 common rename sys_rename
92+83 common mkdir sys_mkdir
93+84 common rmdir sys_rmdir
94+85 common creat sys_creat
95+86 common link sys_link
96+87 common unlink sys_unlink
97+88 common symlink sys_symlink
98+89 common readlink sys_readlink
99+90 common chmod sys_chmod
100+91 common fchmod sys_fchmod
101+92 common chown sys_chown
102+93 common fchown sys_fchown
103+94 common lchown sys_lchown
104+95 common umask sys_umask
105+96 common gettimeofday sys_gettimeofday
106+97 common getrlimit sys_getrlimit
107+98 common getrusage sys_getrusage
108+99 common sysinfo sys_sysinfo
109+100 common times sys_times
110+101 64 ptrace sys_ptrace
111+102 common getuid sys_getuid
112+103 common syslog sys_syslog
113+104 common getgid sys_getgid
114+105 common setuid sys_setuid
115+106 common setgid sys_setgid
116+107 common geteuid sys_geteuid
117+108 common getegid sys_getegid
118+109 common setpgid sys_setpgid
119+110 common getppid sys_getppid
120+111 common getpgrp sys_getpgrp
121+112 common setsid sys_setsid
122+113 common setreuid sys_setreuid
123+114 common setregid sys_setregid
124+115 common getgroups sys_getgroups
125+116 common setgroups sys_setgroups
126+117 common setresuid sys_setresuid
127+118 common getresuid sys_getresuid
128+119 common setresgid sys_setresgid
129+120 common getresgid sys_getresgid
130+121 common getpgid sys_getpgid
131+122 common setfsuid sys_setfsuid
132+123 common setfsgid sys_setfsgid
133+124 common getsid sys_getsid
134+125 common capget sys_capget
135+126 common capset sys_capset
136+127 64 rt_sigpending sys_rt_sigpending
137+128 64 rt_sigtimedwait sys_rt_sigtimedwait
138+129 64 rt_sigqueueinfo sys_rt_sigqueueinfo
139+130 common rt_sigsuspend sys_rt_sigsuspend
140+131 64 sigaltstack sys_sigaltstack
141+132 common utime sys_utime
142+133 common mknod sys_mknod
143+134 64 uselib
144+135 common personality sys_personality
145+136 common ustat sys_ustat
146+137 common statfs sys_statfs
147+138 common fstatfs sys_fstatfs
148+139 common sysfs sys_sysfs
149+140 common getpriority sys_getpriority
150+141 common setpriority sys_setpriority
151+142 common sched_setparam sys_sched_setparam
152+143 common sched_getparam sys_sched_getparam
153+144 common sched_setscheduler sys_sched_setscheduler
154+145 common sched_getscheduler sys_sched_getscheduler
155+146 common sched_get_priority_max sys_sched_get_priority_max
156+147 common sched_get_priority_min sys_sched_get_priority_min
157+148 common sched_rr_get_interval sys_sched_rr_get_interval
158+149 common mlock sys_mlock
159+150 common munlock sys_munlock
160+151 common mlockall sys_mlockall
161+152 common munlockall sys_munlockall
162+153 common vhangup sys_vhangup
163+154 common modify_ldt sys_modify_ldt
164+155 common pivot_root sys_pivot_root
165+156 64 _sysctl sys_sysctl
166+157 common prctl sys_prctl
167+158 common arch_prctl sys_arch_prctl
168+159 common adjtimex sys_adjtimex
169+160 common setrlimit sys_setrlimit
170+161 common chroot sys_chroot
171+162 common sync sys_sync
172+163 common acct sys_acct
173+164 common settimeofday sys_settimeofday
174+165 common mount sys_mount
175+166 common umount2 sys_umount
176+167 common swapon sys_swapon
177+168 common swapoff sys_swapoff
178+169 common reboot sys_reboot
179+170 common sethostname sys_sethostname
180+171 common setdomainname sys_setdomainname
181+172 common iopl sys_iopl/ptregs
182+173 common ioperm sys_ioperm
183+174 64 create_module
184+175 common init_module sys_init_module
185+176 common delete_module sys_delete_module
186+177 64 get_kernel_syms
187+178 64 query_module
188+179 common quotactl sys_quotactl
189+180 64 nfsservctl
190+181 common getpmsg
191+182 common putpmsg
192+183 common afs_syscall
193+184 common tuxcall
194+185 common security
195+186 common gettid sys_gettid
196+187 common readahead sys_readahead
197+188 common setxattr sys_setxattr
198+189 common lsetxattr sys_lsetxattr
199+190 common fsetxattr sys_fsetxattr
200+191 common getxattr sys_getxattr
201+192 common lgetxattr sys_lgetxattr
202+193 common fgetxattr sys_fgetxattr
203+194 common listxattr sys_listxattr
204+195 common llistxattr sys_llistxattr
205+196 common flistxattr sys_flistxattr
206+197 common removexattr sys_removexattr
207+198 common lremovexattr sys_lremovexattr
208+199 common fremovexattr sys_fremovexattr
209+200 common tkill sys_tkill
210+201 common time sys_time
211+202 common futex sys_futex
212+203 common sched_setaffinity sys_sched_setaffinity
213+204 common sched_getaffinity sys_sched_getaffinity
214+205 64 set_thread_area
215+206 64 io_setup sys_io_setup
216+207 common io_destroy sys_io_destroy
217+208 common io_getevents sys_io_getevents
218+209 64 io_submit sys_io_submit
219+210 common io_cancel sys_io_cancel
220+211 64 get_thread_area
221+212 common lookup_dcookie sys_lookup_dcookie
222+213 common epoll_create sys_epoll_create
223+214 64 epoll_ctl_old
224+215 64 epoll_wait_old
225+216 common remap_file_pages sys_remap_file_pages
226+217 common getdents64 sys_getdents64
227+218 common set_tid_address sys_set_tid_address
228+219 common restart_syscall sys_restart_syscall
229+220 common semtimedop sys_semtimedop
230+221 common fadvise64 sys_fadvise64
231+222 64 timer_create sys_timer_create
232+223 common timer_settime sys_timer_settime
233+224 common timer_gettime sys_timer_gettime
234+225 common timer_getoverrun sys_timer_getoverrun
235+226 common timer_delete sys_timer_delete
236+227 common clock_settime sys_clock_settime
237+228 common clock_gettime sys_clock_gettime
238+229 common clock_getres sys_clock_getres
239+230 common clock_nanosleep sys_clock_nanosleep
240+231 common exit_group sys_exit_group
241+232 common epoll_wait sys_epoll_wait
242+233 common epoll_ctl sys_epoll_ctl
243+234 common tgkill sys_tgkill
244+235 common utimes sys_utimes
245+236 64 vserver
246+237 common mbind sys_mbind
247+238 common set_mempolicy sys_set_mempolicy
248+239 common get_mempolicy sys_get_mempolicy
249+240 common mq_open sys_mq_open
250+241 common mq_unlink sys_mq_unlink
251+242 common mq_timedsend sys_mq_timedsend
252+243 common mq_timedreceive sys_mq_timedreceive
253+244 64 mq_notify sys_mq_notify
254+245 common mq_getsetattr sys_mq_getsetattr
255+246 64 kexec_load sys_kexec_load
256+247 64 waitid sys_waitid
257+248 common add_key sys_add_key
258+249 common request_key sys_request_key
259+250 common keyctl sys_keyctl
260+251 common ioprio_set sys_ioprio_set
261+252 common ioprio_get sys_ioprio_get
262+253 common inotify_init sys_inotify_init
263+254 common inotify_add_watch sys_inotify_add_watch
264+255 common inotify_rm_watch sys_inotify_rm_watch
265+256 common migrate_pages sys_migrate_pages
266+257 common openat sys_openat
267+258 common mkdirat sys_mkdirat
268+259 common mknodat sys_mknodat
269+260 common fchownat sys_fchownat
270+261 common futimesat sys_futimesat
271+262 common newfstatat sys_newfstatat
272+263 common unlinkat sys_unlinkat
273+264 common renameat sys_renameat
274+265 common linkat sys_linkat
275+266 common symlinkat sys_symlinkat
276+267 common readlinkat sys_readlinkat
277+268 common fchmodat sys_fchmodat
278+269 common faccessat sys_faccessat
279+270 common pselect6 sys_pselect6
280+271 common ppoll sys_ppoll
281+272 common unshare sys_unshare
282+273 64 set_robust_list sys_set_robust_list
283+274 64 get_robust_list sys_get_robust_list
284+275 common splice sys_splice
285+276 common tee sys_tee
286+277 common sync_file_range sys_sync_file_range
287+278 64 vmsplice sys_vmsplice
288+279 64 move_pages sys_move_pages
289+280 common utimensat sys_utimensat
290+281 common epoll_pwait sys_epoll_pwait
291+282 common signalfd sys_signalfd
292+283 common timerfd_create sys_timerfd_create
293+284 common eventfd sys_eventfd
294+285 common fallocate sys_fallocate
295+286 common timerfd_settime sys_timerfd_settime
296+287 common timerfd_gettime sys_timerfd_gettime
297+288 common accept4 sys_accept4
298+289 common signalfd4 sys_signalfd4
299+290 common eventfd2 sys_eventfd2
300+291 common epoll_create1 sys_epoll_create1
301+292 common dup3 sys_dup3
302+293 common pipe2 sys_pipe2
303+294 common inotify_init1 sys_inotify_init1
304+295 64 preadv sys_preadv
305+296 64 pwritev sys_pwritev
306+297 64 rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
307+298 common perf_event_open sys_perf_event_open
308+299 64 recvmmsg sys_recvmmsg
309+300 common fanotify_init sys_fanotify_init
310+301 common fanotify_mark sys_fanotify_mark
311+302 common prlimit64 sys_prlimit64
312+303 common name_to_handle_at sys_name_to_handle_at
313+304 common open_by_handle_at sys_open_by_handle_at
314+305 common clock_adjtime sys_clock_adjtime
315+306 common syncfs sys_syncfs
316+307 64 sendmmsg sys_sendmmsg
317+308 common setns sys_setns
318+309 common getcpu sys_getcpu
319+310 64 process_vm_readv sys_process_vm_readv
320+311 64 process_vm_writev sys_process_vm_writev
321+312 common kcmp sys_kcmp
322+313 common finit_module sys_finit_module
323+314 common sched_setattr sys_sched_setattr
324+315 common sched_getattr sys_sched_getattr
325+316 common renameat2 sys_renameat2
326+317 common seccomp sys_seccomp
327+318 common getrandom sys_getrandom
328+319 common memfd_create sys_memfd_create
329+320 common kexec_file_load sys_kexec_file_load
330+321 common bpf sys_bpf
331+322 64 execveat sys_execveat/ptregs
332+323 common userfaultfd sys_userfaultfd
333+324 common membarrier sys_membarrier
334+325 common mlock2 sys_mlock2
335+326 common copy_file_range sys_copy_file_range
336+327 64 preadv2 sys_preadv2
337+328 64 pwritev2 sys_pwritev2
338+
339+#
340+# x32-specific system call numbers start at 512 to avoid cache impact
341+# for native 64-bit operation.
342+#
343+512 x32 rt_sigaction compat_sys_rt_sigaction
344+513 x32 rt_sigreturn sys32_x32_rt_sigreturn
345+514 x32 ioctl compat_sys_ioctl
346+515 x32 readv compat_sys_readv
347+516 x32 writev compat_sys_writev
348+517 x32 recvfrom compat_sys_recvfrom
349+518 x32 sendmsg compat_sys_sendmsg
350+519 x32 recvmsg compat_sys_recvmsg
351+520 x32 execve compat_sys_execve/ptregs
352+521 x32 ptrace compat_sys_ptrace
353+522 x32 rt_sigpending compat_sys_rt_sigpending
354+523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait
355+524 x32 rt_sigqueueinfo compat_sys_rt_sigqueueinfo
356+525 x32 sigaltstack compat_sys_sigaltstack
357+526 x32 timer_create compat_sys_timer_create
358+527 x32 mq_notify compat_sys_mq_notify
359+528 x32 kexec_load compat_sys_kexec_load
360+529 x32 waitid compat_sys_waitid
361+530 x32 set_robust_list compat_sys_set_robust_list
362+531 x32 get_robust_list compat_sys_get_robust_list
363+532 x32 vmsplice compat_sys_vmsplice
364+533 x32 move_pages compat_sys_move_pages
365+534 x32 preadv compat_sys_preadv64
366+535 x32 pwritev compat_sys_pwritev64
367+536 x32 rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
368+537 x32 recvmmsg compat_sys_recvmmsg
369+538 x32 sendmmsg compat_sys_sendmmsg
370+539 x32 process_vm_readv compat_sys_process_vm_readv
371+540 x32 process_vm_writev compat_sys_process_vm_writev
372+541 x32 setsockopt compat_sys_setsockopt
373+542 x32 getsockopt compat_sys_getsockopt
374+543 x32 io_setup compat_sys_io_setup
375+544 x32 io_submit compat_sys_io_submit
376+545 x32 execveat compat_sys_execveat/ptregs
tools/perf/arch/x86/entry/syscalls/syscalltbl.sh+39−0
@@ -0,0 +1,39 @@
1+#!/bin/sh
2+
3+in="$1"
4+arch="$2"
5+
6+syscall_macro() {
7+ nr="$1"
8+ name="$2"
9+
10+ echo " [$nr] = \"$name\","
11+}
12+
13+emit() {
14+ nr="$1"
15+ entry="$2"
16+
17+ syscall_macro "$nr" "$entry"
18+}
19+
20+echo "static const char *syscalltbl_${arch}[] = {"
21+
22+sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
23+grep '^[0-9]' "$in" | sort -n > $sorted_table
24+
25+max_nr=0
26+while read nr abi name entry compat; do
27+ if [ $nr -ge 512 ] ; then # discard compat sycalls
28+ break
29+ fi
30+
31+ emit "$nr" "$name"
32+ max_nr=$nr
33+done < $sorted_table
34+
35+rm -f $sorted_table
36+
37+echo "};"
38+
39+echo "#define SYSCALLTBL_${arch}_MAX_ID ${max_nr}"
tools/perf/arch/x86/tests/perf-time-to-tsc.c+1−1
@@ -71,7 +71,7 @@ int test__perf_time_to_tsc(int subtest __maybe_unused) · 70 unmodified lines
7171
7272 CHECK__(parse_events(evlist, "cycles:u", NULL));
7373
74− perf_evlist__config(evlist, &opts);
74+ perf_evlist__config(evlist, &opts, NULL);
7575
7676 evsel = perf_evlist__first(evlist);
7777
tools/perf/arch/x86/util/intel-bts.c+5−0
@@ -438,6 +438,11 @@ struct auxtrace_record *intel_bts_recording_init(int *err) · 437 unmodified lines
438438 if (!intel_bts_pmu)
439439 return NULL;
440440
441+ if (setenv("JITDUMP_USE_ARCH_TIMESTAMP", "1", 1)) {
442+ *err = -errno;
443+ return NULL;
444+ }
445+
441446 btsr = zalloc(sizeof(struct intel_bts_recording));
442447 if (!btsr) {
443448 *err = -ENOMEM;
tools/perf/arch/x86/util/intel-pt.c+5−0
@@ -1027,6 +1027,11 @@ struct auxtrace_record *intel_pt_recording_init(int *err) · 1026 unmodified lines
10271027 if (!intel_pt_pmu)
10281028 return NULL;
10291029
1030+ if (setenv("JITDUMP_USE_ARCH_TIMESTAMP", "1", 1)) {
1031+ *err = -errno;
1032+ return NULL;
1033+ }
1034+
10301035 ptr = zalloc(sizeof(struct intel_pt_recording));
10311036 if (!ptr) {
10321037 *err = -ENOMEM;
tools/perf/arch/x86/util/tsc.c+31−1
@@ -7,7 +7,6 @@ · 6 unmodified lines
77 #include <linux/types.h>
88 #include "../../util/debug.h"
99 #include "../../util/tsc.h"
10−#include "tsc.h"
1110
1211 int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
1312 struct perf_tsc_conversion *tc)
@@ -46,3 +45,34 @@ u64 rdtsc(void) · 32 unmodified lines
4645
4746 return low | ((u64)high) << 32;
4847 }
48+
49+int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc,
50+ struct perf_tool *tool,
51+ perf_event__handler_t process,
52+ struct machine *machine)
53+{
54+ union perf_event event = {
55+ .time_conv = {
56+ .header = {
57+ .type = PERF_RECORD_TIME_CONV,
58+ .size = sizeof(struct time_conv_event),
59+ },
60+ },
61+ };
62+ struct perf_tsc_conversion tc;
63+ int err;
64+
65+ err = perf_read_tsc_conversion(pc, &tc);
66+ if (err == -EOPNOTSUPP)
67+ return 0;
68+ if (err)
69+ return err;
70+
71+ pr_debug2("Synthesizing TSC conversion information\n");
72+
73+ event.time_conv.time_mult = tc.time_mult;
74+ event.time_conv.time_shift = tc.time_shift;
75+ event.time_conv.time_zero = tc.time_zero;
76+
77+ return process(tool, &event, NULL, machine);
78+}
tools/perf/arch/x86/util/tsc.h+0−17
@@ -1,17 +0,0 @@
1−#ifndef TOOLS_PERF_ARCH_X86_UTIL_TSC_H__
2−#define TOOLS_PERF_ARCH_X86_UTIL_TSC_H__
3−
4−#include <linux/types.h>
5−
6−struct perf_tsc_conversion {
7− u16 time_shift;
8− u32 time_mult;
9− u64 time_zero;
10−};
11−
12−struct perf_event_mmap_page;
13−
14−int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
15− struct perf_tsc_conversion *tc);
16−
17−#endif /* TOOLS_PERF_ARCH_X86_UTIL_TSC_H__ */
tools/perf/bench/futex-lock-pi.c+1−1
@@ -83,7 +83,7 @@ static void *workerfn(void *arg) · 82 unmodified lines
8383 do {
8484 int ret;
8585 again:
86− ret = futex_lock_pi(w->futex, NULL, 0, futex_flag);
86+ ret = futex_lock_pi(w->futex, NULL, futex_flag);
8787
8888 if (ret) { /* handle lock acquisition */
8989 if (!silent)
tools/perf/bench/futex.h+2−4
@@ -57,13 +57,11 @@ futex_wake(u_int32_t *uaddr, int nr_wake, int opflags) · 56 unmodified lines
5757
5858 /**
5959 * futex_lock_pi() - block on uaddr as a PI mutex
60− * @detect: whether (1) or not (0) to perform deadlock detection
6160 */
6261 static inline int
63−futex_lock_pi(u_int32_t *uaddr, struct timespec *timeout, int detect,
64− int opflags)
62+futex_lock_pi(u_int32_t *uaddr, struct timespec *timeout, int opflags)
6563 {
66− return futex(uaddr, FUTEX_LOCK_PI, detect, timeout, NULL, 0, opflags);
64+ return futex(uaddr, FUTEX_LOCK_PI, 0, timeout, NULL, 0, opflags);
6765 }
6866
6967 /**
tools/perf/bench/mem-functions.c+15−7
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
77 */
88
9+#include "debug.h"
910 #include "../perf.h"
1011 #include "../util/util.h"
1112 #include <subcmd/parse-options.h>
@@ -63,14 +64,16 @@ static struct perf_event_attr cycle_attr = { · 51 unmodified lines
6364 .config = PERF_COUNT_HW_CPU_CYCLES
6465 };
6566
66−static void init_cycles(void)
67+static int init_cycles(void)
6768 {
6869 cycles_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
6970
70− if (cycles_fd < 0 && errno == ENOSYS)
71− die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
72− else
73− BUG_ON(cycles_fd < 0);
71+ if (cycles_fd < 0 && errno == ENOSYS) {
72+ pr_debug("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
73+ return -1;
74+ }
75+
76+ return cycles_fd;
7477 }
7578
7679 static u64 get_cycles(void)
@@ -155,8 +158,13 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info * · 78 unmodified lines
155158
156159 argc = parse_options(argc, argv, options, info->usage, 0);
157160
158− if (use_cycles)
159− init_cycles();
161+ if (use_cycles) {
162+ i = init_cycles();
163+ if (i < 0) {
164+ fprintf(stderr, "Failed to open cycles counter\n");
165+ return i;
166+ }
167+ }
160168
161169 size = (size_t)perf_atoll((char *)size_str);
162170 size_total = (double)size * nr_loops;
tools/perf/builtin-config.c+32−7
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <subcmd/parse-options.h>
1313 #include "util/util.h"
1414 #include "util/debug.h"
15+#include "util/config.h"
1516
1617 static bool use_system_config, use_user_config;
1718
@@ -32,13 +33,28 @@ static struct option config_options[] = { · 14 unmodified lines
3233 OPT_END()
3334 };
3435
35−static int show_config(const char *key, const char *value,
36− void *cb __maybe_unused)
36+static int show_config(struct perf_config_set *set)
3737 {
38− if (value)
39− printf("%s=%s\n", key, value);
40− else
41− printf("%s\n", key);
38+ struct perf_config_section *section;
39+ struct perf_config_item *item;
40+ struct list_head *sections;
41+
42+ if (set == NULL)
43+ return -1;
44+
45+ sections = &set->sections;
46+ if (list_empty(sections))
47+ return -1;
48+
49+ list_for_each_entry(section, sections, node) {
50+ list_for_each_entry(item, &section->items, node) {
51+ char *value = item->value;
52+
53+ if (value)
54+ printf("%s.%s=%s\n", section->name,
55+ item->name, value);
56+ }
57+ }
4258
4359 return 0;
4460 }
@@ -46,6 +62,7 @@ static int show_config(const char *key, const char *value, · 1 unmodified line
4662 int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
4763 {
4864 int ret = 0;
65+ struct perf_config_set *set;
4966 char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
5067
5168 argc = parse_options(argc, argv, config_options, config_usage,
@@ -63,13 +80,19 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) · 11 unmodified lines
6380 else if (use_user_config)
6481 config_exclusive_filename = user_config;
6582
83+ set = perf_config_set__new();
84+ if (!set) {
85+ ret = -1;
86+ goto out_err;
87+ }
88+
6689 switch (actions) {
6790 case ACTION_LIST:
6891 if (argc) {
6992 pr_err("Error: takes no arguments\n");
7093 parse_options_usage(config_usage, config_options, "l", 1);
7194 } else {
72− ret = perf_config(show_config, NULL);
95+ ret = show_config(set);
7396 if (ret < 0) {
7497 const char * config_filename = config_exclusive_filename;
7598 if (!config_exclusive_filename)
@@ -83,5 +106,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) · 7 unmodified lines
83106 usage_with_options(config_usage, config_options);
84107 }
85108
109+ perf_config_set__delete(set);
110+out_err:
86111 return ret;
87112 }
tools/perf/builtin-diff.c+2−2
@@ -428,7 +428,7 @@ static void hists__baseline_only(struct hists *hists) · 427 unmodified lines
428428 struct rb_root *root;
429429 struct rb_node *next;
430430
431− if (sort__need_collapse)
431+ if (hists__has(hists, need_collapse))
432432 root = &hists->entries_collapsed;
433433 else
434434 root = hists->entries_in;
@@ -450,7 +450,7 @@ static void hists__precompute(struct hists *hists) · 15 unmodified lines
450450 struct rb_root *root;
451451 struct rb_node *next;
452452
453− if (sort__need_collapse)
453+ if (hists__has(hists, need_collapse))
454454 root = &hists->entries_collapsed;
455455 else
456456 root = hists->entries_in;
tools/perf/builtin-help.c+10−8
@@ -61,6 +61,7 @@ static int check_emacsclient_version(void) · 60 unmodified lines
6161 struct child_process ec_process;
6262 const char *argv_ec[] = { "emacsclient", "--version", NULL };
6363 int version;
64+ int ret = -1;
6465
6566 /* emacsclient prints its version number on stderr */
6667 memset(&ec_process, 0, sizeof(ec_process));
@@ -71,7 +72,10 @@ static int check_emacsclient_version(void) · 4 unmodified lines
7172 fprintf(stderr, "Failed to start emacsclient.\n");
7273 return -1;
7374 }
74− strbuf_read(&buffer, ec_process.err, 20);
75+ if (strbuf_read(&buffer, ec_process.err, 20) < 0) {
76+ fprintf(stderr, "Failed to read emacsclient version\n");
77+ goto out;
78+ }
7579 close(ec_process.err);
7680
7781 /*
@@ -82,8 +86,7 @@ static int check_emacsclient_version(void) · 4 unmodified lines
8286
8387 if (prefixcmp(buffer.buf, "emacsclient")) {
8488 fprintf(stderr, "Failed to parse emacsclient version.\n");
85− strbuf_release(&buffer);
86− return -1;
89+ goto out;
8790 }
8891
8992 version = atoi(buffer.buf + strlen("emacsclient"));
@@ -92,12 +95,11 @@ static int check_emacsclient_version(void) · 2 unmodified lines
9295 fprintf(stderr,
9396 "emacsclient version '%d' too old (< 22).\n",
9497 version);
95− strbuf_release(&buffer);
96− return -1;
97− }
98−
98+ } else
99+ ret = 0;
100+out:
99101 strbuf_release(&buffer);
100− return 0;
102+ return ret;
101103 }
102104
103105 static void exec_woman_emacs(const char *path, const char *page)
tools/perf/builtin-inject.c+1−0
@@ -748,6 +748,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) · 747 unmodified lines
748748 .auxtrace_info = perf_event__repipe_op2_synth,
749749 .auxtrace = perf_event__repipe_auxtrace,
750750 .auxtrace_error = perf_event__repipe_op2_synth,
751+ .time_conv = perf_event__repipe_op2_synth,
751752 .finished_round = perf_event__repipe_oe_synth,
752753 .build_id = perf_event__repipe_op2_synth,
753754 .id_index = perf_event__repipe_op2_synth,
tools/perf/builtin-kmem.c+1−1
@@ -375,7 +375,7 @@ static u64 find_callsite(struct perf_evsel *evsel, struct perf_sample *sample) · 374 unmodified lines
375375 }
376376
377377 al.thread = machine__findnew_thread(machine, sample->pid, sample->tid);
378− sample__resolve_callchain(sample, NULL, evsel, &al, 16);
378+ sample__resolve_callchain(sample, &callchain_cursor, NULL, evsel, &al, 16);
379379
380380 callchain_cursor_commit(&callchain_cursor);
381381 while (true) {
tools/perf/builtin-kvm.c+1−1
@@ -982,7 +982,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) · 981 unmodified lines
982982 struct perf_evlist *evlist = kvm->evlist;
983983 char sbuf[STRERR_BUFSIZE];
984984
985− perf_evlist__config(evlist, &kvm->opts);
985+ perf_evlist__config(evlist, &kvm->opts, NULL);
986986
987987 /*
988988 * Note: exclude_{guest,host} do not apply here.
tools/perf/builtin-mem.c+10−1
@@ -62,19 +62,22 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) · 61 unmodified lines
6262 int rec_argc, i = 0, j;
6363 const char **rec_argv;
6464 int ret;
65+ bool all_user = false, all_kernel = false;
6566 struct option options[] = {
6667 OPT_CALLBACK('e', "event", &mem, "event",
6768 "event selector. use 'perf mem record -e list' to list available events",
6869 parse_record_events),
6970 OPT_INCR('v', "verbose", &verbose,
7071 "be more verbose (show counter open errors, etc)"),
72+ OPT_BOOLEAN('U', "--all-user", &all_user, "collect only user level data"),
73+ OPT_BOOLEAN('K', "--all-kernel", &all_kernel, "collect only kernel level data"),
7174 OPT_END()
7275 };
7376
7477 argc = parse_options(argc, argv, options, record_mem_usage,
7578 PARSE_OPT_STOP_AT_NON_OPTION);
7679
77− rec_argc = argc + 7; /* max number of arguments */
80+ rec_argc = argc + 9; /* max number of arguments */
7881 rec_argv = calloc(rec_argc + 1, sizeof(char *));
7982 if (!rec_argv)
8083 return -1;
@@ -103,6 +106,12 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) · 22 unmodified lines
103106 rec_argv[i++] = perf_mem_events__name(j);
104107 };
105108
109+ if (all_user)
110+ rec_argv[i++] = "--all-user";
111+
112+ if (all_kernel)
113+ rec_argv[i++] = "--all-kernel";
114+
106115 for (j = 0; j < argc; j++, i++)
107116 rec_argv[i] = argv[j];
108117
tools/perf/builtin-record.c+220−47
@@ -29,10 +29,12 @@ · 28 unmodified lines
2929 #include "util/data.h"
3030 #include "util/perf_regs.h"
3131 #include "util/auxtrace.h"
32+#include "util/tsc.h"
3233 #include "util/parse-branch-options.h"
3334 #include "util/parse-regs-options.h"
3435 #include "util/llvm-utils.h"
3536 #include "util/bpf-loader.h"
37+#include "util/trigger.h"
3638 #include "asm/bug.h"
3739
3840 #include <unistd.h>
@@ -55,6 +57,8 @@ struct record { · 16 unmodified lines
5557 bool no_buildid_cache;
5658 bool no_buildid_cache_set;
5759 bool buildid_all;
60+ bool timestamp_filename;
61+ bool switch_output;
5862 unsigned long long samples;
5963 };
6064
@@ -124,9 +128,10 @@ out: · 63 unmodified lines
124128 static volatile int done;
125129 static volatile int signr = -1;
126130 static volatile int child_finished;
127−static volatile int auxtrace_snapshot_enabled;
128−static volatile int auxtrace_snapshot_err;
131+
129132 static volatile int auxtrace_record__snapshot_started;
133+static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
134+static DEFINE_TRIGGER(switch_output_trigger);
130135
131136 static void sig_handler(int sig)
132137 {
@@ -244,11 +249,12 @@ static void record__read_auxtrace_snapshot(struct record *rec) · 111 unmodified lines
244249 {
245250 pr_debug("Recording AUX area tracing snapshot\n");
246251 if (record__auxtrace_read_snapshot_all(rec) < 0) {
247− auxtrace_snapshot_err = -1;
252+ trigger_error(&auxtrace_snapshot_trigger);
248253 } else {
249− auxtrace_snapshot_err = auxtrace_record__snapshot_finish(rec->itr);
250− if (!auxtrace_snapshot_err)
251− auxtrace_snapshot_enabled = 1;
254+ if (auxtrace_record__snapshot_finish(rec->itr))
255+ trigger_error(&auxtrace_snapshot_trigger);
256+ else
257+ trigger_ready(&auxtrace_snapshot_trigger);
252258 }
253259 }
254260
@@ -283,7 +289,7 @@ static int record__open(struct record *rec) · 28 unmodified lines
283289 struct record_opts *opts = &rec->opts;
284290 int rc = 0;
285291
286− perf_evlist__config(evlist, opts);
292+ perf_evlist__config(evlist, opts, &callchain_param);
287293
288294 evlist__for_each(evlist, pos) {
289295 try_again:
@@ -494,6 +500,73 @@ record__finish_output(struct record *rec) · 204 unmodified lines
494500 return;
495501 }
496502
503+static int record__synthesize_workload(struct record *rec)
504+{
505+ struct {
506+ struct thread_map map;
507+ struct thread_map_data map_data;
508+ } thread_map;
509+
510+ thread_map.map.nr = 1;
511+ thread_map.map.map[0].pid = rec->evlist->workload.pid;
512+ thread_map.map.map[0].comm = NULL;
513+ return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map,
514+ process_synthesized_event,
515+ &rec->session->machines.host,
516+ rec->opts.sample_address,
517+ rec->opts.proc_map_timeout);
518+}
519+
520+static int record__synthesize(struct record *rec);
521+
522+static int
523+record__switch_output(struct record *rec, bool at_exit)
524+{
525+ struct perf_data_file *file = &rec->file;
526+ int fd, err;
527+
528+ /* Same Size: "2015122520103046"*/
529+ char timestamp[] = "InvalidTimestamp";
530+
531+ rec->samples = 0;
532+ record__finish_output(rec);
533+ err = fetch_current_timestamp(timestamp, sizeof(timestamp));
534+ if (err) {
535+ pr_err("Failed to get current timestamp\n");
536+ return -EINVAL;
537+ }
538+
539+ fd = perf_data_file__switch(file, timestamp,
540+ rec->session->header.data_offset,
541+ at_exit);
542+ if (fd >= 0 && !at_exit) {
543+ rec->bytes_written = 0;
544+ rec->session->header.data_size = 0;
545+ }
546+
547+ if (!quiet)
548+ fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
549+ file->path, timestamp);
550+
551+ /* Output tracking events */
552+ if (!at_exit) {
553+ record__synthesize(rec);
554+
555+ /*
556+ * In 'perf record --switch-output' without -a,
557+ * record__synthesize() in record__switch_output() won't
558+ * generate tracking events because there's no thread_map
559+ * in evlist. Which causes newly created perf.data doesn't
560+ * contain map and comm information.
561+ * Create a fake thread_map and directly call
562+ * perf_event__synthesize_thread_map() for those events.
563+ */
564+ if (target__none(&rec->opts.target))
565+ record__synthesize_workload(rec);
566+ }
567+ return fd;
568+}
569+
497570 static volatile int workload_exec_errno;
498571
499572 /*
@@ -512,6 +585,15 @@ static void workload_exec_failed_signal(int signo __maybe_unused, · 12 unmodified lines
512585
513586 static void snapshot_sig_handler(int sig);
514587
588+int __weak
589+perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
590+ struct perf_tool *tool __maybe_unused,
591+ perf_event__handler_t process __maybe_unused,
592+ struct machine *machine __maybe_unused)
593+{
594+ return 0;
595+}
596+
515597 static int record__synthesize(struct record *rec)
516598 {
517599 struct perf_session *session = rec->session;
@@ -549,6 +631,11 @@ static int record__synthesize(struct record *rec) · 31 unmodified lines
549631 }
550632 }
551633
634+ err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool,
635+ process_synthesized_event, machine);
636+ if (err)
637+ goto out;
638+
552639 if (rec->opts.full_auxtrace) {
553640 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
554641 session, process_synthesized_event);
@@ -600,10 +687,16 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) · 45 unmodified lines
600687 signal(SIGCHLD, sig_handler);
601688 signal(SIGINT, sig_handler);
602689 signal(SIGTERM, sig_handler);
603− if (rec->opts.auxtrace_snapshot_mode)
690+
691+ if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) {
604692 signal(SIGUSR2, snapshot_sig_handler);
605− else
693+ if (rec->opts.auxtrace_snapshot_mode)
694+ trigger_on(&auxtrace_snapshot_trigger);
695+ if (rec->switch_output)
696+ trigger_on(&switch_output_trigger);
697+ } else {
606698 signal(SIGUSR2, SIG_IGN);
699+ }
607700
608701 session = perf_session__new(file, false, tool);
609702 if (session == NULL) {
@@ -729,27 +822,45 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) · 119 unmodified lines
729822 perf_evlist__enable(rec->evlist);
730823 }
731824
732− auxtrace_snapshot_enabled = 1;
825+ trigger_ready(&auxtrace_snapshot_trigger);
826+ trigger_ready(&switch_output_trigger);
733827 for (;;) {
734828 unsigned long long hits = rec->samples;
735829
736830 if (record__mmap_read_all(rec) < 0) {
737− auxtrace_snapshot_enabled = 0;
831+ trigger_error(&auxtrace_snapshot_trigger);
832+ trigger_error(&switch_output_trigger);
738833 err = -1;
739834 goto out_child;
740835 }
741836
742837 if (auxtrace_record__snapshot_started) {
743838 auxtrace_record__snapshot_started = 0;
744− if (!auxtrace_snapshot_err)
839+ if (!trigger_is_error(&auxtrace_snapshot_trigger))
745840 record__read_auxtrace_snapshot(rec);
746− if (auxtrace_snapshot_err) {
841+ if (trigger_is_error(&auxtrace_snapshot_trigger)) {
747842 pr_err("AUX area tracing snapshot failed\n");
748843 err = -1;
749844 goto out_child;
750845 }
751846 }
752847
848+ if (trigger_is_hit(&switch_output_trigger)) {
849+ trigger_ready(&switch_output_trigger);
850+
851+ if (!quiet)
852+ fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
853+ waking);
854+ waking = 0;
855+ fd = record__switch_output(rec, false);
856+ if (fd < 0) {
857+ pr_err("Failed to switch to new file\n");
858+ trigger_error(&switch_output_trigger);
859+ err = fd;
860+ goto out_child;
861+ }
862+ }
863+
753864 if (hits == rec->samples) {
754865 if (done || draining)
755866 break;
@@ -772,12 +883,13 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) · 16 unmodified lines
772883 * disable events in this case.
773884 */
774885 if (done && !disabled && !target__none(&opts->target)) {
775− auxtrace_snapshot_enabled = 0;
886+ trigger_off(&auxtrace_snapshot_trigger);
776887 perf_evlist__disable(rec->evlist);
777888 disabled = true;
778889 }
779890 }
780− auxtrace_snapshot_enabled = 0;
891+ trigger_off(&auxtrace_snapshot_trigger);
892+ trigger_off(&switch_output_trigger);
781893
782894 if (forks && workload_exec_errno) {
783895 char msg[STRERR_BUFSIZE];
@@ -811,11 +923,22 @@ out_child: · 27 unmodified lines
811923 /* this will be recalculated during process_buildids() */
812924 rec->samples = 0;
813925
814− if (!err)
815− record__finish_output(rec);
926+ if (!err) {
927+ if (!rec->timestamp_filename) {
928+ record__finish_output(rec);
929+ } else {
930+ fd = record__switch_output(rec, true);
931+ if (fd < 0) {
932+ status = fd;
933+ goto out_delete_session;
934+ }
935+ }
936+ }
816937
817938 if (!err && !quiet) {
818939 char samples[128];
940+ const char *postfix = rec->timestamp_filename ?
941+ ".<timestamp>" : "";
819942
820943 if (rec->samples && !rec->opts.full_auxtrace)
821944 scnprintf(samples, sizeof(samples),
@@ -823,9 +946,9 @@ out_child: · 1 unmodified line
823946 else
824947 samples[0] = '\0';
825948
826− fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s ]\n",
949+ fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
827950 perf_data_file__size(file) / 1024.0 / 1024.0,
828− file->path, samples);
951+ file->path, postfix, samples);
829952 }
830953
831954 out_delete_session:
@@ -833,58 +956,61 @@ out_delete_session: · 1 unmodified line
833956 return status;
834957 }
835958
836−static void callchain_debug(void)
959+static void callchain_debug(struct callchain_param *callchain)
837960 {
838961 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
839962
840− pr_debug("callchain: type %s\n", str[callchain_param.record_mode]);
963+ pr_debug("callchain: type %s\n", str[callchain->record_mode]);
841964
842− if (callchain_param.record_mode == CALLCHAIN_DWARF)
965+ if (callchain->record_mode == CALLCHAIN_DWARF)
843966 pr_debug("callchain: stack dump size %d\n",
844− callchain_param.dump_size);
967+ callchain->dump_size);
845968 }
846969
847−int record_parse_callchain_opt(const struct option *opt,
848− const char *arg,
849− int unset)
970+int record_opts__parse_callchain(struct record_opts *record,
971+ struct callchain_param *callchain,
972+ const char *arg, bool unset)
850973 {
851974 int ret;
852− struct record_opts *record = (struct record_opts *)opt->value;
853−
854− record->callgraph_set = true;
855− callchain_param.enabled = !unset;
975+ callchain->enabled = !unset;
856976
857977 /* --no-call-graph */
858978 if (unset) {
859− callchain_param.record_mode = CALLCHAIN_NONE;
979+ callchain->record_mode = CALLCHAIN_NONE;
860980 pr_debug("callchain: disabled\n");
861981 return 0;
862982 }
863983
864− ret = parse_callchain_record_opt(arg, &callchain_param);
984+ ret = parse_callchain_record_opt(arg, callchain);
865985 if (!ret) {
866986 /* Enable data address sampling for DWARF unwind. */
867− if (callchain_param.record_mode == CALLCHAIN_DWARF)
987+ if (callchain->record_mode == CALLCHAIN_DWARF)
868988 record->sample_address = true;
869− callchain_debug();
989+ callchain_debug(callchain);
870990 }
871991
872992 return ret;
873993 }
874994
995+int record_parse_callchain_opt(const struct option *opt,
996+ const char *arg,
997+ int unset)
998+{
999+ return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
1000+}
1001+
8751002 int record_callchain_opt(const struct option *opt,
8761003 const char *arg __maybe_unused,
8771004 int unset __maybe_unused)
8781005 {
879− struct record_opts *record = (struct record_opts *)opt->value;
1006+ struct callchain_param *callchain = opt->value;
8801007
881− record->callgraph_set = true;
882− callchain_param.enabled = true;
1008+ callchain->enabled = true;
8831009
884− if (callchain_param.record_mode == CALLCHAIN_NONE)
885− callchain_param.record_mode = CALLCHAIN_FP;
1010+ if (callchain->record_mode == CALLCHAIN_NONE)
1011+ callchain->record_mode = CALLCHAIN_FP;
8861012
887− callchain_debug();
1013+ callchain_debug(callchain);
8881014 return 0;
8891015 }
8901016
@@ -1122,7 +1248,7 @@ struct option __record_options[] = { · 231 unmodified lines
11221248 record__parse_mmap_pages),
11231249 OPT_BOOLEAN(0, "group", &record.opts.group,
11241250 "put the counters into a counter group"),
1125− OPT_CALLBACK_NOOPT('g', NULL, &record.opts,
1251+ OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
11261252 NULL, "enables call-graph recording" ,
11271253 &record_callchain_opt),
11281254 OPT_CALLBACK(0, "call-graph", &record.opts,
@@ -1195,6 +1321,10 @@ struct option __record_options[] = { · 66 unmodified lines
11951321 "file", "vmlinux pathname"),
11961322 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
11971323 "Record build-id of all DSOs regardless of hits"),
1324+ OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1325+ "append timestamp to output filename"),
1326+ OPT_BOOLEAN(0, "switch-output", &record.switch_output,
1327+ "Switch output when receive SIGUSR2"),
11981328 OPT_END()
11991329 };
12001330
@@ -1250,6 +1380,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) · 49 unmodified lines
12501380 return -EINVAL;
12511381 }
12521382
1383+ if (rec->switch_output)
1384+ rec->timestamp_filename = true;
1385+
12531386 if (!rec->itr) {
12541387 rec->itr = auxtrace_record__init(rec->evlist, &err);
12551388 if (err)
@@ -1261,6 +1394,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) · 5 unmodified lines
12611394 if (err)
12621395 return err;
12631396
1397+ err = bpf__setup_stdout(rec->evlist);
1398+ if (err) {
1399+ bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1400+ pr_err("ERROR: Setup BPF stdout failed: %s\n",
1401+ errbuf);
1402+ return err;
1403+ }
1404+
12641405 err = -ENOMEM;
12651406
12661407 symbol__init(NULL);
@@ -1275,8 +1416,36 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) · 8 unmodified lines
12751416 "If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
12761417 "even with a suitable vmlinux or kallsyms file.\n\n");
12771418
1278− if (rec->no_buildid_cache || rec->no_buildid)
1419+ if (rec->no_buildid_cache || rec->no_buildid) {
12791420 disable_buildid_cache();
1421+ } else if (rec->switch_output) {
1422+ /*
1423+ * In 'perf record --switch-output', disable buildid
1424+ * generation by default to reduce data file switching
1425+ * overhead. Still generate buildid if they are required
1426+ * explicitly using
1427+ *
1428+ * perf record --signal-trigger --no-no-buildid \
1429+ * --no-no-buildid-cache
1430+ *
1431+ * Following code equals to:
1432+ *
1433+ * if ((rec->no_buildid || !rec->no_buildid_set) &&
1434+ * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1435+ * disable_buildid_cache();
1436+ */
1437+ bool disable = true;
1438+
1439+ if (rec->no_buildid_set && !rec->no_buildid)
1440+ disable = false;
1441+ if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1442+ disable = false;
1443+ if (disable) {
1444+ rec->no_buildid = true;
1445+ rec->no_buildid_cache = true;
1446+ disable_buildid_cache();
1447+ }
1448+ }
12801449
12811450 if (rec->evlist->nr_entries == 0 &&
12821451 perf_evlist__add_default(rec->evlist) < 0) {
@@ -1335,9 +1504,13 @@ out_symbol_exit: · 52 unmodified lines
13351504
13361505 static void snapshot_sig_handler(int sig __maybe_unused)
13371506 {
1338− if (!auxtrace_snapshot_enabled)
1339− return;
1340− auxtrace_snapshot_enabled = 0;
1341− auxtrace_snapshot_err = auxtrace_record__snapshot_start(record.itr);
1342− auxtrace_record__snapshot_started = 1;
1507+ if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1508+ trigger_hit(&auxtrace_snapshot_trigger);
1509+ auxtrace_record__snapshot_started = 1;
1510+ if (auxtrace_record__snapshot_start(record.itr))
1511+ trigger_error(&auxtrace_snapshot_trigger);
1512+ }
1513+
1514+ if (trigger_is_ready(&switch_output_trigger))
1515+ trigger_hit(&switch_output_trigger);
13431516 }
tools/perf/builtin-report.c+10−9
@@ -47,7 +47,6 @@ struct report { · 46 unmodified lines
4747 struct perf_tool tool;
4848 struct perf_session *session;
4949 bool use_tui, use_gtk, use_stdio;
50− bool dont_use_callchains;
5150 bool show_full_info;
5251 bool show_threads;
5352 bool inverted_callchain;
@@ -235,7 +234,7 @@ static int report__setup_sample_type(struct report *rep) · 181 unmodified lines
235234 sample_type |= PERF_SAMPLE_BRANCH_STACK;
236235
237236 if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
238− if (sort__has_parent) {
237+ if (perf_hpp_list.parent) {
239238 ui__error("Selected --sort parent, but no "
240239 "callchain data. Did you call "
241240 "'perf record' without -g?\n");
@@ -247,7 +246,7 @@ static int report__setup_sample_type(struct report *rep) · 5 unmodified lines
247246 "you call 'perf record' without -g?\n");
248247 return -1;
249248 }
250− } else if (!rep->dont_use_callchains &&
249+ } else if (!callchain_param.enabled &&
251250 callchain_param.mode != CHAIN_NONE &&
252251 !symbol_conf.use_callchain) {
253252 symbol_conf.use_callchain = true;
@@ -599,13 +598,15 @@ static int __cmd_report(struct report *rep) · 345 unmodified lines
599598 static int
600599 report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
601600 {
602− struct report *rep = (struct report *)opt->value;
601+ struct callchain_param *callchain = opt->value;
603602
603+ callchain->enabled = !unset;
604604 /*
605605 * --no-call-graph
606606 */
607607 if (unset) {
608− rep->dont_use_callchains = true;
608+ symbol_conf.use_callchain = false;
609+ callchain->mode = CHAIN_NONE;
609610 return 0;
610611 }
611612
@@ -690,7 +691,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) · 78 unmodified lines
690691 .ordered_events = true,
691692 .ordering_requires_timestamps = true,
692693 },
693− .max_stack = PERF_MAX_STACK_DEPTH,
694+ .max_stack = sysctl_perf_event_max_stack,
694695 .pretty_printing_style = "normal",
695696 .socket_filter = -1,
696697 };
@@ -734,7 +735,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) · 37 unmodified lines
734735 "regex filter to identify parent, see: '--sort parent'"),
735736 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
736737 "Only display entries with parent-match"),
737− OPT_CALLBACK_DEFAULT('g', "call-graph", &report,
738+ OPT_CALLBACK_DEFAULT('g', "call-graph", &callchain_param,
738739 "print_type,threshold[,print_limit],order,sort_key[,branch],value",
739740 report_callchain_help, &report_parse_callchain_opt,
740741 callchain_default_opt),
@@ -743,7 +744,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) · 2 unmodified lines
743744 OPT_INTEGER(0, "max-stack", &report.max_stack,
744745 "Set the maximum stack depth when parsing the callchain, "
745746 "anything beyond the specified depth will be ignored. "
746− "Default: " __stringify(PERF_MAX_STACK_DEPTH)),
747+ "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
747748 OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
748749 "alias for inverted call graph"),
749750 OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
@@ -935,7 +936,7 @@ repeat: · 185 unmodified lines
935936 goto error;
936937 }
937938
938− sort__need_collapse = true;
939+ perf_hpp_list.need_collapse = true;
939940 }
940941
941942 /* Force tty output for header output and per-thread stat. */
tools/perf/builtin-sched.c+186−12
@@ -11,6 +11,8 @@ · 10 unmodified lines
1111 #include "util/session.h"
1212 #include "util/tool.h"
1313 #include "util/cloexec.h"
14+#include "util/thread_map.h"
15+#include "util/color.h"
1416
1517 #include <subcmd/parse-options.h>
1618 #include "util/trace-event.h"
@@ -122,6 +124,21 @@ struct trace_sched_handler { · 105 unmodified lines
122124 struct machine *machine);
123125 };
124126
127+#define COLOR_PIDS PERF_COLOR_BLUE
128+#define COLOR_CPUS PERF_COLOR_BG_RED
129+
130+struct perf_sched_map {
131+ DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS);
132+ int *comp_cpus;
133+ bool comp;
134+ struct thread_map *color_pids;
135+ const char *color_pids_str;
136+ struct cpu_map *color_cpus;
137+ const char *color_cpus_str;
138+ struct cpu_map *cpus;
139+ const char *cpus_str;
140+};
141+
125142 struct perf_sched {
126143 struct perf_tool tool;
127144 const char *sort_order;
@@ -173,6 +190,7 @@ struct perf_sched { · 45 unmodified lines
173190 struct list_head sort_list, cmp_pid;
174191 bool force;
175192 bool skip_merge;
193+ struct perf_sched_map map;
176194 };
177195
178196 static u64 get_nsecs(void)
@@ -1339,6 +1357,38 @@ static int process_sched_wakeup_event(struct perf_tool *tool, · 1160 unmodified lines
13391357 return 0;
13401358 }
13411359
1360+union map_priv {
1361+ void *ptr;
1362+ bool color;
1363+};
1364+
1365+static bool thread__has_color(struct thread *thread)
1366+{
1367+ union map_priv priv = {
1368+ .ptr = thread__priv(thread),
1369+ };
1370+
1371+ return priv.color;
1372+}
1373+
1374+static struct thread*
1375+map__findnew_thread(struct perf_sched *sched, struct machine *machine, pid_t pid, pid_t tid)
1376+{
1377+ struct thread *thread = machine__findnew_thread(machine, pid, tid);
1378+ union map_priv priv = {
1379+ .color = false,
1380+ };
1381+
1382+ if (!sched->map.color_pids || !thread || thread__priv(thread))
1383+ return thread;
1384+
1385+ if (thread_map__has(sched->map.color_pids, tid))
1386+ priv.color = true;
1387+
1388+ thread__set_priv(thread, priv.ptr);
1389+ return thread;
1390+}
1391+
13421392 static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
13431393 struct perf_sample *sample, struct machine *machine)
13441394 {
@@ -1347,13 +1397,25 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, · 2 unmodified lines
13471397 int new_shortname;
13481398 u64 timestamp0, timestamp = sample->time;
13491399 s64 delta;
1350− int cpu, this_cpu = sample->cpu;
1400+ int i, this_cpu = sample->cpu;
1401+ int cpus_nr;
1402+ bool new_cpu = false;
1403+ const char *color = PERF_COLOR_NORMAL;
13511404
13521405 BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0);
13531406
13541407 if (this_cpu > sched->max_cpu)
13551408 sched->max_cpu = this_cpu;
13561409
1410+ if (sched->map.comp) {
1411+ cpus_nr = bitmap_weight(sched->map.comp_cpus_mask, MAX_CPUS);
1412+ if (!test_and_set_bit(this_cpu, sched->map.comp_cpus_mask)) {
1413+ sched->map.comp_cpus[cpus_nr++] = this_cpu;
1414+ new_cpu = true;
1415+ }
1416+ } else
1417+ cpus_nr = sched->max_cpu;
1418+
13571419 timestamp0 = sched->cpu_last_switched[this_cpu];
13581420 sched->cpu_last_switched[this_cpu] = timestamp;
13591421 if (timestamp0)
@@ -1366,7 +1428,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, · 6 unmodified lines
13661428 return -1;
13671429 }
13681430
1369− sched_in = machine__findnew_thread(machine, -1, next_pid);
1431+ sched_in = map__findnew_thread(sched, machine, -1, next_pid);
13701432 if (sched_in == NULL)
13711433 return -1;
13721434
@@ -1400,26 +1462,52 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, · 27 unmodified lines
14001462 new_shortname = 1;
14011463 }
14021464
1403− for (cpu = 0; cpu <= sched->max_cpu; cpu++) {
1465+ for (i = 0; i < cpus_nr; i++) {
1466+ int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i;
1467+ struct thread *curr_thread = sched->curr_thread[cpu];
1468+ const char *pid_color = color;
1469+ const char *cpu_color = color;
1470+
1471+ if (curr_thread && thread__has_color(curr_thread))
1472+ pid_color = COLOR_PIDS;
1473+
1474+ if (sched->map.cpus && !cpu_map__has(sched->map.cpus, cpu))
1475+ continue;
1476+
1477+ if (sched->map.color_cpus && cpu_map__has(sched->map.color_cpus, cpu))
1478+ cpu_color = COLOR_CPUS;
1479+
14041480 if (cpu != this_cpu)
1405− printf(" ");
1481+ color_fprintf(stdout, cpu_color, " ");
14061482 else
1407− printf("*");
1483+ color_fprintf(stdout, cpu_color, "*");
14081484
14091485 if (sched->curr_thread[cpu])
1410− printf("%2s ", sched->curr_thread[cpu]->shortname);
1486+ color_fprintf(stdout, pid_color, "%2s ", sched->curr_thread[cpu]->shortname);
14111487 else
1412− printf(" ");
1488+ color_fprintf(stdout, color, " ");
14131489 }
14141490
1415− printf(" %12.6f secs ", (double)timestamp/1e9);
1491+ if (sched->map.cpus && !cpu_map__has(sched->map.cpus, this_cpu))
1492+ goto out;
1493+
1494+ color_fprintf(stdout, color, " %12.6f secs ", (double)timestamp/1e9);
14161495 if (new_shortname) {
1417− printf("%s => %s:%d\n",
1496+ const char *pid_color = color;
1497+
1498+ if (thread__has_color(sched_in))
1499+ pid_color = COLOR_PIDS;
1500+
1501+ color_fprintf(stdout, pid_color, "%s => %s:%d",
14181502 sched_in->shortname, thread__comm_str(sched_in), sched_in->tid);
1419− } else {
1420− printf("\n");
14211503 }
14221504
1505+ if (sched->map.comp && new_cpu)
1506+ color_fprintf(stdout, color, " (CPU %d)", this_cpu);
1507+
1508+out:
1509+ color_fprintf(stdout, color, "\n");
1510+
14231511 thread__put(sched_in);
14241512
14251513 return 0;
@@ -1675,9 +1763,75 @@ static int perf_sched__lat(struct perf_sched *sched) · 249 unmodified lines
16751763 return 0;
16761764 }
16771765
1766+static int setup_map_cpus(struct perf_sched *sched)
1767+{
1768+ struct cpu_map *map;
1769+
1770+ sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF);
1771+
1772+ if (sched->map.comp) {
1773+ sched->map.comp_cpus = zalloc(sched->max_cpu * sizeof(int));
1774+ if (!sched->map.comp_cpus)
1775+ return -1;
1776+ }
1777+
1778+ if (!sched->map.cpus_str)
1779+ return 0;
1780+
1781+ map = cpu_map__new(sched->map.cpus_str);
1782+ if (!map) {
1783+ pr_err("failed to get cpus map from %s\n", sched->map.cpus_str);
1784+ return -1;
1785+ }
1786+
1787+ sched->map.cpus = map;
1788+ return 0;
1789+}
1790+
1791+static int setup_color_pids(struct perf_sched *sched)
1792+{
1793+ struct thread_map *map;
1794+
1795+ if (!sched->map.color_pids_str)
1796+ return 0;
1797+
1798+ map = thread_map__new_by_tid_str(sched->map.color_pids_str);
1799+ if (!map) {
1800+ pr_err("failed to get thread map from %s\n", sched->map.color_pids_str);
1801+ return -1;
1802+ }
1803+
1804+ sched->map.color_pids = map;
1805+ return 0;
1806+}
1807+
1808+static int setup_color_cpus(struct perf_sched *sched)
1809+{
1810+ struct cpu_map *map;
1811+
1812+ if (!sched->map.color_cpus_str)
1813+ return 0;
1814+
1815+ map = cpu_map__new(sched->map.color_cpus_str);
1816+ if (!map) {
1817+ pr_err("failed to get thread map from %s\n", sched->map.color_cpus_str);
1818+ return -1;
1819+ }
1820+
1821+ sched->map.color_cpus = map;
1822+ return 0;
1823+}
1824+
16781825 static int perf_sched__map(struct perf_sched *sched)
16791826 {
1680− sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF);
1827+ if (setup_map_cpus(sched))
1828+ return -1;
1829+
1830+ if (setup_color_pids(sched))
1831+ return -1;
1832+
1833+ if (setup_color_cpus(sched))
1834+ return -1;
16811835
16821836 setup_pager();
16831837 if (perf_sched__read_events(sched))
@@ -1831,6 +1985,17 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) · 147 unmodified lines
18311985 "dump raw trace in ASCII"),
18321986 OPT_END()
18331987 };
1988+ const struct option map_options[] = {
1989+ OPT_BOOLEAN(0, "compact", &sched.map.comp,
1990+ "map output in compact mode"),
1991+ OPT_STRING(0, "color-pids", &sched.map.color_pids_str, "pids",
1992+ "highlight given pids in map"),
1993+ OPT_STRING(0, "color-cpus", &sched.map.color_cpus_str, "cpus",
1994+ "highlight given CPUs in map"),
1995+ OPT_STRING(0, "cpus", &sched.map.cpus_str, "cpus",
1996+ "display given CPUs in map"),
1997+ OPT_END()
1998+ };
18341999 const char * const latency_usage[] = {
18352000 "perf sched latency [<options>]",
18362001 NULL
@@ -1839,6 +2004,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) · 2 unmodified lines
18392004 "perf sched replay [<options>]",
18402005 NULL
18412006 };
2007+ const char * const map_usage[] = {
2008+ "perf sched map [<options>]",
2009+ NULL
2010+ };
18422011 const char *const sched_subcommands[] = { "record", "latency", "map",
18432012 "replay", "script", NULL };
18442013 const char *sched_usage[] = {
@@ -1887,6 +2056,11 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) · 42 unmodified lines
18872056 setup_sorting(&sched, latency_options, latency_usage);
18882057 return perf_sched__lat(&sched);
18892058 } else if (!strcmp(argv[0], "map")) {
2059+ if (argc) {
2060+ argc = parse_options(argc, argv, map_options, map_usage, 0);
2061+ if (argc)
2062+ usage_with_options(map_usage, map_options);
2063+ }
18902064 sched.tp_handler = &map_ops;
18912065 setup_sorting(&sched, latency_options, latency_usage);
18922066 return perf_sched__map(&sched);
tools/perf/builtin-script.c+35−21
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222 #include "util/thread_map.h"
2323 #include "util/stat.h"
2424 #include <linux/bitmap.h>
25+#include <linux/stringify.h>
2526 #include "asm/bug.h"
2627 #include "util/mem-events.h"
2728
@@ -317,19 +318,19 @@ static void set_print_ip_opts(struct perf_event_attr *attr) · 289 unmodified lines
317318
318319 output[type].print_ip_opts = 0;
319320 if (PRINT_FIELD(IP))
320− output[type].print_ip_opts |= PRINT_IP_OPT_IP;
321+ output[type].print_ip_opts |= EVSEL__PRINT_IP;
321322
322323 if (PRINT_FIELD(SYM))
323− output[type].print_ip_opts |= PRINT_IP_OPT_SYM;
324+ output[type].print_ip_opts |= EVSEL__PRINT_SYM;
324325
325326 if (PRINT_FIELD(DSO))
326− output[type].print_ip_opts |= PRINT_IP_OPT_DSO;
327+ output[type].print_ip_opts |= EVSEL__PRINT_DSO;
327328
328329 if (PRINT_FIELD(SYMOFFSET))
329− output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
330+ output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
330331
331332 if (PRINT_FIELD(SRCLINE))
332− output[type].print_ip_opts |= PRINT_IP_OPT_SRCLINE;
333+ output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
333334 }
334335
335336 /*
@@ -569,18 +570,23 @@ static void print_sample_bts(struct perf_sample *sample, · 233 unmodified lines
569570 /* print branch_from information */
570571 if (PRINT_FIELD(IP)) {
571572 unsigned int print_opts = output[attr->type].print_ip_opts;
573+ struct callchain_cursor *cursor = NULL;
572574
573− if (symbol_conf.use_callchain && sample->callchain) {
574− printf("\n");
575− } else {
576− printf(" ");
577− if (print_opts & PRINT_IP_OPT_SRCLINE) {
575+ if (symbol_conf.use_callchain && sample->callchain &&
576+ thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
577+ sample, NULL, NULL, scripting_max_stack) == 0)
578+ cursor = &callchain_cursor;
579+
580+ if (cursor == NULL) {
581+ putchar(' ');
582+ if (print_opts & EVSEL__PRINT_SRCLINE) {
578583 print_srcline_last = true;
579− print_opts &= ~PRINT_IP_OPT_SRCLINE;
584+ print_opts &= ~EVSEL__PRINT_SRCLINE;
580585 }
581− }
582− perf_evsel__print_ip(evsel, sample, al, print_opts,
583− scripting_max_stack);
586+ } else
587+ putchar('\n');
588+
589+ sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout);
584590 }
585591
586592 /* print branch_to information */
@@ -783,14 +789,15 @@ static void process_event(struct perf_script *script, · 196 unmodified lines
783789 printf("%16" PRIu64, sample->weight);
784790
785791 if (PRINT_FIELD(IP)) {
786− if (!symbol_conf.use_callchain)
787− printf(" ");
788− else
789− printf("\n");
792+ struct callchain_cursor *cursor = NULL;
793+
794+ if (symbol_conf.use_callchain && sample->callchain &&
795+ thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
796+ sample, NULL, NULL, scripting_max_stack) == 0)
797+ cursor = &callchain_cursor;
790798
791− perf_evsel__print_ip(evsel, sample, al,
792− output[attr->type].print_ip_opts,
793− scripting_max_stack);
799+ putchar(cursor ? '\n' : ' ');
800+ sample__fprintf_sym(sample, al, 0, output[attr->type].print_ip_opts, cursor, stdout);
794801 }
795802
796803 if (PRINT_FIELD(IREGS))
@@ -1959,6 +1966,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) · 1162 unmodified lines
19591966 .exit = perf_event__process_exit,
19601967 .fork = perf_event__process_fork,
19611968 .attr = process_attr,
1969+ .event_update = perf_event__process_event_update,
19621970 .tracing_data = perf_event__process_tracing_data,
19631971 .build_id = perf_event__process_build_id,
19641972 .id_index = perf_event__process_id_index,
@@ -2020,6 +2028,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) · 55 unmodified lines
20202028 "only consider symbols in these pids"),
20212029 OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
20222030 "only consider symbols in these tids"),
2031+ OPT_UINTEGER(0, "max-stack", &scripting_max_stack,
2032+ "Set the maximum stack depth when parsing the callchain, "
2033+ "anything beyond the specified depth will be ignored. "
2034+ "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
20232035 OPT_BOOLEAN('I', "show-info", &show_full_info,
20242036 "display extended information from perf.data file"),
20252037 OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
@@ -2055,6 +2067,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) · 29 unmodified lines
20552067 NULL
20562068 };
20572069
2070+ scripting_max_stack = sysctl_perf_event_max_stack;
2071+
20582072 setup_scripting();
20592073
20602074 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
tools/perf/builtin-stat.c+8−0
@@ -298,6 +298,14 @@ static int read_counter(struct perf_evsel *counter) · 297 unmodified lines
298298 return -1;
299299 }
300300 }
301+
302+ if (verbose > 1) {
303+ fprintf(stat_config.output,
304+ "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
305+ perf_evsel__name(counter),
306+ cpu,
307+ count->val, count->ena, count->run);
308+ }
301309 }
302310 }
303311
tools/perf/builtin-top.c+19−20
@@ -688,7 +688,7 @@ static int hist_iter__top_callback(struct hist_entry_iter *iter, · 687 unmodified lines
688688 struct hist_entry *he = iter->he;
689689 struct perf_evsel *evsel = iter->evsel;
690690
691− if (sort__has_sym && single)
691+ if (perf_hpp_list.sym && single)
692692 perf_top__record_precise_ip(top, he, evsel->idx, al->addr);
693693
694694 hist__account_cycles(iter->sample->branch_stack, al, iter->sample,
@@ -886,7 +886,7 @@ static int perf_top__start_counters(struct perf_top *top) · 191 unmodified lines
886886 struct perf_evlist *evlist = top->evlist;
887887 struct record_opts *opts = &top->record_opts;
888888
889− perf_evlist__config(evlist, opts);
889+ perf_evlist__config(evlist, opts, &callchain_param);
890890
891891 evlist__for_each(evlist, counter) {
892892 try_again:
@@ -917,15 +917,15 @@ out_err: · 24 unmodified lines
917917 return -1;
918918 }
919919
920−static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)
920+static int callchain_param__setup_sample_type(struct callchain_param *callchain)
921921 {
922− if (!sort__has_sym) {
923− if (symbol_conf.use_callchain) {
922+ if (!perf_hpp_list.sym) {
923+ if (callchain->enabled) {
924924 ui__error("Selected -g but \"sym\" not present in --sort/-s.");
925925 return -EINVAL;
926926 }
927− } else if (callchain_param.mode != CHAIN_NONE) {
928− if (callchain_register_param(&callchain_param) < 0) {
927+ } else if (callchain->mode != CHAIN_NONE) {
928+ if (callchain_register_param(callchain) < 0) {
929929 ui__error("Can't register callchain params.\n");
930930 return -EINVAL;
931931 }
@@ -952,7 +952,7 @@ static int __cmd_top(struct perf_top *top) · 20 unmodified lines
952952 goto out_delete;
953953 }
954954
955− ret = perf_top__setup_sample_type(top);
955+ ret = callchain_param__setup_sample_type(&callchain_param);
956956 if (ret)
957957 goto out_delete;
958958
@@ -962,7 +962,7 @@ static int __cmd_top(struct perf_top *top) · 3 unmodified lines
962962 machine__synthesize_threads(&top->session->machines.host, &opts->target,
963963 top->evlist->threads, false, opts->proc_map_timeout);
964964
965− if (sort__has_socket) {
965+ if (perf_hpp_list.socket) {
966966 ret = perf_env__read_cpu_topology_map(&perf_env);
967967 if (ret < 0)
968968 goto out_err_cpu_topo;
@@ -1045,18 +1045,17 @@ callchain_opt(const struct option *opt, const char *arg, int unset) · 76 unmodified lines
10451045 static int
10461046 parse_callchain_opt(const struct option *opt, const char *arg, int unset)
10471047 {
1048− struct record_opts *record = (struct record_opts *)opt->value;
1048+ struct callchain_param *callchain = opt->value;
10491049
1050− record->callgraph_set = true;
1051− callchain_param.enabled = !unset;
1052− callchain_param.record_mode = CALLCHAIN_FP;
1050+ callchain->enabled = !unset;
1051+ callchain->record_mode = CALLCHAIN_FP;
10531052
10541053 /*
10551054 * --no-call-graph
10561055 */
10571056 if (unset) {
10581057 symbol_conf.use_callchain = false;
1059− callchain_param.record_mode = CALLCHAIN_NONE;
1058+ callchain->record_mode = CALLCHAIN_NONE;
10601059 return 0;
10611060 }
10621061
@@ -1104,7 +1103,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) · 41 unmodified lines
11041103 },
11051104 .proc_map_timeout = 500,
11061105 },
1107− .max_stack = PERF_MAX_STACK_DEPTH,
1106+ .max_stack = sysctl_perf_event_max_stack,
11081107 .sym_pcnt_filter = 5,
11091108 };
11101109 struct record_opts *opts = &top.record_opts;
@@ -1162,17 +1161,17 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) · 51 unmodified lines
11621161 "output field(s): overhead, period, sample plus all of sort keys"),
11631162 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
11641163 "Show a column with the number of samples"),
1165− OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
1164+ OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
11661165 NULL, "enables call-graph recording and display",
11671166 &callchain_opt),
1168− OPT_CALLBACK(0, "call-graph", &top.record_opts,
1167+ OPT_CALLBACK(0, "call-graph", &callchain_param,
11691168 "record_mode[,record_size],print_type,threshold[,print_limit],order,sort_key[,branch]",
11701169 top_callchain_help, &parse_callchain_opt),
11711170 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
11721171 "Accumulate callchains of children and show total overhead as well"),
11731172 OPT_INTEGER(0, "max-stack", &top.max_stack,
11741173 "Set the maximum stack depth when parsing the callchain. "
1175− "Default: " __stringify(PERF_MAX_STACK_DEPTH)),
1174+ "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
11761175 OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
11771176 "ignore callees of these functions in call graphs",
11781177 report_parse_ignore_callees_opt),
@@ -1256,7 +1255,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) · 77 unmodified lines
12561255
12571256 sort__mode = SORT_MODE__TOP;
12581257 /* display thread wants entries to be collapsed in a different tree */
1259− sort__need_collapse = 1;
1258+ perf_hpp_list.need_collapse = 1;
12601259
12611260 if (top.use_stdio)
12621261 use_browser = 0;
@@ -1312,7 +1311,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) · 49 unmodified lines
13121311
13131312 top.sym_evsel = perf_evlist__first(top.evlist);
13141313
1315− if (!symbol_conf.use_callchain) {
1314+ if (!callchain_param.enabled) {
13161315 symbol_conf.cumulate_callchain = false;
13171316 perf_hpp__cancel_cumulate();
13181317 }
tools/perf/builtin-trace.c+416−669
@@ -34,79 +34,76 @@ · 33 unmodified lines
3434 #include "trace-event.h"
3535 #include "util/parse-events.h"
3636 #include "util/bpf-loader.h"
37+#include "callchain.h"
38+#include "syscalltbl.h"
39+#include "rb_resort.h"
3740
38−#include <libaudit.h>
41+#include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */
3942 #include <stdlib.h>
40−#include <sys/mman.h>
41−#include <linux/futex.h>
4243 #include <linux/err.h>
43−
44−/* For older distros: */
45−#ifndef MAP_STACK
46−# define MAP_STACK 0x20000
47−#endif
48−
49−#ifndef MADV_HWPOISON
50−# define MADV_HWPOISON 100
51−
52−#endif
53−
54−#ifndef MADV_MERGEABLE
55−# define MADV_MERGEABLE 12
56−#endif
57−
58−#ifndef MADV_UNMERGEABLE
59−# define MADV_UNMERGEABLE 13
60−#endif
61−
62−#ifndef EFD_SEMAPHORE
63−# define EFD_SEMAPHORE 1
64−#endif
65−
66−#ifndef EFD_NONBLOCK
67−# define EFD_NONBLOCK 00004000
68−#endif
69−
70−#ifndef EFD_CLOEXEC
71−# define EFD_CLOEXEC 02000000
72−#endif
44+#include <linux/filter.h>
45+#include <linux/audit.h>
46+#include <sys/ptrace.h>
47+#include <linux/random.h>
48+#include <linux/stringify.h>
7349
7450 #ifndef O_CLOEXEC
7551 # define O_CLOEXEC 02000000
7652 #endif
7753
78−#ifndef SOCK_DCCP
79−# define SOCK_DCCP 6
80−#endif
81−
82−#ifndef SOCK_CLOEXEC
83−# define SOCK_CLOEXEC 02000000
84−#endif
85−
86−#ifndef SOCK_NONBLOCK
87−# define SOCK_NONBLOCK 00004000
88−#endif
89−
90−#ifndef MSG_CMSG_CLOEXEC
91−# define MSG_CMSG_CLOEXEC 0x40000000
92−#endif
93−
94−#ifndef PERF_FLAG_FD_NO_GROUP
95−# define PERF_FLAG_FD_NO_GROUP (1UL << 0)
96−#endif
97−
98−#ifndef PERF_FLAG_FD_OUTPUT
99−# define PERF_FLAG_FD_OUTPUT (1UL << 1)
100−#endif
101−
102−#ifndef PERF_FLAG_PID_CGROUP
103−# define PERF_FLAG_PID_CGROUP (1UL << 2) /* pid=cgroup id, per-cpu mode only */
104−#endif
105−
106−#ifndef PERF_FLAG_FD_CLOEXEC
107−# define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */
108−#endif
109−
54+struct trace {
55+ struct perf_tool tool;
56+ struct syscalltbl *sctbl;
57+ struct {
58+ int max;
59+ struct syscall *table;
60+ struct {
61+ struct perf_evsel *sys_enter,
62+ *sys_exit;
63+ } events;
64+ } syscalls;
65+ struct record_opts opts;
66+ struct perf_evlist *evlist;
67+ struct machine *host;
68+ struct thread *current;
69+ u64 base_time;
70+ FILE *output;
71+ unsigned long nr_events;
72+ struct strlist *ev_qualifier;
73+ struct {
74+ size_t nr;
75+ int *entries;
76+ } ev_qualifier_ids;
77+ struct intlist *tid_list;
78+ struct intlist *pid_list;
79+ struct {
80+ size_t nr;
81+ pid_t *entries;
82+ } filter_pids;
83+ double duration_filter;
84+ double runtime_ms;
85+ struct {
86+ u64 vfs_getname,
87+ proc_getname;
88+ } stats;
89+ unsigned int max_stack;
90+ unsigned int min_stack;
91+ bool not_ev_qualifier;
92+ bool live;
93+ bool full_time;
94+ bool sched;
95+ bool multiple_threads;
96+ bool summary;
97+ bool summary_only;
98+ bool show_comm;
99+ bool show_tool_stats;
100+ bool trace_syscalls;
101+ bool kernel_syscallchains;
102+ bool force;
103+ bool vfs_getname;
104+ int trace_pgfaults;
105+ int open_id;
106+};
110107
111108 struct tp_field {
112109 int offset;
@@ -371,221 +368,6 @@ static size_t syscall_arg__scnprintf_int(char *bf, size_t size, · 258 unmodified lines
371368
372369 #define SCA_INT syscall_arg__scnprintf_int
373370
374−static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
375− struct syscall_arg *arg)
376−{
377− int printed = 0, prot = arg->val;
378−
379− if (prot == PROT_NONE)
380− return scnprintf(bf, size, "NONE");
381−#define P_MMAP_PROT(n) \
382− if (prot & PROT_##n) { \
383− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
384− prot &= ~PROT_##n; \
385− }
386−
387− P_MMAP_PROT(EXEC);
388− P_MMAP_PROT(READ);
389− P_MMAP_PROT(WRITE);
390−#ifdef PROT_SEM
391− P_MMAP_PROT(SEM);
392−#endif
393− P_MMAP_PROT(GROWSDOWN);
394− P_MMAP_PROT(GROWSUP);
395−#undef P_MMAP_PROT
396−
397− if (prot)
398− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", prot);
399−
400− return printed;
401−}
402−
403−#define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
404−
405−static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
406− struct syscall_arg *arg)
407−{
408− int printed = 0, flags = arg->val;
409−
410−#define P_MMAP_FLAG(n) \
411− if (flags & MAP_##n) { \
412− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
413− flags &= ~MAP_##n; \
414− }
415−
416− P_MMAP_FLAG(SHARED);
417− P_MMAP_FLAG(PRIVATE);
418−#ifdef MAP_32BIT
419− P_MMAP_FLAG(32BIT);
420−#endif
421− P_MMAP_FLAG(ANONYMOUS);
422− P_MMAP_FLAG(DENYWRITE);
423− P_MMAP_FLAG(EXECUTABLE);
424− P_MMAP_FLAG(FILE);
425− P_MMAP_FLAG(FIXED);
426− P_MMAP_FLAG(GROWSDOWN);
427−#ifdef MAP_HUGETLB
428− P_MMAP_FLAG(HUGETLB);
429−#endif
430− P_MMAP_FLAG(LOCKED);
431− P_MMAP_FLAG(NONBLOCK);
432− P_MMAP_FLAG(NORESERVE);
433− P_MMAP_FLAG(POPULATE);
434− P_MMAP_FLAG(STACK);
435−#ifdef MAP_UNINITIALIZED
436− P_MMAP_FLAG(UNINITIALIZED);
437−#endif
438−#undef P_MMAP_FLAG
439−
440− if (flags)
441− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
442−
443− return printed;
444−}
445−
446−#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
447−
448−static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
449− struct syscall_arg *arg)
450−{
451− int printed = 0, flags = arg->val;
452−
453−#define P_MREMAP_FLAG(n) \
454− if (flags & MREMAP_##n) { \
455− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
456− flags &= ~MREMAP_##n; \
457− }
458−
459− P_MREMAP_FLAG(MAYMOVE);
460−#ifdef MREMAP_FIXED
461− P_MREMAP_FLAG(FIXED);
462−#endif
463−#undef P_MREMAP_FLAG
464−
465− if (flags)
466− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
467−
468− return printed;
469−}
470−
471−#define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags
472−
473−static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
474− struct syscall_arg *arg)
475−{
476− int behavior = arg->val;
477−
478− switch (behavior) {
479−#define P_MADV_BHV(n) case MADV_##n: return scnprintf(bf, size, #n)
480− P_MADV_BHV(NORMAL);
481− P_MADV_BHV(RANDOM);
482− P_MADV_BHV(SEQUENTIAL);
483− P_MADV_BHV(WILLNEED);
484− P_MADV_BHV(DONTNEED);
485− P_MADV_BHV(REMOVE);
486− P_MADV_BHV(DONTFORK);
487− P_MADV_BHV(DOFORK);
488− P_MADV_BHV(HWPOISON);
489−#ifdef MADV_SOFT_OFFLINE
490− P_MADV_BHV(SOFT_OFFLINE);
491−#endif
492− P_MADV_BHV(MERGEABLE);
493− P_MADV_BHV(UNMERGEABLE);
494−#ifdef MADV_HUGEPAGE
495− P_MADV_BHV(HUGEPAGE);
496−#endif
497−#ifdef MADV_NOHUGEPAGE
498− P_MADV_BHV(NOHUGEPAGE);
499−#endif
500−#ifdef MADV_DONTDUMP
501− P_MADV_BHV(DONTDUMP);
502−#endif
503−#ifdef MADV_DODUMP
504− P_MADV_BHV(DODUMP);
505−#endif
506−#undef P_MADV_PHV
507− default: break;
508− }
509−
510− return scnprintf(bf, size, "%#x", behavior);
511−}
512−
513−#define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior
514−
515−static size_t syscall_arg__scnprintf_flock(char *bf, size_t size,
516− struct syscall_arg *arg)
517−{
518− int printed = 0, op = arg->val;
519−
520− if (op == 0)
521− return scnprintf(bf, size, "NONE");
522−#define P_CMD(cmd) \
523− if ((op & LOCK_##cmd) == LOCK_##cmd) { \
524− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \
525− op &= ~LOCK_##cmd; \
526− }
527−
528− P_CMD(SH);
529− P_CMD(EX);
530− P_CMD(NB);
531− P_CMD(UN);
532− P_CMD(MAND);
533− P_CMD(RW);
534− P_CMD(READ);
535− P_CMD(WRITE);
536−#undef P_OP
537−
538− if (op)
539− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", op);
540−
541− return printed;
542−}
543−
544−#define SCA_FLOCK syscall_arg__scnprintf_flock
545−
546−static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg)
547−{
548− enum syscall_futex_args {
549− SCF_UADDR = (1 << 0),
550− SCF_OP = (1 << 1),
551− SCF_VAL = (1 << 2),
552− SCF_TIMEOUT = (1 << 3),
553− SCF_UADDR2 = (1 << 4),
554− SCF_VAL3 = (1 << 5),
555− };
556− int op = arg->val;
557− int cmd = op & FUTEX_CMD_MASK;
558− size_t printed = 0;
559−
560− switch (cmd) {
561−#define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n);
562− P_FUTEX_OP(WAIT); arg->mask |= SCF_VAL3|SCF_UADDR2; break;
563− P_FUTEX_OP(WAKE); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
564− P_FUTEX_OP(FD); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
565− P_FUTEX_OP(REQUEUE); arg->mask |= SCF_VAL3|SCF_TIMEOUT; break;
566− P_FUTEX_OP(CMP_REQUEUE); arg->mask |= SCF_TIMEOUT; break;
567− P_FUTEX_OP(CMP_REQUEUE_PI); arg->mask |= SCF_TIMEOUT; break;
568− P_FUTEX_OP(WAKE_OP); break;
569− P_FUTEX_OP(LOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
570− P_FUTEX_OP(UNLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
571− P_FUTEX_OP(TRYLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2; break;
572− P_FUTEX_OP(WAIT_BITSET); arg->mask |= SCF_UADDR2; break;
573− P_FUTEX_OP(WAKE_BITSET); arg->mask |= SCF_UADDR2; break;
574− P_FUTEX_OP(WAIT_REQUEUE_PI); break;
575− default: printed = scnprintf(bf, size, "%#x", cmd); break;
576− }
577−
578− if (op & FUTEX_PRIVATE_FLAG)
579− printed += scnprintf(bf + printed, size - printed, "|PRIV");
580−
581− if (op & FUTEX_CLOCK_REALTIME)
582− printed += scnprintf(bf + printed, size - printed, "|CLKRT");
583−
584− return printed;
585−}
586−
587−#define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op
588−
589371 static const char *bpf_cmd[] = {
590372 "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM",
591373 "MAP_GET_NEXT_KEY", "PROG_LOAD",
@@ -652,110 +434,6 @@ static const char *socket_families[] = { · 60 unmodified lines
652434 };
653435 static DEFINE_STRARRAY(socket_families);
654436
655−#ifndef SOCK_TYPE_MASK
656−#define SOCK_TYPE_MASK 0xf
657−#endif
658−
659−static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size,
660− struct syscall_arg *arg)
661−{
662− size_t printed;
663− int type = arg->val,
664− flags = type & ~SOCK_TYPE_MASK;
665−
666− type &= SOCK_TYPE_MASK;
667− /*
668− * Can't use a strarray, MIPS may override for ABI reasons.
669− */
670− switch (type) {
671−#define P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
672− P_SK_TYPE(STREAM);
673− P_SK_TYPE(DGRAM);
674− P_SK_TYPE(RAW);
675− P_SK_TYPE(RDM);
676− P_SK_TYPE(SEQPACKET);
677− P_SK_TYPE(DCCP);
678− P_SK_TYPE(PACKET);
679−#undef P_SK_TYPE
680− default:
681− printed = scnprintf(bf, size, "%#x", type);
682− }
683−
684−#define P_SK_FLAG(n) \
685− if (flags & SOCK_##n) { \
686− printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
687− flags &= ~SOCK_##n; \
688− }
689−
690− P_SK_FLAG(CLOEXEC);
691− P_SK_FLAG(NONBLOCK);
692−#undef P_SK_FLAG
693−
694− if (flags)
695− printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
696−
697− return printed;
698−}
699−
700−#define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
701−
702−#ifndef MSG_PROBE
703−#define MSG_PROBE 0x10
704−#endif
705−#ifndef MSG_WAITFORONE
706−#define MSG_WAITFORONE 0x10000
707−#endif
708−#ifndef MSG_SENDPAGE_NOTLAST
709−#define MSG_SENDPAGE_NOTLAST 0x20000
710−#endif
711−#ifndef MSG_FASTOPEN
712−#define MSG_FASTOPEN 0x20000000
713−#endif
714−
715−static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
716− struct syscall_arg *arg)
717−{
718− int printed = 0, flags = arg->val;
719−
720− if (flags == 0)
721− return scnprintf(bf, size, "NONE");
722−#define P_MSG_FLAG(n) \
723− if (flags & MSG_##n) { \
724− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
725− flags &= ~MSG_##n; \
726− }
727−
728− P_MSG_FLAG(OOB);
729− P_MSG_FLAG(PEEK);
730− P_MSG_FLAG(DONTROUTE);
731− P_MSG_FLAG(TRYHARD);
732− P_MSG_FLAG(CTRUNC);
733− P_MSG_FLAG(PROBE);
734− P_MSG_FLAG(TRUNC);
735− P_MSG_FLAG(DONTWAIT);
736− P_MSG_FLAG(EOR);
737− P_MSG_FLAG(WAITALL);
738− P_MSG_FLAG(FIN);
739− P_MSG_FLAG(SYN);
740− P_MSG_FLAG(CONFIRM);
741− P_MSG_FLAG(RST);
742− P_MSG_FLAG(ERRQUEUE);
743− P_MSG_FLAG(NOSIGNAL);
744− P_MSG_FLAG(MORE);
745− P_MSG_FLAG(WAITFORONE);
746− P_MSG_FLAG(SENDPAGE_NOTLAST);
747− P_MSG_FLAG(FASTOPEN);
748− P_MSG_FLAG(CMSG_CLOEXEC);
749−#undef P_MSG_FLAG
750−
751− if (flags)
752− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
753−
754− return printed;
755−}
756−
757−#define SCA_MSG_FLAGS syscall_arg__scnprintf_msg_flags
758−
759437 static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size,
760438 struct syscall_arg *arg)
761439 {
@@ -788,116 +466,6 @@ static size_t syscall_arg__scnprintf_filename(char *bf, size_t size, · 26 unmodified lines
788466
789467 #define SCA_FILENAME syscall_arg__scnprintf_filename
790468
791−static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
792− struct syscall_arg *arg)
793−{
794− int printed = 0, flags = arg->val;
795−
796− if (!(flags & O_CREAT))
797− arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */
798−
799− if (flags == 0)
800− return scnprintf(bf, size, "RDONLY");
801−#define P_FLAG(n) \
802− if (flags & O_##n) { \
803− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
804− flags &= ~O_##n; \
805− }
806−
807− P_FLAG(APPEND);
808− P_FLAG(ASYNC);
809− P_FLAG(CLOEXEC);
810− P_FLAG(CREAT);
811− P_FLAG(DIRECT);
812− P_FLAG(DIRECTORY);
813− P_FLAG(EXCL);
814− P_FLAG(LARGEFILE);
815− P_FLAG(NOATIME);
816− P_FLAG(NOCTTY);
817−#ifdef O_NONBLOCK
818− P_FLAG(NONBLOCK);
819−#elif O_NDELAY
820− P_FLAG(NDELAY);
821−#endif
822−#ifdef O_PATH
823− P_FLAG(PATH);
824−#endif
825− P_FLAG(RDWR);
826−#ifdef O_DSYNC
827− if ((flags & O_SYNC) == O_SYNC)
828− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC");
829− else {
830− P_FLAG(DSYNC);
831− }
832−#else
833− P_FLAG(SYNC);
834−#endif
835− P_FLAG(TRUNC);
836− P_FLAG(WRONLY);
837−#undef P_FLAG
838−
839− if (flags)
840− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
841−
842− return printed;
843−}
844−
845−#define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags
846−
847−static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size,
848− struct syscall_arg *arg)
849−{
850− int printed = 0, flags = arg->val;
851−
852− if (flags == 0)
853− return 0;
854−
855−#define P_FLAG(n) \
856− if (flags & PERF_FLAG_##n) { \
857− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
858− flags &= ~PERF_FLAG_##n; \
859− }
860−
861− P_FLAG(FD_NO_GROUP);
862− P_FLAG(FD_OUTPUT);
863− P_FLAG(PID_CGROUP);
864− P_FLAG(FD_CLOEXEC);
865−#undef P_FLAG
866−
867− if (flags)
868− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
869−
870− return printed;
871−}
872−
873−#define SCA_PERF_FLAGS syscall_arg__scnprintf_perf_flags
874−
875−static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size,
876− struct syscall_arg *arg)
877−{
878− int printed = 0, flags = arg->val;
879−
880− if (flags == 0)
881− return scnprintf(bf, size, "NONE");
882−#define P_FLAG(n) \
883− if (flags & EFD_##n) { \
884− printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
885− flags &= ~EFD_##n; \
886− }
887−
888− P_FLAG(SEMAPHORE);
889− P_FLAG(CLOEXEC);
890− P_FLAG(NONBLOCK);
891−#undef P_FLAG
892−
893− if (flags)
894− printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
895−
896− return printed;
897−}
898−
899−#define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags
900−
901469 static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size,
902470 struct syscall_arg *arg)
903471 {
@@ -921,59 +489,6 @@ static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, · 17 unmodified lines
921489
922490 #define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags
923491
924−static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg)
925−{
926− int sig = arg->val;
927−
928− switch (sig) {
929−#define P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n)
930− P_SIGNUM(HUP);
931− P_SIGNUM(INT);
932− P_SIGNUM(QUIT);
933− P_SIGNUM(ILL);
934− P_SIGNUM(TRAP);
935− P_SIGNUM(ABRT);
936− P_SIGNUM(BUS);
937− P_SIGNUM(FPE);
938− P_SIGNUM(KILL);
939− P_SIGNUM(USR1);
940− P_SIGNUM(SEGV);
941− P_SIGNUM(USR2);
942− P_SIGNUM(PIPE);
943− P_SIGNUM(ALRM);
944− P_SIGNUM(TERM);
945− P_SIGNUM(CHLD);
946− P_SIGNUM(CONT);
947− P_SIGNUM(STOP);
948− P_SIGNUM(TSTP);
949− P_SIGNUM(TTIN);
950− P_SIGNUM(TTOU);
951− P_SIGNUM(URG);
952− P_SIGNUM(XCPU);
953− P_SIGNUM(XFSZ);
954− P_SIGNUM(VTALRM);
955− P_SIGNUM(PROF);
956− P_SIGNUM(WINCH);
957− P_SIGNUM(IO);
958− P_SIGNUM(PWR);
959− P_SIGNUM(SYS);
960−#ifdef SIGEMT
961− P_SIGNUM(EMT);
962−#endif
963−#ifdef SIGSTKFLT
964− P_SIGNUM(STKFLT);
965−#endif
966−#ifdef SIGSWI
967− P_SIGNUM(SWI);
968−#endif
969− default: break;
970− }
971−
972− return scnprintf(bf, size, "%#x", sig);
973−}
974−
975−#define SCA_SIGNUM syscall_arg__scnprintf_signum
976−
977492 #if defined(__i386__) || defined(__x86_64__)
978493 /*
979494 * FIXME: Make this available to all arches.
@@ -1001,16 +516,62 @@ static const char *tioctls[] = { · 21 unmodified lines
1001516 static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401);
1002517 #endif /* defined(__i386__) || defined(__x86_64__) */
1003518
519+#ifndef GRND_NONBLOCK
520+#define GRND_NONBLOCK 0x0001
521+#endif
522+#ifndef GRND_RANDOM
523+#define GRND_RANDOM 0x0002
524+#endif
525+
526+static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size,
527+ struct syscall_arg *arg)
528+{
529+ int printed = 0, flags = arg->val;
530+
531+#define P_FLAG(n) \
532+ if (flags & GRND_##n) { \
533+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
534+ flags &= ~GRND_##n; \
535+ }
536+
537+ P_FLAG(RANDOM);
538+ P_FLAG(NONBLOCK);
539+#undef P_FLAG
540+
541+ if (flags)
542+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
543+
544+ return printed;
545+}
546+
547+#define SCA_GETRANDOM_FLAGS syscall_arg__scnprintf_getrandom_flags
548+
1004549 #define STRARRAY(arg, name, array) \
1005550 .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \
1006551 .arg_parm = { [arg] = &strarray__##array, }
1007552
553+#include "trace/beauty/eventfd.c"
554+#include "trace/beauty/flock.c"
555+#include "trace/beauty/futex_op.c"
556+#include "trace/beauty/mmap.c"
557+#include "trace/beauty/mode_t.c"
558+#include "trace/beauty/msg_flags.c"
559+#include "trace/beauty/open_flags.c"
560+#include "trace/beauty/perf_event_open.c"
561+#include "trace/beauty/pid.c"
562+#include "trace/beauty/sched_policy.c"
563+#include "trace/beauty/seccomp.c"
564+#include "trace/beauty/signum.c"
565+#include "trace/beauty/socket_type.c"
566+#include "trace/beauty/waitid_options.c"
567+
1008568 static struct syscall_fmt {
1009569 const char *name;
1010570 const char *alias;
1011571 size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg);
1012572 void *arg_parm[6];
1013573 bool errmsg;
574+ bool errpid;
1014575 bool timeout;
1015576 bool hexret;
1016577 } syscall_fmts[] = {
@@ -1028,6 +589,7 @@ static struct syscall_fmt { · 11 unmodified lines
1028589 { .name = "chroot", .errmsg = true,
1029590 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1030591 { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), },
592+ { .name = "clone", .errpid = true, },
1031593 { .name = "close", .errmsg = true,
1032594 .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, },
1033595 { .name = "connect", .errmsg = true, },
@@ -1093,6 +655,11 @@ static struct syscall_fmt { · 59 unmodified lines
1093655 { .name = "getdents64", .errmsg = true,
1094656 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1095657 { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), },
658+ { .name = "getpid", .errpid = true, },
659+ { .name = "getpgid", .errpid = true, },
660+ { .name = "getppid", .errpid = true, },
661+ { .name = "getrandom", .errmsg = true,
662+ .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, },
1096663 { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
1097664 { .name = "getxattr", .errmsg = true,
1098665 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
@@ -1186,8 +753,7 @@ static struct syscall_fmt { · 87 unmodified lines
1186753 [1] = SCA_FILENAME, /* filename */
1187754 [2] = SCA_OPEN_FLAGS, /* flags */ }, },
1188755 { .name = "perf_event_open", .errmsg = true,
1189− .arg_scnprintf = { [1] = SCA_INT, /* pid */
1190− [2] = SCA_INT, /* cpu */
756+ .arg_scnprintf = { [2] = SCA_INT, /* cpu */
1191757 [3] = SCA_FD, /* group_fd */
1192758 [4] = SCA_PERF_FLAGS, /* flags */ }, },
1193759 { .name = "pipe2", .errmsg = true,
@@ -1234,6 +800,11 @@ static struct syscall_fmt { · 40 unmodified lines
1234800 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1235801 { .name = "rt_tgsigqueueinfo", .errmsg = true,
1236802 .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
803+ { .name = "sched_setscheduler", .errmsg = true,
804+ .arg_scnprintf = { [1] = SCA_SCHED_POLICY, /* policy */ }, },
805+ { .name = "seccomp", .errmsg = true,
806+ .arg_scnprintf = { [0] = SCA_SECCOMP_OP, /* op */
807+ [1] = SCA_SECCOMP_FLAGS, /* flags */ }, },
1237808 { .name = "select", .errmsg = true, .timeout = true, },
1238809 { .name = "sendmmsg", .errmsg = true,
1239810 .arg_scnprintf = { [0] = SCA_FD, /* fd */
@@ -1244,7 +815,9 @@ static struct syscall_fmt { · 4 unmodified lines
1244815 { .name = "sendto", .errmsg = true,
1245816 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1246817 [3] = SCA_MSG_FLAGS, /* flags */ }, },
818+ { .name = "set_tid_address", .errpid = true, },
1247819 { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), },
820+ { .name = "setpgid", .errmsg = true, },
1248821 { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
1249822 { .name = "setxattr", .errmsg = true,
1250823 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
@@ -1287,6 +860,10 @@ static struct syscall_fmt { · 36 unmodified lines
1287860 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1288861 { .name = "vmsplice", .errmsg = true,
1289862 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
863+ { .name = "wait4", .errpid = true,
864+ .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, },
865+ { .name = "waitid", .errpid = true,
866+ .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, },
1290867 { .name = "write", .errmsg = true,
1291868 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1292869 { .name = "writev", .errmsg = true,
@@ -1398,59 +975,6 @@ fail: · 105 unmodified lines
1398975
1399976 static const size_t trace__entry_str_size = 2048;
1400977
1401−struct trace {
1402− struct perf_tool tool;
1403− struct {
1404− int machine;
1405− int open_id;
1406− } audit;
1407− struct {
1408− int max;
1409− struct syscall *table;
1410− struct {
1411− struct perf_evsel *sys_enter,
1412− *sys_exit;
1413− } events;
1414− } syscalls;
1415− struct record_opts opts;
1416− struct perf_evlist *evlist;
1417− struct machine *host;
1418− struct thread *current;
1419− u64 base_time;
1420− FILE *output;
1421− unsigned long nr_events;
1422− struct strlist *ev_qualifier;
1423− struct {
1424− size_t nr;
1425− int *entries;
1426− } ev_qualifier_ids;
1427− struct intlist *tid_list;
1428− struct intlist *pid_list;
1429− struct {
1430− size_t nr;
1431− pid_t *entries;
1432− } filter_pids;
1433− double duration_filter;
1434− double runtime_ms;
1435− struct {
1436− u64 vfs_getname,
1437− proc_getname;
1438− } stats;
1439− bool not_ev_qualifier;
1440− bool live;
1441− bool full_time;
1442− bool sched;
1443− bool multiple_threads;
1444− bool summary;
1445− bool summary_only;
1446− bool show_comm;
1447− bool show_tool_stats;
1448− bool trace_syscalls;
1449− bool force;
1450− bool vfs_getname;
1451− int trace_pgfaults;
1452−};
1453−
1454978 static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)
1455979 {
1456980 struct thread_trace *ttrace = thread__priv(thread);
@@ -1618,6 +1142,7 @@ static int trace__process_event(struct trace *trace, struct machine *machine, · 161 unmodified lines
16181142 color_fprintf(trace->output, PERF_COLOR_RED,
16191143 "LOST %" PRIu64 " events!\n", event->lost.lost);
16201144 ret = machine__process_lost_event(machine, event, sample);
1145+ break;
16211146 default:
16221147 ret = machine__process_event(machine, event, sample);
16231148 break;
@@ -1675,6 +1200,10 @@ static int syscall__set_arg_fmts(struct syscall *sc) · 51 unmodified lines
16751200 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
16761201 else if (field->flags & FIELD_IS_POINTER)
16771202 sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex;
1203+ else if (strcmp(field->type, "pid_t") == 0)
1204+ sc->arg_scnprintf[idx] = SCA_PID;
1205+ else if (strcmp(field->type, "umode_t") == 0)
1206+ sc->arg_scnprintf[idx] = SCA_MODE_T;
16781207 ++idx;
16791208 }
16801209
@@ -1685,7 +1214,7 @@ static int trace__read_syscall_info(struct trace *trace, int id) · 4 unmodified lines
16851214 {
16861215 char tp_name[128];
16871216 struct syscall *sc;
1688− const char *name = audit_syscall_to_name(id, trace->audit.machine);
1217+ const char *name = syscalltbl__name(trace->sctbl, id);
16891218
16901219 if (name == NULL)
16911220 return -1;
@@ -1760,7 +1289,7 @@ static int trace__validate_ev_qualifier(struct trace *trace) · 68 unmodified lines
17601289
17611290 strlist__for_each(pos, trace->ev_qualifier) {
17621291 const char *sc = pos->s;
1763− int id = audit_name_to_syscall(sc, trace->audit.machine);
1292+ int id = syscalltbl__id(trace->sctbl, sc);
17641293
17651294 if (id < 0) {
17661295 if (err == 0) {
@@ -1846,7 +1375,12 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, · 79 unmodified lines
18461375 "%ld", val);
18471376 }
18481377 }
1849− } else {
1378+ } else if (IS_ERR(sc->tp_format)) {
1379+ /*
1380+ * If we managed to read the tracepoint /format file, then we
1381+ * may end up not having any args, like with gettid(), so only
1382+ * print the raw args when we didn't manage to read it.
1383+ */
18501384 int i = 0;
18511385
18521386 while (i < 6) {
@@ -1987,7 +1521,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, · 134 unmodified lines
19871521 goto out_put;
19881522 }
19891523
1990− if (!trace->summary_only)
1524+ if (!(trace->duration_filter || trace->summary_only || trace->min_stack))
19911525 trace__printf_interrupted_entry(trace, sample);
19921526
19931527 ttrace->entry_time = sample->time;
@@ -1998,7 +1532,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, · 4 unmodified lines
19981532 args, trace, thread);
19991533
20001534 if (sc->is_exit) {
2001− if (!trace->duration_filter && !trace->summary_only) {
1535+ if (!(trace->duration_filter || trace->summary_only || trace->min_stack)) {
20021536 trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
20031537 fprintf(trace->output, "%-70s\n", ttrace->entry_str);
20041538 }
@@ -2018,6 +1552,29 @@ out_put: · 13 unmodified lines
20181552 return err;
20191553 }
20201554
1555+static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evsel,
1556+ struct perf_sample *sample,
1557+ struct callchain_cursor *cursor)
1558+{
1559+ struct addr_location al;
1560+
1561+ if (machine__resolve(trace->host, &al, sample) < 0 ||
1562+ thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, trace->max_stack))
1563+ return -1;
1564+
1565+ return 0;
1566+}
1567+
1568+static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sample)
1569+{
1570+ /* TODO: user-configurable print_opts */
1571+ const unsigned int print_opts = EVSEL__PRINT_SYM |
1572+ EVSEL__PRINT_DSO |
1573+ EVSEL__PRINT_UNKNOWN_AS_ADDR;
1574+
1575+ return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output);
1576+}
1577+
20211578 static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
20221579 union perf_event *event __maybe_unused,
20231580 struct perf_sample *sample)
@@ -2025,7 +1582,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, · 1 unmodified line
20251582 long ret;
20261583 u64 duration = 0;
20271584 struct thread *thread;
2028− int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
1585+ int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0;
20291586 struct syscall *sc = trace__syscall_info(trace, evsel, id);
20301587 struct thread_trace *ttrace;
20311588
@@ -2042,7 +1599,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, · 10 unmodified lines
20421599
20431600 ret = perf_evsel__sc_tp_uint(evsel, ret, sample);
20441601
2045− if (id == trace->audit.open_id && ret >= 0 && ttrace->filename.pending_open) {
1602+ if (id == trace->open_id && ret >= 0 && ttrace->filename.pending_open) {
20461603 trace__set_fd_pathname(thread, ret, ttrace->filename.name);
20471604 ttrace->filename.pending_open = false;
20481605 ++trace->stats.vfs_getname;
@@ -2057,6 +1614,15 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, · 8 unmodified lines
20571614 } else if (trace->duration_filter)
20581615 goto out;
20591616
1617+ if (sample->callchain) {
1618+ callchain_ret = trace__resolve_callchain(trace, evsel, sample, &callchain_cursor);
1619+ if (callchain_ret == 0) {
1620+ if (callchain_cursor.nr < trace->min_stack)
1621+ goto out;
1622+ callchain_ret = 1;
1623+ }
1624+ }
1625+
20601626 if (trace->summary_only)
20611627 goto out;
20621628
@@ -2073,7 +1639,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, · 10 unmodified lines
20731639 if (sc->fmt == NULL) {
20741640 signed_print:
20751641 fprintf(trace->output, ") = %ld", ret);
2076− } else if (ret < 0 && sc->fmt->errmsg) {
1642+ } else if (ret < 0 && (sc->fmt->errmsg || sc->fmt->errpid)) {
20771643 char bf[STRERR_BUFSIZE];
20781644 const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
20791645 *e = audit_errno_to_name(-ret);
@@ -2083,10 +1649,24 @@ signed_print: · 3 unmodified lines
20831649 fprintf(trace->output, ") = 0 Timeout");
20841650 else if (sc->fmt->hexret)
20851651 fprintf(trace->output, ") = %#lx", ret);
2086− else
1652+ else if (sc->fmt->errpid) {
1653+ struct thread *child = machine__find_thread(trace->host, ret, ret);
1654+
1655+ if (child != NULL) {
1656+ fprintf(trace->output, ") = %ld", ret);
1657+ if (child->comm_set)
1658+ fprintf(trace->output, " (%s)", thread__comm_str(child));
1659+ thread__put(child);
1660+ }
1661+ } else
20871662 goto signed_print;
20881663
20891664 fputc('\n', trace->output);
1665+
1666+ if (callchain_ret > 0)
1667+ trace__fprintf_callchain(trace, sample);
1668+ else if (callchain_ret < 0)
1669+ pr_err("Problem processing %s callchain, skipping...\n", perf_evsel__name(evsel));
20901670 out:
20911671 ttrace->entry_pending = false;
20921672 err = 0;
@@ -2217,6 +1797,17 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, · 124 unmodified lines
22171797 union perf_event *event __maybe_unused,
22181798 struct perf_sample *sample)
22191799 {
1800+ int callchain_ret = 0;
1801+
1802+ if (sample->callchain) {
1803+ callchain_ret = trace__resolve_callchain(trace, evsel, sample, &callchain_cursor);
1804+ if (callchain_ret == 0) {
1805+ if (callchain_cursor.nr < trace->min_stack)
1806+ goto out;
1807+ callchain_ret = 1;
1808+ }
1809+ }
1810+
22201811 trace__printf_interrupted_entry(trace, sample);
22211812 trace__fprintf_tstamp(trace, sample->time, trace->output);
22221813
@@ -2234,6 +1825,12 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, · 11 unmodified lines
22341825 }
22351826
22361827 fprintf(trace->output, ")\n");
1828+
1829+ if (callchain_ret > 0)
1830+ trace__fprintf_callchain(trace, sample);
1831+ else if (callchain_ret < 0)
1832+ pr_err("Problem processing %s callchain, skipping...\n", perf_evsel__name(evsel));
1833+out:
22371834 return 0;
22381835 }
22391836
@@ -2264,8 +1861,19 @@ static int trace__pgfault(struct trace *trace, · 24 unmodified lines
22641861 char map_type = 'd';
22651862 struct thread_trace *ttrace;
22661863 int err = -1;
1864+ int callchain_ret = 0;
22671865
22681866 thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
1867+
1868+ if (sample->callchain) {
1869+ callchain_ret = trace__resolve_callchain(trace, evsel, sample, &callchain_cursor);
1870+ if (callchain_ret == 0) {
1871+ if (callchain_cursor.nr < trace->min_stack)
1872+ goto out_put;
1873+ callchain_ret = 1;
1874+ }
1875+ }
1876+
22691877 ttrace = thread__trace(thread, trace->output);
22701878 if (ttrace == NULL)
22711879 goto out_put;
@@ -2307,6 +1915,11 @@ static int trace__pgfault(struct trace *trace, · 35 unmodified lines
23071915 print_location(trace->output, sample, &al, true, false);
23081916
23091917 fprintf(trace->output, " (%c%c)\n", map_type, al.level);
1918+
1919+ if (callchain_ret > 0)
1920+ trace__fprintf_callchain(trace, sample);
1921+ else if (callchain_ret < 0)
1922+ pr_err("Problem processing %s callchain, skipping...\n", perf_evsel__name(evsel));
23101923 out:
23111924 err = 0;
23121925 out_put:
@@ -2326,6 +1939,23 @@ static bool skip_sample(struct trace *trace, struct perf_sample *sample) · 13 unmodified lines
23261939 return false;
23271940 }
23281941
1942+static void trace__set_base_time(struct trace *trace,
1943+ struct perf_evsel *evsel,
1944+ struct perf_sample *sample)
1945+{
1946+ /*
1947+ * BPF events were not setting PERF_SAMPLE_TIME, so be more robust
1948+ * and don't use sample->time unconditionally, we may end up having
1949+ * some other event in the future without PERF_SAMPLE_TIME for good
1950+ * reason, i.e. we may not be interested in its timestamps, just in
1951+ * it taking place, picking some piece of information when it
1952+ * appears in our event stream (vfs_getname comes to mind).
1953+ */
1954+ if (trace->base_time == 0 && !trace->full_time &&
1955+ (evsel->attr.sample_type & PERF_SAMPLE_TIME))
1956+ trace->base_time = sample->time;
1957+}
1958+
23291959 static int trace__process_sample(struct perf_tool *tool,
23301960 union perf_event *event,
23311961 struct perf_sample *sample,
@@ -2340,8 +1970,7 @@ static int trace__process_sample(struct perf_tool *tool, · 8 unmodified lines
23401970 if (skip_sample(trace, sample))
23411971 return 0;
23421972
2343− if (!trace->full_time && trace->base_time == 0)
2344− trace->base_time = sample->time;
1973+ trace__set_base_time(trace, evsel, sample);
23451974
23461975 if (handler) {
23471976 ++trace->nr_events;
@@ -2450,8 +2079,7 @@ static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) · 102 unmodified lines
24502079 return true;
24512080 }
24522081
2453−static int perf_evlist__add_pgfault(struct perf_evlist *evlist,
2454− u64 config)
2082+static struct perf_evsel *perf_evsel__new_pgfault(u64 config)
24552083 {
24562084 struct perf_evsel *evsel;
24572085 struct perf_event_attr attr = {
@@ -2465,13 +2093,10 @@ static int perf_evlist__add_pgfault(struct perf_evlist *evlist, · 7 unmodified lines
24652093 event_attr_init(&attr);
24662094
24672095 evsel = perf_evsel__new(&attr);
2468− if (!evsel)
2469− return -ENOMEM;
2470−
2471− evsel->handler = trace__pgfault;
2472− perf_evlist__add(evlist, evsel);
2096+ if (evsel)
2097+ evsel->handler = trace__pgfault;
24732098
2474− return 0;
2099+ return evsel;
24752100 }
24762101
24772102 static void trace__handle_event(struct trace *trace, union perf_event *event, struct perf_sample *sample)
@@ -2479,9 +2104,6 @@ static void trace__handle_event(struct trace *trace, union perf_event *event, st · 1 unmodified line
24792104 const u32 type = event->header.type;
24802105 struct perf_evsel *evsel;
24812106
2482− if (!trace->full_time && trace->base_time == 0)
2483− trace->base_time = sample->time;
2484−
24852107 if (type != PERF_RECORD_SAMPLE) {
24862108 trace__process_event(trace, trace->host, event, sample);
24872109 return;
@@ -2493,6 +2115,8 @@ static void trace__handle_event(struct trace *trace, union perf_event *event, st · 5 unmodified lines
24932115 return;
24942116 }
24952117
2118+ trace__set_base_time(trace, evsel, sample);
2119+
24962120 if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
24972121 sample->raw_data == NULL) {
24982122 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
@@ -2527,6 +2151,15 @@ static int trace__add_syscall_newtp(struct trace *trace) · 28 unmodified lines
25272151 perf_evlist__add(evlist, sys_enter);
25282152 perf_evlist__add(evlist, sys_exit);
25292153
2154+ if (callchain_param.enabled && !trace->kernel_syscallchains) {
2155+ /*
2156+ * We're interested only in the user space callchain
2157+ * leading to the syscall, allow overriding that for
2158+ * debugging reasons using --kernel_syscall_callchains
2159+ */
2160+ sys_exit->attr.exclude_callchain_kernel = 1;
2161+ }
2162+
25302163 trace->syscalls.events.sys_enter = sys_enter;
25312164 trace->syscalls.events.sys_exit = sys_exit;
25322165
@@ -2565,7 +2198,7 @@ out_enomem: · 32 unmodified lines
25652198 static int trace__run(struct trace *trace, int argc, const char **argv)
25662199 {
25672200 struct perf_evlist *evlist = trace->evlist;
2568− struct perf_evsel *evsel;
2201+ struct perf_evsel *evsel, *pgfault_maj = NULL, *pgfault_min = NULL;
25692202 int err = -1, i;
25702203 unsigned long before;
25712204 const bool forks = argc > 0;
@@ -2579,14 +2212,19 @@ static int trace__run(struct trace *trace, int argc, const char **argv) · 7 unmodified lines
25792212 if (trace->trace_syscalls)
25802213 trace->vfs_getname = perf_evlist__add_vfs_getname(evlist);
25812214
2582− if ((trace->trace_pgfaults & TRACE_PFMAJ) &&
2583− perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MAJ)) {
2584− goto out_error_mem;
2215+ if ((trace->trace_pgfaults & TRACE_PFMAJ)) {
2216+ pgfault_maj = perf_evsel__new_pgfault(PERF_COUNT_SW_PAGE_FAULTS_MAJ);
2217+ if (pgfault_maj == NULL)
2218+ goto out_error_mem;
2219+ perf_evlist__add(evlist, pgfault_maj);
25852220 }
25862221
2587− if ((trace->trace_pgfaults & TRACE_PFMIN) &&
2588− perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MIN))
2589− goto out_error_mem;
2222+ if ((trace->trace_pgfaults & TRACE_PFMIN)) {
2223+ pgfault_min = perf_evsel__new_pgfault(PERF_COUNT_SW_PAGE_FAULTS_MIN);
2224+ if (pgfault_min == NULL)
2225+ goto out_error_mem;
2226+ perf_evlist__add(evlist, pgfault_min);
2227+ }
25902228
25912229 if (trace->sched &&
25922230 perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime",
@@ -2605,7 +2243,45 @@ static int trace__run(struct trace *trace, int argc, const char **argv) · 12 unmodified lines
26052243 goto out_delete_evlist;
26062244 }
26072245
2608− perf_evlist__config(evlist, &trace->opts);
2246+ perf_evlist__config(evlist, &trace->opts, NULL);
2247+
2248+ if (callchain_param.enabled) {
2249+ bool use_identifier = false;
2250+
2251+ if (trace->syscalls.events.sys_exit) {
2252+ perf_evsel__config_callchain(trace->syscalls.events.sys_exit,
2253+ &trace->opts, &callchain_param);
2254+ use_identifier = true;
2255+ }
2256+
2257+ if (pgfault_maj) {
2258+ perf_evsel__config_callchain(pgfault_maj, &trace->opts, &callchain_param);
2259+ use_identifier = true;
2260+ }
2261+
2262+ if (pgfault_min) {
2263+ perf_evsel__config_callchain(pgfault_min, &trace->opts, &callchain_param);
2264+ use_identifier = true;
2265+ }
2266+
2267+ if (use_identifier) {
2268+ /*
2269+ * Now we have evsels with different sample_ids, use
2270+ * PERF_SAMPLE_IDENTIFIER to map from sample to evsel
2271+ * from a fixed position in each ring buffer record.
2272+ *
2273+ * As of this the changeset introducing this comment, this
2274+ * isn't strictly needed, as the fields that can come before
2275+ * PERF_SAMPLE_ID are all used, but we'll probably disable
2276+ * some of those for things like copying the payload of
2277+ * pointer syscall arguments, and for vfs_getname we don't
2278+ * need PERF_SAMPLE_ADDR and PERF_SAMPLE_IP, so do this
2279+ * here as a warning we need to use PERF_SAMPLE_IDENTIFIER.
2280+ */
2281+ perf_evlist__set_sample_bit(evlist, IDENTIFIER);
2282+ perf_evlist__reset_sample_bit(evlist, ID);
2283+ }
2284+ }
26092285
26102286 signal(SIGCHLD, sig_handler);
26112287 signal(SIGINT, sig_handler);
@@ -2883,15 +2559,29 @@ static size_t trace__fprintf_threads_header(FILE *fp) · 271 unmodified lines
28832559 return printed;
28842560 }
28852561
2562+DEFINE_RESORT_RB(syscall_stats, a->msecs > b->msecs,
2563+ struct stats *stats;
2564+ double msecs;
2565+ int syscall;
2566+)
2567+{
2568+ struct int_node *source = rb_entry(nd, struct int_node, rb_node);
2569+ struct stats *stats = source->priv;
2570+
2571+ entry->syscall = source->i;
2572+ entry->stats = stats;
2573+ entry->msecs = stats ? (u64)stats->n * (avg_stats(stats) / NSEC_PER_MSEC) : 0;
2574+}
2575+
28862576 static size_t thread__dump_stats(struct thread_trace *ttrace,
28872577 struct trace *trace, FILE *fp)
28882578 {
2889− struct stats *stats;
28902579 size_t printed = 0;
28912580 struct syscall *sc;
2892− struct int_node *inode = intlist__first(ttrace->syscall_stats);
2581+ struct rb_node *nd;
2582+ DECLARE_RESORT_RB_INTLIST(syscall_stats, ttrace->syscall_stats);
28932583
2894− if (inode == NULL)
2584+ if (syscall_stats == NULL)
28952585 return 0;
28962586
28972587 printed += fprintf(fp, "\n");
@@ -2900,9 +2590,8 @@ static size_t thread__dump_stats(struct thread_trace *ttrace, · 2 unmodified lines
29002590 printed += fprintf(fp, " (msec) (msec) (msec) (msec) (%%)\n");
29012591 printed += fprintf(fp, " --------------- -------- --------- --------- --------- --------- ------\n");
29022592
2903− /* each int_node is a syscall */
2904− while (inode) {
2905− stats = inode->priv;
2593+ resort_rb__for_each(nd, syscall_stats) {
2594+ struct stats *stats = syscall_stats_entry->stats;
29062595 if (stats) {
29072596 double min = (double)(stats->min) / NSEC_PER_MSEC;
29082597 double max = (double)(stats->max) / NSEC_PER_MSEC;
@@ -2913,34 +2602,23 @@ static size_t thread__dump_stats(struct thread_trace *ttrace, · 4 unmodified lines
29132602 pct = avg ? 100.0 * stddev_stats(stats)/avg : 0.0;
29142603 avg /= NSEC_PER_MSEC;
29152604
2916− sc = &trace->syscalls.table[inode->i];
2605+ sc = &trace->syscalls.table[syscall_stats_entry->syscall];
29172606 printed += fprintf(fp, " %-15s", sc->name);
29182607 printed += fprintf(fp, " %8" PRIu64 " %9.3f %9.3f %9.3f",
2919− n, avg * n, min, avg);
2608+ n, syscall_stats_entry->msecs, min, avg);
29202609 printed += fprintf(fp, " %9.3f %9.2f%%\n", max, pct);
29212610 }
2922−
2923− inode = intlist__next(inode);
29242611 }
29252612
2613+ resort_rb__delete(syscall_stats);
29262614 printed += fprintf(fp, "\n\n");
29272615
29282616 return printed;
29292617 }
29302618
2931−/* struct used to pass data to per-thread function */
2932−struct summary_data {
2933− FILE *fp;
2934− struct trace *trace;
2935− size_t printed;
2936−};
2937−
2938−static int trace__fprintf_one_thread(struct thread *thread, void *priv)
2619+static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trace *trace)
29392620 {
2940− struct summary_data *data = priv;
2941− FILE *fp = data->fp;
2942− size_t printed = data->printed;
2943− struct trace *trace = data->trace;
2621+ size_t printed = 0;
29442622 struct thread_trace *ttrace = thread__priv(thread);
29452623 double ratio;
29462624
@@ -2956,25 +2634,45 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv) · 9 unmodified lines
29562634 printed += fprintf(fp, ", %lu majfaults", ttrace->pfmaj);
29572635 if (ttrace->pfmin)
29582636 printed += fprintf(fp, ", %lu minfaults", ttrace->pfmin);
2959− printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
2637+ if (trace->sched)
2638+ printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
2639+ else if (fputc('\n', fp) != EOF)
2640+ ++printed;
2641+
29602642 printed += thread__dump_stats(ttrace, trace, fp);
29612643
2962− data->printed += printed;
2644+ return printed;
2645+}
29632646
2964− return 0;
2647+static unsigned long thread__nr_events(struct thread_trace *ttrace)
2648+{
2649+ return ttrace ? ttrace->nr_events : 0;
2650+}
2651+
2652+DEFINE_RESORT_RB(threads, (thread__nr_events(a->thread->priv) < thread__nr_events(b->thread->priv)),
2653+ struct thread *thread;
2654+)
2655+{
2656+ entry->thread = rb_entry(nd, struct thread, rb_node);
29652657 }
29662658
29672659 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
29682660 {
2969− struct summary_data data = {
2970− .fp = fp,
2971− .trace = trace
2972− };
2973− data.printed = trace__fprintf_threads_header(fp);
2661+ DECLARE_RESORT_RB_MACHINE_THREADS(threads, trace->host);
2662+ size_t printed = trace__fprintf_threads_header(fp);
2663+ struct rb_node *nd;
2664+
2665+ if (threads == NULL) {
2666+ fprintf(fp, "%s", "Error sorting output by nr_events!\n");
2667+ return 0;
2668+ }
29742669
2975− machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data);
2670+ resort_rb__for_each(nd, threads)
2671+ printed += trace__fprintf_thread(fp, threads_entry->thread, trace);
29762672
2977− return data.printed;
2673+ resort_rb__delete(threads);
2674+
2675+ return printed;
29782676 }
29792677
29802678 static int trace__set_duration(const struct option *opt, const char *str,
@@ -3070,10 +2768,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) · 89 unmodified lines
30702768 NULL
30712769 };
30722770 struct trace trace = {
3073− .audit = {
3074− .machine = audit_detect_machine(),
3075− .open_id = audit_name_to_syscall("open", trace.audit.machine),
3076− },
30772771 .syscalls = {
30782772 . max = -1,
30792773 },
@@ -3091,6 +2785,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) · 11 unmodified lines
30912785 .output = stderr,
30922786 .show_comm = true,
30932787 .trace_syscalls = true,
2788+ .kernel_syscallchains = false,
2789+ .max_stack = UINT_MAX,
30942790 };
30952791 const char *output_name = NULL;
30962792 const char *ev_qualifier_str = NULL;
@@ -3136,10 +2832,24 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) · 39 unmodified lines
31362832 "Trace pagefaults", parse_pagefaults, "maj"),
31372833 OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
31382834 OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
2835+ OPT_CALLBACK(0, "call-graph", &trace.opts,
2836+ "record_mode[,record_size]", record_callchain_help,
2837+ &record_parse_callchain_opt),
2838+ OPT_BOOLEAN(0, "kernel-syscall-graph", &trace.kernel_syscallchains,
2839+ "Show the kernel callchains on the syscall exit path"),
2840+ OPT_UINTEGER(0, "min-stack", &trace.min_stack,
2841+ "Set the minimum stack depth when parsing the callchain, "
2842+ "anything below the specified depth will be ignored."),
2843+ OPT_UINTEGER(0, "max-stack", &trace.max_stack,
2844+ "Set the maximum stack depth when parsing the callchain, "
2845+ "anything beyond the specified depth will be ignored. "
2846+ "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
31392847 OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout,
31402848 "per thread proc mmap processing timeout in ms"),
31412849 OPT_END()
31422850 };
2851+ bool __maybe_unused max_stack_user_set = true;
2852+ bool mmap_pages_user_set = true;
31432853 const char * const trace_subcommands[] = { "record", NULL };
31442854 int err;
31452855 char bf[BUFSIZ];
@@ -3148,8 +2858,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) · 2 unmodified lines
31482858 signal(SIGFPE, sighandler_dump_stack);
31492859
31502860 trace.evlist = perf_evlist__new();
2861+ trace.sctbl = syscalltbl__new();
31512862
3152− if (trace.evlist == NULL) {
2863+ if (trace.evlist == NULL || trace.sctbl == NULL) {
31532864 pr_err("Not enough memory to run!\n");
31542865 err = -ENOMEM;
31552866 goto out;
@@ -3158,11 +2869,40 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) · 2 unmodified lines
31582869 argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands,
31592870 trace_usage, PARSE_OPT_STOP_AT_NON_OPTION);
31602871
2872+ err = bpf__setup_stdout(trace.evlist);
2873+ if (err) {
2874+ bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf));
2875+ pr_err("ERROR: Setup BPF stdout failed: %s\n", bf);
2876+ goto out;
2877+ }
2878+
2879+ err = -1;
2880+
31612881 if (trace.trace_pgfaults) {
31622882 trace.opts.sample_address = true;
31632883 trace.opts.sample_time = true;
31642884 }
31652885
2886+ if (trace.opts.mmap_pages == UINT_MAX)
2887+ mmap_pages_user_set = false;
2888+
2889+ if (trace.max_stack == UINT_MAX) {
2890+ trace.max_stack = sysctl_perf_event_max_stack;
2891+ max_stack_user_set = false;
2892+ }
2893+
2894+#ifdef HAVE_DWARF_UNWIND_SUPPORT
2895+ if ((trace.min_stack || max_stack_user_set) && !callchain_param.enabled)
2896+ record_opts__parse_callchain(&trace.opts, &callchain_param, "dwarf", false);
2897+#endif
2898+
2899+ if (callchain_param.enabled) {
2900+ if (!mmap_pages_user_set && geteuid() == 0)
2901+ trace.opts.mmap_pages = perf_event_mlock_kb_in_pages() * 4;
2902+
2903+ symbol_conf.use_callchain = true;
2904+ }
2905+
31662906 if (trace.evlist->nr_entries > 0)
31672907 evlist__set_evsel_handler(trace.evlist, trace__event_handler);
31682908
@@ -3179,6 +2919,11 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) · 10 unmodified lines
31792919 return -1;
31802920 }
31812921
2922+ if (!trace.trace_syscalls && ev_qualifier_str) {
2923+ pr_err("The -e option can't be used with --no-syscalls.\n");
2924+ goto out;
2925+ }
2926+
31822927 if (output_name != NULL) {
31832928 err = trace__open_output(&trace, output_name);
31842929 if (err < 0) {
@@ -3187,6 +2932,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) · 2 unmodified lines
31872932 }
31882933 }
31892934
2935+ trace.open_id = syscalltbl__id(trace.sctbl, "open");
2936+
31902937 if (ev_qualifier_str != NULL) {
31912938 const char *s = ev_qualifier_str;
31922939 struct strlist_config slist_config = {
tools/perf/config/Makefile+1−4
@@ -27,7 +27,7 @@ NO_PERF_REGS := 1 · 26 unmodified lines
2727 ifeq ($(ARCH),x86)
2828 $(call detected,CONFIG_X86)
2929 ifeq (${IS_64_BIT}, 1)
30− CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT
30+ CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated
3131 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
3232 LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
3333 $(call detected,CONFIG_X86_64)
@@ -295,9 +295,6 @@ ifndef NO_LIBELF · 261 unmodified lines
295295 CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT
296296 endif
297297
298− # include ARCH specific config
299− -include $(src-perf)/arch/$(ARCH)/Makefile
300−
301298 ifndef NO_DWARF
302299 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
303300 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
tools/perf/jvmti/jvmti_agent.c+41−2
@@ -92,6 +92,22 @@ error: · 91 unmodified lines
9292 return ret;
9393 }
9494
95+static int use_arch_timestamp;
96+
97+static inline uint64_t
98+get_arch_timestamp(void)
99+{
100+#if defined(__i386__) || defined(__x86_64__)
101+ unsigned int low, high;
102+
103+ asm volatile("rdtsc" : "=a" (low), "=d" (high));
104+
105+ return low | ((uint64_t)high) << 32;
106+#else
107+ return 0;
108+#endif
109+}
110+
95111 #define NSEC_PER_SEC 1000000000
96112 static int perf_clk_id = CLOCK_MONOTONIC;
97113
@@ -107,6 +123,9 @@ perf_get_timestamp(void) · 9 unmodified lines
107123 struct timespec ts;
108124 int ret;
109125
126+ if (use_arch_timestamp)
127+ return get_arch_timestamp();
128+
110129 ret = clock_gettime(perf_clk_id, &ts);
111130 if (ret)
112131 return 0;
@@ -203,6 +222,17 @@ perf_close_marker_file(void) · 90 unmodified lines
203222 munmap(marker_addr, pgsz);
204223 }
205224
225+static void
226+init_arch_timestamp(void)
227+{
228+ char *str = getenv("JITDUMP_USE_ARCH_TIMESTAMP");
229+
230+ if (!str || !*str || !strcmp(str, "0"))
231+ return;
232+
233+ use_arch_timestamp = 1;
234+}
235+
206236 void *jvmti_open(void)
207237 {
208238 int pad_cnt;
@@ -211,11 +241,17 @@ void *jvmti_open(void) · 2 unmodified lines
211241 int fd;
212242 FILE *fp;
213243
244+ init_arch_timestamp();
245+
214246 /*
215247 * check if clockid is supported
216248 */
217− if (!perf_get_timestamp())
218− warnx("jvmti: kernel does not support %d clock id", perf_clk_id);
249+ if (!perf_get_timestamp()) {
250+ if (use_arch_timestamp)
251+ warnx("jvmti: arch timestamp not supported");
252+ else
253+ warnx("jvmti: kernel does not support %d clock id", perf_clk_id);
254+ }
219255
220256 memset(&header, 0, sizeof(header));
221257
@@ -263,6 +299,9 @@ void *jvmti_open(void) · 41 unmodified lines
263299
264300 header.timestamp = perf_get_timestamp();
265301
302+ if (use_arch_timestamp)
303+ header.flags |= JITDUMP_FLAGS_ARCH_TIMESTAMP;
304+
266305 if (!fwrite(&header, sizeof(header), 1, fp)) {
267306 warn("jvmti: cannot write dumpfile header");
268307 goto error;
tools/perf/perf.c+11−5
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <subcmd/parse-options.h>
1818 #include "util/bpf-loader.h"
1919 #include "util/debug.h"
20+#include <api/fs/fs.h>
2021 #include <api/fs/tracing_path.h>
2122 #include <pthread.h>
2223 #include <stdlib.h>
@@ -308,9 +309,11 @@ static int handle_alias(int *argcp, const char ***argv) · 285 unmodified lines
308309 if (*argcp > 1) {
309310 struct strbuf buf;
310311
311− strbuf_init(&buf, PATH_MAX);
312− strbuf_addstr(&buf, alias_string);
313− sq_quote_argv(&buf, (*argv) + 1, PATH_MAX);
312+ if (strbuf_init(&buf, PATH_MAX) < 0 ||
313+ strbuf_addstr(&buf, alias_string) < 0 ||
314+ sq_quote_argv(&buf, (*argv) + 1,
315+ PATH_MAX) < 0)
316+ die("Failed to allocate memory.");
314317 free(alias_string);
315318 alias_string = buf.buf;
316319 }
@@ -533,6 +536,7 @@ int main(int argc, const char **argv) · 216 unmodified lines
533536 {
534537 const char *cmd;
535538 char sbuf[STRERR_BUFSIZE];
539+ int value;
536540
537541 /* libsubcmd init */
538542 exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT);
@@ -542,6 +546,9 @@ int main(int argc, const char **argv) · 3 unmodified lines
542546 page_size = sysconf(_SC_PAGE_SIZE);
543547 cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
544548
549+ if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0)
550+ sysctl_perf_event_max_stack = value;
551+
545552 cmd = extract_argv0_path(argv[0]);
546553 if (!cmd)
547554 cmd = "perf-help";
@@ -549,6 +556,7 @@ int main(int argc, const char **argv) · 1 unmodified line
549556 srandom(time(NULL));
550557
551558 perf_config(perf_default_config, NULL);
559+ set_buildid_dir(NULL);
552560
553561 /* get debugfs/tracefs mount point from /proc/mounts */
554562 tracing_path_mount();
@@ -572,7 +580,6 @@ int main(int argc, const char **argv) · 17 unmodified lines
572580 }
573581 if (!prefixcmp(cmd, "trace")) {
574582 #ifdef HAVE_LIBAUDIT_SUPPORT
575− set_buildid_dir(NULL);
576583 setup_path();
577584 argv[0] = "trace";
578585 return cmd_trace(argc, argv, NULL);
@@ -587,7 +594,6 @@ int main(int argc, const char **argv) · 8 unmodified lines
587594 argc--;
588595 handle_options(&argv, &argc, NULL);
589596 commit_pager_choice();
590− set_buildid_dir(NULL);
591597
592598 if (argc > 0) {
593599 if (!prefixcmp(argv[0], "--"))
tools/perf/perf.h+0−1
@@ -52,7 +52,6 @@ struct record_opts { · 51 unmodified lines
5252 bool sample_weight;
5353 bool sample_time;
5454 bool sample_time_set;
55− bool callgraph_set;
5655 bool period;
5756 bool running_time;
5857 bool full_auxtrace;
tools/perf/scripts/python/export-to-postgresql.py+32−20
@@ -34,10 +34,9 @@ import datetime · 33 unmodified lines
3434 #
3535 # ubuntu:
3636 #
37−# $ sudo apt-get install postgresql
37+# $ sudo apt-get install postgresql python-pyside.qtsql libqt4-sql-psql
3838 # $ sudo su - postgres
39−# $ createuser <your user id here>
40−# Shall the new role be a superuser? (y/n) y
39+# $ createuser -s <your user id here>
4140 #
4241 # An example of using this script with Intel PT:
4342 #
@@ -224,11 +223,14 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ · 180 unmodified lines
224223
225224 perf_db_export_mode = True
226225 perf_db_export_calls = False
226+perf_db_export_callchains = False
227+
227228
228229 def usage():
229− print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>]"
230+ print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]"
230231 print >> sys.stderr, "where: columns 'all' or 'branches'"
231− print >> sys.stderr, " calls 'calls' => create calls table"
232+ print >> sys.stderr, " calls 'calls' => create calls and call_paths table"
233+ print >> sys.stderr, " callchains 'callchains' => create call_paths table"
232234 raise Exception("Too few arguments")
233235
234236 if (len(sys.argv) < 2):
@@ -246,9 +248,11 @@ if columns not in ("all", "branches"): · 11 unmodified lines
246248
247249 branches = (columns == "branches")
248250
249−if (len(sys.argv) >= 4):
250− if (sys.argv[3] == "calls"):
251+for i in range(3,len(sys.argv)):
252+ if (sys.argv[i] == "calls"):
251253 perf_db_export_calls = True
254+ elif (sys.argv[i] == "callchains"):
255+ perf_db_export_callchains = True
252256 else:
253257 usage()
254258
@@ -359,14 +363,16 @@ else: · 104 unmodified lines
359363 'transaction bigint,'
360364 'data_src bigint,'
361365 'branch_type integer,'
362− 'in_tx boolean)')
366+ 'in_tx boolean,'
367+ 'call_path_id bigint)')
363368
364−if perf_db_export_calls:
369+if perf_db_export_calls or perf_db_export_callchains:
365370 do_query(query, 'CREATE TABLE call_paths ('
366371 'id bigint NOT NULL,'
367372 'parent_id bigint,'
368373 'symbol_id bigint,'
369374 'ip bigint)')
375+if perf_db_export_calls:
370376 do_query(query, 'CREATE TABLE calls ('
371377 'id bigint NOT NULL,'
372378 'thread_id bigint,'
@@ -428,7 +434,7 @@ do_query(query, 'CREATE VIEW comm_threads_view AS ' · 55 unmodified lines
428434 '(SELECT tid FROM threads WHERE id = thread_id) AS tid'
429435 ' FROM comm_threads')
430436
431−if perf_db_export_calls:
437+if perf_db_export_calls or perf_db_export_callchains:
432438 do_query(query, 'CREATE VIEW call_paths_view AS '
433439 'SELECT '
434440 'c.id,'
@@ -444,6 +450,7 @@ if perf_db_export_calls: · 9 unmodified lines
444450 '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'
445451 '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name'
446452 ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')
453+if perf_db_export_calls:
447454 do_query(query, 'CREATE VIEW calls_view AS '
448455 'SELECT '
449456 'calls.id,'
@@ -541,8 +548,9 @@ dso_file = open_output_file("dso_table.bin") · 91 unmodified lines
541548 symbol_file = open_output_file("symbol_table.bin")
542549 branch_type_file = open_output_file("branch_type_table.bin")
543550 sample_file = open_output_file("sample_table.bin")
544−if perf_db_export_calls:
551+if perf_db_export_calls or perf_db_export_callchains:
545552 call_path_file = open_output_file("call_path_table.bin")
553+if perf_db_export_calls:
546554 call_file = open_output_file("call_table.bin")
547555
548556 def trace_begin():
@@ -554,8 +562,8 @@ def trace_begin(): · 5 unmodified lines
554562 comm_table(0, "unknown")
555563 dso_table(0, 0, "unknown", "unknown", "")
556564 symbol_table(0, 0, 0, 0, 0, "unknown")
557− sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
558− if perf_db_export_calls:
565+ sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
566+ if perf_db_export_calls or perf_db_export_callchains:
559567 call_path_table(0, 0, 0, 0)
560568
561569 unhandled_count = 0
@@ -571,8 +579,9 @@ def trace_end(): · 9 unmodified lines
571579 copy_output_file(symbol_file, "symbols")
572580 copy_output_file(branch_type_file, "branch_types")
573581 copy_output_file(sample_file, "samples")
574− if perf_db_export_calls:
582+ if perf_db_export_calls or perf_db_export_callchains:
575583 copy_output_file(call_path_file, "call_paths")
584+ if perf_db_export_calls:
576585 copy_output_file(call_file, "calls")
577586
578587 print datetime.datetime.today(), "Removing intermediate files..."
@@ -585,8 +594,9 @@ def trace_end(): · 6 unmodified lines
585594 remove_output_file(symbol_file)
586595 remove_output_file(branch_type_file)
587596 remove_output_file(sample_file)
588− if perf_db_export_calls:
597+ if perf_db_export_calls or perf_db_export_callchains:
589598 remove_output_file(call_path_file)
599+ if perf_db_export_calls:
590600 remove_output_file(call_file)
591601 os.rmdir(output_dir_name)
592602 print datetime.datetime.today(), "Adding primary keys"
@@ -599,8 +609,9 @@ def trace_end(): · 6 unmodified lines
599609 do_query(query, 'ALTER TABLE symbols ADD PRIMARY KEY (id)')
600610 do_query(query, 'ALTER TABLE branch_types ADD PRIMARY KEY (id)')
601611 do_query(query, 'ALTER TABLE samples ADD PRIMARY KEY (id)')
602− if perf_db_export_calls:
612+ if perf_db_export_calls or perf_db_export_callchains:
603613 do_query(query, 'ALTER TABLE call_paths ADD PRIMARY KEY (id)')
614+ if perf_db_export_calls:
604615 do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)')
605616
606617 print datetime.datetime.today(), "Adding foreign keys"
@@ -623,10 +634,11 @@ def trace_end(): · 16 unmodified lines
623634 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id),'
624635 'ADD CONSTRAINT todsofk FOREIGN KEY (to_dso_id) REFERENCES dsos (id),'
625636 'ADD CONSTRAINT tosymbolfk FOREIGN KEY (to_symbol_id) REFERENCES symbols (id)')
626− if perf_db_export_calls:
637+ if perf_db_export_calls or perf_db_export_callchains:
627638 do_query(query, 'ALTER TABLE call_paths '
628639 'ADD CONSTRAINT parentfk FOREIGN KEY (parent_id) REFERENCES call_paths (id),'
629640 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id)')
641+ if perf_db_export_calls:
630642 do_query(query, 'ALTER TABLE calls '
631643 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id),'
632644 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),'
@@ -694,11 +706,11 @@ def branch_type_table(branch_type, name, *x): · 61 unmodified lines
694706 value = struct.pack(fmt, 2, 4, branch_type, n, name)
695707 branch_type_file.write(value)
696708
697−def sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, symbol_id, sym_offset, ip, time, cpu, to_dso_id, to_symbol_id, to_sym_offset, to_ip, period, weight, transaction, data_src, branch_type, in_tx, *x):
709+def sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, symbol_id, sym_offset, ip, time, cpu, to_dso_id, to_symbol_id, to_sym_offset, to_ip, period, weight, transaction, data_src, branch_type, in_tx, call_path_id, *x):
698710 if branches:
699− value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiiiB", 17, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 4, branch_type, 1, in_tx)
711+ value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiiiBiq", 18, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 4, branch_type, 1, in_tx, 8, call_path_id)
700712 else:
701− value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiqiiiB", 21, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 8, period, 8, weight, 8, transaction, 8, data_src, 4, branch_type, 1, in_tx)
713+ value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiqiiiBiq", 22, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 8, period, 8, weight, 8, transaction, 8, data_src, 4, branch_type, 1, in_tx, 8, call_path_id)
702714 sample_file.write(value)
703715
704716 def call_path_table(cp_id, parent_id, symbol_id, ip, *x):
tools/perf/tests/Build+2−0
@@ -37,6 +37,8 @@ perf-y += topology.o · 36 unmodified lines
3737 perf-y += cpumap.o
3838 perf-y += stat.o
3939 perf-y += event_update.o
40+perf-y += event-times.o
41+perf-y += backward-ring-buffer.o
4042
4143 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
4244 $(call rule_mkdir)
tools/perf/tests/backward-ring-buffer.c+151−0
@@ -0,0 +1,151 @@
1+/*
2+ * Test backward bit in event attribute, read ring buffer from end to
3+ * beginning
4+ */
5+
6+#include <perf.h>
7+#include <evlist.h>
8+#include <sys/prctl.h>
9+#include "tests.h"
10+#include "debug.h"
11+
12+#define NR_ITERS 111
13+
14+static void testcase(void)
15+{
16+ int i;
17+
18+ for (i = 0; i < NR_ITERS; i++) {
19+ char proc_name[10];
20+
21+ snprintf(proc_name, sizeof(proc_name), "p:%d\n", i);
22+ prctl(PR_SET_NAME, proc_name);
23+ }
24+}
25+
26+static int count_samples(struct perf_evlist *evlist, int *sample_count,
27+ int *comm_count)
28+{
29+ int i;
30+
31+ for (i = 0; i < evlist->nr_mmaps; i++) {
32+ union perf_event *event;
33+
34+ perf_evlist__mmap_read_catchup(evlist, i);
35+ while ((event = perf_evlist__mmap_read_backward(evlist, i)) != NULL) {
36+ const u32 type = event->header.type;
37+
38+ switch (type) {
39+ case PERF_RECORD_SAMPLE:
40+ (*sample_count)++;
41+ break;
42+ case PERF_RECORD_COMM:
43+ (*comm_count)++;
44+ break;
45+ default:
46+ pr_err("Unexpected record of type %d\n", type);
47+ return TEST_FAIL;
48+ }
49+ }
50+ }
51+ return TEST_OK;
52+}
53+
54+static int do_test(struct perf_evlist *evlist, int mmap_pages,
55+ int *sample_count, int *comm_count)
56+{
57+ int err;
58+ char sbuf[STRERR_BUFSIZE];
59+
60+ err = perf_evlist__mmap(evlist, mmap_pages, true);
61+ if (err < 0) {
62+ pr_debug("perf_evlist__mmap: %s\n",
63+ strerror_r(errno, sbuf, sizeof(sbuf)));
64+ return TEST_FAIL;
65+ }
66+
67+ perf_evlist__enable(evlist);
68+ testcase();
69+ perf_evlist__disable(evlist);
70+
71+ err = count_samples(evlist, sample_count, comm_count);
72+ perf_evlist__munmap(evlist);
73+ return err;
74+}
75+
76+
77+int test__backward_ring_buffer(int subtest __maybe_unused)
78+{
79+ int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0;
80+ char pid[16], sbuf[STRERR_BUFSIZE];
81+ struct perf_evlist *evlist;
82+ struct perf_evsel *evsel __maybe_unused;
83+ struct parse_events_error parse_error;
84+ struct record_opts opts = {
85+ .target = {
86+ .uid = UINT_MAX,
87+ .uses_mmap = true,
88+ },
89+ .freq = 0,
90+ .mmap_pages = 256,
91+ .default_interval = 1,
92+ };
93+
94+ snprintf(pid, sizeof(pid), "%d", getpid());
95+ pid[sizeof(pid) - 1] = '\0';
96+ opts.target.tid = opts.target.pid = pid;
97+
98+ evlist = perf_evlist__new();
99+ if (!evlist) {
100+ pr_debug("No ehough memory to create evlist\n");
101+ return TEST_FAIL;
102+ }
103+
104+ err = perf_evlist__create_maps(evlist, &opts.target);
105+ if (err < 0) {
106+ pr_debug("Not enough memory to create thread/cpu maps\n");
107+ goto out_delete_evlist;
108+ }
109+
110+ bzero(&parse_error, sizeof(parse_error));
111+ err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error);
112+ if (err) {
113+ pr_debug("Failed to parse tracepoint event, try use root\n");
114+ ret = TEST_SKIP;
115+ goto out_delete_evlist;
116+ }
117+
118+ perf_evlist__config(evlist, &opts, NULL);
119+
120+ /* Set backward bit, ring buffer should be writing from end */
121+ evlist__for_each(evlist, evsel)
122+ evsel->attr.write_backward = 1;
123+
124+ err = perf_evlist__open(evlist);
125+ if (err < 0) {
126+ pr_debug("perf_evlist__open: %s\n",
127+ strerror_r(errno, sbuf, sizeof(sbuf)));
128+ goto out_delete_evlist;
129+ }
130+
131+ ret = TEST_FAIL;
132+ err = do_test(evlist, opts.mmap_pages, &sample_count,
133+ &comm_count);
134+ if (err != TEST_OK)
135+ goto out_delete_evlist;
136+
137+ if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) {
138+ pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n",
139+ sample_count, comm_count);
140+ goto out_delete_evlist;
141+ }
142+
143+ err = do_test(evlist, 1, &sample_count, &comm_count);
144+ if (err != TEST_OK)
145+ goto out_delete_evlist;
146+
147+ ret = TEST_OK;
148+out_delete_evlist:
149+ perf_evlist__delete(evlist);
150+ return ret;
151+}
tools/perf/tests/bpf.c+1−1
@@ -138,7 +138,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), · 137 unmodified lines
138138 perf_evlist__splice_list_tail(evlist, &parse_evlist.list);
139139 evlist->nr_groups = parse_evlist.nr_groups;
140140
141− perf_evlist__config(evlist, &opts);
141+ perf_evlist__config(evlist, &opts, NULL);
142142
143143 err = perf_evlist__open(evlist);
144144 if (err < 0) {
tools/perf/tests/builtin-test.c+8−0
@@ -203,6 +203,14 @@ static struct test generic_tests[] = { · 202 unmodified lines
203203 .desc = "Test attr update synthesize",
204204 .func = test__event_update,
205205 },
206+ {
207+ .desc = "Test events times",
208+ .func = test__event_times,
209+ },
210+ {
211+ .desc = "Test backward reading from ring buffer",
212+ .func = test__backward_ring_buffer,
213+ },
206214 {
207215 .func = NULL,
208216 },
tools/perf/tests/code-reading.c+1−1
@@ -532,7 +532,7 @@ static int do_test_code_reading(bool try_kcore) · 531 unmodified lines
532532 goto out_put;
533533 }
534534
535− perf_evlist__config(evlist, &opts);
535+ perf_evlist__config(evlist, &opts, NULL);
536536
537537 evsel = perf_evlist__first(evlist);
538538
tools/perf/tests/dso-data.c+1−1
@@ -202,7 +202,7 @@ static int dsos__create(int cnt, int size) · 201 unmodified lines
202202 {
203203 int i;
204204
205− dsos = malloc(sizeof(dsos) * cnt);
205+ dsos = malloc(sizeof(*dsos) * cnt);
206206 TEST_ASSERT_VAL("failed to alloc dsos array", dsos);
207207
208208 for (i = 0; i < cnt; i++) {
tools/perf/tests/event-times.c+236−0
@@ -0,0 +1,236 @@
1+#include <linux/compiler.h>
2+#include <string.h>
3+#include "tests.h"
4+#include "evlist.h"
5+#include "evsel.h"
6+#include "util.h"
7+#include "debug.h"
8+#include "thread_map.h"
9+#include "target.h"
10+
11+static int attach__enable_on_exec(struct perf_evlist *evlist)
12+{
13+ struct perf_evsel *evsel = perf_evlist__last(evlist);
14+ struct target target = {
15+ .uid = UINT_MAX,
16+ };
17+ const char *argv[] = { "true", NULL, };
18+ char sbuf[STRERR_BUFSIZE];
19+ int err;
20+
21+ pr_debug("attaching to spawned child, enable on exec\n");
22+
23+ err = perf_evlist__create_maps(evlist, &target);
24+ if (err < 0) {
25+ pr_debug("Not enough memory to create thread/cpu maps\n");
26+ return err;
27+ }
28+
29+ err = perf_evlist__prepare_workload(evlist, &target, argv, false, NULL);
30+ if (err < 0) {
31+ pr_debug("Couldn't run the workload!\n");
32+ return err;
33+ }
34+
35+ evsel->attr.enable_on_exec = 1;
36+
37+ err = perf_evlist__open(evlist);
38+ if (err < 0) {
39+ pr_debug("perf_evlist__open: %s\n",
40+ strerror_r(errno, sbuf, sizeof(sbuf)));
41+ return err;
42+ }
43+
44+ return perf_evlist__start_workload(evlist) == 1 ? TEST_OK : TEST_FAIL;
45+}
46+
47+static int detach__enable_on_exec(struct perf_evlist *evlist)
48+{
49+ waitpid(evlist->workload.pid, NULL, 0);
50+ return 0;
51+}
52+
53+static int attach__current_disabled(struct perf_evlist *evlist)
54+{
55+ struct perf_evsel *evsel = perf_evlist__last(evlist);
56+ struct thread_map *threads;
57+ int err;
58+
59+ pr_debug("attaching to current thread as disabled\n");
60+
61+ threads = thread_map__new(-1, getpid(), UINT_MAX);
62+ if (threads == NULL) {
63+ pr_debug("thread_map__new\n");
64+ return -1;
65+ }
66+
67+ evsel->attr.disabled = 1;
68+
69+ err = perf_evsel__open_per_thread(evsel, threads);
70+ if (err) {
71+ pr_debug("Failed to open event cpu-clock:u\n");
72+ return err;
73+ }
74+
75+ thread_map__put(threads);
76+ return perf_evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL;
77+}
78+
79+static int attach__current_enabled(struct perf_evlist *evlist)
80+{
81+ struct perf_evsel *evsel = perf_evlist__last(evlist);
82+ struct thread_map *threads;
83+ int err;
84+
85+ pr_debug("attaching to current thread as enabled\n");
86+
87+ threads = thread_map__new(-1, getpid(), UINT_MAX);
88+ if (threads == NULL) {
89+ pr_debug("failed to call thread_map__new\n");
90+ return -1;
91+ }
92+
93+ err = perf_evsel__open_per_thread(evsel, threads);
94+
95+ thread_map__put(threads);
96+ return err == 0 ? TEST_OK : TEST_FAIL;
97+}
98+
99+static int detach__disable(struct perf_evlist *evlist)
100+{
101+ struct perf_evsel *evsel = perf_evlist__last(evlist);
102+
103+ return perf_evsel__enable(evsel);
104+}
105+
106+static int attach__cpu_disabled(struct perf_evlist *evlist)
107+{
108+ struct perf_evsel *evsel = perf_evlist__last(evlist);
109+ struct cpu_map *cpus;
110+ int err;
111+
112+ pr_debug("attaching to CPU 0 as enabled\n");
113+
114+ cpus = cpu_map__new("0");
115+ if (cpus == NULL) {
116+ pr_debug("failed to call cpu_map__new\n");
117+ return -1;
118+ }
119+
120+ evsel->attr.disabled = 1;
121+
122+ err = perf_evsel__open_per_cpu(evsel, cpus);
123+ if (err) {
124+ if (err == -EACCES)
125+ return TEST_SKIP;
126+
127+ pr_debug("Failed to open event cpu-clock:u\n");
128+ return err;
129+ }
130+
131+ cpu_map__put(cpus);
132+ return perf_evsel__enable(evsel);
133+}
134+
135+static int attach__cpu_enabled(struct perf_evlist *evlist)
136+{
137+ struct perf_evsel *evsel = perf_evlist__last(evlist);
138+ struct cpu_map *cpus;
139+ int err;
140+
141+ pr_debug("attaching to CPU 0 as enabled\n");
142+
143+ cpus = cpu_map__new("0");
144+ if (cpus == NULL) {
145+ pr_debug("failed to call cpu_map__new\n");
146+ return -1;
147+ }
148+
149+ err = perf_evsel__open_per_cpu(evsel, cpus);
150+ if (err == -EACCES)
151+ return TEST_SKIP;
152+
153+ cpu_map__put(cpus);
154+ return err ? TEST_FAIL : TEST_OK;
155+}
156+
157+static int test_times(int (attach)(struct perf_evlist *),
158+ int (detach)(struct perf_evlist *))
159+{
160+ struct perf_counts_values count;
161+ struct perf_evlist *evlist = NULL;
162+ struct perf_evsel *evsel;
163+ int err = -1, i;
164+
165+ evlist = perf_evlist__new();
166+ if (!evlist) {
167+ pr_debug("failed to create event list\n");
168+ goto out_err;
169+ }
170+
171+ err = parse_events(evlist, "cpu-clock:u", NULL);
172+ if (err) {
173+ pr_debug("failed to parse event cpu-clock:u\n");
174+ goto out_err;
175+ }
176+
177+ evsel = perf_evlist__last(evlist);
178+ evsel->attr.read_format |=
179+ PERF_FORMAT_TOTAL_TIME_ENABLED |
180+ PERF_FORMAT_TOTAL_TIME_RUNNING;
181+
182+ err = attach(evlist);
183+ if (err == TEST_SKIP) {
184+ pr_debug(" SKIP : not enough rights\n");
185+ return err;
186+ }
187+
188+ TEST_ASSERT_VAL("failed to attach", !err);
189+
190+ for (i = 0; i < 100000000; i++) { }
191+
192+ TEST_ASSERT_VAL("failed to detach", !detach(evlist));
193+
194+ perf_evsel__read(evsel, 0, 0, &count);
195+
196+ err = !(count.ena == count.run);
197+
198+ pr_debug(" %s: ena %" PRIu64", run %" PRIu64"\n",
199+ !err ? "OK " : "FAILED",
200+ count.ena, count.run);
201+
202+out_err:
203+ if (evlist)
204+ perf_evlist__delete(evlist);
205+ return !err ? TEST_OK : TEST_FAIL;
206+}
207+
208+/*
209+ * This test creates software event 'cpu-clock'
210+ * attaches it in several ways (explained below)
211+ * and checks that enabled and running times
212+ * match.
213+ */
214+int test__event_times(int subtest __maybe_unused)
215+{
216+ int err, ret = 0;
217+
218+#define _T(attach, detach) \
219+ err = test_times(attach, detach); \
220+ if (err && (ret == TEST_OK || ret == TEST_SKIP)) \
221+ ret = err;
222+
223+ /* attach on newly spawned process after exec */
224+ _T(attach__enable_on_exec, detach__enable_on_exec)
225+ /* attach on current process as enabled */
226+ _T(attach__current_enabled, detach__disable)
227+ /* attach on current process as disabled */
228+ _T(attach__current_disabled, detach__disable)
229+ /* attach on cpu as disabled */
230+ _T(attach__cpu_disabled, detach__disable)
231+ /* attach on cpu as enabled */
232+ _T(attach__cpu_enabled, detach__disable)
233+
234+#undef _T
235+ return ret;
236+}
tools/perf/tests/event_update.c+1−1
@@ -30,7 +30,7 @@ static int process_event_scale(struct perf_tool *tool __maybe_unused, · 29 unmodified lines
3030
3131 TEST_ASSERT_VAL("wrong id", ev->id == 123);
3232 TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__SCALE);
33− TEST_ASSERT_VAL("wrong scale", ev_data->scale = 0.123);
33+ TEST_ASSERT_VAL("wrong scale", ev_data->scale == 0.123);
3434 return 0;
3535 }
3636
tools/perf/tests/hists_common.c+1−1
@@ -161,7 +161,7 @@ void print_hists_in(struct hists *hists) · 160 unmodified lines
161161 struct rb_root *root;
162162 struct rb_node *node;
163163
164− if (sort__need_collapse)
164+ if (hists__has(hists, need_collapse))
165165 root = &hists->entries_collapsed;
166166 else
167167 root = hists->entries_in;
tools/perf/tests/hists_cumulate.c+2−2
@@ -101,7 +101,7 @@ static int add_hist_entries(struct hists *hists, struct machine *machine) · 100 unmodified lines
101101 if (machine__resolve(machine, &al, &sample) < 0)
102102 goto out;
103103
104− if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
104+ if (hist_entry_iter__add(&iter, &al, sysctl_perf_event_max_stack,
105105 NULL) < 0) {
106106 addr_location__put(&al);
107107 goto out;
@@ -126,7 +126,7 @@ static void del_hist_entries(struct hists *hists) · 18 unmodified lines
126126 struct rb_root *root_out;
127127 struct rb_node *node;
128128
129− if (sort__need_collapse)
129+ if (hists__has(hists, need_collapse))
130130 root_in = &hists->entries_collapsed;
131131 else
132132 root_in = hists->entries_in;
tools/perf/tests/hists_filter.c+1−1
@@ -81,7 +81,7 @@ static int add_hist_entries(struct perf_evlist *evlist, · 80 unmodified lines
8181
8282 al.socket = fake_samples[i].socket;
8383 if (hist_entry_iter__add(&iter, &al,
84− PERF_MAX_STACK_DEPTH, NULL) < 0) {
84+ sysctl_perf_event_max_stack, NULL) < 0) {
8585 addr_location__put(&al);
8686 goto out;
8787 }
tools/perf/tests/hists_link.c+2−2
@@ -145,7 +145,7 @@ static int __validate_match(struct hists *hists) · 144 unmodified lines
145145 /*
146146 * Only entries from fake_common_samples should have a pair.
147147 */
148− if (sort__need_collapse)
148+ if (hists__has(hists, need_collapse))
149149 root = &hists->entries_collapsed;
150150 else
151151 root = hists->entries_in;
@@ -197,7 +197,7 @@ static int __validate_link(struct hists *hists, int idx) · 45 unmodified lines
197197 * and some entries will have no pair. However every entry
198198 * in other hists should have (dummy) pair.
199199 */
200− if (sort__need_collapse)
200+ if (hists__has(hists, need_collapse))
201201 root = &hists->entries_collapsed;
202202 else
203203 root = hists->entries_in;
tools/perf/tests/hists_output.c+2−2
@@ -67,7 +67,7 @@ static int add_hist_entries(struct hists *hists, struct machine *machine) · 66 unmodified lines
6767 if (machine__resolve(machine, &al, &sample) < 0)
6868 goto out;
6969
70− if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
70+ if (hist_entry_iter__add(&iter, &al, sysctl_perf_event_max_stack,
7171 NULL) < 0) {
7272 addr_location__put(&al);
7373 goto out;
@@ -92,7 +92,7 @@ static void del_hist_entries(struct hists *hists) · 18 unmodified lines
9292 struct rb_root *root_out;
9393 struct rb_node *node;
9494
95− if (sort__need_collapse)
95+ if (hists__has(hists, need_collapse))
9696 root_in = &hists->entries_collapsed;
9797 else
9898 root_in = hists->entries_in;
tools/perf/tests/keep-tracking.c+1−1
@@ -80,7 +80,7 @@ int test__keep_tracking(int subtest __maybe_unused) · 79 unmodified lines
8080 CHECK__(parse_events(evlist, "dummy:u", NULL));
8181 CHECK__(parse_events(evlist, "cycles:u", NULL));
8282
83− perf_evlist__config(evlist, &opts);
83+ perf_evlist__config(evlist, &opts, NULL);
8484
8585 evsel = perf_evlist__first(evlist);
8686
tools/perf/tests/openat-syscall-tp-fields.c+1−1
@@ -44,7 +44,7 @@ int test__syscall_openat_tp_fields(int subtest __maybe_unused) · 43 unmodified lines
4444 goto out_delete_evlist;
4545 }
4646
47− perf_evsel__config(evsel, &opts);
47+ perf_evsel__config(evsel, &opts, NULL);
4848
4949 thread_map__set_pid(evlist->threads, 0, getpid());
5050
tools/perf/tests/perf-record.c+1−1
@@ -99,7 +99,7 @@ int test__PERF_RECORD(int subtest __maybe_unused) · 98 unmodified lines
9999 perf_evsel__set_sample_bit(evsel, CPU);
100100 perf_evsel__set_sample_bit(evsel, TID);
101101 perf_evsel__set_sample_bit(evsel, TIME);
102− perf_evlist__config(evlist, &opts);
102+ perf_evlist__config(evlist, &opts, NULL);
103103
104104 err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
105105 if (err < 0) {
tools/perf/tests/switch-tracking.c+1−1
@@ -417,7 +417,7 @@ int test__switch_tracking(int subtest __maybe_unused) · 416 unmodified lines
417417 perf_evsel__set_sample_bit(tracking_evsel, TIME);
418418
419419 /* Config events */
420− perf_evlist__config(evlist, &opts);
420+ perf_evlist__config(evlist, &opts, NULL);
421421
422422 /* Check moved event is still at the front */
423423 if (cycles_evsel != perf_evlist__first(evlist)) {
tools/perf/tests/tests.h+2−0
@@ -85,6 +85,8 @@ int test__synthesize_stat_config(int subtest); · 84 unmodified lines
8585 int test__synthesize_stat(int subtest);
8686 int test__synthesize_stat_round(int subtest);
8787 int test__event_update(int subtest);
88+int test__event_times(int subtest);
89+int test__backward_ring_buffer(int subtest);
8890
8991 #if defined(__arm__) || defined(__aarch64__)
9092 #ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/tests/vmlinux-kallsyms.c+10−1
@@ -54,8 +54,14 @@ int test__vmlinux_matches_kallsyms(int subtest __maybe_unused) · 53 unmodified lines
5454 * Step 3:
5555 *
5656 * Load and split /proc/kallsyms into multiple maps, one per module.
57+ * Do not use kcore, as this test was designed before kcore support
58+ * and has parts that only make sense if using the non-kcore code.
59+ * XXX: extend it to stress the kcorre code as well, hint: the list
60+ * of modules extracted from /proc/kcore, in its current form, can't
61+ * be compacted against the list of modules found in the "vmlinux"
62+ * code and with the one got from /proc/modules from the "kallsyms" code.
5763 */
58− if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) {
64+ if (__machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, true, NULL) <= 0) {
5965 pr_debug("dso__load_kallsyms ");
6066 goto out;
6167 }
@@ -157,6 +163,9 @@ next_pair: · 95 unmodified lines
157163
158164 pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n",
159165 mem_start, sym->name, pair->name);
166+ } else {
167+ pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n",
168+ mem_start, sym->name, first_pair->name);
160169 }
161170 }
162171 } else
tools/perf/trace/beauty/eventfd.c+38−0
@@ -0,0 +1,38 @@
1+#include <sys/eventfd.h>
2+
3+#ifndef EFD_SEMAPHORE
4+#define EFD_SEMAPHORE 1
5+#endif
6+
7+#ifndef EFD_NONBLOCK
8+#define EFD_NONBLOCK 00004000
9+#endif
10+
11+#ifndef EFD_CLOEXEC
12+#define EFD_CLOEXEC 02000000
13+#endif
14+
15+static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size, struct syscall_arg *arg)
16+{
17+ int printed = 0, flags = arg->val;
18+
19+ if (flags == 0)
20+ return scnprintf(bf, size, "NONE");
21+#define P_FLAG(n) \
22+ if (flags & EFD_##n) { \
23+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
24+ flags &= ~EFD_##n; \
25+ }
26+
27+ P_FLAG(SEMAPHORE);
28+ P_FLAG(CLOEXEC);
29+ P_FLAG(NONBLOCK);
30+#undef P_FLAG
31+
32+ if (flags)
33+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
34+
35+ return printed;
36+}
37+
38+#define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags
tools/perf/trace/beauty/flock.c+31−0
@@ -0,0 +1,31 @@
1+
2+static size_t syscall_arg__scnprintf_flock(char *bf, size_t size,
3+ struct syscall_arg *arg)
4+{
5+ int printed = 0, op = arg->val;
6+
7+ if (op == 0)
8+ return scnprintf(bf, size, "NONE");
9+#define P_CMD(cmd) \
10+ if ((op & LOCK_##cmd) == LOCK_##cmd) { \
11+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \
12+ op &= ~LOCK_##cmd; \
13+ }
14+
15+ P_CMD(SH);
16+ P_CMD(EX);
17+ P_CMD(NB);
18+ P_CMD(UN);
19+ P_CMD(MAND);
20+ P_CMD(RW);
21+ P_CMD(READ);
22+ P_CMD(WRITE);
23+#undef P_OP
24+
25+ if (op)
26+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", op);
27+
28+ return printed;
29+}
30+
31+#define SCA_FLOCK syscall_arg__scnprintf_flock
tools/perf/trace/beauty/futex_op.c+44−0
@@ -0,0 +1,44 @@
1+#include <linux/futex.h>
2+
3+static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg)
4+{
5+ enum syscall_futex_args {
6+ SCF_UADDR = (1 << 0),
7+ SCF_OP = (1 << 1),
8+ SCF_VAL = (1 << 2),
9+ SCF_TIMEOUT = (1 << 3),
10+ SCF_UADDR2 = (1 << 4),
11+ SCF_VAL3 = (1 << 5),
12+ };
13+ int op = arg->val;
14+ int cmd = op & FUTEX_CMD_MASK;
15+ size_t printed = 0;
16+
17+ switch (cmd) {
18+#define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n);
19+ P_FUTEX_OP(WAIT); arg->mask |= SCF_VAL3|SCF_UADDR2; break;
20+ P_FUTEX_OP(WAKE); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
21+ P_FUTEX_OP(FD); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
22+ P_FUTEX_OP(REQUEUE); arg->mask |= SCF_VAL3|SCF_TIMEOUT; break;
23+ P_FUTEX_OP(CMP_REQUEUE); arg->mask |= SCF_TIMEOUT; break;
24+ P_FUTEX_OP(CMP_REQUEUE_PI); arg->mask |= SCF_TIMEOUT; break;
25+ P_FUTEX_OP(WAKE_OP); break;
26+ P_FUTEX_OP(LOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
27+ P_FUTEX_OP(UNLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
28+ P_FUTEX_OP(TRYLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2; break;
29+ P_FUTEX_OP(WAIT_BITSET); arg->mask |= SCF_UADDR2; break;
30+ P_FUTEX_OP(WAKE_BITSET); arg->mask |= SCF_UADDR2; break;
31+ P_FUTEX_OP(WAIT_REQUEUE_PI); break;
32+ default: printed = scnprintf(bf, size, "%#x", cmd); break;
33+ }
34+
35+ if (op & FUTEX_PRIVATE_FLAG)
36+ printed += scnprintf(bf + printed, size - printed, "|PRIV");
37+
38+ if (op & FUTEX_CLOCK_REALTIME)
39+ printed += scnprintf(bf + printed, size - printed, "|CLKRT");
40+
41+ return printed;
42+}
43+
44+#define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op
tools/perf/trace/beauty/mmap.c+158−0
@@ -0,0 +1,158 @@
1+#include <sys/mman.h>
2+
3+static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
4+ struct syscall_arg *arg)
5+{
6+ int printed = 0, prot = arg->val;
7+
8+ if (prot == PROT_NONE)
9+ return scnprintf(bf, size, "NONE");
10+#define P_MMAP_PROT(n) \
11+ if (prot & PROT_##n) { \
12+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
13+ prot &= ~PROT_##n; \
14+ }
15+
16+ P_MMAP_PROT(EXEC);
17+ P_MMAP_PROT(READ);
18+ P_MMAP_PROT(WRITE);
19+#ifdef PROT_SEM
20+ P_MMAP_PROT(SEM);
21+#endif
22+ P_MMAP_PROT(GROWSDOWN);
23+ P_MMAP_PROT(GROWSUP);
24+#undef P_MMAP_PROT
25+
26+ if (prot)
27+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", prot);
28+
29+ return printed;
30+}
31+
32+#define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
33+
34+#ifndef MAP_STACK
35+# define MAP_STACK 0x20000
36+#endif
37+
38+static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
39+ struct syscall_arg *arg)
40+{
41+ int printed = 0, flags = arg->val;
42+
43+#define P_MMAP_FLAG(n) \
44+ if (flags & MAP_##n) { \
45+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
46+ flags &= ~MAP_##n; \
47+ }
48+
49+ P_MMAP_FLAG(SHARED);
50+ P_MMAP_FLAG(PRIVATE);
51+#ifdef MAP_32BIT
52+ P_MMAP_FLAG(32BIT);
53+#endif
54+ P_MMAP_FLAG(ANONYMOUS);
55+ P_MMAP_FLAG(DENYWRITE);
56+ P_MMAP_FLAG(EXECUTABLE);
57+ P_MMAP_FLAG(FILE);
58+ P_MMAP_FLAG(FIXED);
59+ P_MMAP_FLAG(GROWSDOWN);
60+#ifdef MAP_HUGETLB
61+ P_MMAP_FLAG(HUGETLB);
62+#endif
63+ P_MMAP_FLAG(LOCKED);
64+ P_MMAP_FLAG(NONBLOCK);
65+ P_MMAP_FLAG(NORESERVE);
66+ P_MMAP_FLAG(POPULATE);
67+ P_MMAP_FLAG(STACK);
68+#ifdef MAP_UNINITIALIZED
69+ P_MMAP_FLAG(UNINITIALIZED);
70+#endif
71+#undef P_MMAP_FLAG
72+
73+ if (flags)
74+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
75+
76+ return printed;
77+}
78+
79+#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
80+
81+static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
82+ struct syscall_arg *arg)
83+{
84+ int printed = 0, flags = arg->val;
85+
86+#define P_MREMAP_FLAG(n) \
87+ if (flags & MREMAP_##n) { \
88+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
89+ flags &= ~MREMAP_##n; \
90+ }
91+
92+ P_MREMAP_FLAG(MAYMOVE);
93+#ifdef MREMAP_FIXED
94+ P_MREMAP_FLAG(FIXED);
95+#endif
96+#undef P_MREMAP_FLAG
97+
98+ if (flags)
99+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
100+
101+ return printed;
102+}
103+
104+#define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags
105+
106+#ifndef MADV_HWPOISON
107+#define MADV_HWPOISON 100
108+#endif
109+
110+#ifndef MADV_MERGEABLE
111+#define MADV_MERGEABLE 12
112+#endif
113+
114+#ifndef MADV_UNMERGEABLE
115+#define MADV_UNMERGEABLE 13
116+#endif
117+
118+static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
119+ struct syscall_arg *arg)
120+{
121+ int behavior = arg->val;
122+
123+ switch (behavior) {
124+#define P_MADV_BHV(n) case MADV_##n: return scnprintf(bf, size, #n)
125+ P_MADV_BHV(NORMAL);
126+ P_MADV_BHV(RANDOM);
127+ P_MADV_BHV(SEQUENTIAL);
128+ P_MADV_BHV(WILLNEED);
129+ P_MADV_BHV(DONTNEED);
130+ P_MADV_BHV(REMOVE);
131+ P_MADV_BHV(DONTFORK);
132+ P_MADV_BHV(DOFORK);
133+ P_MADV_BHV(HWPOISON);
134+#ifdef MADV_SOFT_OFFLINE
135+ P_MADV_BHV(SOFT_OFFLINE);
136+#endif
137+ P_MADV_BHV(MERGEABLE);
138+ P_MADV_BHV(UNMERGEABLE);
139+#ifdef MADV_HUGEPAGE
140+ P_MADV_BHV(HUGEPAGE);
141+#endif
142+#ifdef MADV_NOHUGEPAGE
143+ P_MADV_BHV(NOHUGEPAGE);
144+#endif
145+#ifdef MADV_DONTDUMP
146+ P_MADV_BHV(DONTDUMP);
147+#endif
148+#ifdef MADV_DODUMP
149+ P_MADV_BHV(DODUMP);
150+#endif
151+#undef P_MADV_PHV
152+ default: break;
153+ }
154+
155+ return scnprintf(bf, size, "%#x", behavior);
156+}
157+
158+#define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior
tools/perf/trace/beauty/mode_t.c+68−0
@@ -0,0 +1,68 @@
1+#include <sys/types.h>
2+#include <sys/stat.h>
3+#include <unistd.h>
4+
5+/* From include/linux/stat.h */
6+#ifndef S_IRWXUGO
7+#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
8+#endif
9+#ifndef S_IALLUGO
10+#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
11+#endif
12+#ifndef S_IRUGO
13+#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
14+#endif
15+#ifndef S_IWUGO
16+#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
17+#endif
18+#ifndef S_IXUGO
19+#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
20+#endif
21+
22+static size_t syscall_arg__scnprintf_mode_t(char *bf, size_t size, struct syscall_arg *arg)
23+{
24+ int printed = 0, mode = arg->val;
25+
26+#define P_MODE(n) \
27+ if ((mode & S_##n) == S_##n) { \
28+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
29+ mode &= ~S_##n; \
30+ }
31+
32+ P_MODE(IALLUGO);
33+ P_MODE(IRWXUGO);
34+ P_MODE(IRUGO);
35+ P_MODE(IWUGO);
36+ P_MODE(IXUGO);
37+ P_MODE(IFMT);
38+ P_MODE(IFSOCK);
39+ P_MODE(IFLNK);
40+ P_MODE(IFREG);
41+ P_MODE(IFBLK);
42+ P_MODE(IFDIR);
43+ P_MODE(IFCHR);
44+ P_MODE(IFIFO);
45+ P_MODE(ISUID);
46+ P_MODE(ISGID);
47+ P_MODE(ISVTX);
48+ P_MODE(IRWXU);
49+ P_MODE(IRUSR);
50+ P_MODE(IWUSR);
51+ P_MODE(IXUSR);
52+ P_MODE(IRWXG);
53+ P_MODE(IRGRP);
54+ P_MODE(IWGRP);
55+ P_MODE(IXGRP);
56+ P_MODE(IRWXO);
57+ P_MODE(IROTH);
58+ P_MODE(IWOTH);
59+ P_MODE(IXOTH);
60+#undef P_MODE
61+
62+ if (mode)
63+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", mode);
64+
65+ return printed;
66+}
67+
68+#define SCA_MODE_T syscall_arg__scnprintf_mode_t
tools/perf/trace/beauty/msg_flags.c+62−0
@@ -0,0 +1,62 @@
1+#include <sys/types.h>
2+#include <sys/socket.h>
3+
4+#ifndef MSG_PROBE
5+#define MSG_PROBE 0x10
6+#endif
7+#ifndef MSG_WAITFORONE
8+#define MSG_WAITFORONE 0x10000
9+#endif
10+#ifndef MSG_SENDPAGE_NOTLAST
11+#define MSG_SENDPAGE_NOTLAST 0x20000
12+#endif
13+#ifndef MSG_FASTOPEN
14+#define MSG_FASTOPEN 0x20000000
15+#endif
16+#ifndef MSG_CMSG_CLOEXEC
17+# define MSG_CMSG_CLOEXEC 0x40000000
18+#endif
19+
20+static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
21+ struct syscall_arg *arg)
22+{
23+ int printed = 0, flags = arg->val;
24+
25+ if (flags == 0)
26+ return scnprintf(bf, size, "NONE");
27+#define P_MSG_FLAG(n) \
28+ if (flags & MSG_##n) { \
29+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
30+ flags &= ~MSG_##n; \
31+ }
32+
33+ P_MSG_FLAG(OOB);
34+ P_MSG_FLAG(PEEK);
35+ P_MSG_FLAG(DONTROUTE);
36+ P_MSG_FLAG(TRYHARD);
37+ P_MSG_FLAG(CTRUNC);
38+ P_MSG_FLAG(PROBE);
39+ P_MSG_FLAG(TRUNC);
40+ P_MSG_FLAG(DONTWAIT);
41+ P_MSG_FLAG(EOR);
42+ P_MSG_FLAG(WAITALL);
43+ P_MSG_FLAG(FIN);
44+ P_MSG_FLAG(SYN);
45+ P_MSG_FLAG(CONFIRM);
46+ P_MSG_FLAG(RST);
47+ P_MSG_FLAG(ERRQUEUE);
48+ P_MSG_FLAG(NOSIGNAL);
49+ P_MSG_FLAG(MORE);
50+ P_MSG_FLAG(WAITFORONE);
51+ P_MSG_FLAG(SENDPAGE_NOTLAST);
52+ P_MSG_FLAG(FASTOPEN);
53+ P_MSG_FLAG(CMSG_CLOEXEC);
54+#undef P_MSG_FLAG
55+
56+ if (flags)
57+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
58+
59+ return printed;
60+}
61+
62+#define SCA_MSG_FLAGS syscall_arg__scnprintf_msg_flags
tools/perf/trace/beauty/open_flags.c+56−0
@@ -0,0 +1,56 @@
1+
2+static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
3+ struct syscall_arg *arg)
4+{
5+ int printed = 0, flags = arg->val;
6+
7+ if (!(flags & O_CREAT))
8+ arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */
9+
10+ if (flags == 0)
11+ return scnprintf(bf, size, "RDONLY");
12+#define P_FLAG(n) \
13+ if (flags & O_##n) { \
14+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
15+ flags &= ~O_##n; \
16+ }
17+
18+ P_FLAG(APPEND);
19+ P_FLAG(ASYNC);
20+ P_FLAG(CLOEXEC);
21+ P_FLAG(CREAT);
22+ P_FLAG(DIRECT);
23+ P_FLAG(DIRECTORY);
24+ P_FLAG(EXCL);
25+ P_FLAG(LARGEFILE);
26+ P_FLAG(NOATIME);
27+ P_FLAG(NOCTTY);
28+#ifdef O_NONBLOCK
29+ P_FLAG(NONBLOCK);
30+#elif O_NDELAY
31+ P_FLAG(NDELAY);
32+#endif
33+#ifdef O_PATH
34+ P_FLAG(PATH);
35+#endif
36+ P_FLAG(RDWR);
37+#ifdef O_DSYNC
38+ if ((flags & O_SYNC) == O_SYNC)
39+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC");
40+ else {
41+ P_FLAG(DSYNC);
42+ }
43+#else
44+ P_FLAG(SYNC);
45+#endif
46+ P_FLAG(TRUNC);
47+ P_FLAG(WRONLY);
48+#undef P_FLAG
49+
50+ if (flags)
51+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
52+
53+ return printed;
54+}
55+
56+#define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags
tools/perf/trace/beauty/perf_event_open.c+43−0
@@ -0,0 +1,43 @@
1+#ifndef PERF_FLAG_FD_NO_GROUP
2+# define PERF_FLAG_FD_NO_GROUP (1UL << 0)
3+#endif
4+
5+#ifndef PERF_FLAG_FD_OUTPUT
6+# define PERF_FLAG_FD_OUTPUT (1UL << 1)
7+#endif
8+
9+#ifndef PERF_FLAG_PID_CGROUP
10+# define PERF_FLAG_PID_CGROUP (1UL << 2) /* pid=cgroup id, per-cpu mode only */
11+#endif
12+
13+#ifndef PERF_FLAG_FD_CLOEXEC
14+# define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */
15+#endif
16+
17+static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size,
18+ struct syscall_arg *arg)
19+{
20+ int printed = 0, flags = arg->val;
21+
22+ if (flags == 0)
23+ return 0;
24+
25+#define P_FLAG(n) \
26+ if (flags & PERF_FLAG_##n) { \
27+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
28+ flags &= ~PERF_FLAG_##n; \
29+ }
30+
31+ P_FLAG(FD_NO_GROUP);
32+ P_FLAG(FD_OUTPUT);
33+ P_FLAG(PID_CGROUP);
34+ P_FLAG(FD_CLOEXEC);
35+#undef P_FLAG
36+
37+ if (flags)
38+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
39+
40+ return printed;
41+}
42+
43+#define SCA_PERF_FLAGS syscall_arg__scnprintf_perf_flags
tools/perf/trace/beauty/pid.c+21−0
@@ -0,0 +1,21 @@
1+static size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg)
2+{
3+ int pid = arg->val;
4+ struct trace *trace = arg->trace;
5+ size_t printed = scnprintf(bf, size, "%d", pid);
6+ struct thread *thread = machine__findnew_thread(trace->host, pid, pid);
7+
8+ if (thread != NULL) {
9+ if (!thread->comm_set)
10+ thread__set_comm_from_proc(thread);
11+
12+ if (thread->comm_set)
13+ printed += scnprintf(bf + printed, size - printed,
14+ " (%s)", thread__comm_str(thread));
15+ thread__put(thread);
16+ }
17+
18+ return printed;
19+}
20+
21+#define SCA_PID syscall_arg__scnprintf_pid
tools/perf/trace/beauty/sched_policy.c+44−0
@@ -0,0 +1,44 @@
1+#include <sched.h>
2+
3+/*
4+ * Not defined anywhere else, probably, just to make sure we
5+ * catch future flags
6+ */
7+#define SCHED_POLICY_MASK 0xff
8+
9+#ifndef SCHED_DEADLINE
10+#define SCHED_DEADLINE 6
11+#endif
12+
13+static size_t syscall_arg__scnprintf_sched_policy(char *bf, size_t size,
14+ struct syscall_arg *arg)
15+{
16+ const char *policies[] = {
17+ "NORMAL", "FIFO", "RR", "BATCH", "ISO", "IDLE", "DEADLINE",
18+ };
19+ size_t printed;
20+ int policy = arg->val,
21+ flags = policy & ~SCHED_POLICY_MASK;
22+
23+ policy &= SCHED_POLICY_MASK;
24+ if (policy <= SCHED_DEADLINE)
25+ printed = scnprintf(bf, size, "%s", policies[policy]);
26+ else
27+ printed = scnprintf(bf, size, "%#x", policy);
28+
29+#define P_POLICY_FLAG(n) \
30+ if (flags & SCHED_##n) { \
31+ printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
32+ flags &= ~SCHED_##n; \
33+ }
34+
35+ P_POLICY_FLAG(RESET_ON_FORK);
36+#undef P_POLICY_FLAG
37+
38+ if (flags)
39+ printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
40+
41+ return printed;
42+}
43+
44+#define SCA_SCHED_POLICY syscall_arg__scnprintf_sched_policy
tools/perf/trace/beauty/seccomp.c+52−0
@@ -0,0 +1,52 @@
1+#include <linux/seccomp.h>
2+
3+#ifndef SECCOMP_SET_MODE_STRICT
4+#define SECCOMP_SET_MODE_STRICT 0
5+#endif
6+#ifndef SECCOMP_SET_MODE_FILTER
7+#define SECCOMP_SET_MODE_FILTER 1
8+#endif
9+
10+static size_t syscall_arg__scnprintf_seccomp_op(char *bf, size_t size, struct syscall_arg *arg)
11+{
12+ int op = arg->val;
13+ size_t printed = 0;
14+
15+ switch (op) {
16+#define P_SECCOMP_SET_MODE_OP(n) case SECCOMP_SET_MODE_##n: printed = scnprintf(bf, size, #n); break
17+ P_SECCOMP_SET_MODE_OP(STRICT);
18+ P_SECCOMP_SET_MODE_OP(FILTER);
19+#undef P_SECCOMP_SET_MODE_OP
20+ default: printed = scnprintf(bf, size, "%#x", op); break;
21+ }
22+
23+ return printed;
24+}
25+
26+#define SCA_SECCOMP_OP syscall_arg__scnprintf_seccomp_op
27+
28+#ifndef SECCOMP_FILTER_FLAG_TSYNC
29+#define SECCOMP_FILTER_FLAG_TSYNC 1
30+#endif
31+
32+static size_t syscall_arg__scnprintf_seccomp_flags(char *bf, size_t size,
33+ struct syscall_arg *arg)
34+{
35+ int printed = 0, flags = arg->val;
36+
37+#define P_FLAG(n) \
38+ if (flags & SECCOMP_FILTER_FLAG_##n) { \
39+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
40+ flags &= ~SECCOMP_FILTER_FLAG_##n; \
41+ }
42+
43+ P_FLAG(TSYNC);
44+#undef P_FLAG
45+
46+ if (flags)
47+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
48+
49+ return printed;
50+}
51+
52+#define SCA_SECCOMP_FLAGS syscall_arg__scnprintf_seccomp_flags
tools/perf/trace/beauty/signum.c+53−0
@@ -0,0 +1,53 @@
1+
2+static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg)
3+{
4+ int sig = arg->val;
5+
6+ switch (sig) {
7+#define P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n)
8+ P_SIGNUM(HUP);
9+ P_SIGNUM(INT);
10+ P_SIGNUM(QUIT);
11+ P_SIGNUM(ILL);
12+ P_SIGNUM(TRAP);
13+ P_SIGNUM(ABRT);
14+ P_SIGNUM(BUS);
15+ P_SIGNUM(FPE);
16+ P_SIGNUM(KILL);
17+ P_SIGNUM(USR1);
18+ P_SIGNUM(SEGV);
19+ P_SIGNUM(USR2);
20+ P_SIGNUM(PIPE);
21+ P_SIGNUM(ALRM);
22+ P_SIGNUM(TERM);
23+ P_SIGNUM(CHLD);
24+ P_SIGNUM(CONT);
25+ P_SIGNUM(STOP);
26+ P_SIGNUM(TSTP);
27+ P_SIGNUM(TTIN);
28+ P_SIGNUM(TTOU);
29+ P_SIGNUM(URG);
30+ P_SIGNUM(XCPU);
31+ P_SIGNUM(XFSZ);
32+ P_SIGNUM(VTALRM);
33+ P_SIGNUM(PROF);
34+ P_SIGNUM(WINCH);
35+ P_SIGNUM(IO);
36+ P_SIGNUM(PWR);
37+ P_SIGNUM(SYS);
38+#ifdef SIGEMT
39+ P_SIGNUM(EMT);
40+#endif
41+#ifdef SIGSTKFLT
42+ P_SIGNUM(STKFLT);
43+#endif
44+#ifdef SIGSWI
45+ P_SIGNUM(SWI);
46+#endif
47+ default: break;
48+ }
49+
50+ return scnprintf(bf, size, "%#x", sig);
51+}
52+
53+#define SCA_SIGNUM syscall_arg__scnprintf_signum
tools/perf/trace/beauty/socket_type.c+60−0
@@ -0,0 +1,60 @@
1+#include <sys/types.h>
2+#include <sys/socket.h>
3+
4+#ifndef SOCK_DCCP
5+# define SOCK_DCCP 6
6+#endif
7+
8+#ifndef SOCK_CLOEXEC
9+# define SOCK_CLOEXEC 02000000
10+#endif
11+
12+#ifndef SOCK_NONBLOCK
13+# define SOCK_NONBLOCK 00004000
14+#endif
15+
16+#ifndef SOCK_TYPE_MASK
17+#define SOCK_TYPE_MASK 0xf
18+#endif
19+
20+static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, struct syscall_arg *arg)
21+{
22+ size_t printed;
23+ int type = arg->val,
24+ flags = type & ~SOCK_TYPE_MASK;
25+
26+ type &= SOCK_TYPE_MASK;
27+ /*
28+ * Can't use a strarray, MIPS may override for ABI reasons.
29+ */
30+ switch (type) {
31+#define P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
32+ P_SK_TYPE(STREAM);
33+ P_SK_TYPE(DGRAM);
34+ P_SK_TYPE(RAW);
35+ P_SK_TYPE(RDM);
36+ P_SK_TYPE(SEQPACKET);
37+ P_SK_TYPE(DCCP);
38+ P_SK_TYPE(PACKET);
39+#undef P_SK_TYPE
40+ default:
41+ printed = scnprintf(bf, size, "%#x", type);
42+ }
43+
44+#define P_SK_FLAG(n) \
45+ if (flags & SOCK_##n) { \
46+ printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
47+ flags &= ~SOCK_##n; \
48+ }
49+
50+ P_SK_FLAG(CLOEXEC);
51+ P_SK_FLAG(NONBLOCK);
52+#undef P_SK_FLAG
53+
54+ if (flags)
55+ printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
56+
57+ return printed;
58+}
59+
60+#define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
tools/perf/trace/beauty/waitid_options.c+26−0
@@ -0,0 +1,26 @@
1+#include <sys/types.h>
2+#include <sys/wait.h>
3+
4+static size_t syscall_arg__scnprintf_waitid_options(char *bf, size_t size,
5+ struct syscall_arg *arg)
6+{
7+ int printed = 0, options = arg->val;
8+
9+#define P_OPTION(n) \
10+ if (options & W##n) { \
11+ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
12+ options &= ~W##n; \
13+ }
14+
15+ P_OPTION(NOHANG);
16+ P_OPTION(UNTRACED);
17+ P_OPTION(CONTINUED);
18+#undef P_OPTION
19+
20+ if (options)
21+ printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", options);
22+
23+ return printed;
24+}
25+
26+#define SCA_WAITID_OPTIONS syscall_arg__scnprintf_waitid_options
tools/perf/ui/browsers/hists.c+20−20
@@ -1607,9 +1607,8 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows · 1606 unmodified lines
16071607
16081608 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists));
16091609 dummy_hpp.buf[ret] = '\0';
1610− rtrim(dummy_hpp.buf);
16111610
1612− start = ltrim(dummy_hpp.buf);
1611+ start = trim(dummy_hpp.buf);
16131612 ret = strlen(start);
16141613
16151614 if (start != dummy_hpp.buf)
@@ -1897,11 +1896,10 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, · 281 unmodified lines
18971896 bool first = true;
18981897 int ret;
18991898
1900− if (symbol_conf.use_callchain)
1899+ if (symbol_conf.use_callchain) {
19011900 folded_sign = hist_entry__folded(he);
1902−
1903− if (symbol_conf.use_callchain)
19041901 printed += fprintf(fp, "%c ", folded_sign);
1902+ }
19051903
19061904 hists__for_each_format(browser->hists, fmt) {
19071905 if (perf_hpp__should_skip(fmt, he->hists))
@@ -2137,7 +2135,7 @@ static int hists__browser_title(struct hists *hists, · 229 unmodified lines
21372135 printed += snprintf(bf + printed, size - printed,
21382136 ", UID: %s", hists->uid_filter_str);
21392137 if (thread) {
2140− if (sort__has_thread) {
2138+ if (hists__has(hists, thread)) {
21412139 printed += scnprintf(bf + printed, size - printed,
21422140 ", Thread: %s(%d)",
21432141 (thread->comm_set ? thread__comm_str(thread) : ""),
@@ -2322,7 +2320,8 @@ do_zoom_thread(struct hist_browser *browser, struct popup_action *act) · 178 unmodified lines
23222320 {
23232321 struct thread *thread = act->thread;
23242322
2325− if ((!sort__has_thread && !sort__has_comm) || thread == NULL)
2323+ if ((!hists__has(browser->hists, thread) &&
2324+ !hists__has(browser->hists, comm)) || thread == NULL)
23262325 return 0;
23272326
23282327 if (browser->hists->thread_filter) {
@@ -2331,7 +2330,7 @@ do_zoom_thread(struct hist_browser *browser, struct popup_action *act) · 2 unmodified lines
23312330 thread__zput(browser->hists->thread_filter);
23322331 ui_helpline__pop();
23332332 } else {
2334− if (sort__has_thread) {
2333+ if (hists__has(browser->hists, thread)) {
23352334 ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s(%d) thread\"",
23362335 thread->comm_set ? thread__comm_str(thread) : "",
23372336 thread->tid);
@@ -2356,10 +2355,11 @@ add_thread_opt(struct hist_browser *browser, struct popup_action *act, · 18 unmodified lines
23562355 {
23572356 int ret;
23582357
2359− if ((!sort__has_thread && !sort__has_comm) || thread == NULL)
2358+ if ((!hists__has(browser->hists, thread) &&
2359+ !hists__has(browser->hists, comm)) || thread == NULL)
23602360 return 0;
23612361
2362− if (sort__has_thread) {
2362+ if (hists__has(browser->hists, thread)) {
23632363 ret = asprintf(optstr, "Zoom %s %s(%d) thread",
23642364 browser->hists->thread_filter ? "out of" : "into",
23652365 thread->comm_set ? thread__comm_str(thread) : "",
@@ -2382,7 +2382,7 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act) · 16 unmodified lines
23822382 {
23832383 struct map *map = act->ms.map;
23842384
2385− if (!sort__has_dso || map == NULL)
2385+ if (!hists__has(browser->hists, dso) || map == NULL)
23862386 return 0;
23872387
23882388 if (browser->hists->dso_filter) {
@@ -2409,7 +2409,7 @@ static int · 20 unmodified lines
24092409 add_dso_opt(struct hist_browser *browser, struct popup_action *act,
24102410 char **optstr, struct map *map)
24112411 {
2412− if (!sort__has_dso || map == NULL)
2412+ if (!hists__has(browser->hists, dso) || map == NULL)
24132413 return 0;
24142414
24152415 if (asprintf(optstr, "Zoom %s %s DSO",
@@ -2431,10 +2431,10 @@ do_browse_map(struct hist_browser *browser __maybe_unused, · 15 unmodified lines
24312431 }
24322432
24332433 static int
2434−add_map_opt(struct hist_browser *browser __maybe_unused,
2434+add_map_opt(struct hist_browser *browser,
24352435 struct popup_action *act, char **optstr, struct map *map)
24362436 {
2437− if (!sort__has_dso || map == NULL)
2437+ if (!hists__has(browser->hists, dso) || map == NULL)
24382438 return 0;
24392439
24402440 if (asprintf(optstr, "Browse map details") < 0)
@@ -2536,7 +2536,7 @@ add_exit_opt(struct hist_browser *browser __maybe_unused, · 95 unmodified lines
25362536 static int
25372537 do_zoom_socket(struct hist_browser *browser, struct popup_action *act)
25382538 {
2539− if (!sort__has_socket || act->socket < 0)
2539+ if (!hists__has(browser->hists, socket) || act->socket < 0)
25402540 return 0;
25412541
25422542 if (browser->hists->socket_filter > -1) {
@@ -2558,7 +2558,7 @@ static int · 15 unmodified lines
25582558 add_socket_opt(struct hist_browser *browser, struct popup_action *act,
25592559 char **optstr, int socket_id)
25602560 {
2561− if (!sort__has_socket || socket_id < 0)
2561+ if (!hists__has(browser->hists, socket) || socket_id < 0)
25622562 return 0;
25632563
25642564 if (asprintf(optstr, "Zoom %s Processor Socket %d",
@@ -2749,7 +2749,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, · 184 unmodified lines
27492749 */
27502750 goto out_free_stack;
27512751 case 'a':
2752− if (!sort__has_sym) {
2752+ if (!hists__has(hists, sym)) {
27532753 ui_browser__warning(&browser->b, delay_secs * 2,
27542754 "Annotation is only available for symbolic views, "
27552755 "include \"sym*\" in --sort to use it.");
@@ -2912,7 +2912,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, · 156 unmodified lines
29122912 continue;
29132913 }
29142914
2915− if (!sort__has_sym || browser->selection == NULL)
2915+ if (!hists__has(hists, sym) || browser->selection == NULL)
29162916 goto skip_annotation;
29172917
29182918 if (sort__mode == SORT_MODE__BRANCH) {
@@ -2956,7 +2956,7 @@ skip_annotation: · 37 unmodified lines
29562956 goto skip_scripting;
29572957
29582958 if (browser->he_selection) {
2959− if (sort__has_thread && thread) {
2959+ if (hists__has(hists, thread) && thread) {
29602960 nr_options += add_script_opt(browser,
29612961 &actions[nr_options],
29622962 &options[nr_options],
@@ -2971,7 +2971,7 @@ skip_annotation: · 8 unmodified lines
29712971 *
29722972 * See hist_browser__show_entry.
29732973 */
2974− if (sort__has_sym && browser->selection->sym) {
2974+ if (hists__has(hists, sym) && browser->selection->sym) {
29752975 nr_options += add_script_opt(browser,
29762976 &actions[nr_options],
29772977 &options[nr_options],
tools/perf/ui/gtk/hists.c+1−1
@@ -379,7 +379,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, · 378 unmodified lines
379379 gtk_tree_store_set(store, &iter, col_idx++, s, -1);
380380 }
381381
382− if (symbol_conf.use_callchain && sort__has_sym) {
382+ if (symbol_conf.use_callchain && hists__has(hists, sym)) {
383383 if (callchain_param.mode == CHAIN_GRAPH_REL)
384384 total = symbol_conf.cumulate_callchain ?
385385 h->stat_acc->period : h->stat.period;
tools/perf/ui/hist.c+1−1
@@ -635,7 +635,7 @@ unsigned int hists__sort_list_width(struct hists *hists) · 634 unmodified lines
635635 ret += fmt->width(fmt, &dummy_hpp, hists_to_evsel(hists));
636636 }
637637
638− if (verbose && sort__has_sym) /* Addr + origin */
638+ if (verbose && hists__has(hists, sym)) /* Addr + origin */
639639 ret += 3 + BITS_PER_LONG / 4;
640640
641641 return ret;
tools/perf/ui/stdio/hist.c+1−2
@@ -569,9 +569,8 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, · 568 unmodified lines
569569 first_col = false;
570570
571571 fmt->header(fmt, hpp, hists_to_evsel(hists));
572− rtrim(hpp->buf);
573572
574− header_width += fprintf(fp, "%s", ltrim(hpp->buf));
573+ header_width += fprintf(fp, "%s", trim(hpp->buf));
575574 }
576575 }
577576
tools/perf/util/Build+5−3
@@ -8,6 +8,7 @@ libperf-y += env.o · 7 unmodified lines
88 libperf-y += event.o
99 libperf-y += evlist.o
1010 libperf-y += evsel.o
11+libperf-y += evsel_fprintf.o
1112 libperf-y += find_bit.o
1213 libperf-y += kallsyms.o
1314 libperf-y += levenshtein.o
@@ -26,9 +27,9 @@ libperf-y += strlist.o · 12 unmodified lines
2627 libperf-y += strfilter.o
2728 libperf-y += top.o
2829 libperf-y += usage.o
29−libperf-y += wrapper.o
3030 libperf-y += dso.o
3131 libperf-y += symbol.o
32+libperf-y += symbol_fprintf.o
3233 libperf-y += color.o
3334 libperf-y += header.o
3435 libperf-y += callchain.o
@@ -38,6 +39,7 @@ libperf-y += machine.o · 3 unmodified lines
3839 libperf-y += map.o
3940 libperf-y += pstack.o
4041 libperf-y += session.o
42+libperf-$(CONFIG_AUDIT) += syscalltbl.o
4143 libperf-y += ordered-events.o
4244 libperf-y += comm.o
4345 libperf-y += thread.o
@@ -69,9 +71,9 @@ libperf-y += stat-shadow.o · 25 unmodified lines
6971 libperf-y += record.o
7072 libperf-y += srcline.o
7173 libperf-y += data.o
72−libperf-$(CONFIG_X86) += tsc.o
73−libperf-$(CONFIG_AUXTRACE) += tsc.o
74+libperf-y += tsc.o
7475 libperf-y += cloexec.o
76+libperf-y += call-path.o
7577 libperf-y += thread-stack.o
7678 libperf-$(CONFIG_AUXTRACE) += auxtrace.o
7779 libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/
tools/perf/util/annotate.c+2−2
@@ -1138,7 +1138,7 @@ fallback: · 1137 unmodified lines
11381138
11391139 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
11401140 !dso__is_kcore(dso)) {
1141− char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
1141+ char bf[SBUILD_ID_SIZE + 15] = " with build id ";
11421142 char *build_id_msg = NULL;
11431143
11441144 if (dso->annotate_warned)
@@ -1665,5 +1665,5 @@ int hist_entry__annotate(struct hist_entry *he, size_t privsize) · 520 unmodified lines
16651665
16661666 bool ui__has_annotation(void)
16671667 {
1668− return use_browser == 1 && sort__has_sym;
1668+ return use_browser == 1 && perf_hpp_list.sym;
16691669 }
tools/perf/util/auxtrace.c+7−0
@@ -940,6 +940,7 @@ void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts) · 939 unmodified lines
940940 synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
941941 synth_opts->callchain_sz = PERF_ITRACE_DEFAULT_CALLCHAIN_SZ;
942942 synth_opts->last_branch_sz = PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ;
943+ synth_opts->initial_skip = 0;
943944 }
944945
945946 /*
@@ -1064,6 +1065,12 @@ int itrace_parse_synth_opts(const struct option *opt, const char *str, · 118 unmodified lines
10641065 synth_opts->last_branch_sz = val;
10651066 }
10661067 break;
1068+ case 's':
1069+ synth_opts->initial_skip = strtoul(p, &endptr, 10);
1070+ if (p == endptr)
1071+ goto out_err;
1072+ p = endptr;
1073+ break;
10671074 case ' ':
10681075 case ',':
10691076 break;
tools/perf/util/auxtrace.h+2−0
@@ -68,6 +68,7 @@ enum itrace_period_type { · 67 unmodified lines
6868 * @last_branch_sz: branch context size
6969 * @period: 'instructions' events period
7070 * @period_type: 'instructions' events period type
71+ * @initial_skip: skip N events at the beginning.
7172 */
7273 struct itrace_synth_opts {
7374 bool set;
@@ -86,6 +87,7 @@ struct itrace_synth_opts { · 12 unmodified lines
8687 unsigned int last_branch_sz;
8788 unsigned long long period;
8889 enum itrace_period_type period_type;
90+ unsigned long initial_skip;
8991 };
9092
9193 /**
tools/perf/util/bpf-loader.c+143−0
@@ -842,6 +842,58 @@ bpf_map_op__new(struct parse_events_term *term) · 841 unmodified lines
842842 return op;
843843 }
844844
845+static struct bpf_map_op *
846+bpf_map_op__clone(struct bpf_map_op *op)
847+{
848+ struct bpf_map_op *newop;
849+
850+ newop = memdup(op, sizeof(*op));
851+ if (!newop) {
852+ pr_debug("Failed to alloc bpf_map_op\n");
853+ return NULL;
854+ }
855+
856+ INIT_LIST_HEAD(&newop->list);
857+ if (op->key_type == BPF_MAP_KEY_RANGES) {
858+ size_t memsz = op->k.array.nr_ranges *
859+ sizeof(op->k.array.ranges[0]);
860+
861+ newop->k.array.ranges = memdup(op->k.array.ranges, memsz);
862+ if (!newop->k.array.ranges) {
863+ pr_debug("Failed to alloc indices for map\n");
864+ free(newop);
865+ return NULL;
866+ }
867+ }
868+
869+ return newop;
870+}
871+
872+static struct bpf_map_priv *
873+bpf_map_priv__clone(struct bpf_map_priv *priv)
874+{
875+ struct bpf_map_priv *newpriv;
876+ struct bpf_map_op *pos, *newop;
877+
878+ newpriv = zalloc(sizeof(*newpriv));
879+ if (!newpriv) {
880+ pr_debug("No enough memory to alloc map private\n");
881+ return NULL;
882+ }
883+ INIT_LIST_HEAD(&newpriv->ops_list);
884+
885+ list_for_each_entry(pos, &priv->ops_list, list) {
886+ newop = bpf_map_op__clone(pos);
887+ if (!newop) {
888+ bpf_map_priv__purge(newpriv);
889+ return NULL;
890+ }
891+ list_add_tail(&newop->list, &newpriv->ops_list);
892+ }
893+
894+ return newpriv;
895+}
896+
845897 static int
846898 bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
847899 {
@@ -1417,6 +1469,89 @@ int bpf__apply_obj_config(void) · 569 unmodified lines
14171469 return 0;
14181470 }
14191471
1472+#define bpf__for_each_map(pos, obj, objtmp) \
1473+ bpf_object__for_each_safe(obj, objtmp) \
1474+ bpf_map__for_each(pos, obj)
1475+
1476+#define bpf__for_each_stdout_map(pos, obj, objtmp) \
1477+ bpf__for_each_map(pos, obj, objtmp) \
1478+ if (bpf_map__get_name(pos) && \
1479+ (strcmp("__bpf_stdout__", \
1480+ bpf_map__get_name(pos)) == 0))
1481+
1482+int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
1483+{
1484+ struct bpf_map_priv *tmpl_priv = NULL;
1485+ struct bpf_object *obj, *tmp;
1486+ struct perf_evsel *evsel = NULL;
1487+ struct bpf_map *map;
1488+ int err;
1489+ bool need_init = false;
1490+
1491+ bpf__for_each_stdout_map(map, obj, tmp) {
1492+ struct bpf_map_priv *priv;
1493+
1494+ err = bpf_map__get_private(map, (void **)&priv);
1495+ if (err)
1496+ return -BPF_LOADER_ERRNO__INTERNAL;
1497+
1498+ /*
1499+ * No need to check map type: type should have been
1500+ * verified by kernel.
1501+ */
1502+ if (!need_init && !priv)
1503+ need_init = !priv;
1504+ if (!tmpl_priv && priv)
1505+ tmpl_priv = priv;
1506+ }
1507+
1508+ if (!need_init)
1509+ return 0;
1510+
1511+ if (!tmpl_priv) {
1512+ err = parse_events(evlist, "bpf-output/no-inherit=1,name=__bpf_stdout__/",
1513+ NULL);
1514+ if (err) {
1515+ pr_debug("ERROR: failed to create bpf-output event\n");
1516+ return -err;
1517+ }
1518+
1519+ evsel = perf_evlist__last(evlist);
1520+ }
1521+
1522+ bpf__for_each_stdout_map(map, obj, tmp) {
1523+ struct bpf_map_priv *priv;
1524+
1525+ err = bpf_map__get_private(map, (void **)&priv);
1526+ if (err)
1527+ return -BPF_LOADER_ERRNO__INTERNAL;
1528+ if (priv)
1529+ continue;
1530+
1531+ if (tmpl_priv) {
1532+ priv = bpf_map_priv__clone(tmpl_priv);
1533+ if (!priv)
1534+ return -ENOMEM;
1535+
1536+ err = bpf_map__set_private(map, priv, bpf_map_priv__clear);
1537+ if (err) {
1538+ bpf_map_priv__clear(map, priv);
1539+ return err;
1540+ }
1541+ } else if (evsel) {
1542+ struct bpf_map_op *op;
1543+
1544+ op = bpf_map__add_newop(map, NULL);
1545+ if (IS_ERR(op))
1546+ return PTR_ERR(op);
1547+ op->op_type = BPF_MAP_OP_SET_EVSEL;
1548+ op->v.evsel = evsel;
1549+ }
1550+ }
1551+
1552+ return 0;
1553+}
1554+
14201555 #define ERRNO_OFFSET(e) ((e) - __BPF_LOADER_ERRNO__START)
14211556 #define ERRCODE_OFFSET(c) ERRNO_OFFSET(BPF_LOADER_ERRNO__##c)
14221557 #define NR_ERRNO (__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START)
@@ -1590,3 +1725,11 @@ int bpf__strerror_apply_obj_config(int err, char *buf, size_t size) · 167 unmodified lines
15901725 bpf__strerror_end(buf, size);
15911726 return 0;
15921727 }
1728+
1729+int bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
1730+ int err, char *buf, size_t size)
1731+{
1732+ bpf__strerror_head(err, buf, size);
1733+ bpf__strerror_end(buf, size);
1734+ return 0;
1735+}
tools/perf/util/bpf-loader.h+19−0
@@ -79,6 +79,11 @@ int bpf__strerror_config_obj(struct bpf_object *obj, · 78 unmodified lines
7979 size_t size);
8080 int bpf__apply_obj_config(void);
8181 int bpf__strerror_apply_obj_config(int err, char *buf, size_t size);
82+
83+int bpf__setup_stdout(struct perf_evlist *evlist);
84+int bpf__strerror_setup_stdout(struct perf_evlist *evlist, int err,
85+ char *buf, size_t size);
86+
8287 #else
8388 static inline struct bpf_object *
8489 bpf__prepare_load(const char *filename __maybe_unused,
@@ -124,6 +129,12 @@ bpf__apply_obj_config(void) · 39 unmodified lines
124129 return 0;
125130 }
126131
132+static inline int
133+bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
134+{
135+ return 0;
136+}
137+
127138 static inline int
128139 __bpf_strerror(char *buf, size_t size)
129140 {
@@ -177,5 +188,13 @@ bpf__strerror_apply_obj_config(int err __maybe_unused, · 47 unmodified lines
177188 {
178189 return __bpf_strerror(buf, size);
179190 }
191+
192+static inline int
193+bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
194+ int err __maybe_unused, char *buf,
195+ size_t size)
196+{
197+ return __bpf_strerror(buf, size);
198+}
180199 #endif
181200 #endif
tools/perf/util/build-id.c+7−29
@@ -261,14 +261,14 @@ static int machine__write_buildid_table(struct machine *machine, int fd) · 260 unmodified lines
261261
262262 if (dso__is_vdso(pos)) {
263263 name = pos->short_name;
264− name_len = pos->short_name_len + 1;
264+ name_len = pos->short_name_len;
265265 } else if (dso__is_kcore(pos)) {
266266 machine__mmap_name(machine, nm, sizeof(nm));
267267 name = nm;
268− name_len = strlen(nm) + 1;
268+ name_len = strlen(nm);
269269 } else {
270270 name = pos->long_name;
271− name_len = pos->long_name_len + 1;
271+ name_len = pos->long_name_len;
272272 }
273273
274274 in_kernel = pos->kernel ||
@@ -365,39 +365,17 @@ static char *build_id_cache__dirname_from_path(const char *name, · 90 unmodified lines
365365 int build_id_cache__list_build_ids(const char *pathname,
366366 struct strlist **result)
367367 {
368− struct strlist *list;
369368 char *dir_name;
370− DIR *dir;
371− struct dirent *d;
372369 int ret = 0;
373370
374− list = strlist__new(NULL, NULL);
375371 dir_name = build_id_cache__dirname_from_path(pathname, false, false);
376− if (!list || !dir_name) {
377− ret = -ENOMEM;
378− goto out;
379− }
372+ if (!dir_name)
373+ return -ENOMEM;
380374
381− /* List up all dirents */
382− dir = opendir(dir_name);
383− if (!dir) {
375+ *result = lsdir(dir_name, lsdir_no_dot_filter);
376+ if (!*result)
384377 ret = -errno;
385− goto out;
386− }
387−
388− while ((d = readdir(dir)) != NULL) {
389− if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
390− continue;
391− strlist__add(list, d->d_name);
392− }
393− closedir(dir);
394−
395−out:
396378 free(dir_name);
397− if (ret)
398− strlist__delete(list);
399− else
400− *result = list;
401379
402380 return ret;
403381 }
tools/perf/util/cache.h+0−19
@@ -40,25 +40,6 @@ int split_cmdline(char *cmdline, const char ***argv); · 39 unmodified lines
4040
4141 #define alloc_nr(x) (((x)+16)*3/2)
4242
43−/*
44− * Realloc the buffer pointed at by variable 'x' so that it can hold
45− * at least 'nr' entries; the number of entries currently allocated
46− * is 'alloc', using the standard growing factor alloc_nr() macro.
47− *
48− * DO NOT USE any expression with side-effect for 'x' or 'alloc'.
49− */
50−#define ALLOC_GROW(x, nr, alloc) \
51− do { \
52− if ((nr) > alloc) { \
53− if (alloc_nr(alloc) < (nr)) \
54− alloc = (nr); \
55− else \
56− alloc = alloc_nr(alloc); \
57− x = xrealloc((x), alloc * sizeof(*(x))); \
58− } \
59− } while(0)
60−
61−
6243 static inline int is_absolute_path(const char *path)
6344 {
6445 return path[0] == '/';
tools/perf/util/call-path.c+122−0
@@ -0,0 +1,122 @@
1+/*
2+ * call-path.h: Manipulate a tree data structure containing function call paths
3+ * Copyright (c) 2014, Intel Corporation.
4+ *
5+ * This program is free software; you can redistribute it and/or modify it
6+ * under the terms and conditions of the GNU General Public License,
7+ * version 2, as published by the Free Software Foundation.
8+ *
9+ * This program is distributed in the hope it will be useful, but WITHOUT
10+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12+ * more details.
13+ *
14+ */
15+
16+#include <linux/rbtree.h>
17+#include <linux/list.h>
18+
19+#include "util.h"
20+#include "call-path.h"
21+
22+static void call_path__init(struct call_path *cp, struct call_path *parent,
23+ struct symbol *sym, u64 ip, bool in_kernel)
24+{
25+ cp->parent = parent;
26+ cp->sym = sym;
27+ cp->ip = sym ? 0 : ip;
28+ cp->db_id = 0;
29+ cp->in_kernel = in_kernel;
30+ RB_CLEAR_NODE(&cp->rb_node);
31+ cp->children = RB_ROOT;
32+}
33+
34+struct call_path_root *call_path_root__new(void)
35+{
36+ struct call_path_root *cpr;
37+
38+ cpr = zalloc(sizeof(struct call_path_root));
39+ if (!cpr)
40+ return NULL;
41+ call_path__init(&cpr->call_path, NULL, NULL, 0, false);
42+ INIT_LIST_HEAD(&cpr->blocks);
43+ return cpr;
44+}
45+
46+void call_path_root__free(struct call_path_root *cpr)
47+{
48+ struct call_path_block *pos, *n;
49+
50+ list_for_each_entry_safe(pos, n, &cpr->blocks, node) {
51+ list_del(&pos->node);
52+ free(pos);
53+ }
54+ free(cpr);
55+}
56+
57+static struct call_path *call_path__new(struct call_path_root *cpr,
58+ struct call_path *parent,
59+ struct symbol *sym, u64 ip,
60+ bool in_kernel)
61+{
62+ struct call_path_block *cpb;
63+ struct call_path *cp;
64+ size_t n;
65+
66+ if (cpr->next < cpr->sz) {
67+ cpb = list_last_entry(&cpr->blocks, struct call_path_block,
68+ node);
69+ } else {
70+ cpb = zalloc(sizeof(struct call_path_block));
71+ if (!cpb)
72+ return NULL;
73+ list_add_tail(&cpb->node, &cpr->blocks);
74+ cpr->sz += CALL_PATH_BLOCK_SIZE;
75+ }
76+
77+ n = cpr->next++ & CALL_PATH_BLOCK_MASK;
78+ cp = &cpb->cp[n];
79+
80+ call_path__init(cp, parent, sym, ip, in_kernel);
81+
82+ return cp;
83+}
84+
85+struct call_path *call_path__findnew(struct call_path_root *cpr,
86+ struct call_path *parent,
87+ struct symbol *sym, u64 ip, u64 ks)
88+{
89+ struct rb_node **p;
90+ struct rb_node *node_parent = NULL;
91+ struct call_path *cp;
92+ bool in_kernel = ip >= ks;
93+
94+ if (sym)
95+ ip = 0;
96+
97+ if (!parent)
98+ return call_path__new(cpr, parent, sym, ip, in_kernel);
99+
100+ p = &parent->children.rb_node;
101+ while (*p != NULL) {
102+ node_parent = *p;
103+ cp = rb_entry(node_parent, struct call_path, rb_node);
104+
105+ if (cp->sym == sym && cp->ip == ip)
106+ return cp;
107+
108+ if (sym < cp->sym || (sym == cp->sym && ip < cp->ip))
109+ p = &(*p)->rb_left;
110+ else
111+ p = &(*p)->rb_right;
112+ }
113+
114+ cp = call_path__new(cpr, parent, sym, ip, in_kernel);
115+ if (!cp)
116+ return NULL;
117+
118+ rb_link_node(&cp->rb_node, node_parent, p);
119+ rb_insert_color(&cp->rb_node, &parent->children);
120+
121+ return cp;
122+}
tools/perf/util/call-path.h+77−0
@@ -0,0 +1,77 @@
1+/*
2+ * call-path.h: Manipulate a tree data structure containing function call paths
3+ * Copyright (c) 2014, Intel Corporation.
4+ *
5+ * This program is free software; you can redistribute it and/or modify it
6+ * under the terms and conditions of the GNU General Public License,
7+ * version 2, as published by the Free Software Foundation.
8+ *
9+ * This program is distributed in the hope it will be useful, but WITHOUT
10+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12+ * more details.
13+ *
14+ */
15+
16+#ifndef __PERF_CALL_PATH_H
17+#define __PERF_CALL_PATH_H
18+
19+#include <sys/types.h>
20+
21+#include <linux/types.h>
22+#include <linux/rbtree.h>
23+
24+/**
25+ * struct call_path - node in list of calls leading to a function call.
26+ * @parent: call path to the parent function call
27+ * @sym: symbol of function called
28+ * @ip: only if sym is null, the ip of the function
29+ * @db_id: id used for db-export
30+ * @in_kernel: whether function is a in the kernel
31+ * @rb_node: node in parent's tree of called functions
32+ * @children: tree of call paths of functions called
33+ *
34+ * In combination with the call_return structure, the call_path structure
35+ * defines a context-sensitve call-graph.
36+ */
37+struct call_path {
38+ struct call_path *parent;
39+ struct symbol *sym;
40+ u64 ip;
41+ u64 db_id;
42+ bool in_kernel;
43+ struct rb_node rb_node;
44+ struct rb_root children;
45+};
46+
47+#define CALL_PATH_BLOCK_SHIFT 8
48+#define CALL_PATH_BLOCK_SIZE (1 << CALL_PATH_BLOCK_SHIFT)
49+#define CALL_PATH_BLOCK_MASK (CALL_PATH_BLOCK_SIZE - 1)
50+
51+struct call_path_block {
52+ struct call_path cp[CALL_PATH_BLOCK_SIZE];
53+ struct list_head node;
54+};
55+
56+/**
57+ * struct call_path_root - root of all call paths.
58+ * @call_path: root call path
59+ * @blocks: list of blocks to store call paths
60+ * @next: next free space
61+ * @sz: number of spaces
62+ */
63+struct call_path_root {
64+ struct call_path call_path;
65+ struct list_head blocks;
66+ size_t next;
67+ size_t sz;
68+};
69+
70+struct call_path_root *call_path_root__new(void);
71+void call_path_root__free(struct call_path_root *cpr);
72+
73+struct call_path *call_path__findnew(struct call_path_root *cpr,
74+ struct call_path *parent,
75+ struct symbol *sym, u64 ip, u64 ks);
76+
77+#endif
tools/perf/util/callchain.c+6−3
@@ -109,6 +109,7 @@ __parse_callchain_report_opt(const char *arg, bool allow_record_opt) · 108 unmodified lines
109109 bool record_opt_set = false;
110110 bool try_stack_size = false;
111111
112+ callchain_param.enabled = true;
112113 symbol_conf.use_callchain = true;
113114
114115 if (!arg)
@@ -117,6 +118,7 @@ __parse_callchain_report_opt(const char *arg, bool allow_record_opt) · 2 unmodified lines
117118 while ((tok = strtok((char *)arg, ",")) != NULL) {
118119 if (!strncmp(tok, "none", strlen(tok))) {
119120 callchain_param.mode = CHAIN_NONE;
121+ callchain_param.enabled = false;
120122 symbol_conf.use_callchain = false;
121123 return 0;
122124 }
@@ -788,7 +790,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor, · 665 unmodified lines
788790 return 0;
789791 }
790792
791−int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
793+int sample__resolve_callchain(struct perf_sample *sample,
794+ struct callchain_cursor *cursor, struct symbol **parent,
792795 struct perf_evsel *evsel, struct addr_location *al,
793796 int max_stack)
794797 {
@@ -796,8 +799,8 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent · 1 unmodified line
796799 return 0;
797800
798801 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||
799− sort__has_parent) {
800− return thread__resolve_callchain(al->thread, evsel, sample,
802+ perf_hpp_list.parent) {
803+ return thread__resolve_callchain(al->thread, cursor, evsel, sample,
801804 parent, al, max_stack);
802805 }
803806 return 0;
tools/perf/util/callchain.h+8−1
@@ -212,7 +212,14 @@ struct hist_entry; · 211 unmodified lines
212212 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
213213 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
214214
215−int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
215+struct record_opts;
216+
217+int record_opts__parse_callchain(struct record_opts *record,
218+ struct callchain_param *callchain,
219+ const char *arg, bool unset);
220+
221+int sample__resolve_callchain(struct perf_sample *sample,
222+ struct callchain_cursor *cursor, struct symbol **parent,
216223 struct perf_evsel *evsel, struct addr_location *al,
217224 int max_stack);
218225 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
tools/perf/util/config.c+191−31
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include <subcmd/exec-cmd.h>
1414 #include "util/hist.h" /* perf_hist_config */
1515 #include "util/llvm-utils.h" /* perf_llvm_config */
16+#include "config.h"
1617
1718 #define MAXNAME (256)
1819
@@ -377,6 +378,21 @@ const char *perf_config_dirname(const char *name, const char *value) · 358 unmodified lines
377378 return value;
378379 }
379380
381+static int perf_buildid_config(const char *var, const char *value)
382+{
383+ /* same dir for all commands */
384+ if (!strcmp(var, "buildid.dir")) {
385+ const char *dir = perf_config_dirname(var, value);
386+
387+ if (!dir)
388+ return -1;
389+ strncpy(buildid_dir, dir, MAXPATHLEN-1);
390+ buildid_dir[MAXPATHLEN-1] = '\0';
391+ }
392+
393+ return 0;
394+}
395+
380396 static int perf_default_core_config(const char *var __maybe_unused,
381397 const char *value __maybe_unused)
382398 {
@@ -412,6 +428,9 @@ int perf_default_config(const char *var, const char *value, · 29 unmodified lines
412428 if (!prefixcmp(var, "llvm."))
413429 return perf_llvm_config(var, value);
414430
431+ if (!prefixcmp(var, "buildid."))
432+ return perf_buildid_config(var, value);
433+
415434 /* Add other config variables here. */
416435 return 0;
417436 }
@@ -506,41 +525,185 @@ out: · 88 unmodified lines
506525 return ret;
507526 }
508527
509−/*
510− * Call this to report error for your variable that should not
511− * get a boolean value (i.e. "[my] var" means "true").
512− */
513−int config_error_nonbool(const char *var)
528+static struct perf_config_section *find_section(struct list_head *sections,
529+ const char *section_name)
514530 {
515− return error("Missing value for '%s'", var);
531+ struct perf_config_section *section;
532+
533+ list_for_each_entry(section, sections, node)
534+ if (!strcmp(section->name, section_name))
535+ return section;
536+
537+ return NULL;
538+}
539+
540+static struct perf_config_item *find_config_item(const char *name,
541+ struct perf_config_section *section)
542+{
543+ struct perf_config_item *item;
544+
545+ list_for_each_entry(item, &section->items, node)
546+ if (!strcmp(item->name, name))
547+ return item;
548+
549+ return NULL;
516550 }
517551
518−struct buildid_dir_config {
519− char *dir;
520−};
552+static struct perf_config_section *add_section(struct list_head *sections,
553+ const char *section_name)
554+{
555+ struct perf_config_section *section = zalloc(sizeof(*section));
556+
557+ if (!section)
558+ return NULL;
559+
560+ INIT_LIST_HEAD(&section->items);
561+ section->name = strdup(section_name);
562+ if (!section->name) {
563+ pr_debug("%s: strdup failed\n", __func__);
564+ free(section);
565+ return NULL;
566+ }
567+
568+ list_add_tail(&section->node, sections);
569+ return section;
570+}
521571
522−static int buildid_dir_command_config(const char *var, const char *value,
523− void *data)
572+static struct perf_config_item *add_config_item(struct perf_config_section *section,
573+ const char *name)
524574 {
525− struct buildid_dir_config *c = data;
526− const char *v;
575+ struct perf_config_item *item = zalloc(sizeof(*item));
527576
528− /* same dir for all commands */
529− if (!strcmp(var, "buildid.dir")) {
530− v = perf_config_dirname(var, value);
531− if (!v)
532− return -1;
533− strncpy(c->dir, v, MAXPATHLEN-1);
534− c->dir[MAXPATHLEN-1] = '\0';
577+ if (!item)
578+ return NULL;
579+
580+ item->name = strdup(name);
581+ if (!item->name) {
582+ pr_debug("%s: strdup failed\n", __func__);
583+ free(item);
584+ return NULL;
535585 }
586+
587+ list_add_tail(&item->node, &section->items);
588+ return item;
589+}
590+
591+static int set_value(struct perf_config_item *item, const char *value)
592+{
593+ char *val = strdup(value);
594+
595+ if (!val)
596+ return -1;
597+
598+ zfree(&item->value);
599+ item->value = val;
536600 return 0;
537601 }
538602
539−static void check_buildid_dir_config(void)
603+static int collect_config(const char *var, const char *value,
604+ void *perf_config_set)
540605 {
541− struct buildid_dir_config c;
542− c.dir = buildid_dir;
543− perf_config(buildid_dir_command_config, &c);
606+ int ret = -1;
607+ char *ptr, *key;
608+ char *section_name, *name;
609+ struct perf_config_section *section = NULL;
610+ struct perf_config_item *item = NULL;
611+ struct perf_config_set *set = perf_config_set;
612+ struct list_head *sections = &set->sections;
613+
614+ key = ptr = strdup(var);
615+ if (!key) {
616+ pr_debug("%s: strdup failed\n", __func__);
617+ return -1;
618+ }
619+
620+ section_name = strsep(&ptr, ".");
621+ name = ptr;
622+ if (name == NULL || value == NULL)
623+ goto out_free;
624+
625+ section = find_section(sections, section_name);
626+ if (!section) {
627+ section = add_section(sections, section_name);
628+ if (!section)
629+ goto out_free;
630+ }
631+
632+ item = find_config_item(name, section);
633+ if (!item) {
634+ item = add_config_item(section, name);
635+ if (!item)
636+ goto out_free;
637+ }
638+
639+ ret = set_value(item, value);
640+ return ret;
641+
642+out_free:
643+ free(key);
644+ perf_config_set__delete(set);
645+ return -1;
646+}
647+
648+struct perf_config_set *perf_config_set__new(void)
649+{
650+ struct perf_config_set *set = zalloc(sizeof(*set));
651+
652+ if (set) {
653+ INIT_LIST_HEAD(&set->sections);
654+ perf_config(collect_config, set);
655+ }
656+
657+ return set;
658+}
659+
660+static void perf_config_item__delete(struct perf_config_item *item)
661+{
662+ zfree(&item->name);
663+ zfree(&item->value);
664+ free(item);
665+}
666+
667+static void perf_config_section__purge(struct perf_config_section *section)
668+{
669+ struct perf_config_item *item, *tmp;
670+
671+ list_for_each_entry_safe(item, tmp, &section->items, node) {
672+ list_del_init(&item->node);
673+ perf_config_item__delete(item);
674+ }
675+}
676+
677+static void perf_config_section__delete(struct perf_config_section *section)
678+{
679+ perf_config_section__purge(section);
680+ zfree(&section->name);
681+ free(section);
682+}
683+
684+static void perf_config_set__purge(struct perf_config_set *set)
685+{
686+ struct perf_config_section *section, *tmp;
687+
688+ list_for_each_entry_safe(section, tmp, &set->sections, node) {
689+ list_del_init(&section->node);
690+ perf_config_section__delete(section);
691+ }
692+}
693+
694+void perf_config_set__delete(struct perf_config_set *set)
695+{
696+ perf_config_set__purge(set);
697+ free(set);
698+}
699+
700+/*
701+ * Call this to report error for your variable that should not
702+ * get a boolean value (i.e. "[my] var" means "true").
703+ */
704+int config_error_nonbool(const char *var)
705+{
706+ return error("Missing value for '%s'", var);
544707 }
545708
546709 void set_buildid_dir(const char *dir)
@@ -548,16 +711,13 @@ void set_buildid_dir(const char *dir) · 1 unmodified line
548711 if (dir)
549712 scnprintf(buildid_dir, MAXPATHLEN-1, "%s", dir);
550713
551− /* try config file */
552− if (buildid_dir[0] == '\0')
553− check_buildid_dir_config();
554−
555714 /* default to $HOME/.debug */
556715 if (buildid_dir[0] == '\0') {
557− char *v = getenv("HOME");
558− if (v) {
716+ char *home = getenv("HOME");
717+
718+ if (home) {
559719 snprintf(buildid_dir, MAXPATHLEN-1, "%s/%s",
560− v, DEBUG_CACHE_DIR);
720+ home, DEBUG_CACHE_DIR);
561721 } else {
562722 strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1);
563723 }
tools/perf/util/config.h+26−0
@@ -0,0 +1,26 @@
1+#ifndef __PERF_CONFIG_H
2+#define __PERF_CONFIG_H
3+
4+#include <stdbool.h>
5+#include <linux/list.h>
6+
7+struct perf_config_item {
8+ char *name;
9+ char *value;
10+ struct list_head node;
11+};
12+
13+struct perf_config_section {
14+ char *name;
15+ struct list_head items;
16+ struct list_head node;
17+};
18+
19+struct perf_config_set {
20+ struct list_head sections;
21+};
22+
23+struct perf_config_set *perf_config_set__new(void);
24+void perf_config_set__delete(struct perf_config_set *set);
25+
26+#endif /* __PERF_CONFIG_H */
tools/perf/util/cpumap.c+12−0
@@ -587,3 +587,15 @@ int cpu__setup_cpunode_map(void) · 586 unmodified lines
587587 closedir(dir1);
588588 return 0;
589589 }
590+
591+bool cpu_map__has(struct cpu_map *cpus, int cpu)
592+{
593+ int i;
594+
595+ for (i = 0; i < cpus->nr; ++i) {
596+ if (cpus->map[i] == cpu)
597+ return true;
598+ }
599+
600+ return false;
601+}
tools/perf/util/cpumap.h+2−0
@@ -66,4 +66,6 @@ int cpu__get_node(int cpu); · 65 unmodified lines
6666 int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
6767 int (*f)(struct cpu_map *map, int cpu, void *data),
6868 void *data);
69+
70+bool cpu_map__has(struct cpu_map *cpus, int cpu);
6971 #endif /* __PERF_CPUMAP_H */
tools/perf/util/data.c+41−0
@@ -136,3 +136,44 @@ ssize_t perf_data_file__write(struct perf_data_file *file, · 135 unmodified lines
136136 {
137137 return writen(file->fd, buf, size);
138138 }
139+
140+int perf_data_file__switch(struct perf_data_file *file,
141+ const char *postfix,
142+ size_t pos, bool at_exit)
143+{
144+ char *new_filepath;
145+ int ret;
146+
147+ if (check_pipe(file))
148+ return -EINVAL;
149+ if (perf_data_file__is_read(file))
150+ return -EINVAL;
151+
152+ if (asprintf(&new_filepath, "%s.%s", file->path, postfix) < 0)
153+ return -ENOMEM;
154+
155+ /*
156+ * Only fire a warning, don't return error, continue fill
157+ * original file.
158+ */
159+ if (rename(file->path, new_filepath))
160+ pr_warning("Failed to rename %s to %s\n", file->path, new_filepath);
161+
162+ if (!at_exit) {
163+ close(file->fd);
164+ ret = perf_data_file__open(file);
165+ if (ret < 0)
166+ goto out;
167+
168+ if (lseek(file->fd, pos, SEEK_SET) == (off_t)-1) {
169+ ret = -errno;
170+ pr_debug("Failed to lseek to %zu: %s",
171+ pos, strerror(errno));
172+ goto out;
173+ }
174+ }
175+ ret = file->fd;
176+out:
177+ free(new_filepath);
178+ return ret;
179+}
tools/perf/util/data.h+10−1
@@ -46,5 +46,14 @@ int perf_data_file__open(struct perf_data_file *file); · 45 unmodified lines
4646 void perf_data_file__close(struct perf_data_file *file);
4747 ssize_t perf_data_file__write(struct perf_data_file *file,
4848 void *buf, size_t size);
49−
49+/*
50+ * If at_exit is set, only rename current perf.data to
51+ * perf.data.<postfix>, continue write on original file.
52+ * Set at_exit when flushing the last output.
53+ *
54+ * Return value is fd of new output.
55+ */
56+int perf_data_file__switch(struct perf_data_file *file,
57+ const char *postfix,
58+ size_t pos, bool at_exit);
5059 #endif /* __PERF_DATA_H */
tools/perf/util/db-export.c+87−2
@@ -23,6 +23,8 @@ · 22 unmodified lines
2323 #include "event.h"
2424 #include "util.h"
2525 #include "thread-stack.h"
26+#include "callchain.h"
27+#include "call-path.h"
2628 #include "db-export.h"
2729
2830 struct deferred_export {
@@ -258,8 +260,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al, · 229 unmodified lines
258260 if (!al->sym) {
259261 al->sym = symbol__new(al->addr, 0, 0, "unknown");
260262 if (al->sym)
261− symbols__insert(&dso->symbols[al->map->type],
262− al->sym);
263+ dso__insert_symbol(dso, al->map->type, al->sym);
263264 }
264265
265266 if (al->sym) {
@@ -276,6 +277,80 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al, · 10 unmodified lines
276277 return 0;
277278 }
278279
280+static struct call_path *call_path_from_sample(struct db_export *dbe,
281+ struct machine *machine,
282+ struct thread *thread,
283+ struct perf_sample *sample,
284+ struct perf_evsel *evsel)
285+{
286+ u64 kernel_start = machine__kernel_start(machine);
287+ struct call_path *current = &dbe->cpr->call_path;
288+ enum chain_order saved_order = callchain_param.order;
289+ int err;
290+
291+ if (!symbol_conf.use_callchain || !sample->callchain)
292+ return NULL;
293+
294+ /*
295+ * Since the call path tree must be built starting with the root, we
296+ * must use ORDER_CALL for call chain resolution, in order to process
297+ * the callchain starting with the root node and ending with the leaf.
298+ */
299+ callchain_param.order = ORDER_CALLER;
300+ err = thread__resolve_callchain(thread, &callchain_cursor, evsel,
301+ sample, NULL, NULL,
302+ sysctl_perf_event_max_stack);
303+ if (err) {
304+ callchain_param.order = saved_order;
305+ return NULL;
306+ }
307+ callchain_cursor_commit(&callchain_cursor);
308+
309+ while (1) {
310+ struct callchain_cursor_node *node;
311+ struct addr_location al;
312+ u64 dso_db_id = 0, sym_db_id = 0, offset = 0;
313+
314+ memset(&al, 0, sizeof(al));
315+
316+ node = callchain_cursor_current(&callchain_cursor);
317+ if (!node)
318+ break;
319+ /*
320+ * Handle export of symbol and dso for this node by
321+ * constructing an addr_location struct and then passing it to
322+ * db_ids_from_al() to perform the export.
323+ */
324+ al.sym = node->sym;
325+ al.map = node->map;
326+ al.machine = machine;
327+ al.addr = node->ip;
328+
329+ if (al.map && !al.sym)
330+ al.sym = dso__find_symbol(al.map->dso, MAP__FUNCTION,
331+ al.addr);
332+
333+ db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset);
334+
335+ /* add node to the call path tree if it doesn't exist */
336+ current = call_path__findnew(dbe->cpr, current,
337+ al.sym, node->ip,
338+ kernel_start);
339+
340+ callchain_cursor_advance(&callchain_cursor);
341+ }
342+
343+ /* Reset the callchain order to its prior value. */
344+ callchain_param.order = saved_order;
345+
346+ if (current == &dbe->cpr->call_path) {
347+ /* Bail because the callchain was empty. */
348+ return NULL;
349+ }
350+
351+ return current;
352+}
353+
279354 int db_export__branch_type(struct db_export *dbe, u32 branch_type,
280355 const char *name)
281356 {
@@ -329,6 +404,16 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, · 47 unmodified lines
329404 if (err)
330405 goto out_put;
331406
407+ if (dbe->cpr) {
408+ struct call_path *cp = call_path_from_sample(dbe, al->machine,
409+ thread, sample,
410+ evsel);
411+ if (cp) {
412+ db_export__call_path(dbe, cp);
413+ es.call_path_id = cp->db_id;
414+ }
415+ }
416+
332417 if ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
333418 sample_addr_correlates_sym(&evsel->attr)) {
334419 struct addr_location addr_al;
tools/perf/util/db-export.h+3−0
@@ -27,6 +27,7 @@ struct dso; · 26 unmodified lines
2727 struct perf_sample;
2828 struct addr_location;
2929 struct call_return_processor;
30+struct call_path_root;
3031 struct call_path;
3132 struct call_return;
3233
@@ -43,6 +44,7 @@ struct export_sample { · 10 unmodified lines
4344 u64 addr_dso_db_id;
4445 u64 addr_sym_db_id;
4546 u64 addr_offset; /* addr offset from symbol start */
47+ u64 call_path_id;
4648 };
4749
4850 struct db_export {
@@ -64,6 +66,7 @@ struct db_export { · 15 unmodified lines
6466 int (*export_call_return)(struct db_export *dbe,
6567 struct call_return *cr);
6668 struct call_return_processor *crp;
69+ struct call_path_root *cpr;
6770 u64 evsel_last_db_id;
6871 u64 machine_last_db_id;
6972 u64 thread_last_db_id;
tools/perf/util/dso.c+2−2
@@ -38,7 +38,7 @@ int dso__read_binary_type_filename(const struct dso *dso, · 37 unmodified lines
3838 enum dso_binary_type type,
3939 char *root_dir, char *filename, size_t size)
4040 {
41− char build_id_hex[BUILD_ID_SIZE * 2 + 1];
41+ char build_id_hex[SBUILD_ID_SIZE];
4242 int ret = 0;
4343 size_t len;
4444
@@ -1301,7 +1301,7 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp) · 1256 unmodified lines
13011301
13021302 size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
13031303 {
1304− char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1304+ char sbuild_id[SBUILD_ID_SIZE];
13051305
13061306 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
13071307 return fprintf(fp, "%s", sbuild_id);
tools/perf/util/dwarf-aux.c+24−28
@@ -915,8 +915,7 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf) · 914 unmodified lines
915915 tmp = "*";
916916 else if (tag == DW_TAG_subroutine_type) {
917917 /* Function pointer */
918− strbuf_add(buf, "(function_type)", 15);
919− return 0;
918+ return strbuf_add(buf, "(function_type)", 15);
920919 } else {
921920 if (!dwarf_diename(&type))
922921 return -ENOENT;
@@ -927,14 +926,10 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf) · 4 unmodified lines
927926 else if (tag == DW_TAG_enumeration_type)
928927 tmp = "enum ";
929928 /* Write a base name */
930− strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type));
931− return 0;
929+ return strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type));
932930 }
933931 ret = die_get_typename(&type, buf);
934− if (ret == 0)
935− strbuf_addstr(buf, tmp);
936−
937− return ret;
932+ return ret ? ret : strbuf_addstr(buf, tmp);
938933 }
939934
940935 /**
@@ -951,12 +946,10 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf) · 10 unmodified lines
951946 ret = die_get_typename(vr_die, buf);
952947 if (ret < 0) {
953948 pr_debug("Failed to get type, make it unknown.\n");
954− strbuf_add(buf, " (unknown_type)", 14);
949+ ret = strbuf_add(buf, " (unknown_type)", 14);
955950 }
956951
957− strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
958−
959− return 0;
952+ return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
960953 }
961954
962955 #ifdef HAVE_DWARF_GETLOCATIONS
@@ -999,22 +992,24 @@ static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die, · 36 unmodified lines
999992 }
1000993
1001994 while ((offset = dwarf_ranges(&scopes[1], offset, &base,
1002− &start, &end)) > 0) {
995+ &start, &end)) > 0) {
1003996 start -= entry;
1004997 end -= entry;
1005998
1006999 if (first) {
1007− strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1008− name, start, end);
1000+ ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1001+ name, start, end);
10091002 first = false;
10101003 } else {
1011− strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1012− start, end);
1004+ ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1005+ start, end);
10131006 }
1007+ if (ret < 0)
1008+ goto out;
10141009 }
10151010
10161011 if (!first)
1017− strbuf_add(buf, "]>", 2);
1012+ ret = strbuf_add(buf, "]>", 2);
10181013
10191014 out:
10201015 free(scopes);
@@ -1054,31 +1049,32 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf) · 33 unmodified lines
10541049 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
10551050 return -EINVAL;
10561051
1057− while ((offset = dwarf_getlocations(
1058− &attr, offset, &base,
1059− &start, &end, &op, &nops)) > 0) {
1052+ while ((offset = dwarf_getlocations(&attr, offset, &base,
1053+ &start, &end, &op, &nops)) > 0) {
10601054 if (start == 0) {
10611055 /* Single Location Descriptions */
10621056 ret = die_get_var_innermost_scope(sp_die, vr_die, buf);
1063− return ret;
1057+ goto out;
10641058 }
10651059
10661060 /* Location Lists */
10671061 start -= entry;
10681062 end -= entry;
10691063 if (first) {
1070− strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1071− name, start, end);
1064+ ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1065+ name, start, end);
10721066 first = false;
10731067 } else {
1074− strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1075− start, end);
1068+ ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1069+ start, end);
10761070 }
1071+ if (ret < 0)
1072+ goto out;
10771073 }
10781074
10791075 if (!first)
1080− strbuf_add(buf, "]>", 2);
1081−
1076+ ret = strbuf_add(buf, "]>", 2);
1077+out:
10821078 return ret;
10831079 }
10841080 #else
tools/perf/util/event.c+1−0
@@ -45,6 +45,7 @@ static const char *perf_event__names[] = { · 44 unmodified lines
4545 [PERF_RECORD_STAT] = "STAT",
4646 [PERF_RECORD_STAT_ROUND] = "STAT_ROUND",
4747 [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE",
48+ [PERF_RECORD_TIME_CONV] = "TIME_CONV",
4849 };
4950
5051 const char *perf_event__name(unsigned int id)
tools/perf/util/event.h+9−0
@@ -233,6 +233,7 @@ enum perf_user_event_type { /* above any possible kernel type */ · 232 unmodified lines
233233 PERF_RECORD_STAT = 76,
234234 PERF_RECORD_STAT_ROUND = 77,
235235 PERF_RECORD_EVENT_UPDATE = 78,
236+ PERF_RECORD_TIME_CONV = 79,
236237 PERF_RECORD_HEADER_MAX
237238 };
238239
@@ -469,6 +470,13 @@ struct stat_round_event { · 230 unmodified lines
469470 u64 time;
470471 };
471472
473+struct time_conv_event {
474+ struct perf_event_header header;
475+ u64 time_shift;
476+ u64 time_mult;
477+ u64 time_zero;
478+};
479+
472480 union perf_event {
473481 struct perf_event_header header;
474482 struct mmap_event mmap;
@@ -497,6 +505,7 @@ union perf_event { · 22 unmodified lines
497505 struct stat_config_event stat_config;
498506 struct stat_event stat;
499507 struct stat_round_event stat_round;
508+ struct time_conv_event time_conv;
500509 };
501510
502511 void perf_event__print_totals(void);
tools/perf/util/evlist.c+134−40
@@ -679,53 +679,52 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, · 678 unmodified lines
679679 return NULL;
680680 }
681681
682−union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
682+/* When check_messup is true, 'end' must points to a good entry */
683+static union perf_event *
684+perf_mmap__read(struct perf_mmap *md, bool check_messup, u64 start,
685+ u64 end, u64 *prev)
683686 {
684− struct perf_mmap *md = &evlist->mmap[idx];
685− u64 head;
686− u64 old = md->prev;
687687 unsigned char *data = md->base + page_size;
688688 union perf_event *event = NULL;
689+ int diff = end - start;
689690
690− /*
691− * Check if event was unmapped due to a POLLHUP/POLLERR.
692− */
693− if (!atomic_read(&md->refcnt))
694− return NULL;
695−
696− head = perf_mmap__read_head(md);
697− if (evlist->overwrite) {
691+ if (check_messup) {
698692 /*
699693 * If we're further behind than half the buffer, there's a chance
700694 * the writer will bite our tail and mess up the samples under us.
701695 *
702− * If we somehow ended up ahead of the head, we got messed up.
696+ * If we somehow ended up ahead of the 'end', we got messed up.
703697 *
704− * In either case, truncate and restart at head.
698+ * In either case, truncate and restart at 'end'.
705699 */
706− int diff = head - old;
707700 if (diff > md->mask / 2 || diff < 0) {
708701 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
709702
710703 /*
711− * head points to a known good entry, start there.
704+ * 'end' points to a known good entry, start there.
712705 */
713− old = head;
706+ start = end;
707+ diff = 0;
714708 }
715709 }
716710
717− if (old != head) {
711+ if (diff >= (int)sizeof(event->header)) {
718712 size_t size;
719713
720− event = (union perf_event *)&data[old & md->mask];
714+ event = (union perf_event *)&data[start & md->mask];
721715 size = event->header.size;
722716
717+ if (size < sizeof(event->header) || diff < (int)size) {
718+ event = NULL;
719+ goto broken_event;
720+ }
721+
723722 /*
724723 * Event straddles the mmap boundary -- header should always
725724 * be inside due to u64 alignment of output.
726725 */
727− if ((old & md->mask) + size != ((old + size) & md->mask)) {
728− unsigned int offset = old;
726+ if ((start & md->mask) + size != ((start + size) & md->mask)) {
727+ unsigned int offset = start;
729728 unsigned int len = min(sizeof(*event), size), cpy;
730729 void *dst = md->event_copy;
731730
@@ -740,14 +739,83 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) · 8 unmodified lines
740739 event = (union perf_event *) md->event_copy;
741740 }
742741
743− old += size;
742+ start += size;
744743 }
745744
746− md->prev = old;
745+broken_event:
746+ if (prev)
747+ *prev = start;
747748
748749 return event;
749750 }
750751
752+union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
753+{
754+ struct perf_mmap *md = &evlist->mmap[idx];
755+ u64 head;
756+ u64 old = md->prev;
757+
758+ /*
759+ * Check if event was unmapped due to a POLLHUP/POLLERR.
760+ */
761+ if (!atomic_read(&md->refcnt))
762+ return NULL;
763+
764+ head = perf_mmap__read_head(md);
765+
766+ return perf_mmap__read(md, evlist->overwrite, old, head, &md->prev);
767+}
768+
769+union perf_event *
770+perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
771+{
772+ struct perf_mmap *md = &evlist->mmap[idx];
773+ u64 head, end;
774+ u64 start = md->prev;
775+
776+ /*
777+ * Check if event was unmapped due to a POLLHUP/POLLERR.
778+ */
779+ if (!atomic_read(&md->refcnt))
780+ return NULL;
781+
782+ head = perf_mmap__read_head(md);
783+ if (!head)
784+ return NULL;
785+
786+ /*
787+ * 'head' pointer starts from 0. Kernel minus sizeof(record) form
788+ * it each time when kernel writes to it, so in fact 'head' is
789+ * negative. 'end' pointer is made manually by adding the size of
790+ * the ring buffer to 'head' pointer, means the validate data can
791+ * read is the whole ring buffer. If 'end' is positive, the ring
792+ * buffer has not fully filled, so we must adjust 'end' to 0.
793+ *
794+ * However, since both 'head' and 'end' is unsigned, we can't
795+ * simply compare 'end' against 0. Here we compare '-head' and
796+ * the size of the ring buffer, where -head is the number of bytes
797+ * kernel write to the ring buffer.
798+ */
799+ if (-head < (u64)(md->mask + 1))
800+ end = 0;
801+ else
802+ end = head + md->mask + 1;
803+
804+ return perf_mmap__read(md, false, start, end, &md->prev);
805+}
806+
807+void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
808+{
809+ struct perf_mmap *md = &evlist->mmap[idx];
810+ u64 head;
811+
812+ if (!atomic_read(&md->refcnt))
813+ return;
814+
815+ head = perf_mmap__read_head(md);
816+ md->prev = head;
817+}
818+
751819 static bool perf_mmap__empty(struct perf_mmap *md)
752820 {
753821 return perf_mmap__read_head(md) == md->prev && !md->auxtrace_mmap.base;
@@ -986,26 +1054,34 @@ out_unmap: · 232 unmodified lines
9861054 return -1;
9871055 }
9881056
989−static size_t perf_evlist__mmap_size(unsigned long pages)
1057+unsigned long perf_event_mlock_kb_in_pages(void)
9901058 {
991− if (pages == UINT_MAX) {
992− int max;
1059+ unsigned long pages;
1060+ int max;
9931061
994− if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
995− /*
996− * Pick a once upon a time good value, i.e. things look
997− * strange since we can't read a sysctl value, but lets not
998− * die yet...
999− */
1000− max = 512;
1001− } else {
1002− max -= (page_size / 1024);
1003− }
1062+ if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
1063+ /*
1064+ * Pick a once upon a time good value, i.e. things look
1065+ * strange since we can't read a sysctl value, but lets not
1066+ * die yet...
1067+ */
1068+ max = 512;
1069+ } else {
1070+ max -= (page_size / 1024);
1071+ }
10041072
1005− pages = (max * 1024) / page_size;
1006− if (!is_power_of_2(pages))
1007− pages = rounddown_pow_of_two(pages);
1008− } else if (!is_power_of_2(pages))
1073+ pages = (max * 1024) / page_size;
1074+ if (!is_power_of_2(pages))
1075+ pages = rounddown_pow_of_two(pages);
1076+
1077+ return pages;
1078+}
1079+
1080+static size_t perf_evlist__mmap_size(unsigned long pages)
1081+{
1082+ if (pages == UINT_MAX)
1083+ pages = perf_event_mlock_kb_in_pages();
1084+ else if (!is_power_of_2(pages))
10091085 return 0;
10101086
10111087 return (pages + 1) * page_size;
@@ -1192,6 +1268,24 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, · 180 unmodified lines
11921268 perf_evlist__propagate_maps(evlist);
11931269 }
11941270
1271+void __perf_evlist__set_sample_bit(struct perf_evlist *evlist,
1272+ enum perf_event_sample_format bit)
1273+{
1274+ struct perf_evsel *evsel;
1275+
1276+ evlist__for_each(evlist, evsel)
1277+ __perf_evsel__set_sample_bit(evsel, bit);
1278+}
1279+
1280+void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist,
1281+ enum perf_event_sample_format bit)
1282+{
1283+ struct perf_evsel *evsel;
1284+
1285+ evlist__for_each(evlist, evsel)
1286+ __perf_evsel__reset_sample_bit(evsel, bit);
1287+}
1288+
11951289 int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel)
11961290 {
11971291 struct perf_evsel *evsel;
tools/perf/util/evlist.h+21−1
@@ -87,6 +87,17 @@ int perf_evlist__add_dummy(struct perf_evlist *evlist); · 86 unmodified lines
8787 int perf_evlist__add_newtp(struct perf_evlist *evlist,
8888 const char *sys, const char *name, void *handler);
8989
90+void __perf_evlist__set_sample_bit(struct perf_evlist *evlist,
91+ enum perf_event_sample_format bit);
92+void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist,
93+ enum perf_event_sample_format bit);
94+
95+#define perf_evlist__set_sample_bit(evlist, bit) \
96+ __perf_evlist__set_sample_bit(evlist, PERF_SAMPLE_##bit)
97+
98+#define perf_evlist__reset_sample_bit(evlist, bit) \
99+ __perf_evlist__reset_sample_bit(evlist, PERF_SAMPLE_##bit)
100+
90101 int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter);
91102 int perf_evlist__set_filter_pid(struct perf_evlist *evlist, pid_t pid);
92103 int perf_evlist__set_filter_pids(struct perf_evlist *evlist, size_t npids, pid_t *pids);
@@ -118,16 +129,23 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); · 25 unmodified lines
118129
119130 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx);
120131
132+union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist,
133+ int idx);
134+void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx);
135+
121136 void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
122137
123138 int perf_evlist__open(struct perf_evlist *evlist);
124139 void perf_evlist__close(struct perf_evlist *evlist);
125140
141+struct callchain_param;
142+
126143 void perf_evlist__set_id_pos(struct perf_evlist *evlist);
127144 bool perf_can_sample_identifier(void);
128145 bool perf_can_record_switch_events(void);
129146 bool perf_can_record_cpu_wide(void);
130−void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts);
147+void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
148+ struct callchain_param *callchain);
131149 int record_opts__config(struct record_opts *opts);
132150
133151 int perf_evlist__prepare_workload(struct perf_evlist *evlist,
@@ -144,6 +162,8 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, · 10 unmodified lines
144162 const char *str,
145163 int unset);
146164
165+unsigned long perf_event_mlock_kb_in_pages(void);
166+
147167 int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
148168 bool overwrite, unsigned int auxtrace_pages,
149169 bool auxtrace_overwrite);
tools/perf/util/evsel.c+38−101
@@ -226,7 +226,8 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) · 225 unmodified lines
226226 perf_evsel__init(evsel, attr, idx);
227227
228228 if (perf_evsel__is_bpf_output(evsel)) {
229− evsel->attr.sample_type |= PERF_SAMPLE_RAW;
229+ evsel->attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
230+ PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD),
230231 evsel->attr.sample_period = 1;
231232 }
232233
@@ -561,10 +562,9 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size) · 328 unmodified lines
561562 return ret;
562563 }
563564
564−static void
565−perf_evsel__config_callgraph(struct perf_evsel *evsel,
566− struct record_opts *opts,
567− struct callchain_param *param)
565+void perf_evsel__config_callchain(struct perf_evsel *evsel,
566+ struct record_opts *opts,
567+ struct callchain_param *param)
568568 {
569569 bool function = perf_evsel__is_function_event(evsel);
570570 struct perf_event_attr *attr = &evsel->attr;
@@ -704,7 +704,7 @@ static void apply_config_terms(struct perf_evsel *evsel, · 133 unmodified lines
704704
705705 /* set perf-event callgraph */
706706 if (param.enabled)
707− perf_evsel__config_callgraph(evsel, opts, &param);
707+ perf_evsel__config_callchain(evsel, opts, &param);
708708 }
709709 }
710710
@@ -736,7 +736,8 @@ static void apply_config_terms(struct perf_evsel *evsel, · 25 unmodified lines
736736 * enable/disable events specifically, as there's no
737737 * initial traced exec call.
738738 */
739−void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
739+void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
740+ struct callchain_param *callchain)
740741 {
741742 struct perf_evsel *leader = evsel->leader;
742743 struct perf_event_attr *attr = &evsel->attr;
@@ -811,8 +812,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) · 68 unmodified lines
811812 if (perf_evsel__is_function_event(evsel))
812813 evsel->attr.exclude_callchain_user = 1;
813814
814− if (callchain_param.enabled && !evsel->no_aux_samples)
815− perf_evsel__config_callgraph(evsel, opts, &callchain_param);
815+ if (callchain && callchain->enabled && !evsel->no_aux_samples)
816+ perf_evsel__config_callchain(evsel, opts, callchain);
816817
817818 if (opts->sample_intr_regs) {
818819 attr->sample_regs_intr = opts->sample_intr_regs;
@@ -1230,6 +1231,21 @@ static void __p_sample_type(char *buf, size_t size, u64 value) · 411 unmodified lines
12301231 __p_bits(buf, size, value, bits);
12311232 }
12321233
1234+static void __p_branch_sample_type(char *buf, size_t size, u64 value)
1235+{
1236+#define bit_name(n) { PERF_SAMPLE_BRANCH_##n, #n }
1237+ struct bit_names bits[] = {
1238+ bit_name(USER), bit_name(KERNEL), bit_name(HV), bit_name(ANY),
1239+ bit_name(ANY_CALL), bit_name(ANY_RETURN), bit_name(IND_CALL),
1240+ bit_name(ABORT_TX), bit_name(IN_TX), bit_name(NO_TX),
1241+ bit_name(COND), bit_name(CALL_STACK), bit_name(IND_JUMP),
1242+ bit_name(CALL), bit_name(NO_FLAGS), bit_name(NO_CYCLES),
1243+ { .name = NULL, }
1244+ };
1245+#undef bit_name
1246+ __p_bits(buf, size, value, bits);
1247+}
1248+
12331249 static void __p_read_format(char *buf, size_t size, u64 value)
12341250 {
12351251 #define bit_name(n) { PERF_FORMAT_##n, #n }
@@ -1248,6 +1264,7 @@ static void __p_read_format(char *buf, size_t size, u64 value) · 12 unmodified lines
12481264 #define p_unsigned(val) snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val))
12491265 #define p_signed(val) snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val))
12501266 #define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val)
1267+#define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val)
12511268 #define p_read_format(val) __p_read_format(buf, BUF_SIZE, val)
12521269
12531270 #define PRINT_ATTRn(_n, _f, _p) \
@@ -1299,12 +1316,13 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, · 45 unmodified lines
12991316 PRINT_ATTRf(comm_exec, p_unsigned);
13001317 PRINT_ATTRf(use_clockid, p_unsigned);
13011318 PRINT_ATTRf(context_switch, p_unsigned);
1319+ PRINT_ATTRf(write_backward, p_unsigned);
13021320
13031321 PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned);
13041322 PRINT_ATTRf(bp_type, p_unsigned);
13051323 PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex);
13061324 PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex);
1307− PRINT_ATTRf(branch_sample_type, p_unsigned);
1325+ PRINT_ATTRf(branch_sample_type, p_branch_sample_type);
13081326 PRINT_ATTRf(sample_regs_user, p_hex);
13091327 PRINT_ATTRf(sample_stack_user, p_unsigned);
13101328 PRINT_ATTRf(clockid, p_signed);
@@ -2253,95 +2271,6 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, · 942 unmodified lines
22532271 return 0;
22542272 }
22552273
2256−static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
2257−{
2258− va_list args;
2259− int ret = 0;
2260−
2261− if (!*first) {
2262− ret += fprintf(fp, ",");
2263− } else {
2264− ret += fprintf(fp, ":");
2265− *first = false;
2266− }
2267−
2268− va_start(args, fmt);
2269− ret += vfprintf(fp, fmt, args);
2270− va_end(args);
2271− return ret;
2272−}
2273−
2274−static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
2275−{
2276− return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
2277−}
2278−
2279−int perf_evsel__fprintf(struct perf_evsel *evsel,
2280− struct perf_attr_details *details, FILE *fp)
2281−{
2282− bool first = true;
2283− int printed = 0;
2284−
2285− if (details->event_group) {
2286− struct perf_evsel *pos;
2287−
2288− if (!perf_evsel__is_group_leader(evsel))
2289− return 0;
2290−
2291− if (evsel->nr_members > 1)
2292− printed += fprintf(fp, "%s{", evsel->group_name ?: "");
2293−
2294− printed += fprintf(fp, "%s", perf_evsel__name(evsel));
2295− for_each_group_member(pos, evsel)
2296− printed += fprintf(fp, ",%s", perf_evsel__name(pos));
2297−
2298− if (evsel->nr_members > 1)
2299− printed += fprintf(fp, "}");
2300− goto out;
2301− }
2302−
2303− printed += fprintf(fp, "%s", perf_evsel__name(evsel));
2304−
2305− if (details->verbose) {
2306− printed += perf_event_attr__fprintf(fp, &evsel->attr,
2307− __print_attr__fprintf, &first);
2308− } else if (details->freq) {
2309− const char *term = "sample_freq";
2310−
2311− if (!evsel->attr.freq)
2312− term = "sample_period";
2313−
2314− printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
2315− term, (u64)evsel->attr.sample_freq);
2316− }
2317−
2318− if (details->trace_fields) {
2319− struct format_field *field;
2320−
2321− if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2322− printed += comma_fprintf(fp, &first, " (not a tracepoint)");
2323− goto out;
2324− }
2325−
2326− field = evsel->tp_format->format.fields;
2327− if (field == NULL) {
2328− printed += comma_fprintf(fp, &first, " (no trace field)");
2329− goto out;
2330− }
2331−
2332− printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
2333−
2334− field = field->next;
2335− while (field) {
2336− printed += comma_fprintf(fp, &first, "%s", field->name);
2337− field = field->next;
2338− }
2339− }
2340−out:
2341− fputc('\n', fp);
2342− return ++printed;
2343−}
2344−
23452274 bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
23462275 char *msg, size_t msgsize)
23472276 {
@@ -2416,10 +2345,18 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, · 68 unmodified lines
24162345 "Probably the maximum number of open file descriptors has been reached.\n"
24172346 "Hint: Try again after reducing the number of events.\n"
24182347 "Hint: Try increasing the limit with 'ulimit -n <limit>'");
2348+ case ENOMEM:
2349+ if ((evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0 &&
2350+ access("/proc/sys/kernel/perf_event_max_stack", F_OK) == 0)
2351+ return scnprintf(msg, size,
2352+ "Not enough memory to setup event with callchain.\n"
2353+ "Hint: Try tweaking /proc/sys/kernel/perf_event_max_stack\n"
2354+ "Hint: Current value: %d", sysctl_perf_event_max_stack);
2355+ break;
24192356 case ENODEV:
24202357 if (target->cpu_list)
24212358 return scnprintf(msg, size, "%s",
2422− "No such device - did you specify an out-of-range profile CPU?\n");
2359+ "No such device - did you specify an out-of-range profile CPU?");
24232360 break;
24242361 case EOPNOTSUPP:
24252362 if (evsel->attr.precise_ip)
@@ -2451,7 +2388,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, · 25 unmodified lines
24512388 return scnprintf(msg, size,
24522389 "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n"
24532390 "/bin/dmesg may provide additional information.\n"
2454− "No CONFIG_PERF_EVENTS=y kernel support configured?\n",
2391+ "No CONFIG_PERF_EVENTS=y kernel support configured?",
24552392 err, strerror_r(err, sbuf, sizeof(sbuf)),
24562393 perf_evsel__name(evsel));
24572394 }
tools/perf/util/evsel.h+26−2
@@ -178,8 +178,14 @@ void perf_evsel__init(struct perf_evsel *evsel, · 177 unmodified lines
178178 void perf_evsel__exit(struct perf_evsel *evsel);
179179 void perf_evsel__delete(struct perf_evsel *evsel);
180180
181+struct callchain_param;
182+
181183 void perf_evsel__config(struct perf_evsel *evsel,
182− struct record_opts *opts);
184+ struct record_opts *opts,
185+ struct callchain_param *callchain);
186+void perf_evsel__config_callchain(struct perf_evsel *evsel,
187+ struct record_opts *opts,
188+ struct callchain_param *callchain);
183189
184190 int __perf_evsel__sample_size(u64 sample_type);
185191 void perf_evsel__calc_id_pos(struct perf_evsel *evsel);
@@ -381,6 +387,24 @@ struct perf_attr_details { · 195 unmodified lines
381387 int perf_evsel__fprintf(struct perf_evsel *evsel,
382388 struct perf_attr_details *details, FILE *fp);
383389
390+#define EVSEL__PRINT_IP (1<<0)
391+#define EVSEL__PRINT_SYM (1<<1)
392+#define EVSEL__PRINT_DSO (1<<2)
393+#define EVSEL__PRINT_SYMOFFSET (1<<3)
394+#define EVSEL__PRINT_ONELINE (1<<4)
395+#define EVSEL__PRINT_SRCLINE (1<<5)
396+#define EVSEL__PRINT_UNKNOWN_AS_ADDR (1<<6)
397+
398+struct callchain_cursor;
399+
400+int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
401+ unsigned int print_opts,
402+ struct callchain_cursor *cursor, FILE *fp);
403+
404+int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
405+ int left_alignment, unsigned int print_opts,
406+ struct callchain_cursor *cursor, FILE *fp);
407+
384408 bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
385409 char *msg, size_t msgsize);
386410 int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
@@ -396,7 +420,7 @@ for ((_evsel) = list_entry((_leader)->node.next, struct perf_evsel, node); \ · 9 unmodified lines
396420 (_evsel) && (_evsel)->leader == (_leader); \
397421 (_evsel) = list_entry((_evsel)->node.next, struct perf_evsel, node))
398422
399−static inline bool has_branch_callstack(struct perf_evsel *evsel)
423+static inline bool perf_evsel__has_branch_callstack(const struct perf_evsel *evsel)
400424 {
401425 return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK;
402426 }
tools/perf/util/evsel_fprintf.c+212−0
@@ -0,0 +1,212 @@
1+#include <stdio.h>
2+#include <stdbool.h>
3+#include <traceevent/event-parse.h>
4+#include "evsel.h"
5+#include "callchain.h"
6+#include "map.h"
7+#include "symbol.h"
8+
9+static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
10+{
11+ va_list args;
12+ int ret = 0;
13+
14+ if (!*first) {
15+ ret += fprintf(fp, ",");
16+ } else {
17+ ret += fprintf(fp, ":");
18+ *first = false;
19+ }
20+
21+ va_start(args, fmt);
22+ ret += vfprintf(fp, fmt, args);
23+ va_end(args);
24+ return ret;
25+}
26+
27+static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
28+{
29+ return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
30+}
31+
32+int perf_evsel__fprintf(struct perf_evsel *evsel,
33+ struct perf_attr_details *details, FILE *fp)
34+{
35+ bool first = true;
36+ int printed = 0;
37+
38+ if (details->event_group) {
39+ struct perf_evsel *pos;
40+
41+ if (!perf_evsel__is_group_leader(evsel))
42+ return 0;
43+
44+ if (evsel->nr_members > 1)
45+ printed += fprintf(fp, "%s{", evsel->group_name ?: "");
46+
47+ printed += fprintf(fp, "%s", perf_evsel__name(evsel));
48+ for_each_group_member(pos, evsel)
49+ printed += fprintf(fp, ",%s", perf_evsel__name(pos));
50+
51+ if (evsel->nr_members > 1)
52+ printed += fprintf(fp, "}");
53+ goto out;
54+ }
55+
56+ printed += fprintf(fp, "%s", perf_evsel__name(evsel));
57+
58+ if (details->verbose) {
59+ printed += perf_event_attr__fprintf(fp, &evsel->attr,
60+ __print_attr__fprintf, &first);
61+ } else if (details->freq) {
62+ const char *term = "sample_freq";
63+
64+ if (!evsel->attr.freq)
65+ term = "sample_period";
66+
67+ printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
68+ term, (u64)evsel->attr.sample_freq);
69+ }
70+
71+ if (details->trace_fields) {
72+ struct format_field *field;
73+
74+ if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
75+ printed += comma_fprintf(fp, &first, " (not a tracepoint)");
76+ goto out;
77+ }
78+
79+ field = evsel->tp_format->format.fields;
80+ if (field == NULL) {
81+ printed += comma_fprintf(fp, &first, " (no trace field)");
82+ goto out;
83+ }
84+
85+ printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
86+
87+ field = field->next;
88+ while (field) {
89+ printed += comma_fprintf(fp, &first, "%s", field->name);
90+ field = field->next;
91+ }
92+ }
93+out:
94+ fputc('\n', fp);
95+ return ++printed;
96+}
97+
98+int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
99+ unsigned int print_opts, struct callchain_cursor *cursor,
100+ FILE *fp)
101+{
102+ int printed = 0;
103+ struct callchain_cursor_node *node;
104+ int print_ip = print_opts & EVSEL__PRINT_IP;
105+ int print_sym = print_opts & EVSEL__PRINT_SYM;
106+ int print_dso = print_opts & EVSEL__PRINT_DSO;
107+ int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
108+ int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
109+ int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
110+ int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
111+ char s = print_oneline ? ' ' : '\t';
112+
113+ if (sample->callchain) {
114+ struct addr_location node_al;
115+
116+ callchain_cursor_commit(cursor);
117+
118+ while (1) {
119+ u64 addr = 0;
120+
121+ node = callchain_cursor_current(cursor);
122+ if (!node)
123+ break;
124+
125+ if (node->sym && node->sym->ignore)
126+ goto next;
127+
128+ printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
129+
130+ if (print_ip)
131+ printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
132+
133+ if (node->map)
134+ addr = node->map->map_ip(node->map, node->ip);
135+
136+ if (print_sym) {
137+ printed += fprintf(fp, " ");
138+ node_al.addr = addr;
139+ node_al.map = node->map;
140+
141+ if (print_symoffset) {
142+ printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
143+ print_unknown_as_addr, fp);
144+ } else {
145+ printed += __symbol__fprintf_symname(node->sym, &node_al,
146+ print_unknown_as_addr, fp);
147+ }
148+ }
149+
150+ if (print_dso) {
151+ printed += fprintf(fp, " (");
152+ printed += map__fprintf_dsoname(node->map, fp);
153+ printed += fprintf(fp, ")");
154+ }
155+
156+ if (print_srcline)
157+ printed += map__fprintf_srcline(node->map, addr, "\n ", fp);
158+
159+ if (!print_oneline)
160+ printed += fprintf(fp, "\n");
161+next:
162+ callchain_cursor_advance(cursor);
163+ }
164+ }
165+
166+ return printed;
167+}
168+
169+int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
170+ int left_alignment, unsigned int print_opts,
171+ struct callchain_cursor *cursor, FILE *fp)
172+{
173+ int printed = 0;
174+ int print_ip = print_opts & EVSEL__PRINT_IP;
175+ int print_sym = print_opts & EVSEL__PRINT_SYM;
176+ int print_dso = print_opts & EVSEL__PRINT_DSO;
177+ int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
178+ int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
179+ int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
180+
181+ if (cursor != NULL) {
182+ printed += sample__fprintf_callchain(sample, left_alignment,
183+ print_opts, cursor, fp);
184+ } else if (!(al->sym && al->sym->ignore)) {
185+ printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
186+
187+ if (print_ip)
188+ printed += fprintf(fp, "%16" PRIx64, sample->ip);
189+
190+ if (print_sym) {
191+ printed += fprintf(fp, " ");
192+ if (print_symoffset) {
193+ printed += __symbol__fprintf_symname_offs(al->sym, al,
194+ print_unknown_as_addr, fp);
195+ } else {
196+ printed += __symbol__fprintf_symname(al->sym, al,
197+ print_unknown_as_addr, fp);
198+ }
199+ }
200+
201+ if (print_dso) {
202+ printed += fprintf(fp, " (");
203+ printed += map__fprintf_dsoname(al->map, fp);
204+ printed += fprintf(fp, ")");
205+ }
206+
207+ if (print_srcline)
208+ printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
209+ }
210+
211+ return printed;
212+}
tools/perf/util/header.c+21−12
@@ -1474,7 +1474,7 @@ static int __event_process_build_id(struct build_id_event *bev, · 1473 unmodified lines
14741474
14751475 dso = machine__findnew_dso(machine, filename);
14761476 if (dso != NULL) {
1477− char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1477+ char sbuild_id[SBUILD_ID_SIZE];
14781478
14791479 dso__set_build_id(dso, &bev->build_id);
14801480
@@ -1819,7 +1819,8 @@ static int process_cpu_topology(struct perf_file_section *section, · 338 unmodified lines
18191819
18201820 ph->env.nr_sibling_cores = nr;
18211821 size += sizeof(u32);
1822− strbuf_init(&sb, 128);
1822+ if (strbuf_init(&sb, 128) < 0)
1823+ goto free_cpu;
18231824
18241825 for (i = 0; i < nr; i++) {
18251826 str = do_read_string(fd, ph);
@@ -1827,7 +1828,8 @@ static int process_cpu_topology(struct perf_file_section *section, · 1 unmodified line
18271828 goto error;
18281829
18291830 /* include a NULL character at the end */
1830− strbuf_add(&sb, str, strlen(str) + 1);
1831+ if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
1832+ goto error;
18311833 size += string_size(str);
18321834 free(str);
18331835 }
@@ -1849,7 +1851,8 @@ static int process_cpu_topology(struct perf_file_section *section, · 15 unmodified lines
18491851 goto error;
18501852
18511853 /* include a NULL character at the end */
1852− strbuf_add(&sb, str, strlen(str) + 1);
1854+ if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
1855+ goto error;
18531856 size += string_size(str);
18541857 free(str);
18551858 }
@@ -1912,13 +1915,14 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse · 56 unmodified lines
19121915 /* nr nodes */
19131916 ret = readn(fd, &nr, sizeof(nr));
19141917 if (ret != sizeof(nr))
1915− goto error;
1918+ return -1;
19161919
19171920 if (ph->needs_swap)
19181921 nr = bswap_32(nr);
19191922
19201923 ph->env.nr_numa_nodes = nr;
1921− strbuf_init(&sb, 256);
1924+ if (strbuf_init(&sb, 256) < 0)
1925+ return -1;
19221926
19231927 for (i = 0; i < nr; i++) {
19241928 /* node number */
@@ -1940,15 +1944,17 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse · 15 unmodified lines
19401944 mem_free = bswap_64(mem_free);
19411945 }
19421946
1943− strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
1944− node, mem_total, mem_free);
1947+ if (strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
1948+ node, mem_total, mem_free) < 0)
1949+ goto error;
19451950
19461951 str = do_read_string(fd, ph);
19471952 if (!str)
19481953 goto error;
19491954
19501955 /* include a NULL character at the end */
1951− strbuf_add(&sb, str, strlen(str) + 1);
1956+ if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
1957+ goto error;
19521958 free(str);
19531959 }
19541960 ph->env.numa_nodes = strbuf_detach(&sb, NULL);
@@ -1982,7 +1988,8 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused · 27 unmodified lines
19821988 }
19831989
19841990 ph->env.nr_pmu_mappings = pmu_num;
1985− strbuf_init(&sb, 128);
1991+ if (strbuf_init(&sb, 128) < 0)
1992+ return -1;
19861993
19871994 while (pmu_num) {
19881995 if (readn(fd, &type, sizeof(type)) != sizeof(type))
@@ -1994,9 +2001,11 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused · 5 unmodified lines
19942001 if (!name)
19952002 goto error;
19962003
1997− strbuf_addf(&sb, "%u:%s", type, name);
2004+ if (strbuf_addf(&sb, "%u:%s", type, name) < 0)
2005+ goto error;
19982006 /* include a NULL character at the end */
1999− strbuf_add(&sb, "", 1);
2007+ if (strbuf_add(&sb, "", 1) < 0)
2008+ goto error;
20002009
20012010 if (!strcmp(name, "msr"))
20022011 ph->env.msr_pmu_type = type;
tools/perf/util/help-unknown-cmd.c+22−8
@@ -27,16 +27,27 @@ static int levenshtein_compare(const void *p1, const void *p2) · 26 unmodified lines
2727 return l1 != l2 ? l1 - l2 : strcmp(s1, s2);
2828 }
2929
30−static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
30+static int add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
3131 {
32− unsigned int i;
33−
34− ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);
35−
32+ unsigned int i, nr = cmds->cnt + old->cnt;
33+ void *tmp;
34+
35+ if (nr > cmds->alloc) {
36+ /* Choose bigger one to alloc */
37+ if (alloc_nr(cmds->alloc) < nr)
38+ cmds->alloc = nr;
39+ else
40+ cmds->alloc = alloc_nr(cmds->alloc);
41+ tmp = realloc(cmds->names, cmds->alloc * sizeof(*cmds->names));
42+ if (!tmp)
43+ return -1;
44+ cmds->names = tmp;
45+ }
3646 for (i = 0; i < old->cnt; i++)
3747 cmds->names[cmds->cnt++] = old->names[i];
3848 zfree(&old->names);
3949 old->cnt = 0;
50+ return 0;
4051 }
4152
4253 const char *help_unknown_cmd(const char *cmd)
@@ -52,8 +63,11 @@ const char *help_unknown_cmd(const char *cmd) · 9 unmodified lines
5263
5364 load_command_list("perf-", &main_cmds, &other_cmds);
5465
55− add_cmd_list(&main_cmds, &aliases);
56− add_cmd_list(&main_cmds, &other_cmds);
66+ if (add_cmd_list(&main_cmds, &aliases) < 0 ||
67+ add_cmd_list(&main_cmds, &other_cmds) < 0) {
68+ fprintf(stderr, "ERROR: Failed to allocate command list for unknown command.\n");
69+ goto end;
70+ }
5771 qsort(main_cmds.names, main_cmds.cnt,
5872 sizeof(main_cmds.names), cmdname_compare);
5973 uniq(&main_cmds);
@@ -99,6 +113,6 @@ const char *help_unknown_cmd(const char *cmd) · 39 unmodified lines
99113 for (i = 0; i < n; i++)
100114 fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
101115 }
102−
116+end:
103117 exit(1);
104118 }
tools/perf/util/hist.c+13−10
@@ -295,7 +295,7 @@ static void hists__delete_entry(struct hists *hists, struct hist_entry *he) · 294 unmodified lines
295295 root_in = &he->parent_he->hroot_in;
296296 root_out = &he->parent_he->hroot_out;
297297 } else {
298− if (sort__need_collapse)
298+ if (hists__has(hists, need_collapse))
299299 root_in = &hists->entries_collapsed;
300300 else
301301 root_in = hists->entries_in;
@@ -953,7 +953,7 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, · 651 unmodified lines
953953 {
954954 int err, err2;
955955
956− err = sample__resolve_callchain(iter->sample, &iter->parent,
956+ err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
957957 iter->evsel, al, max_stack_depth);
958958 if (err)
959959 return err;
@@ -1295,8 +1295,9 @@ static int hists__hierarchy_insert_entry(struct hists *hists, · 335 unmodified lines
12951295 return ret;
12961296 }
12971297
1298−int hists__collapse_insert_entry(struct hists *hists, struct rb_root *root,
1299− struct hist_entry *he)
1298+static int hists__collapse_insert_entry(struct hists *hists,
1299+ struct rb_root *root,
1300+ struct hist_entry *he)
13001301 {
13011302 struct rb_node **p = &root->rb_node;
13021303 struct rb_node *parent = NULL;
@@ -1372,7 +1373,7 @@ int hists__collapse_resort(struct hists *hists, struct ui_progress *prog) · 69 unmodified lines
13721373 struct hist_entry *n;
13731374 int ret;
13741375
1375− if (!sort__need_collapse)
1376+ if (!hists__has(hists, need_collapse))
13761377 return 0;
13771378
13781379 hists->nr_entries = 0;
@@ -1631,7 +1632,7 @@ static void output_resort(struct hists *hists, struct ui_progress *prog, · 252 unmodified lines
16311632 return;
16321633 }
16331634
1634− if (sort__need_collapse)
1635+ if (hists__has(hists, need_collapse))
16351636 root = &hists->entries_collapsed;
16361637 else
16371638 root = hists->entries_in;
@@ -2035,7 +2036,7 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists, · 397 unmodified lines
20352036 struct hist_entry *he;
20362037 int64_t cmp;
20372038
2038− if (sort__need_collapse)
2039+ if (hists__has(hists, need_collapse))
20392040 root = &hists->entries_collapsed;
20402041 else
20412042 root = hists->entries_in;
@@ -2061,6 +2062,8 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists, · 19 unmodified lines
20612062 if (he) {
20622063 memset(&he->stat, 0, sizeof(he->stat));
20632064 he->hists = hists;
2065+ if (symbol_conf.cumulate_callchain)
2066+ memset(he->stat_acc, 0, sizeof(he->stat));
20642067 rb_link_node(&he->rb_node_in, parent, p);
20652068 rb_insert_color(&he->rb_node_in, root);
20662069 hists__inc_stats(hists, he);
@@ -2075,7 +2078,7 @@ static struct hist_entry *hists__find_entry(struct hists *hists, · 8 unmodified lines
20752078 {
20762079 struct rb_node *n;
20772080
2078− if (sort__need_collapse)
2081+ if (hists__has(hists, need_collapse))
20792082 n = hists->entries_collapsed.rb_node;
20802083 else
20812084 n = hists->entries_in->rb_node;
@@ -2104,7 +2107,7 @@ void hists__match(struct hists *leader, struct hists *other) · 22 unmodified lines
21042107 struct rb_node *nd;
21052108 struct hist_entry *pos, *pair;
21062109
2107− if (sort__need_collapse)
2110+ if (hists__has(leader, need_collapse))
21082111 root = &leader->entries_collapsed;
21092112 else
21102113 root = leader->entries_in;
@@ -2129,7 +2132,7 @@ int hists__link(struct hists *leader, struct hists *other) · 18 unmodified lines
21292132 struct rb_node *nd;
21302133 struct hist_entry *pos, *pair;
21312134
2132− if (sort__need_collapse)
2135+ if (hists__has(other, need_collapse))
21332136 root = &other->entries_collapsed;
21342137 else
21352138 root = other->entries_in;
tools/perf/util/hist.h+10−2
@@ -82,6 +82,8 @@ struct hists { · 81 unmodified lines
8282 int nr_hpp_node;
8383 };
8484
85+#define hists__has(__h, __f) (__h)->hpp_list->__f
86+
8587 struct hist_entry_iter;
8688
8789 struct hist_iter_ops {
@@ -199,8 +201,6 @@ int hists__init(void); · 111 unmodified lines
199201 int __hists__init(struct hists *hists, struct perf_hpp_list *hpp_list);
200202
201203 struct rb_root *hists__get_rotate_entries_in(struct hists *hists);
202−int hists__collapse_insert_entry(struct hists *hists,
203− struct rb_root *root, struct hist_entry *he);
204204
205205 struct perf_hpp {
206206 char *buf;
@@ -240,6 +240,14 @@ struct perf_hpp_fmt { · 33 unmodified lines
240240 struct perf_hpp_list {
241241 struct list_head fields;
242242 struct list_head sorts;
243+
244+ int need_collapse;
245+ int parent;
246+ int sym;
247+ int dso;
248+ int socket;
249+ int thread;
250+ int comm;
243251 };
244252
245253 extern struct perf_hpp_list perf_hpp_list;
tools/perf/util/intel-bts.c+5−0
@@ -66,6 +66,7 @@ struct intel_bts { · 65 unmodified lines
6666 u64 branches_id;
6767 size_t branches_event_size;
6868 bool synth_needs_swap;
69+ unsigned long num_events;
6970 };
7071
7172 struct intel_bts_queue {
@@ -275,6 +276,10 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq, · 203 unmodified lines
275276 union perf_event event;
276277 struct perf_sample sample = { .ip = 0, };
277278
279+ if (bts->synth_opts.initial_skip &&
280+ bts->num_events++ <= bts->synth_opts.initial_skip)
281+ return 0;
282+
278283 event.sample.header.type = PERF_RECORD_SAMPLE;
279284 event.sample.header.misc = PERF_RECORD_MISC_USER;
280285 event.sample.header.size = sizeof(struct perf_event_header);
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c+1−1
@@ -356,7 +356,7 @@ static const char *intel_pt_err_msgs[] = { · 355 unmodified lines
356356
357357 int intel_pt__strerror(int code, char *buf, size_t buflen)
358358 {
359− if (code < 1 || code > INTEL_PT_ERR_MAX)
359+ if (code < 1 || code >= INTEL_PT_ERR_MAX)
360360 code = INTEL_PT_ERR_UNK;
361361 strlcpy(buf, intel_pt_err_msgs[code], buflen);
362362 return 0;
tools/perf/util/intel-pt.c+20−2
@@ -100,6 +100,8 @@ struct intel_pt { · 99 unmodified lines
100100 u64 cyc_bit;
101101 u64 noretcomp_bit;
102102 unsigned max_non_turbo_ratio;
103+
104+ unsigned long num_events;
103105 };
104106
105107 enum switch_state {
@@ -972,6 +974,10 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq) · 866 unmodified lines
972974 if (pt->branches_filter && !(pt->branches_filter & ptq->flags))
973975 return 0;
974976
977+ if (pt->synth_opts.initial_skip &&
978+ pt->num_events++ < pt->synth_opts.initial_skip)
979+ return 0;
980+
975981 event->sample.header.type = PERF_RECORD_SAMPLE;
976982 event->sample.header.misc = PERF_RECORD_MISC_USER;
977983 event->sample.header.size = sizeof(struct perf_event_header);
@@ -1029,6 +1035,10 @@ static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq) · 51 unmodified lines
10291035 union perf_event *event = ptq->event_buf;
10301036 struct perf_sample sample = { .ip = 0, };
10311037
1038+ if (pt->synth_opts.initial_skip &&
1039+ pt->num_events++ < pt->synth_opts.initial_skip)
1040+ return 0;
1041+
10321042 event->sample.header.type = PERF_RECORD_SAMPLE;
10331043 event->sample.header.misc = PERF_RECORD_MISC_USER;
10341044 event->sample.header.size = sizeof(struct perf_event_header);
@@ -1087,6 +1097,10 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq) · 52 unmodified lines
10871097 union perf_event *event = ptq->event_buf;
10881098 struct perf_sample sample = { .ip = 0, };
10891099
1100+ if (pt->synth_opts.initial_skip &&
1101+ pt->num_events++ < pt->synth_opts.initial_skip)
1102+ return 0;
1103+
10901104 event->sample.header.type = PERF_RECORD_SAMPLE;
10911105 event->sample.header.misc = PERF_RECORD_MISC_USER;
10921106 event->sample.header.size = sizeof(struct perf_event_header);
@@ -1199,14 +1213,18 @@ static int intel_pt_sample(struct intel_pt_queue *ptq) · 106 unmodified lines
11991213 ptq->have_sample = false;
12001214
12011215 if (pt->sample_instructions &&
1202− (state->type & INTEL_PT_INSTRUCTION)) {
1216+ (state->type & INTEL_PT_INSTRUCTION) &&
1217+ (!pt->synth_opts.initial_skip ||
1218+ pt->num_events++ >= pt->synth_opts.initial_skip)) {
12031219 err = intel_pt_synth_instruction_sample(ptq);
12041220 if (err)
12051221 return err;
12061222 }
12071223
12081224 if (pt->sample_transactions &&
1209− (state->type & INTEL_PT_TRANSACTION)) {
1225+ (state->type & INTEL_PT_TRANSACTION) &&
1226+ (!pt->synth_opts.initial_skip ||
1227+ pt->num_events++ >= pt->synth_opts.initial_skip)) {
12101228 err = intel_pt_synth_transaction_sample(ptq);
12111229 if (err)
12121230 return err;
tools/perf/util/jitdump.c+34−7
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include "strlist.h"
1818 #include <elf.h>
1919
20+#include "tsc.h"
2021 #include "session.h"
2122 #include "jit.h"
2223 #include "jitdump.h"
@@ -33,6 +34,7 @@ struct jit_buf_desc { · 10 unmodified lines
3334 size_t bufsize;
3435 FILE *in;
3536 bool needs_bswap; /* handles cross-endianess */
37+ bool use_arch_timestamp;
3638 void *debug_data;
3739 size_t nr_debug_entries;
3840 uint32_t code_load_count;
@@ -158,13 +160,16 @@ jit_open(struct jit_buf_desc *jd, const char *name) · 119 unmodified lines
158160 header.flags = bswap_64(header.flags);
159161 }
160162
163+ jd->use_arch_timestamp = header.flags & JITDUMP_FLAGS_ARCH_TIMESTAMP;
164+
161165 if (verbose > 2)
162− pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\n",
166+ pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\nuse_arch_timestamp=%d\n",
163167 header.version,
164168 header.total_size,
165169 (unsigned long long)header.timestamp,
166170 header.pid,
167− header.elf_mach);
171+ header.elf_mach,
172+ jd->use_arch_timestamp);
168173
169174 if (header.flags & JITDUMP_FLAGS_RESERVED) {
170175 pr_err("jitdump file contains invalid or unsupported flags 0x%llx\n",
@@ -172,10 +177,15 @@ jit_open(struct jit_buf_desc *jd, const char *name) · 1 unmodified line
172177 goto error;
173178 }
174179
180+ if (jd->use_arch_timestamp && !jd->session->time_conv.time_mult) {
181+ pr_err("jitdump file uses arch timestamps but there is no timestamp conversion\n");
182+ goto error;
183+ }
184+
175185 /*
176186 * validate event is using the correct clockid
177187 */
178− if (jit_validate_events(jd->session)) {
188+ if (!jd->use_arch_timestamp && jit_validate_events(jd->session)) {
179189 pr_err("error, jitted code must be sampled with perf record -k 1\n");
180190 goto error;
181191 }
@@ -329,6 +339,23 @@ jit_inject_event(struct jit_buf_desc *jd, union perf_event *event) · 147 unmodified lines
329339 return 0;
330340 }
331341
342+static uint64_t convert_timestamp(struct jit_buf_desc *jd, uint64_t timestamp)
343+{
344+ struct perf_tsc_conversion tc;
345+
346+ if (!jd->use_arch_timestamp)
347+ return timestamp;
348+
349+ tc.time_shift = jd->session->time_conv.time_shift;
350+ tc.time_mult = jd->session->time_conv.time_mult;
351+ tc.time_zero = jd->session->time_conv.time_zero;
352+
353+ if (!tc.time_mult)
354+ return 0;
355+
356+ return tsc_to_perf_time(timestamp, &tc);
357+}
358+
332359 static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
333360 {
334361 struct perf_sample sample;
@@ -385,7 +412,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) · 50 unmodified lines
385412 return -1;
386413 }
387414 if (stat(filename, &st))
388− memset(&st, 0, sizeof(stat));
415+ memset(&st, 0, sizeof(st));
389416
390417 event->mmap2.header.type = PERF_RECORD_MMAP2;
391418 event->mmap2.header.misc = PERF_RECORD_MISC_USER;
@@ -410,7 +437,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) · 18 unmodified lines
410437 id->tid = tid;
411438 }
412439 if (jd->sample_type & PERF_SAMPLE_TIME)
413− id->time = jr->load.p.timestamp;
440+ id->time = convert_timestamp(jd, jr->load.p.timestamp);
414441
415442 /*
416443 * create pseudo sample to induce dso hit increment
@@ -473,7 +500,7 @@ static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr) · 56 unmodified lines
473500 size++; /* for \0 */
474501
475502 if (stat(filename, &st))
476− memset(&st, 0, sizeof(stat));
503+ memset(&st, 0, sizeof(st));
477504
478505 size = PERF_ALIGN(size, sizeof(u64));
479506
@@ -499,7 +526,7 @@ static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr) · 19 unmodified lines
499526 id->tid = tid;
500527 }
501528 if (jd->sample_type & PERF_SAMPLE_TIME)
502− id->time = jr->load.p.timestamp;
529+ id->time = convert_timestamp(jd, jr->load.p.timestamp);
503530
504531 /*
505532 * create pseudo sample to induce dso hit increment
tools/perf/util/jitdump.h+3−0
@@ -23,9 +23,12 @@ · 22 unmodified lines
2323 #define JITHEADER_VERSION 1
2424
2525 enum jitdump_flags_bits {
26+ JITDUMP_FLAGS_ARCH_TIMESTAMP_BIT,
2627 JITDUMP_FLAGS_MAX_BIT,
2728 };
2829
30+#define JITDUMP_FLAGS_ARCH_TIMESTAMP (1ULL << JITDUMP_FLAGS_ARCH_TIMESTAMP_BIT)
31+
2932 #define JITDUMP_FLAGS_RESERVED (JITDUMP_FLAGS_MAX_BIT < 64 ? \
3033 (~((1ULL << JITDUMP_FLAGS_MAX_BIT) - 1)) : 0)
3134
tools/perf/util/machine.c+73−32
@@ -32,6 +32,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) · 31 unmodified lines
3232
3333 machine->threads = RB_ROOT;
3434 pthread_rwlock_init(&machine->threads_lock, NULL);
35+ machine->nr_threads = 0;
3536 INIT_LIST_HEAD(&machine->dead_threads);
3637 machine->last_match = NULL;
3738
@@ -430,6 +431,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, · 392 unmodified lines
430431 */
431432 thread__get(th);
432433 machine->last_match = th;
434+ ++machine->nr_threads;
433435 }
434436
435437 return th;
@@ -681,11 +683,13 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp) · 245 unmodified lines
681683
682684 size_t machine__fprintf(struct machine *machine, FILE *fp)
683685 {
684− size_t ret = 0;
686+ size_t ret;
685687 struct rb_node *nd;
686688
687689 pthread_rwlock_rdlock(&machine->threads_lock);
688690
691+ ret = fprintf(fp, "Threads: %u\n", machine->nr_threads);
692+
689693 for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
690694 struct thread *pos = rb_entry(nd, struct thread, rb_node);
691695
@@ -908,11 +912,11 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid) · 216 unmodified lines
908912 return machine__create_kernel_maps(machine);
909913 }
910914
911−int machine__load_kallsyms(struct machine *machine, const char *filename,
912− enum map_type type, symbol_filter_t filter)
915+int __machine__load_kallsyms(struct machine *machine, const char *filename,
916+ enum map_type type, bool no_kcore, symbol_filter_t filter)
913917 {
914918 struct map *map = machine__kernel_map(machine);
915− int ret = dso__load_kallsyms(map->dso, filename, map, filter);
919+ int ret = __dso__load_kallsyms(map->dso, filename, map, no_kcore, filter);
916920
917921 if (ret > 0) {
918922 dso__set_loaded(map->dso, type);
@@ -927,6 +931,12 @@ int machine__load_kallsyms(struct machine *machine, const char *filename, · 8 unmodified lines
927931 return ret;
928932 }
929933
934+int machine__load_kallsyms(struct machine *machine, const char *filename,
935+ enum map_type type, symbol_filter_t filter)
936+{
937+ return __machine__load_kallsyms(machine, filename, type, false, filter);
938+}
939+
930940 int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
931941 symbol_filter_t filter)
932942 {
@@ -1413,6 +1423,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th, · 480 unmodified lines
14131423 pthread_rwlock_wrlock(&machine->threads_lock);
14141424 rb_erase_init(&th->rb_node, &machine->threads);
14151425 RB_CLEAR_NODE(&th->rb_node);
1426+ --machine->nr_threads;
14161427 /*
14171428 * Move it first to the dead_threads list, then drop the reference,
14181429 * if this is the last reference, then the thread__delete destructor
@@ -1599,6 +1610,7 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, · 180 unmodified lines
15991610 }
16001611
16011612 static int add_callchain_ip(struct thread *thread,
1613+ struct callchain_cursor *cursor,
16021614 struct symbol **parent,
16031615 struct addr_location *root_al,
16041616 u8 *cpumode,
@@ -1630,7 +1642,7 @@ static int add_callchain_ip(struct thread *thread, · 25 unmodified lines
16301642 * It seems the callchain is corrupted.
16311643 * Discard all.
16321644 */
1633− callchain_cursor_reset(&callchain_cursor);
1645+ callchain_cursor_reset(cursor);
16341646 return 1;
16351647 }
16361648 return 0;
@@ -1640,7 +1652,7 @@ static int add_callchain_ip(struct thread *thread, · 3 unmodified lines
16401652 }
16411653
16421654 if (al.sym != NULL) {
1643− if (sort__has_parent && !*parent &&
1655+ if (perf_hpp_list.parent && !*parent &&
16441656 symbol__match_regex(al.sym, &parent_regex))
16451657 *parent = al.sym;
16461658 else if (have_ignore_callees && root_al &&
@@ -1648,13 +1660,13 @@ static int add_callchain_ip(struct thread *thread, · 1 unmodified line
16481660 /* Treat this symbol as the root,
16491661 forgetting its callees. */
16501662 *root_al = al;
1651− callchain_cursor_reset(&callchain_cursor);
1663+ callchain_cursor_reset(cursor);
16521664 }
16531665 }
16541666
16551667 if (symbol_conf.hide_unresolved && al.sym == NULL)
16561668 return 0;
1657− return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym);
1669+ return callchain_cursor_append(cursor, al.addr, al.map, al.sym);
16581670 }
16591671
16601672 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
@@ -1724,6 +1736,7 @@ static int remove_loops(struct branch_entry *l, int nr) · 63 unmodified lines
17241736 * negative error code on other errors.
17251737 */
17261738 static int resolve_lbr_callchain_sample(struct thread *thread,
1739+ struct callchain_cursor *cursor,
17271740 struct perf_sample *sample,
17281741 struct symbol **parent,
17291742 struct addr_location *root_al,
@@ -1756,7 +1769,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, · 26 unmodified lines
17561769 */
17571770 int mix_chain_nr = i + 1 + lbr_nr + 1;
17581771
1759− if (mix_chain_nr > PERF_MAX_STACK_DEPTH + PERF_MAX_BRANCH_DEPTH) {
1772+ if (mix_chain_nr > (int)sysctl_perf_event_max_stack + PERF_MAX_BRANCH_DEPTH) {
17601773 pr_warning("corrupted callchain. skipping...\n");
17611774 return 0;
17621775 }
@@ -1778,7 +1791,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, · 15 unmodified lines
17781791 ip = lbr_stack->entries[0].to;
17791792 }
17801793
1781− err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
1794+ err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
17821795 if (err)
17831796 return (err < 0) ? err : 0;
17841797 }
@@ -1789,6 +1802,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, · 4 unmodified lines
17891802 }
17901803
17911804 static int thread__resolve_callchain_sample(struct thread *thread,
1805+ struct callchain_cursor *cursor,
17921806 struct perf_evsel *evsel,
17931807 struct perf_sample *sample,
17941808 struct symbol **parent,
@@ -1803,10 +1817,8 @@ static int thread__resolve_callchain_sample(struct thread *thread, · 8 unmodified lines
18031817 int skip_idx = -1;
18041818 int first_call = 0;
18051819
1806− callchain_cursor_reset(&callchain_cursor);
1807−
1808− if (has_branch_callstack(evsel)) {
1809− err = resolve_lbr_callchain_sample(thread, sample, parent,
1820+ if (perf_evsel__has_branch_callstack(evsel)) {
1821+ err = resolve_lbr_callchain_sample(thread, cursor, sample, parent,
18101822 root_al, max_stack);
18111823 if (err)
18121824 return (err < 0) ? err : 0;
@@ -1816,7 +1828,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, · 3 unmodified lines
18161828 * Based on DWARF debug information, some architectures skip
18171829 * a callchain entry saved by the kernel.
18181830 */
1819− if (chain->nr < PERF_MAX_STACK_DEPTH)
1831+ if (chain->nr < sysctl_perf_event_max_stack)
18201832 skip_idx = arch_skip_callchain_idx(thread, chain);
18211833
18221834 /*
@@ -1863,10 +1875,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, · 40 unmodified lines
18631875 nr = remove_loops(be, nr);
18641876
18651877 for (i = 0; i < nr; i++) {
1866− err = add_callchain_ip(thread, parent, root_al,
1878+ err = add_callchain_ip(thread, cursor, parent, root_al,
18671879 NULL, be[i].to);
18681880 if (!err)
1869− err = add_callchain_ip(thread, parent, root_al,
1881+ err = add_callchain_ip(thread, cursor, parent, root_al,
18701882 NULL, be[i].from);
18711883 if (err == -EINVAL)
18721884 break;
@@ -1877,7 +1889,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, · 4 unmodified lines
18771889 }
18781890
18791891 check_calls:
1880− if (chain->nr > PERF_MAX_STACK_DEPTH && (int)chain->nr > max_stack) {
1892+ if (chain->nr > sysctl_perf_event_max_stack && (int)chain->nr > max_stack) {
18811893 pr_warning("corrupted callchain. skipping...\n");
18821894 return 0;
18831895 }
@@ -1896,7 +1908,7 @@ check_calls: · 12 unmodified lines
18961908 #endif
18971909 ip = chain->ips[j];
18981910
1899− err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
1911+ err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
19001912
19011913 if (err)
19021914 return (err < 0) ? err : 0;
@@ -1915,19 +1927,12 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) · 12 unmodified lines
19151927 entry->map, entry->sym);
19161928 }
19171929
1918−int thread__resolve_callchain(struct thread *thread,
1919− struct perf_evsel *evsel,
1920− struct perf_sample *sample,
1921− struct symbol **parent,
1922− struct addr_location *root_al,
1923− int max_stack)
1930+static int thread__resolve_callchain_unwind(struct thread *thread,
1931+ struct callchain_cursor *cursor,
1932+ struct perf_evsel *evsel,
1933+ struct perf_sample *sample,
1934+ int max_stack)
19241935 {
1925− int ret = thread__resolve_callchain_sample(thread, evsel,
1926− sample, parent,
1927− root_al, max_stack);
1928− if (ret)
1929− return ret;
1930−
19311936 /* Can we do dwarf post unwind? */
19321937 if (!((evsel->attr.sample_type & PERF_SAMPLE_REGS_USER) &&
19331938 (evsel->attr.sample_type & PERF_SAMPLE_STACK_USER)))
@@ -1938,9 +1943,45 @@ int thread__resolve_callchain(struct thread *thread, · 4 unmodified lines
19381943 (!sample->user_stack.size))
19391944 return 0;
19401945
1941− return unwind__get_entries(unwind_entry, &callchain_cursor,
1946+ return unwind__get_entries(unwind_entry, cursor,
19421947 thread, sample, max_stack);
1948+}
1949+
1950+int thread__resolve_callchain(struct thread *thread,
1951+ struct callchain_cursor *cursor,
1952+ struct perf_evsel *evsel,
1953+ struct perf_sample *sample,
1954+ struct symbol **parent,
1955+ struct addr_location *root_al,
1956+ int max_stack)
1957+{
1958+ int ret = 0;
1959+
1960+ callchain_cursor_reset(&callchain_cursor);
19431961
1962+ if (callchain_param.order == ORDER_CALLEE) {
1963+ ret = thread__resolve_callchain_sample(thread, cursor,
1964+ evsel, sample,
1965+ parent, root_al,
1966+ max_stack);
1967+ if (ret)
1968+ return ret;
1969+ ret = thread__resolve_callchain_unwind(thread, cursor,
1970+ evsel, sample,
1971+ max_stack);
1972+ } else {
1973+ ret = thread__resolve_callchain_unwind(thread, cursor,
1974+ evsel, sample,
1975+ max_stack);
1976+ if (ret)
1977+ return ret;
1978+ ret = thread__resolve_callchain_sample(thread, cursor,
1979+ evsel, sample,
1980+ parent, root_al,
1981+ max_stack);
1982+ }
1983+
1984+ return ret;
19441985 }
19451986
19461987 int machine__for_each_thread(struct machine *machine,
tools/perf/util/machine.h+7−0
@@ -31,6 +31,7 @@ struct machine { · 30 unmodified lines
3131 char *root_dir;
3232 struct rb_root threads;
3333 pthread_rwlock_t threads_lock;
34+ unsigned int nr_threads;
3435 struct list_head dead_threads;
3536 struct thread *last_match;
3637 struct vdso_info *vdso_info;
@@ -141,7 +142,11 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, · 104 unmodified lines
141142 struct addr_location *al);
142143 struct mem_info *sample__resolve_mem(struct perf_sample *sample,
143144 struct addr_location *al);
145+
146+struct callchain_cursor;
147+
144148 int thread__resolve_callchain(struct thread *thread,
149+ struct callchain_cursor *cursor,
145150 struct perf_evsel *evsel,
146151 struct perf_sample *sample,
147152 struct symbol **parent,
@@ -211,6 +216,8 @@ struct symbol *machine__find_kernel_function_by_name(struct machine *machine, · 63 unmodified lines
211216 struct map *machine__findnew_module_map(struct machine *machine, u64 start,
212217 const char *filename);
213218
219+int __machine__load_kallsyms(struct machine *machine, const char *filename,
220+ enum map_type type, bool no_kcore, symbol_filter_t filter);
214221 int machine__load_kallsyms(struct machine *machine, const char *filename,
215222 enum map_type type, symbol_filter_t filter);
216223 int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
tools/perf/util/map.c+15−1
@@ -289,7 +289,7 @@ int map__load(struct map *map, symbol_filter_t filter) · 288 unmodified lines
289289 nr = dso__load(map->dso, map, filter);
290290 if (nr < 0) {
291291 if (map->dso->has_build_id) {
292− char sbuild_id[BUILD_ID_SIZE * 2 + 1];
292+ char sbuild_id[SBUILD_ID_SIZE];
293293
294294 build_id__sprintf(map->dso->build_id,
295295 sizeof(map->dso->build_id),
@@ -431,6 +431,13 @@ u64 map__rip_2objdump(struct map *map, u64 rip) · 135 unmodified lines
431431 if (map->dso->rel)
432432 return rip - map->pgoff;
433433
434+ /*
435+ * kernel modules also have DSO_TYPE_USER in dso->kernel,
436+ * but all kernel modules are ET_REL, so won't get here.
437+ */
438+ if (map->dso->kernel == DSO_TYPE_USER)
439+ return rip + map->dso->text_offset;
440+
434441 return map->unmap_ip(map, rip) - map->reloc;
435442 }
436443
@@ -454,6 +461,13 @@ u64 map__objdump_2mem(struct map *map, u64 ip) · 17 unmodified lines
454461 if (map->dso->rel)
455462 return map->unmap_ip(map, ip + map->pgoff);
456463
464+ /*
465+ * kernel modules also have DSO_TYPE_USER in dso->kernel,
466+ * but all kernel modules are ET_REL, so won't get here.
467+ */
468+ if (map->dso->kernel == DSO_TYPE_USER)
469+ return map->unmap_ip(map, ip - map->dso->text_offset);
470+
457471 return ip + map->reloc;
458472 }
459473
tools/perf/util/ordered-events.c+9−0
@@ -308,3 +308,12 @@ void ordered_events__free(struct ordered_events *oe) · 307 unmodified lines
308308 free(event);
309309 }
310310 }
311+
312+void ordered_events__reinit(struct ordered_events *oe)
313+{
314+ ordered_events__deliver_t old_deliver = oe->deliver;
315+
316+ ordered_events__free(oe);
317+ memset(oe, '\0', sizeof(*oe));
318+ ordered_events__init(oe, old_deliver);
319+}
tools/perf/util/ordered-events.h+1−0
@@ -49,6 +49,7 @@ void ordered_events__delete(struct ordered_events *oe, struct ordered_event *eve · 48 unmodified lines
4949 int ordered_events__flush(struct ordered_events *oe, enum oe_flush how);
5050 void ordered_events__init(struct ordered_events *oe, ordered_events__deliver_t deliver);
5151 void ordered_events__free(struct ordered_events *oe);
52+void ordered_events__reinit(struct ordered_events *oe);
5253
5354 static inline
5455 void ordered_events__set_alloc_size(struct ordered_events *oe, u64 size)
tools/perf/util/pmu.c+11−12
@@ -602,14 +602,13 @@ static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v, · 601 unmodified lines
602602
603603 static __u64 pmu_format_max_value(const unsigned long *format)
604604 {
605− int w;
605+ __u64 w = 0;
606+ int fbit;
606607
607− w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
608− if (!w)
609− return 0;
610− if (w < 64)
611− return (1ULL << w) - 1;
612− return -1;
608+ for_each_set_bit(fbit, format, PERF_PMU_FORMAT_BITS)
609+ w |= (1ULL << fbit);
610+
611+ return w;
613612 }
614613
615614 /*
@@ -644,20 +643,20 @@ static int pmu_resolve_param_term(struct parse_events_term *term, · 28 unmodified lines
644643 static char *pmu_formats_string(struct list_head *formats)
645644 {
646645 struct perf_pmu_format *format;
647− char *str;
648− struct strbuf buf;
646+ char *str = NULL;
647+ struct strbuf buf = STRBUF_INIT;
649648 unsigned i = 0;
650649
651650 if (!formats)
652651 return NULL;
653652
654− strbuf_init(&buf, 0);
655653 /* sysfs exported terms */
656654 list_for_each_entry(format, formats, list)
657− strbuf_addf(&buf, i++ ? ",%s" : "%s",
658− format->name);
655+ if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)
656+ goto error;
659657
660658 str = strbuf_detach(&buf, NULL);
659+error:
661660 strbuf_release(&buf);
662661
663662 return str;
tools/perf/util/probe-event.c+215−191
@@ -265,6 +265,65 @@ static bool kprobe_warn_out_range(const char *symbol, unsigned long address) · 264 unmodified lines
265265 return true;
266266 }
267267
268+/*
269+ * NOTE:
270+ * '.gnu.linkonce.this_module' section of kernel module elf directly
271+ * maps to 'struct module' from linux/module.h. This section contains
272+ * actual module name which will be used by kernel after loading it.
273+ * But, we cannot use 'struct module' here since linux/module.h is not
274+ * exposed to user-space. Offset of 'name' has remained same from long
275+ * time, so hardcoding it here.
276+ */
277+#ifdef __LP64__
278+#define MOD_NAME_OFFSET 24
279+#else
280+#define MOD_NAME_OFFSET 12
281+#endif
282+
283+/*
284+ * @module can be module name of module file path. In case of path,
285+ * inspect elf and find out what is actual module name.
286+ * Caller has to free mod_name after using it.
287+ */
288+static char *find_module_name(const char *module)
289+{
290+ int fd;
291+ Elf *elf;
292+ GElf_Ehdr ehdr;
293+ GElf_Shdr shdr;
294+ Elf_Data *data;
295+ Elf_Scn *sec;
296+ char *mod_name = NULL;
297+
298+ fd = open(module, O_RDONLY);
299+ if (fd < 0)
300+ return NULL;
301+
302+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
303+ if (elf == NULL)
304+ goto elf_err;
305+
306+ if (gelf_getehdr(elf, &ehdr) == NULL)
307+ goto ret_err;
308+
309+ sec = elf_section_by_name(elf, &ehdr, &shdr,
310+ ".gnu.linkonce.this_module", NULL);
311+ if (!sec)
312+ goto ret_err;
313+
314+ data = elf_getdata(sec, NULL);
315+ if (!data || !data->d_buf)
316+ goto ret_err;
317+
318+ mod_name = strdup((char *)data->d_buf + MOD_NAME_OFFSET);
319+
320+ret_err:
321+ elf_end(elf);
322+elf_err:
323+ close(fd);
324+ return mod_name;
325+}
326+
268327 #ifdef HAVE_DWARF_SUPPORT
269328
270329 static int kernel_get_module_dso(const char *module, struct dso **pdso)
@@ -486,8 +545,10 @@ static int get_text_start_address(const char *exec, unsigned long *address) · 215 unmodified lines
486545 return -errno;
487546
488547 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
489− if (elf == NULL)
490− return -EINVAL;
548+ if (elf == NULL) {
549+ ret = -EINVAL;
550+ goto out_close;
551+ }
491552
492553 if (gelf_getehdr(elf, &ehdr) == NULL)
493554 goto out;
@@ -499,6 +560,9 @@ static int get_text_start_address(const char *exec, unsigned long *address) · 5 unmodified lines
499560 ret = 0;
500561 out:
501562 elf_end(elf);
563+out_close:
564+ close(fd);
565+
502566 return ret;
503567 }
504568
@@ -583,32 +647,23 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, · 78 unmodified lines
583647 int ntevs, const char *module)
584648 {
585649 int i, ret = 0;
586− char *tmp;
650+ char *mod_name = NULL;
587651
588652 if (!module)
589653 return 0;
590654
591− tmp = strrchr(module, '/');
592− if (tmp) {
593− /* This is a module path -- get the module name */
594− module = strdup(tmp + 1);
595− if (!module)
596− return -ENOMEM;
597− tmp = strchr(module, '.');
598− if (tmp)
599− *tmp = '\0';
600− tmp = (char *)module; /* For free() */
601− }
655+ mod_name = find_module_name(module);
602656
603657 for (i = 0; i < ntevs; i++) {
604− tevs[i].point.module = strdup(module);
658+ tevs[i].point.module =
659+ strdup(mod_name ? mod_name : module);
605660 if (!tevs[i].point.module) {
606661 ret = -ENOMEM;
607662 break;
608663 }
609664 }
610665
611− free(tmp);
666+ free(mod_name);
612667 return ret;
613668 }
614669
@@ -1618,69 +1673,65 @@ out: · 1003 unmodified lines
16181673 }
16191674
16201675 /* Compose only probe arg */
1621−int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
1676+char *synthesize_perf_probe_arg(struct perf_probe_arg *pa)
16221677 {
16231678 struct perf_probe_arg_field *field = pa->field;
1624− int ret;
1625− char *tmp = buf;
1679+ struct strbuf buf;
1680+ char *ret = NULL;
1681+ int err;
1682+
1683+ if (strbuf_init(&buf, 64) < 0)
1684+ return NULL;
16261685
16271686 if (pa->name && pa->var)
1628− ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
1687+ err = strbuf_addf(&buf, "%s=%s", pa->name, pa->var);
16291688 else
1630− ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
1631− if (ret <= 0)
1632− goto error;
1633− tmp += ret;
1634− len -= ret;
1689+ err = strbuf_addstr(&buf, pa->name ?: pa->var);
1690+ if (err)
1691+ goto out;
16351692
16361693 while (field) {
16371694 if (field->name[0] == '[')
1638− ret = e_snprintf(tmp, len, "%s", field->name);
1695+ err = strbuf_addstr(&buf, field->name);
16391696 else
1640− ret = e_snprintf(tmp, len, "%s%s",
1641− field->ref ? "->" : ".", field->name);
1642− if (ret <= 0)
1643− goto error;
1644− tmp += ret;
1645− len -= ret;
1697+ err = strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".",
1698+ field->name);
16461699 field = field->next;
1700+ if (err)
1701+ goto out;
16471702 }
16481703
1649− if (pa->type) {
1650− ret = e_snprintf(tmp, len, ":%s", pa->type);
1651− if (ret <= 0)
1652− goto error;
1653− tmp += ret;
1654− len -= ret;
1655− }
1704+ if (pa->type)
1705+ if (strbuf_addf(&buf, ":%s", pa->type) < 0)
1706+ goto out;
16561707
1657− return tmp - buf;
1658−error:
1659− pr_debug("Failed to synthesize perf probe argument: %d\n", ret);
1708+ ret = strbuf_detach(&buf, NULL);
1709+out:
1710+ strbuf_release(&buf);
16601711 return ret;
16611712 }
16621713
16631714 /* Compose only probe point (not argument) */
16641715 static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
16651716 {
1666− char *buf, *tmp;
1667− char offs[32] = "", line[32] = "", file[32] = "";
1668− int ret, len;
1717+ struct strbuf buf;
1718+ char *tmp, *ret = NULL;
1719+ int len, err = 0;
16691720
1670− buf = zalloc(MAX_CMDLEN);
1671− if (buf == NULL) {
1672− ret = -ENOMEM;
1673− goto error;
1674− }
1675− if (pp->offset) {
1676− ret = e_snprintf(offs, 32, "+%lu", pp->offset);
1677− if (ret <= 0)
1678− goto error;
1679− }
1680− if (pp->line) {
1681− ret = e_snprintf(line, 32, ":%d", pp->line);
1682− if (ret <= 0)
1683− goto error;
1721+ if (strbuf_init(&buf, 64) < 0)
1722+ return NULL;
1723+
1724+ if (pp->function) {
1725+ if (strbuf_addstr(&buf, pp->function) < 0)
1726+ goto out;
1727+ if (pp->offset)
1728+ err = strbuf_addf(&buf, "+%lu", pp->offset);
1729+ else if (pp->line)
1730+ err = strbuf_addf(&buf, ":%d", pp->line);
1731+ else if (pp->retprobe)
1732+ err = strbuf_addstr(&buf, "%return");
1733+ if (err)
1734+ goto out;
16841735 }
16851736 if (pp->file) {
16861737 tmp = pp->file;
@@ -1689,25 +1740,15 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp) · 2 unmodified lines
16891740 tmp = strchr(pp->file + len - 30, '/');
16901741 tmp = tmp ? tmp + 1 : pp->file + len - 30;
16911742 }
1692− ret = e_snprintf(file, 32, "@%s", tmp);
1693− if (ret <= 0)
1694− goto error;
1743+ err = strbuf_addf(&buf, "@%s", tmp);
1744+ if (!err && !pp->function && pp->line)
1745+ err = strbuf_addf(&buf, ":%d", pp->line);
16951746 }
1696−
1697− if (pp->function)
1698− ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
1699− offs, pp->retprobe ? "%return" : "", line,
1700− file);
1701− else
1702− ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
1703− if (ret <= 0)
1704− goto error;
1705−
1706− return buf;
1707−error:
1708− pr_debug("Failed to synthesize perf probe point: %d\n", ret);
1709− free(buf);
1710− return NULL;
1747+ if (!err)
1748+ ret = strbuf_detach(&buf, NULL);
1749+out:
1750+ strbuf_release(&buf);
1751+ return ret;
17111752 }
17121753
17131754 #if 0
@@ -1736,45 +1777,32 @@ char *synthesize_perf_probe_command(struct perf_probe_event *pev) · 22 unmodified lines
17361777 #endif
17371778
17381779 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
1739− char **buf, size_t *buflen,
1740− int depth)
1780+ struct strbuf *buf, int depth)
17411781 {
1742− int ret;
1782+ int err;
17431783 if (ref->next) {
17441784 depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
1745− buflen, depth + 1);
1785+ depth + 1);
17461786 if (depth < 0)
1747− goto out;
1748− }
1749−
1750− ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
1751− if (ret < 0)
1752− depth = ret;
1753− else {
1754− *buf += ret;
1755− *buflen -= ret;
1787+ return depth;
17561788 }
1757−out:
1758− return depth;
1759−
1789+ err = strbuf_addf(buf, "%+ld(", ref->offset);
1790+ return (err < 0) ? err : depth;
17601791 }
17611792
17621793 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
1763− char *buf, size_t buflen)
1794+ struct strbuf *buf)
17641795 {
17651796 struct probe_trace_arg_ref *ref = arg->ref;
1766− int ret, depth = 0;
1767− char *tmp = buf;
1797+ int depth = 0, err;
17681798
17691799 /* Argument name or separator */
17701800 if (arg->name)
1771− ret = e_snprintf(buf, buflen, " %s=", arg->name);
1801+ err = strbuf_addf(buf, " %s=", arg->name);
17721802 else
1773− ret = e_snprintf(buf, buflen, " ");
1774− if (ret < 0)
1775− return ret;
1776− buf += ret;
1777− buflen -= ret;
1803+ err = strbuf_addch(buf, ' ');
1804+ if (err)
1805+ return err;
17781806
17791807 /* Special case: @XXX */
17801808 if (arg->value[0] == '@' && arg->ref)
@@ -1782,59 +1810,44 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, · 1 unmodified line
17821810
17831811 /* Dereferencing arguments */
17841812 if (ref) {
1785− depth = __synthesize_probe_trace_arg_ref(ref, &buf,
1786− &buflen, 1);
1813+ depth = __synthesize_probe_trace_arg_ref(ref, buf, 1);
17871814 if (depth < 0)
17881815 return depth;
17891816 }
17901817
17911818 /* Print argument value */
17921819 if (arg->value[0] == '@' && arg->ref)
1793− ret = e_snprintf(buf, buflen, "%s%+ld", arg->value,
1794− arg->ref->offset);
1820+ err = strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset);
17951821 else
1796− ret = e_snprintf(buf, buflen, "%s", arg->value);
1797− if (ret < 0)
1798− return ret;
1799− buf += ret;
1800− buflen -= ret;
1822+ err = strbuf_addstr(buf, arg->value);
18011823
18021824 /* Closing */
1803− while (depth--) {
1804− ret = e_snprintf(buf, buflen, ")");
1805− if (ret < 0)
1806− return ret;
1807− buf += ret;
1808− buflen -= ret;
1809− }
1825+ while (!err && depth--)
1826+ err = strbuf_addch(buf, ')');
1827+
18101828 /* Print argument type */
1811− if (arg->type) {
1812− ret = e_snprintf(buf, buflen, ":%s", arg->type);
1813− if (ret <= 0)
1814− return ret;
1815− buf += ret;
1816− }
1829+ if (!err && arg->type)
1830+ err = strbuf_addf(buf, ":%s", arg->type);
18171831
1818− return buf - tmp;
1832+ return err;
18191833 }
18201834
18211835 char *synthesize_probe_trace_command(struct probe_trace_event *tev)
18221836 {
18231837 struct probe_trace_point *tp = &tev->point;
1824− char *buf;
1825− int i, len, ret;
1838+ struct strbuf buf;
1839+ char *ret = NULL;
1840+ int i, err;
18261841
1827− buf = zalloc(MAX_CMDLEN);
1828− if (buf == NULL)
1842+ /* Uprobes must have tp->module */
1843+ if (tev->uprobes && !tp->module)
18291844 return NULL;
18301845
1831− len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s ", tp->retprobe ? 'r' : 'p',
1832− tev->group, tev->event);
1833− if (len <= 0)
1834− goto error;
1846+ if (strbuf_init(&buf, 32) < 0)
1847+ return NULL;
18351848
1836− /* Uprobes must have tp->module */
1837− if (tev->uprobes && !tp->module)
1849+ if (strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p',
1850+ tev->group, tev->event) < 0)
18381851 goto error;
18391852 /*
18401853 * If tp->address == 0, then this point must be a
@@ -1849,34 +1862,25 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev) · 8 unmodified lines
18491862
18501863 /* Use the tp->address for uprobes */
18511864 if (tev->uprobes)
1852− ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx",
1853− tp->module, tp->address);
1865+ err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address);
18541866 else if (!strncmp(tp->symbol, "0x", 2))
18551867 /* Absolute address. See try_to_find_absolute_address() */
1856− ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s0x%lx",
1857− tp->module ?: "", tp->module ? ":" : "",
1858− tp->address);
1868+ err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "",
1869+ tp->module ? ":" : "", tp->address);
18591870 else
1860− ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu",
1861− tp->module ?: "", tp->module ? ":" : "",
1862− tp->symbol, tp->offset);
1863−
1864− if (ret <= 0)
1871+ err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "",
1872+ tp->module ? ":" : "", tp->symbol, tp->offset);
1873+ if (err)
18651874 goto error;
1866− len += ret;
18671875
1868− for (i = 0; i < tev->nargs; i++) {
1869− ret = synthesize_probe_trace_arg(&tev->args[i], buf + len,
1870− MAX_CMDLEN - len);
1871− if (ret <= 0)
1876+ for (i = 0; i < tev->nargs; i++)
1877+ if (synthesize_probe_trace_arg(&tev->args[i], &buf) < 0)
18721878 goto error;
1873− len += ret;
1874− }
18751879
1876− return buf;
1880+ ret = strbuf_detach(&buf, NULL);
18771881 error:
1878− free(buf);
1879− return NULL;
1882+ strbuf_release(&buf);
1883+ return ret;
18801884 }
18811885
18821886 static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
@@ -1958,7 +1962,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp, · 75 unmodified lines
19581962 static int convert_to_perf_probe_event(struct probe_trace_event *tev,
19591963 struct perf_probe_event *pev, bool is_kprobe)
19601964 {
1961− char buf[64] = "";
1965+ struct strbuf buf = STRBUF_INIT;
19621966 int i, ret;
19631967
19641968 /* Convert event/group name */
@@ -1981,14 +1985,15 @@ static int convert_to_perf_probe_event(struct probe_trace_event *tev, · 16 unmodified lines
19811985 if (tev->args[i].name)
19821986 pev->args[i].name = strdup(tev->args[i].name);
19831987 else {
1984− ret = synthesize_probe_trace_arg(&tev->args[i],
1985− buf, 64);
1986− pev->args[i].name = strdup(buf);
1988+ if ((ret = strbuf_init(&buf, 32)) < 0)
1989+ goto error;
1990+ ret = synthesize_probe_trace_arg(&tev->args[i], &buf);
1991+ pev->args[i].name = strbuf_detach(&buf, NULL);
19871992 }
19881993 if (pev->args[i].name == NULL && ret >= 0)
19891994 ret = -ENOMEM;
19901995 }
1991−
1996+error:
19921997 if (ret < 0)
19931998 clear_perf_probe_event(pev);
19941999
@@ -2162,35 +2167,38 @@ static int perf_probe_event__sprintf(const char *group, const char *event, · 167 unmodified lines
21622167 struct strbuf *result)
21632168 {
21642169 int i, ret;
2165− char buf[128];
2166− char *place;
2170+ char *buf;
21672171
2168− /* Synthesize only event probe point */
2169− place = synthesize_perf_probe_point(&pev->point);
2170− if (!place)
2171− return -EINVAL;
2172+ if (asprintf(&buf, "%s:%s", group, event) < 0)
2173+ return -errno;
2174+ ret = strbuf_addf(result, " %-20s (on ", buf);
2175+ free(buf);
2176+ if (ret)
2177+ return ret;
21722178
2173− ret = e_snprintf(buf, 128, "%s:%s", group, event);
2174− if (ret < 0)
2175− goto out;
2179+ /* Synthesize only event probe point */
2180+ buf = synthesize_perf_probe_point(&pev->point);
2181+ if (!buf)
2182+ return -ENOMEM;
2183+ ret = strbuf_addstr(result, buf);
2184+ free(buf);
21762185
2177− strbuf_addf(result, " %-20s (on %s", buf, place);
2178− if (module)
2179− strbuf_addf(result, " in %s", module);
2186+ if (!ret && module)
2187+ ret = strbuf_addf(result, " in %s", module);
21802188
2181− if (pev->nargs > 0) {
2182− strbuf_add(result, " with", 5);
2183− for (i = 0; i < pev->nargs; i++) {
2184− ret = synthesize_perf_probe_arg(&pev->args[i],
2185− buf, 128);
2186− if (ret < 0)
2187− goto out;
2188− strbuf_addf(result, " %s", buf);
2189+ if (!ret && pev->nargs > 0) {
2190+ ret = strbuf_add(result, " with", 5);
2191+ for (i = 0; !ret && i < pev->nargs; i++) {
2192+ buf = synthesize_perf_probe_arg(&pev->args[i]);
2193+ if (!buf)
2194+ return -ENOMEM;
2195+ ret = strbuf_addf(result, " %s", buf);
2196+ free(buf);
21892197 }
21902198 }
2191− strbuf_addch(result, ')');
2192−out:
2193− free(place);
2199+ if (!ret)
2200+ ret = strbuf_addch(result, ')');
2201+
21942202 return ret;
21952203 }
21962204
@@ -2498,7 +2506,8 @@ static int find_probe_functions(struct map *map, char *name, · 301 unmodified lines
24982506
24992507 void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
25002508 struct probe_trace_event *tev __maybe_unused,
2501− struct map *map __maybe_unused) { }
2509+ struct map *map __maybe_unused,
2510+ struct symbol *sym __maybe_unused) { }
25022511
25032512 /*
25042513 * Find probe function addresses from map.
@@ -2516,6 +2525,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, · 11 unmodified lines
25162525 struct probe_trace_point *tp;
25172526 int num_matched_functions;
25182527 int ret, i, j, skipped = 0;
2528+ char *mod_name;
25192529
25202530 map = get_target_map(pev->target, pev->uprobes);
25212531 if (!map) {
@@ -2600,9 +2610,19 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, · 78 unmodified lines
26002610 tp->realname = strdup_or_goto(sym->name, nomem_out);
26012611
26022612 tp->retprobe = pp->retprobe;
2603− if (pev->target)
2604− tev->point.module = strdup_or_goto(pev->target,
2605− nomem_out);
2613+ if (pev->target) {
2614+ if (pev->uprobes) {
2615+ tev->point.module = strdup_or_goto(pev->target,
2616+ nomem_out);
2617+ } else {
2618+ mod_name = find_module_name(pev->target);
2619+ tev->point.module =
2620+ strdup(mod_name ? mod_name : pev->target);
2621+ free(mod_name);
2622+ if (!tev->point.module)
2623+ goto nomem_out;
2624+ }
2625+ }
26062626 tev->uprobes = pev->uprobes;
26072627 tev->nargs = pev->nargs;
26082628 if (tev->nargs) {
@@ -2624,7 +2644,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, · 15 unmodified lines
26242644 strdup_or_goto(pev->args[i].type,
26252645 nomem_out);
26262646 }
2627− arch__fix_tev_from_maps(pev, tev, map);
2647+ arch__fix_tev_from_maps(pev, tev, map, sym);
26282648 }
26292649 if (ret == skipped) {
26302650 ret = -ENOENT;
@@ -2743,9 +2763,13 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, · 112 unmodified lines
27432763 {
27442764 int ret;
27452765
2746− if (pev->uprobes && !pev->group) {
2747− /* Replace group name if not given */
2748− ret = convert_exec_to_group(pev->target, &pev->group);
2766+ if (!pev->group) {
2767+ /* Set group name if not given */
2768+ if (!pev->uprobes) {
2769+ pev->group = strdup(PERFPROBE_GROUP);
2770+ ret = pev->group ? 0 : -ENOMEM;
2771+ } else
2772+ ret = convert_exec_to_group(pev->target, &pev->group);
27492773 if (ret != 0) {
27502774 pr_warning("Failed to make a group name.\n");
27512775 return ret;
tools/perf/util/probe-event.h+3−2
@@ -120,7 +120,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev); · 119 unmodified lines
120120 /* Events to command string */
121121 char *synthesize_perf_probe_command(struct perf_probe_event *pev);
122122 char *synthesize_probe_trace_command(struct probe_trace_event *tev);
123−int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len);
123+char *synthesize_perf_probe_arg(struct perf_probe_arg *pa);
124124
125125 /* Check the perf_probe_event needs debuginfo */
126126 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
@@ -154,7 +154,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, · 27 unmodified lines
154154 int show_available_funcs(const char *module, struct strfilter *filter, bool user);
155155 bool arch__prefers_symtab(void);
156156 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
157− struct probe_trace_event *tev, struct map *map);
157+ struct probe_trace_event *tev, struct map *map,
158+ struct symbol *sym);
158159
159160 /* If there is no space to write, returns -E2BIG. */
160161 int e_snprintf(char *str, size_t size, const char *format, ...)
tools/perf/util/probe-file.c+1−2
@@ -220,8 +220,7 @@ int probe_file__add_event(int fd, struct probe_trace_event *tev) · 219 unmodified lines
220220
221221 pr_debug("Writing event: %s\n", buf);
222222 if (!probe_event_dry_run) {
223− ret = write(fd, buf, strlen(buf));
224− if (ret <= 0) {
223+ if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) {
225224 ret = -errno;
226225 pr_warning("Failed to write event: %s\n",
227226 strerror_r(errno, sbuf, sizeof(sbuf)));
tools/perf/util/probe-finder.c+21−15
@@ -553,7 +553,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) · 552 unmodified lines
553553 static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
554554 {
555555 Dwarf_Die vr_die;
556− char buf[32], *ptr;
556+ char *buf, *ptr;
557557 int ret = 0;
558558
559559 /* Copy raw parameters */
@@ -563,13 +563,13 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) · 3 unmodified lines
563563 if (pf->pvar->name)
564564 pf->tvar->name = strdup(pf->pvar->name);
565565 else {
566− ret = synthesize_perf_probe_arg(pf->pvar, buf, 32);
567− if (ret < 0)
568− return ret;
566+ buf = synthesize_perf_probe_arg(pf->pvar);
567+ if (!buf)
568+ return -ENOMEM;
569569 ptr = strchr(buf, ':'); /* Change type separator to _ */
570570 if (ptr)
571571 *ptr = '_';
572− pf->tvar->name = strdup(buf);
572+ pf->tvar->name = buf;
573573 }
574574 if (pf->tvar->name == NULL)
575575 return -ENOMEM;
@@ -1294,6 +1294,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data) · 718 unmodified lines
12941294 {
12951295 struct available_var_finder *af = data;
12961296 struct variable_list *vl;
1297+ struct strbuf buf = STRBUF_INIT;
12971298 int tag, ret;
12981299
12991300 vl = &af->vls[af->nvls - 1];
@@ -1307,25 +1308,26 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data) · 7 unmodified lines
13071308 if (ret == 0 || ret == -ERANGE) {
13081309 int ret2;
13091310 bool externs = !af->child;
1310− struct strbuf buf;
13111311
1312− strbuf_init(&buf, 64);
1312+ if (strbuf_init(&buf, 64) < 0)
1313+ goto error;
13131314
13141315 if (probe_conf.show_location_range) {
1315− if (!externs) {
1316− if (ret)
1317− strbuf_add(&buf, "[INV]\t", 6);
1318− else
1319− strbuf_add(&buf, "[VAL]\t", 6);
1320− } else
1321− strbuf_add(&buf, "[EXT]\t", 6);
1316+ if (!externs)
1317+ ret2 = strbuf_add(&buf,
1318+ ret ? "[INV]\t" : "[VAL]\t", 6);
1319+ else
1320+ ret2 = strbuf_add(&buf, "[EXT]\t", 6);
1321+ if (ret2)
1322+ goto error;
13221323 }
13231324
13241325 ret2 = die_get_varname(die_mem, &buf);
13251326
13261327 if (!ret2 && probe_conf.show_location_range &&
13271328 !externs) {
1328− strbuf_addch(&buf, '\t');
1329+ if (strbuf_addch(&buf, '\t') < 0)
1330+ goto error;
13291331 ret2 = die_get_var_range(&af->pf.sp_die,
13301332 die_mem, &buf);
13311333 }
@@ -1343,6 +1345,10 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data) · 11 unmodified lines
13431345 return DIE_FIND_CB_CONTINUE;
13441346 else
13451347 return DIE_FIND_CB_SIBLING;
1348+error:
1349+ strbuf_release(&buf);
1350+ pr_debug("Error in strbuf\n");
1351+ return DIE_FIND_CB_END;
13461352 }
13471353
13481354 /* Add a found vars into available variables list */
tools/perf/util/python-ext-sources+1−0
@@ -23,3 +23,4 @@ util/strlist.c · 22 unmodified lines
2323 util/trace-event.c
2424 ../lib/rbtree.c
2525 util/string.c
26+util/symbol_fprintf.c
tools/perf/util/quote.c+20−16
@@ -17,38 +17,42 @@ static inline int need_bs_quote(char c) · 16 unmodified lines
1717 return (c == '\'' || c == '!');
1818 }
1919
20−static void sq_quote_buf(struct strbuf *dst, const char *src)
20+static int sq_quote_buf(struct strbuf *dst, const char *src)
2121 {
2222 char *to_free = NULL;
23+ int ret;
2324
2425 if (dst->buf == src)
2526 to_free = strbuf_detach(dst, NULL);
2627
27− strbuf_addch(dst, '\'');
28− while (*src) {
28+ ret = strbuf_addch(dst, '\'');
29+ while (!ret && *src) {
2930 size_t len = strcspn(src, "'!");
30− strbuf_add(dst, src, len);
31+ ret = strbuf_add(dst, src, len);
3132 src += len;
32− while (need_bs_quote(*src)) {
33− strbuf_addstr(dst, "'\\");
34− strbuf_addch(dst, *src++);
35− strbuf_addch(dst, '\'');
36− }
33+ while (!ret && need_bs_quote(*src))
34+ ret = strbuf_addf(dst, "'\\%c\'", *src++);
3735 }
38− strbuf_addch(dst, '\'');
36+ if (!ret)
37+ ret = strbuf_addch(dst, '\'');
3938 free(to_free);
39+
40+ return ret;
4041 }
4142
42−void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen)
43+int sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen)
4344 {
44− int i;
45+ int i, ret;
4546
4647 /* Copy into destination buffer. */
47− strbuf_grow(dst, 255);
48− for (i = 0; argv[i]; ++i) {
49− strbuf_addch(dst, ' ');
50− sq_quote_buf(dst, argv[i]);
48+ ret = strbuf_grow(dst, 255);
49+ for (i = 0; !ret && argv[i]; ++i) {
50+ ret = strbuf_addch(dst, ' ');
51+ if (ret)
52+ break;
53+ ret = sq_quote_buf(dst, argv[i]);
5154 if (maxlen && dst->len > maxlen)
5255 die("Too many or long arguments");
5356 }
57+ return ret;
5458 }
tools/perf/util/quote.h+1−1
@@ -24,6 +24,6 @@ · 23 unmodified lines
2424 * sq_quote() in a real application.
2525 */
2626
27−void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
27+int sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
2828
2929 #endif /* __PERF_QUOTE_H */
tools/perf/util/rb_resort.h+149−0
@@ -0,0 +1,149 @@
1+#ifndef _PERF_RESORT_RB_H_
2+#define _PERF_RESORT_RB_H_
3+/*
4+ * Template for creating a class to resort an existing rb_tree according to
5+ * a new sort criteria, that must be present in the entries of the source
6+ * rb_tree.
7+ *
8+ * (c) 2016 Arnaldo Carvalho de Melo <acme@redhat.com>
9+ *
10+ * Quick example, resorting threads by its shortname:
11+ *
12+ * First define the prefix (threads) to be used for the functions and data
13+ * structures created, and provide an expression for the sorting, then the
14+ * fields to be present in each of the entries in the new, sorted, rb_tree.
15+ *
16+ * The body of the init function should collect the fields, maybe
17+ * pre-calculating them from multiple entries in the original 'entry' from
18+ * the rb_tree used as a source for the entries to be sorted:
19+
20+DEFINE_RB_RESORT_RB(threads, strcmp(a->thread->shortname,
21+ b->thread->shortname) < 0,
22+ struct thread *thread;
23+)
24+{
25+ entry->thread = rb_entry(nd, struct thread, rb_node);
26+}
27+
28+ * After this it is just a matter of instantiating it and iterating it,
29+ * for a few data structures with existing rb_trees, such as 'struct machine',
30+ * helpers are available to get the rb_root and the nr_entries:
31+
32+ DECLARE_RESORT_RB_MACHINE_THREADS(threads, machine_ptr);
33+
34+ * This will instantiate the new rb_tree and a cursor for it, that can be used as:
35+
36+ struct rb_node *nd;
37+
38+ resort_rb__for_each(nd, threads) {
39+ struct thread *t = threads_entry;
40+ printf("%s: %d\n", t->shortname, t->tid);
41+ }
42+
43+ * Then delete it:
44+
45+ resort_rb__delete(threads);
46+
47+ * The name of the data structures and functions will have a _sorted suffix
48+ * right before the method names, i.e. will look like:
49+ *
50+ * struct threads_sorted_entry {}
51+ * threads_sorted__insert()
52+ */
53+
54+#define DEFINE_RESORT_RB(__name, __comp, ...) \
55+struct __name##_sorted_entry { \
56+ struct rb_node rb_node; \
57+ __VA_ARGS__ \
58+}; \
59+static void __name##_sorted__init_entry(struct rb_node *nd, \
60+ struct __name##_sorted_entry *entry); \
61+ \
62+static int __name##_sorted__cmp(struct rb_node *nda, struct rb_node *ndb) \
63+{ \
64+ struct __name##_sorted_entry *a, *b; \
65+ a = rb_entry(nda, struct __name##_sorted_entry, rb_node); \
66+ b = rb_entry(ndb, struct __name##_sorted_entry, rb_node); \
67+ return __comp; \
68+} \
69+ \
70+struct __name##_sorted { \
71+ struct rb_root entries; \
72+ struct __name##_sorted_entry nd[0]; \
73+}; \
74+ \
75+static void __name##_sorted__insert(struct __name##_sorted *sorted, \
76+ struct rb_node *sorted_nd) \
77+{ \
78+ struct rb_node **p = &sorted->entries.rb_node, *parent = NULL; \
79+ while (*p != NULL) { \
80+ parent = *p; \
81+ if (__name##_sorted__cmp(sorted_nd, parent)) \
82+ p = &(*p)->rb_left; \
83+ else \
84+ p = &(*p)->rb_right; \
85+ } \
86+ rb_link_node(sorted_nd, parent, p); \
87+ rb_insert_color(sorted_nd, &sorted->entries); \
88+} \
89+ \
90+static void __name##_sorted__sort(struct __name##_sorted *sorted, \
91+ struct rb_root *entries) \
92+{ \
93+ struct rb_node *nd; \
94+ unsigned int i = 0; \
95+ for (nd = rb_first(entries); nd; nd = rb_next(nd)) { \
96+ struct __name##_sorted_entry *snd = &sorted->nd[i++]; \
97+ __name##_sorted__init_entry(nd, snd); \
98+ __name##_sorted__insert(sorted, &snd->rb_node); \
99+ } \
100+} \
101+ \
102+static struct __name##_sorted *__name##_sorted__new(struct rb_root *entries, \
103+ int nr_entries) \
104+{ \
105+ struct __name##_sorted *sorted; \
106+ sorted = malloc(sizeof(*sorted) + sizeof(sorted->nd[0]) * nr_entries); \
107+ if (sorted) { \
108+ sorted->entries = RB_ROOT; \
109+ __name##_sorted__sort(sorted, entries); \
110+ } \
111+ return sorted; \
112+} \
113+ \
114+static void __name##_sorted__delete(struct __name##_sorted *sorted) \
115+{ \
116+ free(sorted); \
117+} \
118+ \
119+static void __name##_sorted__init_entry(struct rb_node *nd, \
120+ struct __name##_sorted_entry *entry)
121+
122+#define DECLARE_RESORT_RB(__name) \
123+struct __name##_sorted_entry *__name##_entry; \
124+struct __name##_sorted *__name = __name##_sorted__new
125+
126+#define resort_rb__for_each(__nd, __name) \
127+ for (__nd = rb_first(&__name->entries); \
128+ __name##_entry = rb_entry(__nd, struct __name##_sorted_entry, \
129+ rb_node), __nd; \
130+ __nd = rb_next(__nd))
131+
132+#define resort_rb__delete(__name) \
133+ __name##_sorted__delete(__name), __name = NULL
134+
135+/*
136+ * Helpers for other classes that contains both an rbtree and the
137+ * number of entries in it:
138+ */
139+
140+/* For 'struct intlist' */
141+#define DECLARE_RESORT_RB_INTLIST(__name, __ilist) \
142+ DECLARE_RESORT_RB(__name)(&__ilist->rblist.entries, \
143+ __ilist->rblist.nr_entries)
144+
145+/* For 'struct machine->threads' */
146+#define DECLARE_RESORT_RB_MACHINE_THREADS(__name, __machine) \
147+ DECLARE_RESORT_RB(__name)(&__machine->threads, __machine->nr_threads)
148+
149+#endif /* _PERF_RESORT_RB_H_ */
tools/perf/util/record.c+3−2
@@ -129,7 +129,8 @@ bool perf_can_record_cpu_wide(void) · 128 unmodified lines
129129 return true;
130130 }
131131
132−void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
132+void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
133+ struct callchain_param *callchain)
133134 {
134135 struct perf_evsel *evsel;
135136 bool use_sample_identifier = false;
@@ -148,7 +149,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) · 12 unmodified lines
148149 use_comm_exec = perf_can_comm_exec();
149150
150151 evlist__for_each(evlist, evsel) {
151− perf_evsel__config(evsel, opts);
152+ perf_evsel__config(evsel, opts, callchain);
152153 if (evsel->tracking && use_comm_exec)
153154 evsel->attr.comm_exec = 1;
154155 }
tools/perf/util/scripting-engines/trace-event-perl.c+118−8
@@ -31,6 +31,8 @@ · 30 unmodified lines
3131 #include <perl.h>
3232
3333 #include "../../perf.h"
34+#include "../callchain.h"
35+#include "../machine.h"
3436 #include "../thread.h"
3537 #include "../event.h"
3638 #include "../trace-event.h"
@@ -248,10 +250,90 @@ static void define_event_symbols(struct event_format *event, · 211 unmodified lines
248250 define_event_symbols(event, ev_name, args->next);
249251 }
250252
253+static SV *perl_process_callchain(struct perf_sample *sample,
254+ struct perf_evsel *evsel,
255+ struct addr_location *al)
256+{
257+ AV *list;
258+
259+ list = newAV();
260+ if (!list)
261+ goto exit;
262+
263+ if (!symbol_conf.use_callchain || !sample->callchain)
264+ goto exit;
265+
266+ if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
267+ sample, NULL, NULL,
268+ sysctl_perf_event_max_stack) != 0) {
269+ pr_err("Failed to resolve callchain. Skipping\n");
270+ goto exit;
271+ }
272+ callchain_cursor_commit(&callchain_cursor);
273+
274+
275+ while (1) {
276+ HV *elem;
277+ struct callchain_cursor_node *node;
278+ node = callchain_cursor_current(&callchain_cursor);
279+ if (!node)
280+ break;
281+
282+ elem = newHV();
283+ if (!elem)
284+ goto exit;
285+
286+ if (!hv_stores(elem, "ip", newSVuv(node->ip))) {
287+ hv_undef(elem);
288+ goto exit;
289+ }
290+
291+ if (node->sym) {
292+ HV *sym = newHV();
293+ if (!sym) {
294+ hv_undef(elem);
295+ goto exit;
296+ }
297+ if (!hv_stores(sym, "start", newSVuv(node->sym->start)) ||
298+ !hv_stores(sym, "end", newSVuv(node->sym->end)) ||
299+ !hv_stores(sym, "binding", newSVuv(node->sym->binding)) ||
300+ !hv_stores(sym, "name", newSVpvn(node->sym->name,
301+ node->sym->namelen)) ||
302+ !hv_stores(elem, "sym", newRV_noinc((SV*)sym))) {
303+ hv_undef(sym);
304+ hv_undef(elem);
305+ goto exit;
306+ }
307+ }
308+
309+ if (node->map) {
310+ struct map *map = node->map;
311+ const char *dsoname = "[unknown]";
312+ if (map && map->dso && (map->dso->name || map->dso->long_name)) {
313+ if (symbol_conf.show_kernel_path && map->dso->long_name)
314+ dsoname = map->dso->long_name;
315+ else if (map->dso->name)
316+ dsoname = map->dso->name;
317+ }
318+ if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) {
319+ hv_undef(elem);
320+ goto exit;
321+ }
322+ }
323+
324+ callchain_cursor_advance(&callchain_cursor);
325+ av_push(list, newRV_noinc((SV*)elem));
326+ }
327+
328+exit:
329+ return newRV_noinc((SV*)list);
330+}
331+
251332 static void perl_process_tracepoint(struct perf_sample *sample,
252333 struct perf_evsel *evsel,
253− struct thread *thread)
334+ struct addr_location *al)
254335 {
336+ struct thread *thread = al->thread;
255337 struct event_format *event = evsel->tp_format;
256338 struct format_field *field;
257339 static char handler[256];
@@ -295,6 +377,7 @@ static void perl_process_tracepoint(struct perf_sample *sample, · 37 unmodified lines
295377 XPUSHs(sv_2mortal(newSVuv(ns)));
296378 XPUSHs(sv_2mortal(newSViv(pid)));
297379 XPUSHs(sv_2mortal(newSVpv(comm, 0)));
380+ XPUSHs(sv_2mortal(perl_process_callchain(sample, evsel, al)));
298381
299382 /* common fields other than pid can be accessed via xsub fns */
300383
@@ -329,6 +412,7 @@ static void perl_process_tracepoint(struct perf_sample *sample, · 28 unmodified lines
329412 XPUSHs(sv_2mortal(newSVuv(nsecs)));
330413 XPUSHs(sv_2mortal(newSViv(pid)));
331414 XPUSHs(sv_2mortal(newSVpv(comm, 0)));
415+ XPUSHs(sv_2mortal(perl_process_callchain(sample, evsel, al)));
332416 call_pv("main::trace_unhandled", G_SCALAR);
333417 }
334418 SPAGAIN;
@@ -366,7 +450,7 @@ static void perl_process_event(union perf_event *event, · 31 unmodified lines
366450 struct perf_evsel *evsel,
367451 struct addr_location *al)
368452 {
369− perl_process_tracepoint(sample, evsel, al->thread);
453+ perl_process_tracepoint(sample, evsel, al);
370454 perl_process_event_generic(event, sample, evsel);
371455 }
372456
@@ -490,7 +574,27 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile) · 117 unmodified lines
490574 fprintf(ofp, "use Perf::Trace::Util;\n\n");
491575
492576 fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
493− fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n");
577+ fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n");
578+
579+
580+ fprintf(ofp, "\n\
581+sub print_backtrace\n\
582+{\n\
583+ my $callchain = shift;\n\
584+ for my $node (@$callchain)\n\
585+ {\n\
586+ if(exists $node->{sym})\n\
587+ {\n\
588+ printf( \"\\t[\\%%x] \\%%s\\n\", $node->{ip}, $node->{sym}{name});\n\
589+ }\n\
590+ else\n\
591+ {\n\
592+ printf( \"\\t[\\%%x]\\n\", $node{ip});\n\
593+ }\n\
594+ }\n\
595+}\n\n\
596+");
597+
494598
495599 while ((event = trace_find_next_event(pevent, event))) {
496600 fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
@@ -502,7 +606,8 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile) · 5 unmodified lines
502606 fprintf(ofp, "$common_secs, ");
503607 fprintf(ofp, "$common_nsecs,\n");
504608 fprintf(ofp, "\t $common_pid, ");
505− fprintf(ofp, "$common_comm,\n\t ");
609+ fprintf(ofp, "$common_comm, ");
610+ fprintf(ofp, "$common_callchain,\n\t ");
506611
507612 not_first = 0;
508613 count = 0;
@@ -519,7 +624,7 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile) · 10 unmodified lines
519624
520625 fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
521626 "$common_secs, $common_nsecs,\n\t "
522− "$common_pid, $common_comm);\n\n");
627+ "$common_pid, $common_comm, $common_callchain);\n\n");
523628
524629 fprintf(ofp, "\tprintf(\"");
525630
@@ -581,17 +686,22 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile) · 55 unmodified lines
581686 fprintf(ofp, "$%s", f->name);
582687 }
583688
584− fprintf(ofp, ");\n");
689+ fprintf(ofp, ");\n\n");
690+
691+ fprintf(ofp, "\tprint_backtrace($common_callchain);\n");
692+
585693 fprintf(ofp, "}\n\n");
586694 }
587695
588696 fprintf(ofp, "sub trace_unhandled\n{\n\tmy ($event_name, $context, "
589697 "$common_cpu, $common_secs, $common_nsecs,\n\t "
590− "$common_pid, $common_comm) = @_;\n\n");
698+ "$common_pid, $common_comm, $common_callchain) = @_;\n\n");
591699
592700 fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
593701 "$common_secs, $common_nsecs,\n\t $common_pid, "
594− "$common_comm);\n}\n\n");
702+ "$common_comm, $common_callchain);\n");
703+ fprintf(ofp, "\tprint_backtrace($common_callchain);\n");
704+ fprintf(ofp, "}\n\n");
595705
596706 fprintf(ofp, "sub print_header\n{\n"
597707 "\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
tools/perf/util/scripting-engines/trace-event-python.c+41−6
@@ -41,6 +41,7 @@ · 40 unmodified lines
4141 #include "../thread-stack.h"
4242 #include "../trace-event.h"
4343 #include "../machine.h"
44+#include "../call-path.h"
4445 #include "thread_map.h"
4546 #include "cpumap.h"
4647 #include "stat.h"
@@ -323,7 +324,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample, · 276 unmodified lines
323324 if (!symbol_conf.use_callchain || !sample->callchain)
324325 goto exit;
325326
326− if (thread__resolve_callchain(al->thread, evsel,
327+ if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
327328 sample, NULL, NULL,
328329 scripting_max_stack) != 0) {
329330 pr_err("Failed to resolve callchain. Skipping\n");
@@ -407,8 +408,11 @@ static void python_process_tracepoint(struct perf_sample *sample, · 77 unmodified lines
407408 if (!t)
408409 Py_FatalError("couldn't create Python tuple");
409410
410− if (!event)
411− die("ug! no event found for type %d", (int)evsel->attr.config);
411+ if (!event) {
412+ snprintf(handler_name, sizeof(handler_name),
413+ "ug! no event found for type %" PRIu64, (u64)evsel->attr.config);
414+ Py_FatalError(handler_name);
415+ }
412416
413417 pid = raw_field_value(event, "common_pid", data);
414418
@@ -614,7 +618,7 @@ static int python_export_dso(struct db_export *dbe, struct dso *dso, · 199 unmodified lines
614618 struct machine *machine)
615619 {
616620 struct tables *tables = container_of(dbe, struct tables, dbe);
617− char sbuild_id[BUILD_ID_SIZE * 2 + 1];
621+ char sbuild_id[SBUILD_ID_SIZE];
618622 PyObject *t;
619623
620624 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
@@ -681,7 +685,7 @@ static int python_export_sample(struct db_export *dbe, · 60 unmodified lines
681685 struct tables *tables = container_of(dbe, struct tables, dbe);
682686 PyObject *t;
683687
684− t = tuple_new(21);
688+ t = tuple_new(22);
685689
686690 tuple_set_u64(t, 0, es->db_id);
687691 tuple_set_u64(t, 1, es->evsel->db_id);
@@ -704,6 +708,7 @@ static int python_export_sample(struct db_export *dbe, · 16 unmodified lines
704708 tuple_set_u64(t, 18, es->sample->data_src);
705709 tuple_set_s32(t, 19, es->sample->flags & PERF_BRANCH_MASK);
706710 tuple_set_s32(t, 20, !!(es->sample->flags & PERF_IP_FLAG_IN_TX));
711+ tuple_set_u64(t, 21, es->call_path_id);
707712
708713 call_object(tables->sample_handler, t, "sample_table");
709714
@@ -998,8 +1003,10 @@ static void set_table_handlers(struct tables *tables) · 288 unmodified lines
9981003 {
9991004 const char *perf_db_export_mode = "perf_db_export_mode";
10001005 const char *perf_db_export_calls = "perf_db_export_calls";
1001− PyObject *db_export_mode, *db_export_calls;
1006+ const char *perf_db_export_callchains = "perf_db_export_callchains";
1007+ PyObject *db_export_mode, *db_export_calls, *db_export_callchains;
10021008 bool export_calls = false;
1009+ bool export_callchains = false;
10031010 int ret;
10041011
10051012 memset(tables, 0, sizeof(struct tables));
@@ -1016,6 +1023,7 @@ static void set_table_handlers(struct tables *tables) · 10 unmodified lines
10161023 if (!ret)
10171024 return;
10181025
1026+ /* handle export calls */
10191027 tables->dbe.crp = NULL;
10201028 db_export_calls = PyDict_GetItemString(main_dict, perf_db_export_calls);
10211029 if (db_export_calls) {
@@ -1033,6 +1041,33 @@ static void set_table_handlers(struct tables *tables) · 11 unmodified lines
10331041 Py_FatalError("failed to create calls processor");
10341042 }
10351043
1044+ /* handle export callchains */
1045+ tables->dbe.cpr = NULL;
1046+ db_export_callchains = PyDict_GetItemString(main_dict,
1047+ perf_db_export_callchains);
1048+ if (db_export_callchains) {
1049+ ret = PyObject_IsTrue(db_export_callchains);
1050+ if (ret == -1)
1051+ handler_call_die(perf_db_export_callchains);
1052+ export_callchains = !!ret;
1053+ }
1054+
1055+ if (export_callchains) {
1056+ /*
1057+ * Attempt to use the call path root from the call return
1058+ * processor, if the call return processor is in use. Otherwise,
1059+ * we allocate a new call path root. This prevents exporting
1060+ * duplicate call path ids when both are in use simultaniously.
1061+ */
1062+ if (tables->dbe.crp)
1063+ tables->dbe.cpr = tables->dbe.crp->cpr;
1064+ else
1065+ tables->dbe.cpr = call_path_root__new();
1066+
1067+ if (!tables->dbe.cpr)
1068+ Py_FatalError("failed to create call path root");
1069+ }
1070+
10361071 tables->db_export_mode = true;
10371072 /*
10381073 * Reserve per symbol space for symbol->db_id via symbol__priv()
tools/perf/util/session.c+13−102
@@ -409,6 +409,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) · 408 unmodified lines
409409 tool->stat = process_stat_stub;
410410 if (tool->stat_round == NULL)
411411 tool->stat_round = process_stat_round_stub;
412+ if (tool->time_conv == NULL)
413+ tool->time_conv = process_event_op2_stub;
412414 }
413415
414416 static void swap_sample_id_all(union perf_event *event, void *data)
@@ -794,6 +796,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { · 379 unmodified lines
794796 [PERF_RECORD_STAT] = perf_event__stat_swap,
795797 [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap,
796798 [PERF_RECORD_EVENT_UPDATE] = perf_event__event_update_swap,
799+ [PERF_RECORD_TIME_CONV] = perf_event__all64_swap,
797800 [PERF_RECORD_HEADER_MAX] = NULL,
798801 };
799802
@@ -904,7 +907,7 @@ static void callchain__printf(struct perf_evsel *evsel, · 104 unmodified lines
904907 unsigned int i;
905908 struct ip_callchain *callchain = sample->callchain;
906909
907− if (has_branch_callstack(evsel))
910+ if (perf_evsel__has_branch_callstack(evsel))
908911 callchain__lbr_callstack_printf(sample);
909912
910913 printf("... FP chain: nr:%" PRIu64 "\n", callchain->nr);
@@ -1078,7 +1081,7 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, · 167 unmodified lines
10781081 if (sample_type & PERF_SAMPLE_CALLCHAIN)
10791082 callchain__printf(evsel, sample);
10801083
1081− if ((sample_type & PERF_SAMPLE_BRANCH_STACK) && !has_branch_callstack(evsel))
1084+ if ((sample_type & PERF_SAMPLE_BRANCH_STACK) && !perf_evsel__has_branch_callstack(evsel))
10821085 branch_stack__printf(sample);
10831086
10841087 if (sample_type & PERF_SAMPLE_REGS_USER)
@@ -1341,6 +1344,9 @@ static s64 perf_session__process_user_event(struct perf_session *session, · 256 unmodified lines
13411344 return tool->stat(tool, event, session);
13421345 case PERF_RECORD_STAT_ROUND:
13431346 return tool->stat_round(tool, event, session);
1347+ case PERF_RECORD_TIME_CONV:
1348+ session->time_conv = event->time_conv;
1349+ return tool->time_conv(tool, event, session);
13441350 default:
13451351 return -EINVAL;
13461352 }
@@ -1830,7 +1836,11 @@ out: · 483 unmodified lines
18301836 out_err:
18311837 ui_progress__finish();
18321838 perf_session__warn_about_errors(session);
1833− ordered_events__free(&session->ordered_events);
1839+ /*
1840+ * We may switching perf.data output, make ordered_events
1841+ * reusable.
1842+ */
1843+ ordered_events__reinit(&session->ordered_events);
18341844 auxtrace__free_events(session);
18351845 session->one_mmap = false;
18361846 return err;
@@ -1947,105 +1957,6 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, · 110 unmodified lines
19471957 return NULL;
19481958 }
19491959
1950−void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1951− struct addr_location *al,
1952− unsigned int print_opts, unsigned int stack_depth)
1953−{
1954− struct callchain_cursor_node *node;
1955− int print_ip = print_opts & PRINT_IP_OPT_IP;
1956− int print_sym = print_opts & PRINT_IP_OPT_SYM;
1957− int print_dso = print_opts & PRINT_IP_OPT_DSO;
1958− int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
1959− int print_oneline = print_opts & PRINT_IP_OPT_ONELINE;
1960− int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE;
1961− char s = print_oneline ? ' ' : '\t';
1962−
1963− if (symbol_conf.use_callchain && sample->callchain) {
1964− struct addr_location node_al;
1965−
1966− if (thread__resolve_callchain(al->thread, evsel,
1967− sample, NULL, NULL,
1968− stack_depth) != 0) {
1969− if (verbose)
1970− error("Failed to resolve callchain. Skipping\n");
1971− return;
1972− }
1973− callchain_cursor_commit(&callchain_cursor);
1974−
1975− if (print_symoffset)
1976− node_al = *al;
1977−
1978− while (stack_depth) {
1979− u64 addr = 0;
1980−
1981− node = callchain_cursor_current(&callchain_cursor);
1982− if (!node)
1983− break;
1984−
1985− if (node->sym && node->sym->ignore)
1986− goto next;
1987−
1988− if (print_ip)
1989− printf("%c%16" PRIx64, s, node->ip);
1990−
1991− if (node->map)
1992− addr = node->map->map_ip(node->map, node->ip);
1993−
1994− if (print_sym) {
1995− printf(" ");
1996− if (print_symoffset) {
1997− node_al.addr = addr;
1998− node_al.map = node->map;
1999− symbol__fprintf_symname_offs(node->sym, &node_al, stdout);
2000− } else
2001− symbol__fprintf_symname(node->sym, stdout);
2002− }
2003−
2004− if (print_dso) {
2005− printf(" (");
2006− map__fprintf_dsoname(node->map, stdout);
2007− printf(")");
2008− }
2009−
2010− if (print_srcline)
2011− map__fprintf_srcline(node->map, addr, "\n ",
2012− stdout);
2013−
2014− if (!print_oneline)
2015− printf("\n");
2016−
2017− stack_depth--;
2018−next:
2019− callchain_cursor_advance(&callchain_cursor);
2020− }
2021−
2022− } else {
2023− if (al->sym && al->sym->ignore)
2024− return;
2025−
2026− if (print_ip)
2027− printf("%16" PRIx64, sample->ip);
2028−
2029− if (print_sym) {
2030− printf(" ");
2031− if (print_symoffset)
2032− symbol__fprintf_symname_offs(al->sym, al,
2033− stdout);
2034− else
2035− symbol__fprintf_symname(al->sym, stdout);
2036− }
2037−
2038− if (print_dso) {
2039− printf(" (");
2040− map__fprintf_dsoname(al->map, stdout);
2041− printf(")");
2042− }
2043−
2044− if (print_srcline)
2045− map__fprintf_srcline(al->map, al->addr, "\n ", stdout);
2046− }
2047−}
2048−
20491960 int perf_session__cpu_bitmap(struct perf_session *session,
20501961 const char *cpu_list, unsigned long *cpu_bitmap)
20511962 {
tools/perf/util/session.h+1−11
@@ -26,6 +26,7 @@ struct perf_session { · 25 unmodified lines
2626 struct itrace_synth_opts *itrace_synth_opts;
2727 struct list_head auxtrace_index;
2828 struct trace_event tevent;
29+ struct time_conv_event time_conv;
2930 bool repipe;
3031 bool one_mmap;
3132 void *one_mmap_addr;
@@ -35,13 +36,6 @@ struct perf_session { · 3 unmodified lines
3536 struct perf_tool *tool;
3637 };
3738
38−#define PRINT_IP_OPT_IP (1<<0)
39−#define PRINT_IP_OPT_SYM (1<<1)
40−#define PRINT_IP_OPT_DSO (1<<2)
41−#define PRINT_IP_OPT_SYMOFFSET (1<<3)
42−#define PRINT_IP_OPT_ONELINE (1<<4)
43−#define PRINT_IP_OPT_SRCLINE (1<<5)
44−
4539 struct perf_tool;
4640
4741 struct perf_session *perf_session__new(struct perf_data_file *file,
@@ -103,10 +97,6 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); · 55 unmodified lines
10397 struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
10498 unsigned int type);
10599
106−void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
107− struct addr_location *al,
108− unsigned int print_opts, unsigned int stack_depth);
109−
110100 int perf_session__cpu_bitmap(struct perf_session *session,
111101 const char *cpu_list, unsigned long *cpu_bitmap);
112102
tools/perf/util/sort.c+14−21
@@ -21,13 +21,6 @@ const char *sort_order; · 20 unmodified lines
2121 const char *field_order;
2222 regex_t ignore_callees_regex;
2323 int have_ignore_callees = 0;
24−int sort__need_collapse = 0;
25−int sort__has_parent = 0;
26−int sort__has_sym = 0;
27−int sort__has_dso = 0;
28−int sort__has_socket = 0;
29−int sort__has_thread = 0;
30−int sort__has_comm = 0;
3124 enum sort_mode sort__mode = SORT_MODE__NORMAL;
3225
3326 /*
@@ -244,7 +237,7 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) · 210 unmodified lines
244237 * comparing symbol address alone is not enough since it's a
245238 * relative address within a dso.
246239 */
247− if (!sort__has_dso) {
240+ if (!hists__has(left->hists, dso) || hists__has(right->hists, dso)) {
248241 ret = sort__dso_cmp(left, right);
249242 if (ret != 0)
250243 return ret;
@@ -2163,7 +2156,7 @@ static int __sort_dimension__add(struct sort_dimension *sd, · 1912 unmodified lines
21632156 return -1;
21642157
21652158 if (sd->entry->se_collapse)
2166− sort__need_collapse = 1;
2159+ list->need_collapse = 1;
21672160
21682161 sd->taken = 1;
21692162
@@ -2245,9 +2238,9 @@ static int sort_dimension__add(struct perf_hpp_list *list, const char *tok, · 75 unmodified lines
22452238 pr_err("Invalid regex: %s\n%s", parent_pattern, err);
22462239 return -EINVAL;
22472240 }
2248− sort__has_parent = 1;
2241+ list->parent = 1;
22492242 } else if (sd->entry == &sort_sym) {
2250− sort__has_sym = 1;
2243+ list->sym = 1;
22512244 /*
22522245 * perf diff displays the performance difference amongst
22532246 * two or more perf.data files. Those files could come
@@ -2258,13 +2251,13 @@ static int sort_dimension__add(struct perf_hpp_list *list, const char *tok, · 4 unmodified lines
22582251 sd->entry->se_collapse = sort__sym_sort;
22592252
22602253 } else if (sd->entry == &sort_dso) {
2261− sort__has_dso = 1;
2254+ list->dso = 1;
22622255 } else if (sd->entry == &sort_socket) {
2263− sort__has_socket = 1;
2256+ list->socket = 1;
22642257 } else if (sd->entry == &sort_thread) {
2265− sort__has_thread = 1;
2258+ list->thread = 1;
22662259 } else if (sd->entry == &sort_comm) {
2267− sort__has_comm = 1;
2260+ list->comm = 1;
22682261 }
22692262
22702263 return __sort_dimension__add(sd, list, level);
@@ -2289,7 +2282,7 @@ static int sort_dimension__add(struct perf_hpp_list *list, const char *tok, · 18 unmodified lines
22892282 return -EINVAL;
22902283
22912284 if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
2292− sort__has_sym = 1;
2285+ list->sym = 1;
22932286
22942287 __sort_dimension__add(sd, list, level);
22952288 return 0;
@@ -2305,7 +2298,7 @@ static int sort_dimension__add(struct perf_hpp_list *list, const char *tok, · 9 unmodified lines
23052298 return -EINVAL;
23062299
23072300 if (sd->entry == &sort_mem_daddr_sym)
2308− sort__has_sym = 1;
2301+ list->sym = 1;
23092302
23102303 __sort_dimension__add(sd, list, level);
23112304 return 0;
@@ -2749,10 +2742,10 @@ int setup_sorting(struct perf_evlist *evlist) · 437 unmodified lines
27492742
27502743 void reset_output_field(void)
27512744 {
2752− sort__need_collapse = 0;
2753− sort__has_parent = 0;
2754− sort__has_sym = 0;
2755− sort__has_dso = 0;
2745+ perf_hpp_list.need_collapse = 0;
2746+ perf_hpp_list.parent = 0;
2747+ perf_hpp_list.sym = 0;
2748+ perf_hpp_list.dso = 0;
27562749
27572750 field_order = NULL;
27582751 sort_order = NULL;
tools/perf/util/sort.h+0−7
@@ -31,13 +31,6 @@ extern const char *parent_pattern; · 30 unmodified lines
3131 extern const char default_sort_order[];
3232 extern regex_t ignore_callees_regex;
3333 extern int have_ignore_callees;
34−extern int sort__need_collapse;
35−extern int sort__has_dso;
36−extern int sort__has_parent;
37−extern int sort__has_sym;
38−extern int sort__has_socket;
39−extern int sort__has_thread;
40−extern int sort__has_comm;
4134 extern enum sort_mode sort__mode;
4235 extern struct sort_entry sort_comm;
4336 extern struct sort_entry sort_dso;
tools/perf/util/stat.c+3−1
@@ -307,6 +307,7 @@ int perf_stat_process_counter(struct perf_stat_config *config, · 306 unmodified lines
307307 struct perf_counts_values *aggr = &counter->counts->aggr;
308308 struct perf_stat_evsel *ps = counter->priv;
309309 u64 *count = counter->counts->aggr.values;
310+ u64 val;
310311 int i, ret;
311312
312313 aggr->val = aggr->ena = aggr->run = 0;
@@ -346,7 +347,8 @@ int perf_stat_process_counter(struct perf_stat_config *config, · 33 unmodified lines
346347 /*
347348 * Save the full runtime - to allow normalization during printout:
348349 */
349− perf_stat__update_shadow_stats(counter, count, 0);
350+ val = counter->scale * *count;
351+ perf_stat__update_shadow_stats(counter, &val, 0);
350352
351353 return 0;
352354 }
tools/perf/util/strbuf.c+67−26
@@ -1,3 +1,4 @@
1+#include "debug.h"
12 #include "cache.h"
23 #include <linux/kernel.h>
34
@@ -17,12 +18,13 @@ int prefixcmp(const char *str, const char *prefix) · 13 unmodified lines
1718 */
1819 char strbuf_slopbuf[1];
1920
20−void strbuf_init(struct strbuf *sb, ssize_t hint)
21+int strbuf_init(struct strbuf *sb, ssize_t hint)
2122 {
2223 sb->alloc = sb->len = 0;
2324 sb->buf = strbuf_slopbuf;
2425 if (hint)
25− strbuf_grow(sb, hint);
26+ return strbuf_grow(sb, hint);
27+ return 0;
2628 }
2729
2830 void strbuf_release(struct strbuf *sb)
@@ -42,67 +44,104 @@ char *strbuf_detach(struct strbuf *sb, size_t *sz) · 13 unmodified lines
4244 return res;
4345 }
4446
45−void strbuf_grow(struct strbuf *sb, size_t extra)
47+int strbuf_grow(struct strbuf *sb, size_t extra)
4648 {
47− if (sb->len + extra + 1 <= sb->len)
48− die("you want to use way too much memory");
49− if (!sb->alloc)
50− sb->buf = NULL;
51− ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
49+ char *buf;
50+ size_t nr = sb->len + extra + 1;
51+
52+ if (nr < sb->alloc)
53+ return 0;
54+
55+ if (nr <= sb->len)
56+ return -E2BIG;
57+
58+ if (alloc_nr(sb->alloc) > nr)
59+ nr = alloc_nr(sb->alloc);
60+
61+ /*
62+ * Note that sb->buf == strbuf_slopbuf if sb->alloc == 0, and it is
63+ * a static variable. Thus we have to avoid passing it to realloc.
64+ */
65+ buf = realloc(sb->alloc ? sb->buf : NULL, nr * sizeof(*buf));
66+ if (!buf)
67+ return -ENOMEM;
68+
69+ sb->buf = buf;
70+ sb->alloc = nr;
71+ return 0;
5272 }
5373
54−void strbuf_addch(struct strbuf *sb, int c)
74+int strbuf_addch(struct strbuf *sb, int c)
5575 {
56− strbuf_grow(sb, 1);
76+ int ret = strbuf_grow(sb, 1);
77+ if (ret)
78+ return ret;
79+
5780 sb->buf[sb->len++] = c;
5881 sb->buf[sb->len] = '\0';
82+ return 0;
5983 }
6084
61−void strbuf_add(struct strbuf *sb, const void *data, size_t len)
85+int strbuf_add(struct strbuf *sb, const void *data, size_t len)
6286 {
63− strbuf_grow(sb, len);
87+ int ret = strbuf_grow(sb, len);
88+ if (ret)
89+ return ret;
90+
6491 memcpy(sb->buf + sb->len, data, len);
65− strbuf_setlen(sb, sb->len + len);
92+ return strbuf_setlen(sb, sb->len + len);
6693 }
6794
68−static void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
95+static int strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
6996 {
70− int len;
97+ int len, ret;
7198 va_list ap_saved;
7299
73− if (!strbuf_avail(sb))
74− strbuf_grow(sb, 64);
100+ if (!strbuf_avail(sb)) {
101+ ret = strbuf_grow(sb, 64);
102+ if (ret)
103+ return ret;
104+ }
75105
76106 va_copy(ap_saved, ap);
77107 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
78108 if (len < 0)
79− die("your vsnprintf is broken");
109+ return len;
80110 if (len > strbuf_avail(sb)) {
81− strbuf_grow(sb, len);
111+ ret = strbuf_grow(sb, len);
112+ if (ret)
113+ return ret;
82114 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
83115 va_end(ap_saved);
84116 if (len > strbuf_avail(sb)) {
85− die("this should not happen, your vsnprintf is broken");
117+ pr_debug("this should not happen, your vsnprintf is broken");
118+ return -EINVAL;
86119 }
87120 }
88− strbuf_setlen(sb, sb->len + len);
121+ return strbuf_setlen(sb, sb->len + len);
89122 }
90123
91−void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
124+int strbuf_addf(struct strbuf *sb, const char *fmt, ...)
92125 {
93126 va_list ap;
127+ int ret;
94128
95129 va_start(ap, fmt);
96− strbuf_addv(sb, fmt, ap);
130+ ret = strbuf_addv(sb, fmt, ap);
97131 va_end(ap);
132+ return ret;
98133 }
99134
100135 ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
101136 {
102137 size_t oldlen = sb->len;
103138 size_t oldalloc = sb->alloc;
139+ int ret;
140+
141+ ret = strbuf_grow(sb, hint ? hint : 8192);
142+ if (ret)
143+ return ret;
104144
105− strbuf_grow(sb, hint ? hint : 8192);
106145 for (;;) {
107146 ssize_t cnt;
108147
@@ -112,12 +151,14 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) · 3 unmodified lines
112151 strbuf_release(sb);
113152 else
114153 strbuf_setlen(sb, oldlen);
115− return -1;
154+ return cnt;
116155 }
117156 if (!cnt)
118157 break;
119158 sb->len += cnt;
120− strbuf_grow(sb, 8192);
159+ ret = strbuf_grow(sb, 8192);
160+ if (ret)
161+ return ret;
121162 }
122163
123164 sb->buf[sb->len] = '\0';
tools/perf/util/strbuf.h+15−10
@@ -51,7 +51,7 @@ struct strbuf { · 50 unmodified lines
5151 #define STRBUF_INIT { 0, 0, strbuf_slopbuf }
5252
5353 /*----- strbuf life cycle -----*/
54−void strbuf_init(struct strbuf *buf, ssize_t hint);
54+int strbuf_init(struct strbuf *buf, ssize_t hint);
5555 void strbuf_release(struct strbuf *buf);
5656 char *strbuf_detach(struct strbuf *buf, size_t *);
5757
@@ -60,26 +60,31 @@ static inline ssize_t strbuf_avail(const struct strbuf *sb) { · 2 unmodified lines
6060 return sb->alloc ? sb->alloc - sb->len - 1 : 0;
6161 }
6262
63−void strbuf_grow(struct strbuf *buf, size_t);
63+int strbuf_grow(struct strbuf *buf, size_t);
6464
65−static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
66− if (!sb->alloc)
67− strbuf_grow(sb, 0);
65+static inline int strbuf_setlen(struct strbuf *sb, size_t len) {
66+ int ret;
67+ if (!sb->alloc) {
68+ ret = strbuf_grow(sb, 0);
69+ if (ret)
70+ return ret;
71+ }
6872 assert(len < sb->alloc);
6973 sb->len = len;
7074 sb->buf[len] = '\0';
75+ return 0;
7176 }
7277
7378 /*----- add data in your buffer -----*/
74−void strbuf_addch(struct strbuf *sb, int c);
79+int strbuf_addch(struct strbuf *sb, int c);
7580
76−void strbuf_add(struct strbuf *buf, const void *, size_t);
77−static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
78− strbuf_add(sb, s, strlen(s));
81+int strbuf_add(struct strbuf *buf, const void *, size_t);
82+static inline int strbuf_addstr(struct strbuf *sb, const char *s) {
83+ return strbuf_add(sb, s, strlen(s));
7984 }
8085
8186 __attribute__((format(printf,2,3)))
82−void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
87+int strbuf_addf(struct strbuf *sb, const char *fmt, ...);
8388
8489 /* XXX: if read fails, any partial read is undone */
8590 ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
tools/perf/util/symbol-elf.c+7−13
@@ -709,17 +709,10 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, · 708 unmodified lines
709709 if (ss->opdshdr.sh_type != SHT_PROGBITS)
710710 ss->opdsec = NULL;
711711
712− if (dso->kernel == DSO_TYPE_USER) {
713− GElf_Shdr shdr;
714− ss->adjust_symbols = (ehdr.e_type == ET_EXEC ||
715− ehdr.e_type == ET_REL ||
716− dso__is_vdso(dso) ||
717− elf_section_by_name(elf, &ehdr, &shdr,
718− ".gnu.prelink_undo",
719− NULL) != NULL);
720− } else {
712+ if (dso->kernel == DSO_TYPE_USER)
713+ ss->adjust_symbols = true;
714+ else
721715 ss->adjust_symbols = elf__needs_adjust_symbols(ehdr);
722− }
723716
724717 ss->name = strdup(name);
725718 if (!ss->name) {
@@ -777,7 +770,8 @@ static bool want_demangle(bool is_kernel_sym) · 51 unmodified lines
777770 return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
778771 }
779772
780−void __weak arch__elf_sym_adjust(GElf_Sym *sym __maybe_unused) { }
773+void __weak arch__sym_update(struct symbol *s __maybe_unused,
774+ GElf_Sym *sym __maybe_unused) { }
781775
782776 int dso__load_sym(struct dso *dso, struct map *map,
783777 struct symsrc *syms_ss, struct symsrc *runtime_ss,
@@ -954,8 +948,6 @@ int dso__load_sym(struct dso *dso, struct map *map, · 170 unmodified lines
954948 (sym.st_value & 1))
955949 --sym.st_value;
956950
957− arch__elf_sym_adjust(&sym);
958−
959951 if (dso->kernel || kmodule) {
960952 char dso_name[PATH_MAX];
961953
@@ -1089,6 +1081,8 @@ new_symbol: · 127 unmodified lines
10891081 if (!f)
10901082 goto out_elf_end;
10911083
1084+ arch__sym_update(f, &sym);
1085+
10921086 if (filter && filter(curr_map, f))
10931087 symbol__delete(f);
10941088 else {
tools/perf/util/symbol.c+37−71
@@ -255,40 +255,6 @@ void symbol__delete(struct symbol *sym) · 254 unmodified lines
255255 free(((void *)sym) - symbol_conf.priv_size);
256256 }
257257
258−size_t symbol__fprintf(struct symbol *sym, FILE *fp)
259−{
260− return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
261− sym->start, sym->end,
262− sym->binding == STB_GLOBAL ? 'g' :
263− sym->binding == STB_LOCAL ? 'l' : 'w',
264− sym->name);
265−}
266−
267−size_t symbol__fprintf_symname_offs(const struct symbol *sym,
268− const struct addr_location *al, FILE *fp)
269−{
270− unsigned long offset;
271− size_t length;
272−
273− if (sym && sym->name) {
274− length = fprintf(fp, "%s", sym->name);
275− if (al) {
276− if (al->addr < sym->end)
277− offset = al->addr - sym->start;
278− else
279− offset = al->addr - al->map->start - sym->start;
280− length += fprintf(fp, "+0x%lx", offset);
281− }
282− return length;
283− } else
284− return fprintf(fp, "[unknown]");
285−}
286−
287−size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
288−{
289− return symbol__fprintf_symname_offs(sym, NULL, fp);
290−}
291−
292258 void symbols__delete(struct rb_root *symbols)
293259 {
294260 struct symbol *pos;
@@ -335,7 +301,7 @@ static struct symbol *symbols__find(struct rb_root *symbols, u64 ip) · 40 unmodified lines
335301
336302 if (ip < s->start)
337303 n = n->rb_left;
338− else if (ip >= s->end)
304+ else if (ip > s->end || (ip == s->end && ip != s->start))
339305 n = n->rb_right;
340306 else
341307 return s;
@@ -364,11 +330,6 @@ static struct symbol *symbols__next(struct symbol *sym) · 22 unmodified lines
364330 return NULL;
365331 }
366332
367−struct symbol_name_rb_node {
368− struct rb_node rb_node;
369− struct symbol sym;
370−};
371−
372333 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
373334 {
374335 struct rb_node **p = &symbols->rb_node;
@@ -452,6 +413,18 @@ void dso__reset_find_symbol_cache(struct dso *dso) · 77 unmodified lines
452413 }
453414 }
454415
416+void dso__insert_symbol(struct dso *dso, enum map_type type, struct symbol *sym)
417+{
418+ symbols__insert(&dso->symbols[type], sym);
419+
420+ /* update the symbol cache if necessary */
421+ if (dso->last_find_result[type].addr >= sym->start &&
422+ (dso->last_find_result[type].addr < sym->end ||
423+ sym->start == sym->end)) {
424+ dso->last_find_result[type].symbol = sym;
425+ }
426+}
427+
455428 struct symbol *dso__find_symbol(struct dso *dso,
456429 enum map_type type, u64 addr)
457430 {
@@ -497,21 +470,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type) · 39 unmodified lines
497470 &dso->symbols[type]);
498471 }
499472
500−size_t dso__fprintf_symbols_by_name(struct dso *dso,
501− enum map_type type, FILE *fp)
502−{
503− size_t ret = 0;
504− struct rb_node *nd;
505− struct symbol_name_rb_node *pos;
506−
507− for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
508− pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
509− fprintf(fp, "%s\n", pos->sym.name);
510− }
511−
512− return ret;
513−}
514−
515473 int modules__parse(const char *filename, void *arg,
516474 int (*process_module)(void *arg, const char *name,
517475 u64 start))
@@ -1262,8 +1220,8 @@ static int kallsyms__delta(struct map *map, const char *filename, u64 *delta) · 744 unmodified lines
12621220 return 0;
12631221 }
12641222
1265−int dso__load_kallsyms(struct dso *dso, const char *filename,
1266− struct map *map, symbol_filter_t filter)
1223+int __dso__load_kallsyms(struct dso *dso, const char *filename,
1224+ struct map *map, bool no_kcore, symbol_filter_t filter)
12671225 {
12681226 u64 delta = 0;
12691227
@@ -1284,12 +1242,18 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, · 14 unmodified lines
12841242 else
12851243 dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
12861244
1287− if (!dso__load_kcore(dso, map, filename))
1245+ if (!no_kcore && !dso__load_kcore(dso, map, filename))
12881246 return dso__split_kallsyms_for_kcore(dso, map, filter);
12891247 else
12901248 return dso__split_kallsyms(dso, map, delta, filter);
12911249 }
12921250
1251+int dso__load_kallsyms(struct dso *dso, const char *filename,
1252+ struct map *map, symbol_filter_t filter)
1253+{
1254+ return __dso__load_kallsyms(dso, filename, map, false, filter);
1255+}
1256+
12931257 static int dso__load_perf_map(struct dso *dso, struct map *map,
12941258 symbol_filter_t filter)
12951259 {
@@ -1644,25 +1608,27 @@ out: · 348 unmodified lines
16441608 return err;
16451609 }
16461610
1611+static bool visible_dir_filter(const char *name, struct dirent *d)
1612+{
1613+ if (d->d_type != DT_DIR)
1614+ return false;
1615+ return lsdir_no_dot_filter(name, d);
1616+}
1617+
16471618 static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
16481619 {
16491620 char kallsyms_filename[PATH_MAX];
1650− struct dirent *dent;
16511621 int ret = -1;
1652− DIR *d;
1622+ struct strlist *dirs;
1623+ struct str_node *nd;
16531624
1654− d = opendir(dir);
1655− if (!d)
1625+ dirs = lsdir(dir, visible_dir_filter);
1626+ if (!dirs)
16561627 return -1;
16571628
1658− while (1) {
1659− dent = readdir(d);
1660− if (!dent)
1661− break;
1662− if (dent->d_type != DT_DIR)
1663− continue;
1629+ strlist__for_each(nd, dirs) {
16641630 scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
1665− "%s/%s/kallsyms", dir, dent->d_name);
1631+ "%s/%s/kallsyms", dir, nd->s);
16661632 if (!validate_kcore_addresses(kallsyms_filename, map)) {
16671633 strlcpy(dir, kallsyms_filename, dir_sz);
16681634 ret = 0;
@@ -1670,7 +1636,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz) · 1 unmodified line
16701636 }
16711637 }
16721638
1673− closedir(d);
1639+ strlist__delete(dirs);
16741640
16751641 return ret;
16761642 }
@@ -1678,7 +1644,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz) · 1 unmodified line
16781644 static char *dso__find_kallsyms(struct dso *dso, struct map *map)
16791645 {
16801646 u8 host_build_id[BUILD_ID_SIZE];
1681− char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1647+ char sbuild_id[SBUILD_ID_SIZE];
16821648 bool is_host = false;
16831649 char path[PATH_MAX];
16841650
tools/perf/util/symbol.h+18−1
@@ -55,6 +55,7 @@ struct symbol { · 54 unmodified lines
5555 u16 namelen;
5656 u8 binding;
5757 bool ignore;
58+ u8 arch_sym;
5859 char name[0];
5960 };
6061
@@ -140,6 +141,11 @@ struct symbol_conf { · 79 unmodified lines
140141
141142 extern struct symbol_conf symbol_conf;
142143
144+struct symbol_name_rb_node {
145+ struct rb_node rb_node;
146+ struct symbol sym;
147+};
148+
143149 static inline int __symbol__join_symfs(char *bf, size_t size, const char *path)
144150 {
145151 return path__join(bf, size, symbol_conf.symfs, path);
@@ -235,9 +241,14 @@ int dso__load_vmlinux(struct dso *dso, struct map *map, · 89 unmodified lines
235241 symbol_filter_t filter);
236242 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
237243 symbol_filter_t filter);
244+int __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
245+ bool no_kcore, symbol_filter_t filter);
238246 int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
239247 symbol_filter_t filter);
240248
249+void dso__insert_symbol(struct dso *dso, enum map_type type,
250+ struct symbol *sym);
251+
241252 struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
242253 u64 addr);
243254 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
@@ -262,8 +273,14 @@ int symbol__init(struct perf_env *env); · 18 unmodified lines
262273 void symbol__exit(void);
263274 void symbol__elf_init(void);
264275 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name);
276+size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
277+ const struct addr_location *al,
278+ bool unknown_as_addr, FILE *fp);
265279 size_t symbol__fprintf_symname_offs(const struct symbol *sym,
266280 const struct addr_location *al, FILE *fp);
281+size_t __symbol__fprintf_symname(const struct symbol *sym,
282+ const struct addr_location *al,
283+ bool unknown_as_addr, FILE *fp);
267284 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
268285 size_t symbol__fprintf(struct symbol *sym, FILE *fp);
269286 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
@@ -310,7 +327,7 @@ int setup_intlist(struct intlist **list, const char *list_str, · 40 unmodified lines
310327
311328 #ifdef HAVE_LIBELF_SUPPORT
312329 bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
313−void arch__elf_sym_adjust(GElf_Sym *sym);
330+void arch__sym_update(struct symbol *s, GElf_Sym *sym);
314331 #endif
315332
316333 #define SYMBOL_A 0
tools/perf/util/symbol_fprintf.c+71−0
@@ -0,0 +1,71 @@
1+#include <elf.h>
2+#include <inttypes.h>
3+#include <stdio.h>
4+
5+#include "symbol.h"
6+
7+size_t symbol__fprintf(struct symbol *sym, FILE *fp)
8+{
9+ return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
10+ sym->start, sym->end,
11+ sym->binding == STB_GLOBAL ? 'g' :
12+ sym->binding == STB_LOCAL ? 'l' : 'w',
13+ sym->name);
14+}
15+
16+size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
17+ const struct addr_location *al,
18+ bool unknown_as_addr, FILE *fp)
19+{
20+ unsigned long offset;
21+ size_t length;
22+
23+ if (sym && sym->name) {
24+ length = fprintf(fp, "%s", sym->name);
25+ if (al) {
26+ if (al->addr < sym->end)
27+ offset = al->addr - sym->start;
28+ else
29+ offset = al->addr - al->map->start - sym->start;
30+ length += fprintf(fp, "+0x%lx", offset);
31+ }
32+ return length;
33+ } else if (al && unknown_as_addr)
34+ return fprintf(fp, "[%#" PRIx64 "]", al->addr);
35+ else
36+ return fprintf(fp, "[unknown]");
37+}
38+
39+size_t symbol__fprintf_symname_offs(const struct symbol *sym,
40+ const struct addr_location *al,
41+ FILE *fp)
42+{
43+ return __symbol__fprintf_symname_offs(sym, al, false, fp);
44+}
45+
46+size_t __symbol__fprintf_symname(const struct symbol *sym,
47+ const struct addr_location *al,
48+ bool unknown_as_addr, FILE *fp)
49+{
50+ return __symbol__fprintf_symname_offs(sym, al, unknown_as_addr, fp);
51+}
52+
53+size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
54+{
55+ return __symbol__fprintf_symname_offs(sym, NULL, false, fp);
56+}
57+
58+size_t dso__fprintf_symbols_by_name(struct dso *dso,
59+ enum map_type type, FILE *fp)
60+{
61+ size_t ret = 0;
62+ struct rb_node *nd;
63+ struct symbol_name_rb_node *pos;
64+
65+ for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
66+ pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
67+ fprintf(fp, "%s\n", pos->sym.name);
68+ }
69+
70+ return ret;
71+}
tools/perf/util/syscalltbl.c+134−0
@@ -0,0 +1,134 @@
1+/*
2+ * System call table mapper
3+ *
4+ * (C) 2016 Arnaldo Carvalho de Melo <acme@redhat.com>
5+ *
6+ * This program is free software; you can redistribute it and/or modify it
7+ * under the terms and conditions of the GNU General Public License,
8+ * version 2, as published by the Free Software Foundation.
9+ *
10+ * This program is distributed in the hope it will be useful, but WITHOUT
11+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13+ * more details.
14+ */
15+
16+#include "syscalltbl.h"
17+#include <stdlib.h>
18+
19+#ifdef HAVE_SYSCALL_TABLE
20+#include <linux/compiler.h>
21+#include <string.h>
22+#include "util.h"
23+
24+#if defined(__x86_64__)
25+#include <asm/syscalls_64.c>
26+const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
27+static const char **syscalltbl_native = syscalltbl_x86_64;
28+#endif
29+
30+struct syscall {
31+ int id;
32+ const char *name;
33+};
34+
35+static int syscallcmpname(const void *vkey, const void *ventry)
36+{
37+ const char *key = vkey;
38+ const struct syscall *entry = ventry;
39+
40+ return strcmp(key, entry->name);
41+}
42+
43+static int syscallcmp(const void *va, const void *vb)
44+{
45+ const struct syscall *a = va, *b = vb;
46+
47+ return strcmp(a->name, b->name);
48+}
49+
50+static int syscalltbl__init_native(struct syscalltbl *tbl)
51+{
52+ int nr_entries = 0, i, j;
53+ struct syscall *entries;
54+
55+ for (i = 0; i <= syscalltbl_native_max_id; ++i)
56+ if (syscalltbl_native[i])
57+ ++nr_entries;
58+
59+ entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
60+ if (tbl->syscalls.entries == NULL)
61+ return -1;
62+
63+ for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
64+ if (syscalltbl_native[i]) {
65+ entries[j].name = syscalltbl_native[i];
66+ entries[j].id = i;
67+ ++j;
68+ }
69+ }
70+
71+ qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
72+ tbl->syscalls.nr_entries = nr_entries;
73+ return 0;
74+}
75+
76+struct syscalltbl *syscalltbl__new(void)
77+{
78+ struct syscalltbl *tbl = malloc(sizeof(*tbl));
79+ if (tbl) {
80+ if (syscalltbl__init_native(tbl)) {
81+ free(tbl);
82+ return NULL;
83+ }
84+ }
85+ return tbl;
86+}
87+
88+void syscalltbl__delete(struct syscalltbl *tbl)
89+{
90+ zfree(&tbl->syscalls.entries);
91+ free(tbl);
92+}
93+
94+const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
95+{
96+ return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
97+}
98+
99+int syscalltbl__id(struct syscalltbl *tbl, const char *name)
100+{
101+ struct syscall *sc = bsearch(name, tbl->syscalls.entries,
102+ tbl->syscalls.nr_entries, sizeof(*sc),
103+ syscallcmpname);
104+
105+ return sc ? sc->id : -1;
106+}
107+
108+#else /* HAVE_SYSCALL_TABLE */
109+
110+#include <libaudit.h>
111+
112+struct syscalltbl *syscalltbl__new(void)
113+{
114+ struct syscalltbl *tbl = malloc(sizeof(*tbl));
115+ if (tbl)
116+ tbl->audit_machine = audit_detect_machine();
117+ return tbl;
118+}
119+
120+void syscalltbl__delete(struct syscalltbl *tbl)
121+{
122+ free(tbl);
123+}
124+
125+const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
126+{
127+ return audit_syscall_to_name(id, tbl->audit_machine);
128+}
129+
130+int syscalltbl__id(struct syscalltbl *tbl, const char *name)
131+{
132+ return audit_name_to_syscall(name, tbl->audit_machine);
133+}
134+#endif /* HAVE_SYSCALL_TABLE */
tools/perf/util/syscalltbl.h+20−0
@@ -0,0 +1,20 @@
1+#ifndef __PERF_SYSCALLTBL_H
2+#define __PERF_SYSCALLTBL_H
3+
4+struct syscalltbl {
5+ union {
6+ int audit_machine;
7+ struct {
8+ int nr_entries;
9+ void *entries;
10+ } syscalls;
11+ };
12+};
13+
14+struct syscalltbl *syscalltbl__new(void);
15+void syscalltbl__delete(struct syscalltbl *tbl);
16+
17+const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
18+int syscalltbl__id(struct syscalltbl *tbl, const char *name);
19+
20+#endif /* __PERF_SYSCALLTBL_H */
tools/perf/util/thread-stack.c+1−138
@@ -22,44 +22,9 @@ · 21 unmodified lines
2222 #include "debug.h"
2323 #include "symbol.h"
2424 #include "comm.h"
25+#include "call-path.h"
2526 #include "thread-stack.h"
2627
27−#define CALL_PATH_BLOCK_SHIFT 8
28−#define CALL_PATH_BLOCK_SIZE (1 << CALL_PATH_BLOCK_SHIFT)
29−#define CALL_PATH_BLOCK_MASK (CALL_PATH_BLOCK_SIZE - 1)
30−
31−struct call_path_block {
32− struct call_path cp[CALL_PATH_BLOCK_SIZE];
33− struct list_head node;
34−};
35−
36−/**
37− * struct call_path_root - root of all call paths.
38− * @call_path: root call path
39− * @blocks: list of blocks to store call paths
40− * @next: next free space
41− * @sz: number of spaces
42− */
43−struct call_path_root {
44− struct call_path call_path;
45− struct list_head blocks;
46− size_t next;
47− size_t sz;
48−};
49−
50−/**
51− * struct call_return_processor - provides a call-back to consume call-return
52− * information.
53− * @cpr: call path root
54− * @process: call-back that accepts call/return information
55− * @data: anonymous data for call-back
56− */
57−struct call_return_processor {
58− struct call_path_root *cpr;
59− int (*process)(struct call_return *cr, void *data);
60− void *data;
61−};
62−
6328 #define STACK_GROWTH 2048
6429
6530 /**
@@ -335,108 +300,6 @@ void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, · 269 unmodified lines
335300 chain->ips[i] = thread->ts->stack[thread->ts->cnt - i].ret_addr;
336301 }
337302
338−static void call_path__init(struct call_path *cp, struct call_path *parent,
339− struct symbol *sym, u64 ip, bool in_kernel)
340−{
341− cp->parent = parent;
342− cp->sym = sym;
343− cp->ip = sym ? 0 : ip;
344− cp->db_id = 0;
345− cp->in_kernel = in_kernel;
346− RB_CLEAR_NODE(&cp->rb_node);
347− cp->children = RB_ROOT;
348−}
349−
350−static struct call_path_root *call_path_root__new(void)
351−{
352− struct call_path_root *cpr;
353−
354− cpr = zalloc(sizeof(struct call_path_root));
355− if (!cpr)
356− return NULL;
357− call_path__init(&cpr->call_path, NULL, NULL, 0, false);
358− INIT_LIST_HEAD(&cpr->blocks);
359− return cpr;
360−}
361−
362−static void call_path_root__free(struct call_path_root *cpr)
363−{
364− struct call_path_block *pos, *n;
365−
366− list_for_each_entry_safe(pos, n, &cpr->blocks, node) {
367− list_del(&pos->node);
368− free(pos);
369− }
370− free(cpr);
371−}
372−
373−static struct call_path *call_path__new(struct call_path_root *cpr,
374− struct call_path *parent,
375− struct symbol *sym, u64 ip,
376− bool in_kernel)
377−{
378− struct call_path_block *cpb;
379− struct call_path *cp;
380− size_t n;
381−
382− if (cpr->next < cpr->sz) {
383− cpb = list_last_entry(&cpr->blocks, struct call_path_block,
384− node);
385− } else {
386− cpb = zalloc(sizeof(struct call_path_block));
387− if (!cpb)
388− return NULL;
389− list_add_tail(&cpb->node, &cpr->blocks);
390− cpr->sz += CALL_PATH_BLOCK_SIZE;
391− }
392−
393− n = cpr->next++ & CALL_PATH_BLOCK_MASK;
394− cp = &cpb->cp[n];
395−
396− call_path__init(cp, parent, sym, ip, in_kernel);
397−
398− return cp;
399−}
400−
401−static struct call_path *call_path__findnew(struct call_path_root *cpr,
402− struct call_path *parent,
403− struct symbol *sym, u64 ip, u64 ks)
404−{
405− struct rb_node **p;
406− struct rb_node *node_parent = NULL;
407− struct call_path *cp;
408− bool in_kernel = ip >= ks;
409−
410− if (sym)
411− ip = 0;
412−
413− if (!parent)
414− return call_path__new(cpr, parent, sym, ip, in_kernel);
415−
416− p = &parent->children.rb_node;
417− while (*p != NULL) {
418− node_parent = *p;
419− cp = rb_entry(node_parent, struct call_path, rb_node);
420−
421− if (cp->sym == sym && cp->ip == ip)
422− return cp;
423−
424− if (sym < cp->sym || (sym == cp->sym && ip < cp->ip))
425− p = &(*p)->rb_left;
426− else
427− p = &(*p)->rb_right;
428− }
429−
430− cp = call_path__new(cpr, parent, sym, ip, in_kernel);
431− if (!cp)
432− return NULL;
433−
434− rb_link_node(&cp->rb_node, node_parent, p);
435− rb_insert_color(&cp->rb_node, &parent->children);
436−
437− return cp;
438−}
439−
440303 struct call_return_processor *
441304 call_return_processor__new(int (*process)(struct call_return *cr, void *data),
442305 void *data)
tools/perf/util/thread-stack.h+10−21
@@ -19,17 +19,16 @@ · 18 unmodified lines
1919 #include <sys/types.h>
2020
2121 #include <linux/types.h>
22−#include <linux/rbtree.h>
2322
2423 struct thread;
2524 struct comm;
2625 struct ip_callchain;
2726 struct symbol;
2827 struct dso;
29−struct call_return_processor;
3028 struct comm;
3129 struct perf_sample;
3230 struct addr_location;
31+struct call_path;
3332
3433 /*
3534 * Call/Return flags.
@@ -69,26 +68,16 @@ struct call_return { · 33 unmodified lines
6968 };
7069
7170 /**
72− * struct call_path - node in list of calls leading to a function call.
73− * @parent: call path to the parent function call
74− * @sym: symbol of function called
75− * @ip: only if sym is null, the ip of the function
76− * @db_id: id used for db-export
77− * @in_kernel: whether function is a in the kernel
78− * @rb_node: node in parent's tree of called functions
79− * @children: tree of call paths of functions called
80− *
81− * In combination with the call_return structure, the call_path structure
82− * defines a context-sensitve call-graph.
71+ * struct call_return_processor - provides a call-back to consume call-return
72+ * information.
73+ * @cpr: call path root
74+ * @process: call-back that accepts call/return information
75+ * @data: anonymous data for call-back
8376 */
84−struct call_path {
85− struct call_path *parent;
86− struct symbol *sym;
87− u64 ip;
88− u64 db_id;
89− bool in_kernel;
90− struct rb_node rb_node;
91− struct rb_root children;
77+struct call_return_processor {
78+ struct call_path_root *cpr;
79+ int (*process)(struct call_return *cr, void *data);
80+ void *data;
9281 };
9382
9483 int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip,
tools/perf/util/thread.c+20−1
@@ -10,6 +10,8 @@ · 9 unmodified lines
1010 #include "comm.h"
1111 #include "unwind.h"
1212
13+#include <api/fs/fs.h>
14+
1315 int thread__init_map_groups(struct thread *thread, struct machine *machine)
1416 {
1517 struct thread *leader;
@@ -153,6 +155,23 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, · 137 unmodified lines
153155 return 0;
154156 }
155157
158+int thread__set_comm_from_proc(struct thread *thread)
159+{
160+ char path[64];
161+ char *comm = NULL;
162+ size_t sz;
163+ int err = -1;
164+
165+ if (!(snprintf(path, sizeof(path), "%d/task/%d/comm",
166+ thread->pid_, thread->tid) >= (int)sizeof(path)) &&
167+ procfs__read_str(path, &comm, &sz) == 0) {
168+ comm[sz - 1] = '\0';
169+ err = thread__set_comm(thread, comm, 0);
170+ }
171+
172+ return err;
173+}
174+
156175 const char *thread__comm_str(const struct thread *thread)
157176 {
158177 const struct comm *comm = thread__comm(thread);
@@ -233,7 +252,7 @@ void thread__find_cpumode_addr_location(struct thread *thread, · 74 unmodified lines
233252 struct addr_location *al)
234253 {
235254 size_t i;
236− const u8 const cpumodes[] = {
255+ const u8 cpumodes[] = {
237256 PERF_RECORD_MISC_USER,
238257 PERF_RECORD_MISC_KERNEL,
239258 PERF_RECORD_MISC_GUEST_USER,
tools/perf/util/thread.h+8−0
@@ -9,6 +9,9 @@ · 8 unmodified lines
99 #include "symbol.h"
1010 #include <strlist.h>
1111 #include <intlist.h>
12+#ifdef HAVE_LIBUNWIND_SUPPORT
13+#include <libunwind.h>
14+#endif
1215
1316 struct thread_stack;
1417
@@ -32,6 +35,9 @@ struct thread { · 17 unmodified lines
3235
3336 void *priv;
3437 struct thread_stack *ts;
38+#ifdef HAVE_LIBUNWIND_SUPPORT
39+ unw_addr_space_t addr_space;
40+#endif
3541 };
3642
3743 struct machine;
@@ -65,6 +71,8 @@ static inline int thread__set_comm(struct thread *thread, const char *comm, · 27 unmodified lines
6571 return __thread__set_comm(thread, comm, timestamp, false);
6672 }
6773
74+int thread__set_comm_from_proc(struct thread *thread);
75+
6876 int thread__comm_len(struct thread *thread);
6977 struct comm *thread__comm(const struct thread *thread);
7078 struct comm *thread__exec_comm(const struct thread *thread);
tools/perf/util/thread_map.c+13−1
@@ -260,7 +260,7 @@ struct thread_map *thread_map__new_dummy(void) · 259 unmodified lines
260260 return threads;
261261 }
262262
263−static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
263+struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
264264 {
265265 struct thread_map *threads = NULL, *nt;
266266 int ntasks = 0;
@@ -436,3 +436,15 @@ struct thread_map *thread_map__new_event(struct thread_map_event *event) · 169 unmodified lines
436436
437437 return threads;
438438 }
439+
440+bool thread_map__has(struct thread_map *threads, pid_t pid)
441+{
442+ int i;
443+
444+ for (i = 0; i < threads->nr; ++i) {
445+ if (threads->map[i].pid == pid)
446+ return true;
447+ }
448+
449+ return false;
450+}
tools/perf/util/thread_map.h+3−0
@@ -31,6 +31,8 @@ void thread_map__put(struct thread_map *map); · 30 unmodified lines
3131 struct thread_map *thread_map__new_str(const char *pid,
3232 const char *tid, uid_t uid);
3333
34+struct thread_map *thread_map__new_by_tid_str(const char *tid_str);
35+
3436 size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
3537
3638 static inline int thread_map__nr(struct thread_map *threads)
@@ -55,4 +57,5 @@ static inline char *thread_map__comm(struct thread_map *map, int thread) · 18 unmodified lines
5557 }
5658
5759 void thread_map__read_comms(struct thread_map *threads);
60+bool thread_map__has(struct thread_map *threads, pid_t pid);
5861 #endif /* __PERF_THREAD_MAP_H */
tools/perf/util/tool.h+1−0
@@ -57,6 +57,7 @@ struct perf_tool { · 56 unmodified lines
5757 id_index,
5858 auxtrace_info,
5959 auxtrace_error,
60+ time_conv,
6061 thread_map,
6162 cpu_map,
6263 stat_config,
tools/perf/util/trigger.h+94−0
@@ -0,0 +1,94 @@
1+#ifndef __TRIGGER_H_
2+#define __TRIGGER_H_ 1
3+
4+#include "util/debug.h"
5+#include "asm/bug.h"
6+
7+/*
8+ * Use trigger to model operations which need to be executed when
9+ * an event (a signal, for example) is observed.
10+ *
11+ * States and transits:
12+ *
13+ *
14+ * OFF--(on)--> READY --(hit)--> HIT
15+ * ^ |
16+ * | (ready)
17+ * | |
18+ * \_____________/
19+ *
20+ * is_hit and is_ready are two key functions to query the state of
21+ * a trigger. is_hit means the event already happen; is_ready means the
22+ * trigger is waiting for the event.
23+ */
24+
25+struct trigger {
26+ volatile enum {
27+ TRIGGER_ERROR = -2,
28+ TRIGGER_OFF = -1,
29+ TRIGGER_READY = 0,
30+ TRIGGER_HIT = 1,
31+ } state;
32+ const char *name;
33+};
34+
35+#define TRIGGER_WARN_ONCE(t, exp) \
36+ WARN_ONCE(t->state != exp, "trigger '%s' state transist error: %d in %s()\n", \
37+ t->name, t->state, __func__)
38+
39+static inline bool trigger_is_available(struct trigger *t)
40+{
41+ return t->state >= 0;
42+}
43+
44+static inline bool trigger_is_error(struct trigger *t)
45+{
46+ return t->state <= TRIGGER_ERROR;
47+}
48+
49+static inline void trigger_on(struct trigger *t)
50+{
51+ TRIGGER_WARN_ONCE(t, TRIGGER_OFF);
52+ t->state = TRIGGER_READY;
53+}
54+
55+static inline void trigger_ready(struct trigger *t)
56+{
57+ if (!trigger_is_available(t))
58+ return;
59+ t->state = TRIGGER_READY;
60+}
61+
62+static inline void trigger_hit(struct trigger *t)
63+{
64+ if (!trigger_is_available(t))
65+ return;
66+ TRIGGER_WARN_ONCE(t, TRIGGER_READY);
67+ t->state = TRIGGER_HIT;
68+}
69+
70+static inline void trigger_off(struct trigger *t)
71+{
72+ if (!trigger_is_available(t))
73+ return;
74+ t->state = TRIGGER_OFF;
75+}
76+
77+static inline void trigger_error(struct trigger *t)
78+{
79+ t->state = TRIGGER_ERROR;
80+}
81+
82+static inline bool trigger_is_ready(struct trigger *t)
83+{
84+ return t->state == TRIGGER_READY;
85+}
86+
87+static inline bool trigger_is_hit(struct trigger *t)
88+{
89+ return t->state == TRIGGER_HIT;
90+}
91+
92+#define DEFINE_TRIGGER(n) \
93+struct trigger n = {.state = TRIGGER_OFF, .name = #n}
94+#endif
tools/perf/util/tsc.h+20−1
@@ -3,10 +3,29 @@ · 2 unmodified lines
33
44 #include <linux/types.h>
55
6−#include "../arch/x86/util/tsc.h"
6+#include "event.h"
7+
8+struct perf_tsc_conversion {
9+ u16 time_shift;
10+ u32 time_mult;
11+ u64 time_zero;
12+};
13+struct perf_event_mmap_page;
14+
15+int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
16+ struct perf_tsc_conversion *tc);
717
818 u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
919 u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
1020 u64 rdtsc(void);
1121
22+struct perf_event_mmap_page;
23+struct perf_tool;
24+struct machine;
25+
26+int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc,
27+ struct perf_tool *tool,
28+ perf_event__handler_t process,
29+ struct machine *machine);
30+
1231 #endif
tools/perf/util/unwind-libunwind.c+9−16
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 #include "symbol.h"
3333 #include "util.h"
3434 #include "debug.h"
35+#include "asm/bug.h"
3536
3637 extern int
3738 UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
@@ -580,43 +581,33 @@ static unw_accessors_t accessors = { · 542 unmodified lines
580581
581582 int unwind__prepare_access(struct thread *thread)
582583 {
583− unw_addr_space_t addr_space;
584−
585584 if (callchain_param.record_mode != CALLCHAIN_DWARF)
586585 return 0;
587586
588− addr_space = unw_create_addr_space(&accessors, 0);
589− if (!addr_space) {
587+ thread->addr_space = unw_create_addr_space(&accessors, 0);
588+ if (!thread->addr_space) {
590589 pr_err("unwind: Can't create unwind address space.\n");
591590 return -ENOMEM;
592591 }
593592
594− unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL);
595− thread__set_priv(thread, addr_space);
596−
593+ unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
597594 return 0;
598595 }
599596
600597 void unwind__flush_access(struct thread *thread)
601598 {
602− unw_addr_space_t addr_space;
603−
604599 if (callchain_param.record_mode != CALLCHAIN_DWARF)
605600 return;
606601
607− addr_space = thread__priv(thread);
608− unw_flush_cache(addr_space, 0, 0);
602+ unw_flush_cache(thread->addr_space, 0, 0);
609603 }
610604
611605 void unwind__finish_access(struct thread *thread)
612606 {
613− unw_addr_space_t addr_space;
614−
615607 if (callchain_param.record_mode != CALLCHAIN_DWARF)
616608 return;
617609
618− addr_space = thread__priv(thread);
619− unw_destroy_addr_space(addr_space);
610+ unw_destroy_addr_space(thread->addr_space);
620611 }
621612
622613 static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
@@ -639,7 +630,9 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, · 16 unmodified lines
639630 * unwind itself.
640631 */
641632 if (max_stack - 1 > 0) {
642− addr_space = thread__priv(ui->thread);
633+ WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
634+ addr_space = ui->thread->addr_space;
635+
643636 if (addr_space == NULL)
644637 return -1;
645638
tools/perf/util/util.c+36−2
@@ -33,6 +33,8 @@ struct callchain_param callchain_param = { · 32 unmodified lines
3333 unsigned int page_size;
3434 int cacheline_size;
3535
36+unsigned int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH;
37+
3638 bool test_attr__enabled;
3739
3840 bool perf_host = true;
@@ -117,6 +119,40 @@ int rm_rf(char *path) · 78 unmodified lines
117119 return rmdir(path);
118120 }
119121
122+/* A filter which removes dot files */
123+bool lsdir_no_dot_filter(const char *name __maybe_unused, struct dirent *d)
124+{
125+ return d->d_name[0] != '.';
126+}
127+
128+/* lsdir reads a directory and store it in strlist */
129+struct strlist *lsdir(const char *name,
130+ bool (*filter)(const char *, struct dirent *))
131+{
132+ struct strlist *list = NULL;
133+ DIR *dir;
134+ struct dirent *d;
135+
136+ dir = opendir(name);
137+ if (!dir)
138+ return NULL;
139+
140+ list = strlist__new(NULL, NULL);
141+ if (!list) {
142+ errno = ENOMEM;
143+ goto out;
144+ }
145+
146+ while ((d = readdir(dir)) != NULL) {
147+ if (!filter || filter(name, d))
148+ strlist__add(list, d->d_name);
149+ }
150+
151+out:
152+ closedir(dir);
153+ return list;
154+}
155+
120156 static int slow_copyfile(const char *from, const char *to)
121157 {
122158 int err = -1;
@@ -471,7 +507,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param) · 348 unmodified lines
471507 "needed for --call-graph fp\n");
472508 break;
473509
474−#ifdef HAVE_DWARF_UNWIND_SUPPORT
475510 /* Dwarf style */
476511 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
477512 const unsigned long default_stack_dump_size = 8192;
@@ -487,7 +522,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param) · 9 unmodified lines
487522 ret = get_stack_size(tok, &size);
488523 param->dump_size = size;
489524 }
490−#endif /* HAVE_DWARF_UNWIND_SUPPORT */
491525 } else if (!strncmp(name, "lbr", sizeof("lbr"))) {
492526 if (!strtok_r(NULL, ",", &saveptr)) {
493527 param->record_mode = CALLCHAIN_LBR;
tools/perf/util/util.h+9−6
@@ -79,6 +79,7 @@ · 78 unmodified lines
7979 #include <termios.h>
8080 #include <linux/bitops.h>
8181 #include <termios.h>
82+#include "strlist.h"
8283
8384 extern const char *graph_line;
8485 extern const char *graph_dotted_line;
@@ -159,12 +160,6 @@ static inline char *gitstrchrnul(const char *s, int c) · 74 unmodified lines
159160 }
160161 #endif
161162
162−/*
163− * Wrappers:
164− */
165−void *xrealloc(void *ptr, size_t size) __attribute__((weak));
166−
167−
168163 static inline void *zalloc(size_t size)
169164 {
170165 return calloc(1, size);
@@ -222,6 +217,8 @@ static inline int sane_case(int x, int high) · 51 unmodified lines
222217
223218 int mkdir_p(char *path, mode_t mode);
224219 int rm_rf(char *path);
220+struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *));
221+bool lsdir_no_dot_filter(const char *name, struct dirent *d);
225222 int copyfile(const char *from, const char *to);
226223 int copyfile_mode(const char *from, const char *to, mode_t mode);
227224 int copyfile_offset(int fromfd, loff_t from_ofs, int tofd, loff_t to_ofs, u64 size);
@@ -254,11 +251,17 @@ int hex2u64(const char *ptr, u64 *val); · 26 unmodified lines
254251 char *ltrim(char *s);
255252 char *rtrim(char *s);
256253
254+static inline char *trim(char *s)
255+{
256+ return ltrim(rtrim(s));
257+}
258+
257259 void dump_stack(void);
258260 void sighandler_dump_stack(int sig);
259261
260262 extern unsigned int page_size;
261263 extern int cacheline_size;
264+extern unsigned int sysctl_perf_event_max_stack;
262265
263266 struct parse_tag {
264267 char tag;
tools/perf/util/wrapper.c+0−29
@@ -1,29 +0,0 @@
1−/*
2− * Various trivial helper wrappers around standard functions
3− */
4−#include "cache.h"
5−
6−/*
7− * There's no pack memory to release - but stay close to the Git
8− * version so wrap this away:
9− */
10−static inline void release_pack_memory(size_t size __maybe_unused,
11− int flag __maybe_unused)
12−{
13−}
14−
15−void *xrealloc(void *ptr, size_t size)
16−{
17− void *ret = realloc(ptr, size);
18− if (!ret && !size)
19− ret = realloc(ptr, 1);
20− if (!ret) {
21− release_pack_memory(size, -1);
22− ret = realloc(ptr, size);
23− if (!ret && !size)
24− ret = realloc(ptr, 1);
25− if (!ret)
26− die("Out of memory, realloc failed");
27− }
28− return ret;
29−}