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

Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace into perf/core

Pull ftrace updates from Steve Rostedt.

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+176 -111
+1
arch/alpha/include/asm/Kbuild
··· 11 11 header-y += regdef.h 12 12 header-y += sysinfo.h 13 13 generic-y += exec.h 14 + generic-y += trace_clock.h
+1
arch/arm/include/asm/Kbuild
··· 31 31 generic-y += termbits.h 32 32 generic-y += termios.h 33 33 generic-y += timex.h 34 + generic-y += trace_clock.h 34 35 generic-y += types.h 35 36 generic-y += unaligned.h
+1
arch/arm64/include/asm/Kbuild
··· 43 43 generic-y += termbits.h 44 44 generic-y += termios.h 45 45 generic-y += topology.h 46 + generic-y += trace_clock.h 46 47 generic-y += types.h 47 48 generic-y += unaligned.h 48 49 generic-y += user.h
+1
arch/avr32/include/asm/Kbuild
··· 1 1 2 2 generic-y += clkdev.h 3 3 generic-y += exec.h 4 + generic-y += trace_clock.h
+1
arch/blackfin/include/asm/Kbuild
··· 38 38 generic-y += termbits.h 39 39 generic-y += termios.h 40 40 generic-y += topology.h 41 + generic-y += trace_clock.h 41 42 generic-y += types.h 42 43 generic-y += ucontext.h 43 44 generic-y += unaligned.h
+1
arch/c6x/include/asm/Kbuild
··· 49 49 generic-y += termios.h 50 50 generic-y += tlbflush.h 51 51 generic-y += topology.h 52 + generic-y += trace_clock.h 52 53 generic-y += types.h 53 54 generic-y += ucontext.h 54 55 generic-y += user.h
+1
arch/cris/include/asm/Kbuild
··· 11 11 generic-y += clkdev.h 12 12 generic-y += exec.h 13 13 generic-y += module.h 14 + generic-y += trace_clock.h
+1
arch/frv/include/asm/Kbuild
··· 1 1 2 2 generic-y += clkdev.h 3 3 generic-y += exec.h 4 + generic-y += trace_clock.h
+1
arch/h8300/include/asm/Kbuild
··· 3 3 generic-y += clkdev.h 4 4 generic-y += exec.h 5 5 generic-y += module.h 6 + generic-y += trace_clock.h
+1
arch/hexagon/include/asm/Kbuild
··· 48 48 generic-y += termbits.h 49 49 generic-y += termios.h 50 50 generic-y += topology.h 51 + generic-y += trace_clock.h 51 52 generic-y += types.h 52 53 generic-y += ucontext.h 53 54 generic-y += unaligned.h
+1
arch/ia64/include/asm/Kbuild
··· 2 2 generic-y += clkdev.h 3 3 generic-y += exec.h 4 4 generic-y += kvm_para.h 5 + generic-y += trace_clock.h
+1
arch/m32r/include/asm/Kbuild
··· 3 3 generic-y += clkdev.h 4 4 generic-y += exec.h 5 5 generic-y += module.h 6 + generic-y += trace_clock.h
+1
arch/m68k/include/asm/Kbuild
··· 24 24 generic-y += siginfo.h 25 25 generic-y += statfs.h 26 26 generic-y += topology.h 27 + generic-y += trace_clock.h 27 28 generic-y += types.h 28 29 generic-y += word-at-a-time.h 29 30 generic-y += xor.h
+1
arch/microblaze/include/asm/Kbuild
··· 3 3 header-y += elf.h 4 4 generic-y += clkdev.h 5 5 generic-y += exec.h 6 + generic-y += trace_clock.h
+1
arch/mips/include/asm/Kbuild
··· 1 1 # MIPS headers 2 + generic-y += trace_clock.h
+1
arch/mn10300/include/asm/Kbuild
··· 1 1 2 2 generic-y += clkdev.h 3 3 generic-y += exec.h 4 + generic-y += trace_clock.h
+1
arch/openrisc/include/asm/Kbuild
··· 60 60 generic-y += termbits.h 61 61 generic-y += termios.h 62 62 generic-y += topology.h 63 + generic-y += trace_clock.h 63 64 generic-y += types.h 64 65 generic-y += ucontext.h 65 66 generic-y += user.h
+1
arch/parisc/include/asm/Kbuild
··· 3 3 segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \ 4 4 div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ 5 5 poll.h xor.h clkdev.h exec.h 6 + generic-y += trace_clock.h
+1
arch/powerpc/include/asm/Kbuild
··· 2 2 3 3 generic-y += clkdev.h 4 4 generic-y += rwsem.h 5 + generic-y += trace_clock.h
+1
arch/s390/include/asm/Kbuild
··· 1 1 2 2 3 3 generic-y += clkdev.h 4 + generic-y += trace_clock.h
+1
arch/score/include/asm/Kbuild
··· 3 3 header-y += 4 4 5 5 generic-y += clkdev.h 6 + generic-y += trace_clock.h
+1
arch/sh/include/asm/Kbuild
··· 31 31 generic-y += statfs.h 32 32 generic-y += termbits.h 33 33 generic-y += termios.h 34 + generic-y += trace_clock.h 34 35 generic-y += ucontext.h 35 36 generic-y += xor.h
+1
arch/sparc/include/asm/Kbuild
··· 8 8 generic-y += irq_regs.h 9 9 generic-y += local.h 10 10 generic-y += module.h 11 + generic-y += trace_clock.h 11 12 generic-y += word-at-a-time.h
+1
arch/tile/include/asm/Kbuild
··· 34 34 generic-y += statfs.h 35 35 generic-y += termbits.h 36 36 generic-y += termios.h 37 + generic-y += trace_clock.h 37 38 generic-y += types.h 38 39 generic-y += xor.h
+1
arch/um/include/asm/Kbuild
··· 2 2 generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h 3 3 generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h 4 4 generic-y += switch_to.h clkdev.h 5 + generic-y += trace_clock.h
+1
arch/unicore32/include/asm/Kbuild
··· 53 53 generic-y += termbits.h 54 54 generic-y += termios.h 55 55 generic-y += topology.h 56 + generic-y += trace_clock.h 56 57 generic-y += types.h 57 58 generic-y += ucontext.h 58 59 generic-y += unaligned.h
+20
arch/x86/include/asm/trace_clock.h
··· 1 + #ifndef _ASM_X86_TRACE_CLOCK_H 2 + #define _ASM_X86_TRACE_CLOCK_H 3 + 4 + #include <linux/compiler.h> 5 + #include <linux/types.h> 6 + 7 + #ifdef CONFIG_X86_TSC 8 + 9 + extern u64 notrace trace_clock_x86_tsc(void); 10 + 11 + # define ARCH_TRACE_CLOCKS \ 12 + { trace_clock_x86_tsc, "x86-tsc", .in_ns = 0 }, 13 + 14 + #else /* !CONFIG_X86_TSC */ 15 + 16 + #define ARCH_TRACE_CLOCKS 17 + 18 + #endif 19 + 20 + #endif /* _ASM_X86_TRACE_CLOCK_H */
+1
arch/x86/kernel/Makefile
··· 61 61 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 62 62 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 63 63 obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 64 + obj-$(CONFIG_X86_TSC) += trace_clock.o 64 65 obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o 65 66 obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o 66 67 obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
+21
arch/x86/kernel/trace_clock.c
··· 1 + /* 2 + * X86 trace clocks 3 + */ 4 + #include <asm/trace_clock.h> 5 + #include <asm/barrier.h> 6 + #include <asm/msr.h> 7 + 8 + /* 9 + * trace_clock_x86_tsc(): A clock that is just the cycle counter. 10 + * 11 + * Unlike the other clocks, this is not in nanoseconds. 12 + */ 13 + u64 notrace trace_clock_x86_tsc(void) 14 + { 15 + u64 ret; 16 + 17 + rdtsc_barrier(); 18 + rdtscll(ret); 19 + 20 + return ret; 21 + }
+1
arch/xtensa/include/asm/Kbuild
··· 25 25 generic-y += statfs.h 26 26 generic-y += termios.h 27 27 generic-y += topology.h 28 + generic-y += trace_clock.h 28 29 generic-y += xor.h
+16
include/asm-generic/trace_clock.h
··· 1 + #ifndef _ASM_GENERIC_TRACE_CLOCK_H 2 + #define _ASM_GENERIC_TRACE_CLOCK_H 3 + /* 4 + * Arch-specific trace clocks. 5 + */ 6 + 7 + /* 8 + * Additional trace clocks added to the trace_clocks 9 + * array in kernel/trace/trace.c 10 + * None if the architecture has not defined it. 11 + */ 12 + #ifndef ARCH_TRACE_CLOCKS 13 + # define ARCH_TRACE_CLOCKS 14 + #endif 15 + 16 + #endif /* _ASM_GENERIC_TRACE_CLOCK_H */
+6
include/linux/ftrace_event.h
··· 86 86 cpumask_var_t started; 87 87 }; 88 88 89 + enum trace_iter_flags { 90 + TRACE_FILE_LAT_FMT = 1, 91 + TRACE_FILE_ANNOTATE = 2, 92 + TRACE_FILE_TIME_IN_NS = 4, 93 + }; 94 + 89 95 90 96 struct trace_event; 91 97
+2
include/linux/trace_clock.h
··· 12 12 #include <linux/compiler.h> 13 13 #include <linux/types.h> 14 14 15 + #include <asm/trace_clock.h> 16 + 15 17 extern u64 notrace trace_clock_local(void); 16 18 extern u64 notrace trace_clock(void); 17 19 extern u64 notrace trace_clock_global(void);
-73
include/trace/ftrace.h
··· 619 619 620 620 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 621 621 622 - /* 623 - * Define the insertion callback to perf events 624 - * 625 - * The job is very similar to ftrace_raw_event_<call> except that we don't 626 - * insert in the ring buffer but in a perf counter. 627 - * 628 - * static void ftrace_perf_<call>(proto) 629 - * { 630 - * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; 631 - * struct ftrace_event_call *event_call = &event_<call>; 632 - * extern void perf_tp_event(int, u64, u64, void *, int); 633 - * struct ftrace_raw_##call *entry; 634 - * struct perf_trace_buf *trace_buf; 635 - * u64 __addr = 0, __count = 1; 636 - * unsigned long irq_flags; 637 - * struct trace_entry *ent; 638 - * int __entry_size; 639 - * int __data_size; 640 - * int __cpu 641 - * int pc; 642 - * 643 - * pc = preempt_count(); 644 - * 645 - * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); 646 - * 647 - * // Below we want to get the aligned size by taking into account 648 - * // the u32 field that will later store the buffer size 649 - * __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32), 650 - * sizeof(u64)); 651 - * __entry_size -= sizeof(u32); 652 - * 653 - * // Protect the non nmi buffer 654 - * // This also protects the rcu read side 655 - * local_irq_save(irq_flags); 656 - * __cpu = smp_processor_id(); 657 - * 658 - * if (in_nmi()) 659 - * trace_buf = rcu_dereference_sched(perf_trace_buf_nmi); 660 - * else 661 - * trace_buf = rcu_dereference_sched(perf_trace_buf); 662 - * 663 - * if (!trace_buf) 664 - * goto end; 665 - * 666 - * trace_buf = per_cpu_ptr(trace_buf, __cpu); 667 - * 668 - * // Avoid recursion from perf that could mess up the buffer 669 - * if (trace_buf->recursion++) 670 - * goto end_recursion; 671 - * 672 - * raw_data = trace_buf->buf; 673 - * 674 - * // Make recursion update visible before entering perf_tp_event 675 - * // so that we protect from perf recursions. 676 - * 677 - * barrier(); 678 - * 679 - * //zero dead bytes from alignment to avoid stack leak to userspace: 680 - * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; 681 - * entry = (struct ftrace_raw_<call> *)raw_data; 682 - * ent = &entry->ent; 683 - * tracing_generic_entry_update(ent, irq_flags, pc); 684 - * ent->type = event_call->id; 685 - * 686 - * <tstruct> <- do some jobs with dynamic arrays 687 - * 688 - * <assign> <- affect our values 689 - * 690 - * perf_tp_event(event_call->id, __addr, __count, entry, 691 - * __entry_size); <- submit them to perf counter 692 - * 693 - * } 694 - */ 695 622 696 623 #ifdef CONFIG_PERF_EVENTS 697 624
+30 -9
kernel/trace/trace.c
··· 484 484 static struct { 485 485 u64 (*func)(void); 486 486 const char *name; 487 + int in_ns; /* is this clock in nanoseconds? */ 487 488 } trace_clocks[] = { 488 - { trace_clock_local, "local" }, 489 - { trace_clock_global, "global" }, 490 - { trace_clock_counter, "counter" }, 489 + { trace_clock_local, "local", 1 }, 490 + { trace_clock_global, "global", 1 }, 491 + { trace_clock_counter, "counter", 0 }, 492 + ARCH_TRACE_CLOCKS 491 493 }; 492 494 493 495 int trace_clock_id; ··· 2479 2477 if (ring_buffer_overruns(iter->tr->buffer)) 2480 2478 iter->iter_flags |= TRACE_FILE_ANNOTATE; 2481 2479 2480 + /* Output in nanoseconds only if we are using a clock in nanoseconds. */ 2481 + if (trace_clocks[trace_clock_id].in_ns) 2482 + iter->iter_flags |= TRACE_FILE_TIME_IN_NS; 2483 + 2482 2484 /* stop the trace while dumping */ 2483 2485 tracing_stop(); 2484 2486 ··· 3343 3337 3344 3338 if (trace_flags & TRACE_ITER_LATENCY_FMT) 3345 3339 iter->iter_flags |= TRACE_FILE_LAT_FMT; 3340 + 3341 + /* Output in nanoseconds only if we are using a clock in nanoseconds. */ 3342 + if (trace_clocks[trace_clock_id].in_ns) 3343 + iter->iter_flags |= TRACE_FILE_TIME_IN_NS; 3346 3344 3347 3345 iter->cpu_file = cpu_file; 3348 3346 iter->tr = &global_trace; ··· 4388 4378 cnt = ring_buffer_bytes_cpu(tr->buffer, cpu); 4389 4379 trace_seq_printf(s, "bytes: %ld\n", cnt); 4390 4380 4391 - t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu)); 4392 - usec_rem = do_div(t, USEC_PER_SEC); 4393 - trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", t, usec_rem); 4381 + if (trace_clocks[trace_clock_id].in_ns) { 4382 + /* local or global for trace_clock */ 4383 + t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu)); 4384 + usec_rem = do_div(t, USEC_PER_SEC); 4385 + trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", 4386 + t, usec_rem); 4394 4387 4395 - t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu)); 4396 - usec_rem = do_div(t, USEC_PER_SEC); 4397 - trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); 4388 + t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu)); 4389 + usec_rem = do_div(t, USEC_PER_SEC); 4390 + trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); 4391 + } else { 4392 + /* counter or tsc mode for trace_clock */ 4393 + trace_seq_printf(s, "oldest event ts: %llu\n", 4394 + ring_buffer_oldest_event_ts(tr->buffer, cpu)); 4395 + 4396 + trace_seq_printf(s, "now ts: %llu\n", 4397 + ring_buffer_time_stamp(tr->buffer, cpu)); 4398 + } 4398 4399 4399 4400 cnt = ring_buffer_dropped_events_cpu(tr->buffer, cpu); 4400 4401 trace_seq_printf(s, "dropped events: %ld\n", cnt);
-4
kernel/trace/trace.h
··· 406 406 void tracing_start_sched_switch_record(void); 407 407 int register_tracer(struct tracer *type); 408 408 int is_tracing_stopped(void); 409 - enum trace_file_type { 410 - TRACE_FILE_LAT_FMT = 1, 411 - TRACE_FILE_ANNOTATE = 2, 412 - }; 413 409 414 410 extern cpumask_var_t __read_mostly tracing_buffer_mask; 415 411
+53 -25
kernel/trace/trace_output.c
··· 610 610 return trace_print_lat_fmt(s, entry); 611 611 } 612 612 613 - static unsigned long preempt_mark_thresh = 100; 613 + static unsigned long preempt_mark_thresh_us = 100; 614 614 615 615 static int 616 - lat_print_timestamp(struct trace_seq *s, u64 abs_usecs, 617 - unsigned long rel_usecs) 616 + lat_print_timestamp(struct trace_iterator *iter, u64 next_ts) 618 617 { 619 - return trace_seq_printf(s, " %4lldus%c: ", abs_usecs, 620 - rel_usecs > preempt_mark_thresh ? '!' : 621 - rel_usecs > 1 ? '+' : ' '); 618 + unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE; 619 + unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS; 620 + unsigned long long abs_ts = iter->ts - iter->tr->time_start; 621 + unsigned long long rel_ts = next_ts - iter->ts; 622 + struct trace_seq *s = &iter->seq; 623 + 624 + if (in_ns) { 625 + abs_ts = ns2usecs(abs_ts); 626 + rel_ts = ns2usecs(rel_ts); 627 + } 628 + 629 + if (verbose && in_ns) { 630 + unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC); 631 + unsigned long abs_msec = (unsigned long)abs_ts; 632 + unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC); 633 + unsigned long rel_msec = (unsigned long)rel_ts; 634 + 635 + return trace_seq_printf( 636 + s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ", 637 + ns2usecs(iter->ts), 638 + abs_msec, abs_usec, 639 + rel_msec, rel_usec); 640 + } else if (verbose && !in_ns) { 641 + return trace_seq_printf( 642 + s, "[%016llx] %lld (+%lld): ", 643 + iter->ts, abs_ts, rel_ts); 644 + } else if (!verbose && in_ns) { 645 + return trace_seq_printf( 646 + s, " %4lldus%c: ", 647 + abs_ts, 648 + rel_ts > preempt_mark_thresh_us ? '!' : 649 + rel_ts > 1 ? '+' : ' '); 650 + } else { /* !verbose && !in_ns */ 651 + return trace_seq_printf(s, " %4lld: ", abs_ts); 652 + } 622 653 } 623 654 624 655 int trace_print_context(struct trace_iterator *iter) 625 656 { 626 657 struct trace_seq *s = &iter->seq; 627 658 struct trace_entry *entry = iter->ent; 628 - unsigned long long t = ns2usecs(iter->ts); 629 - unsigned long usec_rem = do_div(t, USEC_PER_SEC); 630 - unsigned long secs = (unsigned long)t; 659 + unsigned long long t; 660 + unsigned long secs, usec_rem; 631 661 char comm[TASK_COMM_LEN]; 632 662 int ret; 633 663 ··· 674 644 return 0; 675 645 } 676 646 677 - return trace_seq_printf(s, " %5lu.%06lu: ", 678 - secs, usec_rem); 647 + if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { 648 + t = ns2usecs(iter->ts); 649 + usec_rem = do_div(t, USEC_PER_SEC); 650 + secs = (unsigned long)t; 651 + return trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem); 652 + } else 653 + return trace_seq_printf(s, " %12llu: ", iter->ts); 679 654 } 680 655 681 656 int trace_print_lat_context(struct trace_iterator *iter) ··· 694 659 *next_entry = trace_find_next_entry(iter, NULL, 695 660 &next_ts); 696 661 unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); 697 - unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start); 698 - unsigned long rel_usecs; 699 662 700 663 /* Restore the original ent_size */ 701 664 iter->ent_size = ent_size; 702 665 703 666 if (!next_entry) 704 667 next_ts = iter->ts; 705 - rel_usecs = ns2usecs(next_ts - iter->ts); 706 668 707 669 if (verbose) { 708 670 char comm[TASK_COMM_LEN]; 709 671 710 672 trace_find_cmdline(entry->pid, comm); 711 673 712 - ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]" 713 - " %ld.%03ldms (+%ld.%03ldms): ", comm, 714 - entry->pid, iter->cpu, entry->flags, 715 - entry->preempt_count, iter->idx, 716 - ns2usecs(iter->ts), 717 - abs_usecs / USEC_PER_MSEC, 718 - abs_usecs % USEC_PER_MSEC, 719 - rel_usecs / USEC_PER_MSEC, 720 - rel_usecs % USEC_PER_MSEC); 674 + ret = trace_seq_printf( 675 + s, "%16s %5d %3d %d %08x %08lx ", 676 + comm, entry->pid, iter->cpu, entry->flags, 677 + entry->preempt_count, iter->idx); 721 678 } else { 722 679 ret = lat_print_generic(s, entry, iter->cpu); 723 - if (ret) 724 - ret = lat_print_timestamp(s, abs_usecs, rel_usecs); 725 680 } 681 + 682 + if (ret) 683 + ret = lat_print_timestamp(iter, next_ts); 726 684 727 685 return ret; 728 686 }