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

Merge tag 'perf-core-for-mingo-20160516' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

- Honour the kernel.perf_event_max_stack knob more precisely by not counting
PERF_CONTEXT_{KERNEL,USER} when deciding when to stop adding entries to
the perf_sample->ip_callchain[] array (Arnaldo Carvalho de Melo)

- Fix identation of 'stalled-backend-cycles' in 'perf stat' (Namhyung Kim)

- Update runtime using 'cpu-clock' event in 'perf stat' (Namhyung Kim)

- Use 'cpu-clock' for cpu targets in 'perf stat' (Namhyung Kim)

- Avoid fractional digits for integer scales in 'perf stat' (Andi Kleen)

- Store vdso buildid unconditionally, as it appears in callchains and
we're not checking those when creating the build-id table, so we
end up not being able to resolve VDSO symbols when doing analysis
on a different machine than the one where recording was done, possibly
of a different arch even (arm -> x86_64) (He Kuang)

Infrastructure changes:

- Generalize max_stack sysctl handler, will be used for configuring
multiple kernel knobs related to callchains (Arnaldo Carvalho de Melo)

Cleanups:

- Introduce DSO__NAME_KALLSYMS and DSO__NAME_KCORE, to stop using
open coded strings (Masami Hiramatsu)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

+201 -117
+14
Documentation/sysctl/kernel.txt
··· 61 61 - perf_cpu_time_max_percent 62 62 - perf_event_paranoid 63 63 - perf_event_max_stack 64 + - perf_event_max_contexts_per_stack 64 65 - pid_max 65 66 - powersave-nap [ PPC only ] 66 67 - printk ··· 666 665 enabled, otherwise writing to this file will return -EBUSY. 667 666 668 667 The default value is 127. 668 + 669 + ============================================================== 670 + 671 + perf_event_max_contexts_per_stack: 672 + 673 + Controls maximum number of stack frame context entries for 674 + (attr.sample_type & PERF_SAMPLE_CALLCHAIN) configured events, for 675 + instance, when using 'perf record -g' or 'perf trace --call-graph fp'. 676 + 677 + This can only be done when no events are in use that have callchains 678 + enabled, otherwise writing to this file will return -EBUSY. 679 + 680 + The default value is 8. 669 681 670 682 ============================================================== 671 683
+3 -3
arch/arc/kernel/perf_event.c
··· 48 48 static int callchain_trace(unsigned int addr, void *data) 49 49 { 50 50 struct arc_callchain_trace *ctrl = data; 51 - struct perf_callchain_entry *entry = ctrl->perf_stuff; 51 + struct perf_callchain_entry_ctx *entry = ctrl->perf_stuff; 52 52 perf_callchain_store(entry, addr); 53 53 54 54 if (ctrl->depth++ < 3) ··· 58 58 } 59 59 60 60 void 61 - perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) 61 + perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 62 62 { 63 63 struct arc_callchain_trace ctrl = { 64 64 .depth = 0, ··· 69 69 } 70 70 71 71 void 72 - perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) 72 + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 73 73 { 74 74 /* 75 75 * User stack can't be unwound trivially with kernel dwarf unwinder
+5 -5
arch/arm/kernel/perf_callchain.c
··· 31 31 */ 32 32 static struct frame_tail __user * 33 33 user_backtrace(struct frame_tail __user *tail, 34 - struct perf_callchain_entry *entry) 34 + struct perf_callchain_entry_ctx *entry) 35 35 { 36 36 struct frame_tail buftail; 37 37 unsigned long err; ··· 59 59 } 60 60 61 61 void 62 - perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) 62 + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 63 63 { 64 64 struct frame_tail __user *tail; 65 65 ··· 75 75 76 76 tail = (struct frame_tail __user *)regs->ARM_fp - 1; 77 77 78 - while ((entry->nr < sysctl_perf_event_max_stack) && 78 + while ((entry->nr < entry->max_stack) && 79 79 tail && !((unsigned long)tail & 0x3)) 80 80 tail = user_backtrace(tail, entry); 81 81 } ··· 89 89 callchain_trace(struct stackframe *fr, 90 90 void *data) 91 91 { 92 - struct perf_callchain_entry *entry = data; 92 + struct perf_callchain_entry_ctx *entry = data; 93 93 perf_callchain_store(entry, fr->pc); 94 94 return 0; 95 95 } 96 96 97 97 void 98 - perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) 98 + perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 99 99 { 100 100 struct stackframe fr; 101 101
+7 -7
arch/arm64/kernel/perf_callchain.c
··· 31 31 */ 32 32 static struct frame_tail __user * 33 33 user_backtrace(struct frame_tail __user *tail, 34 - struct perf_callchain_entry *entry) 34 + struct perf_callchain_entry_ctx *entry) 35 35 { 36 36 struct frame_tail buftail; 37 37 unsigned long err; ··· 76 76 77 77 static struct compat_frame_tail __user * 78 78 compat_user_backtrace(struct compat_frame_tail __user *tail, 79 - struct perf_callchain_entry *entry) 79 + struct perf_callchain_entry_ctx *entry) 80 80 { 81 81 struct compat_frame_tail buftail; 82 82 unsigned long err; ··· 106 106 } 107 107 #endif /* CONFIG_COMPAT */ 108 108 109 - void perf_callchain_user(struct perf_callchain_entry *entry, 109 + void perf_callchain_user(struct perf_callchain_entry_ctx *entry, 110 110 struct pt_regs *regs) 111 111 { 112 112 if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { ··· 122 122 123 123 tail = (struct frame_tail __user *)regs->regs[29]; 124 124 125 - while (entry->nr < sysctl_perf_event_max_stack && 125 + while (entry->nr < entry->max_stack && 126 126 tail && !((unsigned long)tail & 0xf)) 127 127 tail = user_backtrace(tail, entry); 128 128 } else { ··· 132 132 133 133 tail = (struct compat_frame_tail __user *)regs->compat_fp - 1; 134 134 135 - while ((entry->nr < sysctl_perf_event_max_stack) && 135 + while ((entry->nr < entry->max_stack) && 136 136 tail && !((unsigned long)tail & 0x3)) 137 137 tail = compat_user_backtrace(tail, entry); 138 138 #endif ··· 146 146 */ 147 147 static int callchain_trace(struct stackframe *frame, void *data) 148 148 { 149 - struct perf_callchain_entry *entry = data; 149 + struct perf_callchain_entry_ctx *entry = data; 150 150 perf_callchain_store(entry, frame->pc); 151 151 return 0; 152 152 } 153 153 154 - void perf_callchain_kernel(struct perf_callchain_entry *entry, 154 + void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 155 155 struct pt_regs *regs) 156 156 { 157 157 struct stackframe frame;
+5 -5
arch/metag/kernel/perf_callchain.c
··· 29 29 30 30 static struct metag_frame __user * 31 31 user_backtrace(struct metag_frame __user *user_frame, 32 - struct perf_callchain_entry *entry) 32 + struct perf_callchain_entry_ctx *entry) 33 33 { 34 34 struct metag_frame frame; 35 35 unsigned long calladdr; ··· 56 56 } 57 57 58 58 void 59 - perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) 59 + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 60 60 { 61 61 unsigned long sp = regs->ctx.AX[0].U0; 62 62 struct metag_frame __user *frame; ··· 65 65 66 66 --frame; 67 67 68 - while ((entry->nr < sysctl_perf_event_max_stack) && frame) 68 + while ((entry->nr < entry->max_stack) && frame) 69 69 frame = user_backtrace(frame, entry); 70 70 } 71 71 ··· 78 78 callchain_trace(struct stackframe *fr, 79 79 void *data) 80 80 { 81 - struct perf_callchain_entry *entry = data; 81 + struct perf_callchain_entry_ctx *entry = data; 82 82 perf_callchain_store(entry, fr->pc); 83 83 return 0; 84 84 } 85 85 86 86 void 87 - perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) 87 + perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 88 88 { 89 89 struct stackframe fr; 90 90
+6 -6
arch/mips/kernel/perf_event.c
··· 25 25 * the user stack callchains, we will add it here. 26 26 */ 27 27 28 - static void save_raw_perf_callchain(struct perf_callchain_entry *entry, 29 - unsigned long reg29) 28 + static void save_raw_perf_callchain(struct perf_callchain_entry_ctx *entry, 29 + unsigned long reg29) 30 30 { 31 31 unsigned long *sp = (unsigned long *)reg29; 32 32 unsigned long addr; ··· 35 35 addr = *sp++; 36 36 if (__kernel_text_address(addr)) { 37 37 perf_callchain_store(entry, addr); 38 - if (entry->nr >= sysctl_perf_event_max_stack) 38 + if (entry->nr >= entry->max_stack) 39 39 break; 40 40 } 41 41 } 42 42 } 43 43 44 - void perf_callchain_kernel(struct perf_callchain_entry *entry, 45 - struct pt_regs *regs) 44 + void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 45 + struct pt_regs *regs) 46 46 { 47 47 unsigned long sp = regs->regs[29]; 48 48 #ifdef CONFIG_KALLSYMS ··· 59 59 } 60 60 do { 61 61 perf_callchain_store(entry, pc); 62 - if (entry->nr >= sysctl_perf_event_max_stack) 62 + if (entry->nr >= entry->max_stack) 63 63 break; 64 64 pc = unwind_stack(current, &sp, pc, &ra); 65 65 } while (pc);
+10 -10
arch/powerpc/perf/callchain.c
··· 47 47 } 48 48 49 49 void 50 - perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) 50 + perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 51 51 { 52 52 unsigned long sp, next_sp; 53 53 unsigned long next_ip; ··· 76 76 next_ip = regs->nip; 77 77 lr = regs->link; 78 78 level = 0; 79 - perf_callchain_store(entry, PERF_CONTEXT_KERNEL); 79 + perf_callchain_store_context(entry, PERF_CONTEXT_KERNEL); 80 80 81 81 } else { 82 82 if (level == 0) ··· 232 232 puc == (unsigned long) &sf->uc; 233 233 } 234 234 235 - static void perf_callchain_user_64(struct perf_callchain_entry *entry, 235 + static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, 236 236 struct pt_regs *regs) 237 237 { 238 238 unsigned long sp, next_sp; ··· 247 247 sp = regs->gpr[1]; 248 248 perf_callchain_store(entry, next_ip); 249 249 250 - while (entry->nr < sysctl_perf_event_max_stack) { 250 + while (entry->nr < entry->max_stack) { 251 251 fp = (unsigned long __user *) sp; 252 252 if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp)) 253 253 return; ··· 274 274 read_user_stack_64(&uregs[PT_R1], &sp)) 275 275 return; 276 276 level = 0; 277 - perf_callchain_store(entry, PERF_CONTEXT_USER); 277 + perf_callchain_store_context(entry, PERF_CONTEXT_USER); 278 278 perf_callchain_store(entry, next_ip); 279 279 continue; 280 280 } ··· 319 319 return rc; 320 320 } 321 321 322 - static inline void perf_callchain_user_64(struct perf_callchain_entry *entry, 322 + static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, 323 323 struct pt_regs *regs) 324 324 { 325 325 } ··· 439 439 return mctx->mc_gregs; 440 440 } 441 441 442 - static void perf_callchain_user_32(struct perf_callchain_entry *entry, 442 + static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, 443 443 struct pt_regs *regs) 444 444 { 445 445 unsigned int sp, next_sp; ··· 453 453 sp = regs->gpr[1]; 454 454 perf_callchain_store(entry, next_ip); 455 455 456 - while (entry->nr < sysctl_perf_event_max_stack) { 456 + while (entry->nr < entry->max_stack) { 457 457 fp = (unsigned int __user *) (unsigned long) sp; 458 458 if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp)) 459 459 return; ··· 473 473 read_user_stack_32(&uregs[PT_R1], &sp)) 474 474 return; 475 475 level = 0; 476 - perf_callchain_store(entry, PERF_CONTEXT_USER); 476 + perf_callchain_store_context(entry, PERF_CONTEXT_USER); 477 477 perf_callchain_store(entry, next_ip); 478 478 continue; 479 479 } ··· 487 487 } 488 488 489 489 void 490 - perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) 490 + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 491 491 { 492 492 if (current_is_64bit()) 493 493 perf_callchain_user_64(entry, regs);
+2 -2
arch/s390/kernel/perf_event.c
··· 224 224 225 225 static int __perf_callchain_kernel(void *data, unsigned long address) 226 226 { 227 - struct perf_callchain_entry *entry = data; 227 + struct perf_callchain_entry_ctx *entry = data; 228 228 229 229 perf_callchain_store(entry, address); 230 230 return 0; 231 231 } 232 232 233 - void perf_callchain_kernel(struct perf_callchain_entry *entry, 233 + void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 234 234 struct pt_regs *regs) 235 235 { 236 236 if (user_mode(regs))
+2 -2
arch/sh/kernel/perf_callchain.c
··· 21 21 22 22 static void callchain_address(void *data, unsigned long addr, int reliable) 23 23 { 24 - struct perf_callchain_entry *entry = data; 24 + struct perf_callchain_entry_ctx *entry = data; 25 25 26 26 if (reliable) 27 27 perf_callchain_store(entry, addr); ··· 33 33 }; 34 34 35 35 void 36 - perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) 36 + perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 37 37 { 38 38 perf_callchain_store(entry, regs->pc); 39 39
+7 -7
arch/sparc/kernel/perf_event.c
··· 1711 1711 } 1712 1712 pure_initcall(init_hw_perf_events); 1713 1713 1714 - void perf_callchain_kernel(struct perf_callchain_entry *entry, 1714 + void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 1715 1715 struct pt_regs *regs) 1716 1716 { 1717 1717 unsigned long ksp, fp; ··· 1756 1756 } 1757 1757 } 1758 1758 #endif 1759 - } while (entry->nr < sysctl_perf_event_max_stack); 1759 + } while (entry->nr < entry->max_stack); 1760 1760 } 1761 1761 1762 1762 static inline int ··· 1769 1769 return (__range_not_ok(fp, size, TASK_SIZE) == 0); 1770 1770 } 1771 1771 1772 - static void perf_callchain_user_64(struct perf_callchain_entry *entry, 1772 + static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, 1773 1773 struct pt_regs *regs) 1774 1774 { 1775 1775 unsigned long ufp; ··· 1790 1790 pc = sf.callers_pc; 1791 1791 ufp = (unsigned long)sf.fp + STACK_BIAS; 1792 1792 perf_callchain_store(entry, pc); 1793 - } while (entry->nr < sysctl_perf_event_max_stack); 1793 + } while (entry->nr < entry->max_stack); 1794 1794 } 1795 1795 1796 - static void perf_callchain_user_32(struct perf_callchain_entry *entry, 1796 + static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, 1797 1797 struct pt_regs *regs) 1798 1798 { 1799 1799 unsigned long ufp; ··· 1822 1822 ufp = (unsigned long)sf.fp; 1823 1823 } 1824 1824 perf_callchain_store(entry, pc); 1825 - } while (entry->nr < sysctl_perf_event_max_stack); 1825 + } while (entry->nr < entry->max_stack); 1826 1826 } 1827 1827 1828 1828 void 1829 - perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) 1829 + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 1830 1830 { 1831 1831 u64 saved_fault_address = current_thread_info()->fault_address; 1832 1832 u8 saved_fault_code = get_thread_fault_code();
+3 -3
arch/tile/kernel/perf_event.c
··· 941 941 /* 942 942 * Tile specific backtracing code for perf_events. 943 943 */ 944 - static inline void perf_callchain(struct perf_callchain_entry *entry, 944 + static inline void perf_callchain(struct perf_callchain_entry_ctx *entry, 945 945 struct pt_regs *regs) 946 946 { 947 947 struct KBacktraceIterator kbt; ··· 992 992 } 993 993 } 994 994 995 - void perf_callchain_user(struct perf_callchain_entry *entry, 995 + void perf_callchain_user(struct perf_callchain_entry_ctx *entry, 996 996 struct pt_regs *regs) 997 997 { 998 998 perf_callchain(entry, regs); 999 999 } 1000 1000 1001 - void perf_callchain_kernel(struct perf_callchain_entry *entry, 1001 + void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 1002 1002 struct pt_regs *regs) 1003 1003 { 1004 1004 perf_callchain(entry, regs);
+7 -7
arch/x86/events/core.c
··· 2202 2202 2203 2203 static int backtrace_address(void *data, unsigned long addr, int reliable) 2204 2204 { 2205 - struct perf_callchain_entry *entry = data; 2205 + struct perf_callchain_entry_ctx *entry = data; 2206 2206 2207 2207 return perf_callchain_store(entry, addr); 2208 2208 } ··· 2214 2214 }; 2215 2215 2216 2216 void 2217 - perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) 2217 + perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 2218 2218 { 2219 2219 if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { 2220 2220 /* TODO: We don't support guest os callchain now */ ··· 2268 2268 #include <asm/compat.h> 2269 2269 2270 2270 static inline int 2271 - perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) 2271 + perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry) 2272 2272 { 2273 2273 /* 32-bit process in 64-bit kernel. */ 2274 2274 unsigned long ss_base, cs_base; ··· 2283 2283 2284 2284 fp = compat_ptr(ss_base + regs->bp); 2285 2285 pagefault_disable(); 2286 - while (entry->nr < sysctl_perf_event_max_stack) { 2286 + while (entry->nr < entry->max_stack) { 2287 2287 unsigned long bytes; 2288 2288 frame.next_frame = 0; 2289 2289 frame.return_address = 0; ··· 2309 2309 } 2310 2310 #else 2311 2311 static inline int 2312 - perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) 2312 + perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry) 2313 2313 { 2314 2314 return 0; 2315 2315 } 2316 2316 #endif 2317 2317 2318 2318 void 2319 - perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) 2319 + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 2320 2320 { 2321 2321 struct stack_frame frame; 2322 2322 const void __user *fp; ··· 2343 2343 return; 2344 2344 2345 2345 pagefault_disable(); 2346 - while (entry->nr < sysctl_perf_event_max_stack) { 2346 + while (entry->nr < entry->max_stack) { 2347 2347 unsigned long bytes; 2348 2348 frame.next_frame = NULL; 2349 2349 frame.return_address = 0;
+5 -5
arch/xtensa/kernel/perf_event.c
··· 323 323 324 324 static int callchain_trace(struct stackframe *frame, void *data) 325 325 { 326 - struct perf_callchain_entry *entry = data; 326 + struct perf_callchain_entry_ctx *entry = data; 327 327 328 328 perf_callchain_store(entry, frame->pc); 329 329 return 0; 330 330 } 331 331 332 - void perf_callchain_kernel(struct perf_callchain_entry *entry, 332 + void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 333 333 struct pt_regs *regs) 334 334 { 335 - xtensa_backtrace_kernel(regs, sysctl_perf_event_max_stack, 335 + xtensa_backtrace_kernel(regs, entry->max_stack, 336 336 callchain_trace, NULL, entry); 337 337 } 338 338 339 - void perf_callchain_user(struct perf_callchain_entry *entry, 339 + void perf_callchain_user(struct perf_callchain_entry_ctx *entry, 340 340 struct pt_regs *regs) 341 341 { 342 - xtensa_backtrace_user(regs, sysctl_perf_event_max_stack, 342 + xtensa_backtrace_user(regs, entry->max_stack, 343 343 callchain_trace, entry); 344 344 } 345 345
+29 -5
include/linux/perf_event.h
··· 61 61 __u64 ip[0]; /* /proc/sys/kernel/perf_event_max_stack */ 62 62 }; 63 63 64 + struct perf_callchain_entry_ctx { 65 + struct perf_callchain_entry *entry; 66 + u32 max_stack; 67 + u32 nr; 68 + short contexts; 69 + bool contexts_maxed; 70 + }; 71 + 64 72 struct perf_raw_record { 65 73 u32 size; 66 74 void *data; ··· 1071 1063 /* Callchains */ 1072 1064 DECLARE_PER_CPU(struct perf_callchain_entry, perf_callchain_entry); 1073 1065 1074 - extern void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs); 1075 - extern void perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs); 1066 + extern void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); 1067 + extern void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); 1076 1068 extern struct perf_callchain_entry * 1077 1069 get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, 1078 - bool crosstask, bool add_mark); 1070 + u32 max_stack, bool crosstask, bool add_mark); 1079 1071 extern int get_callchain_buffers(void); 1080 1072 extern void put_callchain_buffers(void); 1081 1073 1082 1074 extern int sysctl_perf_event_max_stack; 1075 + extern int sysctl_perf_event_max_contexts_per_stack; 1083 1076 1084 - static inline int perf_callchain_store(struct perf_callchain_entry *entry, u64 ip) 1077 + static inline int perf_callchain_store_context(struct perf_callchain_entry_ctx *ctx, u64 ip) 1085 1078 { 1086 - if (entry->nr < sysctl_perf_event_max_stack) { 1079 + if (ctx->contexts < sysctl_perf_event_max_contexts_per_stack) { 1080 + struct perf_callchain_entry *entry = ctx->entry; 1087 1081 entry->ip[entry->nr++] = ip; 1082 + ++ctx->contexts; 1083 + return 0; 1084 + } else { 1085 + ctx->contexts_maxed = true; 1086 + return -1; /* no more room, stop walking the stack */ 1087 + } 1088 + } 1089 + 1090 + static inline int perf_callchain_store(struct perf_callchain_entry_ctx *ctx, u64 ip) 1091 + { 1092 + if (ctx->nr < ctx->max_stack && !ctx->contexts_maxed) { 1093 + struct perf_callchain_entry *entry = ctx->entry; 1094 + entry->ip[entry->nr++] = ip; 1095 + ++ctx->nr; 1088 1096 return 0; 1089 1097 } else { 1090 1098 return -1; /* no more room, stop walking the stack */
+1
include/uapi/linux/perf_event.h
··· 862 862 }; 863 863 864 864 #define PERF_MAX_STACK_DEPTH 127 865 + #define PERF_MAX_CONTEXTS_PER_STACK 8 865 866 866 867 enum perf_callchain_context { 867 868 PERF_CONTEXT_HV = (__u64)-32,
+2 -1
kernel/bpf/stackmap.c
··· 136 136 BPF_F_FAST_STACK_CMP | BPF_F_REUSE_STACKID))) 137 137 return -EINVAL; 138 138 139 - trace = get_perf_callchain(regs, init_nr, kernel, user, false, false); 139 + trace = get_perf_callchain(regs, init_nr, kernel, user, 140 + sysctl_perf_event_max_stack, false, false); 140 141 141 142 if (unlikely(!trace)) 142 143 /* couldn't fetch the stack trace */
+24 -12
kernel/events/callchain.c
··· 19 19 }; 20 20 21 21 int sysctl_perf_event_max_stack __read_mostly = PERF_MAX_STACK_DEPTH; 22 + int sysctl_perf_event_max_contexts_per_stack __read_mostly = PERF_MAX_CONTEXTS_PER_STACK; 22 23 23 24 static inline size_t perf_callchain_entry__sizeof(void) 24 25 { 25 26 return (sizeof(struct perf_callchain_entry) + 26 - sizeof(__u64) * sysctl_perf_event_max_stack); 27 + sizeof(__u64) * (sysctl_perf_event_max_stack + 28 + sysctl_perf_event_max_contexts_per_stack)); 27 29 } 28 30 29 31 static DEFINE_PER_CPU(int, callchain_recursion[PERF_NR_CONTEXTS]); ··· 34 32 static struct callchain_cpus_entries *callchain_cpus_entries; 35 33 36 34 37 - __weak void perf_callchain_kernel(struct perf_callchain_entry *entry, 35 + __weak void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 38 36 struct pt_regs *regs) 39 37 { 40 38 } 41 39 42 - __weak void perf_callchain_user(struct perf_callchain_entry *entry, 40 + __weak void perf_callchain_user(struct perf_callchain_entry_ctx *entry, 43 41 struct pt_regs *regs) 44 42 { 45 43 } ··· 178 176 if (!kernel && !user) 179 177 return NULL; 180 178 181 - return get_perf_callchain(regs, 0, kernel, user, crosstask, true); 179 + return get_perf_callchain(regs, 0, kernel, user, sysctl_perf_event_max_stack, crosstask, true); 182 180 } 183 181 184 182 struct perf_callchain_entry * 185 183 get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, 186 - bool crosstask, bool add_mark) 184 + u32 max_stack, bool crosstask, bool add_mark) 187 185 { 188 186 struct perf_callchain_entry *entry; 187 + struct perf_callchain_entry_ctx ctx; 189 188 int rctx; 190 189 191 190 entry = get_callchain_entry(&rctx); ··· 196 193 if (!entry) 197 194 goto exit_put; 198 195 199 - entry->nr = init_nr; 196 + ctx.entry = entry; 197 + ctx.max_stack = max_stack; 198 + ctx.nr = entry->nr = init_nr; 199 + ctx.contexts = 0; 200 + ctx.contexts_maxed = false; 200 201 201 202 if (kernel && !user_mode(regs)) { 202 203 if (add_mark) 203 - perf_callchain_store(entry, PERF_CONTEXT_KERNEL); 204 - perf_callchain_kernel(entry, regs); 204 + perf_callchain_store_context(&ctx, PERF_CONTEXT_KERNEL); 205 + perf_callchain_kernel(&ctx, regs); 205 206 } 206 207 207 208 if (user) { ··· 221 214 goto exit_put; 222 215 223 216 if (add_mark) 224 - perf_callchain_store(entry, PERF_CONTEXT_USER); 225 - perf_callchain_user(entry, regs); 217 + perf_callchain_store_context(&ctx, PERF_CONTEXT_USER); 218 + perf_callchain_user(&ctx, regs); 226 219 } 227 220 } 228 221 ··· 232 225 return entry; 233 226 } 234 227 228 + /* 229 + * Used for sysctl_perf_event_max_stack and 230 + * sysctl_perf_event_max_contexts_per_stack. 231 + */ 235 232 int perf_event_max_stack_handler(struct ctl_table *table, int write, 236 233 void __user *buffer, size_t *lenp, loff_t *ppos) 237 234 { 238 - int new_value = sysctl_perf_event_max_stack, ret; 235 + int *value = table->data; 236 + int new_value = *value, ret; 239 237 struct ctl_table new_table = *table; 240 238 241 239 new_table.data = &new_value; ··· 252 240 if (atomic_read(&nr_callchain_events)) 253 241 ret = -EBUSY; 254 242 else 255 - sysctl_perf_event_max_stack = new_value; 243 + *value = new_value; 256 244 257 245 mutex_unlock(&callchain_mutex); 258 246
+10 -1
kernel/sysctl.c
··· 1149 1149 }, 1150 1150 { 1151 1151 .procname = "perf_event_max_stack", 1152 - .data = NULL, /* filled in by handler */ 1152 + .data = &sysctl_perf_event_max_stack, 1153 1153 .maxlen = sizeof(sysctl_perf_event_max_stack), 1154 1154 .mode = 0644, 1155 1155 .proc_handler = perf_event_max_stack_handler, 1156 1156 .extra1 = &zero, 1157 1157 .extra2 = &six_hundred_forty_kb, 1158 + }, 1159 + { 1160 + .procname = "perf_event_max_contexts_per_stack", 1161 + .data = &sysctl_perf_event_max_contexts_per_stack, 1162 + .maxlen = sizeof(sysctl_perf_event_max_contexts_per_stack), 1163 + .mode = 0644, 1164 + .proc_handler = perf_event_max_stack_handler, 1165 + .extra1 = &zero, 1166 + .extra2 = &one_thousand, 1158 1167 }, 1159 1168 #endif 1160 1169 #ifdef CONFIG_KMEMCHECK
+4 -4
tools/perf/builtin-buildid-cache.c
··· 119 119 if (build_id_cache__kcore_buildid(from_dir, sbuildid) < 0) 120 120 return -1; 121 121 122 - scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s", 123 - buildid_dir, sbuildid); 122 + scnprintf(to_dir, sizeof(to_dir), "%s/%s/%s", 123 + buildid_dir, DSO__NAME_KCORE, sbuildid); 124 124 125 125 if (!force && 126 126 !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) { ··· 131 131 if (build_id_cache__kcore_dir(dir, sizeof(dir))) 132 132 return -1; 133 133 134 - scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s/%s", 135 - buildid_dir, sbuildid, dir); 134 + scnprintf(to_dir, sizeof(to_dir), "%s/%s/%s/%s", 135 + buildid_dir, DSO__NAME_KCORE, sbuildid, dir); 136 136 137 137 if (mkdir_p(to_dir, 0755)) 138 138 return -1;
+13 -9
tools/perf/builtin-stat.c
··· 66 66 #include <stdlib.h> 67 67 #include <sys/prctl.h> 68 68 #include <locale.h> 69 + #include <math.h> 69 70 70 71 #define DEFAULT_SEPARATOR " " 71 72 #define CNTR_NOT_SUPPORTED "<not supported>" ··· 992 991 const char *fmt; 993 992 994 993 if (csv_output) { 995 - fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s"; 994 + fmt = floor(sc) != sc ? "%.2f%s" : "%.0f%s"; 996 995 } else { 997 996 if (big_num) 998 - fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s"; 997 + fmt = floor(sc) != sc ? "%'18.2f%s" : "%'18.0f%s"; 999 998 else 1000 - fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s"; 999 + fmt = floor(sc) != sc ? "%18.2f%s" : "%18.0f%s"; 1001 1000 } 1002 1001 1003 1002 aggr_printout(evsel, id, nr); ··· 1910 1909 } 1911 1910 1912 1911 if (!evsel_list->nr_entries) { 1912 + if (target__has_cpu(&target)) 1913 + default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; 1914 + 1913 1915 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0) 1914 1916 return -1; 1915 1917 if (pmu_have_event("cpu", "stalled-cycles-frontend")) { ··· 2004 2000 union perf_event *event, 2005 2001 struct perf_session *session) 2006 2002 { 2007 - struct stat_round_event *round = &event->stat_round; 2003 + struct stat_round_event *stat_round = &event->stat_round; 2008 2004 struct perf_evsel *counter; 2009 2005 struct timespec tsh, *ts = NULL; 2010 2006 const char **argv = session->header.env.cmdline_argv; ··· 2013 2009 evlist__for_each(evsel_list, counter) 2014 2010 perf_stat_process_counter(&stat_config, counter); 2015 2011 2016 - if (round->type == PERF_STAT_ROUND_TYPE__FINAL) 2017 - update_stats(&walltime_nsecs_stats, round->time); 2012 + if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL) 2013 + update_stats(&walltime_nsecs_stats, stat_round->time); 2018 2014 2019 - if (stat_config.interval && round->time) { 2020 - tsh.tv_sec = round->time / NSECS_PER_SEC; 2021 - tsh.tv_nsec = round->time % NSECS_PER_SEC; 2015 + if (stat_config.interval && stat_round->time) { 2016 + tsh.tv_sec = stat_round->time / NSECS_PER_SEC; 2017 + tsh.tv_nsec = stat_round->time % NSECS_PER_SEC; 2022 2018 ts = &tsh; 2023 2019 } 2024 2020
+3
tools/perf/perf.c
··· 549 549 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0) 550 550 sysctl_perf_event_max_stack = value; 551 551 552 + if (sysctl__read_int("kernel/perf_event_max_contexts_per_stack", &value) == 0) 553 + sysctl_perf_event_max_contexts_per_stack = value; 554 + 552 555 cmd = extract_argv0_path(argv[0]); 553 556 if (!cmd) 554 557 cmd = "perf-help";
+1 -1
tools/perf/util/annotate.c
··· 1122 1122 } else if (dso__is_kcore(dso)) { 1123 1123 goto fallback; 1124 1124 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || 1125 - strstr(command, "[kernel.kallsyms]") || 1125 + strstr(command, DSO__NAME_KALLSYMS) || 1126 1126 access(symfs_filename, R_OK)) { 1127 1127 free(filename); 1128 1128 fallback:
+1 -1
tools/perf/util/build-id.c
··· 256 256 size_t name_len; 257 257 bool in_kernel = false; 258 258 259 - if (!pos->hit) 259 + if (!pos->hit && !dso__is_vdso(pos)) 260 260 continue; 261 261 262 262 if (dso__is_vdso(pos)) {
+2 -1
tools/perf/util/dso.c
··· 7 7 #include "auxtrace.h" 8 8 #include "util.h" 9 9 #include "debug.h" 10 + #include "vdso.h" 10 11 11 12 char dso__symtab_origin(const struct dso *dso) 12 13 { ··· 1170 1169 struct dso *pos; 1171 1170 1172 1171 list_for_each_entry(pos, head, node) { 1173 - if (with_hits && !pos->hit) 1172 + if (with_hits && !pos->hit && !dso__is_vdso(pos)) 1174 1173 continue; 1175 1174 if (pos->has_build_id) { 1176 1175 have_build_id = true;
+18 -10
tools/perf/util/machine.c
··· 709 709 if (machine__is_host(machine)) { 710 710 vmlinux_name = symbol_conf.vmlinux_name; 711 711 if (!vmlinux_name) 712 - vmlinux_name = "[kernel.kallsyms]"; 712 + vmlinux_name = DSO__NAME_KALLSYMS; 713 713 714 714 kernel = machine__findnew_kernel(machine, vmlinux_name, 715 715 "[kernel]", DSO_TYPE_KERNEL); ··· 1811 1811 { 1812 1812 struct branch_stack *branch = sample->branch_stack; 1813 1813 struct ip_callchain *chain = sample->callchain; 1814 - int chain_nr = min(max_stack, (int)chain->nr); 1814 + int chain_nr = chain->nr; 1815 1815 u8 cpumode = PERF_RECORD_MISC_USER; 1816 - int i, j, err; 1816 + int i, j, err, nr_entries, nr_contexts; 1817 1817 int skip_idx = -1; 1818 1818 int first_call = 0; 1819 1819 ··· 1828 1828 * Based on DWARF debug information, some architectures skip 1829 1829 * a callchain entry saved by the kernel. 1830 1830 */ 1831 - if (chain->nr < sysctl_perf_event_max_stack) 1831 + if (chain_nr < sysctl_perf_event_max_stack) 1832 1832 skip_idx = arch_skip_callchain_idx(thread, chain); 1833 1833 1834 1834 /* ··· 1889 1889 } 1890 1890 1891 1891 check_calls: 1892 - if (chain->nr > sysctl_perf_event_max_stack && (int)chain->nr > max_stack) { 1893 - pr_warning("corrupted callchain. skipping...\n"); 1894 - return 0; 1895 - } 1896 - 1897 - for (i = first_call; i < chain_nr; i++) { 1892 + for (i = first_call, nr_entries = 0, nr_contexts = 0; 1893 + i < chain_nr && nr_entries < max_stack; i++) { 1898 1894 u64 ip; 1899 1895 1900 1896 if (callchain_param.order == ORDER_CALLEE) ··· 1904 1908 #endif 1905 1909 ip = chain->ips[j]; 1906 1910 1911 + if (ip >= PERF_CONTEXT_MAX) { 1912 + if (++nr_contexts > sysctl_perf_event_max_contexts_per_stack) 1913 + goto out_corrupted_callchain; 1914 + } else { 1915 + if (++nr_entries > sysctl_perf_event_max_stack) 1916 + goto out_corrupted_callchain; 1917 + } 1918 + 1907 1919 err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); 1908 1920 1909 1921 if (err) 1910 1922 return (err < 0) ? err : 0; 1911 1923 } 1912 1924 1925 + return 0; 1926 + 1927 + out_corrupted_callchain: 1928 + pr_warning("corrupted callchain. skipping...\n"); 1913 1929 return 0; 1914 1930 } 1915 1931
+5 -3
tools/perf/util/stat-shadow.c
··· 94 94 { 95 95 int ctx = evsel_context(counter); 96 96 97 - if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 97 + if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK) || 98 + perf_evsel__match(counter, SOFTWARE, SW_CPU_CLOCK)) 98 99 update_stats(&runtime_nsecs_stats[cpu], count[0]); 99 100 else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 100 101 update_stats(&runtime_cycles_stats[ctx][cpu], count[0]); ··· 189 188 190 189 color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 191 190 192 - out->print_metric(out->ctx, color, "%6.2f%%", "backend cycles idle", ratio); 191 + out->print_metric(out->ctx, color, "%7.2f%%", "backend cycles idle", ratio); 193 192 } 194 193 195 194 static void print_branch_misses(int cpu, ··· 445 444 ratio = total / avg; 446 445 447 446 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio); 448 - } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) { 447 + } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK) || 448 + perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK)) { 449 449 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0) 450 450 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized", 451 451 avg / ratio);
+5 -5
tools/perf/util/symbol.c
··· 1662 1662 1663 1663 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); 1664 1664 1665 - scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", buildid_dir, 1666 - sbuild_id); 1665 + scnprintf(path, sizeof(path), "%s/%s/%s", buildid_dir, 1666 + DSO__NAME_KCORE, sbuild_id); 1667 1667 1668 1668 /* Use /proc/kallsyms if possible */ 1669 1669 if (is_host) { ··· 1699 1699 if (!find_matching_kcore(map, path, sizeof(path))) 1700 1700 return strdup(path); 1701 1701 1702 - scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s", 1703 - buildid_dir, sbuild_id); 1702 + scnprintf(path, sizeof(path), "%s/%s/%s", 1703 + buildid_dir, DSO__NAME_KALLSYMS, sbuild_id); 1704 1704 1705 1705 if (access(path, F_OK)) { 1706 1706 pr_err("No kallsyms or vmlinux with build-id %s was found\n", ··· 1769 1769 1770 1770 if (err > 0 && !dso__is_kcore(dso)) { 1771 1771 dso->binary_type = DSO_BINARY_TYPE__KALLSYMS; 1772 - dso__set_long_name(dso, "[kernel.kallsyms]", false); 1772 + dso__set_long_name(dso, DSO__NAME_KALLSYMS, false); 1773 1773 map__fixup_start(map); 1774 1774 map__fixup_end(map); 1775 1775 }
+3
tools/perf/util/symbol.h
··· 44 44 #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 45 45 #endif 46 46 47 + #define DSO__NAME_KALLSYMS "[kernel.kallsyms]" 48 + #define DSO__NAME_KCORE "[kernel.kcore]" 49 + 47 50 /** struct symbol - symtab entry 48 51 * 49 52 * @ignore - resolvable but tools ignore it (e.g. idle routines)
+2 -1
tools/perf/util/util.c
··· 33 33 unsigned int page_size; 34 34 int cacheline_size; 35 35 36 - unsigned int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; 36 + int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; 37 + int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK; 37 38 38 39 bool test_attr__enabled; 39 40
+2 -1
tools/perf/util/util.h
··· 261 261 262 262 extern unsigned int page_size; 263 263 extern int cacheline_size; 264 - extern unsigned int sysctl_perf_event_max_stack; 264 + extern int sysctl_perf_event_max_stack; 265 + extern int sysctl_perf_event_max_contexts_per_stack; 265 266 266 267 struct parse_tag { 267 268 char tag;