diff options
37 files changed, 176 insertions, 111 deletions
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index 64ffc9e9e548..dcfabb9f05a0 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild | |||
@@ -11,3 +11,4 @@ header-y += reg.h | |||
11 | header-y += regdef.h | 11 | header-y += regdef.h |
12 | header-y += sysinfo.h | 12 | header-y += sysinfo.h |
13 | generic-y += exec.h | 13 | generic-y += exec.h |
14 | generic-y += trace_clock.h | ||
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index f70ae175a3d6..514e398f1a07 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild | |||
@@ -31,5 +31,6 @@ generic-y += sockios.h | |||
31 | generic-y += termbits.h | 31 | generic-y += termbits.h |
32 | generic-y += termios.h | 32 | generic-y += termios.h |
33 | generic-y += timex.h | 33 | generic-y += timex.h |
34 | generic-y += trace_clock.h | ||
34 | generic-y += types.h | 35 | generic-y += types.h |
35 | generic-y += unaligned.h | 36 | generic-y += unaligned.h |
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index a581a2205938..6e9ca462127f 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild | |||
@@ -43,6 +43,7 @@ generic-y += swab.h | |||
43 | generic-y += termbits.h | 43 | generic-y += termbits.h |
44 | generic-y += termios.h | 44 | generic-y += termios.h |
45 | generic-y += topology.h | 45 | generic-y += topology.h |
46 | generic-y += trace_clock.h | ||
46 | generic-y += types.h | 47 | generic-y += types.h |
47 | generic-y += unaligned.h | 48 | generic-y += unaligned.h |
48 | generic-y += user.h | 49 | generic-y += user.h |
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index 4807ded352c5..4dd4f78d3dcc 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild | |||
@@ -1,3 +1,4 @@ | |||
1 | 1 | ||
2 | generic-y += clkdev.h | 2 | generic-y += clkdev.h |
3 | generic-y += exec.h | 3 | generic-y += exec.h |
4 | generic-y += trace_clock.h | ||
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index 5a0625aad6a0..27d70759474c 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild | |||
@@ -38,6 +38,7 @@ generic-y += statfs.h | |||
38 | generic-y += termbits.h | 38 | generic-y += termbits.h |
39 | generic-y += termios.h | 39 | generic-y += termios.h |
40 | generic-y += topology.h | 40 | generic-y += topology.h |
41 | generic-y += trace_clock.h | ||
41 | generic-y += types.h | 42 | generic-y += types.h |
42 | generic-y += ucontext.h | 43 | generic-y += ucontext.h |
43 | generic-y += unaligned.h | 44 | generic-y += unaligned.h |
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild index 112a496d8355..eae7b5963e86 100644 --- a/arch/c6x/include/asm/Kbuild +++ b/arch/c6x/include/asm/Kbuild | |||
@@ -49,6 +49,7 @@ generic-y += termbits.h | |||
49 | generic-y += termios.h | 49 | generic-y += termios.h |
50 | generic-y += tlbflush.h | 50 | generic-y += tlbflush.h |
51 | generic-y += topology.h | 51 | generic-y += topology.h |
52 | generic-y += trace_clock.h | ||
52 | generic-y += types.h | 53 | generic-y += types.h |
53 | generic-y += ucontext.h | 54 | generic-y += ucontext.h |
54 | generic-y += user.h | 55 | generic-y += user.h |
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 6d43a951b5ec..15a122c3767c 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild | |||
@@ -11,3 +11,4 @@ header-y += sync_serial.h | |||
11 | generic-y += clkdev.h | 11 | generic-y += clkdev.h |
12 | generic-y += exec.h | 12 | generic-y += exec.h |
13 | generic-y += module.h | 13 | generic-y += module.h |
14 | generic-y += trace_clock.h | ||
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index 4a159da23633..c5d767028306 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild | |||
@@ -1,3 +1,4 @@ | |||
1 | 1 | ||
2 | generic-y += clkdev.h | 2 | generic-y += clkdev.h |
3 | generic-y += exec.h | 3 | generic-y += exec.h |
4 | generic-y += trace_clock.h | ||
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild index 50bbf387b2f8..4bc8ae73e08a 100644 --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild | |||
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm | |||
3 | generic-y += clkdev.h | 3 | generic-y += clkdev.h |
4 | generic-y += exec.h | 4 | generic-y += exec.h |
5 | generic-y += module.h | 5 | generic-y += module.h |
6 | generic-y += trace_clock.h | ||
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 3bfa9b30f448..bdb54ceb53bc 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild | |||
@@ -48,6 +48,7 @@ generic-y += stat.h | |||
48 | generic-y += termbits.h | 48 | generic-y += termbits.h |
49 | generic-y += termios.h | 49 | generic-y += termios.h |
50 | generic-y += topology.h | 50 | generic-y += topology.h |
51 | generic-y += trace_clock.h | ||
51 | generic-y += types.h | 52 | generic-y += types.h |
52 | generic-y += ucontext.h | 53 | generic-y += ucontext.h |
53 | generic-y += unaligned.h | 54 | generic-y += unaligned.h |
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index dd02f09b6eda..05b03ecd7933 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild | |||
@@ -2,3 +2,4 @@ | |||
2 | generic-y += clkdev.h | 2 | generic-y += clkdev.h |
3 | generic-y += exec.h | 3 | generic-y += exec.h |
4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
5 | generic-y += trace_clock.h | ||
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index 50bbf387b2f8..4bc8ae73e08a 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild | |||
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm | |||
3 | generic-y += clkdev.h | 3 | generic-y += clkdev.h |
4 | generic-y += exec.h | 4 | generic-y += exec.h |
5 | generic-y += module.h | 5 | generic-y += module.h |
6 | generic-y += trace_clock.h | ||
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 88fa3ac86fae..7f1949c0e089 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild | |||
@@ -24,6 +24,7 @@ generic-y += sections.h | |||
24 | generic-y += siginfo.h | 24 | generic-y += siginfo.h |
25 | generic-y += statfs.h | 25 | generic-y += statfs.h |
26 | generic-y += topology.h | 26 | generic-y += topology.h |
27 | generic-y += trace_clock.h | ||
27 | generic-y += types.h | 28 | generic-y += types.h |
28 | generic-y += word-at-a-time.h | 29 | generic-y += word-at-a-time.h |
29 | generic-y += xor.h | 30 | generic-y += xor.h |
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 8653072d7e9f..2957fcc71764 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild | |||
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm | |||
3 | header-y += elf.h | 3 | header-y += elf.h |
4 | generic-y += clkdev.h | 4 | generic-y += clkdev.h |
5 | generic-y += exec.h | 5 | generic-y += exec.h |
6 | generic-y += trace_clock.h | ||
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 533053d12ced..9b54b7a403d4 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild | |||
@@ -1 +1,2 @@ | |||
1 | # MIPS headers | 1 | # MIPS headers |
2 | generic-y += trace_clock.h | ||
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index 4a159da23633..c5d767028306 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild | |||
@@ -1,3 +1,4 @@ | |||
1 | 1 | ||
2 | generic-y += clkdev.h | 2 | generic-y += clkdev.h |
3 | generic-y += exec.h | 3 | generic-y += exec.h |
4 | generic-y += trace_clock.h | ||
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index 78de6805268d..8971026e1c63 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild | |||
@@ -60,6 +60,7 @@ generic-y += swab.h | |||
60 | generic-y += termbits.h | 60 | generic-y += termbits.h |
61 | generic-y += termios.h | 61 | generic-y += termios.h |
62 | generic-y += topology.h | 62 | generic-y += topology.h |
63 | generic-y += trace_clock.h | ||
63 | generic-y += types.h | 64 | generic-y += types.h |
64 | generic-y += ucontext.h | 65 | generic-y += ucontext.h |
65 | generic-y += user.h | 66 | generic-y += user.h |
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index bac8debecffb..ff4c9faed546 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild | |||
@@ -3,3 +3,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \ | |||
3 | segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \ | 3 | segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \ |
4 | div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ | 4 | div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ |
5 | poll.h xor.h clkdev.h exec.h | 5 | poll.h xor.h clkdev.h exec.h |
6 | generic-y += trace_clock.h | ||
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index a4fe15e33c6f..2d62b484b3fc 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild | |||
@@ -2,3 +2,4 @@ | |||
2 | 2 | ||
3 | generic-y += clkdev.h | 3 | generic-y += clkdev.h |
4 | generic-y += rwsem.h | 4 | generic-y += rwsem.h |
5 | generic-y += trace_clock.h | ||
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 0633dc6d254d..f313f9cbcf44 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild | |||
@@ -1,3 +1,4 @@ | |||
1 | 1 | ||
2 | 2 | ||
3 | generic-y += clkdev.h | 3 | generic-y += clkdev.h |
4 | generic-y += trace_clock.h | ||
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index ec697aeefd05..16e41fe1a419 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild | |||
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm | |||
3 | header-y += | 3 | header-y += |
4 | 4 | ||
5 | generic-y += clkdev.h | 5 | generic-y += clkdev.h |
6 | generic-y += trace_clock.h | ||
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 29f83beeef7a..280bea9e5e2b 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild | |||
@@ -31,5 +31,6 @@ generic-y += socket.h | |||
31 | generic-y += statfs.h | 31 | generic-y += statfs.h |
32 | generic-y += termbits.h | 32 | generic-y += termbits.h |
33 | generic-y += termios.h | 33 | generic-y += termios.h |
34 | generic-y += trace_clock.h | ||
34 | generic-y += ucontext.h | 35 | generic-y += ucontext.h |
35 | generic-y += xor.h | 36 | generic-y += xor.h |
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 645a58da0e86..e26d430ce2fd 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild | |||
@@ -8,4 +8,5 @@ generic-y += local64.h | |||
8 | generic-y += irq_regs.h | 8 | generic-y += irq_regs.h |
9 | generic-y += local.h | 9 | generic-y += local.h |
10 | generic-y += module.h | 10 | generic-y += module.h |
11 | generic-y += trace_clock.h | ||
11 | generic-y += word-at-a-time.h | 12 | generic-y += word-at-a-time.h |
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 6948015e08a2..b17b9b8e53cd 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild | |||
@@ -34,5 +34,6 @@ generic-y += sockios.h | |||
34 | generic-y += statfs.h | 34 | generic-y += statfs.h |
35 | generic-y += termbits.h | 35 | generic-y += termbits.h |
36 | generic-y += termios.h | 36 | generic-y += termios.h |
37 | generic-y += trace_clock.h | ||
37 | generic-y += types.h | 38 | generic-y += types.h |
38 | generic-y += xor.h | 39 | generic-y += xor.h |
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 0f6e7b328265..b30f34a79882 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild | |||
@@ -2,3 +2,4 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h | |||
2 | generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h | 2 | generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h |
3 | generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h | 3 | generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h |
4 | generic-y += switch_to.h clkdev.h | 4 | generic-y += switch_to.h clkdev.h |
5 | generic-y += trace_clock.h | ||
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index 601e92f18af6..89d8b6c4e39a 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild | |||
@@ -53,6 +53,7 @@ generic-y += syscalls.h | |||
53 | generic-y += termbits.h | 53 | generic-y += termbits.h |
54 | generic-y += termios.h | 54 | generic-y += termios.h |
55 | generic-y += topology.h | 55 | generic-y += topology.h |
56 | generic-y += trace_clock.h | ||
56 | generic-y += types.h | 57 | generic-y += types.h |
57 | generic-y += ucontext.h | 58 | generic-y += ucontext.h |
58 | generic-y += unaligned.h | 59 | generic-y += unaligned.h |
diff --git a/arch/x86/include/asm/trace_clock.h b/arch/x86/include/asm/trace_clock.h new file mode 100644 index 000000000000..beab86cc282d --- /dev/null +++ b/arch/x86/include/asm/trace_clock.h | |||
@@ -0,0 +1,20 @@ | |||
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 */ | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 9fd5eed3f8f5..34e923a53762 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -61,6 +61,7 @@ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o | |||
61 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 61 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
62 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 62 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
63 | obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o | 63 | obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o |
64 | obj-$(CONFIG_X86_TSC) += trace_clock.o | ||
64 | obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o | 65 | obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o |
65 | obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o | 66 | obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o |
66 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o | 67 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o |
diff --git a/arch/x86/kernel/trace_clock.c b/arch/x86/kernel/trace_clock.c new file mode 100644 index 000000000000..25b993729f9b --- /dev/null +++ b/arch/x86/kernel/trace_clock.c | |||
@@ -0,0 +1,21 @@ | |||
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 | } | ||
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 6d1302789995..095f0a2244f7 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild | |||
@@ -25,4 +25,5 @@ generic-y += siginfo.h | |||
25 | generic-y += statfs.h | 25 | generic-y += statfs.h |
26 | generic-y += termios.h | 26 | generic-y += termios.h |
27 | generic-y += topology.h | 27 | generic-y += topology.h |
28 | generic-y += trace_clock.h | ||
28 | generic-y += xor.h | 29 | generic-y += xor.h |
diff --git a/include/asm-generic/trace_clock.h b/include/asm-generic/trace_clock.h new file mode 100644 index 000000000000..6726f1bafb5e --- /dev/null +++ b/include/asm-generic/trace_clock.h | |||
@@ -0,0 +1,16 @@ | |||
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 */ | ||
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index b80c8ddfbbdc..a3d489531d83 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -86,6 +86,12 @@ struct trace_iterator { | |||
86 | cpumask_var_t started; | 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 | struct trace_event; | 96 | struct trace_event; |
91 | 97 | ||
diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h index 4eb490237d4c..d563f37e1a1d 100644 --- a/include/linux/trace_clock.h +++ b/include/linux/trace_clock.h | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | 14 | ||
15 | #include <asm/trace_clock.h> | ||
16 | |||
15 | extern u64 notrace trace_clock_local(void); | 17 | extern u64 notrace trace_clock_local(void); |
16 | extern u64 notrace trace_clock(void); | 18 | extern u64 notrace trace_clock(void); |
17 | extern u64 notrace trace_clock_global(void); | 19 | extern u64 notrace trace_clock_global(void); |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 698f2a890322..40dc5e8fe340 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -619,79 +619,6 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call | |||
619 | 619 | ||
620 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 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 | #ifdef CONFIG_PERF_EVENTS | 623 | #ifdef CONFIG_PERF_EVENTS |
697 | 624 | ||
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c1434b5ce4d1..b69cc380322d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -484,10 +484,12 @@ static const char *trace_options[] = { | |||
484 | static struct { | 484 | static struct { |
485 | u64 (*func)(void); | 485 | u64 (*func)(void); |
486 | const char *name; | 486 | const char *name; |
487 | int in_ns; /* is this clock in nanoseconds? */ | ||
487 | } trace_clocks[] = { | 488 | } trace_clocks[] = { |
488 | { trace_clock_local, "local" }, | 489 | { trace_clock_local, "local", 1 }, |
489 | { trace_clock_global, "global" }, | 490 | { trace_clock_global, "global", 1 }, |
490 | { trace_clock_counter, "counter" }, | 491 | { trace_clock_counter, "counter", 0 }, |
492 | ARCH_TRACE_CLOCKS | ||
491 | }; | 493 | }; |
492 | 494 | ||
493 | int trace_clock_id; | 495 | int trace_clock_id; |
@@ -2477,6 +2479,10 @@ __tracing_open(struct inode *inode, struct file *file) | |||
2477 | if (ring_buffer_overruns(iter->tr->buffer)) | 2479 | if (ring_buffer_overruns(iter->tr->buffer)) |
2478 | iter->iter_flags |= TRACE_FILE_ANNOTATE; | 2480 | iter->iter_flags |= TRACE_FILE_ANNOTATE; |
2479 | 2481 | ||
2482 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ | ||
2483 | if (trace_clocks[trace_clock_id].in_ns) | ||
2484 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; | ||
2485 | |||
2480 | /* stop the trace while dumping */ | 2486 | /* stop the trace while dumping */ |
2481 | tracing_stop(); | 2487 | tracing_stop(); |
2482 | 2488 | ||
@@ -3338,6 +3344,10 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
3338 | if (trace_flags & TRACE_ITER_LATENCY_FMT) | 3344 | if (trace_flags & TRACE_ITER_LATENCY_FMT) |
3339 | iter->iter_flags |= TRACE_FILE_LAT_FMT; | 3345 | iter->iter_flags |= TRACE_FILE_LAT_FMT; |
3340 | 3346 | ||
3347 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ | ||
3348 | if (trace_clocks[trace_clock_id].in_ns) | ||
3349 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; | ||
3350 | |||
3341 | iter->cpu_file = cpu_file; | 3351 | iter->cpu_file = cpu_file; |
3342 | iter->tr = &global_trace; | 3352 | iter->tr = &global_trace; |
3343 | mutex_init(&iter->mutex); | 3353 | mutex_init(&iter->mutex); |
@@ -4378,13 +4388,24 @@ tracing_stats_read(struct file *filp, char __user *ubuf, | |||
4378 | cnt = ring_buffer_bytes_cpu(tr->buffer, cpu); | 4388 | cnt = ring_buffer_bytes_cpu(tr->buffer, cpu); |
4379 | trace_seq_printf(s, "bytes: %ld\n", cnt); | 4389 | trace_seq_printf(s, "bytes: %ld\n", cnt); |
4380 | 4390 | ||
4381 | t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu)); | 4391 | if (trace_clocks[trace_clock_id].in_ns) { |
4382 | usec_rem = do_div(t, USEC_PER_SEC); | 4392 | /* local or global for trace_clock */ |
4383 | trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", t, usec_rem); | 4393 | t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu)); |
4394 | usec_rem = do_div(t, USEC_PER_SEC); | ||
4395 | trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", | ||
4396 | t, usec_rem); | ||
4384 | 4397 | ||
4385 | t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu)); | 4398 | t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu)); |
4386 | usec_rem = do_div(t, USEC_PER_SEC); | 4399 | usec_rem = do_div(t, USEC_PER_SEC); |
4387 | trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); | 4400 | trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); |
4401 | } else { | ||
4402 | /* counter or tsc mode for trace_clock */ | ||
4403 | trace_seq_printf(s, "oldest event ts: %llu\n", | ||
4404 | ring_buffer_oldest_event_ts(tr->buffer, cpu)); | ||
4405 | |||
4406 | trace_seq_printf(s, "now ts: %llu\n", | ||
4407 | ring_buffer_time_stamp(tr->buffer, cpu)); | ||
4408 | } | ||
4388 | 4409 | ||
4389 | cnt = ring_buffer_dropped_events_cpu(tr->buffer, cpu); | 4410 | cnt = ring_buffer_dropped_events_cpu(tr->buffer, cpu); |
4390 | trace_seq_printf(s, "dropped events: %ld\n", cnt); | 4411 | trace_seq_printf(s, "dropped events: %ld\n", cnt); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 55010ed175f0..c75d7988902c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -406,10 +406,6 @@ void tracing_stop_sched_switch_record(void); | |||
406 | void tracing_start_sched_switch_record(void); | 406 | void tracing_start_sched_switch_record(void); |
407 | int register_tracer(struct tracer *type); | 407 | int register_tracer(struct tracer *type); |
408 | int is_tracing_stopped(void); | 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 | extern cpumask_var_t __read_mostly tracing_buffer_mask; | 410 | extern cpumask_var_t __read_mostly tracing_buffer_mask; |
415 | 411 | ||
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 123b189c732c..194d79602dc7 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -610,24 +610,54 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) | |||
610 | return trace_print_lat_fmt(s, entry); | 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 | static int | 615 | static int |
616 | lat_print_timestamp(struct trace_seq *s, u64 abs_usecs, | 616 | lat_print_timestamp(struct trace_iterator *iter, u64 next_ts) |
617 | unsigned long rel_usecs) | ||
618 | { | 617 | { |
619 | return trace_seq_printf(s, " %4lldus%c: ", abs_usecs, | 618 | unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE; |
620 | rel_usecs > preempt_mark_thresh ? '!' : | 619 | unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS; |
621 | rel_usecs > 1 ? '+' : ' '); | 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 | int trace_print_context(struct trace_iterator *iter) | 655 | int trace_print_context(struct trace_iterator *iter) |
625 | { | 656 | { |
626 | struct trace_seq *s = &iter->seq; | 657 | struct trace_seq *s = &iter->seq; |
627 | struct trace_entry *entry = iter->ent; | 658 | struct trace_entry *entry = iter->ent; |
628 | unsigned long long t = ns2usecs(iter->ts); | 659 | unsigned long long t; |
629 | unsigned long usec_rem = do_div(t, USEC_PER_SEC); | 660 | unsigned long secs, usec_rem; |
630 | unsigned long secs = (unsigned long)t; | ||
631 | char comm[TASK_COMM_LEN]; | 661 | char comm[TASK_COMM_LEN]; |
632 | int ret; | 662 | int ret; |
633 | 663 | ||
@@ -644,8 +674,13 @@ int trace_print_context(struct trace_iterator *iter) | |||
644 | return 0; | 674 | return 0; |
645 | } | 675 | } |
646 | 676 | ||
647 | return trace_seq_printf(s, " %5lu.%06lu: ", | 677 | if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { |
648 | secs, usec_rem); | 678 | t = ns2usecs(iter->ts); |
679 | usec_rem = do_div(t, USEC_PER_SEC); | ||
680 | secs = (unsigned long)t; | ||
681 | return trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem); | ||
682 | } else | ||
683 | return trace_seq_printf(s, " %12llu: ", iter->ts); | ||
649 | } | 684 | } |
650 | 685 | ||
651 | int trace_print_lat_context(struct trace_iterator *iter) | 686 | int trace_print_lat_context(struct trace_iterator *iter) |
@@ -659,36 +694,29 @@ int trace_print_lat_context(struct trace_iterator *iter) | |||
659 | *next_entry = trace_find_next_entry(iter, NULL, | 694 | *next_entry = trace_find_next_entry(iter, NULL, |
660 | &next_ts); | 695 | &next_ts); |
661 | unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); | 696 | unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); |
662 | unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start); | ||
663 | unsigned long rel_usecs; | ||
664 | 697 | ||
665 | /* Restore the original ent_size */ | 698 | /* Restore the original ent_size */ |
666 | iter->ent_size = ent_size; | 699 | iter->ent_size = ent_size; |
667 | 700 | ||
668 | if (!next_entry) | 701 | if (!next_entry) |
669 | next_ts = iter->ts; | 702 | next_ts = iter->ts; |
670 | rel_usecs = ns2usecs(next_ts - iter->ts); | ||
671 | 703 | ||
672 | if (verbose) { | 704 | if (verbose) { |
673 | char comm[TASK_COMM_LEN]; | 705 | char comm[TASK_COMM_LEN]; |
674 | 706 | ||
675 | trace_find_cmdline(entry->pid, comm); | 707 | trace_find_cmdline(entry->pid, comm); |
676 | 708 | ||
677 | ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]" | 709 | ret = trace_seq_printf( |
678 | " %ld.%03ldms (+%ld.%03ldms): ", comm, | 710 | s, "%16s %5d %3d %d %08x %08lx ", |
679 | entry->pid, iter->cpu, entry->flags, | 711 | comm, entry->pid, iter->cpu, entry->flags, |
680 | entry->preempt_count, iter->idx, | 712 | entry->preempt_count, iter->idx); |
681 | ns2usecs(iter->ts), | ||
682 | abs_usecs / USEC_PER_MSEC, | ||
683 | abs_usecs % USEC_PER_MSEC, | ||
684 | rel_usecs / USEC_PER_MSEC, | ||
685 | rel_usecs % USEC_PER_MSEC); | ||
686 | } else { | 713 | } else { |
687 | ret = lat_print_generic(s, entry, iter->cpu); | 714 | ret = lat_print_generic(s, entry, iter->cpu); |
688 | if (ret) | ||
689 | ret = lat_print_timestamp(s, abs_usecs, rel_usecs); | ||
690 | } | 715 | } |
691 | 716 | ||
717 | if (ret) | ||
718 | ret = lat_print_timestamp(iter, next_ts); | ||
719 | |||
692 | return ret; | 720 | return ret; |
693 | } | 721 | } |
694 | 722 | ||