Commit 7eb69529cbaf4229baf5559a400a7a46352c6e52
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
Merge tag 'trace-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt: "Not much changes for the 3.12 merge window. The major tracing changes are still in flux, and will have to wait for 3.13. The changes for 3.12 are mostly clean ups and minor fixes. H Peter Anvin added a check to x86_32 static function tracing that helps a small segment of the kernel community. Oleg Nesterov had a few changes from 3.11, but were mostly clean ups and not worth pushing in the -rc time frame. Li Zefan had small clean up with annotating a raw_init with __init. I fixed a slight race in updating function callbacks, but the race is so small and the bug that happens when it occurs is so minor it's not even worth pushing to stable. The only real enhancement is from Alexander Z Lam that made the tracing_cpumask work for trace buffer instances, instead of them all sharing a global cpumask" * tag 'trace-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: ftrace/rcu: Do not trace debug_lockdep_rcu_enabled() x86-32, ftrace: Fix static ftrace when early microcode is enabled ftrace: Fix a slight race in modifying what function callback gets traced tracing: Make tracing_cpumask available for all instances tracing: Kill the !CONFIG_MODULES code in trace_events.c tracing: Don't pass file_operations array to event_create_dir() tracing: Kill trace_create_file_ops() and friends tracing/syscalls: Annotate raw_init function with __init
Showing 7 changed files Inline Diff
arch/x86/kernel/entry_32.S
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
4 | */ | 4 | */ |
5 | 5 | ||
6 | /* | 6 | /* |
7 | * entry.S contains the system-call and fault low-level handling routines. | 7 | * entry.S contains the system-call and fault low-level handling routines. |
8 | * This also contains the timer-interrupt handler, as well as all interrupts | 8 | * This also contains the timer-interrupt handler, as well as all interrupts |
9 | * and faults that can result in a task-switch. | 9 | * and faults that can result in a task-switch. |
10 | * | 10 | * |
11 | * NOTE: This code handles signal-recognition, which happens every time | 11 | * NOTE: This code handles signal-recognition, which happens every time |
12 | * after a timer-interrupt and after each system call. | 12 | * after a timer-interrupt and after each system call. |
13 | * | 13 | * |
14 | * I changed all the .align's to 4 (16 byte alignment), as that's faster | 14 | * I changed all the .align's to 4 (16 byte alignment), as that's faster |
15 | * on a 486. | 15 | * on a 486. |
16 | * | 16 | * |
17 | * Stack layout in 'syscall_exit': | 17 | * Stack layout in 'syscall_exit': |
18 | * ptrace needs to have all regs on the stack. | 18 | * ptrace needs to have all regs on the stack. |
19 | * if the order here is changed, it needs to be | 19 | * if the order here is changed, it needs to be |
20 | * updated in fork.c:copy_process, signal.c:do_signal, | 20 | * updated in fork.c:copy_process, signal.c:do_signal, |
21 | * ptrace.c and ptrace.h | 21 | * ptrace.c and ptrace.h |
22 | * | 22 | * |
23 | * 0(%esp) - %ebx | 23 | * 0(%esp) - %ebx |
24 | * 4(%esp) - %ecx | 24 | * 4(%esp) - %ecx |
25 | * 8(%esp) - %edx | 25 | * 8(%esp) - %edx |
26 | * C(%esp) - %esi | 26 | * C(%esp) - %esi |
27 | * 10(%esp) - %edi | 27 | * 10(%esp) - %edi |
28 | * 14(%esp) - %ebp | 28 | * 14(%esp) - %ebp |
29 | * 18(%esp) - %eax | 29 | * 18(%esp) - %eax |
30 | * 1C(%esp) - %ds | 30 | * 1C(%esp) - %ds |
31 | * 20(%esp) - %es | 31 | * 20(%esp) - %es |
32 | * 24(%esp) - %fs | 32 | * 24(%esp) - %fs |
33 | * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS | 33 | * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS |
34 | * 2C(%esp) - orig_eax | 34 | * 2C(%esp) - orig_eax |
35 | * 30(%esp) - %eip | 35 | * 30(%esp) - %eip |
36 | * 34(%esp) - %cs | 36 | * 34(%esp) - %cs |
37 | * 38(%esp) - %eflags | 37 | * 38(%esp) - %eflags |
38 | * 3C(%esp) - %oldesp | 38 | * 3C(%esp) - %oldesp |
39 | * 40(%esp) - %oldss | 39 | * 40(%esp) - %oldss |
40 | * | 40 | * |
41 | * "current" is in register %ebx during any slow entries. | 41 | * "current" is in register %ebx during any slow entries. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/linkage.h> | 44 | #include <linux/linkage.h> |
45 | #include <linux/err.h> | 45 | #include <linux/err.h> |
46 | #include <asm/thread_info.h> | 46 | #include <asm/thread_info.h> |
47 | #include <asm/irqflags.h> | 47 | #include <asm/irqflags.h> |
48 | #include <asm/errno.h> | 48 | #include <asm/errno.h> |
49 | #include <asm/segment.h> | 49 | #include <asm/segment.h> |
50 | #include <asm/smp.h> | 50 | #include <asm/smp.h> |
51 | #include <asm/page_types.h> | 51 | #include <asm/page_types.h> |
52 | #include <asm/percpu.h> | 52 | #include <asm/percpu.h> |
53 | #include <asm/dwarf2.h> | 53 | #include <asm/dwarf2.h> |
54 | #include <asm/processor-flags.h> | 54 | #include <asm/processor-flags.h> |
55 | #include <asm/ftrace.h> | 55 | #include <asm/ftrace.h> |
56 | #include <asm/irq_vectors.h> | 56 | #include <asm/irq_vectors.h> |
57 | #include <asm/cpufeature.h> | 57 | #include <asm/cpufeature.h> |
58 | #include <asm/alternative-asm.h> | 58 | #include <asm/alternative-asm.h> |
59 | #include <asm/asm.h> | 59 | #include <asm/asm.h> |
60 | #include <asm/smap.h> | 60 | #include <asm/smap.h> |
61 | 61 | ||
62 | /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ | 62 | /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ |
63 | #include <linux/elf-em.h> | 63 | #include <linux/elf-em.h> |
64 | #define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE) | 64 | #define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE) |
65 | #define __AUDIT_ARCH_LE 0x40000000 | 65 | #define __AUDIT_ARCH_LE 0x40000000 |
66 | 66 | ||
67 | #ifndef CONFIG_AUDITSYSCALL | 67 | #ifndef CONFIG_AUDITSYSCALL |
68 | #define sysenter_audit syscall_trace_entry | 68 | #define sysenter_audit syscall_trace_entry |
69 | #define sysexit_audit syscall_exit_work | 69 | #define sysexit_audit syscall_exit_work |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | .section .entry.text, "ax" | 72 | .section .entry.text, "ax" |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * We use macros for low-level operations which need to be overridden | 75 | * We use macros for low-level operations which need to be overridden |
76 | * for paravirtualization. The following will never clobber any registers: | 76 | * for paravirtualization. The following will never clobber any registers: |
77 | * INTERRUPT_RETURN (aka. "iret") | 77 | * INTERRUPT_RETURN (aka. "iret") |
78 | * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") | 78 | * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") |
79 | * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). | 79 | * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). |
80 | * | 80 | * |
81 | * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must | 81 | * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must |
82 | * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). | 82 | * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). |
83 | * Allowing a register to be clobbered can shrink the paravirt replacement | 83 | * Allowing a register to be clobbered can shrink the paravirt replacement |
84 | * enough to patch inline, increasing performance. | 84 | * enough to patch inline, increasing performance. |
85 | */ | 85 | */ |
86 | 86 | ||
87 | #ifdef CONFIG_PREEMPT | 87 | #ifdef CONFIG_PREEMPT |
88 | #define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF | 88 | #define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF |
89 | #else | 89 | #else |
90 | #define preempt_stop(clobbers) | 90 | #define preempt_stop(clobbers) |
91 | #define resume_kernel restore_all | 91 | #define resume_kernel restore_all |
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | .macro TRACE_IRQS_IRET | 94 | .macro TRACE_IRQS_IRET |
95 | #ifdef CONFIG_TRACE_IRQFLAGS | 95 | #ifdef CONFIG_TRACE_IRQFLAGS |
96 | testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off? | 96 | testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off? |
97 | jz 1f | 97 | jz 1f |
98 | TRACE_IRQS_ON | 98 | TRACE_IRQS_ON |
99 | 1: | 99 | 1: |
100 | #endif | 100 | #endif |
101 | .endm | 101 | .endm |
102 | 102 | ||
103 | /* | 103 | /* |
104 | * User gs save/restore | 104 | * User gs save/restore |
105 | * | 105 | * |
106 | * %gs is used for userland TLS and kernel only uses it for stack | 106 | * %gs is used for userland TLS and kernel only uses it for stack |
107 | * canary which is required to be at %gs:20 by gcc. Read the comment | 107 | * canary which is required to be at %gs:20 by gcc. Read the comment |
108 | * at the top of stackprotector.h for more info. | 108 | * at the top of stackprotector.h for more info. |
109 | * | 109 | * |
110 | * Local labels 98 and 99 are used. | 110 | * Local labels 98 and 99 are used. |
111 | */ | 111 | */ |
112 | #ifdef CONFIG_X86_32_LAZY_GS | 112 | #ifdef CONFIG_X86_32_LAZY_GS |
113 | 113 | ||
114 | /* unfortunately push/pop can't be no-op */ | 114 | /* unfortunately push/pop can't be no-op */ |
115 | .macro PUSH_GS | 115 | .macro PUSH_GS |
116 | pushl_cfi $0 | 116 | pushl_cfi $0 |
117 | .endm | 117 | .endm |
118 | .macro POP_GS pop=0 | 118 | .macro POP_GS pop=0 |
119 | addl $(4 + \pop), %esp | 119 | addl $(4 + \pop), %esp |
120 | CFI_ADJUST_CFA_OFFSET -(4 + \pop) | 120 | CFI_ADJUST_CFA_OFFSET -(4 + \pop) |
121 | .endm | 121 | .endm |
122 | .macro POP_GS_EX | 122 | .macro POP_GS_EX |
123 | .endm | 123 | .endm |
124 | 124 | ||
125 | /* all the rest are no-op */ | 125 | /* all the rest are no-op */ |
126 | .macro PTGS_TO_GS | 126 | .macro PTGS_TO_GS |
127 | .endm | 127 | .endm |
128 | .macro PTGS_TO_GS_EX | 128 | .macro PTGS_TO_GS_EX |
129 | .endm | 129 | .endm |
130 | .macro GS_TO_REG reg | 130 | .macro GS_TO_REG reg |
131 | .endm | 131 | .endm |
132 | .macro REG_TO_PTGS reg | 132 | .macro REG_TO_PTGS reg |
133 | .endm | 133 | .endm |
134 | .macro SET_KERNEL_GS reg | 134 | .macro SET_KERNEL_GS reg |
135 | .endm | 135 | .endm |
136 | 136 | ||
137 | #else /* CONFIG_X86_32_LAZY_GS */ | 137 | #else /* CONFIG_X86_32_LAZY_GS */ |
138 | 138 | ||
139 | .macro PUSH_GS | 139 | .macro PUSH_GS |
140 | pushl_cfi %gs | 140 | pushl_cfi %gs |
141 | /*CFI_REL_OFFSET gs, 0*/ | 141 | /*CFI_REL_OFFSET gs, 0*/ |
142 | .endm | 142 | .endm |
143 | 143 | ||
144 | .macro POP_GS pop=0 | 144 | .macro POP_GS pop=0 |
145 | 98: popl_cfi %gs | 145 | 98: popl_cfi %gs |
146 | /*CFI_RESTORE gs*/ | 146 | /*CFI_RESTORE gs*/ |
147 | .if \pop <> 0 | 147 | .if \pop <> 0 |
148 | add $\pop, %esp | 148 | add $\pop, %esp |
149 | CFI_ADJUST_CFA_OFFSET -\pop | 149 | CFI_ADJUST_CFA_OFFSET -\pop |
150 | .endif | 150 | .endif |
151 | .endm | 151 | .endm |
152 | .macro POP_GS_EX | 152 | .macro POP_GS_EX |
153 | .pushsection .fixup, "ax" | 153 | .pushsection .fixup, "ax" |
154 | 99: movl $0, (%esp) | 154 | 99: movl $0, (%esp) |
155 | jmp 98b | 155 | jmp 98b |
156 | .popsection | 156 | .popsection |
157 | _ASM_EXTABLE(98b,99b) | 157 | _ASM_EXTABLE(98b,99b) |
158 | .endm | 158 | .endm |
159 | 159 | ||
160 | .macro PTGS_TO_GS | 160 | .macro PTGS_TO_GS |
161 | 98: mov PT_GS(%esp), %gs | 161 | 98: mov PT_GS(%esp), %gs |
162 | .endm | 162 | .endm |
163 | .macro PTGS_TO_GS_EX | 163 | .macro PTGS_TO_GS_EX |
164 | .pushsection .fixup, "ax" | 164 | .pushsection .fixup, "ax" |
165 | 99: movl $0, PT_GS(%esp) | 165 | 99: movl $0, PT_GS(%esp) |
166 | jmp 98b | 166 | jmp 98b |
167 | .popsection | 167 | .popsection |
168 | _ASM_EXTABLE(98b,99b) | 168 | _ASM_EXTABLE(98b,99b) |
169 | .endm | 169 | .endm |
170 | 170 | ||
171 | .macro GS_TO_REG reg | 171 | .macro GS_TO_REG reg |
172 | movl %gs, \reg | 172 | movl %gs, \reg |
173 | /*CFI_REGISTER gs, \reg*/ | 173 | /*CFI_REGISTER gs, \reg*/ |
174 | .endm | 174 | .endm |
175 | .macro REG_TO_PTGS reg | 175 | .macro REG_TO_PTGS reg |
176 | movl \reg, PT_GS(%esp) | 176 | movl \reg, PT_GS(%esp) |
177 | /*CFI_REL_OFFSET gs, PT_GS*/ | 177 | /*CFI_REL_OFFSET gs, PT_GS*/ |
178 | .endm | 178 | .endm |
179 | .macro SET_KERNEL_GS reg | 179 | .macro SET_KERNEL_GS reg |
180 | movl $(__KERNEL_STACK_CANARY), \reg | 180 | movl $(__KERNEL_STACK_CANARY), \reg |
181 | movl \reg, %gs | 181 | movl \reg, %gs |
182 | .endm | 182 | .endm |
183 | 183 | ||
184 | #endif /* CONFIG_X86_32_LAZY_GS */ | 184 | #endif /* CONFIG_X86_32_LAZY_GS */ |
185 | 185 | ||
186 | .macro SAVE_ALL | 186 | .macro SAVE_ALL |
187 | cld | 187 | cld |
188 | PUSH_GS | 188 | PUSH_GS |
189 | pushl_cfi %fs | 189 | pushl_cfi %fs |
190 | /*CFI_REL_OFFSET fs, 0;*/ | 190 | /*CFI_REL_OFFSET fs, 0;*/ |
191 | pushl_cfi %es | 191 | pushl_cfi %es |
192 | /*CFI_REL_OFFSET es, 0;*/ | 192 | /*CFI_REL_OFFSET es, 0;*/ |
193 | pushl_cfi %ds | 193 | pushl_cfi %ds |
194 | /*CFI_REL_OFFSET ds, 0;*/ | 194 | /*CFI_REL_OFFSET ds, 0;*/ |
195 | pushl_cfi %eax | 195 | pushl_cfi %eax |
196 | CFI_REL_OFFSET eax, 0 | 196 | CFI_REL_OFFSET eax, 0 |
197 | pushl_cfi %ebp | 197 | pushl_cfi %ebp |
198 | CFI_REL_OFFSET ebp, 0 | 198 | CFI_REL_OFFSET ebp, 0 |
199 | pushl_cfi %edi | 199 | pushl_cfi %edi |
200 | CFI_REL_OFFSET edi, 0 | 200 | CFI_REL_OFFSET edi, 0 |
201 | pushl_cfi %esi | 201 | pushl_cfi %esi |
202 | CFI_REL_OFFSET esi, 0 | 202 | CFI_REL_OFFSET esi, 0 |
203 | pushl_cfi %edx | 203 | pushl_cfi %edx |
204 | CFI_REL_OFFSET edx, 0 | 204 | CFI_REL_OFFSET edx, 0 |
205 | pushl_cfi %ecx | 205 | pushl_cfi %ecx |
206 | CFI_REL_OFFSET ecx, 0 | 206 | CFI_REL_OFFSET ecx, 0 |
207 | pushl_cfi %ebx | 207 | pushl_cfi %ebx |
208 | CFI_REL_OFFSET ebx, 0 | 208 | CFI_REL_OFFSET ebx, 0 |
209 | movl $(__USER_DS), %edx | 209 | movl $(__USER_DS), %edx |
210 | movl %edx, %ds | 210 | movl %edx, %ds |
211 | movl %edx, %es | 211 | movl %edx, %es |
212 | movl $(__KERNEL_PERCPU), %edx | 212 | movl $(__KERNEL_PERCPU), %edx |
213 | movl %edx, %fs | 213 | movl %edx, %fs |
214 | SET_KERNEL_GS %edx | 214 | SET_KERNEL_GS %edx |
215 | .endm | 215 | .endm |
216 | 216 | ||
217 | .macro RESTORE_INT_REGS | 217 | .macro RESTORE_INT_REGS |
218 | popl_cfi %ebx | 218 | popl_cfi %ebx |
219 | CFI_RESTORE ebx | 219 | CFI_RESTORE ebx |
220 | popl_cfi %ecx | 220 | popl_cfi %ecx |
221 | CFI_RESTORE ecx | 221 | CFI_RESTORE ecx |
222 | popl_cfi %edx | 222 | popl_cfi %edx |
223 | CFI_RESTORE edx | 223 | CFI_RESTORE edx |
224 | popl_cfi %esi | 224 | popl_cfi %esi |
225 | CFI_RESTORE esi | 225 | CFI_RESTORE esi |
226 | popl_cfi %edi | 226 | popl_cfi %edi |
227 | CFI_RESTORE edi | 227 | CFI_RESTORE edi |
228 | popl_cfi %ebp | 228 | popl_cfi %ebp |
229 | CFI_RESTORE ebp | 229 | CFI_RESTORE ebp |
230 | popl_cfi %eax | 230 | popl_cfi %eax |
231 | CFI_RESTORE eax | 231 | CFI_RESTORE eax |
232 | .endm | 232 | .endm |
233 | 233 | ||
234 | .macro RESTORE_REGS pop=0 | 234 | .macro RESTORE_REGS pop=0 |
235 | RESTORE_INT_REGS | 235 | RESTORE_INT_REGS |
236 | 1: popl_cfi %ds | 236 | 1: popl_cfi %ds |
237 | /*CFI_RESTORE ds;*/ | 237 | /*CFI_RESTORE ds;*/ |
238 | 2: popl_cfi %es | 238 | 2: popl_cfi %es |
239 | /*CFI_RESTORE es;*/ | 239 | /*CFI_RESTORE es;*/ |
240 | 3: popl_cfi %fs | 240 | 3: popl_cfi %fs |
241 | /*CFI_RESTORE fs;*/ | 241 | /*CFI_RESTORE fs;*/ |
242 | POP_GS \pop | 242 | POP_GS \pop |
243 | .pushsection .fixup, "ax" | 243 | .pushsection .fixup, "ax" |
244 | 4: movl $0, (%esp) | 244 | 4: movl $0, (%esp) |
245 | jmp 1b | 245 | jmp 1b |
246 | 5: movl $0, (%esp) | 246 | 5: movl $0, (%esp) |
247 | jmp 2b | 247 | jmp 2b |
248 | 6: movl $0, (%esp) | 248 | 6: movl $0, (%esp) |
249 | jmp 3b | 249 | jmp 3b |
250 | .popsection | 250 | .popsection |
251 | _ASM_EXTABLE(1b,4b) | 251 | _ASM_EXTABLE(1b,4b) |
252 | _ASM_EXTABLE(2b,5b) | 252 | _ASM_EXTABLE(2b,5b) |
253 | _ASM_EXTABLE(3b,6b) | 253 | _ASM_EXTABLE(3b,6b) |
254 | POP_GS_EX | 254 | POP_GS_EX |
255 | .endm | 255 | .endm |
256 | 256 | ||
257 | .macro RING0_INT_FRAME | 257 | .macro RING0_INT_FRAME |
258 | CFI_STARTPROC simple | 258 | CFI_STARTPROC simple |
259 | CFI_SIGNAL_FRAME | 259 | CFI_SIGNAL_FRAME |
260 | CFI_DEF_CFA esp, 3*4 | 260 | CFI_DEF_CFA esp, 3*4 |
261 | /*CFI_OFFSET cs, -2*4;*/ | 261 | /*CFI_OFFSET cs, -2*4;*/ |
262 | CFI_OFFSET eip, -3*4 | 262 | CFI_OFFSET eip, -3*4 |
263 | .endm | 263 | .endm |
264 | 264 | ||
265 | .macro RING0_EC_FRAME | 265 | .macro RING0_EC_FRAME |
266 | CFI_STARTPROC simple | 266 | CFI_STARTPROC simple |
267 | CFI_SIGNAL_FRAME | 267 | CFI_SIGNAL_FRAME |
268 | CFI_DEF_CFA esp, 4*4 | 268 | CFI_DEF_CFA esp, 4*4 |
269 | /*CFI_OFFSET cs, -2*4;*/ | 269 | /*CFI_OFFSET cs, -2*4;*/ |
270 | CFI_OFFSET eip, -3*4 | 270 | CFI_OFFSET eip, -3*4 |
271 | .endm | 271 | .endm |
272 | 272 | ||
273 | .macro RING0_PTREGS_FRAME | 273 | .macro RING0_PTREGS_FRAME |
274 | CFI_STARTPROC simple | 274 | CFI_STARTPROC simple |
275 | CFI_SIGNAL_FRAME | 275 | CFI_SIGNAL_FRAME |
276 | CFI_DEF_CFA esp, PT_OLDESP-PT_EBX | 276 | CFI_DEF_CFA esp, PT_OLDESP-PT_EBX |
277 | /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/ | 277 | /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/ |
278 | CFI_OFFSET eip, PT_EIP-PT_OLDESP | 278 | CFI_OFFSET eip, PT_EIP-PT_OLDESP |
279 | /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/ | 279 | /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/ |
280 | /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/ | 280 | /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/ |
281 | CFI_OFFSET eax, PT_EAX-PT_OLDESP | 281 | CFI_OFFSET eax, PT_EAX-PT_OLDESP |
282 | CFI_OFFSET ebp, PT_EBP-PT_OLDESP | 282 | CFI_OFFSET ebp, PT_EBP-PT_OLDESP |
283 | CFI_OFFSET edi, PT_EDI-PT_OLDESP | 283 | CFI_OFFSET edi, PT_EDI-PT_OLDESP |
284 | CFI_OFFSET esi, PT_ESI-PT_OLDESP | 284 | CFI_OFFSET esi, PT_ESI-PT_OLDESP |
285 | CFI_OFFSET edx, PT_EDX-PT_OLDESP | 285 | CFI_OFFSET edx, PT_EDX-PT_OLDESP |
286 | CFI_OFFSET ecx, PT_ECX-PT_OLDESP | 286 | CFI_OFFSET ecx, PT_ECX-PT_OLDESP |
287 | CFI_OFFSET ebx, PT_EBX-PT_OLDESP | 287 | CFI_OFFSET ebx, PT_EBX-PT_OLDESP |
288 | .endm | 288 | .endm |
289 | 289 | ||
290 | ENTRY(ret_from_fork) | 290 | ENTRY(ret_from_fork) |
291 | CFI_STARTPROC | 291 | CFI_STARTPROC |
292 | pushl_cfi %eax | 292 | pushl_cfi %eax |
293 | call schedule_tail | 293 | call schedule_tail |
294 | GET_THREAD_INFO(%ebp) | 294 | GET_THREAD_INFO(%ebp) |
295 | popl_cfi %eax | 295 | popl_cfi %eax |
296 | pushl_cfi $0x0202 # Reset kernel eflags | 296 | pushl_cfi $0x0202 # Reset kernel eflags |
297 | popfl_cfi | 297 | popfl_cfi |
298 | jmp syscall_exit | 298 | jmp syscall_exit |
299 | CFI_ENDPROC | 299 | CFI_ENDPROC |
300 | END(ret_from_fork) | 300 | END(ret_from_fork) |
301 | 301 | ||
302 | ENTRY(ret_from_kernel_thread) | 302 | ENTRY(ret_from_kernel_thread) |
303 | CFI_STARTPROC | 303 | CFI_STARTPROC |
304 | pushl_cfi %eax | 304 | pushl_cfi %eax |
305 | call schedule_tail | 305 | call schedule_tail |
306 | GET_THREAD_INFO(%ebp) | 306 | GET_THREAD_INFO(%ebp) |
307 | popl_cfi %eax | 307 | popl_cfi %eax |
308 | pushl_cfi $0x0202 # Reset kernel eflags | 308 | pushl_cfi $0x0202 # Reset kernel eflags |
309 | popfl_cfi | 309 | popfl_cfi |
310 | movl PT_EBP(%esp),%eax | 310 | movl PT_EBP(%esp),%eax |
311 | call *PT_EBX(%esp) | 311 | call *PT_EBX(%esp) |
312 | movl $0,PT_EAX(%esp) | 312 | movl $0,PT_EAX(%esp) |
313 | jmp syscall_exit | 313 | jmp syscall_exit |
314 | CFI_ENDPROC | 314 | CFI_ENDPROC |
315 | ENDPROC(ret_from_kernel_thread) | 315 | ENDPROC(ret_from_kernel_thread) |
316 | 316 | ||
317 | /* | 317 | /* |
318 | * Interrupt exit functions should be protected against kprobes | 318 | * Interrupt exit functions should be protected against kprobes |
319 | */ | 319 | */ |
320 | .pushsection .kprobes.text, "ax" | 320 | .pushsection .kprobes.text, "ax" |
321 | /* | 321 | /* |
322 | * Return to user mode is not as complex as all this looks, | 322 | * Return to user mode is not as complex as all this looks, |
323 | * but we want the default path for a system call return to | 323 | * but we want the default path for a system call return to |
324 | * go as quickly as possible which is why some of this is | 324 | * go as quickly as possible which is why some of this is |
325 | * less clear than it otherwise should be. | 325 | * less clear than it otherwise should be. |
326 | */ | 326 | */ |
327 | 327 | ||
328 | # userspace resumption stub bypassing syscall exit tracing | 328 | # userspace resumption stub bypassing syscall exit tracing |
329 | ALIGN | 329 | ALIGN |
330 | RING0_PTREGS_FRAME | 330 | RING0_PTREGS_FRAME |
331 | ret_from_exception: | 331 | ret_from_exception: |
332 | preempt_stop(CLBR_ANY) | 332 | preempt_stop(CLBR_ANY) |
333 | ret_from_intr: | 333 | ret_from_intr: |
334 | GET_THREAD_INFO(%ebp) | 334 | GET_THREAD_INFO(%ebp) |
335 | #ifdef CONFIG_VM86 | 335 | #ifdef CONFIG_VM86 |
336 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS | 336 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS |
337 | movb PT_CS(%esp), %al | 337 | movb PT_CS(%esp), %al |
338 | andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax | 338 | andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax |
339 | #else | 339 | #else |
340 | /* | 340 | /* |
341 | * We can be coming here from child spawned by kernel_thread(). | 341 | * We can be coming here from child spawned by kernel_thread(). |
342 | */ | 342 | */ |
343 | movl PT_CS(%esp), %eax | 343 | movl PT_CS(%esp), %eax |
344 | andl $SEGMENT_RPL_MASK, %eax | 344 | andl $SEGMENT_RPL_MASK, %eax |
345 | #endif | 345 | #endif |
346 | cmpl $USER_RPL, %eax | 346 | cmpl $USER_RPL, %eax |
347 | jb resume_kernel # not returning to v8086 or userspace | 347 | jb resume_kernel # not returning to v8086 or userspace |
348 | 348 | ||
349 | ENTRY(resume_userspace) | 349 | ENTRY(resume_userspace) |
350 | LOCKDEP_SYS_EXIT | 350 | LOCKDEP_SYS_EXIT |
351 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt | 351 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt |
352 | # setting need_resched or sigpending | 352 | # setting need_resched or sigpending |
353 | # between sampling and the iret | 353 | # between sampling and the iret |
354 | TRACE_IRQS_OFF | 354 | TRACE_IRQS_OFF |
355 | movl TI_flags(%ebp), %ecx | 355 | movl TI_flags(%ebp), %ecx |
356 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done on | 356 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done on |
357 | # int/exception return? | 357 | # int/exception return? |
358 | jne work_pending | 358 | jne work_pending |
359 | jmp restore_all | 359 | jmp restore_all |
360 | END(ret_from_exception) | 360 | END(ret_from_exception) |
361 | 361 | ||
362 | #ifdef CONFIG_PREEMPT | 362 | #ifdef CONFIG_PREEMPT |
363 | ENTRY(resume_kernel) | 363 | ENTRY(resume_kernel) |
364 | DISABLE_INTERRUPTS(CLBR_ANY) | 364 | DISABLE_INTERRUPTS(CLBR_ANY) |
365 | cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? | 365 | cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? |
366 | jnz restore_all | 366 | jnz restore_all |
367 | need_resched: | 367 | need_resched: |
368 | movl TI_flags(%ebp), %ecx # need_resched set ? | 368 | movl TI_flags(%ebp), %ecx # need_resched set ? |
369 | testb $_TIF_NEED_RESCHED, %cl | 369 | testb $_TIF_NEED_RESCHED, %cl |
370 | jz restore_all | 370 | jz restore_all |
371 | testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off (exception path) ? | 371 | testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off (exception path) ? |
372 | jz restore_all | 372 | jz restore_all |
373 | call preempt_schedule_irq | 373 | call preempt_schedule_irq |
374 | jmp need_resched | 374 | jmp need_resched |
375 | END(resume_kernel) | 375 | END(resume_kernel) |
376 | #endif | 376 | #endif |
377 | CFI_ENDPROC | 377 | CFI_ENDPROC |
378 | /* | 378 | /* |
379 | * End of kprobes section | 379 | * End of kprobes section |
380 | */ | 380 | */ |
381 | .popsection | 381 | .popsection |
382 | 382 | ||
383 | /* SYSENTER_RETURN points to after the "sysenter" instruction in | 383 | /* SYSENTER_RETURN points to after the "sysenter" instruction in |
384 | the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ | 384 | the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ |
385 | 385 | ||
386 | # sysenter call handler stub | 386 | # sysenter call handler stub |
387 | ENTRY(ia32_sysenter_target) | 387 | ENTRY(ia32_sysenter_target) |
388 | CFI_STARTPROC simple | 388 | CFI_STARTPROC simple |
389 | CFI_SIGNAL_FRAME | 389 | CFI_SIGNAL_FRAME |
390 | CFI_DEF_CFA esp, 0 | 390 | CFI_DEF_CFA esp, 0 |
391 | CFI_REGISTER esp, ebp | 391 | CFI_REGISTER esp, ebp |
392 | movl TSS_sysenter_sp0(%esp),%esp | 392 | movl TSS_sysenter_sp0(%esp),%esp |
393 | sysenter_past_esp: | 393 | sysenter_past_esp: |
394 | /* | 394 | /* |
395 | * Interrupts are disabled here, but we can't trace it until | 395 | * Interrupts are disabled here, but we can't trace it until |
396 | * enough kernel state to call TRACE_IRQS_OFF can be called - but | 396 | * enough kernel state to call TRACE_IRQS_OFF can be called - but |
397 | * we immediately enable interrupts at that point anyway. | 397 | * we immediately enable interrupts at that point anyway. |
398 | */ | 398 | */ |
399 | pushl_cfi $__USER_DS | 399 | pushl_cfi $__USER_DS |
400 | /*CFI_REL_OFFSET ss, 0*/ | 400 | /*CFI_REL_OFFSET ss, 0*/ |
401 | pushl_cfi %ebp | 401 | pushl_cfi %ebp |
402 | CFI_REL_OFFSET esp, 0 | 402 | CFI_REL_OFFSET esp, 0 |
403 | pushfl_cfi | 403 | pushfl_cfi |
404 | orl $X86_EFLAGS_IF, (%esp) | 404 | orl $X86_EFLAGS_IF, (%esp) |
405 | pushl_cfi $__USER_CS | 405 | pushl_cfi $__USER_CS |
406 | /*CFI_REL_OFFSET cs, 0*/ | 406 | /*CFI_REL_OFFSET cs, 0*/ |
407 | /* | 407 | /* |
408 | * Push current_thread_info()->sysenter_return to the stack. | 408 | * Push current_thread_info()->sysenter_return to the stack. |
409 | * A tiny bit of offset fixup is necessary - 4*4 means the 4 words | 409 | * A tiny bit of offset fixup is necessary - 4*4 means the 4 words |
410 | * pushed above; +8 corresponds to copy_thread's esp0 setting. | 410 | * pushed above; +8 corresponds to copy_thread's esp0 setting. |
411 | */ | 411 | */ |
412 | pushl_cfi ((TI_sysenter_return)-THREAD_SIZE+8+4*4)(%esp) | 412 | pushl_cfi ((TI_sysenter_return)-THREAD_SIZE+8+4*4)(%esp) |
413 | CFI_REL_OFFSET eip, 0 | 413 | CFI_REL_OFFSET eip, 0 |
414 | 414 | ||
415 | pushl_cfi %eax | 415 | pushl_cfi %eax |
416 | SAVE_ALL | 416 | SAVE_ALL |
417 | ENABLE_INTERRUPTS(CLBR_NONE) | 417 | ENABLE_INTERRUPTS(CLBR_NONE) |
418 | 418 | ||
419 | /* | 419 | /* |
420 | * Load the potential sixth argument from user stack. | 420 | * Load the potential sixth argument from user stack. |
421 | * Careful about security. | 421 | * Careful about security. |
422 | */ | 422 | */ |
423 | cmpl $__PAGE_OFFSET-3,%ebp | 423 | cmpl $__PAGE_OFFSET-3,%ebp |
424 | jae syscall_fault | 424 | jae syscall_fault |
425 | ASM_STAC | 425 | ASM_STAC |
426 | 1: movl (%ebp),%ebp | 426 | 1: movl (%ebp),%ebp |
427 | ASM_CLAC | 427 | ASM_CLAC |
428 | movl %ebp,PT_EBP(%esp) | 428 | movl %ebp,PT_EBP(%esp) |
429 | _ASM_EXTABLE(1b,syscall_fault) | 429 | _ASM_EXTABLE(1b,syscall_fault) |
430 | 430 | ||
431 | GET_THREAD_INFO(%ebp) | 431 | GET_THREAD_INFO(%ebp) |
432 | 432 | ||
433 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) | 433 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) |
434 | jnz sysenter_audit | 434 | jnz sysenter_audit |
435 | sysenter_do_call: | 435 | sysenter_do_call: |
436 | cmpl $(NR_syscalls), %eax | 436 | cmpl $(NR_syscalls), %eax |
437 | jae syscall_badsys | 437 | jae syscall_badsys |
438 | call *sys_call_table(,%eax,4) | 438 | call *sys_call_table(,%eax,4) |
439 | movl %eax,PT_EAX(%esp) | 439 | movl %eax,PT_EAX(%esp) |
440 | LOCKDEP_SYS_EXIT | 440 | LOCKDEP_SYS_EXIT |
441 | DISABLE_INTERRUPTS(CLBR_ANY) | 441 | DISABLE_INTERRUPTS(CLBR_ANY) |
442 | TRACE_IRQS_OFF | 442 | TRACE_IRQS_OFF |
443 | movl TI_flags(%ebp), %ecx | 443 | movl TI_flags(%ebp), %ecx |
444 | testl $_TIF_ALLWORK_MASK, %ecx | 444 | testl $_TIF_ALLWORK_MASK, %ecx |
445 | jne sysexit_audit | 445 | jne sysexit_audit |
446 | sysenter_exit: | 446 | sysenter_exit: |
447 | /* if something modifies registers it must also disable sysexit */ | 447 | /* if something modifies registers it must also disable sysexit */ |
448 | movl PT_EIP(%esp), %edx | 448 | movl PT_EIP(%esp), %edx |
449 | movl PT_OLDESP(%esp), %ecx | 449 | movl PT_OLDESP(%esp), %ecx |
450 | xorl %ebp,%ebp | 450 | xorl %ebp,%ebp |
451 | TRACE_IRQS_ON | 451 | TRACE_IRQS_ON |
452 | 1: mov PT_FS(%esp), %fs | 452 | 1: mov PT_FS(%esp), %fs |
453 | PTGS_TO_GS | 453 | PTGS_TO_GS |
454 | ENABLE_INTERRUPTS_SYSEXIT | 454 | ENABLE_INTERRUPTS_SYSEXIT |
455 | 455 | ||
456 | #ifdef CONFIG_AUDITSYSCALL | 456 | #ifdef CONFIG_AUDITSYSCALL |
457 | sysenter_audit: | 457 | sysenter_audit: |
458 | testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) | 458 | testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) |
459 | jnz syscall_trace_entry | 459 | jnz syscall_trace_entry |
460 | addl $4,%esp | 460 | addl $4,%esp |
461 | CFI_ADJUST_CFA_OFFSET -4 | 461 | CFI_ADJUST_CFA_OFFSET -4 |
462 | /* %esi already in 8(%esp) 6th arg: 4th syscall arg */ | 462 | /* %esi already in 8(%esp) 6th arg: 4th syscall arg */ |
463 | /* %edx already in 4(%esp) 5th arg: 3rd syscall arg */ | 463 | /* %edx already in 4(%esp) 5th arg: 3rd syscall arg */ |
464 | /* %ecx already in 0(%esp) 4th arg: 2nd syscall arg */ | 464 | /* %ecx already in 0(%esp) 4th arg: 2nd syscall arg */ |
465 | movl %ebx,%ecx /* 3rd arg: 1st syscall arg */ | 465 | movl %ebx,%ecx /* 3rd arg: 1st syscall arg */ |
466 | movl %eax,%edx /* 2nd arg: syscall number */ | 466 | movl %eax,%edx /* 2nd arg: syscall number */ |
467 | movl $AUDIT_ARCH_I386,%eax /* 1st arg: audit arch */ | 467 | movl $AUDIT_ARCH_I386,%eax /* 1st arg: audit arch */ |
468 | call __audit_syscall_entry | 468 | call __audit_syscall_entry |
469 | pushl_cfi %ebx | 469 | pushl_cfi %ebx |
470 | movl PT_EAX(%esp),%eax /* reload syscall number */ | 470 | movl PT_EAX(%esp),%eax /* reload syscall number */ |
471 | jmp sysenter_do_call | 471 | jmp sysenter_do_call |
472 | 472 | ||
473 | sysexit_audit: | 473 | sysexit_audit: |
474 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx | 474 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx |
475 | jne syscall_exit_work | 475 | jne syscall_exit_work |
476 | TRACE_IRQS_ON | 476 | TRACE_IRQS_ON |
477 | ENABLE_INTERRUPTS(CLBR_ANY) | 477 | ENABLE_INTERRUPTS(CLBR_ANY) |
478 | movl %eax,%edx /* second arg, syscall return value */ | 478 | movl %eax,%edx /* second arg, syscall return value */ |
479 | cmpl $-MAX_ERRNO,%eax /* is it an error ? */ | 479 | cmpl $-MAX_ERRNO,%eax /* is it an error ? */ |
480 | setbe %al /* 1 if so, 0 if not */ | 480 | setbe %al /* 1 if so, 0 if not */ |
481 | movzbl %al,%eax /* zero-extend that */ | 481 | movzbl %al,%eax /* zero-extend that */ |
482 | call __audit_syscall_exit | 482 | call __audit_syscall_exit |
483 | DISABLE_INTERRUPTS(CLBR_ANY) | 483 | DISABLE_INTERRUPTS(CLBR_ANY) |
484 | TRACE_IRQS_OFF | 484 | TRACE_IRQS_OFF |
485 | movl TI_flags(%ebp), %ecx | 485 | movl TI_flags(%ebp), %ecx |
486 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx | 486 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx |
487 | jne syscall_exit_work | 487 | jne syscall_exit_work |
488 | movl PT_EAX(%esp),%eax /* reload syscall return value */ | 488 | movl PT_EAX(%esp),%eax /* reload syscall return value */ |
489 | jmp sysenter_exit | 489 | jmp sysenter_exit |
490 | #endif | 490 | #endif |
491 | 491 | ||
492 | CFI_ENDPROC | 492 | CFI_ENDPROC |
493 | .pushsection .fixup,"ax" | 493 | .pushsection .fixup,"ax" |
494 | 2: movl $0,PT_FS(%esp) | 494 | 2: movl $0,PT_FS(%esp) |
495 | jmp 1b | 495 | jmp 1b |
496 | .popsection | 496 | .popsection |
497 | _ASM_EXTABLE(1b,2b) | 497 | _ASM_EXTABLE(1b,2b) |
498 | PTGS_TO_GS_EX | 498 | PTGS_TO_GS_EX |
499 | ENDPROC(ia32_sysenter_target) | 499 | ENDPROC(ia32_sysenter_target) |
500 | 500 | ||
501 | /* | 501 | /* |
502 | * syscall stub including irq exit should be protected against kprobes | 502 | * syscall stub including irq exit should be protected against kprobes |
503 | */ | 503 | */ |
504 | .pushsection .kprobes.text, "ax" | 504 | .pushsection .kprobes.text, "ax" |
505 | # system call handler stub | 505 | # system call handler stub |
506 | ENTRY(system_call) | 506 | ENTRY(system_call) |
507 | RING0_INT_FRAME # can't unwind into user space anyway | 507 | RING0_INT_FRAME # can't unwind into user space anyway |
508 | ASM_CLAC | 508 | ASM_CLAC |
509 | pushl_cfi %eax # save orig_eax | 509 | pushl_cfi %eax # save orig_eax |
510 | SAVE_ALL | 510 | SAVE_ALL |
511 | GET_THREAD_INFO(%ebp) | 511 | GET_THREAD_INFO(%ebp) |
512 | # system call tracing in operation / emulation | 512 | # system call tracing in operation / emulation |
513 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) | 513 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) |
514 | jnz syscall_trace_entry | 514 | jnz syscall_trace_entry |
515 | cmpl $(NR_syscalls), %eax | 515 | cmpl $(NR_syscalls), %eax |
516 | jae syscall_badsys | 516 | jae syscall_badsys |
517 | syscall_call: | 517 | syscall_call: |
518 | call *sys_call_table(,%eax,4) | 518 | call *sys_call_table(,%eax,4) |
519 | movl %eax,PT_EAX(%esp) # store the return value | 519 | movl %eax,PT_EAX(%esp) # store the return value |
520 | syscall_exit: | 520 | syscall_exit: |
521 | LOCKDEP_SYS_EXIT | 521 | LOCKDEP_SYS_EXIT |
522 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt | 522 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt |
523 | # setting need_resched or sigpending | 523 | # setting need_resched or sigpending |
524 | # between sampling and the iret | 524 | # between sampling and the iret |
525 | TRACE_IRQS_OFF | 525 | TRACE_IRQS_OFF |
526 | movl TI_flags(%ebp), %ecx | 526 | movl TI_flags(%ebp), %ecx |
527 | testl $_TIF_ALLWORK_MASK, %ecx # current->work | 527 | testl $_TIF_ALLWORK_MASK, %ecx # current->work |
528 | jne syscall_exit_work | 528 | jne syscall_exit_work |
529 | 529 | ||
530 | restore_all: | 530 | restore_all: |
531 | TRACE_IRQS_IRET | 531 | TRACE_IRQS_IRET |
532 | restore_all_notrace: | 532 | restore_all_notrace: |
533 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS | 533 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS |
534 | # Warning: PT_OLDSS(%esp) contains the wrong/random values if we | 534 | # Warning: PT_OLDSS(%esp) contains the wrong/random values if we |
535 | # are returning to the kernel. | 535 | # are returning to the kernel. |
536 | # See comments in process.c:copy_thread() for details. | 536 | # See comments in process.c:copy_thread() for details. |
537 | movb PT_OLDSS(%esp), %ah | 537 | movb PT_OLDSS(%esp), %ah |
538 | movb PT_CS(%esp), %al | 538 | movb PT_CS(%esp), %al |
539 | andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax | 539 | andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax |
540 | cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax | 540 | cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax |
541 | CFI_REMEMBER_STATE | 541 | CFI_REMEMBER_STATE |
542 | je ldt_ss # returning to user-space with LDT SS | 542 | je ldt_ss # returning to user-space with LDT SS |
543 | restore_nocheck: | 543 | restore_nocheck: |
544 | RESTORE_REGS 4 # skip orig_eax/error_code | 544 | RESTORE_REGS 4 # skip orig_eax/error_code |
545 | irq_return: | 545 | irq_return: |
546 | INTERRUPT_RETURN | 546 | INTERRUPT_RETURN |
547 | .section .fixup,"ax" | 547 | .section .fixup,"ax" |
548 | ENTRY(iret_exc) | 548 | ENTRY(iret_exc) |
549 | pushl $0 # no error code | 549 | pushl $0 # no error code |
550 | pushl $do_iret_error | 550 | pushl $do_iret_error |
551 | jmp error_code | 551 | jmp error_code |
552 | .previous | 552 | .previous |
553 | _ASM_EXTABLE(irq_return,iret_exc) | 553 | _ASM_EXTABLE(irq_return,iret_exc) |
554 | 554 | ||
555 | CFI_RESTORE_STATE | 555 | CFI_RESTORE_STATE |
556 | ldt_ss: | 556 | ldt_ss: |
557 | larl PT_OLDSS(%esp), %eax | 557 | larl PT_OLDSS(%esp), %eax |
558 | jnz restore_nocheck | 558 | jnz restore_nocheck |
559 | testl $0x00400000, %eax # returning to 32bit stack? | 559 | testl $0x00400000, %eax # returning to 32bit stack? |
560 | jnz restore_nocheck # allright, normal return | 560 | jnz restore_nocheck # allright, normal return |
561 | 561 | ||
562 | #ifdef CONFIG_PARAVIRT | 562 | #ifdef CONFIG_PARAVIRT |
563 | /* | 563 | /* |
564 | * The kernel can't run on a non-flat stack if paravirt mode | 564 | * The kernel can't run on a non-flat stack if paravirt mode |
565 | * is active. Rather than try to fixup the high bits of | 565 | * is active. Rather than try to fixup the high bits of |
566 | * ESP, bypass this code entirely. This may break DOSemu | 566 | * ESP, bypass this code entirely. This may break DOSemu |
567 | * and/or Wine support in a paravirt VM, although the option | 567 | * and/or Wine support in a paravirt VM, although the option |
568 | * is still available to implement the setting of the high | 568 | * is still available to implement the setting of the high |
569 | * 16-bits in the INTERRUPT_RETURN paravirt-op. | 569 | * 16-bits in the INTERRUPT_RETURN paravirt-op. |
570 | */ | 570 | */ |
571 | cmpl $0, pv_info+PARAVIRT_enabled | 571 | cmpl $0, pv_info+PARAVIRT_enabled |
572 | jne restore_nocheck | 572 | jne restore_nocheck |
573 | #endif | 573 | #endif |
574 | 574 | ||
575 | /* | 575 | /* |
576 | * Setup and switch to ESPFIX stack | 576 | * Setup and switch to ESPFIX stack |
577 | * | 577 | * |
578 | * We're returning to userspace with a 16 bit stack. The CPU will not | 578 | * We're returning to userspace with a 16 bit stack. The CPU will not |
579 | * restore the high word of ESP for us on executing iret... This is an | 579 | * restore the high word of ESP for us on executing iret... This is an |
580 | * "official" bug of all the x86-compatible CPUs, which we can work | 580 | * "official" bug of all the x86-compatible CPUs, which we can work |
581 | * around to make dosemu and wine happy. We do this by preloading the | 581 | * around to make dosemu and wine happy. We do this by preloading the |
582 | * high word of ESP with the high word of the userspace ESP while | 582 | * high word of ESP with the high word of the userspace ESP while |
583 | * compensating for the offset by changing to the ESPFIX segment with | 583 | * compensating for the offset by changing to the ESPFIX segment with |
584 | * a base address that matches for the difference. | 584 | * a base address that matches for the difference. |
585 | */ | 585 | */ |
586 | #define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8) | 586 | #define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8) |
587 | mov %esp, %edx /* load kernel esp */ | 587 | mov %esp, %edx /* load kernel esp */ |
588 | mov PT_OLDESP(%esp), %eax /* load userspace esp */ | 588 | mov PT_OLDESP(%esp), %eax /* load userspace esp */ |
589 | mov %dx, %ax /* eax: new kernel esp */ | 589 | mov %dx, %ax /* eax: new kernel esp */ |
590 | sub %eax, %edx /* offset (low word is 0) */ | 590 | sub %eax, %edx /* offset (low word is 0) */ |
591 | shr $16, %edx | 591 | shr $16, %edx |
592 | mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */ | 592 | mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */ |
593 | mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */ | 593 | mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */ |
594 | pushl_cfi $__ESPFIX_SS | 594 | pushl_cfi $__ESPFIX_SS |
595 | pushl_cfi %eax /* new kernel esp */ | 595 | pushl_cfi %eax /* new kernel esp */ |
596 | /* Disable interrupts, but do not irqtrace this section: we | 596 | /* Disable interrupts, but do not irqtrace this section: we |
597 | * will soon execute iret and the tracer was already set to | 597 | * will soon execute iret and the tracer was already set to |
598 | * the irqstate after the iret */ | 598 | * the irqstate after the iret */ |
599 | DISABLE_INTERRUPTS(CLBR_EAX) | 599 | DISABLE_INTERRUPTS(CLBR_EAX) |
600 | lss (%esp), %esp /* switch to espfix segment */ | 600 | lss (%esp), %esp /* switch to espfix segment */ |
601 | CFI_ADJUST_CFA_OFFSET -8 | 601 | CFI_ADJUST_CFA_OFFSET -8 |
602 | jmp restore_nocheck | 602 | jmp restore_nocheck |
603 | CFI_ENDPROC | 603 | CFI_ENDPROC |
604 | ENDPROC(system_call) | 604 | ENDPROC(system_call) |
605 | 605 | ||
606 | # perform work that needs to be done immediately before resumption | 606 | # perform work that needs to be done immediately before resumption |
607 | ALIGN | 607 | ALIGN |
608 | RING0_PTREGS_FRAME # can't unwind into user space anyway | 608 | RING0_PTREGS_FRAME # can't unwind into user space anyway |
609 | work_pending: | 609 | work_pending: |
610 | testb $_TIF_NEED_RESCHED, %cl | 610 | testb $_TIF_NEED_RESCHED, %cl |
611 | jz work_notifysig | 611 | jz work_notifysig |
612 | work_resched: | 612 | work_resched: |
613 | call schedule | 613 | call schedule |
614 | LOCKDEP_SYS_EXIT | 614 | LOCKDEP_SYS_EXIT |
615 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt | 615 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt |
616 | # setting need_resched or sigpending | 616 | # setting need_resched or sigpending |
617 | # between sampling and the iret | 617 | # between sampling and the iret |
618 | TRACE_IRQS_OFF | 618 | TRACE_IRQS_OFF |
619 | movl TI_flags(%ebp), %ecx | 619 | movl TI_flags(%ebp), %ecx |
620 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done other | 620 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done other |
621 | # than syscall tracing? | 621 | # than syscall tracing? |
622 | jz restore_all | 622 | jz restore_all |
623 | testb $_TIF_NEED_RESCHED, %cl | 623 | testb $_TIF_NEED_RESCHED, %cl |
624 | jnz work_resched | 624 | jnz work_resched |
625 | 625 | ||
626 | work_notifysig: # deal with pending signals and | 626 | work_notifysig: # deal with pending signals and |
627 | # notify-resume requests | 627 | # notify-resume requests |
628 | #ifdef CONFIG_VM86 | 628 | #ifdef CONFIG_VM86 |
629 | testl $X86_EFLAGS_VM, PT_EFLAGS(%esp) | 629 | testl $X86_EFLAGS_VM, PT_EFLAGS(%esp) |
630 | movl %esp, %eax | 630 | movl %esp, %eax |
631 | jne work_notifysig_v86 # returning to kernel-space or | 631 | jne work_notifysig_v86 # returning to kernel-space or |
632 | # vm86-space | 632 | # vm86-space |
633 | 1: | 633 | 1: |
634 | #else | 634 | #else |
635 | movl %esp, %eax | 635 | movl %esp, %eax |
636 | #endif | 636 | #endif |
637 | TRACE_IRQS_ON | 637 | TRACE_IRQS_ON |
638 | ENABLE_INTERRUPTS(CLBR_NONE) | 638 | ENABLE_INTERRUPTS(CLBR_NONE) |
639 | movb PT_CS(%esp), %bl | 639 | movb PT_CS(%esp), %bl |
640 | andb $SEGMENT_RPL_MASK, %bl | 640 | andb $SEGMENT_RPL_MASK, %bl |
641 | cmpb $USER_RPL, %bl | 641 | cmpb $USER_RPL, %bl |
642 | jb resume_kernel | 642 | jb resume_kernel |
643 | xorl %edx, %edx | 643 | xorl %edx, %edx |
644 | call do_notify_resume | 644 | call do_notify_resume |
645 | jmp resume_userspace | 645 | jmp resume_userspace |
646 | 646 | ||
647 | #ifdef CONFIG_VM86 | 647 | #ifdef CONFIG_VM86 |
648 | ALIGN | 648 | ALIGN |
649 | work_notifysig_v86: | 649 | work_notifysig_v86: |
650 | pushl_cfi %ecx # save ti_flags for do_notify_resume | 650 | pushl_cfi %ecx # save ti_flags for do_notify_resume |
651 | call save_v86_state # %eax contains pt_regs pointer | 651 | call save_v86_state # %eax contains pt_regs pointer |
652 | popl_cfi %ecx | 652 | popl_cfi %ecx |
653 | movl %eax, %esp | 653 | movl %eax, %esp |
654 | jmp 1b | 654 | jmp 1b |
655 | #endif | 655 | #endif |
656 | END(work_pending) | 656 | END(work_pending) |
657 | 657 | ||
658 | # perform syscall exit tracing | 658 | # perform syscall exit tracing |
659 | ALIGN | 659 | ALIGN |
660 | syscall_trace_entry: | 660 | syscall_trace_entry: |
661 | movl $-ENOSYS,PT_EAX(%esp) | 661 | movl $-ENOSYS,PT_EAX(%esp) |
662 | movl %esp, %eax | 662 | movl %esp, %eax |
663 | call syscall_trace_enter | 663 | call syscall_trace_enter |
664 | /* What it returned is what we'll actually use. */ | 664 | /* What it returned is what we'll actually use. */ |
665 | cmpl $(NR_syscalls), %eax | 665 | cmpl $(NR_syscalls), %eax |
666 | jnae syscall_call | 666 | jnae syscall_call |
667 | jmp syscall_exit | 667 | jmp syscall_exit |
668 | END(syscall_trace_entry) | 668 | END(syscall_trace_entry) |
669 | 669 | ||
670 | # perform syscall exit tracing | 670 | # perform syscall exit tracing |
671 | ALIGN | 671 | ALIGN |
672 | syscall_exit_work: | 672 | syscall_exit_work: |
673 | testl $_TIF_WORK_SYSCALL_EXIT, %ecx | 673 | testl $_TIF_WORK_SYSCALL_EXIT, %ecx |
674 | jz work_pending | 674 | jz work_pending |
675 | TRACE_IRQS_ON | 675 | TRACE_IRQS_ON |
676 | ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call | 676 | ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call |
677 | # schedule() instead | 677 | # schedule() instead |
678 | movl %esp, %eax | 678 | movl %esp, %eax |
679 | call syscall_trace_leave | 679 | call syscall_trace_leave |
680 | jmp resume_userspace | 680 | jmp resume_userspace |
681 | END(syscall_exit_work) | 681 | END(syscall_exit_work) |
682 | CFI_ENDPROC | 682 | CFI_ENDPROC |
683 | 683 | ||
684 | RING0_INT_FRAME # can't unwind into user space anyway | 684 | RING0_INT_FRAME # can't unwind into user space anyway |
685 | syscall_fault: | 685 | syscall_fault: |
686 | ASM_CLAC | 686 | ASM_CLAC |
687 | GET_THREAD_INFO(%ebp) | 687 | GET_THREAD_INFO(%ebp) |
688 | movl $-EFAULT,PT_EAX(%esp) | 688 | movl $-EFAULT,PT_EAX(%esp) |
689 | jmp resume_userspace | 689 | jmp resume_userspace |
690 | END(syscall_fault) | 690 | END(syscall_fault) |
691 | 691 | ||
692 | syscall_badsys: | 692 | syscall_badsys: |
693 | movl $-ENOSYS,PT_EAX(%esp) | 693 | movl $-ENOSYS,PT_EAX(%esp) |
694 | jmp resume_userspace | 694 | jmp resume_userspace |
695 | END(syscall_badsys) | 695 | END(syscall_badsys) |
696 | CFI_ENDPROC | 696 | CFI_ENDPROC |
697 | /* | 697 | /* |
698 | * End of kprobes section | 698 | * End of kprobes section |
699 | */ | 699 | */ |
700 | .popsection | 700 | .popsection |
701 | 701 | ||
702 | .macro FIXUP_ESPFIX_STACK | 702 | .macro FIXUP_ESPFIX_STACK |
703 | /* | 703 | /* |
704 | * Switch back for ESPFIX stack to the normal zerobased stack | 704 | * Switch back for ESPFIX stack to the normal zerobased stack |
705 | * | 705 | * |
706 | * We can't call C functions using the ESPFIX stack. This code reads | 706 | * We can't call C functions using the ESPFIX stack. This code reads |
707 | * the high word of the segment base from the GDT and swiches to the | 707 | * the high word of the segment base from the GDT and swiches to the |
708 | * normal stack and adjusts ESP with the matching offset. | 708 | * normal stack and adjusts ESP with the matching offset. |
709 | */ | 709 | */ |
710 | /* fixup the stack */ | 710 | /* fixup the stack */ |
711 | mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */ | 711 | mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */ |
712 | mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */ | 712 | mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */ |
713 | shl $16, %eax | 713 | shl $16, %eax |
714 | addl %esp, %eax /* the adjusted stack pointer */ | 714 | addl %esp, %eax /* the adjusted stack pointer */ |
715 | pushl_cfi $__KERNEL_DS | 715 | pushl_cfi $__KERNEL_DS |
716 | pushl_cfi %eax | 716 | pushl_cfi %eax |
717 | lss (%esp), %esp /* switch to the normal stack segment */ | 717 | lss (%esp), %esp /* switch to the normal stack segment */ |
718 | CFI_ADJUST_CFA_OFFSET -8 | 718 | CFI_ADJUST_CFA_OFFSET -8 |
719 | .endm | 719 | .endm |
720 | .macro UNWIND_ESPFIX_STACK | 720 | .macro UNWIND_ESPFIX_STACK |
721 | movl %ss, %eax | 721 | movl %ss, %eax |
722 | /* see if on espfix stack */ | 722 | /* see if on espfix stack */ |
723 | cmpw $__ESPFIX_SS, %ax | 723 | cmpw $__ESPFIX_SS, %ax |
724 | jne 27f | 724 | jne 27f |
725 | movl $__KERNEL_DS, %eax | 725 | movl $__KERNEL_DS, %eax |
726 | movl %eax, %ds | 726 | movl %eax, %ds |
727 | movl %eax, %es | 727 | movl %eax, %es |
728 | /* switch to normal stack */ | 728 | /* switch to normal stack */ |
729 | FIXUP_ESPFIX_STACK | 729 | FIXUP_ESPFIX_STACK |
730 | 27: | 730 | 27: |
731 | .endm | 731 | .endm |
732 | 732 | ||
733 | /* | 733 | /* |
734 | * Build the entry stubs and pointer table with some assembler magic. | 734 | * Build the entry stubs and pointer table with some assembler magic. |
735 | * We pack 7 stubs into a single 32-byte chunk, which will fit in a | 735 | * We pack 7 stubs into a single 32-byte chunk, which will fit in a |
736 | * single cache line on all modern x86 implementations. | 736 | * single cache line on all modern x86 implementations. |
737 | */ | 737 | */ |
738 | .section .init.rodata,"a" | 738 | .section .init.rodata,"a" |
739 | ENTRY(interrupt) | 739 | ENTRY(interrupt) |
740 | .section .entry.text, "ax" | 740 | .section .entry.text, "ax" |
741 | .p2align 5 | 741 | .p2align 5 |
742 | .p2align CONFIG_X86_L1_CACHE_SHIFT | 742 | .p2align CONFIG_X86_L1_CACHE_SHIFT |
743 | ENTRY(irq_entries_start) | 743 | ENTRY(irq_entries_start) |
744 | RING0_INT_FRAME | 744 | RING0_INT_FRAME |
745 | vector=FIRST_EXTERNAL_VECTOR | 745 | vector=FIRST_EXTERNAL_VECTOR |
746 | .rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7 | 746 | .rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7 |
747 | .balign 32 | 747 | .balign 32 |
748 | .rept 7 | 748 | .rept 7 |
749 | .if vector < NR_VECTORS | 749 | .if vector < NR_VECTORS |
750 | .if vector <> FIRST_EXTERNAL_VECTOR | 750 | .if vector <> FIRST_EXTERNAL_VECTOR |
751 | CFI_ADJUST_CFA_OFFSET -4 | 751 | CFI_ADJUST_CFA_OFFSET -4 |
752 | .endif | 752 | .endif |
753 | 1: pushl_cfi $(~vector+0x80) /* Note: always in signed byte range */ | 753 | 1: pushl_cfi $(~vector+0x80) /* Note: always in signed byte range */ |
754 | .if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6 | 754 | .if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6 |
755 | jmp 2f | 755 | jmp 2f |
756 | .endif | 756 | .endif |
757 | .previous | 757 | .previous |
758 | .long 1b | 758 | .long 1b |
759 | .section .entry.text, "ax" | 759 | .section .entry.text, "ax" |
760 | vector=vector+1 | 760 | vector=vector+1 |
761 | .endif | 761 | .endif |
762 | .endr | 762 | .endr |
763 | 2: jmp common_interrupt | 763 | 2: jmp common_interrupt |
764 | .endr | 764 | .endr |
765 | END(irq_entries_start) | 765 | END(irq_entries_start) |
766 | 766 | ||
767 | .previous | 767 | .previous |
768 | END(interrupt) | 768 | END(interrupt) |
769 | .previous | 769 | .previous |
770 | 770 | ||
771 | /* | 771 | /* |
772 | * the CPU automatically disables interrupts when executing an IRQ vector, | 772 | * the CPU automatically disables interrupts when executing an IRQ vector, |
773 | * so IRQ-flags tracing has to follow that: | 773 | * so IRQ-flags tracing has to follow that: |
774 | */ | 774 | */ |
775 | .p2align CONFIG_X86_L1_CACHE_SHIFT | 775 | .p2align CONFIG_X86_L1_CACHE_SHIFT |
776 | common_interrupt: | 776 | common_interrupt: |
777 | ASM_CLAC | 777 | ASM_CLAC |
778 | addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */ | 778 | addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */ |
779 | SAVE_ALL | 779 | SAVE_ALL |
780 | TRACE_IRQS_OFF | 780 | TRACE_IRQS_OFF |
781 | movl %esp,%eax | 781 | movl %esp,%eax |
782 | call do_IRQ | 782 | call do_IRQ |
783 | jmp ret_from_intr | 783 | jmp ret_from_intr |
784 | ENDPROC(common_interrupt) | 784 | ENDPROC(common_interrupt) |
785 | CFI_ENDPROC | 785 | CFI_ENDPROC |
786 | 786 | ||
787 | /* | 787 | /* |
788 | * Irq entries should be protected against kprobes | 788 | * Irq entries should be protected against kprobes |
789 | */ | 789 | */ |
790 | .pushsection .kprobes.text, "ax" | 790 | .pushsection .kprobes.text, "ax" |
791 | #define BUILD_INTERRUPT3(name, nr, fn) \ | 791 | #define BUILD_INTERRUPT3(name, nr, fn) \ |
792 | ENTRY(name) \ | 792 | ENTRY(name) \ |
793 | RING0_INT_FRAME; \ | 793 | RING0_INT_FRAME; \ |
794 | ASM_CLAC; \ | 794 | ASM_CLAC; \ |
795 | pushl_cfi $~(nr); \ | 795 | pushl_cfi $~(nr); \ |
796 | SAVE_ALL; \ | 796 | SAVE_ALL; \ |
797 | TRACE_IRQS_OFF \ | 797 | TRACE_IRQS_OFF \ |
798 | movl %esp,%eax; \ | 798 | movl %esp,%eax; \ |
799 | call fn; \ | 799 | call fn; \ |
800 | jmp ret_from_intr; \ | 800 | jmp ret_from_intr; \ |
801 | CFI_ENDPROC; \ | 801 | CFI_ENDPROC; \ |
802 | ENDPROC(name) | 802 | ENDPROC(name) |
803 | 803 | ||
804 | 804 | ||
805 | #ifdef CONFIG_TRACING | 805 | #ifdef CONFIG_TRACING |
806 | #define TRACE_BUILD_INTERRUPT(name, nr) \ | 806 | #define TRACE_BUILD_INTERRUPT(name, nr) \ |
807 | BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) | 807 | BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) |
808 | #else | 808 | #else |
809 | #define TRACE_BUILD_INTERRUPT(name, nr) | 809 | #define TRACE_BUILD_INTERRUPT(name, nr) |
810 | #endif | 810 | #endif |
811 | 811 | ||
812 | #define BUILD_INTERRUPT(name, nr) \ | 812 | #define BUILD_INTERRUPT(name, nr) \ |
813 | BUILD_INTERRUPT3(name, nr, smp_##name); \ | 813 | BUILD_INTERRUPT3(name, nr, smp_##name); \ |
814 | TRACE_BUILD_INTERRUPT(name, nr) | 814 | TRACE_BUILD_INTERRUPT(name, nr) |
815 | 815 | ||
816 | /* The include is where all of the SMP etc. interrupts come from */ | 816 | /* The include is where all of the SMP etc. interrupts come from */ |
817 | #include <asm/entry_arch.h> | 817 | #include <asm/entry_arch.h> |
818 | 818 | ||
819 | ENTRY(coprocessor_error) | 819 | ENTRY(coprocessor_error) |
820 | RING0_INT_FRAME | 820 | RING0_INT_FRAME |
821 | ASM_CLAC | 821 | ASM_CLAC |
822 | pushl_cfi $0 | 822 | pushl_cfi $0 |
823 | pushl_cfi $do_coprocessor_error | 823 | pushl_cfi $do_coprocessor_error |
824 | jmp error_code | 824 | jmp error_code |
825 | CFI_ENDPROC | 825 | CFI_ENDPROC |
826 | END(coprocessor_error) | 826 | END(coprocessor_error) |
827 | 827 | ||
828 | ENTRY(simd_coprocessor_error) | 828 | ENTRY(simd_coprocessor_error) |
829 | RING0_INT_FRAME | 829 | RING0_INT_FRAME |
830 | ASM_CLAC | 830 | ASM_CLAC |
831 | pushl_cfi $0 | 831 | pushl_cfi $0 |
832 | #ifdef CONFIG_X86_INVD_BUG | 832 | #ifdef CONFIG_X86_INVD_BUG |
833 | /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */ | 833 | /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */ |
834 | 661: pushl_cfi $do_general_protection | 834 | 661: pushl_cfi $do_general_protection |
835 | 662: | 835 | 662: |
836 | .section .altinstructions,"a" | 836 | .section .altinstructions,"a" |
837 | altinstruction_entry 661b, 663f, X86_FEATURE_XMM, 662b-661b, 664f-663f | 837 | altinstruction_entry 661b, 663f, X86_FEATURE_XMM, 662b-661b, 664f-663f |
838 | .previous | 838 | .previous |
839 | .section .altinstr_replacement,"ax" | 839 | .section .altinstr_replacement,"ax" |
840 | 663: pushl $do_simd_coprocessor_error | 840 | 663: pushl $do_simd_coprocessor_error |
841 | 664: | 841 | 664: |
842 | .previous | 842 | .previous |
843 | #else | 843 | #else |
844 | pushl_cfi $do_simd_coprocessor_error | 844 | pushl_cfi $do_simd_coprocessor_error |
845 | #endif | 845 | #endif |
846 | jmp error_code | 846 | jmp error_code |
847 | CFI_ENDPROC | 847 | CFI_ENDPROC |
848 | END(simd_coprocessor_error) | 848 | END(simd_coprocessor_error) |
849 | 849 | ||
850 | ENTRY(device_not_available) | 850 | ENTRY(device_not_available) |
851 | RING0_INT_FRAME | 851 | RING0_INT_FRAME |
852 | ASM_CLAC | 852 | ASM_CLAC |
853 | pushl_cfi $-1 # mark this as an int | 853 | pushl_cfi $-1 # mark this as an int |
854 | pushl_cfi $do_device_not_available | 854 | pushl_cfi $do_device_not_available |
855 | jmp error_code | 855 | jmp error_code |
856 | CFI_ENDPROC | 856 | CFI_ENDPROC |
857 | END(device_not_available) | 857 | END(device_not_available) |
858 | 858 | ||
859 | #ifdef CONFIG_PARAVIRT | 859 | #ifdef CONFIG_PARAVIRT |
860 | ENTRY(native_iret) | 860 | ENTRY(native_iret) |
861 | iret | 861 | iret |
862 | _ASM_EXTABLE(native_iret, iret_exc) | 862 | _ASM_EXTABLE(native_iret, iret_exc) |
863 | END(native_iret) | 863 | END(native_iret) |
864 | 864 | ||
865 | ENTRY(native_irq_enable_sysexit) | 865 | ENTRY(native_irq_enable_sysexit) |
866 | sti | 866 | sti |
867 | sysexit | 867 | sysexit |
868 | END(native_irq_enable_sysexit) | 868 | END(native_irq_enable_sysexit) |
869 | #endif | 869 | #endif |
870 | 870 | ||
871 | ENTRY(overflow) | 871 | ENTRY(overflow) |
872 | RING0_INT_FRAME | 872 | RING0_INT_FRAME |
873 | ASM_CLAC | 873 | ASM_CLAC |
874 | pushl_cfi $0 | 874 | pushl_cfi $0 |
875 | pushl_cfi $do_overflow | 875 | pushl_cfi $do_overflow |
876 | jmp error_code | 876 | jmp error_code |
877 | CFI_ENDPROC | 877 | CFI_ENDPROC |
878 | END(overflow) | 878 | END(overflow) |
879 | 879 | ||
880 | ENTRY(bounds) | 880 | ENTRY(bounds) |
881 | RING0_INT_FRAME | 881 | RING0_INT_FRAME |
882 | ASM_CLAC | 882 | ASM_CLAC |
883 | pushl_cfi $0 | 883 | pushl_cfi $0 |
884 | pushl_cfi $do_bounds | 884 | pushl_cfi $do_bounds |
885 | jmp error_code | 885 | jmp error_code |
886 | CFI_ENDPROC | 886 | CFI_ENDPROC |
887 | END(bounds) | 887 | END(bounds) |
888 | 888 | ||
889 | ENTRY(invalid_op) | 889 | ENTRY(invalid_op) |
890 | RING0_INT_FRAME | 890 | RING0_INT_FRAME |
891 | ASM_CLAC | 891 | ASM_CLAC |
892 | pushl_cfi $0 | 892 | pushl_cfi $0 |
893 | pushl_cfi $do_invalid_op | 893 | pushl_cfi $do_invalid_op |
894 | jmp error_code | 894 | jmp error_code |
895 | CFI_ENDPROC | 895 | CFI_ENDPROC |
896 | END(invalid_op) | 896 | END(invalid_op) |
897 | 897 | ||
898 | ENTRY(coprocessor_segment_overrun) | 898 | ENTRY(coprocessor_segment_overrun) |
899 | RING0_INT_FRAME | 899 | RING0_INT_FRAME |
900 | ASM_CLAC | 900 | ASM_CLAC |
901 | pushl_cfi $0 | 901 | pushl_cfi $0 |
902 | pushl_cfi $do_coprocessor_segment_overrun | 902 | pushl_cfi $do_coprocessor_segment_overrun |
903 | jmp error_code | 903 | jmp error_code |
904 | CFI_ENDPROC | 904 | CFI_ENDPROC |
905 | END(coprocessor_segment_overrun) | 905 | END(coprocessor_segment_overrun) |
906 | 906 | ||
907 | ENTRY(invalid_TSS) | 907 | ENTRY(invalid_TSS) |
908 | RING0_EC_FRAME | 908 | RING0_EC_FRAME |
909 | ASM_CLAC | 909 | ASM_CLAC |
910 | pushl_cfi $do_invalid_TSS | 910 | pushl_cfi $do_invalid_TSS |
911 | jmp error_code | 911 | jmp error_code |
912 | CFI_ENDPROC | 912 | CFI_ENDPROC |
913 | END(invalid_TSS) | 913 | END(invalid_TSS) |
914 | 914 | ||
915 | ENTRY(segment_not_present) | 915 | ENTRY(segment_not_present) |
916 | RING0_EC_FRAME | 916 | RING0_EC_FRAME |
917 | ASM_CLAC | 917 | ASM_CLAC |
918 | pushl_cfi $do_segment_not_present | 918 | pushl_cfi $do_segment_not_present |
919 | jmp error_code | 919 | jmp error_code |
920 | CFI_ENDPROC | 920 | CFI_ENDPROC |
921 | END(segment_not_present) | 921 | END(segment_not_present) |
922 | 922 | ||
923 | ENTRY(stack_segment) | 923 | ENTRY(stack_segment) |
924 | RING0_EC_FRAME | 924 | RING0_EC_FRAME |
925 | ASM_CLAC | 925 | ASM_CLAC |
926 | pushl_cfi $do_stack_segment | 926 | pushl_cfi $do_stack_segment |
927 | jmp error_code | 927 | jmp error_code |
928 | CFI_ENDPROC | 928 | CFI_ENDPROC |
929 | END(stack_segment) | 929 | END(stack_segment) |
930 | 930 | ||
931 | ENTRY(alignment_check) | 931 | ENTRY(alignment_check) |
932 | RING0_EC_FRAME | 932 | RING0_EC_FRAME |
933 | ASM_CLAC | 933 | ASM_CLAC |
934 | pushl_cfi $do_alignment_check | 934 | pushl_cfi $do_alignment_check |
935 | jmp error_code | 935 | jmp error_code |
936 | CFI_ENDPROC | 936 | CFI_ENDPROC |
937 | END(alignment_check) | 937 | END(alignment_check) |
938 | 938 | ||
939 | ENTRY(divide_error) | 939 | ENTRY(divide_error) |
940 | RING0_INT_FRAME | 940 | RING0_INT_FRAME |
941 | ASM_CLAC | 941 | ASM_CLAC |
942 | pushl_cfi $0 # no error code | 942 | pushl_cfi $0 # no error code |
943 | pushl_cfi $do_divide_error | 943 | pushl_cfi $do_divide_error |
944 | jmp error_code | 944 | jmp error_code |
945 | CFI_ENDPROC | 945 | CFI_ENDPROC |
946 | END(divide_error) | 946 | END(divide_error) |
947 | 947 | ||
948 | #ifdef CONFIG_X86_MCE | 948 | #ifdef CONFIG_X86_MCE |
949 | ENTRY(machine_check) | 949 | ENTRY(machine_check) |
950 | RING0_INT_FRAME | 950 | RING0_INT_FRAME |
951 | ASM_CLAC | 951 | ASM_CLAC |
952 | pushl_cfi $0 | 952 | pushl_cfi $0 |
953 | pushl_cfi machine_check_vector | 953 | pushl_cfi machine_check_vector |
954 | jmp error_code | 954 | jmp error_code |
955 | CFI_ENDPROC | 955 | CFI_ENDPROC |
956 | END(machine_check) | 956 | END(machine_check) |
957 | #endif | 957 | #endif |
958 | 958 | ||
959 | ENTRY(spurious_interrupt_bug) | 959 | ENTRY(spurious_interrupt_bug) |
960 | RING0_INT_FRAME | 960 | RING0_INT_FRAME |
961 | ASM_CLAC | 961 | ASM_CLAC |
962 | pushl_cfi $0 | 962 | pushl_cfi $0 |
963 | pushl_cfi $do_spurious_interrupt_bug | 963 | pushl_cfi $do_spurious_interrupt_bug |
964 | jmp error_code | 964 | jmp error_code |
965 | CFI_ENDPROC | 965 | CFI_ENDPROC |
966 | END(spurious_interrupt_bug) | 966 | END(spurious_interrupt_bug) |
967 | /* | 967 | /* |
968 | * End of kprobes section | 968 | * End of kprobes section |
969 | */ | 969 | */ |
970 | .popsection | 970 | .popsection |
971 | 971 | ||
972 | #ifdef CONFIG_XEN | 972 | #ifdef CONFIG_XEN |
973 | /* Xen doesn't set %esp to be precisely what the normal sysenter | 973 | /* Xen doesn't set %esp to be precisely what the normal sysenter |
974 | entrypoint expects, so fix it up before using the normal path. */ | 974 | entrypoint expects, so fix it up before using the normal path. */ |
975 | ENTRY(xen_sysenter_target) | 975 | ENTRY(xen_sysenter_target) |
976 | RING0_INT_FRAME | 976 | RING0_INT_FRAME |
977 | addl $5*4, %esp /* remove xen-provided frame */ | 977 | addl $5*4, %esp /* remove xen-provided frame */ |
978 | CFI_ADJUST_CFA_OFFSET -5*4 | 978 | CFI_ADJUST_CFA_OFFSET -5*4 |
979 | jmp sysenter_past_esp | 979 | jmp sysenter_past_esp |
980 | CFI_ENDPROC | 980 | CFI_ENDPROC |
981 | 981 | ||
982 | ENTRY(xen_hypervisor_callback) | 982 | ENTRY(xen_hypervisor_callback) |
983 | CFI_STARTPROC | 983 | CFI_STARTPROC |
984 | pushl_cfi $-1 /* orig_ax = -1 => not a system call */ | 984 | pushl_cfi $-1 /* orig_ax = -1 => not a system call */ |
985 | SAVE_ALL | 985 | SAVE_ALL |
986 | TRACE_IRQS_OFF | 986 | TRACE_IRQS_OFF |
987 | 987 | ||
988 | /* Check to see if we got the event in the critical | 988 | /* Check to see if we got the event in the critical |
989 | region in xen_iret_direct, after we've reenabled | 989 | region in xen_iret_direct, after we've reenabled |
990 | events and checked for pending events. This simulates | 990 | events and checked for pending events. This simulates |
991 | iret instruction's behaviour where it delivers a | 991 | iret instruction's behaviour where it delivers a |
992 | pending interrupt when enabling interrupts. */ | 992 | pending interrupt when enabling interrupts. */ |
993 | movl PT_EIP(%esp),%eax | 993 | movl PT_EIP(%esp),%eax |
994 | cmpl $xen_iret_start_crit,%eax | 994 | cmpl $xen_iret_start_crit,%eax |
995 | jb 1f | 995 | jb 1f |
996 | cmpl $xen_iret_end_crit,%eax | 996 | cmpl $xen_iret_end_crit,%eax |
997 | jae 1f | 997 | jae 1f |
998 | 998 | ||
999 | jmp xen_iret_crit_fixup | 999 | jmp xen_iret_crit_fixup |
1000 | 1000 | ||
1001 | ENTRY(xen_do_upcall) | 1001 | ENTRY(xen_do_upcall) |
1002 | 1: mov %esp, %eax | 1002 | 1: mov %esp, %eax |
1003 | call xen_evtchn_do_upcall | 1003 | call xen_evtchn_do_upcall |
1004 | jmp ret_from_intr | 1004 | jmp ret_from_intr |
1005 | CFI_ENDPROC | 1005 | CFI_ENDPROC |
1006 | ENDPROC(xen_hypervisor_callback) | 1006 | ENDPROC(xen_hypervisor_callback) |
1007 | 1007 | ||
1008 | # Hypervisor uses this for application faults while it executes. | 1008 | # Hypervisor uses this for application faults while it executes. |
1009 | # We get here for two reasons: | 1009 | # We get here for two reasons: |
1010 | # 1. Fault while reloading DS, ES, FS or GS | 1010 | # 1. Fault while reloading DS, ES, FS or GS |
1011 | # 2. Fault while executing IRET | 1011 | # 2. Fault while executing IRET |
1012 | # Category 1 we fix up by reattempting the load, and zeroing the segment | 1012 | # Category 1 we fix up by reattempting the load, and zeroing the segment |
1013 | # register if the load fails. | 1013 | # register if the load fails. |
1014 | # Category 2 we fix up by jumping to do_iret_error. We cannot use the | 1014 | # Category 2 we fix up by jumping to do_iret_error. We cannot use the |
1015 | # normal Linux return path in this case because if we use the IRET hypercall | 1015 | # normal Linux return path in this case because if we use the IRET hypercall |
1016 | # to pop the stack frame we end up in an infinite loop of failsafe callbacks. | 1016 | # to pop the stack frame we end up in an infinite loop of failsafe callbacks. |
1017 | # We distinguish between categories by maintaining a status value in EAX. | 1017 | # We distinguish between categories by maintaining a status value in EAX. |
1018 | ENTRY(xen_failsafe_callback) | 1018 | ENTRY(xen_failsafe_callback) |
1019 | CFI_STARTPROC | 1019 | CFI_STARTPROC |
1020 | pushl_cfi %eax | 1020 | pushl_cfi %eax |
1021 | movl $1,%eax | 1021 | movl $1,%eax |
1022 | 1: mov 4(%esp),%ds | 1022 | 1: mov 4(%esp),%ds |
1023 | 2: mov 8(%esp),%es | 1023 | 2: mov 8(%esp),%es |
1024 | 3: mov 12(%esp),%fs | 1024 | 3: mov 12(%esp),%fs |
1025 | 4: mov 16(%esp),%gs | 1025 | 4: mov 16(%esp),%gs |
1026 | /* EAX == 0 => Category 1 (Bad segment) | 1026 | /* EAX == 0 => Category 1 (Bad segment) |
1027 | EAX != 0 => Category 2 (Bad IRET) */ | 1027 | EAX != 0 => Category 2 (Bad IRET) */ |
1028 | testl %eax,%eax | 1028 | testl %eax,%eax |
1029 | popl_cfi %eax | 1029 | popl_cfi %eax |
1030 | lea 16(%esp),%esp | 1030 | lea 16(%esp),%esp |
1031 | CFI_ADJUST_CFA_OFFSET -16 | 1031 | CFI_ADJUST_CFA_OFFSET -16 |
1032 | jz 5f | 1032 | jz 5f |
1033 | jmp iret_exc | 1033 | jmp iret_exc |
1034 | 5: pushl_cfi $-1 /* orig_ax = -1 => not a system call */ | 1034 | 5: pushl_cfi $-1 /* orig_ax = -1 => not a system call */ |
1035 | SAVE_ALL | 1035 | SAVE_ALL |
1036 | jmp ret_from_exception | 1036 | jmp ret_from_exception |
1037 | CFI_ENDPROC | 1037 | CFI_ENDPROC |
1038 | 1038 | ||
1039 | .section .fixup,"ax" | 1039 | .section .fixup,"ax" |
1040 | 6: xorl %eax,%eax | 1040 | 6: xorl %eax,%eax |
1041 | movl %eax,4(%esp) | 1041 | movl %eax,4(%esp) |
1042 | jmp 1b | 1042 | jmp 1b |
1043 | 7: xorl %eax,%eax | 1043 | 7: xorl %eax,%eax |
1044 | movl %eax,8(%esp) | 1044 | movl %eax,8(%esp) |
1045 | jmp 2b | 1045 | jmp 2b |
1046 | 8: xorl %eax,%eax | 1046 | 8: xorl %eax,%eax |
1047 | movl %eax,12(%esp) | 1047 | movl %eax,12(%esp) |
1048 | jmp 3b | 1048 | jmp 3b |
1049 | 9: xorl %eax,%eax | 1049 | 9: xorl %eax,%eax |
1050 | movl %eax,16(%esp) | 1050 | movl %eax,16(%esp) |
1051 | jmp 4b | 1051 | jmp 4b |
1052 | .previous | 1052 | .previous |
1053 | _ASM_EXTABLE(1b,6b) | 1053 | _ASM_EXTABLE(1b,6b) |
1054 | _ASM_EXTABLE(2b,7b) | 1054 | _ASM_EXTABLE(2b,7b) |
1055 | _ASM_EXTABLE(3b,8b) | 1055 | _ASM_EXTABLE(3b,8b) |
1056 | _ASM_EXTABLE(4b,9b) | 1056 | _ASM_EXTABLE(4b,9b) |
1057 | ENDPROC(xen_failsafe_callback) | 1057 | ENDPROC(xen_failsafe_callback) |
1058 | 1058 | ||
1059 | BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, | 1059 | BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, |
1060 | xen_evtchn_do_upcall) | 1060 | xen_evtchn_do_upcall) |
1061 | 1061 | ||
1062 | #endif /* CONFIG_XEN */ | 1062 | #endif /* CONFIG_XEN */ |
1063 | 1063 | ||
1064 | #if IS_ENABLED(CONFIG_HYPERV) | 1064 | #if IS_ENABLED(CONFIG_HYPERV) |
1065 | 1065 | ||
1066 | BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, | 1066 | BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, |
1067 | hyperv_vector_handler) | 1067 | hyperv_vector_handler) |
1068 | 1068 | ||
1069 | #endif /* CONFIG_HYPERV */ | 1069 | #endif /* CONFIG_HYPERV */ |
1070 | 1070 | ||
1071 | #ifdef CONFIG_FUNCTION_TRACER | 1071 | #ifdef CONFIG_FUNCTION_TRACER |
1072 | #ifdef CONFIG_DYNAMIC_FTRACE | 1072 | #ifdef CONFIG_DYNAMIC_FTRACE |
1073 | 1073 | ||
1074 | ENTRY(mcount) | 1074 | ENTRY(mcount) |
1075 | ret | 1075 | ret |
1076 | END(mcount) | 1076 | END(mcount) |
1077 | 1077 | ||
1078 | ENTRY(ftrace_caller) | 1078 | ENTRY(ftrace_caller) |
1079 | cmpl $0, function_trace_stop | 1079 | cmpl $0, function_trace_stop |
1080 | jne ftrace_stub | 1080 | jne ftrace_stub |
1081 | 1081 | ||
1082 | pushl %eax | 1082 | pushl %eax |
1083 | pushl %ecx | 1083 | pushl %ecx |
1084 | pushl %edx | 1084 | pushl %edx |
1085 | pushl $0 /* Pass NULL as regs pointer */ | 1085 | pushl $0 /* Pass NULL as regs pointer */ |
1086 | movl 4*4(%esp), %eax | 1086 | movl 4*4(%esp), %eax |
1087 | movl 0x4(%ebp), %edx | 1087 | movl 0x4(%ebp), %edx |
1088 | leal function_trace_op, %ecx | 1088 | leal function_trace_op, %ecx |
1089 | subl $MCOUNT_INSN_SIZE, %eax | 1089 | subl $MCOUNT_INSN_SIZE, %eax |
1090 | 1090 | ||
1091 | .globl ftrace_call | 1091 | .globl ftrace_call |
1092 | ftrace_call: | 1092 | ftrace_call: |
1093 | call ftrace_stub | 1093 | call ftrace_stub |
1094 | 1094 | ||
1095 | addl $4,%esp /* skip NULL pointer */ | 1095 | addl $4,%esp /* skip NULL pointer */ |
1096 | popl %edx | 1096 | popl %edx |
1097 | popl %ecx | 1097 | popl %ecx |
1098 | popl %eax | 1098 | popl %eax |
1099 | ftrace_ret: | 1099 | ftrace_ret: |
1100 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1100 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1101 | .globl ftrace_graph_call | 1101 | .globl ftrace_graph_call |
1102 | ftrace_graph_call: | 1102 | ftrace_graph_call: |
1103 | jmp ftrace_stub | 1103 | jmp ftrace_stub |
1104 | #endif | 1104 | #endif |
1105 | 1105 | ||
1106 | .globl ftrace_stub | 1106 | .globl ftrace_stub |
1107 | ftrace_stub: | 1107 | ftrace_stub: |
1108 | ret | 1108 | ret |
1109 | END(ftrace_caller) | 1109 | END(ftrace_caller) |
1110 | 1110 | ||
1111 | ENTRY(ftrace_regs_caller) | 1111 | ENTRY(ftrace_regs_caller) |
1112 | pushf /* push flags before compare (in cs location) */ | 1112 | pushf /* push flags before compare (in cs location) */ |
1113 | cmpl $0, function_trace_stop | 1113 | cmpl $0, function_trace_stop |
1114 | jne ftrace_restore_flags | 1114 | jne ftrace_restore_flags |
1115 | 1115 | ||
1116 | /* | 1116 | /* |
1117 | * i386 does not save SS and ESP when coming from kernel. | 1117 | * i386 does not save SS and ESP when coming from kernel. |
1118 | * Instead, to get sp, ®s->sp is used (see ptrace.h). | 1118 | * Instead, to get sp, ®s->sp is used (see ptrace.h). |
1119 | * Unfortunately, that means eflags must be at the same location | 1119 | * Unfortunately, that means eflags must be at the same location |
1120 | * as the current return ip is. We move the return ip into the | 1120 | * as the current return ip is. We move the return ip into the |
1121 | * ip location, and move flags into the return ip location. | 1121 | * ip location, and move flags into the return ip location. |
1122 | */ | 1122 | */ |
1123 | pushl 4(%esp) /* save return ip into ip slot */ | 1123 | pushl 4(%esp) /* save return ip into ip slot */ |
1124 | 1124 | ||
1125 | pushl $0 /* Load 0 into orig_ax */ | 1125 | pushl $0 /* Load 0 into orig_ax */ |
1126 | pushl %gs | 1126 | pushl %gs |
1127 | pushl %fs | 1127 | pushl %fs |
1128 | pushl %es | 1128 | pushl %es |
1129 | pushl %ds | 1129 | pushl %ds |
1130 | pushl %eax | 1130 | pushl %eax |
1131 | pushl %ebp | 1131 | pushl %ebp |
1132 | pushl %edi | 1132 | pushl %edi |
1133 | pushl %esi | 1133 | pushl %esi |
1134 | pushl %edx | 1134 | pushl %edx |
1135 | pushl %ecx | 1135 | pushl %ecx |
1136 | pushl %ebx | 1136 | pushl %ebx |
1137 | 1137 | ||
1138 | movl 13*4(%esp), %eax /* Get the saved flags */ | 1138 | movl 13*4(%esp), %eax /* Get the saved flags */ |
1139 | movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */ | 1139 | movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */ |
1140 | /* clobbering return ip */ | 1140 | /* clobbering return ip */ |
1141 | movl $__KERNEL_CS,13*4(%esp) | 1141 | movl $__KERNEL_CS,13*4(%esp) |
1142 | 1142 | ||
1143 | movl 12*4(%esp), %eax /* Load ip (1st parameter) */ | 1143 | movl 12*4(%esp), %eax /* Load ip (1st parameter) */ |
1144 | subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */ | 1144 | subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */ |
1145 | movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */ | 1145 | movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */ |
1146 | leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */ | 1146 | leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */ |
1147 | pushl %esp /* Save pt_regs as 4th parameter */ | 1147 | pushl %esp /* Save pt_regs as 4th parameter */ |
1148 | 1148 | ||
1149 | GLOBAL(ftrace_regs_call) | 1149 | GLOBAL(ftrace_regs_call) |
1150 | call ftrace_stub | 1150 | call ftrace_stub |
1151 | 1151 | ||
1152 | addl $4, %esp /* Skip pt_regs */ | 1152 | addl $4, %esp /* Skip pt_regs */ |
1153 | movl 14*4(%esp), %eax /* Move flags back into cs */ | 1153 | movl 14*4(%esp), %eax /* Move flags back into cs */ |
1154 | movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */ | 1154 | movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */ |
1155 | movl 12*4(%esp), %eax /* Get return ip from regs->ip */ | 1155 | movl 12*4(%esp), %eax /* Get return ip from regs->ip */ |
1156 | movl %eax, 14*4(%esp) /* Put return ip back for ret */ | 1156 | movl %eax, 14*4(%esp) /* Put return ip back for ret */ |
1157 | 1157 | ||
1158 | popl %ebx | 1158 | popl %ebx |
1159 | popl %ecx | 1159 | popl %ecx |
1160 | popl %edx | 1160 | popl %edx |
1161 | popl %esi | 1161 | popl %esi |
1162 | popl %edi | 1162 | popl %edi |
1163 | popl %ebp | 1163 | popl %ebp |
1164 | popl %eax | 1164 | popl %eax |
1165 | popl %ds | 1165 | popl %ds |
1166 | popl %es | 1166 | popl %es |
1167 | popl %fs | 1167 | popl %fs |
1168 | popl %gs | 1168 | popl %gs |
1169 | addl $8, %esp /* Skip orig_ax and ip */ | 1169 | addl $8, %esp /* Skip orig_ax and ip */ |
1170 | popf /* Pop flags at end (no addl to corrupt flags) */ | 1170 | popf /* Pop flags at end (no addl to corrupt flags) */ |
1171 | jmp ftrace_ret | 1171 | jmp ftrace_ret |
1172 | 1172 | ||
1173 | ftrace_restore_flags: | 1173 | ftrace_restore_flags: |
1174 | popf | 1174 | popf |
1175 | jmp ftrace_stub | 1175 | jmp ftrace_stub |
1176 | #else /* ! CONFIG_DYNAMIC_FTRACE */ | 1176 | #else /* ! CONFIG_DYNAMIC_FTRACE */ |
1177 | 1177 | ||
1178 | ENTRY(mcount) | 1178 | ENTRY(mcount) |
1179 | cmpl $__PAGE_OFFSET, %esp | ||
1180 | jb ftrace_stub /* Paging not enabled yet? */ | ||
1181 | |||
1179 | cmpl $0, function_trace_stop | 1182 | cmpl $0, function_trace_stop |
1180 | jne ftrace_stub | 1183 | jne ftrace_stub |
1181 | 1184 | ||
1182 | cmpl $ftrace_stub, ftrace_trace_function | 1185 | cmpl $ftrace_stub, ftrace_trace_function |
1183 | jnz trace | 1186 | jnz trace |
1184 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1187 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1185 | cmpl $ftrace_stub, ftrace_graph_return | 1188 | cmpl $ftrace_stub, ftrace_graph_return |
1186 | jnz ftrace_graph_caller | 1189 | jnz ftrace_graph_caller |
1187 | 1190 | ||
1188 | cmpl $ftrace_graph_entry_stub, ftrace_graph_entry | 1191 | cmpl $ftrace_graph_entry_stub, ftrace_graph_entry |
1189 | jnz ftrace_graph_caller | 1192 | jnz ftrace_graph_caller |
1190 | #endif | 1193 | #endif |
1191 | .globl ftrace_stub | 1194 | .globl ftrace_stub |
1192 | ftrace_stub: | 1195 | ftrace_stub: |
1193 | ret | 1196 | ret |
1194 | 1197 | ||
1195 | /* taken from glibc */ | 1198 | /* taken from glibc */ |
1196 | trace: | 1199 | trace: |
1197 | pushl %eax | 1200 | pushl %eax |
1198 | pushl %ecx | 1201 | pushl %ecx |
1199 | pushl %edx | 1202 | pushl %edx |
1200 | movl 0xc(%esp), %eax | 1203 | movl 0xc(%esp), %eax |
1201 | movl 0x4(%ebp), %edx | 1204 | movl 0x4(%ebp), %edx |
1202 | subl $MCOUNT_INSN_SIZE, %eax | 1205 | subl $MCOUNT_INSN_SIZE, %eax |
1203 | 1206 | ||
1204 | call *ftrace_trace_function | 1207 | call *ftrace_trace_function |
1205 | 1208 | ||
1206 | popl %edx | 1209 | popl %edx |
1207 | popl %ecx | 1210 | popl %ecx |
1208 | popl %eax | 1211 | popl %eax |
1209 | jmp ftrace_stub | 1212 | jmp ftrace_stub |
1210 | END(mcount) | 1213 | END(mcount) |
1211 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 1214 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
1212 | #endif /* CONFIG_FUNCTION_TRACER */ | 1215 | #endif /* CONFIG_FUNCTION_TRACER */ |
1213 | 1216 | ||
1214 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1217 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1215 | ENTRY(ftrace_graph_caller) | 1218 | ENTRY(ftrace_graph_caller) |
1216 | pushl %eax | 1219 | pushl %eax |
1217 | pushl %ecx | 1220 | pushl %ecx |
1218 | pushl %edx | 1221 | pushl %edx |
1219 | movl 0xc(%esp), %edx | 1222 | movl 0xc(%esp), %edx |
1220 | lea 0x4(%ebp), %eax | 1223 | lea 0x4(%ebp), %eax |
1221 | movl (%ebp), %ecx | 1224 | movl (%ebp), %ecx |
1222 | subl $MCOUNT_INSN_SIZE, %edx | 1225 | subl $MCOUNT_INSN_SIZE, %edx |
1223 | call prepare_ftrace_return | 1226 | call prepare_ftrace_return |
1224 | popl %edx | 1227 | popl %edx |
1225 | popl %ecx | 1228 | popl %ecx |
1226 | popl %eax | 1229 | popl %eax |
1227 | ret | 1230 | ret |
1228 | END(ftrace_graph_caller) | 1231 | END(ftrace_graph_caller) |
1229 | 1232 | ||
1230 | .globl return_to_handler | 1233 | .globl return_to_handler |
1231 | return_to_handler: | 1234 | return_to_handler: |
1232 | pushl %eax | 1235 | pushl %eax |
1233 | pushl %edx | 1236 | pushl %edx |
1234 | movl %ebp, %eax | 1237 | movl %ebp, %eax |
1235 | call ftrace_return_to_handler | 1238 | call ftrace_return_to_handler |
1236 | movl %eax, %ecx | 1239 | movl %eax, %ecx |
1237 | popl %edx | 1240 | popl %edx |
1238 | popl %eax | 1241 | popl %eax |
1239 | jmp *%ecx | 1242 | jmp *%ecx |
1240 | #endif | 1243 | #endif |
1241 | 1244 | ||
1242 | /* | 1245 | /* |
1243 | * Some functions should be protected against kprobes | 1246 | * Some functions should be protected against kprobes |
1244 | */ | 1247 | */ |
1245 | .pushsection .kprobes.text, "ax" | 1248 | .pushsection .kprobes.text, "ax" |
1246 | 1249 | ||
1247 | ENTRY(page_fault) | 1250 | ENTRY(page_fault) |
1248 | RING0_EC_FRAME | 1251 | RING0_EC_FRAME |
1249 | ASM_CLAC | 1252 | ASM_CLAC |
1250 | pushl_cfi $do_page_fault | 1253 | pushl_cfi $do_page_fault |
1251 | ALIGN | 1254 | ALIGN |
1252 | error_code: | 1255 | error_code: |
1253 | /* the function address is in %gs's slot on the stack */ | 1256 | /* the function address is in %gs's slot on the stack */ |
1254 | pushl_cfi %fs | 1257 | pushl_cfi %fs |
1255 | /*CFI_REL_OFFSET fs, 0*/ | 1258 | /*CFI_REL_OFFSET fs, 0*/ |
1256 | pushl_cfi %es | 1259 | pushl_cfi %es |
1257 | /*CFI_REL_OFFSET es, 0*/ | 1260 | /*CFI_REL_OFFSET es, 0*/ |
1258 | pushl_cfi %ds | 1261 | pushl_cfi %ds |
1259 | /*CFI_REL_OFFSET ds, 0*/ | 1262 | /*CFI_REL_OFFSET ds, 0*/ |
1260 | pushl_cfi %eax | 1263 | pushl_cfi %eax |
1261 | CFI_REL_OFFSET eax, 0 | 1264 | CFI_REL_OFFSET eax, 0 |
1262 | pushl_cfi %ebp | 1265 | pushl_cfi %ebp |
1263 | CFI_REL_OFFSET ebp, 0 | 1266 | CFI_REL_OFFSET ebp, 0 |
1264 | pushl_cfi %edi | 1267 | pushl_cfi %edi |
1265 | CFI_REL_OFFSET edi, 0 | 1268 | CFI_REL_OFFSET edi, 0 |
1266 | pushl_cfi %esi | 1269 | pushl_cfi %esi |
1267 | CFI_REL_OFFSET esi, 0 | 1270 | CFI_REL_OFFSET esi, 0 |
1268 | pushl_cfi %edx | 1271 | pushl_cfi %edx |
1269 | CFI_REL_OFFSET edx, 0 | 1272 | CFI_REL_OFFSET edx, 0 |
1270 | pushl_cfi %ecx | 1273 | pushl_cfi %ecx |
1271 | CFI_REL_OFFSET ecx, 0 | 1274 | CFI_REL_OFFSET ecx, 0 |
1272 | pushl_cfi %ebx | 1275 | pushl_cfi %ebx |
1273 | CFI_REL_OFFSET ebx, 0 | 1276 | CFI_REL_OFFSET ebx, 0 |
1274 | cld | 1277 | cld |
1275 | movl $(__KERNEL_PERCPU), %ecx | 1278 | movl $(__KERNEL_PERCPU), %ecx |
1276 | movl %ecx, %fs | 1279 | movl %ecx, %fs |
1277 | UNWIND_ESPFIX_STACK | 1280 | UNWIND_ESPFIX_STACK |
1278 | GS_TO_REG %ecx | 1281 | GS_TO_REG %ecx |
1279 | movl PT_GS(%esp), %edi # get the function address | 1282 | movl PT_GS(%esp), %edi # get the function address |
1280 | movl PT_ORIG_EAX(%esp), %edx # get the error code | 1283 | movl PT_ORIG_EAX(%esp), %edx # get the error code |
1281 | movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart | 1284 | movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart |
1282 | REG_TO_PTGS %ecx | 1285 | REG_TO_PTGS %ecx |
1283 | SET_KERNEL_GS %ecx | 1286 | SET_KERNEL_GS %ecx |
1284 | movl $(__USER_DS), %ecx | 1287 | movl $(__USER_DS), %ecx |
1285 | movl %ecx, %ds | 1288 | movl %ecx, %ds |
1286 | movl %ecx, %es | 1289 | movl %ecx, %es |
1287 | TRACE_IRQS_OFF | 1290 | TRACE_IRQS_OFF |
1288 | movl %esp,%eax # pt_regs pointer | 1291 | movl %esp,%eax # pt_regs pointer |
1289 | call *%edi | 1292 | call *%edi |
1290 | jmp ret_from_exception | 1293 | jmp ret_from_exception |
1291 | CFI_ENDPROC | 1294 | CFI_ENDPROC |
1292 | END(page_fault) | 1295 | END(page_fault) |
1293 | 1296 | ||
1294 | /* | 1297 | /* |
1295 | * Debug traps and NMI can happen at the one SYSENTER instruction | 1298 | * Debug traps and NMI can happen at the one SYSENTER instruction |
1296 | * that sets up the real kernel stack. Check here, since we can't | 1299 | * that sets up the real kernel stack. Check here, since we can't |
1297 | * allow the wrong stack to be used. | 1300 | * allow the wrong stack to be used. |
1298 | * | 1301 | * |
1299 | * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have | 1302 | * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have |
1300 | * already pushed 3 words if it hits on the sysenter instruction: | 1303 | * already pushed 3 words if it hits on the sysenter instruction: |
1301 | * eflags, cs and eip. | 1304 | * eflags, cs and eip. |
1302 | * | 1305 | * |
1303 | * We just load the right stack, and push the three (known) values | 1306 | * We just load the right stack, and push the three (known) values |
1304 | * by hand onto the new stack - while updating the return eip past | 1307 | * by hand onto the new stack - while updating the return eip past |
1305 | * the instruction that would have done it for sysenter. | 1308 | * the instruction that would have done it for sysenter. |
1306 | */ | 1309 | */ |
1307 | .macro FIX_STACK offset ok label | 1310 | .macro FIX_STACK offset ok label |
1308 | cmpw $__KERNEL_CS, 4(%esp) | 1311 | cmpw $__KERNEL_CS, 4(%esp) |
1309 | jne \ok | 1312 | jne \ok |
1310 | \label: | 1313 | \label: |
1311 | movl TSS_sysenter_sp0 + \offset(%esp), %esp | 1314 | movl TSS_sysenter_sp0 + \offset(%esp), %esp |
1312 | CFI_DEF_CFA esp, 0 | 1315 | CFI_DEF_CFA esp, 0 |
1313 | CFI_UNDEFINED eip | 1316 | CFI_UNDEFINED eip |
1314 | pushfl_cfi | 1317 | pushfl_cfi |
1315 | pushl_cfi $__KERNEL_CS | 1318 | pushl_cfi $__KERNEL_CS |
1316 | pushl_cfi $sysenter_past_esp | 1319 | pushl_cfi $sysenter_past_esp |
1317 | CFI_REL_OFFSET eip, 0 | 1320 | CFI_REL_OFFSET eip, 0 |
1318 | .endm | 1321 | .endm |
1319 | 1322 | ||
1320 | ENTRY(debug) | 1323 | ENTRY(debug) |
1321 | RING0_INT_FRAME | 1324 | RING0_INT_FRAME |
1322 | ASM_CLAC | 1325 | ASM_CLAC |
1323 | cmpl $ia32_sysenter_target,(%esp) | 1326 | cmpl $ia32_sysenter_target,(%esp) |
1324 | jne debug_stack_correct | 1327 | jne debug_stack_correct |
1325 | FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn | 1328 | FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn |
1326 | debug_stack_correct: | 1329 | debug_stack_correct: |
1327 | pushl_cfi $-1 # mark this as an int | 1330 | pushl_cfi $-1 # mark this as an int |
1328 | SAVE_ALL | 1331 | SAVE_ALL |
1329 | TRACE_IRQS_OFF | 1332 | TRACE_IRQS_OFF |
1330 | xorl %edx,%edx # error code 0 | 1333 | xorl %edx,%edx # error code 0 |
1331 | movl %esp,%eax # pt_regs pointer | 1334 | movl %esp,%eax # pt_regs pointer |
1332 | call do_debug | 1335 | call do_debug |
1333 | jmp ret_from_exception | 1336 | jmp ret_from_exception |
1334 | CFI_ENDPROC | 1337 | CFI_ENDPROC |
1335 | END(debug) | 1338 | END(debug) |
1336 | 1339 | ||
1337 | /* | 1340 | /* |
1338 | * NMI is doubly nasty. It can happen _while_ we're handling | 1341 | * NMI is doubly nasty. It can happen _while_ we're handling |
1339 | * a debug fault, and the debug fault hasn't yet been able to | 1342 | * a debug fault, and the debug fault hasn't yet been able to |
1340 | * clear up the stack. So we first check whether we got an | 1343 | * clear up the stack. So we first check whether we got an |
1341 | * NMI on the sysenter entry path, but after that we need to | 1344 | * NMI on the sysenter entry path, but after that we need to |
1342 | * check whether we got an NMI on the debug path where the debug | 1345 | * check whether we got an NMI on the debug path where the debug |
1343 | * fault happened on the sysenter path. | 1346 | * fault happened on the sysenter path. |
1344 | */ | 1347 | */ |
1345 | ENTRY(nmi) | 1348 | ENTRY(nmi) |
1346 | RING0_INT_FRAME | 1349 | RING0_INT_FRAME |
1347 | ASM_CLAC | 1350 | ASM_CLAC |
1348 | pushl_cfi %eax | 1351 | pushl_cfi %eax |
1349 | movl %ss, %eax | 1352 | movl %ss, %eax |
1350 | cmpw $__ESPFIX_SS, %ax | 1353 | cmpw $__ESPFIX_SS, %ax |
1351 | popl_cfi %eax | 1354 | popl_cfi %eax |
1352 | je nmi_espfix_stack | 1355 | je nmi_espfix_stack |
1353 | cmpl $ia32_sysenter_target,(%esp) | 1356 | cmpl $ia32_sysenter_target,(%esp) |
1354 | je nmi_stack_fixup | 1357 | je nmi_stack_fixup |
1355 | pushl_cfi %eax | 1358 | pushl_cfi %eax |
1356 | movl %esp,%eax | 1359 | movl %esp,%eax |
1357 | /* Do not access memory above the end of our stack page, | 1360 | /* Do not access memory above the end of our stack page, |
1358 | * it might not exist. | 1361 | * it might not exist. |
1359 | */ | 1362 | */ |
1360 | andl $(THREAD_SIZE-1),%eax | 1363 | andl $(THREAD_SIZE-1),%eax |
1361 | cmpl $(THREAD_SIZE-20),%eax | 1364 | cmpl $(THREAD_SIZE-20),%eax |
1362 | popl_cfi %eax | 1365 | popl_cfi %eax |
1363 | jae nmi_stack_correct | 1366 | jae nmi_stack_correct |
1364 | cmpl $ia32_sysenter_target,12(%esp) | 1367 | cmpl $ia32_sysenter_target,12(%esp) |
1365 | je nmi_debug_stack_check | 1368 | je nmi_debug_stack_check |
1366 | nmi_stack_correct: | 1369 | nmi_stack_correct: |
1367 | /* We have a RING0_INT_FRAME here */ | 1370 | /* We have a RING0_INT_FRAME here */ |
1368 | pushl_cfi %eax | 1371 | pushl_cfi %eax |
1369 | SAVE_ALL | 1372 | SAVE_ALL |
1370 | xorl %edx,%edx # zero error code | 1373 | xorl %edx,%edx # zero error code |
1371 | movl %esp,%eax # pt_regs pointer | 1374 | movl %esp,%eax # pt_regs pointer |
1372 | call do_nmi | 1375 | call do_nmi |
1373 | jmp restore_all_notrace | 1376 | jmp restore_all_notrace |
1374 | CFI_ENDPROC | 1377 | CFI_ENDPROC |
1375 | 1378 | ||
1376 | nmi_stack_fixup: | 1379 | nmi_stack_fixup: |
1377 | RING0_INT_FRAME | 1380 | RING0_INT_FRAME |
1378 | FIX_STACK 12, nmi_stack_correct, 1 | 1381 | FIX_STACK 12, nmi_stack_correct, 1 |
1379 | jmp nmi_stack_correct | 1382 | jmp nmi_stack_correct |
1380 | 1383 | ||
1381 | nmi_debug_stack_check: | 1384 | nmi_debug_stack_check: |
1382 | /* We have a RING0_INT_FRAME here */ | 1385 | /* We have a RING0_INT_FRAME here */ |
1383 | cmpw $__KERNEL_CS,16(%esp) | 1386 | cmpw $__KERNEL_CS,16(%esp) |
1384 | jne nmi_stack_correct | 1387 | jne nmi_stack_correct |
1385 | cmpl $debug,(%esp) | 1388 | cmpl $debug,(%esp) |
1386 | jb nmi_stack_correct | 1389 | jb nmi_stack_correct |
1387 | cmpl $debug_esp_fix_insn,(%esp) | 1390 | cmpl $debug_esp_fix_insn,(%esp) |
1388 | ja nmi_stack_correct | 1391 | ja nmi_stack_correct |
1389 | FIX_STACK 24, nmi_stack_correct, 1 | 1392 | FIX_STACK 24, nmi_stack_correct, 1 |
1390 | jmp nmi_stack_correct | 1393 | jmp nmi_stack_correct |
1391 | 1394 | ||
1392 | nmi_espfix_stack: | 1395 | nmi_espfix_stack: |
1393 | /* We have a RING0_INT_FRAME here. | 1396 | /* We have a RING0_INT_FRAME here. |
1394 | * | 1397 | * |
1395 | * create the pointer to lss back | 1398 | * create the pointer to lss back |
1396 | */ | 1399 | */ |
1397 | pushl_cfi %ss | 1400 | pushl_cfi %ss |
1398 | pushl_cfi %esp | 1401 | pushl_cfi %esp |
1399 | addl $4, (%esp) | 1402 | addl $4, (%esp) |
1400 | /* copy the iret frame of 12 bytes */ | 1403 | /* copy the iret frame of 12 bytes */ |
1401 | .rept 3 | 1404 | .rept 3 |
1402 | pushl_cfi 16(%esp) | 1405 | pushl_cfi 16(%esp) |
1403 | .endr | 1406 | .endr |
1404 | pushl_cfi %eax | 1407 | pushl_cfi %eax |
1405 | SAVE_ALL | 1408 | SAVE_ALL |
1406 | FIXUP_ESPFIX_STACK # %eax == %esp | 1409 | FIXUP_ESPFIX_STACK # %eax == %esp |
1407 | xorl %edx,%edx # zero error code | 1410 | xorl %edx,%edx # zero error code |
1408 | call do_nmi | 1411 | call do_nmi |
1409 | RESTORE_REGS | 1412 | RESTORE_REGS |
1410 | lss 12+4(%esp), %esp # back to espfix stack | 1413 | lss 12+4(%esp), %esp # back to espfix stack |
1411 | CFI_ADJUST_CFA_OFFSET -24 | 1414 | CFI_ADJUST_CFA_OFFSET -24 |
1412 | jmp irq_return | 1415 | jmp irq_return |
1413 | CFI_ENDPROC | 1416 | CFI_ENDPROC |
1414 | END(nmi) | 1417 | END(nmi) |
1415 | 1418 | ||
1416 | ENTRY(int3) | 1419 | ENTRY(int3) |
1417 | RING0_INT_FRAME | 1420 | RING0_INT_FRAME |
1418 | ASM_CLAC | 1421 | ASM_CLAC |
1419 | pushl_cfi $-1 # mark this as an int | 1422 | pushl_cfi $-1 # mark this as an int |
1420 | SAVE_ALL | 1423 | SAVE_ALL |
1421 | TRACE_IRQS_OFF | 1424 | TRACE_IRQS_OFF |
1422 | xorl %edx,%edx # zero error code | 1425 | xorl %edx,%edx # zero error code |
1423 | movl %esp,%eax # pt_regs pointer | 1426 | movl %esp,%eax # pt_regs pointer |
1424 | call do_int3 | 1427 | call do_int3 |
1425 | jmp ret_from_exception | 1428 | jmp ret_from_exception |
1426 | CFI_ENDPROC | 1429 | CFI_ENDPROC |
1427 | END(int3) | 1430 | END(int3) |
1428 | 1431 | ||
1429 | ENTRY(general_protection) | 1432 | ENTRY(general_protection) |
1430 | RING0_EC_FRAME | 1433 | RING0_EC_FRAME |
1431 | pushl_cfi $do_general_protection | 1434 | pushl_cfi $do_general_protection |
1432 | jmp error_code | 1435 | jmp error_code |
1433 | CFI_ENDPROC | 1436 | CFI_ENDPROC |
1434 | END(general_protection) | 1437 | END(general_protection) |
1435 | 1438 | ||
1436 | #ifdef CONFIG_KVM_GUEST | 1439 | #ifdef CONFIG_KVM_GUEST |
1437 | ENTRY(async_page_fault) | 1440 | ENTRY(async_page_fault) |
1438 | RING0_EC_FRAME | 1441 | RING0_EC_FRAME |
1439 | ASM_CLAC | 1442 | ASM_CLAC |
1440 | pushl_cfi $do_async_page_fault | 1443 | pushl_cfi $do_async_page_fault |
1441 | jmp error_code | 1444 | jmp error_code |
1442 | CFI_ENDPROC | 1445 | CFI_ENDPROC |
1443 | END(async_page_fault) | 1446 | END(async_page_fault) |
1444 | #endif | 1447 | #endif |
1445 | 1448 | ||
1446 | /* | 1449 | /* |
1447 | * End of kprobes section | 1450 | * End of kprobes section |
1448 | */ | 1451 | */ |
1449 | .popsection | 1452 | .popsection |
1450 | 1453 |
kernel/rcupdate.c
1 | /* | 1 | /* |
2 | * Read-Copy Update mechanism for mutual exclusion | 2 | * Read-Copy Update mechanism for mutual exclusion |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or | 6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. | 7 | * (at your option) any later version. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it will be useful, | 9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | * | 17 | * |
18 | * Copyright IBM Corporation, 2001 | 18 | * Copyright IBM Corporation, 2001 |
19 | * | 19 | * |
20 | * Authors: Dipankar Sarma <dipankar@in.ibm.com> | 20 | * Authors: Dipankar Sarma <dipankar@in.ibm.com> |
21 | * Manfred Spraul <manfred@colorfullife.com> | 21 | * Manfred Spraul <manfred@colorfullife.com> |
22 | * | 22 | * |
23 | * Based on the original work by Paul McKenney <paulmck@us.ibm.com> | 23 | * Based on the original work by Paul McKenney <paulmck@us.ibm.com> |
24 | * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen. | 24 | * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen. |
25 | * Papers: | 25 | * Papers: |
26 | * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf | 26 | * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf |
27 | * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001) | 27 | * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001) |
28 | * | 28 | * |
29 | * For detailed explanation of Read-Copy Update mechanism see - | 29 | * For detailed explanation of Read-Copy Update mechanism see - |
30 | * http://lse.sourceforge.net/locking/rcupdate.html | 30 | * http://lse.sourceforge.net/locking/rcupdate.html |
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/smp.h> | 37 | #include <linux/smp.h> |
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/atomic.h> | 40 | #include <linux/atomic.h> |
41 | #include <linux/bitops.h> | 41 | #include <linux/bitops.h> |
42 | #include <linux/percpu.h> | 42 | #include <linux/percpu.h> |
43 | #include <linux/notifier.h> | 43 | #include <linux/notifier.h> |
44 | #include <linux/cpu.h> | 44 | #include <linux/cpu.h> |
45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
46 | #include <linux/export.h> | 46 | #include <linux/export.h> |
47 | #include <linux/hardirq.h> | 47 | #include <linux/hardirq.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/module.h> | 49 | #include <linux/module.h> |
50 | 50 | ||
51 | #define CREATE_TRACE_POINTS | 51 | #define CREATE_TRACE_POINTS |
52 | #include <trace/events/rcu.h> | 52 | #include <trace/events/rcu.h> |
53 | 53 | ||
54 | #include "rcu.h" | 54 | #include "rcu.h" |
55 | 55 | ||
56 | module_param(rcu_expedited, int, 0); | 56 | module_param(rcu_expedited, int, 0); |
57 | 57 | ||
58 | #ifdef CONFIG_PREEMPT_RCU | 58 | #ifdef CONFIG_PREEMPT_RCU |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Preemptible RCU implementation for rcu_read_lock(). | 61 | * Preemptible RCU implementation for rcu_read_lock(). |
62 | * Just increment ->rcu_read_lock_nesting, shared state will be updated | 62 | * Just increment ->rcu_read_lock_nesting, shared state will be updated |
63 | * if we block. | 63 | * if we block. |
64 | */ | 64 | */ |
65 | void __rcu_read_lock(void) | 65 | void __rcu_read_lock(void) |
66 | { | 66 | { |
67 | current->rcu_read_lock_nesting++; | 67 | current->rcu_read_lock_nesting++; |
68 | barrier(); /* critical section after entry code. */ | 68 | barrier(); /* critical section after entry code. */ |
69 | } | 69 | } |
70 | EXPORT_SYMBOL_GPL(__rcu_read_lock); | 70 | EXPORT_SYMBOL_GPL(__rcu_read_lock); |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Preemptible RCU implementation for rcu_read_unlock(). | 73 | * Preemptible RCU implementation for rcu_read_unlock(). |
74 | * Decrement ->rcu_read_lock_nesting. If the result is zero (outermost | 74 | * Decrement ->rcu_read_lock_nesting. If the result is zero (outermost |
75 | * rcu_read_unlock()) and ->rcu_read_unlock_special is non-zero, then | 75 | * rcu_read_unlock()) and ->rcu_read_unlock_special is non-zero, then |
76 | * invoke rcu_read_unlock_special() to clean up after a context switch | 76 | * invoke rcu_read_unlock_special() to clean up after a context switch |
77 | * in an RCU read-side critical section and other special cases. | 77 | * in an RCU read-side critical section and other special cases. |
78 | */ | 78 | */ |
79 | void __rcu_read_unlock(void) | 79 | void __rcu_read_unlock(void) |
80 | { | 80 | { |
81 | struct task_struct *t = current; | 81 | struct task_struct *t = current; |
82 | 82 | ||
83 | if (t->rcu_read_lock_nesting != 1) { | 83 | if (t->rcu_read_lock_nesting != 1) { |
84 | --t->rcu_read_lock_nesting; | 84 | --t->rcu_read_lock_nesting; |
85 | } else { | 85 | } else { |
86 | barrier(); /* critical section before exit code. */ | 86 | barrier(); /* critical section before exit code. */ |
87 | t->rcu_read_lock_nesting = INT_MIN; | 87 | t->rcu_read_lock_nesting = INT_MIN; |
88 | #ifdef CONFIG_PROVE_RCU_DELAY | 88 | #ifdef CONFIG_PROVE_RCU_DELAY |
89 | udelay(10); /* Make preemption more probable. */ | 89 | udelay(10); /* Make preemption more probable. */ |
90 | #endif /* #ifdef CONFIG_PROVE_RCU_DELAY */ | 90 | #endif /* #ifdef CONFIG_PROVE_RCU_DELAY */ |
91 | barrier(); /* assign before ->rcu_read_unlock_special load */ | 91 | barrier(); /* assign before ->rcu_read_unlock_special load */ |
92 | if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) | 92 | if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) |
93 | rcu_read_unlock_special(t); | 93 | rcu_read_unlock_special(t); |
94 | barrier(); /* ->rcu_read_unlock_special load before assign */ | 94 | barrier(); /* ->rcu_read_unlock_special load before assign */ |
95 | t->rcu_read_lock_nesting = 0; | 95 | t->rcu_read_lock_nesting = 0; |
96 | } | 96 | } |
97 | #ifdef CONFIG_PROVE_LOCKING | 97 | #ifdef CONFIG_PROVE_LOCKING |
98 | { | 98 | { |
99 | int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting); | 99 | int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting); |
100 | 100 | ||
101 | WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2); | 101 | WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2); |
102 | } | 102 | } |
103 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | 103 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ |
104 | } | 104 | } |
105 | EXPORT_SYMBOL_GPL(__rcu_read_unlock); | 105 | EXPORT_SYMBOL_GPL(__rcu_read_unlock); |
106 | 106 | ||
107 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ | 107 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ |
108 | 108 | ||
109 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 109 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
110 | static struct lock_class_key rcu_lock_key; | 110 | static struct lock_class_key rcu_lock_key; |
111 | struct lockdep_map rcu_lock_map = | 111 | struct lockdep_map rcu_lock_map = |
112 | STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key); | 112 | STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key); |
113 | EXPORT_SYMBOL_GPL(rcu_lock_map); | 113 | EXPORT_SYMBOL_GPL(rcu_lock_map); |
114 | 114 | ||
115 | static struct lock_class_key rcu_bh_lock_key; | 115 | static struct lock_class_key rcu_bh_lock_key; |
116 | struct lockdep_map rcu_bh_lock_map = | 116 | struct lockdep_map rcu_bh_lock_map = |
117 | STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_bh", &rcu_bh_lock_key); | 117 | STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_bh", &rcu_bh_lock_key); |
118 | EXPORT_SYMBOL_GPL(rcu_bh_lock_map); | 118 | EXPORT_SYMBOL_GPL(rcu_bh_lock_map); |
119 | 119 | ||
120 | static struct lock_class_key rcu_sched_lock_key; | 120 | static struct lock_class_key rcu_sched_lock_key; |
121 | struct lockdep_map rcu_sched_lock_map = | 121 | struct lockdep_map rcu_sched_lock_map = |
122 | STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_sched", &rcu_sched_lock_key); | 122 | STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_sched", &rcu_sched_lock_key); |
123 | EXPORT_SYMBOL_GPL(rcu_sched_lock_map); | 123 | EXPORT_SYMBOL_GPL(rcu_sched_lock_map); |
124 | 124 | ||
125 | int debug_lockdep_rcu_enabled(void) | 125 | int notrace debug_lockdep_rcu_enabled(void) |
126 | { | 126 | { |
127 | return rcu_scheduler_active && debug_locks && | 127 | return rcu_scheduler_active && debug_locks && |
128 | current->lockdep_recursion == 0; | 128 | current->lockdep_recursion == 0; |
129 | } | 129 | } |
130 | EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled); | 130 | EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled); |
131 | 131 | ||
132 | /** | 132 | /** |
133 | * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section? | 133 | * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section? |
134 | * | 134 | * |
135 | * Check for bottom half being disabled, which covers both the | 135 | * Check for bottom half being disabled, which covers both the |
136 | * CONFIG_PROVE_RCU and not cases. Note that if someone uses | 136 | * CONFIG_PROVE_RCU and not cases. Note that if someone uses |
137 | * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled) | 137 | * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled) |
138 | * will show the situation. This is useful for debug checks in functions | 138 | * will show the situation. This is useful for debug checks in functions |
139 | * that require that they be called within an RCU read-side critical | 139 | * that require that they be called within an RCU read-side critical |
140 | * section. | 140 | * section. |
141 | * | 141 | * |
142 | * Check debug_lockdep_rcu_enabled() to prevent false positives during boot. | 142 | * Check debug_lockdep_rcu_enabled() to prevent false positives during boot. |
143 | * | 143 | * |
144 | * Note that rcu_read_lock() is disallowed if the CPU is either idle or | 144 | * Note that rcu_read_lock() is disallowed if the CPU is either idle or |
145 | * offline from an RCU perspective, so check for those as well. | 145 | * offline from an RCU perspective, so check for those as well. |
146 | */ | 146 | */ |
147 | int rcu_read_lock_bh_held(void) | 147 | int rcu_read_lock_bh_held(void) |
148 | { | 148 | { |
149 | if (!debug_lockdep_rcu_enabled()) | 149 | if (!debug_lockdep_rcu_enabled()) |
150 | return 1; | 150 | return 1; |
151 | if (rcu_is_cpu_idle()) | 151 | if (rcu_is_cpu_idle()) |
152 | return 0; | 152 | return 0; |
153 | if (!rcu_lockdep_current_cpu_online()) | 153 | if (!rcu_lockdep_current_cpu_online()) |
154 | return 0; | 154 | return 0; |
155 | return in_softirq() || irqs_disabled(); | 155 | return in_softirq() || irqs_disabled(); |
156 | } | 156 | } |
157 | EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); | 157 | EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); |
158 | 158 | ||
159 | #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | 159 | #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ |
160 | 160 | ||
161 | struct rcu_synchronize { | 161 | struct rcu_synchronize { |
162 | struct rcu_head head; | 162 | struct rcu_head head; |
163 | struct completion completion; | 163 | struct completion completion; |
164 | }; | 164 | }; |
165 | 165 | ||
166 | /* | 166 | /* |
167 | * Awaken the corresponding synchronize_rcu() instance now that a | 167 | * Awaken the corresponding synchronize_rcu() instance now that a |
168 | * grace period has elapsed. | 168 | * grace period has elapsed. |
169 | */ | 169 | */ |
170 | static void wakeme_after_rcu(struct rcu_head *head) | 170 | static void wakeme_after_rcu(struct rcu_head *head) |
171 | { | 171 | { |
172 | struct rcu_synchronize *rcu; | 172 | struct rcu_synchronize *rcu; |
173 | 173 | ||
174 | rcu = container_of(head, struct rcu_synchronize, head); | 174 | rcu = container_of(head, struct rcu_synchronize, head); |
175 | complete(&rcu->completion); | 175 | complete(&rcu->completion); |
176 | } | 176 | } |
177 | 177 | ||
178 | void wait_rcu_gp(call_rcu_func_t crf) | 178 | void wait_rcu_gp(call_rcu_func_t crf) |
179 | { | 179 | { |
180 | struct rcu_synchronize rcu; | 180 | struct rcu_synchronize rcu; |
181 | 181 | ||
182 | init_rcu_head_on_stack(&rcu.head); | 182 | init_rcu_head_on_stack(&rcu.head); |
183 | init_completion(&rcu.completion); | 183 | init_completion(&rcu.completion); |
184 | /* Will wake me after RCU finished. */ | 184 | /* Will wake me after RCU finished. */ |
185 | crf(&rcu.head, wakeme_after_rcu); | 185 | crf(&rcu.head, wakeme_after_rcu); |
186 | /* Wait for it. */ | 186 | /* Wait for it. */ |
187 | wait_for_completion(&rcu.completion); | 187 | wait_for_completion(&rcu.completion); |
188 | destroy_rcu_head_on_stack(&rcu.head); | 188 | destroy_rcu_head_on_stack(&rcu.head); |
189 | } | 189 | } |
190 | EXPORT_SYMBOL_GPL(wait_rcu_gp); | 190 | EXPORT_SYMBOL_GPL(wait_rcu_gp); |
191 | 191 | ||
192 | #ifdef CONFIG_PROVE_RCU | 192 | #ifdef CONFIG_PROVE_RCU |
193 | /* | 193 | /* |
194 | * wrapper function to avoid #include problems. | 194 | * wrapper function to avoid #include problems. |
195 | */ | 195 | */ |
196 | int rcu_my_thread_group_empty(void) | 196 | int rcu_my_thread_group_empty(void) |
197 | { | 197 | { |
198 | return thread_group_empty(current); | 198 | return thread_group_empty(current); |
199 | } | 199 | } |
200 | EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty); | 200 | EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty); |
201 | #endif /* #ifdef CONFIG_PROVE_RCU */ | 201 | #endif /* #ifdef CONFIG_PROVE_RCU */ |
202 | 202 | ||
203 | #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD | 203 | #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD |
204 | static inline void debug_init_rcu_head(struct rcu_head *head) | 204 | static inline void debug_init_rcu_head(struct rcu_head *head) |
205 | { | 205 | { |
206 | debug_object_init(head, &rcuhead_debug_descr); | 206 | debug_object_init(head, &rcuhead_debug_descr); |
207 | } | 207 | } |
208 | 208 | ||
209 | static inline void debug_rcu_head_free(struct rcu_head *head) | 209 | static inline void debug_rcu_head_free(struct rcu_head *head) |
210 | { | 210 | { |
211 | debug_object_free(head, &rcuhead_debug_descr); | 211 | debug_object_free(head, &rcuhead_debug_descr); |
212 | } | 212 | } |
213 | 213 | ||
214 | /* | 214 | /* |
215 | * fixup_activate is called when: | 215 | * fixup_activate is called when: |
216 | * - an active object is activated | 216 | * - an active object is activated |
217 | * - an unknown object is activated (might be a statically initialized object) | 217 | * - an unknown object is activated (might be a statically initialized object) |
218 | * Activation is performed internally by call_rcu(). | 218 | * Activation is performed internally by call_rcu(). |
219 | */ | 219 | */ |
220 | static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state) | 220 | static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state) |
221 | { | 221 | { |
222 | struct rcu_head *head = addr; | 222 | struct rcu_head *head = addr; |
223 | 223 | ||
224 | switch (state) { | 224 | switch (state) { |
225 | 225 | ||
226 | case ODEBUG_STATE_NOTAVAILABLE: | 226 | case ODEBUG_STATE_NOTAVAILABLE: |
227 | /* | 227 | /* |
228 | * This is not really a fixup. We just make sure that it is | 228 | * This is not really a fixup. We just make sure that it is |
229 | * tracked in the object tracker. | 229 | * tracked in the object tracker. |
230 | */ | 230 | */ |
231 | debug_object_init(head, &rcuhead_debug_descr); | 231 | debug_object_init(head, &rcuhead_debug_descr); |
232 | debug_object_activate(head, &rcuhead_debug_descr); | 232 | debug_object_activate(head, &rcuhead_debug_descr); |
233 | return 0; | 233 | return 0; |
234 | default: | 234 | default: |
235 | return 1; | 235 | return 1; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | /** | 239 | /** |
240 | * init_rcu_head_on_stack() - initialize on-stack rcu_head for debugobjects | 240 | * init_rcu_head_on_stack() - initialize on-stack rcu_head for debugobjects |
241 | * @head: pointer to rcu_head structure to be initialized | 241 | * @head: pointer to rcu_head structure to be initialized |
242 | * | 242 | * |
243 | * This function informs debugobjects of a new rcu_head structure that | 243 | * This function informs debugobjects of a new rcu_head structure that |
244 | * has been allocated as an auto variable on the stack. This function | 244 | * has been allocated as an auto variable on the stack. This function |
245 | * is not required for rcu_head structures that are statically defined or | 245 | * is not required for rcu_head structures that are statically defined or |
246 | * that are dynamically allocated on the heap. This function has no | 246 | * that are dynamically allocated on the heap. This function has no |
247 | * effect for !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds. | 247 | * effect for !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds. |
248 | */ | 248 | */ |
249 | void init_rcu_head_on_stack(struct rcu_head *head) | 249 | void init_rcu_head_on_stack(struct rcu_head *head) |
250 | { | 250 | { |
251 | debug_object_init_on_stack(head, &rcuhead_debug_descr); | 251 | debug_object_init_on_stack(head, &rcuhead_debug_descr); |
252 | } | 252 | } |
253 | EXPORT_SYMBOL_GPL(init_rcu_head_on_stack); | 253 | EXPORT_SYMBOL_GPL(init_rcu_head_on_stack); |
254 | 254 | ||
255 | /** | 255 | /** |
256 | * destroy_rcu_head_on_stack() - destroy on-stack rcu_head for debugobjects | 256 | * destroy_rcu_head_on_stack() - destroy on-stack rcu_head for debugobjects |
257 | * @head: pointer to rcu_head structure to be initialized | 257 | * @head: pointer to rcu_head structure to be initialized |
258 | * | 258 | * |
259 | * This function informs debugobjects that an on-stack rcu_head structure | 259 | * This function informs debugobjects that an on-stack rcu_head structure |
260 | * is about to go out of scope. As with init_rcu_head_on_stack(), this | 260 | * is about to go out of scope. As with init_rcu_head_on_stack(), this |
261 | * function is not required for rcu_head structures that are statically | 261 | * function is not required for rcu_head structures that are statically |
262 | * defined or that are dynamically allocated on the heap. Also as with | 262 | * defined or that are dynamically allocated on the heap. Also as with |
263 | * init_rcu_head_on_stack(), this function has no effect for | 263 | * init_rcu_head_on_stack(), this function has no effect for |
264 | * !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds. | 264 | * !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds. |
265 | */ | 265 | */ |
266 | void destroy_rcu_head_on_stack(struct rcu_head *head) | 266 | void destroy_rcu_head_on_stack(struct rcu_head *head) |
267 | { | 267 | { |
268 | debug_object_free(head, &rcuhead_debug_descr); | 268 | debug_object_free(head, &rcuhead_debug_descr); |
269 | } | 269 | } |
270 | EXPORT_SYMBOL_GPL(destroy_rcu_head_on_stack); | 270 | EXPORT_SYMBOL_GPL(destroy_rcu_head_on_stack); |
271 | 271 | ||
272 | struct debug_obj_descr rcuhead_debug_descr = { | 272 | struct debug_obj_descr rcuhead_debug_descr = { |
273 | .name = "rcu_head", | 273 | .name = "rcu_head", |
274 | .fixup_activate = rcuhead_fixup_activate, | 274 | .fixup_activate = rcuhead_fixup_activate, |
275 | }; | 275 | }; |
276 | EXPORT_SYMBOL_GPL(rcuhead_debug_descr); | 276 | EXPORT_SYMBOL_GPL(rcuhead_debug_descr); |
277 | #endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | 277 | #endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */ |
278 | 278 | ||
279 | #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) || defined(CONFIG_RCU_TRACE) | 279 | #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) || defined(CONFIG_RCU_TRACE) |
280 | void do_trace_rcu_torture_read(const char *rcutorturename, struct rcu_head *rhp, | 280 | void do_trace_rcu_torture_read(const char *rcutorturename, struct rcu_head *rhp, |
281 | unsigned long secs, | 281 | unsigned long secs, |
282 | unsigned long c_old, unsigned long c) | 282 | unsigned long c_old, unsigned long c) |
283 | { | 283 | { |
284 | trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c); | 284 | trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c); |
285 | } | 285 | } |
286 | EXPORT_SYMBOL_GPL(do_trace_rcu_torture_read); | 286 | EXPORT_SYMBOL_GPL(do_trace_rcu_torture_read); |
287 | #else | 287 | #else |
288 | #define do_trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \ | 288 | #define do_trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \ |
289 | do { } while (0) | 289 | do { } while (0) |
290 | #endif | 290 | #endif |
291 | 291 | ||
292 | #ifdef CONFIG_RCU_STALL_COMMON | 292 | #ifdef CONFIG_RCU_STALL_COMMON |
293 | 293 | ||
294 | #ifdef CONFIG_PROVE_RCU | 294 | #ifdef CONFIG_PROVE_RCU |
295 | #define RCU_STALL_DELAY_DELTA (5 * HZ) | 295 | #define RCU_STALL_DELAY_DELTA (5 * HZ) |
296 | #else | 296 | #else |
297 | #define RCU_STALL_DELAY_DELTA 0 | 297 | #define RCU_STALL_DELAY_DELTA 0 |
298 | #endif | 298 | #endif |
299 | 299 | ||
300 | int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */ | 300 | int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */ |
301 | int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT; | 301 | int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT; |
302 | 302 | ||
303 | module_param(rcu_cpu_stall_suppress, int, 0644); | 303 | module_param(rcu_cpu_stall_suppress, int, 0644); |
304 | module_param(rcu_cpu_stall_timeout, int, 0644); | 304 | module_param(rcu_cpu_stall_timeout, int, 0644); |
305 | 305 | ||
306 | int rcu_jiffies_till_stall_check(void) | 306 | int rcu_jiffies_till_stall_check(void) |
307 | { | 307 | { |
308 | int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout); | 308 | int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout); |
309 | 309 | ||
310 | /* | 310 | /* |
311 | * Limit check must be consistent with the Kconfig limits | 311 | * Limit check must be consistent with the Kconfig limits |
312 | * for CONFIG_RCU_CPU_STALL_TIMEOUT. | 312 | * for CONFIG_RCU_CPU_STALL_TIMEOUT. |
313 | */ | 313 | */ |
314 | if (till_stall_check < 3) { | 314 | if (till_stall_check < 3) { |
315 | ACCESS_ONCE(rcu_cpu_stall_timeout) = 3; | 315 | ACCESS_ONCE(rcu_cpu_stall_timeout) = 3; |
316 | till_stall_check = 3; | 316 | till_stall_check = 3; |
317 | } else if (till_stall_check > 300) { | 317 | } else if (till_stall_check > 300) { |
318 | ACCESS_ONCE(rcu_cpu_stall_timeout) = 300; | 318 | ACCESS_ONCE(rcu_cpu_stall_timeout) = 300; |
319 | till_stall_check = 300; | 319 | till_stall_check = 300; |
320 | } | 320 | } |
321 | return till_stall_check * HZ + RCU_STALL_DELAY_DELTA; | 321 | return till_stall_check * HZ + RCU_STALL_DELAY_DELTA; |
322 | } | 322 | } |
323 | 323 | ||
324 | static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr) | 324 | static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr) |
325 | { | 325 | { |
326 | rcu_cpu_stall_suppress = 1; | 326 | rcu_cpu_stall_suppress = 1; |
327 | return NOTIFY_DONE; | 327 | return NOTIFY_DONE; |
328 | } | 328 | } |
329 | 329 | ||
330 | static struct notifier_block rcu_panic_block = { | 330 | static struct notifier_block rcu_panic_block = { |
331 | .notifier_call = rcu_panic, | 331 | .notifier_call = rcu_panic, |
332 | }; | 332 | }; |
333 | 333 | ||
334 | static int __init check_cpu_stall_init(void) | 334 | static int __init check_cpu_stall_init(void) |
335 | { | 335 | { |
336 | atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block); | 336 | atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block); |
337 | return 0; | 337 | return 0; |
338 | } | 338 | } |
339 | early_initcall(check_cpu_stall_init); | 339 | early_initcall(check_cpu_stall_init); |
340 | 340 | ||
341 | #endif /* #ifdef CONFIG_RCU_STALL_COMMON */ | 341 | #endif /* #ifdef CONFIG_RCU_STALL_COMMON */ |
342 | 342 |
kernel/trace/ftrace.c
1 | /* | 1 | /* |
2 | * Infrastructure for profiling code inserted by 'gcc -pg'. | 2 | * Infrastructure for profiling code inserted by 'gcc -pg'. |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com> | 4 | * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com> |
5 | * Copyright (C) 2004-2008 Ingo Molnar <mingo@redhat.com> | 5 | * Copyright (C) 2004-2008 Ingo Molnar <mingo@redhat.com> |
6 | * | 6 | * |
7 | * Originally ported from the -rt patch by: | 7 | * Originally ported from the -rt patch by: |
8 | * Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@redhat.com> | 8 | * Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@redhat.com> |
9 | * | 9 | * |
10 | * Based on code in the latency_tracer, that is: | 10 | * Based on code in the latency_tracer, that is: |
11 | * | 11 | * |
12 | * Copyright (C) 2004-2006 Ingo Molnar | 12 | * Copyright (C) 2004-2006 Ingo Molnar |
13 | * Copyright (C) 2004 Nadia Yvette Chambers | 13 | * Copyright (C) 2004 Nadia Yvette Chambers |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/stop_machine.h> | 16 | #include <linux/stop_machine.h> |
17 | #include <linux/clocksource.h> | 17 | #include <linux/clocksource.h> |
18 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/suspend.h> | 20 | #include <linux/suspend.h> |
21 | #include <linux/debugfs.h> | 21 | #include <linux/debugfs.h> |
22 | #include <linux/hardirq.h> | 22 | #include <linux/hardirq.h> |
23 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
25 | #include <linux/bsearch.h> | 25 | #include <linux/bsearch.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/ftrace.h> | 27 | #include <linux/ftrace.h> |
28 | #include <linux/sysctl.h> | 28 | #include <linux/sysctl.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/ctype.h> | 30 | #include <linux/ctype.h> |
31 | #include <linux/sort.h> | 31 | #include <linux/sort.h> |
32 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/hash.h> | 33 | #include <linux/hash.h> |
34 | #include <linux/rcupdate.h> | 34 | #include <linux/rcupdate.h> |
35 | 35 | ||
36 | #include <trace/events/sched.h> | 36 | #include <trace/events/sched.h> |
37 | 37 | ||
38 | #include <asm/setup.h> | 38 | #include <asm/setup.h> |
39 | 39 | ||
40 | #include "trace_output.h" | 40 | #include "trace_output.h" |
41 | #include "trace_stat.h" | 41 | #include "trace_stat.h" |
42 | 42 | ||
43 | #define FTRACE_WARN_ON(cond) \ | 43 | #define FTRACE_WARN_ON(cond) \ |
44 | ({ \ | 44 | ({ \ |
45 | int ___r = cond; \ | 45 | int ___r = cond; \ |
46 | if (WARN_ON(___r)) \ | 46 | if (WARN_ON(___r)) \ |
47 | ftrace_kill(); \ | 47 | ftrace_kill(); \ |
48 | ___r; \ | 48 | ___r; \ |
49 | }) | 49 | }) |
50 | 50 | ||
51 | #define FTRACE_WARN_ON_ONCE(cond) \ | 51 | #define FTRACE_WARN_ON_ONCE(cond) \ |
52 | ({ \ | 52 | ({ \ |
53 | int ___r = cond; \ | 53 | int ___r = cond; \ |
54 | if (WARN_ON_ONCE(___r)) \ | 54 | if (WARN_ON_ONCE(___r)) \ |
55 | ftrace_kill(); \ | 55 | ftrace_kill(); \ |
56 | ___r; \ | 56 | ___r; \ |
57 | }) | 57 | }) |
58 | 58 | ||
59 | /* hash bits for specific function selection */ | 59 | /* hash bits for specific function selection */ |
60 | #define FTRACE_HASH_BITS 7 | 60 | #define FTRACE_HASH_BITS 7 |
61 | #define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS) | 61 | #define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS) |
62 | #define FTRACE_HASH_DEFAULT_BITS 10 | 62 | #define FTRACE_HASH_DEFAULT_BITS 10 |
63 | #define FTRACE_HASH_MAX_BITS 12 | 63 | #define FTRACE_HASH_MAX_BITS 12 |
64 | 64 | ||
65 | #define FL_GLOBAL_CONTROL_MASK (FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_CONTROL) | 65 | #define FL_GLOBAL_CONTROL_MASK (FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_CONTROL) |
66 | 66 | ||
67 | #ifdef CONFIG_DYNAMIC_FTRACE | 67 | #ifdef CONFIG_DYNAMIC_FTRACE |
68 | #define INIT_REGEX_LOCK(opsname) \ | 68 | #define INIT_REGEX_LOCK(opsname) \ |
69 | .regex_lock = __MUTEX_INITIALIZER(opsname.regex_lock), | 69 | .regex_lock = __MUTEX_INITIALIZER(opsname.regex_lock), |
70 | #else | 70 | #else |
71 | #define INIT_REGEX_LOCK(opsname) | 71 | #define INIT_REGEX_LOCK(opsname) |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | static struct ftrace_ops ftrace_list_end __read_mostly = { | 74 | static struct ftrace_ops ftrace_list_end __read_mostly = { |
75 | .func = ftrace_stub, | 75 | .func = ftrace_stub, |
76 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_STUB, | 76 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_STUB, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* ftrace_enabled is a method to turn ftrace on or off */ | 79 | /* ftrace_enabled is a method to turn ftrace on or off */ |
80 | int ftrace_enabled __read_mostly; | 80 | int ftrace_enabled __read_mostly; |
81 | static int last_ftrace_enabled; | 81 | static int last_ftrace_enabled; |
82 | 82 | ||
83 | /* Quick disabling of function tracer. */ | 83 | /* Quick disabling of function tracer. */ |
84 | int function_trace_stop __read_mostly; | 84 | int function_trace_stop __read_mostly; |
85 | 85 | ||
86 | /* Current function tracing op */ | 86 | /* Current function tracing op */ |
87 | struct ftrace_ops *function_trace_op __read_mostly = &ftrace_list_end; | 87 | struct ftrace_ops *function_trace_op __read_mostly = &ftrace_list_end; |
88 | 88 | ||
89 | /* List for set_ftrace_pid's pids. */ | 89 | /* List for set_ftrace_pid's pids. */ |
90 | LIST_HEAD(ftrace_pids); | 90 | LIST_HEAD(ftrace_pids); |
91 | struct ftrace_pid { | 91 | struct ftrace_pid { |
92 | struct list_head list; | 92 | struct list_head list; |
93 | struct pid *pid; | 93 | struct pid *pid; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * ftrace_disabled is set when an anomaly is discovered. | 97 | * ftrace_disabled is set when an anomaly is discovered. |
98 | * ftrace_disabled is much stronger than ftrace_enabled. | 98 | * ftrace_disabled is much stronger than ftrace_enabled. |
99 | */ | 99 | */ |
100 | static int ftrace_disabled __read_mostly; | 100 | static int ftrace_disabled __read_mostly; |
101 | 101 | ||
102 | static DEFINE_MUTEX(ftrace_lock); | 102 | static DEFINE_MUTEX(ftrace_lock); |
103 | 103 | ||
104 | static struct ftrace_ops *ftrace_global_list __read_mostly = &ftrace_list_end; | 104 | static struct ftrace_ops *ftrace_global_list __read_mostly = &ftrace_list_end; |
105 | static struct ftrace_ops *ftrace_control_list __read_mostly = &ftrace_list_end; | 105 | static struct ftrace_ops *ftrace_control_list __read_mostly = &ftrace_list_end; |
106 | static struct ftrace_ops *ftrace_ops_list __read_mostly = &ftrace_list_end; | 106 | static struct ftrace_ops *ftrace_ops_list __read_mostly = &ftrace_list_end; |
107 | ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; | 107 | ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; |
108 | ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; | 108 | ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; |
109 | static struct ftrace_ops global_ops; | 109 | static struct ftrace_ops global_ops; |
110 | static struct ftrace_ops control_ops; | 110 | static struct ftrace_ops control_ops; |
111 | 111 | ||
112 | #if ARCH_SUPPORTS_FTRACE_OPS | 112 | #if ARCH_SUPPORTS_FTRACE_OPS |
113 | static void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, | 113 | static void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, |
114 | struct ftrace_ops *op, struct pt_regs *regs); | 114 | struct ftrace_ops *op, struct pt_regs *regs); |
115 | #else | 115 | #else |
116 | /* See comment below, where ftrace_ops_list_func is defined */ | 116 | /* See comment below, where ftrace_ops_list_func is defined */ |
117 | static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip); | 117 | static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip); |
118 | #define ftrace_ops_list_func ((ftrace_func_t)ftrace_ops_no_ops) | 118 | #define ftrace_ops_list_func ((ftrace_func_t)ftrace_ops_no_ops) |
119 | #endif | 119 | #endif |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Traverse the ftrace_global_list, invoking all entries. The reason that we | 122 | * Traverse the ftrace_global_list, invoking all entries. The reason that we |
123 | * can use rcu_dereference_raw_notrace() is that elements removed from this list | 123 | * can use rcu_dereference_raw_notrace() is that elements removed from this list |
124 | * are simply leaked, so there is no need to interact with a grace-period | 124 | * are simply leaked, so there is no need to interact with a grace-period |
125 | * mechanism. The rcu_dereference_raw_notrace() calls are needed to handle | 125 | * mechanism. The rcu_dereference_raw_notrace() calls are needed to handle |
126 | * concurrent insertions into the ftrace_global_list. | 126 | * concurrent insertions into the ftrace_global_list. |
127 | * | 127 | * |
128 | * Silly Alpha and silly pointer-speculation compiler optimizations! | 128 | * Silly Alpha and silly pointer-speculation compiler optimizations! |
129 | */ | 129 | */ |
130 | #define do_for_each_ftrace_op(op, list) \ | 130 | #define do_for_each_ftrace_op(op, list) \ |
131 | op = rcu_dereference_raw_notrace(list); \ | 131 | op = rcu_dereference_raw_notrace(list); \ |
132 | do | 132 | do |
133 | 133 | ||
134 | /* | 134 | /* |
135 | * Optimized for just a single item in the list (as that is the normal case). | 135 | * Optimized for just a single item in the list (as that is the normal case). |
136 | */ | 136 | */ |
137 | #define while_for_each_ftrace_op(op) \ | 137 | #define while_for_each_ftrace_op(op) \ |
138 | while (likely(op = rcu_dereference_raw_notrace((op)->next)) && \ | 138 | while (likely(op = rcu_dereference_raw_notrace((op)->next)) && \ |
139 | unlikely((op) != &ftrace_list_end)) | 139 | unlikely((op) != &ftrace_list_end)) |
140 | 140 | ||
141 | static inline void ftrace_ops_init(struct ftrace_ops *ops) | 141 | static inline void ftrace_ops_init(struct ftrace_ops *ops) |
142 | { | 142 | { |
143 | #ifdef CONFIG_DYNAMIC_FTRACE | 143 | #ifdef CONFIG_DYNAMIC_FTRACE |
144 | if (!(ops->flags & FTRACE_OPS_FL_INITIALIZED)) { | 144 | if (!(ops->flags & FTRACE_OPS_FL_INITIALIZED)) { |
145 | mutex_init(&ops->regex_lock); | 145 | mutex_init(&ops->regex_lock); |
146 | ops->flags |= FTRACE_OPS_FL_INITIALIZED; | 146 | ops->flags |= FTRACE_OPS_FL_INITIALIZED; |
147 | } | 147 | } |
148 | #endif | 148 | #endif |
149 | } | 149 | } |
150 | 150 | ||
151 | /** | 151 | /** |
152 | * ftrace_nr_registered_ops - return number of ops registered | 152 | * ftrace_nr_registered_ops - return number of ops registered |
153 | * | 153 | * |
154 | * Returns the number of ftrace_ops registered and tracing functions | 154 | * Returns the number of ftrace_ops registered and tracing functions |
155 | */ | 155 | */ |
156 | int ftrace_nr_registered_ops(void) | 156 | int ftrace_nr_registered_ops(void) |
157 | { | 157 | { |
158 | struct ftrace_ops *ops; | 158 | struct ftrace_ops *ops; |
159 | int cnt = 0; | 159 | int cnt = 0; |
160 | 160 | ||
161 | mutex_lock(&ftrace_lock); | 161 | mutex_lock(&ftrace_lock); |
162 | 162 | ||
163 | for (ops = ftrace_ops_list; | 163 | for (ops = ftrace_ops_list; |
164 | ops != &ftrace_list_end; ops = ops->next) | 164 | ops != &ftrace_list_end; ops = ops->next) |
165 | cnt++; | 165 | cnt++; |
166 | 166 | ||
167 | mutex_unlock(&ftrace_lock); | 167 | mutex_unlock(&ftrace_lock); |
168 | 168 | ||
169 | return cnt; | 169 | return cnt; |
170 | } | 170 | } |
171 | 171 | ||
172 | static void | 172 | static void |
173 | ftrace_global_list_func(unsigned long ip, unsigned long parent_ip, | 173 | ftrace_global_list_func(unsigned long ip, unsigned long parent_ip, |
174 | struct ftrace_ops *op, struct pt_regs *regs) | 174 | struct ftrace_ops *op, struct pt_regs *regs) |
175 | { | 175 | { |
176 | int bit; | 176 | int bit; |
177 | 177 | ||
178 | bit = trace_test_and_set_recursion(TRACE_GLOBAL_START, TRACE_GLOBAL_MAX); | 178 | bit = trace_test_and_set_recursion(TRACE_GLOBAL_START, TRACE_GLOBAL_MAX); |
179 | if (bit < 0) | 179 | if (bit < 0) |
180 | return; | 180 | return; |
181 | 181 | ||
182 | do_for_each_ftrace_op(op, ftrace_global_list) { | 182 | do_for_each_ftrace_op(op, ftrace_global_list) { |
183 | op->func(ip, parent_ip, op, regs); | 183 | op->func(ip, parent_ip, op, regs); |
184 | } while_for_each_ftrace_op(op); | 184 | } while_for_each_ftrace_op(op); |
185 | 185 | ||
186 | trace_clear_recursion(bit); | 186 | trace_clear_recursion(bit); |
187 | } | 187 | } |
188 | 188 | ||
189 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip, | 189 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip, |
190 | struct ftrace_ops *op, struct pt_regs *regs) | 190 | struct ftrace_ops *op, struct pt_regs *regs) |
191 | { | 191 | { |
192 | if (!test_tsk_trace_trace(current)) | 192 | if (!test_tsk_trace_trace(current)) |
193 | return; | 193 | return; |
194 | 194 | ||
195 | ftrace_pid_function(ip, parent_ip, op, regs); | 195 | ftrace_pid_function(ip, parent_ip, op, regs); |
196 | } | 196 | } |
197 | 197 | ||
198 | static void set_ftrace_pid_function(ftrace_func_t func) | 198 | static void set_ftrace_pid_function(ftrace_func_t func) |
199 | { | 199 | { |
200 | /* do not set ftrace_pid_function to itself! */ | 200 | /* do not set ftrace_pid_function to itself! */ |
201 | if (func != ftrace_pid_func) | 201 | if (func != ftrace_pid_func) |
202 | ftrace_pid_function = func; | 202 | ftrace_pid_function = func; |
203 | } | 203 | } |
204 | 204 | ||
205 | /** | 205 | /** |
206 | * clear_ftrace_function - reset the ftrace function | 206 | * clear_ftrace_function - reset the ftrace function |
207 | * | 207 | * |
208 | * This NULLs the ftrace function and in essence stops | 208 | * This NULLs the ftrace function and in essence stops |
209 | * tracing. There may be lag | 209 | * tracing. There may be lag |
210 | */ | 210 | */ |
211 | void clear_ftrace_function(void) | 211 | void clear_ftrace_function(void) |
212 | { | 212 | { |
213 | ftrace_trace_function = ftrace_stub; | 213 | ftrace_trace_function = ftrace_stub; |
214 | ftrace_pid_function = ftrace_stub; | 214 | ftrace_pid_function = ftrace_stub; |
215 | } | 215 | } |
216 | 216 | ||
217 | static void control_ops_disable_all(struct ftrace_ops *ops) | 217 | static void control_ops_disable_all(struct ftrace_ops *ops) |
218 | { | 218 | { |
219 | int cpu; | 219 | int cpu; |
220 | 220 | ||
221 | for_each_possible_cpu(cpu) | 221 | for_each_possible_cpu(cpu) |
222 | *per_cpu_ptr(ops->disabled, cpu) = 1; | 222 | *per_cpu_ptr(ops->disabled, cpu) = 1; |
223 | } | 223 | } |
224 | 224 | ||
225 | static int control_ops_alloc(struct ftrace_ops *ops) | 225 | static int control_ops_alloc(struct ftrace_ops *ops) |
226 | { | 226 | { |
227 | int __percpu *disabled; | 227 | int __percpu *disabled; |
228 | 228 | ||
229 | disabled = alloc_percpu(int); | 229 | disabled = alloc_percpu(int); |
230 | if (!disabled) | 230 | if (!disabled) |
231 | return -ENOMEM; | 231 | return -ENOMEM; |
232 | 232 | ||
233 | ops->disabled = disabled; | 233 | ops->disabled = disabled; |
234 | control_ops_disable_all(ops); | 234 | control_ops_disable_all(ops); |
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
238 | static void control_ops_free(struct ftrace_ops *ops) | 238 | static void control_ops_free(struct ftrace_ops *ops) |
239 | { | 239 | { |
240 | free_percpu(ops->disabled); | 240 | free_percpu(ops->disabled); |
241 | } | 241 | } |
242 | 242 | ||
243 | static void update_global_ops(void) | 243 | static void update_global_ops(void) |
244 | { | 244 | { |
245 | ftrace_func_t func; | 245 | ftrace_func_t func; |
246 | 246 | ||
247 | /* | 247 | /* |
248 | * If there's only one function registered, then call that | 248 | * If there's only one function registered, then call that |
249 | * function directly. Otherwise, we need to iterate over the | 249 | * function directly. Otherwise, we need to iterate over the |
250 | * registered callers. | 250 | * registered callers. |
251 | */ | 251 | */ |
252 | if (ftrace_global_list == &ftrace_list_end || | 252 | if (ftrace_global_list == &ftrace_list_end || |
253 | ftrace_global_list->next == &ftrace_list_end) { | 253 | ftrace_global_list->next == &ftrace_list_end) { |
254 | func = ftrace_global_list->func; | 254 | func = ftrace_global_list->func; |
255 | /* | 255 | /* |
256 | * As we are calling the function directly. | 256 | * As we are calling the function directly. |
257 | * If it does not have recursion protection, | 257 | * If it does not have recursion protection, |
258 | * the function_trace_op needs to be updated | 258 | * the function_trace_op needs to be updated |
259 | * accordingly. | 259 | * accordingly. |
260 | */ | 260 | */ |
261 | if (ftrace_global_list->flags & FTRACE_OPS_FL_RECURSION_SAFE) | 261 | if (ftrace_global_list->flags & FTRACE_OPS_FL_RECURSION_SAFE) |
262 | global_ops.flags |= FTRACE_OPS_FL_RECURSION_SAFE; | 262 | global_ops.flags |= FTRACE_OPS_FL_RECURSION_SAFE; |
263 | else | 263 | else |
264 | global_ops.flags &= ~FTRACE_OPS_FL_RECURSION_SAFE; | 264 | global_ops.flags &= ~FTRACE_OPS_FL_RECURSION_SAFE; |
265 | } else { | 265 | } else { |
266 | func = ftrace_global_list_func; | 266 | func = ftrace_global_list_func; |
267 | /* The list has its own recursion protection. */ | 267 | /* The list has its own recursion protection. */ |
268 | global_ops.flags |= FTRACE_OPS_FL_RECURSION_SAFE; | 268 | global_ops.flags |= FTRACE_OPS_FL_RECURSION_SAFE; |
269 | } | 269 | } |
270 | 270 | ||
271 | 271 | ||
272 | /* If we filter on pids, update to use the pid function */ | 272 | /* If we filter on pids, update to use the pid function */ |
273 | if (!list_empty(&ftrace_pids)) { | 273 | if (!list_empty(&ftrace_pids)) { |
274 | set_ftrace_pid_function(func); | 274 | set_ftrace_pid_function(func); |
275 | func = ftrace_pid_func; | 275 | func = ftrace_pid_func; |
276 | } | 276 | } |
277 | 277 | ||
278 | global_ops.func = func; | 278 | global_ops.func = func; |
279 | } | 279 | } |
280 | 280 | ||
281 | static void update_ftrace_function(void) | 281 | static void update_ftrace_function(void) |
282 | { | 282 | { |
283 | ftrace_func_t func; | 283 | ftrace_func_t func; |
284 | 284 | ||
285 | update_global_ops(); | 285 | update_global_ops(); |
286 | 286 | ||
287 | /* | 287 | /* |
288 | * If we are at the end of the list and this ops is | 288 | * If we are at the end of the list and this ops is |
289 | * recursion safe and not dynamic and the arch supports passing ops, | 289 | * recursion safe and not dynamic and the arch supports passing ops, |
290 | * then have the mcount trampoline call the function directly. | 290 | * then have the mcount trampoline call the function directly. |
291 | */ | 291 | */ |
292 | if (ftrace_ops_list == &ftrace_list_end || | 292 | if (ftrace_ops_list == &ftrace_list_end || |
293 | (ftrace_ops_list->next == &ftrace_list_end && | 293 | (ftrace_ops_list->next == &ftrace_list_end && |
294 | !(ftrace_ops_list->flags & FTRACE_OPS_FL_DYNAMIC) && | 294 | !(ftrace_ops_list->flags & FTRACE_OPS_FL_DYNAMIC) && |
295 | (ftrace_ops_list->flags & FTRACE_OPS_FL_RECURSION_SAFE) && | 295 | (ftrace_ops_list->flags & FTRACE_OPS_FL_RECURSION_SAFE) && |
296 | !FTRACE_FORCE_LIST_FUNC)) { | 296 | !FTRACE_FORCE_LIST_FUNC)) { |
297 | /* Set the ftrace_ops that the arch callback uses */ | 297 | /* Set the ftrace_ops that the arch callback uses */ |
298 | if (ftrace_ops_list == &global_ops) | 298 | if (ftrace_ops_list == &global_ops) |
299 | function_trace_op = ftrace_global_list; | 299 | function_trace_op = ftrace_global_list; |
300 | else | 300 | else |
301 | function_trace_op = ftrace_ops_list; | 301 | function_trace_op = ftrace_ops_list; |
302 | func = ftrace_ops_list->func; | 302 | func = ftrace_ops_list->func; |
303 | } else { | 303 | } else { |
304 | /* Just use the default ftrace_ops */ | 304 | /* Just use the default ftrace_ops */ |
305 | function_trace_op = &ftrace_list_end; | 305 | function_trace_op = &ftrace_list_end; |
306 | func = ftrace_ops_list_func; | 306 | func = ftrace_ops_list_func; |
307 | } | 307 | } |
308 | 308 | ||
309 | ftrace_trace_function = func; | 309 | ftrace_trace_function = func; |
310 | } | 310 | } |
311 | 311 | ||
312 | static void add_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) | 312 | static void add_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) |
313 | { | 313 | { |
314 | ops->next = *list; | 314 | ops->next = *list; |
315 | /* | 315 | /* |
316 | * We are entering ops into the list but another | 316 | * We are entering ops into the list but another |
317 | * CPU might be walking that list. We need to make sure | 317 | * CPU might be walking that list. We need to make sure |
318 | * the ops->next pointer is valid before another CPU sees | 318 | * the ops->next pointer is valid before another CPU sees |
319 | * the ops pointer included into the list. | 319 | * the ops pointer included into the list. |
320 | */ | 320 | */ |
321 | rcu_assign_pointer(*list, ops); | 321 | rcu_assign_pointer(*list, ops); |
322 | } | 322 | } |
323 | 323 | ||
324 | static int remove_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) | 324 | static int remove_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) |
325 | { | 325 | { |
326 | struct ftrace_ops **p; | 326 | struct ftrace_ops **p; |
327 | 327 | ||
328 | /* | 328 | /* |
329 | * If we are removing the last function, then simply point | 329 | * If we are removing the last function, then simply point |
330 | * to the ftrace_stub. | 330 | * to the ftrace_stub. |
331 | */ | 331 | */ |
332 | if (*list == ops && ops->next == &ftrace_list_end) { | 332 | if (*list == ops && ops->next == &ftrace_list_end) { |
333 | *list = &ftrace_list_end; | 333 | *list = &ftrace_list_end; |
334 | return 0; | 334 | return 0; |
335 | } | 335 | } |
336 | 336 | ||
337 | for (p = list; *p != &ftrace_list_end; p = &(*p)->next) | 337 | for (p = list; *p != &ftrace_list_end; p = &(*p)->next) |
338 | if (*p == ops) | 338 | if (*p == ops) |
339 | break; | 339 | break; |
340 | 340 | ||
341 | if (*p != ops) | 341 | if (*p != ops) |
342 | return -1; | 342 | return -1; |
343 | 343 | ||
344 | *p = (*p)->next; | 344 | *p = (*p)->next; |
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | 347 | ||
348 | static void add_ftrace_list_ops(struct ftrace_ops **list, | 348 | static void add_ftrace_list_ops(struct ftrace_ops **list, |
349 | struct ftrace_ops *main_ops, | 349 | struct ftrace_ops *main_ops, |
350 | struct ftrace_ops *ops) | 350 | struct ftrace_ops *ops) |
351 | { | 351 | { |
352 | int first = *list == &ftrace_list_end; | 352 | int first = *list == &ftrace_list_end; |
353 | add_ftrace_ops(list, ops); | 353 | add_ftrace_ops(list, ops); |
354 | if (first) | 354 | if (first) |
355 | add_ftrace_ops(&ftrace_ops_list, main_ops); | 355 | add_ftrace_ops(&ftrace_ops_list, main_ops); |
356 | } | 356 | } |
357 | 357 | ||
358 | static int remove_ftrace_list_ops(struct ftrace_ops **list, | 358 | static int remove_ftrace_list_ops(struct ftrace_ops **list, |
359 | struct ftrace_ops *main_ops, | 359 | struct ftrace_ops *main_ops, |
360 | struct ftrace_ops *ops) | 360 | struct ftrace_ops *ops) |
361 | { | 361 | { |
362 | int ret = remove_ftrace_ops(list, ops); | 362 | int ret = remove_ftrace_ops(list, ops); |
363 | if (!ret && *list == &ftrace_list_end) | 363 | if (!ret && *list == &ftrace_list_end) |
364 | ret = remove_ftrace_ops(&ftrace_ops_list, main_ops); | 364 | ret = remove_ftrace_ops(&ftrace_ops_list, main_ops); |
365 | return ret; | 365 | return ret; |
366 | } | 366 | } |
367 | 367 | ||
368 | static int __register_ftrace_function(struct ftrace_ops *ops) | 368 | static int __register_ftrace_function(struct ftrace_ops *ops) |
369 | { | 369 | { |
370 | if (unlikely(ftrace_disabled)) | 370 | if (unlikely(ftrace_disabled)) |
371 | return -ENODEV; | 371 | return -ENODEV; |
372 | 372 | ||
373 | if (FTRACE_WARN_ON(ops == &global_ops)) | 373 | if (FTRACE_WARN_ON(ops == &global_ops)) |
374 | return -EINVAL; | 374 | return -EINVAL; |
375 | 375 | ||
376 | if (WARN_ON(ops->flags & FTRACE_OPS_FL_ENABLED)) | 376 | if (WARN_ON(ops->flags & FTRACE_OPS_FL_ENABLED)) |
377 | return -EBUSY; | 377 | return -EBUSY; |
378 | 378 | ||
379 | /* We don't support both control and global flags set. */ | 379 | /* We don't support both control and global flags set. */ |
380 | if ((ops->flags & FL_GLOBAL_CONTROL_MASK) == FL_GLOBAL_CONTROL_MASK) | 380 | if ((ops->flags & FL_GLOBAL_CONTROL_MASK) == FL_GLOBAL_CONTROL_MASK) |
381 | return -EINVAL; | 381 | return -EINVAL; |
382 | 382 | ||
383 | #ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS | 383 | #ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS |
384 | /* | 384 | /* |
385 | * If the ftrace_ops specifies SAVE_REGS, then it only can be used | 385 | * If the ftrace_ops specifies SAVE_REGS, then it only can be used |
386 | * if the arch supports it, or SAVE_REGS_IF_SUPPORTED is also set. | 386 | * if the arch supports it, or SAVE_REGS_IF_SUPPORTED is also set. |
387 | * Setting SAVE_REGS_IF_SUPPORTED makes SAVE_REGS irrelevant. | 387 | * Setting SAVE_REGS_IF_SUPPORTED makes SAVE_REGS irrelevant. |
388 | */ | 388 | */ |
389 | if (ops->flags & FTRACE_OPS_FL_SAVE_REGS && | 389 | if (ops->flags & FTRACE_OPS_FL_SAVE_REGS && |
390 | !(ops->flags & FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED)) | 390 | !(ops->flags & FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED)) |
391 | return -EINVAL; | 391 | return -EINVAL; |
392 | 392 | ||
393 | if (ops->flags & FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED) | 393 | if (ops->flags & FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED) |
394 | ops->flags |= FTRACE_OPS_FL_SAVE_REGS; | 394 | ops->flags |= FTRACE_OPS_FL_SAVE_REGS; |
395 | #endif | 395 | #endif |
396 | 396 | ||
397 | if (!core_kernel_data((unsigned long)ops)) | 397 | if (!core_kernel_data((unsigned long)ops)) |
398 | ops->flags |= FTRACE_OPS_FL_DYNAMIC; | 398 | ops->flags |= FTRACE_OPS_FL_DYNAMIC; |
399 | 399 | ||
400 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { | 400 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { |
401 | add_ftrace_list_ops(&ftrace_global_list, &global_ops, ops); | 401 | add_ftrace_list_ops(&ftrace_global_list, &global_ops, ops); |
402 | ops->flags |= FTRACE_OPS_FL_ENABLED; | 402 | ops->flags |= FTRACE_OPS_FL_ENABLED; |
403 | } else if (ops->flags & FTRACE_OPS_FL_CONTROL) { | 403 | } else if (ops->flags & FTRACE_OPS_FL_CONTROL) { |
404 | if (control_ops_alloc(ops)) | 404 | if (control_ops_alloc(ops)) |
405 | return -ENOMEM; | 405 | return -ENOMEM; |
406 | add_ftrace_list_ops(&ftrace_control_list, &control_ops, ops); | 406 | add_ftrace_list_ops(&ftrace_control_list, &control_ops, ops); |
407 | } else | 407 | } else |
408 | add_ftrace_ops(&ftrace_ops_list, ops); | 408 | add_ftrace_ops(&ftrace_ops_list, ops); |
409 | 409 | ||
410 | if (ftrace_enabled) | 410 | if (ftrace_enabled) |
411 | update_ftrace_function(); | 411 | update_ftrace_function(); |
412 | 412 | ||
413 | return 0; | 413 | return 0; |
414 | } | 414 | } |
415 | 415 | ||
416 | static void ftrace_sync(struct work_struct *work) | 416 | static void ftrace_sync(struct work_struct *work) |
417 | { | 417 | { |
418 | /* | 418 | /* |
419 | * This function is just a stub to implement a hard force | 419 | * This function is just a stub to implement a hard force |
420 | * of synchronize_sched(). This requires synchronizing | 420 | * of synchronize_sched(). This requires synchronizing |
421 | * tasks even in userspace and idle. | 421 | * tasks even in userspace and idle. |
422 | * | 422 | * |
423 | * Yes, function tracing is rude. | 423 | * Yes, function tracing is rude. |
424 | */ | 424 | */ |
425 | } | 425 | } |
426 | 426 | ||
427 | static int __unregister_ftrace_function(struct ftrace_ops *ops) | 427 | static int __unregister_ftrace_function(struct ftrace_ops *ops) |
428 | { | 428 | { |
429 | int ret; | 429 | int ret; |
430 | 430 | ||
431 | if (ftrace_disabled) | 431 | if (ftrace_disabled) |
432 | return -ENODEV; | 432 | return -ENODEV; |
433 | 433 | ||
434 | if (WARN_ON(!(ops->flags & FTRACE_OPS_FL_ENABLED))) | 434 | if (WARN_ON(!(ops->flags & FTRACE_OPS_FL_ENABLED))) |
435 | return -EBUSY; | 435 | return -EBUSY; |
436 | 436 | ||
437 | if (FTRACE_WARN_ON(ops == &global_ops)) | 437 | if (FTRACE_WARN_ON(ops == &global_ops)) |
438 | return -EINVAL; | 438 | return -EINVAL; |
439 | 439 | ||
440 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { | 440 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { |
441 | ret = remove_ftrace_list_ops(&ftrace_global_list, | 441 | ret = remove_ftrace_list_ops(&ftrace_global_list, |
442 | &global_ops, ops); | 442 | &global_ops, ops); |
443 | if (!ret) | 443 | if (!ret) |
444 | ops->flags &= ~FTRACE_OPS_FL_ENABLED; | 444 | ops->flags &= ~FTRACE_OPS_FL_ENABLED; |
445 | } else if (ops->flags & FTRACE_OPS_FL_CONTROL) { | 445 | } else if (ops->flags & FTRACE_OPS_FL_CONTROL) { |
446 | ret = remove_ftrace_list_ops(&ftrace_control_list, | 446 | ret = remove_ftrace_list_ops(&ftrace_control_list, |
447 | &control_ops, ops); | 447 | &control_ops, ops); |
448 | if (!ret) { | 448 | if (!ret) { |
449 | /* | 449 | /* |
450 | * The ftrace_ops is now removed from the list, | 450 | * The ftrace_ops is now removed from the list, |
451 | * so there'll be no new users. We must ensure | 451 | * so there'll be no new users. We must ensure |
452 | * all current users are done before we free | 452 | * all current users are done before we free |
453 | * the control data. | 453 | * the control data. |
454 | * Note synchronize_sched() is not enough, as we | 454 | * Note synchronize_sched() is not enough, as we |
455 | * use preempt_disable() to do RCU, but the function | 455 | * use preempt_disable() to do RCU, but the function |
456 | * tracer can be called where RCU is not active | 456 | * tracer can be called where RCU is not active |
457 | * (before user_exit()). | 457 | * (before user_exit()). |
458 | */ | 458 | */ |
459 | schedule_on_each_cpu(ftrace_sync); | 459 | schedule_on_each_cpu(ftrace_sync); |
460 | control_ops_free(ops); | 460 | control_ops_free(ops); |
461 | } | 461 | } |
462 | } else | 462 | } else |
463 | ret = remove_ftrace_ops(&ftrace_ops_list, ops); | 463 | ret = remove_ftrace_ops(&ftrace_ops_list, ops); |
464 | 464 | ||
465 | if (ret < 0) | 465 | if (ret < 0) |
466 | return ret; | 466 | return ret; |
467 | 467 | ||
468 | if (ftrace_enabled) | 468 | if (ftrace_enabled) |
469 | update_ftrace_function(); | 469 | update_ftrace_function(); |
470 | 470 | ||
471 | /* | 471 | /* |
472 | * Dynamic ops may be freed, we must make sure that all | 472 | * Dynamic ops may be freed, we must make sure that all |
473 | * callers are done before leaving this function. | 473 | * callers are done before leaving this function. |
474 | * | 474 | * |
475 | * Again, normal synchronize_sched() is not good enough. | 475 | * Again, normal synchronize_sched() is not good enough. |
476 | * We need to do a hard force of sched synchronization. | 476 | * We need to do a hard force of sched synchronization. |
477 | */ | 477 | */ |
478 | if (ops->flags & FTRACE_OPS_FL_DYNAMIC) | 478 | if (ops->flags & FTRACE_OPS_FL_DYNAMIC) |
479 | schedule_on_each_cpu(ftrace_sync); | 479 | schedule_on_each_cpu(ftrace_sync); |
480 | 480 | ||
481 | 481 | ||
482 | return 0; | 482 | return 0; |
483 | } | 483 | } |
484 | 484 | ||
485 | static void ftrace_update_pid_func(void) | 485 | static void ftrace_update_pid_func(void) |
486 | { | 486 | { |
487 | /* Only do something if we are tracing something */ | 487 | /* Only do something if we are tracing something */ |
488 | if (ftrace_trace_function == ftrace_stub) | 488 | if (ftrace_trace_function == ftrace_stub) |
489 | return; | 489 | return; |
490 | 490 | ||
491 | update_ftrace_function(); | 491 | update_ftrace_function(); |
492 | } | 492 | } |
493 | 493 | ||
494 | #ifdef CONFIG_FUNCTION_PROFILER | 494 | #ifdef CONFIG_FUNCTION_PROFILER |
495 | struct ftrace_profile { | 495 | struct ftrace_profile { |
496 | struct hlist_node node; | 496 | struct hlist_node node; |
497 | unsigned long ip; | 497 | unsigned long ip; |
498 | unsigned long counter; | 498 | unsigned long counter; |
499 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 499 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
500 | unsigned long long time; | 500 | unsigned long long time; |
501 | unsigned long long time_squared; | 501 | unsigned long long time_squared; |
502 | #endif | 502 | #endif |
503 | }; | 503 | }; |
504 | 504 | ||
505 | struct ftrace_profile_page { | 505 | struct ftrace_profile_page { |
506 | struct ftrace_profile_page *next; | 506 | struct ftrace_profile_page *next; |
507 | unsigned long index; | 507 | unsigned long index; |
508 | struct ftrace_profile records[]; | 508 | struct ftrace_profile records[]; |
509 | }; | 509 | }; |
510 | 510 | ||
511 | struct ftrace_profile_stat { | 511 | struct ftrace_profile_stat { |
512 | atomic_t disabled; | 512 | atomic_t disabled; |
513 | struct hlist_head *hash; | 513 | struct hlist_head *hash; |
514 | struct ftrace_profile_page *pages; | 514 | struct ftrace_profile_page *pages; |
515 | struct ftrace_profile_page *start; | 515 | struct ftrace_profile_page *start; |
516 | struct tracer_stat stat; | 516 | struct tracer_stat stat; |
517 | }; | 517 | }; |
518 | 518 | ||
519 | #define PROFILE_RECORDS_SIZE \ | 519 | #define PROFILE_RECORDS_SIZE \ |
520 | (PAGE_SIZE - offsetof(struct ftrace_profile_page, records)) | 520 | (PAGE_SIZE - offsetof(struct ftrace_profile_page, records)) |
521 | 521 | ||
522 | #define PROFILES_PER_PAGE \ | 522 | #define PROFILES_PER_PAGE \ |
523 | (PROFILE_RECORDS_SIZE / sizeof(struct ftrace_profile)) | 523 | (PROFILE_RECORDS_SIZE / sizeof(struct ftrace_profile)) |
524 | 524 | ||
525 | static int ftrace_profile_enabled __read_mostly; | 525 | static int ftrace_profile_enabled __read_mostly; |
526 | 526 | ||
527 | /* ftrace_profile_lock - synchronize the enable and disable of the profiler */ | 527 | /* ftrace_profile_lock - synchronize the enable and disable of the profiler */ |
528 | static DEFINE_MUTEX(ftrace_profile_lock); | 528 | static DEFINE_MUTEX(ftrace_profile_lock); |
529 | 529 | ||
530 | static DEFINE_PER_CPU(struct ftrace_profile_stat, ftrace_profile_stats); | 530 | static DEFINE_PER_CPU(struct ftrace_profile_stat, ftrace_profile_stats); |
531 | 531 | ||
532 | #define FTRACE_PROFILE_HASH_BITS 10 | 532 | #define FTRACE_PROFILE_HASH_BITS 10 |
533 | #define FTRACE_PROFILE_HASH_SIZE (1 << FTRACE_PROFILE_HASH_BITS) | 533 | #define FTRACE_PROFILE_HASH_SIZE (1 << FTRACE_PROFILE_HASH_BITS) |
534 | 534 | ||
535 | static void * | 535 | static void * |
536 | function_stat_next(void *v, int idx) | 536 | function_stat_next(void *v, int idx) |
537 | { | 537 | { |
538 | struct ftrace_profile *rec = v; | 538 | struct ftrace_profile *rec = v; |
539 | struct ftrace_profile_page *pg; | 539 | struct ftrace_profile_page *pg; |
540 | 540 | ||
541 | pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK); | 541 | pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK); |
542 | 542 | ||
543 | again: | 543 | again: |
544 | if (idx != 0) | 544 | if (idx != 0) |
545 | rec++; | 545 | rec++; |
546 | 546 | ||
547 | if ((void *)rec >= (void *)&pg->records[pg->index]) { | 547 | if ((void *)rec >= (void *)&pg->records[pg->index]) { |
548 | pg = pg->next; | 548 | pg = pg->next; |
549 | if (!pg) | 549 | if (!pg) |
550 | return NULL; | 550 | return NULL; |
551 | rec = &pg->records[0]; | 551 | rec = &pg->records[0]; |
552 | if (!rec->counter) | 552 | if (!rec->counter) |
553 | goto again; | 553 | goto again; |
554 | } | 554 | } |
555 | 555 | ||
556 | return rec; | 556 | return rec; |
557 | } | 557 | } |
558 | 558 | ||
559 | static void *function_stat_start(struct tracer_stat *trace) | 559 | static void *function_stat_start(struct tracer_stat *trace) |
560 | { | 560 | { |
561 | struct ftrace_profile_stat *stat = | 561 | struct ftrace_profile_stat *stat = |
562 | container_of(trace, struct ftrace_profile_stat, stat); | 562 | container_of(trace, struct ftrace_profile_stat, stat); |
563 | 563 | ||
564 | if (!stat || !stat->start) | 564 | if (!stat || !stat->start) |
565 | return NULL; | 565 | return NULL; |
566 | 566 | ||
567 | return function_stat_next(&stat->start->records[0], 0); | 567 | return function_stat_next(&stat->start->records[0], 0); |
568 | } | 568 | } |
569 | 569 | ||
570 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 570 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
571 | /* function graph compares on total time */ | 571 | /* function graph compares on total time */ |
572 | static int function_stat_cmp(void *p1, void *p2) | 572 | static int function_stat_cmp(void *p1, void *p2) |
573 | { | 573 | { |
574 | struct ftrace_profile *a = p1; | 574 | struct ftrace_profile *a = p1; |
575 | struct ftrace_profile *b = p2; | 575 | struct ftrace_profile *b = p2; |
576 | 576 | ||
577 | if (a->time < b->time) | 577 | if (a->time < b->time) |
578 | return -1; | 578 | return -1; |
579 | if (a->time > b->time) | 579 | if (a->time > b->time) |
580 | return 1; | 580 | return 1; |
581 | else | 581 | else |
582 | return 0; | 582 | return 0; |
583 | } | 583 | } |
584 | #else | 584 | #else |
585 | /* not function graph compares against hits */ | 585 | /* not function graph compares against hits */ |
586 | static int function_stat_cmp(void *p1, void *p2) | 586 | static int function_stat_cmp(void *p1, void *p2) |
587 | { | 587 | { |
588 | struct ftrace_profile *a = p1; | 588 | struct ftrace_profile *a = p1; |
589 | struct ftrace_profile *b = p2; | 589 | struct ftrace_profile *b = p2; |
590 | 590 | ||
591 | if (a->counter < b->counter) | 591 | if (a->counter < b->counter) |
592 | return -1; | 592 | return -1; |
593 | if (a->counter > b->counter) | 593 | if (a->counter > b->counter) |
594 | return 1; | 594 | return 1; |
595 | else | 595 | else |
596 | return 0; | 596 | return 0; |
597 | } | 597 | } |
598 | #endif | 598 | #endif |
599 | 599 | ||
600 | static int function_stat_headers(struct seq_file *m) | 600 | static int function_stat_headers(struct seq_file *m) |
601 | { | 601 | { |
602 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 602 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
603 | seq_printf(m, " Function " | 603 | seq_printf(m, " Function " |
604 | "Hit Time Avg s^2\n" | 604 | "Hit Time Avg s^2\n" |
605 | " -------- " | 605 | " -------- " |
606 | "--- ---- --- ---\n"); | 606 | "--- ---- --- ---\n"); |
607 | #else | 607 | #else |
608 | seq_printf(m, " Function Hit\n" | 608 | seq_printf(m, " Function Hit\n" |
609 | " -------- ---\n"); | 609 | " -------- ---\n"); |
610 | #endif | 610 | #endif |
611 | return 0; | 611 | return 0; |
612 | } | 612 | } |
613 | 613 | ||
614 | static int function_stat_show(struct seq_file *m, void *v) | 614 | static int function_stat_show(struct seq_file *m, void *v) |
615 | { | 615 | { |
616 | struct ftrace_profile *rec = v; | 616 | struct ftrace_profile *rec = v; |
617 | char str[KSYM_SYMBOL_LEN]; | 617 | char str[KSYM_SYMBOL_LEN]; |
618 | int ret = 0; | 618 | int ret = 0; |
619 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 619 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
620 | static struct trace_seq s; | 620 | static struct trace_seq s; |
621 | unsigned long long avg; | 621 | unsigned long long avg; |
622 | unsigned long long stddev; | 622 | unsigned long long stddev; |
623 | #endif | 623 | #endif |
624 | mutex_lock(&ftrace_profile_lock); | 624 | mutex_lock(&ftrace_profile_lock); |
625 | 625 | ||
626 | /* we raced with function_profile_reset() */ | 626 | /* we raced with function_profile_reset() */ |
627 | if (unlikely(rec->counter == 0)) { | 627 | if (unlikely(rec->counter == 0)) { |
628 | ret = -EBUSY; | 628 | ret = -EBUSY; |
629 | goto out; | 629 | goto out; |
630 | } | 630 | } |
631 | 631 | ||
632 | kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); | 632 | kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); |
633 | seq_printf(m, " %-30.30s %10lu", str, rec->counter); | 633 | seq_printf(m, " %-30.30s %10lu", str, rec->counter); |
634 | 634 | ||
635 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 635 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
636 | seq_printf(m, " "); | 636 | seq_printf(m, " "); |
637 | avg = rec->time; | 637 | avg = rec->time; |
638 | do_div(avg, rec->counter); | 638 | do_div(avg, rec->counter); |
639 | 639 | ||
640 | /* Sample standard deviation (s^2) */ | 640 | /* Sample standard deviation (s^2) */ |
641 | if (rec->counter <= 1) | 641 | if (rec->counter <= 1) |
642 | stddev = 0; | 642 | stddev = 0; |
643 | else { | 643 | else { |
644 | /* | 644 | /* |
645 | * Apply Welford's method: | 645 | * Apply Welford's method: |
646 | * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) | 646 | * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) |
647 | */ | 647 | */ |
648 | stddev = rec->counter * rec->time_squared - | 648 | stddev = rec->counter * rec->time_squared - |
649 | rec->time * rec->time; | 649 | rec->time * rec->time; |
650 | 650 | ||
651 | /* | 651 | /* |
652 | * Divide only 1000 for ns^2 -> us^2 conversion. | 652 | * Divide only 1000 for ns^2 -> us^2 conversion. |
653 | * trace_print_graph_duration will divide 1000 again. | 653 | * trace_print_graph_duration will divide 1000 again. |
654 | */ | 654 | */ |
655 | do_div(stddev, rec->counter * (rec->counter - 1) * 1000); | 655 | do_div(stddev, rec->counter * (rec->counter - 1) * 1000); |
656 | } | 656 | } |
657 | 657 | ||
658 | trace_seq_init(&s); | 658 | trace_seq_init(&s); |
659 | trace_print_graph_duration(rec->time, &s); | 659 | trace_print_graph_duration(rec->time, &s); |
660 | trace_seq_puts(&s, " "); | 660 | trace_seq_puts(&s, " "); |
661 | trace_print_graph_duration(avg, &s); | 661 | trace_print_graph_duration(avg, &s); |
662 | trace_seq_puts(&s, " "); | 662 | trace_seq_puts(&s, " "); |
663 | trace_print_graph_duration(stddev, &s); | 663 | trace_print_graph_duration(stddev, &s); |
664 | trace_print_seq(m, &s); | 664 | trace_print_seq(m, &s); |
665 | #endif | 665 | #endif |
666 | seq_putc(m, '\n'); | 666 | seq_putc(m, '\n'); |
667 | out: | 667 | out: |
668 | mutex_unlock(&ftrace_profile_lock); | 668 | mutex_unlock(&ftrace_profile_lock); |
669 | 669 | ||
670 | return ret; | 670 | return ret; |
671 | } | 671 | } |
672 | 672 | ||
673 | static void ftrace_profile_reset(struct ftrace_profile_stat *stat) | 673 | static void ftrace_profile_reset(struct ftrace_profile_stat *stat) |
674 | { | 674 | { |
675 | struct ftrace_profile_page *pg; | 675 | struct ftrace_profile_page *pg; |
676 | 676 | ||
677 | pg = stat->pages = stat->start; | 677 | pg = stat->pages = stat->start; |
678 | 678 | ||
679 | while (pg) { | 679 | while (pg) { |
680 | memset(pg->records, 0, PROFILE_RECORDS_SIZE); | 680 | memset(pg->records, 0, PROFILE_RECORDS_SIZE); |
681 | pg->index = 0; | 681 | pg->index = 0; |
682 | pg = pg->next; | 682 | pg = pg->next; |
683 | } | 683 | } |
684 | 684 | ||
685 | memset(stat->hash, 0, | 685 | memset(stat->hash, 0, |
686 | FTRACE_PROFILE_HASH_SIZE * sizeof(struct hlist_head)); | 686 | FTRACE_PROFILE_HASH_SIZE * sizeof(struct hlist_head)); |
687 | } | 687 | } |
688 | 688 | ||
689 | int ftrace_profile_pages_init(struct ftrace_profile_stat *stat) | 689 | int ftrace_profile_pages_init(struct ftrace_profile_stat *stat) |
690 | { | 690 | { |
691 | struct ftrace_profile_page *pg; | 691 | struct ftrace_profile_page *pg; |
692 | int functions; | 692 | int functions; |
693 | int pages; | 693 | int pages; |
694 | int i; | 694 | int i; |
695 | 695 | ||
696 | /* If we already allocated, do nothing */ | 696 | /* If we already allocated, do nothing */ |
697 | if (stat->pages) | 697 | if (stat->pages) |
698 | return 0; | 698 | return 0; |
699 | 699 | ||
700 | stat->pages = (void *)get_zeroed_page(GFP_KERNEL); | 700 | stat->pages = (void *)get_zeroed_page(GFP_KERNEL); |
701 | if (!stat->pages) | 701 | if (!stat->pages) |
702 | return -ENOMEM; | 702 | return -ENOMEM; |
703 | 703 | ||
704 | #ifdef CONFIG_DYNAMIC_FTRACE | 704 | #ifdef CONFIG_DYNAMIC_FTRACE |
705 | functions = ftrace_update_tot_cnt; | 705 | functions = ftrace_update_tot_cnt; |
706 | #else | 706 | #else |
707 | /* | 707 | /* |
708 | * We do not know the number of functions that exist because | 708 | * We do not know the number of functions that exist because |
709 | * dynamic tracing is what counts them. With past experience | 709 | * dynamic tracing is what counts them. With past experience |
710 | * we have around 20K functions. That should be more than enough. | 710 | * we have around 20K functions. That should be more than enough. |
711 | * It is highly unlikely we will execute every function in | 711 | * It is highly unlikely we will execute every function in |
712 | * the kernel. | 712 | * the kernel. |
713 | */ | 713 | */ |
714 | functions = 20000; | 714 | functions = 20000; |
715 | #endif | 715 | #endif |
716 | 716 | ||
717 | pg = stat->start = stat->pages; | 717 | pg = stat->start = stat->pages; |
718 | 718 | ||
719 | pages = DIV_ROUND_UP(functions, PROFILES_PER_PAGE); | 719 | pages = DIV_ROUND_UP(functions, PROFILES_PER_PAGE); |
720 | 720 | ||
721 | for (i = 1; i < pages; i++) { | 721 | for (i = 1; i < pages; i++) { |
722 | pg->next = (void *)get_zeroed_page(GFP_KERNEL); | 722 | pg->next = (void *)get_zeroed_page(GFP_KERNEL); |
723 | if (!pg->next) | 723 | if (!pg->next) |
724 | goto out_free; | 724 | goto out_free; |
725 | pg = pg->next; | 725 | pg = pg->next; |
726 | } | 726 | } |
727 | 727 | ||
728 | return 0; | 728 | return 0; |
729 | 729 | ||
730 | out_free: | 730 | out_free: |
731 | pg = stat->start; | 731 | pg = stat->start; |
732 | while (pg) { | 732 | while (pg) { |
733 | unsigned long tmp = (unsigned long)pg; | 733 | unsigned long tmp = (unsigned long)pg; |
734 | 734 | ||
735 | pg = pg->next; | 735 | pg = pg->next; |
736 | free_page(tmp); | 736 | free_page(tmp); |
737 | } | 737 | } |
738 | 738 | ||
739 | stat->pages = NULL; | 739 | stat->pages = NULL; |
740 | stat->start = NULL; | 740 | stat->start = NULL; |
741 | 741 | ||
742 | return -ENOMEM; | 742 | return -ENOMEM; |
743 | } | 743 | } |
744 | 744 | ||
745 | static int ftrace_profile_init_cpu(int cpu) | 745 | static int ftrace_profile_init_cpu(int cpu) |
746 | { | 746 | { |
747 | struct ftrace_profile_stat *stat; | 747 | struct ftrace_profile_stat *stat; |
748 | int size; | 748 | int size; |
749 | 749 | ||
750 | stat = &per_cpu(ftrace_profile_stats, cpu); | 750 | stat = &per_cpu(ftrace_profile_stats, cpu); |
751 | 751 | ||
752 | if (stat->hash) { | 752 | if (stat->hash) { |
753 | /* If the profile is already created, simply reset it */ | 753 | /* If the profile is already created, simply reset it */ |
754 | ftrace_profile_reset(stat); | 754 | ftrace_profile_reset(stat); |
755 | return 0; | 755 | return 0; |
756 | } | 756 | } |
757 | 757 | ||
758 | /* | 758 | /* |
759 | * We are profiling all functions, but usually only a few thousand | 759 | * We are profiling all functions, but usually only a few thousand |
760 | * functions are hit. We'll make a hash of 1024 items. | 760 | * functions are hit. We'll make a hash of 1024 items. |
761 | */ | 761 | */ |
762 | size = FTRACE_PROFILE_HASH_SIZE; | 762 | size = FTRACE_PROFILE_HASH_SIZE; |
763 | 763 | ||
764 | stat->hash = kzalloc(sizeof(struct hlist_head) * size, GFP_KERNEL); | 764 | stat->hash = kzalloc(sizeof(struct hlist_head) * size, GFP_KERNEL); |
765 | 765 | ||
766 | if (!stat->hash) | 766 | if (!stat->hash) |
767 | return -ENOMEM; | 767 | return -ENOMEM; |
768 | 768 | ||
769 | /* Preallocate the function profiling pages */ | 769 | /* Preallocate the function profiling pages */ |
770 | if (ftrace_profile_pages_init(stat) < 0) { | 770 | if (ftrace_profile_pages_init(stat) < 0) { |
771 | kfree(stat->hash); | 771 | kfree(stat->hash); |
772 | stat->hash = NULL; | 772 | stat->hash = NULL; |
773 | return -ENOMEM; | 773 | return -ENOMEM; |
774 | } | 774 | } |
775 | 775 | ||
776 | return 0; | 776 | return 0; |
777 | } | 777 | } |
778 | 778 | ||
779 | static int ftrace_profile_init(void) | 779 | static int ftrace_profile_init(void) |
780 | { | 780 | { |
781 | int cpu; | 781 | int cpu; |
782 | int ret = 0; | 782 | int ret = 0; |
783 | 783 | ||
784 | for_each_online_cpu(cpu) { | 784 | for_each_online_cpu(cpu) { |
785 | ret = ftrace_profile_init_cpu(cpu); | 785 | ret = ftrace_profile_init_cpu(cpu); |
786 | if (ret) | 786 | if (ret) |
787 | break; | 787 | break; |
788 | } | 788 | } |
789 | 789 | ||
790 | return ret; | 790 | return ret; |
791 | } | 791 | } |
792 | 792 | ||
793 | /* interrupts must be disabled */ | 793 | /* interrupts must be disabled */ |
794 | static struct ftrace_profile * | 794 | static struct ftrace_profile * |
795 | ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip) | 795 | ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip) |
796 | { | 796 | { |
797 | struct ftrace_profile *rec; | 797 | struct ftrace_profile *rec; |
798 | struct hlist_head *hhd; | 798 | struct hlist_head *hhd; |
799 | unsigned long key; | 799 | unsigned long key; |
800 | 800 | ||
801 | key = hash_long(ip, FTRACE_PROFILE_HASH_BITS); | 801 | key = hash_long(ip, FTRACE_PROFILE_HASH_BITS); |
802 | hhd = &stat->hash[key]; | 802 | hhd = &stat->hash[key]; |
803 | 803 | ||
804 | if (hlist_empty(hhd)) | 804 | if (hlist_empty(hhd)) |
805 | return NULL; | 805 | return NULL; |
806 | 806 | ||
807 | hlist_for_each_entry_rcu_notrace(rec, hhd, node) { | 807 | hlist_for_each_entry_rcu_notrace(rec, hhd, node) { |
808 | if (rec->ip == ip) | 808 | if (rec->ip == ip) |
809 | return rec; | 809 | return rec; |
810 | } | 810 | } |
811 | 811 | ||
812 | return NULL; | 812 | return NULL; |
813 | } | 813 | } |
814 | 814 | ||
815 | static void ftrace_add_profile(struct ftrace_profile_stat *stat, | 815 | static void ftrace_add_profile(struct ftrace_profile_stat *stat, |
816 | struct ftrace_profile *rec) | 816 | struct ftrace_profile *rec) |
817 | { | 817 | { |
818 | unsigned long key; | 818 | unsigned long key; |
819 | 819 | ||
820 | key = hash_long(rec->ip, FTRACE_PROFILE_HASH_BITS); | 820 | key = hash_long(rec->ip, FTRACE_PROFILE_HASH_BITS); |
821 | hlist_add_head_rcu(&rec->node, &stat->hash[key]); | 821 | hlist_add_head_rcu(&rec->node, &stat->hash[key]); |
822 | } | 822 | } |
823 | 823 | ||
824 | /* | 824 | /* |
825 | * The memory is already allocated, this simply finds a new record to use. | 825 | * The memory is already allocated, this simply finds a new record to use. |
826 | */ | 826 | */ |
827 | static struct ftrace_profile * | 827 | static struct ftrace_profile * |
828 | ftrace_profile_alloc(struct ftrace_profile_stat *stat, unsigned long ip) | 828 | ftrace_profile_alloc(struct ftrace_profile_stat *stat, unsigned long ip) |
829 | { | 829 | { |
830 | struct ftrace_profile *rec = NULL; | 830 | struct ftrace_profile *rec = NULL; |
831 | 831 | ||
832 | /* prevent recursion (from NMIs) */ | 832 | /* prevent recursion (from NMIs) */ |
833 | if (atomic_inc_return(&stat->disabled) != 1) | 833 | if (atomic_inc_return(&stat->disabled) != 1) |
834 | goto out; | 834 | goto out; |
835 | 835 | ||
836 | /* | 836 | /* |
837 | * Try to find the function again since an NMI | 837 | * Try to find the function again since an NMI |
838 | * could have added it | 838 | * could have added it |
839 | */ | 839 | */ |
840 | rec = ftrace_find_profiled_func(stat, ip); | 840 | rec = ftrace_find_profiled_func(stat, ip); |
841 | if (rec) | 841 | if (rec) |
842 | goto out; | 842 | goto out; |
843 | 843 | ||
844 | if (stat->pages->index == PROFILES_PER_PAGE) { | 844 | if (stat->pages->index == PROFILES_PER_PAGE) { |
845 | if (!stat->pages->next) | 845 | if (!stat->pages->next) |
846 | goto out; | 846 | goto out; |
847 | stat->pages = stat->pages->next; | 847 | stat->pages = stat->pages->next; |
848 | } | 848 | } |
849 | 849 | ||
850 | rec = &stat->pages->records[stat->pages->index++]; | 850 | rec = &stat->pages->records[stat->pages->index++]; |
851 | rec->ip = ip; | 851 | rec->ip = ip; |
852 | ftrace_add_profile(stat, rec); | 852 | ftrace_add_profile(stat, rec); |
853 | 853 | ||
854 | out: | 854 | out: |
855 | atomic_dec(&stat->disabled); | 855 | atomic_dec(&stat->disabled); |
856 | 856 | ||
857 | return rec; | 857 | return rec; |
858 | } | 858 | } |
859 | 859 | ||
860 | static void | 860 | static void |
861 | function_profile_call(unsigned long ip, unsigned long parent_ip, | 861 | function_profile_call(unsigned long ip, unsigned long parent_ip, |
862 | struct ftrace_ops *ops, struct pt_regs *regs) | 862 | struct ftrace_ops *ops, struct pt_regs *regs) |
863 | { | 863 | { |
864 | struct ftrace_profile_stat *stat; | 864 | struct ftrace_profile_stat *stat; |
865 | struct ftrace_profile *rec; | 865 | struct ftrace_profile *rec; |
866 | unsigned long flags; | 866 | unsigned long flags; |
867 | 867 | ||
868 | if (!ftrace_profile_enabled) | 868 | if (!ftrace_profile_enabled) |
869 | return; | 869 | return; |
870 | 870 | ||
871 | local_irq_save(flags); | 871 | local_irq_save(flags); |
872 | 872 | ||
873 | stat = &__get_cpu_var(ftrace_profile_stats); | 873 | stat = &__get_cpu_var(ftrace_profile_stats); |
874 | if (!stat->hash || !ftrace_profile_enabled) | 874 | if (!stat->hash || !ftrace_profile_enabled) |
875 | goto out; | 875 | goto out; |
876 | 876 | ||
877 | rec = ftrace_find_profiled_func(stat, ip); | 877 | rec = ftrace_find_profiled_func(stat, ip); |
878 | if (!rec) { | 878 | if (!rec) { |
879 | rec = ftrace_profile_alloc(stat, ip); | 879 | rec = ftrace_profile_alloc(stat, ip); |
880 | if (!rec) | 880 | if (!rec) |
881 | goto out; | 881 | goto out; |
882 | } | 882 | } |
883 | 883 | ||
884 | rec->counter++; | 884 | rec->counter++; |
885 | out: | 885 | out: |
886 | local_irq_restore(flags); | 886 | local_irq_restore(flags); |
887 | } | 887 | } |
888 | 888 | ||
889 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 889 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
890 | static int profile_graph_entry(struct ftrace_graph_ent *trace) | 890 | static int profile_graph_entry(struct ftrace_graph_ent *trace) |
891 | { | 891 | { |
892 | function_profile_call(trace->func, 0, NULL, NULL); | 892 | function_profile_call(trace->func, 0, NULL, NULL); |
893 | return 1; | 893 | return 1; |
894 | } | 894 | } |
895 | 895 | ||
896 | static void profile_graph_return(struct ftrace_graph_ret *trace) | 896 | static void profile_graph_return(struct ftrace_graph_ret *trace) |
897 | { | 897 | { |
898 | struct ftrace_profile_stat *stat; | 898 | struct ftrace_profile_stat *stat; |
899 | unsigned long long calltime; | 899 | unsigned long long calltime; |
900 | struct ftrace_profile *rec; | 900 | struct ftrace_profile *rec; |
901 | unsigned long flags; | 901 | unsigned long flags; |
902 | 902 | ||
903 | local_irq_save(flags); | 903 | local_irq_save(flags); |
904 | stat = &__get_cpu_var(ftrace_profile_stats); | 904 | stat = &__get_cpu_var(ftrace_profile_stats); |
905 | if (!stat->hash || !ftrace_profile_enabled) | 905 | if (!stat->hash || !ftrace_profile_enabled) |
906 | goto out; | 906 | goto out; |
907 | 907 | ||
908 | /* If the calltime was zero'd ignore it */ | 908 | /* If the calltime was zero'd ignore it */ |
909 | if (!trace->calltime) | 909 | if (!trace->calltime) |
910 | goto out; | 910 | goto out; |
911 | 911 | ||
912 | calltime = trace->rettime - trace->calltime; | 912 | calltime = trace->rettime - trace->calltime; |
913 | 913 | ||
914 | if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) { | 914 | if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) { |
915 | int index; | 915 | int index; |
916 | 916 | ||
917 | index = trace->depth; | 917 | index = trace->depth; |
918 | 918 | ||
919 | /* Append this call time to the parent time to subtract */ | 919 | /* Append this call time to the parent time to subtract */ |
920 | if (index) | 920 | if (index) |
921 | current->ret_stack[index - 1].subtime += calltime; | 921 | current->ret_stack[index - 1].subtime += calltime; |
922 | 922 | ||
923 | if (current->ret_stack[index].subtime < calltime) | 923 | if (current->ret_stack[index].subtime < calltime) |
924 | calltime -= current->ret_stack[index].subtime; | 924 | calltime -= current->ret_stack[index].subtime; |
925 | else | 925 | else |
926 | calltime = 0; | 926 | calltime = 0; |
927 | } | 927 | } |
928 | 928 | ||
929 | rec = ftrace_find_profiled_func(stat, trace->func); | 929 | rec = ftrace_find_profiled_func(stat, trace->func); |
930 | if (rec) { | 930 | if (rec) { |
931 | rec->time += calltime; | 931 | rec->time += calltime; |
932 | rec->time_squared += calltime * calltime; | 932 | rec->time_squared += calltime * calltime; |
933 | } | 933 | } |
934 | 934 | ||
935 | out: | 935 | out: |
936 | local_irq_restore(flags); | 936 | local_irq_restore(flags); |
937 | } | 937 | } |
938 | 938 | ||
939 | static int register_ftrace_profiler(void) | 939 | static int register_ftrace_profiler(void) |
940 | { | 940 | { |
941 | return register_ftrace_graph(&profile_graph_return, | 941 | return register_ftrace_graph(&profile_graph_return, |
942 | &profile_graph_entry); | 942 | &profile_graph_entry); |
943 | } | 943 | } |
944 | 944 | ||
945 | static void unregister_ftrace_profiler(void) | 945 | static void unregister_ftrace_profiler(void) |
946 | { | 946 | { |
947 | unregister_ftrace_graph(); | 947 | unregister_ftrace_graph(); |
948 | } | 948 | } |
949 | #else | 949 | #else |
950 | static struct ftrace_ops ftrace_profile_ops __read_mostly = { | 950 | static struct ftrace_ops ftrace_profile_ops __read_mostly = { |
951 | .func = function_profile_call, | 951 | .func = function_profile_call, |
952 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, | 952 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, |
953 | INIT_REGEX_LOCK(ftrace_profile_ops) | 953 | INIT_REGEX_LOCK(ftrace_profile_ops) |
954 | }; | 954 | }; |
955 | 955 | ||
956 | static int register_ftrace_profiler(void) | 956 | static int register_ftrace_profiler(void) |
957 | { | 957 | { |
958 | return register_ftrace_function(&ftrace_profile_ops); | 958 | return register_ftrace_function(&ftrace_profile_ops); |
959 | } | 959 | } |
960 | 960 | ||
961 | static void unregister_ftrace_profiler(void) | 961 | static void unregister_ftrace_profiler(void) |
962 | { | 962 | { |
963 | unregister_ftrace_function(&ftrace_profile_ops); | 963 | unregister_ftrace_function(&ftrace_profile_ops); |
964 | } | 964 | } |
965 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 965 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
966 | 966 | ||
967 | static ssize_t | 967 | static ssize_t |
968 | ftrace_profile_write(struct file *filp, const char __user *ubuf, | 968 | ftrace_profile_write(struct file *filp, const char __user *ubuf, |
969 | size_t cnt, loff_t *ppos) | 969 | size_t cnt, loff_t *ppos) |
970 | { | 970 | { |
971 | unsigned long val; | 971 | unsigned long val; |
972 | int ret; | 972 | int ret; |
973 | 973 | ||
974 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 974 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
975 | if (ret) | 975 | if (ret) |
976 | return ret; | 976 | return ret; |
977 | 977 | ||
978 | val = !!val; | 978 | val = !!val; |
979 | 979 | ||
980 | mutex_lock(&ftrace_profile_lock); | 980 | mutex_lock(&ftrace_profile_lock); |
981 | if (ftrace_profile_enabled ^ val) { | 981 | if (ftrace_profile_enabled ^ val) { |
982 | if (val) { | 982 | if (val) { |
983 | ret = ftrace_profile_init(); | 983 | ret = ftrace_profile_init(); |
984 | if (ret < 0) { | 984 | if (ret < 0) { |
985 | cnt = ret; | 985 | cnt = ret; |
986 | goto out; | 986 | goto out; |
987 | } | 987 | } |
988 | 988 | ||
989 | ret = register_ftrace_profiler(); | 989 | ret = register_ftrace_profiler(); |
990 | if (ret < 0) { | 990 | if (ret < 0) { |
991 | cnt = ret; | 991 | cnt = ret; |
992 | goto out; | 992 | goto out; |
993 | } | 993 | } |
994 | ftrace_profile_enabled = 1; | 994 | ftrace_profile_enabled = 1; |
995 | } else { | 995 | } else { |
996 | ftrace_profile_enabled = 0; | 996 | ftrace_profile_enabled = 0; |
997 | /* | 997 | /* |
998 | * unregister_ftrace_profiler calls stop_machine | 998 | * unregister_ftrace_profiler calls stop_machine |
999 | * so this acts like an synchronize_sched. | 999 | * so this acts like an synchronize_sched. |
1000 | */ | 1000 | */ |
1001 | unregister_ftrace_profiler(); | 1001 | unregister_ftrace_profiler(); |
1002 | } | 1002 | } |
1003 | } | 1003 | } |
1004 | out: | 1004 | out: |
1005 | mutex_unlock(&ftrace_profile_lock); | 1005 | mutex_unlock(&ftrace_profile_lock); |
1006 | 1006 | ||
1007 | *ppos += cnt; | 1007 | *ppos += cnt; |
1008 | 1008 | ||
1009 | return cnt; | 1009 | return cnt; |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | static ssize_t | 1012 | static ssize_t |
1013 | ftrace_profile_read(struct file *filp, char __user *ubuf, | 1013 | ftrace_profile_read(struct file *filp, char __user *ubuf, |
1014 | size_t cnt, loff_t *ppos) | 1014 | size_t cnt, loff_t *ppos) |
1015 | { | 1015 | { |
1016 | char buf[64]; /* big enough to hold a number */ | 1016 | char buf[64]; /* big enough to hold a number */ |
1017 | int r; | 1017 | int r; |
1018 | 1018 | ||
1019 | r = sprintf(buf, "%u\n", ftrace_profile_enabled); | 1019 | r = sprintf(buf, "%u\n", ftrace_profile_enabled); |
1020 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 1020 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | static const struct file_operations ftrace_profile_fops = { | 1023 | static const struct file_operations ftrace_profile_fops = { |
1024 | .open = tracing_open_generic, | 1024 | .open = tracing_open_generic, |
1025 | .read = ftrace_profile_read, | 1025 | .read = ftrace_profile_read, |
1026 | .write = ftrace_profile_write, | 1026 | .write = ftrace_profile_write, |
1027 | .llseek = default_llseek, | 1027 | .llseek = default_llseek, |
1028 | }; | 1028 | }; |
1029 | 1029 | ||
1030 | /* used to initialize the real stat files */ | 1030 | /* used to initialize the real stat files */ |
1031 | static struct tracer_stat function_stats __initdata = { | 1031 | static struct tracer_stat function_stats __initdata = { |
1032 | .name = "functions", | 1032 | .name = "functions", |
1033 | .stat_start = function_stat_start, | 1033 | .stat_start = function_stat_start, |
1034 | .stat_next = function_stat_next, | 1034 | .stat_next = function_stat_next, |
1035 | .stat_cmp = function_stat_cmp, | 1035 | .stat_cmp = function_stat_cmp, |
1036 | .stat_headers = function_stat_headers, | 1036 | .stat_headers = function_stat_headers, |
1037 | .stat_show = function_stat_show | 1037 | .stat_show = function_stat_show |
1038 | }; | 1038 | }; |
1039 | 1039 | ||
1040 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) | 1040 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) |
1041 | { | 1041 | { |
1042 | struct ftrace_profile_stat *stat; | 1042 | struct ftrace_profile_stat *stat; |
1043 | struct dentry *entry; | 1043 | struct dentry *entry; |
1044 | char *name; | 1044 | char *name; |
1045 | int ret; | 1045 | int ret; |
1046 | int cpu; | 1046 | int cpu; |
1047 | 1047 | ||
1048 | for_each_possible_cpu(cpu) { | 1048 | for_each_possible_cpu(cpu) { |
1049 | stat = &per_cpu(ftrace_profile_stats, cpu); | 1049 | stat = &per_cpu(ftrace_profile_stats, cpu); |
1050 | 1050 | ||
1051 | /* allocate enough for function name + cpu number */ | 1051 | /* allocate enough for function name + cpu number */ |
1052 | name = kmalloc(32, GFP_KERNEL); | 1052 | name = kmalloc(32, GFP_KERNEL); |
1053 | if (!name) { | 1053 | if (!name) { |
1054 | /* | 1054 | /* |
1055 | * The files created are permanent, if something happens | 1055 | * The files created are permanent, if something happens |
1056 | * we still do not free memory. | 1056 | * we still do not free memory. |
1057 | */ | 1057 | */ |
1058 | WARN(1, | 1058 | WARN(1, |
1059 | "Could not allocate stat file for cpu %d\n", | 1059 | "Could not allocate stat file for cpu %d\n", |
1060 | cpu); | 1060 | cpu); |
1061 | return; | 1061 | return; |
1062 | } | 1062 | } |
1063 | stat->stat = function_stats; | 1063 | stat->stat = function_stats; |
1064 | snprintf(name, 32, "function%d", cpu); | 1064 | snprintf(name, 32, "function%d", cpu); |
1065 | stat->stat.name = name; | 1065 | stat->stat.name = name; |
1066 | ret = register_stat_tracer(&stat->stat); | 1066 | ret = register_stat_tracer(&stat->stat); |
1067 | if (ret) { | 1067 | if (ret) { |
1068 | WARN(1, | 1068 | WARN(1, |
1069 | "Could not register function stat for cpu %d\n", | 1069 | "Could not register function stat for cpu %d\n", |
1070 | cpu); | 1070 | cpu); |
1071 | kfree(name); | 1071 | kfree(name); |
1072 | return; | 1072 | return; |
1073 | } | 1073 | } |
1074 | } | 1074 | } |
1075 | 1075 | ||
1076 | entry = debugfs_create_file("function_profile_enabled", 0644, | 1076 | entry = debugfs_create_file("function_profile_enabled", 0644, |
1077 | d_tracer, NULL, &ftrace_profile_fops); | 1077 | d_tracer, NULL, &ftrace_profile_fops); |
1078 | if (!entry) | 1078 | if (!entry) |
1079 | pr_warning("Could not create debugfs " | 1079 | pr_warning("Could not create debugfs " |
1080 | "'function_profile_enabled' entry\n"); | 1080 | "'function_profile_enabled' entry\n"); |
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | #else /* CONFIG_FUNCTION_PROFILER */ | 1083 | #else /* CONFIG_FUNCTION_PROFILER */ |
1084 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) | 1084 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) |
1085 | { | 1085 | { |
1086 | } | 1086 | } |
1087 | #endif /* CONFIG_FUNCTION_PROFILER */ | 1087 | #endif /* CONFIG_FUNCTION_PROFILER */ |
1088 | 1088 | ||
1089 | static struct pid * const ftrace_swapper_pid = &init_struct_pid; | 1089 | static struct pid * const ftrace_swapper_pid = &init_struct_pid; |
1090 | 1090 | ||
1091 | loff_t | 1091 | loff_t |
1092 | ftrace_filter_lseek(struct file *file, loff_t offset, int whence) | 1092 | ftrace_filter_lseek(struct file *file, loff_t offset, int whence) |
1093 | { | 1093 | { |
1094 | loff_t ret; | 1094 | loff_t ret; |
1095 | 1095 | ||
1096 | if (file->f_mode & FMODE_READ) | 1096 | if (file->f_mode & FMODE_READ) |
1097 | ret = seq_lseek(file, offset, whence); | 1097 | ret = seq_lseek(file, offset, whence); |
1098 | else | 1098 | else |
1099 | file->f_pos = ret = 1; | 1099 | file->f_pos = ret = 1; |
1100 | 1100 | ||
1101 | return ret; | 1101 | return ret; |
1102 | } | 1102 | } |
1103 | 1103 | ||
1104 | #ifdef CONFIG_DYNAMIC_FTRACE | 1104 | #ifdef CONFIG_DYNAMIC_FTRACE |
1105 | 1105 | ||
1106 | #ifndef CONFIG_FTRACE_MCOUNT_RECORD | 1106 | #ifndef CONFIG_FTRACE_MCOUNT_RECORD |
1107 | # error Dynamic ftrace depends on MCOUNT_RECORD | 1107 | # error Dynamic ftrace depends on MCOUNT_RECORD |
1108 | #endif | 1108 | #endif |
1109 | 1109 | ||
1110 | static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly; | 1110 | static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly; |
1111 | 1111 | ||
1112 | struct ftrace_func_probe { | 1112 | struct ftrace_func_probe { |
1113 | struct hlist_node node; | 1113 | struct hlist_node node; |
1114 | struct ftrace_probe_ops *ops; | 1114 | struct ftrace_probe_ops *ops; |
1115 | unsigned long flags; | 1115 | unsigned long flags; |
1116 | unsigned long ip; | 1116 | unsigned long ip; |
1117 | void *data; | 1117 | void *data; |
1118 | struct list_head free_list; | 1118 | struct list_head free_list; |
1119 | }; | 1119 | }; |
1120 | 1120 | ||
1121 | struct ftrace_func_entry { | 1121 | struct ftrace_func_entry { |
1122 | struct hlist_node hlist; | 1122 | struct hlist_node hlist; |
1123 | unsigned long ip; | 1123 | unsigned long ip; |
1124 | }; | 1124 | }; |
1125 | 1125 | ||
1126 | struct ftrace_hash { | 1126 | struct ftrace_hash { |
1127 | unsigned long size_bits; | 1127 | unsigned long size_bits; |
1128 | struct hlist_head *buckets; | 1128 | struct hlist_head *buckets; |
1129 | unsigned long count; | 1129 | unsigned long count; |
1130 | struct rcu_head rcu; | 1130 | struct rcu_head rcu; |
1131 | }; | 1131 | }; |
1132 | 1132 | ||
1133 | /* | 1133 | /* |
1134 | * We make these constant because no one should touch them, | 1134 | * We make these constant because no one should touch them, |
1135 | * but they are used as the default "empty hash", to avoid allocating | 1135 | * but they are used as the default "empty hash", to avoid allocating |
1136 | * it all the time. These are in a read only section such that if | 1136 | * it all the time. These are in a read only section such that if |
1137 | * anyone does try to modify it, it will cause an exception. | 1137 | * anyone does try to modify it, it will cause an exception. |
1138 | */ | 1138 | */ |
1139 | static const struct hlist_head empty_buckets[1]; | 1139 | static const struct hlist_head empty_buckets[1]; |
1140 | static const struct ftrace_hash empty_hash = { | 1140 | static const struct ftrace_hash empty_hash = { |
1141 | .buckets = (struct hlist_head *)empty_buckets, | 1141 | .buckets = (struct hlist_head *)empty_buckets, |
1142 | }; | 1142 | }; |
1143 | #define EMPTY_HASH ((struct ftrace_hash *)&empty_hash) | 1143 | #define EMPTY_HASH ((struct ftrace_hash *)&empty_hash) |
1144 | 1144 | ||
1145 | static struct ftrace_ops global_ops = { | 1145 | static struct ftrace_ops global_ops = { |
1146 | .func = ftrace_stub, | 1146 | .func = ftrace_stub, |
1147 | .notrace_hash = EMPTY_HASH, | 1147 | .notrace_hash = EMPTY_HASH, |
1148 | .filter_hash = EMPTY_HASH, | 1148 | .filter_hash = EMPTY_HASH, |
1149 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, | 1149 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, |
1150 | INIT_REGEX_LOCK(global_ops) | 1150 | INIT_REGEX_LOCK(global_ops) |
1151 | }; | 1151 | }; |
1152 | 1152 | ||
1153 | struct ftrace_page { | 1153 | struct ftrace_page { |
1154 | struct ftrace_page *next; | 1154 | struct ftrace_page *next; |
1155 | struct dyn_ftrace *records; | 1155 | struct dyn_ftrace *records; |
1156 | int index; | 1156 | int index; |
1157 | int size; | 1157 | int size; |
1158 | }; | 1158 | }; |
1159 | 1159 | ||
1160 | static struct ftrace_page *ftrace_new_pgs; | 1160 | static struct ftrace_page *ftrace_new_pgs; |
1161 | 1161 | ||
1162 | #define ENTRY_SIZE sizeof(struct dyn_ftrace) | 1162 | #define ENTRY_SIZE sizeof(struct dyn_ftrace) |
1163 | #define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE) | 1163 | #define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE) |
1164 | 1164 | ||
1165 | /* estimate from running different kernels */ | 1165 | /* estimate from running different kernels */ |
1166 | #define NR_TO_INIT 10000 | 1166 | #define NR_TO_INIT 10000 |
1167 | 1167 | ||
1168 | static struct ftrace_page *ftrace_pages_start; | 1168 | static struct ftrace_page *ftrace_pages_start; |
1169 | static struct ftrace_page *ftrace_pages; | 1169 | static struct ftrace_page *ftrace_pages; |
1170 | 1170 | ||
1171 | static bool ftrace_hash_empty(struct ftrace_hash *hash) | 1171 | static bool ftrace_hash_empty(struct ftrace_hash *hash) |
1172 | { | 1172 | { |
1173 | return !hash || !hash->count; | 1173 | return !hash || !hash->count; |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | static struct ftrace_func_entry * | 1176 | static struct ftrace_func_entry * |
1177 | ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) | 1177 | ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) |
1178 | { | 1178 | { |
1179 | unsigned long key; | 1179 | unsigned long key; |
1180 | struct ftrace_func_entry *entry; | 1180 | struct ftrace_func_entry *entry; |
1181 | struct hlist_head *hhd; | 1181 | struct hlist_head *hhd; |
1182 | 1182 | ||
1183 | if (ftrace_hash_empty(hash)) | 1183 | if (ftrace_hash_empty(hash)) |
1184 | return NULL; | 1184 | return NULL; |
1185 | 1185 | ||
1186 | if (hash->size_bits > 0) | 1186 | if (hash->size_bits > 0) |
1187 | key = hash_long(ip, hash->size_bits); | 1187 | key = hash_long(ip, hash->size_bits); |
1188 | else | 1188 | else |
1189 | key = 0; | 1189 | key = 0; |
1190 | 1190 | ||
1191 | hhd = &hash->buckets[key]; | 1191 | hhd = &hash->buckets[key]; |
1192 | 1192 | ||
1193 | hlist_for_each_entry_rcu_notrace(entry, hhd, hlist) { | 1193 | hlist_for_each_entry_rcu_notrace(entry, hhd, hlist) { |
1194 | if (entry->ip == ip) | 1194 | if (entry->ip == ip) |
1195 | return entry; | 1195 | return entry; |
1196 | } | 1196 | } |
1197 | return NULL; | 1197 | return NULL; |
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | static void __add_hash_entry(struct ftrace_hash *hash, | 1200 | static void __add_hash_entry(struct ftrace_hash *hash, |
1201 | struct ftrace_func_entry *entry) | 1201 | struct ftrace_func_entry *entry) |
1202 | { | 1202 | { |
1203 | struct hlist_head *hhd; | 1203 | struct hlist_head *hhd; |
1204 | unsigned long key; | 1204 | unsigned long key; |
1205 | 1205 | ||
1206 | if (hash->size_bits) | 1206 | if (hash->size_bits) |
1207 | key = hash_long(entry->ip, hash->size_bits); | 1207 | key = hash_long(entry->ip, hash->size_bits); |
1208 | else | 1208 | else |
1209 | key = 0; | 1209 | key = 0; |
1210 | 1210 | ||
1211 | hhd = &hash->buckets[key]; | 1211 | hhd = &hash->buckets[key]; |
1212 | hlist_add_head(&entry->hlist, hhd); | 1212 | hlist_add_head(&entry->hlist, hhd); |
1213 | hash->count++; | 1213 | hash->count++; |
1214 | } | 1214 | } |
1215 | 1215 | ||
1216 | static int add_hash_entry(struct ftrace_hash *hash, unsigned long ip) | 1216 | static int add_hash_entry(struct ftrace_hash *hash, unsigned long ip) |
1217 | { | 1217 | { |
1218 | struct ftrace_func_entry *entry; | 1218 | struct ftrace_func_entry *entry; |
1219 | 1219 | ||
1220 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | 1220 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
1221 | if (!entry) | 1221 | if (!entry) |
1222 | return -ENOMEM; | 1222 | return -ENOMEM; |
1223 | 1223 | ||
1224 | entry->ip = ip; | 1224 | entry->ip = ip; |
1225 | __add_hash_entry(hash, entry); | 1225 | __add_hash_entry(hash, entry); |
1226 | 1226 | ||
1227 | return 0; | 1227 | return 0; |
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | static void | 1230 | static void |
1231 | free_hash_entry(struct ftrace_hash *hash, | 1231 | free_hash_entry(struct ftrace_hash *hash, |
1232 | struct ftrace_func_entry *entry) | 1232 | struct ftrace_func_entry *entry) |
1233 | { | 1233 | { |
1234 | hlist_del(&entry->hlist); | 1234 | hlist_del(&entry->hlist); |
1235 | kfree(entry); | 1235 | kfree(entry); |
1236 | hash->count--; | 1236 | hash->count--; |
1237 | } | 1237 | } |
1238 | 1238 | ||
1239 | static void | 1239 | static void |
1240 | remove_hash_entry(struct ftrace_hash *hash, | 1240 | remove_hash_entry(struct ftrace_hash *hash, |
1241 | struct ftrace_func_entry *entry) | 1241 | struct ftrace_func_entry *entry) |
1242 | { | 1242 | { |
1243 | hlist_del(&entry->hlist); | 1243 | hlist_del(&entry->hlist); |
1244 | hash->count--; | 1244 | hash->count--; |
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | static void ftrace_hash_clear(struct ftrace_hash *hash) | 1247 | static void ftrace_hash_clear(struct ftrace_hash *hash) |
1248 | { | 1248 | { |
1249 | struct hlist_head *hhd; | 1249 | struct hlist_head *hhd; |
1250 | struct hlist_node *tn; | 1250 | struct hlist_node *tn; |
1251 | struct ftrace_func_entry *entry; | 1251 | struct ftrace_func_entry *entry; |
1252 | int size = 1 << hash->size_bits; | 1252 | int size = 1 << hash->size_bits; |
1253 | int i; | 1253 | int i; |
1254 | 1254 | ||
1255 | if (!hash->count) | 1255 | if (!hash->count) |
1256 | return; | 1256 | return; |
1257 | 1257 | ||
1258 | for (i = 0; i < size; i++) { | 1258 | for (i = 0; i < size; i++) { |
1259 | hhd = &hash->buckets[i]; | 1259 | hhd = &hash->buckets[i]; |
1260 | hlist_for_each_entry_safe(entry, tn, hhd, hlist) | 1260 | hlist_for_each_entry_safe(entry, tn, hhd, hlist) |
1261 | free_hash_entry(hash, entry); | 1261 | free_hash_entry(hash, entry); |
1262 | } | 1262 | } |
1263 | FTRACE_WARN_ON(hash->count); | 1263 | FTRACE_WARN_ON(hash->count); |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | static void free_ftrace_hash(struct ftrace_hash *hash) | 1266 | static void free_ftrace_hash(struct ftrace_hash *hash) |
1267 | { | 1267 | { |
1268 | if (!hash || hash == EMPTY_HASH) | 1268 | if (!hash || hash == EMPTY_HASH) |
1269 | return; | 1269 | return; |
1270 | ftrace_hash_clear(hash); | 1270 | ftrace_hash_clear(hash); |
1271 | kfree(hash->buckets); | 1271 | kfree(hash->buckets); |
1272 | kfree(hash); | 1272 | kfree(hash); |
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | static void __free_ftrace_hash_rcu(struct rcu_head *rcu) | 1275 | static void __free_ftrace_hash_rcu(struct rcu_head *rcu) |
1276 | { | 1276 | { |
1277 | struct ftrace_hash *hash; | 1277 | struct ftrace_hash *hash; |
1278 | 1278 | ||
1279 | hash = container_of(rcu, struct ftrace_hash, rcu); | 1279 | hash = container_of(rcu, struct ftrace_hash, rcu); |
1280 | free_ftrace_hash(hash); | 1280 | free_ftrace_hash(hash); |
1281 | } | 1281 | } |
1282 | 1282 | ||
1283 | static void free_ftrace_hash_rcu(struct ftrace_hash *hash) | 1283 | static void free_ftrace_hash_rcu(struct ftrace_hash *hash) |
1284 | { | 1284 | { |
1285 | if (!hash || hash == EMPTY_HASH) | 1285 | if (!hash || hash == EMPTY_HASH) |
1286 | return; | 1286 | return; |
1287 | call_rcu_sched(&hash->rcu, __free_ftrace_hash_rcu); | 1287 | call_rcu_sched(&hash->rcu, __free_ftrace_hash_rcu); |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | void ftrace_free_filter(struct ftrace_ops *ops) | 1290 | void ftrace_free_filter(struct ftrace_ops *ops) |
1291 | { | 1291 | { |
1292 | ftrace_ops_init(ops); | 1292 | ftrace_ops_init(ops); |
1293 | free_ftrace_hash(ops->filter_hash); | 1293 | free_ftrace_hash(ops->filter_hash); |
1294 | free_ftrace_hash(ops->notrace_hash); | 1294 | free_ftrace_hash(ops->notrace_hash); |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | static struct ftrace_hash *alloc_ftrace_hash(int size_bits) | 1297 | static struct ftrace_hash *alloc_ftrace_hash(int size_bits) |
1298 | { | 1298 | { |
1299 | struct ftrace_hash *hash; | 1299 | struct ftrace_hash *hash; |
1300 | int size; | 1300 | int size; |
1301 | 1301 | ||
1302 | hash = kzalloc(sizeof(*hash), GFP_KERNEL); | 1302 | hash = kzalloc(sizeof(*hash), GFP_KERNEL); |
1303 | if (!hash) | 1303 | if (!hash) |
1304 | return NULL; | 1304 | return NULL; |
1305 | 1305 | ||
1306 | size = 1 << size_bits; | 1306 | size = 1 << size_bits; |
1307 | hash->buckets = kcalloc(size, sizeof(*hash->buckets), GFP_KERNEL); | 1307 | hash->buckets = kcalloc(size, sizeof(*hash->buckets), GFP_KERNEL); |
1308 | 1308 | ||
1309 | if (!hash->buckets) { | 1309 | if (!hash->buckets) { |
1310 | kfree(hash); | 1310 | kfree(hash); |
1311 | return NULL; | 1311 | return NULL; |
1312 | } | 1312 | } |
1313 | 1313 | ||
1314 | hash->size_bits = size_bits; | 1314 | hash->size_bits = size_bits; |
1315 | 1315 | ||
1316 | return hash; | 1316 | return hash; |
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | static struct ftrace_hash * | 1319 | static struct ftrace_hash * |
1320 | alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash) | 1320 | alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash) |
1321 | { | 1321 | { |
1322 | struct ftrace_func_entry *entry; | 1322 | struct ftrace_func_entry *entry; |
1323 | struct ftrace_hash *new_hash; | 1323 | struct ftrace_hash *new_hash; |
1324 | int size; | 1324 | int size; |
1325 | int ret; | 1325 | int ret; |
1326 | int i; | 1326 | int i; |
1327 | 1327 | ||
1328 | new_hash = alloc_ftrace_hash(size_bits); | 1328 | new_hash = alloc_ftrace_hash(size_bits); |
1329 | if (!new_hash) | 1329 | if (!new_hash) |
1330 | return NULL; | 1330 | return NULL; |
1331 | 1331 | ||
1332 | /* Empty hash? */ | 1332 | /* Empty hash? */ |
1333 | if (ftrace_hash_empty(hash)) | 1333 | if (ftrace_hash_empty(hash)) |
1334 | return new_hash; | 1334 | return new_hash; |
1335 | 1335 | ||
1336 | size = 1 << hash->size_bits; | 1336 | size = 1 << hash->size_bits; |
1337 | for (i = 0; i < size; i++) { | 1337 | for (i = 0; i < size; i++) { |
1338 | hlist_for_each_entry(entry, &hash->buckets[i], hlist) { | 1338 | hlist_for_each_entry(entry, &hash->buckets[i], hlist) { |
1339 | ret = add_hash_entry(new_hash, entry->ip); | 1339 | ret = add_hash_entry(new_hash, entry->ip); |
1340 | if (ret < 0) | 1340 | if (ret < 0) |
1341 | goto free_hash; | 1341 | goto free_hash; |
1342 | } | 1342 | } |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | FTRACE_WARN_ON(new_hash->count != hash->count); | 1345 | FTRACE_WARN_ON(new_hash->count != hash->count); |
1346 | 1346 | ||
1347 | return new_hash; | 1347 | return new_hash; |
1348 | 1348 | ||
1349 | free_hash: | 1349 | free_hash: |
1350 | free_ftrace_hash(new_hash); | 1350 | free_ftrace_hash(new_hash); |
1351 | return NULL; | 1351 | return NULL; |
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | static void | 1354 | static void |
1355 | ftrace_hash_rec_disable(struct ftrace_ops *ops, int filter_hash); | 1355 | ftrace_hash_rec_disable(struct ftrace_ops *ops, int filter_hash); |
1356 | static void | 1356 | static void |
1357 | ftrace_hash_rec_enable(struct ftrace_ops *ops, int filter_hash); | 1357 | ftrace_hash_rec_enable(struct ftrace_ops *ops, int filter_hash); |
1358 | 1358 | ||
1359 | static int | 1359 | static int |
1360 | ftrace_hash_move(struct ftrace_ops *ops, int enable, | 1360 | ftrace_hash_move(struct ftrace_ops *ops, int enable, |
1361 | struct ftrace_hash **dst, struct ftrace_hash *src) | 1361 | struct ftrace_hash **dst, struct ftrace_hash *src) |
1362 | { | 1362 | { |
1363 | struct ftrace_func_entry *entry; | 1363 | struct ftrace_func_entry *entry; |
1364 | struct hlist_node *tn; | 1364 | struct hlist_node *tn; |
1365 | struct hlist_head *hhd; | 1365 | struct hlist_head *hhd; |
1366 | struct ftrace_hash *old_hash; | 1366 | struct ftrace_hash *old_hash; |
1367 | struct ftrace_hash *new_hash; | 1367 | struct ftrace_hash *new_hash; |
1368 | int size = src->count; | 1368 | int size = src->count; |
1369 | int bits = 0; | 1369 | int bits = 0; |
1370 | int ret; | 1370 | int ret; |
1371 | int i; | 1371 | int i; |
1372 | 1372 | ||
1373 | /* | 1373 | /* |
1374 | * Remove the current set, update the hash and add | 1374 | * Remove the current set, update the hash and add |
1375 | * them back. | 1375 | * them back. |
1376 | */ | 1376 | */ |
1377 | ftrace_hash_rec_disable(ops, enable); | 1377 | ftrace_hash_rec_disable(ops, enable); |
1378 | 1378 | ||
1379 | /* | 1379 | /* |
1380 | * If the new source is empty, just free dst and assign it | 1380 | * If the new source is empty, just free dst and assign it |
1381 | * the empty_hash. | 1381 | * the empty_hash. |
1382 | */ | 1382 | */ |
1383 | if (!src->count) { | 1383 | if (!src->count) { |
1384 | free_ftrace_hash_rcu(*dst); | 1384 | free_ftrace_hash_rcu(*dst); |
1385 | rcu_assign_pointer(*dst, EMPTY_HASH); | 1385 | rcu_assign_pointer(*dst, EMPTY_HASH); |
1386 | /* still need to update the function records */ | 1386 | /* still need to update the function records */ |
1387 | ret = 0; | 1387 | ret = 0; |
1388 | goto out; | 1388 | goto out; |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | /* | 1391 | /* |
1392 | * Make the hash size about 1/2 the # found | 1392 | * Make the hash size about 1/2 the # found |
1393 | */ | 1393 | */ |
1394 | for (size /= 2; size; size >>= 1) | 1394 | for (size /= 2; size; size >>= 1) |
1395 | bits++; | 1395 | bits++; |
1396 | 1396 | ||
1397 | /* Don't allocate too much */ | 1397 | /* Don't allocate too much */ |
1398 | if (bits > FTRACE_HASH_MAX_BITS) | 1398 | if (bits > FTRACE_HASH_MAX_BITS) |
1399 | bits = FTRACE_HASH_MAX_BITS; | 1399 | bits = FTRACE_HASH_MAX_BITS; |
1400 | 1400 | ||
1401 | ret = -ENOMEM; | 1401 | ret = -ENOMEM; |
1402 | new_hash = alloc_ftrace_hash(bits); | 1402 | new_hash = alloc_ftrace_hash(bits); |
1403 | if (!new_hash) | 1403 | if (!new_hash) |
1404 | goto out; | 1404 | goto out; |
1405 | 1405 | ||
1406 | size = 1 << src->size_bits; | 1406 | size = 1 << src->size_bits; |
1407 | for (i = 0; i < size; i++) { | 1407 | for (i = 0; i < size; i++) { |
1408 | hhd = &src->buckets[i]; | 1408 | hhd = &src->buckets[i]; |
1409 | hlist_for_each_entry_safe(entry, tn, hhd, hlist) { | 1409 | hlist_for_each_entry_safe(entry, tn, hhd, hlist) { |
1410 | remove_hash_entry(src, entry); | 1410 | remove_hash_entry(src, entry); |
1411 | __add_hash_entry(new_hash, entry); | 1411 | __add_hash_entry(new_hash, entry); |
1412 | } | 1412 | } |
1413 | } | 1413 | } |
1414 | 1414 | ||
1415 | old_hash = *dst; | 1415 | old_hash = *dst; |
1416 | rcu_assign_pointer(*dst, new_hash); | 1416 | rcu_assign_pointer(*dst, new_hash); |
1417 | free_ftrace_hash_rcu(old_hash); | 1417 | free_ftrace_hash_rcu(old_hash); |
1418 | 1418 | ||
1419 | ret = 0; | 1419 | ret = 0; |
1420 | out: | 1420 | out: |
1421 | /* | 1421 | /* |
1422 | * Enable regardless of ret: | 1422 | * Enable regardless of ret: |
1423 | * On success, we enable the new hash. | 1423 | * On success, we enable the new hash. |
1424 | * On failure, we re-enable the original hash. | 1424 | * On failure, we re-enable the original hash. |
1425 | */ | 1425 | */ |
1426 | ftrace_hash_rec_enable(ops, enable); | 1426 | ftrace_hash_rec_enable(ops, enable); |
1427 | 1427 | ||
1428 | return ret; | 1428 | return ret; |
1429 | } | 1429 | } |
1430 | 1430 | ||
1431 | /* | 1431 | /* |
1432 | * Test the hashes for this ops to see if we want to call | 1432 | * Test the hashes for this ops to see if we want to call |
1433 | * the ops->func or not. | 1433 | * the ops->func or not. |
1434 | * | 1434 | * |
1435 | * It's a match if the ip is in the ops->filter_hash or | 1435 | * It's a match if the ip is in the ops->filter_hash or |
1436 | * the filter_hash does not exist or is empty, | 1436 | * the filter_hash does not exist or is empty, |
1437 | * AND | 1437 | * AND |
1438 | * the ip is not in the ops->notrace_hash. | 1438 | * the ip is not in the ops->notrace_hash. |
1439 | * | 1439 | * |
1440 | * This needs to be called with preemption disabled as | 1440 | * This needs to be called with preemption disabled as |
1441 | * the hashes are freed with call_rcu_sched(). | 1441 | * the hashes are freed with call_rcu_sched(). |
1442 | */ | 1442 | */ |
1443 | static int | 1443 | static int |
1444 | ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) | 1444 | ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) |
1445 | { | 1445 | { |
1446 | struct ftrace_hash *filter_hash; | 1446 | struct ftrace_hash *filter_hash; |
1447 | struct ftrace_hash *notrace_hash; | 1447 | struct ftrace_hash *notrace_hash; |
1448 | int ret; | 1448 | int ret; |
1449 | 1449 | ||
1450 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS | 1450 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS |
1451 | /* | 1451 | /* |
1452 | * There's a small race when adding ops that the ftrace handler | 1452 | * There's a small race when adding ops that the ftrace handler |
1453 | * that wants regs, may be called without them. We can not | 1453 | * that wants regs, may be called without them. We can not |
1454 | * allow that handler to be called if regs is NULL. | 1454 | * allow that handler to be called if regs is NULL. |
1455 | */ | 1455 | */ |
1456 | if (regs == NULL && (ops->flags & FTRACE_OPS_FL_SAVE_REGS)) | 1456 | if (regs == NULL && (ops->flags & FTRACE_OPS_FL_SAVE_REGS)) |
1457 | return 0; | 1457 | return 0; |
1458 | #endif | 1458 | #endif |
1459 | 1459 | ||
1460 | filter_hash = rcu_dereference_raw_notrace(ops->filter_hash); | 1460 | filter_hash = rcu_dereference_raw_notrace(ops->filter_hash); |
1461 | notrace_hash = rcu_dereference_raw_notrace(ops->notrace_hash); | 1461 | notrace_hash = rcu_dereference_raw_notrace(ops->notrace_hash); |
1462 | 1462 | ||
1463 | if ((ftrace_hash_empty(filter_hash) || | 1463 | if ((ftrace_hash_empty(filter_hash) || |
1464 | ftrace_lookup_ip(filter_hash, ip)) && | 1464 | ftrace_lookup_ip(filter_hash, ip)) && |
1465 | (ftrace_hash_empty(notrace_hash) || | 1465 | (ftrace_hash_empty(notrace_hash) || |
1466 | !ftrace_lookup_ip(notrace_hash, ip))) | 1466 | !ftrace_lookup_ip(notrace_hash, ip))) |
1467 | ret = 1; | 1467 | ret = 1; |
1468 | else | 1468 | else |
1469 | ret = 0; | 1469 | ret = 0; |
1470 | 1470 | ||
1471 | return ret; | 1471 | return ret; |
1472 | } | 1472 | } |
1473 | 1473 | ||
1474 | /* | 1474 | /* |
1475 | * This is a double for. Do not use 'break' to break out of the loop, | 1475 | * This is a double for. Do not use 'break' to break out of the loop, |
1476 | * you must use a goto. | 1476 | * you must use a goto. |
1477 | */ | 1477 | */ |
1478 | #define do_for_each_ftrace_rec(pg, rec) \ | 1478 | #define do_for_each_ftrace_rec(pg, rec) \ |
1479 | for (pg = ftrace_pages_start; pg; pg = pg->next) { \ | 1479 | for (pg = ftrace_pages_start; pg; pg = pg->next) { \ |
1480 | int _____i; \ | 1480 | int _____i; \ |
1481 | for (_____i = 0; _____i < pg->index; _____i++) { \ | 1481 | for (_____i = 0; _____i < pg->index; _____i++) { \ |
1482 | rec = &pg->records[_____i]; | 1482 | rec = &pg->records[_____i]; |
1483 | 1483 | ||
1484 | #define while_for_each_ftrace_rec() \ | 1484 | #define while_for_each_ftrace_rec() \ |
1485 | } \ | 1485 | } \ |
1486 | } | 1486 | } |
1487 | 1487 | ||
1488 | 1488 | ||
1489 | static int ftrace_cmp_recs(const void *a, const void *b) | 1489 | static int ftrace_cmp_recs(const void *a, const void *b) |
1490 | { | 1490 | { |
1491 | const struct dyn_ftrace *key = a; | 1491 | const struct dyn_ftrace *key = a; |
1492 | const struct dyn_ftrace *rec = b; | 1492 | const struct dyn_ftrace *rec = b; |
1493 | 1493 | ||
1494 | if (key->flags < rec->ip) | 1494 | if (key->flags < rec->ip) |
1495 | return -1; | 1495 | return -1; |
1496 | if (key->ip >= rec->ip + MCOUNT_INSN_SIZE) | 1496 | if (key->ip >= rec->ip + MCOUNT_INSN_SIZE) |
1497 | return 1; | 1497 | return 1; |
1498 | return 0; | 1498 | return 0; |
1499 | } | 1499 | } |
1500 | 1500 | ||
1501 | static unsigned long ftrace_location_range(unsigned long start, unsigned long end) | 1501 | static unsigned long ftrace_location_range(unsigned long start, unsigned long end) |
1502 | { | 1502 | { |
1503 | struct ftrace_page *pg; | 1503 | struct ftrace_page *pg; |
1504 | struct dyn_ftrace *rec; | 1504 | struct dyn_ftrace *rec; |
1505 | struct dyn_ftrace key; | 1505 | struct dyn_ftrace key; |
1506 | 1506 | ||
1507 | key.ip = start; | 1507 | key.ip = start; |
1508 | key.flags = end; /* overload flags, as it is unsigned long */ | 1508 | key.flags = end; /* overload flags, as it is unsigned long */ |
1509 | 1509 | ||
1510 | for (pg = ftrace_pages_start; pg; pg = pg->next) { | 1510 | for (pg = ftrace_pages_start; pg; pg = pg->next) { |
1511 | if (end < pg->records[0].ip || | 1511 | if (end < pg->records[0].ip || |
1512 | start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE)) | 1512 | start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE)) |
1513 | continue; | 1513 | continue; |
1514 | rec = bsearch(&key, pg->records, pg->index, | 1514 | rec = bsearch(&key, pg->records, pg->index, |
1515 | sizeof(struct dyn_ftrace), | 1515 | sizeof(struct dyn_ftrace), |
1516 | ftrace_cmp_recs); | 1516 | ftrace_cmp_recs); |
1517 | if (rec) | 1517 | if (rec) |
1518 | return rec->ip; | 1518 | return rec->ip; |
1519 | } | 1519 | } |
1520 | 1520 | ||
1521 | return 0; | 1521 | return 0; |
1522 | } | 1522 | } |
1523 | 1523 | ||
1524 | /** | 1524 | /** |
1525 | * ftrace_location - return true if the ip giving is a traced location | 1525 | * ftrace_location - return true if the ip giving is a traced location |
1526 | * @ip: the instruction pointer to check | 1526 | * @ip: the instruction pointer to check |
1527 | * | 1527 | * |
1528 | * Returns rec->ip if @ip given is a pointer to a ftrace location. | 1528 | * Returns rec->ip if @ip given is a pointer to a ftrace location. |
1529 | * That is, the instruction that is either a NOP or call to | 1529 | * That is, the instruction that is either a NOP or call to |
1530 | * the function tracer. It checks the ftrace internal tables to | 1530 | * the function tracer. It checks the ftrace internal tables to |
1531 | * determine if the address belongs or not. | 1531 | * determine if the address belongs or not. |
1532 | */ | 1532 | */ |
1533 | unsigned long ftrace_location(unsigned long ip) | 1533 | unsigned long ftrace_location(unsigned long ip) |
1534 | { | 1534 | { |
1535 | return ftrace_location_range(ip, ip); | 1535 | return ftrace_location_range(ip, ip); |
1536 | } | 1536 | } |
1537 | 1537 | ||
1538 | /** | 1538 | /** |
1539 | * ftrace_text_reserved - return true if range contains an ftrace location | 1539 | * ftrace_text_reserved - return true if range contains an ftrace location |
1540 | * @start: start of range to search | 1540 | * @start: start of range to search |
1541 | * @end: end of range to search (inclusive). @end points to the last byte to check. | 1541 | * @end: end of range to search (inclusive). @end points to the last byte to check. |
1542 | * | 1542 | * |
1543 | * Returns 1 if @start and @end contains a ftrace location. | 1543 | * Returns 1 if @start and @end contains a ftrace location. |
1544 | * That is, the instruction that is either a NOP or call to | 1544 | * That is, the instruction that is either a NOP or call to |
1545 | * the function tracer. It checks the ftrace internal tables to | 1545 | * the function tracer. It checks the ftrace internal tables to |
1546 | * determine if the address belongs or not. | 1546 | * determine if the address belongs or not. |
1547 | */ | 1547 | */ |
1548 | int ftrace_text_reserved(void *start, void *end) | 1548 | int ftrace_text_reserved(void *start, void *end) |
1549 | { | 1549 | { |
1550 | unsigned long ret; | 1550 | unsigned long ret; |
1551 | 1551 | ||
1552 | ret = ftrace_location_range((unsigned long)start, | 1552 | ret = ftrace_location_range((unsigned long)start, |
1553 | (unsigned long)end); | 1553 | (unsigned long)end); |
1554 | 1554 | ||
1555 | return (int)!!ret; | 1555 | return (int)!!ret; |
1556 | } | 1556 | } |
1557 | 1557 | ||
1558 | static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | 1558 | static void __ftrace_hash_rec_update(struct ftrace_ops *ops, |
1559 | int filter_hash, | 1559 | int filter_hash, |
1560 | bool inc) | 1560 | bool inc) |
1561 | { | 1561 | { |
1562 | struct ftrace_hash *hash; | 1562 | struct ftrace_hash *hash; |
1563 | struct ftrace_hash *other_hash; | 1563 | struct ftrace_hash *other_hash; |
1564 | struct ftrace_page *pg; | 1564 | struct ftrace_page *pg; |
1565 | struct dyn_ftrace *rec; | 1565 | struct dyn_ftrace *rec; |
1566 | int count = 0; | 1566 | int count = 0; |
1567 | int all = 0; | 1567 | int all = 0; |
1568 | 1568 | ||
1569 | /* Only update if the ops has been registered */ | 1569 | /* Only update if the ops has been registered */ |
1570 | if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) | 1570 | if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) |
1571 | return; | 1571 | return; |
1572 | 1572 | ||
1573 | /* | 1573 | /* |
1574 | * In the filter_hash case: | 1574 | * In the filter_hash case: |
1575 | * If the count is zero, we update all records. | 1575 | * If the count is zero, we update all records. |
1576 | * Otherwise we just update the items in the hash. | 1576 | * Otherwise we just update the items in the hash. |
1577 | * | 1577 | * |
1578 | * In the notrace_hash case: | 1578 | * In the notrace_hash case: |
1579 | * We enable the update in the hash. | 1579 | * We enable the update in the hash. |
1580 | * As disabling notrace means enabling the tracing, | 1580 | * As disabling notrace means enabling the tracing, |
1581 | * and enabling notrace means disabling, the inc variable | 1581 | * and enabling notrace means disabling, the inc variable |
1582 | * gets inversed. | 1582 | * gets inversed. |
1583 | */ | 1583 | */ |
1584 | if (filter_hash) { | 1584 | if (filter_hash) { |
1585 | hash = ops->filter_hash; | 1585 | hash = ops->filter_hash; |
1586 | other_hash = ops->notrace_hash; | 1586 | other_hash = ops->notrace_hash; |
1587 | if (ftrace_hash_empty(hash)) | 1587 | if (ftrace_hash_empty(hash)) |
1588 | all = 1; | 1588 | all = 1; |
1589 | } else { | 1589 | } else { |
1590 | inc = !inc; | 1590 | inc = !inc; |
1591 | hash = ops->notrace_hash; | 1591 | hash = ops->notrace_hash; |
1592 | other_hash = ops->filter_hash; | 1592 | other_hash = ops->filter_hash; |
1593 | /* | 1593 | /* |
1594 | * If the notrace hash has no items, | 1594 | * If the notrace hash has no items, |
1595 | * then there's nothing to do. | 1595 | * then there's nothing to do. |
1596 | */ | 1596 | */ |
1597 | if (ftrace_hash_empty(hash)) | 1597 | if (ftrace_hash_empty(hash)) |
1598 | return; | 1598 | return; |
1599 | } | 1599 | } |
1600 | 1600 | ||
1601 | do_for_each_ftrace_rec(pg, rec) { | 1601 | do_for_each_ftrace_rec(pg, rec) { |
1602 | int in_other_hash = 0; | 1602 | int in_other_hash = 0; |
1603 | int in_hash = 0; | 1603 | int in_hash = 0; |
1604 | int match = 0; | 1604 | int match = 0; |
1605 | 1605 | ||
1606 | if (all) { | 1606 | if (all) { |
1607 | /* | 1607 | /* |
1608 | * Only the filter_hash affects all records. | 1608 | * Only the filter_hash affects all records. |
1609 | * Update if the record is not in the notrace hash. | 1609 | * Update if the record is not in the notrace hash. |
1610 | */ | 1610 | */ |
1611 | if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip)) | 1611 | if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip)) |
1612 | match = 1; | 1612 | match = 1; |
1613 | } else { | 1613 | } else { |
1614 | in_hash = !!ftrace_lookup_ip(hash, rec->ip); | 1614 | in_hash = !!ftrace_lookup_ip(hash, rec->ip); |
1615 | in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip); | 1615 | in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip); |
1616 | 1616 | ||
1617 | /* | 1617 | /* |
1618 | * | 1618 | * |
1619 | */ | 1619 | */ |
1620 | if (filter_hash && in_hash && !in_other_hash) | 1620 | if (filter_hash && in_hash && !in_other_hash) |
1621 | match = 1; | 1621 | match = 1; |
1622 | else if (!filter_hash && in_hash && | 1622 | else if (!filter_hash && in_hash && |
1623 | (in_other_hash || ftrace_hash_empty(other_hash))) | 1623 | (in_other_hash || ftrace_hash_empty(other_hash))) |
1624 | match = 1; | 1624 | match = 1; |
1625 | } | 1625 | } |
1626 | if (!match) | 1626 | if (!match) |
1627 | continue; | 1627 | continue; |
1628 | 1628 | ||
1629 | if (inc) { | 1629 | if (inc) { |
1630 | rec->flags++; | 1630 | rec->flags++; |
1631 | if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == FTRACE_REF_MAX)) | 1631 | if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == FTRACE_REF_MAX)) |
1632 | return; | 1632 | return; |
1633 | /* | 1633 | /* |
1634 | * If any ops wants regs saved for this function | 1634 | * If any ops wants regs saved for this function |
1635 | * then all ops will get saved regs. | 1635 | * then all ops will get saved regs. |
1636 | */ | 1636 | */ |
1637 | if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) | 1637 | if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) |
1638 | rec->flags |= FTRACE_FL_REGS; | 1638 | rec->flags |= FTRACE_FL_REGS; |
1639 | } else { | 1639 | } else { |
1640 | if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == 0)) | 1640 | if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == 0)) |
1641 | return; | 1641 | return; |
1642 | rec->flags--; | 1642 | rec->flags--; |
1643 | } | 1643 | } |
1644 | count++; | 1644 | count++; |
1645 | /* Shortcut, if we handled all records, we are done. */ | 1645 | /* Shortcut, if we handled all records, we are done. */ |
1646 | if (!all && count == hash->count) | 1646 | if (!all && count == hash->count) |
1647 | return; | 1647 | return; |
1648 | } while_for_each_ftrace_rec(); | 1648 | } while_for_each_ftrace_rec(); |
1649 | } | 1649 | } |
1650 | 1650 | ||
1651 | static void ftrace_hash_rec_disable(struct ftrace_ops *ops, | 1651 | static void ftrace_hash_rec_disable(struct ftrace_ops *ops, |
1652 | int filter_hash) | 1652 | int filter_hash) |
1653 | { | 1653 | { |
1654 | __ftrace_hash_rec_update(ops, filter_hash, 0); | 1654 | __ftrace_hash_rec_update(ops, filter_hash, 0); |
1655 | } | 1655 | } |
1656 | 1656 | ||
1657 | static void ftrace_hash_rec_enable(struct ftrace_ops *ops, | 1657 | static void ftrace_hash_rec_enable(struct ftrace_ops *ops, |
1658 | int filter_hash) | 1658 | int filter_hash) |
1659 | { | 1659 | { |
1660 | __ftrace_hash_rec_update(ops, filter_hash, 1); | 1660 | __ftrace_hash_rec_update(ops, filter_hash, 1); |
1661 | } | 1661 | } |
1662 | 1662 | ||
1663 | static void print_ip_ins(const char *fmt, unsigned char *p) | 1663 | static void print_ip_ins(const char *fmt, unsigned char *p) |
1664 | { | 1664 | { |
1665 | int i; | 1665 | int i; |
1666 | 1666 | ||
1667 | printk(KERN_CONT "%s", fmt); | 1667 | printk(KERN_CONT "%s", fmt); |
1668 | 1668 | ||
1669 | for (i = 0; i < MCOUNT_INSN_SIZE; i++) | 1669 | for (i = 0; i < MCOUNT_INSN_SIZE; i++) |
1670 | printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); | 1670 | printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); |
1671 | } | 1671 | } |
1672 | 1672 | ||
1673 | /** | 1673 | /** |
1674 | * ftrace_bug - report and shutdown function tracer | 1674 | * ftrace_bug - report and shutdown function tracer |
1675 | * @failed: The failed type (EFAULT, EINVAL, EPERM) | 1675 | * @failed: The failed type (EFAULT, EINVAL, EPERM) |
1676 | * @ip: The address that failed | 1676 | * @ip: The address that failed |
1677 | * | 1677 | * |
1678 | * The arch code that enables or disables the function tracing | 1678 | * The arch code that enables or disables the function tracing |
1679 | * can call ftrace_bug() when it has detected a problem in | 1679 | * can call ftrace_bug() when it has detected a problem in |
1680 | * modifying the code. @failed should be one of either: | 1680 | * modifying the code. @failed should be one of either: |
1681 | * EFAULT - if the problem happens on reading the @ip address | 1681 | * EFAULT - if the problem happens on reading the @ip address |
1682 | * EINVAL - if what is read at @ip is not what was expected | 1682 | * EINVAL - if what is read at @ip is not what was expected |
1683 | * EPERM - if the problem happens on writting to the @ip address | 1683 | * EPERM - if the problem happens on writting to the @ip address |
1684 | */ | 1684 | */ |
1685 | void ftrace_bug(int failed, unsigned long ip) | 1685 | void ftrace_bug(int failed, unsigned long ip) |
1686 | { | 1686 | { |
1687 | switch (failed) { | 1687 | switch (failed) { |
1688 | case -EFAULT: | 1688 | case -EFAULT: |
1689 | FTRACE_WARN_ON_ONCE(1); | 1689 | FTRACE_WARN_ON_ONCE(1); |
1690 | pr_info("ftrace faulted on modifying "); | 1690 | pr_info("ftrace faulted on modifying "); |
1691 | print_ip_sym(ip); | 1691 | print_ip_sym(ip); |
1692 | break; | 1692 | break; |
1693 | case -EINVAL: | 1693 | case -EINVAL: |
1694 | FTRACE_WARN_ON_ONCE(1); | 1694 | FTRACE_WARN_ON_ONCE(1); |
1695 | pr_info("ftrace failed to modify "); | 1695 | pr_info("ftrace failed to modify "); |
1696 | print_ip_sym(ip); | 1696 | print_ip_sym(ip); |
1697 | print_ip_ins(" actual: ", (unsigned char *)ip); | 1697 | print_ip_ins(" actual: ", (unsigned char *)ip); |
1698 | printk(KERN_CONT "\n"); | 1698 | printk(KERN_CONT "\n"); |
1699 | break; | 1699 | break; |
1700 | case -EPERM: | 1700 | case -EPERM: |
1701 | FTRACE_WARN_ON_ONCE(1); | 1701 | FTRACE_WARN_ON_ONCE(1); |
1702 | pr_info("ftrace faulted on writing "); | 1702 | pr_info("ftrace faulted on writing "); |
1703 | print_ip_sym(ip); | 1703 | print_ip_sym(ip); |
1704 | break; | 1704 | break; |
1705 | default: | 1705 | default: |
1706 | FTRACE_WARN_ON_ONCE(1); | 1706 | FTRACE_WARN_ON_ONCE(1); |
1707 | pr_info("ftrace faulted on unknown error "); | 1707 | pr_info("ftrace faulted on unknown error "); |
1708 | print_ip_sym(ip); | 1708 | print_ip_sym(ip); |
1709 | } | 1709 | } |
1710 | } | 1710 | } |
1711 | 1711 | ||
1712 | static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) | 1712 | static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) |
1713 | { | 1713 | { |
1714 | unsigned long flag = 0UL; | 1714 | unsigned long flag = 0UL; |
1715 | 1715 | ||
1716 | /* | 1716 | /* |
1717 | * If we are updating calls: | 1717 | * If we are updating calls: |
1718 | * | 1718 | * |
1719 | * If the record has a ref count, then we need to enable it | 1719 | * If the record has a ref count, then we need to enable it |
1720 | * because someone is using it. | 1720 | * because someone is using it. |
1721 | * | 1721 | * |
1722 | * Otherwise we make sure its disabled. | 1722 | * Otherwise we make sure its disabled. |
1723 | * | 1723 | * |
1724 | * If we are disabling calls, then disable all records that | 1724 | * If we are disabling calls, then disable all records that |
1725 | * are enabled. | 1725 | * are enabled. |
1726 | */ | 1726 | */ |
1727 | if (enable && (rec->flags & ~FTRACE_FL_MASK)) | 1727 | if (enable && (rec->flags & ~FTRACE_FL_MASK)) |
1728 | flag = FTRACE_FL_ENABLED; | 1728 | flag = FTRACE_FL_ENABLED; |
1729 | 1729 | ||
1730 | /* | 1730 | /* |
1731 | * If enabling and the REGS flag does not match the REGS_EN, then | 1731 | * If enabling and the REGS flag does not match the REGS_EN, then |
1732 | * do not ignore this record. Set flags to fail the compare against | 1732 | * do not ignore this record. Set flags to fail the compare against |
1733 | * ENABLED. | 1733 | * ENABLED. |
1734 | */ | 1734 | */ |
1735 | if (flag && | 1735 | if (flag && |
1736 | (!(rec->flags & FTRACE_FL_REGS) != !(rec->flags & FTRACE_FL_REGS_EN))) | 1736 | (!(rec->flags & FTRACE_FL_REGS) != !(rec->flags & FTRACE_FL_REGS_EN))) |
1737 | flag |= FTRACE_FL_REGS; | 1737 | flag |= FTRACE_FL_REGS; |
1738 | 1738 | ||
1739 | /* If the state of this record hasn't changed, then do nothing */ | 1739 | /* If the state of this record hasn't changed, then do nothing */ |
1740 | if ((rec->flags & FTRACE_FL_ENABLED) == flag) | 1740 | if ((rec->flags & FTRACE_FL_ENABLED) == flag) |
1741 | return FTRACE_UPDATE_IGNORE; | 1741 | return FTRACE_UPDATE_IGNORE; |
1742 | 1742 | ||
1743 | if (flag) { | 1743 | if (flag) { |
1744 | /* Save off if rec is being enabled (for return value) */ | 1744 | /* Save off if rec is being enabled (for return value) */ |
1745 | flag ^= rec->flags & FTRACE_FL_ENABLED; | 1745 | flag ^= rec->flags & FTRACE_FL_ENABLED; |
1746 | 1746 | ||
1747 | if (update) { | 1747 | if (update) { |
1748 | rec->flags |= FTRACE_FL_ENABLED; | 1748 | rec->flags |= FTRACE_FL_ENABLED; |
1749 | if (flag & FTRACE_FL_REGS) { | 1749 | if (flag & FTRACE_FL_REGS) { |
1750 | if (rec->flags & FTRACE_FL_REGS) | 1750 | if (rec->flags & FTRACE_FL_REGS) |
1751 | rec->flags |= FTRACE_FL_REGS_EN; | 1751 | rec->flags |= FTRACE_FL_REGS_EN; |
1752 | else | 1752 | else |
1753 | rec->flags &= ~FTRACE_FL_REGS_EN; | 1753 | rec->flags &= ~FTRACE_FL_REGS_EN; |
1754 | } | 1754 | } |
1755 | } | 1755 | } |
1756 | 1756 | ||
1757 | /* | 1757 | /* |
1758 | * If this record is being updated from a nop, then | 1758 | * If this record is being updated from a nop, then |
1759 | * return UPDATE_MAKE_CALL. | 1759 | * return UPDATE_MAKE_CALL. |
1760 | * Otherwise, if the EN flag is set, then return | 1760 | * Otherwise, if the EN flag is set, then return |
1761 | * UPDATE_MODIFY_CALL_REGS to tell the caller to convert | 1761 | * UPDATE_MODIFY_CALL_REGS to tell the caller to convert |
1762 | * from the non-save regs, to a save regs function. | 1762 | * from the non-save regs, to a save regs function. |
1763 | * Otherwise, | 1763 | * Otherwise, |
1764 | * return UPDATE_MODIFY_CALL to tell the caller to convert | 1764 | * return UPDATE_MODIFY_CALL to tell the caller to convert |
1765 | * from the save regs, to a non-save regs function. | 1765 | * from the save regs, to a non-save regs function. |
1766 | */ | 1766 | */ |
1767 | if (flag & FTRACE_FL_ENABLED) | 1767 | if (flag & FTRACE_FL_ENABLED) |
1768 | return FTRACE_UPDATE_MAKE_CALL; | 1768 | return FTRACE_UPDATE_MAKE_CALL; |
1769 | else if (rec->flags & FTRACE_FL_REGS_EN) | 1769 | else if (rec->flags & FTRACE_FL_REGS_EN) |
1770 | return FTRACE_UPDATE_MODIFY_CALL_REGS; | 1770 | return FTRACE_UPDATE_MODIFY_CALL_REGS; |
1771 | else | 1771 | else |
1772 | return FTRACE_UPDATE_MODIFY_CALL; | 1772 | return FTRACE_UPDATE_MODIFY_CALL; |
1773 | } | 1773 | } |
1774 | 1774 | ||
1775 | if (update) { | 1775 | if (update) { |
1776 | /* If there's no more users, clear all flags */ | 1776 | /* If there's no more users, clear all flags */ |
1777 | if (!(rec->flags & ~FTRACE_FL_MASK)) | 1777 | if (!(rec->flags & ~FTRACE_FL_MASK)) |
1778 | rec->flags = 0; | 1778 | rec->flags = 0; |
1779 | else | 1779 | else |
1780 | /* Just disable the record (keep REGS state) */ | 1780 | /* Just disable the record (keep REGS state) */ |
1781 | rec->flags &= ~FTRACE_FL_ENABLED; | 1781 | rec->flags &= ~FTRACE_FL_ENABLED; |
1782 | } | 1782 | } |
1783 | 1783 | ||
1784 | return FTRACE_UPDATE_MAKE_NOP; | 1784 | return FTRACE_UPDATE_MAKE_NOP; |
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | /** | 1787 | /** |
1788 | * ftrace_update_record, set a record that now is tracing or not | 1788 | * ftrace_update_record, set a record that now is tracing or not |
1789 | * @rec: the record to update | 1789 | * @rec: the record to update |
1790 | * @enable: set to 1 if the record is tracing, zero to force disable | 1790 | * @enable: set to 1 if the record is tracing, zero to force disable |
1791 | * | 1791 | * |
1792 | * The records that represent all functions that can be traced need | 1792 | * The records that represent all functions that can be traced need |
1793 | * to be updated when tracing has been enabled. | 1793 | * to be updated when tracing has been enabled. |
1794 | */ | 1794 | */ |
1795 | int ftrace_update_record(struct dyn_ftrace *rec, int enable) | 1795 | int ftrace_update_record(struct dyn_ftrace *rec, int enable) |
1796 | { | 1796 | { |
1797 | return ftrace_check_record(rec, enable, 1); | 1797 | return ftrace_check_record(rec, enable, 1); |
1798 | } | 1798 | } |
1799 | 1799 | ||
1800 | /** | 1800 | /** |
1801 | * ftrace_test_record, check if the record has been enabled or not | 1801 | * ftrace_test_record, check if the record has been enabled or not |
1802 | * @rec: the record to test | 1802 | * @rec: the record to test |
1803 | * @enable: set to 1 to check if enabled, 0 if it is disabled | 1803 | * @enable: set to 1 to check if enabled, 0 if it is disabled |
1804 | * | 1804 | * |
1805 | * The arch code may need to test if a record is already set to | 1805 | * The arch code may need to test if a record is already set to |
1806 | * tracing to determine how to modify the function code that it | 1806 | * tracing to determine how to modify the function code that it |
1807 | * represents. | 1807 | * represents. |
1808 | */ | 1808 | */ |
1809 | int ftrace_test_record(struct dyn_ftrace *rec, int enable) | 1809 | int ftrace_test_record(struct dyn_ftrace *rec, int enable) |
1810 | { | 1810 | { |
1811 | return ftrace_check_record(rec, enable, 0); | 1811 | return ftrace_check_record(rec, enable, 0); |
1812 | } | 1812 | } |
1813 | 1813 | ||
1814 | static int | 1814 | static int |
1815 | __ftrace_replace_code(struct dyn_ftrace *rec, int enable) | 1815 | __ftrace_replace_code(struct dyn_ftrace *rec, int enable) |
1816 | { | 1816 | { |
1817 | unsigned long ftrace_old_addr; | 1817 | unsigned long ftrace_old_addr; |
1818 | unsigned long ftrace_addr; | 1818 | unsigned long ftrace_addr; |
1819 | int ret; | 1819 | int ret; |
1820 | 1820 | ||
1821 | ret = ftrace_update_record(rec, enable); | 1821 | ret = ftrace_update_record(rec, enable); |
1822 | 1822 | ||
1823 | if (rec->flags & FTRACE_FL_REGS) | 1823 | if (rec->flags & FTRACE_FL_REGS) |
1824 | ftrace_addr = (unsigned long)FTRACE_REGS_ADDR; | 1824 | ftrace_addr = (unsigned long)FTRACE_REGS_ADDR; |
1825 | else | 1825 | else |
1826 | ftrace_addr = (unsigned long)FTRACE_ADDR; | 1826 | ftrace_addr = (unsigned long)FTRACE_ADDR; |
1827 | 1827 | ||
1828 | switch (ret) { | 1828 | switch (ret) { |
1829 | case FTRACE_UPDATE_IGNORE: | 1829 | case FTRACE_UPDATE_IGNORE: |
1830 | return 0; | 1830 | return 0; |
1831 | 1831 | ||
1832 | case FTRACE_UPDATE_MAKE_CALL: | 1832 | case FTRACE_UPDATE_MAKE_CALL: |
1833 | return ftrace_make_call(rec, ftrace_addr); | 1833 | return ftrace_make_call(rec, ftrace_addr); |
1834 | 1834 | ||
1835 | case FTRACE_UPDATE_MAKE_NOP: | 1835 | case FTRACE_UPDATE_MAKE_NOP: |
1836 | return ftrace_make_nop(NULL, rec, ftrace_addr); | 1836 | return ftrace_make_nop(NULL, rec, ftrace_addr); |
1837 | 1837 | ||
1838 | case FTRACE_UPDATE_MODIFY_CALL_REGS: | 1838 | case FTRACE_UPDATE_MODIFY_CALL_REGS: |
1839 | case FTRACE_UPDATE_MODIFY_CALL: | 1839 | case FTRACE_UPDATE_MODIFY_CALL: |
1840 | if (rec->flags & FTRACE_FL_REGS) | 1840 | if (rec->flags & FTRACE_FL_REGS) |
1841 | ftrace_old_addr = (unsigned long)FTRACE_ADDR; | 1841 | ftrace_old_addr = (unsigned long)FTRACE_ADDR; |
1842 | else | 1842 | else |
1843 | ftrace_old_addr = (unsigned long)FTRACE_REGS_ADDR; | 1843 | ftrace_old_addr = (unsigned long)FTRACE_REGS_ADDR; |
1844 | 1844 | ||
1845 | return ftrace_modify_call(rec, ftrace_old_addr, ftrace_addr); | 1845 | return ftrace_modify_call(rec, ftrace_old_addr, ftrace_addr); |
1846 | } | 1846 | } |
1847 | 1847 | ||
1848 | return -1; /* unknow ftrace bug */ | 1848 | return -1; /* unknow ftrace bug */ |
1849 | } | 1849 | } |
1850 | 1850 | ||
1851 | void __weak ftrace_replace_code(int enable) | 1851 | void __weak ftrace_replace_code(int enable) |
1852 | { | 1852 | { |
1853 | struct dyn_ftrace *rec; | 1853 | struct dyn_ftrace *rec; |
1854 | struct ftrace_page *pg; | 1854 | struct ftrace_page *pg; |
1855 | int failed; | 1855 | int failed; |
1856 | 1856 | ||
1857 | if (unlikely(ftrace_disabled)) | 1857 | if (unlikely(ftrace_disabled)) |
1858 | return; | 1858 | return; |
1859 | 1859 | ||
1860 | do_for_each_ftrace_rec(pg, rec) { | 1860 | do_for_each_ftrace_rec(pg, rec) { |
1861 | failed = __ftrace_replace_code(rec, enable); | 1861 | failed = __ftrace_replace_code(rec, enable); |
1862 | if (failed) { | 1862 | if (failed) { |
1863 | ftrace_bug(failed, rec->ip); | 1863 | ftrace_bug(failed, rec->ip); |
1864 | /* Stop processing */ | 1864 | /* Stop processing */ |
1865 | return; | 1865 | return; |
1866 | } | 1866 | } |
1867 | } while_for_each_ftrace_rec(); | 1867 | } while_for_each_ftrace_rec(); |
1868 | } | 1868 | } |
1869 | 1869 | ||
1870 | struct ftrace_rec_iter { | 1870 | struct ftrace_rec_iter { |
1871 | struct ftrace_page *pg; | 1871 | struct ftrace_page *pg; |
1872 | int index; | 1872 | int index; |
1873 | }; | 1873 | }; |
1874 | 1874 | ||
1875 | /** | 1875 | /** |
1876 | * ftrace_rec_iter_start, start up iterating over traced functions | 1876 | * ftrace_rec_iter_start, start up iterating over traced functions |
1877 | * | 1877 | * |
1878 | * Returns an iterator handle that is used to iterate over all | 1878 | * Returns an iterator handle that is used to iterate over all |
1879 | * the records that represent address locations where functions | 1879 | * the records that represent address locations where functions |
1880 | * are traced. | 1880 | * are traced. |
1881 | * | 1881 | * |
1882 | * May return NULL if no records are available. | 1882 | * May return NULL if no records are available. |
1883 | */ | 1883 | */ |
1884 | struct ftrace_rec_iter *ftrace_rec_iter_start(void) | 1884 | struct ftrace_rec_iter *ftrace_rec_iter_start(void) |
1885 | { | 1885 | { |
1886 | /* | 1886 | /* |
1887 | * We only use a single iterator. | 1887 | * We only use a single iterator. |
1888 | * Protected by the ftrace_lock mutex. | 1888 | * Protected by the ftrace_lock mutex. |
1889 | */ | 1889 | */ |
1890 | static struct ftrace_rec_iter ftrace_rec_iter; | 1890 | static struct ftrace_rec_iter ftrace_rec_iter; |
1891 | struct ftrace_rec_iter *iter = &ftrace_rec_iter; | 1891 | struct ftrace_rec_iter *iter = &ftrace_rec_iter; |
1892 | 1892 | ||
1893 | iter->pg = ftrace_pages_start; | 1893 | iter->pg = ftrace_pages_start; |
1894 | iter->index = 0; | 1894 | iter->index = 0; |
1895 | 1895 | ||
1896 | /* Could have empty pages */ | 1896 | /* Could have empty pages */ |
1897 | while (iter->pg && !iter->pg->index) | 1897 | while (iter->pg && !iter->pg->index) |
1898 | iter->pg = iter->pg->next; | 1898 | iter->pg = iter->pg->next; |
1899 | 1899 | ||
1900 | if (!iter->pg) | 1900 | if (!iter->pg) |
1901 | return NULL; | 1901 | return NULL; |
1902 | 1902 | ||
1903 | return iter; | 1903 | return iter; |
1904 | } | 1904 | } |
1905 | 1905 | ||
1906 | /** | 1906 | /** |
1907 | * ftrace_rec_iter_next, get the next record to process. | 1907 | * ftrace_rec_iter_next, get the next record to process. |
1908 | * @iter: The handle to the iterator. | 1908 | * @iter: The handle to the iterator. |
1909 | * | 1909 | * |
1910 | * Returns the next iterator after the given iterator @iter. | 1910 | * Returns the next iterator after the given iterator @iter. |
1911 | */ | 1911 | */ |
1912 | struct ftrace_rec_iter *ftrace_rec_iter_next(struct ftrace_rec_iter *iter) | 1912 | struct ftrace_rec_iter *ftrace_rec_iter_next(struct ftrace_rec_iter *iter) |
1913 | { | 1913 | { |
1914 | iter->index++; | 1914 | iter->index++; |
1915 | 1915 | ||
1916 | if (iter->index >= iter->pg->index) { | 1916 | if (iter->index >= iter->pg->index) { |
1917 | iter->pg = iter->pg->next; | 1917 | iter->pg = iter->pg->next; |
1918 | iter->index = 0; | 1918 | iter->index = 0; |
1919 | 1919 | ||
1920 | /* Could have empty pages */ | 1920 | /* Could have empty pages */ |
1921 | while (iter->pg && !iter->pg->index) | 1921 | while (iter->pg && !iter->pg->index) |
1922 | iter->pg = iter->pg->next; | 1922 | iter->pg = iter->pg->next; |
1923 | } | 1923 | } |
1924 | 1924 | ||
1925 | if (!iter->pg) | 1925 | if (!iter->pg) |
1926 | return NULL; | 1926 | return NULL; |
1927 | 1927 | ||
1928 | return iter; | 1928 | return iter; |
1929 | } | 1929 | } |
1930 | 1930 | ||
1931 | /** | 1931 | /** |
1932 | * ftrace_rec_iter_record, get the record at the iterator location | 1932 | * ftrace_rec_iter_record, get the record at the iterator location |
1933 | * @iter: The current iterator location | 1933 | * @iter: The current iterator location |
1934 | * | 1934 | * |
1935 | * Returns the record that the current @iter is at. | 1935 | * Returns the record that the current @iter is at. |
1936 | */ | 1936 | */ |
1937 | struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter) | 1937 | struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter) |
1938 | { | 1938 | { |
1939 | return &iter->pg->records[iter->index]; | 1939 | return &iter->pg->records[iter->index]; |
1940 | } | 1940 | } |
1941 | 1941 | ||
1942 | static int | 1942 | static int |
1943 | ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) | 1943 | ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) |
1944 | { | 1944 | { |
1945 | unsigned long ip; | 1945 | unsigned long ip; |
1946 | int ret; | 1946 | int ret; |
1947 | 1947 | ||
1948 | ip = rec->ip; | 1948 | ip = rec->ip; |
1949 | 1949 | ||
1950 | if (unlikely(ftrace_disabled)) | 1950 | if (unlikely(ftrace_disabled)) |
1951 | return 0; | 1951 | return 0; |
1952 | 1952 | ||
1953 | ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR); | 1953 | ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR); |
1954 | if (ret) { | 1954 | if (ret) { |
1955 | ftrace_bug(ret, ip); | 1955 | ftrace_bug(ret, ip); |
1956 | return 0; | 1956 | return 0; |
1957 | } | 1957 | } |
1958 | return 1; | 1958 | return 1; |
1959 | } | 1959 | } |
1960 | 1960 | ||
1961 | /* | 1961 | /* |
1962 | * archs can override this function if they must do something | 1962 | * archs can override this function if they must do something |
1963 | * before the modifying code is performed. | 1963 | * before the modifying code is performed. |
1964 | */ | 1964 | */ |
1965 | int __weak ftrace_arch_code_modify_prepare(void) | 1965 | int __weak ftrace_arch_code_modify_prepare(void) |
1966 | { | 1966 | { |
1967 | return 0; | 1967 | return 0; |
1968 | } | 1968 | } |
1969 | 1969 | ||
1970 | /* | 1970 | /* |
1971 | * archs can override this function if they must do something | 1971 | * archs can override this function if they must do something |
1972 | * after the modifying code is performed. | 1972 | * after the modifying code is performed. |
1973 | */ | 1973 | */ |
1974 | int __weak ftrace_arch_code_modify_post_process(void) | 1974 | int __weak ftrace_arch_code_modify_post_process(void) |
1975 | { | 1975 | { |
1976 | return 0; | 1976 | return 0; |
1977 | } | 1977 | } |
1978 | 1978 | ||
1979 | void ftrace_modify_all_code(int command) | 1979 | void ftrace_modify_all_code(int command) |
1980 | { | 1980 | { |
1981 | int update = command & FTRACE_UPDATE_TRACE_FUNC; | ||
1982 | |||
1983 | /* | ||
1984 | * If the ftrace_caller calls a ftrace_ops func directly, | ||
1985 | * we need to make sure that it only traces functions it | ||
1986 | * expects to trace. When doing the switch of functions, | ||
1987 | * we need to update to the ftrace_ops_list_func first | ||
1988 | * before the transition between old and new calls are set, | ||
1989 | * as the ftrace_ops_list_func will check the ops hashes | ||
1990 | * to make sure the ops are having the right functions | ||
1991 | * traced. | ||
1992 | */ | ||
1993 | if (update) | ||
1994 | ftrace_update_ftrace_func(ftrace_ops_list_func); | ||
1995 | |||
1981 | if (command & FTRACE_UPDATE_CALLS) | 1996 | if (command & FTRACE_UPDATE_CALLS) |
1982 | ftrace_replace_code(1); | 1997 | ftrace_replace_code(1); |
1983 | else if (command & FTRACE_DISABLE_CALLS) | 1998 | else if (command & FTRACE_DISABLE_CALLS) |
1984 | ftrace_replace_code(0); | 1999 | ftrace_replace_code(0); |
1985 | 2000 | ||
1986 | if (command & FTRACE_UPDATE_TRACE_FUNC) | 2001 | if (update && ftrace_trace_function != ftrace_ops_list_func) |
1987 | ftrace_update_ftrace_func(ftrace_trace_function); | 2002 | ftrace_update_ftrace_func(ftrace_trace_function); |
1988 | 2003 | ||
1989 | if (command & FTRACE_START_FUNC_RET) | 2004 | if (command & FTRACE_START_FUNC_RET) |
1990 | ftrace_enable_ftrace_graph_caller(); | 2005 | ftrace_enable_ftrace_graph_caller(); |
1991 | else if (command & FTRACE_STOP_FUNC_RET) | 2006 | else if (command & FTRACE_STOP_FUNC_RET) |
1992 | ftrace_disable_ftrace_graph_caller(); | 2007 | ftrace_disable_ftrace_graph_caller(); |
1993 | } | 2008 | } |
1994 | 2009 | ||
1995 | static int __ftrace_modify_code(void *data) | 2010 | static int __ftrace_modify_code(void *data) |
1996 | { | 2011 | { |
1997 | int *command = data; | 2012 | int *command = data; |
1998 | 2013 | ||
1999 | ftrace_modify_all_code(*command); | 2014 | ftrace_modify_all_code(*command); |
2000 | 2015 | ||
2001 | return 0; | 2016 | return 0; |
2002 | } | 2017 | } |
2003 | 2018 | ||
2004 | /** | 2019 | /** |
2005 | * ftrace_run_stop_machine, go back to the stop machine method | 2020 | * ftrace_run_stop_machine, go back to the stop machine method |
2006 | * @command: The command to tell ftrace what to do | 2021 | * @command: The command to tell ftrace what to do |
2007 | * | 2022 | * |
2008 | * If an arch needs to fall back to the stop machine method, the | 2023 | * If an arch needs to fall back to the stop machine method, the |
2009 | * it can call this function. | 2024 | * it can call this function. |
2010 | */ | 2025 | */ |
2011 | void ftrace_run_stop_machine(int command) | 2026 | void ftrace_run_stop_machine(int command) |
2012 | { | 2027 | { |
2013 | stop_machine(__ftrace_modify_code, &command, NULL); | 2028 | stop_machine(__ftrace_modify_code, &command, NULL); |
2014 | } | 2029 | } |
2015 | 2030 | ||
2016 | /** | 2031 | /** |
2017 | * arch_ftrace_update_code, modify the code to trace or not trace | 2032 | * arch_ftrace_update_code, modify the code to trace or not trace |
2018 | * @command: The command that needs to be done | 2033 | * @command: The command that needs to be done |
2019 | * | 2034 | * |
2020 | * Archs can override this function if it does not need to | 2035 | * Archs can override this function if it does not need to |
2021 | * run stop_machine() to modify code. | 2036 | * run stop_machine() to modify code. |
2022 | */ | 2037 | */ |
2023 | void __weak arch_ftrace_update_code(int command) | 2038 | void __weak arch_ftrace_update_code(int command) |
2024 | { | 2039 | { |
2025 | ftrace_run_stop_machine(command); | 2040 | ftrace_run_stop_machine(command); |
2026 | } | 2041 | } |
2027 | 2042 | ||
2028 | static void ftrace_run_update_code(int command) | 2043 | static void ftrace_run_update_code(int command) |
2029 | { | 2044 | { |
2030 | int ret; | 2045 | int ret; |
2031 | 2046 | ||
2032 | ret = ftrace_arch_code_modify_prepare(); | 2047 | ret = ftrace_arch_code_modify_prepare(); |
2033 | FTRACE_WARN_ON(ret); | 2048 | FTRACE_WARN_ON(ret); |
2034 | if (ret) | 2049 | if (ret) |
2035 | return; | 2050 | return; |
2036 | /* | 2051 | /* |
2037 | * Do not call function tracer while we update the code. | 2052 | * Do not call function tracer while we update the code. |
2038 | * We are in stop machine. | 2053 | * We are in stop machine. |
2039 | */ | 2054 | */ |
2040 | function_trace_stop++; | 2055 | function_trace_stop++; |
2041 | 2056 | ||
2042 | /* | 2057 | /* |
2043 | * By default we use stop_machine() to modify the code. | 2058 | * By default we use stop_machine() to modify the code. |
2044 | * But archs can do what ever they want as long as it | 2059 | * But archs can do what ever they want as long as it |
2045 | * is safe. The stop_machine() is the safest, but also | 2060 | * is safe. The stop_machine() is the safest, but also |
2046 | * produces the most overhead. | 2061 | * produces the most overhead. |
2047 | */ | 2062 | */ |
2048 | arch_ftrace_update_code(command); | 2063 | arch_ftrace_update_code(command); |
2049 | 2064 | ||
2050 | function_trace_stop--; | 2065 | function_trace_stop--; |
2051 | 2066 | ||
2052 | ret = ftrace_arch_code_modify_post_process(); | 2067 | ret = ftrace_arch_code_modify_post_process(); |
2053 | FTRACE_WARN_ON(ret); | 2068 | FTRACE_WARN_ON(ret); |
2054 | } | 2069 | } |
2055 | 2070 | ||
2056 | static ftrace_func_t saved_ftrace_func; | 2071 | static ftrace_func_t saved_ftrace_func; |
2057 | static int ftrace_start_up; | 2072 | static int ftrace_start_up; |
2058 | static int global_start_up; | 2073 | static int global_start_up; |
2059 | 2074 | ||
2060 | static void ftrace_startup_enable(int command) | 2075 | static void ftrace_startup_enable(int command) |
2061 | { | 2076 | { |
2062 | if (saved_ftrace_func != ftrace_trace_function) { | 2077 | if (saved_ftrace_func != ftrace_trace_function) { |
2063 | saved_ftrace_func = ftrace_trace_function; | 2078 | saved_ftrace_func = ftrace_trace_function; |
2064 | command |= FTRACE_UPDATE_TRACE_FUNC; | 2079 | command |= FTRACE_UPDATE_TRACE_FUNC; |
2065 | } | 2080 | } |
2066 | 2081 | ||
2067 | if (!command || !ftrace_enabled) | 2082 | if (!command || !ftrace_enabled) |
2068 | return; | 2083 | return; |
2069 | 2084 | ||
2070 | ftrace_run_update_code(command); | 2085 | ftrace_run_update_code(command); |
2071 | } | 2086 | } |
2072 | 2087 | ||
2073 | static int ftrace_startup(struct ftrace_ops *ops, int command) | 2088 | static int ftrace_startup(struct ftrace_ops *ops, int command) |
2074 | { | 2089 | { |
2075 | bool hash_enable = true; | 2090 | bool hash_enable = true; |
2076 | 2091 | ||
2077 | if (unlikely(ftrace_disabled)) | 2092 | if (unlikely(ftrace_disabled)) |
2078 | return -ENODEV; | 2093 | return -ENODEV; |
2079 | 2094 | ||
2080 | ftrace_start_up++; | 2095 | ftrace_start_up++; |
2081 | command |= FTRACE_UPDATE_CALLS; | 2096 | command |= FTRACE_UPDATE_CALLS; |
2082 | 2097 | ||
2083 | /* ops marked global share the filter hashes */ | 2098 | /* ops marked global share the filter hashes */ |
2084 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { | 2099 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { |
2085 | ops = &global_ops; | 2100 | ops = &global_ops; |
2086 | /* Don't update hash if global is already set */ | 2101 | /* Don't update hash if global is already set */ |
2087 | if (global_start_up) | 2102 | if (global_start_up) |
2088 | hash_enable = false; | 2103 | hash_enable = false; |
2089 | global_start_up++; | 2104 | global_start_up++; |
2090 | } | 2105 | } |
2091 | 2106 | ||
2092 | ops->flags |= FTRACE_OPS_FL_ENABLED; | 2107 | ops->flags |= FTRACE_OPS_FL_ENABLED; |
2093 | if (hash_enable) | 2108 | if (hash_enable) |
2094 | ftrace_hash_rec_enable(ops, 1); | 2109 | ftrace_hash_rec_enable(ops, 1); |
2095 | 2110 | ||
2096 | ftrace_startup_enable(command); | 2111 | ftrace_startup_enable(command); |
2097 | 2112 | ||
2098 | return 0; | 2113 | return 0; |
2099 | } | 2114 | } |
2100 | 2115 | ||
2101 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) | 2116 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) |
2102 | { | 2117 | { |
2103 | bool hash_disable = true; | 2118 | bool hash_disable = true; |
2104 | 2119 | ||
2105 | if (unlikely(ftrace_disabled)) | 2120 | if (unlikely(ftrace_disabled)) |
2106 | return; | 2121 | return; |
2107 | 2122 | ||
2108 | ftrace_start_up--; | 2123 | ftrace_start_up--; |
2109 | /* | 2124 | /* |
2110 | * Just warn in case of unbalance, no need to kill ftrace, it's not | 2125 | * Just warn in case of unbalance, no need to kill ftrace, it's not |
2111 | * critical but the ftrace_call callers may be never nopped again after | 2126 | * critical but the ftrace_call callers may be never nopped again after |
2112 | * further ftrace uses. | 2127 | * further ftrace uses. |
2113 | */ | 2128 | */ |
2114 | WARN_ON_ONCE(ftrace_start_up < 0); | 2129 | WARN_ON_ONCE(ftrace_start_up < 0); |
2115 | 2130 | ||
2116 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { | 2131 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { |
2117 | ops = &global_ops; | 2132 | ops = &global_ops; |
2118 | global_start_up--; | 2133 | global_start_up--; |
2119 | WARN_ON_ONCE(global_start_up < 0); | 2134 | WARN_ON_ONCE(global_start_up < 0); |
2120 | /* Don't update hash if global still has users */ | 2135 | /* Don't update hash if global still has users */ |
2121 | if (global_start_up) { | 2136 | if (global_start_up) { |
2122 | WARN_ON_ONCE(!ftrace_start_up); | 2137 | WARN_ON_ONCE(!ftrace_start_up); |
2123 | hash_disable = false; | 2138 | hash_disable = false; |
2124 | } | 2139 | } |
2125 | } | 2140 | } |
2126 | 2141 | ||
2127 | if (hash_disable) | 2142 | if (hash_disable) |
2128 | ftrace_hash_rec_disable(ops, 1); | 2143 | ftrace_hash_rec_disable(ops, 1); |
2129 | 2144 | ||
2130 | if (ops != &global_ops || !global_start_up) | 2145 | if (ops != &global_ops || !global_start_up) |
2131 | ops->flags &= ~FTRACE_OPS_FL_ENABLED; | 2146 | ops->flags &= ~FTRACE_OPS_FL_ENABLED; |
2132 | 2147 | ||
2133 | command |= FTRACE_UPDATE_CALLS; | 2148 | command |= FTRACE_UPDATE_CALLS; |
2134 | 2149 | ||
2135 | if (saved_ftrace_func != ftrace_trace_function) { | 2150 | if (saved_ftrace_func != ftrace_trace_function) { |
2136 | saved_ftrace_func = ftrace_trace_function; | 2151 | saved_ftrace_func = ftrace_trace_function; |
2137 | command |= FTRACE_UPDATE_TRACE_FUNC; | 2152 | command |= FTRACE_UPDATE_TRACE_FUNC; |
2138 | } | 2153 | } |
2139 | 2154 | ||
2140 | if (!command || !ftrace_enabled) | 2155 | if (!command || !ftrace_enabled) |
2141 | return; | 2156 | return; |
2142 | 2157 | ||
2143 | ftrace_run_update_code(command); | 2158 | ftrace_run_update_code(command); |
2144 | } | 2159 | } |
2145 | 2160 | ||
2146 | static void ftrace_startup_sysctl(void) | 2161 | static void ftrace_startup_sysctl(void) |
2147 | { | 2162 | { |
2148 | if (unlikely(ftrace_disabled)) | 2163 | if (unlikely(ftrace_disabled)) |
2149 | return; | 2164 | return; |
2150 | 2165 | ||
2151 | /* Force update next time */ | 2166 | /* Force update next time */ |
2152 | saved_ftrace_func = NULL; | 2167 | saved_ftrace_func = NULL; |
2153 | /* ftrace_start_up is true if we want ftrace running */ | 2168 | /* ftrace_start_up is true if we want ftrace running */ |
2154 | if (ftrace_start_up) | 2169 | if (ftrace_start_up) |
2155 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); | 2170 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); |
2156 | } | 2171 | } |
2157 | 2172 | ||
2158 | static void ftrace_shutdown_sysctl(void) | 2173 | static void ftrace_shutdown_sysctl(void) |
2159 | { | 2174 | { |
2160 | if (unlikely(ftrace_disabled)) | 2175 | if (unlikely(ftrace_disabled)) |
2161 | return; | 2176 | return; |
2162 | 2177 | ||
2163 | /* ftrace_start_up is true if ftrace is running */ | 2178 | /* ftrace_start_up is true if ftrace is running */ |
2164 | if (ftrace_start_up) | 2179 | if (ftrace_start_up) |
2165 | ftrace_run_update_code(FTRACE_DISABLE_CALLS); | 2180 | ftrace_run_update_code(FTRACE_DISABLE_CALLS); |
2166 | } | 2181 | } |
2167 | 2182 | ||
2168 | static cycle_t ftrace_update_time; | 2183 | static cycle_t ftrace_update_time; |
2169 | static unsigned long ftrace_update_cnt; | 2184 | static unsigned long ftrace_update_cnt; |
2170 | unsigned long ftrace_update_tot_cnt; | 2185 | unsigned long ftrace_update_tot_cnt; |
2171 | 2186 | ||
2172 | static inline int ops_traces_mod(struct ftrace_ops *ops) | 2187 | static inline int ops_traces_mod(struct ftrace_ops *ops) |
2173 | { | 2188 | { |
2174 | /* | 2189 | /* |
2175 | * Filter_hash being empty will default to trace module. | 2190 | * Filter_hash being empty will default to trace module. |
2176 | * But notrace hash requires a test of individual module functions. | 2191 | * But notrace hash requires a test of individual module functions. |
2177 | */ | 2192 | */ |
2178 | return ftrace_hash_empty(ops->filter_hash) && | 2193 | return ftrace_hash_empty(ops->filter_hash) && |
2179 | ftrace_hash_empty(ops->notrace_hash); | 2194 | ftrace_hash_empty(ops->notrace_hash); |
2180 | } | 2195 | } |
2181 | 2196 | ||
2182 | /* | 2197 | /* |
2183 | * Check if the current ops references the record. | 2198 | * Check if the current ops references the record. |
2184 | * | 2199 | * |
2185 | * If the ops traces all functions, then it was already accounted for. | 2200 | * If the ops traces all functions, then it was already accounted for. |
2186 | * If the ops does not trace the current record function, skip it. | 2201 | * If the ops does not trace the current record function, skip it. |
2187 | * If the ops ignores the function via notrace filter, skip it. | 2202 | * If the ops ignores the function via notrace filter, skip it. |
2188 | */ | 2203 | */ |
2189 | static inline bool | 2204 | static inline bool |
2190 | ops_references_rec(struct ftrace_ops *ops, struct dyn_ftrace *rec) | 2205 | ops_references_rec(struct ftrace_ops *ops, struct dyn_ftrace *rec) |
2191 | { | 2206 | { |
2192 | /* If ops isn't enabled, ignore it */ | 2207 | /* If ops isn't enabled, ignore it */ |
2193 | if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) | 2208 | if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) |
2194 | return 0; | 2209 | return 0; |
2195 | 2210 | ||
2196 | /* If ops traces all mods, we already accounted for it */ | 2211 | /* If ops traces all mods, we already accounted for it */ |
2197 | if (ops_traces_mod(ops)) | 2212 | if (ops_traces_mod(ops)) |
2198 | return 0; | 2213 | return 0; |
2199 | 2214 | ||
2200 | /* The function must be in the filter */ | 2215 | /* The function must be in the filter */ |
2201 | if (!ftrace_hash_empty(ops->filter_hash) && | 2216 | if (!ftrace_hash_empty(ops->filter_hash) && |
2202 | !ftrace_lookup_ip(ops->filter_hash, rec->ip)) | 2217 | !ftrace_lookup_ip(ops->filter_hash, rec->ip)) |
2203 | return 0; | 2218 | return 0; |
2204 | 2219 | ||
2205 | /* If in notrace hash, we ignore it too */ | 2220 | /* If in notrace hash, we ignore it too */ |
2206 | if (ftrace_lookup_ip(ops->notrace_hash, rec->ip)) | 2221 | if (ftrace_lookup_ip(ops->notrace_hash, rec->ip)) |
2207 | return 0; | 2222 | return 0; |
2208 | 2223 | ||
2209 | return 1; | 2224 | return 1; |
2210 | } | 2225 | } |
2211 | 2226 | ||
2212 | static int referenced_filters(struct dyn_ftrace *rec) | 2227 | static int referenced_filters(struct dyn_ftrace *rec) |
2213 | { | 2228 | { |
2214 | struct ftrace_ops *ops; | 2229 | struct ftrace_ops *ops; |
2215 | int cnt = 0; | 2230 | int cnt = 0; |
2216 | 2231 | ||
2217 | for (ops = ftrace_ops_list; ops != &ftrace_list_end; ops = ops->next) { | 2232 | for (ops = ftrace_ops_list; ops != &ftrace_list_end; ops = ops->next) { |
2218 | if (ops_references_rec(ops, rec)) | 2233 | if (ops_references_rec(ops, rec)) |
2219 | cnt++; | 2234 | cnt++; |
2220 | } | 2235 | } |
2221 | 2236 | ||
2222 | return cnt; | 2237 | return cnt; |
2223 | } | 2238 | } |
2224 | 2239 | ||
2225 | static int ftrace_update_code(struct module *mod) | 2240 | static int ftrace_update_code(struct module *mod) |
2226 | { | 2241 | { |
2227 | struct ftrace_page *pg; | 2242 | struct ftrace_page *pg; |
2228 | struct dyn_ftrace *p; | 2243 | struct dyn_ftrace *p; |
2229 | cycle_t start, stop; | 2244 | cycle_t start, stop; |
2230 | unsigned long ref = 0; | 2245 | unsigned long ref = 0; |
2231 | bool test = false; | 2246 | bool test = false; |
2232 | int i; | 2247 | int i; |
2233 | 2248 | ||
2234 | /* | 2249 | /* |
2235 | * When adding a module, we need to check if tracers are | 2250 | * When adding a module, we need to check if tracers are |
2236 | * currently enabled and if they are set to trace all functions. | 2251 | * currently enabled and if they are set to trace all functions. |
2237 | * If they are, we need to enable the module functions as well | 2252 | * If they are, we need to enable the module functions as well |
2238 | * as update the reference counts for those function records. | 2253 | * as update the reference counts for those function records. |
2239 | */ | 2254 | */ |
2240 | if (mod) { | 2255 | if (mod) { |
2241 | struct ftrace_ops *ops; | 2256 | struct ftrace_ops *ops; |
2242 | 2257 | ||
2243 | for (ops = ftrace_ops_list; | 2258 | for (ops = ftrace_ops_list; |
2244 | ops != &ftrace_list_end; ops = ops->next) { | 2259 | ops != &ftrace_list_end; ops = ops->next) { |
2245 | if (ops->flags & FTRACE_OPS_FL_ENABLED) { | 2260 | if (ops->flags & FTRACE_OPS_FL_ENABLED) { |
2246 | if (ops_traces_mod(ops)) | 2261 | if (ops_traces_mod(ops)) |
2247 | ref++; | 2262 | ref++; |
2248 | else | 2263 | else |
2249 | test = true; | 2264 | test = true; |
2250 | } | 2265 | } |
2251 | } | 2266 | } |
2252 | } | 2267 | } |
2253 | 2268 | ||
2254 | start = ftrace_now(raw_smp_processor_id()); | 2269 | start = ftrace_now(raw_smp_processor_id()); |
2255 | ftrace_update_cnt = 0; | 2270 | ftrace_update_cnt = 0; |
2256 | 2271 | ||
2257 | for (pg = ftrace_new_pgs; pg; pg = pg->next) { | 2272 | for (pg = ftrace_new_pgs; pg; pg = pg->next) { |
2258 | 2273 | ||
2259 | for (i = 0; i < pg->index; i++) { | 2274 | for (i = 0; i < pg->index; i++) { |
2260 | int cnt = ref; | 2275 | int cnt = ref; |
2261 | 2276 | ||
2262 | /* If something went wrong, bail without enabling anything */ | 2277 | /* If something went wrong, bail without enabling anything */ |
2263 | if (unlikely(ftrace_disabled)) | 2278 | if (unlikely(ftrace_disabled)) |
2264 | return -1; | 2279 | return -1; |
2265 | 2280 | ||
2266 | p = &pg->records[i]; | 2281 | p = &pg->records[i]; |
2267 | if (test) | 2282 | if (test) |
2268 | cnt += referenced_filters(p); | 2283 | cnt += referenced_filters(p); |
2269 | p->flags = cnt; | 2284 | p->flags = cnt; |
2270 | 2285 | ||
2271 | /* | 2286 | /* |
2272 | * Do the initial record conversion from mcount jump | 2287 | * Do the initial record conversion from mcount jump |
2273 | * to the NOP instructions. | 2288 | * to the NOP instructions. |
2274 | */ | 2289 | */ |
2275 | if (!ftrace_code_disable(mod, p)) | 2290 | if (!ftrace_code_disable(mod, p)) |
2276 | break; | 2291 | break; |
2277 | 2292 | ||
2278 | ftrace_update_cnt++; | 2293 | ftrace_update_cnt++; |
2279 | 2294 | ||
2280 | /* | 2295 | /* |
2281 | * If the tracing is enabled, go ahead and enable the record. | 2296 | * If the tracing is enabled, go ahead and enable the record. |
2282 | * | 2297 | * |
2283 | * The reason not to enable the record immediatelly is the | 2298 | * The reason not to enable the record immediatelly is the |
2284 | * inherent check of ftrace_make_nop/ftrace_make_call for | 2299 | * inherent check of ftrace_make_nop/ftrace_make_call for |
2285 | * correct previous instructions. Making first the NOP | 2300 | * correct previous instructions. Making first the NOP |
2286 | * conversion puts the module to the correct state, thus | 2301 | * conversion puts the module to the correct state, thus |
2287 | * passing the ftrace_make_call check. | 2302 | * passing the ftrace_make_call check. |
2288 | */ | 2303 | */ |
2289 | if (ftrace_start_up && cnt) { | 2304 | if (ftrace_start_up && cnt) { |
2290 | int failed = __ftrace_replace_code(p, 1); | 2305 | int failed = __ftrace_replace_code(p, 1); |
2291 | if (failed) | 2306 | if (failed) |
2292 | ftrace_bug(failed, p->ip); | 2307 | ftrace_bug(failed, p->ip); |
2293 | } | 2308 | } |
2294 | } | 2309 | } |
2295 | } | 2310 | } |
2296 | 2311 | ||
2297 | ftrace_new_pgs = NULL; | 2312 | ftrace_new_pgs = NULL; |
2298 | 2313 | ||
2299 | stop = ftrace_now(raw_smp_processor_id()); | 2314 | stop = ftrace_now(raw_smp_processor_id()); |
2300 | ftrace_update_time = stop - start; | 2315 | ftrace_update_time = stop - start; |
2301 | ftrace_update_tot_cnt += ftrace_update_cnt; | 2316 | ftrace_update_tot_cnt += ftrace_update_cnt; |
2302 | 2317 | ||
2303 | return 0; | 2318 | return 0; |
2304 | } | 2319 | } |
2305 | 2320 | ||
2306 | static int ftrace_allocate_records(struct ftrace_page *pg, int count) | 2321 | static int ftrace_allocate_records(struct ftrace_page *pg, int count) |
2307 | { | 2322 | { |
2308 | int order; | 2323 | int order; |
2309 | int cnt; | 2324 | int cnt; |
2310 | 2325 | ||
2311 | if (WARN_ON(!count)) | 2326 | if (WARN_ON(!count)) |
2312 | return -EINVAL; | 2327 | return -EINVAL; |
2313 | 2328 | ||
2314 | order = get_count_order(DIV_ROUND_UP(count, ENTRIES_PER_PAGE)); | 2329 | order = get_count_order(DIV_ROUND_UP(count, ENTRIES_PER_PAGE)); |
2315 | 2330 | ||
2316 | /* | 2331 | /* |
2317 | * We want to fill as much as possible. No more than a page | 2332 | * We want to fill as much as possible. No more than a page |
2318 | * may be empty. | 2333 | * may be empty. |
2319 | */ | 2334 | */ |
2320 | while ((PAGE_SIZE << order) / ENTRY_SIZE >= count + ENTRIES_PER_PAGE) | 2335 | while ((PAGE_SIZE << order) / ENTRY_SIZE >= count + ENTRIES_PER_PAGE) |
2321 | order--; | 2336 | order--; |
2322 | 2337 | ||
2323 | again: | 2338 | again: |
2324 | pg->records = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); | 2339 | pg->records = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); |
2325 | 2340 | ||
2326 | if (!pg->records) { | 2341 | if (!pg->records) { |
2327 | /* if we can't allocate this size, try something smaller */ | 2342 | /* if we can't allocate this size, try something smaller */ |
2328 | if (!order) | 2343 | if (!order) |
2329 | return -ENOMEM; | 2344 | return -ENOMEM; |
2330 | order >>= 1; | 2345 | order >>= 1; |
2331 | goto again; | 2346 | goto again; |
2332 | } | 2347 | } |
2333 | 2348 | ||
2334 | cnt = (PAGE_SIZE << order) / ENTRY_SIZE; | 2349 | cnt = (PAGE_SIZE << order) / ENTRY_SIZE; |
2335 | pg->size = cnt; | 2350 | pg->size = cnt; |
2336 | 2351 | ||
2337 | if (cnt > count) | 2352 | if (cnt > count) |
2338 | cnt = count; | 2353 | cnt = count; |
2339 | 2354 | ||
2340 | return cnt; | 2355 | return cnt; |
2341 | } | 2356 | } |
2342 | 2357 | ||
2343 | static struct ftrace_page * | 2358 | static struct ftrace_page * |
2344 | ftrace_allocate_pages(unsigned long num_to_init) | 2359 | ftrace_allocate_pages(unsigned long num_to_init) |
2345 | { | 2360 | { |
2346 | struct ftrace_page *start_pg; | 2361 | struct ftrace_page *start_pg; |
2347 | struct ftrace_page *pg; | 2362 | struct ftrace_page *pg; |
2348 | int order; | 2363 | int order; |
2349 | int cnt; | 2364 | int cnt; |
2350 | 2365 | ||
2351 | if (!num_to_init) | 2366 | if (!num_to_init) |
2352 | return 0; | 2367 | return 0; |
2353 | 2368 | ||
2354 | start_pg = pg = kzalloc(sizeof(*pg), GFP_KERNEL); | 2369 | start_pg = pg = kzalloc(sizeof(*pg), GFP_KERNEL); |
2355 | if (!pg) | 2370 | if (!pg) |
2356 | return NULL; | 2371 | return NULL; |
2357 | 2372 | ||
2358 | /* | 2373 | /* |
2359 | * Try to allocate as much as possible in one continues | 2374 | * Try to allocate as much as possible in one continues |
2360 | * location that fills in all of the space. We want to | 2375 | * location that fills in all of the space. We want to |
2361 | * waste as little space as possible. | 2376 | * waste as little space as possible. |
2362 | */ | 2377 | */ |
2363 | for (;;) { | 2378 | for (;;) { |
2364 | cnt = ftrace_allocate_records(pg, num_to_init); | 2379 | cnt = ftrace_allocate_records(pg, num_to_init); |
2365 | if (cnt < 0) | 2380 | if (cnt < 0) |
2366 | goto free_pages; | 2381 | goto free_pages; |
2367 | 2382 | ||
2368 | num_to_init -= cnt; | 2383 | num_to_init -= cnt; |
2369 | if (!num_to_init) | 2384 | if (!num_to_init) |
2370 | break; | 2385 | break; |
2371 | 2386 | ||
2372 | pg->next = kzalloc(sizeof(*pg), GFP_KERNEL); | 2387 | pg->next = kzalloc(sizeof(*pg), GFP_KERNEL); |
2373 | if (!pg->next) | 2388 | if (!pg->next) |
2374 | goto free_pages; | 2389 | goto free_pages; |
2375 | 2390 | ||
2376 | pg = pg->next; | 2391 | pg = pg->next; |
2377 | } | 2392 | } |
2378 | 2393 | ||
2379 | return start_pg; | 2394 | return start_pg; |
2380 | 2395 | ||
2381 | free_pages: | 2396 | free_pages: |
2382 | while (start_pg) { | 2397 | while (start_pg) { |
2383 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); | 2398 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); |
2384 | free_pages((unsigned long)pg->records, order); | 2399 | free_pages((unsigned long)pg->records, order); |
2385 | start_pg = pg->next; | 2400 | start_pg = pg->next; |
2386 | kfree(pg); | 2401 | kfree(pg); |
2387 | pg = start_pg; | 2402 | pg = start_pg; |
2388 | } | 2403 | } |
2389 | pr_info("ftrace: FAILED to allocate memory for functions\n"); | 2404 | pr_info("ftrace: FAILED to allocate memory for functions\n"); |
2390 | return NULL; | 2405 | return NULL; |
2391 | } | 2406 | } |
2392 | 2407 | ||
2393 | static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) | 2408 | static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) |
2394 | { | 2409 | { |
2395 | int cnt; | 2410 | int cnt; |
2396 | 2411 | ||
2397 | if (!num_to_init) { | 2412 | if (!num_to_init) { |
2398 | pr_info("ftrace: No functions to be traced?\n"); | 2413 | pr_info("ftrace: No functions to be traced?\n"); |
2399 | return -1; | 2414 | return -1; |
2400 | } | 2415 | } |
2401 | 2416 | ||
2402 | cnt = num_to_init / ENTRIES_PER_PAGE; | 2417 | cnt = num_to_init / ENTRIES_PER_PAGE; |
2403 | pr_info("ftrace: allocating %ld entries in %d pages\n", | 2418 | pr_info("ftrace: allocating %ld entries in %d pages\n", |
2404 | num_to_init, cnt + 1); | 2419 | num_to_init, cnt + 1); |
2405 | 2420 | ||
2406 | return 0; | 2421 | return 0; |
2407 | } | 2422 | } |
2408 | 2423 | ||
2409 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ | 2424 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ |
2410 | 2425 | ||
2411 | struct ftrace_iterator { | 2426 | struct ftrace_iterator { |
2412 | loff_t pos; | 2427 | loff_t pos; |
2413 | loff_t func_pos; | 2428 | loff_t func_pos; |
2414 | struct ftrace_page *pg; | 2429 | struct ftrace_page *pg; |
2415 | struct dyn_ftrace *func; | 2430 | struct dyn_ftrace *func; |
2416 | struct ftrace_func_probe *probe; | 2431 | struct ftrace_func_probe *probe; |
2417 | struct trace_parser parser; | 2432 | struct trace_parser parser; |
2418 | struct ftrace_hash *hash; | 2433 | struct ftrace_hash *hash; |
2419 | struct ftrace_ops *ops; | 2434 | struct ftrace_ops *ops; |
2420 | int hidx; | 2435 | int hidx; |
2421 | int idx; | 2436 | int idx; |
2422 | unsigned flags; | 2437 | unsigned flags; |
2423 | }; | 2438 | }; |
2424 | 2439 | ||
2425 | static void * | 2440 | static void * |
2426 | t_hash_next(struct seq_file *m, loff_t *pos) | 2441 | t_hash_next(struct seq_file *m, loff_t *pos) |
2427 | { | 2442 | { |
2428 | struct ftrace_iterator *iter = m->private; | 2443 | struct ftrace_iterator *iter = m->private; |
2429 | struct hlist_node *hnd = NULL; | 2444 | struct hlist_node *hnd = NULL; |
2430 | struct hlist_head *hhd; | 2445 | struct hlist_head *hhd; |
2431 | 2446 | ||
2432 | (*pos)++; | 2447 | (*pos)++; |
2433 | iter->pos = *pos; | 2448 | iter->pos = *pos; |
2434 | 2449 | ||
2435 | if (iter->probe) | 2450 | if (iter->probe) |
2436 | hnd = &iter->probe->node; | 2451 | hnd = &iter->probe->node; |
2437 | retry: | 2452 | retry: |
2438 | if (iter->hidx >= FTRACE_FUNC_HASHSIZE) | 2453 | if (iter->hidx >= FTRACE_FUNC_HASHSIZE) |
2439 | return NULL; | 2454 | return NULL; |
2440 | 2455 | ||
2441 | hhd = &ftrace_func_hash[iter->hidx]; | 2456 | hhd = &ftrace_func_hash[iter->hidx]; |
2442 | 2457 | ||
2443 | if (hlist_empty(hhd)) { | 2458 | if (hlist_empty(hhd)) { |
2444 | iter->hidx++; | 2459 | iter->hidx++; |
2445 | hnd = NULL; | 2460 | hnd = NULL; |
2446 | goto retry; | 2461 | goto retry; |
2447 | } | 2462 | } |
2448 | 2463 | ||
2449 | if (!hnd) | 2464 | if (!hnd) |
2450 | hnd = hhd->first; | 2465 | hnd = hhd->first; |
2451 | else { | 2466 | else { |
2452 | hnd = hnd->next; | 2467 | hnd = hnd->next; |
2453 | if (!hnd) { | 2468 | if (!hnd) { |
2454 | iter->hidx++; | 2469 | iter->hidx++; |
2455 | goto retry; | 2470 | goto retry; |
2456 | } | 2471 | } |
2457 | } | 2472 | } |
2458 | 2473 | ||
2459 | if (WARN_ON_ONCE(!hnd)) | 2474 | if (WARN_ON_ONCE(!hnd)) |
2460 | return NULL; | 2475 | return NULL; |
2461 | 2476 | ||
2462 | iter->probe = hlist_entry(hnd, struct ftrace_func_probe, node); | 2477 | iter->probe = hlist_entry(hnd, struct ftrace_func_probe, node); |
2463 | 2478 | ||
2464 | return iter; | 2479 | return iter; |
2465 | } | 2480 | } |
2466 | 2481 | ||
2467 | static void *t_hash_start(struct seq_file *m, loff_t *pos) | 2482 | static void *t_hash_start(struct seq_file *m, loff_t *pos) |
2468 | { | 2483 | { |
2469 | struct ftrace_iterator *iter = m->private; | 2484 | struct ftrace_iterator *iter = m->private; |
2470 | void *p = NULL; | 2485 | void *p = NULL; |
2471 | loff_t l; | 2486 | loff_t l; |
2472 | 2487 | ||
2473 | if (!(iter->flags & FTRACE_ITER_DO_HASH)) | 2488 | if (!(iter->flags & FTRACE_ITER_DO_HASH)) |
2474 | return NULL; | 2489 | return NULL; |
2475 | 2490 | ||
2476 | if (iter->func_pos > *pos) | 2491 | if (iter->func_pos > *pos) |
2477 | return NULL; | 2492 | return NULL; |
2478 | 2493 | ||
2479 | iter->hidx = 0; | 2494 | iter->hidx = 0; |
2480 | for (l = 0; l <= (*pos - iter->func_pos); ) { | 2495 | for (l = 0; l <= (*pos - iter->func_pos); ) { |
2481 | p = t_hash_next(m, &l); | 2496 | p = t_hash_next(m, &l); |
2482 | if (!p) | 2497 | if (!p) |
2483 | break; | 2498 | break; |
2484 | } | 2499 | } |
2485 | if (!p) | 2500 | if (!p) |
2486 | return NULL; | 2501 | return NULL; |
2487 | 2502 | ||
2488 | /* Only set this if we have an item */ | 2503 | /* Only set this if we have an item */ |
2489 | iter->flags |= FTRACE_ITER_HASH; | 2504 | iter->flags |= FTRACE_ITER_HASH; |
2490 | 2505 | ||
2491 | return iter; | 2506 | return iter; |
2492 | } | 2507 | } |
2493 | 2508 | ||
2494 | static int | 2509 | static int |
2495 | t_hash_show(struct seq_file *m, struct ftrace_iterator *iter) | 2510 | t_hash_show(struct seq_file *m, struct ftrace_iterator *iter) |
2496 | { | 2511 | { |
2497 | struct ftrace_func_probe *rec; | 2512 | struct ftrace_func_probe *rec; |
2498 | 2513 | ||
2499 | rec = iter->probe; | 2514 | rec = iter->probe; |
2500 | if (WARN_ON_ONCE(!rec)) | 2515 | if (WARN_ON_ONCE(!rec)) |
2501 | return -EIO; | 2516 | return -EIO; |
2502 | 2517 | ||
2503 | if (rec->ops->print) | 2518 | if (rec->ops->print) |
2504 | return rec->ops->print(m, rec->ip, rec->ops, rec->data); | 2519 | return rec->ops->print(m, rec->ip, rec->ops, rec->data); |
2505 | 2520 | ||
2506 | seq_printf(m, "%ps:%ps", (void *)rec->ip, (void *)rec->ops->func); | 2521 | seq_printf(m, "%ps:%ps", (void *)rec->ip, (void *)rec->ops->func); |
2507 | 2522 | ||
2508 | if (rec->data) | 2523 | if (rec->data) |
2509 | seq_printf(m, ":%p", rec->data); | 2524 | seq_printf(m, ":%p", rec->data); |
2510 | seq_putc(m, '\n'); | 2525 | seq_putc(m, '\n'); |
2511 | 2526 | ||
2512 | return 0; | 2527 | return 0; |
2513 | } | 2528 | } |
2514 | 2529 | ||
2515 | static void * | 2530 | static void * |
2516 | t_next(struct seq_file *m, void *v, loff_t *pos) | 2531 | t_next(struct seq_file *m, void *v, loff_t *pos) |
2517 | { | 2532 | { |
2518 | struct ftrace_iterator *iter = m->private; | 2533 | struct ftrace_iterator *iter = m->private; |
2519 | struct ftrace_ops *ops = iter->ops; | 2534 | struct ftrace_ops *ops = iter->ops; |
2520 | struct dyn_ftrace *rec = NULL; | 2535 | struct dyn_ftrace *rec = NULL; |
2521 | 2536 | ||
2522 | if (unlikely(ftrace_disabled)) | 2537 | if (unlikely(ftrace_disabled)) |
2523 | return NULL; | 2538 | return NULL; |
2524 | 2539 | ||
2525 | if (iter->flags & FTRACE_ITER_HASH) | 2540 | if (iter->flags & FTRACE_ITER_HASH) |
2526 | return t_hash_next(m, pos); | 2541 | return t_hash_next(m, pos); |
2527 | 2542 | ||
2528 | (*pos)++; | 2543 | (*pos)++; |
2529 | iter->pos = iter->func_pos = *pos; | 2544 | iter->pos = iter->func_pos = *pos; |
2530 | 2545 | ||
2531 | if (iter->flags & FTRACE_ITER_PRINTALL) | 2546 | if (iter->flags & FTRACE_ITER_PRINTALL) |
2532 | return t_hash_start(m, pos); | 2547 | return t_hash_start(m, pos); |
2533 | 2548 | ||
2534 | retry: | 2549 | retry: |
2535 | if (iter->idx >= iter->pg->index) { | 2550 | if (iter->idx >= iter->pg->index) { |
2536 | if (iter->pg->next) { | 2551 | if (iter->pg->next) { |
2537 | iter->pg = iter->pg->next; | 2552 | iter->pg = iter->pg->next; |
2538 | iter->idx = 0; | 2553 | iter->idx = 0; |
2539 | goto retry; | 2554 | goto retry; |
2540 | } | 2555 | } |
2541 | } else { | 2556 | } else { |
2542 | rec = &iter->pg->records[iter->idx++]; | 2557 | rec = &iter->pg->records[iter->idx++]; |
2543 | if (((iter->flags & FTRACE_ITER_FILTER) && | 2558 | if (((iter->flags & FTRACE_ITER_FILTER) && |
2544 | !(ftrace_lookup_ip(ops->filter_hash, rec->ip))) || | 2559 | !(ftrace_lookup_ip(ops->filter_hash, rec->ip))) || |
2545 | 2560 | ||
2546 | ((iter->flags & FTRACE_ITER_NOTRACE) && | 2561 | ((iter->flags & FTRACE_ITER_NOTRACE) && |
2547 | !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) || | 2562 | !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) || |
2548 | 2563 | ||
2549 | ((iter->flags & FTRACE_ITER_ENABLED) && | 2564 | ((iter->flags & FTRACE_ITER_ENABLED) && |
2550 | !(rec->flags & FTRACE_FL_ENABLED))) { | 2565 | !(rec->flags & FTRACE_FL_ENABLED))) { |
2551 | 2566 | ||
2552 | rec = NULL; | 2567 | rec = NULL; |
2553 | goto retry; | 2568 | goto retry; |
2554 | } | 2569 | } |
2555 | } | 2570 | } |
2556 | 2571 | ||
2557 | if (!rec) | 2572 | if (!rec) |
2558 | return t_hash_start(m, pos); | 2573 | return t_hash_start(m, pos); |
2559 | 2574 | ||
2560 | iter->func = rec; | 2575 | iter->func = rec; |
2561 | 2576 | ||
2562 | return iter; | 2577 | return iter; |
2563 | } | 2578 | } |
2564 | 2579 | ||
2565 | static void reset_iter_read(struct ftrace_iterator *iter) | 2580 | static void reset_iter_read(struct ftrace_iterator *iter) |
2566 | { | 2581 | { |
2567 | iter->pos = 0; | 2582 | iter->pos = 0; |
2568 | iter->func_pos = 0; | 2583 | iter->func_pos = 0; |
2569 | iter->flags &= ~(FTRACE_ITER_PRINTALL | FTRACE_ITER_HASH); | 2584 | iter->flags &= ~(FTRACE_ITER_PRINTALL | FTRACE_ITER_HASH); |
2570 | } | 2585 | } |
2571 | 2586 | ||
2572 | static void *t_start(struct seq_file *m, loff_t *pos) | 2587 | static void *t_start(struct seq_file *m, loff_t *pos) |
2573 | { | 2588 | { |
2574 | struct ftrace_iterator *iter = m->private; | 2589 | struct ftrace_iterator *iter = m->private; |
2575 | struct ftrace_ops *ops = iter->ops; | 2590 | struct ftrace_ops *ops = iter->ops; |
2576 | void *p = NULL; | 2591 | void *p = NULL; |
2577 | loff_t l; | 2592 | loff_t l; |
2578 | 2593 | ||
2579 | mutex_lock(&ftrace_lock); | 2594 | mutex_lock(&ftrace_lock); |
2580 | 2595 | ||
2581 | if (unlikely(ftrace_disabled)) | 2596 | if (unlikely(ftrace_disabled)) |
2582 | return NULL; | 2597 | return NULL; |
2583 | 2598 | ||
2584 | /* | 2599 | /* |
2585 | * If an lseek was done, then reset and start from beginning. | 2600 | * If an lseek was done, then reset and start from beginning. |
2586 | */ | 2601 | */ |
2587 | if (*pos < iter->pos) | 2602 | if (*pos < iter->pos) |
2588 | reset_iter_read(iter); | 2603 | reset_iter_read(iter); |
2589 | 2604 | ||
2590 | /* | 2605 | /* |
2591 | * For set_ftrace_filter reading, if we have the filter | 2606 | * For set_ftrace_filter reading, if we have the filter |
2592 | * off, we can short cut and just print out that all | 2607 | * off, we can short cut and just print out that all |
2593 | * functions are enabled. | 2608 | * functions are enabled. |
2594 | */ | 2609 | */ |
2595 | if (iter->flags & FTRACE_ITER_FILTER && | 2610 | if (iter->flags & FTRACE_ITER_FILTER && |
2596 | ftrace_hash_empty(ops->filter_hash)) { | 2611 | ftrace_hash_empty(ops->filter_hash)) { |
2597 | if (*pos > 0) | 2612 | if (*pos > 0) |
2598 | return t_hash_start(m, pos); | 2613 | return t_hash_start(m, pos); |
2599 | iter->flags |= FTRACE_ITER_PRINTALL; | 2614 | iter->flags |= FTRACE_ITER_PRINTALL; |
2600 | /* reset in case of seek/pread */ | 2615 | /* reset in case of seek/pread */ |
2601 | iter->flags &= ~FTRACE_ITER_HASH; | 2616 | iter->flags &= ~FTRACE_ITER_HASH; |
2602 | return iter; | 2617 | return iter; |
2603 | } | 2618 | } |
2604 | 2619 | ||
2605 | if (iter->flags & FTRACE_ITER_HASH) | 2620 | if (iter->flags & FTRACE_ITER_HASH) |
2606 | return t_hash_start(m, pos); | 2621 | return t_hash_start(m, pos); |
2607 | 2622 | ||
2608 | /* | 2623 | /* |
2609 | * Unfortunately, we need to restart at ftrace_pages_start | 2624 | * Unfortunately, we need to restart at ftrace_pages_start |
2610 | * every time we let go of the ftrace_mutex. This is because | 2625 | * every time we let go of the ftrace_mutex. This is because |
2611 | * those pointers can change without the lock. | 2626 | * those pointers can change without the lock. |
2612 | */ | 2627 | */ |
2613 | iter->pg = ftrace_pages_start; | 2628 | iter->pg = ftrace_pages_start; |
2614 | iter->idx = 0; | 2629 | iter->idx = 0; |
2615 | for (l = 0; l <= *pos; ) { | 2630 | for (l = 0; l <= *pos; ) { |
2616 | p = t_next(m, p, &l); | 2631 | p = t_next(m, p, &l); |
2617 | if (!p) | 2632 | if (!p) |
2618 | break; | 2633 | break; |
2619 | } | 2634 | } |
2620 | 2635 | ||
2621 | if (!p) | 2636 | if (!p) |
2622 | return t_hash_start(m, pos); | 2637 | return t_hash_start(m, pos); |
2623 | 2638 | ||
2624 | return iter; | 2639 | return iter; |
2625 | } | 2640 | } |
2626 | 2641 | ||
2627 | static void t_stop(struct seq_file *m, void *p) | 2642 | static void t_stop(struct seq_file *m, void *p) |
2628 | { | 2643 | { |
2629 | mutex_unlock(&ftrace_lock); | 2644 | mutex_unlock(&ftrace_lock); |
2630 | } | 2645 | } |
2631 | 2646 | ||
2632 | static int t_show(struct seq_file *m, void *v) | 2647 | static int t_show(struct seq_file *m, void *v) |
2633 | { | 2648 | { |
2634 | struct ftrace_iterator *iter = m->private; | 2649 | struct ftrace_iterator *iter = m->private; |
2635 | struct dyn_ftrace *rec; | 2650 | struct dyn_ftrace *rec; |
2636 | 2651 | ||
2637 | if (iter->flags & FTRACE_ITER_HASH) | 2652 | if (iter->flags & FTRACE_ITER_HASH) |
2638 | return t_hash_show(m, iter); | 2653 | return t_hash_show(m, iter); |
2639 | 2654 | ||
2640 | if (iter->flags & FTRACE_ITER_PRINTALL) { | 2655 | if (iter->flags & FTRACE_ITER_PRINTALL) { |
2641 | seq_printf(m, "#### all functions enabled ####\n"); | 2656 | seq_printf(m, "#### all functions enabled ####\n"); |
2642 | return 0; | 2657 | return 0; |
2643 | } | 2658 | } |
2644 | 2659 | ||
2645 | rec = iter->func; | 2660 | rec = iter->func; |
2646 | 2661 | ||
2647 | if (!rec) | 2662 | if (!rec) |
2648 | return 0; | 2663 | return 0; |
2649 | 2664 | ||
2650 | seq_printf(m, "%ps", (void *)rec->ip); | 2665 | seq_printf(m, "%ps", (void *)rec->ip); |
2651 | if (iter->flags & FTRACE_ITER_ENABLED) | 2666 | if (iter->flags & FTRACE_ITER_ENABLED) |
2652 | seq_printf(m, " (%ld)%s", | 2667 | seq_printf(m, " (%ld)%s", |
2653 | rec->flags & ~FTRACE_FL_MASK, | 2668 | rec->flags & ~FTRACE_FL_MASK, |
2654 | rec->flags & FTRACE_FL_REGS ? " R" : ""); | 2669 | rec->flags & FTRACE_FL_REGS ? " R" : ""); |
2655 | seq_printf(m, "\n"); | 2670 | seq_printf(m, "\n"); |
2656 | 2671 | ||
2657 | return 0; | 2672 | return 0; |
2658 | } | 2673 | } |
2659 | 2674 | ||
2660 | static const struct seq_operations show_ftrace_seq_ops = { | 2675 | static const struct seq_operations show_ftrace_seq_ops = { |
2661 | .start = t_start, | 2676 | .start = t_start, |
2662 | .next = t_next, | 2677 | .next = t_next, |
2663 | .stop = t_stop, | 2678 | .stop = t_stop, |
2664 | .show = t_show, | 2679 | .show = t_show, |
2665 | }; | 2680 | }; |
2666 | 2681 | ||
2667 | static int | 2682 | static int |
2668 | ftrace_avail_open(struct inode *inode, struct file *file) | 2683 | ftrace_avail_open(struct inode *inode, struct file *file) |
2669 | { | 2684 | { |
2670 | struct ftrace_iterator *iter; | 2685 | struct ftrace_iterator *iter; |
2671 | 2686 | ||
2672 | if (unlikely(ftrace_disabled)) | 2687 | if (unlikely(ftrace_disabled)) |
2673 | return -ENODEV; | 2688 | return -ENODEV; |
2674 | 2689 | ||
2675 | iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); | 2690 | iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); |
2676 | if (iter) { | 2691 | if (iter) { |
2677 | iter->pg = ftrace_pages_start; | 2692 | iter->pg = ftrace_pages_start; |
2678 | iter->ops = &global_ops; | 2693 | iter->ops = &global_ops; |
2679 | } | 2694 | } |
2680 | 2695 | ||
2681 | return iter ? 0 : -ENOMEM; | 2696 | return iter ? 0 : -ENOMEM; |
2682 | } | 2697 | } |
2683 | 2698 | ||
2684 | static int | 2699 | static int |
2685 | ftrace_enabled_open(struct inode *inode, struct file *file) | 2700 | ftrace_enabled_open(struct inode *inode, struct file *file) |
2686 | { | 2701 | { |
2687 | struct ftrace_iterator *iter; | 2702 | struct ftrace_iterator *iter; |
2688 | 2703 | ||
2689 | if (unlikely(ftrace_disabled)) | 2704 | if (unlikely(ftrace_disabled)) |
2690 | return -ENODEV; | 2705 | return -ENODEV; |
2691 | 2706 | ||
2692 | iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); | 2707 | iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); |
2693 | if (iter) { | 2708 | if (iter) { |
2694 | iter->pg = ftrace_pages_start; | 2709 | iter->pg = ftrace_pages_start; |
2695 | iter->flags = FTRACE_ITER_ENABLED; | 2710 | iter->flags = FTRACE_ITER_ENABLED; |
2696 | iter->ops = &global_ops; | 2711 | iter->ops = &global_ops; |
2697 | } | 2712 | } |
2698 | 2713 | ||
2699 | return iter ? 0 : -ENOMEM; | 2714 | return iter ? 0 : -ENOMEM; |
2700 | } | 2715 | } |
2701 | 2716 | ||
2702 | static void ftrace_filter_reset(struct ftrace_hash *hash) | 2717 | static void ftrace_filter_reset(struct ftrace_hash *hash) |
2703 | { | 2718 | { |
2704 | mutex_lock(&ftrace_lock); | 2719 | mutex_lock(&ftrace_lock); |
2705 | ftrace_hash_clear(hash); | 2720 | ftrace_hash_clear(hash); |
2706 | mutex_unlock(&ftrace_lock); | 2721 | mutex_unlock(&ftrace_lock); |
2707 | } | 2722 | } |
2708 | 2723 | ||
2709 | /** | 2724 | /** |
2710 | * ftrace_regex_open - initialize function tracer filter files | 2725 | * ftrace_regex_open - initialize function tracer filter files |
2711 | * @ops: The ftrace_ops that hold the hash filters | 2726 | * @ops: The ftrace_ops that hold the hash filters |
2712 | * @flag: The type of filter to process | 2727 | * @flag: The type of filter to process |
2713 | * @inode: The inode, usually passed in to your open routine | 2728 | * @inode: The inode, usually passed in to your open routine |
2714 | * @file: The file, usually passed in to your open routine | 2729 | * @file: The file, usually passed in to your open routine |
2715 | * | 2730 | * |
2716 | * ftrace_regex_open() initializes the filter files for the | 2731 | * ftrace_regex_open() initializes the filter files for the |
2717 | * @ops. Depending on @flag it may process the filter hash or | 2732 | * @ops. Depending on @flag it may process the filter hash or |
2718 | * the notrace hash of @ops. With this called from the open | 2733 | * the notrace hash of @ops. With this called from the open |
2719 | * routine, you can use ftrace_filter_write() for the write | 2734 | * routine, you can use ftrace_filter_write() for the write |
2720 | * routine if @flag has FTRACE_ITER_FILTER set, or | 2735 | * routine if @flag has FTRACE_ITER_FILTER set, or |
2721 | * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set. | 2736 | * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set. |
2722 | * ftrace_filter_lseek() should be used as the lseek routine, and | 2737 | * ftrace_filter_lseek() should be used as the lseek routine, and |
2723 | * release must call ftrace_regex_release(). | 2738 | * release must call ftrace_regex_release(). |
2724 | */ | 2739 | */ |
2725 | int | 2740 | int |
2726 | ftrace_regex_open(struct ftrace_ops *ops, int flag, | 2741 | ftrace_regex_open(struct ftrace_ops *ops, int flag, |
2727 | struct inode *inode, struct file *file) | 2742 | struct inode *inode, struct file *file) |
2728 | { | 2743 | { |
2729 | struct ftrace_iterator *iter; | 2744 | struct ftrace_iterator *iter; |
2730 | struct ftrace_hash *hash; | 2745 | struct ftrace_hash *hash; |
2731 | int ret = 0; | 2746 | int ret = 0; |
2732 | 2747 | ||
2733 | ftrace_ops_init(ops); | 2748 | ftrace_ops_init(ops); |
2734 | 2749 | ||
2735 | if (unlikely(ftrace_disabled)) | 2750 | if (unlikely(ftrace_disabled)) |
2736 | return -ENODEV; | 2751 | return -ENODEV; |
2737 | 2752 | ||
2738 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 2753 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
2739 | if (!iter) | 2754 | if (!iter) |
2740 | return -ENOMEM; | 2755 | return -ENOMEM; |
2741 | 2756 | ||
2742 | if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) { | 2757 | if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) { |
2743 | kfree(iter); | 2758 | kfree(iter); |
2744 | return -ENOMEM; | 2759 | return -ENOMEM; |
2745 | } | 2760 | } |
2746 | 2761 | ||
2747 | iter->ops = ops; | 2762 | iter->ops = ops; |
2748 | iter->flags = flag; | 2763 | iter->flags = flag; |
2749 | 2764 | ||
2750 | mutex_lock(&ops->regex_lock); | 2765 | mutex_lock(&ops->regex_lock); |
2751 | 2766 | ||
2752 | if (flag & FTRACE_ITER_NOTRACE) | 2767 | if (flag & FTRACE_ITER_NOTRACE) |
2753 | hash = ops->notrace_hash; | 2768 | hash = ops->notrace_hash; |
2754 | else | 2769 | else |
2755 | hash = ops->filter_hash; | 2770 | hash = ops->filter_hash; |
2756 | 2771 | ||
2757 | if (file->f_mode & FMODE_WRITE) { | 2772 | if (file->f_mode & FMODE_WRITE) { |
2758 | iter->hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, hash); | 2773 | iter->hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, hash); |
2759 | if (!iter->hash) { | 2774 | if (!iter->hash) { |
2760 | trace_parser_put(&iter->parser); | 2775 | trace_parser_put(&iter->parser); |
2761 | kfree(iter); | 2776 | kfree(iter); |
2762 | ret = -ENOMEM; | 2777 | ret = -ENOMEM; |
2763 | goto out_unlock; | 2778 | goto out_unlock; |
2764 | } | 2779 | } |
2765 | } | 2780 | } |
2766 | 2781 | ||
2767 | if ((file->f_mode & FMODE_WRITE) && | 2782 | if ((file->f_mode & FMODE_WRITE) && |
2768 | (file->f_flags & O_TRUNC)) | 2783 | (file->f_flags & O_TRUNC)) |
2769 | ftrace_filter_reset(iter->hash); | 2784 | ftrace_filter_reset(iter->hash); |
2770 | 2785 | ||
2771 | if (file->f_mode & FMODE_READ) { | 2786 | if (file->f_mode & FMODE_READ) { |
2772 | iter->pg = ftrace_pages_start; | 2787 | iter->pg = ftrace_pages_start; |
2773 | 2788 | ||
2774 | ret = seq_open(file, &show_ftrace_seq_ops); | 2789 | ret = seq_open(file, &show_ftrace_seq_ops); |
2775 | if (!ret) { | 2790 | if (!ret) { |
2776 | struct seq_file *m = file->private_data; | 2791 | struct seq_file *m = file->private_data; |
2777 | m->private = iter; | 2792 | m->private = iter; |
2778 | } else { | 2793 | } else { |
2779 | /* Failed */ | 2794 | /* Failed */ |
2780 | free_ftrace_hash(iter->hash); | 2795 | free_ftrace_hash(iter->hash); |
2781 | trace_parser_put(&iter->parser); | 2796 | trace_parser_put(&iter->parser); |
2782 | kfree(iter); | 2797 | kfree(iter); |
2783 | } | 2798 | } |
2784 | } else | 2799 | } else |
2785 | file->private_data = iter; | 2800 | file->private_data = iter; |
2786 | 2801 | ||
2787 | out_unlock: | 2802 | out_unlock: |
2788 | mutex_unlock(&ops->regex_lock); | 2803 | mutex_unlock(&ops->regex_lock); |
2789 | 2804 | ||
2790 | return ret; | 2805 | return ret; |
2791 | } | 2806 | } |
2792 | 2807 | ||
2793 | static int | 2808 | static int |
2794 | ftrace_filter_open(struct inode *inode, struct file *file) | 2809 | ftrace_filter_open(struct inode *inode, struct file *file) |
2795 | { | 2810 | { |
2796 | return ftrace_regex_open(&global_ops, | 2811 | return ftrace_regex_open(&global_ops, |
2797 | FTRACE_ITER_FILTER | FTRACE_ITER_DO_HASH, | 2812 | FTRACE_ITER_FILTER | FTRACE_ITER_DO_HASH, |
2798 | inode, file); | 2813 | inode, file); |
2799 | } | 2814 | } |
2800 | 2815 | ||
2801 | static int | 2816 | static int |
2802 | ftrace_notrace_open(struct inode *inode, struct file *file) | 2817 | ftrace_notrace_open(struct inode *inode, struct file *file) |
2803 | { | 2818 | { |
2804 | return ftrace_regex_open(&global_ops, FTRACE_ITER_NOTRACE, | 2819 | return ftrace_regex_open(&global_ops, FTRACE_ITER_NOTRACE, |
2805 | inode, file); | 2820 | inode, file); |
2806 | } | 2821 | } |
2807 | 2822 | ||
2808 | static int ftrace_match(char *str, char *regex, int len, int type) | 2823 | static int ftrace_match(char *str, char *regex, int len, int type) |
2809 | { | 2824 | { |
2810 | int matched = 0; | 2825 | int matched = 0; |
2811 | int slen; | 2826 | int slen; |
2812 | 2827 | ||
2813 | switch (type) { | 2828 | switch (type) { |
2814 | case MATCH_FULL: | 2829 | case MATCH_FULL: |
2815 | if (strcmp(str, regex) == 0) | 2830 | if (strcmp(str, regex) == 0) |
2816 | matched = 1; | 2831 | matched = 1; |
2817 | break; | 2832 | break; |
2818 | case MATCH_FRONT_ONLY: | 2833 | case MATCH_FRONT_ONLY: |
2819 | if (strncmp(str, regex, len) == 0) | 2834 | if (strncmp(str, regex, len) == 0) |
2820 | matched = 1; | 2835 | matched = 1; |
2821 | break; | 2836 | break; |
2822 | case MATCH_MIDDLE_ONLY: | 2837 | case MATCH_MIDDLE_ONLY: |
2823 | if (strstr(str, regex)) | 2838 | if (strstr(str, regex)) |
2824 | matched = 1; | 2839 | matched = 1; |
2825 | break; | 2840 | break; |
2826 | case MATCH_END_ONLY: | 2841 | case MATCH_END_ONLY: |
2827 | slen = strlen(str); | 2842 | slen = strlen(str); |
2828 | if (slen >= len && memcmp(str + slen - len, regex, len) == 0) | 2843 | if (slen >= len && memcmp(str + slen - len, regex, len) == 0) |
2829 | matched = 1; | 2844 | matched = 1; |
2830 | break; | 2845 | break; |
2831 | } | 2846 | } |
2832 | 2847 | ||
2833 | return matched; | 2848 | return matched; |
2834 | } | 2849 | } |
2835 | 2850 | ||
2836 | static int | 2851 | static int |
2837 | enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int not) | 2852 | enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int not) |
2838 | { | 2853 | { |
2839 | struct ftrace_func_entry *entry; | 2854 | struct ftrace_func_entry *entry; |
2840 | int ret = 0; | 2855 | int ret = 0; |
2841 | 2856 | ||
2842 | entry = ftrace_lookup_ip(hash, rec->ip); | 2857 | entry = ftrace_lookup_ip(hash, rec->ip); |
2843 | if (not) { | 2858 | if (not) { |
2844 | /* Do nothing if it doesn't exist */ | 2859 | /* Do nothing if it doesn't exist */ |
2845 | if (!entry) | 2860 | if (!entry) |
2846 | return 0; | 2861 | return 0; |
2847 | 2862 | ||
2848 | free_hash_entry(hash, entry); | 2863 | free_hash_entry(hash, entry); |
2849 | } else { | 2864 | } else { |
2850 | /* Do nothing if it exists */ | 2865 | /* Do nothing if it exists */ |
2851 | if (entry) | 2866 | if (entry) |
2852 | return 0; | 2867 | return 0; |
2853 | 2868 | ||
2854 | ret = add_hash_entry(hash, rec->ip); | 2869 | ret = add_hash_entry(hash, rec->ip); |
2855 | } | 2870 | } |
2856 | return ret; | 2871 | return ret; |
2857 | } | 2872 | } |
2858 | 2873 | ||
2859 | static int | 2874 | static int |
2860 | ftrace_match_record(struct dyn_ftrace *rec, char *mod, | 2875 | ftrace_match_record(struct dyn_ftrace *rec, char *mod, |
2861 | char *regex, int len, int type) | 2876 | char *regex, int len, int type) |
2862 | { | 2877 | { |
2863 | char str[KSYM_SYMBOL_LEN]; | 2878 | char str[KSYM_SYMBOL_LEN]; |
2864 | char *modname; | 2879 | char *modname; |
2865 | 2880 | ||
2866 | kallsyms_lookup(rec->ip, NULL, NULL, &modname, str); | 2881 | kallsyms_lookup(rec->ip, NULL, NULL, &modname, str); |
2867 | 2882 | ||
2868 | if (mod) { | 2883 | if (mod) { |
2869 | /* module lookup requires matching the module */ | 2884 | /* module lookup requires matching the module */ |
2870 | if (!modname || strcmp(modname, mod)) | 2885 | if (!modname || strcmp(modname, mod)) |
2871 | return 0; | 2886 | return 0; |
2872 | 2887 | ||
2873 | /* blank search means to match all funcs in the mod */ | 2888 | /* blank search means to match all funcs in the mod */ |
2874 | if (!len) | 2889 | if (!len) |
2875 | return 1; | 2890 | return 1; |
2876 | } | 2891 | } |
2877 | 2892 | ||
2878 | return ftrace_match(str, regex, len, type); | 2893 | return ftrace_match(str, regex, len, type); |
2879 | } | 2894 | } |
2880 | 2895 | ||
2881 | static int | 2896 | static int |
2882 | match_records(struct ftrace_hash *hash, char *buff, | 2897 | match_records(struct ftrace_hash *hash, char *buff, |
2883 | int len, char *mod, int not) | 2898 | int len, char *mod, int not) |
2884 | { | 2899 | { |
2885 | unsigned search_len = 0; | 2900 | unsigned search_len = 0; |
2886 | struct ftrace_page *pg; | 2901 | struct ftrace_page *pg; |
2887 | struct dyn_ftrace *rec; | 2902 | struct dyn_ftrace *rec; |
2888 | int type = MATCH_FULL; | 2903 | int type = MATCH_FULL; |
2889 | char *search = buff; | 2904 | char *search = buff; |
2890 | int found = 0; | 2905 | int found = 0; |
2891 | int ret; | 2906 | int ret; |
2892 | 2907 | ||
2893 | if (len) { | 2908 | if (len) { |
2894 | type = filter_parse_regex(buff, len, &search, ¬); | 2909 | type = filter_parse_regex(buff, len, &search, ¬); |
2895 | search_len = strlen(search); | 2910 | search_len = strlen(search); |
2896 | } | 2911 | } |
2897 | 2912 | ||
2898 | mutex_lock(&ftrace_lock); | 2913 | mutex_lock(&ftrace_lock); |
2899 | 2914 | ||
2900 | if (unlikely(ftrace_disabled)) | 2915 | if (unlikely(ftrace_disabled)) |
2901 | goto out_unlock; | 2916 | goto out_unlock; |
2902 | 2917 | ||
2903 | do_for_each_ftrace_rec(pg, rec) { | 2918 | do_for_each_ftrace_rec(pg, rec) { |
2904 | if (ftrace_match_record(rec, mod, search, search_len, type)) { | 2919 | if (ftrace_match_record(rec, mod, search, search_len, type)) { |
2905 | ret = enter_record(hash, rec, not); | 2920 | ret = enter_record(hash, rec, not); |
2906 | if (ret < 0) { | 2921 | if (ret < 0) { |
2907 | found = ret; | 2922 | found = ret; |
2908 | goto out_unlock; | 2923 | goto out_unlock; |
2909 | } | 2924 | } |
2910 | found = 1; | 2925 | found = 1; |
2911 | } | 2926 | } |
2912 | } while_for_each_ftrace_rec(); | 2927 | } while_for_each_ftrace_rec(); |
2913 | out_unlock: | 2928 | out_unlock: |
2914 | mutex_unlock(&ftrace_lock); | 2929 | mutex_unlock(&ftrace_lock); |
2915 | 2930 | ||
2916 | return found; | 2931 | return found; |
2917 | } | 2932 | } |
2918 | 2933 | ||
2919 | static int | 2934 | static int |
2920 | ftrace_match_records(struct ftrace_hash *hash, char *buff, int len) | 2935 | ftrace_match_records(struct ftrace_hash *hash, char *buff, int len) |
2921 | { | 2936 | { |
2922 | return match_records(hash, buff, len, NULL, 0); | 2937 | return match_records(hash, buff, len, NULL, 0); |
2923 | } | 2938 | } |
2924 | 2939 | ||
2925 | static int | 2940 | static int |
2926 | ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod) | 2941 | ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod) |
2927 | { | 2942 | { |
2928 | int not = 0; | 2943 | int not = 0; |
2929 | 2944 | ||
2930 | /* blank or '*' mean the same */ | 2945 | /* blank or '*' mean the same */ |
2931 | if (strcmp(buff, "*") == 0) | 2946 | if (strcmp(buff, "*") == 0) |
2932 | buff[0] = 0; | 2947 | buff[0] = 0; |
2933 | 2948 | ||
2934 | /* handle the case of 'dont filter this module' */ | 2949 | /* handle the case of 'dont filter this module' */ |
2935 | if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) { | 2950 | if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) { |
2936 | buff[0] = 0; | 2951 | buff[0] = 0; |
2937 | not = 1; | 2952 | not = 1; |
2938 | } | 2953 | } |
2939 | 2954 | ||
2940 | return match_records(hash, buff, strlen(buff), mod, not); | 2955 | return match_records(hash, buff, strlen(buff), mod, not); |
2941 | } | 2956 | } |
2942 | 2957 | ||
2943 | /* | 2958 | /* |
2944 | * We register the module command as a template to show others how | 2959 | * We register the module command as a template to show others how |
2945 | * to register the a command as well. | 2960 | * to register the a command as well. |
2946 | */ | 2961 | */ |
2947 | 2962 | ||
2948 | static int | 2963 | static int |
2949 | ftrace_mod_callback(struct ftrace_hash *hash, | 2964 | ftrace_mod_callback(struct ftrace_hash *hash, |
2950 | char *func, char *cmd, char *param, int enable) | 2965 | char *func, char *cmd, char *param, int enable) |
2951 | { | 2966 | { |
2952 | char *mod; | 2967 | char *mod; |
2953 | int ret = -EINVAL; | 2968 | int ret = -EINVAL; |
2954 | 2969 | ||
2955 | /* | 2970 | /* |
2956 | * cmd == 'mod' because we only registered this func | 2971 | * cmd == 'mod' because we only registered this func |
2957 | * for the 'mod' ftrace_func_command. | 2972 | * for the 'mod' ftrace_func_command. |
2958 | * But if you register one func with multiple commands, | 2973 | * But if you register one func with multiple commands, |
2959 | * you can tell which command was used by the cmd | 2974 | * you can tell which command was used by the cmd |
2960 | * parameter. | 2975 | * parameter. |
2961 | */ | 2976 | */ |
2962 | 2977 | ||
2963 | /* we must have a module name */ | 2978 | /* we must have a module name */ |
2964 | if (!param) | 2979 | if (!param) |
2965 | return ret; | 2980 | return ret; |
2966 | 2981 | ||
2967 | mod = strsep(¶m, ":"); | 2982 | mod = strsep(¶m, ":"); |
2968 | if (!strlen(mod)) | 2983 | if (!strlen(mod)) |
2969 | return ret; | 2984 | return ret; |
2970 | 2985 | ||
2971 | ret = ftrace_match_module_records(hash, func, mod); | 2986 | ret = ftrace_match_module_records(hash, func, mod); |
2972 | if (!ret) | 2987 | if (!ret) |
2973 | ret = -EINVAL; | 2988 | ret = -EINVAL; |
2974 | if (ret < 0) | 2989 | if (ret < 0) |
2975 | return ret; | 2990 | return ret; |
2976 | 2991 | ||
2977 | return 0; | 2992 | return 0; |
2978 | } | 2993 | } |
2979 | 2994 | ||
2980 | static struct ftrace_func_command ftrace_mod_cmd = { | 2995 | static struct ftrace_func_command ftrace_mod_cmd = { |
2981 | .name = "mod", | 2996 | .name = "mod", |
2982 | .func = ftrace_mod_callback, | 2997 | .func = ftrace_mod_callback, |
2983 | }; | 2998 | }; |
2984 | 2999 | ||
2985 | static int __init ftrace_mod_cmd_init(void) | 3000 | static int __init ftrace_mod_cmd_init(void) |
2986 | { | 3001 | { |
2987 | return register_ftrace_command(&ftrace_mod_cmd); | 3002 | return register_ftrace_command(&ftrace_mod_cmd); |
2988 | } | 3003 | } |
2989 | core_initcall(ftrace_mod_cmd_init); | 3004 | core_initcall(ftrace_mod_cmd_init); |
2990 | 3005 | ||
2991 | static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip, | 3006 | static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip, |
2992 | struct ftrace_ops *op, struct pt_regs *pt_regs) | 3007 | struct ftrace_ops *op, struct pt_regs *pt_regs) |
2993 | { | 3008 | { |
2994 | struct ftrace_func_probe *entry; | 3009 | struct ftrace_func_probe *entry; |
2995 | struct hlist_head *hhd; | 3010 | struct hlist_head *hhd; |
2996 | unsigned long key; | 3011 | unsigned long key; |
2997 | 3012 | ||
2998 | key = hash_long(ip, FTRACE_HASH_BITS); | 3013 | key = hash_long(ip, FTRACE_HASH_BITS); |
2999 | 3014 | ||
3000 | hhd = &ftrace_func_hash[key]; | 3015 | hhd = &ftrace_func_hash[key]; |
3001 | 3016 | ||
3002 | if (hlist_empty(hhd)) | 3017 | if (hlist_empty(hhd)) |
3003 | return; | 3018 | return; |
3004 | 3019 | ||
3005 | /* | 3020 | /* |
3006 | * Disable preemption for these calls to prevent a RCU grace | 3021 | * Disable preemption for these calls to prevent a RCU grace |
3007 | * period. This syncs the hash iteration and freeing of items | 3022 | * period. This syncs the hash iteration and freeing of items |
3008 | * on the hash. rcu_read_lock is too dangerous here. | 3023 | * on the hash. rcu_read_lock is too dangerous here. |
3009 | */ | 3024 | */ |
3010 | preempt_disable_notrace(); | 3025 | preempt_disable_notrace(); |
3011 | hlist_for_each_entry_rcu_notrace(entry, hhd, node) { | 3026 | hlist_for_each_entry_rcu_notrace(entry, hhd, node) { |
3012 | if (entry->ip == ip) | 3027 | if (entry->ip == ip) |
3013 | entry->ops->func(ip, parent_ip, &entry->data); | 3028 | entry->ops->func(ip, parent_ip, &entry->data); |
3014 | } | 3029 | } |
3015 | preempt_enable_notrace(); | 3030 | preempt_enable_notrace(); |
3016 | } | 3031 | } |
3017 | 3032 | ||
3018 | static struct ftrace_ops trace_probe_ops __read_mostly = | 3033 | static struct ftrace_ops trace_probe_ops __read_mostly = |
3019 | { | 3034 | { |
3020 | .func = function_trace_probe_call, | 3035 | .func = function_trace_probe_call, |
3021 | .flags = FTRACE_OPS_FL_INITIALIZED, | 3036 | .flags = FTRACE_OPS_FL_INITIALIZED, |
3022 | INIT_REGEX_LOCK(trace_probe_ops) | 3037 | INIT_REGEX_LOCK(trace_probe_ops) |
3023 | }; | 3038 | }; |
3024 | 3039 | ||
3025 | static int ftrace_probe_registered; | 3040 | static int ftrace_probe_registered; |
3026 | 3041 | ||
3027 | static void __enable_ftrace_function_probe(void) | 3042 | static void __enable_ftrace_function_probe(void) |
3028 | { | 3043 | { |
3029 | int ret; | 3044 | int ret; |
3030 | int i; | 3045 | int i; |
3031 | 3046 | ||
3032 | if (ftrace_probe_registered) { | 3047 | if (ftrace_probe_registered) { |
3033 | /* still need to update the function call sites */ | 3048 | /* still need to update the function call sites */ |
3034 | if (ftrace_enabled) | 3049 | if (ftrace_enabled) |
3035 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); | 3050 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); |
3036 | return; | 3051 | return; |
3037 | } | 3052 | } |
3038 | 3053 | ||
3039 | for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { | 3054 | for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { |
3040 | struct hlist_head *hhd = &ftrace_func_hash[i]; | 3055 | struct hlist_head *hhd = &ftrace_func_hash[i]; |
3041 | if (hhd->first) | 3056 | if (hhd->first) |
3042 | break; | 3057 | break; |
3043 | } | 3058 | } |
3044 | /* Nothing registered? */ | 3059 | /* Nothing registered? */ |
3045 | if (i == FTRACE_FUNC_HASHSIZE) | 3060 | if (i == FTRACE_FUNC_HASHSIZE) |
3046 | return; | 3061 | return; |
3047 | 3062 | ||
3048 | ret = __register_ftrace_function(&trace_probe_ops); | 3063 | ret = __register_ftrace_function(&trace_probe_ops); |
3049 | if (!ret) | 3064 | if (!ret) |
3050 | ret = ftrace_startup(&trace_probe_ops, 0); | 3065 | ret = ftrace_startup(&trace_probe_ops, 0); |
3051 | 3066 | ||
3052 | ftrace_probe_registered = 1; | 3067 | ftrace_probe_registered = 1; |
3053 | } | 3068 | } |
3054 | 3069 | ||
3055 | static void __disable_ftrace_function_probe(void) | 3070 | static void __disable_ftrace_function_probe(void) |
3056 | { | 3071 | { |
3057 | int ret; | 3072 | int ret; |
3058 | int i; | 3073 | int i; |
3059 | 3074 | ||
3060 | if (!ftrace_probe_registered) | 3075 | if (!ftrace_probe_registered) |
3061 | return; | 3076 | return; |
3062 | 3077 | ||
3063 | for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { | 3078 | for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { |
3064 | struct hlist_head *hhd = &ftrace_func_hash[i]; | 3079 | struct hlist_head *hhd = &ftrace_func_hash[i]; |
3065 | if (hhd->first) | 3080 | if (hhd->first) |
3066 | return; | 3081 | return; |
3067 | } | 3082 | } |
3068 | 3083 | ||
3069 | /* no more funcs left */ | 3084 | /* no more funcs left */ |
3070 | ret = __unregister_ftrace_function(&trace_probe_ops); | 3085 | ret = __unregister_ftrace_function(&trace_probe_ops); |
3071 | if (!ret) | 3086 | if (!ret) |
3072 | ftrace_shutdown(&trace_probe_ops, 0); | 3087 | ftrace_shutdown(&trace_probe_ops, 0); |
3073 | 3088 | ||
3074 | ftrace_probe_registered = 0; | 3089 | ftrace_probe_registered = 0; |
3075 | } | 3090 | } |
3076 | 3091 | ||
3077 | 3092 | ||
3078 | static void ftrace_free_entry(struct ftrace_func_probe *entry) | 3093 | static void ftrace_free_entry(struct ftrace_func_probe *entry) |
3079 | { | 3094 | { |
3080 | if (entry->ops->free) | 3095 | if (entry->ops->free) |
3081 | entry->ops->free(entry->ops, entry->ip, &entry->data); | 3096 | entry->ops->free(entry->ops, entry->ip, &entry->data); |
3082 | kfree(entry); | 3097 | kfree(entry); |
3083 | } | 3098 | } |
3084 | 3099 | ||
3085 | int | 3100 | int |
3086 | register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, | 3101 | register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, |
3087 | void *data) | 3102 | void *data) |
3088 | { | 3103 | { |
3089 | struct ftrace_func_probe *entry; | 3104 | struct ftrace_func_probe *entry; |
3090 | struct ftrace_hash **orig_hash = &trace_probe_ops.filter_hash; | 3105 | struct ftrace_hash **orig_hash = &trace_probe_ops.filter_hash; |
3091 | struct ftrace_hash *hash; | 3106 | struct ftrace_hash *hash; |
3092 | struct ftrace_page *pg; | 3107 | struct ftrace_page *pg; |
3093 | struct dyn_ftrace *rec; | 3108 | struct dyn_ftrace *rec; |
3094 | int type, len, not; | 3109 | int type, len, not; |
3095 | unsigned long key; | 3110 | unsigned long key; |
3096 | int count = 0; | 3111 | int count = 0; |
3097 | char *search; | 3112 | char *search; |
3098 | int ret; | 3113 | int ret; |
3099 | 3114 | ||
3100 | type = filter_parse_regex(glob, strlen(glob), &search, ¬); | 3115 | type = filter_parse_regex(glob, strlen(glob), &search, ¬); |
3101 | len = strlen(search); | 3116 | len = strlen(search); |
3102 | 3117 | ||
3103 | /* we do not support '!' for function probes */ | 3118 | /* we do not support '!' for function probes */ |
3104 | if (WARN_ON(not)) | 3119 | if (WARN_ON(not)) |
3105 | return -EINVAL; | 3120 | return -EINVAL; |
3106 | 3121 | ||
3107 | mutex_lock(&trace_probe_ops.regex_lock); | 3122 | mutex_lock(&trace_probe_ops.regex_lock); |
3108 | 3123 | ||
3109 | hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); | 3124 | hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); |
3110 | if (!hash) { | 3125 | if (!hash) { |
3111 | count = -ENOMEM; | 3126 | count = -ENOMEM; |
3112 | goto out; | 3127 | goto out; |
3113 | } | 3128 | } |
3114 | 3129 | ||
3115 | if (unlikely(ftrace_disabled)) { | 3130 | if (unlikely(ftrace_disabled)) { |
3116 | count = -ENODEV; | 3131 | count = -ENODEV; |
3117 | goto out; | 3132 | goto out; |
3118 | } | 3133 | } |
3119 | 3134 | ||
3120 | mutex_lock(&ftrace_lock); | 3135 | mutex_lock(&ftrace_lock); |
3121 | 3136 | ||
3122 | do_for_each_ftrace_rec(pg, rec) { | 3137 | do_for_each_ftrace_rec(pg, rec) { |
3123 | 3138 | ||
3124 | if (!ftrace_match_record(rec, NULL, search, len, type)) | 3139 | if (!ftrace_match_record(rec, NULL, search, len, type)) |
3125 | continue; | 3140 | continue; |
3126 | 3141 | ||
3127 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | 3142 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
3128 | if (!entry) { | 3143 | if (!entry) { |
3129 | /* If we did not process any, then return error */ | 3144 | /* If we did not process any, then return error */ |
3130 | if (!count) | 3145 | if (!count) |
3131 | count = -ENOMEM; | 3146 | count = -ENOMEM; |
3132 | goto out_unlock; | 3147 | goto out_unlock; |
3133 | } | 3148 | } |
3134 | 3149 | ||
3135 | count++; | 3150 | count++; |
3136 | 3151 | ||
3137 | entry->data = data; | 3152 | entry->data = data; |
3138 | 3153 | ||
3139 | /* | 3154 | /* |
3140 | * The caller might want to do something special | 3155 | * The caller might want to do something special |
3141 | * for each function we find. We call the callback | 3156 | * for each function we find. We call the callback |
3142 | * to give the caller an opportunity to do so. | 3157 | * to give the caller an opportunity to do so. |
3143 | */ | 3158 | */ |
3144 | if (ops->init) { | 3159 | if (ops->init) { |
3145 | if (ops->init(ops, rec->ip, &entry->data) < 0) { | 3160 | if (ops->init(ops, rec->ip, &entry->data) < 0) { |
3146 | /* caller does not like this func */ | 3161 | /* caller does not like this func */ |
3147 | kfree(entry); | 3162 | kfree(entry); |
3148 | continue; | 3163 | continue; |
3149 | } | 3164 | } |
3150 | } | 3165 | } |
3151 | 3166 | ||
3152 | ret = enter_record(hash, rec, 0); | 3167 | ret = enter_record(hash, rec, 0); |
3153 | if (ret < 0) { | 3168 | if (ret < 0) { |
3154 | kfree(entry); | 3169 | kfree(entry); |
3155 | count = ret; | 3170 | count = ret; |
3156 | goto out_unlock; | 3171 | goto out_unlock; |
3157 | } | 3172 | } |
3158 | 3173 | ||
3159 | entry->ops = ops; | 3174 | entry->ops = ops; |
3160 | entry->ip = rec->ip; | 3175 | entry->ip = rec->ip; |
3161 | 3176 | ||
3162 | key = hash_long(entry->ip, FTRACE_HASH_BITS); | 3177 | key = hash_long(entry->ip, FTRACE_HASH_BITS); |
3163 | hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]); | 3178 | hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]); |
3164 | 3179 | ||
3165 | } while_for_each_ftrace_rec(); | 3180 | } while_for_each_ftrace_rec(); |
3166 | 3181 | ||
3167 | ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); | 3182 | ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); |
3168 | if (ret < 0) | 3183 | if (ret < 0) |
3169 | count = ret; | 3184 | count = ret; |
3170 | 3185 | ||
3171 | __enable_ftrace_function_probe(); | 3186 | __enable_ftrace_function_probe(); |
3172 | 3187 | ||
3173 | out_unlock: | 3188 | out_unlock: |
3174 | mutex_unlock(&ftrace_lock); | 3189 | mutex_unlock(&ftrace_lock); |
3175 | out: | 3190 | out: |
3176 | mutex_unlock(&trace_probe_ops.regex_lock); | 3191 | mutex_unlock(&trace_probe_ops.regex_lock); |
3177 | free_ftrace_hash(hash); | 3192 | free_ftrace_hash(hash); |
3178 | 3193 | ||
3179 | return count; | 3194 | return count; |
3180 | } | 3195 | } |
3181 | 3196 | ||
3182 | enum { | 3197 | enum { |
3183 | PROBE_TEST_FUNC = 1, | 3198 | PROBE_TEST_FUNC = 1, |
3184 | PROBE_TEST_DATA = 2 | 3199 | PROBE_TEST_DATA = 2 |
3185 | }; | 3200 | }; |
3186 | 3201 | ||
3187 | static void | 3202 | static void |
3188 | __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, | 3203 | __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, |
3189 | void *data, int flags) | 3204 | void *data, int flags) |
3190 | { | 3205 | { |
3191 | struct ftrace_func_entry *rec_entry; | 3206 | struct ftrace_func_entry *rec_entry; |
3192 | struct ftrace_func_probe *entry; | 3207 | struct ftrace_func_probe *entry; |
3193 | struct ftrace_func_probe *p; | 3208 | struct ftrace_func_probe *p; |
3194 | struct ftrace_hash **orig_hash = &trace_probe_ops.filter_hash; | 3209 | struct ftrace_hash **orig_hash = &trace_probe_ops.filter_hash; |
3195 | struct list_head free_list; | 3210 | struct list_head free_list; |
3196 | struct ftrace_hash *hash; | 3211 | struct ftrace_hash *hash; |
3197 | struct hlist_node *tmp; | 3212 | struct hlist_node *tmp; |
3198 | char str[KSYM_SYMBOL_LEN]; | 3213 | char str[KSYM_SYMBOL_LEN]; |
3199 | int type = MATCH_FULL; | 3214 | int type = MATCH_FULL; |
3200 | int i, len = 0; | 3215 | int i, len = 0; |
3201 | char *search; | 3216 | char *search; |
3202 | 3217 | ||
3203 | if (glob && (strcmp(glob, "*") == 0 || !strlen(glob))) | 3218 | if (glob && (strcmp(glob, "*") == 0 || !strlen(glob))) |
3204 | glob = NULL; | 3219 | glob = NULL; |
3205 | else if (glob) { | 3220 | else if (glob) { |
3206 | int not; | 3221 | int not; |
3207 | 3222 | ||
3208 | type = filter_parse_regex(glob, strlen(glob), &search, ¬); | 3223 | type = filter_parse_regex(glob, strlen(glob), &search, ¬); |
3209 | len = strlen(search); | 3224 | len = strlen(search); |
3210 | 3225 | ||
3211 | /* we do not support '!' for function probes */ | 3226 | /* we do not support '!' for function probes */ |
3212 | if (WARN_ON(not)) | 3227 | if (WARN_ON(not)) |
3213 | return; | 3228 | return; |
3214 | } | 3229 | } |
3215 | 3230 | ||
3216 | mutex_lock(&trace_probe_ops.regex_lock); | 3231 | mutex_lock(&trace_probe_ops.regex_lock); |
3217 | 3232 | ||
3218 | hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); | 3233 | hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); |
3219 | if (!hash) | 3234 | if (!hash) |
3220 | /* Hmm, should report this somehow */ | 3235 | /* Hmm, should report this somehow */ |
3221 | goto out_unlock; | 3236 | goto out_unlock; |
3222 | 3237 | ||
3223 | INIT_LIST_HEAD(&free_list); | 3238 | INIT_LIST_HEAD(&free_list); |
3224 | 3239 | ||
3225 | for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { | 3240 | for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { |
3226 | struct hlist_head *hhd = &ftrace_func_hash[i]; | 3241 | struct hlist_head *hhd = &ftrace_func_hash[i]; |
3227 | 3242 | ||
3228 | hlist_for_each_entry_safe(entry, tmp, hhd, node) { | 3243 | hlist_for_each_entry_safe(entry, tmp, hhd, node) { |
3229 | 3244 | ||
3230 | /* break up if statements for readability */ | 3245 | /* break up if statements for readability */ |
3231 | if ((flags & PROBE_TEST_FUNC) && entry->ops != ops) | 3246 | if ((flags & PROBE_TEST_FUNC) && entry->ops != ops) |
3232 | continue; | 3247 | continue; |
3233 | 3248 | ||
3234 | if ((flags & PROBE_TEST_DATA) && entry->data != data) | 3249 | if ((flags & PROBE_TEST_DATA) && entry->data != data) |
3235 | continue; | 3250 | continue; |
3236 | 3251 | ||
3237 | /* do this last, since it is the most expensive */ | 3252 | /* do this last, since it is the most expensive */ |
3238 | if (glob) { | 3253 | if (glob) { |
3239 | kallsyms_lookup(entry->ip, NULL, NULL, | 3254 | kallsyms_lookup(entry->ip, NULL, NULL, |
3240 | NULL, str); | 3255 | NULL, str); |
3241 | if (!ftrace_match(str, glob, len, type)) | 3256 | if (!ftrace_match(str, glob, len, type)) |
3242 | continue; | 3257 | continue; |
3243 | } | 3258 | } |
3244 | 3259 | ||
3245 | rec_entry = ftrace_lookup_ip(hash, entry->ip); | 3260 | rec_entry = ftrace_lookup_ip(hash, entry->ip); |
3246 | /* It is possible more than one entry had this ip */ | 3261 | /* It is possible more than one entry had this ip */ |
3247 | if (rec_entry) | 3262 | if (rec_entry) |
3248 | free_hash_entry(hash, rec_entry); | 3263 | free_hash_entry(hash, rec_entry); |
3249 | 3264 | ||
3250 | hlist_del_rcu(&entry->node); | 3265 | hlist_del_rcu(&entry->node); |
3251 | list_add(&entry->free_list, &free_list); | 3266 | list_add(&entry->free_list, &free_list); |
3252 | } | 3267 | } |
3253 | } | 3268 | } |
3254 | mutex_lock(&ftrace_lock); | 3269 | mutex_lock(&ftrace_lock); |
3255 | __disable_ftrace_function_probe(); | 3270 | __disable_ftrace_function_probe(); |
3256 | /* | 3271 | /* |
3257 | * Remove after the disable is called. Otherwise, if the last | 3272 | * Remove after the disable is called. Otherwise, if the last |
3258 | * probe is removed, a null hash means *all enabled*. | 3273 | * probe is removed, a null hash means *all enabled*. |
3259 | */ | 3274 | */ |
3260 | ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); | 3275 | ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); |
3261 | synchronize_sched(); | 3276 | synchronize_sched(); |
3262 | list_for_each_entry_safe(entry, p, &free_list, free_list) { | 3277 | list_for_each_entry_safe(entry, p, &free_list, free_list) { |
3263 | list_del(&entry->free_list); | 3278 | list_del(&entry->free_list); |
3264 | ftrace_free_entry(entry); | 3279 | ftrace_free_entry(entry); |
3265 | } | 3280 | } |
3266 | mutex_unlock(&ftrace_lock); | 3281 | mutex_unlock(&ftrace_lock); |
3267 | 3282 | ||
3268 | out_unlock: | 3283 | out_unlock: |
3269 | mutex_unlock(&trace_probe_ops.regex_lock); | 3284 | mutex_unlock(&trace_probe_ops.regex_lock); |
3270 | free_ftrace_hash(hash); | 3285 | free_ftrace_hash(hash); |
3271 | } | 3286 | } |
3272 | 3287 | ||
3273 | void | 3288 | void |
3274 | unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, | 3289 | unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, |
3275 | void *data) | 3290 | void *data) |
3276 | { | 3291 | { |
3277 | __unregister_ftrace_function_probe(glob, ops, data, | 3292 | __unregister_ftrace_function_probe(glob, ops, data, |
3278 | PROBE_TEST_FUNC | PROBE_TEST_DATA); | 3293 | PROBE_TEST_FUNC | PROBE_TEST_DATA); |
3279 | } | 3294 | } |
3280 | 3295 | ||
3281 | void | 3296 | void |
3282 | unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops) | 3297 | unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops) |
3283 | { | 3298 | { |
3284 | __unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC); | 3299 | __unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC); |
3285 | } | 3300 | } |
3286 | 3301 | ||
3287 | void unregister_ftrace_function_probe_all(char *glob) | 3302 | void unregister_ftrace_function_probe_all(char *glob) |
3288 | { | 3303 | { |
3289 | __unregister_ftrace_function_probe(glob, NULL, NULL, 0); | 3304 | __unregister_ftrace_function_probe(glob, NULL, NULL, 0); |
3290 | } | 3305 | } |
3291 | 3306 | ||
3292 | static LIST_HEAD(ftrace_commands); | 3307 | static LIST_HEAD(ftrace_commands); |
3293 | static DEFINE_MUTEX(ftrace_cmd_mutex); | 3308 | static DEFINE_MUTEX(ftrace_cmd_mutex); |
3294 | 3309 | ||
3295 | int register_ftrace_command(struct ftrace_func_command *cmd) | 3310 | int register_ftrace_command(struct ftrace_func_command *cmd) |
3296 | { | 3311 | { |
3297 | struct ftrace_func_command *p; | 3312 | struct ftrace_func_command *p; |
3298 | int ret = 0; | 3313 | int ret = 0; |
3299 | 3314 | ||
3300 | mutex_lock(&ftrace_cmd_mutex); | 3315 | mutex_lock(&ftrace_cmd_mutex); |
3301 | list_for_each_entry(p, &ftrace_commands, list) { | 3316 | list_for_each_entry(p, &ftrace_commands, list) { |
3302 | if (strcmp(cmd->name, p->name) == 0) { | 3317 | if (strcmp(cmd->name, p->name) == 0) { |
3303 | ret = -EBUSY; | 3318 | ret = -EBUSY; |
3304 | goto out_unlock; | 3319 | goto out_unlock; |
3305 | } | 3320 | } |
3306 | } | 3321 | } |
3307 | list_add(&cmd->list, &ftrace_commands); | 3322 | list_add(&cmd->list, &ftrace_commands); |
3308 | out_unlock: | 3323 | out_unlock: |
3309 | mutex_unlock(&ftrace_cmd_mutex); | 3324 | mutex_unlock(&ftrace_cmd_mutex); |
3310 | 3325 | ||
3311 | return ret; | 3326 | return ret; |
3312 | } | 3327 | } |
3313 | 3328 | ||
3314 | int unregister_ftrace_command(struct ftrace_func_command *cmd) | 3329 | int unregister_ftrace_command(struct ftrace_func_command *cmd) |
3315 | { | 3330 | { |
3316 | struct ftrace_func_command *p, *n; | 3331 | struct ftrace_func_command *p, *n; |
3317 | int ret = -ENODEV; | 3332 | int ret = -ENODEV; |
3318 | 3333 | ||
3319 | mutex_lock(&ftrace_cmd_mutex); | 3334 | mutex_lock(&ftrace_cmd_mutex); |
3320 | list_for_each_entry_safe(p, n, &ftrace_commands, list) { | 3335 | list_for_each_entry_safe(p, n, &ftrace_commands, list) { |
3321 | if (strcmp(cmd->name, p->name) == 0) { | 3336 | if (strcmp(cmd->name, p->name) == 0) { |
3322 | ret = 0; | 3337 | ret = 0; |
3323 | list_del_init(&p->list); | 3338 | list_del_init(&p->list); |
3324 | goto out_unlock; | 3339 | goto out_unlock; |
3325 | } | 3340 | } |
3326 | } | 3341 | } |
3327 | out_unlock: | 3342 | out_unlock: |
3328 | mutex_unlock(&ftrace_cmd_mutex); | 3343 | mutex_unlock(&ftrace_cmd_mutex); |
3329 | 3344 | ||
3330 | return ret; | 3345 | return ret; |
3331 | } | 3346 | } |
3332 | 3347 | ||
3333 | static int ftrace_process_regex(struct ftrace_hash *hash, | 3348 | static int ftrace_process_regex(struct ftrace_hash *hash, |
3334 | char *buff, int len, int enable) | 3349 | char *buff, int len, int enable) |
3335 | { | 3350 | { |
3336 | char *func, *command, *next = buff; | 3351 | char *func, *command, *next = buff; |
3337 | struct ftrace_func_command *p; | 3352 | struct ftrace_func_command *p; |
3338 | int ret = -EINVAL; | 3353 | int ret = -EINVAL; |
3339 | 3354 | ||
3340 | func = strsep(&next, ":"); | 3355 | func = strsep(&next, ":"); |
3341 | 3356 | ||
3342 | if (!next) { | 3357 | if (!next) { |
3343 | ret = ftrace_match_records(hash, func, len); | 3358 | ret = ftrace_match_records(hash, func, len); |
3344 | if (!ret) | 3359 | if (!ret) |
3345 | ret = -EINVAL; | 3360 | ret = -EINVAL; |
3346 | if (ret < 0) | 3361 | if (ret < 0) |
3347 | return ret; | 3362 | return ret; |
3348 | return 0; | 3363 | return 0; |
3349 | } | 3364 | } |
3350 | 3365 | ||
3351 | /* command found */ | 3366 | /* command found */ |
3352 | 3367 | ||
3353 | command = strsep(&next, ":"); | 3368 | command = strsep(&next, ":"); |
3354 | 3369 | ||
3355 | mutex_lock(&ftrace_cmd_mutex); | 3370 | mutex_lock(&ftrace_cmd_mutex); |
3356 | list_for_each_entry(p, &ftrace_commands, list) { | 3371 | list_for_each_entry(p, &ftrace_commands, list) { |
3357 | if (strcmp(p->name, command) == 0) { | 3372 | if (strcmp(p->name, command) == 0) { |
3358 | ret = p->func(hash, func, command, next, enable); | 3373 | ret = p->func(hash, func, command, next, enable); |
3359 | goto out_unlock; | 3374 | goto out_unlock; |
3360 | } | 3375 | } |
3361 | } | 3376 | } |
3362 | out_unlock: | 3377 | out_unlock: |
3363 | mutex_unlock(&ftrace_cmd_mutex); | 3378 | mutex_unlock(&ftrace_cmd_mutex); |
3364 | 3379 | ||
3365 | return ret; | 3380 | return ret; |
3366 | } | 3381 | } |
3367 | 3382 | ||
3368 | static ssize_t | 3383 | static ssize_t |
3369 | ftrace_regex_write(struct file *file, const char __user *ubuf, | 3384 | ftrace_regex_write(struct file *file, const char __user *ubuf, |
3370 | size_t cnt, loff_t *ppos, int enable) | 3385 | size_t cnt, loff_t *ppos, int enable) |
3371 | { | 3386 | { |
3372 | struct ftrace_iterator *iter; | 3387 | struct ftrace_iterator *iter; |
3373 | struct trace_parser *parser; | 3388 | struct trace_parser *parser; |
3374 | ssize_t ret, read; | 3389 | ssize_t ret, read; |
3375 | 3390 | ||
3376 | if (!cnt) | 3391 | if (!cnt) |
3377 | return 0; | 3392 | return 0; |
3378 | 3393 | ||
3379 | if (file->f_mode & FMODE_READ) { | 3394 | if (file->f_mode & FMODE_READ) { |
3380 | struct seq_file *m = file->private_data; | 3395 | struct seq_file *m = file->private_data; |
3381 | iter = m->private; | 3396 | iter = m->private; |
3382 | } else | 3397 | } else |
3383 | iter = file->private_data; | 3398 | iter = file->private_data; |
3384 | 3399 | ||
3385 | if (unlikely(ftrace_disabled)) | 3400 | if (unlikely(ftrace_disabled)) |
3386 | return -ENODEV; | 3401 | return -ENODEV; |
3387 | 3402 | ||
3388 | /* iter->hash is a local copy, so we don't need regex_lock */ | 3403 | /* iter->hash is a local copy, so we don't need regex_lock */ |
3389 | 3404 | ||
3390 | parser = &iter->parser; | 3405 | parser = &iter->parser; |
3391 | read = trace_get_user(parser, ubuf, cnt, ppos); | 3406 | read = trace_get_user(parser, ubuf, cnt, ppos); |
3392 | 3407 | ||
3393 | if (read >= 0 && trace_parser_loaded(parser) && | 3408 | if (read >= 0 && trace_parser_loaded(parser) && |
3394 | !trace_parser_cont(parser)) { | 3409 | !trace_parser_cont(parser)) { |
3395 | ret = ftrace_process_regex(iter->hash, parser->buffer, | 3410 | ret = ftrace_process_regex(iter->hash, parser->buffer, |
3396 | parser->idx, enable); | 3411 | parser->idx, enable); |
3397 | trace_parser_clear(parser); | 3412 | trace_parser_clear(parser); |
3398 | if (ret < 0) | 3413 | if (ret < 0) |
3399 | goto out; | 3414 | goto out; |
3400 | } | 3415 | } |
3401 | 3416 | ||
3402 | ret = read; | 3417 | ret = read; |
3403 | out: | 3418 | out: |
3404 | return ret; | 3419 | return ret; |
3405 | } | 3420 | } |
3406 | 3421 | ||
3407 | ssize_t | 3422 | ssize_t |
3408 | ftrace_filter_write(struct file *file, const char __user *ubuf, | 3423 | ftrace_filter_write(struct file *file, const char __user *ubuf, |
3409 | size_t cnt, loff_t *ppos) | 3424 | size_t cnt, loff_t *ppos) |
3410 | { | 3425 | { |
3411 | return ftrace_regex_write(file, ubuf, cnt, ppos, 1); | 3426 | return ftrace_regex_write(file, ubuf, cnt, ppos, 1); |
3412 | } | 3427 | } |
3413 | 3428 | ||
3414 | ssize_t | 3429 | ssize_t |
3415 | ftrace_notrace_write(struct file *file, const char __user *ubuf, | 3430 | ftrace_notrace_write(struct file *file, const char __user *ubuf, |
3416 | size_t cnt, loff_t *ppos) | 3431 | size_t cnt, loff_t *ppos) |
3417 | { | 3432 | { |
3418 | return ftrace_regex_write(file, ubuf, cnt, ppos, 0); | 3433 | return ftrace_regex_write(file, ubuf, cnt, ppos, 0); |
3419 | } | 3434 | } |
3420 | 3435 | ||
3421 | static int | 3436 | static int |
3422 | ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) | 3437 | ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) |
3423 | { | 3438 | { |
3424 | struct ftrace_func_entry *entry; | 3439 | struct ftrace_func_entry *entry; |
3425 | 3440 | ||
3426 | if (!ftrace_location(ip)) | 3441 | if (!ftrace_location(ip)) |
3427 | return -EINVAL; | 3442 | return -EINVAL; |
3428 | 3443 | ||
3429 | if (remove) { | 3444 | if (remove) { |
3430 | entry = ftrace_lookup_ip(hash, ip); | 3445 | entry = ftrace_lookup_ip(hash, ip); |
3431 | if (!entry) | 3446 | if (!entry) |
3432 | return -ENOENT; | 3447 | return -ENOENT; |
3433 | free_hash_entry(hash, entry); | 3448 | free_hash_entry(hash, entry); |
3434 | return 0; | 3449 | return 0; |
3435 | } | 3450 | } |
3436 | 3451 | ||
3437 | return add_hash_entry(hash, ip); | 3452 | return add_hash_entry(hash, ip); |
3438 | } | 3453 | } |
3439 | 3454 | ||
3440 | static void ftrace_ops_update_code(struct ftrace_ops *ops) | 3455 | static void ftrace_ops_update_code(struct ftrace_ops *ops) |
3441 | { | 3456 | { |
3442 | if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) | 3457 | if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) |
3443 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); | 3458 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); |
3444 | } | 3459 | } |
3445 | 3460 | ||
3446 | static int | 3461 | static int |
3447 | ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, | 3462 | ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, |
3448 | unsigned long ip, int remove, int reset, int enable) | 3463 | unsigned long ip, int remove, int reset, int enable) |
3449 | { | 3464 | { |
3450 | struct ftrace_hash **orig_hash; | 3465 | struct ftrace_hash **orig_hash; |
3451 | struct ftrace_hash *hash; | 3466 | struct ftrace_hash *hash; |
3452 | int ret; | 3467 | int ret; |
3453 | 3468 | ||
3454 | /* All global ops uses the global ops filters */ | 3469 | /* All global ops uses the global ops filters */ |
3455 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) | 3470 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) |
3456 | ops = &global_ops; | 3471 | ops = &global_ops; |
3457 | 3472 | ||
3458 | if (unlikely(ftrace_disabled)) | 3473 | if (unlikely(ftrace_disabled)) |
3459 | return -ENODEV; | 3474 | return -ENODEV; |
3460 | 3475 | ||
3461 | mutex_lock(&ops->regex_lock); | 3476 | mutex_lock(&ops->regex_lock); |
3462 | 3477 | ||
3463 | if (enable) | 3478 | if (enable) |
3464 | orig_hash = &ops->filter_hash; | 3479 | orig_hash = &ops->filter_hash; |
3465 | else | 3480 | else |
3466 | orig_hash = &ops->notrace_hash; | 3481 | orig_hash = &ops->notrace_hash; |
3467 | 3482 | ||
3468 | hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); | 3483 | hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); |
3469 | if (!hash) { | 3484 | if (!hash) { |
3470 | ret = -ENOMEM; | 3485 | ret = -ENOMEM; |
3471 | goto out_regex_unlock; | 3486 | goto out_regex_unlock; |
3472 | } | 3487 | } |
3473 | 3488 | ||
3474 | if (reset) | 3489 | if (reset) |
3475 | ftrace_filter_reset(hash); | 3490 | ftrace_filter_reset(hash); |
3476 | if (buf && !ftrace_match_records(hash, buf, len)) { | 3491 | if (buf && !ftrace_match_records(hash, buf, len)) { |
3477 | ret = -EINVAL; | 3492 | ret = -EINVAL; |
3478 | goto out_regex_unlock; | 3493 | goto out_regex_unlock; |
3479 | } | 3494 | } |
3480 | if (ip) { | 3495 | if (ip) { |
3481 | ret = ftrace_match_addr(hash, ip, remove); | 3496 | ret = ftrace_match_addr(hash, ip, remove); |
3482 | if (ret < 0) | 3497 | if (ret < 0) |
3483 | goto out_regex_unlock; | 3498 | goto out_regex_unlock; |
3484 | } | 3499 | } |
3485 | 3500 | ||
3486 | mutex_lock(&ftrace_lock); | 3501 | mutex_lock(&ftrace_lock); |
3487 | ret = ftrace_hash_move(ops, enable, orig_hash, hash); | 3502 | ret = ftrace_hash_move(ops, enable, orig_hash, hash); |
3488 | if (!ret) | 3503 | if (!ret) |
3489 | ftrace_ops_update_code(ops); | 3504 | ftrace_ops_update_code(ops); |
3490 | 3505 | ||
3491 | mutex_unlock(&ftrace_lock); | 3506 | mutex_unlock(&ftrace_lock); |
3492 | 3507 | ||
3493 | out_regex_unlock: | 3508 | out_regex_unlock: |
3494 | mutex_unlock(&ops->regex_lock); | 3509 | mutex_unlock(&ops->regex_lock); |
3495 | 3510 | ||
3496 | free_ftrace_hash(hash); | 3511 | free_ftrace_hash(hash); |
3497 | return ret; | 3512 | return ret; |
3498 | } | 3513 | } |
3499 | 3514 | ||
3500 | static int | 3515 | static int |
3501 | ftrace_set_addr(struct ftrace_ops *ops, unsigned long ip, int remove, | 3516 | ftrace_set_addr(struct ftrace_ops *ops, unsigned long ip, int remove, |
3502 | int reset, int enable) | 3517 | int reset, int enable) |
3503 | { | 3518 | { |
3504 | return ftrace_set_hash(ops, 0, 0, ip, remove, reset, enable); | 3519 | return ftrace_set_hash(ops, 0, 0, ip, remove, reset, enable); |
3505 | } | 3520 | } |
3506 | 3521 | ||
3507 | /** | 3522 | /** |
3508 | * ftrace_set_filter_ip - set a function to filter on in ftrace by address | 3523 | * ftrace_set_filter_ip - set a function to filter on in ftrace by address |
3509 | * @ops - the ops to set the filter with | 3524 | * @ops - the ops to set the filter with |
3510 | * @ip - the address to add to or remove from the filter. | 3525 | * @ip - the address to add to or remove from the filter. |
3511 | * @remove - non zero to remove the ip from the filter | 3526 | * @remove - non zero to remove the ip from the filter |
3512 | * @reset - non zero to reset all filters before applying this filter. | 3527 | * @reset - non zero to reset all filters before applying this filter. |
3513 | * | 3528 | * |
3514 | * Filters denote which functions should be enabled when tracing is enabled | 3529 | * Filters denote which functions should be enabled when tracing is enabled |
3515 | * If @ip is NULL, it failes to update filter. | 3530 | * If @ip is NULL, it failes to update filter. |
3516 | */ | 3531 | */ |
3517 | int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip, | 3532 | int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip, |
3518 | int remove, int reset) | 3533 | int remove, int reset) |
3519 | { | 3534 | { |
3520 | ftrace_ops_init(ops); | 3535 | ftrace_ops_init(ops); |
3521 | return ftrace_set_addr(ops, ip, remove, reset, 1); | 3536 | return ftrace_set_addr(ops, ip, remove, reset, 1); |
3522 | } | 3537 | } |
3523 | EXPORT_SYMBOL_GPL(ftrace_set_filter_ip); | 3538 | EXPORT_SYMBOL_GPL(ftrace_set_filter_ip); |
3524 | 3539 | ||
3525 | static int | 3540 | static int |
3526 | ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, | 3541 | ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, |
3527 | int reset, int enable) | 3542 | int reset, int enable) |
3528 | { | 3543 | { |
3529 | return ftrace_set_hash(ops, buf, len, 0, 0, reset, enable); | 3544 | return ftrace_set_hash(ops, buf, len, 0, 0, reset, enable); |
3530 | } | 3545 | } |
3531 | 3546 | ||
3532 | /** | 3547 | /** |
3533 | * ftrace_set_filter - set a function to filter on in ftrace | 3548 | * ftrace_set_filter - set a function to filter on in ftrace |
3534 | * @ops - the ops to set the filter with | 3549 | * @ops - the ops to set the filter with |
3535 | * @buf - the string that holds the function filter text. | 3550 | * @buf - the string that holds the function filter text. |
3536 | * @len - the length of the string. | 3551 | * @len - the length of the string. |
3537 | * @reset - non zero to reset all filters before applying this filter. | 3552 | * @reset - non zero to reset all filters before applying this filter. |
3538 | * | 3553 | * |
3539 | * Filters denote which functions should be enabled when tracing is enabled. | 3554 | * Filters denote which functions should be enabled when tracing is enabled. |
3540 | * If @buf is NULL and reset is set, all functions will be enabled for tracing. | 3555 | * If @buf is NULL and reset is set, all functions will be enabled for tracing. |
3541 | */ | 3556 | */ |
3542 | int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, | 3557 | int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, |
3543 | int len, int reset) | 3558 | int len, int reset) |
3544 | { | 3559 | { |
3545 | ftrace_ops_init(ops); | 3560 | ftrace_ops_init(ops); |
3546 | return ftrace_set_regex(ops, buf, len, reset, 1); | 3561 | return ftrace_set_regex(ops, buf, len, reset, 1); |
3547 | } | 3562 | } |
3548 | EXPORT_SYMBOL_GPL(ftrace_set_filter); | 3563 | EXPORT_SYMBOL_GPL(ftrace_set_filter); |
3549 | 3564 | ||
3550 | /** | 3565 | /** |
3551 | * ftrace_set_notrace - set a function to not trace in ftrace | 3566 | * ftrace_set_notrace - set a function to not trace in ftrace |
3552 | * @ops - the ops to set the notrace filter with | 3567 | * @ops - the ops to set the notrace filter with |
3553 | * @buf - the string that holds the function notrace text. | 3568 | * @buf - the string that holds the function notrace text. |
3554 | * @len - the length of the string. | 3569 | * @len - the length of the string. |
3555 | * @reset - non zero to reset all filters before applying this filter. | 3570 | * @reset - non zero to reset all filters before applying this filter. |
3556 | * | 3571 | * |
3557 | * Notrace Filters denote which functions should not be enabled when tracing | 3572 | * Notrace Filters denote which functions should not be enabled when tracing |
3558 | * is enabled. If @buf is NULL and reset is set, all functions will be enabled | 3573 | * is enabled. If @buf is NULL and reset is set, all functions will be enabled |
3559 | * for tracing. | 3574 | * for tracing. |
3560 | */ | 3575 | */ |
3561 | int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, | 3576 | int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, |
3562 | int len, int reset) | 3577 | int len, int reset) |
3563 | { | 3578 | { |
3564 | ftrace_ops_init(ops); | 3579 | ftrace_ops_init(ops); |
3565 | return ftrace_set_regex(ops, buf, len, reset, 0); | 3580 | return ftrace_set_regex(ops, buf, len, reset, 0); |
3566 | } | 3581 | } |
3567 | EXPORT_SYMBOL_GPL(ftrace_set_notrace); | 3582 | EXPORT_SYMBOL_GPL(ftrace_set_notrace); |
3568 | /** | 3583 | /** |
3569 | * ftrace_set_filter - set a function to filter on in ftrace | 3584 | * ftrace_set_filter - set a function to filter on in ftrace |
3570 | * @ops - the ops to set the filter with | 3585 | * @ops - the ops to set the filter with |
3571 | * @buf - the string that holds the function filter text. | 3586 | * @buf - the string that holds the function filter text. |
3572 | * @len - the length of the string. | 3587 | * @len - the length of the string. |
3573 | * @reset - non zero to reset all filters before applying this filter. | 3588 | * @reset - non zero to reset all filters before applying this filter. |
3574 | * | 3589 | * |
3575 | * Filters denote which functions should be enabled when tracing is enabled. | 3590 | * Filters denote which functions should be enabled when tracing is enabled. |
3576 | * If @buf is NULL and reset is set, all functions will be enabled for tracing. | 3591 | * If @buf is NULL and reset is set, all functions will be enabled for tracing. |
3577 | */ | 3592 | */ |
3578 | void ftrace_set_global_filter(unsigned char *buf, int len, int reset) | 3593 | void ftrace_set_global_filter(unsigned char *buf, int len, int reset) |
3579 | { | 3594 | { |
3580 | ftrace_set_regex(&global_ops, buf, len, reset, 1); | 3595 | ftrace_set_regex(&global_ops, buf, len, reset, 1); |
3581 | } | 3596 | } |
3582 | EXPORT_SYMBOL_GPL(ftrace_set_global_filter); | 3597 | EXPORT_SYMBOL_GPL(ftrace_set_global_filter); |
3583 | 3598 | ||
3584 | /** | 3599 | /** |
3585 | * ftrace_set_notrace - set a function to not trace in ftrace | 3600 | * ftrace_set_notrace - set a function to not trace in ftrace |
3586 | * @ops - the ops to set the notrace filter with | 3601 | * @ops - the ops to set the notrace filter with |
3587 | * @buf - the string that holds the function notrace text. | 3602 | * @buf - the string that holds the function notrace text. |
3588 | * @len - the length of the string. | 3603 | * @len - the length of the string. |
3589 | * @reset - non zero to reset all filters before applying this filter. | 3604 | * @reset - non zero to reset all filters before applying this filter. |
3590 | * | 3605 | * |
3591 | * Notrace Filters denote which functions should not be enabled when tracing | 3606 | * Notrace Filters denote which functions should not be enabled when tracing |
3592 | * is enabled. If @buf is NULL and reset is set, all functions will be enabled | 3607 | * is enabled. If @buf is NULL and reset is set, all functions will be enabled |
3593 | * for tracing. | 3608 | * for tracing. |
3594 | */ | 3609 | */ |
3595 | void ftrace_set_global_notrace(unsigned char *buf, int len, int reset) | 3610 | void ftrace_set_global_notrace(unsigned char *buf, int len, int reset) |
3596 | { | 3611 | { |
3597 | ftrace_set_regex(&global_ops, buf, len, reset, 0); | 3612 | ftrace_set_regex(&global_ops, buf, len, reset, 0); |
3598 | } | 3613 | } |
3599 | EXPORT_SYMBOL_GPL(ftrace_set_global_notrace); | 3614 | EXPORT_SYMBOL_GPL(ftrace_set_global_notrace); |
3600 | 3615 | ||
3601 | /* | 3616 | /* |
3602 | * command line interface to allow users to set filters on boot up. | 3617 | * command line interface to allow users to set filters on boot up. |
3603 | */ | 3618 | */ |
3604 | #define FTRACE_FILTER_SIZE COMMAND_LINE_SIZE | 3619 | #define FTRACE_FILTER_SIZE COMMAND_LINE_SIZE |
3605 | static char ftrace_notrace_buf[FTRACE_FILTER_SIZE] __initdata; | 3620 | static char ftrace_notrace_buf[FTRACE_FILTER_SIZE] __initdata; |
3606 | static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata; | 3621 | static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata; |
3607 | 3622 | ||
3608 | /* Used by function selftest to not test if filter is set */ | 3623 | /* Used by function selftest to not test if filter is set */ |
3609 | bool ftrace_filter_param __initdata; | 3624 | bool ftrace_filter_param __initdata; |
3610 | 3625 | ||
3611 | static int __init set_ftrace_notrace(char *str) | 3626 | static int __init set_ftrace_notrace(char *str) |
3612 | { | 3627 | { |
3613 | ftrace_filter_param = true; | 3628 | ftrace_filter_param = true; |
3614 | strlcpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE); | 3629 | strlcpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE); |
3615 | return 1; | 3630 | return 1; |
3616 | } | 3631 | } |
3617 | __setup("ftrace_notrace=", set_ftrace_notrace); | 3632 | __setup("ftrace_notrace=", set_ftrace_notrace); |
3618 | 3633 | ||
3619 | static int __init set_ftrace_filter(char *str) | 3634 | static int __init set_ftrace_filter(char *str) |
3620 | { | 3635 | { |
3621 | ftrace_filter_param = true; | 3636 | ftrace_filter_param = true; |
3622 | strlcpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE); | 3637 | strlcpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE); |
3623 | return 1; | 3638 | return 1; |
3624 | } | 3639 | } |
3625 | __setup("ftrace_filter=", set_ftrace_filter); | 3640 | __setup("ftrace_filter=", set_ftrace_filter); |
3626 | 3641 | ||
3627 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 3642 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
3628 | static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; | 3643 | static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; |
3629 | static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); | 3644 | static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); |
3630 | 3645 | ||
3631 | static int __init set_graph_function(char *str) | 3646 | static int __init set_graph_function(char *str) |
3632 | { | 3647 | { |
3633 | strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE); | 3648 | strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE); |
3634 | return 1; | 3649 | return 1; |
3635 | } | 3650 | } |
3636 | __setup("ftrace_graph_filter=", set_graph_function); | 3651 | __setup("ftrace_graph_filter=", set_graph_function); |
3637 | 3652 | ||
3638 | static void __init set_ftrace_early_graph(char *buf) | 3653 | static void __init set_ftrace_early_graph(char *buf) |
3639 | { | 3654 | { |
3640 | int ret; | 3655 | int ret; |
3641 | char *func; | 3656 | char *func; |
3642 | 3657 | ||
3643 | while (buf) { | 3658 | while (buf) { |
3644 | func = strsep(&buf, ","); | 3659 | func = strsep(&buf, ","); |
3645 | /* we allow only one expression at a time */ | 3660 | /* we allow only one expression at a time */ |
3646 | ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, | 3661 | ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, |
3647 | func); | 3662 | func); |
3648 | if (ret) | 3663 | if (ret) |
3649 | printk(KERN_DEBUG "ftrace: function %s not " | 3664 | printk(KERN_DEBUG "ftrace: function %s not " |
3650 | "traceable\n", func); | 3665 | "traceable\n", func); |
3651 | } | 3666 | } |
3652 | } | 3667 | } |
3653 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 3668 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
3654 | 3669 | ||
3655 | void __init | 3670 | void __init |
3656 | ftrace_set_early_filter(struct ftrace_ops *ops, char *buf, int enable) | 3671 | ftrace_set_early_filter(struct ftrace_ops *ops, char *buf, int enable) |
3657 | { | 3672 | { |
3658 | char *func; | 3673 | char *func; |
3659 | 3674 | ||
3660 | ftrace_ops_init(ops); | 3675 | ftrace_ops_init(ops); |
3661 | 3676 | ||
3662 | while (buf) { | 3677 | while (buf) { |
3663 | func = strsep(&buf, ","); | 3678 | func = strsep(&buf, ","); |
3664 | ftrace_set_regex(ops, func, strlen(func), 0, enable); | 3679 | ftrace_set_regex(ops, func, strlen(func), 0, enable); |
3665 | } | 3680 | } |
3666 | } | 3681 | } |
3667 | 3682 | ||
3668 | static void __init set_ftrace_early_filters(void) | 3683 | static void __init set_ftrace_early_filters(void) |
3669 | { | 3684 | { |
3670 | if (ftrace_filter_buf[0]) | 3685 | if (ftrace_filter_buf[0]) |
3671 | ftrace_set_early_filter(&global_ops, ftrace_filter_buf, 1); | 3686 | ftrace_set_early_filter(&global_ops, ftrace_filter_buf, 1); |
3672 | if (ftrace_notrace_buf[0]) | 3687 | if (ftrace_notrace_buf[0]) |
3673 | ftrace_set_early_filter(&global_ops, ftrace_notrace_buf, 0); | 3688 | ftrace_set_early_filter(&global_ops, ftrace_notrace_buf, 0); |
3674 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 3689 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
3675 | if (ftrace_graph_buf[0]) | 3690 | if (ftrace_graph_buf[0]) |
3676 | set_ftrace_early_graph(ftrace_graph_buf); | 3691 | set_ftrace_early_graph(ftrace_graph_buf); |
3677 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 3692 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
3678 | } | 3693 | } |
3679 | 3694 | ||
3680 | int ftrace_regex_release(struct inode *inode, struct file *file) | 3695 | int ftrace_regex_release(struct inode *inode, struct file *file) |
3681 | { | 3696 | { |
3682 | struct seq_file *m = (struct seq_file *)file->private_data; | 3697 | struct seq_file *m = (struct seq_file *)file->private_data; |
3683 | struct ftrace_iterator *iter; | 3698 | struct ftrace_iterator *iter; |
3684 | struct ftrace_hash **orig_hash; | 3699 | struct ftrace_hash **orig_hash; |
3685 | struct trace_parser *parser; | 3700 | struct trace_parser *parser; |
3686 | int filter_hash; | 3701 | int filter_hash; |
3687 | int ret; | 3702 | int ret; |
3688 | 3703 | ||
3689 | if (file->f_mode & FMODE_READ) { | 3704 | if (file->f_mode & FMODE_READ) { |
3690 | iter = m->private; | 3705 | iter = m->private; |
3691 | seq_release(inode, file); | 3706 | seq_release(inode, file); |
3692 | } else | 3707 | } else |
3693 | iter = file->private_data; | 3708 | iter = file->private_data; |
3694 | 3709 | ||
3695 | parser = &iter->parser; | 3710 | parser = &iter->parser; |
3696 | if (trace_parser_loaded(parser)) { | 3711 | if (trace_parser_loaded(parser)) { |
3697 | parser->buffer[parser->idx] = 0; | 3712 | parser->buffer[parser->idx] = 0; |
3698 | ftrace_match_records(iter->hash, parser->buffer, parser->idx); | 3713 | ftrace_match_records(iter->hash, parser->buffer, parser->idx); |
3699 | } | 3714 | } |
3700 | 3715 | ||
3701 | trace_parser_put(parser); | 3716 | trace_parser_put(parser); |
3702 | 3717 | ||
3703 | mutex_lock(&iter->ops->regex_lock); | 3718 | mutex_lock(&iter->ops->regex_lock); |
3704 | 3719 | ||
3705 | if (file->f_mode & FMODE_WRITE) { | 3720 | if (file->f_mode & FMODE_WRITE) { |
3706 | filter_hash = !!(iter->flags & FTRACE_ITER_FILTER); | 3721 | filter_hash = !!(iter->flags & FTRACE_ITER_FILTER); |
3707 | 3722 | ||
3708 | if (filter_hash) | 3723 | if (filter_hash) |
3709 | orig_hash = &iter->ops->filter_hash; | 3724 | orig_hash = &iter->ops->filter_hash; |
3710 | else | 3725 | else |
3711 | orig_hash = &iter->ops->notrace_hash; | 3726 | orig_hash = &iter->ops->notrace_hash; |
3712 | 3727 | ||
3713 | mutex_lock(&ftrace_lock); | 3728 | mutex_lock(&ftrace_lock); |
3714 | ret = ftrace_hash_move(iter->ops, filter_hash, | 3729 | ret = ftrace_hash_move(iter->ops, filter_hash, |
3715 | orig_hash, iter->hash); | 3730 | orig_hash, iter->hash); |
3716 | if (!ret) | 3731 | if (!ret) |
3717 | ftrace_ops_update_code(iter->ops); | 3732 | ftrace_ops_update_code(iter->ops); |
3718 | 3733 | ||
3719 | mutex_unlock(&ftrace_lock); | 3734 | mutex_unlock(&ftrace_lock); |
3720 | } | 3735 | } |
3721 | 3736 | ||
3722 | mutex_unlock(&iter->ops->regex_lock); | 3737 | mutex_unlock(&iter->ops->regex_lock); |
3723 | free_ftrace_hash(iter->hash); | 3738 | free_ftrace_hash(iter->hash); |
3724 | kfree(iter); | 3739 | kfree(iter); |
3725 | 3740 | ||
3726 | return 0; | 3741 | return 0; |
3727 | } | 3742 | } |
3728 | 3743 | ||
3729 | static const struct file_operations ftrace_avail_fops = { | 3744 | static const struct file_operations ftrace_avail_fops = { |
3730 | .open = ftrace_avail_open, | 3745 | .open = ftrace_avail_open, |
3731 | .read = seq_read, | 3746 | .read = seq_read, |
3732 | .llseek = seq_lseek, | 3747 | .llseek = seq_lseek, |
3733 | .release = seq_release_private, | 3748 | .release = seq_release_private, |
3734 | }; | 3749 | }; |
3735 | 3750 | ||
3736 | static const struct file_operations ftrace_enabled_fops = { | 3751 | static const struct file_operations ftrace_enabled_fops = { |
3737 | .open = ftrace_enabled_open, | 3752 | .open = ftrace_enabled_open, |
3738 | .read = seq_read, | 3753 | .read = seq_read, |
3739 | .llseek = seq_lseek, | 3754 | .llseek = seq_lseek, |
3740 | .release = seq_release_private, | 3755 | .release = seq_release_private, |
3741 | }; | 3756 | }; |
3742 | 3757 | ||
3743 | static const struct file_operations ftrace_filter_fops = { | 3758 | static const struct file_operations ftrace_filter_fops = { |
3744 | .open = ftrace_filter_open, | 3759 | .open = ftrace_filter_open, |
3745 | .read = seq_read, | 3760 | .read = seq_read, |
3746 | .write = ftrace_filter_write, | 3761 | .write = ftrace_filter_write, |
3747 | .llseek = ftrace_filter_lseek, | 3762 | .llseek = ftrace_filter_lseek, |
3748 | .release = ftrace_regex_release, | 3763 | .release = ftrace_regex_release, |
3749 | }; | 3764 | }; |
3750 | 3765 | ||
3751 | static const struct file_operations ftrace_notrace_fops = { | 3766 | static const struct file_operations ftrace_notrace_fops = { |
3752 | .open = ftrace_notrace_open, | 3767 | .open = ftrace_notrace_open, |
3753 | .read = seq_read, | 3768 | .read = seq_read, |
3754 | .write = ftrace_notrace_write, | 3769 | .write = ftrace_notrace_write, |
3755 | .llseek = ftrace_filter_lseek, | 3770 | .llseek = ftrace_filter_lseek, |
3756 | .release = ftrace_regex_release, | 3771 | .release = ftrace_regex_release, |
3757 | }; | 3772 | }; |
3758 | 3773 | ||
3759 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 3774 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
3760 | 3775 | ||
3761 | static DEFINE_MUTEX(graph_lock); | 3776 | static DEFINE_MUTEX(graph_lock); |
3762 | 3777 | ||
3763 | int ftrace_graph_count; | 3778 | int ftrace_graph_count; |
3764 | int ftrace_graph_filter_enabled; | 3779 | int ftrace_graph_filter_enabled; |
3765 | unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; | 3780 | unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; |
3766 | 3781 | ||
3767 | static void * | 3782 | static void * |
3768 | __g_next(struct seq_file *m, loff_t *pos) | 3783 | __g_next(struct seq_file *m, loff_t *pos) |
3769 | { | 3784 | { |
3770 | if (*pos >= ftrace_graph_count) | 3785 | if (*pos >= ftrace_graph_count) |
3771 | return NULL; | 3786 | return NULL; |
3772 | return &ftrace_graph_funcs[*pos]; | 3787 | return &ftrace_graph_funcs[*pos]; |
3773 | } | 3788 | } |
3774 | 3789 | ||
3775 | static void * | 3790 | static void * |
3776 | g_next(struct seq_file *m, void *v, loff_t *pos) | 3791 | g_next(struct seq_file *m, void *v, loff_t *pos) |
3777 | { | 3792 | { |
3778 | (*pos)++; | 3793 | (*pos)++; |
3779 | return __g_next(m, pos); | 3794 | return __g_next(m, pos); |
3780 | } | 3795 | } |
3781 | 3796 | ||
3782 | static void *g_start(struct seq_file *m, loff_t *pos) | 3797 | static void *g_start(struct seq_file *m, loff_t *pos) |
3783 | { | 3798 | { |
3784 | mutex_lock(&graph_lock); | 3799 | mutex_lock(&graph_lock); |
3785 | 3800 | ||
3786 | /* Nothing, tell g_show to print all functions are enabled */ | 3801 | /* Nothing, tell g_show to print all functions are enabled */ |
3787 | if (!ftrace_graph_filter_enabled && !*pos) | 3802 | if (!ftrace_graph_filter_enabled && !*pos) |
3788 | return (void *)1; | 3803 | return (void *)1; |
3789 | 3804 | ||
3790 | return __g_next(m, pos); | 3805 | return __g_next(m, pos); |
3791 | } | 3806 | } |
3792 | 3807 | ||
3793 | static void g_stop(struct seq_file *m, void *p) | 3808 | static void g_stop(struct seq_file *m, void *p) |
3794 | { | 3809 | { |
3795 | mutex_unlock(&graph_lock); | 3810 | mutex_unlock(&graph_lock); |
3796 | } | 3811 | } |
3797 | 3812 | ||
3798 | static int g_show(struct seq_file *m, void *v) | 3813 | static int g_show(struct seq_file *m, void *v) |
3799 | { | 3814 | { |
3800 | unsigned long *ptr = v; | 3815 | unsigned long *ptr = v; |
3801 | 3816 | ||
3802 | if (!ptr) | 3817 | if (!ptr) |
3803 | return 0; | 3818 | return 0; |
3804 | 3819 | ||
3805 | if (ptr == (unsigned long *)1) { | 3820 | if (ptr == (unsigned long *)1) { |
3806 | seq_printf(m, "#### all functions enabled ####\n"); | 3821 | seq_printf(m, "#### all functions enabled ####\n"); |
3807 | return 0; | 3822 | return 0; |
3808 | } | 3823 | } |
3809 | 3824 | ||
3810 | seq_printf(m, "%ps\n", (void *)*ptr); | 3825 | seq_printf(m, "%ps\n", (void *)*ptr); |
3811 | 3826 | ||
3812 | return 0; | 3827 | return 0; |
3813 | } | 3828 | } |
3814 | 3829 | ||
3815 | static const struct seq_operations ftrace_graph_seq_ops = { | 3830 | static const struct seq_operations ftrace_graph_seq_ops = { |
3816 | .start = g_start, | 3831 | .start = g_start, |
3817 | .next = g_next, | 3832 | .next = g_next, |
3818 | .stop = g_stop, | 3833 | .stop = g_stop, |
3819 | .show = g_show, | 3834 | .show = g_show, |
3820 | }; | 3835 | }; |
3821 | 3836 | ||
3822 | static int | 3837 | static int |
3823 | ftrace_graph_open(struct inode *inode, struct file *file) | 3838 | ftrace_graph_open(struct inode *inode, struct file *file) |
3824 | { | 3839 | { |
3825 | int ret = 0; | 3840 | int ret = 0; |
3826 | 3841 | ||
3827 | if (unlikely(ftrace_disabled)) | 3842 | if (unlikely(ftrace_disabled)) |
3828 | return -ENODEV; | 3843 | return -ENODEV; |
3829 | 3844 | ||
3830 | mutex_lock(&graph_lock); | 3845 | mutex_lock(&graph_lock); |
3831 | if ((file->f_mode & FMODE_WRITE) && | 3846 | if ((file->f_mode & FMODE_WRITE) && |
3832 | (file->f_flags & O_TRUNC)) { | 3847 | (file->f_flags & O_TRUNC)) { |
3833 | ftrace_graph_filter_enabled = 0; | 3848 | ftrace_graph_filter_enabled = 0; |
3834 | ftrace_graph_count = 0; | 3849 | ftrace_graph_count = 0; |
3835 | memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs)); | 3850 | memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs)); |
3836 | } | 3851 | } |
3837 | mutex_unlock(&graph_lock); | 3852 | mutex_unlock(&graph_lock); |
3838 | 3853 | ||
3839 | if (file->f_mode & FMODE_READ) | 3854 | if (file->f_mode & FMODE_READ) |
3840 | ret = seq_open(file, &ftrace_graph_seq_ops); | 3855 | ret = seq_open(file, &ftrace_graph_seq_ops); |
3841 | 3856 | ||
3842 | return ret; | 3857 | return ret; |
3843 | } | 3858 | } |
3844 | 3859 | ||
3845 | static int | 3860 | static int |
3846 | ftrace_graph_release(struct inode *inode, struct file *file) | 3861 | ftrace_graph_release(struct inode *inode, struct file *file) |
3847 | { | 3862 | { |
3848 | if (file->f_mode & FMODE_READ) | 3863 | if (file->f_mode & FMODE_READ) |
3849 | seq_release(inode, file); | 3864 | seq_release(inode, file); |
3850 | return 0; | 3865 | return 0; |
3851 | } | 3866 | } |
3852 | 3867 | ||
3853 | static int | 3868 | static int |
3854 | ftrace_set_func(unsigned long *array, int *idx, char *buffer) | 3869 | ftrace_set_func(unsigned long *array, int *idx, char *buffer) |
3855 | { | 3870 | { |
3856 | struct dyn_ftrace *rec; | 3871 | struct dyn_ftrace *rec; |
3857 | struct ftrace_page *pg; | 3872 | struct ftrace_page *pg; |
3858 | int search_len; | 3873 | int search_len; |
3859 | int fail = 1; | 3874 | int fail = 1; |
3860 | int type, not; | 3875 | int type, not; |
3861 | char *search; | 3876 | char *search; |
3862 | bool exists; | 3877 | bool exists; |
3863 | int i; | 3878 | int i; |
3864 | 3879 | ||
3865 | /* decode regex */ | 3880 | /* decode regex */ |
3866 | type = filter_parse_regex(buffer, strlen(buffer), &search, ¬); | 3881 | type = filter_parse_regex(buffer, strlen(buffer), &search, ¬); |
3867 | if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS) | 3882 | if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS) |
3868 | return -EBUSY; | 3883 | return -EBUSY; |
3869 | 3884 | ||
3870 | search_len = strlen(search); | 3885 | search_len = strlen(search); |
3871 | 3886 | ||
3872 | mutex_lock(&ftrace_lock); | 3887 | mutex_lock(&ftrace_lock); |
3873 | 3888 | ||
3874 | if (unlikely(ftrace_disabled)) { | 3889 | if (unlikely(ftrace_disabled)) { |
3875 | mutex_unlock(&ftrace_lock); | 3890 | mutex_unlock(&ftrace_lock); |
3876 | return -ENODEV; | 3891 | return -ENODEV; |
3877 | } | 3892 | } |
3878 | 3893 | ||
3879 | do_for_each_ftrace_rec(pg, rec) { | 3894 | do_for_each_ftrace_rec(pg, rec) { |
3880 | 3895 | ||
3881 | if (ftrace_match_record(rec, NULL, search, search_len, type)) { | 3896 | if (ftrace_match_record(rec, NULL, search, search_len, type)) { |
3882 | /* if it is in the array */ | 3897 | /* if it is in the array */ |
3883 | exists = false; | 3898 | exists = false; |
3884 | for (i = 0; i < *idx; i++) { | 3899 | for (i = 0; i < *idx; i++) { |
3885 | if (array[i] == rec->ip) { | 3900 | if (array[i] == rec->ip) { |
3886 | exists = true; | 3901 | exists = true; |
3887 | break; | 3902 | break; |
3888 | } | 3903 | } |
3889 | } | 3904 | } |
3890 | 3905 | ||
3891 | if (!not) { | 3906 | if (!not) { |
3892 | fail = 0; | 3907 | fail = 0; |
3893 | if (!exists) { | 3908 | if (!exists) { |
3894 | array[(*idx)++] = rec->ip; | 3909 | array[(*idx)++] = rec->ip; |
3895 | if (*idx >= FTRACE_GRAPH_MAX_FUNCS) | 3910 | if (*idx >= FTRACE_GRAPH_MAX_FUNCS) |
3896 | goto out; | 3911 | goto out; |
3897 | } | 3912 | } |
3898 | } else { | 3913 | } else { |
3899 | if (exists) { | 3914 | if (exists) { |
3900 | array[i] = array[--(*idx)]; | 3915 | array[i] = array[--(*idx)]; |
3901 | array[*idx] = 0; | 3916 | array[*idx] = 0; |
3902 | fail = 0; | 3917 | fail = 0; |
3903 | } | 3918 | } |
3904 | } | 3919 | } |
3905 | } | 3920 | } |
3906 | } while_for_each_ftrace_rec(); | 3921 | } while_for_each_ftrace_rec(); |
3907 | out: | 3922 | out: |
3908 | mutex_unlock(&ftrace_lock); | 3923 | mutex_unlock(&ftrace_lock); |
3909 | 3924 | ||
3910 | if (fail) | 3925 | if (fail) |
3911 | return -EINVAL; | 3926 | return -EINVAL; |
3912 | 3927 | ||
3913 | ftrace_graph_filter_enabled = !!(*idx); | 3928 | ftrace_graph_filter_enabled = !!(*idx); |
3914 | 3929 | ||
3915 | return 0; | 3930 | return 0; |
3916 | } | 3931 | } |
3917 | 3932 | ||
3918 | static ssize_t | 3933 | static ssize_t |
3919 | ftrace_graph_write(struct file *file, const char __user *ubuf, | 3934 | ftrace_graph_write(struct file *file, const char __user *ubuf, |
3920 | size_t cnt, loff_t *ppos) | 3935 | size_t cnt, loff_t *ppos) |
3921 | { | 3936 | { |
3922 | struct trace_parser parser; | 3937 | struct trace_parser parser; |
3923 | ssize_t read, ret; | 3938 | ssize_t read, ret; |
3924 | 3939 | ||
3925 | if (!cnt) | 3940 | if (!cnt) |
3926 | return 0; | 3941 | return 0; |
3927 | 3942 | ||
3928 | mutex_lock(&graph_lock); | 3943 | mutex_lock(&graph_lock); |
3929 | 3944 | ||
3930 | if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) { | 3945 | if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) { |
3931 | ret = -ENOMEM; | 3946 | ret = -ENOMEM; |
3932 | goto out_unlock; | 3947 | goto out_unlock; |
3933 | } | 3948 | } |
3934 | 3949 | ||
3935 | read = trace_get_user(&parser, ubuf, cnt, ppos); | 3950 | read = trace_get_user(&parser, ubuf, cnt, ppos); |
3936 | 3951 | ||
3937 | if (read >= 0 && trace_parser_loaded((&parser))) { | 3952 | if (read >= 0 && trace_parser_loaded((&parser))) { |
3938 | parser.buffer[parser.idx] = 0; | 3953 | parser.buffer[parser.idx] = 0; |
3939 | 3954 | ||
3940 | /* we allow only one expression at a time */ | 3955 | /* we allow only one expression at a time */ |
3941 | ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, | 3956 | ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, |
3942 | parser.buffer); | 3957 | parser.buffer); |
3943 | if (ret) | 3958 | if (ret) |
3944 | goto out_free; | 3959 | goto out_free; |
3945 | } | 3960 | } |
3946 | 3961 | ||
3947 | ret = read; | 3962 | ret = read; |
3948 | 3963 | ||
3949 | out_free: | 3964 | out_free: |
3950 | trace_parser_put(&parser); | 3965 | trace_parser_put(&parser); |
3951 | out_unlock: | 3966 | out_unlock: |
3952 | mutex_unlock(&graph_lock); | 3967 | mutex_unlock(&graph_lock); |
3953 | 3968 | ||
3954 | return ret; | 3969 | return ret; |
3955 | } | 3970 | } |
3956 | 3971 | ||
3957 | static const struct file_operations ftrace_graph_fops = { | 3972 | static const struct file_operations ftrace_graph_fops = { |
3958 | .open = ftrace_graph_open, | 3973 | .open = ftrace_graph_open, |
3959 | .read = seq_read, | 3974 | .read = seq_read, |
3960 | .write = ftrace_graph_write, | 3975 | .write = ftrace_graph_write, |
3961 | .llseek = ftrace_filter_lseek, | 3976 | .llseek = ftrace_filter_lseek, |
3962 | .release = ftrace_graph_release, | 3977 | .release = ftrace_graph_release, |
3963 | }; | 3978 | }; |
3964 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 3979 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
3965 | 3980 | ||
3966 | static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) | 3981 | static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) |
3967 | { | 3982 | { |
3968 | 3983 | ||
3969 | trace_create_file("available_filter_functions", 0444, | 3984 | trace_create_file("available_filter_functions", 0444, |
3970 | d_tracer, NULL, &ftrace_avail_fops); | 3985 | d_tracer, NULL, &ftrace_avail_fops); |
3971 | 3986 | ||
3972 | trace_create_file("enabled_functions", 0444, | 3987 | trace_create_file("enabled_functions", 0444, |
3973 | d_tracer, NULL, &ftrace_enabled_fops); | 3988 | d_tracer, NULL, &ftrace_enabled_fops); |
3974 | 3989 | ||
3975 | trace_create_file("set_ftrace_filter", 0644, d_tracer, | 3990 | trace_create_file("set_ftrace_filter", 0644, d_tracer, |
3976 | NULL, &ftrace_filter_fops); | 3991 | NULL, &ftrace_filter_fops); |
3977 | 3992 | ||
3978 | trace_create_file("set_ftrace_notrace", 0644, d_tracer, | 3993 | trace_create_file("set_ftrace_notrace", 0644, d_tracer, |
3979 | NULL, &ftrace_notrace_fops); | 3994 | NULL, &ftrace_notrace_fops); |
3980 | 3995 | ||
3981 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 3996 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
3982 | trace_create_file("set_graph_function", 0444, d_tracer, | 3997 | trace_create_file("set_graph_function", 0444, d_tracer, |
3983 | NULL, | 3998 | NULL, |
3984 | &ftrace_graph_fops); | 3999 | &ftrace_graph_fops); |
3985 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 4000 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
3986 | 4001 | ||
3987 | return 0; | 4002 | return 0; |
3988 | } | 4003 | } |
3989 | 4004 | ||
3990 | static int ftrace_cmp_ips(const void *a, const void *b) | 4005 | static int ftrace_cmp_ips(const void *a, const void *b) |
3991 | { | 4006 | { |
3992 | const unsigned long *ipa = a; | 4007 | const unsigned long *ipa = a; |
3993 | const unsigned long *ipb = b; | 4008 | const unsigned long *ipb = b; |
3994 | 4009 | ||
3995 | if (*ipa > *ipb) | 4010 | if (*ipa > *ipb) |
3996 | return 1; | 4011 | return 1; |
3997 | if (*ipa < *ipb) | 4012 | if (*ipa < *ipb) |
3998 | return -1; | 4013 | return -1; |
3999 | return 0; | 4014 | return 0; |
4000 | } | 4015 | } |
4001 | 4016 | ||
4002 | static void ftrace_swap_ips(void *a, void *b, int size) | 4017 | static void ftrace_swap_ips(void *a, void *b, int size) |
4003 | { | 4018 | { |
4004 | unsigned long *ipa = a; | 4019 | unsigned long *ipa = a; |
4005 | unsigned long *ipb = b; | 4020 | unsigned long *ipb = b; |
4006 | unsigned long t; | 4021 | unsigned long t; |
4007 | 4022 | ||
4008 | t = *ipa; | 4023 | t = *ipa; |
4009 | *ipa = *ipb; | 4024 | *ipa = *ipb; |
4010 | *ipb = t; | 4025 | *ipb = t; |
4011 | } | 4026 | } |
4012 | 4027 | ||
4013 | static int ftrace_process_locs(struct module *mod, | 4028 | static int ftrace_process_locs(struct module *mod, |
4014 | unsigned long *start, | 4029 | unsigned long *start, |
4015 | unsigned long *end) | 4030 | unsigned long *end) |
4016 | { | 4031 | { |
4017 | struct ftrace_page *start_pg; | 4032 | struct ftrace_page *start_pg; |
4018 | struct ftrace_page *pg; | 4033 | struct ftrace_page *pg; |
4019 | struct dyn_ftrace *rec; | 4034 | struct dyn_ftrace *rec; |
4020 | unsigned long count; | 4035 | unsigned long count; |
4021 | unsigned long *p; | 4036 | unsigned long *p; |
4022 | unsigned long addr; | 4037 | unsigned long addr; |
4023 | unsigned long flags = 0; /* Shut up gcc */ | 4038 | unsigned long flags = 0; /* Shut up gcc */ |
4024 | int ret = -ENOMEM; | 4039 | int ret = -ENOMEM; |
4025 | 4040 | ||
4026 | count = end - start; | 4041 | count = end - start; |
4027 | 4042 | ||
4028 | if (!count) | 4043 | if (!count) |
4029 | return 0; | 4044 | return 0; |
4030 | 4045 | ||
4031 | sort(start, count, sizeof(*start), | 4046 | sort(start, count, sizeof(*start), |
4032 | ftrace_cmp_ips, ftrace_swap_ips); | 4047 | ftrace_cmp_ips, ftrace_swap_ips); |
4033 | 4048 | ||
4034 | start_pg = ftrace_allocate_pages(count); | 4049 | start_pg = ftrace_allocate_pages(count); |
4035 | if (!start_pg) | 4050 | if (!start_pg) |
4036 | return -ENOMEM; | 4051 | return -ENOMEM; |
4037 | 4052 | ||
4038 | mutex_lock(&ftrace_lock); | 4053 | mutex_lock(&ftrace_lock); |
4039 | 4054 | ||
4040 | /* | 4055 | /* |
4041 | * Core and each module needs their own pages, as | 4056 | * Core and each module needs their own pages, as |
4042 | * modules will free them when they are removed. | 4057 | * modules will free them when they are removed. |
4043 | * Force a new page to be allocated for modules. | 4058 | * Force a new page to be allocated for modules. |
4044 | */ | 4059 | */ |
4045 | if (!mod) { | 4060 | if (!mod) { |
4046 | WARN_ON(ftrace_pages || ftrace_pages_start); | 4061 | WARN_ON(ftrace_pages || ftrace_pages_start); |
4047 | /* First initialization */ | 4062 | /* First initialization */ |
4048 | ftrace_pages = ftrace_pages_start = start_pg; | 4063 | ftrace_pages = ftrace_pages_start = start_pg; |
4049 | } else { | 4064 | } else { |
4050 | if (!ftrace_pages) | 4065 | if (!ftrace_pages) |
4051 | goto out; | 4066 | goto out; |
4052 | 4067 | ||
4053 | if (WARN_ON(ftrace_pages->next)) { | 4068 | if (WARN_ON(ftrace_pages->next)) { |
4054 | /* Hmm, we have free pages? */ | 4069 | /* Hmm, we have free pages? */ |
4055 | while (ftrace_pages->next) | 4070 | while (ftrace_pages->next) |
4056 | ftrace_pages = ftrace_pages->next; | 4071 | ftrace_pages = ftrace_pages->next; |
4057 | } | 4072 | } |
4058 | 4073 | ||
4059 | ftrace_pages->next = start_pg; | 4074 | ftrace_pages->next = start_pg; |
4060 | } | 4075 | } |
4061 | 4076 | ||
4062 | p = start; | 4077 | p = start; |
4063 | pg = start_pg; | 4078 | pg = start_pg; |
4064 | while (p < end) { | 4079 | while (p < end) { |
4065 | addr = ftrace_call_adjust(*p++); | 4080 | addr = ftrace_call_adjust(*p++); |
4066 | /* | 4081 | /* |
4067 | * Some architecture linkers will pad between | 4082 | * Some architecture linkers will pad between |
4068 | * the different mcount_loc sections of different | 4083 | * the different mcount_loc sections of different |
4069 | * object files to satisfy alignments. | 4084 | * object files to satisfy alignments. |
4070 | * Skip any NULL pointers. | 4085 | * Skip any NULL pointers. |
4071 | */ | 4086 | */ |
4072 | if (!addr) | 4087 | if (!addr) |
4073 | continue; | 4088 | continue; |
4074 | 4089 | ||
4075 | if (pg->index == pg->size) { | 4090 | if (pg->index == pg->size) { |
4076 | /* We should have allocated enough */ | 4091 | /* We should have allocated enough */ |
4077 | if (WARN_ON(!pg->next)) | 4092 | if (WARN_ON(!pg->next)) |
4078 | break; | 4093 | break; |
4079 | pg = pg->next; | 4094 | pg = pg->next; |
4080 | } | 4095 | } |
4081 | 4096 | ||
4082 | rec = &pg->records[pg->index++]; | 4097 | rec = &pg->records[pg->index++]; |
4083 | rec->ip = addr; | 4098 | rec->ip = addr; |
4084 | } | 4099 | } |
4085 | 4100 | ||
4086 | /* We should have used all pages */ | 4101 | /* We should have used all pages */ |
4087 | WARN_ON(pg->next); | 4102 | WARN_ON(pg->next); |
4088 | 4103 | ||
4089 | /* Assign the last page to ftrace_pages */ | 4104 | /* Assign the last page to ftrace_pages */ |
4090 | ftrace_pages = pg; | 4105 | ftrace_pages = pg; |
4091 | 4106 | ||
4092 | /* These new locations need to be initialized */ | 4107 | /* These new locations need to be initialized */ |
4093 | ftrace_new_pgs = start_pg; | 4108 | ftrace_new_pgs = start_pg; |
4094 | 4109 | ||
4095 | /* | 4110 | /* |
4096 | * We only need to disable interrupts on start up | 4111 | * We only need to disable interrupts on start up |
4097 | * because we are modifying code that an interrupt | 4112 | * because we are modifying code that an interrupt |
4098 | * may execute, and the modification is not atomic. | 4113 | * may execute, and the modification is not atomic. |
4099 | * But for modules, nothing runs the code we modify | 4114 | * But for modules, nothing runs the code we modify |
4100 | * until we are finished with it, and there's no | 4115 | * until we are finished with it, and there's no |
4101 | * reason to cause large interrupt latencies while we do it. | 4116 | * reason to cause large interrupt latencies while we do it. |
4102 | */ | 4117 | */ |
4103 | if (!mod) | 4118 | if (!mod) |
4104 | local_irq_save(flags); | 4119 | local_irq_save(flags); |
4105 | ftrace_update_code(mod); | 4120 | ftrace_update_code(mod); |
4106 | if (!mod) | 4121 | if (!mod) |
4107 | local_irq_restore(flags); | 4122 | local_irq_restore(flags); |
4108 | ret = 0; | 4123 | ret = 0; |
4109 | out: | 4124 | out: |
4110 | mutex_unlock(&ftrace_lock); | 4125 | mutex_unlock(&ftrace_lock); |
4111 | 4126 | ||
4112 | return ret; | 4127 | return ret; |
4113 | } | 4128 | } |
4114 | 4129 | ||
4115 | #ifdef CONFIG_MODULES | 4130 | #ifdef CONFIG_MODULES |
4116 | 4131 | ||
4117 | #define next_to_ftrace_page(p) container_of(p, struct ftrace_page, next) | 4132 | #define next_to_ftrace_page(p) container_of(p, struct ftrace_page, next) |
4118 | 4133 | ||
4119 | void ftrace_release_mod(struct module *mod) | 4134 | void ftrace_release_mod(struct module *mod) |
4120 | { | 4135 | { |
4121 | struct dyn_ftrace *rec; | 4136 | struct dyn_ftrace *rec; |
4122 | struct ftrace_page **last_pg; | 4137 | struct ftrace_page **last_pg; |
4123 | struct ftrace_page *pg; | 4138 | struct ftrace_page *pg; |
4124 | int order; | 4139 | int order; |
4125 | 4140 | ||
4126 | mutex_lock(&ftrace_lock); | 4141 | mutex_lock(&ftrace_lock); |
4127 | 4142 | ||
4128 | if (ftrace_disabled) | 4143 | if (ftrace_disabled) |
4129 | goto out_unlock; | 4144 | goto out_unlock; |
4130 | 4145 | ||
4131 | /* | 4146 | /* |
4132 | * Each module has its own ftrace_pages, remove | 4147 | * Each module has its own ftrace_pages, remove |
4133 | * them from the list. | 4148 | * them from the list. |
4134 | */ | 4149 | */ |
4135 | last_pg = &ftrace_pages_start; | 4150 | last_pg = &ftrace_pages_start; |
4136 | for (pg = ftrace_pages_start; pg; pg = *last_pg) { | 4151 | for (pg = ftrace_pages_start; pg; pg = *last_pg) { |
4137 | rec = &pg->records[0]; | 4152 | rec = &pg->records[0]; |
4138 | if (within_module_core(rec->ip, mod)) { | 4153 | if (within_module_core(rec->ip, mod)) { |
4139 | /* | 4154 | /* |
4140 | * As core pages are first, the first | 4155 | * As core pages are first, the first |
4141 | * page should never be a module page. | 4156 | * page should never be a module page. |
4142 | */ | 4157 | */ |
4143 | if (WARN_ON(pg == ftrace_pages_start)) | 4158 | if (WARN_ON(pg == ftrace_pages_start)) |
4144 | goto out_unlock; | 4159 | goto out_unlock; |
4145 | 4160 | ||
4146 | /* Check if we are deleting the last page */ | 4161 | /* Check if we are deleting the last page */ |
4147 | if (pg == ftrace_pages) | 4162 | if (pg == ftrace_pages) |
4148 | ftrace_pages = next_to_ftrace_page(last_pg); | 4163 | ftrace_pages = next_to_ftrace_page(last_pg); |
4149 | 4164 | ||
4150 | *last_pg = pg->next; | 4165 | *last_pg = pg->next; |
4151 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); | 4166 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); |
4152 | free_pages((unsigned long)pg->records, order); | 4167 | free_pages((unsigned long)pg->records, order); |
4153 | kfree(pg); | 4168 | kfree(pg); |
4154 | } else | 4169 | } else |
4155 | last_pg = &pg->next; | 4170 | last_pg = &pg->next; |
4156 | } | 4171 | } |
4157 | out_unlock: | 4172 | out_unlock: |
4158 | mutex_unlock(&ftrace_lock); | 4173 | mutex_unlock(&ftrace_lock); |
4159 | } | 4174 | } |
4160 | 4175 | ||
4161 | static void ftrace_init_module(struct module *mod, | 4176 | static void ftrace_init_module(struct module *mod, |
4162 | unsigned long *start, unsigned long *end) | 4177 | unsigned long *start, unsigned long *end) |
4163 | { | 4178 | { |
4164 | if (ftrace_disabled || start == end) | 4179 | if (ftrace_disabled || start == end) |
4165 | return; | 4180 | return; |
4166 | ftrace_process_locs(mod, start, end); | 4181 | ftrace_process_locs(mod, start, end); |
4167 | } | 4182 | } |
4168 | 4183 | ||
4169 | static int ftrace_module_notify_enter(struct notifier_block *self, | 4184 | static int ftrace_module_notify_enter(struct notifier_block *self, |
4170 | unsigned long val, void *data) | 4185 | unsigned long val, void *data) |
4171 | { | 4186 | { |
4172 | struct module *mod = data; | 4187 | struct module *mod = data; |
4173 | 4188 | ||
4174 | if (val == MODULE_STATE_COMING) | 4189 | if (val == MODULE_STATE_COMING) |
4175 | ftrace_init_module(mod, mod->ftrace_callsites, | 4190 | ftrace_init_module(mod, mod->ftrace_callsites, |
4176 | mod->ftrace_callsites + | 4191 | mod->ftrace_callsites + |
4177 | mod->num_ftrace_callsites); | 4192 | mod->num_ftrace_callsites); |
4178 | return 0; | 4193 | return 0; |
4179 | } | 4194 | } |
4180 | 4195 | ||
4181 | static int ftrace_module_notify_exit(struct notifier_block *self, | 4196 | static int ftrace_module_notify_exit(struct notifier_block *self, |
4182 | unsigned long val, void *data) | 4197 | unsigned long val, void *data) |
4183 | { | 4198 | { |
4184 | struct module *mod = data; | 4199 | struct module *mod = data; |
4185 | 4200 | ||
4186 | if (val == MODULE_STATE_GOING) | 4201 | if (val == MODULE_STATE_GOING) |
4187 | ftrace_release_mod(mod); | 4202 | ftrace_release_mod(mod); |
4188 | 4203 | ||
4189 | return 0; | 4204 | return 0; |
4190 | } | 4205 | } |
4191 | #else | 4206 | #else |
4192 | static int ftrace_module_notify_enter(struct notifier_block *self, | 4207 | static int ftrace_module_notify_enter(struct notifier_block *self, |
4193 | unsigned long val, void *data) | 4208 | unsigned long val, void *data) |
4194 | { | 4209 | { |
4195 | return 0; | 4210 | return 0; |
4196 | } | 4211 | } |
4197 | static int ftrace_module_notify_exit(struct notifier_block *self, | 4212 | static int ftrace_module_notify_exit(struct notifier_block *self, |
4198 | unsigned long val, void *data) | 4213 | unsigned long val, void *data) |
4199 | { | 4214 | { |
4200 | return 0; | 4215 | return 0; |
4201 | } | 4216 | } |
4202 | #endif /* CONFIG_MODULES */ | 4217 | #endif /* CONFIG_MODULES */ |
4203 | 4218 | ||
4204 | struct notifier_block ftrace_module_enter_nb = { | 4219 | struct notifier_block ftrace_module_enter_nb = { |
4205 | .notifier_call = ftrace_module_notify_enter, | 4220 | .notifier_call = ftrace_module_notify_enter, |
4206 | .priority = INT_MAX, /* Run before anything that can use kprobes */ | 4221 | .priority = INT_MAX, /* Run before anything that can use kprobes */ |
4207 | }; | 4222 | }; |
4208 | 4223 | ||
4209 | struct notifier_block ftrace_module_exit_nb = { | 4224 | struct notifier_block ftrace_module_exit_nb = { |
4210 | .notifier_call = ftrace_module_notify_exit, | 4225 | .notifier_call = ftrace_module_notify_exit, |
4211 | .priority = INT_MIN, /* Run after anything that can remove kprobes */ | 4226 | .priority = INT_MIN, /* Run after anything that can remove kprobes */ |
4212 | }; | 4227 | }; |
4213 | 4228 | ||
4214 | extern unsigned long __start_mcount_loc[]; | 4229 | extern unsigned long __start_mcount_loc[]; |
4215 | extern unsigned long __stop_mcount_loc[]; | 4230 | extern unsigned long __stop_mcount_loc[]; |
4216 | 4231 | ||
4217 | void __init ftrace_init(void) | 4232 | void __init ftrace_init(void) |
4218 | { | 4233 | { |
4219 | unsigned long count, addr, flags; | 4234 | unsigned long count, addr, flags; |
4220 | int ret; | 4235 | int ret; |
4221 | 4236 | ||
4222 | /* Keep the ftrace pointer to the stub */ | 4237 | /* Keep the ftrace pointer to the stub */ |
4223 | addr = (unsigned long)ftrace_stub; | 4238 | addr = (unsigned long)ftrace_stub; |
4224 | 4239 | ||
4225 | local_irq_save(flags); | 4240 | local_irq_save(flags); |
4226 | ftrace_dyn_arch_init(&addr); | 4241 | ftrace_dyn_arch_init(&addr); |
4227 | local_irq_restore(flags); | 4242 | local_irq_restore(flags); |
4228 | 4243 | ||
4229 | /* ftrace_dyn_arch_init places the return code in addr */ | 4244 | /* ftrace_dyn_arch_init places the return code in addr */ |
4230 | if (addr) | 4245 | if (addr) |
4231 | goto failed; | 4246 | goto failed; |
4232 | 4247 | ||
4233 | count = __stop_mcount_loc - __start_mcount_loc; | 4248 | count = __stop_mcount_loc - __start_mcount_loc; |
4234 | 4249 | ||
4235 | ret = ftrace_dyn_table_alloc(count); | 4250 | ret = ftrace_dyn_table_alloc(count); |
4236 | if (ret) | 4251 | if (ret) |
4237 | goto failed; | 4252 | goto failed; |
4238 | 4253 | ||
4239 | last_ftrace_enabled = ftrace_enabled = 1; | 4254 | last_ftrace_enabled = ftrace_enabled = 1; |
4240 | 4255 | ||
4241 | ret = ftrace_process_locs(NULL, | 4256 | ret = ftrace_process_locs(NULL, |
4242 | __start_mcount_loc, | 4257 | __start_mcount_loc, |
4243 | __stop_mcount_loc); | 4258 | __stop_mcount_loc); |
4244 | 4259 | ||
4245 | ret = register_module_notifier(&ftrace_module_enter_nb); | 4260 | ret = register_module_notifier(&ftrace_module_enter_nb); |
4246 | if (ret) | 4261 | if (ret) |
4247 | pr_warning("Failed to register trace ftrace module enter notifier\n"); | 4262 | pr_warning("Failed to register trace ftrace module enter notifier\n"); |
4248 | 4263 | ||
4249 | ret = register_module_notifier(&ftrace_module_exit_nb); | 4264 | ret = register_module_notifier(&ftrace_module_exit_nb); |
4250 | if (ret) | 4265 | if (ret) |
4251 | pr_warning("Failed to register trace ftrace module exit notifier\n"); | 4266 | pr_warning("Failed to register trace ftrace module exit notifier\n"); |
4252 | 4267 | ||
4253 | set_ftrace_early_filters(); | 4268 | set_ftrace_early_filters(); |
4254 | 4269 | ||
4255 | return; | 4270 | return; |
4256 | failed: | 4271 | failed: |
4257 | ftrace_disabled = 1; | 4272 | ftrace_disabled = 1; |
4258 | } | 4273 | } |
4259 | 4274 | ||
4260 | #else | 4275 | #else |
4261 | 4276 | ||
4262 | static struct ftrace_ops global_ops = { | 4277 | static struct ftrace_ops global_ops = { |
4263 | .func = ftrace_stub, | 4278 | .func = ftrace_stub, |
4264 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, | 4279 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, |
4265 | INIT_REGEX_LOCK(global_ops) | 4280 | INIT_REGEX_LOCK(global_ops) |
4266 | }; | 4281 | }; |
4267 | 4282 | ||
4268 | static int __init ftrace_nodyn_init(void) | 4283 | static int __init ftrace_nodyn_init(void) |
4269 | { | 4284 | { |
4270 | ftrace_enabled = 1; | 4285 | ftrace_enabled = 1; |
4271 | return 0; | 4286 | return 0; |
4272 | } | 4287 | } |
4273 | core_initcall(ftrace_nodyn_init); | 4288 | core_initcall(ftrace_nodyn_init); |
4274 | 4289 | ||
4275 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } | 4290 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } |
4276 | static inline void ftrace_startup_enable(int command) { } | 4291 | static inline void ftrace_startup_enable(int command) { } |
4277 | /* Keep as macros so we do not need to define the commands */ | 4292 | /* Keep as macros so we do not need to define the commands */ |
4278 | # define ftrace_startup(ops, command) \ | 4293 | # define ftrace_startup(ops, command) \ |
4279 | ({ \ | 4294 | ({ \ |
4280 | (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ | 4295 | (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ |
4281 | 0; \ | 4296 | 0; \ |
4282 | }) | 4297 | }) |
4283 | # define ftrace_shutdown(ops, command) do { } while (0) | 4298 | # define ftrace_shutdown(ops, command) do { } while (0) |
4284 | # define ftrace_startup_sysctl() do { } while (0) | 4299 | # define ftrace_startup_sysctl() do { } while (0) |
4285 | # define ftrace_shutdown_sysctl() do { } while (0) | 4300 | # define ftrace_shutdown_sysctl() do { } while (0) |
4286 | 4301 | ||
4287 | static inline int | 4302 | static inline int |
4288 | ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) | 4303 | ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) |
4289 | { | 4304 | { |
4290 | return 1; | 4305 | return 1; |
4291 | } | 4306 | } |
4292 | 4307 | ||
4293 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 4308 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
4294 | 4309 | ||
4295 | static void | 4310 | static void |
4296 | ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip, | 4311 | ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip, |
4297 | struct ftrace_ops *op, struct pt_regs *regs) | 4312 | struct ftrace_ops *op, struct pt_regs *regs) |
4298 | { | 4313 | { |
4299 | if (unlikely(trace_recursion_test(TRACE_CONTROL_BIT))) | 4314 | if (unlikely(trace_recursion_test(TRACE_CONTROL_BIT))) |
4300 | return; | 4315 | return; |
4301 | 4316 | ||
4302 | /* | 4317 | /* |
4303 | * Some of the ops may be dynamically allocated, | 4318 | * Some of the ops may be dynamically allocated, |
4304 | * they must be freed after a synchronize_sched(). | 4319 | * they must be freed after a synchronize_sched(). |
4305 | */ | 4320 | */ |
4306 | preempt_disable_notrace(); | 4321 | preempt_disable_notrace(); |
4307 | trace_recursion_set(TRACE_CONTROL_BIT); | 4322 | trace_recursion_set(TRACE_CONTROL_BIT); |
4308 | do_for_each_ftrace_op(op, ftrace_control_list) { | 4323 | do_for_each_ftrace_op(op, ftrace_control_list) { |
4309 | if (!(op->flags & FTRACE_OPS_FL_STUB) && | 4324 | if (!(op->flags & FTRACE_OPS_FL_STUB) && |
4310 | !ftrace_function_local_disabled(op) && | 4325 | !ftrace_function_local_disabled(op) && |
4311 | ftrace_ops_test(op, ip, regs)) | 4326 | ftrace_ops_test(op, ip, regs)) |
4312 | op->func(ip, parent_ip, op, regs); | 4327 | op->func(ip, parent_ip, op, regs); |
4313 | } while_for_each_ftrace_op(op); | 4328 | } while_for_each_ftrace_op(op); |
4314 | trace_recursion_clear(TRACE_CONTROL_BIT); | 4329 | trace_recursion_clear(TRACE_CONTROL_BIT); |
4315 | preempt_enable_notrace(); | 4330 | preempt_enable_notrace(); |
4316 | } | 4331 | } |
4317 | 4332 | ||
4318 | static struct ftrace_ops control_ops = { | 4333 | static struct ftrace_ops control_ops = { |
4319 | .func = ftrace_ops_control_func, | 4334 | .func = ftrace_ops_control_func, |
4320 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, | 4335 | .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, |
4321 | INIT_REGEX_LOCK(control_ops) | 4336 | INIT_REGEX_LOCK(control_ops) |
4322 | }; | 4337 | }; |
4323 | 4338 | ||
4324 | static inline void | 4339 | static inline void |
4325 | __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, | 4340 | __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, |
4326 | struct ftrace_ops *ignored, struct pt_regs *regs) | 4341 | struct ftrace_ops *ignored, struct pt_regs *regs) |
4327 | { | 4342 | { |
4328 | struct ftrace_ops *op; | 4343 | struct ftrace_ops *op; |
4329 | int bit; | 4344 | int bit; |
4330 | 4345 | ||
4331 | if (function_trace_stop) | 4346 | if (function_trace_stop) |
4332 | return; | 4347 | return; |
4333 | 4348 | ||
4334 | bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX); | 4349 | bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX); |
4335 | if (bit < 0) | 4350 | if (bit < 0) |
4336 | return; | 4351 | return; |
4337 | 4352 | ||
4338 | /* | 4353 | /* |
4339 | * Some of the ops may be dynamically allocated, | 4354 | * Some of the ops may be dynamically allocated, |
4340 | * they must be freed after a synchronize_sched(). | 4355 | * they must be freed after a synchronize_sched(). |
4341 | */ | 4356 | */ |
4342 | preempt_disable_notrace(); | 4357 | preempt_disable_notrace(); |
4343 | do_for_each_ftrace_op(op, ftrace_ops_list) { | 4358 | do_for_each_ftrace_op(op, ftrace_ops_list) { |
4344 | if (ftrace_ops_test(op, ip, regs)) | 4359 | if (ftrace_ops_test(op, ip, regs)) |
4345 | op->func(ip, parent_ip, op, regs); | 4360 | op->func(ip, parent_ip, op, regs); |
4346 | } while_for_each_ftrace_op(op); | 4361 | } while_for_each_ftrace_op(op); |
4347 | preempt_enable_notrace(); | 4362 | preempt_enable_notrace(); |
4348 | trace_clear_recursion(bit); | 4363 | trace_clear_recursion(bit); |
4349 | } | 4364 | } |
4350 | 4365 | ||
4351 | /* | 4366 | /* |
4352 | * Some archs only support passing ip and parent_ip. Even though | 4367 | * Some archs only support passing ip and parent_ip. Even though |
4353 | * the list function ignores the op parameter, we do not want any | 4368 | * the list function ignores the op parameter, we do not want any |
4354 | * C side effects, where a function is called without the caller | 4369 | * C side effects, where a function is called without the caller |
4355 | * sending a third parameter. | 4370 | * sending a third parameter. |
4356 | * Archs are to support both the regs and ftrace_ops at the same time. | 4371 | * Archs are to support both the regs and ftrace_ops at the same time. |
4357 | * If they support ftrace_ops, it is assumed they support regs. | 4372 | * If they support ftrace_ops, it is assumed they support regs. |
4358 | * If call backs want to use regs, they must either check for regs | 4373 | * If call backs want to use regs, they must either check for regs |
4359 | * being NULL, or CONFIG_DYNAMIC_FTRACE_WITH_REGS. | 4374 | * being NULL, or CONFIG_DYNAMIC_FTRACE_WITH_REGS. |
4360 | * Note, CONFIG_DYNAMIC_FTRACE_WITH_REGS expects a full regs to be saved. | 4375 | * Note, CONFIG_DYNAMIC_FTRACE_WITH_REGS expects a full regs to be saved. |
4361 | * An architecture can pass partial regs with ftrace_ops and still | 4376 | * An architecture can pass partial regs with ftrace_ops and still |
4362 | * set the ARCH_SUPPORT_FTARCE_OPS. | 4377 | * set the ARCH_SUPPORT_FTARCE_OPS. |
4363 | */ | 4378 | */ |
4364 | #if ARCH_SUPPORTS_FTRACE_OPS | 4379 | #if ARCH_SUPPORTS_FTRACE_OPS |
4365 | static void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, | 4380 | static void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, |
4366 | struct ftrace_ops *op, struct pt_regs *regs) | 4381 | struct ftrace_ops *op, struct pt_regs *regs) |
4367 | { | 4382 | { |
4368 | __ftrace_ops_list_func(ip, parent_ip, NULL, regs); | 4383 | __ftrace_ops_list_func(ip, parent_ip, NULL, regs); |
4369 | } | 4384 | } |
4370 | #else | 4385 | #else |
4371 | static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip) | 4386 | static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip) |
4372 | { | 4387 | { |
4373 | __ftrace_ops_list_func(ip, parent_ip, NULL, NULL); | 4388 | __ftrace_ops_list_func(ip, parent_ip, NULL, NULL); |
4374 | } | 4389 | } |
4375 | #endif | 4390 | #endif |
4376 | 4391 | ||
4377 | static void clear_ftrace_swapper(void) | 4392 | static void clear_ftrace_swapper(void) |
4378 | { | 4393 | { |
4379 | struct task_struct *p; | 4394 | struct task_struct *p; |
4380 | int cpu; | 4395 | int cpu; |
4381 | 4396 | ||
4382 | get_online_cpus(); | 4397 | get_online_cpus(); |
4383 | for_each_online_cpu(cpu) { | 4398 | for_each_online_cpu(cpu) { |
4384 | p = idle_task(cpu); | 4399 | p = idle_task(cpu); |
4385 | clear_tsk_trace_trace(p); | 4400 | clear_tsk_trace_trace(p); |
4386 | } | 4401 | } |
4387 | put_online_cpus(); | 4402 | put_online_cpus(); |
4388 | } | 4403 | } |
4389 | 4404 | ||
4390 | static void set_ftrace_swapper(void) | 4405 | static void set_ftrace_swapper(void) |
4391 | { | 4406 | { |
4392 | struct task_struct *p; | 4407 | struct task_struct *p; |
4393 | int cpu; | 4408 | int cpu; |
4394 | 4409 | ||
4395 | get_online_cpus(); | 4410 | get_online_cpus(); |
4396 | for_each_online_cpu(cpu) { | 4411 | for_each_online_cpu(cpu) { |
4397 | p = idle_task(cpu); | 4412 | p = idle_task(cpu); |
4398 | set_tsk_trace_trace(p); | 4413 | set_tsk_trace_trace(p); |
4399 | } | 4414 | } |
4400 | put_online_cpus(); | 4415 | put_online_cpus(); |
4401 | } | 4416 | } |
4402 | 4417 | ||
4403 | static void clear_ftrace_pid(struct pid *pid) | 4418 | static void clear_ftrace_pid(struct pid *pid) |
4404 | { | 4419 | { |
4405 | struct task_struct *p; | 4420 | struct task_struct *p; |
4406 | 4421 | ||
4407 | rcu_read_lock(); | 4422 | rcu_read_lock(); |
4408 | do_each_pid_task(pid, PIDTYPE_PID, p) { | 4423 | do_each_pid_task(pid, PIDTYPE_PID, p) { |
4409 | clear_tsk_trace_trace(p); | 4424 | clear_tsk_trace_trace(p); |
4410 | } while_each_pid_task(pid, PIDTYPE_PID, p); | 4425 | } while_each_pid_task(pid, PIDTYPE_PID, p); |
4411 | rcu_read_unlock(); | 4426 | rcu_read_unlock(); |
4412 | 4427 | ||
4413 | put_pid(pid); | 4428 | put_pid(pid); |
4414 | } | 4429 | } |
4415 | 4430 | ||
4416 | static void set_ftrace_pid(struct pid *pid) | 4431 | static void set_ftrace_pid(struct pid *pid) |
4417 | { | 4432 | { |
4418 | struct task_struct *p; | 4433 | struct task_struct *p; |
4419 | 4434 | ||
4420 | rcu_read_lock(); | 4435 | rcu_read_lock(); |
4421 | do_each_pid_task(pid, PIDTYPE_PID, p) { | 4436 | do_each_pid_task(pid, PIDTYPE_PID, p) { |
4422 | set_tsk_trace_trace(p); | 4437 | set_tsk_trace_trace(p); |
4423 | } while_each_pid_task(pid, PIDTYPE_PID, p); | 4438 | } while_each_pid_task(pid, PIDTYPE_PID, p); |
4424 | rcu_read_unlock(); | 4439 | rcu_read_unlock(); |
4425 | } | 4440 | } |
4426 | 4441 | ||
4427 | static void clear_ftrace_pid_task(struct pid *pid) | 4442 | static void clear_ftrace_pid_task(struct pid *pid) |
4428 | { | 4443 | { |
4429 | if (pid == ftrace_swapper_pid) | 4444 | if (pid == ftrace_swapper_pid) |
4430 | clear_ftrace_swapper(); | 4445 | clear_ftrace_swapper(); |
4431 | else | 4446 | else |
4432 | clear_ftrace_pid(pid); | 4447 | clear_ftrace_pid(pid); |
4433 | } | 4448 | } |
4434 | 4449 | ||
4435 | static void set_ftrace_pid_task(struct pid *pid) | 4450 | static void set_ftrace_pid_task(struct pid *pid) |
4436 | { | 4451 | { |
4437 | if (pid == ftrace_swapper_pid) | 4452 | if (pid == ftrace_swapper_pid) |
4438 | set_ftrace_swapper(); | 4453 | set_ftrace_swapper(); |
4439 | else | 4454 | else |
4440 | set_ftrace_pid(pid); | 4455 | set_ftrace_pid(pid); |
4441 | } | 4456 | } |
4442 | 4457 | ||
4443 | static int ftrace_pid_add(int p) | 4458 | static int ftrace_pid_add(int p) |
4444 | { | 4459 | { |
4445 | struct pid *pid; | 4460 | struct pid *pid; |
4446 | struct ftrace_pid *fpid; | 4461 | struct ftrace_pid *fpid; |
4447 | int ret = -EINVAL; | 4462 | int ret = -EINVAL; |
4448 | 4463 | ||
4449 | mutex_lock(&ftrace_lock); | 4464 | mutex_lock(&ftrace_lock); |
4450 | 4465 | ||
4451 | if (!p) | 4466 | if (!p) |
4452 | pid = ftrace_swapper_pid; | 4467 | pid = ftrace_swapper_pid; |
4453 | else | 4468 | else |
4454 | pid = find_get_pid(p); | 4469 | pid = find_get_pid(p); |
4455 | 4470 | ||
4456 | if (!pid) | 4471 | if (!pid) |
4457 | goto out; | 4472 | goto out; |
4458 | 4473 | ||
4459 | ret = 0; | 4474 | ret = 0; |
4460 | 4475 | ||
4461 | list_for_each_entry(fpid, &ftrace_pids, list) | 4476 | list_for_each_entry(fpid, &ftrace_pids, list) |
4462 | if (fpid->pid == pid) | 4477 | if (fpid->pid == pid) |
4463 | goto out_put; | 4478 | goto out_put; |
4464 | 4479 | ||
4465 | ret = -ENOMEM; | 4480 | ret = -ENOMEM; |
4466 | 4481 | ||
4467 | fpid = kmalloc(sizeof(*fpid), GFP_KERNEL); | 4482 | fpid = kmalloc(sizeof(*fpid), GFP_KERNEL); |
4468 | if (!fpid) | 4483 | if (!fpid) |
4469 | goto out_put; | 4484 | goto out_put; |
4470 | 4485 | ||
4471 | list_add(&fpid->list, &ftrace_pids); | 4486 | list_add(&fpid->list, &ftrace_pids); |
4472 | fpid->pid = pid; | 4487 | fpid->pid = pid; |
4473 | 4488 | ||
4474 | set_ftrace_pid_task(pid); | 4489 | set_ftrace_pid_task(pid); |
4475 | 4490 | ||
4476 | ftrace_update_pid_func(); | 4491 | ftrace_update_pid_func(); |
4477 | ftrace_startup_enable(0); | 4492 | ftrace_startup_enable(0); |
4478 | 4493 | ||
4479 | mutex_unlock(&ftrace_lock); | 4494 | mutex_unlock(&ftrace_lock); |
4480 | return 0; | 4495 | return 0; |
4481 | 4496 | ||
4482 | out_put: | 4497 | out_put: |
4483 | if (pid != ftrace_swapper_pid) | 4498 | if (pid != ftrace_swapper_pid) |
4484 | put_pid(pid); | 4499 | put_pid(pid); |
4485 | 4500 | ||
4486 | out: | 4501 | out: |
4487 | mutex_unlock(&ftrace_lock); | 4502 | mutex_unlock(&ftrace_lock); |
4488 | return ret; | 4503 | return ret; |
4489 | } | 4504 | } |
4490 | 4505 | ||
4491 | static void ftrace_pid_reset(void) | 4506 | static void ftrace_pid_reset(void) |
4492 | { | 4507 | { |
4493 | struct ftrace_pid *fpid, *safe; | 4508 | struct ftrace_pid *fpid, *safe; |
4494 | 4509 | ||
4495 | mutex_lock(&ftrace_lock); | 4510 | mutex_lock(&ftrace_lock); |
4496 | list_for_each_entry_safe(fpid, safe, &ftrace_pids, list) { | 4511 | list_for_each_entry_safe(fpid, safe, &ftrace_pids, list) { |
4497 | struct pid *pid = fpid->pid; | 4512 | struct pid *pid = fpid->pid; |
4498 | 4513 | ||
4499 | clear_ftrace_pid_task(pid); | 4514 | clear_ftrace_pid_task(pid); |
4500 | 4515 | ||
4501 | list_del(&fpid->list); | 4516 | list_del(&fpid->list); |
4502 | kfree(fpid); | 4517 | kfree(fpid); |
4503 | } | 4518 | } |
4504 | 4519 | ||
4505 | ftrace_update_pid_func(); | 4520 | ftrace_update_pid_func(); |
4506 | ftrace_startup_enable(0); | 4521 | ftrace_startup_enable(0); |
4507 | 4522 | ||
4508 | mutex_unlock(&ftrace_lock); | 4523 | mutex_unlock(&ftrace_lock); |
4509 | } | 4524 | } |
4510 | 4525 | ||
4511 | static void *fpid_start(struct seq_file *m, loff_t *pos) | 4526 | static void *fpid_start(struct seq_file *m, loff_t *pos) |
4512 | { | 4527 | { |
4513 | mutex_lock(&ftrace_lock); | 4528 | mutex_lock(&ftrace_lock); |
4514 | 4529 | ||
4515 | if (list_empty(&ftrace_pids) && (!*pos)) | 4530 | if (list_empty(&ftrace_pids) && (!*pos)) |
4516 | return (void *) 1; | 4531 | return (void *) 1; |
4517 | 4532 | ||
4518 | return seq_list_start(&ftrace_pids, *pos); | 4533 | return seq_list_start(&ftrace_pids, *pos); |
4519 | } | 4534 | } |
4520 | 4535 | ||
4521 | static void *fpid_next(struct seq_file *m, void *v, loff_t *pos) | 4536 | static void *fpid_next(struct seq_file *m, void *v, loff_t *pos) |
4522 | { | 4537 | { |
4523 | if (v == (void *)1) | 4538 | if (v == (void *)1) |
4524 | return NULL; | 4539 | return NULL; |
4525 | 4540 | ||
4526 | return seq_list_next(v, &ftrace_pids, pos); | 4541 | return seq_list_next(v, &ftrace_pids, pos); |
4527 | } | 4542 | } |
4528 | 4543 | ||
4529 | static void fpid_stop(struct seq_file *m, void *p) | 4544 | static void fpid_stop(struct seq_file *m, void *p) |
4530 | { | 4545 | { |
4531 | mutex_unlock(&ftrace_lock); | 4546 | mutex_unlock(&ftrace_lock); |
4532 | } | 4547 | } |
4533 | 4548 | ||
4534 | static int fpid_show(struct seq_file *m, void *v) | 4549 | static int fpid_show(struct seq_file *m, void *v) |
4535 | { | 4550 | { |
4536 | const struct ftrace_pid *fpid = list_entry(v, struct ftrace_pid, list); | 4551 | const struct ftrace_pid *fpid = list_entry(v, struct ftrace_pid, list); |
4537 | 4552 | ||
4538 | if (v == (void *)1) { | 4553 | if (v == (void *)1) { |
4539 | seq_printf(m, "no pid\n"); | 4554 | seq_printf(m, "no pid\n"); |
4540 | return 0; | 4555 | return 0; |
4541 | } | 4556 | } |
4542 | 4557 | ||
4543 | if (fpid->pid == ftrace_swapper_pid) | 4558 | if (fpid->pid == ftrace_swapper_pid) |
4544 | seq_printf(m, "swapper tasks\n"); | 4559 | seq_printf(m, "swapper tasks\n"); |
4545 | else | 4560 | else |
4546 | seq_printf(m, "%u\n", pid_vnr(fpid->pid)); | 4561 | seq_printf(m, "%u\n", pid_vnr(fpid->pid)); |
4547 | 4562 | ||
4548 | return 0; | 4563 | return 0; |
4549 | } | 4564 | } |
4550 | 4565 | ||
4551 | static const struct seq_operations ftrace_pid_sops = { | 4566 | static const struct seq_operations ftrace_pid_sops = { |
4552 | .start = fpid_start, | 4567 | .start = fpid_start, |
4553 | .next = fpid_next, | 4568 | .next = fpid_next, |
4554 | .stop = fpid_stop, | 4569 | .stop = fpid_stop, |
4555 | .show = fpid_show, | 4570 | .show = fpid_show, |
4556 | }; | 4571 | }; |
4557 | 4572 | ||
4558 | static int | 4573 | static int |
4559 | ftrace_pid_open(struct inode *inode, struct file *file) | 4574 | ftrace_pid_open(struct inode *inode, struct file *file) |
4560 | { | 4575 | { |
4561 | int ret = 0; | 4576 | int ret = 0; |
4562 | 4577 | ||
4563 | if ((file->f_mode & FMODE_WRITE) && | 4578 | if ((file->f_mode & FMODE_WRITE) && |
4564 | (file->f_flags & O_TRUNC)) | 4579 | (file->f_flags & O_TRUNC)) |
4565 | ftrace_pid_reset(); | 4580 | ftrace_pid_reset(); |
4566 | 4581 | ||
4567 | if (file->f_mode & FMODE_READ) | 4582 | if (file->f_mode & FMODE_READ) |
4568 | ret = seq_open(file, &ftrace_pid_sops); | 4583 | ret = seq_open(file, &ftrace_pid_sops); |
4569 | 4584 | ||
4570 | return ret; | 4585 | return ret; |
4571 | } | 4586 | } |
4572 | 4587 | ||
4573 | static ssize_t | 4588 | static ssize_t |
4574 | ftrace_pid_write(struct file *filp, const char __user *ubuf, | 4589 | ftrace_pid_write(struct file *filp, const char __user *ubuf, |
4575 | size_t cnt, loff_t *ppos) | 4590 | size_t cnt, loff_t *ppos) |
4576 | { | 4591 | { |
4577 | char buf[64], *tmp; | 4592 | char buf[64], *tmp; |
4578 | long val; | 4593 | long val; |
4579 | int ret; | 4594 | int ret; |
4580 | 4595 | ||
4581 | if (cnt >= sizeof(buf)) | 4596 | if (cnt >= sizeof(buf)) |
4582 | return -EINVAL; | 4597 | return -EINVAL; |
4583 | 4598 | ||
4584 | if (copy_from_user(&buf, ubuf, cnt)) | 4599 | if (copy_from_user(&buf, ubuf, cnt)) |
4585 | return -EFAULT; | 4600 | return -EFAULT; |
4586 | 4601 | ||
4587 | buf[cnt] = 0; | 4602 | buf[cnt] = 0; |
4588 | 4603 | ||
4589 | /* | 4604 | /* |
4590 | * Allow "echo > set_ftrace_pid" or "echo -n '' > set_ftrace_pid" | 4605 | * Allow "echo > set_ftrace_pid" or "echo -n '' > set_ftrace_pid" |
4591 | * to clean the filter quietly. | 4606 | * to clean the filter quietly. |
4592 | */ | 4607 | */ |
4593 | tmp = strstrip(buf); | 4608 | tmp = strstrip(buf); |
4594 | if (strlen(tmp) == 0) | 4609 | if (strlen(tmp) == 0) |
4595 | return 1; | 4610 | return 1; |
4596 | 4611 | ||
4597 | ret = kstrtol(tmp, 10, &val); | 4612 | ret = kstrtol(tmp, 10, &val); |
4598 | if (ret < 0) | 4613 | if (ret < 0) |
4599 | return ret; | 4614 | return ret; |
4600 | 4615 | ||
4601 | ret = ftrace_pid_add(val); | 4616 | ret = ftrace_pid_add(val); |
4602 | 4617 | ||
4603 | return ret ? ret : cnt; | 4618 | return ret ? ret : cnt; |
4604 | } | 4619 | } |
4605 | 4620 | ||
4606 | static int | 4621 | static int |
4607 | ftrace_pid_release(struct inode *inode, struct file *file) | 4622 | ftrace_pid_release(struct inode *inode, struct file *file) |
4608 | { | 4623 | { |
4609 | if (file->f_mode & FMODE_READ) | 4624 | if (file->f_mode & FMODE_READ) |
4610 | seq_release(inode, file); | 4625 | seq_release(inode, file); |
4611 | 4626 | ||
4612 | return 0; | 4627 | return 0; |
4613 | } | 4628 | } |
4614 | 4629 | ||
4615 | static const struct file_operations ftrace_pid_fops = { | 4630 | static const struct file_operations ftrace_pid_fops = { |
4616 | .open = ftrace_pid_open, | 4631 | .open = ftrace_pid_open, |
4617 | .write = ftrace_pid_write, | 4632 | .write = ftrace_pid_write, |
4618 | .read = seq_read, | 4633 | .read = seq_read, |
4619 | .llseek = ftrace_filter_lseek, | 4634 | .llseek = ftrace_filter_lseek, |
4620 | .release = ftrace_pid_release, | 4635 | .release = ftrace_pid_release, |
4621 | }; | 4636 | }; |
4622 | 4637 | ||
4623 | static __init int ftrace_init_debugfs(void) | 4638 | static __init int ftrace_init_debugfs(void) |
4624 | { | 4639 | { |
4625 | struct dentry *d_tracer; | 4640 | struct dentry *d_tracer; |
4626 | 4641 | ||
4627 | d_tracer = tracing_init_dentry(); | 4642 | d_tracer = tracing_init_dentry(); |
4628 | if (!d_tracer) | 4643 | if (!d_tracer) |
4629 | return 0; | 4644 | return 0; |
4630 | 4645 | ||
4631 | ftrace_init_dyn_debugfs(d_tracer); | 4646 | ftrace_init_dyn_debugfs(d_tracer); |
4632 | 4647 | ||
4633 | trace_create_file("set_ftrace_pid", 0644, d_tracer, | 4648 | trace_create_file("set_ftrace_pid", 0644, d_tracer, |
4634 | NULL, &ftrace_pid_fops); | 4649 | NULL, &ftrace_pid_fops); |
4635 | 4650 | ||
4636 | ftrace_profile_debugfs(d_tracer); | 4651 | ftrace_profile_debugfs(d_tracer); |
4637 | 4652 | ||
4638 | return 0; | 4653 | return 0; |
4639 | } | 4654 | } |
4640 | fs_initcall(ftrace_init_debugfs); | 4655 | fs_initcall(ftrace_init_debugfs); |
4641 | 4656 | ||
4642 | /** | 4657 | /** |
4643 | * ftrace_kill - kill ftrace | 4658 | * ftrace_kill - kill ftrace |
4644 | * | 4659 | * |
4645 | * This function should be used by panic code. It stops ftrace | 4660 | * This function should be used by panic code. It stops ftrace |
4646 | * but in a not so nice way. If you need to simply kill ftrace | 4661 | * but in a not so nice way. If you need to simply kill ftrace |
4647 | * from a non-atomic section, use ftrace_kill. | 4662 | * from a non-atomic section, use ftrace_kill. |
4648 | */ | 4663 | */ |
4649 | void ftrace_kill(void) | 4664 | void ftrace_kill(void) |
4650 | { | 4665 | { |
4651 | ftrace_disabled = 1; | 4666 | ftrace_disabled = 1; |
4652 | ftrace_enabled = 0; | 4667 | ftrace_enabled = 0; |
4653 | clear_ftrace_function(); | 4668 | clear_ftrace_function(); |
4654 | } | 4669 | } |
4655 | 4670 | ||
4656 | /** | 4671 | /** |
4657 | * Test if ftrace is dead or not. | 4672 | * Test if ftrace is dead or not. |
4658 | */ | 4673 | */ |
4659 | int ftrace_is_dead(void) | 4674 | int ftrace_is_dead(void) |
4660 | { | 4675 | { |
4661 | return ftrace_disabled; | 4676 | return ftrace_disabled; |
4662 | } | 4677 | } |
4663 | 4678 | ||
4664 | /** | 4679 | /** |
4665 | * register_ftrace_function - register a function for profiling | 4680 | * register_ftrace_function - register a function for profiling |
4666 | * @ops - ops structure that holds the function for profiling. | 4681 | * @ops - ops structure that holds the function for profiling. |
4667 | * | 4682 | * |
4668 | * Register a function to be called by all functions in the | 4683 | * Register a function to be called by all functions in the |
4669 | * kernel. | 4684 | * kernel. |
4670 | * | 4685 | * |
4671 | * Note: @ops->func and all the functions it calls must be labeled | 4686 | * Note: @ops->func and all the functions it calls must be labeled |
4672 | * with "notrace", otherwise it will go into a | 4687 | * with "notrace", otherwise it will go into a |
4673 | * recursive loop. | 4688 | * recursive loop. |
4674 | */ | 4689 | */ |
4675 | int register_ftrace_function(struct ftrace_ops *ops) | 4690 | int register_ftrace_function(struct ftrace_ops *ops) |
4676 | { | 4691 | { |
4677 | int ret = -1; | 4692 | int ret = -1; |
4678 | 4693 | ||
4679 | ftrace_ops_init(ops); | 4694 | ftrace_ops_init(ops); |
4680 | 4695 | ||
4681 | mutex_lock(&ftrace_lock); | 4696 | mutex_lock(&ftrace_lock); |
4682 | 4697 | ||
4683 | ret = __register_ftrace_function(ops); | 4698 | ret = __register_ftrace_function(ops); |
4684 | if (!ret) | 4699 | if (!ret) |
4685 | ret = ftrace_startup(ops, 0); | 4700 | ret = ftrace_startup(ops, 0); |
4686 | 4701 | ||
4687 | mutex_unlock(&ftrace_lock); | 4702 | mutex_unlock(&ftrace_lock); |
4688 | 4703 | ||
4689 | return ret; | 4704 | return ret; |
4690 | } | 4705 | } |
4691 | EXPORT_SYMBOL_GPL(register_ftrace_function); | 4706 | EXPORT_SYMBOL_GPL(register_ftrace_function); |
4692 | 4707 | ||
4693 | /** | 4708 | /** |
4694 | * unregister_ftrace_function - unregister a function for profiling. | 4709 | * unregister_ftrace_function - unregister a function for profiling. |
4695 | * @ops - ops structure that holds the function to unregister | 4710 | * @ops - ops structure that holds the function to unregister |
4696 | * | 4711 | * |
4697 | * Unregister a function that was added to be called by ftrace profiling. | 4712 | * Unregister a function that was added to be called by ftrace profiling. |
4698 | */ | 4713 | */ |
4699 | int unregister_ftrace_function(struct ftrace_ops *ops) | 4714 | int unregister_ftrace_function(struct ftrace_ops *ops) |
4700 | { | 4715 | { |
4701 | int ret; | 4716 | int ret; |
4702 | 4717 | ||
4703 | mutex_lock(&ftrace_lock); | 4718 | mutex_lock(&ftrace_lock); |
4704 | ret = __unregister_ftrace_function(ops); | 4719 | ret = __unregister_ftrace_function(ops); |
4705 | if (!ret) | 4720 | if (!ret) |
4706 | ftrace_shutdown(ops, 0); | 4721 | ftrace_shutdown(ops, 0); |
4707 | mutex_unlock(&ftrace_lock); | 4722 | mutex_unlock(&ftrace_lock); |
4708 | 4723 | ||
4709 | return ret; | 4724 | return ret; |
4710 | } | 4725 | } |
4711 | EXPORT_SYMBOL_GPL(unregister_ftrace_function); | 4726 | EXPORT_SYMBOL_GPL(unregister_ftrace_function); |
4712 | 4727 | ||
4713 | int | 4728 | int |
4714 | ftrace_enable_sysctl(struct ctl_table *table, int write, | 4729 | ftrace_enable_sysctl(struct ctl_table *table, int write, |
4715 | void __user *buffer, size_t *lenp, | 4730 | void __user *buffer, size_t *lenp, |
4716 | loff_t *ppos) | 4731 | loff_t *ppos) |
4717 | { | 4732 | { |
4718 | int ret = -ENODEV; | 4733 | int ret = -ENODEV; |
4719 | 4734 | ||
4720 | mutex_lock(&ftrace_lock); | 4735 | mutex_lock(&ftrace_lock); |
4721 | 4736 | ||
4722 | if (unlikely(ftrace_disabled)) | 4737 | if (unlikely(ftrace_disabled)) |
4723 | goto out; | 4738 | goto out; |
4724 | 4739 | ||
4725 | ret = proc_dointvec(table, write, buffer, lenp, ppos); | 4740 | ret = proc_dointvec(table, write, buffer, lenp, ppos); |
4726 | 4741 | ||
4727 | if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) | 4742 | if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) |
4728 | goto out; | 4743 | goto out; |
4729 | 4744 | ||
4730 | last_ftrace_enabled = !!ftrace_enabled; | 4745 | last_ftrace_enabled = !!ftrace_enabled; |
4731 | 4746 | ||
4732 | if (ftrace_enabled) { | 4747 | if (ftrace_enabled) { |
4733 | 4748 | ||
4734 | ftrace_startup_sysctl(); | 4749 | ftrace_startup_sysctl(); |
4735 | 4750 | ||
4736 | /* we are starting ftrace again */ | 4751 | /* we are starting ftrace again */ |
4737 | if (ftrace_ops_list != &ftrace_list_end) | 4752 | if (ftrace_ops_list != &ftrace_list_end) |
4738 | update_ftrace_function(); | 4753 | update_ftrace_function(); |
4739 | 4754 | ||
4740 | } else { | 4755 | } else { |
4741 | /* stopping ftrace calls (just send to ftrace_stub) */ | 4756 | /* stopping ftrace calls (just send to ftrace_stub) */ |
4742 | ftrace_trace_function = ftrace_stub; | 4757 | ftrace_trace_function = ftrace_stub; |
4743 | 4758 | ||
4744 | ftrace_shutdown_sysctl(); | 4759 | ftrace_shutdown_sysctl(); |
4745 | } | 4760 | } |
4746 | 4761 | ||
4747 | out: | 4762 | out: |
4748 | mutex_unlock(&ftrace_lock); | 4763 | mutex_unlock(&ftrace_lock); |
4749 | return ret; | 4764 | return ret; |
4750 | } | 4765 | } |
4751 | 4766 | ||
4752 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 4767 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
4753 | 4768 | ||
4754 | static int ftrace_graph_active; | 4769 | static int ftrace_graph_active; |
4755 | static struct notifier_block ftrace_suspend_notifier; | 4770 | static struct notifier_block ftrace_suspend_notifier; |
4756 | 4771 | ||
4757 | int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) | 4772 | int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) |
4758 | { | 4773 | { |
4759 | return 0; | 4774 | return 0; |
4760 | } | 4775 | } |
4761 | 4776 | ||
4762 | /* The callbacks that hook a function */ | 4777 | /* The callbacks that hook a function */ |
4763 | trace_func_graph_ret_t ftrace_graph_return = | 4778 | trace_func_graph_ret_t ftrace_graph_return = |
4764 | (trace_func_graph_ret_t)ftrace_stub; | 4779 | (trace_func_graph_ret_t)ftrace_stub; |
4765 | trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub; | 4780 | trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub; |
4766 | 4781 | ||
4767 | /* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */ | 4782 | /* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */ |
4768 | static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) | 4783 | static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) |
4769 | { | 4784 | { |
4770 | int i; | 4785 | int i; |
4771 | int ret = 0; | 4786 | int ret = 0; |
4772 | unsigned long flags; | 4787 | unsigned long flags; |
4773 | int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE; | 4788 | int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE; |
4774 | struct task_struct *g, *t; | 4789 | struct task_struct *g, *t; |
4775 | 4790 | ||
4776 | for (i = 0; i < FTRACE_RETSTACK_ALLOC_SIZE; i++) { | 4791 | for (i = 0; i < FTRACE_RETSTACK_ALLOC_SIZE; i++) { |
4777 | ret_stack_list[i] = kmalloc(FTRACE_RETFUNC_DEPTH | 4792 | ret_stack_list[i] = kmalloc(FTRACE_RETFUNC_DEPTH |
4778 | * sizeof(struct ftrace_ret_stack), | 4793 | * sizeof(struct ftrace_ret_stack), |
4779 | GFP_KERNEL); | 4794 | GFP_KERNEL); |
4780 | if (!ret_stack_list[i]) { | 4795 | if (!ret_stack_list[i]) { |
4781 | start = 0; | 4796 | start = 0; |
4782 | end = i; | 4797 | end = i; |
4783 | ret = -ENOMEM; | 4798 | ret = -ENOMEM; |
4784 | goto free; | 4799 | goto free; |
4785 | } | 4800 | } |
4786 | } | 4801 | } |
4787 | 4802 | ||
4788 | read_lock_irqsave(&tasklist_lock, flags); | 4803 | read_lock_irqsave(&tasklist_lock, flags); |
4789 | do_each_thread(g, t) { | 4804 | do_each_thread(g, t) { |
4790 | if (start == end) { | 4805 | if (start == end) { |
4791 | ret = -EAGAIN; | 4806 | ret = -EAGAIN; |
4792 | goto unlock; | 4807 | goto unlock; |
4793 | } | 4808 | } |
4794 | 4809 | ||
4795 | if (t->ret_stack == NULL) { | 4810 | if (t->ret_stack == NULL) { |
4796 | atomic_set(&t->tracing_graph_pause, 0); | 4811 | atomic_set(&t->tracing_graph_pause, 0); |
4797 | atomic_set(&t->trace_overrun, 0); | 4812 | atomic_set(&t->trace_overrun, 0); |
4798 | t->curr_ret_stack = -1; | 4813 | t->curr_ret_stack = -1; |
4799 | /* Make sure the tasks see the -1 first: */ | 4814 | /* Make sure the tasks see the -1 first: */ |
4800 | smp_wmb(); | 4815 | smp_wmb(); |
4801 | t->ret_stack = ret_stack_list[start++]; | 4816 | t->ret_stack = ret_stack_list[start++]; |
4802 | } | 4817 | } |
4803 | } while_each_thread(g, t); | 4818 | } while_each_thread(g, t); |
4804 | 4819 | ||
4805 | unlock: | 4820 | unlock: |
4806 | read_unlock_irqrestore(&tasklist_lock, flags); | 4821 | read_unlock_irqrestore(&tasklist_lock, flags); |
4807 | free: | 4822 | free: |
4808 | for (i = start; i < end; i++) | 4823 | for (i = start; i < end; i++) |
4809 | kfree(ret_stack_list[i]); | 4824 | kfree(ret_stack_list[i]); |
4810 | return ret; | 4825 | return ret; |
4811 | } | 4826 | } |
4812 | 4827 | ||
4813 | static void | 4828 | static void |
4814 | ftrace_graph_probe_sched_switch(void *ignore, | 4829 | ftrace_graph_probe_sched_switch(void *ignore, |
4815 | struct task_struct *prev, struct task_struct *next) | 4830 | struct task_struct *prev, struct task_struct *next) |
4816 | { | 4831 | { |
4817 | unsigned long long timestamp; | 4832 | unsigned long long timestamp; |
4818 | int index; | 4833 | int index; |
4819 | 4834 | ||
4820 | /* | 4835 | /* |
4821 | * Does the user want to count the time a function was asleep. | 4836 | * Does the user want to count the time a function was asleep. |
4822 | * If so, do not update the time stamps. | 4837 | * If so, do not update the time stamps. |
4823 | */ | 4838 | */ |
4824 | if (trace_flags & TRACE_ITER_SLEEP_TIME) | 4839 | if (trace_flags & TRACE_ITER_SLEEP_TIME) |
4825 | return; | 4840 | return; |
4826 | 4841 | ||
4827 | timestamp = trace_clock_local(); | 4842 | timestamp = trace_clock_local(); |
4828 | 4843 | ||
4829 | prev->ftrace_timestamp = timestamp; | 4844 | prev->ftrace_timestamp = timestamp; |
4830 | 4845 | ||
4831 | /* only process tasks that we timestamped */ | 4846 | /* only process tasks that we timestamped */ |
4832 | if (!next->ftrace_timestamp) | 4847 | if (!next->ftrace_timestamp) |
4833 | return; | 4848 | return; |
4834 | 4849 | ||
4835 | /* | 4850 | /* |
4836 | * Update all the counters in next to make up for the | 4851 | * Update all the counters in next to make up for the |
4837 | * time next was sleeping. | 4852 | * time next was sleeping. |
4838 | */ | 4853 | */ |
4839 | timestamp -= next->ftrace_timestamp; | 4854 | timestamp -= next->ftrace_timestamp; |
4840 | 4855 | ||
4841 | for (index = next->curr_ret_stack; index >= 0; index--) | 4856 | for (index = next->curr_ret_stack; index >= 0; index--) |
4842 | next->ret_stack[index].calltime += timestamp; | 4857 | next->ret_stack[index].calltime += timestamp; |
4843 | } | 4858 | } |
4844 | 4859 | ||
4845 | /* Allocate a return stack for each task */ | 4860 | /* Allocate a return stack for each task */ |
4846 | static int start_graph_tracing(void) | 4861 | static int start_graph_tracing(void) |
4847 | { | 4862 | { |
4848 | struct ftrace_ret_stack **ret_stack_list; | 4863 | struct ftrace_ret_stack **ret_stack_list; |
4849 | int ret, cpu; | 4864 | int ret, cpu; |
4850 | 4865 | ||
4851 | ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE * | 4866 | ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE * |
4852 | sizeof(struct ftrace_ret_stack *), | 4867 | sizeof(struct ftrace_ret_stack *), |
4853 | GFP_KERNEL); | 4868 | GFP_KERNEL); |
4854 | 4869 | ||
4855 | if (!ret_stack_list) | 4870 | if (!ret_stack_list) |
4856 | return -ENOMEM; | 4871 | return -ENOMEM; |
4857 | 4872 | ||
4858 | /* The cpu_boot init_task->ret_stack will never be freed */ | 4873 | /* The cpu_boot init_task->ret_stack will never be freed */ |
4859 | for_each_online_cpu(cpu) { | 4874 | for_each_online_cpu(cpu) { |
4860 | if (!idle_task(cpu)->ret_stack) | 4875 | if (!idle_task(cpu)->ret_stack) |
4861 | ftrace_graph_init_idle_task(idle_task(cpu), cpu); | 4876 | ftrace_graph_init_idle_task(idle_task(cpu), cpu); |
4862 | } | 4877 | } |
4863 | 4878 | ||
4864 | do { | 4879 | do { |
4865 | ret = alloc_retstack_tasklist(ret_stack_list); | 4880 | ret = alloc_retstack_tasklist(ret_stack_list); |
4866 | } while (ret == -EAGAIN); | 4881 | } while (ret == -EAGAIN); |
4867 | 4882 | ||
4868 | if (!ret) { | 4883 | if (!ret) { |
4869 | ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); | 4884 | ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); |
4870 | if (ret) | 4885 | if (ret) |
4871 | pr_info("ftrace_graph: Couldn't activate tracepoint" | 4886 | pr_info("ftrace_graph: Couldn't activate tracepoint" |
4872 | " probe to kernel_sched_switch\n"); | 4887 | " probe to kernel_sched_switch\n"); |
4873 | } | 4888 | } |
4874 | 4889 | ||
4875 | kfree(ret_stack_list); | 4890 | kfree(ret_stack_list); |
4876 | return ret; | 4891 | return ret; |
4877 | } | 4892 | } |
4878 | 4893 | ||
4879 | /* | 4894 | /* |
4880 | * Hibernation protection. | 4895 | * Hibernation protection. |
4881 | * The state of the current task is too much unstable during | 4896 | * The state of the current task is too much unstable during |
4882 | * suspend/restore to disk. We want to protect against that. | 4897 | * suspend/restore to disk. We want to protect against that. |
4883 | */ | 4898 | */ |
4884 | static int | 4899 | static int |
4885 | ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, | 4900 | ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, |
4886 | void *unused) | 4901 | void *unused) |
4887 | { | 4902 | { |
4888 | switch (state) { | 4903 | switch (state) { |
4889 | case PM_HIBERNATION_PREPARE: | 4904 | case PM_HIBERNATION_PREPARE: |
4890 | pause_graph_tracing(); | 4905 | pause_graph_tracing(); |
4891 | break; | 4906 | break; |
4892 | 4907 | ||
4893 | case PM_POST_HIBERNATION: | 4908 | case PM_POST_HIBERNATION: |
4894 | unpause_graph_tracing(); | 4909 | unpause_graph_tracing(); |
4895 | break; | 4910 | break; |
4896 | } | 4911 | } |
4897 | return NOTIFY_DONE; | 4912 | return NOTIFY_DONE; |
4898 | } | 4913 | } |
4899 | 4914 | ||
4900 | int register_ftrace_graph(trace_func_graph_ret_t retfunc, | 4915 | int register_ftrace_graph(trace_func_graph_ret_t retfunc, |
4901 | trace_func_graph_ent_t entryfunc) | 4916 | trace_func_graph_ent_t entryfunc) |
4902 | { | 4917 | { |
4903 | int ret = 0; | 4918 | int ret = 0; |
4904 | 4919 | ||
4905 | mutex_lock(&ftrace_lock); | 4920 | mutex_lock(&ftrace_lock); |
4906 | 4921 | ||
4907 | /* we currently allow only one tracer registered at a time */ | 4922 | /* we currently allow only one tracer registered at a time */ |
4908 | if (ftrace_graph_active) { | 4923 | if (ftrace_graph_active) { |
4909 | ret = -EBUSY; | 4924 | ret = -EBUSY; |
4910 | goto out; | 4925 | goto out; |
4911 | } | 4926 | } |
4912 | 4927 | ||
4913 | ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call; | 4928 | ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call; |
4914 | register_pm_notifier(&ftrace_suspend_notifier); | 4929 | register_pm_notifier(&ftrace_suspend_notifier); |
4915 | 4930 | ||
4916 | ftrace_graph_active++; | 4931 | ftrace_graph_active++; |
4917 | ret = start_graph_tracing(); | 4932 | ret = start_graph_tracing(); |
4918 | if (ret) { | 4933 | if (ret) { |
4919 | ftrace_graph_active--; | 4934 | ftrace_graph_active--; |
4920 | goto out; | 4935 | goto out; |
4921 | } | 4936 | } |
4922 | 4937 | ||
4923 | ftrace_graph_return = retfunc; | 4938 | ftrace_graph_return = retfunc; |
4924 | ftrace_graph_entry = entryfunc; | 4939 | ftrace_graph_entry = entryfunc; |
4925 | 4940 | ||
4926 | ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); | 4941 | ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); |
4927 | 4942 | ||
4928 | out: | 4943 | out: |
4929 | mutex_unlock(&ftrace_lock); | 4944 | mutex_unlock(&ftrace_lock); |
4930 | return ret; | 4945 | return ret; |
4931 | } | 4946 | } |
4932 | 4947 | ||
4933 | void unregister_ftrace_graph(void) | 4948 | void unregister_ftrace_graph(void) |
4934 | { | 4949 | { |
4935 | mutex_lock(&ftrace_lock); | 4950 | mutex_lock(&ftrace_lock); |
4936 | 4951 | ||
4937 | if (unlikely(!ftrace_graph_active)) | 4952 | if (unlikely(!ftrace_graph_active)) |
4938 | goto out; | 4953 | goto out; |
4939 | 4954 | ||
4940 | ftrace_graph_active--; | 4955 | ftrace_graph_active--; |
4941 | ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; | 4956 | ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; |
4942 | ftrace_graph_entry = ftrace_graph_entry_stub; | 4957 | ftrace_graph_entry = ftrace_graph_entry_stub; |
4943 | ftrace_shutdown(&global_ops, FTRACE_STOP_FUNC_RET); | 4958 | ftrace_shutdown(&global_ops, FTRACE_STOP_FUNC_RET); |
4944 | unregister_pm_notifier(&ftrace_suspend_notifier); | 4959 | unregister_pm_notifier(&ftrace_suspend_notifier); |
4945 | unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); | 4960 | unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); |
4946 | 4961 | ||
4947 | out: | 4962 | out: |
4948 | mutex_unlock(&ftrace_lock); | 4963 | mutex_unlock(&ftrace_lock); |
4949 | } | 4964 | } |
4950 | 4965 | ||
4951 | static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack); | 4966 | static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack); |
4952 | 4967 | ||
4953 | static void | 4968 | static void |
4954 | graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack) | 4969 | graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack) |
4955 | { | 4970 | { |
4956 | atomic_set(&t->tracing_graph_pause, 0); | 4971 | atomic_set(&t->tracing_graph_pause, 0); |
4957 | atomic_set(&t->trace_overrun, 0); | 4972 | atomic_set(&t->trace_overrun, 0); |
4958 | t->ftrace_timestamp = 0; | 4973 | t->ftrace_timestamp = 0; |
4959 | /* make curr_ret_stack visible before we add the ret_stack */ | 4974 | /* make curr_ret_stack visible before we add the ret_stack */ |
4960 | smp_wmb(); | 4975 | smp_wmb(); |
4961 | t->ret_stack = ret_stack; | 4976 | t->ret_stack = ret_stack; |
4962 | } | 4977 | } |
4963 | 4978 | ||
4964 | /* | 4979 | /* |
4965 | * Allocate a return stack for the idle task. May be the first | 4980 | * Allocate a return stack for the idle task. May be the first |
4966 | * time through, or it may be done by CPU hotplug online. | 4981 | * time through, or it may be done by CPU hotplug online. |
4967 | */ | 4982 | */ |
4968 | void ftrace_graph_init_idle_task(struct task_struct *t, int cpu) | 4983 | void ftrace_graph_init_idle_task(struct task_struct *t, int cpu) |
4969 | { | 4984 | { |
4970 | t->curr_ret_stack = -1; | 4985 | t->curr_ret_stack = -1; |
4971 | /* | 4986 | /* |
4972 | * The idle task has no parent, it either has its own | 4987 | * The idle task has no parent, it either has its own |
4973 | * stack or no stack at all. | 4988 | * stack or no stack at all. |
4974 | */ | 4989 | */ |
4975 | if (t->ret_stack) | 4990 | if (t->ret_stack) |
4976 | WARN_ON(t->ret_stack != per_cpu(idle_ret_stack, cpu)); | 4991 | WARN_ON(t->ret_stack != per_cpu(idle_ret_stack, cpu)); |
4977 | 4992 | ||
4978 | if (ftrace_graph_active) { | 4993 | if (ftrace_graph_active) { |
4979 | struct ftrace_ret_stack *ret_stack; | 4994 | struct ftrace_ret_stack *ret_stack; |
4980 | 4995 | ||
4981 | ret_stack = per_cpu(idle_ret_stack, cpu); | 4996 | ret_stack = per_cpu(idle_ret_stack, cpu); |
4982 | if (!ret_stack) { | 4997 | if (!ret_stack) { |
4983 | ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH | 4998 | ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH |
4984 | * sizeof(struct ftrace_ret_stack), | 4999 | * sizeof(struct ftrace_ret_stack), |
4985 | GFP_KERNEL); | 5000 | GFP_KERNEL); |
4986 | if (!ret_stack) | 5001 | if (!ret_stack) |
4987 | return; | 5002 | return; |
4988 | per_cpu(idle_ret_stack, cpu) = ret_stack; | 5003 | per_cpu(idle_ret_stack, cpu) = ret_stack; |
4989 | } | 5004 | } |
4990 | graph_init_task(t, ret_stack); | 5005 | graph_init_task(t, ret_stack); |
4991 | } | 5006 | } |
4992 | } | 5007 | } |
4993 | 5008 | ||
4994 | /* Allocate a return stack for newly created task */ | 5009 | /* Allocate a return stack for newly created task */ |
4995 | void ftrace_graph_init_task(struct task_struct *t) | 5010 | void ftrace_graph_init_task(struct task_struct *t) |
4996 | { | 5011 | { |
4997 | /* Make sure we do not use the parent ret_stack */ | 5012 | /* Make sure we do not use the parent ret_stack */ |
4998 | t->ret_stack = NULL; | 5013 | t->ret_stack = NULL; |
4999 | t->curr_ret_stack = -1; | 5014 | t->curr_ret_stack = -1; |
5000 | 5015 | ||
5001 | if (ftrace_graph_active) { | 5016 | if (ftrace_graph_active) { |
5002 | struct ftrace_ret_stack *ret_stack; | 5017 | struct ftrace_ret_stack *ret_stack; |
5003 | 5018 | ||
5004 | ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH | 5019 | ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH |
5005 | * sizeof(struct ftrace_ret_stack), | 5020 | * sizeof(struct ftrace_ret_stack), |
5006 | GFP_KERNEL); | 5021 | GFP_KERNEL); |
5007 | if (!ret_stack) | 5022 | if (!ret_stack) |
5008 | return; | 5023 | return; |
5009 | graph_init_task(t, ret_stack); | 5024 | graph_init_task(t, ret_stack); |
5010 | } | 5025 | } |
5011 | } | 5026 | } |
5012 | 5027 | ||
5013 | void ftrace_graph_exit_task(struct task_struct *t) | 5028 | void ftrace_graph_exit_task(struct task_struct *t) |
5014 | { | 5029 | { |
5015 | struct ftrace_ret_stack *ret_stack = t->ret_stack; | 5030 | struct ftrace_ret_stack *ret_stack = t->ret_stack; |
5016 | 5031 | ||
5017 | t->ret_stack = NULL; | 5032 | t->ret_stack = NULL; |
5018 | /* NULL must become visible to IRQs before we free it: */ | 5033 | /* NULL must become visible to IRQs before we free it: */ |
5019 | barrier(); | 5034 | barrier(); |
5020 | 5035 | ||
5021 | kfree(ret_stack); | 5036 | kfree(ret_stack); |
5022 | } | 5037 | } |
5023 | 5038 | ||
5024 | void ftrace_graph_stop(void) | 5039 | void ftrace_graph_stop(void) |
5025 | { | 5040 | { |
5026 | ftrace_stop(); | 5041 | ftrace_stop(); |
5027 | } | 5042 | } |
5028 | #endif | 5043 | #endif |
5029 | 5044 |
kernel/trace/trace.c
1 | /* | 1 | /* |
2 | * ring buffer based function tracer | 2 | * ring buffer based function tracer |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2012 Steven Rostedt <srostedt@redhat.com> | 4 | * Copyright (C) 2007-2012 Steven Rostedt <srostedt@redhat.com> |
5 | * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com> | 5 | * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com> |
6 | * | 6 | * |
7 | * Originally taken from the RT patch by: | 7 | * Originally taken from the RT patch by: |
8 | * Arnaldo Carvalho de Melo <acme@redhat.com> | 8 | * Arnaldo Carvalho de Melo <acme@redhat.com> |
9 | * | 9 | * |
10 | * Based on code from the latency_tracer, that is: | 10 | * Based on code from the latency_tracer, that is: |
11 | * Copyright (C) 2004-2006 Ingo Molnar | 11 | * Copyright (C) 2004-2006 Ingo Molnar |
12 | * Copyright (C) 2004 Nadia Yvette Chambers | 12 | * Copyright (C) 2004 Nadia Yvette Chambers |
13 | */ | 13 | */ |
14 | #include <linux/ring_buffer.h> | 14 | #include <linux/ring_buffer.h> |
15 | #include <generated/utsrelease.h> | 15 | #include <generated/utsrelease.h> |
16 | #include <linux/stacktrace.h> | 16 | #include <linux/stacktrace.h> |
17 | #include <linux/writeback.h> | 17 | #include <linux/writeback.h> |
18 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/notifier.h> | 20 | #include <linux/notifier.h> |
21 | #include <linux/irqflags.h> | 21 | #include <linux/irqflags.h> |
22 | #include <linux/debugfs.h> | 22 | #include <linux/debugfs.h> |
23 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
24 | #include <linux/hardirq.h> | 24 | #include <linux/hardirq.h> |
25 | #include <linux/linkage.h> | 25 | #include <linux/linkage.h> |
26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | #include <linux/kprobes.h> | 27 | #include <linux/kprobes.h> |
28 | #include <linux/ftrace.h> | 28 | #include <linux/ftrace.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/percpu.h> | 30 | #include <linux/percpu.h> |
31 | #include <linux/splice.h> | 31 | #include <linux/splice.h> |
32 | #include <linux/kdebug.h> | 32 | #include <linux/kdebug.h> |
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/rwsem.h> | 34 | #include <linux/rwsem.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/ctype.h> | 36 | #include <linux/ctype.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
39 | #include <linux/nmi.h> | 39 | #include <linux/nmi.h> |
40 | #include <linux/fs.h> | 40 | #include <linux/fs.h> |
41 | #include <linux/sched/rt.h> | 41 | #include <linux/sched/rt.h> |
42 | 42 | ||
43 | #include "trace.h" | 43 | #include "trace.h" |
44 | #include "trace_output.h" | 44 | #include "trace_output.h" |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * On boot up, the ring buffer is set to the minimum size, so that | 47 | * On boot up, the ring buffer is set to the minimum size, so that |
48 | * we do not waste memory on systems that are not using tracing. | 48 | * we do not waste memory on systems that are not using tracing. |
49 | */ | 49 | */ |
50 | bool ring_buffer_expanded; | 50 | bool ring_buffer_expanded; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * We need to change this state when a selftest is running. | 53 | * We need to change this state when a selftest is running. |
54 | * A selftest will lurk into the ring-buffer to count the | 54 | * A selftest will lurk into the ring-buffer to count the |
55 | * entries inserted during the selftest although some concurrent | 55 | * entries inserted during the selftest although some concurrent |
56 | * insertions into the ring-buffer such as trace_printk could occurred | 56 | * insertions into the ring-buffer such as trace_printk could occurred |
57 | * at the same time, giving false positive or negative results. | 57 | * at the same time, giving false positive or negative results. |
58 | */ | 58 | */ |
59 | static bool __read_mostly tracing_selftest_running; | 59 | static bool __read_mostly tracing_selftest_running; |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * If a tracer is running, we do not want to run SELFTEST. | 62 | * If a tracer is running, we do not want to run SELFTEST. |
63 | */ | 63 | */ |
64 | bool __read_mostly tracing_selftest_disabled; | 64 | bool __read_mostly tracing_selftest_disabled; |
65 | 65 | ||
66 | /* For tracers that don't implement custom flags */ | 66 | /* For tracers that don't implement custom flags */ |
67 | static struct tracer_opt dummy_tracer_opt[] = { | 67 | static struct tracer_opt dummy_tracer_opt[] = { |
68 | { } | 68 | { } |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static struct tracer_flags dummy_tracer_flags = { | 71 | static struct tracer_flags dummy_tracer_flags = { |
72 | .val = 0, | 72 | .val = 0, |
73 | .opts = dummy_tracer_opt | 73 | .opts = dummy_tracer_opt |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static int dummy_set_flag(u32 old_flags, u32 bit, int set) | 76 | static int dummy_set_flag(u32 old_flags, u32 bit, int set) |
77 | { | 77 | { |
78 | return 0; | 78 | return 0; |
79 | } | 79 | } |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * To prevent the comm cache from being overwritten when no | 82 | * To prevent the comm cache from being overwritten when no |
83 | * tracing is active, only save the comm when a trace event | 83 | * tracing is active, only save the comm when a trace event |
84 | * occurred. | 84 | * occurred. |
85 | */ | 85 | */ |
86 | static DEFINE_PER_CPU(bool, trace_cmdline_save); | 86 | static DEFINE_PER_CPU(bool, trace_cmdline_save); |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * Kill all tracing for good (never come back). | 89 | * Kill all tracing for good (never come back). |
90 | * It is initialized to 1 but will turn to zero if the initialization | 90 | * It is initialized to 1 but will turn to zero if the initialization |
91 | * of the tracer is successful. But that is the only place that sets | 91 | * of the tracer is successful. But that is the only place that sets |
92 | * this back to zero. | 92 | * this back to zero. |
93 | */ | 93 | */ |
94 | static int tracing_disabled = 1; | 94 | static int tracing_disabled = 1; |
95 | 95 | ||
96 | DEFINE_PER_CPU(int, ftrace_cpu_disabled); | 96 | DEFINE_PER_CPU(int, ftrace_cpu_disabled); |
97 | 97 | ||
98 | cpumask_var_t __read_mostly tracing_buffer_mask; | 98 | cpumask_var_t __read_mostly tracing_buffer_mask; |
99 | 99 | ||
100 | /* | 100 | /* |
101 | * ftrace_dump_on_oops - variable to dump ftrace buffer on oops | 101 | * ftrace_dump_on_oops - variable to dump ftrace buffer on oops |
102 | * | 102 | * |
103 | * If there is an oops (or kernel panic) and the ftrace_dump_on_oops | 103 | * If there is an oops (or kernel panic) and the ftrace_dump_on_oops |
104 | * is set, then ftrace_dump is called. This will output the contents | 104 | * is set, then ftrace_dump is called. This will output the contents |
105 | * of the ftrace buffers to the console. This is very useful for | 105 | * of the ftrace buffers to the console. This is very useful for |
106 | * capturing traces that lead to crashes and outputing it to a | 106 | * capturing traces that lead to crashes and outputing it to a |
107 | * serial console. | 107 | * serial console. |
108 | * | 108 | * |
109 | * It is default off, but you can enable it with either specifying | 109 | * It is default off, but you can enable it with either specifying |
110 | * "ftrace_dump_on_oops" in the kernel command line, or setting | 110 | * "ftrace_dump_on_oops" in the kernel command line, or setting |
111 | * /proc/sys/kernel/ftrace_dump_on_oops | 111 | * /proc/sys/kernel/ftrace_dump_on_oops |
112 | * Set 1 if you want to dump buffers of all CPUs | 112 | * Set 1 if you want to dump buffers of all CPUs |
113 | * Set 2 if you want to dump the buffer of the CPU that triggered oops | 113 | * Set 2 if you want to dump the buffer of the CPU that triggered oops |
114 | */ | 114 | */ |
115 | 115 | ||
116 | enum ftrace_dump_mode ftrace_dump_on_oops; | 116 | enum ftrace_dump_mode ftrace_dump_on_oops; |
117 | 117 | ||
118 | /* When set, tracing will stop when a WARN*() is hit */ | 118 | /* When set, tracing will stop when a WARN*() is hit */ |
119 | int __disable_trace_on_warning; | 119 | int __disable_trace_on_warning; |
120 | 120 | ||
121 | static int tracing_set_tracer(const char *buf); | 121 | static int tracing_set_tracer(const char *buf); |
122 | 122 | ||
123 | #define MAX_TRACER_SIZE 100 | 123 | #define MAX_TRACER_SIZE 100 |
124 | static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata; | 124 | static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata; |
125 | static char *default_bootup_tracer; | 125 | static char *default_bootup_tracer; |
126 | 126 | ||
127 | static bool allocate_snapshot; | 127 | static bool allocate_snapshot; |
128 | 128 | ||
129 | static int __init set_cmdline_ftrace(char *str) | 129 | static int __init set_cmdline_ftrace(char *str) |
130 | { | 130 | { |
131 | strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE); | 131 | strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE); |
132 | default_bootup_tracer = bootup_tracer_buf; | 132 | default_bootup_tracer = bootup_tracer_buf; |
133 | /* We are using ftrace early, expand it */ | 133 | /* We are using ftrace early, expand it */ |
134 | ring_buffer_expanded = true; | 134 | ring_buffer_expanded = true; |
135 | return 1; | 135 | return 1; |
136 | } | 136 | } |
137 | __setup("ftrace=", set_cmdline_ftrace); | 137 | __setup("ftrace=", set_cmdline_ftrace); |
138 | 138 | ||
139 | static int __init set_ftrace_dump_on_oops(char *str) | 139 | static int __init set_ftrace_dump_on_oops(char *str) |
140 | { | 140 | { |
141 | if (*str++ != '=' || !*str) { | 141 | if (*str++ != '=' || !*str) { |
142 | ftrace_dump_on_oops = DUMP_ALL; | 142 | ftrace_dump_on_oops = DUMP_ALL; |
143 | return 1; | 143 | return 1; |
144 | } | 144 | } |
145 | 145 | ||
146 | if (!strcmp("orig_cpu", str)) { | 146 | if (!strcmp("orig_cpu", str)) { |
147 | ftrace_dump_on_oops = DUMP_ORIG; | 147 | ftrace_dump_on_oops = DUMP_ORIG; |
148 | return 1; | 148 | return 1; |
149 | } | 149 | } |
150 | 150 | ||
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops); | 153 | __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops); |
154 | 154 | ||
155 | static int __init stop_trace_on_warning(char *str) | 155 | static int __init stop_trace_on_warning(char *str) |
156 | { | 156 | { |
157 | __disable_trace_on_warning = 1; | 157 | __disable_trace_on_warning = 1; |
158 | return 1; | 158 | return 1; |
159 | } | 159 | } |
160 | __setup("traceoff_on_warning=", stop_trace_on_warning); | 160 | __setup("traceoff_on_warning=", stop_trace_on_warning); |
161 | 161 | ||
162 | static int __init boot_alloc_snapshot(char *str) | 162 | static int __init boot_alloc_snapshot(char *str) |
163 | { | 163 | { |
164 | allocate_snapshot = true; | 164 | allocate_snapshot = true; |
165 | /* We also need the main ring buffer expanded */ | 165 | /* We also need the main ring buffer expanded */ |
166 | ring_buffer_expanded = true; | 166 | ring_buffer_expanded = true; |
167 | return 1; | 167 | return 1; |
168 | } | 168 | } |
169 | __setup("alloc_snapshot", boot_alloc_snapshot); | 169 | __setup("alloc_snapshot", boot_alloc_snapshot); |
170 | 170 | ||
171 | 171 | ||
172 | static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; | 172 | static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; |
173 | static char *trace_boot_options __initdata; | 173 | static char *trace_boot_options __initdata; |
174 | 174 | ||
175 | static int __init set_trace_boot_options(char *str) | 175 | static int __init set_trace_boot_options(char *str) |
176 | { | 176 | { |
177 | strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); | 177 | strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); |
178 | trace_boot_options = trace_boot_options_buf; | 178 | trace_boot_options = trace_boot_options_buf; |
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
181 | __setup("trace_options=", set_trace_boot_options); | 181 | __setup("trace_options=", set_trace_boot_options); |
182 | 182 | ||
183 | 183 | ||
184 | unsigned long long ns2usecs(cycle_t nsec) | 184 | unsigned long long ns2usecs(cycle_t nsec) |
185 | { | 185 | { |
186 | nsec += 500; | 186 | nsec += 500; |
187 | do_div(nsec, 1000); | 187 | do_div(nsec, 1000); |
188 | return nsec; | 188 | return nsec; |
189 | } | 189 | } |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * The global_trace is the descriptor that holds the tracing | 192 | * The global_trace is the descriptor that holds the tracing |
193 | * buffers for the live tracing. For each CPU, it contains | 193 | * buffers for the live tracing. For each CPU, it contains |
194 | * a link list of pages that will store trace entries. The | 194 | * a link list of pages that will store trace entries. The |
195 | * page descriptor of the pages in the memory is used to hold | 195 | * page descriptor of the pages in the memory is used to hold |
196 | * the link list by linking the lru item in the page descriptor | 196 | * the link list by linking the lru item in the page descriptor |
197 | * to each of the pages in the buffer per CPU. | 197 | * to each of the pages in the buffer per CPU. |
198 | * | 198 | * |
199 | * For each active CPU there is a data field that holds the | 199 | * For each active CPU there is a data field that holds the |
200 | * pages for the buffer for that CPU. Each CPU has the same number | 200 | * pages for the buffer for that CPU. Each CPU has the same number |
201 | * of pages allocated for its buffer. | 201 | * of pages allocated for its buffer. |
202 | */ | 202 | */ |
203 | static struct trace_array global_trace; | 203 | static struct trace_array global_trace; |
204 | 204 | ||
205 | LIST_HEAD(ftrace_trace_arrays); | 205 | LIST_HEAD(ftrace_trace_arrays); |
206 | 206 | ||
207 | int trace_array_get(struct trace_array *this_tr) | 207 | int trace_array_get(struct trace_array *this_tr) |
208 | { | 208 | { |
209 | struct trace_array *tr; | 209 | struct trace_array *tr; |
210 | int ret = -ENODEV; | 210 | int ret = -ENODEV; |
211 | 211 | ||
212 | mutex_lock(&trace_types_lock); | 212 | mutex_lock(&trace_types_lock); |
213 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 213 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
214 | if (tr == this_tr) { | 214 | if (tr == this_tr) { |
215 | tr->ref++; | 215 | tr->ref++; |
216 | ret = 0; | 216 | ret = 0; |
217 | break; | 217 | break; |
218 | } | 218 | } |
219 | } | 219 | } |
220 | mutex_unlock(&trace_types_lock); | 220 | mutex_unlock(&trace_types_lock); |
221 | 221 | ||
222 | return ret; | 222 | return ret; |
223 | } | 223 | } |
224 | 224 | ||
225 | static void __trace_array_put(struct trace_array *this_tr) | 225 | static void __trace_array_put(struct trace_array *this_tr) |
226 | { | 226 | { |
227 | WARN_ON(!this_tr->ref); | 227 | WARN_ON(!this_tr->ref); |
228 | this_tr->ref--; | 228 | this_tr->ref--; |
229 | } | 229 | } |
230 | 230 | ||
231 | void trace_array_put(struct trace_array *this_tr) | 231 | void trace_array_put(struct trace_array *this_tr) |
232 | { | 232 | { |
233 | mutex_lock(&trace_types_lock); | 233 | mutex_lock(&trace_types_lock); |
234 | __trace_array_put(this_tr); | 234 | __trace_array_put(this_tr); |
235 | mutex_unlock(&trace_types_lock); | 235 | mutex_unlock(&trace_types_lock); |
236 | } | 236 | } |
237 | 237 | ||
238 | int filter_current_check_discard(struct ring_buffer *buffer, | 238 | int filter_current_check_discard(struct ring_buffer *buffer, |
239 | struct ftrace_event_call *call, void *rec, | 239 | struct ftrace_event_call *call, void *rec, |
240 | struct ring_buffer_event *event) | 240 | struct ring_buffer_event *event) |
241 | { | 241 | { |
242 | return filter_check_discard(call, rec, buffer, event); | 242 | return filter_check_discard(call, rec, buffer, event); |
243 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(filter_current_check_discard); | 244 | EXPORT_SYMBOL_GPL(filter_current_check_discard); |
245 | 245 | ||
246 | cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu) | 246 | cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu) |
247 | { | 247 | { |
248 | u64 ts; | 248 | u64 ts; |
249 | 249 | ||
250 | /* Early boot up does not have a buffer yet */ | 250 | /* Early boot up does not have a buffer yet */ |
251 | if (!buf->buffer) | 251 | if (!buf->buffer) |
252 | return trace_clock_local(); | 252 | return trace_clock_local(); |
253 | 253 | ||
254 | ts = ring_buffer_time_stamp(buf->buffer, cpu); | 254 | ts = ring_buffer_time_stamp(buf->buffer, cpu); |
255 | ring_buffer_normalize_time_stamp(buf->buffer, cpu, &ts); | 255 | ring_buffer_normalize_time_stamp(buf->buffer, cpu, &ts); |
256 | 256 | ||
257 | return ts; | 257 | return ts; |
258 | } | 258 | } |
259 | 259 | ||
260 | cycle_t ftrace_now(int cpu) | 260 | cycle_t ftrace_now(int cpu) |
261 | { | 261 | { |
262 | return buffer_ftrace_now(&global_trace.trace_buffer, cpu); | 262 | return buffer_ftrace_now(&global_trace.trace_buffer, cpu); |
263 | } | 263 | } |
264 | 264 | ||
265 | /** | 265 | /** |
266 | * tracing_is_enabled - Show if global_trace has been disabled | 266 | * tracing_is_enabled - Show if global_trace has been disabled |
267 | * | 267 | * |
268 | * Shows if the global trace has been enabled or not. It uses the | 268 | * Shows if the global trace has been enabled or not. It uses the |
269 | * mirror flag "buffer_disabled" to be used in fast paths such as for | 269 | * mirror flag "buffer_disabled" to be used in fast paths such as for |
270 | * the irqsoff tracer. But it may be inaccurate due to races. If you | 270 | * the irqsoff tracer. But it may be inaccurate due to races. If you |
271 | * need to know the accurate state, use tracing_is_on() which is a little | 271 | * need to know the accurate state, use tracing_is_on() which is a little |
272 | * slower, but accurate. | 272 | * slower, but accurate. |
273 | */ | 273 | */ |
274 | int tracing_is_enabled(void) | 274 | int tracing_is_enabled(void) |
275 | { | 275 | { |
276 | /* | 276 | /* |
277 | * For quick access (irqsoff uses this in fast path), just | 277 | * For quick access (irqsoff uses this in fast path), just |
278 | * return the mirror variable of the state of the ring buffer. | 278 | * return the mirror variable of the state of the ring buffer. |
279 | * It's a little racy, but we don't really care. | 279 | * It's a little racy, but we don't really care. |
280 | */ | 280 | */ |
281 | smp_rmb(); | 281 | smp_rmb(); |
282 | return !global_trace.buffer_disabled; | 282 | return !global_trace.buffer_disabled; |
283 | } | 283 | } |
284 | 284 | ||
285 | /* | 285 | /* |
286 | * trace_buf_size is the size in bytes that is allocated | 286 | * trace_buf_size is the size in bytes that is allocated |
287 | * for a buffer. Note, the number of bytes is always rounded | 287 | * for a buffer. Note, the number of bytes is always rounded |
288 | * to page size. | 288 | * to page size. |
289 | * | 289 | * |
290 | * This number is purposely set to a low number of 16384. | 290 | * This number is purposely set to a low number of 16384. |
291 | * If the dump on oops happens, it will be much appreciated | 291 | * If the dump on oops happens, it will be much appreciated |
292 | * to not have to wait for all that output. Anyway this can be | 292 | * to not have to wait for all that output. Anyway this can be |
293 | * boot time and run time configurable. | 293 | * boot time and run time configurable. |
294 | */ | 294 | */ |
295 | #define TRACE_BUF_SIZE_DEFAULT 1441792UL /* 16384 * 88 (sizeof(entry)) */ | 295 | #define TRACE_BUF_SIZE_DEFAULT 1441792UL /* 16384 * 88 (sizeof(entry)) */ |
296 | 296 | ||
297 | static unsigned long trace_buf_size = TRACE_BUF_SIZE_DEFAULT; | 297 | static unsigned long trace_buf_size = TRACE_BUF_SIZE_DEFAULT; |
298 | 298 | ||
299 | /* trace_types holds a link list of available tracers. */ | 299 | /* trace_types holds a link list of available tracers. */ |
300 | static struct tracer *trace_types __read_mostly; | 300 | static struct tracer *trace_types __read_mostly; |
301 | 301 | ||
302 | /* | 302 | /* |
303 | * trace_types_lock is used to protect the trace_types list. | 303 | * trace_types_lock is used to protect the trace_types list. |
304 | */ | 304 | */ |
305 | DEFINE_MUTEX(trace_types_lock); | 305 | DEFINE_MUTEX(trace_types_lock); |
306 | 306 | ||
307 | /* | 307 | /* |
308 | * serialize the access of the ring buffer | 308 | * serialize the access of the ring buffer |
309 | * | 309 | * |
310 | * ring buffer serializes readers, but it is low level protection. | 310 | * ring buffer serializes readers, but it is low level protection. |
311 | * The validity of the events (which returns by ring_buffer_peek() ..etc) | 311 | * The validity of the events (which returns by ring_buffer_peek() ..etc) |
312 | * are not protected by ring buffer. | 312 | * are not protected by ring buffer. |
313 | * | 313 | * |
314 | * The content of events may become garbage if we allow other process consumes | 314 | * The content of events may become garbage if we allow other process consumes |
315 | * these events concurrently: | 315 | * these events concurrently: |
316 | * A) the page of the consumed events may become a normal page | 316 | * A) the page of the consumed events may become a normal page |
317 | * (not reader page) in ring buffer, and this page will be rewrited | 317 | * (not reader page) in ring buffer, and this page will be rewrited |
318 | * by events producer. | 318 | * by events producer. |
319 | * B) The page of the consumed events may become a page for splice_read, | 319 | * B) The page of the consumed events may become a page for splice_read, |
320 | * and this page will be returned to system. | 320 | * and this page will be returned to system. |
321 | * | 321 | * |
322 | * These primitives allow multi process access to different cpu ring buffer | 322 | * These primitives allow multi process access to different cpu ring buffer |
323 | * concurrently. | 323 | * concurrently. |
324 | * | 324 | * |
325 | * These primitives don't distinguish read-only and read-consume access. | 325 | * These primitives don't distinguish read-only and read-consume access. |
326 | * Multi read-only access are also serialized. | 326 | * Multi read-only access are also serialized. |
327 | */ | 327 | */ |
328 | 328 | ||
329 | #ifdef CONFIG_SMP | 329 | #ifdef CONFIG_SMP |
330 | static DECLARE_RWSEM(all_cpu_access_lock); | 330 | static DECLARE_RWSEM(all_cpu_access_lock); |
331 | static DEFINE_PER_CPU(struct mutex, cpu_access_lock); | 331 | static DEFINE_PER_CPU(struct mutex, cpu_access_lock); |
332 | 332 | ||
333 | static inline void trace_access_lock(int cpu) | 333 | static inline void trace_access_lock(int cpu) |
334 | { | 334 | { |
335 | if (cpu == RING_BUFFER_ALL_CPUS) { | 335 | if (cpu == RING_BUFFER_ALL_CPUS) { |
336 | /* gain it for accessing the whole ring buffer. */ | 336 | /* gain it for accessing the whole ring buffer. */ |
337 | down_write(&all_cpu_access_lock); | 337 | down_write(&all_cpu_access_lock); |
338 | } else { | 338 | } else { |
339 | /* gain it for accessing a cpu ring buffer. */ | 339 | /* gain it for accessing a cpu ring buffer. */ |
340 | 340 | ||
341 | /* Firstly block other trace_access_lock(RING_BUFFER_ALL_CPUS). */ | 341 | /* Firstly block other trace_access_lock(RING_BUFFER_ALL_CPUS). */ |
342 | down_read(&all_cpu_access_lock); | 342 | down_read(&all_cpu_access_lock); |
343 | 343 | ||
344 | /* Secondly block other access to this @cpu ring buffer. */ | 344 | /* Secondly block other access to this @cpu ring buffer. */ |
345 | mutex_lock(&per_cpu(cpu_access_lock, cpu)); | 345 | mutex_lock(&per_cpu(cpu_access_lock, cpu)); |
346 | } | 346 | } |
347 | } | 347 | } |
348 | 348 | ||
349 | static inline void trace_access_unlock(int cpu) | 349 | static inline void trace_access_unlock(int cpu) |
350 | { | 350 | { |
351 | if (cpu == RING_BUFFER_ALL_CPUS) { | 351 | if (cpu == RING_BUFFER_ALL_CPUS) { |
352 | up_write(&all_cpu_access_lock); | 352 | up_write(&all_cpu_access_lock); |
353 | } else { | 353 | } else { |
354 | mutex_unlock(&per_cpu(cpu_access_lock, cpu)); | 354 | mutex_unlock(&per_cpu(cpu_access_lock, cpu)); |
355 | up_read(&all_cpu_access_lock); | 355 | up_read(&all_cpu_access_lock); |
356 | } | 356 | } |
357 | } | 357 | } |
358 | 358 | ||
359 | static inline void trace_access_lock_init(void) | 359 | static inline void trace_access_lock_init(void) |
360 | { | 360 | { |
361 | int cpu; | 361 | int cpu; |
362 | 362 | ||
363 | for_each_possible_cpu(cpu) | 363 | for_each_possible_cpu(cpu) |
364 | mutex_init(&per_cpu(cpu_access_lock, cpu)); | 364 | mutex_init(&per_cpu(cpu_access_lock, cpu)); |
365 | } | 365 | } |
366 | 366 | ||
367 | #else | 367 | #else |
368 | 368 | ||
369 | static DEFINE_MUTEX(access_lock); | 369 | static DEFINE_MUTEX(access_lock); |
370 | 370 | ||
371 | static inline void trace_access_lock(int cpu) | 371 | static inline void trace_access_lock(int cpu) |
372 | { | 372 | { |
373 | (void)cpu; | 373 | (void)cpu; |
374 | mutex_lock(&access_lock); | 374 | mutex_lock(&access_lock); |
375 | } | 375 | } |
376 | 376 | ||
377 | static inline void trace_access_unlock(int cpu) | 377 | static inline void trace_access_unlock(int cpu) |
378 | { | 378 | { |
379 | (void)cpu; | 379 | (void)cpu; |
380 | mutex_unlock(&access_lock); | 380 | mutex_unlock(&access_lock); |
381 | } | 381 | } |
382 | 382 | ||
383 | static inline void trace_access_lock_init(void) | 383 | static inline void trace_access_lock_init(void) |
384 | { | 384 | { |
385 | } | 385 | } |
386 | 386 | ||
387 | #endif | 387 | #endif |
388 | 388 | ||
389 | /* trace_flags holds trace_options default values */ | 389 | /* trace_flags holds trace_options default values */ |
390 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | | 390 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | |
391 | TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME | | 391 | TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME | |
392 | TRACE_ITER_GRAPH_TIME | TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE | | 392 | TRACE_ITER_GRAPH_TIME | TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE | |
393 | TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS | TRACE_ITER_FUNCTION; | 393 | TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS | TRACE_ITER_FUNCTION; |
394 | 394 | ||
395 | static void tracer_tracing_on(struct trace_array *tr) | 395 | static void tracer_tracing_on(struct trace_array *tr) |
396 | { | 396 | { |
397 | if (tr->trace_buffer.buffer) | 397 | if (tr->trace_buffer.buffer) |
398 | ring_buffer_record_on(tr->trace_buffer.buffer); | 398 | ring_buffer_record_on(tr->trace_buffer.buffer); |
399 | /* | 399 | /* |
400 | * This flag is looked at when buffers haven't been allocated | 400 | * This flag is looked at when buffers haven't been allocated |
401 | * yet, or by some tracers (like irqsoff), that just want to | 401 | * yet, or by some tracers (like irqsoff), that just want to |
402 | * know if the ring buffer has been disabled, but it can handle | 402 | * know if the ring buffer has been disabled, but it can handle |
403 | * races of where it gets disabled but we still do a record. | 403 | * races of where it gets disabled but we still do a record. |
404 | * As the check is in the fast path of the tracers, it is more | 404 | * As the check is in the fast path of the tracers, it is more |
405 | * important to be fast than accurate. | 405 | * important to be fast than accurate. |
406 | */ | 406 | */ |
407 | tr->buffer_disabled = 0; | 407 | tr->buffer_disabled = 0; |
408 | /* Make the flag seen by readers */ | 408 | /* Make the flag seen by readers */ |
409 | smp_wmb(); | 409 | smp_wmb(); |
410 | } | 410 | } |
411 | 411 | ||
412 | /** | 412 | /** |
413 | * tracing_on - enable tracing buffers | 413 | * tracing_on - enable tracing buffers |
414 | * | 414 | * |
415 | * This function enables tracing buffers that may have been | 415 | * This function enables tracing buffers that may have been |
416 | * disabled with tracing_off. | 416 | * disabled with tracing_off. |
417 | */ | 417 | */ |
418 | void tracing_on(void) | 418 | void tracing_on(void) |
419 | { | 419 | { |
420 | tracer_tracing_on(&global_trace); | 420 | tracer_tracing_on(&global_trace); |
421 | } | 421 | } |
422 | EXPORT_SYMBOL_GPL(tracing_on); | 422 | EXPORT_SYMBOL_GPL(tracing_on); |
423 | 423 | ||
424 | /** | 424 | /** |
425 | * __trace_puts - write a constant string into the trace buffer. | 425 | * __trace_puts - write a constant string into the trace buffer. |
426 | * @ip: The address of the caller | 426 | * @ip: The address of the caller |
427 | * @str: The constant string to write | 427 | * @str: The constant string to write |
428 | * @size: The size of the string. | 428 | * @size: The size of the string. |
429 | */ | 429 | */ |
430 | int __trace_puts(unsigned long ip, const char *str, int size) | 430 | int __trace_puts(unsigned long ip, const char *str, int size) |
431 | { | 431 | { |
432 | struct ring_buffer_event *event; | 432 | struct ring_buffer_event *event; |
433 | struct ring_buffer *buffer; | 433 | struct ring_buffer *buffer; |
434 | struct print_entry *entry; | 434 | struct print_entry *entry; |
435 | unsigned long irq_flags; | 435 | unsigned long irq_flags; |
436 | int alloc; | 436 | int alloc; |
437 | 437 | ||
438 | alloc = sizeof(*entry) + size + 2; /* possible \n added */ | 438 | alloc = sizeof(*entry) + size + 2; /* possible \n added */ |
439 | 439 | ||
440 | local_save_flags(irq_flags); | 440 | local_save_flags(irq_flags); |
441 | buffer = global_trace.trace_buffer.buffer; | 441 | buffer = global_trace.trace_buffer.buffer; |
442 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, | 442 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, |
443 | irq_flags, preempt_count()); | 443 | irq_flags, preempt_count()); |
444 | if (!event) | 444 | if (!event) |
445 | return 0; | 445 | return 0; |
446 | 446 | ||
447 | entry = ring_buffer_event_data(event); | 447 | entry = ring_buffer_event_data(event); |
448 | entry->ip = ip; | 448 | entry->ip = ip; |
449 | 449 | ||
450 | memcpy(&entry->buf, str, size); | 450 | memcpy(&entry->buf, str, size); |
451 | 451 | ||
452 | /* Add a newline if necessary */ | 452 | /* Add a newline if necessary */ |
453 | if (entry->buf[size - 1] != '\n') { | 453 | if (entry->buf[size - 1] != '\n') { |
454 | entry->buf[size] = '\n'; | 454 | entry->buf[size] = '\n'; |
455 | entry->buf[size + 1] = '\0'; | 455 | entry->buf[size + 1] = '\0'; |
456 | } else | 456 | } else |
457 | entry->buf[size] = '\0'; | 457 | entry->buf[size] = '\0'; |
458 | 458 | ||
459 | __buffer_unlock_commit(buffer, event); | 459 | __buffer_unlock_commit(buffer, event); |
460 | 460 | ||
461 | return size; | 461 | return size; |
462 | } | 462 | } |
463 | EXPORT_SYMBOL_GPL(__trace_puts); | 463 | EXPORT_SYMBOL_GPL(__trace_puts); |
464 | 464 | ||
465 | /** | 465 | /** |
466 | * __trace_bputs - write the pointer to a constant string into trace buffer | 466 | * __trace_bputs - write the pointer to a constant string into trace buffer |
467 | * @ip: The address of the caller | 467 | * @ip: The address of the caller |
468 | * @str: The constant string to write to the buffer to | 468 | * @str: The constant string to write to the buffer to |
469 | */ | 469 | */ |
470 | int __trace_bputs(unsigned long ip, const char *str) | 470 | int __trace_bputs(unsigned long ip, const char *str) |
471 | { | 471 | { |
472 | struct ring_buffer_event *event; | 472 | struct ring_buffer_event *event; |
473 | struct ring_buffer *buffer; | 473 | struct ring_buffer *buffer; |
474 | struct bputs_entry *entry; | 474 | struct bputs_entry *entry; |
475 | unsigned long irq_flags; | 475 | unsigned long irq_flags; |
476 | int size = sizeof(struct bputs_entry); | 476 | int size = sizeof(struct bputs_entry); |
477 | 477 | ||
478 | local_save_flags(irq_flags); | 478 | local_save_flags(irq_flags); |
479 | buffer = global_trace.trace_buffer.buffer; | 479 | buffer = global_trace.trace_buffer.buffer; |
480 | event = trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, | 480 | event = trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, |
481 | irq_flags, preempt_count()); | 481 | irq_flags, preempt_count()); |
482 | if (!event) | 482 | if (!event) |
483 | return 0; | 483 | return 0; |
484 | 484 | ||
485 | entry = ring_buffer_event_data(event); | 485 | entry = ring_buffer_event_data(event); |
486 | entry->ip = ip; | 486 | entry->ip = ip; |
487 | entry->str = str; | 487 | entry->str = str; |
488 | 488 | ||
489 | __buffer_unlock_commit(buffer, event); | 489 | __buffer_unlock_commit(buffer, event); |
490 | 490 | ||
491 | return 1; | 491 | return 1; |
492 | } | 492 | } |
493 | EXPORT_SYMBOL_GPL(__trace_bputs); | 493 | EXPORT_SYMBOL_GPL(__trace_bputs); |
494 | 494 | ||
495 | #ifdef CONFIG_TRACER_SNAPSHOT | 495 | #ifdef CONFIG_TRACER_SNAPSHOT |
496 | /** | 496 | /** |
497 | * trace_snapshot - take a snapshot of the current buffer. | 497 | * trace_snapshot - take a snapshot of the current buffer. |
498 | * | 498 | * |
499 | * This causes a swap between the snapshot buffer and the current live | 499 | * This causes a swap between the snapshot buffer and the current live |
500 | * tracing buffer. You can use this to take snapshots of the live | 500 | * tracing buffer. You can use this to take snapshots of the live |
501 | * trace when some condition is triggered, but continue to trace. | 501 | * trace when some condition is triggered, but continue to trace. |
502 | * | 502 | * |
503 | * Note, make sure to allocate the snapshot with either | 503 | * Note, make sure to allocate the snapshot with either |
504 | * a tracing_snapshot_alloc(), or by doing it manually | 504 | * a tracing_snapshot_alloc(), or by doing it manually |
505 | * with: echo 1 > /sys/kernel/debug/tracing/snapshot | 505 | * with: echo 1 > /sys/kernel/debug/tracing/snapshot |
506 | * | 506 | * |
507 | * If the snapshot buffer is not allocated, it will stop tracing. | 507 | * If the snapshot buffer is not allocated, it will stop tracing. |
508 | * Basically making a permanent snapshot. | 508 | * Basically making a permanent snapshot. |
509 | */ | 509 | */ |
510 | void tracing_snapshot(void) | 510 | void tracing_snapshot(void) |
511 | { | 511 | { |
512 | struct trace_array *tr = &global_trace; | 512 | struct trace_array *tr = &global_trace; |
513 | struct tracer *tracer = tr->current_trace; | 513 | struct tracer *tracer = tr->current_trace; |
514 | unsigned long flags; | 514 | unsigned long flags; |
515 | 515 | ||
516 | if (in_nmi()) { | 516 | if (in_nmi()) { |
517 | internal_trace_puts("*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n"); | 517 | internal_trace_puts("*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n"); |
518 | internal_trace_puts("*** snapshot is being ignored ***\n"); | 518 | internal_trace_puts("*** snapshot is being ignored ***\n"); |
519 | return; | 519 | return; |
520 | } | 520 | } |
521 | 521 | ||
522 | if (!tr->allocated_snapshot) { | 522 | if (!tr->allocated_snapshot) { |
523 | internal_trace_puts("*** SNAPSHOT NOT ALLOCATED ***\n"); | 523 | internal_trace_puts("*** SNAPSHOT NOT ALLOCATED ***\n"); |
524 | internal_trace_puts("*** stopping trace here! ***\n"); | 524 | internal_trace_puts("*** stopping trace here! ***\n"); |
525 | tracing_off(); | 525 | tracing_off(); |
526 | return; | 526 | return; |
527 | } | 527 | } |
528 | 528 | ||
529 | /* Note, snapshot can not be used when the tracer uses it */ | 529 | /* Note, snapshot can not be used when the tracer uses it */ |
530 | if (tracer->use_max_tr) { | 530 | if (tracer->use_max_tr) { |
531 | internal_trace_puts("*** LATENCY TRACER ACTIVE ***\n"); | 531 | internal_trace_puts("*** LATENCY TRACER ACTIVE ***\n"); |
532 | internal_trace_puts("*** Can not use snapshot (sorry) ***\n"); | 532 | internal_trace_puts("*** Can not use snapshot (sorry) ***\n"); |
533 | return; | 533 | return; |
534 | } | 534 | } |
535 | 535 | ||
536 | local_irq_save(flags); | 536 | local_irq_save(flags); |
537 | update_max_tr(tr, current, smp_processor_id()); | 537 | update_max_tr(tr, current, smp_processor_id()); |
538 | local_irq_restore(flags); | 538 | local_irq_restore(flags); |
539 | } | 539 | } |
540 | EXPORT_SYMBOL_GPL(tracing_snapshot); | 540 | EXPORT_SYMBOL_GPL(tracing_snapshot); |
541 | 541 | ||
542 | static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf, | 542 | static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf, |
543 | struct trace_buffer *size_buf, int cpu_id); | 543 | struct trace_buffer *size_buf, int cpu_id); |
544 | static void set_buffer_entries(struct trace_buffer *buf, unsigned long val); | 544 | static void set_buffer_entries(struct trace_buffer *buf, unsigned long val); |
545 | 545 | ||
546 | static int alloc_snapshot(struct trace_array *tr) | 546 | static int alloc_snapshot(struct trace_array *tr) |
547 | { | 547 | { |
548 | int ret; | 548 | int ret; |
549 | 549 | ||
550 | if (!tr->allocated_snapshot) { | 550 | if (!tr->allocated_snapshot) { |
551 | 551 | ||
552 | /* allocate spare buffer */ | 552 | /* allocate spare buffer */ |
553 | ret = resize_buffer_duplicate_size(&tr->max_buffer, | 553 | ret = resize_buffer_duplicate_size(&tr->max_buffer, |
554 | &tr->trace_buffer, RING_BUFFER_ALL_CPUS); | 554 | &tr->trace_buffer, RING_BUFFER_ALL_CPUS); |
555 | if (ret < 0) | 555 | if (ret < 0) |
556 | return ret; | 556 | return ret; |
557 | 557 | ||
558 | tr->allocated_snapshot = true; | 558 | tr->allocated_snapshot = true; |
559 | } | 559 | } |
560 | 560 | ||
561 | return 0; | 561 | return 0; |
562 | } | 562 | } |
563 | 563 | ||
564 | void free_snapshot(struct trace_array *tr) | 564 | void free_snapshot(struct trace_array *tr) |
565 | { | 565 | { |
566 | /* | 566 | /* |
567 | * We don't free the ring buffer. instead, resize it because | 567 | * We don't free the ring buffer. instead, resize it because |
568 | * The max_tr ring buffer has some state (e.g. ring->clock) and | 568 | * The max_tr ring buffer has some state (e.g. ring->clock) and |
569 | * we want preserve it. | 569 | * we want preserve it. |
570 | */ | 570 | */ |
571 | ring_buffer_resize(tr->max_buffer.buffer, 1, RING_BUFFER_ALL_CPUS); | 571 | ring_buffer_resize(tr->max_buffer.buffer, 1, RING_BUFFER_ALL_CPUS); |
572 | set_buffer_entries(&tr->max_buffer, 1); | 572 | set_buffer_entries(&tr->max_buffer, 1); |
573 | tracing_reset_online_cpus(&tr->max_buffer); | 573 | tracing_reset_online_cpus(&tr->max_buffer); |
574 | tr->allocated_snapshot = false; | 574 | tr->allocated_snapshot = false; |
575 | } | 575 | } |
576 | 576 | ||
577 | /** | 577 | /** |
578 | * trace_snapshot_alloc - allocate and take a snapshot of the current buffer. | 578 | * trace_snapshot_alloc - allocate and take a snapshot of the current buffer. |
579 | * | 579 | * |
580 | * This is similar to trace_snapshot(), but it will allocate the | 580 | * This is similar to trace_snapshot(), but it will allocate the |
581 | * snapshot buffer if it isn't already allocated. Use this only | 581 | * snapshot buffer if it isn't already allocated. Use this only |
582 | * where it is safe to sleep, as the allocation may sleep. | 582 | * where it is safe to sleep, as the allocation may sleep. |
583 | * | 583 | * |
584 | * This causes a swap between the snapshot buffer and the current live | 584 | * This causes a swap between the snapshot buffer and the current live |
585 | * tracing buffer. You can use this to take snapshots of the live | 585 | * tracing buffer. You can use this to take snapshots of the live |
586 | * trace when some condition is triggered, but continue to trace. | 586 | * trace when some condition is triggered, but continue to trace. |
587 | */ | 587 | */ |
588 | void tracing_snapshot_alloc(void) | 588 | void tracing_snapshot_alloc(void) |
589 | { | 589 | { |
590 | struct trace_array *tr = &global_trace; | 590 | struct trace_array *tr = &global_trace; |
591 | int ret; | 591 | int ret; |
592 | 592 | ||
593 | ret = alloc_snapshot(tr); | 593 | ret = alloc_snapshot(tr); |
594 | if (WARN_ON(ret < 0)) | 594 | if (WARN_ON(ret < 0)) |
595 | return; | 595 | return; |
596 | 596 | ||
597 | tracing_snapshot(); | 597 | tracing_snapshot(); |
598 | } | 598 | } |
599 | EXPORT_SYMBOL_GPL(tracing_snapshot_alloc); | 599 | EXPORT_SYMBOL_GPL(tracing_snapshot_alloc); |
600 | #else | 600 | #else |
601 | void tracing_snapshot(void) | 601 | void tracing_snapshot(void) |
602 | { | 602 | { |
603 | WARN_ONCE(1, "Snapshot feature not enabled, but internal snapshot used"); | 603 | WARN_ONCE(1, "Snapshot feature not enabled, but internal snapshot used"); |
604 | } | 604 | } |
605 | EXPORT_SYMBOL_GPL(tracing_snapshot); | 605 | EXPORT_SYMBOL_GPL(tracing_snapshot); |
606 | void tracing_snapshot_alloc(void) | 606 | void tracing_snapshot_alloc(void) |
607 | { | 607 | { |
608 | /* Give warning */ | 608 | /* Give warning */ |
609 | tracing_snapshot(); | 609 | tracing_snapshot(); |
610 | } | 610 | } |
611 | EXPORT_SYMBOL_GPL(tracing_snapshot_alloc); | 611 | EXPORT_SYMBOL_GPL(tracing_snapshot_alloc); |
612 | #endif /* CONFIG_TRACER_SNAPSHOT */ | 612 | #endif /* CONFIG_TRACER_SNAPSHOT */ |
613 | 613 | ||
614 | static void tracer_tracing_off(struct trace_array *tr) | 614 | static void tracer_tracing_off(struct trace_array *tr) |
615 | { | 615 | { |
616 | if (tr->trace_buffer.buffer) | 616 | if (tr->trace_buffer.buffer) |
617 | ring_buffer_record_off(tr->trace_buffer.buffer); | 617 | ring_buffer_record_off(tr->trace_buffer.buffer); |
618 | /* | 618 | /* |
619 | * This flag is looked at when buffers haven't been allocated | 619 | * This flag is looked at when buffers haven't been allocated |
620 | * yet, or by some tracers (like irqsoff), that just want to | 620 | * yet, or by some tracers (like irqsoff), that just want to |
621 | * know if the ring buffer has been disabled, but it can handle | 621 | * know if the ring buffer has been disabled, but it can handle |
622 | * races of where it gets disabled but we still do a record. | 622 | * races of where it gets disabled but we still do a record. |
623 | * As the check is in the fast path of the tracers, it is more | 623 | * As the check is in the fast path of the tracers, it is more |
624 | * important to be fast than accurate. | 624 | * important to be fast than accurate. |
625 | */ | 625 | */ |
626 | tr->buffer_disabled = 1; | 626 | tr->buffer_disabled = 1; |
627 | /* Make the flag seen by readers */ | 627 | /* Make the flag seen by readers */ |
628 | smp_wmb(); | 628 | smp_wmb(); |
629 | } | 629 | } |
630 | 630 | ||
631 | /** | 631 | /** |
632 | * tracing_off - turn off tracing buffers | 632 | * tracing_off - turn off tracing buffers |
633 | * | 633 | * |
634 | * This function stops the tracing buffers from recording data. | 634 | * This function stops the tracing buffers from recording data. |
635 | * It does not disable any overhead the tracers themselves may | 635 | * It does not disable any overhead the tracers themselves may |
636 | * be causing. This function simply causes all recording to | 636 | * be causing. This function simply causes all recording to |
637 | * the ring buffers to fail. | 637 | * the ring buffers to fail. |
638 | */ | 638 | */ |
639 | void tracing_off(void) | 639 | void tracing_off(void) |
640 | { | 640 | { |
641 | tracer_tracing_off(&global_trace); | 641 | tracer_tracing_off(&global_trace); |
642 | } | 642 | } |
643 | EXPORT_SYMBOL_GPL(tracing_off); | 643 | EXPORT_SYMBOL_GPL(tracing_off); |
644 | 644 | ||
645 | void disable_trace_on_warning(void) | 645 | void disable_trace_on_warning(void) |
646 | { | 646 | { |
647 | if (__disable_trace_on_warning) | 647 | if (__disable_trace_on_warning) |
648 | tracing_off(); | 648 | tracing_off(); |
649 | } | 649 | } |
650 | 650 | ||
651 | /** | 651 | /** |
652 | * tracer_tracing_is_on - show real state of ring buffer enabled | 652 | * tracer_tracing_is_on - show real state of ring buffer enabled |
653 | * @tr : the trace array to know if ring buffer is enabled | 653 | * @tr : the trace array to know if ring buffer is enabled |
654 | * | 654 | * |
655 | * Shows real state of the ring buffer if it is enabled or not. | 655 | * Shows real state of the ring buffer if it is enabled or not. |
656 | */ | 656 | */ |
657 | static int tracer_tracing_is_on(struct trace_array *tr) | 657 | static int tracer_tracing_is_on(struct trace_array *tr) |
658 | { | 658 | { |
659 | if (tr->trace_buffer.buffer) | 659 | if (tr->trace_buffer.buffer) |
660 | return ring_buffer_record_is_on(tr->trace_buffer.buffer); | 660 | return ring_buffer_record_is_on(tr->trace_buffer.buffer); |
661 | return !tr->buffer_disabled; | 661 | return !tr->buffer_disabled; |
662 | } | 662 | } |
663 | 663 | ||
664 | /** | 664 | /** |
665 | * tracing_is_on - show state of ring buffers enabled | 665 | * tracing_is_on - show state of ring buffers enabled |
666 | */ | 666 | */ |
667 | int tracing_is_on(void) | 667 | int tracing_is_on(void) |
668 | { | 668 | { |
669 | return tracer_tracing_is_on(&global_trace); | 669 | return tracer_tracing_is_on(&global_trace); |
670 | } | 670 | } |
671 | EXPORT_SYMBOL_GPL(tracing_is_on); | 671 | EXPORT_SYMBOL_GPL(tracing_is_on); |
672 | 672 | ||
673 | static int __init set_buf_size(char *str) | 673 | static int __init set_buf_size(char *str) |
674 | { | 674 | { |
675 | unsigned long buf_size; | 675 | unsigned long buf_size; |
676 | 676 | ||
677 | if (!str) | 677 | if (!str) |
678 | return 0; | 678 | return 0; |
679 | buf_size = memparse(str, &str); | 679 | buf_size = memparse(str, &str); |
680 | /* nr_entries can not be zero */ | 680 | /* nr_entries can not be zero */ |
681 | if (buf_size == 0) | 681 | if (buf_size == 0) |
682 | return 0; | 682 | return 0; |
683 | trace_buf_size = buf_size; | 683 | trace_buf_size = buf_size; |
684 | return 1; | 684 | return 1; |
685 | } | 685 | } |
686 | __setup("trace_buf_size=", set_buf_size); | 686 | __setup("trace_buf_size=", set_buf_size); |
687 | 687 | ||
688 | static int __init set_tracing_thresh(char *str) | 688 | static int __init set_tracing_thresh(char *str) |
689 | { | 689 | { |
690 | unsigned long threshold; | 690 | unsigned long threshold; |
691 | int ret; | 691 | int ret; |
692 | 692 | ||
693 | if (!str) | 693 | if (!str) |
694 | return 0; | 694 | return 0; |
695 | ret = kstrtoul(str, 0, &threshold); | 695 | ret = kstrtoul(str, 0, &threshold); |
696 | if (ret < 0) | 696 | if (ret < 0) |
697 | return 0; | 697 | return 0; |
698 | tracing_thresh = threshold * 1000; | 698 | tracing_thresh = threshold * 1000; |
699 | return 1; | 699 | return 1; |
700 | } | 700 | } |
701 | __setup("tracing_thresh=", set_tracing_thresh); | 701 | __setup("tracing_thresh=", set_tracing_thresh); |
702 | 702 | ||
703 | unsigned long nsecs_to_usecs(unsigned long nsecs) | 703 | unsigned long nsecs_to_usecs(unsigned long nsecs) |
704 | { | 704 | { |
705 | return nsecs / 1000; | 705 | return nsecs / 1000; |
706 | } | 706 | } |
707 | 707 | ||
708 | /* These must match the bit postions in trace_iterator_flags */ | 708 | /* These must match the bit postions in trace_iterator_flags */ |
709 | static const char *trace_options[] = { | 709 | static const char *trace_options[] = { |
710 | "print-parent", | 710 | "print-parent", |
711 | "sym-offset", | 711 | "sym-offset", |
712 | "sym-addr", | 712 | "sym-addr", |
713 | "verbose", | 713 | "verbose", |
714 | "raw", | 714 | "raw", |
715 | "hex", | 715 | "hex", |
716 | "bin", | 716 | "bin", |
717 | "block", | 717 | "block", |
718 | "stacktrace", | 718 | "stacktrace", |
719 | "trace_printk", | 719 | "trace_printk", |
720 | "ftrace_preempt", | 720 | "ftrace_preempt", |
721 | "branch", | 721 | "branch", |
722 | "annotate", | 722 | "annotate", |
723 | "userstacktrace", | 723 | "userstacktrace", |
724 | "sym-userobj", | 724 | "sym-userobj", |
725 | "printk-msg-only", | 725 | "printk-msg-only", |
726 | "context-info", | 726 | "context-info", |
727 | "latency-format", | 727 | "latency-format", |
728 | "sleep-time", | 728 | "sleep-time", |
729 | "graph-time", | 729 | "graph-time", |
730 | "record-cmd", | 730 | "record-cmd", |
731 | "overwrite", | 731 | "overwrite", |
732 | "disable_on_free", | 732 | "disable_on_free", |
733 | "irq-info", | 733 | "irq-info", |
734 | "markers", | 734 | "markers", |
735 | "function-trace", | 735 | "function-trace", |
736 | NULL | 736 | NULL |
737 | }; | 737 | }; |
738 | 738 | ||
739 | static struct { | 739 | static struct { |
740 | u64 (*func)(void); | 740 | u64 (*func)(void); |
741 | const char *name; | 741 | const char *name; |
742 | int in_ns; /* is this clock in nanoseconds? */ | 742 | int in_ns; /* is this clock in nanoseconds? */ |
743 | } trace_clocks[] = { | 743 | } trace_clocks[] = { |
744 | { trace_clock_local, "local", 1 }, | 744 | { trace_clock_local, "local", 1 }, |
745 | { trace_clock_global, "global", 1 }, | 745 | { trace_clock_global, "global", 1 }, |
746 | { trace_clock_counter, "counter", 0 }, | 746 | { trace_clock_counter, "counter", 0 }, |
747 | { trace_clock_jiffies, "uptime", 1 }, | 747 | { trace_clock_jiffies, "uptime", 1 }, |
748 | { trace_clock, "perf", 1 }, | 748 | { trace_clock, "perf", 1 }, |
749 | ARCH_TRACE_CLOCKS | 749 | ARCH_TRACE_CLOCKS |
750 | }; | 750 | }; |
751 | 751 | ||
752 | /* | 752 | /* |
753 | * trace_parser_get_init - gets the buffer for trace parser | 753 | * trace_parser_get_init - gets the buffer for trace parser |
754 | */ | 754 | */ |
755 | int trace_parser_get_init(struct trace_parser *parser, int size) | 755 | int trace_parser_get_init(struct trace_parser *parser, int size) |
756 | { | 756 | { |
757 | memset(parser, 0, sizeof(*parser)); | 757 | memset(parser, 0, sizeof(*parser)); |
758 | 758 | ||
759 | parser->buffer = kmalloc(size, GFP_KERNEL); | 759 | parser->buffer = kmalloc(size, GFP_KERNEL); |
760 | if (!parser->buffer) | 760 | if (!parser->buffer) |
761 | return 1; | 761 | return 1; |
762 | 762 | ||
763 | parser->size = size; | 763 | parser->size = size; |
764 | return 0; | 764 | return 0; |
765 | } | 765 | } |
766 | 766 | ||
767 | /* | 767 | /* |
768 | * trace_parser_put - frees the buffer for trace parser | 768 | * trace_parser_put - frees the buffer for trace parser |
769 | */ | 769 | */ |
770 | void trace_parser_put(struct trace_parser *parser) | 770 | void trace_parser_put(struct trace_parser *parser) |
771 | { | 771 | { |
772 | kfree(parser->buffer); | 772 | kfree(parser->buffer); |
773 | } | 773 | } |
774 | 774 | ||
775 | /* | 775 | /* |
776 | * trace_get_user - reads the user input string separated by space | 776 | * trace_get_user - reads the user input string separated by space |
777 | * (matched by isspace(ch)) | 777 | * (matched by isspace(ch)) |
778 | * | 778 | * |
779 | * For each string found the 'struct trace_parser' is updated, | 779 | * For each string found the 'struct trace_parser' is updated, |
780 | * and the function returns. | 780 | * and the function returns. |
781 | * | 781 | * |
782 | * Returns number of bytes read. | 782 | * Returns number of bytes read. |
783 | * | 783 | * |
784 | * See kernel/trace/trace.h for 'struct trace_parser' details. | 784 | * See kernel/trace/trace.h for 'struct trace_parser' details. |
785 | */ | 785 | */ |
786 | int trace_get_user(struct trace_parser *parser, const char __user *ubuf, | 786 | int trace_get_user(struct trace_parser *parser, const char __user *ubuf, |
787 | size_t cnt, loff_t *ppos) | 787 | size_t cnt, loff_t *ppos) |
788 | { | 788 | { |
789 | char ch; | 789 | char ch; |
790 | size_t read = 0; | 790 | size_t read = 0; |
791 | ssize_t ret; | 791 | ssize_t ret; |
792 | 792 | ||
793 | if (!*ppos) | 793 | if (!*ppos) |
794 | trace_parser_clear(parser); | 794 | trace_parser_clear(parser); |
795 | 795 | ||
796 | ret = get_user(ch, ubuf++); | 796 | ret = get_user(ch, ubuf++); |
797 | if (ret) | 797 | if (ret) |
798 | goto out; | 798 | goto out; |
799 | 799 | ||
800 | read++; | 800 | read++; |
801 | cnt--; | 801 | cnt--; |
802 | 802 | ||
803 | /* | 803 | /* |
804 | * The parser is not finished with the last write, | 804 | * The parser is not finished with the last write, |
805 | * continue reading the user input without skipping spaces. | 805 | * continue reading the user input without skipping spaces. |
806 | */ | 806 | */ |
807 | if (!parser->cont) { | 807 | if (!parser->cont) { |
808 | /* skip white space */ | 808 | /* skip white space */ |
809 | while (cnt && isspace(ch)) { | 809 | while (cnt && isspace(ch)) { |
810 | ret = get_user(ch, ubuf++); | 810 | ret = get_user(ch, ubuf++); |
811 | if (ret) | 811 | if (ret) |
812 | goto out; | 812 | goto out; |
813 | read++; | 813 | read++; |
814 | cnt--; | 814 | cnt--; |
815 | } | 815 | } |
816 | 816 | ||
817 | /* only spaces were written */ | 817 | /* only spaces were written */ |
818 | if (isspace(ch)) { | 818 | if (isspace(ch)) { |
819 | *ppos += read; | 819 | *ppos += read; |
820 | ret = read; | 820 | ret = read; |
821 | goto out; | 821 | goto out; |
822 | } | 822 | } |
823 | 823 | ||
824 | parser->idx = 0; | 824 | parser->idx = 0; |
825 | } | 825 | } |
826 | 826 | ||
827 | /* read the non-space input */ | 827 | /* read the non-space input */ |
828 | while (cnt && !isspace(ch)) { | 828 | while (cnt && !isspace(ch)) { |
829 | if (parser->idx < parser->size - 1) | 829 | if (parser->idx < parser->size - 1) |
830 | parser->buffer[parser->idx++] = ch; | 830 | parser->buffer[parser->idx++] = ch; |
831 | else { | 831 | else { |
832 | ret = -EINVAL; | 832 | ret = -EINVAL; |
833 | goto out; | 833 | goto out; |
834 | } | 834 | } |
835 | ret = get_user(ch, ubuf++); | 835 | ret = get_user(ch, ubuf++); |
836 | if (ret) | 836 | if (ret) |
837 | goto out; | 837 | goto out; |
838 | read++; | 838 | read++; |
839 | cnt--; | 839 | cnt--; |
840 | } | 840 | } |
841 | 841 | ||
842 | /* We either got finished input or we have to wait for another call. */ | 842 | /* We either got finished input or we have to wait for another call. */ |
843 | if (isspace(ch)) { | 843 | if (isspace(ch)) { |
844 | parser->buffer[parser->idx] = 0; | 844 | parser->buffer[parser->idx] = 0; |
845 | parser->cont = false; | 845 | parser->cont = false; |
846 | } else { | 846 | } else { |
847 | parser->cont = true; | 847 | parser->cont = true; |
848 | parser->buffer[parser->idx++] = ch; | 848 | parser->buffer[parser->idx++] = ch; |
849 | } | 849 | } |
850 | 850 | ||
851 | *ppos += read; | 851 | *ppos += read; |
852 | ret = read; | 852 | ret = read; |
853 | 853 | ||
854 | out: | 854 | out: |
855 | return ret; | 855 | return ret; |
856 | } | 856 | } |
857 | 857 | ||
858 | ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) | 858 | ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) |
859 | { | 859 | { |
860 | int len; | 860 | int len; |
861 | int ret; | 861 | int ret; |
862 | 862 | ||
863 | if (!cnt) | 863 | if (!cnt) |
864 | return 0; | 864 | return 0; |
865 | 865 | ||
866 | if (s->len <= s->readpos) | 866 | if (s->len <= s->readpos) |
867 | return -EBUSY; | 867 | return -EBUSY; |
868 | 868 | ||
869 | len = s->len - s->readpos; | 869 | len = s->len - s->readpos; |
870 | if (cnt > len) | 870 | if (cnt > len) |
871 | cnt = len; | 871 | cnt = len; |
872 | ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); | 872 | ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); |
873 | if (ret == cnt) | 873 | if (ret == cnt) |
874 | return -EFAULT; | 874 | return -EFAULT; |
875 | 875 | ||
876 | cnt -= ret; | 876 | cnt -= ret; |
877 | 877 | ||
878 | s->readpos += cnt; | 878 | s->readpos += cnt; |
879 | return cnt; | 879 | return cnt; |
880 | } | 880 | } |
881 | 881 | ||
882 | static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) | 882 | static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) |
883 | { | 883 | { |
884 | int len; | 884 | int len; |
885 | 885 | ||
886 | if (s->len <= s->readpos) | 886 | if (s->len <= s->readpos) |
887 | return -EBUSY; | 887 | return -EBUSY; |
888 | 888 | ||
889 | len = s->len - s->readpos; | 889 | len = s->len - s->readpos; |
890 | if (cnt > len) | 890 | if (cnt > len) |
891 | cnt = len; | 891 | cnt = len; |
892 | memcpy(buf, s->buffer + s->readpos, cnt); | 892 | memcpy(buf, s->buffer + s->readpos, cnt); |
893 | 893 | ||
894 | s->readpos += cnt; | 894 | s->readpos += cnt; |
895 | return cnt; | 895 | return cnt; |
896 | } | 896 | } |
897 | 897 | ||
898 | /* | 898 | /* |
899 | * ftrace_max_lock is used to protect the swapping of buffers | 899 | * ftrace_max_lock is used to protect the swapping of buffers |
900 | * when taking a max snapshot. The buffers themselves are | 900 | * when taking a max snapshot. The buffers themselves are |
901 | * protected by per_cpu spinlocks. But the action of the swap | 901 | * protected by per_cpu spinlocks. But the action of the swap |
902 | * needs its own lock. | 902 | * needs its own lock. |
903 | * | 903 | * |
904 | * This is defined as a arch_spinlock_t in order to help | 904 | * This is defined as a arch_spinlock_t in order to help |
905 | * with performance when lockdep debugging is enabled. | 905 | * with performance when lockdep debugging is enabled. |
906 | * | 906 | * |
907 | * It is also used in other places outside the update_max_tr | 907 | * It is also used in other places outside the update_max_tr |
908 | * so it needs to be defined outside of the | 908 | * so it needs to be defined outside of the |
909 | * CONFIG_TRACER_MAX_TRACE. | 909 | * CONFIG_TRACER_MAX_TRACE. |
910 | */ | 910 | */ |
911 | static arch_spinlock_t ftrace_max_lock = | 911 | static arch_spinlock_t ftrace_max_lock = |
912 | (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; | 912 | (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; |
913 | 913 | ||
914 | unsigned long __read_mostly tracing_thresh; | 914 | unsigned long __read_mostly tracing_thresh; |
915 | 915 | ||
916 | #ifdef CONFIG_TRACER_MAX_TRACE | 916 | #ifdef CONFIG_TRACER_MAX_TRACE |
917 | unsigned long __read_mostly tracing_max_latency; | 917 | unsigned long __read_mostly tracing_max_latency; |
918 | 918 | ||
919 | /* | 919 | /* |
920 | * Copy the new maximum trace into the separate maximum-trace | 920 | * Copy the new maximum trace into the separate maximum-trace |
921 | * structure. (this way the maximum trace is permanently saved, | 921 | * structure. (this way the maximum trace is permanently saved, |
922 | * for later retrieval via /sys/kernel/debug/tracing/latency_trace) | 922 | * for later retrieval via /sys/kernel/debug/tracing/latency_trace) |
923 | */ | 923 | */ |
924 | static void | 924 | static void |
925 | __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) | 925 | __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) |
926 | { | 926 | { |
927 | struct trace_buffer *trace_buf = &tr->trace_buffer; | 927 | struct trace_buffer *trace_buf = &tr->trace_buffer; |
928 | struct trace_buffer *max_buf = &tr->max_buffer; | 928 | struct trace_buffer *max_buf = &tr->max_buffer; |
929 | struct trace_array_cpu *data = per_cpu_ptr(trace_buf->data, cpu); | 929 | struct trace_array_cpu *data = per_cpu_ptr(trace_buf->data, cpu); |
930 | struct trace_array_cpu *max_data = per_cpu_ptr(max_buf->data, cpu); | 930 | struct trace_array_cpu *max_data = per_cpu_ptr(max_buf->data, cpu); |
931 | 931 | ||
932 | max_buf->cpu = cpu; | 932 | max_buf->cpu = cpu; |
933 | max_buf->time_start = data->preempt_timestamp; | 933 | max_buf->time_start = data->preempt_timestamp; |
934 | 934 | ||
935 | max_data->saved_latency = tracing_max_latency; | 935 | max_data->saved_latency = tracing_max_latency; |
936 | max_data->critical_start = data->critical_start; | 936 | max_data->critical_start = data->critical_start; |
937 | max_data->critical_end = data->critical_end; | 937 | max_data->critical_end = data->critical_end; |
938 | 938 | ||
939 | memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN); | 939 | memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN); |
940 | max_data->pid = tsk->pid; | 940 | max_data->pid = tsk->pid; |
941 | /* | 941 | /* |
942 | * If tsk == current, then use current_uid(), as that does not use | 942 | * If tsk == current, then use current_uid(), as that does not use |
943 | * RCU. The irq tracer can be called out of RCU scope. | 943 | * RCU. The irq tracer can be called out of RCU scope. |
944 | */ | 944 | */ |
945 | if (tsk == current) | 945 | if (tsk == current) |
946 | max_data->uid = current_uid(); | 946 | max_data->uid = current_uid(); |
947 | else | 947 | else |
948 | max_data->uid = task_uid(tsk); | 948 | max_data->uid = task_uid(tsk); |
949 | 949 | ||
950 | max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO; | 950 | max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO; |
951 | max_data->policy = tsk->policy; | 951 | max_data->policy = tsk->policy; |
952 | max_data->rt_priority = tsk->rt_priority; | 952 | max_data->rt_priority = tsk->rt_priority; |
953 | 953 | ||
954 | /* record this tasks comm */ | 954 | /* record this tasks comm */ |
955 | tracing_record_cmdline(tsk); | 955 | tracing_record_cmdline(tsk); |
956 | } | 956 | } |
957 | 957 | ||
958 | /** | 958 | /** |
959 | * update_max_tr - snapshot all trace buffers from global_trace to max_tr | 959 | * update_max_tr - snapshot all trace buffers from global_trace to max_tr |
960 | * @tr: tracer | 960 | * @tr: tracer |
961 | * @tsk: the task with the latency | 961 | * @tsk: the task with the latency |
962 | * @cpu: The cpu that initiated the trace. | 962 | * @cpu: The cpu that initiated the trace. |
963 | * | 963 | * |
964 | * Flip the buffers between the @tr and the max_tr and record information | 964 | * Flip the buffers between the @tr and the max_tr and record information |
965 | * about which task was the cause of this latency. | 965 | * about which task was the cause of this latency. |
966 | */ | 966 | */ |
967 | void | 967 | void |
968 | update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) | 968 | update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) |
969 | { | 969 | { |
970 | struct ring_buffer *buf; | 970 | struct ring_buffer *buf; |
971 | 971 | ||
972 | if (tr->stop_count) | 972 | if (tr->stop_count) |
973 | return; | 973 | return; |
974 | 974 | ||
975 | WARN_ON_ONCE(!irqs_disabled()); | 975 | WARN_ON_ONCE(!irqs_disabled()); |
976 | 976 | ||
977 | if (!tr->allocated_snapshot) { | 977 | if (!tr->allocated_snapshot) { |
978 | /* Only the nop tracer should hit this when disabling */ | 978 | /* Only the nop tracer should hit this when disabling */ |
979 | WARN_ON_ONCE(tr->current_trace != &nop_trace); | 979 | WARN_ON_ONCE(tr->current_trace != &nop_trace); |
980 | return; | 980 | return; |
981 | } | 981 | } |
982 | 982 | ||
983 | arch_spin_lock(&ftrace_max_lock); | 983 | arch_spin_lock(&ftrace_max_lock); |
984 | 984 | ||
985 | buf = tr->trace_buffer.buffer; | 985 | buf = tr->trace_buffer.buffer; |
986 | tr->trace_buffer.buffer = tr->max_buffer.buffer; | 986 | tr->trace_buffer.buffer = tr->max_buffer.buffer; |
987 | tr->max_buffer.buffer = buf; | 987 | tr->max_buffer.buffer = buf; |
988 | 988 | ||
989 | __update_max_tr(tr, tsk, cpu); | 989 | __update_max_tr(tr, tsk, cpu); |
990 | arch_spin_unlock(&ftrace_max_lock); | 990 | arch_spin_unlock(&ftrace_max_lock); |
991 | } | 991 | } |
992 | 992 | ||
993 | /** | 993 | /** |
994 | * update_max_tr_single - only copy one trace over, and reset the rest | 994 | * update_max_tr_single - only copy one trace over, and reset the rest |
995 | * @tr - tracer | 995 | * @tr - tracer |
996 | * @tsk - task with the latency | 996 | * @tsk - task with the latency |
997 | * @cpu - the cpu of the buffer to copy. | 997 | * @cpu - the cpu of the buffer to copy. |
998 | * | 998 | * |
999 | * Flip the trace of a single CPU buffer between the @tr and the max_tr. | 999 | * Flip the trace of a single CPU buffer between the @tr and the max_tr. |
1000 | */ | 1000 | */ |
1001 | void | 1001 | void |
1002 | update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) | 1002 | update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) |
1003 | { | 1003 | { |
1004 | int ret; | 1004 | int ret; |
1005 | 1005 | ||
1006 | if (tr->stop_count) | 1006 | if (tr->stop_count) |
1007 | return; | 1007 | return; |
1008 | 1008 | ||
1009 | WARN_ON_ONCE(!irqs_disabled()); | 1009 | WARN_ON_ONCE(!irqs_disabled()); |
1010 | if (!tr->allocated_snapshot) { | 1010 | if (!tr->allocated_snapshot) { |
1011 | /* Only the nop tracer should hit this when disabling */ | 1011 | /* Only the nop tracer should hit this when disabling */ |
1012 | WARN_ON_ONCE(tr->current_trace != &nop_trace); | 1012 | WARN_ON_ONCE(tr->current_trace != &nop_trace); |
1013 | return; | 1013 | return; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | arch_spin_lock(&ftrace_max_lock); | 1016 | arch_spin_lock(&ftrace_max_lock); |
1017 | 1017 | ||
1018 | ret = ring_buffer_swap_cpu(tr->max_buffer.buffer, tr->trace_buffer.buffer, cpu); | 1018 | ret = ring_buffer_swap_cpu(tr->max_buffer.buffer, tr->trace_buffer.buffer, cpu); |
1019 | 1019 | ||
1020 | if (ret == -EBUSY) { | 1020 | if (ret == -EBUSY) { |
1021 | /* | 1021 | /* |
1022 | * We failed to swap the buffer due to a commit taking | 1022 | * We failed to swap the buffer due to a commit taking |
1023 | * place on this CPU. We fail to record, but we reset | 1023 | * place on this CPU. We fail to record, but we reset |
1024 | * the max trace buffer (no one writes directly to it) | 1024 | * the max trace buffer (no one writes directly to it) |
1025 | * and flag that it failed. | 1025 | * and flag that it failed. |
1026 | */ | 1026 | */ |
1027 | trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_, | 1027 | trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_, |
1028 | "Failed to swap buffers due to commit in progress\n"); | 1028 | "Failed to swap buffers due to commit in progress\n"); |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY); | 1031 | WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY); |
1032 | 1032 | ||
1033 | __update_max_tr(tr, tsk, cpu); | 1033 | __update_max_tr(tr, tsk, cpu); |
1034 | arch_spin_unlock(&ftrace_max_lock); | 1034 | arch_spin_unlock(&ftrace_max_lock); |
1035 | } | 1035 | } |
1036 | #endif /* CONFIG_TRACER_MAX_TRACE */ | 1036 | #endif /* CONFIG_TRACER_MAX_TRACE */ |
1037 | 1037 | ||
1038 | static void default_wait_pipe(struct trace_iterator *iter) | 1038 | static void default_wait_pipe(struct trace_iterator *iter) |
1039 | { | 1039 | { |
1040 | /* Iterators are static, they should be filled or empty */ | 1040 | /* Iterators are static, they should be filled or empty */ |
1041 | if (trace_buffer_iter(iter, iter->cpu_file)) | 1041 | if (trace_buffer_iter(iter, iter->cpu_file)) |
1042 | return; | 1042 | return; |
1043 | 1043 | ||
1044 | ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file); | 1044 | ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file); |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 1047 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
1048 | static int run_tracer_selftest(struct tracer *type) | 1048 | static int run_tracer_selftest(struct tracer *type) |
1049 | { | 1049 | { |
1050 | struct trace_array *tr = &global_trace; | 1050 | struct trace_array *tr = &global_trace; |
1051 | struct tracer *saved_tracer = tr->current_trace; | 1051 | struct tracer *saved_tracer = tr->current_trace; |
1052 | int ret; | 1052 | int ret; |
1053 | 1053 | ||
1054 | if (!type->selftest || tracing_selftest_disabled) | 1054 | if (!type->selftest || tracing_selftest_disabled) |
1055 | return 0; | 1055 | return 0; |
1056 | 1056 | ||
1057 | /* | 1057 | /* |
1058 | * Run a selftest on this tracer. | 1058 | * Run a selftest on this tracer. |
1059 | * Here we reset the trace buffer, and set the current | 1059 | * Here we reset the trace buffer, and set the current |
1060 | * tracer to be this tracer. The tracer can then run some | 1060 | * tracer to be this tracer. The tracer can then run some |
1061 | * internal tracing to verify that everything is in order. | 1061 | * internal tracing to verify that everything is in order. |
1062 | * If we fail, we do not register this tracer. | 1062 | * If we fail, we do not register this tracer. |
1063 | */ | 1063 | */ |
1064 | tracing_reset_online_cpus(&tr->trace_buffer); | 1064 | tracing_reset_online_cpus(&tr->trace_buffer); |
1065 | 1065 | ||
1066 | tr->current_trace = type; | 1066 | tr->current_trace = type; |
1067 | 1067 | ||
1068 | #ifdef CONFIG_TRACER_MAX_TRACE | 1068 | #ifdef CONFIG_TRACER_MAX_TRACE |
1069 | if (type->use_max_tr) { | 1069 | if (type->use_max_tr) { |
1070 | /* If we expanded the buffers, make sure the max is expanded too */ | 1070 | /* If we expanded the buffers, make sure the max is expanded too */ |
1071 | if (ring_buffer_expanded) | 1071 | if (ring_buffer_expanded) |
1072 | ring_buffer_resize(tr->max_buffer.buffer, trace_buf_size, | 1072 | ring_buffer_resize(tr->max_buffer.buffer, trace_buf_size, |
1073 | RING_BUFFER_ALL_CPUS); | 1073 | RING_BUFFER_ALL_CPUS); |
1074 | tr->allocated_snapshot = true; | 1074 | tr->allocated_snapshot = true; |
1075 | } | 1075 | } |
1076 | #endif | 1076 | #endif |
1077 | 1077 | ||
1078 | /* the test is responsible for initializing and enabling */ | 1078 | /* the test is responsible for initializing and enabling */ |
1079 | pr_info("Testing tracer %s: ", type->name); | 1079 | pr_info("Testing tracer %s: ", type->name); |
1080 | ret = type->selftest(type, tr); | 1080 | ret = type->selftest(type, tr); |
1081 | /* the test is responsible for resetting too */ | 1081 | /* the test is responsible for resetting too */ |
1082 | tr->current_trace = saved_tracer; | 1082 | tr->current_trace = saved_tracer; |
1083 | if (ret) { | 1083 | if (ret) { |
1084 | printk(KERN_CONT "FAILED!\n"); | 1084 | printk(KERN_CONT "FAILED!\n"); |
1085 | /* Add the warning after printing 'FAILED' */ | 1085 | /* Add the warning after printing 'FAILED' */ |
1086 | WARN_ON(1); | 1086 | WARN_ON(1); |
1087 | return -1; | 1087 | return -1; |
1088 | } | 1088 | } |
1089 | /* Only reset on passing, to avoid touching corrupted buffers */ | 1089 | /* Only reset on passing, to avoid touching corrupted buffers */ |
1090 | tracing_reset_online_cpus(&tr->trace_buffer); | 1090 | tracing_reset_online_cpus(&tr->trace_buffer); |
1091 | 1091 | ||
1092 | #ifdef CONFIG_TRACER_MAX_TRACE | 1092 | #ifdef CONFIG_TRACER_MAX_TRACE |
1093 | if (type->use_max_tr) { | 1093 | if (type->use_max_tr) { |
1094 | tr->allocated_snapshot = false; | 1094 | tr->allocated_snapshot = false; |
1095 | 1095 | ||
1096 | /* Shrink the max buffer again */ | 1096 | /* Shrink the max buffer again */ |
1097 | if (ring_buffer_expanded) | 1097 | if (ring_buffer_expanded) |
1098 | ring_buffer_resize(tr->max_buffer.buffer, 1, | 1098 | ring_buffer_resize(tr->max_buffer.buffer, 1, |
1099 | RING_BUFFER_ALL_CPUS); | 1099 | RING_BUFFER_ALL_CPUS); |
1100 | } | 1100 | } |
1101 | #endif | 1101 | #endif |
1102 | 1102 | ||
1103 | printk(KERN_CONT "PASSED\n"); | 1103 | printk(KERN_CONT "PASSED\n"); |
1104 | return 0; | 1104 | return 0; |
1105 | } | 1105 | } |
1106 | #else | 1106 | #else |
1107 | static inline int run_tracer_selftest(struct tracer *type) | 1107 | static inline int run_tracer_selftest(struct tracer *type) |
1108 | { | 1108 | { |
1109 | return 0; | 1109 | return 0; |
1110 | } | 1110 | } |
1111 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ | 1111 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ |
1112 | 1112 | ||
1113 | /** | 1113 | /** |
1114 | * register_tracer - register a tracer with the ftrace system. | 1114 | * register_tracer - register a tracer with the ftrace system. |
1115 | * @type - the plugin for the tracer | 1115 | * @type - the plugin for the tracer |
1116 | * | 1116 | * |
1117 | * Register a new plugin tracer. | 1117 | * Register a new plugin tracer. |
1118 | */ | 1118 | */ |
1119 | int register_tracer(struct tracer *type) | 1119 | int register_tracer(struct tracer *type) |
1120 | { | 1120 | { |
1121 | struct tracer *t; | 1121 | struct tracer *t; |
1122 | int ret = 0; | 1122 | int ret = 0; |
1123 | 1123 | ||
1124 | if (!type->name) { | 1124 | if (!type->name) { |
1125 | pr_info("Tracer must have a name\n"); | 1125 | pr_info("Tracer must have a name\n"); |
1126 | return -1; | 1126 | return -1; |
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | if (strlen(type->name) >= MAX_TRACER_SIZE) { | 1129 | if (strlen(type->name) >= MAX_TRACER_SIZE) { |
1130 | pr_info("Tracer has a name longer than %d\n", MAX_TRACER_SIZE); | 1130 | pr_info("Tracer has a name longer than %d\n", MAX_TRACER_SIZE); |
1131 | return -1; | 1131 | return -1; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | mutex_lock(&trace_types_lock); | 1134 | mutex_lock(&trace_types_lock); |
1135 | 1135 | ||
1136 | tracing_selftest_running = true; | 1136 | tracing_selftest_running = true; |
1137 | 1137 | ||
1138 | for (t = trace_types; t; t = t->next) { | 1138 | for (t = trace_types; t; t = t->next) { |
1139 | if (strcmp(type->name, t->name) == 0) { | 1139 | if (strcmp(type->name, t->name) == 0) { |
1140 | /* already found */ | 1140 | /* already found */ |
1141 | pr_info("Tracer %s already registered\n", | 1141 | pr_info("Tracer %s already registered\n", |
1142 | type->name); | 1142 | type->name); |
1143 | ret = -1; | 1143 | ret = -1; |
1144 | goto out; | 1144 | goto out; |
1145 | } | 1145 | } |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | if (!type->set_flag) | 1148 | if (!type->set_flag) |
1149 | type->set_flag = &dummy_set_flag; | 1149 | type->set_flag = &dummy_set_flag; |
1150 | if (!type->flags) | 1150 | if (!type->flags) |
1151 | type->flags = &dummy_tracer_flags; | 1151 | type->flags = &dummy_tracer_flags; |
1152 | else | 1152 | else |
1153 | if (!type->flags->opts) | 1153 | if (!type->flags->opts) |
1154 | type->flags->opts = dummy_tracer_opt; | 1154 | type->flags->opts = dummy_tracer_opt; |
1155 | if (!type->wait_pipe) | 1155 | if (!type->wait_pipe) |
1156 | type->wait_pipe = default_wait_pipe; | 1156 | type->wait_pipe = default_wait_pipe; |
1157 | 1157 | ||
1158 | ret = run_tracer_selftest(type); | 1158 | ret = run_tracer_selftest(type); |
1159 | if (ret < 0) | 1159 | if (ret < 0) |
1160 | goto out; | 1160 | goto out; |
1161 | 1161 | ||
1162 | type->next = trace_types; | 1162 | type->next = trace_types; |
1163 | trace_types = type; | 1163 | trace_types = type; |
1164 | 1164 | ||
1165 | out: | 1165 | out: |
1166 | tracing_selftest_running = false; | 1166 | tracing_selftest_running = false; |
1167 | mutex_unlock(&trace_types_lock); | 1167 | mutex_unlock(&trace_types_lock); |
1168 | 1168 | ||
1169 | if (ret || !default_bootup_tracer) | 1169 | if (ret || !default_bootup_tracer) |
1170 | goto out_unlock; | 1170 | goto out_unlock; |
1171 | 1171 | ||
1172 | if (strncmp(default_bootup_tracer, type->name, MAX_TRACER_SIZE)) | 1172 | if (strncmp(default_bootup_tracer, type->name, MAX_TRACER_SIZE)) |
1173 | goto out_unlock; | 1173 | goto out_unlock; |
1174 | 1174 | ||
1175 | printk(KERN_INFO "Starting tracer '%s'\n", type->name); | 1175 | printk(KERN_INFO "Starting tracer '%s'\n", type->name); |
1176 | /* Do we want this tracer to start on bootup? */ | 1176 | /* Do we want this tracer to start on bootup? */ |
1177 | tracing_set_tracer(type->name); | 1177 | tracing_set_tracer(type->name); |
1178 | default_bootup_tracer = NULL; | 1178 | default_bootup_tracer = NULL; |
1179 | /* disable other selftests, since this will break it. */ | 1179 | /* disable other selftests, since this will break it. */ |
1180 | tracing_selftest_disabled = true; | 1180 | tracing_selftest_disabled = true; |
1181 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 1181 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
1182 | printk(KERN_INFO "Disabling FTRACE selftests due to running tracer '%s'\n", | 1182 | printk(KERN_INFO "Disabling FTRACE selftests due to running tracer '%s'\n", |
1183 | type->name); | 1183 | type->name); |
1184 | #endif | 1184 | #endif |
1185 | 1185 | ||
1186 | out_unlock: | 1186 | out_unlock: |
1187 | return ret; | 1187 | return ret; |
1188 | } | 1188 | } |
1189 | 1189 | ||
1190 | void tracing_reset(struct trace_buffer *buf, int cpu) | 1190 | void tracing_reset(struct trace_buffer *buf, int cpu) |
1191 | { | 1191 | { |
1192 | struct ring_buffer *buffer = buf->buffer; | 1192 | struct ring_buffer *buffer = buf->buffer; |
1193 | 1193 | ||
1194 | if (!buffer) | 1194 | if (!buffer) |
1195 | return; | 1195 | return; |
1196 | 1196 | ||
1197 | ring_buffer_record_disable(buffer); | 1197 | ring_buffer_record_disable(buffer); |
1198 | 1198 | ||
1199 | /* Make sure all commits have finished */ | 1199 | /* Make sure all commits have finished */ |
1200 | synchronize_sched(); | 1200 | synchronize_sched(); |
1201 | ring_buffer_reset_cpu(buffer, cpu); | 1201 | ring_buffer_reset_cpu(buffer, cpu); |
1202 | 1202 | ||
1203 | ring_buffer_record_enable(buffer); | 1203 | ring_buffer_record_enable(buffer); |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | void tracing_reset_online_cpus(struct trace_buffer *buf) | 1206 | void tracing_reset_online_cpus(struct trace_buffer *buf) |
1207 | { | 1207 | { |
1208 | struct ring_buffer *buffer = buf->buffer; | 1208 | struct ring_buffer *buffer = buf->buffer; |
1209 | int cpu; | 1209 | int cpu; |
1210 | 1210 | ||
1211 | if (!buffer) | 1211 | if (!buffer) |
1212 | return; | 1212 | return; |
1213 | 1213 | ||
1214 | ring_buffer_record_disable(buffer); | 1214 | ring_buffer_record_disable(buffer); |
1215 | 1215 | ||
1216 | /* Make sure all commits have finished */ | 1216 | /* Make sure all commits have finished */ |
1217 | synchronize_sched(); | 1217 | synchronize_sched(); |
1218 | 1218 | ||
1219 | buf->time_start = buffer_ftrace_now(buf, buf->cpu); | 1219 | buf->time_start = buffer_ftrace_now(buf, buf->cpu); |
1220 | 1220 | ||
1221 | for_each_online_cpu(cpu) | 1221 | for_each_online_cpu(cpu) |
1222 | ring_buffer_reset_cpu(buffer, cpu); | 1222 | ring_buffer_reset_cpu(buffer, cpu); |
1223 | 1223 | ||
1224 | ring_buffer_record_enable(buffer); | 1224 | ring_buffer_record_enable(buffer); |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | /* Must have trace_types_lock held */ | 1227 | /* Must have trace_types_lock held */ |
1228 | void tracing_reset_all_online_cpus(void) | 1228 | void tracing_reset_all_online_cpus(void) |
1229 | { | 1229 | { |
1230 | struct trace_array *tr; | 1230 | struct trace_array *tr; |
1231 | 1231 | ||
1232 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 1232 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
1233 | tracing_reset_online_cpus(&tr->trace_buffer); | 1233 | tracing_reset_online_cpus(&tr->trace_buffer); |
1234 | #ifdef CONFIG_TRACER_MAX_TRACE | 1234 | #ifdef CONFIG_TRACER_MAX_TRACE |
1235 | tracing_reset_online_cpus(&tr->max_buffer); | 1235 | tracing_reset_online_cpus(&tr->max_buffer); |
1236 | #endif | 1236 | #endif |
1237 | } | 1237 | } |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | #define SAVED_CMDLINES 128 | 1240 | #define SAVED_CMDLINES 128 |
1241 | #define NO_CMDLINE_MAP UINT_MAX | 1241 | #define NO_CMDLINE_MAP UINT_MAX |
1242 | static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; | 1242 | static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; |
1243 | static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; | 1243 | static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; |
1244 | static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; | 1244 | static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; |
1245 | static int cmdline_idx; | 1245 | static int cmdline_idx; |
1246 | static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; | 1246 | static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; |
1247 | 1247 | ||
1248 | /* temporary disable recording */ | 1248 | /* temporary disable recording */ |
1249 | static atomic_t trace_record_cmdline_disabled __read_mostly; | 1249 | static atomic_t trace_record_cmdline_disabled __read_mostly; |
1250 | 1250 | ||
1251 | static void trace_init_cmdlines(void) | 1251 | static void trace_init_cmdlines(void) |
1252 | { | 1252 | { |
1253 | memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); | 1253 | memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); |
1254 | memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); | 1254 | memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); |
1255 | cmdline_idx = 0; | 1255 | cmdline_idx = 0; |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | int is_tracing_stopped(void) | 1258 | int is_tracing_stopped(void) |
1259 | { | 1259 | { |
1260 | return global_trace.stop_count; | 1260 | return global_trace.stop_count; |
1261 | } | 1261 | } |
1262 | 1262 | ||
1263 | /** | 1263 | /** |
1264 | * ftrace_off_permanent - disable all ftrace code permanently | 1264 | * ftrace_off_permanent - disable all ftrace code permanently |
1265 | * | 1265 | * |
1266 | * This should only be called when a serious anomally has | 1266 | * This should only be called when a serious anomally has |
1267 | * been detected. This will turn off the function tracing, | 1267 | * been detected. This will turn off the function tracing, |
1268 | * ring buffers, and other tracing utilites. It takes no | 1268 | * ring buffers, and other tracing utilites. It takes no |
1269 | * locks and can be called from any context. | 1269 | * locks and can be called from any context. |
1270 | */ | 1270 | */ |
1271 | void ftrace_off_permanent(void) | 1271 | void ftrace_off_permanent(void) |
1272 | { | 1272 | { |
1273 | tracing_disabled = 1; | 1273 | tracing_disabled = 1; |
1274 | ftrace_stop(); | 1274 | ftrace_stop(); |
1275 | tracing_off_permanent(); | 1275 | tracing_off_permanent(); |
1276 | } | 1276 | } |
1277 | 1277 | ||
1278 | /** | 1278 | /** |
1279 | * tracing_start - quick start of the tracer | 1279 | * tracing_start - quick start of the tracer |
1280 | * | 1280 | * |
1281 | * If tracing is enabled but was stopped by tracing_stop, | 1281 | * If tracing is enabled but was stopped by tracing_stop, |
1282 | * this will start the tracer back up. | 1282 | * this will start the tracer back up. |
1283 | */ | 1283 | */ |
1284 | void tracing_start(void) | 1284 | void tracing_start(void) |
1285 | { | 1285 | { |
1286 | struct ring_buffer *buffer; | 1286 | struct ring_buffer *buffer; |
1287 | unsigned long flags; | 1287 | unsigned long flags; |
1288 | 1288 | ||
1289 | if (tracing_disabled) | 1289 | if (tracing_disabled) |
1290 | return; | 1290 | return; |
1291 | 1291 | ||
1292 | raw_spin_lock_irqsave(&global_trace.start_lock, flags); | 1292 | raw_spin_lock_irqsave(&global_trace.start_lock, flags); |
1293 | if (--global_trace.stop_count) { | 1293 | if (--global_trace.stop_count) { |
1294 | if (global_trace.stop_count < 0) { | 1294 | if (global_trace.stop_count < 0) { |
1295 | /* Someone screwed up their debugging */ | 1295 | /* Someone screwed up their debugging */ |
1296 | WARN_ON_ONCE(1); | 1296 | WARN_ON_ONCE(1); |
1297 | global_trace.stop_count = 0; | 1297 | global_trace.stop_count = 0; |
1298 | } | 1298 | } |
1299 | goto out; | 1299 | goto out; |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | /* Prevent the buffers from switching */ | 1302 | /* Prevent the buffers from switching */ |
1303 | arch_spin_lock(&ftrace_max_lock); | 1303 | arch_spin_lock(&ftrace_max_lock); |
1304 | 1304 | ||
1305 | buffer = global_trace.trace_buffer.buffer; | 1305 | buffer = global_trace.trace_buffer.buffer; |
1306 | if (buffer) | 1306 | if (buffer) |
1307 | ring_buffer_record_enable(buffer); | 1307 | ring_buffer_record_enable(buffer); |
1308 | 1308 | ||
1309 | #ifdef CONFIG_TRACER_MAX_TRACE | 1309 | #ifdef CONFIG_TRACER_MAX_TRACE |
1310 | buffer = global_trace.max_buffer.buffer; | 1310 | buffer = global_trace.max_buffer.buffer; |
1311 | if (buffer) | 1311 | if (buffer) |
1312 | ring_buffer_record_enable(buffer); | 1312 | ring_buffer_record_enable(buffer); |
1313 | #endif | 1313 | #endif |
1314 | 1314 | ||
1315 | arch_spin_unlock(&ftrace_max_lock); | 1315 | arch_spin_unlock(&ftrace_max_lock); |
1316 | 1316 | ||
1317 | ftrace_start(); | 1317 | ftrace_start(); |
1318 | out: | 1318 | out: |
1319 | raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); | 1319 | raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); |
1320 | } | 1320 | } |
1321 | 1321 | ||
1322 | static void tracing_start_tr(struct trace_array *tr) | 1322 | static void tracing_start_tr(struct trace_array *tr) |
1323 | { | 1323 | { |
1324 | struct ring_buffer *buffer; | 1324 | struct ring_buffer *buffer; |
1325 | unsigned long flags; | 1325 | unsigned long flags; |
1326 | 1326 | ||
1327 | if (tracing_disabled) | 1327 | if (tracing_disabled) |
1328 | return; | 1328 | return; |
1329 | 1329 | ||
1330 | /* If global, we need to also start the max tracer */ | 1330 | /* If global, we need to also start the max tracer */ |
1331 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) | 1331 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) |
1332 | return tracing_start(); | 1332 | return tracing_start(); |
1333 | 1333 | ||
1334 | raw_spin_lock_irqsave(&tr->start_lock, flags); | 1334 | raw_spin_lock_irqsave(&tr->start_lock, flags); |
1335 | 1335 | ||
1336 | if (--tr->stop_count) { | 1336 | if (--tr->stop_count) { |
1337 | if (tr->stop_count < 0) { | 1337 | if (tr->stop_count < 0) { |
1338 | /* Someone screwed up their debugging */ | 1338 | /* Someone screwed up their debugging */ |
1339 | WARN_ON_ONCE(1); | 1339 | WARN_ON_ONCE(1); |
1340 | tr->stop_count = 0; | 1340 | tr->stop_count = 0; |
1341 | } | 1341 | } |
1342 | goto out; | 1342 | goto out; |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | buffer = tr->trace_buffer.buffer; | 1345 | buffer = tr->trace_buffer.buffer; |
1346 | if (buffer) | 1346 | if (buffer) |
1347 | ring_buffer_record_enable(buffer); | 1347 | ring_buffer_record_enable(buffer); |
1348 | 1348 | ||
1349 | out: | 1349 | out: |
1350 | raw_spin_unlock_irqrestore(&tr->start_lock, flags); | 1350 | raw_spin_unlock_irqrestore(&tr->start_lock, flags); |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | /** | 1353 | /** |
1354 | * tracing_stop - quick stop of the tracer | 1354 | * tracing_stop - quick stop of the tracer |
1355 | * | 1355 | * |
1356 | * Light weight way to stop tracing. Use in conjunction with | 1356 | * Light weight way to stop tracing. Use in conjunction with |
1357 | * tracing_start. | 1357 | * tracing_start. |
1358 | */ | 1358 | */ |
1359 | void tracing_stop(void) | 1359 | void tracing_stop(void) |
1360 | { | 1360 | { |
1361 | struct ring_buffer *buffer; | 1361 | struct ring_buffer *buffer; |
1362 | unsigned long flags; | 1362 | unsigned long flags; |
1363 | 1363 | ||
1364 | ftrace_stop(); | 1364 | ftrace_stop(); |
1365 | raw_spin_lock_irqsave(&global_trace.start_lock, flags); | 1365 | raw_spin_lock_irqsave(&global_trace.start_lock, flags); |
1366 | if (global_trace.stop_count++) | 1366 | if (global_trace.stop_count++) |
1367 | goto out; | 1367 | goto out; |
1368 | 1368 | ||
1369 | /* Prevent the buffers from switching */ | 1369 | /* Prevent the buffers from switching */ |
1370 | arch_spin_lock(&ftrace_max_lock); | 1370 | arch_spin_lock(&ftrace_max_lock); |
1371 | 1371 | ||
1372 | buffer = global_trace.trace_buffer.buffer; | 1372 | buffer = global_trace.trace_buffer.buffer; |
1373 | if (buffer) | 1373 | if (buffer) |
1374 | ring_buffer_record_disable(buffer); | 1374 | ring_buffer_record_disable(buffer); |
1375 | 1375 | ||
1376 | #ifdef CONFIG_TRACER_MAX_TRACE | 1376 | #ifdef CONFIG_TRACER_MAX_TRACE |
1377 | buffer = global_trace.max_buffer.buffer; | 1377 | buffer = global_trace.max_buffer.buffer; |
1378 | if (buffer) | 1378 | if (buffer) |
1379 | ring_buffer_record_disable(buffer); | 1379 | ring_buffer_record_disable(buffer); |
1380 | #endif | 1380 | #endif |
1381 | 1381 | ||
1382 | arch_spin_unlock(&ftrace_max_lock); | 1382 | arch_spin_unlock(&ftrace_max_lock); |
1383 | 1383 | ||
1384 | out: | 1384 | out: |
1385 | raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); | 1385 | raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | static void tracing_stop_tr(struct trace_array *tr) | 1388 | static void tracing_stop_tr(struct trace_array *tr) |
1389 | { | 1389 | { |
1390 | struct ring_buffer *buffer; | 1390 | struct ring_buffer *buffer; |
1391 | unsigned long flags; | 1391 | unsigned long flags; |
1392 | 1392 | ||
1393 | /* If global, we need to also stop the max tracer */ | 1393 | /* If global, we need to also stop the max tracer */ |
1394 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) | 1394 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) |
1395 | return tracing_stop(); | 1395 | return tracing_stop(); |
1396 | 1396 | ||
1397 | raw_spin_lock_irqsave(&tr->start_lock, flags); | 1397 | raw_spin_lock_irqsave(&tr->start_lock, flags); |
1398 | if (tr->stop_count++) | 1398 | if (tr->stop_count++) |
1399 | goto out; | 1399 | goto out; |
1400 | 1400 | ||
1401 | buffer = tr->trace_buffer.buffer; | 1401 | buffer = tr->trace_buffer.buffer; |
1402 | if (buffer) | 1402 | if (buffer) |
1403 | ring_buffer_record_disable(buffer); | 1403 | ring_buffer_record_disable(buffer); |
1404 | 1404 | ||
1405 | out: | 1405 | out: |
1406 | raw_spin_unlock_irqrestore(&tr->start_lock, flags); | 1406 | raw_spin_unlock_irqrestore(&tr->start_lock, flags); |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | void trace_stop_cmdline_recording(void); | 1409 | void trace_stop_cmdline_recording(void); |
1410 | 1410 | ||
1411 | static void trace_save_cmdline(struct task_struct *tsk) | 1411 | static void trace_save_cmdline(struct task_struct *tsk) |
1412 | { | 1412 | { |
1413 | unsigned pid, idx; | 1413 | unsigned pid, idx; |
1414 | 1414 | ||
1415 | if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT)) | 1415 | if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT)) |
1416 | return; | 1416 | return; |
1417 | 1417 | ||
1418 | /* | 1418 | /* |
1419 | * It's not the end of the world if we don't get | 1419 | * It's not the end of the world if we don't get |
1420 | * the lock, but we also don't want to spin | 1420 | * the lock, but we also don't want to spin |
1421 | * nor do we want to disable interrupts, | 1421 | * nor do we want to disable interrupts, |
1422 | * so if we miss here, then better luck next time. | 1422 | * so if we miss here, then better luck next time. |
1423 | */ | 1423 | */ |
1424 | if (!arch_spin_trylock(&trace_cmdline_lock)) | 1424 | if (!arch_spin_trylock(&trace_cmdline_lock)) |
1425 | return; | 1425 | return; |
1426 | 1426 | ||
1427 | idx = map_pid_to_cmdline[tsk->pid]; | 1427 | idx = map_pid_to_cmdline[tsk->pid]; |
1428 | if (idx == NO_CMDLINE_MAP) { | 1428 | if (idx == NO_CMDLINE_MAP) { |
1429 | idx = (cmdline_idx + 1) % SAVED_CMDLINES; | 1429 | idx = (cmdline_idx + 1) % SAVED_CMDLINES; |
1430 | 1430 | ||
1431 | /* | 1431 | /* |
1432 | * Check whether the cmdline buffer at idx has a pid | 1432 | * Check whether the cmdline buffer at idx has a pid |
1433 | * mapped. We are going to overwrite that entry so we | 1433 | * mapped. We are going to overwrite that entry so we |
1434 | * need to clear the map_pid_to_cmdline. Otherwise we | 1434 | * need to clear the map_pid_to_cmdline. Otherwise we |
1435 | * would read the new comm for the old pid. | 1435 | * would read the new comm for the old pid. |
1436 | */ | 1436 | */ |
1437 | pid = map_cmdline_to_pid[idx]; | 1437 | pid = map_cmdline_to_pid[idx]; |
1438 | if (pid != NO_CMDLINE_MAP) | 1438 | if (pid != NO_CMDLINE_MAP) |
1439 | map_pid_to_cmdline[pid] = NO_CMDLINE_MAP; | 1439 | map_pid_to_cmdline[pid] = NO_CMDLINE_MAP; |
1440 | 1440 | ||
1441 | map_cmdline_to_pid[idx] = tsk->pid; | 1441 | map_cmdline_to_pid[idx] = tsk->pid; |
1442 | map_pid_to_cmdline[tsk->pid] = idx; | 1442 | map_pid_to_cmdline[tsk->pid] = idx; |
1443 | 1443 | ||
1444 | cmdline_idx = idx; | 1444 | cmdline_idx = idx; |
1445 | } | 1445 | } |
1446 | 1446 | ||
1447 | memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN); | 1447 | memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN); |
1448 | 1448 | ||
1449 | arch_spin_unlock(&trace_cmdline_lock); | 1449 | arch_spin_unlock(&trace_cmdline_lock); |
1450 | } | 1450 | } |
1451 | 1451 | ||
1452 | void trace_find_cmdline(int pid, char comm[]) | 1452 | void trace_find_cmdline(int pid, char comm[]) |
1453 | { | 1453 | { |
1454 | unsigned map; | 1454 | unsigned map; |
1455 | 1455 | ||
1456 | if (!pid) { | 1456 | if (!pid) { |
1457 | strcpy(comm, "<idle>"); | 1457 | strcpy(comm, "<idle>"); |
1458 | return; | 1458 | return; |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | if (WARN_ON_ONCE(pid < 0)) { | 1461 | if (WARN_ON_ONCE(pid < 0)) { |
1462 | strcpy(comm, "<XXX>"); | 1462 | strcpy(comm, "<XXX>"); |
1463 | return; | 1463 | return; |
1464 | } | 1464 | } |
1465 | 1465 | ||
1466 | if (pid > PID_MAX_DEFAULT) { | 1466 | if (pid > PID_MAX_DEFAULT) { |
1467 | strcpy(comm, "<...>"); | 1467 | strcpy(comm, "<...>"); |
1468 | return; | 1468 | return; |
1469 | } | 1469 | } |
1470 | 1470 | ||
1471 | preempt_disable(); | 1471 | preempt_disable(); |
1472 | arch_spin_lock(&trace_cmdline_lock); | 1472 | arch_spin_lock(&trace_cmdline_lock); |
1473 | map = map_pid_to_cmdline[pid]; | 1473 | map = map_pid_to_cmdline[pid]; |
1474 | if (map != NO_CMDLINE_MAP) | 1474 | if (map != NO_CMDLINE_MAP) |
1475 | strcpy(comm, saved_cmdlines[map]); | 1475 | strcpy(comm, saved_cmdlines[map]); |
1476 | else | 1476 | else |
1477 | strcpy(comm, "<...>"); | 1477 | strcpy(comm, "<...>"); |
1478 | 1478 | ||
1479 | arch_spin_unlock(&trace_cmdline_lock); | 1479 | arch_spin_unlock(&trace_cmdline_lock); |
1480 | preempt_enable(); | 1480 | preempt_enable(); |
1481 | } | 1481 | } |
1482 | 1482 | ||
1483 | void tracing_record_cmdline(struct task_struct *tsk) | 1483 | void tracing_record_cmdline(struct task_struct *tsk) |
1484 | { | 1484 | { |
1485 | if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on()) | 1485 | if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on()) |
1486 | return; | 1486 | return; |
1487 | 1487 | ||
1488 | if (!__this_cpu_read(trace_cmdline_save)) | 1488 | if (!__this_cpu_read(trace_cmdline_save)) |
1489 | return; | 1489 | return; |
1490 | 1490 | ||
1491 | __this_cpu_write(trace_cmdline_save, false); | 1491 | __this_cpu_write(trace_cmdline_save, false); |
1492 | 1492 | ||
1493 | trace_save_cmdline(tsk); | 1493 | trace_save_cmdline(tsk); |
1494 | } | 1494 | } |
1495 | 1495 | ||
1496 | void | 1496 | void |
1497 | tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, | 1497 | tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, |
1498 | int pc) | 1498 | int pc) |
1499 | { | 1499 | { |
1500 | struct task_struct *tsk = current; | 1500 | struct task_struct *tsk = current; |
1501 | 1501 | ||
1502 | entry->preempt_count = pc & 0xff; | 1502 | entry->preempt_count = pc & 0xff; |
1503 | entry->pid = (tsk) ? tsk->pid : 0; | 1503 | entry->pid = (tsk) ? tsk->pid : 0; |
1504 | entry->flags = | 1504 | entry->flags = |
1505 | #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT | 1505 | #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT |
1506 | (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | | 1506 | (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | |
1507 | #else | 1507 | #else |
1508 | TRACE_FLAG_IRQS_NOSUPPORT | | 1508 | TRACE_FLAG_IRQS_NOSUPPORT | |
1509 | #endif | 1509 | #endif |
1510 | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | | 1510 | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | |
1511 | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | | 1511 | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | |
1512 | (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); | 1512 | (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); |
1513 | } | 1513 | } |
1514 | EXPORT_SYMBOL_GPL(tracing_generic_entry_update); | 1514 | EXPORT_SYMBOL_GPL(tracing_generic_entry_update); |
1515 | 1515 | ||
1516 | struct ring_buffer_event * | 1516 | struct ring_buffer_event * |
1517 | trace_buffer_lock_reserve(struct ring_buffer *buffer, | 1517 | trace_buffer_lock_reserve(struct ring_buffer *buffer, |
1518 | int type, | 1518 | int type, |
1519 | unsigned long len, | 1519 | unsigned long len, |
1520 | unsigned long flags, int pc) | 1520 | unsigned long flags, int pc) |
1521 | { | 1521 | { |
1522 | struct ring_buffer_event *event; | 1522 | struct ring_buffer_event *event; |
1523 | 1523 | ||
1524 | event = ring_buffer_lock_reserve(buffer, len); | 1524 | event = ring_buffer_lock_reserve(buffer, len); |
1525 | if (event != NULL) { | 1525 | if (event != NULL) { |
1526 | struct trace_entry *ent = ring_buffer_event_data(event); | 1526 | struct trace_entry *ent = ring_buffer_event_data(event); |
1527 | 1527 | ||
1528 | tracing_generic_entry_update(ent, flags, pc); | 1528 | tracing_generic_entry_update(ent, flags, pc); |
1529 | ent->type = type; | 1529 | ent->type = type; |
1530 | } | 1530 | } |
1531 | 1531 | ||
1532 | return event; | 1532 | return event; |
1533 | } | 1533 | } |
1534 | 1534 | ||
1535 | void | 1535 | void |
1536 | __buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event) | 1536 | __buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event) |
1537 | { | 1537 | { |
1538 | __this_cpu_write(trace_cmdline_save, true); | 1538 | __this_cpu_write(trace_cmdline_save, true); |
1539 | ring_buffer_unlock_commit(buffer, event); | 1539 | ring_buffer_unlock_commit(buffer, event); |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | static inline void | 1542 | static inline void |
1543 | __trace_buffer_unlock_commit(struct ring_buffer *buffer, | 1543 | __trace_buffer_unlock_commit(struct ring_buffer *buffer, |
1544 | struct ring_buffer_event *event, | 1544 | struct ring_buffer_event *event, |
1545 | unsigned long flags, int pc) | 1545 | unsigned long flags, int pc) |
1546 | { | 1546 | { |
1547 | __buffer_unlock_commit(buffer, event); | 1547 | __buffer_unlock_commit(buffer, event); |
1548 | 1548 | ||
1549 | ftrace_trace_stack(buffer, flags, 6, pc); | 1549 | ftrace_trace_stack(buffer, flags, 6, pc); |
1550 | ftrace_trace_userstack(buffer, flags, pc); | 1550 | ftrace_trace_userstack(buffer, flags, pc); |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | void trace_buffer_unlock_commit(struct ring_buffer *buffer, | 1553 | void trace_buffer_unlock_commit(struct ring_buffer *buffer, |
1554 | struct ring_buffer_event *event, | 1554 | struct ring_buffer_event *event, |
1555 | unsigned long flags, int pc) | 1555 | unsigned long flags, int pc) |
1556 | { | 1556 | { |
1557 | __trace_buffer_unlock_commit(buffer, event, flags, pc); | 1557 | __trace_buffer_unlock_commit(buffer, event, flags, pc); |
1558 | } | 1558 | } |
1559 | EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit); | 1559 | EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit); |
1560 | 1560 | ||
1561 | struct ring_buffer_event * | 1561 | struct ring_buffer_event * |
1562 | trace_event_buffer_lock_reserve(struct ring_buffer **current_rb, | 1562 | trace_event_buffer_lock_reserve(struct ring_buffer **current_rb, |
1563 | struct ftrace_event_file *ftrace_file, | 1563 | struct ftrace_event_file *ftrace_file, |
1564 | int type, unsigned long len, | 1564 | int type, unsigned long len, |
1565 | unsigned long flags, int pc) | 1565 | unsigned long flags, int pc) |
1566 | { | 1566 | { |
1567 | *current_rb = ftrace_file->tr->trace_buffer.buffer; | 1567 | *current_rb = ftrace_file->tr->trace_buffer.buffer; |
1568 | return trace_buffer_lock_reserve(*current_rb, | 1568 | return trace_buffer_lock_reserve(*current_rb, |
1569 | type, len, flags, pc); | 1569 | type, len, flags, pc); |
1570 | } | 1570 | } |
1571 | EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve); | 1571 | EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve); |
1572 | 1572 | ||
1573 | struct ring_buffer_event * | 1573 | struct ring_buffer_event * |
1574 | trace_current_buffer_lock_reserve(struct ring_buffer **current_rb, | 1574 | trace_current_buffer_lock_reserve(struct ring_buffer **current_rb, |
1575 | int type, unsigned long len, | 1575 | int type, unsigned long len, |
1576 | unsigned long flags, int pc) | 1576 | unsigned long flags, int pc) |
1577 | { | 1577 | { |
1578 | *current_rb = global_trace.trace_buffer.buffer; | 1578 | *current_rb = global_trace.trace_buffer.buffer; |
1579 | return trace_buffer_lock_reserve(*current_rb, | 1579 | return trace_buffer_lock_reserve(*current_rb, |
1580 | type, len, flags, pc); | 1580 | type, len, flags, pc); |
1581 | } | 1581 | } |
1582 | EXPORT_SYMBOL_GPL(trace_current_buffer_lock_reserve); | 1582 | EXPORT_SYMBOL_GPL(trace_current_buffer_lock_reserve); |
1583 | 1583 | ||
1584 | void trace_current_buffer_unlock_commit(struct ring_buffer *buffer, | 1584 | void trace_current_buffer_unlock_commit(struct ring_buffer *buffer, |
1585 | struct ring_buffer_event *event, | 1585 | struct ring_buffer_event *event, |
1586 | unsigned long flags, int pc) | 1586 | unsigned long flags, int pc) |
1587 | { | 1587 | { |
1588 | __trace_buffer_unlock_commit(buffer, event, flags, pc); | 1588 | __trace_buffer_unlock_commit(buffer, event, flags, pc); |
1589 | } | 1589 | } |
1590 | EXPORT_SYMBOL_GPL(trace_current_buffer_unlock_commit); | 1590 | EXPORT_SYMBOL_GPL(trace_current_buffer_unlock_commit); |
1591 | 1591 | ||
1592 | void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer, | 1592 | void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer, |
1593 | struct ring_buffer_event *event, | 1593 | struct ring_buffer_event *event, |
1594 | unsigned long flags, int pc, | 1594 | unsigned long flags, int pc, |
1595 | struct pt_regs *regs) | 1595 | struct pt_regs *regs) |
1596 | { | 1596 | { |
1597 | __buffer_unlock_commit(buffer, event); | 1597 | __buffer_unlock_commit(buffer, event); |
1598 | 1598 | ||
1599 | ftrace_trace_stack_regs(buffer, flags, 0, pc, regs); | 1599 | ftrace_trace_stack_regs(buffer, flags, 0, pc, regs); |
1600 | ftrace_trace_userstack(buffer, flags, pc); | 1600 | ftrace_trace_userstack(buffer, flags, pc); |
1601 | } | 1601 | } |
1602 | EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs); | 1602 | EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs); |
1603 | 1603 | ||
1604 | void trace_current_buffer_discard_commit(struct ring_buffer *buffer, | 1604 | void trace_current_buffer_discard_commit(struct ring_buffer *buffer, |
1605 | struct ring_buffer_event *event) | 1605 | struct ring_buffer_event *event) |
1606 | { | 1606 | { |
1607 | ring_buffer_discard_commit(buffer, event); | 1607 | ring_buffer_discard_commit(buffer, event); |
1608 | } | 1608 | } |
1609 | EXPORT_SYMBOL_GPL(trace_current_buffer_discard_commit); | 1609 | EXPORT_SYMBOL_GPL(trace_current_buffer_discard_commit); |
1610 | 1610 | ||
1611 | void | 1611 | void |
1612 | trace_function(struct trace_array *tr, | 1612 | trace_function(struct trace_array *tr, |
1613 | unsigned long ip, unsigned long parent_ip, unsigned long flags, | 1613 | unsigned long ip, unsigned long parent_ip, unsigned long flags, |
1614 | int pc) | 1614 | int pc) |
1615 | { | 1615 | { |
1616 | struct ftrace_event_call *call = &event_function; | 1616 | struct ftrace_event_call *call = &event_function; |
1617 | struct ring_buffer *buffer = tr->trace_buffer.buffer; | 1617 | struct ring_buffer *buffer = tr->trace_buffer.buffer; |
1618 | struct ring_buffer_event *event; | 1618 | struct ring_buffer_event *event; |
1619 | struct ftrace_entry *entry; | 1619 | struct ftrace_entry *entry; |
1620 | 1620 | ||
1621 | /* If we are reading the ring buffer, don't trace */ | 1621 | /* If we are reading the ring buffer, don't trace */ |
1622 | if (unlikely(__this_cpu_read(ftrace_cpu_disabled))) | 1622 | if (unlikely(__this_cpu_read(ftrace_cpu_disabled))) |
1623 | return; | 1623 | return; |
1624 | 1624 | ||
1625 | event = trace_buffer_lock_reserve(buffer, TRACE_FN, sizeof(*entry), | 1625 | event = trace_buffer_lock_reserve(buffer, TRACE_FN, sizeof(*entry), |
1626 | flags, pc); | 1626 | flags, pc); |
1627 | if (!event) | 1627 | if (!event) |
1628 | return; | 1628 | return; |
1629 | entry = ring_buffer_event_data(event); | 1629 | entry = ring_buffer_event_data(event); |
1630 | entry->ip = ip; | 1630 | entry->ip = ip; |
1631 | entry->parent_ip = parent_ip; | 1631 | entry->parent_ip = parent_ip; |
1632 | 1632 | ||
1633 | if (!filter_check_discard(call, entry, buffer, event)) | 1633 | if (!filter_check_discard(call, entry, buffer, event)) |
1634 | __buffer_unlock_commit(buffer, event); | 1634 | __buffer_unlock_commit(buffer, event); |
1635 | } | 1635 | } |
1636 | 1636 | ||
1637 | #ifdef CONFIG_STACKTRACE | 1637 | #ifdef CONFIG_STACKTRACE |
1638 | 1638 | ||
1639 | #define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long)) | 1639 | #define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long)) |
1640 | struct ftrace_stack { | 1640 | struct ftrace_stack { |
1641 | unsigned long calls[FTRACE_STACK_MAX_ENTRIES]; | 1641 | unsigned long calls[FTRACE_STACK_MAX_ENTRIES]; |
1642 | }; | 1642 | }; |
1643 | 1643 | ||
1644 | static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack); | 1644 | static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack); |
1645 | static DEFINE_PER_CPU(int, ftrace_stack_reserve); | 1645 | static DEFINE_PER_CPU(int, ftrace_stack_reserve); |
1646 | 1646 | ||
1647 | static void __ftrace_trace_stack(struct ring_buffer *buffer, | 1647 | static void __ftrace_trace_stack(struct ring_buffer *buffer, |
1648 | unsigned long flags, | 1648 | unsigned long flags, |
1649 | int skip, int pc, struct pt_regs *regs) | 1649 | int skip, int pc, struct pt_regs *regs) |
1650 | { | 1650 | { |
1651 | struct ftrace_event_call *call = &event_kernel_stack; | 1651 | struct ftrace_event_call *call = &event_kernel_stack; |
1652 | struct ring_buffer_event *event; | 1652 | struct ring_buffer_event *event; |
1653 | struct stack_entry *entry; | 1653 | struct stack_entry *entry; |
1654 | struct stack_trace trace; | 1654 | struct stack_trace trace; |
1655 | int use_stack; | 1655 | int use_stack; |
1656 | int size = FTRACE_STACK_ENTRIES; | 1656 | int size = FTRACE_STACK_ENTRIES; |
1657 | 1657 | ||
1658 | trace.nr_entries = 0; | 1658 | trace.nr_entries = 0; |
1659 | trace.skip = skip; | 1659 | trace.skip = skip; |
1660 | 1660 | ||
1661 | /* | 1661 | /* |
1662 | * Since events can happen in NMIs there's no safe way to | 1662 | * Since events can happen in NMIs there's no safe way to |
1663 | * use the per cpu ftrace_stacks. We reserve it and if an interrupt | 1663 | * use the per cpu ftrace_stacks. We reserve it and if an interrupt |
1664 | * or NMI comes in, it will just have to use the default | 1664 | * or NMI comes in, it will just have to use the default |
1665 | * FTRACE_STACK_SIZE. | 1665 | * FTRACE_STACK_SIZE. |
1666 | */ | 1666 | */ |
1667 | preempt_disable_notrace(); | 1667 | preempt_disable_notrace(); |
1668 | 1668 | ||
1669 | use_stack = __this_cpu_inc_return(ftrace_stack_reserve); | 1669 | use_stack = __this_cpu_inc_return(ftrace_stack_reserve); |
1670 | /* | 1670 | /* |
1671 | * We don't need any atomic variables, just a barrier. | 1671 | * We don't need any atomic variables, just a barrier. |
1672 | * If an interrupt comes in, we don't care, because it would | 1672 | * If an interrupt comes in, we don't care, because it would |
1673 | * have exited and put the counter back to what we want. | 1673 | * have exited and put the counter back to what we want. |
1674 | * We just need a barrier to keep gcc from moving things | 1674 | * We just need a barrier to keep gcc from moving things |
1675 | * around. | 1675 | * around. |
1676 | */ | 1676 | */ |
1677 | barrier(); | 1677 | barrier(); |
1678 | if (use_stack == 1) { | 1678 | if (use_stack == 1) { |
1679 | trace.entries = &__get_cpu_var(ftrace_stack).calls[0]; | 1679 | trace.entries = &__get_cpu_var(ftrace_stack).calls[0]; |
1680 | trace.max_entries = FTRACE_STACK_MAX_ENTRIES; | 1680 | trace.max_entries = FTRACE_STACK_MAX_ENTRIES; |
1681 | 1681 | ||
1682 | if (regs) | 1682 | if (regs) |
1683 | save_stack_trace_regs(regs, &trace); | 1683 | save_stack_trace_regs(regs, &trace); |
1684 | else | 1684 | else |
1685 | save_stack_trace(&trace); | 1685 | save_stack_trace(&trace); |
1686 | 1686 | ||
1687 | if (trace.nr_entries > size) | 1687 | if (trace.nr_entries > size) |
1688 | size = trace.nr_entries; | 1688 | size = trace.nr_entries; |
1689 | } else | 1689 | } else |
1690 | /* From now on, use_stack is a boolean */ | 1690 | /* From now on, use_stack is a boolean */ |
1691 | use_stack = 0; | 1691 | use_stack = 0; |
1692 | 1692 | ||
1693 | size *= sizeof(unsigned long); | 1693 | size *= sizeof(unsigned long); |
1694 | 1694 | ||
1695 | event = trace_buffer_lock_reserve(buffer, TRACE_STACK, | 1695 | event = trace_buffer_lock_reserve(buffer, TRACE_STACK, |
1696 | sizeof(*entry) + size, flags, pc); | 1696 | sizeof(*entry) + size, flags, pc); |
1697 | if (!event) | 1697 | if (!event) |
1698 | goto out; | 1698 | goto out; |
1699 | entry = ring_buffer_event_data(event); | 1699 | entry = ring_buffer_event_data(event); |
1700 | 1700 | ||
1701 | memset(&entry->caller, 0, size); | 1701 | memset(&entry->caller, 0, size); |
1702 | 1702 | ||
1703 | if (use_stack) | 1703 | if (use_stack) |
1704 | memcpy(&entry->caller, trace.entries, | 1704 | memcpy(&entry->caller, trace.entries, |
1705 | trace.nr_entries * sizeof(unsigned long)); | 1705 | trace.nr_entries * sizeof(unsigned long)); |
1706 | else { | 1706 | else { |
1707 | trace.max_entries = FTRACE_STACK_ENTRIES; | 1707 | trace.max_entries = FTRACE_STACK_ENTRIES; |
1708 | trace.entries = entry->caller; | 1708 | trace.entries = entry->caller; |
1709 | if (regs) | 1709 | if (regs) |
1710 | save_stack_trace_regs(regs, &trace); | 1710 | save_stack_trace_regs(regs, &trace); |
1711 | else | 1711 | else |
1712 | save_stack_trace(&trace); | 1712 | save_stack_trace(&trace); |
1713 | } | 1713 | } |
1714 | 1714 | ||
1715 | entry->size = trace.nr_entries; | 1715 | entry->size = trace.nr_entries; |
1716 | 1716 | ||
1717 | if (!filter_check_discard(call, entry, buffer, event)) | 1717 | if (!filter_check_discard(call, entry, buffer, event)) |
1718 | __buffer_unlock_commit(buffer, event); | 1718 | __buffer_unlock_commit(buffer, event); |
1719 | 1719 | ||
1720 | out: | 1720 | out: |
1721 | /* Again, don't let gcc optimize things here */ | 1721 | /* Again, don't let gcc optimize things here */ |
1722 | barrier(); | 1722 | barrier(); |
1723 | __this_cpu_dec(ftrace_stack_reserve); | 1723 | __this_cpu_dec(ftrace_stack_reserve); |
1724 | preempt_enable_notrace(); | 1724 | preempt_enable_notrace(); |
1725 | 1725 | ||
1726 | } | 1726 | } |
1727 | 1727 | ||
1728 | void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags, | 1728 | void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags, |
1729 | int skip, int pc, struct pt_regs *regs) | 1729 | int skip, int pc, struct pt_regs *regs) |
1730 | { | 1730 | { |
1731 | if (!(trace_flags & TRACE_ITER_STACKTRACE)) | 1731 | if (!(trace_flags & TRACE_ITER_STACKTRACE)) |
1732 | return; | 1732 | return; |
1733 | 1733 | ||
1734 | __ftrace_trace_stack(buffer, flags, skip, pc, regs); | 1734 | __ftrace_trace_stack(buffer, flags, skip, pc, regs); |
1735 | } | 1735 | } |
1736 | 1736 | ||
1737 | void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags, | 1737 | void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags, |
1738 | int skip, int pc) | 1738 | int skip, int pc) |
1739 | { | 1739 | { |
1740 | if (!(trace_flags & TRACE_ITER_STACKTRACE)) | 1740 | if (!(trace_flags & TRACE_ITER_STACKTRACE)) |
1741 | return; | 1741 | return; |
1742 | 1742 | ||
1743 | __ftrace_trace_stack(buffer, flags, skip, pc, NULL); | 1743 | __ftrace_trace_stack(buffer, flags, skip, pc, NULL); |
1744 | } | 1744 | } |
1745 | 1745 | ||
1746 | void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, | 1746 | void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, |
1747 | int pc) | 1747 | int pc) |
1748 | { | 1748 | { |
1749 | __ftrace_trace_stack(tr->trace_buffer.buffer, flags, skip, pc, NULL); | 1749 | __ftrace_trace_stack(tr->trace_buffer.buffer, flags, skip, pc, NULL); |
1750 | } | 1750 | } |
1751 | 1751 | ||
1752 | /** | 1752 | /** |
1753 | * trace_dump_stack - record a stack back trace in the trace buffer | 1753 | * trace_dump_stack - record a stack back trace in the trace buffer |
1754 | * @skip: Number of functions to skip (helper handlers) | 1754 | * @skip: Number of functions to skip (helper handlers) |
1755 | */ | 1755 | */ |
1756 | void trace_dump_stack(int skip) | 1756 | void trace_dump_stack(int skip) |
1757 | { | 1757 | { |
1758 | unsigned long flags; | 1758 | unsigned long flags; |
1759 | 1759 | ||
1760 | if (tracing_disabled || tracing_selftest_running) | 1760 | if (tracing_disabled || tracing_selftest_running) |
1761 | return; | 1761 | return; |
1762 | 1762 | ||
1763 | local_save_flags(flags); | 1763 | local_save_flags(flags); |
1764 | 1764 | ||
1765 | /* | 1765 | /* |
1766 | * Skip 3 more, seems to get us at the caller of | 1766 | * Skip 3 more, seems to get us at the caller of |
1767 | * this function. | 1767 | * this function. |
1768 | */ | 1768 | */ |
1769 | skip += 3; | 1769 | skip += 3; |
1770 | __ftrace_trace_stack(global_trace.trace_buffer.buffer, | 1770 | __ftrace_trace_stack(global_trace.trace_buffer.buffer, |
1771 | flags, skip, preempt_count(), NULL); | 1771 | flags, skip, preempt_count(), NULL); |
1772 | } | 1772 | } |
1773 | 1773 | ||
1774 | static DEFINE_PER_CPU(int, user_stack_count); | 1774 | static DEFINE_PER_CPU(int, user_stack_count); |
1775 | 1775 | ||
1776 | void | 1776 | void |
1777 | ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) | 1777 | ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) |
1778 | { | 1778 | { |
1779 | struct ftrace_event_call *call = &event_user_stack; | 1779 | struct ftrace_event_call *call = &event_user_stack; |
1780 | struct ring_buffer_event *event; | 1780 | struct ring_buffer_event *event; |
1781 | struct userstack_entry *entry; | 1781 | struct userstack_entry *entry; |
1782 | struct stack_trace trace; | 1782 | struct stack_trace trace; |
1783 | 1783 | ||
1784 | if (!(trace_flags & TRACE_ITER_USERSTACKTRACE)) | 1784 | if (!(trace_flags & TRACE_ITER_USERSTACKTRACE)) |
1785 | return; | 1785 | return; |
1786 | 1786 | ||
1787 | /* | 1787 | /* |
1788 | * NMIs can not handle page faults, even with fix ups. | 1788 | * NMIs can not handle page faults, even with fix ups. |
1789 | * The save user stack can (and often does) fault. | 1789 | * The save user stack can (and often does) fault. |
1790 | */ | 1790 | */ |
1791 | if (unlikely(in_nmi())) | 1791 | if (unlikely(in_nmi())) |
1792 | return; | 1792 | return; |
1793 | 1793 | ||
1794 | /* | 1794 | /* |
1795 | * prevent recursion, since the user stack tracing may | 1795 | * prevent recursion, since the user stack tracing may |
1796 | * trigger other kernel events. | 1796 | * trigger other kernel events. |
1797 | */ | 1797 | */ |
1798 | preempt_disable(); | 1798 | preempt_disable(); |
1799 | if (__this_cpu_read(user_stack_count)) | 1799 | if (__this_cpu_read(user_stack_count)) |
1800 | goto out; | 1800 | goto out; |
1801 | 1801 | ||
1802 | __this_cpu_inc(user_stack_count); | 1802 | __this_cpu_inc(user_stack_count); |
1803 | 1803 | ||
1804 | event = trace_buffer_lock_reserve(buffer, TRACE_USER_STACK, | 1804 | event = trace_buffer_lock_reserve(buffer, TRACE_USER_STACK, |
1805 | sizeof(*entry), flags, pc); | 1805 | sizeof(*entry), flags, pc); |
1806 | if (!event) | 1806 | if (!event) |
1807 | goto out_drop_count; | 1807 | goto out_drop_count; |
1808 | entry = ring_buffer_event_data(event); | 1808 | entry = ring_buffer_event_data(event); |
1809 | 1809 | ||
1810 | entry->tgid = current->tgid; | 1810 | entry->tgid = current->tgid; |
1811 | memset(&entry->caller, 0, sizeof(entry->caller)); | 1811 | memset(&entry->caller, 0, sizeof(entry->caller)); |
1812 | 1812 | ||
1813 | trace.nr_entries = 0; | 1813 | trace.nr_entries = 0; |
1814 | trace.max_entries = FTRACE_STACK_ENTRIES; | 1814 | trace.max_entries = FTRACE_STACK_ENTRIES; |
1815 | trace.skip = 0; | 1815 | trace.skip = 0; |
1816 | trace.entries = entry->caller; | 1816 | trace.entries = entry->caller; |
1817 | 1817 | ||
1818 | save_stack_trace_user(&trace); | 1818 | save_stack_trace_user(&trace); |
1819 | if (!filter_check_discard(call, entry, buffer, event)) | 1819 | if (!filter_check_discard(call, entry, buffer, event)) |
1820 | __buffer_unlock_commit(buffer, event); | 1820 | __buffer_unlock_commit(buffer, event); |
1821 | 1821 | ||
1822 | out_drop_count: | 1822 | out_drop_count: |
1823 | __this_cpu_dec(user_stack_count); | 1823 | __this_cpu_dec(user_stack_count); |
1824 | out: | 1824 | out: |
1825 | preempt_enable(); | 1825 | preempt_enable(); |
1826 | } | 1826 | } |
1827 | 1827 | ||
1828 | #ifdef UNUSED | 1828 | #ifdef UNUSED |
1829 | static void __trace_userstack(struct trace_array *tr, unsigned long flags) | 1829 | static void __trace_userstack(struct trace_array *tr, unsigned long flags) |
1830 | { | 1830 | { |
1831 | ftrace_trace_userstack(tr, flags, preempt_count()); | 1831 | ftrace_trace_userstack(tr, flags, preempt_count()); |
1832 | } | 1832 | } |
1833 | #endif /* UNUSED */ | 1833 | #endif /* UNUSED */ |
1834 | 1834 | ||
1835 | #endif /* CONFIG_STACKTRACE */ | 1835 | #endif /* CONFIG_STACKTRACE */ |
1836 | 1836 | ||
1837 | /* created for use with alloc_percpu */ | 1837 | /* created for use with alloc_percpu */ |
1838 | struct trace_buffer_struct { | 1838 | struct trace_buffer_struct { |
1839 | char buffer[TRACE_BUF_SIZE]; | 1839 | char buffer[TRACE_BUF_SIZE]; |
1840 | }; | 1840 | }; |
1841 | 1841 | ||
1842 | static struct trace_buffer_struct *trace_percpu_buffer; | 1842 | static struct trace_buffer_struct *trace_percpu_buffer; |
1843 | static struct trace_buffer_struct *trace_percpu_sirq_buffer; | 1843 | static struct trace_buffer_struct *trace_percpu_sirq_buffer; |
1844 | static struct trace_buffer_struct *trace_percpu_irq_buffer; | 1844 | static struct trace_buffer_struct *trace_percpu_irq_buffer; |
1845 | static struct trace_buffer_struct *trace_percpu_nmi_buffer; | 1845 | static struct trace_buffer_struct *trace_percpu_nmi_buffer; |
1846 | 1846 | ||
1847 | /* | 1847 | /* |
1848 | * The buffer used is dependent on the context. There is a per cpu | 1848 | * The buffer used is dependent on the context. There is a per cpu |
1849 | * buffer for normal context, softirq contex, hard irq context and | 1849 | * buffer for normal context, softirq contex, hard irq context and |
1850 | * for NMI context. Thise allows for lockless recording. | 1850 | * for NMI context. Thise allows for lockless recording. |
1851 | * | 1851 | * |
1852 | * Note, if the buffers failed to be allocated, then this returns NULL | 1852 | * Note, if the buffers failed to be allocated, then this returns NULL |
1853 | */ | 1853 | */ |
1854 | static char *get_trace_buf(void) | 1854 | static char *get_trace_buf(void) |
1855 | { | 1855 | { |
1856 | struct trace_buffer_struct *percpu_buffer; | 1856 | struct trace_buffer_struct *percpu_buffer; |
1857 | 1857 | ||
1858 | /* | 1858 | /* |
1859 | * If we have allocated per cpu buffers, then we do not | 1859 | * If we have allocated per cpu buffers, then we do not |
1860 | * need to do any locking. | 1860 | * need to do any locking. |
1861 | */ | 1861 | */ |
1862 | if (in_nmi()) | 1862 | if (in_nmi()) |
1863 | percpu_buffer = trace_percpu_nmi_buffer; | 1863 | percpu_buffer = trace_percpu_nmi_buffer; |
1864 | else if (in_irq()) | 1864 | else if (in_irq()) |
1865 | percpu_buffer = trace_percpu_irq_buffer; | 1865 | percpu_buffer = trace_percpu_irq_buffer; |
1866 | else if (in_softirq()) | 1866 | else if (in_softirq()) |
1867 | percpu_buffer = trace_percpu_sirq_buffer; | 1867 | percpu_buffer = trace_percpu_sirq_buffer; |
1868 | else | 1868 | else |
1869 | percpu_buffer = trace_percpu_buffer; | 1869 | percpu_buffer = trace_percpu_buffer; |
1870 | 1870 | ||
1871 | if (!percpu_buffer) | 1871 | if (!percpu_buffer) |
1872 | return NULL; | 1872 | return NULL; |
1873 | 1873 | ||
1874 | return this_cpu_ptr(&percpu_buffer->buffer[0]); | 1874 | return this_cpu_ptr(&percpu_buffer->buffer[0]); |
1875 | } | 1875 | } |
1876 | 1876 | ||
1877 | static int alloc_percpu_trace_buffer(void) | 1877 | static int alloc_percpu_trace_buffer(void) |
1878 | { | 1878 | { |
1879 | struct trace_buffer_struct *buffers; | 1879 | struct trace_buffer_struct *buffers; |
1880 | struct trace_buffer_struct *sirq_buffers; | 1880 | struct trace_buffer_struct *sirq_buffers; |
1881 | struct trace_buffer_struct *irq_buffers; | 1881 | struct trace_buffer_struct *irq_buffers; |
1882 | struct trace_buffer_struct *nmi_buffers; | 1882 | struct trace_buffer_struct *nmi_buffers; |
1883 | 1883 | ||
1884 | buffers = alloc_percpu(struct trace_buffer_struct); | 1884 | buffers = alloc_percpu(struct trace_buffer_struct); |
1885 | if (!buffers) | 1885 | if (!buffers) |
1886 | goto err_warn; | 1886 | goto err_warn; |
1887 | 1887 | ||
1888 | sirq_buffers = alloc_percpu(struct trace_buffer_struct); | 1888 | sirq_buffers = alloc_percpu(struct trace_buffer_struct); |
1889 | if (!sirq_buffers) | 1889 | if (!sirq_buffers) |
1890 | goto err_sirq; | 1890 | goto err_sirq; |
1891 | 1891 | ||
1892 | irq_buffers = alloc_percpu(struct trace_buffer_struct); | 1892 | irq_buffers = alloc_percpu(struct trace_buffer_struct); |
1893 | if (!irq_buffers) | 1893 | if (!irq_buffers) |
1894 | goto err_irq; | 1894 | goto err_irq; |
1895 | 1895 | ||
1896 | nmi_buffers = alloc_percpu(struct trace_buffer_struct); | 1896 | nmi_buffers = alloc_percpu(struct trace_buffer_struct); |
1897 | if (!nmi_buffers) | 1897 | if (!nmi_buffers) |
1898 | goto err_nmi; | 1898 | goto err_nmi; |
1899 | 1899 | ||
1900 | trace_percpu_buffer = buffers; | 1900 | trace_percpu_buffer = buffers; |
1901 | trace_percpu_sirq_buffer = sirq_buffers; | 1901 | trace_percpu_sirq_buffer = sirq_buffers; |
1902 | trace_percpu_irq_buffer = irq_buffers; | 1902 | trace_percpu_irq_buffer = irq_buffers; |
1903 | trace_percpu_nmi_buffer = nmi_buffers; | 1903 | trace_percpu_nmi_buffer = nmi_buffers; |
1904 | 1904 | ||
1905 | return 0; | 1905 | return 0; |
1906 | 1906 | ||
1907 | err_nmi: | 1907 | err_nmi: |
1908 | free_percpu(irq_buffers); | 1908 | free_percpu(irq_buffers); |
1909 | err_irq: | 1909 | err_irq: |
1910 | free_percpu(sirq_buffers); | 1910 | free_percpu(sirq_buffers); |
1911 | err_sirq: | 1911 | err_sirq: |
1912 | free_percpu(buffers); | 1912 | free_percpu(buffers); |
1913 | err_warn: | 1913 | err_warn: |
1914 | WARN(1, "Could not allocate percpu trace_printk buffer"); | 1914 | WARN(1, "Could not allocate percpu trace_printk buffer"); |
1915 | return -ENOMEM; | 1915 | return -ENOMEM; |
1916 | } | 1916 | } |
1917 | 1917 | ||
1918 | static int buffers_allocated; | 1918 | static int buffers_allocated; |
1919 | 1919 | ||
1920 | void trace_printk_init_buffers(void) | 1920 | void trace_printk_init_buffers(void) |
1921 | { | 1921 | { |
1922 | if (buffers_allocated) | 1922 | if (buffers_allocated) |
1923 | return; | 1923 | return; |
1924 | 1924 | ||
1925 | if (alloc_percpu_trace_buffer()) | 1925 | if (alloc_percpu_trace_buffer()) |
1926 | return; | 1926 | return; |
1927 | 1927 | ||
1928 | pr_info("ftrace: Allocated trace_printk buffers\n"); | 1928 | pr_info("ftrace: Allocated trace_printk buffers\n"); |
1929 | 1929 | ||
1930 | /* Expand the buffers to set size */ | 1930 | /* Expand the buffers to set size */ |
1931 | tracing_update_buffers(); | 1931 | tracing_update_buffers(); |
1932 | 1932 | ||
1933 | buffers_allocated = 1; | 1933 | buffers_allocated = 1; |
1934 | 1934 | ||
1935 | /* | 1935 | /* |
1936 | * trace_printk_init_buffers() can be called by modules. | 1936 | * trace_printk_init_buffers() can be called by modules. |
1937 | * If that happens, then we need to start cmdline recording | 1937 | * If that happens, then we need to start cmdline recording |
1938 | * directly here. If the global_trace.buffer is already | 1938 | * directly here. If the global_trace.buffer is already |
1939 | * allocated here, then this was called by module code. | 1939 | * allocated here, then this was called by module code. |
1940 | */ | 1940 | */ |
1941 | if (global_trace.trace_buffer.buffer) | 1941 | if (global_trace.trace_buffer.buffer) |
1942 | tracing_start_cmdline_record(); | 1942 | tracing_start_cmdline_record(); |
1943 | } | 1943 | } |
1944 | 1944 | ||
1945 | void trace_printk_start_comm(void) | 1945 | void trace_printk_start_comm(void) |
1946 | { | 1946 | { |
1947 | /* Start tracing comms if trace printk is set */ | 1947 | /* Start tracing comms if trace printk is set */ |
1948 | if (!buffers_allocated) | 1948 | if (!buffers_allocated) |
1949 | return; | 1949 | return; |
1950 | tracing_start_cmdline_record(); | 1950 | tracing_start_cmdline_record(); |
1951 | } | 1951 | } |
1952 | 1952 | ||
1953 | static void trace_printk_start_stop_comm(int enabled) | 1953 | static void trace_printk_start_stop_comm(int enabled) |
1954 | { | 1954 | { |
1955 | if (!buffers_allocated) | 1955 | if (!buffers_allocated) |
1956 | return; | 1956 | return; |
1957 | 1957 | ||
1958 | if (enabled) | 1958 | if (enabled) |
1959 | tracing_start_cmdline_record(); | 1959 | tracing_start_cmdline_record(); |
1960 | else | 1960 | else |
1961 | tracing_stop_cmdline_record(); | 1961 | tracing_stop_cmdline_record(); |
1962 | } | 1962 | } |
1963 | 1963 | ||
1964 | /** | 1964 | /** |
1965 | * trace_vbprintk - write binary msg to tracing buffer | 1965 | * trace_vbprintk - write binary msg to tracing buffer |
1966 | * | 1966 | * |
1967 | */ | 1967 | */ |
1968 | int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) | 1968 | int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) |
1969 | { | 1969 | { |
1970 | struct ftrace_event_call *call = &event_bprint; | 1970 | struct ftrace_event_call *call = &event_bprint; |
1971 | struct ring_buffer_event *event; | 1971 | struct ring_buffer_event *event; |
1972 | struct ring_buffer *buffer; | 1972 | struct ring_buffer *buffer; |
1973 | struct trace_array *tr = &global_trace; | 1973 | struct trace_array *tr = &global_trace; |
1974 | struct bprint_entry *entry; | 1974 | struct bprint_entry *entry; |
1975 | unsigned long flags; | 1975 | unsigned long flags; |
1976 | char *tbuffer; | 1976 | char *tbuffer; |
1977 | int len = 0, size, pc; | 1977 | int len = 0, size, pc; |
1978 | 1978 | ||
1979 | if (unlikely(tracing_selftest_running || tracing_disabled)) | 1979 | if (unlikely(tracing_selftest_running || tracing_disabled)) |
1980 | return 0; | 1980 | return 0; |
1981 | 1981 | ||
1982 | /* Don't pollute graph traces with trace_vprintk internals */ | 1982 | /* Don't pollute graph traces with trace_vprintk internals */ |
1983 | pause_graph_tracing(); | 1983 | pause_graph_tracing(); |
1984 | 1984 | ||
1985 | pc = preempt_count(); | 1985 | pc = preempt_count(); |
1986 | preempt_disable_notrace(); | 1986 | preempt_disable_notrace(); |
1987 | 1987 | ||
1988 | tbuffer = get_trace_buf(); | 1988 | tbuffer = get_trace_buf(); |
1989 | if (!tbuffer) { | 1989 | if (!tbuffer) { |
1990 | len = 0; | 1990 | len = 0; |
1991 | goto out; | 1991 | goto out; |
1992 | } | 1992 | } |
1993 | 1993 | ||
1994 | len = vbin_printf((u32 *)tbuffer, TRACE_BUF_SIZE/sizeof(int), fmt, args); | 1994 | len = vbin_printf((u32 *)tbuffer, TRACE_BUF_SIZE/sizeof(int), fmt, args); |
1995 | 1995 | ||
1996 | if (len > TRACE_BUF_SIZE/sizeof(int) || len < 0) | 1996 | if (len > TRACE_BUF_SIZE/sizeof(int) || len < 0) |
1997 | goto out; | 1997 | goto out; |
1998 | 1998 | ||
1999 | local_save_flags(flags); | 1999 | local_save_flags(flags); |
2000 | size = sizeof(*entry) + sizeof(u32) * len; | 2000 | size = sizeof(*entry) + sizeof(u32) * len; |
2001 | buffer = tr->trace_buffer.buffer; | 2001 | buffer = tr->trace_buffer.buffer; |
2002 | event = trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size, | 2002 | event = trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size, |
2003 | flags, pc); | 2003 | flags, pc); |
2004 | if (!event) | 2004 | if (!event) |
2005 | goto out; | 2005 | goto out; |
2006 | entry = ring_buffer_event_data(event); | 2006 | entry = ring_buffer_event_data(event); |
2007 | entry->ip = ip; | 2007 | entry->ip = ip; |
2008 | entry->fmt = fmt; | 2008 | entry->fmt = fmt; |
2009 | 2009 | ||
2010 | memcpy(entry->buf, tbuffer, sizeof(u32) * len); | 2010 | memcpy(entry->buf, tbuffer, sizeof(u32) * len); |
2011 | if (!filter_check_discard(call, entry, buffer, event)) { | 2011 | if (!filter_check_discard(call, entry, buffer, event)) { |
2012 | __buffer_unlock_commit(buffer, event); | 2012 | __buffer_unlock_commit(buffer, event); |
2013 | ftrace_trace_stack(buffer, flags, 6, pc); | 2013 | ftrace_trace_stack(buffer, flags, 6, pc); |
2014 | } | 2014 | } |
2015 | 2015 | ||
2016 | out: | 2016 | out: |
2017 | preempt_enable_notrace(); | 2017 | preempt_enable_notrace(); |
2018 | unpause_graph_tracing(); | 2018 | unpause_graph_tracing(); |
2019 | 2019 | ||
2020 | return len; | 2020 | return len; |
2021 | } | 2021 | } |
2022 | EXPORT_SYMBOL_GPL(trace_vbprintk); | 2022 | EXPORT_SYMBOL_GPL(trace_vbprintk); |
2023 | 2023 | ||
2024 | static int | 2024 | static int |
2025 | __trace_array_vprintk(struct ring_buffer *buffer, | 2025 | __trace_array_vprintk(struct ring_buffer *buffer, |
2026 | unsigned long ip, const char *fmt, va_list args) | 2026 | unsigned long ip, const char *fmt, va_list args) |
2027 | { | 2027 | { |
2028 | struct ftrace_event_call *call = &event_print; | 2028 | struct ftrace_event_call *call = &event_print; |
2029 | struct ring_buffer_event *event; | 2029 | struct ring_buffer_event *event; |
2030 | int len = 0, size, pc; | 2030 | int len = 0, size, pc; |
2031 | struct print_entry *entry; | 2031 | struct print_entry *entry; |
2032 | unsigned long flags; | 2032 | unsigned long flags; |
2033 | char *tbuffer; | 2033 | char *tbuffer; |
2034 | 2034 | ||
2035 | if (tracing_disabled || tracing_selftest_running) | 2035 | if (tracing_disabled || tracing_selftest_running) |
2036 | return 0; | 2036 | return 0; |
2037 | 2037 | ||
2038 | /* Don't pollute graph traces with trace_vprintk internals */ | 2038 | /* Don't pollute graph traces with trace_vprintk internals */ |
2039 | pause_graph_tracing(); | 2039 | pause_graph_tracing(); |
2040 | 2040 | ||
2041 | pc = preempt_count(); | 2041 | pc = preempt_count(); |
2042 | preempt_disable_notrace(); | 2042 | preempt_disable_notrace(); |
2043 | 2043 | ||
2044 | 2044 | ||
2045 | tbuffer = get_trace_buf(); | 2045 | tbuffer = get_trace_buf(); |
2046 | if (!tbuffer) { | 2046 | if (!tbuffer) { |
2047 | len = 0; | 2047 | len = 0; |
2048 | goto out; | 2048 | goto out; |
2049 | } | 2049 | } |
2050 | 2050 | ||
2051 | len = vsnprintf(tbuffer, TRACE_BUF_SIZE, fmt, args); | 2051 | len = vsnprintf(tbuffer, TRACE_BUF_SIZE, fmt, args); |
2052 | if (len > TRACE_BUF_SIZE) | 2052 | if (len > TRACE_BUF_SIZE) |
2053 | goto out; | 2053 | goto out; |
2054 | 2054 | ||
2055 | local_save_flags(flags); | 2055 | local_save_flags(flags); |
2056 | size = sizeof(*entry) + len + 1; | 2056 | size = sizeof(*entry) + len + 1; |
2057 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, | 2057 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, |
2058 | flags, pc); | 2058 | flags, pc); |
2059 | if (!event) | 2059 | if (!event) |
2060 | goto out; | 2060 | goto out; |
2061 | entry = ring_buffer_event_data(event); | 2061 | entry = ring_buffer_event_data(event); |
2062 | entry->ip = ip; | 2062 | entry->ip = ip; |
2063 | 2063 | ||
2064 | memcpy(&entry->buf, tbuffer, len); | 2064 | memcpy(&entry->buf, tbuffer, len); |
2065 | entry->buf[len] = '\0'; | 2065 | entry->buf[len] = '\0'; |
2066 | if (!filter_check_discard(call, entry, buffer, event)) { | 2066 | if (!filter_check_discard(call, entry, buffer, event)) { |
2067 | __buffer_unlock_commit(buffer, event); | 2067 | __buffer_unlock_commit(buffer, event); |
2068 | ftrace_trace_stack(buffer, flags, 6, pc); | 2068 | ftrace_trace_stack(buffer, flags, 6, pc); |
2069 | } | 2069 | } |
2070 | out: | 2070 | out: |
2071 | preempt_enable_notrace(); | 2071 | preempt_enable_notrace(); |
2072 | unpause_graph_tracing(); | 2072 | unpause_graph_tracing(); |
2073 | 2073 | ||
2074 | return len; | 2074 | return len; |
2075 | } | 2075 | } |
2076 | 2076 | ||
2077 | int trace_array_vprintk(struct trace_array *tr, | 2077 | int trace_array_vprintk(struct trace_array *tr, |
2078 | unsigned long ip, const char *fmt, va_list args) | 2078 | unsigned long ip, const char *fmt, va_list args) |
2079 | { | 2079 | { |
2080 | return __trace_array_vprintk(tr->trace_buffer.buffer, ip, fmt, args); | 2080 | return __trace_array_vprintk(tr->trace_buffer.buffer, ip, fmt, args); |
2081 | } | 2081 | } |
2082 | 2082 | ||
2083 | int trace_array_printk(struct trace_array *tr, | 2083 | int trace_array_printk(struct trace_array *tr, |
2084 | unsigned long ip, const char *fmt, ...) | 2084 | unsigned long ip, const char *fmt, ...) |
2085 | { | 2085 | { |
2086 | int ret; | 2086 | int ret; |
2087 | va_list ap; | 2087 | va_list ap; |
2088 | 2088 | ||
2089 | if (!(trace_flags & TRACE_ITER_PRINTK)) | 2089 | if (!(trace_flags & TRACE_ITER_PRINTK)) |
2090 | return 0; | 2090 | return 0; |
2091 | 2091 | ||
2092 | va_start(ap, fmt); | 2092 | va_start(ap, fmt); |
2093 | ret = trace_array_vprintk(tr, ip, fmt, ap); | 2093 | ret = trace_array_vprintk(tr, ip, fmt, ap); |
2094 | va_end(ap); | 2094 | va_end(ap); |
2095 | return ret; | 2095 | return ret; |
2096 | } | 2096 | } |
2097 | 2097 | ||
2098 | int trace_array_printk_buf(struct ring_buffer *buffer, | 2098 | int trace_array_printk_buf(struct ring_buffer *buffer, |
2099 | unsigned long ip, const char *fmt, ...) | 2099 | unsigned long ip, const char *fmt, ...) |
2100 | { | 2100 | { |
2101 | int ret; | 2101 | int ret; |
2102 | va_list ap; | 2102 | va_list ap; |
2103 | 2103 | ||
2104 | if (!(trace_flags & TRACE_ITER_PRINTK)) | 2104 | if (!(trace_flags & TRACE_ITER_PRINTK)) |
2105 | return 0; | 2105 | return 0; |
2106 | 2106 | ||
2107 | va_start(ap, fmt); | 2107 | va_start(ap, fmt); |
2108 | ret = __trace_array_vprintk(buffer, ip, fmt, ap); | 2108 | ret = __trace_array_vprintk(buffer, ip, fmt, ap); |
2109 | va_end(ap); | 2109 | va_end(ap); |
2110 | return ret; | 2110 | return ret; |
2111 | } | 2111 | } |
2112 | 2112 | ||
2113 | int trace_vprintk(unsigned long ip, const char *fmt, va_list args) | 2113 | int trace_vprintk(unsigned long ip, const char *fmt, va_list args) |
2114 | { | 2114 | { |
2115 | return trace_array_vprintk(&global_trace, ip, fmt, args); | 2115 | return trace_array_vprintk(&global_trace, ip, fmt, args); |
2116 | } | 2116 | } |
2117 | EXPORT_SYMBOL_GPL(trace_vprintk); | 2117 | EXPORT_SYMBOL_GPL(trace_vprintk); |
2118 | 2118 | ||
2119 | static void trace_iterator_increment(struct trace_iterator *iter) | 2119 | static void trace_iterator_increment(struct trace_iterator *iter) |
2120 | { | 2120 | { |
2121 | struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu); | 2121 | struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu); |
2122 | 2122 | ||
2123 | iter->idx++; | 2123 | iter->idx++; |
2124 | if (buf_iter) | 2124 | if (buf_iter) |
2125 | ring_buffer_read(buf_iter, NULL); | 2125 | ring_buffer_read(buf_iter, NULL); |
2126 | } | 2126 | } |
2127 | 2127 | ||
2128 | static struct trace_entry * | 2128 | static struct trace_entry * |
2129 | peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts, | 2129 | peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts, |
2130 | unsigned long *lost_events) | 2130 | unsigned long *lost_events) |
2131 | { | 2131 | { |
2132 | struct ring_buffer_event *event; | 2132 | struct ring_buffer_event *event; |
2133 | struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, cpu); | 2133 | struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, cpu); |
2134 | 2134 | ||
2135 | if (buf_iter) | 2135 | if (buf_iter) |
2136 | event = ring_buffer_iter_peek(buf_iter, ts); | 2136 | event = ring_buffer_iter_peek(buf_iter, ts); |
2137 | else | 2137 | else |
2138 | event = ring_buffer_peek(iter->trace_buffer->buffer, cpu, ts, | 2138 | event = ring_buffer_peek(iter->trace_buffer->buffer, cpu, ts, |
2139 | lost_events); | 2139 | lost_events); |
2140 | 2140 | ||
2141 | if (event) { | 2141 | if (event) { |
2142 | iter->ent_size = ring_buffer_event_length(event); | 2142 | iter->ent_size = ring_buffer_event_length(event); |
2143 | return ring_buffer_event_data(event); | 2143 | return ring_buffer_event_data(event); |
2144 | } | 2144 | } |
2145 | iter->ent_size = 0; | 2145 | iter->ent_size = 0; |
2146 | return NULL; | 2146 | return NULL; |
2147 | } | 2147 | } |
2148 | 2148 | ||
2149 | static struct trace_entry * | 2149 | static struct trace_entry * |
2150 | __find_next_entry(struct trace_iterator *iter, int *ent_cpu, | 2150 | __find_next_entry(struct trace_iterator *iter, int *ent_cpu, |
2151 | unsigned long *missing_events, u64 *ent_ts) | 2151 | unsigned long *missing_events, u64 *ent_ts) |
2152 | { | 2152 | { |
2153 | struct ring_buffer *buffer = iter->trace_buffer->buffer; | 2153 | struct ring_buffer *buffer = iter->trace_buffer->buffer; |
2154 | struct trace_entry *ent, *next = NULL; | 2154 | struct trace_entry *ent, *next = NULL; |
2155 | unsigned long lost_events = 0, next_lost = 0; | 2155 | unsigned long lost_events = 0, next_lost = 0; |
2156 | int cpu_file = iter->cpu_file; | 2156 | int cpu_file = iter->cpu_file; |
2157 | u64 next_ts = 0, ts; | 2157 | u64 next_ts = 0, ts; |
2158 | int next_cpu = -1; | 2158 | int next_cpu = -1; |
2159 | int next_size = 0; | 2159 | int next_size = 0; |
2160 | int cpu; | 2160 | int cpu; |
2161 | 2161 | ||
2162 | /* | 2162 | /* |
2163 | * If we are in a per_cpu trace file, don't bother by iterating over | 2163 | * If we are in a per_cpu trace file, don't bother by iterating over |
2164 | * all cpu and peek directly. | 2164 | * all cpu and peek directly. |
2165 | */ | 2165 | */ |
2166 | if (cpu_file > RING_BUFFER_ALL_CPUS) { | 2166 | if (cpu_file > RING_BUFFER_ALL_CPUS) { |
2167 | if (ring_buffer_empty_cpu(buffer, cpu_file)) | 2167 | if (ring_buffer_empty_cpu(buffer, cpu_file)) |
2168 | return NULL; | 2168 | return NULL; |
2169 | ent = peek_next_entry(iter, cpu_file, ent_ts, missing_events); | 2169 | ent = peek_next_entry(iter, cpu_file, ent_ts, missing_events); |
2170 | if (ent_cpu) | 2170 | if (ent_cpu) |
2171 | *ent_cpu = cpu_file; | 2171 | *ent_cpu = cpu_file; |
2172 | 2172 | ||
2173 | return ent; | 2173 | return ent; |
2174 | } | 2174 | } |
2175 | 2175 | ||
2176 | for_each_tracing_cpu(cpu) { | 2176 | for_each_tracing_cpu(cpu) { |
2177 | 2177 | ||
2178 | if (ring_buffer_empty_cpu(buffer, cpu)) | 2178 | if (ring_buffer_empty_cpu(buffer, cpu)) |
2179 | continue; | 2179 | continue; |
2180 | 2180 | ||
2181 | ent = peek_next_entry(iter, cpu, &ts, &lost_events); | 2181 | ent = peek_next_entry(iter, cpu, &ts, &lost_events); |
2182 | 2182 | ||
2183 | /* | 2183 | /* |
2184 | * Pick the entry with the smallest timestamp: | 2184 | * Pick the entry with the smallest timestamp: |
2185 | */ | 2185 | */ |
2186 | if (ent && (!next || ts < next_ts)) { | 2186 | if (ent && (!next || ts < next_ts)) { |
2187 | next = ent; | 2187 | next = ent; |
2188 | next_cpu = cpu; | 2188 | next_cpu = cpu; |
2189 | next_ts = ts; | 2189 | next_ts = ts; |
2190 | next_lost = lost_events; | 2190 | next_lost = lost_events; |
2191 | next_size = iter->ent_size; | 2191 | next_size = iter->ent_size; |
2192 | } | 2192 | } |
2193 | } | 2193 | } |
2194 | 2194 | ||
2195 | iter->ent_size = next_size; | 2195 | iter->ent_size = next_size; |
2196 | 2196 | ||
2197 | if (ent_cpu) | 2197 | if (ent_cpu) |
2198 | *ent_cpu = next_cpu; | 2198 | *ent_cpu = next_cpu; |
2199 | 2199 | ||
2200 | if (ent_ts) | 2200 | if (ent_ts) |
2201 | *ent_ts = next_ts; | 2201 | *ent_ts = next_ts; |
2202 | 2202 | ||
2203 | if (missing_events) | 2203 | if (missing_events) |
2204 | *missing_events = next_lost; | 2204 | *missing_events = next_lost; |
2205 | 2205 | ||
2206 | return next; | 2206 | return next; |
2207 | } | 2207 | } |
2208 | 2208 | ||
2209 | /* Find the next real entry, without updating the iterator itself */ | 2209 | /* Find the next real entry, without updating the iterator itself */ |
2210 | struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, | 2210 | struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, |
2211 | int *ent_cpu, u64 *ent_ts) | 2211 | int *ent_cpu, u64 *ent_ts) |
2212 | { | 2212 | { |
2213 | return __find_next_entry(iter, ent_cpu, NULL, ent_ts); | 2213 | return __find_next_entry(iter, ent_cpu, NULL, ent_ts); |
2214 | } | 2214 | } |
2215 | 2215 | ||
2216 | /* Find the next real entry, and increment the iterator to the next entry */ | 2216 | /* Find the next real entry, and increment the iterator to the next entry */ |
2217 | void *trace_find_next_entry_inc(struct trace_iterator *iter) | 2217 | void *trace_find_next_entry_inc(struct trace_iterator *iter) |
2218 | { | 2218 | { |
2219 | iter->ent = __find_next_entry(iter, &iter->cpu, | 2219 | iter->ent = __find_next_entry(iter, &iter->cpu, |
2220 | &iter->lost_events, &iter->ts); | 2220 | &iter->lost_events, &iter->ts); |
2221 | 2221 | ||
2222 | if (iter->ent) | 2222 | if (iter->ent) |
2223 | trace_iterator_increment(iter); | 2223 | trace_iterator_increment(iter); |
2224 | 2224 | ||
2225 | return iter->ent ? iter : NULL; | 2225 | return iter->ent ? iter : NULL; |
2226 | } | 2226 | } |
2227 | 2227 | ||
2228 | static void trace_consume(struct trace_iterator *iter) | 2228 | static void trace_consume(struct trace_iterator *iter) |
2229 | { | 2229 | { |
2230 | ring_buffer_consume(iter->trace_buffer->buffer, iter->cpu, &iter->ts, | 2230 | ring_buffer_consume(iter->trace_buffer->buffer, iter->cpu, &iter->ts, |
2231 | &iter->lost_events); | 2231 | &iter->lost_events); |
2232 | } | 2232 | } |
2233 | 2233 | ||
2234 | static void *s_next(struct seq_file *m, void *v, loff_t *pos) | 2234 | static void *s_next(struct seq_file *m, void *v, loff_t *pos) |
2235 | { | 2235 | { |
2236 | struct trace_iterator *iter = m->private; | 2236 | struct trace_iterator *iter = m->private; |
2237 | int i = (int)*pos; | 2237 | int i = (int)*pos; |
2238 | void *ent; | 2238 | void *ent; |
2239 | 2239 | ||
2240 | WARN_ON_ONCE(iter->leftover); | 2240 | WARN_ON_ONCE(iter->leftover); |
2241 | 2241 | ||
2242 | (*pos)++; | 2242 | (*pos)++; |
2243 | 2243 | ||
2244 | /* can't go backwards */ | 2244 | /* can't go backwards */ |
2245 | if (iter->idx > i) | 2245 | if (iter->idx > i) |
2246 | return NULL; | 2246 | return NULL; |
2247 | 2247 | ||
2248 | if (iter->idx < 0) | 2248 | if (iter->idx < 0) |
2249 | ent = trace_find_next_entry_inc(iter); | 2249 | ent = trace_find_next_entry_inc(iter); |
2250 | else | 2250 | else |
2251 | ent = iter; | 2251 | ent = iter; |
2252 | 2252 | ||
2253 | while (ent && iter->idx < i) | 2253 | while (ent && iter->idx < i) |
2254 | ent = trace_find_next_entry_inc(iter); | 2254 | ent = trace_find_next_entry_inc(iter); |
2255 | 2255 | ||
2256 | iter->pos = *pos; | 2256 | iter->pos = *pos; |
2257 | 2257 | ||
2258 | return ent; | 2258 | return ent; |
2259 | } | 2259 | } |
2260 | 2260 | ||
2261 | void tracing_iter_reset(struct trace_iterator *iter, int cpu) | 2261 | void tracing_iter_reset(struct trace_iterator *iter, int cpu) |
2262 | { | 2262 | { |
2263 | struct ring_buffer_event *event; | 2263 | struct ring_buffer_event *event; |
2264 | struct ring_buffer_iter *buf_iter; | 2264 | struct ring_buffer_iter *buf_iter; |
2265 | unsigned long entries = 0; | 2265 | unsigned long entries = 0; |
2266 | u64 ts; | 2266 | u64 ts; |
2267 | 2267 | ||
2268 | per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = 0; | 2268 | per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = 0; |
2269 | 2269 | ||
2270 | buf_iter = trace_buffer_iter(iter, cpu); | 2270 | buf_iter = trace_buffer_iter(iter, cpu); |
2271 | if (!buf_iter) | 2271 | if (!buf_iter) |
2272 | return; | 2272 | return; |
2273 | 2273 | ||
2274 | ring_buffer_iter_reset(buf_iter); | 2274 | ring_buffer_iter_reset(buf_iter); |
2275 | 2275 | ||
2276 | /* | 2276 | /* |
2277 | * We could have the case with the max latency tracers | 2277 | * We could have the case with the max latency tracers |
2278 | * that a reset never took place on a cpu. This is evident | 2278 | * that a reset never took place on a cpu. This is evident |
2279 | * by the timestamp being before the start of the buffer. | 2279 | * by the timestamp being before the start of the buffer. |
2280 | */ | 2280 | */ |
2281 | while ((event = ring_buffer_iter_peek(buf_iter, &ts))) { | 2281 | while ((event = ring_buffer_iter_peek(buf_iter, &ts))) { |
2282 | if (ts >= iter->trace_buffer->time_start) | 2282 | if (ts >= iter->trace_buffer->time_start) |
2283 | break; | 2283 | break; |
2284 | entries++; | 2284 | entries++; |
2285 | ring_buffer_read(buf_iter, NULL); | 2285 | ring_buffer_read(buf_iter, NULL); |
2286 | } | 2286 | } |
2287 | 2287 | ||
2288 | per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = entries; | 2288 | per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = entries; |
2289 | } | 2289 | } |
2290 | 2290 | ||
2291 | /* | 2291 | /* |
2292 | * The current tracer is copied to avoid a global locking | 2292 | * The current tracer is copied to avoid a global locking |
2293 | * all around. | 2293 | * all around. |
2294 | */ | 2294 | */ |
2295 | static void *s_start(struct seq_file *m, loff_t *pos) | 2295 | static void *s_start(struct seq_file *m, loff_t *pos) |
2296 | { | 2296 | { |
2297 | struct trace_iterator *iter = m->private; | 2297 | struct trace_iterator *iter = m->private; |
2298 | struct trace_array *tr = iter->tr; | 2298 | struct trace_array *tr = iter->tr; |
2299 | int cpu_file = iter->cpu_file; | 2299 | int cpu_file = iter->cpu_file; |
2300 | void *p = NULL; | 2300 | void *p = NULL; |
2301 | loff_t l = 0; | 2301 | loff_t l = 0; |
2302 | int cpu; | 2302 | int cpu; |
2303 | 2303 | ||
2304 | /* | 2304 | /* |
2305 | * copy the tracer to avoid using a global lock all around. | 2305 | * copy the tracer to avoid using a global lock all around. |
2306 | * iter->trace is a copy of current_trace, the pointer to the | 2306 | * iter->trace is a copy of current_trace, the pointer to the |
2307 | * name may be used instead of a strcmp(), as iter->trace->name | 2307 | * name may be used instead of a strcmp(), as iter->trace->name |
2308 | * will point to the same string as current_trace->name. | 2308 | * will point to the same string as current_trace->name. |
2309 | */ | 2309 | */ |
2310 | mutex_lock(&trace_types_lock); | 2310 | mutex_lock(&trace_types_lock); |
2311 | if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name)) | 2311 | if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name)) |
2312 | *iter->trace = *tr->current_trace; | 2312 | *iter->trace = *tr->current_trace; |
2313 | mutex_unlock(&trace_types_lock); | 2313 | mutex_unlock(&trace_types_lock); |
2314 | 2314 | ||
2315 | #ifdef CONFIG_TRACER_MAX_TRACE | 2315 | #ifdef CONFIG_TRACER_MAX_TRACE |
2316 | if (iter->snapshot && iter->trace->use_max_tr) | 2316 | if (iter->snapshot && iter->trace->use_max_tr) |
2317 | return ERR_PTR(-EBUSY); | 2317 | return ERR_PTR(-EBUSY); |
2318 | #endif | 2318 | #endif |
2319 | 2319 | ||
2320 | if (!iter->snapshot) | 2320 | if (!iter->snapshot) |
2321 | atomic_inc(&trace_record_cmdline_disabled); | 2321 | atomic_inc(&trace_record_cmdline_disabled); |
2322 | 2322 | ||
2323 | if (*pos != iter->pos) { | 2323 | if (*pos != iter->pos) { |
2324 | iter->ent = NULL; | 2324 | iter->ent = NULL; |
2325 | iter->cpu = 0; | 2325 | iter->cpu = 0; |
2326 | iter->idx = -1; | 2326 | iter->idx = -1; |
2327 | 2327 | ||
2328 | if (cpu_file == RING_BUFFER_ALL_CPUS) { | 2328 | if (cpu_file == RING_BUFFER_ALL_CPUS) { |
2329 | for_each_tracing_cpu(cpu) | 2329 | for_each_tracing_cpu(cpu) |
2330 | tracing_iter_reset(iter, cpu); | 2330 | tracing_iter_reset(iter, cpu); |
2331 | } else | 2331 | } else |
2332 | tracing_iter_reset(iter, cpu_file); | 2332 | tracing_iter_reset(iter, cpu_file); |
2333 | 2333 | ||
2334 | iter->leftover = 0; | 2334 | iter->leftover = 0; |
2335 | for (p = iter; p && l < *pos; p = s_next(m, p, &l)) | 2335 | for (p = iter; p && l < *pos; p = s_next(m, p, &l)) |
2336 | ; | 2336 | ; |
2337 | 2337 | ||
2338 | } else { | 2338 | } else { |
2339 | /* | 2339 | /* |
2340 | * If we overflowed the seq_file before, then we want | 2340 | * If we overflowed the seq_file before, then we want |
2341 | * to just reuse the trace_seq buffer again. | 2341 | * to just reuse the trace_seq buffer again. |
2342 | */ | 2342 | */ |
2343 | if (iter->leftover) | 2343 | if (iter->leftover) |
2344 | p = iter; | 2344 | p = iter; |
2345 | else { | 2345 | else { |
2346 | l = *pos - 1; | 2346 | l = *pos - 1; |
2347 | p = s_next(m, p, &l); | 2347 | p = s_next(m, p, &l); |
2348 | } | 2348 | } |
2349 | } | 2349 | } |
2350 | 2350 | ||
2351 | trace_event_read_lock(); | 2351 | trace_event_read_lock(); |
2352 | trace_access_lock(cpu_file); | 2352 | trace_access_lock(cpu_file); |
2353 | return p; | 2353 | return p; |
2354 | } | 2354 | } |
2355 | 2355 | ||
2356 | static void s_stop(struct seq_file *m, void *p) | 2356 | static void s_stop(struct seq_file *m, void *p) |
2357 | { | 2357 | { |
2358 | struct trace_iterator *iter = m->private; | 2358 | struct trace_iterator *iter = m->private; |
2359 | 2359 | ||
2360 | #ifdef CONFIG_TRACER_MAX_TRACE | 2360 | #ifdef CONFIG_TRACER_MAX_TRACE |
2361 | if (iter->snapshot && iter->trace->use_max_tr) | 2361 | if (iter->snapshot && iter->trace->use_max_tr) |
2362 | return; | 2362 | return; |
2363 | #endif | 2363 | #endif |
2364 | 2364 | ||
2365 | if (!iter->snapshot) | 2365 | if (!iter->snapshot) |
2366 | atomic_dec(&trace_record_cmdline_disabled); | 2366 | atomic_dec(&trace_record_cmdline_disabled); |
2367 | 2367 | ||
2368 | trace_access_unlock(iter->cpu_file); | 2368 | trace_access_unlock(iter->cpu_file); |
2369 | trace_event_read_unlock(); | 2369 | trace_event_read_unlock(); |
2370 | } | 2370 | } |
2371 | 2371 | ||
2372 | static void | 2372 | static void |
2373 | get_total_entries(struct trace_buffer *buf, | 2373 | get_total_entries(struct trace_buffer *buf, |
2374 | unsigned long *total, unsigned long *entries) | 2374 | unsigned long *total, unsigned long *entries) |
2375 | { | 2375 | { |
2376 | unsigned long count; | 2376 | unsigned long count; |
2377 | int cpu; | 2377 | int cpu; |
2378 | 2378 | ||
2379 | *total = 0; | 2379 | *total = 0; |
2380 | *entries = 0; | 2380 | *entries = 0; |
2381 | 2381 | ||
2382 | for_each_tracing_cpu(cpu) { | 2382 | for_each_tracing_cpu(cpu) { |
2383 | count = ring_buffer_entries_cpu(buf->buffer, cpu); | 2383 | count = ring_buffer_entries_cpu(buf->buffer, cpu); |
2384 | /* | 2384 | /* |
2385 | * If this buffer has skipped entries, then we hold all | 2385 | * If this buffer has skipped entries, then we hold all |
2386 | * entries for the trace and we need to ignore the | 2386 | * entries for the trace and we need to ignore the |
2387 | * ones before the time stamp. | 2387 | * ones before the time stamp. |
2388 | */ | 2388 | */ |
2389 | if (per_cpu_ptr(buf->data, cpu)->skipped_entries) { | 2389 | if (per_cpu_ptr(buf->data, cpu)->skipped_entries) { |
2390 | count -= per_cpu_ptr(buf->data, cpu)->skipped_entries; | 2390 | count -= per_cpu_ptr(buf->data, cpu)->skipped_entries; |
2391 | /* total is the same as the entries */ | 2391 | /* total is the same as the entries */ |
2392 | *total += count; | 2392 | *total += count; |
2393 | } else | 2393 | } else |
2394 | *total += count + | 2394 | *total += count + |
2395 | ring_buffer_overrun_cpu(buf->buffer, cpu); | 2395 | ring_buffer_overrun_cpu(buf->buffer, cpu); |
2396 | *entries += count; | 2396 | *entries += count; |
2397 | } | 2397 | } |
2398 | } | 2398 | } |
2399 | 2399 | ||
2400 | static void print_lat_help_header(struct seq_file *m) | 2400 | static void print_lat_help_header(struct seq_file *m) |
2401 | { | 2401 | { |
2402 | seq_puts(m, "# _------=> CPU# \n"); | 2402 | seq_puts(m, "# _------=> CPU# \n"); |
2403 | seq_puts(m, "# / _-----=> irqs-off \n"); | 2403 | seq_puts(m, "# / _-----=> irqs-off \n"); |
2404 | seq_puts(m, "# | / _----=> need-resched \n"); | 2404 | seq_puts(m, "# | / _----=> need-resched \n"); |
2405 | seq_puts(m, "# || / _---=> hardirq/softirq \n"); | 2405 | seq_puts(m, "# || / _---=> hardirq/softirq \n"); |
2406 | seq_puts(m, "# ||| / _--=> preempt-depth \n"); | 2406 | seq_puts(m, "# ||| / _--=> preempt-depth \n"); |
2407 | seq_puts(m, "# |||| / delay \n"); | 2407 | seq_puts(m, "# |||| / delay \n"); |
2408 | seq_puts(m, "# cmd pid ||||| time | caller \n"); | 2408 | seq_puts(m, "# cmd pid ||||| time | caller \n"); |
2409 | seq_puts(m, "# \\ / ||||| \\ | / \n"); | 2409 | seq_puts(m, "# \\ / ||||| \\ | / \n"); |
2410 | } | 2410 | } |
2411 | 2411 | ||
2412 | static void print_event_info(struct trace_buffer *buf, struct seq_file *m) | 2412 | static void print_event_info(struct trace_buffer *buf, struct seq_file *m) |
2413 | { | 2413 | { |
2414 | unsigned long total; | 2414 | unsigned long total; |
2415 | unsigned long entries; | 2415 | unsigned long entries; |
2416 | 2416 | ||
2417 | get_total_entries(buf, &total, &entries); | 2417 | get_total_entries(buf, &total, &entries); |
2418 | seq_printf(m, "# entries-in-buffer/entries-written: %lu/%lu #P:%d\n", | 2418 | seq_printf(m, "# entries-in-buffer/entries-written: %lu/%lu #P:%d\n", |
2419 | entries, total, num_online_cpus()); | 2419 | entries, total, num_online_cpus()); |
2420 | seq_puts(m, "#\n"); | 2420 | seq_puts(m, "#\n"); |
2421 | } | 2421 | } |
2422 | 2422 | ||
2423 | static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m) | 2423 | static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m) |
2424 | { | 2424 | { |
2425 | print_event_info(buf, m); | 2425 | print_event_info(buf, m); |
2426 | seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n"); | 2426 | seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n"); |
2427 | seq_puts(m, "# | | | | |\n"); | 2427 | seq_puts(m, "# | | | | |\n"); |
2428 | } | 2428 | } |
2429 | 2429 | ||
2430 | static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m) | 2430 | static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m) |
2431 | { | 2431 | { |
2432 | print_event_info(buf, m); | 2432 | print_event_info(buf, m); |
2433 | seq_puts(m, "# _-----=> irqs-off\n"); | 2433 | seq_puts(m, "# _-----=> irqs-off\n"); |
2434 | seq_puts(m, "# / _----=> need-resched\n"); | 2434 | seq_puts(m, "# / _----=> need-resched\n"); |
2435 | seq_puts(m, "# | / _---=> hardirq/softirq\n"); | 2435 | seq_puts(m, "# | / _---=> hardirq/softirq\n"); |
2436 | seq_puts(m, "# || / _--=> preempt-depth\n"); | 2436 | seq_puts(m, "# || / _--=> preempt-depth\n"); |
2437 | seq_puts(m, "# ||| / delay\n"); | 2437 | seq_puts(m, "# ||| / delay\n"); |
2438 | seq_puts(m, "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n"); | 2438 | seq_puts(m, "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n"); |
2439 | seq_puts(m, "# | | | |||| | |\n"); | 2439 | seq_puts(m, "# | | | |||| | |\n"); |
2440 | } | 2440 | } |
2441 | 2441 | ||
2442 | void | 2442 | void |
2443 | print_trace_header(struct seq_file *m, struct trace_iterator *iter) | 2443 | print_trace_header(struct seq_file *m, struct trace_iterator *iter) |
2444 | { | 2444 | { |
2445 | unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); | 2445 | unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); |
2446 | struct trace_buffer *buf = iter->trace_buffer; | 2446 | struct trace_buffer *buf = iter->trace_buffer; |
2447 | struct trace_array_cpu *data = per_cpu_ptr(buf->data, buf->cpu); | 2447 | struct trace_array_cpu *data = per_cpu_ptr(buf->data, buf->cpu); |
2448 | struct tracer *type = iter->trace; | 2448 | struct tracer *type = iter->trace; |
2449 | unsigned long entries; | 2449 | unsigned long entries; |
2450 | unsigned long total; | 2450 | unsigned long total; |
2451 | const char *name = "preemption"; | 2451 | const char *name = "preemption"; |
2452 | 2452 | ||
2453 | name = type->name; | 2453 | name = type->name; |
2454 | 2454 | ||
2455 | get_total_entries(buf, &total, &entries); | 2455 | get_total_entries(buf, &total, &entries); |
2456 | 2456 | ||
2457 | seq_printf(m, "# %s latency trace v1.1.5 on %s\n", | 2457 | seq_printf(m, "# %s latency trace v1.1.5 on %s\n", |
2458 | name, UTS_RELEASE); | 2458 | name, UTS_RELEASE); |
2459 | seq_puts(m, "# -----------------------------------" | 2459 | seq_puts(m, "# -----------------------------------" |
2460 | "---------------------------------\n"); | 2460 | "---------------------------------\n"); |
2461 | seq_printf(m, "# latency: %lu us, #%lu/%lu, CPU#%d |" | 2461 | seq_printf(m, "# latency: %lu us, #%lu/%lu, CPU#%d |" |
2462 | " (M:%s VP:%d, KP:%d, SP:%d HP:%d", | 2462 | " (M:%s VP:%d, KP:%d, SP:%d HP:%d", |
2463 | nsecs_to_usecs(data->saved_latency), | 2463 | nsecs_to_usecs(data->saved_latency), |
2464 | entries, | 2464 | entries, |
2465 | total, | 2465 | total, |
2466 | buf->cpu, | 2466 | buf->cpu, |
2467 | #if defined(CONFIG_PREEMPT_NONE) | 2467 | #if defined(CONFIG_PREEMPT_NONE) |
2468 | "server", | 2468 | "server", |
2469 | #elif defined(CONFIG_PREEMPT_VOLUNTARY) | 2469 | #elif defined(CONFIG_PREEMPT_VOLUNTARY) |
2470 | "desktop", | 2470 | "desktop", |
2471 | #elif defined(CONFIG_PREEMPT) | 2471 | #elif defined(CONFIG_PREEMPT) |
2472 | "preempt", | 2472 | "preempt", |
2473 | #else | 2473 | #else |
2474 | "unknown", | 2474 | "unknown", |
2475 | #endif | 2475 | #endif |
2476 | /* These are reserved for later use */ | 2476 | /* These are reserved for later use */ |
2477 | 0, 0, 0, 0); | 2477 | 0, 0, 0, 0); |
2478 | #ifdef CONFIG_SMP | 2478 | #ifdef CONFIG_SMP |
2479 | seq_printf(m, " #P:%d)\n", num_online_cpus()); | 2479 | seq_printf(m, " #P:%d)\n", num_online_cpus()); |
2480 | #else | 2480 | #else |
2481 | seq_puts(m, ")\n"); | 2481 | seq_puts(m, ")\n"); |
2482 | #endif | 2482 | #endif |
2483 | seq_puts(m, "# -----------------\n"); | 2483 | seq_puts(m, "# -----------------\n"); |
2484 | seq_printf(m, "# | task: %.16s-%d " | 2484 | seq_printf(m, "# | task: %.16s-%d " |
2485 | "(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n", | 2485 | "(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n", |
2486 | data->comm, data->pid, | 2486 | data->comm, data->pid, |
2487 | from_kuid_munged(seq_user_ns(m), data->uid), data->nice, | 2487 | from_kuid_munged(seq_user_ns(m), data->uid), data->nice, |
2488 | data->policy, data->rt_priority); | 2488 | data->policy, data->rt_priority); |
2489 | seq_puts(m, "# -----------------\n"); | 2489 | seq_puts(m, "# -----------------\n"); |
2490 | 2490 | ||
2491 | if (data->critical_start) { | 2491 | if (data->critical_start) { |
2492 | seq_puts(m, "# => started at: "); | 2492 | seq_puts(m, "# => started at: "); |
2493 | seq_print_ip_sym(&iter->seq, data->critical_start, sym_flags); | 2493 | seq_print_ip_sym(&iter->seq, data->critical_start, sym_flags); |
2494 | trace_print_seq(m, &iter->seq); | 2494 | trace_print_seq(m, &iter->seq); |
2495 | seq_puts(m, "\n# => ended at: "); | 2495 | seq_puts(m, "\n# => ended at: "); |
2496 | seq_print_ip_sym(&iter->seq, data->critical_end, sym_flags); | 2496 | seq_print_ip_sym(&iter->seq, data->critical_end, sym_flags); |
2497 | trace_print_seq(m, &iter->seq); | 2497 | trace_print_seq(m, &iter->seq); |
2498 | seq_puts(m, "\n#\n"); | 2498 | seq_puts(m, "\n#\n"); |
2499 | } | 2499 | } |
2500 | 2500 | ||
2501 | seq_puts(m, "#\n"); | 2501 | seq_puts(m, "#\n"); |
2502 | } | 2502 | } |
2503 | 2503 | ||
2504 | static void test_cpu_buff_start(struct trace_iterator *iter) | 2504 | static void test_cpu_buff_start(struct trace_iterator *iter) |
2505 | { | 2505 | { |
2506 | struct trace_seq *s = &iter->seq; | 2506 | struct trace_seq *s = &iter->seq; |
2507 | 2507 | ||
2508 | if (!(trace_flags & TRACE_ITER_ANNOTATE)) | 2508 | if (!(trace_flags & TRACE_ITER_ANNOTATE)) |
2509 | return; | 2509 | return; |
2510 | 2510 | ||
2511 | if (!(iter->iter_flags & TRACE_FILE_ANNOTATE)) | 2511 | if (!(iter->iter_flags & TRACE_FILE_ANNOTATE)) |
2512 | return; | 2512 | return; |
2513 | 2513 | ||
2514 | if (cpumask_test_cpu(iter->cpu, iter->started)) | 2514 | if (cpumask_test_cpu(iter->cpu, iter->started)) |
2515 | return; | 2515 | return; |
2516 | 2516 | ||
2517 | if (per_cpu_ptr(iter->trace_buffer->data, iter->cpu)->skipped_entries) | 2517 | if (per_cpu_ptr(iter->trace_buffer->data, iter->cpu)->skipped_entries) |
2518 | return; | 2518 | return; |
2519 | 2519 | ||
2520 | cpumask_set_cpu(iter->cpu, iter->started); | 2520 | cpumask_set_cpu(iter->cpu, iter->started); |
2521 | 2521 | ||
2522 | /* Don't print started cpu buffer for the first entry of the trace */ | 2522 | /* Don't print started cpu buffer for the first entry of the trace */ |
2523 | if (iter->idx > 1) | 2523 | if (iter->idx > 1) |
2524 | trace_seq_printf(s, "##### CPU %u buffer started ####\n", | 2524 | trace_seq_printf(s, "##### CPU %u buffer started ####\n", |
2525 | iter->cpu); | 2525 | iter->cpu); |
2526 | } | 2526 | } |
2527 | 2527 | ||
2528 | static enum print_line_t print_trace_fmt(struct trace_iterator *iter) | 2528 | static enum print_line_t print_trace_fmt(struct trace_iterator *iter) |
2529 | { | 2529 | { |
2530 | struct trace_seq *s = &iter->seq; | 2530 | struct trace_seq *s = &iter->seq; |
2531 | unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); | 2531 | unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); |
2532 | struct trace_entry *entry; | 2532 | struct trace_entry *entry; |
2533 | struct trace_event *event; | 2533 | struct trace_event *event; |
2534 | 2534 | ||
2535 | entry = iter->ent; | 2535 | entry = iter->ent; |
2536 | 2536 | ||
2537 | test_cpu_buff_start(iter); | 2537 | test_cpu_buff_start(iter); |
2538 | 2538 | ||
2539 | event = ftrace_find_event(entry->type); | 2539 | event = ftrace_find_event(entry->type); |
2540 | 2540 | ||
2541 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2541 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { |
2542 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) { | 2542 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) { |
2543 | if (!trace_print_lat_context(iter)) | 2543 | if (!trace_print_lat_context(iter)) |
2544 | goto partial; | 2544 | goto partial; |
2545 | } else { | 2545 | } else { |
2546 | if (!trace_print_context(iter)) | 2546 | if (!trace_print_context(iter)) |
2547 | goto partial; | 2547 | goto partial; |
2548 | } | 2548 | } |
2549 | } | 2549 | } |
2550 | 2550 | ||
2551 | if (event) | 2551 | if (event) |
2552 | return event->funcs->trace(iter, sym_flags, event); | 2552 | return event->funcs->trace(iter, sym_flags, event); |
2553 | 2553 | ||
2554 | if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) | 2554 | if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) |
2555 | goto partial; | 2555 | goto partial; |
2556 | 2556 | ||
2557 | return TRACE_TYPE_HANDLED; | 2557 | return TRACE_TYPE_HANDLED; |
2558 | partial: | 2558 | partial: |
2559 | return TRACE_TYPE_PARTIAL_LINE; | 2559 | return TRACE_TYPE_PARTIAL_LINE; |
2560 | } | 2560 | } |
2561 | 2561 | ||
2562 | static enum print_line_t print_raw_fmt(struct trace_iterator *iter) | 2562 | static enum print_line_t print_raw_fmt(struct trace_iterator *iter) |
2563 | { | 2563 | { |
2564 | struct trace_seq *s = &iter->seq; | 2564 | struct trace_seq *s = &iter->seq; |
2565 | struct trace_entry *entry; | 2565 | struct trace_entry *entry; |
2566 | struct trace_event *event; | 2566 | struct trace_event *event; |
2567 | 2567 | ||
2568 | entry = iter->ent; | 2568 | entry = iter->ent; |
2569 | 2569 | ||
2570 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2570 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { |
2571 | if (!trace_seq_printf(s, "%d %d %llu ", | 2571 | if (!trace_seq_printf(s, "%d %d %llu ", |
2572 | entry->pid, iter->cpu, iter->ts)) | 2572 | entry->pid, iter->cpu, iter->ts)) |
2573 | goto partial; | 2573 | goto partial; |
2574 | } | 2574 | } |
2575 | 2575 | ||
2576 | event = ftrace_find_event(entry->type); | 2576 | event = ftrace_find_event(entry->type); |
2577 | if (event) | 2577 | if (event) |
2578 | return event->funcs->raw(iter, 0, event); | 2578 | return event->funcs->raw(iter, 0, event); |
2579 | 2579 | ||
2580 | if (!trace_seq_printf(s, "%d ?\n", entry->type)) | 2580 | if (!trace_seq_printf(s, "%d ?\n", entry->type)) |
2581 | goto partial; | 2581 | goto partial; |
2582 | 2582 | ||
2583 | return TRACE_TYPE_HANDLED; | 2583 | return TRACE_TYPE_HANDLED; |
2584 | partial: | 2584 | partial: |
2585 | return TRACE_TYPE_PARTIAL_LINE; | 2585 | return TRACE_TYPE_PARTIAL_LINE; |
2586 | } | 2586 | } |
2587 | 2587 | ||
2588 | static enum print_line_t print_hex_fmt(struct trace_iterator *iter) | 2588 | static enum print_line_t print_hex_fmt(struct trace_iterator *iter) |
2589 | { | 2589 | { |
2590 | struct trace_seq *s = &iter->seq; | 2590 | struct trace_seq *s = &iter->seq; |
2591 | unsigned char newline = '\n'; | 2591 | unsigned char newline = '\n'; |
2592 | struct trace_entry *entry; | 2592 | struct trace_entry *entry; |
2593 | struct trace_event *event; | 2593 | struct trace_event *event; |
2594 | 2594 | ||
2595 | entry = iter->ent; | 2595 | entry = iter->ent; |
2596 | 2596 | ||
2597 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2597 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { |
2598 | SEQ_PUT_HEX_FIELD_RET(s, entry->pid); | 2598 | SEQ_PUT_HEX_FIELD_RET(s, entry->pid); |
2599 | SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); | 2599 | SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); |
2600 | SEQ_PUT_HEX_FIELD_RET(s, iter->ts); | 2600 | SEQ_PUT_HEX_FIELD_RET(s, iter->ts); |
2601 | } | 2601 | } |
2602 | 2602 | ||
2603 | event = ftrace_find_event(entry->type); | 2603 | event = ftrace_find_event(entry->type); |
2604 | if (event) { | 2604 | if (event) { |
2605 | enum print_line_t ret = event->funcs->hex(iter, 0, event); | 2605 | enum print_line_t ret = event->funcs->hex(iter, 0, event); |
2606 | if (ret != TRACE_TYPE_HANDLED) | 2606 | if (ret != TRACE_TYPE_HANDLED) |
2607 | return ret; | 2607 | return ret; |
2608 | } | 2608 | } |
2609 | 2609 | ||
2610 | SEQ_PUT_FIELD_RET(s, newline); | 2610 | SEQ_PUT_FIELD_RET(s, newline); |
2611 | 2611 | ||
2612 | return TRACE_TYPE_HANDLED; | 2612 | return TRACE_TYPE_HANDLED; |
2613 | } | 2613 | } |
2614 | 2614 | ||
2615 | static enum print_line_t print_bin_fmt(struct trace_iterator *iter) | 2615 | static enum print_line_t print_bin_fmt(struct trace_iterator *iter) |
2616 | { | 2616 | { |
2617 | struct trace_seq *s = &iter->seq; | 2617 | struct trace_seq *s = &iter->seq; |
2618 | struct trace_entry *entry; | 2618 | struct trace_entry *entry; |
2619 | struct trace_event *event; | 2619 | struct trace_event *event; |
2620 | 2620 | ||
2621 | entry = iter->ent; | 2621 | entry = iter->ent; |
2622 | 2622 | ||
2623 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2623 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { |
2624 | SEQ_PUT_FIELD_RET(s, entry->pid); | 2624 | SEQ_PUT_FIELD_RET(s, entry->pid); |
2625 | SEQ_PUT_FIELD_RET(s, iter->cpu); | 2625 | SEQ_PUT_FIELD_RET(s, iter->cpu); |
2626 | SEQ_PUT_FIELD_RET(s, iter->ts); | 2626 | SEQ_PUT_FIELD_RET(s, iter->ts); |
2627 | } | 2627 | } |
2628 | 2628 | ||
2629 | event = ftrace_find_event(entry->type); | 2629 | event = ftrace_find_event(entry->type); |
2630 | return event ? event->funcs->binary(iter, 0, event) : | 2630 | return event ? event->funcs->binary(iter, 0, event) : |
2631 | TRACE_TYPE_HANDLED; | 2631 | TRACE_TYPE_HANDLED; |
2632 | } | 2632 | } |
2633 | 2633 | ||
2634 | int trace_empty(struct trace_iterator *iter) | 2634 | int trace_empty(struct trace_iterator *iter) |
2635 | { | 2635 | { |
2636 | struct ring_buffer_iter *buf_iter; | 2636 | struct ring_buffer_iter *buf_iter; |
2637 | int cpu; | 2637 | int cpu; |
2638 | 2638 | ||
2639 | /* If we are looking at one CPU buffer, only check that one */ | 2639 | /* If we are looking at one CPU buffer, only check that one */ |
2640 | if (iter->cpu_file != RING_BUFFER_ALL_CPUS) { | 2640 | if (iter->cpu_file != RING_BUFFER_ALL_CPUS) { |
2641 | cpu = iter->cpu_file; | 2641 | cpu = iter->cpu_file; |
2642 | buf_iter = trace_buffer_iter(iter, cpu); | 2642 | buf_iter = trace_buffer_iter(iter, cpu); |
2643 | if (buf_iter) { | 2643 | if (buf_iter) { |
2644 | if (!ring_buffer_iter_empty(buf_iter)) | 2644 | if (!ring_buffer_iter_empty(buf_iter)) |
2645 | return 0; | 2645 | return 0; |
2646 | } else { | 2646 | } else { |
2647 | if (!ring_buffer_empty_cpu(iter->trace_buffer->buffer, cpu)) | 2647 | if (!ring_buffer_empty_cpu(iter->trace_buffer->buffer, cpu)) |
2648 | return 0; | 2648 | return 0; |
2649 | } | 2649 | } |
2650 | return 1; | 2650 | return 1; |
2651 | } | 2651 | } |
2652 | 2652 | ||
2653 | for_each_tracing_cpu(cpu) { | 2653 | for_each_tracing_cpu(cpu) { |
2654 | buf_iter = trace_buffer_iter(iter, cpu); | 2654 | buf_iter = trace_buffer_iter(iter, cpu); |
2655 | if (buf_iter) { | 2655 | if (buf_iter) { |
2656 | if (!ring_buffer_iter_empty(buf_iter)) | 2656 | if (!ring_buffer_iter_empty(buf_iter)) |
2657 | return 0; | 2657 | return 0; |
2658 | } else { | 2658 | } else { |
2659 | if (!ring_buffer_empty_cpu(iter->trace_buffer->buffer, cpu)) | 2659 | if (!ring_buffer_empty_cpu(iter->trace_buffer->buffer, cpu)) |
2660 | return 0; | 2660 | return 0; |
2661 | } | 2661 | } |
2662 | } | 2662 | } |
2663 | 2663 | ||
2664 | return 1; | 2664 | return 1; |
2665 | } | 2665 | } |
2666 | 2666 | ||
2667 | /* Called with trace_event_read_lock() held. */ | 2667 | /* Called with trace_event_read_lock() held. */ |
2668 | enum print_line_t print_trace_line(struct trace_iterator *iter) | 2668 | enum print_line_t print_trace_line(struct trace_iterator *iter) |
2669 | { | 2669 | { |
2670 | enum print_line_t ret; | 2670 | enum print_line_t ret; |
2671 | 2671 | ||
2672 | if (iter->lost_events && | 2672 | if (iter->lost_events && |
2673 | !trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n", | 2673 | !trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n", |
2674 | iter->cpu, iter->lost_events)) | 2674 | iter->cpu, iter->lost_events)) |
2675 | return TRACE_TYPE_PARTIAL_LINE; | 2675 | return TRACE_TYPE_PARTIAL_LINE; |
2676 | 2676 | ||
2677 | if (iter->trace && iter->trace->print_line) { | 2677 | if (iter->trace && iter->trace->print_line) { |
2678 | ret = iter->trace->print_line(iter); | 2678 | ret = iter->trace->print_line(iter); |
2679 | if (ret != TRACE_TYPE_UNHANDLED) | 2679 | if (ret != TRACE_TYPE_UNHANDLED) |
2680 | return ret; | 2680 | return ret; |
2681 | } | 2681 | } |
2682 | 2682 | ||
2683 | if (iter->ent->type == TRACE_BPUTS && | 2683 | if (iter->ent->type == TRACE_BPUTS && |
2684 | trace_flags & TRACE_ITER_PRINTK && | 2684 | trace_flags & TRACE_ITER_PRINTK && |
2685 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) | 2685 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) |
2686 | return trace_print_bputs_msg_only(iter); | 2686 | return trace_print_bputs_msg_only(iter); |
2687 | 2687 | ||
2688 | if (iter->ent->type == TRACE_BPRINT && | 2688 | if (iter->ent->type == TRACE_BPRINT && |
2689 | trace_flags & TRACE_ITER_PRINTK && | 2689 | trace_flags & TRACE_ITER_PRINTK && |
2690 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) | 2690 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) |
2691 | return trace_print_bprintk_msg_only(iter); | 2691 | return trace_print_bprintk_msg_only(iter); |
2692 | 2692 | ||
2693 | if (iter->ent->type == TRACE_PRINT && | 2693 | if (iter->ent->type == TRACE_PRINT && |
2694 | trace_flags & TRACE_ITER_PRINTK && | 2694 | trace_flags & TRACE_ITER_PRINTK && |
2695 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) | 2695 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) |
2696 | return trace_print_printk_msg_only(iter); | 2696 | return trace_print_printk_msg_only(iter); |
2697 | 2697 | ||
2698 | if (trace_flags & TRACE_ITER_BIN) | 2698 | if (trace_flags & TRACE_ITER_BIN) |
2699 | return print_bin_fmt(iter); | 2699 | return print_bin_fmt(iter); |
2700 | 2700 | ||
2701 | if (trace_flags & TRACE_ITER_HEX) | 2701 | if (trace_flags & TRACE_ITER_HEX) |
2702 | return print_hex_fmt(iter); | 2702 | return print_hex_fmt(iter); |
2703 | 2703 | ||
2704 | if (trace_flags & TRACE_ITER_RAW) | 2704 | if (trace_flags & TRACE_ITER_RAW) |
2705 | return print_raw_fmt(iter); | 2705 | return print_raw_fmt(iter); |
2706 | 2706 | ||
2707 | return print_trace_fmt(iter); | 2707 | return print_trace_fmt(iter); |
2708 | } | 2708 | } |
2709 | 2709 | ||
2710 | void trace_latency_header(struct seq_file *m) | 2710 | void trace_latency_header(struct seq_file *m) |
2711 | { | 2711 | { |
2712 | struct trace_iterator *iter = m->private; | 2712 | struct trace_iterator *iter = m->private; |
2713 | 2713 | ||
2714 | /* print nothing if the buffers are empty */ | 2714 | /* print nothing if the buffers are empty */ |
2715 | if (trace_empty(iter)) | 2715 | if (trace_empty(iter)) |
2716 | return; | 2716 | return; |
2717 | 2717 | ||
2718 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) | 2718 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) |
2719 | print_trace_header(m, iter); | 2719 | print_trace_header(m, iter); |
2720 | 2720 | ||
2721 | if (!(trace_flags & TRACE_ITER_VERBOSE)) | 2721 | if (!(trace_flags & TRACE_ITER_VERBOSE)) |
2722 | print_lat_help_header(m); | 2722 | print_lat_help_header(m); |
2723 | } | 2723 | } |
2724 | 2724 | ||
2725 | void trace_default_header(struct seq_file *m) | 2725 | void trace_default_header(struct seq_file *m) |
2726 | { | 2726 | { |
2727 | struct trace_iterator *iter = m->private; | 2727 | struct trace_iterator *iter = m->private; |
2728 | 2728 | ||
2729 | if (!(trace_flags & TRACE_ITER_CONTEXT_INFO)) | 2729 | if (!(trace_flags & TRACE_ITER_CONTEXT_INFO)) |
2730 | return; | 2730 | return; |
2731 | 2731 | ||
2732 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) { | 2732 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) { |
2733 | /* print nothing if the buffers are empty */ | 2733 | /* print nothing if the buffers are empty */ |
2734 | if (trace_empty(iter)) | 2734 | if (trace_empty(iter)) |
2735 | return; | 2735 | return; |
2736 | print_trace_header(m, iter); | 2736 | print_trace_header(m, iter); |
2737 | if (!(trace_flags & TRACE_ITER_VERBOSE)) | 2737 | if (!(trace_flags & TRACE_ITER_VERBOSE)) |
2738 | print_lat_help_header(m); | 2738 | print_lat_help_header(m); |
2739 | } else { | 2739 | } else { |
2740 | if (!(trace_flags & TRACE_ITER_VERBOSE)) { | 2740 | if (!(trace_flags & TRACE_ITER_VERBOSE)) { |
2741 | if (trace_flags & TRACE_ITER_IRQ_INFO) | 2741 | if (trace_flags & TRACE_ITER_IRQ_INFO) |
2742 | print_func_help_header_irq(iter->trace_buffer, m); | 2742 | print_func_help_header_irq(iter->trace_buffer, m); |
2743 | else | 2743 | else |
2744 | print_func_help_header(iter->trace_buffer, m); | 2744 | print_func_help_header(iter->trace_buffer, m); |
2745 | } | 2745 | } |
2746 | } | 2746 | } |
2747 | } | 2747 | } |
2748 | 2748 | ||
2749 | static void test_ftrace_alive(struct seq_file *m) | 2749 | static void test_ftrace_alive(struct seq_file *m) |
2750 | { | 2750 | { |
2751 | if (!ftrace_is_dead()) | 2751 | if (!ftrace_is_dead()) |
2752 | return; | 2752 | return; |
2753 | seq_printf(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n"); | 2753 | seq_printf(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n"); |
2754 | seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n"); | 2754 | seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n"); |
2755 | } | 2755 | } |
2756 | 2756 | ||
2757 | #ifdef CONFIG_TRACER_MAX_TRACE | 2757 | #ifdef CONFIG_TRACER_MAX_TRACE |
2758 | static void show_snapshot_main_help(struct seq_file *m) | 2758 | static void show_snapshot_main_help(struct seq_file *m) |
2759 | { | 2759 | { |
2760 | seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n"); | 2760 | seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n"); |
2761 | seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); | 2761 | seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); |
2762 | seq_printf(m, "# Takes a snapshot of the main buffer.\n"); | 2762 | seq_printf(m, "# Takes a snapshot of the main buffer.\n"); |
2763 | seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate)\n"); | 2763 | seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate)\n"); |
2764 | seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); | 2764 | seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); |
2765 | seq_printf(m, "# is not a '0' or '1')\n"); | 2765 | seq_printf(m, "# is not a '0' or '1')\n"); |
2766 | } | 2766 | } |
2767 | 2767 | ||
2768 | static void show_snapshot_percpu_help(struct seq_file *m) | 2768 | static void show_snapshot_percpu_help(struct seq_file *m) |
2769 | { | 2769 | { |
2770 | seq_printf(m, "# echo 0 > snapshot : Invalid for per_cpu snapshot file.\n"); | 2770 | seq_printf(m, "# echo 0 > snapshot : Invalid for per_cpu snapshot file.\n"); |
2771 | #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP | 2771 | #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP |
2772 | seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); | 2772 | seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); |
2773 | seq_printf(m, "# Takes a snapshot of the main buffer for this cpu.\n"); | 2773 | seq_printf(m, "# Takes a snapshot of the main buffer for this cpu.\n"); |
2774 | #else | 2774 | #else |
2775 | seq_printf(m, "# echo 1 > snapshot : Not supported with this kernel.\n"); | 2775 | seq_printf(m, "# echo 1 > snapshot : Not supported with this kernel.\n"); |
2776 | seq_printf(m, "# Must use main snapshot file to allocate.\n"); | 2776 | seq_printf(m, "# Must use main snapshot file to allocate.\n"); |
2777 | #endif | 2777 | #endif |
2778 | seq_printf(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n"); | 2778 | seq_printf(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n"); |
2779 | seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); | 2779 | seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); |
2780 | seq_printf(m, "# is not a '0' or '1')\n"); | 2780 | seq_printf(m, "# is not a '0' or '1')\n"); |
2781 | } | 2781 | } |
2782 | 2782 | ||
2783 | static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) | 2783 | static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) |
2784 | { | 2784 | { |
2785 | if (iter->tr->allocated_snapshot) | 2785 | if (iter->tr->allocated_snapshot) |
2786 | seq_printf(m, "#\n# * Snapshot is allocated *\n#\n"); | 2786 | seq_printf(m, "#\n# * Snapshot is allocated *\n#\n"); |
2787 | else | 2787 | else |
2788 | seq_printf(m, "#\n# * Snapshot is freed *\n#\n"); | 2788 | seq_printf(m, "#\n# * Snapshot is freed *\n#\n"); |
2789 | 2789 | ||
2790 | seq_printf(m, "# Snapshot commands:\n"); | 2790 | seq_printf(m, "# Snapshot commands:\n"); |
2791 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) | 2791 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) |
2792 | show_snapshot_main_help(m); | 2792 | show_snapshot_main_help(m); |
2793 | else | 2793 | else |
2794 | show_snapshot_percpu_help(m); | 2794 | show_snapshot_percpu_help(m); |
2795 | } | 2795 | } |
2796 | #else | 2796 | #else |
2797 | /* Should never be called */ | 2797 | /* Should never be called */ |
2798 | static inline void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) { } | 2798 | static inline void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) { } |
2799 | #endif | 2799 | #endif |
2800 | 2800 | ||
2801 | static int s_show(struct seq_file *m, void *v) | 2801 | static int s_show(struct seq_file *m, void *v) |
2802 | { | 2802 | { |
2803 | struct trace_iterator *iter = v; | 2803 | struct trace_iterator *iter = v; |
2804 | int ret; | 2804 | int ret; |
2805 | 2805 | ||
2806 | if (iter->ent == NULL) { | 2806 | if (iter->ent == NULL) { |
2807 | if (iter->tr) { | 2807 | if (iter->tr) { |
2808 | seq_printf(m, "# tracer: %s\n", iter->trace->name); | 2808 | seq_printf(m, "# tracer: %s\n", iter->trace->name); |
2809 | seq_puts(m, "#\n"); | 2809 | seq_puts(m, "#\n"); |
2810 | test_ftrace_alive(m); | 2810 | test_ftrace_alive(m); |
2811 | } | 2811 | } |
2812 | if (iter->snapshot && trace_empty(iter)) | 2812 | if (iter->snapshot && trace_empty(iter)) |
2813 | print_snapshot_help(m, iter); | 2813 | print_snapshot_help(m, iter); |
2814 | else if (iter->trace && iter->trace->print_header) | 2814 | else if (iter->trace && iter->trace->print_header) |
2815 | iter->trace->print_header(m); | 2815 | iter->trace->print_header(m); |
2816 | else | 2816 | else |
2817 | trace_default_header(m); | 2817 | trace_default_header(m); |
2818 | 2818 | ||
2819 | } else if (iter->leftover) { | 2819 | } else if (iter->leftover) { |
2820 | /* | 2820 | /* |
2821 | * If we filled the seq_file buffer earlier, we | 2821 | * If we filled the seq_file buffer earlier, we |
2822 | * want to just show it now. | 2822 | * want to just show it now. |
2823 | */ | 2823 | */ |
2824 | ret = trace_print_seq(m, &iter->seq); | 2824 | ret = trace_print_seq(m, &iter->seq); |
2825 | 2825 | ||
2826 | /* ret should this time be zero, but you never know */ | 2826 | /* ret should this time be zero, but you never know */ |
2827 | iter->leftover = ret; | 2827 | iter->leftover = ret; |
2828 | 2828 | ||
2829 | } else { | 2829 | } else { |
2830 | print_trace_line(iter); | 2830 | print_trace_line(iter); |
2831 | ret = trace_print_seq(m, &iter->seq); | 2831 | ret = trace_print_seq(m, &iter->seq); |
2832 | /* | 2832 | /* |
2833 | * If we overflow the seq_file buffer, then it will | 2833 | * If we overflow the seq_file buffer, then it will |
2834 | * ask us for this data again at start up. | 2834 | * ask us for this data again at start up. |
2835 | * Use that instead. | 2835 | * Use that instead. |
2836 | * ret is 0 if seq_file write succeeded. | 2836 | * ret is 0 if seq_file write succeeded. |
2837 | * -1 otherwise. | 2837 | * -1 otherwise. |
2838 | */ | 2838 | */ |
2839 | iter->leftover = ret; | 2839 | iter->leftover = ret; |
2840 | } | 2840 | } |
2841 | 2841 | ||
2842 | return 0; | 2842 | return 0; |
2843 | } | 2843 | } |
2844 | 2844 | ||
2845 | /* | 2845 | /* |
2846 | * Should be used after trace_array_get(), trace_types_lock | 2846 | * Should be used after trace_array_get(), trace_types_lock |
2847 | * ensures that i_cdev was already initialized. | 2847 | * ensures that i_cdev was already initialized. |
2848 | */ | 2848 | */ |
2849 | static inline int tracing_get_cpu(struct inode *inode) | 2849 | static inline int tracing_get_cpu(struct inode *inode) |
2850 | { | 2850 | { |
2851 | if (inode->i_cdev) /* See trace_create_cpu_file() */ | 2851 | if (inode->i_cdev) /* See trace_create_cpu_file() */ |
2852 | return (long)inode->i_cdev - 1; | 2852 | return (long)inode->i_cdev - 1; |
2853 | return RING_BUFFER_ALL_CPUS; | 2853 | return RING_BUFFER_ALL_CPUS; |
2854 | } | 2854 | } |
2855 | 2855 | ||
2856 | static const struct seq_operations tracer_seq_ops = { | 2856 | static const struct seq_operations tracer_seq_ops = { |
2857 | .start = s_start, | 2857 | .start = s_start, |
2858 | .next = s_next, | 2858 | .next = s_next, |
2859 | .stop = s_stop, | 2859 | .stop = s_stop, |
2860 | .show = s_show, | 2860 | .show = s_show, |
2861 | }; | 2861 | }; |
2862 | 2862 | ||
2863 | static struct trace_iterator * | 2863 | static struct trace_iterator * |
2864 | __tracing_open(struct inode *inode, struct file *file, bool snapshot) | 2864 | __tracing_open(struct inode *inode, struct file *file, bool snapshot) |
2865 | { | 2865 | { |
2866 | struct trace_array *tr = inode->i_private; | 2866 | struct trace_array *tr = inode->i_private; |
2867 | struct trace_iterator *iter; | 2867 | struct trace_iterator *iter; |
2868 | int cpu; | 2868 | int cpu; |
2869 | 2869 | ||
2870 | if (tracing_disabled) | 2870 | if (tracing_disabled) |
2871 | return ERR_PTR(-ENODEV); | 2871 | return ERR_PTR(-ENODEV); |
2872 | 2872 | ||
2873 | iter = __seq_open_private(file, &tracer_seq_ops, sizeof(*iter)); | 2873 | iter = __seq_open_private(file, &tracer_seq_ops, sizeof(*iter)); |
2874 | if (!iter) | 2874 | if (!iter) |
2875 | return ERR_PTR(-ENOMEM); | 2875 | return ERR_PTR(-ENOMEM); |
2876 | 2876 | ||
2877 | iter->buffer_iter = kzalloc(sizeof(*iter->buffer_iter) * num_possible_cpus(), | 2877 | iter->buffer_iter = kzalloc(sizeof(*iter->buffer_iter) * num_possible_cpus(), |
2878 | GFP_KERNEL); | 2878 | GFP_KERNEL); |
2879 | if (!iter->buffer_iter) | 2879 | if (!iter->buffer_iter) |
2880 | goto release; | 2880 | goto release; |
2881 | 2881 | ||
2882 | /* | 2882 | /* |
2883 | * We make a copy of the current tracer to avoid concurrent | 2883 | * We make a copy of the current tracer to avoid concurrent |
2884 | * changes on it while we are reading. | 2884 | * changes on it while we are reading. |
2885 | */ | 2885 | */ |
2886 | mutex_lock(&trace_types_lock); | 2886 | mutex_lock(&trace_types_lock); |
2887 | iter->trace = kzalloc(sizeof(*iter->trace), GFP_KERNEL); | 2887 | iter->trace = kzalloc(sizeof(*iter->trace), GFP_KERNEL); |
2888 | if (!iter->trace) | 2888 | if (!iter->trace) |
2889 | goto fail; | 2889 | goto fail; |
2890 | 2890 | ||
2891 | *iter->trace = *tr->current_trace; | 2891 | *iter->trace = *tr->current_trace; |
2892 | 2892 | ||
2893 | if (!zalloc_cpumask_var(&iter->started, GFP_KERNEL)) | 2893 | if (!zalloc_cpumask_var(&iter->started, GFP_KERNEL)) |
2894 | goto fail; | 2894 | goto fail; |
2895 | 2895 | ||
2896 | iter->tr = tr; | 2896 | iter->tr = tr; |
2897 | 2897 | ||
2898 | #ifdef CONFIG_TRACER_MAX_TRACE | 2898 | #ifdef CONFIG_TRACER_MAX_TRACE |
2899 | /* Currently only the top directory has a snapshot */ | 2899 | /* Currently only the top directory has a snapshot */ |
2900 | if (tr->current_trace->print_max || snapshot) | 2900 | if (tr->current_trace->print_max || snapshot) |
2901 | iter->trace_buffer = &tr->max_buffer; | 2901 | iter->trace_buffer = &tr->max_buffer; |
2902 | else | 2902 | else |
2903 | #endif | 2903 | #endif |
2904 | iter->trace_buffer = &tr->trace_buffer; | 2904 | iter->trace_buffer = &tr->trace_buffer; |
2905 | iter->snapshot = snapshot; | 2905 | iter->snapshot = snapshot; |
2906 | iter->pos = -1; | 2906 | iter->pos = -1; |
2907 | iter->cpu_file = tracing_get_cpu(inode); | 2907 | iter->cpu_file = tracing_get_cpu(inode); |
2908 | mutex_init(&iter->mutex); | 2908 | mutex_init(&iter->mutex); |
2909 | 2909 | ||
2910 | /* Notify the tracer early; before we stop tracing. */ | 2910 | /* Notify the tracer early; before we stop tracing. */ |
2911 | if (iter->trace && iter->trace->open) | 2911 | if (iter->trace && iter->trace->open) |
2912 | iter->trace->open(iter); | 2912 | iter->trace->open(iter); |
2913 | 2913 | ||
2914 | /* Annotate start of buffers if we had overruns */ | 2914 | /* Annotate start of buffers if we had overruns */ |
2915 | if (ring_buffer_overruns(iter->trace_buffer->buffer)) | 2915 | if (ring_buffer_overruns(iter->trace_buffer->buffer)) |
2916 | iter->iter_flags |= TRACE_FILE_ANNOTATE; | 2916 | iter->iter_flags |= TRACE_FILE_ANNOTATE; |
2917 | 2917 | ||
2918 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ | 2918 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ |
2919 | if (trace_clocks[tr->clock_id].in_ns) | 2919 | if (trace_clocks[tr->clock_id].in_ns) |
2920 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; | 2920 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; |
2921 | 2921 | ||
2922 | /* stop the trace while dumping if we are not opening "snapshot" */ | 2922 | /* stop the trace while dumping if we are not opening "snapshot" */ |
2923 | if (!iter->snapshot) | 2923 | if (!iter->snapshot) |
2924 | tracing_stop_tr(tr); | 2924 | tracing_stop_tr(tr); |
2925 | 2925 | ||
2926 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) { | 2926 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) { |
2927 | for_each_tracing_cpu(cpu) { | 2927 | for_each_tracing_cpu(cpu) { |
2928 | iter->buffer_iter[cpu] = | 2928 | iter->buffer_iter[cpu] = |
2929 | ring_buffer_read_prepare(iter->trace_buffer->buffer, cpu); | 2929 | ring_buffer_read_prepare(iter->trace_buffer->buffer, cpu); |
2930 | } | 2930 | } |
2931 | ring_buffer_read_prepare_sync(); | 2931 | ring_buffer_read_prepare_sync(); |
2932 | for_each_tracing_cpu(cpu) { | 2932 | for_each_tracing_cpu(cpu) { |
2933 | ring_buffer_read_start(iter->buffer_iter[cpu]); | 2933 | ring_buffer_read_start(iter->buffer_iter[cpu]); |
2934 | tracing_iter_reset(iter, cpu); | 2934 | tracing_iter_reset(iter, cpu); |
2935 | } | 2935 | } |
2936 | } else { | 2936 | } else { |
2937 | cpu = iter->cpu_file; | 2937 | cpu = iter->cpu_file; |
2938 | iter->buffer_iter[cpu] = | 2938 | iter->buffer_iter[cpu] = |
2939 | ring_buffer_read_prepare(iter->trace_buffer->buffer, cpu); | 2939 | ring_buffer_read_prepare(iter->trace_buffer->buffer, cpu); |
2940 | ring_buffer_read_prepare_sync(); | 2940 | ring_buffer_read_prepare_sync(); |
2941 | ring_buffer_read_start(iter->buffer_iter[cpu]); | 2941 | ring_buffer_read_start(iter->buffer_iter[cpu]); |
2942 | tracing_iter_reset(iter, cpu); | 2942 | tracing_iter_reset(iter, cpu); |
2943 | } | 2943 | } |
2944 | 2944 | ||
2945 | mutex_unlock(&trace_types_lock); | 2945 | mutex_unlock(&trace_types_lock); |
2946 | 2946 | ||
2947 | return iter; | 2947 | return iter; |
2948 | 2948 | ||
2949 | fail: | 2949 | fail: |
2950 | mutex_unlock(&trace_types_lock); | 2950 | mutex_unlock(&trace_types_lock); |
2951 | kfree(iter->trace); | 2951 | kfree(iter->trace); |
2952 | kfree(iter->buffer_iter); | 2952 | kfree(iter->buffer_iter); |
2953 | release: | 2953 | release: |
2954 | seq_release_private(inode, file); | 2954 | seq_release_private(inode, file); |
2955 | return ERR_PTR(-ENOMEM); | 2955 | return ERR_PTR(-ENOMEM); |
2956 | } | 2956 | } |
2957 | 2957 | ||
2958 | int tracing_open_generic(struct inode *inode, struct file *filp) | 2958 | int tracing_open_generic(struct inode *inode, struct file *filp) |
2959 | { | 2959 | { |
2960 | if (tracing_disabled) | 2960 | if (tracing_disabled) |
2961 | return -ENODEV; | 2961 | return -ENODEV; |
2962 | 2962 | ||
2963 | filp->private_data = inode->i_private; | 2963 | filp->private_data = inode->i_private; |
2964 | return 0; | 2964 | return 0; |
2965 | } | 2965 | } |
2966 | 2966 | ||
2967 | /* | 2967 | /* |
2968 | * Open and update trace_array ref count. | 2968 | * Open and update trace_array ref count. |
2969 | * Must have the current trace_array passed to it. | 2969 | * Must have the current trace_array passed to it. |
2970 | */ | 2970 | */ |
2971 | static int tracing_open_generic_tr(struct inode *inode, struct file *filp) | 2971 | static int tracing_open_generic_tr(struct inode *inode, struct file *filp) |
2972 | { | 2972 | { |
2973 | struct trace_array *tr = inode->i_private; | 2973 | struct trace_array *tr = inode->i_private; |
2974 | 2974 | ||
2975 | if (tracing_disabled) | 2975 | if (tracing_disabled) |
2976 | return -ENODEV; | 2976 | return -ENODEV; |
2977 | 2977 | ||
2978 | if (trace_array_get(tr) < 0) | 2978 | if (trace_array_get(tr) < 0) |
2979 | return -ENODEV; | 2979 | return -ENODEV; |
2980 | 2980 | ||
2981 | filp->private_data = inode->i_private; | 2981 | filp->private_data = inode->i_private; |
2982 | 2982 | ||
2983 | return 0; | 2983 | return 0; |
2984 | } | 2984 | } |
2985 | 2985 | ||
2986 | static int tracing_release(struct inode *inode, struct file *file) | 2986 | static int tracing_release(struct inode *inode, struct file *file) |
2987 | { | 2987 | { |
2988 | struct trace_array *tr = inode->i_private; | 2988 | struct trace_array *tr = inode->i_private; |
2989 | struct seq_file *m = file->private_data; | 2989 | struct seq_file *m = file->private_data; |
2990 | struct trace_iterator *iter; | 2990 | struct trace_iterator *iter; |
2991 | int cpu; | 2991 | int cpu; |
2992 | 2992 | ||
2993 | if (!(file->f_mode & FMODE_READ)) { | 2993 | if (!(file->f_mode & FMODE_READ)) { |
2994 | trace_array_put(tr); | 2994 | trace_array_put(tr); |
2995 | return 0; | 2995 | return 0; |
2996 | } | 2996 | } |
2997 | 2997 | ||
2998 | /* Writes do not use seq_file */ | 2998 | /* Writes do not use seq_file */ |
2999 | iter = m->private; | 2999 | iter = m->private; |
3000 | mutex_lock(&trace_types_lock); | 3000 | mutex_lock(&trace_types_lock); |
3001 | 3001 | ||
3002 | for_each_tracing_cpu(cpu) { | 3002 | for_each_tracing_cpu(cpu) { |
3003 | if (iter->buffer_iter[cpu]) | 3003 | if (iter->buffer_iter[cpu]) |
3004 | ring_buffer_read_finish(iter->buffer_iter[cpu]); | 3004 | ring_buffer_read_finish(iter->buffer_iter[cpu]); |
3005 | } | 3005 | } |
3006 | 3006 | ||
3007 | if (iter->trace && iter->trace->close) | 3007 | if (iter->trace && iter->trace->close) |
3008 | iter->trace->close(iter); | 3008 | iter->trace->close(iter); |
3009 | 3009 | ||
3010 | if (!iter->snapshot) | 3010 | if (!iter->snapshot) |
3011 | /* reenable tracing if it was previously enabled */ | 3011 | /* reenable tracing if it was previously enabled */ |
3012 | tracing_start_tr(tr); | 3012 | tracing_start_tr(tr); |
3013 | 3013 | ||
3014 | __trace_array_put(tr); | 3014 | __trace_array_put(tr); |
3015 | 3015 | ||
3016 | mutex_unlock(&trace_types_lock); | 3016 | mutex_unlock(&trace_types_lock); |
3017 | 3017 | ||
3018 | mutex_destroy(&iter->mutex); | 3018 | mutex_destroy(&iter->mutex); |
3019 | free_cpumask_var(iter->started); | 3019 | free_cpumask_var(iter->started); |
3020 | kfree(iter->trace); | 3020 | kfree(iter->trace); |
3021 | kfree(iter->buffer_iter); | 3021 | kfree(iter->buffer_iter); |
3022 | seq_release_private(inode, file); | 3022 | seq_release_private(inode, file); |
3023 | 3023 | ||
3024 | return 0; | 3024 | return 0; |
3025 | } | 3025 | } |
3026 | 3026 | ||
3027 | static int tracing_release_generic_tr(struct inode *inode, struct file *file) | 3027 | static int tracing_release_generic_tr(struct inode *inode, struct file *file) |
3028 | { | 3028 | { |
3029 | struct trace_array *tr = inode->i_private; | 3029 | struct trace_array *tr = inode->i_private; |
3030 | 3030 | ||
3031 | trace_array_put(tr); | 3031 | trace_array_put(tr); |
3032 | return 0; | 3032 | return 0; |
3033 | } | 3033 | } |
3034 | 3034 | ||
3035 | static int tracing_single_release_tr(struct inode *inode, struct file *file) | 3035 | static int tracing_single_release_tr(struct inode *inode, struct file *file) |
3036 | { | 3036 | { |
3037 | struct trace_array *tr = inode->i_private; | 3037 | struct trace_array *tr = inode->i_private; |
3038 | 3038 | ||
3039 | trace_array_put(tr); | 3039 | trace_array_put(tr); |
3040 | 3040 | ||
3041 | return single_release(inode, file); | 3041 | return single_release(inode, file); |
3042 | } | 3042 | } |
3043 | 3043 | ||
3044 | static int tracing_open(struct inode *inode, struct file *file) | 3044 | static int tracing_open(struct inode *inode, struct file *file) |
3045 | { | 3045 | { |
3046 | struct trace_array *tr = inode->i_private; | 3046 | struct trace_array *tr = inode->i_private; |
3047 | struct trace_iterator *iter; | 3047 | struct trace_iterator *iter; |
3048 | int ret = 0; | 3048 | int ret = 0; |
3049 | 3049 | ||
3050 | if (trace_array_get(tr) < 0) | 3050 | if (trace_array_get(tr) < 0) |
3051 | return -ENODEV; | 3051 | return -ENODEV; |
3052 | 3052 | ||
3053 | /* If this file was open for write, then erase contents */ | 3053 | /* If this file was open for write, then erase contents */ |
3054 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { | 3054 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { |
3055 | int cpu = tracing_get_cpu(inode); | 3055 | int cpu = tracing_get_cpu(inode); |
3056 | 3056 | ||
3057 | if (cpu == RING_BUFFER_ALL_CPUS) | 3057 | if (cpu == RING_BUFFER_ALL_CPUS) |
3058 | tracing_reset_online_cpus(&tr->trace_buffer); | 3058 | tracing_reset_online_cpus(&tr->trace_buffer); |
3059 | else | 3059 | else |
3060 | tracing_reset(&tr->trace_buffer, cpu); | 3060 | tracing_reset(&tr->trace_buffer, cpu); |
3061 | } | 3061 | } |
3062 | 3062 | ||
3063 | if (file->f_mode & FMODE_READ) { | 3063 | if (file->f_mode & FMODE_READ) { |
3064 | iter = __tracing_open(inode, file, false); | 3064 | iter = __tracing_open(inode, file, false); |
3065 | if (IS_ERR(iter)) | 3065 | if (IS_ERR(iter)) |
3066 | ret = PTR_ERR(iter); | 3066 | ret = PTR_ERR(iter); |
3067 | else if (trace_flags & TRACE_ITER_LATENCY_FMT) | 3067 | else if (trace_flags & TRACE_ITER_LATENCY_FMT) |
3068 | iter->iter_flags |= TRACE_FILE_LAT_FMT; | 3068 | iter->iter_flags |= TRACE_FILE_LAT_FMT; |
3069 | } | 3069 | } |
3070 | 3070 | ||
3071 | if (ret < 0) | 3071 | if (ret < 0) |
3072 | trace_array_put(tr); | 3072 | trace_array_put(tr); |
3073 | 3073 | ||
3074 | return ret; | 3074 | return ret; |
3075 | } | 3075 | } |
3076 | 3076 | ||
3077 | static void * | 3077 | static void * |
3078 | t_next(struct seq_file *m, void *v, loff_t *pos) | 3078 | t_next(struct seq_file *m, void *v, loff_t *pos) |
3079 | { | 3079 | { |
3080 | struct tracer *t = v; | 3080 | struct tracer *t = v; |
3081 | 3081 | ||
3082 | (*pos)++; | 3082 | (*pos)++; |
3083 | 3083 | ||
3084 | if (t) | 3084 | if (t) |
3085 | t = t->next; | 3085 | t = t->next; |
3086 | 3086 | ||
3087 | return t; | 3087 | return t; |
3088 | } | 3088 | } |
3089 | 3089 | ||
3090 | static void *t_start(struct seq_file *m, loff_t *pos) | 3090 | static void *t_start(struct seq_file *m, loff_t *pos) |
3091 | { | 3091 | { |
3092 | struct tracer *t; | 3092 | struct tracer *t; |
3093 | loff_t l = 0; | 3093 | loff_t l = 0; |
3094 | 3094 | ||
3095 | mutex_lock(&trace_types_lock); | 3095 | mutex_lock(&trace_types_lock); |
3096 | for (t = trace_types; t && l < *pos; t = t_next(m, t, &l)) | 3096 | for (t = trace_types; t && l < *pos; t = t_next(m, t, &l)) |
3097 | ; | 3097 | ; |
3098 | 3098 | ||
3099 | return t; | 3099 | return t; |
3100 | } | 3100 | } |
3101 | 3101 | ||
3102 | static void t_stop(struct seq_file *m, void *p) | 3102 | static void t_stop(struct seq_file *m, void *p) |
3103 | { | 3103 | { |
3104 | mutex_unlock(&trace_types_lock); | 3104 | mutex_unlock(&trace_types_lock); |
3105 | } | 3105 | } |
3106 | 3106 | ||
3107 | static int t_show(struct seq_file *m, void *v) | 3107 | static int t_show(struct seq_file *m, void *v) |
3108 | { | 3108 | { |
3109 | struct tracer *t = v; | 3109 | struct tracer *t = v; |
3110 | 3110 | ||
3111 | if (!t) | 3111 | if (!t) |
3112 | return 0; | 3112 | return 0; |
3113 | 3113 | ||
3114 | seq_printf(m, "%s", t->name); | 3114 | seq_printf(m, "%s", t->name); |
3115 | if (t->next) | 3115 | if (t->next) |
3116 | seq_putc(m, ' '); | 3116 | seq_putc(m, ' '); |
3117 | else | 3117 | else |
3118 | seq_putc(m, '\n'); | 3118 | seq_putc(m, '\n'); |
3119 | 3119 | ||
3120 | return 0; | 3120 | return 0; |
3121 | } | 3121 | } |
3122 | 3122 | ||
3123 | static const struct seq_operations show_traces_seq_ops = { | 3123 | static const struct seq_operations show_traces_seq_ops = { |
3124 | .start = t_start, | 3124 | .start = t_start, |
3125 | .next = t_next, | 3125 | .next = t_next, |
3126 | .stop = t_stop, | 3126 | .stop = t_stop, |
3127 | .show = t_show, | 3127 | .show = t_show, |
3128 | }; | 3128 | }; |
3129 | 3129 | ||
3130 | static int show_traces_open(struct inode *inode, struct file *file) | 3130 | static int show_traces_open(struct inode *inode, struct file *file) |
3131 | { | 3131 | { |
3132 | if (tracing_disabled) | 3132 | if (tracing_disabled) |
3133 | return -ENODEV; | 3133 | return -ENODEV; |
3134 | 3134 | ||
3135 | return seq_open(file, &show_traces_seq_ops); | 3135 | return seq_open(file, &show_traces_seq_ops); |
3136 | } | 3136 | } |
3137 | 3137 | ||
3138 | static ssize_t | 3138 | static ssize_t |
3139 | tracing_write_stub(struct file *filp, const char __user *ubuf, | 3139 | tracing_write_stub(struct file *filp, const char __user *ubuf, |
3140 | size_t count, loff_t *ppos) | 3140 | size_t count, loff_t *ppos) |
3141 | { | 3141 | { |
3142 | return count; | 3142 | return count; |
3143 | } | 3143 | } |
3144 | 3144 | ||
3145 | static loff_t tracing_seek(struct file *file, loff_t offset, int origin) | 3145 | static loff_t tracing_seek(struct file *file, loff_t offset, int origin) |
3146 | { | 3146 | { |
3147 | if (file->f_mode & FMODE_READ) | 3147 | if (file->f_mode & FMODE_READ) |
3148 | return seq_lseek(file, offset, origin); | 3148 | return seq_lseek(file, offset, origin); |
3149 | else | 3149 | else |
3150 | return 0; | 3150 | return 0; |
3151 | } | 3151 | } |
3152 | 3152 | ||
3153 | static const struct file_operations tracing_fops = { | 3153 | static const struct file_operations tracing_fops = { |
3154 | .open = tracing_open, | 3154 | .open = tracing_open, |
3155 | .read = seq_read, | 3155 | .read = seq_read, |
3156 | .write = tracing_write_stub, | 3156 | .write = tracing_write_stub, |
3157 | .llseek = tracing_seek, | 3157 | .llseek = tracing_seek, |
3158 | .release = tracing_release, | 3158 | .release = tracing_release, |
3159 | }; | 3159 | }; |
3160 | 3160 | ||
3161 | static const struct file_operations show_traces_fops = { | 3161 | static const struct file_operations show_traces_fops = { |
3162 | .open = show_traces_open, | 3162 | .open = show_traces_open, |
3163 | .read = seq_read, | 3163 | .read = seq_read, |
3164 | .release = seq_release, | 3164 | .release = seq_release, |
3165 | .llseek = seq_lseek, | 3165 | .llseek = seq_lseek, |
3166 | }; | 3166 | }; |
3167 | 3167 | ||
3168 | /* | 3168 | /* |
3169 | * Only trace on a CPU if the bitmask is set: | ||
3170 | */ | ||
3171 | static cpumask_var_t tracing_cpumask; | ||
3172 | |||
3173 | /* | ||
3174 | * The tracer itself will not take this lock, but still we want | 3169 | * The tracer itself will not take this lock, but still we want |
3175 | * to provide a consistent cpumask to user-space: | 3170 | * to provide a consistent cpumask to user-space: |
3176 | */ | 3171 | */ |
3177 | static DEFINE_MUTEX(tracing_cpumask_update_lock); | 3172 | static DEFINE_MUTEX(tracing_cpumask_update_lock); |
3178 | 3173 | ||
3179 | /* | 3174 | /* |
3180 | * Temporary storage for the character representation of the | 3175 | * Temporary storage for the character representation of the |
3181 | * CPU bitmask (and one more byte for the newline): | 3176 | * CPU bitmask (and one more byte for the newline): |
3182 | */ | 3177 | */ |
3183 | static char mask_str[NR_CPUS + 1]; | 3178 | static char mask_str[NR_CPUS + 1]; |
3184 | 3179 | ||
3185 | static ssize_t | 3180 | static ssize_t |
3186 | tracing_cpumask_read(struct file *filp, char __user *ubuf, | 3181 | tracing_cpumask_read(struct file *filp, char __user *ubuf, |
3187 | size_t count, loff_t *ppos) | 3182 | size_t count, loff_t *ppos) |
3188 | { | 3183 | { |
3184 | struct trace_array *tr = file_inode(filp)->i_private; | ||
3189 | int len; | 3185 | int len; |
3190 | 3186 | ||
3191 | mutex_lock(&tracing_cpumask_update_lock); | 3187 | mutex_lock(&tracing_cpumask_update_lock); |
3192 | 3188 | ||
3193 | len = cpumask_scnprintf(mask_str, count, tracing_cpumask); | 3189 | len = cpumask_scnprintf(mask_str, count, tr->tracing_cpumask); |
3194 | if (count - len < 2) { | 3190 | if (count - len < 2) { |
3195 | count = -EINVAL; | 3191 | count = -EINVAL; |
3196 | goto out_err; | 3192 | goto out_err; |
3197 | } | 3193 | } |
3198 | len += sprintf(mask_str + len, "\n"); | 3194 | len += sprintf(mask_str + len, "\n"); |
3199 | count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1); | 3195 | count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1); |
3200 | 3196 | ||
3201 | out_err: | 3197 | out_err: |
3202 | mutex_unlock(&tracing_cpumask_update_lock); | 3198 | mutex_unlock(&tracing_cpumask_update_lock); |
3203 | 3199 | ||
3204 | return count; | 3200 | return count; |
3205 | } | 3201 | } |
3206 | 3202 | ||
3207 | static ssize_t | 3203 | static ssize_t |
3208 | tracing_cpumask_write(struct file *filp, const char __user *ubuf, | 3204 | tracing_cpumask_write(struct file *filp, const char __user *ubuf, |
3209 | size_t count, loff_t *ppos) | 3205 | size_t count, loff_t *ppos) |
3210 | { | 3206 | { |
3211 | struct trace_array *tr = filp->private_data; | 3207 | struct trace_array *tr = file_inode(filp)->i_private; |
3212 | cpumask_var_t tracing_cpumask_new; | 3208 | cpumask_var_t tracing_cpumask_new; |
3213 | int err, cpu; | 3209 | int err, cpu; |
3214 | 3210 | ||
3215 | if (!alloc_cpumask_var(&tracing_cpumask_new, GFP_KERNEL)) | 3211 | if (!alloc_cpumask_var(&tracing_cpumask_new, GFP_KERNEL)) |
3216 | return -ENOMEM; | 3212 | return -ENOMEM; |
3217 | 3213 | ||
3218 | err = cpumask_parse_user(ubuf, count, tracing_cpumask_new); | 3214 | err = cpumask_parse_user(ubuf, count, tracing_cpumask_new); |
3219 | if (err) | 3215 | if (err) |
3220 | goto err_unlock; | 3216 | goto err_unlock; |
3221 | 3217 | ||
3222 | mutex_lock(&tracing_cpumask_update_lock); | 3218 | mutex_lock(&tracing_cpumask_update_lock); |
3223 | 3219 | ||
3224 | local_irq_disable(); | 3220 | local_irq_disable(); |
3225 | arch_spin_lock(&ftrace_max_lock); | 3221 | arch_spin_lock(&ftrace_max_lock); |
3226 | for_each_tracing_cpu(cpu) { | 3222 | for_each_tracing_cpu(cpu) { |
3227 | /* | 3223 | /* |
3228 | * Increase/decrease the disabled counter if we are | 3224 | * Increase/decrease the disabled counter if we are |
3229 | * about to flip a bit in the cpumask: | 3225 | * about to flip a bit in the cpumask: |
3230 | */ | 3226 | */ |
3231 | if (cpumask_test_cpu(cpu, tracing_cpumask) && | 3227 | if (cpumask_test_cpu(cpu, tr->tracing_cpumask) && |
3232 | !cpumask_test_cpu(cpu, tracing_cpumask_new)) { | 3228 | !cpumask_test_cpu(cpu, tracing_cpumask_new)) { |
3233 | atomic_inc(&per_cpu_ptr(tr->trace_buffer.data, cpu)->disabled); | 3229 | atomic_inc(&per_cpu_ptr(tr->trace_buffer.data, cpu)->disabled); |
3234 | ring_buffer_record_disable_cpu(tr->trace_buffer.buffer, cpu); | 3230 | ring_buffer_record_disable_cpu(tr->trace_buffer.buffer, cpu); |
3235 | } | 3231 | } |
3236 | if (!cpumask_test_cpu(cpu, tracing_cpumask) && | 3232 | if (!cpumask_test_cpu(cpu, tr->tracing_cpumask) && |
3237 | cpumask_test_cpu(cpu, tracing_cpumask_new)) { | 3233 | cpumask_test_cpu(cpu, tracing_cpumask_new)) { |
3238 | atomic_dec(&per_cpu_ptr(tr->trace_buffer.data, cpu)->disabled); | 3234 | atomic_dec(&per_cpu_ptr(tr->trace_buffer.data, cpu)->disabled); |
3239 | ring_buffer_record_enable_cpu(tr->trace_buffer.buffer, cpu); | 3235 | ring_buffer_record_enable_cpu(tr->trace_buffer.buffer, cpu); |
3240 | } | 3236 | } |
3241 | } | 3237 | } |
3242 | arch_spin_unlock(&ftrace_max_lock); | 3238 | arch_spin_unlock(&ftrace_max_lock); |
3243 | local_irq_enable(); | 3239 | local_irq_enable(); |
3244 | 3240 | ||
3245 | cpumask_copy(tracing_cpumask, tracing_cpumask_new); | 3241 | cpumask_copy(tr->tracing_cpumask, tracing_cpumask_new); |
3246 | 3242 | ||
3247 | mutex_unlock(&tracing_cpumask_update_lock); | 3243 | mutex_unlock(&tracing_cpumask_update_lock); |
3248 | free_cpumask_var(tracing_cpumask_new); | 3244 | free_cpumask_var(tracing_cpumask_new); |
3249 | 3245 | ||
3250 | return count; | 3246 | return count; |
3251 | 3247 | ||
3252 | err_unlock: | 3248 | err_unlock: |
3253 | free_cpumask_var(tracing_cpumask_new); | 3249 | free_cpumask_var(tracing_cpumask_new); |
3254 | 3250 | ||
3255 | return err; | 3251 | return err; |
3256 | } | 3252 | } |
3257 | 3253 | ||
3258 | static const struct file_operations tracing_cpumask_fops = { | 3254 | static const struct file_operations tracing_cpumask_fops = { |
3259 | .open = tracing_open_generic, | 3255 | .open = tracing_open_generic_tr, |
3260 | .read = tracing_cpumask_read, | 3256 | .read = tracing_cpumask_read, |
3261 | .write = tracing_cpumask_write, | 3257 | .write = tracing_cpumask_write, |
3258 | .release = tracing_release_generic_tr, | ||
3262 | .llseek = generic_file_llseek, | 3259 | .llseek = generic_file_llseek, |
3263 | }; | 3260 | }; |
3264 | 3261 | ||
3265 | static int tracing_trace_options_show(struct seq_file *m, void *v) | 3262 | static int tracing_trace_options_show(struct seq_file *m, void *v) |
3266 | { | 3263 | { |
3267 | struct tracer_opt *trace_opts; | 3264 | struct tracer_opt *trace_opts; |
3268 | struct trace_array *tr = m->private; | 3265 | struct trace_array *tr = m->private; |
3269 | u32 tracer_flags; | 3266 | u32 tracer_flags; |
3270 | int i; | 3267 | int i; |
3271 | 3268 | ||
3272 | mutex_lock(&trace_types_lock); | 3269 | mutex_lock(&trace_types_lock); |
3273 | tracer_flags = tr->current_trace->flags->val; | 3270 | tracer_flags = tr->current_trace->flags->val; |
3274 | trace_opts = tr->current_trace->flags->opts; | 3271 | trace_opts = tr->current_trace->flags->opts; |
3275 | 3272 | ||
3276 | for (i = 0; trace_options[i]; i++) { | 3273 | for (i = 0; trace_options[i]; i++) { |
3277 | if (trace_flags & (1 << i)) | 3274 | if (trace_flags & (1 << i)) |
3278 | seq_printf(m, "%s\n", trace_options[i]); | 3275 | seq_printf(m, "%s\n", trace_options[i]); |
3279 | else | 3276 | else |
3280 | seq_printf(m, "no%s\n", trace_options[i]); | 3277 | seq_printf(m, "no%s\n", trace_options[i]); |
3281 | } | 3278 | } |
3282 | 3279 | ||
3283 | for (i = 0; trace_opts[i].name; i++) { | 3280 | for (i = 0; trace_opts[i].name; i++) { |
3284 | if (tracer_flags & trace_opts[i].bit) | 3281 | if (tracer_flags & trace_opts[i].bit) |
3285 | seq_printf(m, "%s\n", trace_opts[i].name); | 3282 | seq_printf(m, "%s\n", trace_opts[i].name); |
3286 | else | 3283 | else |
3287 | seq_printf(m, "no%s\n", trace_opts[i].name); | 3284 | seq_printf(m, "no%s\n", trace_opts[i].name); |
3288 | } | 3285 | } |
3289 | mutex_unlock(&trace_types_lock); | 3286 | mutex_unlock(&trace_types_lock); |
3290 | 3287 | ||
3291 | return 0; | 3288 | return 0; |
3292 | } | 3289 | } |
3293 | 3290 | ||
3294 | static int __set_tracer_option(struct tracer *trace, | 3291 | static int __set_tracer_option(struct tracer *trace, |
3295 | struct tracer_flags *tracer_flags, | 3292 | struct tracer_flags *tracer_flags, |
3296 | struct tracer_opt *opts, int neg) | 3293 | struct tracer_opt *opts, int neg) |
3297 | { | 3294 | { |
3298 | int ret; | 3295 | int ret; |
3299 | 3296 | ||
3300 | ret = trace->set_flag(tracer_flags->val, opts->bit, !neg); | 3297 | ret = trace->set_flag(tracer_flags->val, opts->bit, !neg); |
3301 | if (ret) | 3298 | if (ret) |
3302 | return ret; | 3299 | return ret; |
3303 | 3300 | ||
3304 | if (neg) | 3301 | if (neg) |
3305 | tracer_flags->val &= ~opts->bit; | 3302 | tracer_flags->val &= ~opts->bit; |
3306 | else | 3303 | else |
3307 | tracer_flags->val |= opts->bit; | 3304 | tracer_flags->val |= opts->bit; |
3308 | return 0; | 3305 | return 0; |
3309 | } | 3306 | } |
3310 | 3307 | ||
3311 | /* Try to assign a tracer specific option */ | 3308 | /* Try to assign a tracer specific option */ |
3312 | static int set_tracer_option(struct tracer *trace, char *cmp, int neg) | 3309 | static int set_tracer_option(struct tracer *trace, char *cmp, int neg) |
3313 | { | 3310 | { |
3314 | struct tracer_flags *tracer_flags = trace->flags; | 3311 | struct tracer_flags *tracer_flags = trace->flags; |
3315 | struct tracer_opt *opts = NULL; | 3312 | struct tracer_opt *opts = NULL; |
3316 | int i; | 3313 | int i; |
3317 | 3314 | ||
3318 | for (i = 0; tracer_flags->opts[i].name; i++) { | 3315 | for (i = 0; tracer_flags->opts[i].name; i++) { |
3319 | opts = &tracer_flags->opts[i]; | 3316 | opts = &tracer_flags->opts[i]; |
3320 | 3317 | ||
3321 | if (strcmp(cmp, opts->name) == 0) | 3318 | if (strcmp(cmp, opts->name) == 0) |
3322 | return __set_tracer_option(trace, trace->flags, | 3319 | return __set_tracer_option(trace, trace->flags, |
3323 | opts, neg); | 3320 | opts, neg); |
3324 | } | 3321 | } |
3325 | 3322 | ||
3326 | return -EINVAL; | 3323 | return -EINVAL; |
3327 | } | 3324 | } |
3328 | 3325 | ||
3329 | /* Some tracers require overwrite to stay enabled */ | 3326 | /* Some tracers require overwrite to stay enabled */ |
3330 | int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set) | 3327 | int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set) |
3331 | { | 3328 | { |
3332 | if (tracer->enabled && (mask & TRACE_ITER_OVERWRITE) && !set) | 3329 | if (tracer->enabled && (mask & TRACE_ITER_OVERWRITE) && !set) |
3333 | return -1; | 3330 | return -1; |
3334 | 3331 | ||
3335 | return 0; | 3332 | return 0; |
3336 | } | 3333 | } |
3337 | 3334 | ||
3338 | int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled) | 3335 | int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled) |
3339 | { | 3336 | { |
3340 | /* do nothing if flag is already set */ | 3337 | /* do nothing if flag is already set */ |
3341 | if (!!(trace_flags & mask) == !!enabled) | 3338 | if (!!(trace_flags & mask) == !!enabled) |
3342 | return 0; | 3339 | return 0; |
3343 | 3340 | ||
3344 | /* Give the tracer a chance to approve the change */ | 3341 | /* Give the tracer a chance to approve the change */ |
3345 | if (tr->current_trace->flag_changed) | 3342 | if (tr->current_trace->flag_changed) |
3346 | if (tr->current_trace->flag_changed(tr->current_trace, mask, !!enabled)) | 3343 | if (tr->current_trace->flag_changed(tr->current_trace, mask, !!enabled)) |
3347 | return -EINVAL; | 3344 | return -EINVAL; |
3348 | 3345 | ||
3349 | if (enabled) | 3346 | if (enabled) |
3350 | trace_flags |= mask; | 3347 | trace_flags |= mask; |
3351 | else | 3348 | else |
3352 | trace_flags &= ~mask; | 3349 | trace_flags &= ~mask; |
3353 | 3350 | ||
3354 | if (mask == TRACE_ITER_RECORD_CMD) | 3351 | if (mask == TRACE_ITER_RECORD_CMD) |
3355 | trace_event_enable_cmd_record(enabled); | 3352 | trace_event_enable_cmd_record(enabled); |
3356 | 3353 | ||
3357 | if (mask == TRACE_ITER_OVERWRITE) { | 3354 | if (mask == TRACE_ITER_OVERWRITE) { |
3358 | ring_buffer_change_overwrite(tr->trace_buffer.buffer, enabled); | 3355 | ring_buffer_change_overwrite(tr->trace_buffer.buffer, enabled); |
3359 | #ifdef CONFIG_TRACER_MAX_TRACE | 3356 | #ifdef CONFIG_TRACER_MAX_TRACE |
3360 | ring_buffer_change_overwrite(tr->max_buffer.buffer, enabled); | 3357 | ring_buffer_change_overwrite(tr->max_buffer.buffer, enabled); |
3361 | #endif | 3358 | #endif |
3362 | } | 3359 | } |
3363 | 3360 | ||
3364 | if (mask == TRACE_ITER_PRINTK) | 3361 | if (mask == TRACE_ITER_PRINTK) |
3365 | trace_printk_start_stop_comm(enabled); | 3362 | trace_printk_start_stop_comm(enabled); |
3366 | 3363 | ||
3367 | return 0; | 3364 | return 0; |
3368 | } | 3365 | } |
3369 | 3366 | ||
3370 | static int trace_set_options(struct trace_array *tr, char *option) | 3367 | static int trace_set_options(struct trace_array *tr, char *option) |
3371 | { | 3368 | { |
3372 | char *cmp; | 3369 | char *cmp; |
3373 | int neg = 0; | 3370 | int neg = 0; |
3374 | int ret = -ENODEV; | 3371 | int ret = -ENODEV; |
3375 | int i; | 3372 | int i; |
3376 | 3373 | ||
3377 | cmp = strstrip(option); | 3374 | cmp = strstrip(option); |
3378 | 3375 | ||
3379 | if (strncmp(cmp, "no", 2) == 0) { | 3376 | if (strncmp(cmp, "no", 2) == 0) { |
3380 | neg = 1; | 3377 | neg = 1; |
3381 | cmp += 2; | 3378 | cmp += 2; |
3382 | } | 3379 | } |
3383 | 3380 | ||
3384 | mutex_lock(&trace_types_lock); | 3381 | mutex_lock(&trace_types_lock); |
3385 | 3382 | ||
3386 | for (i = 0; trace_options[i]; i++) { | 3383 | for (i = 0; trace_options[i]; i++) { |
3387 | if (strcmp(cmp, trace_options[i]) == 0) { | 3384 | if (strcmp(cmp, trace_options[i]) == 0) { |
3388 | ret = set_tracer_flag(tr, 1 << i, !neg); | 3385 | ret = set_tracer_flag(tr, 1 << i, !neg); |
3389 | break; | 3386 | break; |
3390 | } | 3387 | } |
3391 | } | 3388 | } |
3392 | 3389 | ||
3393 | /* If no option could be set, test the specific tracer options */ | 3390 | /* If no option could be set, test the specific tracer options */ |
3394 | if (!trace_options[i]) | 3391 | if (!trace_options[i]) |
3395 | ret = set_tracer_option(tr->current_trace, cmp, neg); | 3392 | ret = set_tracer_option(tr->current_trace, cmp, neg); |
3396 | 3393 | ||
3397 | mutex_unlock(&trace_types_lock); | 3394 | mutex_unlock(&trace_types_lock); |
3398 | 3395 | ||
3399 | return ret; | 3396 | return ret; |
3400 | } | 3397 | } |
3401 | 3398 | ||
3402 | static ssize_t | 3399 | static ssize_t |
3403 | tracing_trace_options_write(struct file *filp, const char __user *ubuf, | 3400 | tracing_trace_options_write(struct file *filp, const char __user *ubuf, |
3404 | size_t cnt, loff_t *ppos) | 3401 | size_t cnt, loff_t *ppos) |
3405 | { | 3402 | { |
3406 | struct seq_file *m = filp->private_data; | 3403 | struct seq_file *m = filp->private_data; |
3407 | struct trace_array *tr = m->private; | 3404 | struct trace_array *tr = m->private; |
3408 | char buf[64]; | 3405 | char buf[64]; |
3409 | int ret; | 3406 | int ret; |
3410 | 3407 | ||
3411 | if (cnt >= sizeof(buf)) | 3408 | if (cnt >= sizeof(buf)) |
3412 | return -EINVAL; | 3409 | return -EINVAL; |
3413 | 3410 | ||
3414 | if (copy_from_user(&buf, ubuf, cnt)) | 3411 | if (copy_from_user(&buf, ubuf, cnt)) |
3415 | return -EFAULT; | 3412 | return -EFAULT; |
3416 | 3413 | ||
3417 | buf[cnt] = 0; | 3414 | buf[cnt] = 0; |
3418 | 3415 | ||
3419 | ret = trace_set_options(tr, buf); | 3416 | ret = trace_set_options(tr, buf); |
3420 | if (ret < 0) | 3417 | if (ret < 0) |
3421 | return ret; | 3418 | return ret; |
3422 | 3419 | ||
3423 | *ppos += cnt; | 3420 | *ppos += cnt; |
3424 | 3421 | ||
3425 | return cnt; | 3422 | return cnt; |
3426 | } | 3423 | } |
3427 | 3424 | ||
3428 | static int tracing_trace_options_open(struct inode *inode, struct file *file) | 3425 | static int tracing_trace_options_open(struct inode *inode, struct file *file) |
3429 | { | 3426 | { |
3430 | struct trace_array *tr = inode->i_private; | 3427 | struct trace_array *tr = inode->i_private; |
3431 | int ret; | 3428 | int ret; |
3432 | 3429 | ||
3433 | if (tracing_disabled) | 3430 | if (tracing_disabled) |
3434 | return -ENODEV; | 3431 | return -ENODEV; |
3435 | 3432 | ||
3436 | if (trace_array_get(tr) < 0) | 3433 | if (trace_array_get(tr) < 0) |
3437 | return -ENODEV; | 3434 | return -ENODEV; |
3438 | 3435 | ||
3439 | ret = single_open(file, tracing_trace_options_show, inode->i_private); | 3436 | ret = single_open(file, tracing_trace_options_show, inode->i_private); |
3440 | if (ret < 0) | 3437 | if (ret < 0) |
3441 | trace_array_put(tr); | 3438 | trace_array_put(tr); |
3442 | 3439 | ||
3443 | return ret; | 3440 | return ret; |
3444 | } | 3441 | } |
3445 | 3442 | ||
3446 | static const struct file_operations tracing_iter_fops = { | 3443 | static const struct file_operations tracing_iter_fops = { |
3447 | .open = tracing_trace_options_open, | 3444 | .open = tracing_trace_options_open, |
3448 | .read = seq_read, | 3445 | .read = seq_read, |
3449 | .llseek = seq_lseek, | 3446 | .llseek = seq_lseek, |
3450 | .release = tracing_single_release_tr, | 3447 | .release = tracing_single_release_tr, |
3451 | .write = tracing_trace_options_write, | 3448 | .write = tracing_trace_options_write, |
3452 | }; | 3449 | }; |
3453 | 3450 | ||
3454 | static const char readme_msg[] = | 3451 | static const char readme_msg[] = |
3455 | "tracing mini-HOWTO:\n\n" | 3452 | "tracing mini-HOWTO:\n\n" |
3456 | "# echo 0 > tracing_on : quick way to disable tracing\n" | 3453 | "# echo 0 > tracing_on : quick way to disable tracing\n" |
3457 | "# echo 1 > tracing_on : quick way to re-enable tracing\n\n" | 3454 | "# echo 1 > tracing_on : quick way to re-enable tracing\n\n" |
3458 | " Important files:\n" | 3455 | " Important files:\n" |
3459 | " trace\t\t\t- The static contents of the buffer\n" | 3456 | " trace\t\t\t- The static contents of the buffer\n" |
3460 | "\t\t\t To clear the buffer write into this file: echo > trace\n" | 3457 | "\t\t\t To clear the buffer write into this file: echo > trace\n" |
3461 | " trace_pipe\t\t- A consuming read to see the contents of the buffer\n" | 3458 | " trace_pipe\t\t- A consuming read to see the contents of the buffer\n" |
3462 | " current_tracer\t- function and latency tracers\n" | 3459 | " current_tracer\t- function and latency tracers\n" |
3463 | " available_tracers\t- list of configured tracers for current_tracer\n" | 3460 | " available_tracers\t- list of configured tracers for current_tracer\n" |
3464 | " buffer_size_kb\t- view and modify size of per cpu buffer\n" | 3461 | " buffer_size_kb\t- view and modify size of per cpu buffer\n" |
3465 | " buffer_total_size_kb - view total size of all cpu buffers\n\n" | 3462 | " buffer_total_size_kb - view total size of all cpu buffers\n\n" |
3466 | " trace_clock\t\t-change the clock used to order events\n" | 3463 | " trace_clock\t\t-change the clock used to order events\n" |
3467 | " local: Per cpu clock but may not be synced across CPUs\n" | 3464 | " local: Per cpu clock but may not be synced across CPUs\n" |
3468 | " global: Synced across CPUs but slows tracing down.\n" | 3465 | " global: Synced across CPUs but slows tracing down.\n" |
3469 | " counter: Not a clock, but just an increment\n" | 3466 | " counter: Not a clock, but just an increment\n" |
3470 | " uptime: Jiffy counter from time of boot\n" | 3467 | " uptime: Jiffy counter from time of boot\n" |
3471 | " perf: Same clock that perf events use\n" | 3468 | " perf: Same clock that perf events use\n" |
3472 | #ifdef CONFIG_X86_64 | 3469 | #ifdef CONFIG_X86_64 |
3473 | " x86-tsc: TSC cycle counter\n" | 3470 | " x86-tsc: TSC cycle counter\n" |
3474 | #endif | 3471 | #endif |
3475 | "\n trace_marker\t\t- Writes into this file writes into the kernel buffer\n" | 3472 | "\n trace_marker\t\t- Writes into this file writes into the kernel buffer\n" |
3476 | " tracing_cpumask\t- Limit which CPUs to trace\n" | 3473 | " tracing_cpumask\t- Limit which CPUs to trace\n" |
3477 | " instances\t\t- Make sub-buffers with: mkdir instances/foo\n" | 3474 | " instances\t\t- Make sub-buffers with: mkdir instances/foo\n" |
3478 | "\t\t\t Remove sub-buffer with rmdir\n" | 3475 | "\t\t\t Remove sub-buffer with rmdir\n" |
3479 | " trace_options\t\t- Set format or modify how tracing happens\n" | 3476 | " trace_options\t\t- Set format or modify how tracing happens\n" |
3480 | "\t\t\t Disable an option by adding a suffix 'no' to the option name\n" | 3477 | "\t\t\t Disable an option by adding a suffix 'no' to the option name\n" |
3481 | #ifdef CONFIG_DYNAMIC_FTRACE | 3478 | #ifdef CONFIG_DYNAMIC_FTRACE |
3482 | "\n available_filter_functions - list of functions that can be filtered on\n" | 3479 | "\n available_filter_functions - list of functions that can be filtered on\n" |
3483 | " set_ftrace_filter\t- echo function name in here to only trace these functions\n" | 3480 | " set_ftrace_filter\t- echo function name in here to only trace these functions\n" |
3484 | " accepts: func_full_name, *func_end, func_begin*, *func_middle*\n" | 3481 | " accepts: func_full_name, *func_end, func_begin*, *func_middle*\n" |
3485 | " modules: Can select a group via module\n" | 3482 | " modules: Can select a group via module\n" |
3486 | " Format: :mod:<module-name>\n" | 3483 | " Format: :mod:<module-name>\n" |
3487 | " example: echo :mod:ext3 > set_ftrace_filter\n" | 3484 | " example: echo :mod:ext3 > set_ftrace_filter\n" |
3488 | " triggers: a command to perform when function is hit\n" | 3485 | " triggers: a command to perform when function is hit\n" |
3489 | " Format: <function>:<trigger>[:count]\n" | 3486 | " Format: <function>:<trigger>[:count]\n" |
3490 | " trigger: traceon, traceoff\n" | 3487 | " trigger: traceon, traceoff\n" |
3491 | " enable_event:<system>:<event>\n" | 3488 | " enable_event:<system>:<event>\n" |
3492 | " disable_event:<system>:<event>\n" | 3489 | " disable_event:<system>:<event>\n" |
3493 | #ifdef CONFIG_STACKTRACE | 3490 | #ifdef CONFIG_STACKTRACE |
3494 | " stacktrace\n" | 3491 | " stacktrace\n" |
3495 | #endif | 3492 | #endif |
3496 | #ifdef CONFIG_TRACER_SNAPSHOT | 3493 | #ifdef CONFIG_TRACER_SNAPSHOT |
3497 | " snapshot\n" | 3494 | " snapshot\n" |
3498 | #endif | 3495 | #endif |
3499 | " example: echo do_fault:traceoff > set_ftrace_filter\n" | 3496 | " example: echo do_fault:traceoff > set_ftrace_filter\n" |
3500 | " echo do_trap:traceoff:3 > set_ftrace_filter\n" | 3497 | " echo do_trap:traceoff:3 > set_ftrace_filter\n" |
3501 | " The first one will disable tracing every time do_fault is hit\n" | 3498 | " The first one will disable tracing every time do_fault is hit\n" |
3502 | " The second will disable tracing at most 3 times when do_trap is hit\n" | 3499 | " The second will disable tracing at most 3 times when do_trap is hit\n" |
3503 | " The first time do trap is hit and it disables tracing, the counter\n" | 3500 | " The first time do trap is hit and it disables tracing, the counter\n" |
3504 | " will decrement to 2. If tracing is already disabled, the counter\n" | 3501 | " will decrement to 2. If tracing is already disabled, the counter\n" |
3505 | " will not decrement. It only decrements when the trigger did work\n" | 3502 | " will not decrement. It only decrements when the trigger did work\n" |
3506 | " To remove trigger without count:\n" | 3503 | " To remove trigger without count:\n" |
3507 | " echo '!<function>:<trigger> > set_ftrace_filter\n" | 3504 | " echo '!<function>:<trigger> > set_ftrace_filter\n" |
3508 | " To remove trigger with a count:\n" | 3505 | " To remove trigger with a count:\n" |
3509 | " echo '!<function>:<trigger>:0 > set_ftrace_filter\n" | 3506 | " echo '!<function>:<trigger>:0 > set_ftrace_filter\n" |
3510 | " set_ftrace_notrace\t- echo function name in here to never trace.\n" | 3507 | " set_ftrace_notrace\t- echo function name in here to never trace.\n" |
3511 | " accepts: func_full_name, *func_end, func_begin*, *func_middle*\n" | 3508 | " accepts: func_full_name, *func_end, func_begin*, *func_middle*\n" |
3512 | " modules: Can select a group via module command :mod:\n" | 3509 | " modules: Can select a group via module command :mod:\n" |
3513 | " Does not accept triggers\n" | 3510 | " Does not accept triggers\n" |
3514 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 3511 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
3515 | #ifdef CONFIG_FUNCTION_TRACER | 3512 | #ifdef CONFIG_FUNCTION_TRACER |
3516 | " set_ftrace_pid\t- Write pid(s) to only function trace those pids (function)\n" | 3513 | " set_ftrace_pid\t- Write pid(s) to only function trace those pids (function)\n" |
3517 | #endif | 3514 | #endif |
3518 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 3515 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
3519 | " set_graph_function\t- Trace the nested calls of a function (function_graph)\n" | 3516 | " set_graph_function\t- Trace the nested calls of a function (function_graph)\n" |
3520 | " max_graph_depth\t- Trace a limited depth of nested calls (0 is unlimited)\n" | 3517 | " max_graph_depth\t- Trace a limited depth of nested calls (0 is unlimited)\n" |
3521 | #endif | 3518 | #endif |
3522 | #ifdef CONFIG_TRACER_SNAPSHOT | 3519 | #ifdef CONFIG_TRACER_SNAPSHOT |
3523 | "\n snapshot\t\t- Like 'trace' but shows the content of the static snapshot buffer\n" | 3520 | "\n snapshot\t\t- Like 'trace' but shows the content of the static snapshot buffer\n" |
3524 | "\t\t\t Read the contents for more information\n" | 3521 | "\t\t\t Read the contents for more information\n" |
3525 | #endif | 3522 | #endif |
3526 | #ifdef CONFIG_STACK_TRACER | 3523 | #ifdef CONFIG_STACK_TRACER |
3527 | " stack_trace\t\t- Shows the max stack trace when active\n" | 3524 | " stack_trace\t\t- Shows the max stack trace when active\n" |
3528 | " stack_max_size\t- Shows current max stack size that was traced\n" | 3525 | " stack_max_size\t- Shows current max stack size that was traced\n" |
3529 | "\t\t\t Write into this file to reset the max size (trigger a new trace)\n" | 3526 | "\t\t\t Write into this file to reset the max size (trigger a new trace)\n" |
3530 | #ifdef CONFIG_DYNAMIC_FTRACE | 3527 | #ifdef CONFIG_DYNAMIC_FTRACE |
3531 | " stack_trace_filter\t- Like set_ftrace_filter but limits what stack_trace traces\n" | 3528 | " stack_trace_filter\t- Like set_ftrace_filter but limits what stack_trace traces\n" |
3532 | #endif | 3529 | #endif |
3533 | #endif /* CONFIG_STACK_TRACER */ | 3530 | #endif /* CONFIG_STACK_TRACER */ |
3534 | ; | 3531 | ; |
3535 | 3532 | ||
3536 | static ssize_t | 3533 | static ssize_t |
3537 | tracing_readme_read(struct file *filp, char __user *ubuf, | 3534 | tracing_readme_read(struct file *filp, char __user *ubuf, |
3538 | size_t cnt, loff_t *ppos) | 3535 | size_t cnt, loff_t *ppos) |
3539 | { | 3536 | { |
3540 | return simple_read_from_buffer(ubuf, cnt, ppos, | 3537 | return simple_read_from_buffer(ubuf, cnt, ppos, |
3541 | readme_msg, strlen(readme_msg)); | 3538 | readme_msg, strlen(readme_msg)); |
3542 | } | 3539 | } |
3543 | 3540 | ||
3544 | static const struct file_operations tracing_readme_fops = { | 3541 | static const struct file_operations tracing_readme_fops = { |
3545 | .open = tracing_open_generic, | 3542 | .open = tracing_open_generic, |
3546 | .read = tracing_readme_read, | 3543 | .read = tracing_readme_read, |
3547 | .llseek = generic_file_llseek, | 3544 | .llseek = generic_file_llseek, |
3548 | }; | 3545 | }; |
3549 | 3546 | ||
3550 | static ssize_t | 3547 | static ssize_t |
3551 | tracing_saved_cmdlines_read(struct file *file, char __user *ubuf, | 3548 | tracing_saved_cmdlines_read(struct file *file, char __user *ubuf, |
3552 | size_t cnt, loff_t *ppos) | 3549 | size_t cnt, loff_t *ppos) |
3553 | { | 3550 | { |
3554 | char *buf_comm; | 3551 | char *buf_comm; |
3555 | char *file_buf; | 3552 | char *file_buf; |
3556 | char *buf; | 3553 | char *buf; |
3557 | int len = 0; | 3554 | int len = 0; |
3558 | int pid; | 3555 | int pid; |
3559 | int i; | 3556 | int i; |
3560 | 3557 | ||
3561 | file_buf = kmalloc(SAVED_CMDLINES*(16+TASK_COMM_LEN), GFP_KERNEL); | 3558 | file_buf = kmalloc(SAVED_CMDLINES*(16+TASK_COMM_LEN), GFP_KERNEL); |
3562 | if (!file_buf) | 3559 | if (!file_buf) |
3563 | return -ENOMEM; | 3560 | return -ENOMEM; |
3564 | 3561 | ||
3565 | buf_comm = kmalloc(TASK_COMM_LEN, GFP_KERNEL); | 3562 | buf_comm = kmalloc(TASK_COMM_LEN, GFP_KERNEL); |
3566 | if (!buf_comm) { | 3563 | if (!buf_comm) { |
3567 | kfree(file_buf); | 3564 | kfree(file_buf); |
3568 | return -ENOMEM; | 3565 | return -ENOMEM; |
3569 | } | 3566 | } |
3570 | 3567 | ||
3571 | buf = file_buf; | 3568 | buf = file_buf; |
3572 | 3569 | ||
3573 | for (i = 0; i < SAVED_CMDLINES; i++) { | 3570 | for (i = 0; i < SAVED_CMDLINES; i++) { |
3574 | int r; | 3571 | int r; |
3575 | 3572 | ||
3576 | pid = map_cmdline_to_pid[i]; | 3573 | pid = map_cmdline_to_pid[i]; |
3577 | if (pid == -1 || pid == NO_CMDLINE_MAP) | 3574 | if (pid == -1 || pid == NO_CMDLINE_MAP) |
3578 | continue; | 3575 | continue; |
3579 | 3576 | ||
3580 | trace_find_cmdline(pid, buf_comm); | 3577 | trace_find_cmdline(pid, buf_comm); |
3581 | r = sprintf(buf, "%d %s\n", pid, buf_comm); | 3578 | r = sprintf(buf, "%d %s\n", pid, buf_comm); |
3582 | buf += r; | 3579 | buf += r; |
3583 | len += r; | 3580 | len += r; |
3584 | } | 3581 | } |
3585 | 3582 | ||
3586 | len = simple_read_from_buffer(ubuf, cnt, ppos, | 3583 | len = simple_read_from_buffer(ubuf, cnt, ppos, |
3587 | file_buf, len); | 3584 | file_buf, len); |
3588 | 3585 | ||
3589 | kfree(file_buf); | 3586 | kfree(file_buf); |
3590 | kfree(buf_comm); | 3587 | kfree(buf_comm); |
3591 | 3588 | ||
3592 | return len; | 3589 | return len; |
3593 | } | 3590 | } |
3594 | 3591 | ||
3595 | static const struct file_operations tracing_saved_cmdlines_fops = { | 3592 | static const struct file_operations tracing_saved_cmdlines_fops = { |
3596 | .open = tracing_open_generic, | 3593 | .open = tracing_open_generic, |
3597 | .read = tracing_saved_cmdlines_read, | 3594 | .read = tracing_saved_cmdlines_read, |
3598 | .llseek = generic_file_llseek, | 3595 | .llseek = generic_file_llseek, |
3599 | }; | 3596 | }; |
3600 | 3597 | ||
3601 | static ssize_t | 3598 | static ssize_t |
3602 | tracing_set_trace_read(struct file *filp, char __user *ubuf, | 3599 | tracing_set_trace_read(struct file *filp, char __user *ubuf, |
3603 | size_t cnt, loff_t *ppos) | 3600 | size_t cnt, loff_t *ppos) |
3604 | { | 3601 | { |
3605 | struct trace_array *tr = filp->private_data; | 3602 | struct trace_array *tr = filp->private_data; |
3606 | char buf[MAX_TRACER_SIZE+2]; | 3603 | char buf[MAX_TRACER_SIZE+2]; |
3607 | int r; | 3604 | int r; |
3608 | 3605 | ||
3609 | mutex_lock(&trace_types_lock); | 3606 | mutex_lock(&trace_types_lock); |
3610 | r = sprintf(buf, "%s\n", tr->current_trace->name); | 3607 | r = sprintf(buf, "%s\n", tr->current_trace->name); |
3611 | mutex_unlock(&trace_types_lock); | 3608 | mutex_unlock(&trace_types_lock); |
3612 | 3609 | ||
3613 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 3610 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
3614 | } | 3611 | } |
3615 | 3612 | ||
3616 | int tracer_init(struct tracer *t, struct trace_array *tr) | 3613 | int tracer_init(struct tracer *t, struct trace_array *tr) |
3617 | { | 3614 | { |
3618 | tracing_reset_online_cpus(&tr->trace_buffer); | 3615 | tracing_reset_online_cpus(&tr->trace_buffer); |
3619 | return t->init(tr); | 3616 | return t->init(tr); |
3620 | } | 3617 | } |
3621 | 3618 | ||
3622 | static void set_buffer_entries(struct trace_buffer *buf, unsigned long val) | 3619 | static void set_buffer_entries(struct trace_buffer *buf, unsigned long val) |
3623 | { | 3620 | { |
3624 | int cpu; | 3621 | int cpu; |
3625 | 3622 | ||
3626 | for_each_tracing_cpu(cpu) | 3623 | for_each_tracing_cpu(cpu) |
3627 | per_cpu_ptr(buf->data, cpu)->entries = val; | 3624 | per_cpu_ptr(buf->data, cpu)->entries = val; |
3628 | } | 3625 | } |
3629 | 3626 | ||
3630 | #ifdef CONFIG_TRACER_MAX_TRACE | 3627 | #ifdef CONFIG_TRACER_MAX_TRACE |
3631 | /* resize @tr's buffer to the size of @size_tr's entries */ | 3628 | /* resize @tr's buffer to the size of @size_tr's entries */ |
3632 | static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf, | 3629 | static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf, |
3633 | struct trace_buffer *size_buf, int cpu_id) | 3630 | struct trace_buffer *size_buf, int cpu_id) |
3634 | { | 3631 | { |
3635 | int cpu, ret = 0; | 3632 | int cpu, ret = 0; |
3636 | 3633 | ||
3637 | if (cpu_id == RING_BUFFER_ALL_CPUS) { | 3634 | if (cpu_id == RING_BUFFER_ALL_CPUS) { |
3638 | for_each_tracing_cpu(cpu) { | 3635 | for_each_tracing_cpu(cpu) { |
3639 | ret = ring_buffer_resize(trace_buf->buffer, | 3636 | ret = ring_buffer_resize(trace_buf->buffer, |
3640 | per_cpu_ptr(size_buf->data, cpu)->entries, cpu); | 3637 | per_cpu_ptr(size_buf->data, cpu)->entries, cpu); |
3641 | if (ret < 0) | 3638 | if (ret < 0) |
3642 | break; | 3639 | break; |
3643 | per_cpu_ptr(trace_buf->data, cpu)->entries = | 3640 | per_cpu_ptr(trace_buf->data, cpu)->entries = |
3644 | per_cpu_ptr(size_buf->data, cpu)->entries; | 3641 | per_cpu_ptr(size_buf->data, cpu)->entries; |
3645 | } | 3642 | } |
3646 | } else { | 3643 | } else { |
3647 | ret = ring_buffer_resize(trace_buf->buffer, | 3644 | ret = ring_buffer_resize(trace_buf->buffer, |
3648 | per_cpu_ptr(size_buf->data, cpu_id)->entries, cpu_id); | 3645 | per_cpu_ptr(size_buf->data, cpu_id)->entries, cpu_id); |
3649 | if (ret == 0) | 3646 | if (ret == 0) |
3650 | per_cpu_ptr(trace_buf->data, cpu_id)->entries = | 3647 | per_cpu_ptr(trace_buf->data, cpu_id)->entries = |
3651 | per_cpu_ptr(size_buf->data, cpu_id)->entries; | 3648 | per_cpu_ptr(size_buf->data, cpu_id)->entries; |
3652 | } | 3649 | } |
3653 | 3650 | ||
3654 | return ret; | 3651 | return ret; |
3655 | } | 3652 | } |
3656 | #endif /* CONFIG_TRACER_MAX_TRACE */ | 3653 | #endif /* CONFIG_TRACER_MAX_TRACE */ |
3657 | 3654 | ||
3658 | static int __tracing_resize_ring_buffer(struct trace_array *tr, | 3655 | static int __tracing_resize_ring_buffer(struct trace_array *tr, |
3659 | unsigned long size, int cpu) | 3656 | unsigned long size, int cpu) |
3660 | { | 3657 | { |
3661 | int ret; | 3658 | int ret; |
3662 | 3659 | ||
3663 | /* | 3660 | /* |
3664 | * If kernel or user changes the size of the ring buffer | 3661 | * If kernel or user changes the size of the ring buffer |
3665 | * we use the size that was given, and we can forget about | 3662 | * we use the size that was given, and we can forget about |
3666 | * expanding it later. | 3663 | * expanding it later. |
3667 | */ | 3664 | */ |
3668 | ring_buffer_expanded = true; | 3665 | ring_buffer_expanded = true; |
3669 | 3666 | ||
3670 | /* May be called before buffers are initialized */ | 3667 | /* May be called before buffers are initialized */ |
3671 | if (!tr->trace_buffer.buffer) | 3668 | if (!tr->trace_buffer.buffer) |
3672 | return 0; | 3669 | return 0; |
3673 | 3670 | ||
3674 | ret = ring_buffer_resize(tr->trace_buffer.buffer, size, cpu); | 3671 | ret = ring_buffer_resize(tr->trace_buffer.buffer, size, cpu); |
3675 | if (ret < 0) | 3672 | if (ret < 0) |
3676 | return ret; | 3673 | return ret; |
3677 | 3674 | ||
3678 | #ifdef CONFIG_TRACER_MAX_TRACE | 3675 | #ifdef CONFIG_TRACER_MAX_TRACE |
3679 | if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL) || | 3676 | if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL) || |
3680 | !tr->current_trace->use_max_tr) | 3677 | !tr->current_trace->use_max_tr) |
3681 | goto out; | 3678 | goto out; |
3682 | 3679 | ||
3683 | ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu); | 3680 | ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu); |
3684 | if (ret < 0) { | 3681 | if (ret < 0) { |
3685 | int r = resize_buffer_duplicate_size(&tr->trace_buffer, | 3682 | int r = resize_buffer_duplicate_size(&tr->trace_buffer, |
3686 | &tr->trace_buffer, cpu); | 3683 | &tr->trace_buffer, cpu); |
3687 | if (r < 0) { | 3684 | if (r < 0) { |
3688 | /* | 3685 | /* |
3689 | * AARGH! We are left with different | 3686 | * AARGH! We are left with different |
3690 | * size max buffer!!!! | 3687 | * size max buffer!!!! |
3691 | * The max buffer is our "snapshot" buffer. | 3688 | * The max buffer is our "snapshot" buffer. |
3692 | * When a tracer needs a snapshot (one of the | 3689 | * When a tracer needs a snapshot (one of the |
3693 | * latency tracers), it swaps the max buffer | 3690 | * latency tracers), it swaps the max buffer |
3694 | * with the saved snap shot. We succeeded to | 3691 | * with the saved snap shot. We succeeded to |
3695 | * update the size of the main buffer, but failed to | 3692 | * update the size of the main buffer, but failed to |
3696 | * update the size of the max buffer. But when we tried | 3693 | * update the size of the max buffer. But when we tried |
3697 | * to reset the main buffer to the original size, we | 3694 | * to reset the main buffer to the original size, we |
3698 | * failed there too. This is very unlikely to | 3695 | * failed there too. This is very unlikely to |
3699 | * happen, but if it does, warn and kill all | 3696 | * happen, but if it does, warn and kill all |
3700 | * tracing. | 3697 | * tracing. |
3701 | */ | 3698 | */ |
3702 | WARN_ON(1); | 3699 | WARN_ON(1); |
3703 | tracing_disabled = 1; | 3700 | tracing_disabled = 1; |
3704 | } | 3701 | } |
3705 | return ret; | 3702 | return ret; |
3706 | } | 3703 | } |
3707 | 3704 | ||
3708 | if (cpu == RING_BUFFER_ALL_CPUS) | 3705 | if (cpu == RING_BUFFER_ALL_CPUS) |
3709 | set_buffer_entries(&tr->max_buffer, size); | 3706 | set_buffer_entries(&tr->max_buffer, size); |
3710 | else | 3707 | else |
3711 | per_cpu_ptr(tr->max_buffer.data, cpu)->entries = size; | 3708 | per_cpu_ptr(tr->max_buffer.data, cpu)->entries = size; |
3712 | 3709 | ||
3713 | out: | 3710 | out: |
3714 | #endif /* CONFIG_TRACER_MAX_TRACE */ | 3711 | #endif /* CONFIG_TRACER_MAX_TRACE */ |
3715 | 3712 | ||
3716 | if (cpu == RING_BUFFER_ALL_CPUS) | 3713 | if (cpu == RING_BUFFER_ALL_CPUS) |
3717 | set_buffer_entries(&tr->trace_buffer, size); | 3714 | set_buffer_entries(&tr->trace_buffer, size); |
3718 | else | 3715 | else |
3719 | per_cpu_ptr(tr->trace_buffer.data, cpu)->entries = size; | 3716 | per_cpu_ptr(tr->trace_buffer.data, cpu)->entries = size; |
3720 | 3717 | ||
3721 | return ret; | 3718 | return ret; |
3722 | } | 3719 | } |
3723 | 3720 | ||
3724 | static ssize_t tracing_resize_ring_buffer(struct trace_array *tr, | 3721 | static ssize_t tracing_resize_ring_buffer(struct trace_array *tr, |
3725 | unsigned long size, int cpu_id) | 3722 | unsigned long size, int cpu_id) |
3726 | { | 3723 | { |
3727 | int ret = size; | 3724 | int ret = size; |
3728 | 3725 | ||
3729 | mutex_lock(&trace_types_lock); | 3726 | mutex_lock(&trace_types_lock); |
3730 | 3727 | ||
3731 | if (cpu_id != RING_BUFFER_ALL_CPUS) { | 3728 | if (cpu_id != RING_BUFFER_ALL_CPUS) { |
3732 | /* make sure, this cpu is enabled in the mask */ | 3729 | /* make sure, this cpu is enabled in the mask */ |
3733 | if (!cpumask_test_cpu(cpu_id, tracing_buffer_mask)) { | 3730 | if (!cpumask_test_cpu(cpu_id, tracing_buffer_mask)) { |
3734 | ret = -EINVAL; | 3731 | ret = -EINVAL; |
3735 | goto out; | 3732 | goto out; |
3736 | } | 3733 | } |
3737 | } | 3734 | } |
3738 | 3735 | ||
3739 | ret = __tracing_resize_ring_buffer(tr, size, cpu_id); | 3736 | ret = __tracing_resize_ring_buffer(tr, size, cpu_id); |
3740 | if (ret < 0) | 3737 | if (ret < 0) |
3741 | ret = -ENOMEM; | 3738 | ret = -ENOMEM; |
3742 | 3739 | ||
3743 | out: | 3740 | out: |
3744 | mutex_unlock(&trace_types_lock); | 3741 | mutex_unlock(&trace_types_lock); |
3745 | 3742 | ||
3746 | return ret; | 3743 | return ret; |
3747 | } | 3744 | } |
3748 | 3745 | ||
3749 | 3746 | ||
3750 | /** | 3747 | /** |
3751 | * tracing_update_buffers - used by tracing facility to expand ring buffers | 3748 | * tracing_update_buffers - used by tracing facility to expand ring buffers |
3752 | * | 3749 | * |
3753 | * To save on memory when the tracing is never used on a system with it | 3750 | * To save on memory when the tracing is never used on a system with it |
3754 | * configured in. The ring buffers are set to a minimum size. But once | 3751 | * configured in. The ring buffers are set to a minimum size. But once |
3755 | * a user starts to use the tracing facility, then they need to grow | 3752 | * a user starts to use the tracing facility, then they need to grow |
3756 | * to their default size. | 3753 | * to their default size. |
3757 | * | 3754 | * |
3758 | * This function is to be called when a tracer is about to be used. | 3755 | * This function is to be called when a tracer is about to be used. |
3759 | */ | 3756 | */ |
3760 | int tracing_update_buffers(void) | 3757 | int tracing_update_buffers(void) |
3761 | { | 3758 | { |
3762 | int ret = 0; | 3759 | int ret = 0; |
3763 | 3760 | ||
3764 | mutex_lock(&trace_types_lock); | 3761 | mutex_lock(&trace_types_lock); |
3765 | if (!ring_buffer_expanded) | 3762 | if (!ring_buffer_expanded) |
3766 | ret = __tracing_resize_ring_buffer(&global_trace, trace_buf_size, | 3763 | ret = __tracing_resize_ring_buffer(&global_trace, trace_buf_size, |
3767 | RING_BUFFER_ALL_CPUS); | 3764 | RING_BUFFER_ALL_CPUS); |
3768 | mutex_unlock(&trace_types_lock); | 3765 | mutex_unlock(&trace_types_lock); |
3769 | 3766 | ||
3770 | return ret; | 3767 | return ret; |
3771 | } | 3768 | } |
3772 | 3769 | ||
3773 | struct trace_option_dentry; | 3770 | struct trace_option_dentry; |
3774 | 3771 | ||
3775 | static struct trace_option_dentry * | 3772 | static struct trace_option_dentry * |
3776 | create_trace_option_files(struct trace_array *tr, struct tracer *tracer); | 3773 | create_trace_option_files(struct trace_array *tr, struct tracer *tracer); |
3777 | 3774 | ||
3778 | static void | 3775 | static void |
3779 | destroy_trace_option_files(struct trace_option_dentry *topts); | 3776 | destroy_trace_option_files(struct trace_option_dentry *topts); |
3780 | 3777 | ||
3781 | static int tracing_set_tracer(const char *buf) | 3778 | static int tracing_set_tracer(const char *buf) |
3782 | { | 3779 | { |
3783 | static struct trace_option_dentry *topts; | 3780 | static struct trace_option_dentry *topts; |
3784 | struct trace_array *tr = &global_trace; | 3781 | struct trace_array *tr = &global_trace; |
3785 | struct tracer *t; | 3782 | struct tracer *t; |
3786 | #ifdef CONFIG_TRACER_MAX_TRACE | 3783 | #ifdef CONFIG_TRACER_MAX_TRACE |
3787 | bool had_max_tr; | 3784 | bool had_max_tr; |
3788 | #endif | 3785 | #endif |
3789 | int ret = 0; | 3786 | int ret = 0; |
3790 | 3787 | ||
3791 | mutex_lock(&trace_types_lock); | 3788 | mutex_lock(&trace_types_lock); |
3792 | 3789 | ||
3793 | if (!ring_buffer_expanded) { | 3790 | if (!ring_buffer_expanded) { |
3794 | ret = __tracing_resize_ring_buffer(tr, trace_buf_size, | 3791 | ret = __tracing_resize_ring_buffer(tr, trace_buf_size, |
3795 | RING_BUFFER_ALL_CPUS); | 3792 | RING_BUFFER_ALL_CPUS); |
3796 | if (ret < 0) | 3793 | if (ret < 0) |
3797 | goto out; | 3794 | goto out; |
3798 | ret = 0; | 3795 | ret = 0; |
3799 | } | 3796 | } |
3800 | 3797 | ||
3801 | for (t = trace_types; t; t = t->next) { | 3798 | for (t = trace_types; t; t = t->next) { |
3802 | if (strcmp(t->name, buf) == 0) | 3799 | if (strcmp(t->name, buf) == 0) |
3803 | break; | 3800 | break; |
3804 | } | 3801 | } |
3805 | if (!t) { | 3802 | if (!t) { |
3806 | ret = -EINVAL; | 3803 | ret = -EINVAL; |
3807 | goto out; | 3804 | goto out; |
3808 | } | 3805 | } |
3809 | if (t == tr->current_trace) | 3806 | if (t == tr->current_trace) |
3810 | goto out; | 3807 | goto out; |
3811 | 3808 | ||
3812 | trace_branch_disable(); | 3809 | trace_branch_disable(); |
3813 | 3810 | ||
3814 | tr->current_trace->enabled = false; | 3811 | tr->current_trace->enabled = false; |
3815 | 3812 | ||
3816 | if (tr->current_trace->reset) | 3813 | if (tr->current_trace->reset) |
3817 | tr->current_trace->reset(tr); | 3814 | tr->current_trace->reset(tr); |
3818 | 3815 | ||
3819 | /* Current trace needs to be nop_trace before synchronize_sched */ | 3816 | /* Current trace needs to be nop_trace before synchronize_sched */ |
3820 | tr->current_trace = &nop_trace; | 3817 | tr->current_trace = &nop_trace; |
3821 | 3818 | ||
3822 | #ifdef CONFIG_TRACER_MAX_TRACE | 3819 | #ifdef CONFIG_TRACER_MAX_TRACE |
3823 | had_max_tr = tr->allocated_snapshot; | 3820 | had_max_tr = tr->allocated_snapshot; |
3824 | 3821 | ||
3825 | if (had_max_tr && !t->use_max_tr) { | 3822 | if (had_max_tr && !t->use_max_tr) { |
3826 | /* | 3823 | /* |
3827 | * We need to make sure that the update_max_tr sees that | 3824 | * We need to make sure that the update_max_tr sees that |
3828 | * current_trace changed to nop_trace to keep it from | 3825 | * current_trace changed to nop_trace to keep it from |
3829 | * swapping the buffers after we resize it. | 3826 | * swapping the buffers after we resize it. |
3830 | * The update_max_tr is called from interrupts disabled | 3827 | * The update_max_tr is called from interrupts disabled |
3831 | * so a synchronized_sched() is sufficient. | 3828 | * so a synchronized_sched() is sufficient. |
3832 | */ | 3829 | */ |
3833 | synchronize_sched(); | 3830 | synchronize_sched(); |
3834 | free_snapshot(tr); | 3831 | free_snapshot(tr); |
3835 | } | 3832 | } |
3836 | #endif | 3833 | #endif |
3837 | destroy_trace_option_files(topts); | 3834 | destroy_trace_option_files(topts); |
3838 | 3835 | ||
3839 | topts = create_trace_option_files(tr, t); | 3836 | topts = create_trace_option_files(tr, t); |
3840 | 3837 | ||
3841 | #ifdef CONFIG_TRACER_MAX_TRACE | 3838 | #ifdef CONFIG_TRACER_MAX_TRACE |
3842 | if (t->use_max_tr && !had_max_tr) { | 3839 | if (t->use_max_tr && !had_max_tr) { |
3843 | ret = alloc_snapshot(tr); | 3840 | ret = alloc_snapshot(tr); |
3844 | if (ret < 0) | 3841 | if (ret < 0) |
3845 | goto out; | 3842 | goto out; |
3846 | } | 3843 | } |
3847 | #endif | 3844 | #endif |
3848 | 3845 | ||
3849 | if (t->init) { | 3846 | if (t->init) { |
3850 | ret = tracer_init(t, tr); | 3847 | ret = tracer_init(t, tr); |
3851 | if (ret) | 3848 | if (ret) |
3852 | goto out; | 3849 | goto out; |
3853 | } | 3850 | } |
3854 | 3851 | ||
3855 | tr->current_trace = t; | 3852 | tr->current_trace = t; |
3856 | tr->current_trace->enabled = true; | 3853 | tr->current_trace->enabled = true; |
3857 | trace_branch_enable(tr); | 3854 | trace_branch_enable(tr); |
3858 | out: | 3855 | out: |
3859 | mutex_unlock(&trace_types_lock); | 3856 | mutex_unlock(&trace_types_lock); |
3860 | 3857 | ||
3861 | return ret; | 3858 | return ret; |
3862 | } | 3859 | } |
3863 | 3860 | ||
3864 | static ssize_t | 3861 | static ssize_t |
3865 | tracing_set_trace_write(struct file *filp, const char __user *ubuf, | 3862 | tracing_set_trace_write(struct file *filp, const char __user *ubuf, |
3866 | size_t cnt, loff_t *ppos) | 3863 | size_t cnt, loff_t *ppos) |
3867 | { | 3864 | { |
3868 | char buf[MAX_TRACER_SIZE+1]; | 3865 | char buf[MAX_TRACER_SIZE+1]; |
3869 | int i; | 3866 | int i; |
3870 | size_t ret; | 3867 | size_t ret; |
3871 | int err; | 3868 | int err; |
3872 | 3869 | ||
3873 | ret = cnt; | 3870 | ret = cnt; |
3874 | 3871 | ||
3875 | if (cnt > MAX_TRACER_SIZE) | 3872 | if (cnt > MAX_TRACER_SIZE) |
3876 | cnt = MAX_TRACER_SIZE; | 3873 | cnt = MAX_TRACER_SIZE; |
3877 | 3874 | ||
3878 | if (copy_from_user(&buf, ubuf, cnt)) | 3875 | if (copy_from_user(&buf, ubuf, cnt)) |
3879 | return -EFAULT; | 3876 | return -EFAULT; |
3880 | 3877 | ||
3881 | buf[cnt] = 0; | 3878 | buf[cnt] = 0; |
3882 | 3879 | ||
3883 | /* strip ending whitespace. */ | 3880 | /* strip ending whitespace. */ |
3884 | for (i = cnt - 1; i > 0 && isspace(buf[i]); i--) | 3881 | for (i = cnt - 1; i > 0 && isspace(buf[i]); i--) |
3885 | buf[i] = 0; | 3882 | buf[i] = 0; |
3886 | 3883 | ||
3887 | err = tracing_set_tracer(buf); | 3884 | err = tracing_set_tracer(buf); |
3888 | if (err) | 3885 | if (err) |
3889 | return err; | 3886 | return err; |
3890 | 3887 | ||
3891 | *ppos += ret; | 3888 | *ppos += ret; |
3892 | 3889 | ||
3893 | return ret; | 3890 | return ret; |
3894 | } | 3891 | } |
3895 | 3892 | ||
3896 | static ssize_t | 3893 | static ssize_t |
3897 | tracing_max_lat_read(struct file *filp, char __user *ubuf, | 3894 | tracing_max_lat_read(struct file *filp, char __user *ubuf, |
3898 | size_t cnt, loff_t *ppos) | 3895 | size_t cnt, loff_t *ppos) |
3899 | { | 3896 | { |
3900 | unsigned long *ptr = filp->private_data; | 3897 | unsigned long *ptr = filp->private_data; |
3901 | char buf[64]; | 3898 | char buf[64]; |
3902 | int r; | 3899 | int r; |
3903 | 3900 | ||
3904 | r = snprintf(buf, sizeof(buf), "%ld\n", | 3901 | r = snprintf(buf, sizeof(buf), "%ld\n", |
3905 | *ptr == (unsigned long)-1 ? -1 : nsecs_to_usecs(*ptr)); | 3902 | *ptr == (unsigned long)-1 ? -1 : nsecs_to_usecs(*ptr)); |
3906 | if (r > sizeof(buf)) | 3903 | if (r > sizeof(buf)) |
3907 | r = sizeof(buf); | 3904 | r = sizeof(buf); |
3908 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 3905 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
3909 | } | 3906 | } |
3910 | 3907 | ||
3911 | static ssize_t | 3908 | static ssize_t |
3912 | tracing_max_lat_write(struct file *filp, const char __user *ubuf, | 3909 | tracing_max_lat_write(struct file *filp, const char __user *ubuf, |
3913 | size_t cnt, loff_t *ppos) | 3910 | size_t cnt, loff_t *ppos) |
3914 | { | 3911 | { |
3915 | unsigned long *ptr = filp->private_data; | 3912 | unsigned long *ptr = filp->private_data; |
3916 | unsigned long val; | 3913 | unsigned long val; |
3917 | int ret; | 3914 | int ret; |
3918 | 3915 | ||
3919 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 3916 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
3920 | if (ret) | 3917 | if (ret) |
3921 | return ret; | 3918 | return ret; |
3922 | 3919 | ||
3923 | *ptr = val * 1000; | 3920 | *ptr = val * 1000; |
3924 | 3921 | ||
3925 | return cnt; | 3922 | return cnt; |
3926 | } | 3923 | } |
3927 | 3924 | ||
3928 | static int tracing_open_pipe(struct inode *inode, struct file *filp) | 3925 | static int tracing_open_pipe(struct inode *inode, struct file *filp) |
3929 | { | 3926 | { |
3930 | struct trace_array *tr = inode->i_private; | 3927 | struct trace_array *tr = inode->i_private; |
3931 | struct trace_iterator *iter; | 3928 | struct trace_iterator *iter; |
3932 | int ret = 0; | 3929 | int ret = 0; |
3933 | 3930 | ||
3934 | if (tracing_disabled) | 3931 | if (tracing_disabled) |
3935 | return -ENODEV; | 3932 | return -ENODEV; |
3936 | 3933 | ||
3937 | if (trace_array_get(tr) < 0) | 3934 | if (trace_array_get(tr) < 0) |
3938 | return -ENODEV; | 3935 | return -ENODEV; |
3939 | 3936 | ||
3940 | mutex_lock(&trace_types_lock); | 3937 | mutex_lock(&trace_types_lock); |
3941 | 3938 | ||
3942 | /* create a buffer to store the information to pass to userspace */ | 3939 | /* create a buffer to store the information to pass to userspace */ |
3943 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 3940 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
3944 | if (!iter) { | 3941 | if (!iter) { |
3945 | ret = -ENOMEM; | 3942 | ret = -ENOMEM; |
3946 | __trace_array_put(tr); | 3943 | __trace_array_put(tr); |
3947 | goto out; | 3944 | goto out; |
3948 | } | 3945 | } |
3949 | 3946 | ||
3950 | /* | 3947 | /* |
3951 | * We make a copy of the current tracer to avoid concurrent | 3948 | * We make a copy of the current tracer to avoid concurrent |
3952 | * changes on it while we are reading. | 3949 | * changes on it while we are reading. |
3953 | */ | 3950 | */ |
3954 | iter->trace = kmalloc(sizeof(*iter->trace), GFP_KERNEL); | 3951 | iter->trace = kmalloc(sizeof(*iter->trace), GFP_KERNEL); |
3955 | if (!iter->trace) { | 3952 | if (!iter->trace) { |
3956 | ret = -ENOMEM; | 3953 | ret = -ENOMEM; |
3957 | goto fail; | 3954 | goto fail; |
3958 | } | 3955 | } |
3959 | *iter->trace = *tr->current_trace; | 3956 | *iter->trace = *tr->current_trace; |
3960 | 3957 | ||
3961 | if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) { | 3958 | if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) { |
3962 | ret = -ENOMEM; | 3959 | ret = -ENOMEM; |
3963 | goto fail; | 3960 | goto fail; |
3964 | } | 3961 | } |
3965 | 3962 | ||
3966 | /* trace pipe does not show start of buffer */ | 3963 | /* trace pipe does not show start of buffer */ |
3967 | cpumask_setall(iter->started); | 3964 | cpumask_setall(iter->started); |
3968 | 3965 | ||
3969 | if (trace_flags & TRACE_ITER_LATENCY_FMT) | 3966 | if (trace_flags & TRACE_ITER_LATENCY_FMT) |
3970 | iter->iter_flags |= TRACE_FILE_LAT_FMT; | 3967 | iter->iter_flags |= TRACE_FILE_LAT_FMT; |
3971 | 3968 | ||
3972 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ | 3969 | /* Output in nanoseconds only if we are using a clock in nanoseconds. */ |
3973 | if (trace_clocks[tr->clock_id].in_ns) | 3970 | if (trace_clocks[tr->clock_id].in_ns) |
3974 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; | 3971 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; |
3975 | 3972 | ||
3976 | iter->tr = tr; | 3973 | iter->tr = tr; |
3977 | iter->trace_buffer = &tr->trace_buffer; | 3974 | iter->trace_buffer = &tr->trace_buffer; |
3978 | iter->cpu_file = tracing_get_cpu(inode); | 3975 | iter->cpu_file = tracing_get_cpu(inode); |
3979 | mutex_init(&iter->mutex); | 3976 | mutex_init(&iter->mutex); |
3980 | filp->private_data = iter; | 3977 | filp->private_data = iter; |
3981 | 3978 | ||
3982 | if (iter->trace->pipe_open) | 3979 | if (iter->trace->pipe_open) |
3983 | iter->trace->pipe_open(iter); | 3980 | iter->trace->pipe_open(iter); |
3984 | 3981 | ||
3985 | nonseekable_open(inode, filp); | 3982 | nonseekable_open(inode, filp); |
3986 | out: | 3983 | out: |
3987 | mutex_unlock(&trace_types_lock); | 3984 | mutex_unlock(&trace_types_lock); |
3988 | return ret; | 3985 | return ret; |
3989 | 3986 | ||
3990 | fail: | 3987 | fail: |
3991 | kfree(iter->trace); | 3988 | kfree(iter->trace); |
3992 | kfree(iter); | 3989 | kfree(iter); |
3993 | __trace_array_put(tr); | 3990 | __trace_array_put(tr); |
3994 | mutex_unlock(&trace_types_lock); | 3991 | mutex_unlock(&trace_types_lock); |
3995 | return ret; | 3992 | return ret; |
3996 | } | 3993 | } |
3997 | 3994 | ||
3998 | static int tracing_release_pipe(struct inode *inode, struct file *file) | 3995 | static int tracing_release_pipe(struct inode *inode, struct file *file) |
3999 | { | 3996 | { |
4000 | struct trace_iterator *iter = file->private_data; | 3997 | struct trace_iterator *iter = file->private_data; |
4001 | struct trace_array *tr = inode->i_private; | 3998 | struct trace_array *tr = inode->i_private; |
4002 | 3999 | ||
4003 | mutex_lock(&trace_types_lock); | 4000 | mutex_lock(&trace_types_lock); |
4004 | 4001 | ||
4005 | if (iter->trace->pipe_close) | 4002 | if (iter->trace->pipe_close) |
4006 | iter->trace->pipe_close(iter); | 4003 | iter->trace->pipe_close(iter); |
4007 | 4004 | ||
4008 | mutex_unlock(&trace_types_lock); | 4005 | mutex_unlock(&trace_types_lock); |
4009 | 4006 | ||
4010 | free_cpumask_var(iter->started); | 4007 | free_cpumask_var(iter->started); |
4011 | mutex_destroy(&iter->mutex); | 4008 | mutex_destroy(&iter->mutex); |
4012 | kfree(iter->trace); | 4009 | kfree(iter->trace); |
4013 | kfree(iter); | 4010 | kfree(iter); |
4014 | 4011 | ||
4015 | trace_array_put(tr); | 4012 | trace_array_put(tr); |
4016 | 4013 | ||
4017 | return 0; | 4014 | return 0; |
4018 | } | 4015 | } |
4019 | 4016 | ||
4020 | static unsigned int | 4017 | static unsigned int |
4021 | trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_table) | 4018 | trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_table) |
4022 | { | 4019 | { |
4023 | /* Iterators are static, they should be filled or empty */ | 4020 | /* Iterators are static, they should be filled or empty */ |
4024 | if (trace_buffer_iter(iter, iter->cpu_file)) | 4021 | if (trace_buffer_iter(iter, iter->cpu_file)) |
4025 | return POLLIN | POLLRDNORM; | 4022 | return POLLIN | POLLRDNORM; |
4026 | 4023 | ||
4027 | if (trace_flags & TRACE_ITER_BLOCK) | 4024 | if (trace_flags & TRACE_ITER_BLOCK) |
4028 | /* | 4025 | /* |
4029 | * Always select as readable when in blocking mode | 4026 | * Always select as readable when in blocking mode |
4030 | */ | 4027 | */ |
4031 | return POLLIN | POLLRDNORM; | 4028 | return POLLIN | POLLRDNORM; |
4032 | else | 4029 | else |
4033 | return ring_buffer_poll_wait(iter->trace_buffer->buffer, iter->cpu_file, | 4030 | return ring_buffer_poll_wait(iter->trace_buffer->buffer, iter->cpu_file, |
4034 | filp, poll_table); | 4031 | filp, poll_table); |
4035 | } | 4032 | } |
4036 | 4033 | ||
4037 | static unsigned int | 4034 | static unsigned int |
4038 | tracing_poll_pipe(struct file *filp, poll_table *poll_table) | 4035 | tracing_poll_pipe(struct file *filp, poll_table *poll_table) |
4039 | { | 4036 | { |
4040 | struct trace_iterator *iter = filp->private_data; | 4037 | struct trace_iterator *iter = filp->private_data; |
4041 | 4038 | ||
4042 | return trace_poll(iter, filp, poll_table); | 4039 | return trace_poll(iter, filp, poll_table); |
4043 | } | 4040 | } |
4044 | 4041 | ||
4045 | /* | 4042 | /* |
4046 | * This is a make-shift waitqueue. | 4043 | * This is a make-shift waitqueue. |
4047 | * A tracer might use this callback on some rare cases: | 4044 | * A tracer might use this callback on some rare cases: |
4048 | * | 4045 | * |
4049 | * 1) the current tracer might hold the runqueue lock when it wakes up | 4046 | * 1) the current tracer might hold the runqueue lock when it wakes up |
4050 | * a reader, hence a deadlock (sched, function, and function graph tracers) | 4047 | * a reader, hence a deadlock (sched, function, and function graph tracers) |
4051 | * 2) the function tracers, trace all functions, we don't want | 4048 | * 2) the function tracers, trace all functions, we don't want |
4052 | * the overhead of calling wake_up and friends | 4049 | * the overhead of calling wake_up and friends |
4053 | * (and tracing them too) | 4050 | * (and tracing them too) |
4054 | * | 4051 | * |
4055 | * Anyway, this is really very primitive wakeup. | 4052 | * Anyway, this is really very primitive wakeup. |
4056 | */ | 4053 | */ |
4057 | void poll_wait_pipe(struct trace_iterator *iter) | 4054 | void poll_wait_pipe(struct trace_iterator *iter) |
4058 | { | 4055 | { |
4059 | set_current_state(TASK_INTERRUPTIBLE); | 4056 | set_current_state(TASK_INTERRUPTIBLE); |
4060 | /* sleep for 100 msecs, and try again. */ | 4057 | /* sleep for 100 msecs, and try again. */ |
4061 | schedule_timeout(HZ / 10); | 4058 | schedule_timeout(HZ / 10); |
4062 | } | 4059 | } |
4063 | 4060 | ||
4064 | /* Must be called with trace_types_lock mutex held. */ | 4061 | /* Must be called with trace_types_lock mutex held. */ |
4065 | static int tracing_wait_pipe(struct file *filp) | 4062 | static int tracing_wait_pipe(struct file *filp) |
4066 | { | 4063 | { |
4067 | struct trace_iterator *iter = filp->private_data; | 4064 | struct trace_iterator *iter = filp->private_data; |
4068 | 4065 | ||
4069 | while (trace_empty(iter)) { | 4066 | while (trace_empty(iter)) { |
4070 | 4067 | ||
4071 | if ((filp->f_flags & O_NONBLOCK)) { | 4068 | if ((filp->f_flags & O_NONBLOCK)) { |
4072 | return -EAGAIN; | 4069 | return -EAGAIN; |
4073 | } | 4070 | } |
4074 | 4071 | ||
4075 | mutex_unlock(&iter->mutex); | 4072 | mutex_unlock(&iter->mutex); |
4076 | 4073 | ||
4077 | iter->trace->wait_pipe(iter); | 4074 | iter->trace->wait_pipe(iter); |
4078 | 4075 | ||
4079 | mutex_lock(&iter->mutex); | 4076 | mutex_lock(&iter->mutex); |
4080 | 4077 | ||
4081 | if (signal_pending(current)) | 4078 | if (signal_pending(current)) |
4082 | return -EINTR; | 4079 | return -EINTR; |
4083 | 4080 | ||
4084 | /* | 4081 | /* |
4085 | * We block until we read something and tracing is disabled. | 4082 | * We block until we read something and tracing is disabled. |
4086 | * We still block if tracing is disabled, but we have never | 4083 | * We still block if tracing is disabled, but we have never |
4087 | * read anything. This allows a user to cat this file, and | 4084 | * read anything. This allows a user to cat this file, and |
4088 | * then enable tracing. But after we have read something, | 4085 | * then enable tracing. But after we have read something, |
4089 | * we give an EOF when tracing is again disabled. | 4086 | * we give an EOF when tracing is again disabled. |
4090 | * | 4087 | * |
4091 | * iter->pos will be 0 if we haven't read anything. | 4088 | * iter->pos will be 0 if we haven't read anything. |
4092 | */ | 4089 | */ |
4093 | if (!tracing_is_on() && iter->pos) | 4090 | if (!tracing_is_on() && iter->pos) |
4094 | break; | 4091 | break; |
4095 | } | 4092 | } |
4096 | 4093 | ||
4097 | return 1; | 4094 | return 1; |
4098 | } | 4095 | } |
4099 | 4096 | ||
4100 | /* | 4097 | /* |
4101 | * Consumer reader. | 4098 | * Consumer reader. |
4102 | */ | 4099 | */ |
4103 | static ssize_t | 4100 | static ssize_t |
4104 | tracing_read_pipe(struct file *filp, char __user *ubuf, | 4101 | tracing_read_pipe(struct file *filp, char __user *ubuf, |
4105 | size_t cnt, loff_t *ppos) | 4102 | size_t cnt, loff_t *ppos) |
4106 | { | 4103 | { |
4107 | struct trace_iterator *iter = filp->private_data; | 4104 | struct trace_iterator *iter = filp->private_data; |
4108 | struct trace_array *tr = iter->tr; | 4105 | struct trace_array *tr = iter->tr; |
4109 | ssize_t sret; | 4106 | ssize_t sret; |
4110 | 4107 | ||
4111 | /* return any leftover data */ | 4108 | /* return any leftover data */ |
4112 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); | 4109 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); |
4113 | if (sret != -EBUSY) | 4110 | if (sret != -EBUSY) |
4114 | return sret; | 4111 | return sret; |
4115 | 4112 | ||
4116 | trace_seq_init(&iter->seq); | 4113 | trace_seq_init(&iter->seq); |
4117 | 4114 | ||
4118 | /* copy the tracer to avoid using a global lock all around */ | 4115 | /* copy the tracer to avoid using a global lock all around */ |
4119 | mutex_lock(&trace_types_lock); | 4116 | mutex_lock(&trace_types_lock); |
4120 | if (unlikely(iter->trace->name != tr->current_trace->name)) | 4117 | if (unlikely(iter->trace->name != tr->current_trace->name)) |
4121 | *iter->trace = *tr->current_trace; | 4118 | *iter->trace = *tr->current_trace; |
4122 | mutex_unlock(&trace_types_lock); | 4119 | mutex_unlock(&trace_types_lock); |
4123 | 4120 | ||
4124 | /* | 4121 | /* |
4125 | * Avoid more than one consumer on a single file descriptor | 4122 | * Avoid more than one consumer on a single file descriptor |
4126 | * This is just a matter of traces coherency, the ring buffer itself | 4123 | * This is just a matter of traces coherency, the ring buffer itself |
4127 | * is protected. | 4124 | * is protected. |
4128 | */ | 4125 | */ |
4129 | mutex_lock(&iter->mutex); | 4126 | mutex_lock(&iter->mutex); |
4130 | if (iter->trace->read) { | 4127 | if (iter->trace->read) { |
4131 | sret = iter->trace->read(iter, filp, ubuf, cnt, ppos); | 4128 | sret = iter->trace->read(iter, filp, ubuf, cnt, ppos); |
4132 | if (sret) | 4129 | if (sret) |
4133 | goto out; | 4130 | goto out; |
4134 | } | 4131 | } |
4135 | 4132 | ||
4136 | waitagain: | 4133 | waitagain: |
4137 | sret = tracing_wait_pipe(filp); | 4134 | sret = tracing_wait_pipe(filp); |
4138 | if (sret <= 0) | 4135 | if (sret <= 0) |
4139 | goto out; | 4136 | goto out; |
4140 | 4137 | ||
4141 | /* stop when tracing is finished */ | 4138 | /* stop when tracing is finished */ |
4142 | if (trace_empty(iter)) { | 4139 | if (trace_empty(iter)) { |
4143 | sret = 0; | 4140 | sret = 0; |
4144 | goto out; | 4141 | goto out; |
4145 | } | 4142 | } |
4146 | 4143 | ||
4147 | if (cnt >= PAGE_SIZE) | 4144 | if (cnt >= PAGE_SIZE) |
4148 | cnt = PAGE_SIZE - 1; | 4145 | cnt = PAGE_SIZE - 1; |
4149 | 4146 | ||
4150 | /* reset all but tr, trace, and overruns */ | 4147 | /* reset all but tr, trace, and overruns */ |
4151 | memset(&iter->seq, 0, | 4148 | memset(&iter->seq, 0, |
4152 | sizeof(struct trace_iterator) - | 4149 | sizeof(struct trace_iterator) - |
4153 | offsetof(struct trace_iterator, seq)); | 4150 | offsetof(struct trace_iterator, seq)); |
4154 | cpumask_clear(iter->started); | 4151 | cpumask_clear(iter->started); |
4155 | iter->pos = -1; | 4152 | iter->pos = -1; |
4156 | 4153 | ||
4157 | trace_event_read_lock(); | 4154 | trace_event_read_lock(); |
4158 | trace_access_lock(iter->cpu_file); | 4155 | trace_access_lock(iter->cpu_file); |
4159 | while (trace_find_next_entry_inc(iter) != NULL) { | 4156 | while (trace_find_next_entry_inc(iter) != NULL) { |
4160 | enum print_line_t ret; | 4157 | enum print_line_t ret; |
4161 | int len = iter->seq.len; | 4158 | int len = iter->seq.len; |
4162 | 4159 | ||
4163 | ret = print_trace_line(iter); | 4160 | ret = print_trace_line(iter); |
4164 | if (ret == TRACE_TYPE_PARTIAL_LINE) { | 4161 | if (ret == TRACE_TYPE_PARTIAL_LINE) { |
4165 | /* don't print partial lines */ | 4162 | /* don't print partial lines */ |
4166 | iter->seq.len = len; | 4163 | iter->seq.len = len; |
4167 | break; | 4164 | break; |
4168 | } | 4165 | } |
4169 | if (ret != TRACE_TYPE_NO_CONSUME) | 4166 | if (ret != TRACE_TYPE_NO_CONSUME) |
4170 | trace_consume(iter); | 4167 | trace_consume(iter); |
4171 | 4168 | ||
4172 | if (iter->seq.len >= cnt) | 4169 | if (iter->seq.len >= cnt) |
4173 | break; | 4170 | break; |
4174 | 4171 | ||
4175 | /* | 4172 | /* |
4176 | * Setting the full flag means we reached the trace_seq buffer | 4173 | * Setting the full flag means we reached the trace_seq buffer |
4177 | * size and we should leave by partial output condition above. | 4174 | * size and we should leave by partial output condition above. |
4178 | * One of the trace_seq_* functions is not used properly. | 4175 | * One of the trace_seq_* functions is not used properly. |
4179 | */ | 4176 | */ |
4180 | WARN_ONCE(iter->seq.full, "full flag set for trace type %d", | 4177 | WARN_ONCE(iter->seq.full, "full flag set for trace type %d", |
4181 | iter->ent->type); | 4178 | iter->ent->type); |
4182 | } | 4179 | } |
4183 | trace_access_unlock(iter->cpu_file); | 4180 | trace_access_unlock(iter->cpu_file); |
4184 | trace_event_read_unlock(); | 4181 | trace_event_read_unlock(); |
4185 | 4182 | ||
4186 | /* Now copy what we have to the user */ | 4183 | /* Now copy what we have to the user */ |
4187 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); | 4184 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); |
4188 | if (iter->seq.readpos >= iter->seq.len) | 4185 | if (iter->seq.readpos >= iter->seq.len) |
4189 | trace_seq_init(&iter->seq); | 4186 | trace_seq_init(&iter->seq); |
4190 | 4187 | ||
4191 | /* | 4188 | /* |
4192 | * If there was nothing to send to user, in spite of consuming trace | 4189 | * If there was nothing to send to user, in spite of consuming trace |
4193 | * entries, go back to wait for more entries. | 4190 | * entries, go back to wait for more entries. |
4194 | */ | 4191 | */ |
4195 | if (sret == -EBUSY) | 4192 | if (sret == -EBUSY) |
4196 | goto waitagain; | 4193 | goto waitagain; |
4197 | 4194 | ||
4198 | out: | 4195 | out: |
4199 | mutex_unlock(&iter->mutex); | 4196 | mutex_unlock(&iter->mutex); |
4200 | 4197 | ||
4201 | return sret; | 4198 | return sret; |
4202 | } | 4199 | } |
4203 | 4200 | ||
4204 | static void tracing_pipe_buf_release(struct pipe_inode_info *pipe, | 4201 | static void tracing_pipe_buf_release(struct pipe_inode_info *pipe, |
4205 | struct pipe_buffer *buf) | 4202 | struct pipe_buffer *buf) |
4206 | { | 4203 | { |
4207 | __free_page(buf->page); | 4204 | __free_page(buf->page); |
4208 | } | 4205 | } |
4209 | 4206 | ||
4210 | static void tracing_spd_release_pipe(struct splice_pipe_desc *spd, | 4207 | static void tracing_spd_release_pipe(struct splice_pipe_desc *spd, |
4211 | unsigned int idx) | 4208 | unsigned int idx) |
4212 | { | 4209 | { |
4213 | __free_page(spd->pages[idx]); | 4210 | __free_page(spd->pages[idx]); |
4214 | } | 4211 | } |
4215 | 4212 | ||
4216 | static const struct pipe_buf_operations tracing_pipe_buf_ops = { | 4213 | static const struct pipe_buf_operations tracing_pipe_buf_ops = { |
4217 | .can_merge = 0, | 4214 | .can_merge = 0, |
4218 | .map = generic_pipe_buf_map, | 4215 | .map = generic_pipe_buf_map, |
4219 | .unmap = generic_pipe_buf_unmap, | 4216 | .unmap = generic_pipe_buf_unmap, |
4220 | .confirm = generic_pipe_buf_confirm, | 4217 | .confirm = generic_pipe_buf_confirm, |
4221 | .release = tracing_pipe_buf_release, | 4218 | .release = tracing_pipe_buf_release, |
4222 | .steal = generic_pipe_buf_steal, | 4219 | .steal = generic_pipe_buf_steal, |
4223 | .get = generic_pipe_buf_get, | 4220 | .get = generic_pipe_buf_get, |
4224 | }; | 4221 | }; |
4225 | 4222 | ||
4226 | static size_t | 4223 | static size_t |
4227 | tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter) | 4224 | tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter) |
4228 | { | 4225 | { |
4229 | size_t count; | 4226 | size_t count; |
4230 | int ret; | 4227 | int ret; |
4231 | 4228 | ||
4232 | /* Seq buffer is page-sized, exactly what we need. */ | 4229 | /* Seq buffer is page-sized, exactly what we need. */ |
4233 | for (;;) { | 4230 | for (;;) { |
4234 | count = iter->seq.len; | 4231 | count = iter->seq.len; |
4235 | ret = print_trace_line(iter); | 4232 | ret = print_trace_line(iter); |
4236 | count = iter->seq.len - count; | 4233 | count = iter->seq.len - count; |
4237 | if (rem < count) { | 4234 | if (rem < count) { |
4238 | rem = 0; | 4235 | rem = 0; |
4239 | iter->seq.len -= count; | 4236 | iter->seq.len -= count; |
4240 | break; | 4237 | break; |
4241 | } | 4238 | } |
4242 | if (ret == TRACE_TYPE_PARTIAL_LINE) { | 4239 | if (ret == TRACE_TYPE_PARTIAL_LINE) { |
4243 | iter->seq.len -= count; | 4240 | iter->seq.len -= count; |
4244 | break; | 4241 | break; |
4245 | } | 4242 | } |
4246 | 4243 | ||
4247 | if (ret != TRACE_TYPE_NO_CONSUME) | 4244 | if (ret != TRACE_TYPE_NO_CONSUME) |
4248 | trace_consume(iter); | 4245 | trace_consume(iter); |
4249 | rem -= count; | 4246 | rem -= count; |
4250 | if (!trace_find_next_entry_inc(iter)) { | 4247 | if (!trace_find_next_entry_inc(iter)) { |
4251 | rem = 0; | 4248 | rem = 0; |
4252 | iter->ent = NULL; | 4249 | iter->ent = NULL; |
4253 | break; | 4250 | break; |
4254 | } | 4251 | } |
4255 | } | 4252 | } |
4256 | 4253 | ||
4257 | return rem; | 4254 | return rem; |
4258 | } | 4255 | } |
4259 | 4256 | ||
4260 | static ssize_t tracing_splice_read_pipe(struct file *filp, | 4257 | static ssize_t tracing_splice_read_pipe(struct file *filp, |
4261 | loff_t *ppos, | 4258 | loff_t *ppos, |
4262 | struct pipe_inode_info *pipe, | 4259 | struct pipe_inode_info *pipe, |
4263 | size_t len, | 4260 | size_t len, |
4264 | unsigned int flags) | 4261 | unsigned int flags) |
4265 | { | 4262 | { |
4266 | struct page *pages_def[PIPE_DEF_BUFFERS]; | 4263 | struct page *pages_def[PIPE_DEF_BUFFERS]; |
4267 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; | 4264 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; |
4268 | struct trace_iterator *iter = filp->private_data; | 4265 | struct trace_iterator *iter = filp->private_data; |
4269 | struct splice_pipe_desc spd = { | 4266 | struct splice_pipe_desc spd = { |
4270 | .pages = pages_def, | 4267 | .pages = pages_def, |
4271 | .partial = partial_def, | 4268 | .partial = partial_def, |
4272 | .nr_pages = 0, /* This gets updated below. */ | 4269 | .nr_pages = 0, /* This gets updated below. */ |
4273 | .nr_pages_max = PIPE_DEF_BUFFERS, | 4270 | .nr_pages_max = PIPE_DEF_BUFFERS, |
4274 | .flags = flags, | 4271 | .flags = flags, |
4275 | .ops = &tracing_pipe_buf_ops, | 4272 | .ops = &tracing_pipe_buf_ops, |
4276 | .spd_release = tracing_spd_release_pipe, | 4273 | .spd_release = tracing_spd_release_pipe, |
4277 | }; | 4274 | }; |
4278 | struct trace_array *tr = iter->tr; | 4275 | struct trace_array *tr = iter->tr; |
4279 | ssize_t ret; | 4276 | ssize_t ret; |
4280 | size_t rem; | 4277 | size_t rem; |
4281 | unsigned int i; | 4278 | unsigned int i; |
4282 | 4279 | ||
4283 | if (splice_grow_spd(pipe, &spd)) | 4280 | if (splice_grow_spd(pipe, &spd)) |
4284 | return -ENOMEM; | 4281 | return -ENOMEM; |
4285 | 4282 | ||
4286 | /* copy the tracer to avoid using a global lock all around */ | 4283 | /* copy the tracer to avoid using a global lock all around */ |
4287 | mutex_lock(&trace_types_lock); | 4284 | mutex_lock(&trace_types_lock); |
4288 | if (unlikely(iter->trace->name != tr->current_trace->name)) | 4285 | if (unlikely(iter->trace->name != tr->current_trace->name)) |
4289 | *iter->trace = *tr->current_trace; | 4286 | *iter->trace = *tr->current_trace; |
4290 | mutex_unlock(&trace_types_lock); | 4287 | mutex_unlock(&trace_types_lock); |
4291 | 4288 | ||
4292 | mutex_lock(&iter->mutex); | 4289 | mutex_lock(&iter->mutex); |
4293 | 4290 | ||
4294 | if (iter->trace->splice_read) { | 4291 | if (iter->trace->splice_read) { |
4295 | ret = iter->trace->splice_read(iter, filp, | 4292 | ret = iter->trace->splice_read(iter, filp, |
4296 | ppos, pipe, len, flags); | 4293 | ppos, pipe, len, flags); |
4297 | if (ret) | 4294 | if (ret) |
4298 | goto out_err; | 4295 | goto out_err; |
4299 | } | 4296 | } |
4300 | 4297 | ||
4301 | ret = tracing_wait_pipe(filp); | 4298 | ret = tracing_wait_pipe(filp); |
4302 | if (ret <= 0) | 4299 | if (ret <= 0) |
4303 | goto out_err; | 4300 | goto out_err; |
4304 | 4301 | ||
4305 | if (!iter->ent && !trace_find_next_entry_inc(iter)) { | 4302 | if (!iter->ent && !trace_find_next_entry_inc(iter)) { |
4306 | ret = -EFAULT; | 4303 | ret = -EFAULT; |
4307 | goto out_err; | 4304 | goto out_err; |
4308 | } | 4305 | } |
4309 | 4306 | ||
4310 | trace_event_read_lock(); | 4307 | trace_event_read_lock(); |
4311 | trace_access_lock(iter->cpu_file); | 4308 | trace_access_lock(iter->cpu_file); |
4312 | 4309 | ||
4313 | /* Fill as many pages as possible. */ | 4310 | /* Fill as many pages as possible. */ |
4314 | for (i = 0, rem = len; i < pipe->buffers && rem; i++) { | 4311 | for (i = 0, rem = len; i < pipe->buffers && rem; i++) { |
4315 | spd.pages[i] = alloc_page(GFP_KERNEL); | 4312 | spd.pages[i] = alloc_page(GFP_KERNEL); |
4316 | if (!spd.pages[i]) | 4313 | if (!spd.pages[i]) |
4317 | break; | 4314 | break; |
4318 | 4315 | ||
4319 | rem = tracing_fill_pipe_page(rem, iter); | 4316 | rem = tracing_fill_pipe_page(rem, iter); |
4320 | 4317 | ||
4321 | /* Copy the data into the page, so we can start over. */ | 4318 | /* Copy the data into the page, so we can start over. */ |
4322 | ret = trace_seq_to_buffer(&iter->seq, | 4319 | ret = trace_seq_to_buffer(&iter->seq, |
4323 | page_address(spd.pages[i]), | 4320 | page_address(spd.pages[i]), |
4324 | iter->seq.len); | 4321 | iter->seq.len); |
4325 | if (ret < 0) { | 4322 | if (ret < 0) { |
4326 | __free_page(spd.pages[i]); | 4323 | __free_page(spd.pages[i]); |
4327 | break; | 4324 | break; |
4328 | } | 4325 | } |
4329 | spd.partial[i].offset = 0; | 4326 | spd.partial[i].offset = 0; |
4330 | spd.partial[i].len = iter->seq.len; | 4327 | spd.partial[i].len = iter->seq.len; |
4331 | 4328 | ||
4332 | trace_seq_init(&iter->seq); | 4329 | trace_seq_init(&iter->seq); |
4333 | } | 4330 | } |
4334 | 4331 | ||
4335 | trace_access_unlock(iter->cpu_file); | 4332 | trace_access_unlock(iter->cpu_file); |
4336 | trace_event_read_unlock(); | 4333 | trace_event_read_unlock(); |
4337 | mutex_unlock(&iter->mutex); | 4334 | mutex_unlock(&iter->mutex); |
4338 | 4335 | ||
4339 | spd.nr_pages = i; | 4336 | spd.nr_pages = i; |
4340 | 4337 | ||
4341 | ret = splice_to_pipe(pipe, &spd); | 4338 | ret = splice_to_pipe(pipe, &spd); |
4342 | out: | 4339 | out: |
4343 | splice_shrink_spd(&spd); | 4340 | splice_shrink_spd(&spd); |
4344 | return ret; | 4341 | return ret; |
4345 | 4342 | ||
4346 | out_err: | 4343 | out_err: |
4347 | mutex_unlock(&iter->mutex); | 4344 | mutex_unlock(&iter->mutex); |
4348 | goto out; | 4345 | goto out; |
4349 | } | 4346 | } |
4350 | 4347 | ||
4351 | static ssize_t | 4348 | static ssize_t |
4352 | tracing_entries_read(struct file *filp, char __user *ubuf, | 4349 | tracing_entries_read(struct file *filp, char __user *ubuf, |
4353 | size_t cnt, loff_t *ppos) | 4350 | size_t cnt, loff_t *ppos) |
4354 | { | 4351 | { |
4355 | struct inode *inode = file_inode(filp); | 4352 | struct inode *inode = file_inode(filp); |
4356 | struct trace_array *tr = inode->i_private; | 4353 | struct trace_array *tr = inode->i_private; |
4357 | int cpu = tracing_get_cpu(inode); | 4354 | int cpu = tracing_get_cpu(inode); |
4358 | char buf[64]; | 4355 | char buf[64]; |
4359 | int r = 0; | 4356 | int r = 0; |
4360 | ssize_t ret; | 4357 | ssize_t ret; |
4361 | 4358 | ||
4362 | mutex_lock(&trace_types_lock); | 4359 | mutex_lock(&trace_types_lock); |
4363 | 4360 | ||
4364 | if (cpu == RING_BUFFER_ALL_CPUS) { | 4361 | if (cpu == RING_BUFFER_ALL_CPUS) { |
4365 | int cpu, buf_size_same; | 4362 | int cpu, buf_size_same; |
4366 | unsigned long size; | 4363 | unsigned long size; |
4367 | 4364 | ||
4368 | size = 0; | 4365 | size = 0; |
4369 | buf_size_same = 1; | 4366 | buf_size_same = 1; |
4370 | /* check if all cpu sizes are same */ | 4367 | /* check if all cpu sizes are same */ |
4371 | for_each_tracing_cpu(cpu) { | 4368 | for_each_tracing_cpu(cpu) { |
4372 | /* fill in the size from first enabled cpu */ | 4369 | /* fill in the size from first enabled cpu */ |
4373 | if (size == 0) | 4370 | if (size == 0) |
4374 | size = per_cpu_ptr(tr->trace_buffer.data, cpu)->entries; | 4371 | size = per_cpu_ptr(tr->trace_buffer.data, cpu)->entries; |
4375 | if (size != per_cpu_ptr(tr->trace_buffer.data, cpu)->entries) { | 4372 | if (size != per_cpu_ptr(tr->trace_buffer.data, cpu)->entries) { |
4376 | buf_size_same = 0; | 4373 | buf_size_same = 0; |
4377 | break; | 4374 | break; |
4378 | } | 4375 | } |
4379 | } | 4376 | } |
4380 | 4377 | ||
4381 | if (buf_size_same) { | 4378 | if (buf_size_same) { |
4382 | if (!ring_buffer_expanded) | 4379 | if (!ring_buffer_expanded) |
4383 | r = sprintf(buf, "%lu (expanded: %lu)\n", | 4380 | r = sprintf(buf, "%lu (expanded: %lu)\n", |
4384 | size >> 10, | 4381 | size >> 10, |
4385 | trace_buf_size >> 10); | 4382 | trace_buf_size >> 10); |
4386 | else | 4383 | else |
4387 | r = sprintf(buf, "%lu\n", size >> 10); | 4384 | r = sprintf(buf, "%lu\n", size >> 10); |
4388 | } else | 4385 | } else |
4389 | r = sprintf(buf, "X\n"); | 4386 | r = sprintf(buf, "X\n"); |
4390 | } else | 4387 | } else |
4391 | r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10); | 4388 | r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10); |
4392 | 4389 | ||
4393 | mutex_unlock(&trace_types_lock); | 4390 | mutex_unlock(&trace_types_lock); |
4394 | 4391 | ||
4395 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 4392 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
4396 | return ret; | 4393 | return ret; |
4397 | } | 4394 | } |
4398 | 4395 | ||
4399 | static ssize_t | 4396 | static ssize_t |
4400 | tracing_entries_write(struct file *filp, const char __user *ubuf, | 4397 | tracing_entries_write(struct file *filp, const char __user *ubuf, |
4401 | size_t cnt, loff_t *ppos) | 4398 | size_t cnt, loff_t *ppos) |
4402 | { | 4399 | { |
4403 | struct inode *inode = file_inode(filp); | 4400 | struct inode *inode = file_inode(filp); |
4404 | struct trace_array *tr = inode->i_private; | 4401 | struct trace_array *tr = inode->i_private; |
4405 | unsigned long val; | 4402 | unsigned long val; |
4406 | int ret; | 4403 | int ret; |
4407 | 4404 | ||
4408 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 4405 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
4409 | if (ret) | 4406 | if (ret) |
4410 | return ret; | 4407 | return ret; |
4411 | 4408 | ||
4412 | /* must have at least 1 entry */ | 4409 | /* must have at least 1 entry */ |
4413 | if (!val) | 4410 | if (!val) |
4414 | return -EINVAL; | 4411 | return -EINVAL; |
4415 | 4412 | ||
4416 | /* value is in KB */ | 4413 | /* value is in KB */ |
4417 | val <<= 10; | 4414 | val <<= 10; |
4418 | ret = tracing_resize_ring_buffer(tr, val, tracing_get_cpu(inode)); | 4415 | ret = tracing_resize_ring_buffer(tr, val, tracing_get_cpu(inode)); |
4419 | if (ret < 0) | 4416 | if (ret < 0) |
4420 | return ret; | 4417 | return ret; |
4421 | 4418 | ||
4422 | *ppos += cnt; | 4419 | *ppos += cnt; |
4423 | 4420 | ||
4424 | return cnt; | 4421 | return cnt; |
4425 | } | 4422 | } |
4426 | 4423 | ||
4427 | static ssize_t | 4424 | static ssize_t |
4428 | tracing_total_entries_read(struct file *filp, char __user *ubuf, | 4425 | tracing_total_entries_read(struct file *filp, char __user *ubuf, |
4429 | size_t cnt, loff_t *ppos) | 4426 | size_t cnt, loff_t *ppos) |
4430 | { | 4427 | { |
4431 | struct trace_array *tr = filp->private_data; | 4428 | struct trace_array *tr = filp->private_data; |
4432 | char buf[64]; | 4429 | char buf[64]; |
4433 | int r, cpu; | 4430 | int r, cpu; |
4434 | unsigned long size = 0, expanded_size = 0; | 4431 | unsigned long size = 0, expanded_size = 0; |
4435 | 4432 | ||
4436 | mutex_lock(&trace_types_lock); | 4433 | mutex_lock(&trace_types_lock); |
4437 | for_each_tracing_cpu(cpu) { | 4434 | for_each_tracing_cpu(cpu) { |
4438 | size += per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10; | 4435 | size += per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10; |
4439 | if (!ring_buffer_expanded) | 4436 | if (!ring_buffer_expanded) |
4440 | expanded_size += trace_buf_size >> 10; | 4437 | expanded_size += trace_buf_size >> 10; |
4441 | } | 4438 | } |
4442 | if (ring_buffer_expanded) | 4439 | if (ring_buffer_expanded) |
4443 | r = sprintf(buf, "%lu\n", size); | 4440 | r = sprintf(buf, "%lu\n", size); |
4444 | else | 4441 | else |
4445 | r = sprintf(buf, "%lu (expanded: %lu)\n", size, expanded_size); | 4442 | r = sprintf(buf, "%lu (expanded: %lu)\n", size, expanded_size); |
4446 | mutex_unlock(&trace_types_lock); | 4443 | mutex_unlock(&trace_types_lock); |
4447 | 4444 | ||
4448 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 4445 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
4449 | } | 4446 | } |
4450 | 4447 | ||
4451 | static ssize_t | 4448 | static ssize_t |
4452 | tracing_free_buffer_write(struct file *filp, const char __user *ubuf, | 4449 | tracing_free_buffer_write(struct file *filp, const char __user *ubuf, |
4453 | size_t cnt, loff_t *ppos) | 4450 | size_t cnt, loff_t *ppos) |
4454 | { | 4451 | { |
4455 | /* | 4452 | /* |
4456 | * There is no need to read what the user has written, this function | 4453 | * There is no need to read what the user has written, this function |
4457 | * is just to make sure that there is no error when "echo" is used | 4454 | * is just to make sure that there is no error when "echo" is used |
4458 | */ | 4455 | */ |
4459 | 4456 | ||
4460 | *ppos += cnt; | 4457 | *ppos += cnt; |
4461 | 4458 | ||
4462 | return cnt; | 4459 | return cnt; |
4463 | } | 4460 | } |
4464 | 4461 | ||
4465 | static int | 4462 | static int |
4466 | tracing_free_buffer_release(struct inode *inode, struct file *filp) | 4463 | tracing_free_buffer_release(struct inode *inode, struct file *filp) |
4467 | { | 4464 | { |
4468 | struct trace_array *tr = inode->i_private; | 4465 | struct trace_array *tr = inode->i_private; |
4469 | 4466 | ||
4470 | /* disable tracing ? */ | 4467 | /* disable tracing ? */ |
4471 | if (trace_flags & TRACE_ITER_STOP_ON_FREE) | 4468 | if (trace_flags & TRACE_ITER_STOP_ON_FREE) |
4472 | tracer_tracing_off(tr); | 4469 | tracer_tracing_off(tr); |
4473 | /* resize the ring buffer to 0 */ | 4470 | /* resize the ring buffer to 0 */ |
4474 | tracing_resize_ring_buffer(tr, 0, RING_BUFFER_ALL_CPUS); | 4471 | tracing_resize_ring_buffer(tr, 0, RING_BUFFER_ALL_CPUS); |
4475 | 4472 | ||
4476 | trace_array_put(tr); | 4473 | trace_array_put(tr); |
4477 | 4474 | ||
4478 | return 0; | 4475 | return 0; |
4479 | } | 4476 | } |
4480 | 4477 | ||
4481 | static ssize_t | 4478 | static ssize_t |
4482 | tracing_mark_write(struct file *filp, const char __user *ubuf, | 4479 | tracing_mark_write(struct file *filp, const char __user *ubuf, |
4483 | size_t cnt, loff_t *fpos) | 4480 | size_t cnt, loff_t *fpos) |
4484 | { | 4481 | { |
4485 | unsigned long addr = (unsigned long)ubuf; | 4482 | unsigned long addr = (unsigned long)ubuf; |
4486 | struct trace_array *tr = filp->private_data; | 4483 | struct trace_array *tr = filp->private_data; |
4487 | struct ring_buffer_event *event; | 4484 | struct ring_buffer_event *event; |
4488 | struct ring_buffer *buffer; | 4485 | struct ring_buffer *buffer; |
4489 | struct print_entry *entry; | 4486 | struct print_entry *entry; |
4490 | unsigned long irq_flags; | 4487 | unsigned long irq_flags; |
4491 | struct page *pages[2]; | 4488 | struct page *pages[2]; |
4492 | void *map_page[2]; | 4489 | void *map_page[2]; |
4493 | int nr_pages = 1; | 4490 | int nr_pages = 1; |
4494 | ssize_t written; | 4491 | ssize_t written; |
4495 | int offset; | 4492 | int offset; |
4496 | int size; | 4493 | int size; |
4497 | int len; | 4494 | int len; |
4498 | int ret; | 4495 | int ret; |
4499 | int i; | 4496 | int i; |
4500 | 4497 | ||
4501 | if (tracing_disabled) | 4498 | if (tracing_disabled) |
4502 | return -EINVAL; | 4499 | return -EINVAL; |
4503 | 4500 | ||
4504 | if (!(trace_flags & TRACE_ITER_MARKERS)) | 4501 | if (!(trace_flags & TRACE_ITER_MARKERS)) |
4505 | return -EINVAL; | 4502 | return -EINVAL; |
4506 | 4503 | ||
4507 | if (cnt > TRACE_BUF_SIZE) | 4504 | if (cnt > TRACE_BUF_SIZE) |
4508 | cnt = TRACE_BUF_SIZE; | 4505 | cnt = TRACE_BUF_SIZE; |
4509 | 4506 | ||
4510 | /* | 4507 | /* |
4511 | * Userspace is injecting traces into the kernel trace buffer. | 4508 | * Userspace is injecting traces into the kernel trace buffer. |
4512 | * We want to be as non intrusive as possible. | 4509 | * We want to be as non intrusive as possible. |
4513 | * To do so, we do not want to allocate any special buffers | 4510 | * To do so, we do not want to allocate any special buffers |
4514 | * or take any locks, but instead write the userspace data | 4511 | * or take any locks, but instead write the userspace data |
4515 | * straight into the ring buffer. | 4512 | * straight into the ring buffer. |
4516 | * | 4513 | * |
4517 | * First we need to pin the userspace buffer into memory, | 4514 | * First we need to pin the userspace buffer into memory, |
4518 | * which, most likely it is, because it just referenced it. | 4515 | * which, most likely it is, because it just referenced it. |
4519 | * But there's no guarantee that it is. By using get_user_pages_fast() | 4516 | * But there's no guarantee that it is. By using get_user_pages_fast() |
4520 | * and kmap_atomic/kunmap_atomic() we can get access to the | 4517 | * and kmap_atomic/kunmap_atomic() we can get access to the |
4521 | * pages directly. We then write the data directly into the | 4518 | * pages directly. We then write the data directly into the |
4522 | * ring buffer. | 4519 | * ring buffer. |
4523 | */ | 4520 | */ |
4524 | BUILD_BUG_ON(TRACE_BUF_SIZE >= PAGE_SIZE); | 4521 | BUILD_BUG_ON(TRACE_BUF_SIZE >= PAGE_SIZE); |
4525 | 4522 | ||
4526 | /* check if we cross pages */ | 4523 | /* check if we cross pages */ |
4527 | if ((addr & PAGE_MASK) != ((addr + cnt) & PAGE_MASK)) | 4524 | if ((addr & PAGE_MASK) != ((addr + cnt) & PAGE_MASK)) |
4528 | nr_pages = 2; | 4525 | nr_pages = 2; |
4529 | 4526 | ||
4530 | offset = addr & (PAGE_SIZE - 1); | 4527 | offset = addr & (PAGE_SIZE - 1); |
4531 | addr &= PAGE_MASK; | 4528 | addr &= PAGE_MASK; |
4532 | 4529 | ||
4533 | ret = get_user_pages_fast(addr, nr_pages, 0, pages); | 4530 | ret = get_user_pages_fast(addr, nr_pages, 0, pages); |
4534 | if (ret < nr_pages) { | 4531 | if (ret < nr_pages) { |
4535 | while (--ret >= 0) | 4532 | while (--ret >= 0) |
4536 | put_page(pages[ret]); | 4533 | put_page(pages[ret]); |
4537 | written = -EFAULT; | 4534 | written = -EFAULT; |
4538 | goto out; | 4535 | goto out; |
4539 | } | 4536 | } |
4540 | 4537 | ||
4541 | for (i = 0; i < nr_pages; i++) | 4538 | for (i = 0; i < nr_pages; i++) |
4542 | map_page[i] = kmap_atomic(pages[i]); | 4539 | map_page[i] = kmap_atomic(pages[i]); |
4543 | 4540 | ||
4544 | local_save_flags(irq_flags); | 4541 | local_save_flags(irq_flags); |
4545 | size = sizeof(*entry) + cnt + 2; /* possible \n added */ | 4542 | size = sizeof(*entry) + cnt + 2; /* possible \n added */ |
4546 | buffer = tr->trace_buffer.buffer; | 4543 | buffer = tr->trace_buffer.buffer; |
4547 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, | 4544 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, |
4548 | irq_flags, preempt_count()); | 4545 | irq_flags, preempt_count()); |
4549 | if (!event) { | 4546 | if (!event) { |
4550 | /* Ring buffer disabled, return as if not open for write */ | 4547 | /* Ring buffer disabled, return as if not open for write */ |
4551 | written = -EBADF; | 4548 | written = -EBADF; |
4552 | goto out_unlock; | 4549 | goto out_unlock; |
4553 | } | 4550 | } |
4554 | 4551 | ||
4555 | entry = ring_buffer_event_data(event); | 4552 | entry = ring_buffer_event_data(event); |
4556 | entry->ip = _THIS_IP_; | 4553 | entry->ip = _THIS_IP_; |
4557 | 4554 | ||
4558 | if (nr_pages == 2) { | 4555 | if (nr_pages == 2) { |
4559 | len = PAGE_SIZE - offset; | 4556 | len = PAGE_SIZE - offset; |
4560 | memcpy(&entry->buf, map_page[0] + offset, len); | 4557 | memcpy(&entry->buf, map_page[0] + offset, len); |
4561 | memcpy(&entry->buf[len], map_page[1], cnt - len); | 4558 | memcpy(&entry->buf[len], map_page[1], cnt - len); |
4562 | } else | 4559 | } else |
4563 | memcpy(&entry->buf, map_page[0] + offset, cnt); | 4560 | memcpy(&entry->buf, map_page[0] + offset, cnt); |
4564 | 4561 | ||
4565 | if (entry->buf[cnt - 1] != '\n') { | 4562 | if (entry->buf[cnt - 1] != '\n') { |
4566 | entry->buf[cnt] = '\n'; | 4563 | entry->buf[cnt] = '\n'; |
4567 | entry->buf[cnt + 1] = '\0'; | 4564 | entry->buf[cnt + 1] = '\0'; |
4568 | } else | 4565 | } else |
4569 | entry->buf[cnt] = '\0'; | 4566 | entry->buf[cnt] = '\0'; |
4570 | 4567 | ||
4571 | __buffer_unlock_commit(buffer, event); | 4568 | __buffer_unlock_commit(buffer, event); |
4572 | 4569 | ||
4573 | written = cnt; | 4570 | written = cnt; |
4574 | 4571 | ||
4575 | *fpos += written; | 4572 | *fpos += written; |
4576 | 4573 | ||
4577 | out_unlock: | 4574 | out_unlock: |
4578 | for (i = 0; i < nr_pages; i++){ | 4575 | for (i = 0; i < nr_pages; i++){ |
4579 | kunmap_atomic(map_page[i]); | 4576 | kunmap_atomic(map_page[i]); |
4580 | put_page(pages[i]); | 4577 | put_page(pages[i]); |
4581 | } | 4578 | } |
4582 | out: | 4579 | out: |
4583 | return written; | 4580 | return written; |
4584 | } | 4581 | } |
4585 | 4582 | ||
4586 | static int tracing_clock_show(struct seq_file *m, void *v) | 4583 | static int tracing_clock_show(struct seq_file *m, void *v) |
4587 | { | 4584 | { |
4588 | struct trace_array *tr = m->private; | 4585 | struct trace_array *tr = m->private; |
4589 | int i; | 4586 | int i; |
4590 | 4587 | ||
4591 | for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) | 4588 | for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) |
4592 | seq_printf(m, | 4589 | seq_printf(m, |
4593 | "%s%s%s%s", i ? " " : "", | 4590 | "%s%s%s%s", i ? " " : "", |
4594 | i == tr->clock_id ? "[" : "", trace_clocks[i].name, | 4591 | i == tr->clock_id ? "[" : "", trace_clocks[i].name, |
4595 | i == tr->clock_id ? "]" : ""); | 4592 | i == tr->clock_id ? "]" : ""); |
4596 | seq_putc(m, '\n'); | 4593 | seq_putc(m, '\n'); |
4597 | 4594 | ||
4598 | return 0; | 4595 | return 0; |
4599 | } | 4596 | } |
4600 | 4597 | ||
4601 | static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, | 4598 | static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, |
4602 | size_t cnt, loff_t *fpos) | 4599 | size_t cnt, loff_t *fpos) |
4603 | { | 4600 | { |
4604 | struct seq_file *m = filp->private_data; | 4601 | struct seq_file *m = filp->private_data; |
4605 | struct trace_array *tr = m->private; | 4602 | struct trace_array *tr = m->private; |
4606 | char buf[64]; | 4603 | char buf[64]; |
4607 | const char *clockstr; | 4604 | const char *clockstr; |
4608 | int i; | 4605 | int i; |
4609 | 4606 | ||
4610 | if (cnt >= sizeof(buf)) | 4607 | if (cnt >= sizeof(buf)) |
4611 | return -EINVAL; | 4608 | return -EINVAL; |
4612 | 4609 | ||
4613 | if (copy_from_user(&buf, ubuf, cnt)) | 4610 | if (copy_from_user(&buf, ubuf, cnt)) |
4614 | return -EFAULT; | 4611 | return -EFAULT; |
4615 | 4612 | ||
4616 | buf[cnt] = 0; | 4613 | buf[cnt] = 0; |
4617 | 4614 | ||
4618 | clockstr = strstrip(buf); | 4615 | clockstr = strstrip(buf); |
4619 | 4616 | ||
4620 | for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) { | 4617 | for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) { |
4621 | if (strcmp(trace_clocks[i].name, clockstr) == 0) | 4618 | if (strcmp(trace_clocks[i].name, clockstr) == 0) |
4622 | break; | 4619 | break; |
4623 | } | 4620 | } |
4624 | if (i == ARRAY_SIZE(trace_clocks)) | 4621 | if (i == ARRAY_SIZE(trace_clocks)) |
4625 | return -EINVAL; | 4622 | return -EINVAL; |
4626 | 4623 | ||
4627 | mutex_lock(&trace_types_lock); | 4624 | mutex_lock(&trace_types_lock); |
4628 | 4625 | ||
4629 | tr->clock_id = i; | 4626 | tr->clock_id = i; |
4630 | 4627 | ||
4631 | ring_buffer_set_clock(tr->trace_buffer.buffer, trace_clocks[i].func); | 4628 | ring_buffer_set_clock(tr->trace_buffer.buffer, trace_clocks[i].func); |
4632 | 4629 | ||
4633 | /* | 4630 | /* |
4634 | * New clock may not be consistent with the previous clock. | 4631 | * New clock may not be consistent with the previous clock. |
4635 | * Reset the buffer so that it doesn't have incomparable timestamps. | 4632 | * Reset the buffer so that it doesn't have incomparable timestamps. |
4636 | */ | 4633 | */ |
4637 | tracing_reset_online_cpus(&tr->trace_buffer); | 4634 | tracing_reset_online_cpus(&tr->trace_buffer); |
4638 | 4635 | ||
4639 | #ifdef CONFIG_TRACER_MAX_TRACE | 4636 | #ifdef CONFIG_TRACER_MAX_TRACE |
4640 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) | 4637 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) |
4641 | ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); | 4638 | ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); |
4642 | tracing_reset_online_cpus(&tr->max_buffer); | 4639 | tracing_reset_online_cpus(&tr->max_buffer); |
4643 | #endif | 4640 | #endif |
4644 | 4641 | ||
4645 | mutex_unlock(&trace_types_lock); | 4642 | mutex_unlock(&trace_types_lock); |
4646 | 4643 | ||
4647 | *fpos += cnt; | 4644 | *fpos += cnt; |
4648 | 4645 | ||
4649 | return cnt; | 4646 | return cnt; |
4650 | } | 4647 | } |
4651 | 4648 | ||
4652 | static int tracing_clock_open(struct inode *inode, struct file *file) | 4649 | static int tracing_clock_open(struct inode *inode, struct file *file) |
4653 | { | 4650 | { |
4654 | struct trace_array *tr = inode->i_private; | 4651 | struct trace_array *tr = inode->i_private; |
4655 | int ret; | 4652 | int ret; |
4656 | 4653 | ||
4657 | if (tracing_disabled) | 4654 | if (tracing_disabled) |
4658 | return -ENODEV; | 4655 | return -ENODEV; |
4659 | 4656 | ||
4660 | if (trace_array_get(tr)) | 4657 | if (trace_array_get(tr)) |
4661 | return -ENODEV; | 4658 | return -ENODEV; |
4662 | 4659 | ||
4663 | ret = single_open(file, tracing_clock_show, inode->i_private); | 4660 | ret = single_open(file, tracing_clock_show, inode->i_private); |
4664 | if (ret < 0) | 4661 | if (ret < 0) |
4665 | trace_array_put(tr); | 4662 | trace_array_put(tr); |
4666 | 4663 | ||
4667 | return ret; | 4664 | return ret; |
4668 | } | 4665 | } |
4669 | 4666 | ||
4670 | struct ftrace_buffer_info { | 4667 | struct ftrace_buffer_info { |
4671 | struct trace_iterator iter; | 4668 | struct trace_iterator iter; |
4672 | void *spare; | 4669 | void *spare; |
4673 | unsigned int read; | 4670 | unsigned int read; |
4674 | }; | 4671 | }; |
4675 | 4672 | ||
4676 | #ifdef CONFIG_TRACER_SNAPSHOT | 4673 | #ifdef CONFIG_TRACER_SNAPSHOT |
4677 | static int tracing_snapshot_open(struct inode *inode, struct file *file) | 4674 | static int tracing_snapshot_open(struct inode *inode, struct file *file) |
4678 | { | 4675 | { |
4679 | struct trace_array *tr = inode->i_private; | 4676 | struct trace_array *tr = inode->i_private; |
4680 | struct trace_iterator *iter; | 4677 | struct trace_iterator *iter; |
4681 | struct seq_file *m; | 4678 | struct seq_file *m; |
4682 | int ret = 0; | 4679 | int ret = 0; |
4683 | 4680 | ||
4684 | if (trace_array_get(tr) < 0) | 4681 | if (trace_array_get(tr) < 0) |
4685 | return -ENODEV; | 4682 | return -ENODEV; |
4686 | 4683 | ||
4687 | if (file->f_mode & FMODE_READ) { | 4684 | if (file->f_mode & FMODE_READ) { |
4688 | iter = __tracing_open(inode, file, true); | 4685 | iter = __tracing_open(inode, file, true); |
4689 | if (IS_ERR(iter)) | 4686 | if (IS_ERR(iter)) |
4690 | ret = PTR_ERR(iter); | 4687 | ret = PTR_ERR(iter); |
4691 | } else { | 4688 | } else { |
4692 | /* Writes still need the seq_file to hold the private data */ | 4689 | /* Writes still need the seq_file to hold the private data */ |
4693 | ret = -ENOMEM; | 4690 | ret = -ENOMEM; |
4694 | m = kzalloc(sizeof(*m), GFP_KERNEL); | 4691 | m = kzalloc(sizeof(*m), GFP_KERNEL); |
4695 | if (!m) | 4692 | if (!m) |
4696 | goto out; | 4693 | goto out; |
4697 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 4694 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
4698 | if (!iter) { | 4695 | if (!iter) { |
4699 | kfree(m); | 4696 | kfree(m); |
4700 | goto out; | 4697 | goto out; |
4701 | } | 4698 | } |
4702 | ret = 0; | 4699 | ret = 0; |
4703 | 4700 | ||
4704 | iter->tr = tr; | 4701 | iter->tr = tr; |
4705 | iter->trace_buffer = &tr->max_buffer; | 4702 | iter->trace_buffer = &tr->max_buffer; |
4706 | iter->cpu_file = tracing_get_cpu(inode); | 4703 | iter->cpu_file = tracing_get_cpu(inode); |
4707 | m->private = iter; | 4704 | m->private = iter; |
4708 | file->private_data = m; | 4705 | file->private_data = m; |
4709 | } | 4706 | } |
4710 | out: | 4707 | out: |
4711 | if (ret < 0) | 4708 | if (ret < 0) |
4712 | trace_array_put(tr); | 4709 | trace_array_put(tr); |
4713 | 4710 | ||
4714 | return ret; | 4711 | return ret; |
4715 | } | 4712 | } |
4716 | 4713 | ||
4717 | static ssize_t | 4714 | static ssize_t |
4718 | tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, | 4715 | tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, |
4719 | loff_t *ppos) | 4716 | loff_t *ppos) |
4720 | { | 4717 | { |
4721 | struct seq_file *m = filp->private_data; | 4718 | struct seq_file *m = filp->private_data; |
4722 | struct trace_iterator *iter = m->private; | 4719 | struct trace_iterator *iter = m->private; |
4723 | struct trace_array *tr = iter->tr; | 4720 | struct trace_array *tr = iter->tr; |
4724 | unsigned long val; | 4721 | unsigned long val; |
4725 | int ret; | 4722 | int ret; |
4726 | 4723 | ||
4727 | ret = tracing_update_buffers(); | 4724 | ret = tracing_update_buffers(); |
4728 | if (ret < 0) | 4725 | if (ret < 0) |
4729 | return ret; | 4726 | return ret; |
4730 | 4727 | ||
4731 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 4728 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
4732 | if (ret) | 4729 | if (ret) |
4733 | return ret; | 4730 | return ret; |
4734 | 4731 | ||
4735 | mutex_lock(&trace_types_lock); | 4732 | mutex_lock(&trace_types_lock); |
4736 | 4733 | ||
4737 | if (tr->current_trace->use_max_tr) { | 4734 | if (tr->current_trace->use_max_tr) { |
4738 | ret = -EBUSY; | 4735 | ret = -EBUSY; |
4739 | goto out; | 4736 | goto out; |
4740 | } | 4737 | } |
4741 | 4738 | ||
4742 | switch (val) { | 4739 | switch (val) { |
4743 | case 0: | 4740 | case 0: |
4744 | if (iter->cpu_file != RING_BUFFER_ALL_CPUS) { | 4741 | if (iter->cpu_file != RING_BUFFER_ALL_CPUS) { |
4745 | ret = -EINVAL; | 4742 | ret = -EINVAL; |
4746 | break; | 4743 | break; |
4747 | } | 4744 | } |
4748 | if (tr->allocated_snapshot) | 4745 | if (tr->allocated_snapshot) |
4749 | free_snapshot(tr); | 4746 | free_snapshot(tr); |
4750 | break; | 4747 | break; |
4751 | case 1: | 4748 | case 1: |
4752 | /* Only allow per-cpu swap if the ring buffer supports it */ | 4749 | /* Only allow per-cpu swap if the ring buffer supports it */ |
4753 | #ifndef CONFIG_RING_BUFFER_ALLOW_SWAP | 4750 | #ifndef CONFIG_RING_BUFFER_ALLOW_SWAP |
4754 | if (iter->cpu_file != RING_BUFFER_ALL_CPUS) { | 4751 | if (iter->cpu_file != RING_BUFFER_ALL_CPUS) { |
4755 | ret = -EINVAL; | 4752 | ret = -EINVAL; |
4756 | break; | 4753 | break; |
4757 | } | 4754 | } |
4758 | #endif | 4755 | #endif |
4759 | if (!tr->allocated_snapshot) { | 4756 | if (!tr->allocated_snapshot) { |
4760 | ret = alloc_snapshot(tr); | 4757 | ret = alloc_snapshot(tr); |
4761 | if (ret < 0) | 4758 | if (ret < 0) |
4762 | break; | 4759 | break; |
4763 | } | 4760 | } |
4764 | local_irq_disable(); | 4761 | local_irq_disable(); |
4765 | /* Now, we're going to swap */ | 4762 | /* Now, we're going to swap */ |
4766 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) | 4763 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) |
4767 | update_max_tr(tr, current, smp_processor_id()); | 4764 | update_max_tr(tr, current, smp_processor_id()); |
4768 | else | 4765 | else |
4769 | update_max_tr_single(tr, current, iter->cpu_file); | 4766 | update_max_tr_single(tr, current, iter->cpu_file); |
4770 | local_irq_enable(); | 4767 | local_irq_enable(); |
4771 | break; | 4768 | break; |
4772 | default: | 4769 | default: |
4773 | if (tr->allocated_snapshot) { | 4770 | if (tr->allocated_snapshot) { |
4774 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) | 4771 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) |
4775 | tracing_reset_online_cpus(&tr->max_buffer); | 4772 | tracing_reset_online_cpus(&tr->max_buffer); |
4776 | else | 4773 | else |
4777 | tracing_reset(&tr->max_buffer, iter->cpu_file); | 4774 | tracing_reset(&tr->max_buffer, iter->cpu_file); |
4778 | } | 4775 | } |
4779 | break; | 4776 | break; |
4780 | } | 4777 | } |
4781 | 4778 | ||
4782 | if (ret >= 0) { | 4779 | if (ret >= 0) { |
4783 | *ppos += cnt; | 4780 | *ppos += cnt; |
4784 | ret = cnt; | 4781 | ret = cnt; |
4785 | } | 4782 | } |
4786 | out: | 4783 | out: |
4787 | mutex_unlock(&trace_types_lock); | 4784 | mutex_unlock(&trace_types_lock); |
4788 | return ret; | 4785 | return ret; |
4789 | } | 4786 | } |
4790 | 4787 | ||
4791 | static int tracing_snapshot_release(struct inode *inode, struct file *file) | 4788 | static int tracing_snapshot_release(struct inode *inode, struct file *file) |
4792 | { | 4789 | { |
4793 | struct seq_file *m = file->private_data; | 4790 | struct seq_file *m = file->private_data; |
4794 | int ret; | 4791 | int ret; |
4795 | 4792 | ||
4796 | ret = tracing_release(inode, file); | 4793 | ret = tracing_release(inode, file); |
4797 | 4794 | ||
4798 | if (file->f_mode & FMODE_READ) | 4795 | if (file->f_mode & FMODE_READ) |
4799 | return ret; | 4796 | return ret; |
4800 | 4797 | ||
4801 | /* If write only, the seq_file is just a stub */ | 4798 | /* If write only, the seq_file is just a stub */ |
4802 | if (m) | 4799 | if (m) |
4803 | kfree(m->private); | 4800 | kfree(m->private); |
4804 | kfree(m); | 4801 | kfree(m); |
4805 | 4802 | ||
4806 | return 0; | 4803 | return 0; |
4807 | } | 4804 | } |
4808 | 4805 | ||
4809 | static int tracing_buffers_open(struct inode *inode, struct file *filp); | 4806 | static int tracing_buffers_open(struct inode *inode, struct file *filp); |
4810 | static ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf, | 4807 | static ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf, |
4811 | size_t count, loff_t *ppos); | 4808 | size_t count, loff_t *ppos); |
4812 | static int tracing_buffers_release(struct inode *inode, struct file *file); | 4809 | static int tracing_buffers_release(struct inode *inode, struct file *file); |
4813 | static ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos, | 4810 | static ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos, |
4814 | struct pipe_inode_info *pipe, size_t len, unsigned int flags); | 4811 | struct pipe_inode_info *pipe, size_t len, unsigned int flags); |
4815 | 4812 | ||
4816 | static int snapshot_raw_open(struct inode *inode, struct file *filp) | 4813 | static int snapshot_raw_open(struct inode *inode, struct file *filp) |
4817 | { | 4814 | { |
4818 | struct ftrace_buffer_info *info; | 4815 | struct ftrace_buffer_info *info; |
4819 | int ret; | 4816 | int ret; |
4820 | 4817 | ||
4821 | ret = tracing_buffers_open(inode, filp); | 4818 | ret = tracing_buffers_open(inode, filp); |
4822 | if (ret < 0) | 4819 | if (ret < 0) |
4823 | return ret; | 4820 | return ret; |
4824 | 4821 | ||
4825 | info = filp->private_data; | 4822 | info = filp->private_data; |
4826 | 4823 | ||
4827 | if (info->iter.trace->use_max_tr) { | 4824 | if (info->iter.trace->use_max_tr) { |
4828 | tracing_buffers_release(inode, filp); | 4825 | tracing_buffers_release(inode, filp); |
4829 | return -EBUSY; | 4826 | return -EBUSY; |
4830 | } | 4827 | } |
4831 | 4828 | ||
4832 | info->iter.snapshot = true; | 4829 | info->iter.snapshot = true; |
4833 | info->iter.trace_buffer = &info->iter.tr->max_buffer; | 4830 | info->iter.trace_buffer = &info->iter.tr->max_buffer; |
4834 | 4831 | ||
4835 | return ret; | 4832 | return ret; |
4836 | } | 4833 | } |
4837 | 4834 | ||
4838 | #endif /* CONFIG_TRACER_SNAPSHOT */ | 4835 | #endif /* CONFIG_TRACER_SNAPSHOT */ |
4839 | 4836 | ||
4840 | 4837 | ||
4841 | static const struct file_operations tracing_max_lat_fops = { | 4838 | static const struct file_operations tracing_max_lat_fops = { |
4842 | .open = tracing_open_generic, | 4839 | .open = tracing_open_generic, |
4843 | .read = tracing_max_lat_read, | 4840 | .read = tracing_max_lat_read, |
4844 | .write = tracing_max_lat_write, | 4841 | .write = tracing_max_lat_write, |
4845 | .llseek = generic_file_llseek, | 4842 | .llseek = generic_file_llseek, |
4846 | }; | 4843 | }; |
4847 | 4844 | ||
4848 | static const struct file_operations set_tracer_fops = { | 4845 | static const struct file_operations set_tracer_fops = { |
4849 | .open = tracing_open_generic, | 4846 | .open = tracing_open_generic, |
4850 | .read = tracing_set_trace_read, | 4847 | .read = tracing_set_trace_read, |
4851 | .write = tracing_set_trace_write, | 4848 | .write = tracing_set_trace_write, |
4852 | .llseek = generic_file_llseek, | 4849 | .llseek = generic_file_llseek, |
4853 | }; | 4850 | }; |
4854 | 4851 | ||
4855 | static const struct file_operations tracing_pipe_fops = { | 4852 | static const struct file_operations tracing_pipe_fops = { |
4856 | .open = tracing_open_pipe, | 4853 | .open = tracing_open_pipe, |
4857 | .poll = tracing_poll_pipe, | 4854 | .poll = tracing_poll_pipe, |
4858 | .read = tracing_read_pipe, | 4855 | .read = tracing_read_pipe, |
4859 | .splice_read = tracing_splice_read_pipe, | 4856 | .splice_read = tracing_splice_read_pipe, |
4860 | .release = tracing_release_pipe, | 4857 | .release = tracing_release_pipe, |
4861 | .llseek = no_llseek, | 4858 | .llseek = no_llseek, |
4862 | }; | 4859 | }; |
4863 | 4860 | ||
4864 | static const struct file_operations tracing_entries_fops = { | 4861 | static const struct file_operations tracing_entries_fops = { |
4865 | .open = tracing_open_generic_tr, | 4862 | .open = tracing_open_generic_tr, |
4866 | .read = tracing_entries_read, | 4863 | .read = tracing_entries_read, |
4867 | .write = tracing_entries_write, | 4864 | .write = tracing_entries_write, |
4868 | .llseek = generic_file_llseek, | 4865 | .llseek = generic_file_llseek, |
4869 | .release = tracing_release_generic_tr, | 4866 | .release = tracing_release_generic_tr, |
4870 | }; | 4867 | }; |
4871 | 4868 | ||
4872 | static const struct file_operations tracing_total_entries_fops = { | 4869 | static const struct file_operations tracing_total_entries_fops = { |
4873 | .open = tracing_open_generic_tr, | 4870 | .open = tracing_open_generic_tr, |
4874 | .read = tracing_total_entries_read, | 4871 | .read = tracing_total_entries_read, |
4875 | .llseek = generic_file_llseek, | 4872 | .llseek = generic_file_llseek, |
4876 | .release = tracing_release_generic_tr, | 4873 | .release = tracing_release_generic_tr, |
4877 | }; | 4874 | }; |
4878 | 4875 | ||
4879 | static const struct file_operations tracing_free_buffer_fops = { | 4876 | static const struct file_operations tracing_free_buffer_fops = { |
4880 | .open = tracing_open_generic_tr, | 4877 | .open = tracing_open_generic_tr, |
4881 | .write = tracing_free_buffer_write, | 4878 | .write = tracing_free_buffer_write, |
4882 | .release = tracing_free_buffer_release, | 4879 | .release = tracing_free_buffer_release, |
4883 | }; | 4880 | }; |
4884 | 4881 | ||
4885 | static const struct file_operations tracing_mark_fops = { | 4882 | static const struct file_operations tracing_mark_fops = { |
4886 | .open = tracing_open_generic_tr, | 4883 | .open = tracing_open_generic_tr, |
4887 | .write = tracing_mark_write, | 4884 | .write = tracing_mark_write, |
4888 | .llseek = generic_file_llseek, | 4885 | .llseek = generic_file_llseek, |
4889 | .release = tracing_release_generic_tr, | 4886 | .release = tracing_release_generic_tr, |
4890 | }; | 4887 | }; |
4891 | 4888 | ||
4892 | static const struct file_operations trace_clock_fops = { | 4889 | static const struct file_operations trace_clock_fops = { |
4893 | .open = tracing_clock_open, | 4890 | .open = tracing_clock_open, |
4894 | .read = seq_read, | 4891 | .read = seq_read, |
4895 | .llseek = seq_lseek, | 4892 | .llseek = seq_lseek, |
4896 | .release = tracing_single_release_tr, | 4893 | .release = tracing_single_release_tr, |
4897 | .write = tracing_clock_write, | 4894 | .write = tracing_clock_write, |
4898 | }; | 4895 | }; |
4899 | 4896 | ||
4900 | #ifdef CONFIG_TRACER_SNAPSHOT | 4897 | #ifdef CONFIG_TRACER_SNAPSHOT |
4901 | static const struct file_operations snapshot_fops = { | 4898 | static const struct file_operations snapshot_fops = { |
4902 | .open = tracing_snapshot_open, | 4899 | .open = tracing_snapshot_open, |
4903 | .read = seq_read, | 4900 | .read = seq_read, |
4904 | .write = tracing_snapshot_write, | 4901 | .write = tracing_snapshot_write, |
4905 | .llseek = tracing_seek, | 4902 | .llseek = tracing_seek, |
4906 | .release = tracing_snapshot_release, | 4903 | .release = tracing_snapshot_release, |
4907 | }; | 4904 | }; |
4908 | 4905 | ||
4909 | static const struct file_operations snapshot_raw_fops = { | 4906 | static const struct file_operations snapshot_raw_fops = { |
4910 | .open = snapshot_raw_open, | 4907 | .open = snapshot_raw_open, |
4911 | .read = tracing_buffers_read, | 4908 | .read = tracing_buffers_read, |
4912 | .release = tracing_buffers_release, | 4909 | .release = tracing_buffers_release, |
4913 | .splice_read = tracing_buffers_splice_read, | 4910 | .splice_read = tracing_buffers_splice_read, |
4914 | .llseek = no_llseek, | 4911 | .llseek = no_llseek, |
4915 | }; | 4912 | }; |
4916 | 4913 | ||
4917 | #endif /* CONFIG_TRACER_SNAPSHOT */ | 4914 | #endif /* CONFIG_TRACER_SNAPSHOT */ |
4918 | 4915 | ||
4919 | static int tracing_buffers_open(struct inode *inode, struct file *filp) | 4916 | static int tracing_buffers_open(struct inode *inode, struct file *filp) |
4920 | { | 4917 | { |
4921 | struct trace_array *tr = inode->i_private; | 4918 | struct trace_array *tr = inode->i_private; |
4922 | struct ftrace_buffer_info *info; | 4919 | struct ftrace_buffer_info *info; |
4923 | int ret; | 4920 | int ret; |
4924 | 4921 | ||
4925 | if (tracing_disabled) | 4922 | if (tracing_disabled) |
4926 | return -ENODEV; | 4923 | return -ENODEV; |
4927 | 4924 | ||
4928 | if (trace_array_get(tr) < 0) | 4925 | if (trace_array_get(tr) < 0) |
4929 | return -ENODEV; | 4926 | return -ENODEV; |
4930 | 4927 | ||
4931 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 4928 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
4932 | if (!info) { | 4929 | if (!info) { |
4933 | trace_array_put(tr); | 4930 | trace_array_put(tr); |
4934 | return -ENOMEM; | 4931 | return -ENOMEM; |
4935 | } | 4932 | } |
4936 | 4933 | ||
4937 | mutex_lock(&trace_types_lock); | 4934 | mutex_lock(&trace_types_lock); |
4938 | 4935 | ||
4939 | info->iter.tr = tr; | 4936 | info->iter.tr = tr; |
4940 | info->iter.cpu_file = tracing_get_cpu(inode); | 4937 | info->iter.cpu_file = tracing_get_cpu(inode); |
4941 | info->iter.trace = tr->current_trace; | 4938 | info->iter.trace = tr->current_trace; |
4942 | info->iter.trace_buffer = &tr->trace_buffer; | 4939 | info->iter.trace_buffer = &tr->trace_buffer; |
4943 | info->spare = NULL; | 4940 | info->spare = NULL; |
4944 | /* Force reading ring buffer for first read */ | 4941 | /* Force reading ring buffer for first read */ |
4945 | info->read = (unsigned int)-1; | 4942 | info->read = (unsigned int)-1; |
4946 | 4943 | ||
4947 | filp->private_data = info; | 4944 | filp->private_data = info; |
4948 | 4945 | ||
4949 | mutex_unlock(&trace_types_lock); | 4946 | mutex_unlock(&trace_types_lock); |
4950 | 4947 | ||
4951 | ret = nonseekable_open(inode, filp); | 4948 | ret = nonseekable_open(inode, filp); |
4952 | if (ret < 0) | 4949 | if (ret < 0) |
4953 | trace_array_put(tr); | 4950 | trace_array_put(tr); |
4954 | 4951 | ||
4955 | return ret; | 4952 | return ret; |
4956 | } | 4953 | } |
4957 | 4954 | ||
4958 | static unsigned int | 4955 | static unsigned int |
4959 | tracing_buffers_poll(struct file *filp, poll_table *poll_table) | 4956 | tracing_buffers_poll(struct file *filp, poll_table *poll_table) |
4960 | { | 4957 | { |
4961 | struct ftrace_buffer_info *info = filp->private_data; | 4958 | struct ftrace_buffer_info *info = filp->private_data; |
4962 | struct trace_iterator *iter = &info->iter; | 4959 | struct trace_iterator *iter = &info->iter; |
4963 | 4960 | ||
4964 | return trace_poll(iter, filp, poll_table); | 4961 | return trace_poll(iter, filp, poll_table); |
4965 | } | 4962 | } |
4966 | 4963 | ||
4967 | static ssize_t | 4964 | static ssize_t |
4968 | tracing_buffers_read(struct file *filp, char __user *ubuf, | 4965 | tracing_buffers_read(struct file *filp, char __user *ubuf, |
4969 | size_t count, loff_t *ppos) | 4966 | size_t count, loff_t *ppos) |
4970 | { | 4967 | { |
4971 | struct ftrace_buffer_info *info = filp->private_data; | 4968 | struct ftrace_buffer_info *info = filp->private_data; |
4972 | struct trace_iterator *iter = &info->iter; | 4969 | struct trace_iterator *iter = &info->iter; |
4973 | ssize_t ret; | 4970 | ssize_t ret; |
4974 | ssize_t size; | 4971 | ssize_t size; |
4975 | 4972 | ||
4976 | if (!count) | 4973 | if (!count) |
4977 | return 0; | 4974 | return 0; |
4978 | 4975 | ||
4979 | mutex_lock(&trace_types_lock); | 4976 | mutex_lock(&trace_types_lock); |
4980 | 4977 | ||
4981 | #ifdef CONFIG_TRACER_MAX_TRACE | 4978 | #ifdef CONFIG_TRACER_MAX_TRACE |
4982 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) { | 4979 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) { |
4983 | size = -EBUSY; | 4980 | size = -EBUSY; |
4984 | goto out_unlock; | 4981 | goto out_unlock; |
4985 | } | 4982 | } |
4986 | #endif | 4983 | #endif |
4987 | 4984 | ||
4988 | if (!info->spare) | 4985 | if (!info->spare) |
4989 | info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer, | 4986 | info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer, |
4990 | iter->cpu_file); | 4987 | iter->cpu_file); |
4991 | size = -ENOMEM; | 4988 | size = -ENOMEM; |
4992 | if (!info->spare) | 4989 | if (!info->spare) |
4993 | goto out_unlock; | 4990 | goto out_unlock; |
4994 | 4991 | ||
4995 | /* Do we have previous read data to read? */ | 4992 | /* Do we have previous read data to read? */ |
4996 | if (info->read < PAGE_SIZE) | 4993 | if (info->read < PAGE_SIZE) |
4997 | goto read; | 4994 | goto read; |
4998 | 4995 | ||
4999 | again: | 4996 | again: |
5000 | trace_access_lock(iter->cpu_file); | 4997 | trace_access_lock(iter->cpu_file); |
5001 | ret = ring_buffer_read_page(iter->trace_buffer->buffer, | 4998 | ret = ring_buffer_read_page(iter->trace_buffer->buffer, |
5002 | &info->spare, | 4999 | &info->spare, |
5003 | count, | 5000 | count, |
5004 | iter->cpu_file, 0); | 5001 | iter->cpu_file, 0); |
5005 | trace_access_unlock(iter->cpu_file); | 5002 | trace_access_unlock(iter->cpu_file); |
5006 | 5003 | ||
5007 | if (ret < 0) { | 5004 | if (ret < 0) { |
5008 | if (trace_empty(iter)) { | 5005 | if (trace_empty(iter)) { |
5009 | if ((filp->f_flags & O_NONBLOCK)) { | 5006 | if ((filp->f_flags & O_NONBLOCK)) { |
5010 | size = -EAGAIN; | 5007 | size = -EAGAIN; |
5011 | goto out_unlock; | 5008 | goto out_unlock; |
5012 | } | 5009 | } |
5013 | mutex_unlock(&trace_types_lock); | 5010 | mutex_unlock(&trace_types_lock); |
5014 | iter->trace->wait_pipe(iter); | 5011 | iter->trace->wait_pipe(iter); |
5015 | mutex_lock(&trace_types_lock); | 5012 | mutex_lock(&trace_types_lock); |
5016 | if (signal_pending(current)) { | 5013 | if (signal_pending(current)) { |
5017 | size = -EINTR; | 5014 | size = -EINTR; |
5018 | goto out_unlock; | 5015 | goto out_unlock; |
5019 | } | 5016 | } |
5020 | goto again; | 5017 | goto again; |
5021 | } | 5018 | } |
5022 | size = 0; | 5019 | size = 0; |
5023 | goto out_unlock; | 5020 | goto out_unlock; |
5024 | } | 5021 | } |
5025 | 5022 | ||
5026 | info->read = 0; | 5023 | info->read = 0; |
5027 | read: | 5024 | read: |
5028 | size = PAGE_SIZE - info->read; | 5025 | size = PAGE_SIZE - info->read; |
5029 | if (size > count) | 5026 | if (size > count) |
5030 | size = count; | 5027 | size = count; |
5031 | 5028 | ||
5032 | ret = copy_to_user(ubuf, info->spare + info->read, size); | 5029 | ret = copy_to_user(ubuf, info->spare + info->read, size); |
5033 | if (ret == size) { | 5030 | if (ret == size) { |
5034 | size = -EFAULT; | 5031 | size = -EFAULT; |
5035 | goto out_unlock; | 5032 | goto out_unlock; |
5036 | } | 5033 | } |
5037 | size -= ret; | 5034 | size -= ret; |
5038 | 5035 | ||
5039 | *ppos += size; | 5036 | *ppos += size; |
5040 | info->read += size; | 5037 | info->read += size; |
5041 | 5038 | ||
5042 | out_unlock: | 5039 | out_unlock: |
5043 | mutex_unlock(&trace_types_lock); | 5040 | mutex_unlock(&trace_types_lock); |
5044 | 5041 | ||
5045 | return size; | 5042 | return size; |
5046 | } | 5043 | } |
5047 | 5044 | ||
5048 | static int tracing_buffers_release(struct inode *inode, struct file *file) | 5045 | static int tracing_buffers_release(struct inode *inode, struct file *file) |
5049 | { | 5046 | { |
5050 | struct ftrace_buffer_info *info = file->private_data; | 5047 | struct ftrace_buffer_info *info = file->private_data; |
5051 | struct trace_iterator *iter = &info->iter; | 5048 | struct trace_iterator *iter = &info->iter; |
5052 | 5049 | ||
5053 | mutex_lock(&trace_types_lock); | 5050 | mutex_lock(&trace_types_lock); |
5054 | 5051 | ||
5055 | __trace_array_put(iter->tr); | 5052 | __trace_array_put(iter->tr); |
5056 | 5053 | ||
5057 | if (info->spare) | 5054 | if (info->spare) |
5058 | ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); | 5055 | ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); |
5059 | kfree(info); | 5056 | kfree(info); |
5060 | 5057 | ||
5061 | mutex_unlock(&trace_types_lock); | 5058 | mutex_unlock(&trace_types_lock); |
5062 | 5059 | ||
5063 | return 0; | 5060 | return 0; |
5064 | } | 5061 | } |
5065 | 5062 | ||
5066 | struct buffer_ref { | 5063 | struct buffer_ref { |
5067 | struct ring_buffer *buffer; | 5064 | struct ring_buffer *buffer; |
5068 | void *page; | 5065 | void *page; |
5069 | int ref; | 5066 | int ref; |
5070 | }; | 5067 | }; |
5071 | 5068 | ||
5072 | static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, | 5069 | static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, |
5073 | struct pipe_buffer *buf) | 5070 | struct pipe_buffer *buf) |
5074 | { | 5071 | { |
5075 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; | 5072 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; |
5076 | 5073 | ||
5077 | if (--ref->ref) | 5074 | if (--ref->ref) |
5078 | return; | 5075 | return; |
5079 | 5076 | ||
5080 | ring_buffer_free_read_page(ref->buffer, ref->page); | 5077 | ring_buffer_free_read_page(ref->buffer, ref->page); |
5081 | kfree(ref); | 5078 | kfree(ref); |
5082 | buf->private = 0; | 5079 | buf->private = 0; |
5083 | } | 5080 | } |
5084 | 5081 | ||
5085 | static void buffer_pipe_buf_get(struct pipe_inode_info *pipe, | 5082 | static void buffer_pipe_buf_get(struct pipe_inode_info *pipe, |
5086 | struct pipe_buffer *buf) | 5083 | struct pipe_buffer *buf) |
5087 | { | 5084 | { |
5088 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; | 5085 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; |
5089 | 5086 | ||
5090 | ref->ref++; | 5087 | ref->ref++; |
5091 | } | 5088 | } |
5092 | 5089 | ||
5093 | /* Pipe buffer operations for a buffer. */ | 5090 | /* Pipe buffer operations for a buffer. */ |
5094 | static const struct pipe_buf_operations buffer_pipe_buf_ops = { | 5091 | static const struct pipe_buf_operations buffer_pipe_buf_ops = { |
5095 | .can_merge = 0, | 5092 | .can_merge = 0, |
5096 | .map = generic_pipe_buf_map, | 5093 | .map = generic_pipe_buf_map, |
5097 | .unmap = generic_pipe_buf_unmap, | 5094 | .unmap = generic_pipe_buf_unmap, |
5098 | .confirm = generic_pipe_buf_confirm, | 5095 | .confirm = generic_pipe_buf_confirm, |
5099 | .release = buffer_pipe_buf_release, | 5096 | .release = buffer_pipe_buf_release, |
5100 | .steal = generic_pipe_buf_steal, | 5097 | .steal = generic_pipe_buf_steal, |
5101 | .get = buffer_pipe_buf_get, | 5098 | .get = buffer_pipe_buf_get, |
5102 | }; | 5099 | }; |
5103 | 5100 | ||
5104 | /* | 5101 | /* |
5105 | * Callback from splice_to_pipe(), if we need to release some pages | 5102 | * Callback from splice_to_pipe(), if we need to release some pages |
5106 | * at the end of the spd in case we error'ed out in filling the pipe. | 5103 | * at the end of the spd in case we error'ed out in filling the pipe. |
5107 | */ | 5104 | */ |
5108 | static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i) | 5105 | static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i) |
5109 | { | 5106 | { |
5110 | struct buffer_ref *ref = | 5107 | struct buffer_ref *ref = |
5111 | (struct buffer_ref *)spd->partial[i].private; | 5108 | (struct buffer_ref *)spd->partial[i].private; |
5112 | 5109 | ||
5113 | if (--ref->ref) | 5110 | if (--ref->ref) |
5114 | return; | 5111 | return; |
5115 | 5112 | ||
5116 | ring_buffer_free_read_page(ref->buffer, ref->page); | 5113 | ring_buffer_free_read_page(ref->buffer, ref->page); |
5117 | kfree(ref); | 5114 | kfree(ref); |
5118 | spd->partial[i].private = 0; | 5115 | spd->partial[i].private = 0; |
5119 | } | 5116 | } |
5120 | 5117 | ||
5121 | static ssize_t | 5118 | static ssize_t |
5122 | tracing_buffers_splice_read(struct file *file, loff_t *ppos, | 5119 | tracing_buffers_splice_read(struct file *file, loff_t *ppos, |
5123 | struct pipe_inode_info *pipe, size_t len, | 5120 | struct pipe_inode_info *pipe, size_t len, |
5124 | unsigned int flags) | 5121 | unsigned int flags) |
5125 | { | 5122 | { |
5126 | struct ftrace_buffer_info *info = file->private_data; | 5123 | struct ftrace_buffer_info *info = file->private_data; |
5127 | struct trace_iterator *iter = &info->iter; | 5124 | struct trace_iterator *iter = &info->iter; |
5128 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; | 5125 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; |
5129 | struct page *pages_def[PIPE_DEF_BUFFERS]; | 5126 | struct page *pages_def[PIPE_DEF_BUFFERS]; |
5130 | struct splice_pipe_desc spd = { | 5127 | struct splice_pipe_desc spd = { |
5131 | .pages = pages_def, | 5128 | .pages = pages_def, |
5132 | .partial = partial_def, | 5129 | .partial = partial_def, |
5133 | .nr_pages_max = PIPE_DEF_BUFFERS, | 5130 | .nr_pages_max = PIPE_DEF_BUFFERS, |
5134 | .flags = flags, | 5131 | .flags = flags, |
5135 | .ops = &buffer_pipe_buf_ops, | 5132 | .ops = &buffer_pipe_buf_ops, |
5136 | .spd_release = buffer_spd_release, | 5133 | .spd_release = buffer_spd_release, |
5137 | }; | 5134 | }; |
5138 | struct buffer_ref *ref; | 5135 | struct buffer_ref *ref; |
5139 | int entries, size, i; | 5136 | int entries, size, i; |
5140 | ssize_t ret; | 5137 | ssize_t ret; |
5141 | 5138 | ||
5142 | mutex_lock(&trace_types_lock); | 5139 | mutex_lock(&trace_types_lock); |
5143 | 5140 | ||
5144 | #ifdef CONFIG_TRACER_MAX_TRACE | 5141 | #ifdef CONFIG_TRACER_MAX_TRACE |
5145 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) { | 5142 | if (iter->snapshot && iter->tr->current_trace->use_max_tr) { |
5146 | ret = -EBUSY; | 5143 | ret = -EBUSY; |
5147 | goto out; | 5144 | goto out; |
5148 | } | 5145 | } |
5149 | #endif | 5146 | #endif |
5150 | 5147 | ||
5151 | if (splice_grow_spd(pipe, &spd)) { | 5148 | if (splice_grow_spd(pipe, &spd)) { |
5152 | ret = -ENOMEM; | 5149 | ret = -ENOMEM; |
5153 | goto out; | 5150 | goto out; |
5154 | } | 5151 | } |
5155 | 5152 | ||
5156 | if (*ppos & (PAGE_SIZE - 1)) { | 5153 | if (*ppos & (PAGE_SIZE - 1)) { |
5157 | ret = -EINVAL; | 5154 | ret = -EINVAL; |
5158 | goto out; | 5155 | goto out; |
5159 | } | 5156 | } |
5160 | 5157 | ||
5161 | if (len & (PAGE_SIZE - 1)) { | 5158 | if (len & (PAGE_SIZE - 1)) { |
5162 | if (len < PAGE_SIZE) { | 5159 | if (len < PAGE_SIZE) { |
5163 | ret = -EINVAL; | 5160 | ret = -EINVAL; |
5164 | goto out; | 5161 | goto out; |
5165 | } | 5162 | } |
5166 | len &= PAGE_MASK; | 5163 | len &= PAGE_MASK; |
5167 | } | 5164 | } |
5168 | 5165 | ||
5169 | again: | 5166 | again: |
5170 | trace_access_lock(iter->cpu_file); | 5167 | trace_access_lock(iter->cpu_file); |
5171 | entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); | 5168 | entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); |
5172 | 5169 | ||
5173 | for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) { | 5170 | for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) { |
5174 | struct page *page; | 5171 | struct page *page; |
5175 | int r; | 5172 | int r; |
5176 | 5173 | ||
5177 | ref = kzalloc(sizeof(*ref), GFP_KERNEL); | 5174 | ref = kzalloc(sizeof(*ref), GFP_KERNEL); |
5178 | if (!ref) | 5175 | if (!ref) |
5179 | break; | 5176 | break; |
5180 | 5177 | ||
5181 | ref->ref = 1; | 5178 | ref->ref = 1; |
5182 | ref->buffer = iter->trace_buffer->buffer; | 5179 | ref->buffer = iter->trace_buffer->buffer; |
5183 | ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); | 5180 | ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); |
5184 | if (!ref->page) { | 5181 | if (!ref->page) { |
5185 | kfree(ref); | 5182 | kfree(ref); |
5186 | break; | 5183 | break; |
5187 | } | 5184 | } |
5188 | 5185 | ||
5189 | r = ring_buffer_read_page(ref->buffer, &ref->page, | 5186 | r = ring_buffer_read_page(ref->buffer, &ref->page, |
5190 | len, iter->cpu_file, 1); | 5187 | len, iter->cpu_file, 1); |
5191 | if (r < 0) { | 5188 | if (r < 0) { |
5192 | ring_buffer_free_read_page(ref->buffer, ref->page); | 5189 | ring_buffer_free_read_page(ref->buffer, ref->page); |
5193 | kfree(ref); | 5190 | kfree(ref); |
5194 | break; | 5191 | break; |
5195 | } | 5192 | } |
5196 | 5193 | ||
5197 | /* | 5194 | /* |
5198 | * zero out any left over data, this is going to | 5195 | * zero out any left over data, this is going to |
5199 | * user land. | 5196 | * user land. |
5200 | */ | 5197 | */ |
5201 | size = ring_buffer_page_len(ref->page); | 5198 | size = ring_buffer_page_len(ref->page); |
5202 | if (size < PAGE_SIZE) | 5199 | if (size < PAGE_SIZE) |
5203 | memset(ref->page + size, 0, PAGE_SIZE - size); | 5200 | memset(ref->page + size, 0, PAGE_SIZE - size); |
5204 | 5201 | ||
5205 | page = virt_to_page(ref->page); | 5202 | page = virt_to_page(ref->page); |
5206 | 5203 | ||
5207 | spd.pages[i] = page; | 5204 | spd.pages[i] = page; |
5208 | spd.partial[i].len = PAGE_SIZE; | 5205 | spd.partial[i].len = PAGE_SIZE; |
5209 | spd.partial[i].offset = 0; | 5206 | spd.partial[i].offset = 0; |
5210 | spd.partial[i].private = (unsigned long)ref; | 5207 | spd.partial[i].private = (unsigned long)ref; |
5211 | spd.nr_pages++; | 5208 | spd.nr_pages++; |
5212 | *ppos += PAGE_SIZE; | 5209 | *ppos += PAGE_SIZE; |
5213 | 5210 | ||
5214 | entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); | 5211 | entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); |
5215 | } | 5212 | } |
5216 | 5213 | ||
5217 | trace_access_unlock(iter->cpu_file); | 5214 | trace_access_unlock(iter->cpu_file); |
5218 | spd.nr_pages = i; | 5215 | spd.nr_pages = i; |
5219 | 5216 | ||
5220 | /* did we read anything? */ | 5217 | /* did we read anything? */ |
5221 | if (!spd.nr_pages) { | 5218 | if (!spd.nr_pages) { |
5222 | if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) { | 5219 | if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) { |
5223 | ret = -EAGAIN; | 5220 | ret = -EAGAIN; |
5224 | goto out; | 5221 | goto out; |
5225 | } | 5222 | } |
5226 | mutex_unlock(&trace_types_lock); | 5223 | mutex_unlock(&trace_types_lock); |
5227 | iter->trace->wait_pipe(iter); | 5224 | iter->trace->wait_pipe(iter); |
5228 | mutex_lock(&trace_types_lock); | 5225 | mutex_lock(&trace_types_lock); |
5229 | if (signal_pending(current)) { | 5226 | if (signal_pending(current)) { |
5230 | ret = -EINTR; | 5227 | ret = -EINTR; |
5231 | goto out; | 5228 | goto out; |
5232 | } | 5229 | } |
5233 | goto again; | 5230 | goto again; |
5234 | } | 5231 | } |
5235 | 5232 | ||
5236 | ret = splice_to_pipe(pipe, &spd); | 5233 | ret = splice_to_pipe(pipe, &spd); |
5237 | splice_shrink_spd(&spd); | 5234 | splice_shrink_spd(&spd); |
5238 | out: | 5235 | out: |
5239 | mutex_unlock(&trace_types_lock); | 5236 | mutex_unlock(&trace_types_lock); |
5240 | 5237 | ||
5241 | return ret; | 5238 | return ret; |
5242 | } | 5239 | } |
5243 | 5240 | ||
5244 | static const struct file_operations tracing_buffers_fops = { | 5241 | static const struct file_operations tracing_buffers_fops = { |
5245 | .open = tracing_buffers_open, | 5242 | .open = tracing_buffers_open, |
5246 | .read = tracing_buffers_read, | 5243 | .read = tracing_buffers_read, |
5247 | .poll = tracing_buffers_poll, | 5244 | .poll = tracing_buffers_poll, |
5248 | .release = tracing_buffers_release, | 5245 | .release = tracing_buffers_release, |
5249 | .splice_read = tracing_buffers_splice_read, | 5246 | .splice_read = tracing_buffers_splice_read, |
5250 | .llseek = no_llseek, | 5247 | .llseek = no_llseek, |
5251 | }; | 5248 | }; |
5252 | 5249 | ||
5253 | static ssize_t | 5250 | static ssize_t |
5254 | tracing_stats_read(struct file *filp, char __user *ubuf, | 5251 | tracing_stats_read(struct file *filp, char __user *ubuf, |
5255 | size_t count, loff_t *ppos) | 5252 | size_t count, loff_t *ppos) |
5256 | { | 5253 | { |
5257 | struct inode *inode = file_inode(filp); | 5254 | struct inode *inode = file_inode(filp); |
5258 | struct trace_array *tr = inode->i_private; | 5255 | struct trace_array *tr = inode->i_private; |
5259 | struct trace_buffer *trace_buf = &tr->trace_buffer; | 5256 | struct trace_buffer *trace_buf = &tr->trace_buffer; |
5260 | int cpu = tracing_get_cpu(inode); | 5257 | int cpu = tracing_get_cpu(inode); |
5261 | struct trace_seq *s; | 5258 | struct trace_seq *s; |
5262 | unsigned long cnt; | 5259 | unsigned long cnt; |
5263 | unsigned long long t; | 5260 | unsigned long long t; |
5264 | unsigned long usec_rem; | 5261 | unsigned long usec_rem; |
5265 | 5262 | ||
5266 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 5263 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
5267 | if (!s) | 5264 | if (!s) |
5268 | return -ENOMEM; | 5265 | return -ENOMEM; |
5269 | 5266 | ||
5270 | trace_seq_init(s); | 5267 | trace_seq_init(s); |
5271 | 5268 | ||
5272 | cnt = ring_buffer_entries_cpu(trace_buf->buffer, cpu); | 5269 | cnt = ring_buffer_entries_cpu(trace_buf->buffer, cpu); |
5273 | trace_seq_printf(s, "entries: %ld\n", cnt); | 5270 | trace_seq_printf(s, "entries: %ld\n", cnt); |
5274 | 5271 | ||
5275 | cnt = ring_buffer_overrun_cpu(trace_buf->buffer, cpu); | 5272 | cnt = ring_buffer_overrun_cpu(trace_buf->buffer, cpu); |
5276 | trace_seq_printf(s, "overrun: %ld\n", cnt); | 5273 | trace_seq_printf(s, "overrun: %ld\n", cnt); |
5277 | 5274 | ||
5278 | cnt = ring_buffer_commit_overrun_cpu(trace_buf->buffer, cpu); | 5275 | cnt = ring_buffer_commit_overrun_cpu(trace_buf->buffer, cpu); |
5279 | trace_seq_printf(s, "commit overrun: %ld\n", cnt); | 5276 | trace_seq_printf(s, "commit overrun: %ld\n", cnt); |
5280 | 5277 | ||
5281 | cnt = ring_buffer_bytes_cpu(trace_buf->buffer, cpu); | 5278 | cnt = ring_buffer_bytes_cpu(trace_buf->buffer, cpu); |
5282 | trace_seq_printf(s, "bytes: %ld\n", cnt); | 5279 | trace_seq_printf(s, "bytes: %ld\n", cnt); |
5283 | 5280 | ||
5284 | if (trace_clocks[tr->clock_id].in_ns) { | 5281 | if (trace_clocks[tr->clock_id].in_ns) { |
5285 | /* local or global for trace_clock */ | 5282 | /* local or global for trace_clock */ |
5286 | t = ns2usecs(ring_buffer_oldest_event_ts(trace_buf->buffer, cpu)); | 5283 | t = ns2usecs(ring_buffer_oldest_event_ts(trace_buf->buffer, cpu)); |
5287 | usec_rem = do_div(t, USEC_PER_SEC); | 5284 | usec_rem = do_div(t, USEC_PER_SEC); |
5288 | trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", | 5285 | trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", |
5289 | t, usec_rem); | 5286 | t, usec_rem); |
5290 | 5287 | ||
5291 | t = ns2usecs(ring_buffer_time_stamp(trace_buf->buffer, cpu)); | 5288 | t = ns2usecs(ring_buffer_time_stamp(trace_buf->buffer, cpu)); |
5292 | usec_rem = do_div(t, USEC_PER_SEC); | 5289 | usec_rem = do_div(t, USEC_PER_SEC); |
5293 | trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); | 5290 | trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); |
5294 | } else { | 5291 | } else { |
5295 | /* counter or tsc mode for trace_clock */ | 5292 | /* counter or tsc mode for trace_clock */ |
5296 | trace_seq_printf(s, "oldest event ts: %llu\n", | 5293 | trace_seq_printf(s, "oldest event ts: %llu\n", |
5297 | ring_buffer_oldest_event_ts(trace_buf->buffer, cpu)); | 5294 | ring_buffer_oldest_event_ts(trace_buf->buffer, cpu)); |
5298 | 5295 | ||
5299 | trace_seq_printf(s, "now ts: %llu\n", | 5296 | trace_seq_printf(s, "now ts: %llu\n", |
5300 | ring_buffer_time_stamp(trace_buf->buffer, cpu)); | 5297 | ring_buffer_time_stamp(trace_buf->buffer, cpu)); |
5301 | } | 5298 | } |
5302 | 5299 | ||
5303 | cnt = ring_buffer_dropped_events_cpu(trace_buf->buffer, cpu); | 5300 | cnt = ring_buffer_dropped_events_cpu(trace_buf->buffer, cpu); |
5304 | trace_seq_printf(s, "dropped events: %ld\n", cnt); | 5301 | trace_seq_printf(s, "dropped events: %ld\n", cnt); |
5305 | 5302 | ||
5306 | cnt = ring_buffer_read_events_cpu(trace_buf->buffer, cpu); | 5303 | cnt = ring_buffer_read_events_cpu(trace_buf->buffer, cpu); |
5307 | trace_seq_printf(s, "read events: %ld\n", cnt); | 5304 | trace_seq_printf(s, "read events: %ld\n", cnt); |
5308 | 5305 | ||
5309 | count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len); | 5306 | count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len); |
5310 | 5307 | ||
5311 | kfree(s); | 5308 | kfree(s); |
5312 | 5309 | ||
5313 | return count; | 5310 | return count; |
5314 | } | 5311 | } |
5315 | 5312 | ||
5316 | static const struct file_operations tracing_stats_fops = { | 5313 | static const struct file_operations tracing_stats_fops = { |
5317 | .open = tracing_open_generic_tr, | 5314 | .open = tracing_open_generic_tr, |
5318 | .read = tracing_stats_read, | 5315 | .read = tracing_stats_read, |
5319 | .llseek = generic_file_llseek, | 5316 | .llseek = generic_file_llseek, |
5320 | .release = tracing_release_generic_tr, | 5317 | .release = tracing_release_generic_tr, |
5321 | }; | 5318 | }; |
5322 | 5319 | ||
5323 | #ifdef CONFIG_DYNAMIC_FTRACE | 5320 | #ifdef CONFIG_DYNAMIC_FTRACE |
5324 | 5321 | ||
5325 | int __weak ftrace_arch_read_dyn_info(char *buf, int size) | 5322 | int __weak ftrace_arch_read_dyn_info(char *buf, int size) |
5326 | { | 5323 | { |
5327 | return 0; | 5324 | return 0; |
5328 | } | 5325 | } |
5329 | 5326 | ||
5330 | static ssize_t | 5327 | static ssize_t |
5331 | tracing_read_dyn_info(struct file *filp, char __user *ubuf, | 5328 | tracing_read_dyn_info(struct file *filp, char __user *ubuf, |
5332 | size_t cnt, loff_t *ppos) | 5329 | size_t cnt, loff_t *ppos) |
5333 | { | 5330 | { |
5334 | static char ftrace_dyn_info_buffer[1024]; | 5331 | static char ftrace_dyn_info_buffer[1024]; |
5335 | static DEFINE_MUTEX(dyn_info_mutex); | 5332 | static DEFINE_MUTEX(dyn_info_mutex); |
5336 | unsigned long *p = filp->private_data; | 5333 | unsigned long *p = filp->private_data; |
5337 | char *buf = ftrace_dyn_info_buffer; | 5334 | char *buf = ftrace_dyn_info_buffer; |
5338 | int size = ARRAY_SIZE(ftrace_dyn_info_buffer); | 5335 | int size = ARRAY_SIZE(ftrace_dyn_info_buffer); |
5339 | int r; | 5336 | int r; |
5340 | 5337 | ||
5341 | mutex_lock(&dyn_info_mutex); | 5338 | mutex_lock(&dyn_info_mutex); |
5342 | r = sprintf(buf, "%ld ", *p); | 5339 | r = sprintf(buf, "%ld ", *p); |
5343 | 5340 | ||
5344 | r += ftrace_arch_read_dyn_info(buf+r, (size-1)-r); | 5341 | r += ftrace_arch_read_dyn_info(buf+r, (size-1)-r); |
5345 | buf[r++] = '\n'; | 5342 | buf[r++] = '\n'; |
5346 | 5343 | ||
5347 | r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 5344 | r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
5348 | 5345 | ||
5349 | mutex_unlock(&dyn_info_mutex); | 5346 | mutex_unlock(&dyn_info_mutex); |
5350 | 5347 | ||
5351 | return r; | 5348 | return r; |
5352 | } | 5349 | } |
5353 | 5350 | ||
5354 | static const struct file_operations tracing_dyn_info_fops = { | 5351 | static const struct file_operations tracing_dyn_info_fops = { |
5355 | .open = tracing_open_generic, | 5352 | .open = tracing_open_generic, |
5356 | .read = tracing_read_dyn_info, | 5353 | .read = tracing_read_dyn_info, |
5357 | .llseek = generic_file_llseek, | 5354 | .llseek = generic_file_llseek, |
5358 | }; | 5355 | }; |
5359 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 5356 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
5360 | 5357 | ||
5361 | #if defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) | 5358 | #if defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) |
5362 | static void | 5359 | static void |
5363 | ftrace_snapshot(unsigned long ip, unsigned long parent_ip, void **data) | 5360 | ftrace_snapshot(unsigned long ip, unsigned long parent_ip, void **data) |
5364 | { | 5361 | { |
5365 | tracing_snapshot(); | 5362 | tracing_snapshot(); |
5366 | } | 5363 | } |
5367 | 5364 | ||
5368 | static void | 5365 | static void |
5369 | ftrace_count_snapshot(unsigned long ip, unsigned long parent_ip, void **data) | 5366 | ftrace_count_snapshot(unsigned long ip, unsigned long parent_ip, void **data) |
5370 | { | 5367 | { |
5371 | unsigned long *count = (long *)data; | 5368 | unsigned long *count = (long *)data; |
5372 | 5369 | ||
5373 | if (!*count) | 5370 | if (!*count) |
5374 | return; | 5371 | return; |
5375 | 5372 | ||
5376 | if (*count != -1) | 5373 | if (*count != -1) |
5377 | (*count)--; | 5374 | (*count)--; |
5378 | 5375 | ||
5379 | tracing_snapshot(); | 5376 | tracing_snapshot(); |
5380 | } | 5377 | } |
5381 | 5378 | ||
5382 | static int | 5379 | static int |
5383 | ftrace_snapshot_print(struct seq_file *m, unsigned long ip, | 5380 | ftrace_snapshot_print(struct seq_file *m, unsigned long ip, |
5384 | struct ftrace_probe_ops *ops, void *data) | 5381 | struct ftrace_probe_ops *ops, void *data) |
5385 | { | 5382 | { |
5386 | long count = (long)data; | 5383 | long count = (long)data; |
5387 | 5384 | ||
5388 | seq_printf(m, "%ps:", (void *)ip); | 5385 | seq_printf(m, "%ps:", (void *)ip); |
5389 | 5386 | ||
5390 | seq_printf(m, "snapshot"); | 5387 | seq_printf(m, "snapshot"); |
5391 | 5388 | ||
5392 | if (count == -1) | 5389 | if (count == -1) |
5393 | seq_printf(m, ":unlimited\n"); | 5390 | seq_printf(m, ":unlimited\n"); |
5394 | else | 5391 | else |
5395 | seq_printf(m, ":count=%ld\n", count); | 5392 | seq_printf(m, ":count=%ld\n", count); |
5396 | 5393 | ||
5397 | return 0; | 5394 | return 0; |
5398 | } | 5395 | } |
5399 | 5396 | ||
5400 | static struct ftrace_probe_ops snapshot_probe_ops = { | 5397 | static struct ftrace_probe_ops snapshot_probe_ops = { |
5401 | .func = ftrace_snapshot, | 5398 | .func = ftrace_snapshot, |
5402 | .print = ftrace_snapshot_print, | 5399 | .print = ftrace_snapshot_print, |
5403 | }; | 5400 | }; |
5404 | 5401 | ||
5405 | static struct ftrace_probe_ops snapshot_count_probe_ops = { | 5402 | static struct ftrace_probe_ops snapshot_count_probe_ops = { |
5406 | .func = ftrace_count_snapshot, | 5403 | .func = ftrace_count_snapshot, |
5407 | .print = ftrace_snapshot_print, | 5404 | .print = ftrace_snapshot_print, |
5408 | }; | 5405 | }; |
5409 | 5406 | ||
5410 | static int | 5407 | static int |
5411 | ftrace_trace_snapshot_callback(struct ftrace_hash *hash, | 5408 | ftrace_trace_snapshot_callback(struct ftrace_hash *hash, |
5412 | char *glob, char *cmd, char *param, int enable) | 5409 | char *glob, char *cmd, char *param, int enable) |
5413 | { | 5410 | { |
5414 | struct ftrace_probe_ops *ops; | 5411 | struct ftrace_probe_ops *ops; |
5415 | void *count = (void *)-1; | 5412 | void *count = (void *)-1; |
5416 | char *number; | 5413 | char *number; |
5417 | int ret; | 5414 | int ret; |
5418 | 5415 | ||
5419 | /* hash funcs only work with set_ftrace_filter */ | 5416 | /* hash funcs only work with set_ftrace_filter */ |
5420 | if (!enable) | 5417 | if (!enable) |
5421 | return -EINVAL; | 5418 | return -EINVAL; |
5422 | 5419 | ||
5423 | ops = param ? &snapshot_count_probe_ops : &snapshot_probe_ops; | 5420 | ops = param ? &snapshot_count_probe_ops : &snapshot_probe_ops; |
5424 | 5421 | ||
5425 | if (glob[0] == '!') { | 5422 | if (glob[0] == '!') { |
5426 | unregister_ftrace_function_probe_func(glob+1, ops); | 5423 | unregister_ftrace_function_probe_func(glob+1, ops); |
5427 | return 0; | 5424 | return 0; |
5428 | } | 5425 | } |
5429 | 5426 | ||
5430 | if (!param) | 5427 | if (!param) |
5431 | goto out_reg; | 5428 | goto out_reg; |
5432 | 5429 | ||
5433 | number = strsep(¶m, ":"); | 5430 | number = strsep(¶m, ":"); |
5434 | 5431 | ||
5435 | if (!strlen(number)) | 5432 | if (!strlen(number)) |
5436 | goto out_reg; | 5433 | goto out_reg; |
5437 | 5434 | ||
5438 | /* | 5435 | /* |
5439 | * We use the callback data field (which is a pointer) | 5436 | * We use the callback data field (which is a pointer) |
5440 | * as our counter. | 5437 | * as our counter. |
5441 | */ | 5438 | */ |
5442 | ret = kstrtoul(number, 0, (unsigned long *)&count); | 5439 | ret = kstrtoul(number, 0, (unsigned long *)&count); |
5443 | if (ret) | 5440 | if (ret) |
5444 | return ret; | 5441 | return ret; |
5445 | 5442 | ||
5446 | out_reg: | 5443 | out_reg: |
5447 | ret = register_ftrace_function_probe(glob, ops, count); | 5444 | ret = register_ftrace_function_probe(glob, ops, count); |
5448 | 5445 | ||
5449 | if (ret >= 0) | 5446 | if (ret >= 0) |
5450 | alloc_snapshot(&global_trace); | 5447 | alloc_snapshot(&global_trace); |
5451 | 5448 | ||
5452 | return ret < 0 ? ret : 0; | 5449 | return ret < 0 ? ret : 0; |
5453 | } | 5450 | } |
5454 | 5451 | ||
5455 | static struct ftrace_func_command ftrace_snapshot_cmd = { | 5452 | static struct ftrace_func_command ftrace_snapshot_cmd = { |
5456 | .name = "snapshot", | 5453 | .name = "snapshot", |
5457 | .func = ftrace_trace_snapshot_callback, | 5454 | .func = ftrace_trace_snapshot_callback, |
5458 | }; | 5455 | }; |
5459 | 5456 | ||
5460 | static int register_snapshot_cmd(void) | 5457 | static int register_snapshot_cmd(void) |
5461 | { | 5458 | { |
5462 | return register_ftrace_command(&ftrace_snapshot_cmd); | 5459 | return register_ftrace_command(&ftrace_snapshot_cmd); |
5463 | } | 5460 | } |
5464 | #else | 5461 | #else |
5465 | static inline int register_snapshot_cmd(void) { return 0; } | 5462 | static inline int register_snapshot_cmd(void) { return 0; } |
5466 | #endif /* defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) */ | 5463 | #endif /* defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) */ |
5467 | 5464 | ||
5468 | struct dentry *tracing_init_dentry_tr(struct trace_array *tr) | 5465 | struct dentry *tracing_init_dentry_tr(struct trace_array *tr) |
5469 | { | 5466 | { |
5470 | if (tr->dir) | 5467 | if (tr->dir) |
5471 | return tr->dir; | 5468 | return tr->dir; |
5472 | 5469 | ||
5473 | if (!debugfs_initialized()) | 5470 | if (!debugfs_initialized()) |
5474 | return NULL; | 5471 | return NULL; |
5475 | 5472 | ||
5476 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) | 5473 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) |
5477 | tr->dir = debugfs_create_dir("tracing", NULL); | 5474 | tr->dir = debugfs_create_dir("tracing", NULL); |
5478 | 5475 | ||
5479 | if (!tr->dir) | 5476 | if (!tr->dir) |
5480 | pr_warn_once("Could not create debugfs directory 'tracing'\n"); | 5477 | pr_warn_once("Could not create debugfs directory 'tracing'\n"); |
5481 | 5478 | ||
5482 | return tr->dir; | 5479 | return tr->dir; |
5483 | } | 5480 | } |
5484 | 5481 | ||
5485 | struct dentry *tracing_init_dentry(void) | 5482 | struct dentry *tracing_init_dentry(void) |
5486 | { | 5483 | { |
5487 | return tracing_init_dentry_tr(&global_trace); | 5484 | return tracing_init_dentry_tr(&global_trace); |
5488 | } | 5485 | } |
5489 | 5486 | ||
5490 | static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) | 5487 | static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) |
5491 | { | 5488 | { |
5492 | struct dentry *d_tracer; | 5489 | struct dentry *d_tracer; |
5493 | 5490 | ||
5494 | if (tr->percpu_dir) | 5491 | if (tr->percpu_dir) |
5495 | return tr->percpu_dir; | 5492 | return tr->percpu_dir; |
5496 | 5493 | ||
5497 | d_tracer = tracing_init_dentry_tr(tr); | 5494 | d_tracer = tracing_init_dentry_tr(tr); |
5498 | if (!d_tracer) | 5495 | if (!d_tracer) |
5499 | return NULL; | 5496 | return NULL; |
5500 | 5497 | ||
5501 | tr->percpu_dir = debugfs_create_dir("per_cpu", d_tracer); | 5498 | tr->percpu_dir = debugfs_create_dir("per_cpu", d_tracer); |
5502 | 5499 | ||
5503 | WARN_ONCE(!tr->percpu_dir, | 5500 | WARN_ONCE(!tr->percpu_dir, |
5504 | "Could not create debugfs directory 'per_cpu/%d'\n", cpu); | 5501 | "Could not create debugfs directory 'per_cpu/%d'\n", cpu); |
5505 | 5502 | ||
5506 | return tr->percpu_dir; | 5503 | return tr->percpu_dir; |
5507 | } | 5504 | } |
5508 | 5505 | ||
5509 | static struct dentry * | 5506 | static struct dentry * |
5510 | trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent, | 5507 | trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent, |
5511 | void *data, long cpu, const struct file_operations *fops) | 5508 | void *data, long cpu, const struct file_operations *fops) |
5512 | { | 5509 | { |
5513 | struct dentry *ret = trace_create_file(name, mode, parent, data, fops); | 5510 | struct dentry *ret = trace_create_file(name, mode, parent, data, fops); |
5514 | 5511 | ||
5515 | if (ret) /* See tracing_get_cpu() */ | 5512 | if (ret) /* See tracing_get_cpu() */ |
5516 | ret->d_inode->i_cdev = (void *)(cpu + 1); | 5513 | ret->d_inode->i_cdev = (void *)(cpu + 1); |
5517 | return ret; | 5514 | return ret; |
5518 | } | 5515 | } |
5519 | 5516 | ||
5520 | static void | 5517 | static void |
5521 | tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) | 5518 | tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) |
5522 | { | 5519 | { |
5523 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); | 5520 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); |
5524 | struct dentry *d_cpu; | 5521 | struct dentry *d_cpu; |
5525 | char cpu_dir[30]; /* 30 characters should be more than enough */ | 5522 | char cpu_dir[30]; /* 30 characters should be more than enough */ |
5526 | 5523 | ||
5527 | if (!d_percpu) | 5524 | if (!d_percpu) |
5528 | return; | 5525 | return; |
5529 | 5526 | ||
5530 | snprintf(cpu_dir, 30, "cpu%ld", cpu); | 5527 | snprintf(cpu_dir, 30, "cpu%ld", cpu); |
5531 | d_cpu = debugfs_create_dir(cpu_dir, d_percpu); | 5528 | d_cpu = debugfs_create_dir(cpu_dir, d_percpu); |
5532 | if (!d_cpu) { | 5529 | if (!d_cpu) { |
5533 | pr_warning("Could not create debugfs '%s' entry\n", cpu_dir); | 5530 | pr_warning("Could not create debugfs '%s' entry\n", cpu_dir); |
5534 | return; | 5531 | return; |
5535 | } | 5532 | } |
5536 | 5533 | ||
5537 | /* per cpu trace_pipe */ | 5534 | /* per cpu trace_pipe */ |
5538 | trace_create_cpu_file("trace_pipe", 0444, d_cpu, | 5535 | trace_create_cpu_file("trace_pipe", 0444, d_cpu, |
5539 | tr, cpu, &tracing_pipe_fops); | 5536 | tr, cpu, &tracing_pipe_fops); |
5540 | 5537 | ||
5541 | /* per cpu trace */ | 5538 | /* per cpu trace */ |
5542 | trace_create_cpu_file("trace", 0644, d_cpu, | 5539 | trace_create_cpu_file("trace", 0644, d_cpu, |
5543 | tr, cpu, &tracing_fops); | 5540 | tr, cpu, &tracing_fops); |
5544 | 5541 | ||
5545 | trace_create_cpu_file("trace_pipe_raw", 0444, d_cpu, | 5542 | trace_create_cpu_file("trace_pipe_raw", 0444, d_cpu, |
5546 | tr, cpu, &tracing_buffers_fops); | 5543 | tr, cpu, &tracing_buffers_fops); |
5547 | 5544 | ||
5548 | trace_create_cpu_file("stats", 0444, d_cpu, | 5545 | trace_create_cpu_file("stats", 0444, d_cpu, |
5549 | tr, cpu, &tracing_stats_fops); | 5546 | tr, cpu, &tracing_stats_fops); |
5550 | 5547 | ||
5551 | trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, | 5548 | trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, |
5552 | tr, cpu, &tracing_entries_fops); | 5549 | tr, cpu, &tracing_entries_fops); |
5553 | 5550 | ||
5554 | #ifdef CONFIG_TRACER_SNAPSHOT | 5551 | #ifdef CONFIG_TRACER_SNAPSHOT |
5555 | trace_create_cpu_file("snapshot", 0644, d_cpu, | 5552 | trace_create_cpu_file("snapshot", 0644, d_cpu, |
5556 | tr, cpu, &snapshot_fops); | 5553 | tr, cpu, &snapshot_fops); |
5557 | 5554 | ||
5558 | trace_create_cpu_file("snapshot_raw", 0444, d_cpu, | 5555 | trace_create_cpu_file("snapshot_raw", 0444, d_cpu, |
5559 | tr, cpu, &snapshot_raw_fops); | 5556 | tr, cpu, &snapshot_raw_fops); |
5560 | #endif | 5557 | #endif |
5561 | } | 5558 | } |
5562 | 5559 | ||
5563 | #ifdef CONFIG_FTRACE_SELFTEST | 5560 | #ifdef CONFIG_FTRACE_SELFTEST |
5564 | /* Let selftest have access to static functions in this file */ | 5561 | /* Let selftest have access to static functions in this file */ |
5565 | #include "trace_selftest.c" | 5562 | #include "trace_selftest.c" |
5566 | #endif | 5563 | #endif |
5567 | 5564 | ||
5568 | struct trace_option_dentry { | 5565 | struct trace_option_dentry { |
5569 | struct tracer_opt *opt; | 5566 | struct tracer_opt *opt; |
5570 | struct tracer_flags *flags; | 5567 | struct tracer_flags *flags; |
5571 | struct trace_array *tr; | 5568 | struct trace_array *tr; |
5572 | struct dentry *entry; | 5569 | struct dentry *entry; |
5573 | }; | 5570 | }; |
5574 | 5571 | ||
5575 | static ssize_t | 5572 | static ssize_t |
5576 | trace_options_read(struct file *filp, char __user *ubuf, size_t cnt, | 5573 | trace_options_read(struct file *filp, char __user *ubuf, size_t cnt, |
5577 | loff_t *ppos) | 5574 | loff_t *ppos) |
5578 | { | 5575 | { |
5579 | struct trace_option_dentry *topt = filp->private_data; | 5576 | struct trace_option_dentry *topt = filp->private_data; |
5580 | char *buf; | 5577 | char *buf; |
5581 | 5578 | ||
5582 | if (topt->flags->val & topt->opt->bit) | 5579 | if (topt->flags->val & topt->opt->bit) |
5583 | buf = "1\n"; | 5580 | buf = "1\n"; |
5584 | else | 5581 | else |
5585 | buf = "0\n"; | 5582 | buf = "0\n"; |
5586 | 5583 | ||
5587 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2); | 5584 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2); |
5588 | } | 5585 | } |
5589 | 5586 | ||
5590 | static ssize_t | 5587 | static ssize_t |
5591 | trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, | 5588 | trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, |
5592 | loff_t *ppos) | 5589 | loff_t *ppos) |
5593 | { | 5590 | { |
5594 | struct trace_option_dentry *topt = filp->private_data; | 5591 | struct trace_option_dentry *topt = filp->private_data; |
5595 | unsigned long val; | 5592 | unsigned long val; |
5596 | int ret; | 5593 | int ret; |
5597 | 5594 | ||
5598 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 5595 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
5599 | if (ret) | 5596 | if (ret) |
5600 | return ret; | 5597 | return ret; |
5601 | 5598 | ||
5602 | if (val != 0 && val != 1) | 5599 | if (val != 0 && val != 1) |
5603 | return -EINVAL; | 5600 | return -EINVAL; |
5604 | 5601 | ||
5605 | if (!!(topt->flags->val & topt->opt->bit) != val) { | 5602 | if (!!(topt->flags->val & topt->opt->bit) != val) { |
5606 | mutex_lock(&trace_types_lock); | 5603 | mutex_lock(&trace_types_lock); |
5607 | ret = __set_tracer_option(topt->tr->current_trace, topt->flags, | 5604 | ret = __set_tracer_option(topt->tr->current_trace, topt->flags, |
5608 | topt->opt, !val); | 5605 | topt->opt, !val); |
5609 | mutex_unlock(&trace_types_lock); | 5606 | mutex_unlock(&trace_types_lock); |
5610 | if (ret) | 5607 | if (ret) |
5611 | return ret; | 5608 | return ret; |
5612 | } | 5609 | } |
5613 | 5610 | ||
5614 | *ppos += cnt; | 5611 | *ppos += cnt; |
5615 | 5612 | ||
5616 | return cnt; | 5613 | return cnt; |
5617 | } | 5614 | } |
5618 | 5615 | ||
5619 | 5616 | ||
5620 | static const struct file_operations trace_options_fops = { | 5617 | static const struct file_operations trace_options_fops = { |
5621 | .open = tracing_open_generic, | 5618 | .open = tracing_open_generic, |
5622 | .read = trace_options_read, | 5619 | .read = trace_options_read, |
5623 | .write = trace_options_write, | 5620 | .write = trace_options_write, |
5624 | .llseek = generic_file_llseek, | 5621 | .llseek = generic_file_llseek, |
5625 | }; | 5622 | }; |
5626 | 5623 | ||
5627 | static ssize_t | 5624 | static ssize_t |
5628 | trace_options_core_read(struct file *filp, char __user *ubuf, size_t cnt, | 5625 | trace_options_core_read(struct file *filp, char __user *ubuf, size_t cnt, |
5629 | loff_t *ppos) | 5626 | loff_t *ppos) |
5630 | { | 5627 | { |
5631 | long index = (long)filp->private_data; | 5628 | long index = (long)filp->private_data; |
5632 | char *buf; | 5629 | char *buf; |
5633 | 5630 | ||
5634 | if (trace_flags & (1 << index)) | 5631 | if (trace_flags & (1 << index)) |
5635 | buf = "1\n"; | 5632 | buf = "1\n"; |
5636 | else | 5633 | else |
5637 | buf = "0\n"; | 5634 | buf = "0\n"; |
5638 | 5635 | ||
5639 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2); | 5636 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2); |
5640 | } | 5637 | } |
5641 | 5638 | ||
5642 | static ssize_t | 5639 | static ssize_t |
5643 | trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt, | 5640 | trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt, |
5644 | loff_t *ppos) | 5641 | loff_t *ppos) |
5645 | { | 5642 | { |
5646 | struct trace_array *tr = &global_trace; | 5643 | struct trace_array *tr = &global_trace; |
5647 | long index = (long)filp->private_data; | 5644 | long index = (long)filp->private_data; |
5648 | unsigned long val; | 5645 | unsigned long val; |
5649 | int ret; | 5646 | int ret; |
5650 | 5647 | ||
5651 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 5648 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
5652 | if (ret) | 5649 | if (ret) |
5653 | return ret; | 5650 | return ret; |
5654 | 5651 | ||
5655 | if (val != 0 && val != 1) | 5652 | if (val != 0 && val != 1) |
5656 | return -EINVAL; | 5653 | return -EINVAL; |
5657 | 5654 | ||
5658 | mutex_lock(&trace_types_lock); | 5655 | mutex_lock(&trace_types_lock); |
5659 | ret = set_tracer_flag(tr, 1 << index, val); | 5656 | ret = set_tracer_flag(tr, 1 << index, val); |
5660 | mutex_unlock(&trace_types_lock); | 5657 | mutex_unlock(&trace_types_lock); |
5661 | 5658 | ||
5662 | if (ret < 0) | 5659 | if (ret < 0) |
5663 | return ret; | 5660 | return ret; |
5664 | 5661 | ||
5665 | *ppos += cnt; | 5662 | *ppos += cnt; |
5666 | 5663 | ||
5667 | return cnt; | 5664 | return cnt; |
5668 | } | 5665 | } |
5669 | 5666 | ||
5670 | static const struct file_operations trace_options_core_fops = { | 5667 | static const struct file_operations trace_options_core_fops = { |
5671 | .open = tracing_open_generic, | 5668 | .open = tracing_open_generic, |
5672 | .read = trace_options_core_read, | 5669 | .read = trace_options_core_read, |
5673 | .write = trace_options_core_write, | 5670 | .write = trace_options_core_write, |
5674 | .llseek = generic_file_llseek, | 5671 | .llseek = generic_file_llseek, |
5675 | }; | 5672 | }; |
5676 | 5673 | ||
5677 | struct dentry *trace_create_file(const char *name, | 5674 | struct dentry *trace_create_file(const char *name, |
5678 | umode_t mode, | 5675 | umode_t mode, |
5679 | struct dentry *parent, | 5676 | struct dentry *parent, |
5680 | void *data, | 5677 | void *data, |
5681 | const struct file_operations *fops) | 5678 | const struct file_operations *fops) |
5682 | { | 5679 | { |
5683 | struct dentry *ret; | 5680 | struct dentry *ret; |
5684 | 5681 | ||
5685 | ret = debugfs_create_file(name, mode, parent, data, fops); | 5682 | ret = debugfs_create_file(name, mode, parent, data, fops); |
5686 | if (!ret) | 5683 | if (!ret) |
5687 | pr_warning("Could not create debugfs '%s' entry\n", name); | 5684 | pr_warning("Could not create debugfs '%s' entry\n", name); |
5688 | 5685 | ||
5689 | return ret; | 5686 | return ret; |
5690 | } | 5687 | } |
5691 | 5688 | ||
5692 | 5689 | ||
5693 | static struct dentry *trace_options_init_dentry(struct trace_array *tr) | 5690 | static struct dentry *trace_options_init_dentry(struct trace_array *tr) |
5694 | { | 5691 | { |
5695 | struct dentry *d_tracer; | 5692 | struct dentry *d_tracer; |
5696 | 5693 | ||
5697 | if (tr->options) | 5694 | if (tr->options) |
5698 | return tr->options; | 5695 | return tr->options; |
5699 | 5696 | ||
5700 | d_tracer = tracing_init_dentry_tr(tr); | 5697 | d_tracer = tracing_init_dentry_tr(tr); |
5701 | if (!d_tracer) | 5698 | if (!d_tracer) |
5702 | return NULL; | 5699 | return NULL; |
5703 | 5700 | ||
5704 | tr->options = debugfs_create_dir("options", d_tracer); | 5701 | tr->options = debugfs_create_dir("options", d_tracer); |
5705 | if (!tr->options) { | 5702 | if (!tr->options) { |
5706 | pr_warning("Could not create debugfs directory 'options'\n"); | 5703 | pr_warning("Could not create debugfs directory 'options'\n"); |
5707 | return NULL; | 5704 | return NULL; |
5708 | } | 5705 | } |
5709 | 5706 | ||
5710 | return tr->options; | 5707 | return tr->options; |
5711 | } | 5708 | } |
5712 | 5709 | ||
5713 | static void | 5710 | static void |
5714 | create_trace_option_file(struct trace_array *tr, | 5711 | create_trace_option_file(struct trace_array *tr, |
5715 | struct trace_option_dentry *topt, | 5712 | struct trace_option_dentry *topt, |
5716 | struct tracer_flags *flags, | 5713 | struct tracer_flags *flags, |
5717 | struct tracer_opt *opt) | 5714 | struct tracer_opt *opt) |
5718 | { | 5715 | { |
5719 | struct dentry *t_options; | 5716 | struct dentry *t_options; |
5720 | 5717 | ||
5721 | t_options = trace_options_init_dentry(tr); | 5718 | t_options = trace_options_init_dentry(tr); |
5722 | if (!t_options) | 5719 | if (!t_options) |
5723 | return; | 5720 | return; |
5724 | 5721 | ||
5725 | topt->flags = flags; | 5722 | topt->flags = flags; |
5726 | topt->opt = opt; | 5723 | topt->opt = opt; |
5727 | topt->tr = tr; | 5724 | topt->tr = tr; |
5728 | 5725 | ||
5729 | topt->entry = trace_create_file(opt->name, 0644, t_options, topt, | 5726 | topt->entry = trace_create_file(opt->name, 0644, t_options, topt, |
5730 | &trace_options_fops); | 5727 | &trace_options_fops); |
5731 | 5728 | ||
5732 | } | 5729 | } |
5733 | 5730 | ||
5734 | static struct trace_option_dentry * | 5731 | static struct trace_option_dentry * |
5735 | create_trace_option_files(struct trace_array *tr, struct tracer *tracer) | 5732 | create_trace_option_files(struct trace_array *tr, struct tracer *tracer) |
5736 | { | 5733 | { |
5737 | struct trace_option_dentry *topts; | 5734 | struct trace_option_dentry *topts; |
5738 | struct tracer_flags *flags; | 5735 | struct tracer_flags *flags; |
5739 | struct tracer_opt *opts; | 5736 | struct tracer_opt *opts; |
5740 | int cnt; | 5737 | int cnt; |
5741 | 5738 | ||
5742 | if (!tracer) | 5739 | if (!tracer) |
5743 | return NULL; | 5740 | return NULL; |
5744 | 5741 | ||
5745 | flags = tracer->flags; | 5742 | flags = tracer->flags; |
5746 | 5743 | ||
5747 | if (!flags || !flags->opts) | 5744 | if (!flags || !flags->opts) |
5748 | return NULL; | 5745 | return NULL; |
5749 | 5746 | ||
5750 | opts = flags->opts; | 5747 | opts = flags->opts; |
5751 | 5748 | ||
5752 | for (cnt = 0; opts[cnt].name; cnt++) | 5749 | for (cnt = 0; opts[cnt].name; cnt++) |
5753 | ; | 5750 | ; |
5754 | 5751 | ||
5755 | topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL); | 5752 | topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL); |
5756 | if (!topts) | 5753 | if (!topts) |
5757 | return NULL; | 5754 | return NULL; |
5758 | 5755 | ||
5759 | for (cnt = 0; opts[cnt].name; cnt++) | 5756 | for (cnt = 0; opts[cnt].name; cnt++) |
5760 | create_trace_option_file(tr, &topts[cnt], flags, | 5757 | create_trace_option_file(tr, &topts[cnt], flags, |
5761 | &opts[cnt]); | 5758 | &opts[cnt]); |
5762 | 5759 | ||
5763 | return topts; | 5760 | return topts; |
5764 | } | 5761 | } |
5765 | 5762 | ||
5766 | static void | 5763 | static void |
5767 | destroy_trace_option_files(struct trace_option_dentry *topts) | 5764 | destroy_trace_option_files(struct trace_option_dentry *topts) |
5768 | { | 5765 | { |
5769 | int cnt; | 5766 | int cnt; |
5770 | 5767 | ||
5771 | if (!topts) | 5768 | if (!topts) |
5772 | return; | 5769 | return; |
5773 | 5770 | ||
5774 | for (cnt = 0; topts[cnt].opt; cnt++) { | 5771 | for (cnt = 0; topts[cnt].opt; cnt++) { |
5775 | if (topts[cnt].entry) | 5772 | if (topts[cnt].entry) |
5776 | debugfs_remove(topts[cnt].entry); | 5773 | debugfs_remove(topts[cnt].entry); |
5777 | } | 5774 | } |
5778 | 5775 | ||
5779 | kfree(topts); | 5776 | kfree(topts); |
5780 | } | 5777 | } |
5781 | 5778 | ||
5782 | static struct dentry * | 5779 | static struct dentry * |
5783 | create_trace_option_core_file(struct trace_array *tr, | 5780 | create_trace_option_core_file(struct trace_array *tr, |
5784 | const char *option, long index) | 5781 | const char *option, long index) |
5785 | { | 5782 | { |
5786 | struct dentry *t_options; | 5783 | struct dentry *t_options; |
5787 | 5784 | ||
5788 | t_options = trace_options_init_dentry(tr); | 5785 | t_options = trace_options_init_dentry(tr); |
5789 | if (!t_options) | 5786 | if (!t_options) |
5790 | return NULL; | 5787 | return NULL; |
5791 | 5788 | ||
5792 | return trace_create_file(option, 0644, t_options, (void *)index, | 5789 | return trace_create_file(option, 0644, t_options, (void *)index, |
5793 | &trace_options_core_fops); | 5790 | &trace_options_core_fops); |
5794 | } | 5791 | } |
5795 | 5792 | ||
5796 | static __init void create_trace_options_dir(struct trace_array *tr) | 5793 | static __init void create_trace_options_dir(struct trace_array *tr) |
5797 | { | 5794 | { |
5798 | struct dentry *t_options; | 5795 | struct dentry *t_options; |
5799 | int i; | 5796 | int i; |
5800 | 5797 | ||
5801 | t_options = trace_options_init_dentry(tr); | 5798 | t_options = trace_options_init_dentry(tr); |
5802 | if (!t_options) | 5799 | if (!t_options) |
5803 | return; | 5800 | return; |
5804 | 5801 | ||
5805 | for (i = 0; trace_options[i]; i++) | 5802 | for (i = 0; trace_options[i]; i++) |
5806 | create_trace_option_core_file(tr, trace_options[i], i); | 5803 | create_trace_option_core_file(tr, trace_options[i], i); |
5807 | } | 5804 | } |
5808 | 5805 | ||
5809 | static ssize_t | 5806 | static ssize_t |
5810 | rb_simple_read(struct file *filp, char __user *ubuf, | 5807 | rb_simple_read(struct file *filp, char __user *ubuf, |
5811 | size_t cnt, loff_t *ppos) | 5808 | size_t cnt, loff_t *ppos) |
5812 | { | 5809 | { |
5813 | struct trace_array *tr = filp->private_data; | 5810 | struct trace_array *tr = filp->private_data; |
5814 | char buf[64]; | 5811 | char buf[64]; |
5815 | int r; | 5812 | int r; |
5816 | 5813 | ||
5817 | r = tracer_tracing_is_on(tr); | 5814 | r = tracer_tracing_is_on(tr); |
5818 | r = sprintf(buf, "%d\n", r); | 5815 | r = sprintf(buf, "%d\n", r); |
5819 | 5816 | ||
5820 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 5817 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
5821 | } | 5818 | } |
5822 | 5819 | ||
5823 | static ssize_t | 5820 | static ssize_t |
5824 | rb_simple_write(struct file *filp, const char __user *ubuf, | 5821 | rb_simple_write(struct file *filp, const char __user *ubuf, |
5825 | size_t cnt, loff_t *ppos) | 5822 | size_t cnt, loff_t *ppos) |
5826 | { | 5823 | { |
5827 | struct trace_array *tr = filp->private_data; | 5824 | struct trace_array *tr = filp->private_data; |
5828 | struct ring_buffer *buffer = tr->trace_buffer.buffer; | 5825 | struct ring_buffer *buffer = tr->trace_buffer.buffer; |
5829 | unsigned long val; | 5826 | unsigned long val; |
5830 | int ret; | 5827 | int ret; |
5831 | 5828 | ||
5832 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 5829 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
5833 | if (ret) | 5830 | if (ret) |
5834 | return ret; | 5831 | return ret; |
5835 | 5832 | ||
5836 | if (buffer) { | 5833 | if (buffer) { |
5837 | mutex_lock(&trace_types_lock); | 5834 | mutex_lock(&trace_types_lock); |
5838 | if (val) { | 5835 | if (val) { |
5839 | tracer_tracing_on(tr); | 5836 | tracer_tracing_on(tr); |
5840 | if (tr->current_trace->start) | 5837 | if (tr->current_trace->start) |
5841 | tr->current_trace->start(tr); | 5838 | tr->current_trace->start(tr); |
5842 | } else { | 5839 | } else { |
5843 | tracer_tracing_off(tr); | 5840 | tracer_tracing_off(tr); |
5844 | if (tr->current_trace->stop) | 5841 | if (tr->current_trace->stop) |
5845 | tr->current_trace->stop(tr); | 5842 | tr->current_trace->stop(tr); |
5846 | } | 5843 | } |
5847 | mutex_unlock(&trace_types_lock); | 5844 | mutex_unlock(&trace_types_lock); |
5848 | } | 5845 | } |
5849 | 5846 | ||
5850 | (*ppos)++; | 5847 | (*ppos)++; |
5851 | 5848 | ||
5852 | return cnt; | 5849 | return cnt; |
5853 | } | 5850 | } |
5854 | 5851 | ||
5855 | static const struct file_operations rb_simple_fops = { | 5852 | static const struct file_operations rb_simple_fops = { |
5856 | .open = tracing_open_generic_tr, | 5853 | .open = tracing_open_generic_tr, |
5857 | .read = rb_simple_read, | 5854 | .read = rb_simple_read, |
5858 | .write = rb_simple_write, | 5855 | .write = rb_simple_write, |
5859 | .release = tracing_release_generic_tr, | 5856 | .release = tracing_release_generic_tr, |
5860 | .llseek = default_llseek, | 5857 | .llseek = default_llseek, |
5861 | }; | 5858 | }; |
5862 | 5859 | ||
5863 | struct dentry *trace_instance_dir; | 5860 | struct dentry *trace_instance_dir; |
5864 | 5861 | ||
5865 | static void | 5862 | static void |
5866 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); | 5863 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); |
5867 | 5864 | ||
5868 | static int | 5865 | static int |
5869 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) | 5866 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) |
5870 | { | 5867 | { |
5871 | enum ring_buffer_flags rb_flags; | 5868 | enum ring_buffer_flags rb_flags; |
5872 | 5869 | ||
5873 | rb_flags = trace_flags & TRACE_ITER_OVERWRITE ? RB_FL_OVERWRITE : 0; | 5870 | rb_flags = trace_flags & TRACE_ITER_OVERWRITE ? RB_FL_OVERWRITE : 0; |
5874 | 5871 | ||
5875 | buf->buffer = ring_buffer_alloc(size, rb_flags); | 5872 | buf->buffer = ring_buffer_alloc(size, rb_flags); |
5876 | if (!buf->buffer) | 5873 | if (!buf->buffer) |
5877 | return -ENOMEM; | 5874 | return -ENOMEM; |
5878 | 5875 | ||
5879 | buf->data = alloc_percpu(struct trace_array_cpu); | 5876 | buf->data = alloc_percpu(struct trace_array_cpu); |
5880 | if (!buf->data) { | 5877 | if (!buf->data) { |
5881 | ring_buffer_free(buf->buffer); | 5878 | ring_buffer_free(buf->buffer); |
5882 | return -ENOMEM; | 5879 | return -ENOMEM; |
5883 | } | 5880 | } |
5884 | 5881 | ||
5885 | /* Allocate the first page for all buffers */ | 5882 | /* Allocate the first page for all buffers */ |
5886 | set_buffer_entries(&tr->trace_buffer, | 5883 | set_buffer_entries(&tr->trace_buffer, |
5887 | ring_buffer_size(tr->trace_buffer.buffer, 0)); | 5884 | ring_buffer_size(tr->trace_buffer.buffer, 0)); |
5888 | 5885 | ||
5889 | return 0; | 5886 | return 0; |
5890 | } | 5887 | } |
5891 | 5888 | ||
5892 | static int allocate_trace_buffers(struct trace_array *tr, int size) | 5889 | static int allocate_trace_buffers(struct trace_array *tr, int size) |
5893 | { | 5890 | { |
5894 | int ret; | 5891 | int ret; |
5895 | 5892 | ||
5896 | ret = allocate_trace_buffer(tr, &tr->trace_buffer, size); | 5893 | ret = allocate_trace_buffer(tr, &tr->trace_buffer, size); |
5897 | if (ret) | 5894 | if (ret) |
5898 | return ret; | 5895 | return ret; |
5899 | 5896 | ||
5900 | #ifdef CONFIG_TRACER_MAX_TRACE | 5897 | #ifdef CONFIG_TRACER_MAX_TRACE |
5901 | ret = allocate_trace_buffer(tr, &tr->max_buffer, | 5898 | ret = allocate_trace_buffer(tr, &tr->max_buffer, |
5902 | allocate_snapshot ? size : 1); | 5899 | allocate_snapshot ? size : 1); |
5903 | if (WARN_ON(ret)) { | 5900 | if (WARN_ON(ret)) { |
5904 | ring_buffer_free(tr->trace_buffer.buffer); | 5901 | ring_buffer_free(tr->trace_buffer.buffer); |
5905 | free_percpu(tr->trace_buffer.data); | 5902 | free_percpu(tr->trace_buffer.data); |
5906 | return -ENOMEM; | 5903 | return -ENOMEM; |
5907 | } | 5904 | } |
5908 | tr->allocated_snapshot = allocate_snapshot; | 5905 | tr->allocated_snapshot = allocate_snapshot; |
5909 | 5906 | ||
5910 | /* | 5907 | /* |
5911 | * Only the top level trace array gets its snapshot allocated | 5908 | * Only the top level trace array gets its snapshot allocated |
5912 | * from the kernel command line. | 5909 | * from the kernel command line. |
5913 | */ | 5910 | */ |
5914 | allocate_snapshot = false; | 5911 | allocate_snapshot = false; |
5915 | #endif | 5912 | #endif |
5916 | return 0; | 5913 | return 0; |
5917 | } | 5914 | } |
5918 | 5915 | ||
5919 | static int new_instance_create(const char *name) | 5916 | static int new_instance_create(const char *name) |
5920 | { | 5917 | { |
5921 | struct trace_array *tr; | 5918 | struct trace_array *tr; |
5922 | int ret; | 5919 | int ret; |
5923 | 5920 | ||
5924 | mutex_lock(&trace_types_lock); | 5921 | mutex_lock(&trace_types_lock); |
5925 | 5922 | ||
5926 | ret = -EEXIST; | 5923 | ret = -EEXIST; |
5927 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 5924 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
5928 | if (tr->name && strcmp(tr->name, name) == 0) | 5925 | if (tr->name && strcmp(tr->name, name) == 0) |
5929 | goto out_unlock; | 5926 | goto out_unlock; |
5930 | } | 5927 | } |
5931 | 5928 | ||
5932 | ret = -ENOMEM; | 5929 | ret = -ENOMEM; |
5933 | tr = kzalloc(sizeof(*tr), GFP_KERNEL); | 5930 | tr = kzalloc(sizeof(*tr), GFP_KERNEL); |
5934 | if (!tr) | 5931 | if (!tr) |
5935 | goto out_unlock; | 5932 | goto out_unlock; |
5936 | 5933 | ||
5937 | tr->name = kstrdup(name, GFP_KERNEL); | 5934 | tr->name = kstrdup(name, GFP_KERNEL); |
5938 | if (!tr->name) | 5935 | if (!tr->name) |
5939 | goto out_free_tr; | 5936 | goto out_free_tr; |
5940 | 5937 | ||
5938 | if (!alloc_cpumask_var(&tr->tracing_cpumask, GFP_KERNEL)) | ||
5939 | goto out_free_tr; | ||
5940 | |||
5941 | cpumask_copy(tr->tracing_cpumask, cpu_all_mask); | ||
5942 | |||
5941 | raw_spin_lock_init(&tr->start_lock); | 5943 | raw_spin_lock_init(&tr->start_lock); |
5942 | 5944 | ||
5943 | tr->current_trace = &nop_trace; | 5945 | tr->current_trace = &nop_trace; |
5944 | 5946 | ||
5945 | INIT_LIST_HEAD(&tr->systems); | 5947 | INIT_LIST_HEAD(&tr->systems); |
5946 | INIT_LIST_HEAD(&tr->events); | 5948 | INIT_LIST_HEAD(&tr->events); |
5947 | 5949 | ||
5948 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) | 5950 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) |
5949 | goto out_free_tr; | 5951 | goto out_free_tr; |
5950 | 5952 | ||
5951 | tr->dir = debugfs_create_dir(name, trace_instance_dir); | 5953 | tr->dir = debugfs_create_dir(name, trace_instance_dir); |
5952 | if (!tr->dir) | 5954 | if (!tr->dir) |
5953 | goto out_free_tr; | 5955 | goto out_free_tr; |
5954 | 5956 | ||
5955 | ret = event_trace_add_tracer(tr->dir, tr); | 5957 | ret = event_trace_add_tracer(tr->dir, tr); |
5956 | if (ret) { | 5958 | if (ret) { |
5957 | debugfs_remove_recursive(tr->dir); | 5959 | debugfs_remove_recursive(tr->dir); |
5958 | goto out_free_tr; | 5960 | goto out_free_tr; |
5959 | } | 5961 | } |
5960 | 5962 | ||
5961 | init_tracer_debugfs(tr, tr->dir); | 5963 | init_tracer_debugfs(tr, tr->dir); |
5962 | 5964 | ||
5963 | list_add(&tr->list, &ftrace_trace_arrays); | 5965 | list_add(&tr->list, &ftrace_trace_arrays); |
5964 | 5966 | ||
5965 | mutex_unlock(&trace_types_lock); | 5967 | mutex_unlock(&trace_types_lock); |
5966 | 5968 | ||
5967 | return 0; | 5969 | return 0; |
5968 | 5970 | ||
5969 | out_free_tr: | 5971 | out_free_tr: |
5970 | if (tr->trace_buffer.buffer) | 5972 | if (tr->trace_buffer.buffer) |
5971 | ring_buffer_free(tr->trace_buffer.buffer); | 5973 | ring_buffer_free(tr->trace_buffer.buffer); |
5974 | free_cpumask_var(tr->tracing_cpumask); | ||
5972 | kfree(tr->name); | 5975 | kfree(tr->name); |
5973 | kfree(tr); | 5976 | kfree(tr); |
5974 | 5977 | ||
5975 | out_unlock: | 5978 | out_unlock: |
5976 | mutex_unlock(&trace_types_lock); | 5979 | mutex_unlock(&trace_types_lock); |
5977 | 5980 | ||
5978 | return ret; | 5981 | return ret; |
5979 | 5982 | ||
5980 | } | 5983 | } |
5981 | 5984 | ||
5982 | static int instance_delete(const char *name) | 5985 | static int instance_delete(const char *name) |
5983 | { | 5986 | { |
5984 | struct trace_array *tr; | 5987 | struct trace_array *tr; |
5985 | int found = 0; | 5988 | int found = 0; |
5986 | int ret; | 5989 | int ret; |
5987 | 5990 | ||
5988 | mutex_lock(&trace_types_lock); | 5991 | mutex_lock(&trace_types_lock); |
5989 | 5992 | ||
5990 | ret = -ENODEV; | 5993 | ret = -ENODEV; |
5991 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 5994 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
5992 | if (tr->name && strcmp(tr->name, name) == 0) { | 5995 | if (tr->name && strcmp(tr->name, name) == 0) { |
5993 | found = 1; | 5996 | found = 1; |
5994 | break; | 5997 | break; |
5995 | } | 5998 | } |
5996 | } | 5999 | } |
5997 | if (!found) | 6000 | if (!found) |
5998 | goto out_unlock; | 6001 | goto out_unlock; |
5999 | 6002 | ||
6000 | ret = -EBUSY; | 6003 | ret = -EBUSY; |
6001 | if (tr->ref) | 6004 | if (tr->ref) |
6002 | goto out_unlock; | 6005 | goto out_unlock; |
6003 | 6006 | ||
6004 | list_del(&tr->list); | 6007 | list_del(&tr->list); |
6005 | 6008 | ||
6006 | event_trace_del_tracer(tr); | 6009 | event_trace_del_tracer(tr); |
6007 | debugfs_remove_recursive(tr->dir); | 6010 | debugfs_remove_recursive(tr->dir); |
6008 | free_percpu(tr->trace_buffer.data); | 6011 | free_percpu(tr->trace_buffer.data); |
6009 | ring_buffer_free(tr->trace_buffer.buffer); | 6012 | ring_buffer_free(tr->trace_buffer.buffer); |
6010 | 6013 | ||
6011 | kfree(tr->name); | 6014 | kfree(tr->name); |
6012 | kfree(tr); | 6015 | kfree(tr); |
6013 | 6016 | ||
6014 | ret = 0; | 6017 | ret = 0; |
6015 | 6018 | ||
6016 | out_unlock: | 6019 | out_unlock: |
6017 | mutex_unlock(&trace_types_lock); | 6020 | mutex_unlock(&trace_types_lock); |
6018 | 6021 | ||
6019 | return ret; | 6022 | return ret; |
6020 | } | 6023 | } |
6021 | 6024 | ||
6022 | static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t mode) | 6025 | static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t mode) |
6023 | { | 6026 | { |
6024 | struct dentry *parent; | 6027 | struct dentry *parent; |
6025 | int ret; | 6028 | int ret; |
6026 | 6029 | ||
6027 | /* Paranoid: Make sure the parent is the "instances" directory */ | 6030 | /* Paranoid: Make sure the parent is the "instances" directory */ |
6028 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); | 6031 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); |
6029 | if (WARN_ON_ONCE(parent != trace_instance_dir)) | 6032 | if (WARN_ON_ONCE(parent != trace_instance_dir)) |
6030 | return -ENOENT; | 6033 | return -ENOENT; |
6031 | 6034 | ||
6032 | /* | 6035 | /* |
6033 | * The inode mutex is locked, but debugfs_create_dir() will also | 6036 | * The inode mutex is locked, but debugfs_create_dir() will also |
6034 | * take the mutex. As the instances directory can not be destroyed | 6037 | * take the mutex. As the instances directory can not be destroyed |
6035 | * or changed in any other way, it is safe to unlock it, and | 6038 | * or changed in any other way, it is safe to unlock it, and |
6036 | * let the dentry try. If two users try to make the same dir at | 6039 | * let the dentry try. If two users try to make the same dir at |
6037 | * the same time, then the new_instance_create() will determine the | 6040 | * the same time, then the new_instance_create() will determine the |
6038 | * winner. | 6041 | * winner. |
6039 | */ | 6042 | */ |
6040 | mutex_unlock(&inode->i_mutex); | 6043 | mutex_unlock(&inode->i_mutex); |
6041 | 6044 | ||
6042 | ret = new_instance_create(dentry->d_iname); | 6045 | ret = new_instance_create(dentry->d_iname); |
6043 | 6046 | ||
6044 | mutex_lock(&inode->i_mutex); | 6047 | mutex_lock(&inode->i_mutex); |
6045 | 6048 | ||
6046 | return ret; | 6049 | return ret; |
6047 | } | 6050 | } |
6048 | 6051 | ||
6049 | static int instance_rmdir(struct inode *inode, struct dentry *dentry) | 6052 | static int instance_rmdir(struct inode *inode, struct dentry *dentry) |
6050 | { | 6053 | { |
6051 | struct dentry *parent; | 6054 | struct dentry *parent; |
6052 | int ret; | 6055 | int ret; |
6053 | 6056 | ||
6054 | /* Paranoid: Make sure the parent is the "instances" directory */ | 6057 | /* Paranoid: Make sure the parent is the "instances" directory */ |
6055 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); | 6058 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); |
6056 | if (WARN_ON_ONCE(parent != trace_instance_dir)) | 6059 | if (WARN_ON_ONCE(parent != trace_instance_dir)) |
6057 | return -ENOENT; | 6060 | return -ENOENT; |
6058 | 6061 | ||
6059 | /* The caller did a dget() on dentry */ | 6062 | /* The caller did a dget() on dentry */ |
6060 | mutex_unlock(&dentry->d_inode->i_mutex); | 6063 | mutex_unlock(&dentry->d_inode->i_mutex); |
6061 | 6064 | ||
6062 | /* | 6065 | /* |
6063 | * The inode mutex is locked, but debugfs_create_dir() will also | 6066 | * The inode mutex is locked, but debugfs_create_dir() will also |
6064 | * take the mutex. As the instances directory can not be destroyed | 6067 | * take the mutex. As the instances directory can not be destroyed |
6065 | * or changed in any other way, it is safe to unlock it, and | 6068 | * or changed in any other way, it is safe to unlock it, and |
6066 | * let the dentry try. If two users try to make the same dir at | 6069 | * let the dentry try. If two users try to make the same dir at |
6067 | * the same time, then the instance_delete() will determine the | 6070 | * the same time, then the instance_delete() will determine the |
6068 | * winner. | 6071 | * winner. |
6069 | */ | 6072 | */ |
6070 | mutex_unlock(&inode->i_mutex); | 6073 | mutex_unlock(&inode->i_mutex); |
6071 | 6074 | ||
6072 | ret = instance_delete(dentry->d_iname); | 6075 | ret = instance_delete(dentry->d_iname); |
6073 | 6076 | ||
6074 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | 6077 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); |
6075 | mutex_lock(&dentry->d_inode->i_mutex); | 6078 | mutex_lock(&dentry->d_inode->i_mutex); |
6076 | 6079 | ||
6077 | return ret; | 6080 | return ret; |
6078 | } | 6081 | } |
6079 | 6082 | ||
6080 | static const struct inode_operations instance_dir_inode_operations = { | 6083 | static const struct inode_operations instance_dir_inode_operations = { |
6081 | .lookup = simple_lookup, | 6084 | .lookup = simple_lookup, |
6082 | .mkdir = instance_mkdir, | 6085 | .mkdir = instance_mkdir, |
6083 | .rmdir = instance_rmdir, | 6086 | .rmdir = instance_rmdir, |
6084 | }; | 6087 | }; |
6085 | 6088 | ||
6086 | static __init void create_trace_instances(struct dentry *d_tracer) | 6089 | static __init void create_trace_instances(struct dentry *d_tracer) |
6087 | { | 6090 | { |
6088 | trace_instance_dir = debugfs_create_dir("instances", d_tracer); | 6091 | trace_instance_dir = debugfs_create_dir("instances", d_tracer); |
6089 | if (WARN_ON(!trace_instance_dir)) | 6092 | if (WARN_ON(!trace_instance_dir)) |
6090 | return; | 6093 | return; |
6091 | 6094 | ||
6092 | /* Hijack the dir inode operations, to allow mkdir */ | 6095 | /* Hijack the dir inode operations, to allow mkdir */ |
6093 | trace_instance_dir->d_inode->i_op = &instance_dir_inode_operations; | 6096 | trace_instance_dir->d_inode->i_op = &instance_dir_inode_operations; |
6094 | } | 6097 | } |
6095 | 6098 | ||
6096 | static void | 6099 | static void |
6097 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | 6100 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) |
6098 | { | 6101 | { |
6099 | int cpu; | 6102 | int cpu; |
6100 | 6103 | ||
6104 | trace_create_file("tracing_cpumask", 0644, d_tracer, | ||
6105 | tr, &tracing_cpumask_fops); | ||
6106 | |||
6101 | trace_create_file("trace_options", 0644, d_tracer, | 6107 | trace_create_file("trace_options", 0644, d_tracer, |
6102 | tr, &tracing_iter_fops); | 6108 | tr, &tracing_iter_fops); |
6103 | 6109 | ||
6104 | trace_create_file("trace", 0644, d_tracer, | 6110 | trace_create_file("trace", 0644, d_tracer, |
6105 | tr, &tracing_fops); | 6111 | tr, &tracing_fops); |
6106 | 6112 | ||
6107 | trace_create_file("trace_pipe", 0444, d_tracer, | 6113 | trace_create_file("trace_pipe", 0444, d_tracer, |
6108 | tr, &tracing_pipe_fops); | 6114 | tr, &tracing_pipe_fops); |
6109 | 6115 | ||
6110 | trace_create_file("buffer_size_kb", 0644, d_tracer, | 6116 | trace_create_file("buffer_size_kb", 0644, d_tracer, |
6111 | tr, &tracing_entries_fops); | 6117 | tr, &tracing_entries_fops); |
6112 | 6118 | ||
6113 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, | 6119 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, |
6114 | tr, &tracing_total_entries_fops); | 6120 | tr, &tracing_total_entries_fops); |
6115 | 6121 | ||
6116 | trace_create_file("free_buffer", 0200, d_tracer, | 6122 | trace_create_file("free_buffer", 0200, d_tracer, |
6117 | tr, &tracing_free_buffer_fops); | 6123 | tr, &tracing_free_buffer_fops); |
6118 | 6124 | ||
6119 | trace_create_file("trace_marker", 0220, d_tracer, | 6125 | trace_create_file("trace_marker", 0220, d_tracer, |
6120 | tr, &tracing_mark_fops); | 6126 | tr, &tracing_mark_fops); |
6121 | 6127 | ||
6122 | trace_create_file("trace_clock", 0644, d_tracer, tr, | 6128 | trace_create_file("trace_clock", 0644, d_tracer, tr, |
6123 | &trace_clock_fops); | 6129 | &trace_clock_fops); |
6124 | 6130 | ||
6125 | trace_create_file("tracing_on", 0644, d_tracer, | 6131 | trace_create_file("tracing_on", 0644, d_tracer, |
6126 | tr, &rb_simple_fops); | 6132 | tr, &rb_simple_fops); |
6127 | 6133 | ||
6128 | #ifdef CONFIG_TRACER_SNAPSHOT | 6134 | #ifdef CONFIG_TRACER_SNAPSHOT |
6129 | trace_create_file("snapshot", 0644, d_tracer, | 6135 | trace_create_file("snapshot", 0644, d_tracer, |
6130 | tr, &snapshot_fops); | 6136 | tr, &snapshot_fops); |
6131 | #endif | 6137 | #endif |
6132 | 6138 | ||
6133 | for_each_tracing_cpu(cpu) | 6139 | for_each_tracing_cpu(cpu) |
6134 | tracing_init_debugfs_percpu(tr, cpu); | 6140 | tracing_init_debugfs_percpu(tr, cpu); |
6135 | 6141 | ||
6136 | } | 6142 | } |
6137 | 6143 | ||
6138 | static __init int tracer_init_debugfs(void) | 6144 | static __init int tracer_init_debugfs(void) |
6139 | { | 6145 | { |
6140 | struct dentry *d_tracer; | 6146 | struct dentry *d_tracer; |
6141 | 6147 | ||
6142 | trace_access_lock_init(); | 6148 | trace_access_lock_init(); |
6143 | 6149 | ||
6144 | d_tracer = tracing_init_dentry(); | 6150 | d_tracer = tracing_init_dentry(); |
6145 | if (!d_tracer) | 6151 | if (!d_tracer) |
6146 | return 0; | 6152 | return 0; |
6147 | 6153 | ||
6148 | init_tracer_debugfs(&global_trace, d_tracer); | 6154 | init_tracer_debugfs(&global_trace, d_tracer); |
6149 | 6155 | ||
6150 | trace_create_file("tracing_cpumask", 0644, d_tracer, | ||
6151 | &global_trace, &tracing_cpumask_fops); | ||
6152 | |||
6153 | trace_create_file("available_tracers", 0444, d_tracer, | 6156 | trace_create_file("available_tracers", 0444, d_tracer, |
6154 | &global_trace, &show_traces_fops); | 6157 | &global_trace, &show_traces_fops); |
6155 | 6158 | ||
6156 | trace_create_file("current_tracer", 0644, d_tracer, | 6159 | trace_create_file("current_tracer", 0644, d_tracer, |
6157 | &global_trace, &set_tracer_fops); | 6160 | &global_trace, &set_tracer_fops); |
6158 | 6161 | ||
6159 | #ifdef CONFIG_TRACER_MAX_TRACE | 6162 | #ifdef CONFIG_TRACER_MAX_TRACE |
6160 | trace_create_file("tracing_max_latency", 0644, d_tracer, | 6163 | trace_create_file("tracing_max_latency", 0644, d_tracer, |
6161 | &tracing_max_latency, &tracing_max_lat_fops); | 6164 | &tracing_max_latency, &tracing_max_lat_fops); |
6162 | #endif | 6165 | #endif |
6163 | 6166 | ||
6164 | trace_create_file("tracing_thresh", 0644, d_tracer, | 6167 | trace_create_file("tracing_thresh", 0644, d_tracer, |
6165 | &tracing_thresh, &tracing_max_lat_fops); | 6168 | &tracing_thresh, &tracing_max_lat_fops); |
6166 | 6169 | ||
6167 | trace_create_file("README", 0444, d_tracer, | 6170 | trace_create_file("README", 0444, d_tracer, |
6168 | NULL, &tracing_readme_fops); | 6171 | NULL, &tracing_readme_fops); |
6169 | 6172 | ||
6170 | trace_create_file("saved_cmdlines", 0444, d_tracer, | 6173 | trace_create_file("saved_cmdlines", 0444, d_tracer, |
6171 | NULL, &tracing_saved_cmdlines_fops); | 6174 | NULL, &tracing_saved_cmdlines_fops); |
6172 | 6175 | ||
6173 | #ifdef CONFIG_DYNAMIC_FTRACE | 6176 | #ifdef CONFIG_DYNAMIC_FTRACE |
6174 | trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, | 6177 | trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, |
6175 | &ftrace_update_tot_cnt, &tracing_dyn_info_fops); | 6178 | &ftrace_update_tot_cnt, &tracing_dyn_info_fops); |
6176 | #endif | 6179 | #endif |
6177 | 6180 | ||
6178 | create_trace_instances(d_tracer); | 6181 | create_trace_instances(d_tracer); |
6179 | 6182 | ||
6180 | create_trace_options_dir(&global_trace); | 6183 | create_trace_options_dir(&global_trace); |
6181 | 6184 | ||
6182 | return 0; | 6185 | return 0; |
6183 | } | 6186 | } |
6184 | 6187 | ||
6185 | static int trace_panic_handler(struct notifier_block *this, | 6188 | static int trace_panic_handler(struct notifier_block *this, |
6186 | unsigned long event, void *unused) | 6189 | unsigned long event, void *unused) |
6187 | { | 6190 | { |
6188 | if (ftrace_dump_on_oops) | 6191 | if (ftrace_dump_on_oops) |
6189 | ftrace_dump(ftrace_dump_on_oops); | 6192 | ftrace_dump(ftrace_dump_on_oops); |
6190 | return NOTIFY_OK; | 6193 | return NOTIFY_OK; |
6191 | } | 6194 | } |
6192 | 6195 | ||
6193 | static struct notifier_block trace_panic_notifier = { | 6196 | static struct notifier_block trace_panic_notifier = { |
6194 | .notifier_call = trace_panic_handler, | 6197 | .notifier_call = trace_panic_handler, |
6195 | .next = NULL, | 6198 | .next = NULL, |
6196 | .priority = 150 /* priority: INT_MAX >= x >= 0 */ | 6199 | .priority = 150 /* priority: INT_MAX >= x >= 0 */ |
6197 | }; | 6200 | }; |
6198 | 6201 | ||
6199 | static int trace_die_handler(struct notifier_block *self, | 6202 | static int trace_die_handler(struct notifier_block *self, |
6200 | unsigned long val, | 6203 | unsigned long val, |
6201 | void *data) | 6204 | void *data) |
6202 | { | 6205 | { |
6203 | switch (val) { | 6206 | switch (val) { |
6204 | case DIE_OOPS: | 6207 | case DIE_OOPS: |
6205 | if (ftrace_dump_on_oops) | 6208 | if (ftrace_dump_on_oops) |
6206 | ftrace_dump(ftrace_dump_on_oops); | 6209 | ftrace_dump(ftrace_dump_on_oops); |
6207 | break; | 6210 | break; |
6208 | default: | 6211 | default: |
6209 | break; | 6212 | break; |
6210 | } | 6213 | } |
6211 | return NOTIFY_OK; | 6214 | return NOTIFY_OK; |
6212 | } | 6215 | } |
6213 | 6216 | ||
6214 | static struct notifier_block trace_die_notifier = { | 6217 | static struct notifier_block trace_die_notifier = { |
6215 | .notifier_call = trace_die_handler, | 6218 | .notifier_call = trace_die_handler, |
6216 | .priority = 200 | 6219 | .priority = 200 |
6217 | }; | 6220 | }; |
6218 | 6221 | ||
6219 | /* | 6222 | /* |
6220 | * printk is set to max of 1024, we really don't need it that big. | 6223 | * printk is set to max of 1024, we really don't need it that big. |
6221 | * Nothing should be printing 1000 characters anyway. | 6224 | * Nothing should be printing 1000 characters anyway. |
6222 | */ | 6225 | */ |
6223 | #define TRACE_MAX_PRINT 1000 | 6226 | #define TRACE_MAX_PRINT 1000 |
6224 | 6227 | ||
6225 | /* | 6228 | /* |
6226 | * Define here KERN_TRACE so that we have one place to modify | 6229 | * Define here KERN_TRACE so that we have one place to modify |
6227 | * it if we decide to change what log level the ftrace dump | 6230 | * it if we decide to change what log level the ftrace dump |
6228 | * should be at. | 6231 | * should be at. |
6229 | */ | 6232 | */ |
6230 | #define KERN_TRACE KERN_EMERG | 6233 | #define KERN_TRACE KERN_EMERG |
6231 | 6234 | ||
6232 | void | 6235 | void |
6233 | trace_printk_seq(struct trace_seq *s) | 6236 | trace_printk_seq(struct trace_seq *s) |
6234 | { | 6237 | { |
6235 | /* Probably should print a warning here. */ | 6238 | /* Probably should print a warning here. */ |
6236 | if (s->len >= TRACE_MAX_PRINT) | 6239 | if (s->len >= TRACE_MAX_PRINT) |
6237 | s->len = TRACE_MAX_PRINT; | 6240 | s->len = TRACE_MAX_PRINT; |
6238 | 6241 | ||
6239 | /* should be zero ended, but we are paranoid. */ | 6242 | /* should be zero ended, but we are paranoid. */ |
6240 | s->buffer[s->len] = 0; | 6243 | s->buffer[s->len] = 0; |
6241 | 6244 | ||
6242 | printk(KERN_TRACE "%s", s->buffer); | 6245 | printk(KERN_TRACE "%s", s->buffer); |
6243 | 6246 | ||
6244 | trace_seq_init(s); | 6247 | trace_seq_init(s); |
6245 | } | 6248 | } |
6246 | 6249 | ||
6247 | void trace_init_global_iter(struct trace_iterator *iter) | 6250 | void trace_init_global_iter(struct trace_iterator *iter) |
6248 | { | 6251 | { |
6249 | iter->tr = &global_trace; | 6252 | iter->tr = &global_trace; |
6250 | iter->trace = iter->tr->current_trace; | 6253 | iter->trace = iter->tr->current_trace; |
6251 | iter->cpu_file = RING_BUFFER_ALL_CPUS; | 6254 | iter->cpu_file = RING_BUFFER_ALL_CPUS; |
6252 | iter->trace_buffer = &global_trace.trace_buffer; | 6255 | iter->trace_buffer = &global_trace.trace_buffer; |
6253 | } | 6256 | } |
6254 | 6257 | ||
6255 | void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) | 6258 | void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) |
6256 | { | 6259 | { |
6257 | /* use static because iter can be a bit big for the stack */ | 6260 | /* use static because iter can be a bit big for the stack */ |
6258 | static struct trace_iterator iter; | 6261 | static struct trace_iterator iter; |
6259 | static atomic_t dump_running; | 6262 | static atomic_t dump_running; |
6260 | unsigned int old_userobj; | 6263 | unsigned int old_userobj; |
6261 | unsigned long flags; | 6264 | unsigned long flags; |
6262 | int cnt = 0, cpu; | 6265 | int cnt = 0, cpu; |
6263 | 6266 | ||
6264 | /* Only allow one dump user at a time. */ | 6267 | /* Only allow one dump user at a time. */ |
6265 | if (atomic_inc_return(&dump_running) != 1) { | 6268 | if (atomic_inc_return(&dump_running) != 1) { |
6266 | atomic_dec(&dump_running); | 6269 | atomic_dec(&dump_running); |
6267 | return; | 6270 | return; |
6268 | } | 6271 | } |
6269 | 6272 | ||
6270 | /* | 6273 | /* |
6271 | * Always turn off tracing when we dump. | 6274 | * Always turn off tracing when we dump. |
6272 | * We don't need to show trace output of what happens | 6275 | * We don't need to show trace output of what happens |
6273 | * between multiple crashes. | 6276 | * between multiple crashes. |
6274 | * | 6277 | * |
6275 | * If the user does a sysrq-z, then they can re-enable | 6278 | * If the user does a sysrq-z, then they can re-enable |
6276 | * tracing with echo 1 > tracing_on. | 6279 | * tracing with echo 1 > tracing_on. |
6277 | */ | 6280 | */ |
6278 | tracing_off(); | 6281 | tracing_off(); |
6279 | 6282 | ||
6280 | local_irq_save(flags); | 6283 | local_irq_save(flags); |
6281 | 6284 | ||
6282 | /* Simulate the iterator */ | 6285 | /* Simulate the iterator */ |
6283 | trace_init_global_iter(&iter); | 6286 | trace_init_global_iter(&iter); |
6284 | 6287 | ||
6285 | for_each_tracing_cpu(cpu) { | 6288 | for_each_tracing_cpu(cpu) { |
6286 | atomic_inc(&per_cpu_ptr(iter.tr->trace_buffer.data, cpu)->disabled); | 6289 | atomic_inc(&per_cpu_ptr(iter.tr->trace_buffer.data, cpu)->disabled); |
6287 | } | 6290 | } |
6288 | 6291 | ||
6289 | old_userobj = trace_flags & TRACE_ITER_SYM_USEROBJ; | 6292 | old_userobj = trace_flags & TRACE_ITER_SYM_USEROBJ; |
6290 | 6293 | ||
6291 | /* don't look at user memory in panic mode */ | 6294 | /* don't look at user memory in panic mode */ |
6292 | trace_flags &= ~TRACE_ITER_SYM_USEROBJ; | 6295 | trace_flags &= ~TRACE_ITER_SYM_USEROBJ; |
6293 | 6296 | ||
6294 | switch (oops_dump_mode) { | 6297 | switch (oops_dump_mode) { |
6295 | case DUMP_ALL: | 6298 | case DUMP_ALL: |
6296 | iter.cpu_file = RING_BUFFER_ALL_CPUS; | 6299 | iter.cpu_file = RING_BUFFER_ALL_CPUS; |
6297 | break; | 6300 | break; |
6298 | case DUMP_ORIG: | 6301 | case DUMP_ORIG: |
6299 | iter.cpu_file = raw_smp_processor_id(); | 6302 | iter.cpu_file = raw_smp_processor_id(); |
6300 | break; | 6303 | break; |
6301 | case DUMP_NONE: | 6304 | case DUMP_NONE: |
6302 | goto out_enable; | 6305 | goto out_enable; |
6303 | default: | 6306 | default: |
6304 | printk(KERN_TRACE "Bad dumping mode, switching to all CPUs dump\n"); | 6307 | printk(KERN_TRACE "Bad dumping mode, switching to all CPUs dump\n"); |
6305 | iter.cpu_file = RING_BUFFER_ALL_CPUS; | 6308 | iter.cpu_file = RING_BUFFER_ALL_CPUS; |
6306 | } | 6309 | } |
6307 | 6310 | ||
6308 | printk(KERN_TRACE "Dumping ftrace buffer:\n"); | 6311 | printk(KERN_TRACE "Dumping ftrace buffer:\n"); |
6309 | 6312 | ||
6310 | /* Did function tracer already get disabled? */ | 6313 | /* Did function tracer already get disabled? */ |
6311 | if (ftrace_is_dead()) { | 6314 | if (ftrace_is_dead()) { |
6312 | printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n"); | 6315 | printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n"); |
6313 | printk("# MAY BE MISSING FUNCTION EVENTS\n"); | 6316 | printk("# MAY BE MISSING FUNCTION EVENTS\n"); |
6314 | } | 6317 | } |
6315 | 6318 | ||
6316 | /* | 6319 | /* |
6317 | * We need to stop all tracing on all CPUS to read the | 6320 | * We need to stop all tracing on all CPUS to read the |
6318 | * the next buffer. This is a bit expensive, but is | 6321 | * the next buffer. This is a bit expensive, but is |
6319 | * not done often. We fill all what we can read, | 6322 | * not done often. We fill all what we can read, |
6320 | * and then release the locks again. | 6323 | * and then release the locks again. |
6321 | */ | 6324 | */ |
6322 | 6325 | ||
6323 | while (!trace_empty(&iter)) { | 6326 | while (!trace_empty(&iter)) { |
6324 | 6327 | ||
6325 | if (!cnt) | 6328 | if (!cnt) |
6326 | printk(KERN_TRACE "---------------------------------\n"); | 6329 | printk(KERN_TRACE "---------------------------------\n"); |
6327 | 6330 | ||
6328 | cnt++; | 6331 | cnt++; |
6329 | 6332 | ||
6330 | /* reset all but tr, trace, and overruns */ | 6333 | /* reset all but tr, trace, and overruns */ |
6331 | memset(&iter.seq, 0, | 6334 | memset(&iter.seq, 0, |
6332 | sizeof(struct trace_iterator) - | 6335 | sizeof(struct trace_iterator) - |
6333 | offsetof(struct trace_iterator, seq)); | 6336 | offsetof(struct trace_iterator, seq)); |
6334 | iter.iter_flags |= TRACE_FILE_LAT_FMT; | 6337 | iter.iter_flags |= TRACE_FILE_LAT_FMT; |
6335 | iter.pos = -1; | 6338 | iter.pos = -1; |
6336 | 6339 | ||
6337 | if (trace_find_next_entry_inc(&iter) != NULL) { | 6340 | if (trace_find_next_entry_inc(&iter) != NULL) { |
6338 | int ret; | 6341 | int ret; |
6339 | 6342 | ||
6340 | ret = print_trace_line(&iter); | 6343 | ret = print_trace_line(&iter); |
6341 | if (ret != TRACE_TYPE_NO_CONSUME) | 6344 | if (ret != TRACE_TYPE_NO_CONSUME) |
6342 | trace_consume(&iter); | 6345 | trace_consume(&iter); |
6343 | } | 6346 | } |
6344 | touch_nmi_watchdog(); | 6347 | touch_nmi_watchdog(); |
6345 | 6348 | ||
6346 | trace_printk_seq(&iter.seq); | 6349 | trace_printk_seq(&iter.seq); |
6347 | } | 6350 | } |
6348 | 6351 | ||
6349 | if (!cnt) | 6352 | if (!cnt) |
6350 | printk(KERN_TRACE " (ftrace buffer empty)\n"); | 6353 | printk(KERN_TRACE " (ftrace buffer empty)\n"); |
6351 | else | 6354 | else |
6352 | printk(KERN_TRACE "---------------------------------\n"); | 6355 | printk(KERN_TRACE "---------------------------------\n"); |
6353 | 6356 | ||
6354 | out_enable: | 6357 | out_enable: |
6355 | trace_flags |= old_userobj; | 6358 | trace_flags |= old_userobj; |
6356 | 6359 | ||
6357 | for_each_tracing_cpu(cpu) { | 6360 | for_each_tracing_cpu(cpu) { |
6358 | atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled); | 6361 | atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled); |
6359 | } | 6362 | } |
6360 | atomic_dec(&dump_running); | 6363 | atomic_dec(&dump_running); |
6361 | local_irq_restore(flags); | 6364 | local_irq_restore(flags); |
6362 | } | 6365 | } |
6363 | EXPORT_SYMBOL_GPL(ftrace_dump); | 6366 | EXPORT_SYMBOL_GPL(ftrace_dump); |
6364 | 6367 | ||
6365 | __init static int tracer_alloc_buffers(void) | 6368 | __init static int tracer_alloc_buffers(void) |
6366 | { | 6369 | { |
6367 | int ring_buf_size; | 6370 | int ring_buf_size; |
6368 | int ret = -ENOMEM; | 6371 | int ret = -ENOMEM; |
6369 | 6372 | ||
6370 | 6373 | ||
6371 | if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL)) | 6374 | if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL)) |
6372 | goto out; | 6375 | goto out; |
6373 | 6376 | ||
6374 | if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL)) | 6377 | if (!alloc_cpumask_var(&global_trace.tracing_cpumask, GFP_KERNEL)) |
6375 | goto out_free_buffer_mask; | 6378 | goto out_free_buffer_mask; |
6376 | 6379 | ||
6377 | /* Only allocate trace_printk buffers if a trace_printk exists */ | 6380 | /* Only allocate trace_printk buffers if a trace_printk exists */ |
6378 | if (__stop___trace_bprintk_fmt != __start___trace_bprintk_fmt) | 6381 | if (__stop___trace_bprintk_fmt != __start___trace_bprintk_fmt) |
6379 | /* Must be called before global_trace.buffer is allocated */ | 6382 | /* Must be called before global_trace.buffer is allocated */ |
6380 | trace_printk_init_buffers(); | 6383 | trace_printk_init_buffers(); |
6381 | 6384 | ||
6382 | /* To save memory, keep the ring buffer size to its minimum */ | 6385 | /* To save memory, keep the ring buffer size to its minimum */ |
6383 | if (ring_buffer_expanded) | 6386 | if (ring_buffer_expanded) |
6384 | ring_buf_size = trace_buf_size; | 6387 | ring_buf_size = trace_buf_size; |
6385 | else | 6388 | else |
6386 | ring_buf_size = 1; | 6389 | ring_buf_size = 1; |
6387 | 6390 | ||
6388 | cpumask_copy(tracing_buffer_mask, cpu_possible_mask); | 6391 | cpumask_copy(tracing_buffer_mask, cpu_possible_mask); |
6389 | cpumask_copy(tracing_cpumask, cpu_all_mask); | 6392 | cpumask_copy(global_trace.tracing_cpumask, cpu_all_mask); |
6390 | 6393 | ||
6391 | raw_spin_lock_init(&global_trace.start_lock); | 6394 | raw_spin_lock_init(&global_trace.start_lock); |
6392 | 6395 | ||
6393 | /* TODO: make the number of buffers hot pluggable with CPUS */ | 6396 | /* TODO: make the number of buffers hot pluggable with CPUS */ |
6394 | if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) { | 6397 | if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) { |
6395 | printk(KERN_ERR "tracer: failed to allocate ring buffer!\n"); | 6398 | printk(KERN_ERR "tracer: failed to allocate ring buffer!\n"); |
6396 | WARN_ON(1); | 6399 | WARN_ON(1); |
6397 | goto out_free_cpumask; | 6400 | goto out_free_cpumask; |
6398 | } | 6401 | } |
6399 | 6402 | ||
6400 | if (global_trace.buffer_disabled) | 6403 | if (global_trace.buffer_disabled) |
6401 | tracing_off(); | 6404 | tracing_off(); |
6402 | 6405 | ||
6403 | trace_init_cmdlines(); | 6406 | trace_init_cmdlines(); |
6404 | 6407 | ||
6405 | /* | 6408 | /* |
6406 | * register_tracer() might reference current_trace, so it | 6409 | * register_tracer() might reference current_trace, so it |
6407 | * needs to be set before we register anything. This is | 6410 | * needs to be set before we register anything. This is |
6408 | * just a bootstrap of current_trace anyway. | 6411 | * just a bootstrap of current_trace anyway. |
6409 | */ | 6412 | */ |
6410 | global_trace.current_trace = &nop_trace; | 6413 | global_trace.current_trace = &nop_trace; |
6411 | 6414 | ||
6412 | register_tracer(&nop_trace); | 6415 | register_tracer(&nop_trace); |
6413 | 6416 | ||
6414 | /* All seems OK, enable tracing */ | 6417 | /* All seems OK, enable tracing */ |
6415 | tracing_disabled = 0; | 6418 | tracing_disabled = 0; |
6416 | 6419 | ||
6417 | atomic_notifier_chain_register(&panic_notifier_list, | 6420 | atomic_notifier_chain_register(&panic_notifier_list, |
6418 | &trace_panic_notifier); | 6421 | &trace_panic_notifier); |
6419 | 6422 | ||
6420 | register_die_notifier(&trace_die_notifier); | 6423 | register_die_notifier(&trace_die_notifier); |
6421 | 6424 | ||
6422 | global_trace.flags = TRACE_ARRAY_FL_GLOBAL; | 6425 | global_trace.flags = TRACE_ARRAY_FL_GLOBAL; |
6423 | 6426 | ||
6424 | INIT_LIST_HEAD(&global_trace.systems); | 6427 | INIT_LIST_HEAD(&global_trace.systems); |
6425 | INIT_LIST_HEAD(&global_trace.events); | 6428 | INIT_LIST_HEAD(&global_trace.events); |
6426 | list_add(&global_trace.list, &ftrace_trace_arrays); | 6429 | list_add(&global_trace.list, &ftrace_trace_arrays); |
6427 | 6430 | ||
6428 | while (trace_boot_options) { | 6431 | while (trace_boot_options) { |
6429 | char *option; | 6432 | char *option; |
6430 | 6433 | ||
6431 | option = strsep(&trace_boot_options, ","); | 6434 | option = strsep(&trace_boot_options, ","); |
6432 | trace_set_options(&global_trace, option); | 6435 | trace_set_options(&global_trace, option); |
6433 | } | 6436 | } |
6434 | 6437 | ||
6435 | register_snapshot_cmd(); | 6438 | register_snapshot_cmd(); |
6436 | 6439 | ||
6437 | return 0; | 6440 | return 0; |
6438 | 6441 | ||
6439 | out_free_cpumask: | 6442 | out_free_cpumask: |
6440 | free_percpu(global_trace.trace_buffer.data); | 6443 | free_percpu(global_trace.trace_buffer.data); |
6441 | #ifdef CONFIG_TRACER_MAX_TRACE | 6444 | #ifdef CONFIG_TRACER_MAX_TRACE |
6442 | free_percpu(global_trace.max_buffer.data); | 6445 | free_percpu(global_trace.max_buffer.data); |
6443 | #endif | 6446 | #endif |
6444 | free_cpumask_var(tracing_cpumask); | 6447 | free_cpumask_var(global_trace.tracing_cpumask); |
6445 | out_free_buffer_mask: | 6448 | out_free_buffer_mask: |
6446 | free_cpumask_var(tracing_buffer_mask); | 6449 | free_cpumask_var(tracing_buffer_mask); |
6447 | out: | 6450 | out: |
6448 | return ret; | 6451 | return ret; |
6449 | } | 6452 | } |
6450 | 6453 | ||
6451 | __init static int clear_boot_tracer(void) | 6454 | __init static int clear_boot_tracer(void) |
6452 | { | 6455 | { |
6453 | /* | 6456 | /* |
6454 | * The default tracer at boot buffer is an init section. | 6457 | * The default tracer at boot buffer is an init section. |
6455 | * This function is called in lateinit. If we did not | 6458 | * This function is called in lateinit. If we did not |
6456 | * find the boot tracer, then clear it out, to prevent | 6459 | * find the boot tracer, then clear it out, to prevent |
6457 | * later registration from accessing the buffer that is | 6460 | * later registration from accessing the buffer that is |
6458 | * about to be freed. | 6461 | * about to be freed. |
6459 | */ | 6462 | */ |
6460 | if (!default_bootup_tracer) | 6463 | if (!default_bootup_tracer) |
6461 | return 0; | 6464 | return 0; |
6462 | 6465 | ||
6463 | printk(KERN_INFO "ftrace bootup tracer '%s' not registered.\n", | 6466 | printk(KERN_INFO "ftrace bootup tracer '%s' not registered.\n", |
6464 | default_bootup_tracer); | 6467 | default_bootup_tracer); |
6465 | default_bootup_tracer = NULL; | 6468 | default_bootup_tracer = NULL; |
kernel/trace/trace.h
1 | #ifndef _LINUX_KERNEL_TRACE_H | 1 | #ifndef _LINUX_KERNEL_TRACE_H |
2 | #define _LINUX_KERNEL_TRACE_H | 2 | #define _LINUX_KERNEL_TRACE_H |
3 | 3 | ||
4 | #include <linux/fs.h> | 4 | #include <linux/fs.h> |
5 | #include <linux/atomic.h> | 5 | #include <linux/atomic.h> |
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/clocksource.h> | 7 | #include <linux/clocksource.h> |
8 | #include <linux/ring_buffer.h> | 8 | #include <linux/ring_buffer.h> |
9 | #include <linux/mmiotrace.h> | 9 | #include <linux/mmiotrace.h> |
10 | #include <linux/tracepoint.h> | 10 | #include <linux/tracepoint.h> |
11 | #include <linux/ftrace.h> | 11 | #include <linux/ftrace.h> |
12 | #include <linux/hw_breakpoint.h> | 12 | #include <linux/hw_breakpoint.h> |
13 | #include <linux/trace_seq.h> | 13 | #include <linux/trace_seq.h> |
14 | #include <linux/ftrace_event.h> | 14 | #include <linux/ftrace_event.h> |
15 | 15 | ||
16 | #ifdef CONFIG_FTRACE_SYSCALLS | 16 | #ifdef CONFIG_FTRACE_SYSCALLS |
17 | #include <asm/unistd.h> /* For NR_SYSCALLS */ | 17 | #include <asm/unistd.h> /* For NR_SYSCALLS */ |
18 | #include <asm/syscall.h> /* some archs define it here */ | 18 | #include <asm/syscall.h> /* some archs define it here */ |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | enum trace_type { | 21 | enum trace_type { |
22 | __TRACE_FIRST_TYPE = 0, | 22 | __TRACE_FIRST_TYPE = 0, |
23 | 23 | ||
24 | TRACE_FN, | 24 | TRACE_FN, |
25 | TRACE_CTX, | 25 | TRACE_CTX, |
26 | TRACE_WAKE, | 26 | TRACE_WAKE, |
27 | TRACE_STACK, | 27 | TRACE_STACK, |
28 | TRACE_PRINT, | 28 | TRACE_PRINT, |
29 | TRACE_BPRINT, | 29 | TRACE_BPRINT, |
30 | TRACE_MMIO_RW, | 30 | TRACE_MMIO_RW, |
31 | TRACE_MMIO_MAP, | 31 | TRACE_MMIO_MAP, |
32 | TRACE_BRANCH, | 32 | TRACE_BRANCH, |
33 | TRACE_GRAPH_RET, | 33 | TRACE_GRAPH_RET, |
34 | TRACE_GRAPH_ENT, | 34 | TRACE_GRAPH_ENT, |
35 | TRACE_USER_STACK, | 35 | TRACE_USER_STACK, |
36 | TRACE_BLK, | 36 | TRACE_BLK, |
37 | TRACE_BPUTS, | 37 | TRACE_BPUTS, |
38 | 38 | ||
39 | __TRACE_LAST_TYPE, | 39 | __TRACE_LAST_TYPE, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | 42 | ||
43 | #undef __field | 43 | #undef __field |
44 | #define __field(type, item) type item; | 44 | #define __field(type, item) type item; |
45 | 45 | ||
46 | #undef __field_struct | 46 | #undef __field_struct |
47 | #define __field_struct(type, item) __field(type, item) | 47 | #define __field_struct(type, item) __field(type, item) |
48 | 48 | ||
49 | #undef __field_desc | 49 | #undef __field_desc |
50 | #define __field_desc(type, container, item) | 50 | #define __field_desc(type, container, item) |
51 | 51 | ||
52 | #undef __array | 52 | #undef __array |
53 | #define __array(type, item, size) type item[size]; | 53 | #define __array(type, item, size) type item[size]; |
54 | 54 | ||
55 | #undef __array_desc | 55 | #undef __array_desc |
56 | #define __array_desc(type, container, item, size) | 56 | #define __array_desc(type, container, item, size) |
57 | 57 | ||
58 | #undef __dynamic_array | 58 | #undef __dynamic_array |
59 | #define __dynamic_array(type, item) type item[]; | 59 | #define __dynamic_array(type, item) type item[]; |
60 | 60 | ||
61 | #undef F_STRUCT | 61 | #undef F_STRUCT |
62 | #define F_STRUCT(args...) args | 62 | #define F_STRUCT(args...) args |
63 | 63 | ||
64 | #undef FTRACE_ENTRY | 64 | #undef FTRACE_ENTRY |
65 | #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ | 65 | #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ |
66 | struct struct_name { \ | 66 | struct struct_name { \ |
67 | struct trace_entry ent; \ | 67 | struct trace_entry ent; \ |
68 | tstruct \ | 68 | tstruct \ |
69 | } | 69 | } |
70 | 70 | ||
71 | #undef TP_ARGS | 71 | #undef TP_ARGS |
72 | #define TP_ARGS(args...) args | 72 | #define TP_ARGS(args...) args |
73 | 73 | ||
74 | #undef FTRACE_ENTRY_DUP | 74 | #undef FTRACE_ENTRY_DUP |
75 | #define FTRACE_ENTRY_DUP(name, name_struct, id, tstruct, printk, filter) | 75 | #define FTRACE_ENTRY_DUP(name, name_struct, id, tstruct, printk, filter) |
76 | 76 | ||
77 | #undef FTRACE_ENTRY_REG | 77 | #undef FTRACE_ENTRY_REG |
78 | #define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print, \ | 78 | #define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print, \ |
79 | filter, regfn) \ | 79 | filter, regfn) \ |
80 | FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ | 80 | FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ |
81 | filter) | 81 | filter) |
82 | 82 | ||
83 | #include "trace_entries.h" | 83 | #include "trace_entries.h" |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * syscalls are special, and need special handling, this is why | 86 | * syscalls are special, and need special handling, this is why |
87 | * they are not included in trace_entries.h | 87 | * they are not included in trace_entries.h |
88 | */ | 88 | */ |
89 | struct syscall_trace_enter { | 89 | struct syscall_trace_enter { |
90 | struct trace_entry ent; | 90 | struct trace_entry ent; |
91 | int nr; | 91 | int nr; |
92 | unsigned long args[]; | 92 | unsigned long args[]; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | struct syscall_trace_exit { | 95 | struct syscall_trace_exit { |
96 | struct trace_entry ent; | 96 | struct trace_entry ent; |
97 | int nr; | 97 | int nr; |
98 | long ret; | 98 | long ret; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | struct kprobe_trace_entry_head { | 101 | struct kprobe_trace_entry_head { |
102 | struct trace_entry ent; | 102 | struct trace_entry ent; |
103 | unsigned long ip; | 103 | unsigned long ip; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | struct kretprobe_trace_entry_head { | 106 | struct kretprobe_trace_entry_head { |
107 | struct trace_entry ent; | 107 | struct trace_entry ent; |
108 | unsigned long func; | 108 | unsigned long func; |
109 | unsigned long ret_ip; | 109 | unsigned long ret_ip; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * trace_flag_type is an enumeration that holds different | 113 | * trace_flag_type is an enumeration that holds different |
114 | * states when a trace occurs. These are: | 114 | * states when a trace occurs. These are: |
115 | * IRQS_OFF - interrupts were disabled | 115 | * IRQS_OFF - interrupts were disabled |
116 | * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags | 116 | * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags |
117 | * NEED_RESCHED - reschedule is requested | 117 | * NEED_RESCHED - reschedule is requested |
118 | * HARDIRQ - inside an interrupt handler | 118 | * HARDIRQ - inside an interrupt handler |
119 | * SOFTIRQ - inside a softirq handler | 119 | * SOFTIRQ - inside a softirq handler |
120 | */ | 120 | */ |
121 | enum trace_flag_type { | 121 | enum trace_flag_type { |
122 | TRACE_FLAG_IRQS_OFF = 0x01, | 122 | TRACE_FLAG_IRQS_OFF = 0x01, |
123 | TRACE_FLAG_IRQS_NOSUPPORT = 0x02, | 123 | TRACE_FLAG_IRQS_NOSUPPORT = 0x02, |
124 | TRACE_FLAG_NEED_RESCHED = 0x04, | 124 | TRACE_FLAG_NEED_RESCHED = 0x04, |
125 | TRACE_FLAG_HARDIRQ = 0x08, | 125 | TRACE_FLAG_HARDIRQ = 0x08, |
126 | TRACE_FLAG_SOFTIRQ = 0x10, | 126 | TRACE_FLAG_SOFTIRQ = 0x10, |
127 | }; | 127 | }; |
128 | 128 | ||
129 | #define TRACE_BUF_SIZE 1024 | 129 | #define TRACE_BUF_SIZE 1024 |
130 | 130 | ||
131 | struct trace_array; | 131 | struct trace_array; |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * The CPU trace array - it consists of thousands of trace entries | 134 | * The CPU trace array - it consists of thousands of trace entries |
135 | * plus some other descriptor data: (for example which task started | 135 | * plus some other descriptor data: (for example which task started |
136 | * the trace, etc.) | 136 | * the trace, etc.) |
137 | */ | 137 | */ |
138 | struct trace_array_cpu { | 138 | struct trace_array_cpu { |
139 | atomic_t disabled; | 139 | atomic_t disabled; |
140 | void *buffer_page; /* ring buffer spare */ | 140 | void *buffer_page; /* ring buffer spare */ |
141 | 141 | ||
142 | unsigned long entries; | 142 | unsigned long entries; |
143 | unsigned long saved_latency; | 143 | unsigned long saved_latency; |
144 | unsigned long critical_start; | 144 | unsigned long critical_start; |
145 | unsigned long critical_end; | 145 | unsigned long critical_end; |
146 | unsigned long critical_sequence; | 146 | unsigned long critical_sequence; |
147 | unsigned long nice; | 147 | unsigned long nice; |
148 | unsigned long policy; | 148 | unsigned long policy; |
149 | unsigned long rt_priority; | 149 | unsigned long rt_priority; |
150 | unsigned long skipped_entries; | 150 | unsigned long skipped_entries; |
151 | cycle_t preempt_timestamp; | 151 | cycle_t preempt_timestamp; |
152 | pid_t pid; | 152 | pid_t pid; |
153 | kuid_t uid; | 153 | kuid_t uid; |
154 | char comm[TASK_COMM_LEN]; | 154 | char comm[TASK_COMM_LEN]; |
155 | }; | 155 | }; |
156 | 156 | ||
157 | struct tracer; | 157 | struct tracer; |
158 | 158 | ||
159 | struct trace_buffer { | 159 | struct trace_buffer { |
160 | struct trace_array *tr; | 160 | struct trace_array *tr; |
161 | struct ring_buffer *buffer; | 161 | struct ring_buffer *buffer; |
162 | struct trace_array_cpu __percpu *data; | 162 | struct trace_array_cpu __percpu *data; |
163 | cycle_t time_start; | 163 | cycle_t time_start; |
164 | int cpu; | 164 | int cpu; |
165 | }; | 165 | }; |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * The trace array - an array of per-CPU trace arrays. This is the | 168 | * The trace array - an array of per-CPU trace arrays. This is the |
169 | * highest level data structure that individual tracers deal with. | 169 | * highest level data structure that individual tracers deal with. |
170 | * They have on/off state as well: | 170 | * They have on/off state as well: |
171 | */ | 171 | */ |
172 | struct trace_array { | 172 | struct trace_array { |
173 | struct list_head list; | 173 | struct list_head list; |
174 | char *name; | 174 | char *name; |
175 | struct trace_buffer trace_buffer; | 175 | struct trace_buffer trace_buffer; |
176 | #ifdef CONFIG_TRACER_MAX_TRACE | 176 | #ifdef CONFIG_TRACER_MAX_TRACE |
177 | /* | 177 | /* |
178 | * The max_buffer is used to snapshot the trace when a maximum | 178 | * The max_buffer is used to snapshot the trace when a maximum |
179 | * latency is reached, or when the user initiates a snapshot. | 179 | * latency is reached, or when the user initiates a snapshot. |
180 | * Some tracers will use this to store a maximum trace while | 180 | * Some tracers will use this to store a maximum trace while |
181 | * it continues examining live traces. | 181 | * it continues examining live traces. |
182 | * | 182 | * |
183 | * The buffers for the max_buffer are set up the same as the trace_buffer | 183 | * The buffers for the max_buffer are set up the same as the trace_buffer |
184 | * When a snapshot is taken, the buffer of the max_buffer is swapped | 184 | * When a snapshot is taken, the buffer of the max_buffer is swapped |
185 | * with the buffer of the trace_buffer and the buffers are reset for | 185 | * with the buffer of the trace_buffer and the buffers are reset for |
186 | * the trace_buffer so the tracing can continue. | 186 | * the trace_buffer so the tracing can continue. |
187 | */ | 187 | */ |
188 | struct trace_buffer max_buffer; | 188 | struct trace_buffer max_buffer; |
189 | bool allocated_snapshot; | 189 | bool allocated_snapshot; |
190 | #endif | 190 | #endif |
191 | int buffer_disabled; | 191 | int buffer_disabled; |
192 | #ifdef CONFIG_FTRACE_SYSCALLS | 192 | #ifdef CONFIG_FTRACE_SYSCALLS |
193 | int sys_refcount_enter; | 193 | int sys_refcount_enter; |
194 | int sys_refcount_exit; | 194 | int sys_refcount_exit; |
195 | DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls); | 195 | DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls); |
196 | DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls); | 196 | DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls); |
197 | #endif | 197 | #endif |
198 | int stop_count; | 198 | int stop_count; |
199 | int clock_id; | 199 | int clock_id; |
200 | struct tracer *current_trace; | 200 | struct tracer *current_trace; |
201 | unsigned int flags; | 201 | unsigned int flags; |
202 | raw_spinlock_t start_lock; | 202 | raw_spinlock_t start_lock; |
203 | struct dentry *dir; | 203 | struct dentry *dir; |
204 | struct dentry *options; | 204 | struct dentry *options; |
205 | struct dentry *percpu_dir; | 205 | struct dentry *percpu_dir; |
206 | struct dentry *event_dir; | 206 | struct dentry *event_dir; |
207 | struct list_head systems; | 207 | struct list_head systems; |
208 | struct list_head events; | 208 | struct list_head events; |
209 | cpumask_var_t tracing_cpumask; /* only trace on set CPUs */ | ||
209 | int ref; | 210 | int ref; |
210 | }; | 211 | }; |
211 | 212 | ||
212 | enum { | 213 | enum { |
213 | TRACE_ARRAY_FL_GLOBAL = (1 << 0) | 214 | TRACE_ARRAY_FL_GLOBAL = (1 << 0) |
214 | }; | 215 | }; |
215 | 216 | ||
216 | extern struct list_head ftrace_trace_arrays; | 217 | extern struct list_head ftrace_trace_arrays; |
217 | 218 | ||
218 | extern struct mutex trace_types_lock; | 219 | extern struct mutex trace_types_lock; |
219 | 220 | ||
220 | extern int trace_array_get(struct trace_array *tr); | 221 | extern int trace_array_get(struct trace_array *tr); |
221 | extern void trace_array_put(struct trace_array *tr); | 222 | extern void trace_array_put(struct trace_array *tr); |
222 | 223 | ||
223 | /* | 224 | /* |
224 | * The global tracer (top) should be the first trace array added, | 225 | * The global tracer (top) should be the first trace array added, |
225 | * but we check the flag anyway. | 226 | * but we check the flag anyway. |
226 | */ | 227 | */ |
227 | static inline struct trace_array *top_trace_array(void) | 228 | static inline struct trace_array *top_trace_array(void) |
228 | { | 229 | { |
229 | struct trace_array *tr; | 230 | struct trace_array *tr; |
230 | 231 | ||
231 | tr = list_entry(ftrace_trace_arrays.prev, | 232 | tr = list_entry(ftrace_trace_arrays.prev, |
232 | typeof(*tr), list); | 233 | typeof(*tr), list); |
233 | WARN_ON(!(tr->flags & TRACE_ARRAY_FL_GLOBAL)); | 234 | WARN_ON(!(tr->flags & TRACE_ARRAY_FL_GLOBAL)); |
234 | return tr; | 235 | return tr; |
235 | } | 236 | } |
236 | 237 | ||
237 | #define FTRACE_CMP_TYPE(var, type) \ | 238 | #define FTRACE_CMP_TYPE(var, type) \ |
238 | __builtin_types_compatible_p(typeof(var), type *) | 239 | __builtin_types_compatible_p(typeof(var), type *) |
239 | 240 | ||
240 | #undef IF_ASSIGN | 241 | #undef IF_ASSIGN |
241 | #define IF_ASSIGN(var, entry, etype, id) \ | 242 | #define IF_ASSIGN(var, entry, etype, id) \ |
242 | if (FTRACE_CMP_TYPE(var, etype)) { \ | 243 | if (FTRACE_CMP_TYPE(var, etype)) { \ |
243 | var = (typeof(var))(entry); \ | 244 | var = (typeof(var))(entry); \ |
244 | WARN_ON(id && (entry)->type != id); \ | 245 | WARN_ON(id && (entry)->type != id); \ |
245 | break; \ | 246 | break; \ |
246 | } | 247 | } |
247 | 248 | ||
248 | /* Will cause compile errors if type is not found. */ | 249 | /* Will cause compile errors if type is not found. */ |
249 | extern void __ftrace_bad_type(void); | 250 | extern void __ftrace_bad_type(void); |
250 | 251 | ||
251 | /* | 252 | /* |
252 | * The trace_assign_type is a verifier that the entry type is | 253 | * The trace_assign_type is a verifier that the entry type is |
253 | * the same as the type being assigned. To add new types simply | 254 | * the same as the type being assigned. To add new types simply |
254 | * add a line with the following format: | 255 | * add a line with the following format: |
255 | * | 256 | * |
256 | * IF_ASSIGN(var, ent, type, id); | 257 | * IF_ASSIGN(var, ent, type, id); |
257 | * | 258 | * |
258 | * Where "type" is the trace type that includes the trace_entry | 259 | * Where "type" is the trace type that includes the trace_entry |
259 | * as the "ent" item. And "id" is the trace identifier that is | 260 | * as the "ent" item. And "id" is the trace identifier that is |
260 | * used in the trace_type enum. | 261 | * used in the trace_type enum. |
261 | * | 262 | * |
262 | * If the type can have more than one id, then use zero. | 263 | * If the type can have more than one id, then use zero. |
263 | */ | 264 | */ |
264 | #define trace_assign_type(var, ent) \ | 265 | #define trace_assign_type(var, ent) \ |
265 | do { \ | 266 | do { \ |
266 | IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN); \ | 267 | IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN); \ |
267 | IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \ | 268 | IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \ |
268 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ | 269 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ |
269 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ | 270 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ |
270 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ | 271 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ |
271 | IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \ | 272 | IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \ |
272 | IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS); \ | 273 | IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS); \ |
273 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ | 274 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ |
274 | TRACE_MMIO_RW); \ | 275 | TRACE_MMIO_RW); \ |
275 | IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \ | 276 | IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \ |
276 | TRACE_MMIO_MAP); \ | 277 | TRACE_MMIO_MAP); \ |
277 | IF_ASSIGN(var, ent, struct trace_branch, TRACE_BRANCH); \ | 278 | IF_ASSIGN(var, ent, struct trace_branch, TRACE_BRANCH); \ |
278 | IF_ASSIGN(var, ent, struct ftrace_graph_ent_entry, \ | 279 | IF_ASSIGN(var, ent, struct ftrace_graph_ent_entry, \ |
279 | TRACE_GRAPH_ENT); \ | 280 | TRACE_GRAPH_ENT); \ |
280 | IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \ | 281 | IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \ |
281 | TRACE_GRAPH_RET); \ | 282 | TRACE_GRAPH_RET); \ |
282 | __ftrace_bad_type(); \ | 283 | __ftrace_bad_type(); \ |
283 | } while (0) | 284 | } while (0) |
284 | 285 | ||
285 | /* | 286 | /* |
286 | * An option specific to a tracer. This is a boolean value. | 287 | * An option specific to a tracer. This is a boolean value. |
287 | * The bit is the bit index that sets its value on the | 288 | * The bit is the bit index that sets its value on the |
288 | * flags value in struct tracer_flags. | 289 | * flags value in struct tracer_flags. |
289 | */ | 290 | */ |
290 | struct tracer_opt { | 291 | struct tracer_opt { |
291 | const char *name; /* Will appear on the trace_options file */ | 292 | const char *name; /* Will appear on the trace_options file */ |
292 | u32 bit; /* Mask assigned in val field in tracer_flags */ | 293 | u32 bit; /* Mask assigned in val field in tracer_flags */ |
293 | }; | 294 | }; |
294 | 295 | ||
295 | /* | 296 | /* |
296 | * The set of specific options for a tracer. Your tracer | 297 | * The set of specific options for a tracer. Your tracer |
297 | * have to set the initial value of the flags val. | 298 | * have to set the initial value of the flags val. |
298 | */ | 299 | */ |
299 | struct tracer_flags { | 300 | struct tracer_flags { |
300 | u32 val; | 301 | u32 val; |
301 | struct tracer_opt *opts; | 302 | struct tracer_opt *opts; |
302 | }; | 303 | }; |
303 | 304 | ||
304 | /* Makes more easy to define a tracer opt */ | 305 | /* Makes more easy to define a tracer opt */ |
305 | #define TRACER_OPT(s, b) .name = #s, .bit = b | 306 | #define TRACER_OPT(s, b) .name = #s, .bit = b |
306 | 307 | ||
307 | 308 | ||
308 | /** | 309 | /** |
309 | * struct tracer - a specific tracer and its callbacks to interact with debugfs | 310 | * struct tracer - a specific tracer and its callbacks to interact with debugfs |
310 | * @name: the name chosen to select it on the available_tracers file | 311 | * @name: the name chosen to select it on the available_tracers file |
311 | * @init: called when one switches to this tracer (echo name > current_tracer) | 312 | * @init: called when one switches to this tracer (echo name > current_tracer) |
312 | * @reset: called when one switches to another tracer | 313 | * @reset: called when one switches to another tracer |
313 | * @start: called when tracing is unpaused (echo 1 > tracing_enabled) | 314 | * @start: called when tracing is unpaused (echo 1 > tracing_enabled) |
314 | * @stop: called when tracing is paused (echo 0 > tracing_enabled) | 315 | * @stop: called when tracing is paused (echo 0 > tracing_enabled) |
315 | * @open: called when the trace file is opened | 316 | * @open: called when the trace file is opened |
316 | * @pipe_open: called when the trace_pipe file is opened | 317 | * @pipe_open: called when the trace_pipe file is opened |
317 | * @wait_pipe: override how the user waits for traces on trace_pipe | 318 | * @wait_pipe: override how the user waits for traces on trace_pipe |
318 | * @close: called when the trace file is released | 319 | * @close: called when the trace file is released |
319 | * @pipe_close: called when the trace_pipe file is released | 320 | * @pipe_close: called when the trace_pipe file is released |
320 | * @read: override the default read callback on trace_pipe | 321 | * @read: override the default read callback on trace_pipe |
321 | * @splice_read: override the default splice_read callback on trace_pipe | 322 | * @splice_read: override the default splice_read callback on trace_pipe |
322 | * @selftest: selftest to run on boot (see trace_selftest.c) | 323 | * @selftest: selftest to run on boot (see trace_selftest.c) |
323 | * @print_headers: override the first lines that describe your columns | 324 | * @print_headers: override the first lines that describe your columns |
324 | * @print_line: callback that prints a trace | 325 | * @print_line: callback that prints a trace |
325 | * @set_flag: signals one of your private flags changed (trace_options file) | 326 | * @set_flag: signals one of your private flags changed (trace_options file) |
326 | * @flags: your private flags | 327 | * @flags: your private flags |
327 | */ | 328 | */ |
328 | struct tracer { | 329 | struct tracer { |
329 | const char *name; | 330 | const char *name; |
330 | int (*init)(struct trace_array *tr); | 331 | int (*init)(struct trace_array *tr); |
331 | void (*reset)(struct trace_array *tr); | 332 | void (*reset)(struct trace_array *tr); |
332 | void (*start)(struct trace_array *tr); | 333 | void (*start)(struct trace_array *tr); |
333 | void (*stop)(struct trace_array *tr); | 334 | void (*stop)(struct trace_array *tr); |
334 | void (*open)(struct trace_iterator *iter); | 335 | void (*open)(struct trace_iterator *iter); |
335 | void (*pipe_open)(struct trace_iterator *iter); | 336 | void (*pipe_open)(struct trace_iterator *iter); |
336 | void (*wait_pipe)(struct trace_iterator *iter); | 337 | void (*wait_pipe)(struct trace_iterator *iter); |
337 | void (*close)(struct trace_iterator *iter); | 338 | void (*close)(struct trace_iterator *iter); |
338 | void (*pipe_close)(struct trace_iterator *iter); | 339 | void (*pipe_close)(struct trace_iterator *iter); |
339 | ssize_t (*read)(struct trace_iterator *iter, | 340 | ssize_t (*read)(struct trace_iterator *iter, |
340 | struct file *filp, char __user *ubuf, | 341 | struct file *filp, char __user *ubuf, |
341 | size_t cnt, loff_t *ppos); | 342 | size_t cnt, loff_t *ppos); |
342 | ssize_t (*splice_read)(struct trace_iterator *iter, | 343 | ssize_t (*splice_read)(struct trace_iterator *iter, |
343 | struct file *filp, | 344 | struct file *filp, |
344 | loff_t *ppos, | 345 | loff_t *ppos, |
345 | struct pipe_inode_info *pipe, | 346 | struct pipe_inode_info *pipe, |
346 | size_t len, | 347 | size_t len, |
347 | unsigned int flags); | 348 | unsigned int flags); |
348 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 349 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
349 | int (*selftest)(struct tracer *trace, | 350 | int (*selftest)(struct tracer *trace, |
350 | struct trace_array *tr); | 351 | struct trace_array *tr); |
351 | #endif | 352 | #endif |
352 | void (*print_header)(struct seq_file *m); | 353 | void (*print_header)(struct seq_file *m); |
353 | enum print_line_t (*print_line)(struct trace_iterator *iter); | 354 | enum print_line_t (*print_line)(struct trace_iterator *iter); |
354 | /* If you handled the flag setting, return 0 */ | 355 | /* If you handled the flag setting, return 0 */ |
355 | int (*set_flag)(u32 old_flags, u32 bit, int set); | 356 | int (*set_flag)(u32 old_flags, u32 bit, int set); |
356 | /* Return 0 if OK with change, else return non-zero */ | 357 | /* Return 0 if OK with change, else return non-zero */ |
357 | int (*flag_changed)(struct tracer *tracer, | 358 | int (*flag_changed)(struct tracer *tracer, |
358 | u32 mask, int set); | 359 | u32 mask, int set); |
359 | struct tracer *next; | 360 | struct tracer *next; |
360 | struct tracer_flags *flags; | 361 | struct tracer_flags *flags; |
361 | bool print_max; | 362 | bool print_max; |
362 | bool enabled; | 363 | bool enabled; |
363 | #ifdef CONFIG_TRACER_MAX_TRACE | 364 | #ifdef CONFIG_TRACER_MAX_TRACE |
364 | bool use_max_tr; | 365 | bool use_max_tr; |
365 | #endif | 366 | #endif |
366 | }; | 367 | }; |
367 | 368 | ||
368 | 369 | ||
369 | /* Only current can touch trace_recursion */ | 370 | /* Only current can touch trace_recursion */ |
370 | 371 | ||
371 | /* | 372 | /* |
372 | * For function tracing recursion: | 373 | * For function tracing recursion: |
373 | * The order of these bits are important. | 374 | * The order of these bits are important. |
374 | * | 375 | * |
375 | * When function tracing occurs, the following steps are made: | 376 | * When function tracing occurs, the following steps are made: |
376 | * If arch does not support a ftrace feature: | 377 | * If arch does not support a ftrace feature: |
377 | * call internal function (uses INTERNAL bits) which calls... | 378 | * call internal function (uses INTERNAL bits) which calls... |
378 | * If callback is registered to the "global" list, the list | 379 | * If callback is registered to the "global" list, the list |
379 | * function is called and recursion checks the GLOBAL bits. | 380 | * function is called and recursion checks the GLOBAL bits. |
380 | * then this function calls... | 381 | * then this function calls... |
381 | * The function callback, which can use the FTRACE bits to | 382 | * The function callback, which can use the FTRACE bits to |
382 | * check for recursion. | 383 | * check for recursion. |
383 | * | 384 | * |
384 | * Now if the arch does not suppport a feature, and it calls | 385 | * Now if the arch does not suppport a feature, and it calls |
385 | * the global list function which calls the ftrace callback | 386 | * the global list function which calls the ftrace callback |
386 | * all three of these steps will do a recursion protection. | 387 | * all three of these steps will do a recursion protection. |
387 | * There's no reason to do one if the previous caller already | 388 | * There's no reason to do one if the previous caller already |
388 | * did. The recursion that we are protecting against will | 389 | * did. The recursion that we are protecting against will |
389 | * go through the same steps again. | 390 | * go through the same steps again. |
390 | * | 391 | * |
391 | * To prevent the multiple recursion checks, if a recursion | 392 | * To prevent the multiple recursion checks, if a recursion |
392 | * bit is set that is higher than the MAX bit of the current | 393 | * bit is set that is higher than the MAX bit of the current |
393 | * check, then we know that the check was made by the previous | 394 | * check, then we know that the check was made by the previous |
394 | * caller, and we can skip the current check. | 395 | * caller, and we can skip the current check. |
395 | */ | 396 | */ |
396 | enum { | 397 | enum { |
397 | TRACE_BUFFER_BIT, | 398 | TRACE_BUFFER_BIT, |
398 | TRACE_BUFFER_NMI_BIT, | 399 | TRACE_BUFFER_NMI_BIT, |
399 | TRACE_BUFFER_IRQ_BIT, | 400 | TRACE_BUFFER_IRQ_BIT, |
400 | TRACE_BUFFER_SIRQ_BIT, | 401 | TRACE_BUFFER_SIRQ_BIT, |
401 | 402 | ||
402 | /* Start of function recursion bits */ | 403 | /* Start of function recursion bits */ |
403 | TRACE_FTRACE_BIT, | 404 | TRACE_FTRACE_BIT, |
404 | TRACE_FTRACE_NMI_BIT, | 405 | TRACE_FTRACE_NMI_BIT, |
405 | TRACE_FTRACE_IRQ_BIT, | 406 | TRACE_FTRACE_IRQ_BIT, |
406 | TRACE_FTRACE_SIRQ_BIT, | 407 | TRACE_FTRACE_SIRQ_BIT, |
407 | 408 | ||
408 | /* GLOBAL_BITs must be greater than FTRACE_BITs */ | 409 | /* GLOBAL_BITs must be greater than FTRACE_BITs */ |
409 | TRACE_GLOBAL_BIT, | 410 | TRACE_GLOBAL_BIT, |
410 | TRACE_GLOBAL_NMI_BIT, | 411 | TRACE_GLOBAL_NMI_BIT, |
411 | TRACE_GLOBAL_IRQ_BIT, | 412 | TRACE_GLOBAL_IRQ_BIT, |
412 | TRACE_GLOBAL_SIRQ_BIT, | 413 | TRACE_GLOBAL_SIRQ_BIT, |
413 | 414 | ||
414 | /* INTERNAL_BITs must be greater than GLOBAL_BITs */ | 415 | /* INTERNAL_BITs must be greater than GLOBAL_BITs */ |
415 | TRACE_INTERNAL_BIT, | 416 | TRACE_INTERNAL_BIT, |
416 | TRACE_INTERNAL_NMI_BIT, | 417 | TRACE_INTERNAL_NMI_BIT, |
417 | TRACE_INTERNAL_IRQ_BIT, | 418 | TRACE_INTERNAL_IRQ_BIT, |
418 | TRACE_INTERNAL_SIRQ_BIT, | 419 | TRACE_INTERNAL_SIRQ_BIT, |
419 | 420 | ||
420 | TRACE_CONTROL_BIT, | 421 | TRACE_CONTROL_BIT, |
421 | 422 | ||
422 | /* | 423 | /* |
423 | * Abuse of the trace_recursion. | 424 | * Abuse of the trace_recursion. |
424 | * As we need a way to maintain state if we are tracing the function | 425 | * As we need a way to maintain state if we are tracing the function |
425 | * graph in irq because we want to trace a particular function that | 426 | * graph in irq because we want to trace a particular function that |
426 | * was called in irq context but we have irq tracing off. Since this | 427 | * was called in irq context but we have irq tracing off. Since this |
427 | * can only be modified by current, we can reuse trace_recursion. | 428 | * can only be modified by current, we can reuse trace_recursion. |
428 | */ | 429 | */ |
429 | TRACE_IRQ_BIT, | 430 | TRACE_IRQ_BIT, |
430 | }; | 431 | }; |
431 | 432 | ||
432 | #define trace_recursion_set(bit) do { (current)->trace_recursion |= (1<<(bit)); } while (0) | 433 | #define trace_recursion_set(bit) do { (current)->trace_recursion |= (1<<(bit)); } while (0) |
433 | #define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(1<<(bit)); } while (0) | 434 | #define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(1<<(bit)); } while (0) |
434 | #define trace_recursion_test(bit) ((current)->trace_recursion & (1<<(bit))) | 435 | #define trace_recursion_test(bit) ((current)->trace_recursion & (1<<(bit))) |
435 | 436 | ||
436 | #define TRACE_CONTEXT_BITS 4 | 437 | #define TRACE_CONTEXT_BITS 4 |
437 | 438 | ||
438 | #define TRACE_FTRACE_START TRACE_FTRACE_BIT | 439 | #define TRACE_FTRACE_START TRACE_FTRACE_BIT |
439 | #define TRACE_FTRACE_MAX ((1 << (TRACE_FTRACE_START + TRACE_CONTEXT_BITS)) - 1) | 440 | #define TRACE_FTRACE_MAX ((1 << (TRACE_FTRACE_START + TRACE_CONTEXT_BITS)) - 1) |
440 | 441 | ||
441 | #define TRACE_GLOBAL_START TRACE_GLOBAL_BIT | 442 | #define TRACE_GLOBAL_START TRACE_GLOBAL_BIT |
442 | #define TRACE_GLOBAL_MAX ((1 << (TRACE_GLOBAL_START + TRACE_CONTEXT_BITS)) - 1) | 443 | #define TRACE_GLOBAL_MAX ((1 << (TRACE_GLOBAL_START + TRACE_CONTEXT_BITS)) - 1) |
443 | 444 | ||
444 | #define TRACE_LIST_START TRACE_INTERNAL_BIT | 445 | #define TRACE_LIST_START TRACE_INTERNAL_BIT |
445 | #define TRACE_LIST_MAX ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1) | 446 | #define TRACE_LIST_MAX ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1) |
446 | 447 | ||
447 | #define TRACE_CONTEXT_MASK TRACE_LIST_MAX | 448 | #define TRACE_CONTEXT_MASK TRACE_LIST_MAX |
448 | 449 | ||
449 | static __always_inline int trace_get_context_bit(void) | 450 | static __always_inline int trace_get_context_bit(void) |
450 | { | 451 | { |
451 | int bit; | 452 | int bit; |
452 | 453 | ||
453 | if (in_interrupt()) { | 454 | if (in_interrupt()) { |
454 | if (in_nmi()) | 455 | if (in_nmi()) |
455 | bit = 0; | 456 | bit = 0; |
456 | 457 | ||
457 | else if (in_irq()) | 458 | else if (in_irq()) |
458 | bit = 1; | 459 | bit = 1; |
459 | else | 460 | else |
460 | bit = 2; | 461 | bit = 2; |
461 | } else | 462 | } else |
462 | bit = 3; | 463 | bit = 3; |
463 | 464 | ||
464 | return bit; | 465 | return bit; |
465 | } | 466 | } |
466 | 467 | ||
467 | static __always_inline int trace_test_and_set_recursion(int start, int max) | 468 | static __always_inline int trace_test_and_set_recursion(int start, int max) |
468 | { | 469 | { |
469 | unsigned int val = current->trace_recursion; | 470 | unsigned int val = current->trace_recursion; |
470 | int bit; | 471 | int bit; |
471 | 472 | ||
472 | /* A previous recursion check was made */ | 473 | /* A previous recursion check was made */ |
473 | if ((val & TRACE_CONTEXT_MASK) > max) | 474 | if ((val & TRACE_CONTEXT_MASK) > max) |
474 | return 0; | 475 | return 0; |
475 | 476 | ||
476 | bit = trace_get_context_bit() + start; | 477 | bit = trace_get_context_bit() + start; |
477 | if (unlikely(val & (1 << bit))) | 478 | if (unlikely(val & (1 << bit))) |
478 | return -1; | 479 | return -1; |
479 | 480 | ||
480 | val |= 1 << bit; | 481 | val |= 1 << bit; |
481 | current->trace_recursion = val; | 482 | current->trace_recursion = val; |
482 | barrier(); | 483 | barrier(); |
483 | 484 | ||
484 | return bit; | 485 | return bit; |
485 | } | 486 | } |
486 | 487 | ||
487 | static __always_inline void trace_clear_recursion(int bit) | 488 | static __always_inline void trace_clear_recursion(int bit) |
488 | { | 489 | { |
489 | unsigned int val = current->trace_recursion; | 490 | unsigned int val = current->trace_recursion; |
490 | 491 | ||
491 | if (!bit) | 492 | if (!bit) |
492 | return; | 493 | return; |
493 | 494 | ||
494 | bit = 1 << bit; | 495 | bit = 1 << bit; |
495 | val &= ~bit; | 496 | val &= ~bit; |
496 | 497 | ||
497 | barrier(); | 498 | barrier(); |
498 | current->trace_recursion = val; | 499 | current->trace_recursion = val; |
499 | } | 500 | } |
500 | 501 | ||
501 | static inline struct ring_buffer_iter * | 502 | static inline struct ring_buffer_iter * |
502 | trace_buffer_iter(struct trace_iterator *iter, int cpu) | 503 | trace_buffer_iter(struct trace_iterator *iter, int cpu) |
503 | { | 504 | { |
504 | if (iter->buffer_iter && iter->buffer_iter[cpu]) | 505 | if (iter->buffer_iter && iter->buffer_iter[cpu]) |
505 | return iter->buffer_iter[cpu]; | 506 | return iter->buffer_iter[cpu]; |
506 | return NULL; | 507 | return NULL; |
507 | } | 508 | } |
508 | 509 | ||
509 | int tracer_init(struct tracer *t, struct trace_array *tr); | 510 | int tracer_init(struct tracer *t, struct trace_array *tr); |
510 | int tracing_is_enabled(void); | 511 | int tracing_is_enabled(void); |
511 | void tracing_reset(struct trace_buffer *buf, int cpu); | 512 | void tracing_reset(struct trace_buffer *buf, int cpu); |
512 | void tracing_reset_online_cpus(struct trace_buffer *buf); | 513 | void tracing_reset_online_cpus(struct trace_buffer *buf); |
513 | void tracing_reset_current(int cpu); | 514 | void tracing_reset_current(int cpu); |
514 | void tracing_reset_all_online_cpus(void); | 515 | void tracing_reset_all_online_cpus(void); |
515 | int tracing_open_generic(struct inode *inode, struct file *filp); | 516 | int tracing_open_generic(struct inode *inode, struct file *filp); |
516 | struct dentry *trace_create_file(const char *name, | 517 | struct dentry *trace_create_file(const char *name, |
517 | umode_t mode, | 518 | umode_t mode, |
518 | struct dentry *parent, | 519 | struct dentry *parent, |
519 | void *data, | 520 | void *data, |
520 | const struct file_operations *fops); | 521 | const struct file_operations *fops); |
521 | 522 | ||
522 | struct dentry *tracing_init_dentry_tr(struct trace_array *tr); | 523 | struct dentry *tracing_init_dentry_tr(struct trace_array *tr); |
523 | struct dentry *tracing_init_dentry(void); | 524 | struct dentry *tracing_init_dentry(void); |
524 | 525 | ||
525 | struct ring_buffer_event; | 526 | struct ring_buffer_event; |
526 | 527 | ||
527 | struct ring_buffer_event * | 528 | struct ring_buffer_event * |
528 | trace_buffer_lock_reserve(struct ring_buffer *buffer, | 529 | trace_buffer_lock_reserve(struct ring_buffer *buffer, |
529 | int type, | 530 | int type, |
530 | unsigned long len, | 531 | unsigned long len, |
531 | unsigned long flags, | 532 | unsigned long flags, |
532 | int pc); | 533 | int pc); |
533 | 534 | ||
534 | struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, | 535 | struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, |
535 | struct trace_array_cpu *data); | 536 | struct trace_array_cpu *data); |
536 | 537 | ||
537 | struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, | 538 | struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, |
538 | int *ent_cpu, u64 *ent_ts); | 539 | int *ent_cpu, u64 *ent_ts); |
539 | 540 | ||
540 | void __buffer_unlock_commit(struct ring_buffer *buffer, | 541 | void __buffer_unlock_commit(struct ring_buffer *buffer, |
541 | struct ring_buffer_event *event); | 542 | struct ring_buffer_event *event); |
542 | 543 | ||
543 | int trace_empty(struct trace_iterator *iter); | 544 | int trace_empty(struct trace_iterator *iter); |
544 | 545 | ||
545 | void *trace_find_next_entry_inc(struct trace_iterator *iter); | 546 | void *trace_find_next_entry_inc(struct trace_iterator *iter); |
546 | 547 | ||
547 | void trace_init_global_iter(struct trace_iterator *iter); | 548 | void trace_init_global_iter(struct trace_iterator *iter); |
548 | 549 | ||
549 | void tracing_iter_reset(struct trace_iterator *iter, int cpu); | 550 | void tracing_iter_reset(struct trace_iterator *iter, int cpu); |
550 | 551 | ||
551 | void poll_wait_pipe(struct trace_iterator *iter); | 552 | void poll_wait_pipe(struct trace_iterator *iter); |
552 | 553 | ||
553 | void tracing_sched_switch_trace(struct trace_array *tr, | 554 | void tracing_sched_switch_trace(struct trace_array *tr, |
554 | struct task_struct *prev, | 555 | struct task_struct *prev, |
555 | struct task_struct *next, | 556 | struct task_struct *next, |
556 | unsigned long flags, int pc); | 557 | unsigned long flags, int pc); |
557 | 558 | ||
558 | void tracing_sched_wakeup_trace(struct trace_array *tr, | 559 | void tracing_sched_wakeup_trace(struct trace_array *tr, |
559 | struct task_struct *wakee, | 560 | struct task_struct *wakee, |
560 | struct task_struct *cur, | 561 | struct task_struct *cur, |
561 | unsigned long flags, int pc); | 562 | unsigned long flags, int pc); |
562 | void trace_function(struct trace_array *tr, | 563 | void trace_function(struct trace_array *tr, |
563 | unsigned long ip, | 564 | unsigned long ip, |
564 | unsigned long parent_ip, | 565 | unsigned long parent_ip, |
565 | unsigned long flags, int pc); | 566 | unsigned long flags, int pc); |
566 | void trace_graph_function(struct trace_array *tr, | 567 | void trace_graph_function(struct trace_array *tr, |
567 | unsigned long ip, | 568 | unsigned long ip, |
568 | unsigned long parent_ip, | 569 | unsigned long parent_ip, |
569 | unsigned long flags, int pc); | 570 | unsigned long flags, int pc); |
570 | void trace_latency_header(struct seq_file *m); | 571 | void trace_latency_header(struct seq_file *m); |
571 | void trace_default_header(struct seq_file *m); | 572 | void trace_default_header(struct seq_file *m); |
572 | void print_trace_header(struct seq_file *m, struct trace_iterator *iter); | 573 | void print_trace_header(struct seq_file *m, struct trace_iterator *iter); |
573 | int trace_empty(struct trace_iterator *iter); | 574 | int trace_empty(struct trace_iterator *iter); |
574 | 575 | ||
575 | void trace_graph_return(struct ftrace_graph_ret *trace); | 576 | void trace_graph_return(struct ftrace_graph_ret *trace); |
576 | int trace_graph_entry(struct ftrace_graph_ent *trace); | 577 | int trace_graph_entry(struct ftrace_graph_ent *trace); |
577 | void set_graph_array(struct trace_array *tr); | 578 | void set_graph_array(struct trace_array *tr); |
578 | 579 | ||
579 | void tracing_start_cmdline_record(void); | 580 | void tracing_start_cmdline_record(void); |
580 | void tracing_stop_cmdline_record(void); | 581 | void tracing_stop_cmdline_record(void); |
581 | void tracing_sched_switch_assign_trace(struct trace_array *tr); | 582 | void tracing_sched_switch_assign_trace(struct trace_array *tr); |
582 | void tracing_stop_sched_switch_record(void); | 583 | void tracing_stop_sched_switch_record(void); |
583 | void tracing_start_sched_switch_record(void); | 584 | void tracing_start_sched_switch_record(void); |
584 | int register_tracer(struct tracer *type); | 585 | int register_tracer(struct tracer *type); |
585 | int is_tracing_stopped(void); | 586 | int is_tracing_stopped(void); |
586 | 587 | ||
587 | extern cpumask_var_t __read_mostly tracing_buffer_mask; | 588 | extern cpumask_var_t __read_mostly tracing_buffer_mask; |
588 | 589 | ||
589 | #define for_each_tracing_cpu(cpu) \ | 590 | #define for_each_tracing_cpu(cpu) \ |
590 | for_each_cpu(cpu, tracing_buffer_mask) | 591 | for_each_cpu(cpu, tracing_buffer_mask) |
591 | 592 | ||
592 | extern unsigned long nsecs_to_usecs(unsigned long nsecs); | 593 | extern unsigned long nsecs_to_usecs(unsigned long nsecs); |
593 | 594 | ||
594 | extern unsigned long tracing_thresh; | 595 | extern unsigned long tracing_thresh; |
595 | 596 | ||
596 | #ifdef CONFIG_TRACER_MAX_TRACE | 597 | #ifdef CONFIG_TRACER_MAX_TRACE |
597 | extern unsigned long tracing_max_latency; | 598 | extern unsigned long tracing_max_latency; |
598 | 599 | ||
599 | void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); | 600 | void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); |
600 | void update_max_tr_single(struct trace_array *tr, | 601 | void update_max_tr_single(struct trace_array *tr, |
601 | struct task_struct *tsk, int cpu); | 602 | struct task_struct *tsk, int cpu); |
602 | #endif /* CONFIG_TRACER_MAX_TRACE */ | 603 | #endif /* CONFIG_TRACER_MAX_TRACE */ |
603 | 604 | ||
604 | #ifdef CONFIG_STACKTRACE | 605 | #ifdef CONFIG_STACKTRACE |
605 | void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags, | 606 | void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags, |
606 | int skip, int pc); | 607 | int skip, int pc); |
607 | 608 | ||
608 | void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags, | 609 | void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags, |
609 | int skip, int pc, struct pt_regs *regs); | 610 | int skip, int pc, struct pt_regs *regs); |
610 | 611 | ||
611 | void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, | 612 | void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, |
612 | int pc); | 613 | int pc); |
613 | 614 | ||
614 | void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, | 615 | void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, |
615 | int pc); | 616 | int pc); |
616 | #else | 617 | #else |
617 | static inline void ftrace_trace_stack(struct ring_buffer *buffer, | 618 | static inline void ftrace_trace_stack(struct ring_buffer *buffer, |
618 | unsigned long flags, int skip, int pc) | 619 | unsigned long flags, int skip, int pc) |
619 | { | 620 | { |
620 | } | 621 | } |
621 | 622 | ||
622 | static inline void ftrace_trace_stack_regs(struct ring_buffer *buffer, | 623 | static inline void ftrace_trace_stack_regs(struct ring_buffer *buffer, |
623 | unsigned long flags, int skip, | 624 | unsigned long flags, int skip, |
624 | int pc, struct pt_regs *regs) | 625 | int pc, struct pt_regs *regs) |
625 | { | 626 | { |
626 | } | 627 | } |
627 | 628 | ||
628 | static inline void ftrace_trace_userstack(struct ring_buffer *buffer, | 629 | static inline void ftrace_trace_userstack(struct ring_buffer *buffer, |
629 | unsigned long flags, int pc) | 630 | unsigned long flags, int pc) |
630 | { | 631 | { |
631 | } | 632 | } |
632 | 633 | ||
633 | static inline void __trace_stack(struct trace_array *tr, unsigned long flags, | 634 | static inline void __trace_stack(struct trace_array *tr, unsigned long flags, |
634 | int skip, int pc) | 635 | int skip, int pc) |
635 | { | 636 | { |
636 | } | 637 | } |
637 | #endif /* CONFIG_STACKTRACE */ | 638 | #endif /* CONFIG_STACKTRACE */ |
638 | 639 | ||
639 | extern cycle_t ftrace_now(int cpu); | 640 | extern cycle_t ftrace_now(int cpu); |
640 | 641 | ||
641 | extern void trace_find_cmdline(int pid, char comm[]); | 642 | extern void trace_find_cmdline(int pid, char comm[]); |
642 | 643 | ||
643 | #ifdef CONFIG_DYNAMIC_FTRACE | 644 | #ifdef CONFIG_DYNAMIC_FTRACE |
644 | extern unsigned long ftrace_update_tot_cnt; | 645 | extern unsigned long ftrace_update_tot_cnt; |
645 | #endif | 646 | #endif |
646 | #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func | 647 | #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func |
647 | extern int DYN_FTRACE_TEST_NAME(void); | 648 | extern int DYN_FTRACE_TEST_NAME(void); |
648 | #define DYN_FTRACE_TEST_NAME2 trace_selftest_dynamic_test_func2 | 649 | #define DYN_FTRACE_TEST_NAME2 trace_selftest_dynamic_test_func2 |
649 | extern int DYN_FTRACE_TEST_NAME2(void); | 650 | extern int DYN_FTRACE_TEST_NAME2(void); |
650 | 651 | ||
651 | extern bool ring_buffer_expanded; | 652 | extern bool ring_buffer_expanded; |
652 | extern bool tracing_selftest_disabled; | 653 | extern bool tracing_selftest_disabled; |
653 | DECLARE_PER_CPU(int, ftrace_cpu_disabled); | 654 | DECLARE_PER_CPU(int, ftrace_cpu_disabled); |
654 | 655 | ||
655 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 656 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
656 | extern int trace_selftest_startup_function(struct tracer *trace, | 657 | extern int trace_selftest_startup_function(struct tracer *trace, |
657 | struct trace_array *tr); | 658 | struct trace_array *tr); |
658 | extern int trace_selftest_startup_function_graph(struct tracer *trace, | 659 | extern int trace_selftest_startup_function_graph(struct tracer *trace, |
659 | struct trace_array *tr); | 660 | struct trace_array *tr); |
660 | extern int trace_selftest_startup_irqsoff(struct tracer *trace, | 661 | extern int trace_selftest_startup_irqsoff(struct tracer *trace, |
661 | struct trace_array *tr); | 662 | struct trace_array *tr); |
662 | extern int trace_selftest_startup_preemptoff(struct tracer *trace, | 663 | extern int trace_selftest_startup_preemptoff(struct tracer *trace, |
663 | struct trace_array *tr); | 664 | struct trace_array *tr); |
664 | extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace, | 665 | extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace, |
665 | struct trace_array *tr); | 666 | struct trace_array *tr); |
666 | extern int trace_selftest_startup_wakeup(struct tracer *trace, | 667 | extern int trace_selftest_startup_wakeup(struct tracer *trace, |
667 | struct trace_array *tr); | 668 | struct trace_array *tr); |
668 | extern int trace_selftest_startup_nop(struct tracer *trace, | 669 | extern int trace_selftest_startup_nop(struct tracer *trace, |
669 | struct trace_array *tr); | 670 | struct trace_array *tr); |
670 | extern int trace_selftest_startup_sched_switch(struct tracer *trace, | 671 | extern int trace_selftest_startup_sched_switch(struct tracer *trace, |
671 | struct trace_array *tr); | 672 | struct trace_array *tr); |
672 | extern int trace_selftest_startup_branch(struct tracer *trace, | 673 | extern int trace_selftest_startup_branch(struct tracer *trace, |
673 | struct trace_array *tr); | 674 | struct trace_array *tr); |
674 | /* | 675 | /* |
675 | * Tracer data references selftest functions that only occur | 676 | * Tracer data references selftest functions that only occur |
676 | * on boot up. These can be __init functions. Thus, when selftests | 677 | * on boot up. These can be __init functions. Thus, when selftests |
677 | * are enabled, then the tracers need to reference __init functions. | 678 | * are enabled, then the tracers need to reference __init functions. |
678 | */ | 679 | */ |
679 | #define __tracer_data __refdata | 680 | #define __tracer_data __refdata |
680 | #else | 681 | #else |
681 | /* Tracers are seldom changed. Optimize when selftests are disabled. */ | 682 | /* Tracers are seldom changed. Optimize when selftests are disabled. */ |
682 | #define __tracer_data __read_mostly | 683 | #define __tracer_data __read_mostly |
683 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ | 684 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ |
684 | 685 | ||
685 | extern void *head_page(struct trace_array_cpu *data); | 686 | extern void *head_page(struct trace_array_cpu *data); |
686 | extern unsigned long long ns2usecs(cycle_t nsec); | 687 | extern unsigned long long ns2usecs(cycle_t nsec); |
687 | extern int | 688 | extern int |
688 | trace_vbprintk(unsigned long ip, const char *fmt, va_list args); | 689 | trace_vbprintk(unsigned long ip, const char *fmt, va_list args); |
689 | extern int | 690 | extern int |
690 | trace_vprintk(unsigned long ip, const char *fmt, va_list args); | 691 | trace_vprintk(unsigned long ip, const char *fmt, va_list args); |
691 | extern int | 692 | extern int |
692 | trace_array_vprintk(struct trace_array *tr, | 693 | trace_array_vprintk(struct trace_array *tr, |
693 | unsigned long ip, const char *fmt, va_list args); | 694 | unsigned long ip, const char *fmt, va_list args); |
694 | int trace_array_printk(struct trace_array *tr, | 695 | int trace_array_printk(struct trace_array *tr, |
695 | unsigned long ip, const char *fmt, ...); | 696 | unsigned long ip, const char *fmt, ...); |
696 | int trace_array_printk_buf(struct ring_buffer *buffer, | 697 | int trace_array_printk_buf(struct ring_buffer *buffer, |
697 | unsigned long ip, const char *fmt, ...); | 698 | unsigned long ip, const char *fmt, ...); |
698 | void trace_printk_seq(struct trace_seq *s); | 699 | void trace_printk_seq(struct trace_seq *s); |
699 | enum print_line_t print_trace_line(struct trace_iterator *iter); | 700 | enum print_line_t print_trace_line(struct trace_iterator *iter); |
700 | 701 | ||
701 | extern unsigned long trace_flags; | 702 | extern unsigned long trace_flags; |
702 | 703 | ||
703 | /* Standard output formatting function used for function return traces */ | 704 | /* Standard output formatting function used for function return traces */ |
704 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 705 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
705 | 706 | ||
706 | /* Flag options */ | 707 | /* Flag options */ |
707 | #define TRACE_GRAPH_PRINT_OVERRUN 0x1 | 708 | #define TRACE_GRAPH_PRINT_OVERRUN 0x1 |
708 | #define TRACE_GRAPH_PRINT_CPU 0x2 | 709 | #define TRACE_GRAPH_PRINT_CPU 0x2 |
709 | #define TRACE_GRAPH_PRINT_OVERHEAD 0x4 | 710 | #define TRACE_GRAPH_PRINT_OVERHEAD 0x4 |
710 | #define TRACE_GRAPH_PRINT_PROC 0x8 | 711 | #define TRACE_GRAPH_PRINT_PROC 0x8 |
711 | #define TRACE_GRAPH_PRINT_DURATION 0x10 | 712 | #define TRACE_GRAPH_PRINT_DURATION 0x10 |
712 | #define TRACE_GRAPH_PRINT_ABS_TIME 0x20 | 713 | #define TRACE_GRAPH_PRINT_ABS_TIME 0x20 |
713 | 714 | ||
714 | extern enum print_line_t | 715 | extern enum print_line_t |
715 | print_graph_function_flags(struct trace_iterator *iter, u32 flags); | 716 | print_graph_function_flags(struct trace_iterator *iter, u32 flags); |
716 | extern void print_graph_headers_flags(struct seq_file *s, u32 flags); | 717 | extern void print_graph_headers_flags(struct seq_file *s, u32 flags); |
717 | extern enum print_line_t | 718 | extern enum print_line_t |
718 | trace_print_graph_duration(unsigned long long duration, struct trace_seq *s); | 719 | trace_print_graph_duration(unsigned long long duration, struct trace_seq *s); |
719 | extern void graph_trace_open(struct trace_iterator *iter); | 720 | extern void graph_trace_open(struct trace_iterator *iter); |
720 | extern void graph_trace_close(struct trace_iterator *iter); | 721 | extern void graph_trace_close(struct trace_iterator *iter); |
721 | extern int __trace_graph_entry(struct trace_array *tr, | 722 | extern int __trace_graph_entry(struct trace_array *tr, |
722 | struct ftrace_graph_ent *trace, | 723 | struct ftrace_graph_ent *trace, |
723 | unsigned long flags, int pc); | 724 | unsigned long flags, int pc); |
724 | extern void __trace_graph_return(struct trace_array *tr, | 725 | extern void __trace_graph_return(struct trace_array *tr, |
725 | struct ftrace_graph_ret *trace, | 726 | struct ftrace_graph_ret *trace, |
726 | unsigned long flags, int pc); | 727 | unsigned long flags, int pc); |
727 | 728 | ||
728 | 729 | ||
729 | #ifdef CONFIG_DYNAMIC_FTRACE | 730 | #ifdef CONFIG_DYNAMIC_FTRACE |
730 | /* TODO: make this variable */ | 731 | /* TODO: make this variable */ |
731 | #define FTRACE_GRAPH_MAX_FUNCS 32 | 732 | #define FTRACE_GRAPH_MAX_FUNCS 32 |
732 | extern int ftrace_graph_filter_enabled; | 733 | extern int ftrace_graph_filter_enabled; |
733 | extern int ftrace_graph_count; | 734 | extern int ftrace_graph_count; |
734 | extern unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS]; | 735 | extern unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS]; |
735 | 736 | ||
736 | static inline int ftrace_graph_addr(unsigned long addr) | 737 | static inline int ftrace_graph_addr(unsigned long addr) |
737 | { | 738 | { |
738 | int i; | 739 | int i; |
739 | 740 | ||
740 | if (!ftrace_graph_filter_enabled) | 741 | if (!ftrace_graph_filter_enabled) |
741 | return 1; | 742 | return 1; |
742 | 743 | ||
743 | for (i = 0; i < ftrace_graph_count; i++) { | 744 | for (i = 0; i < ftrace_graph_count; i++) { |
744 | if (addr == ftrace_graph_funcs[i]) { | 745 | if (addr == ftrace_graph_funcs[i]) { |
745 | /* | 746 | /* |
746 | * If no irqs are to be traced, but a set_graph_function | 747 | * If no irqs are to be traced, but a set_graph_function |
747 | * is set, and called by an interrupt handler, we still | 748 | * is set, and called by an interrupt handler, we still |
748 | * want to trace it. | 749 | * want to trace it. |
749 | */ | 750 | */ |
750 | if (in_irq()) | 751 | if (in_irq()) |
751 | trace_recursion_set(TRACE_IRQ_BIT); | 752 | trace_recursion_set(TRACE_IRQ_BIT); |
752 | else | 753 | else |
753 | trace_recursion_clear(TRACE_IRQ_BIT); | 754 | trace_recursion_clear(TRACE_IRQ_BIT); |
754 | return 1; | 755 | return 1; |
755 | } | 756 | } |
756 | } | 757 | } |
757 | 758 | ||
758 | return 0; | 759 | return 0; |
759 | } | 760 | } |
760 | #else | 761 | #else |
761 | static inline int ftrace_graph_addr(unsigned long addr) | 762 | static inline int ftrace_graph_addr(unsigned long addr) |
762 | { | 763 | { |
763 | return 1; | 764 | return 1; |
764 | } | 765 | } |
765 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 766 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
766 | #else /* CONFIG_FUNCTION_GRAPH_TRACER */ | 767 | #else /* CONFIG_FUNCTION_GRAPH_TRACER */ |
767 | static inline enum print_line_t | 768 | static inline enum print_line_t |
768 | print_graph_function_flags(struct trace_iterator *iter, u32 flags) | 769 | print_graph_function_flags(struct trace_iterator *iter, u32 flags) |
769 | { | 770 | { |
770 | return TRACE_TYPE_UNHANDLED; | 771 | return TRACE_TYPE_UNHANDLED; |
771 | } | 772 | } |
772 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 773 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
773 | 774 | ||
774 | extern struct list_head ftrace_pids; | 775 | extern struct list_head ftrace_pids; |
775 | 776 | ||
776 | #ifdef CONFIG_FUNCTION_TRACER | 777 | #ifdef CONFIG_FUNCTION_TRACER |
777 | extern bool ftrace_filter_param __initdata; | 778 | extern bool ftrace_filter_param __initdata; |
778 | static inline int ftrace_trace_task(struct task_struct *task) | 779 | static inline int ftrace_trace_task(struct task_struct *task) |
779 | { | 780 | { |
780 | if (list_empty(&ftrace_pids)) | 781 | if (list_empty(&ftrace_pids)) |
781 | return 1; | 782 | return 1; |
782 | 783 | ||
783 | return test_tsk_trace_trace(task); | 784 | return test_tsk_trace_trace(task); |
784 | } | 785 | } |
785 | extern int ftrace_is_dead(void); | 786 | extern int ftrace_is_dead(void); |
786 | #else | 787 | #else |
787 | static inline int ftrace_trace_task(struct task_struct *task) | 788 | static inline int ftrace_trace_task(struct task_struct *task) |
788 | { | 789 | { |
789 | return 1; | 790 | return 1; |
790 | } | 791 | } |
791 | static inline int ftrace_is_dead(void) { return 0; } | 792 | static inline int ftrace_is_dead(void) { return 0; } |
792 | #endif | 793 | #endif |
793 | 794 | ||
794 | int ftrace_event_is_function(struct ftrace_event_call *call); | 795 | int ftrace_event_is_function(struct ftrace_event_call *call); |
795 | 796 | ||
796 | /* | 797 | /* |
797 | * struct trace_parser - servers for reading the user input separated by spaces | 798 | * struct trace_parser - servers for reading the user input separated by spaces |
798 | * @cont: set if the input is not complete - no final space char was found | 799 | * @cont: set if the input is not complete - no final space char was found |
799 | * @buffer: holds the parsed user input | 800 | * @buffer: holds the parsed user input |
800 | * @idx: user input length | 801 | * @idx: user input length |
801 | * @size: buffer size | 802 | * @size: buffer size |
802 | */ | 803 | */ |
803 | struct trace_parser { | 804 | struct trace_parser { |
804 | bool cont; | 805 | bool cont; |
805 | char *buffer; | 806 | char *buffer; |
806 | unsigned idx; | 807 | unsigned idx; |
807 | unsigned size; | 808 | unsigned size; |
808 | }; | 809 | }; |
809 | 810 | ||
810 | static inline bool trace_parser_loaded(struct trace_parser *parser) | 811 | static inline bool trace_parser_loaded(struct trace_parser *parser) |
811 | { | 812 | { |
812 | return (parser->idx != 0); | 813 | return (parser->idx != 0); |
813 | } | 814 | } |
814 | 815 | ||
815 | static inline bool trace_parser_cont(struct trace_parser *parser) | 816 | static inline bool trace_parser_cont(struct trace_parser *parser) |
816 | { | 817 | { |
817 | return parser->cont; | 818 | return parser->cont; |
818 | } | 819 | } |
819 | 820 | ||
820 | static inline void trace_parser_clear(struct trace_parser *parser) | 821 | static inline void trace_parser_clear(struct trace_parser *parser) |
821 | { | 822 | { |
822 | parser->cont = false; | 823 | parser->cont = false; |
823 | parser->idx = 0; | 824 | parser->idx = 0; |
824 | } | 825 | } |
825 | 826 | ||
826 | extern int trace_parser_get_init(struct trace_parser *parser, int size); | 827 | extern int trace_parser_get_init(struct trace_parser *parser, int size); |
827 | extern void trace_parser_put(struct trace_parser *parser); | 828 | extern void trace_parser_put(struct trace_parser *parser); |
828 | extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, | 829 | extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, |
829 | size_t cnt, loff_t *ppos); | 830 | size_t cnt, loff_t *ppos); |
830 | 831 | ||
831 | /* | 832 | /* |
832 | * trace_iterator_flags is an enumeration that defines bit | 833 | * trace_iterator_flags is an enumeration that defines bit |
833 | * positions into trace_flags that controls the output. | 834 | * positions into trace_flags that controls the output. |
834 | * | 835 | * |
835 | * NOTE: These bits must match the trace_options array in | 836 | * NOTE: These bits must match the trace_options array in |
836 | * trace.c. | 837 | * trace.c. |
837 | */ | 838 | */ |
838 | enum trace_iterator_flags { | 839 | enum trace_iterator_flags { |
839 | TRACE_ITER_PRINT_PARENT = 0x01, | 840 | TRACE_ITER_PRINT_PARENT = 0x01, |
840 | TRACE_ITER_SYM_OFFSET = 0x02, | 841 | TRACE_ITER_SYM_OFFSET = 0x02, |
841 | TRACE_ITER_SYM_ADDR = 0x04, | 842 | TRACE_ITER_SYM_ADDR = 0x04, |
842 | TRACE_ITER_VERBOSE = 0x08, | 843 | TRACE_ITER_VERBOSE = 0x08, |
843 | TRACE_ITER_RAW = 0x10, | 844 | TRACE_ITER_RAW = 0x10, |
844 | TRACE_ITER_HEX = 0x20, | 845 | TRACE_ITER_HEX = 0x20, |
845 | TRACE_ITER_BIN = 0x40, | 846 | TRACE_ITER_BIN = 0x40, |
846 | TRACE_ITER_BLOCK = 0x80, | 847 | TRACE_ITER_BLOCK = 0x80, |
847 | TRACE_ITER_STACKTRACE = 0x100, | 848 | TRACE_ITER_STACKTRACE = 0x100, |
848 | TRACE_ITER_PRINTK = 0x200, | 849 | TRACE_ITER_PRINTK = 0x200, |
849 | TRACE_ITER_PREEMPTONLY = 0x400, | 850 | TRACE_ITER_PREEMPTONLY = 0x400, |
850 | TRACE_ITER_BRANCH = 0x800, | 851 | TRACE_ITER_BRANCH = 0x800, |
851 | TRACE_ITER_ANNOTATE = 0x1000, | 852 | TRACE_ITER_ANNOTATE = 0x1000, |
852 | TRACE_ITER_USERSTACKTRACE = 0x2000, | 853 | TRACE_ITER_USERSTACKTRACE = 0x2000, |
853 | TRACE_ITER_SYM_USEROBJ = 0x4000, | 854 | TRACE_ITER_SYM_USEROBJ = 0x4000, |
854 | TRACE_ITER_PRINTK_MSGONLY = 0x8000, | 855 | TRACE_ITER_PRINTK_MSGONLY = 0x8000, |
855 | TRACE_ITER_CONTEXT_INFO = 0x10000, /* Print pid/cpu/time */ | 856 | TRACE_ITER_CONTEXT_INFO = 0x10000, /* Print pid/cpu/time */ |
856 | TRACE_ITER_LATENCY_FMT = 0x20000, | 857 | TRACE_ITER_LATENCY_FMT = 0x20000, |
857 | TRACE_ITER_SLEEP_TIME = 0x40000, | 858 | TRACE_ITER_SLEEP_TIME = 0x40000, |
858 | TRACE_ITER_GRAPH_TIME = 0x80000, | 859 | TRACE_ITER_GRAPH_TIME = 0x80000, |
859 | TRACE_ITER_RECORD_CMD = 0x100000, | 860 | TRACE_ITER_RECORD_CMD = 0x100000, |
860 | TRACE_ITER_OVERWRITE = 0x200000, | 861 | TRACE_ITER_OVERWRITE = 0x200000, |
861 | TRACE_ITER_STOP_ON_FREE = 0x400000, | 862 | TRACE_ITER_STOP_ON_FREE = 0x400000, |
862 | TRACE_ITER_IRQ_INFO = 0x800000, | 863 | TRACE_ITER_IRQ_INFO = 0x800000, |
863 | TRACE_ITER_MARKERS = 0x1000000, | 864 | TRACE_ITER_MARKERS = 0x1000000, |
864 | TRACE_ITER_FUNCTION = 0x2000000, | 865 | TRACE_ITER_FUNCTION = 0x2000000, |
865 | }; | 866 | }; |
866 | 867 | ||
867 | /* | 868 | /* |
868 | * TRACE_ITER_SYM_MASK masks the options in trace_flags that | 869 | * TRACE_ITER_SYM_MASK masks the options in trace_flags that |
869 | * control the output of kernel symbols. | 870 | * control the output of kernel symbols. |
870 | */ | 871 | */ |
871 | #define TRACE_ITER_SYM_MASK \ | 872 | #define TRACE_ITER_SYM_MASK \ |
872 | (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) | 873 | (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) |
873 | 874 | ||
874 | extern struct tracer nop_trace; | 875 | extern struct tracer nop_trace; |
875 | 876 | ||
876 | #ifdef CONFIG_BRANCH_TRACER | 877 | #ifdef CONFIG_BRANCH_TRACER |
877 | extern int enable_branch_tracing(struct trace_array *tr); | 878 | extern int enable_branch_tracing(struct trace_array *tr); |
878 | extern void disable_branch_tracing(void); | 879 | extern void disable_branch_tracing(void); |
879 | static inline int trace_branch_enable(struct trace_array *tr) | 880 | static inline int trace_branch_enable(struct trace_array *tr) |
880 | { | 881 | { |
881 | if (trace_flags & TRACE_ITER_BRANCH) | 882 | if (trace_flags & TRACE_ITER_BRANCH) |
882 | return enable_branch_tracing(tr); | 883 | return enable_branch_tracing(tr); |
883 | return 0; | 884 | return 0; |
884 | } | 885 | } |
885 | static inline void trace_branch_disable(void) | 886 | static inline void trace_branch_disable(void) |
886 | { | 887 | { |
887 | /* due to races, always disable */ | 888 | /* due to races, always disable */ |
888 | disable_branch_tracing(); | 889 | disable_branch_tracing(); |
889 | } | 890 | } |
890 | #else | 891 | #else |
891 | static inline int trace_branch_enable(struct trace_array *tr) | 892 | static inline int trace_branch_enable(struct trace_array *tr) |
892 | { | 893 | { |
893 | return 0; | 894 | return 0; |
894 | } | 895 | } |
895 | static inline void trace_branch_disable(void) | 896 | static inline void trace_branch_disable(void) |
896 | { | 897 | { |
897 | } | 898 | } |
898 | #endif /* CONFIG_BRANCH_TRACER */ | 899 | #endif /* CONFIG_BRANCH_TRACER */ |
899 | 900 | ||
900 | /* set ring buffers to default size if not already done so */ | 901 | /* set ring buffers to default size if not already done so */ |
901 | int tracing_update_buffers(void); | 902 | int tracing_update_buffers(void); |
902 | 903 | ||
903 | struct ftrace_event_field { | 904 | struct ftrace_event_field { |
904 | struct list_head link; | 905 | struct list_head link; |
905 | const char *name; | 906 | const char *name; |
906 | const char *type; | 907 | const char *type; |
907 | int filter_type; | 908 | int filter_type; |
908 | int offset; | 909 | int offset; |
909 | int size; | 910 | int size; |
910 | int is_signed; | 911 | int is_signed; |
911 | }; | 912 | }; |
912 | 913 | ||
913 | struct event_filter { | 914 | struct event_filter { |
914 | int n_preds; /* Number assigned */ | 915 | int n_preds; /* Number assigned */ |
915 | int a_preds; /* allocated */ | 916 | int a_preds; /* allocated */ |
916 | struct filter_pred *preds; | 917 | struct filter_pred *preds; |
917 | struct filter_pred *root; | 918 | struct filter_pred *root; |
918 | char *filter_string; | 919 | char *filter_string; |
919 | }; | 920 | }; |
920 | 921 | ||
921 | struct event_subsystem { | 922 | struct event_subsystem { |
922 | struct list_head list; | 923 | struct list_head list; |
923 | const char *name; | 924 | const char *name; |
924 | struct event_filter *filter; | 925 | struct event_filter *filter; |
925 | int ref_count; | 926 | int ref_count; |
926 | }; | 927 | }; |
927 | 928 | ||
928 | struct ftrace_subsystem_dir { | 929 | struct ftrace_subsystem_dir { |
929 | struct list_head list; | 930 | struct list_head list; |
930 | struct event_subsystem *subsystem; | 931 | struct event_subsystem *subsystem; |
931 | struct trace_array *tr; | 932 | struct trace_array *tr; |
932 | struct dentry *entry; | 933 | struct dentry *entry; |
933 | int ref_count; | 934 | int ref_count; |
934 | int nr_events; | 935 | int nr_events; |
935 | }; | 936 | }; |
936 | 937 | ||
937 | #define FILTER_PRED_INVALID ((unsigned short)-1) | 938 | #define FILTER_PRED_INVALID ((unsigned short)-1) |
938 | #define FILTER_PRED_IS_RIGHT (1 << 15) | 939 | #define FILTER_PRED_IS_RIGHT (1 << 15) |
939 | #define FILTER_PRED_FOLD (1 << 15) | 940 | #define FILTER_PRED_FOLD (1 << 15) |
940 | 941 | ||
941 | /* | 942 | /* |
942 | * The max preds is the size of unsigned short with | 943 | * The max preds is the size of unsigned short with |
943 | * two flags at the MSBs. One bit is used for both the IS_RIGHT | 944 | * two flags at the MSBs. One bit is used for both the IS_RIGHT |
944 | * and FOLD flags. The other is reserved. | 945 | * and FOLD flags. The other is reserved. |
945 | * | 946 | * |
946 | * 2^14 preds is way more than enough. | 947 | * 2^14 preds is way more than enough. |
947 | */ | 948 | */ |
948 | #define MAX_FILTER_PRED 16384 | 949 | #define MAX_FILTER_PRED 16384 |
949 | 950 | ||
950 | struct filter_pred; | 951 | struct filter_pred; |
951 | struct regex; | 952 | struct regex; |
952 | 953 | ||
953 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); | 954 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); |
954 | 955 | ||
955 | typedef int (*regex_match_func)(char *str, struct regex *r, int len); | 956 | typedef int (*regex_match_func)(char *str, struct regex *r, int len); |
956 | 957 | ||
957 | enum regex_type { | 958 | enum regex_type { |
958 | MATCH_FULL = 0, | 959 | MATCH_FULL = 0, |
959 | MATCH_FRONT_ONLY, | 960 | MATCH_FRONT_ONLY, |
960 | MATCH_MIDDLE_ONLY, | 961 | MATCH_MIDDLE_ONLY, |
961 | MATCH_END_ONLY, | 962 | MATCH_END_ONLY, |
962 | }; | 963 | }; |
963 | 964 | ||
964 | struct regex { | 965 | struct regex { |
965 | char pattern[MAX_FILTER_STR_VAL]; | 966 | char pattern[MAX_FILTER_STR_VAL]; |
966 | int len; | 967 | int len; |
967 | int field_len; | 968 | int field_len; |
968 | regex_match_func match; | 969 | regex_match_func match; |
969 | }; | 970 | }; |
970 | 971 | ||
971 | struct filter_pred { | 972 | struct filter_pred { |
972 | filter_pred_fn_t fn; | 973 | filter_pred_fn_t fn; |
973 | u64 val; | 974 | u64 val; |
974 | struct regex regex; | 975 | struct regex regex; |
975 | unsigned short *ops; | 976 | unsigned short *ops; |
976 | struct ftrace_event_field *field; | 977 | struct ftrace_event_field *field; |
977 | int offset; | 978 | int offset; |
978 | int not; | 979 | int not; |
979 | int op; | 980 | int op; |
980 | unsigned short index; | 981 | unsigned short index; |
981 | unsigned short parent; | 982 | unsigned short parent; |
982 | unsigned short left; | 983 | unsigned short left; |
983 | unsigned short right; | 984 | unsigned short right; |
984 | }; | 985 | }; |
985 | 986 | ||
986 | extern enum regex_type | 987 | extern enum regex_type |
987 | filter_parse_regex(char *buff, int len, char **search, int *not); | 988 | filter_parse_regex(char *buff, int len, char **search, int *not); |
988 | extern void print_event_filter(struct ftrace_event_call *call, | 989 | extern void print_event_filter(struct ftrace_event_call *call, |
989 | struct trace_seq *s); | 990 | struct trace_seq *s); |
990 | extern int apply_event_filter(struct ftrace_event_call *call, | 991 | extern int apply_event_filter(struct ftrace_event_call *call, |
991 | char *filter_string); | 992 | char *filter_string); |
992 | extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir, | 993 | extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir, |
993 | char *filter_string); | 994 | char *filter_string); |
994 | extern void print_subsystem_event_filter(struct event_subsystem *system, | 995 | extern void print_subsystem_event_filter(struct event_subsystem *system, |
995 | struct trace_seq *s); | 996 | struct trace_seq *s); |
996 | extern int filter_assign_type(const char *type); | 997 | extern int filter_assign_type(const char *type); |
997 | 998 | ||
998 | struct ftrace_event_field * | 999 | struct ftrace_event_field * |
999 | trace_find_event_field(struct ftrace_event_call *call, char *name); | 1000 | trace_find_event_field(struct ftrace_event_call *call, char *name); |
1000 | 1001 | ||
1001 | static inline int | 1002 | static inline int |
1002 | filter_check_discard(struct ftrace_event_call *call, void *rec, | 1003 | filter_check_discard(struct ftrace_event_call *call, void *rec, |
1003 | struct ring_buffer *buffer, | 1004 | struct ring_buffer *buffer, |
1004 | struct ring_buffer_event *event) | 1005 | struct ring_buffer_event *event) |
1005 | { | 1006 | { |
1006 | if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) && | 1007 | if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) && |
1007 | !filter_match_preds(call->filter, rec)) { | 1008 | !filter_match_preds(call->filter, rec)) { |
1008 | ring_buffer_discard_commit(buffer, event); | 1009 | ring_buffer_discard_commit(buffer, event); |
1009 | return 1; | 1010 | return 1; |
1010 | } | 1011 | } |
1011 | 1012 | ||
1012 | return 0; | 1013 | return 0; |
1013 | } | 1014 | } |
1014 | 1015 | ||
1015 | extern void trace_event_enable_cmd_record(bool enable); | 1016 | extern void trace_event_enable_cmd_record(bool enable); |
1016 | extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); | 1017 | extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); |
1017 | extern int event_trace_del_tracer(struct trace_array *tr); | 1018 | extern int event_trace_del_tracer(struct trace_array *tr); |
1018 | 1019 | ||
1019 | extern struct mutex event_mutex; | 1020 | extern struct mutex event_mutex; |
1020 | extern struct list_head ftrace_events; | 1021 | extern struct list_head ftrace_events; |
1021 | 1022 | ||
1022 | extern const char *__start___trace_bprintk_fmt[]; | 1023 | extern const char *__start___trace_bprintk_fmt[]; |
1023 | extern const char *__stop___trace_bprintk_fmt[]; | 1024 | extern const char *__stop___trace_bprintk_fmt[]; |
1024 | 1025 | ||
1025 | extern const char *__start___tracepoint_str[]; | 1026 | extern const char *__start___tracepoint_str[]; |
1026 | extern const char *__stop___tracepoint_str[]; | 1027 | extern const char *__stop___tracepoint_str[]; |
1027 | 1028 | ||
1028 | void trace_printk_init_buffers(void); | 1029 | void trace_printk_init_buffers(void); |
1029 | void trace_printk_start_comm(void); | 1030 | void trace_printk_start_comm(void); |
1030 | int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set); | 1031 | int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set); |
1031 | int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled); | 1032 | int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled); |
1032 | 1033 | ||
1033 | /* | 1034 | /* |
1034 | * Normal trace_printk() and friends allocates special buffers | 1035 | * Normal trace_printk() and friends allocates special buffers |
1035 | * to do the manipulation, as well as saves the print formats | 1036 | * to do the manipulation, as well as saves the print formats |
1036 | * into sections to display. But the trace infrastructure wants | 1037 | * into sections to display. But the trace infrastructure wants |
1037 | * to use these without the added overhead at the price of being | 1038 | * to use these without the added overhead at the price of being |
1038 | * a bit slower (used mainly for warnings, where we don't care | 1039 | * a bit slower (used mainly for warnings, where we don't care |
1039 | * about performance). The internal_trace_puts() is for such | 1040 | * about performance). The internal_trace_puts() is for such |
1040 | * a purpose. | 1041 | * a purpose. |
1041 | */ | 1042 | */ |
1042 | #define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str)) | 1043 | #define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str)) |
1043 | 1044 | ||
1044 | #undef FTRACE_ENTRY | 1045 | #undef FTRACE_ENTRY |
1045 | #define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter) \ | 1046 | #define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter) \ |
1046 | extern struct ftrace_event_call \ | 1047 | extern struct ftrace_event_call \ |
1047 | __attribute__((__aligned__(4))) event_##call; | 1048 | __attribute__((__aligned__(4))) event_##call; |
1048 | #undef FTRACE_ENTRY_DUP | 1049 | #undef FTRACE_ENTRY_DUP |
1049 | #define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print, filter) \ | 1050 | #define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print, filter) \ |
1050 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print), \ | 1051 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print), \ |
1051 | filter) | 1052 | filter) |
1052 | #include "trace_entries.h" | 1053 | #include "trace_entries.h" |
1053 | 1054 | ||
1054 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_FUNCTION_TRACER) | 1055 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_FUNCTION_TRACER) |
1055 | int perf_ftrace_event_register(struct ftrace_event_call *call, | 1056 | int perf_ftrace_event_register(struct ftrace_event_call *call, |
1056 | enum trace_reg type, void *data); | 1057 | enum trace_reg type, void *data); |
1057 | #else | 1058 | #else |
1058 | #define perf_ftrace_event_register NULL | 1059 | #define perf_ftrace_event_register NULL |
1059 | #endif | 1060 | #endif |
1060 | 1061 | ||
1061 | #endif /* _LINUX_KERNEL_TRACE_H */ | 1062 | #endif /* _LINUX_KERNEL_TRACE_H */ |
1062 | 1063 |
kernel/trace/trace_events.c
1 | /* | 1 | /* |
2 | * event tracer | 2 | * event tracer |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> | 4 | * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> |
5 | * | 5 | * |
6 | * - Added format output of fields of the trace point. | 6 | * - Added format output of fields of the trace point. |
7 | * This was based off of work by Tom Zanussi <tzanussi@gmail.com>. | 7 | * This was based off of work by Tom Zanussi <tzanussi@gmail.com>. |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/workqueue.h> | 11 | #include <linux/workqueue.h> |
12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
13 | #include <linux/kthread.h> | 13 | #include <linux/kthread.h> |
14 | #include <linux/debugfs.h> | 14 | #include <linux/debugfs.h> |
15 | #include <linux/uaccess.h> | 15 | #include <linux/uaccess.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | 20 | ||
21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
22 | 22 | ||
23 | #include "trace_output.h" | 23 | #include "trace_output.h" |
24 | 24 | ||
25 | #undef TRACE_SYSTEM | 25 | #undef TRACE_SYSTEM |
26 | #define TRACE_SYSTEM "TRACE_SYSTEM" | 26 | #define TRACE_SYSTEM "TRACE_SYSTEM" |
27 | 27 | ||
28 | DEFINE_MUTEX(event_mutex); | 28 | DEFINE_MUTEX(event_mutex); |
29 | 29 | ||
30 | DEFINE_MUTEX(event_storage_mutex); | 30 | DEFINE_MUTEX(event_storage_mutex); |
31 | EXPORT_SYMBOL_GPL(event_storage_mutex); | 31 | EXPORT_SYMBOL_GPL(event_storage_mutex); |
32 | 32 | ||
33 | char event_storage[EVENT_STORAGE_SIZE]; | 33 | char event_storage[EVENT_STORAGE_SIZE]; |
34 | EXPORT_SYMBOL_GPL(event_storage); | 34 | EXPORT_SYMBOL_GPL(event_storage); |
35 | 35 | ||
36 | LIST_HEAD(ftrace_events); | 36 | LIST_HEAD(ftrace_events); |
37 | static LIST_HEAD(ftrace_common_fields); | 37 | static LIST_HEAD(ftrace_common_fields); |
38 | 38 | ||
39 | #define GFP_TRACE (GFP_KERNEL | __GFP_ZERO) | 39 | #define GFP_TRACE (GFP_KERNEL | __GFP_ZERO) |
40 | 40 | ||
41 | static struct kmem_cache *field_cachep; | 41 | static struct kmem_cache *field_cachep; |
42 | static struct kmem_cache *file_cachep; | 42 | static struct kmem_cache *file_cachep; |
43 | 43 | ||
44 | #define SYSTEM_FL_FREE_NAME (1 << 31) | 44 | #define SYSTEM_FL_FREE_NAME (1 << 31) |
45 | 45 | ||
46 | static inline int system_refcount(struct event_subsystem *system) | 46 | static inline int system_refcount(struct event_subsystem *system) |
47 | { | 47 | { |
48 | return system->ref_count & ~SYSTEM_FL_FREE_NAME; | 48 | return system->ref_count & ~SYSTEM_FL_FREE_NAME; |
49 | } | 49 | } |
50 | 50 | ||
51 | static int system_refcount_inc(struct event_subsystem *system) | 51 | static int system_refcount_inc(struct event_subsystem *system) |
52 | { | 52 | { |
53 | return (system->ref_count++) & ~SYSTEM_FL_FREE_NAME; | 53 | return (system->ref_count++) & ~SYSTEM_FL_FREE_NAME; |
54 | } | 54 | } |
55 | 55 | ||
56 | static int system_refcount_dec(struct event_subsystem *system) | 56 | static int system_refcount_dec(struct event_subsystem *system) |
57 | { | 57 | { |
58 | return (--system->ref_count) & ~SYSTEM_FL_FREE_NAME; | 58 | return (--system->ref_count) & ~SYSTEM_FL_FREE_NAME; |
59 | } | 59 | } |
60 | 60 | ||
61 | /* Double loops, do not use break, only goto's work */ | 61 | /* Double loops, do not use break, only goto's work */ |
62 | #define do_for_each_event_file(tr, file) \ | 62 | #define do_for_each_event_file(tr, file) \ |
63 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { \ | 63 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { \ |
64 | list_for_each_entry(file, &tr->events, list) | 64 | list_for_each_entry(file, &tr->events, list) |
65 | 65 | ||
66 | #define do_for_each_event_file_safe(tr, file) \ | 66 | #define do_for_each_event_file_safe(tr, file) \ |
67 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { \ | 67 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { \ |
68 | struct ftrace_event_file *___n; \ | 68 | struct ftrace_event_file *___n; \ |
69 | list_for_each_entry_safe(file, ___n, &tr->events, list) | 69 | list_for_each_entry_safe(file, ___n, &tr->events, list) |
70 | 70 | ||
71 | #define while_for_each_event_file() \ | 71 | #define while_for_each_event_file() \ |
72 | } | 72 | } |
73 | 73 | ||
74 | static struct list_head * | 74 | static struct list_head * |
75 | trace_get_fields(struct ftrace_event_call *event_call) | 75 | trace_get_fields(struct ftrace_event_call *event_call) |
76 | { | 76 | { |
77 | if (!event_call->class->get_fields) | 77 | if (!event_call->class->get_fields) |
78 | return &event_call->class->fields; | 78 | return &event_call->class->fields; |
79 | return event_call->class->get_fields(event_call); | 79 | return event_call->class->get_fields(event_call); |
80 | } | 80 | } |
81 | 81 | ||
82 | static struct ftrace_event_field * | 82 | static struct ftrace_event_field * |
83 | __find_event_field(struct list_head *head, char *name) | 83 | __find_event_field(struct list_head *head, char *name) |
84 | { | 84 | { |
85 | struct ftrace_event_field *field; | 85 | struct ftrace_event_field *field; |
86 | 86 | ||
87 | list_for_each_entry(field, head, link) { | 87 | list_for_each_entry(field, head, link) { |
88 | if (!strcmp(field->name, name)) | 88 | if (!strcmp(field->name, name)) |
89 | return field; | 89 | return field; |
90 | } | 90 | } |
91 | 91 | ||
92 | return NULL; | 92 | return NULL; |
93 | } | 93 | } |
94 | 94 | ||
95 | struct ftrace_event_field * | 95 | struct ftrace_event_field * |
96 | trace_find_event_field(struct ftrace_event_call *call, char *name) | 96 | trace_find_event_field(struct ftrace_event_call *call, char *name) |
97 | { | 97 | { |
98 | struct ftrace_event_field *field; | 98 | struct ftrace_event_field *field; |
99 | struct list_head *head; | 99 | struct list_head *head; |
100 | 100 | ||
101 | field = __find_event_field(&ftrace_common_fields, name); | 101 | field = __find_event_field(&ftrace_common_fields, name); |
102 | if (field) | 102 | if (field) |
103 | return field; | 103 | return field; |
104 | 104 | ||
105 | head = trace_get_fields(call); | 105 | head = trace_get_fields(call); |
106 | return __find_event_field(head, name); | 106 | return __find_event_field(head, name); |
107 | } | 107 | } |
108 | 108 | ||
109 | static int __trace_define_field(struct list_head *head, const char *type, | 109 | static int __trace_define_field(struct list_head *head, const char *type, |
110 | const char *name, int offset, int size, | 110 | const char *name, int offset, int size, |
111 | int is_signed, int filter_type) | 111 | int is_signed, int filter_type) |
112 | { | 112 | { |
113 | struct ftrace_event_field *field; | 113 | struct ftrace_event_field *field; |
114 | 114 | ||
115 | field = kmem_cache_alloc(field_cachep, GFP_TRACE); | 115 | field = kmem_cache_alloc(field_cachep, GFP_TRACE); |
116 | if (!field) | 116 | if (!field) |
117 | return -ENOMEM; | 117 | return -ENOMEM; |
118 | 118 | ||
119 | field->name = name; | 119 | field->name = name; |
120 | field->type = type; | 120 | field->type = type; |
121 | 121 | ||
122 | if (filter_type == FILTER_OTHER) | 122 | if (filter_type == FILTER_OTHER) |
123 | field->filter_type = filter_assign_type(type); | 123 | field->filter_type = filter_assign_type(type); |
124 | else | 124 | else |
125 | field->filter_type = filter_type; | 125 | field->filter_type = filter_type; |
126 | 126 | ||
127 | field->offset = offset; | 127 | field->offset = offset; |
128 | field->size = size; | 128 | field->size = size; |
129 | field->is_signed = is_signed; | 129 | field->is_signed = is_signed; |
130 | 130 | ||
131 | list_add(&field->link, head); | 131 | list_add(&field->link, head); |
132 | 132 | ||
133 | return 0; | 133 | return 0; |
134 | } | 134 | } |
135 | 135 | ||
136 | int trace_define_field(struct ftrace_event_call *call, const char *type, | 136 | int trace_define_field(struct ftrace_event_call *call, const char *type, |
137 | const char *name, int offset, int size, int is_signed, | 137 | const char *name, int offset, int size, int is_signed, |
138 | int filter_type) | 138 | int filter_type) |
139 | { | 139 | { |
140 | struct list_head *head; | 140 | struct list_head *head; |
141 | 141 | ||
142 | if (WARN_ON(!call->class)) | 142 | if (WARN_ON(!call->class)) |
143 | return 0; | 143 | return 0; |
144 | 144 | ||
145 | head = trace_get_fields(call); | 145 | head = trace_get_fields(call); |
146 | return __trace_define_field(head, type, name, offset, size, | 146 | return __trace_define_field(head, type, name, offset, size, |
147 | is_signed, filter_type); | 147 | is_signed, filter_type); |
148 | } | 148 | } |
149 | EXPORT_SYMBOL_GPL(trace_define_field); | 149 | EXPORT_SYMBOL_GPL(trace_define_field); |
150 | 150 | ||
151 | #define __common_field(type, item) \ | 151 | #define __common_field(type, item) \ |
152 | ret = __trace_define_field(&ftrace_common_fields, #type, \ | 152 | ret = __trace_define_field(&ftrace_common_fields, #type, \ |
153 | "common_" #item, \ | 153 | "common_" #item, \ |
154 | offsetof(typeof(ent), item), \ | 154 | offsetof(typeof(ent), item), \ |
155 | sizeof(ent.item), \ | 155 | sizeof(ent.item), \ |
156 | is_signed_type(type), FILTER_OTHER); \ | 156 | is_signed_type(type), FILTER_OTHER); \ |
157 | if (ret) \ | 157 | if (ret) \ |
158 | return ret; | 158 | return ret; |
159 | 159 | ||
160 | static int trace_define_common_fields(void) | 160 | static int trace_define_common_fields(void) |
161 | { | 161 | { |
162 | int ret; | 162 | int ret; |
163 | struct trace_entry ent; | 163 | struct trace_entry ent; |
164 | 164 | ||
165 | __common_field(unsigned short, type); | 165 | __common_field(unsigned short, type); |
166 | __common_field(unsigned char, flags); | 166 | __common_field(unsigned char, flags); |
167 | __common_field(unsigned char, preempt_count); | 167 | __common_field(unsigned char, preempt_count); |
168 | __common_field(int, pid); | 168 | __common_field(int, pid); |
169 | 169 | ||
170 | return ret; | 170 | return ret; |
171 | } | 171 | } |
172 | 172 | ||
173 | static void trace_destroy_fields(struct ftrace_event_call *call) | 173 | static void trace_destroy_fields(struct ftrace_event_call *call) |
174 | { | 174 | { |
175 | struct ftrace_event_field *field, *next; | 175 | struct ftrace_event_field *field, *next; |
176 | struct list_head *head; | 176 | struct list_head *head; |
177 | 177 | ||
178 | head = trace_get_fields(call); | 178 | head = trace_get_fields(call); |
179 | list_for_each_entry_safe(field, next, head, link) { | 179 | list_for_each_entry_safe(field, next, head, link) { |
180 | list_del(&field->link); | 180 | list_del(&field->link); |
181 | kmem_cache_free(field_cachep, field); | 181 | kmem_cache_free(field_cachep, field); |
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | int trace_event_raw_init(struct ftrace_event_call *call) | 185 | int trace_event_raw_init(struct ftrace_event_call *call) |
186 | { | 186 | { |
187 | int id; | 187 | int id; |
188 | 188 | ||
189 | id = register_ftrace_event(&call->event); | 189 | id = register_ftrace_event(&call->event); |
190 | if (!id) | 190 | if (!id) |
191 | return -ENODEV; | 191 | return -ENODEV; |
192 | 192 | ||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | EXPORT_SYMBOL_GPL(trace_event_raw_init); | 195 | EXPORT_SYMBOL_GPL(trace_event_raw_init); |
196 | 196 | ||
197 | int ftrace_event_reg(struct ftrace_event_call *call, | 197 | int ftrace_event_reg(struct ftrace_event_call *call, |
198 | enum trace_reg type, void *data) | 198 | enum trace_reg type, void *data) |
199 | { | 199 | { |
200 | struct ftrace_event_file *file = data; | 200 | struct ftrace_event_file *file = data; |
201 | 201 | ||
202 | switch (type) { | 202 | switch (type) { |
203 | case TRACE_REG_REGISTER: | 203 | case TRACE_REG_REGISTER: |
204 | return tracepoint_probe_register(call->name, | 204 | return tracepoint_probe_register(call->name, |
205 | call->class->probe, | 205 | call->class->probe, |
206 | file); | 206 | file); |
207 | case TRACE_REG_UNREGISTER: | 207 | case TRACE_REG_UNREGISTER: |
208 | tracepoint_probe_unregister(call->name, | 208 | tracepoint_probe_unregister(call->name, |
209 | call->class->probe, | 209 | call->class->probe, |
210 | file); | 210 | file); |
211 | return 0; | 211 | return 0; |
212 | 212 | ||
213 | #ifdef CONFIG_PERF_EVENTS | 213 | #ifdef CONFIG_PERF_EVENTS |
214 | case TRACE_REG_PERF_REGISTER: | 214 | case TRACE_REG_PERF_REGISTER: |
215 | return tracepoint_probe_register(call->name, | 215 | return tracepoint_probe_register(call->name, |
216 | call->class->perf_probe, | 216 | call->class->perf_probe, |
217 | call); | 217 | call); |
218 | case TRACE_REG_PERF_UNREGISTER: | 218 | case TRACE_REG_PERF_UNREGISTER: |
219 | tracepoint_probe_unregister(call->name, | 219 | tracepoint_probe_unregister(call->name, |
220 | call->class->perf_probe, | 220 | call->class->perf_probe, |
221 | call); | 221 | call); |
222 | return 0; | 222 | return 0; |
223 | case TRACE_REG_PERF_OPEN: | 223 | case TRACE_REG_PERF_OPEN: |
224 | case TRACE_REG_PERF_CLOSE: | 224 | case TRACE_REG_PERF_CLOSE: |
225 | case TRACE_REG_PERF_ADD: | 225 | case TRACE_REG_PERF_ADD: |
226 | case TRACE_REG_PERF_DEL: | 226 | case TRACE_REG_PERF_DEL: |
227 | return 0; | 227 | return 0; |
228 | #endif | 228 | #endif |
229 | } | 229 | } |
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | EXPORT_SYMBOL_GPL(ftrace_event_reg); | 232 | EXPORT_SYMBOL_GPL(ftrace_event_reg); |
233 | 233 | ||
234 | void trace_event_enable_cmd_record(bool enable) | 234 | void trace_event_enable_cmd_record(bool enable) |
235 | { | 235 | { |
236 | struct ftrace_event_file *file; | 236 | struct ftrace_event_file *file; |
237 | struct trace_array *tr; | 237 | struct trace_array *tr; |
238 | 238 | ||
239 | mutex_lock(&event_mutex); | 239 | mutex_lock(&event_mutex); |
240 | do_for_each_event_file(tr, file) { | 240 | do_for_each_event_file(tr, file) { |
241 | 241 | ||
242 | if (!(file->flags & FTRACE_EVENT_FL_ENABLED)) | 242 | if (!(file->flags & FTRACE_EVENT_FL_ENABLED)) |
243 | continue; | 243 | continue; |
244 | 244 | ||
245 | if (enable) { | 245 | if (enable) { |
246 | tracing_start_cmdline_record(); | 246 | tracing_start_cmdline_record(); |
247 | set_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); | 247 | set_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); |
248 | } else { | 248 | } else { |
249 | tracing_stop_cmdline_record(); | 249 | tracing_stop_cmdline_record(); |
250 | clear_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); | 250 | clear_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); |
251 | } | 251 | } |
252 | } while_for_each_event_file(); | 252 | } while_for_each_event_file(); |
253 | mutex_unlock(&event_mutex); | 253 | mutex_unlock(&event_mutex); |
254 | } | 254 | } |
255 | 255 | ||
256 | static int __ftrace_event_enable_disable(struct ftrace_event_file *file, | 256 | static int __ftrace_event_enable_disable(struct ftrace_event_file *file, |
257 | int enable, int soft_disable) | 257 | int enable, int soft_disable) |
258 | { | 258 | { |
259 | struct ftrace_event_call *call = file->event_call; | 259 | struct ftrace_event_call *call = file->event_call; |
260 | int ret = 0; | 260 | int ret = 0; |
261 | int disable; | 261 | int disable; |
262 | 262 | ||
263 | switch (enable) { | 263 | switch (enable) { |
264 | case 0: | 264 | case 0: |
265 | /* | 265 | /* |
266 | * When soft_disable is set and enable is cleared, the sm_ref | 266 | * When soft_disable is set and enable is cleared, the sm_ref |
267 | * reference counter is decremented. If it reaches 0, we want | 267 | * reference counter is decremented. If it reaches 0, we want |
268 | * to clear the SOFT_DISABLED flag but leave the event in the | 268 | * to clear the SOFT_DISABLED flag but leave the event in the |
269 | * state that it was. That is, if the event was enabled and | 269 | * state that it was. That is, if the event was enabled and |
270 | * SOFT_DISABLED isn't set, then do nothing. But if SOFT_DISABLED | 270 | * SOFT_DISABLED isn't set, then do nothing. But if SOFT_DISABLED |
271 | * is set we do not want the event to be enabled before we | 271 | * is set we do not want the event to be enabled before we |
272 | * clear the bit. | 272 | * clear the bit. |
273 | * | 273 | * |
274 | * When soft_disable is not set but the SOFT_MODE flag is, | 274 | * When soft_disable is not set but the SOFT_MODE flag is, |
275 | * we do nothing. Do not disable the tracepoint, otherwise | 275 | * we do nothing. Do not disable the tracepoint, otherwise |
276 | * "soft enable"s (clearing the SOFT_DISABLED bit) wont work. | 276 | * "soft enable"s (clearing the SOFT_DISABLED bit) wont work. |
277 | */ | 277 | */ |
278 | if (soft_disable) { | 278 | if (soft_disable) { |
279 | if (atomic_dec_return(&file->sm_ref) > 0) | 279 | if (atomic_dec_return(&file->sm_ref) > 0) |
280 | break; | 280 | break; |
281 | disable = file->flags & FTRACE_EVENT_FL_SOFT_DISABLED; | 281 | disable = file->flags & FTRACE_EVENT_FL_SOFT_DISABLED; |
282 | clear_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags); | 282 | clear_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags); |
283 | } else | 283 | } else |
284 | disable = !(file->flags & FTRACE_EVENT_FL_SOFT_MODE); | 284 | disable = !(file->flags & FTRACE_EVENT_FL_SOFT_MODE); |
285 | 285 | ||
286 | if (disable && (file->flags & FTRACE_EVENT_FL_ENABLED)) { | 286 | if (disable && (file->flags & FTRACE_EVENT_FL_ENABLED)) { |
287 | clear_bit(FTRACE_EVENT_FL_ENABLED_BIT, &file->flags); | 287 | clear_bit(FTRACE_EVENT_FL_ENABLED_BIT, &file->flags); |
288 | if (file->flags & FTRACE_EVENT_FL_RECORDED_CMD) { | 288 | if (file->flags & FTRACE_EVENT_FL_RECORDED_CMD) { |
289 | tracing_stop_cmdline_record(); | 289 | tracing_stop_cmdline_record(); |
290 | clear_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); | 290 | clear_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); |
291 | } | 291 | } |
292 | call->class->reg(call, TRACE_REG_UNREGISTER, file); | 292 | call->class->reg(call, TRACE_REG_UNREGISTER, file); |
293 | } | 293 | } |
294 | /* If in SOFT_MODE, just set the SOFT_DISABLE_BIT, else clear it */ | 294 | /* If in SOFT_MODE, just set the SOFT_DISABLE_BIT, else clear it */ |
295 | if (file->flags & FTRACE_EVENT_FL_SOFT_MODE) | 295 | if (file->flags & FTRACE_EVENT_FL_SOFT_MODE) |
296 | set_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); | 296 | set_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); |
297 | else | 297 | else |
298 | clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); | 298 | clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); |
299 | break; | 299 | break; |
300 | case 1: | 300 | case 1: |
301 | /* | 301 | /* |
302 | * When soft_disable is set and enable is set, we want to | 302 | * When soft_disable is set and enable is set, we want to |
303 | * register the tracepoint for the event, but leave the event | 303 | * register the tracepoint for the event, but leave the event |
304 | * as is. That means, if the event was already enabled, we do | 304 | * as is. That means, if the event was already enabled, we do |
305 | * nothing (but set SOFT_MODE). If the event is disabled, we | 305 | * nothing (but set SOFT_MODE). If the event is disabled, we |
306 | * set SOFT_DISABLED before enabling the event tracepoint, so | 306 | * set SOFT_DISABLED before enabling the event tracepoint, so |
307 | * it still seems to be disabled. | 307 | * it still seems to be disabled. |
308 | */ | 308 | */ |
309 | if (!soft_disable) | 309 | if (!soft_disable) |
310 | clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); | 310 | clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); |
311 | else { | 311 | else { |
312 | if (atomic_inc_return(&file->sm_ref) > 1) | 312 | if (atomic_inc_return(&file->sm_ref) > 1) |
313 | break; | 313 | break; |
314 | set_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags); | 314 | set_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags); |
315 | } | 315 | } |
316 | 316 | ||
317 | if (!(file->flags & FTRACE_EVENT_FL_ENABLED)) { | 317 | if (!(file->flags & FTRACE_EVENT_FL_ENABLED)) { |
318 | 318 | ||
319 | /* Keep the event disabled, when going to SOFT_MODE. */ | 319 | /* Keep the event disabled, when going to SOFT_MODE. */ |
320 | if (soft_disable) | 320 | if (soft_disable) |
321 | set_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); | 321 | set_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); |
322 | 322 | ||
323 | if (trace_flags & TRACE_ITER_RECORD_CMD) { | 323 | if (trace_flags & TRACE_ITER_RECORD_CMD) { |
324 | tracing_start_cmdline_record(); | 324 | tracing_start_cmdline_record(); |
325 | set_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); | 325 | set_bit(FTRACE_EVENT_FL_RECORDED_CMD_BIT, &file->flags); |
326 | } | 326 | } |
327 | ret = call->class->reg(call, TRACE_REG_REGISTER, file); | 327 | ret = call->class->reg(call, TRACE_REG_REGISTER, file); |
328 | if (ret) { | 328 | if (ret) { |
329 | tracing_stop_cmdline_record(); | 329 | tracing_stop_cmdline_record(); |
330 | pr_info("event trace: Could not enable event " | 330 | pr_info("event trace: Could not enable event " |
331 | "%s\n", call->name); | 331 | "%s\n", call->name); |
332 | break; | 332 | break; |
333 | } | 333 | } |
334 | set_bit(FTRACE_EVENT_FL_ENABLED_BIT, &file->flags); | 334 | set_bit(FTRACE_EVENT_FL_ENABLED_BIT, &file->flags); |
335 | 335 | ||
336 | /* WAS_ENABLED gets set but never cleared. */ | 336 | /* WAS_ENABLED gets set but never cleared. */ |
337 | call->flags |= TRACE_EVENT_FL_WAS_ENABLED; | 337 | call->flags |= TRACE_EVENT_FL_WAS_ENABLED; |
338 | } | 338 | } |
339 | break; | 339 | break; |
340 | } | 340 | } |
341 | 341 | ||
342 | return ret; | 342 | return ret; |
343 | } | 343 | } |
344 | 344 | ||
345 | static int ftrace_event_enable_disable(struct ftrace_event_file *file, | 345 | static int ftrace_event_enable_disable(struct ftrace_event_file *file, |
346 | int enable) | 346 | int enable) |
347 | { | 347 | { |
348 | return __ftrace_event_enable_disable(file, enable, 0); | 348 | return __ftrace_event_enable_disable(file, enable, 0); |
349 | } | 349 | } |
350 | 350 | ||
351 | static void ftrace_clear_events(struct trace_array *tr) | 351 | static void ftrace_clear_events(struct trace_array *tr) |
352 | { | 352 | { |
353 | struct ftrace_event_file *file; | 353 | struct ftrace_event_file *file; |
354 | 354 | ||
355 | mutex_lock(&event_mutex); | 355 | mutex_lock(&event_mutex); |
356 | list_for_each_entry(file, &tr->events, list) { | 356 | list_for_each_entry(file, &tr->events, list) { |
357 | ftrace_event_enable_disable(file, 0); | 357 | ftrace_event_enable_disable(file, 0); |
358 | } | 358 | } |
359 | mutex_unlock(&event_mutex); | 359 | mutex_unlock(&event_mutex); |
360 | } | 360 | } |
361 | 361 | ||
362 | static void __put_system(struct event_subsystem *system) | 362 | static void __put_system(struct event_subsystem *system) |
363 | { | 363 | { |
364 | struct event_filter *filter = system->filter; | 364 | struct event_filter *filter = system->filter; |
365 | 365 | ||
366 | WARN_ON_ONCE(system_refcount(system) == 0); | 366 | WARN_ON_ONCE(system_refcount(system) == 0); |
367 | if (system_refcount_dec(system)) | 367 | if (system_refcount_dec(system)) |
368 | return; | 368 | return; |
369 | 369 | ||
370 | list_del(&system->list); | 370 | list_del(&system->list); |
371 | 371 | ||
372 | if (filter) { | 372 | if (filter) { |
373 | kfree(filter->filter_string); | 373 | kfree(filter->filter_string); |
374 | kfree(filter); | 374 | kfree(filter); |
375 | } | 375 | } |
376 | if (system->ref_count & SYSTEM_FL_FREE_NAME) | 376 | if (system->ref_count & SYSTEM_FL_FREE_NAME) |
377 | kfree(system->name); | 377 | kfree(system->name); |
378 | kfree(system); | 378 | kfree(system); |
379 | } | 379 | } |
380 | 380 | ||
381 | static void __get_system(struct event_subsystem *system) | 381 | static void __get_system(struct event_subsystem *system) |
382 | { | 382 | { |
383 | WARN_ON_ONCE(system_refcount(system) == 0); | 383 | WARN_ON_ONCE(system_refcount(system) == 0); |
384 | system_refcount_inc(system); | 384 | system_refcount_inc(system); |
385 | } | 385 | } |
386 | 386 | ||
387 | static void __get_system_dir(struct ftrace_subsystem_dir *dir) | 387 | static void __get_system_dir(struct ftrace_subsystem_dir *dir) |
388 | { | 388 | { |
389 | WARN_ON_ONCE(dir->ref_count == 0); | 389 | WARN_ON_ONCE(dir->ref_count == 0); |
390 | dir->ref_count++; | 390 | dir->ref_count++; |
391 | __get_system(dir->subsystem); | 391 | __get_system(dir->subsystem); |
392 | } | 392 | } |
393 | 393 | ||
394 | static void __put_system_dir(struct ftrace_subsystem_dir *dir) | 394 | static void __put_system_dir(struct ftrace_subsystem_dir *dir) |
395 | { | 395 | { |
396 | WARN_ON_ONCE(dir->ref_count == 0); | 396 | WARN_ON_ONCE(dir->ref_count == 0); |
397 | /* If the subsystem is about to be freed, the dir must be too */ | 397 | /* If the subsystem is about to be freed, the dir must be too */ |
398 | WARN_ON_ONCE(system_refcount(dir->subsystem) == 1 && dir->ref_count != 1); | 398 | WARN_ON_ONCE(system_refcount(dir->subsystem) == 1 && dir->ref_count != 1); |
399 | 399 | ||
400 | __put_system(dir->subsystem); | 400 | __put_system(dir->subsystem); |
401 | if (!--dir->ref_count) | 401 | if (!--dir->ref_count) |
402 | kfree(dir); | 402 | kfree(dir); |
403 | } | 403 | } |
404 | 404 | ||
405 | static void put_system(struct ftrace_subsystem_dir *dir) | 405 | static void put_system(struct ftrace_subsystem_dir *dir) |
406 | { | 406 | { |
407 | mutex_lock(&event_mutex); | 407 | mutex_lock(&event_mutex); |
408 | __put_system_dir(dir); | 408 | __put_system_dir(dir); |
409 | mutex_unlock(&event_mutex); | 409 | mutex_unlock(&event_mutex); |
410 | } | 410 | } |
411 | 411 | ||
412 | static void remove_subsystem(struct ftrace_subsystem_dir *dir) | 412 | static void remove_subsystem(struct ftrace_subsystem_dir *dir) |
413 | { | 413 | { |
414 | if (!dir) | 414 | if (!dir) |
415 | return; | 415 | return; |
416 | 416 | ||
417 | if (!--dir->nr_events) { | 417 | if (!--dir->nr_events) { |
418 | debugfs_remove_recursive(dir->entry); | 418 | debugfs_remove_recursive(dir->entry); |
419 | list_del(&dir->list); | 419 | list_del(&dir->list); |
420 | __put_system_dir(dir); | 420 | __put_system_dir(dir); |
421 | } | 421 | } |
422 | } | 422 | } |
423 | 423 | ||
424 | static void *event_file_data(struct file *filp) | 424 | static void *event_file_data(struct file *filp) |
425 | { | 425 | { |
426 | return ACCESS_ONCE(file_inode(filp)->i_private); | 426 | return ACCESS_ONCE(file_inode(filp)->i_private); |
427 | } | 427 | } |
428 | 428 | ||
429 | static void remove_event_file_dir(struct ftrace_event_file *file) | 429 | static void remove_event_file_dir(struct ftrace_event_file *file) |
430 | { | 430 | { |
431 | struct dentry *dir = file->dir; | 431 | struct dentry *dir = file->dir; |
432 | struct dentry *child; | 432 | struct dentry *child; |
433 | 433 | ||
434 | if (dir) { | 434 | if (dir) { |
435 | spin_lock(&dir->d_lock); /* probably unneeded */ | 435 | spin_lock(&dir->d_lock); /* probably unneeded */ |
436 | list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) { | 436 | list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) { |
437 | if (child->d_inode) /* probably unneeded */ | 437 | if (child->d_inode) /* probably unneeded */ |
438 | child->d_inode->i_private = NULL; | 438 | child->d_inode->i_private = NULL; |
439 | } | 439 | } |
440 | spin_unlock(&dir->d_lock); | 440 | spin_unlock(&dir->d_lock); |
441 | 441 | ||
442 | debugfs_remove_recursive(dir); | 442 | debugfs_remove_recursive(dir); |
443 | } | 443 | } |
444 | 444 | ||
445 | list_del(&file->list); | 445 | list_del(&file->list); |
446 | remove_subsystem(file->system); | 446 | remove_subsystem(file->system); |
447 | kmem_cache_free(file_cachep, file); | 447 | kmem_cache_free(file_cachep, file); |
448 | } | 448 | } |
449 | 449 | ||
450 | /* | 450 | /* |
451 | * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events. | 451 | * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events. |
452 | */ | 452 | */ |
453 | static int | 453 | static int |
454 | __ftrace_set_clr_event_nolock(struct trace_array *tr, const char *match, | 454 | __ftrace_set_clr_event_nolock(struct trace_array *tr, const char *match, |
455 | const char *sub, const char *event, int set) | 455 | const char *sub, const char *event, int set) |
456 | { | 456 | { |
457 | struct ftrace_event_file *file; | 457 | struct ftrace_event_file *file; |
458 | struct ftrace_event_call *call; | 458 | struct ftrace_event_call *call; |
459 | int ret = -EINVAL; | 459 | int ret = -EINVAL; |
460 | 460 | ||
461 | list_for_each_entry(file, &tr->events, list) { | 461 | list_for_each_entry(file, &tr->events, list) { |
462 | 462 | ||
463 | call = file->event_call; | 463 | call = file->event_call; |
464 | 464 | ||
465 | if (!call->name || !call->class || !call->class->reg) | 465 | if (!call->name || !call->class || !call->class->reg) |
466 | continue; | 466 | continue; |
467 | 467 | ||
468 | if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) | 468 | if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) |
469 | continue; | 469 | continue; |
470 | 470 | ||
471 | if (match && | 471 | if (match && |
472 | strcmp(match, call->name) != 0 && | 472 | strcmp(match, call->name) != 0 && |
473 | strcmp(match, call->class->system) != 0) | 473 | strcmp(match, call->class->system) != 0) |
474 | continue; | 474 | continue; |
475 | 475 | ||
476 | if (sub && strcmp(sub, call->class->system) != 0) | 476 | if (sub && strcmp(sub, call->class->system) != 0) |
477 | continue; | 477 | continue; |
478 | 478 | ||
479 | if (event && strcmp(event, call->name) != 0) | 479 | if (event && strcmp(event, call->name) != 0) |
480 | continue; | 480 | continue; |
481 | 481 | ||
482 | ftrace_event_enable_disable(file, set); | 482 | ftrace_event_enable_disable(file, set); |
483 | 483 | ||
484 | ret = 0; | 484 | ret = 0; |
485 | } | 485 | } |
486 | 486 | ||
487 | return ret; | 487 | return ret; |
488 | } | 488 | } |
489 | 489 | ||
490 | static int __ftrace_set_clr_event(struct trace_array *tr, const char *match, | 490 | static int __ftrace_set_clr_event(struct trace_array *tr, const char *match, |
491 | const char *sub, const char *event, int set) | 491 | const char *sub, const char *event, int set) |
492 | { | 492 | { |
493 | int ret; | 493 | int ret; |
494 | 494 | ||
495 | mutex_lock(&event_mutex); | 495 | mutex_lock(&event_mutex); |
496 | ret = __ftrace_set_clr_event_nolock(tr, match, sub, event, set); | 496 | ret = __ftrace_set_clr_event_nolock(tr, match, sub, event, set); |
497 | mutex_unlock(&event_mutex); | 497 | mutex_unlock(&event_mutex); |
498 | 498 | ||
499 | return ret; | 499 | return ret; |
500 | } | 500 | } |
501 | 501 | ||
502 | static int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set) | 502 | static int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set) |
503 | { | 503 | { |
504 | char *event = NULL, *sub = NULL, *match; | 504 | char *event = NULL, *sub = NULL, *match; |
505 | 505 | ||
506 | /* | 506 | /* |
507 | * The buf format can be <subsystem>:<event-name> | 507 | * The buf format can be <subsystem>:<event-name> |
508 | * *:<event-name> means any event by that name. | 508 | * *:<event-name> means any event by that name. |
509 | * :<event-name> is the same. | 509 | * :<event-name> is the same. |
510 | * | 510 | * |
511 | * <subsystem>:* means all events in that subsystem | 511 | * <subsystem>:* means all events in that subsystem |
512 | * <subsystem>: means the same. | 512 | * <subsystem>: means the same. |
513 | * | 513 | * |
514 | * <name> (no ':') means all events in a subsystem with | 514 | * <name> (no ':') means all events in a subsystem with |
515 | * the name <name> or any event that matches <name> | 515 | * the name <name> or any event that matches <name> |
516 | */ | 516 | */ |
517 | 517 | ||
518 | match = strsep(&buf, ":"); | 518 | match = strsep(&buf, ":"); |
519 | if (buf) { | 519 | if (buf) { |
520 | sub = match; | 520 | sub = match; |
521 | event = buf; | 521 | event = buf; |
522 | match = NULL; | 522 | match = NULL; |
523 | 523 | ||
524 | if (!strlen(sub) || strcmp(sub, "*") == 0) | 524 | if (!strlen(sub) || strcmp(sub, "*") == 0) |
525 | sub = NULL; | 525 | sub = NULL; |
526 | if (!strlen(event) || strcmp(event, "*") == 0) | 526 | if (!strlen(event) || strcmp(event, "*") == 0) |
527 | event = NULL; | 527 | event = NULL; |
528 | } | 528 | } |
529 | 529 | ||
530 | return __ftrace_set_clr_event(tr, match, sub, event, set); | 530 | return __ftrace_set_clr_event(tr, match, sub, event, set); |
531 | } | 531 | } |
532 | 532 | ||
533 | /** | 533 | /** |
534 | * trace_set_clr_event - enable or disable an event | 534 | * trace_set_clr_event - enable or disable an event |
535 | * @system: system name to match (NULL for any system) | 535 | * @system: system name to match (NULL for any system) |
536 | * @event: event name to match (NULL for all events, within system) | 536 | * @event: event name to match (NULL for all events, within system) |
537 | * @set: 1 to enable, 0 to disable | 537 | * @set: 1 to enable, 0 to disable |
538 | * | 538 | * |
539 | * This is a way for other parts of the kernel to enable or disable | 539 | * This is a way for other parts of the kernel to enable or disable |
540 | * event recording. | 540 | * event recording. |
541 | * | 541 | * |
542 | * Returns 0 on success, -EINVAL if the parameters do not match any | 542 | * Returns 0 on success, -EINVAL if the parameters do not match any |
543 | * registered events. | 543 | * registered events. |
544 | */ | 544 | */ |
545 | int trace_set_clr_event(const char *system, const char *event, int set) | 545 | int trace_set_clr_event(const char *system, const char *event, int set) |
546 | { | 546 | { |
547 | struct trace_array *tr = top_trace_array(); | 547 | struct trace_array *tr = top_trace_array(); |
548 | 548 | ||
549 | return __ftrace_set_clr_event(tr, NULL, system, event, set); | 549 | return __ftrace_set_clr_event(tr, NULL, system, event, set); |
550 | } | 550 | } |
551 | EXPORT_SYMBOL_GPL(trace_set_clr_event); | 551 | EXPORT_SYMBOL_GPL(trace_set_clr_event); |
552 | 552 | ||
553 | /* 128 should be much more than enough */ | 553 | /* 128 should be much more than enough */ |
554 | #define EVENT_BUF_SIZE 127 | 554 | #define EVENT_BUF_SIZE 127 |
555 | 555 | ||
556 | static ssize_t | 556 | static ssize_t |
557 | ftrace_event_write(struct file *file, const char __user *ubuf, | 557 | ftrace_event_write(struct file *file, const char __user *ubuf, |
558 | size_t cnt, loff_t *ppos) | 558 | size_t cnt, loff_t *ppos) |
559 | { | 559 | { |
560 | struct trace_parser parser; | 560 | struct trace_parser parser; |
561 | struct seq_file *m = file->private_data; | 561 | struct seq_file *m = file->private_data; |
562 | struct trace_array *tr = m->private; | 562 | struct trace_array *tr = m->private; |
563 | ssize_t read, ret; | 563 | ssize_t read, ret; |
564 | 564 | ||
565 | if (!cnt) | 565 | if (!cnt) |
566 | return 0; | 566 | return 0; |
567 | 567 | ||
568 | ret = tracing_update_buffers(); | 568 | ret = tracing_update_buffers(); |
569 | if (ret < 0) | 569 | if (ret < 0) |
570 | return ret; | 570 | return ret; |
571 | 571 | ||
572 | if (trace_parser_get_init(&parser, EVENT_BUF_SIZE + 1)) | 572 | if (trace_parser_get_init(&parser, EVENT_BUF_SIZE + 1)) |
573 | return -ENOMEM; | 573 | return -ENOMEM; |
574 | 574 | ||
575 | read = trace_get_user(&parser, ubuf, cnt, ppos); | 575 | read = trace_get_user(&parser, ubuf, cnt, ppos); |
576 | 576 | ||
577 | if (read >= 0 && trace_parser_loaded((&parser))) { | 577 | if (read >= 0 && trace_parser_loaded((&parser))) { |
578 | int set = 1; | 578 | int set = 1; |
579 | 579 | ||
580 | if (*parser.buffer == '!') | 580 | if (*parser.buffer == '!') |
581 | set = 0; | 581 | set = 0; |
582 | 582 | ||
583 | parser.buffer[parser.idx] = 0; | 583 | parser.buffer[parser.idx] = 0; |
584 | 584 | ||
585 | ret = ftrace_set_clr_event(tr, parser.buffer + !set, set); | 585 | ret = ftrace_set_clr_event(tr, parser.buffer + !set, set); |
586 | if (ret) | 586 | if (ret) |
587 | goto out_put; | 587 | goto out_put; |
588 | } | 588 | } |
589 | 589 | ||
590 | ret = read; | 590 | ret = read; |
591 | 591 | ||
592 | out_put: | 592 | out_put: |
593 | trace_parser_put(&parser); | 593 | trace_parser_put(&parser); |
594 | 594 | ||
595 | return ret; | 595 | return ret; |
596 | } | 596 | } |
597 | 597 | ||
598 | static void * | 598 | static void * |
599 | t_next(struct seq_file *m, void *v, loff_t *pos) | 599 | t_next(struct seq_file *m, void *v, loff_t *pos) |
600 | { | 600 | { |
601 | struct ftrace_event_file *file = v; | 601 | struct ftrace_event_file *file = v; |
602 | struct ftrace_event_call *call; | 602 | struct ftrace_event_call *call; |
603 | struct trace_array *tr = m->private; | 603 | struct trace_array *tr = m->private; |
604 | 604 | ||
605 | (*pos)++; | 605 | (*pos)++; |
606 | 606 | ||
607 | list_for_each_entry_continue(file, &tr->events, list) { | 607 | list_for_each_entry_continue(file, &tr->events, list) { |
608 | call = file->event_call; | 608 | call = file->event_call; |
609 | /* | 609 | /* |
610 | * The ftrace subsystem is for showing formats only. | 610 | * The ftrace subsystem is for showing formats only. |
611 | * They can not be enabled or disabled via the event files. | 611 | * They can not be enabled or disabled via the event files. |
612 | */ | 612 | */ |
613 | if (call->class && call->class->reg) | 613 | if (call->class && call->class->reg) |
614 | return file; | 614 | return file; |
615 | } | 615 | } |
616 | 616 | ||
617 | return NULL; | 617 | return NULL; |
618 | } | 618 | } |
619 | 619 | ||
620 | static void *t_start(struct seq_file *m, loff_t *pos) | 620 | static void *t_start(struct seq_file *m, loff_t *pos) |
621 | { | 621 | { |
622 | struct ftrace_event_file *file; | 622 | struct ftrace_event_file *file; |
623 | struct trace_array *tr = m->private; | 623 | struct trace_array *tr = m->private; |
624 | loff_t l; | 624 | loff_t l; |
625 | 625 | ||
626 | mutex_lock(&event_mutex); | 626 | mutex_lock(&event_mutex); |
627 | 627 | ||
628 | file = list_entry(&tr->events, struct ftrace_event_file, list); | 628 | file = list_entry(&tr->events, struct ftrace_event_file, list); |
629 | for (l = 0; l <= *pos; ) { | 629 | for (l = 0; l <= *pos; ) { |
630 | file = t_next(m, file, &l); | 630 | file = t_next(m, file, &l); |
631 | if (!file) | 631 | if (!file) |
632 | break; | 632 | break; |
633 | } | 633 | } |
634 | return file; | 634 | return file; |
635 | } | 635 | } |
636 | 636 | ||
637 | static void * | 637 | static void * |
638 | s_next(struct seq_file *m, void *v, loff_t *pos) | 638 | s_next(struct seq_file *m, void *v, loff_t *pos) |
639 | { | 639 | { |
640 | struct ftrace_event_file *file = v; | 640 | struct ftrace_event_file *file = v; |
641 | struct trace_array *tr = m->private; | 641 | struct trace_array *tr = m->private; |
642 | 642 | ||
643 | (*pos)++; | 643 | (*pos)++; |
644 | 644 | ||
645 | list_for_each_entry_continue(file, &tr->events, list) { | 645 | list_for_each_entry_continue(file, &tr->events, list) { |
646 | if (file->flags & FTRACE_EVENT_FL_ENABLED) | 646 | if (file->flags & FTRACE_EVENT_FL_ENABLED) |
647 | return file; | 647 | return file; |
648 | } | 648 | } |
649 | 649 | ||
650 | return NULL; | 650 | return NULL; |
651 | } | 651 | } |
652 | 652 | ||
653 | static void *s_start(struct seq_file *m, loff_t *pos) | 653 | static void *s_start(struct seq_file *m, loff_t *pos) |
654 | { | 654 | { |
655 | struct ftrace_event_file *file; | 655 | struct ftrace_event_file *file; |
656 | struct trace_array *tr = m->private; | 656 | struct trace_array *tr = m->private; |
657 | loff_t l; | 657 | loff_t l; |
658 | 658 | ||
659 | mutex_lock(&event_mutex); | 659 | mutex_lock(&event_mutex); |
660 | 660 | ||
661 | file = list_entry(&tr->events, struct ftrace_event_file, list); | 661 | file = list_entry(&tr->events, struct ftrace_event_file, list); |
662 | for (l = 0; l <= *pos; ) { | 662 | for (l = 0; l <= *pos; ) { |
663 | file = s_next(m, file, &l); | 663 | file = s_next(m, file, &l); |
664 | if (!file) | 664 | if (!file) |
665 | break; | 665 | break; |
666 | } | 666 | } |
667 | return file; | 667 | return file; |
668 | } | 668 | } |
669 | 669 | ||
670 | static int t_show(struct seq_file *m, void *v) | 670 | static int t_show(struct seq_file *m, void *v) |
671 | { | 671 | { |
672 | struct ftrace_event_file *file = v; | 672 | struct ftrace_event_file *file = v; |
673 | struct ftrace_event_call *call = file->event_call; | 673 | struct ftrace_event_call *call = file->event_call; |
674 | 674 | ||
675 | if (strcmp(call->class->system, TRACE_SYSTEM) != 0) | 675 | if (strcmp(call->class->system, TRACE_SYSTEM) != 0) |
676 | seq_printf(m, "%s:", call->class->system); | 676 | seq_printf(m, "%s:", call->class->system); |
677 | seq_printf(m, "%s\n", call->name); | 677 | seq_printf(m, "%s\n", call->name); |
678 | 678 | ||
679 | return 0; | 679 | return 0; |
680 | } | 680 | } |
681 | 681 | ||
682 | static void t_stop(struct seq_file *m, void *p) | 682 | static void t_stop(struct seq_file *m, void *p) |
683 | { | 683 | { |
684 | mutex_unlock(&event_mutex); | 684 | mutex_unlock(&event_mutex); |
685 | } | 685 | } |
686 | 686 | ||
687 | static ssize_t | 687 | static ssize_t |
688 | event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, | 688 | event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, |
689 | loff_t *ppos) | 689 | loff_t *ppos) |
690 | { | 690 | { |
691 | struct ftrace_event_file *file; | 691 | struct ftrace_event_file *file; |
692 | unsigned long flags; | 692 | unsigned long flags; |
693 | char buf[4] = "0"; | 693 | char buf[4] = "0"; |
694 | 694 | ||
695 | mutex_lock(&event_mutex); | 695 | mutex_lock(&event_mutex); |
696 | file = event_file_data(filp); | 696 | file = event_file_data(filp); |
697 | if (likely(file)) | 697 | if (likely(file)) |
698 | flags = file->flags; | 698 | flags = file->flags; |
699 | mutex_unlock(&event_mutex); | 699 | mutex_unlock(&event_mutex); |
700 | 700 | ||
701 | if (!file) | 701 | if (!file) |
702 | return -ENODEV; | 702 | return -ENODEV; |
703 | 703 | ||
704 | if (flags & FTRACE_EVENT_FL_ENABLED && | 704 | if (flags & FTRACE_EVENT_FL_ENABLED && |
705 | !(flags & FTRACE_EVENT_FL_SOFT_DISABLED)) | 705 | !(flags & FTRACE_EVENT_FL_SOFT_DISABLED)) |
706 | strcpy(buf, "1"); | 706 | strcpy(buf, "1"); |
707 | 707 | ||
708 | if (flags & FTRACE_EVENT_FL_SOFT_DISABLED || | 708 | if (flags & FTRACE_EVENT_FL_SOFT_DISABLED || |
709 | flags & FTRACE_EVENT_FL_SOFT_MODE) | 709 | flags & FTRACE_EVENT_FL_SOFT_MODE) |
710 | strcat(buf, "*"); | 710 | strcat(buf, "*"); |
711 | 711 | ||
712 | strcat(buf, "\n"); | 712 | strcat(buf, "\n"); |
713 | 713 | ||
714 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, strlen(buf)); | 714 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, strlen(buf)); |
715 | } | 715 | } |
716 | 716 | ||
717 | static ssize_t | 717 | static ssize_t |
718 | event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, | 718 | event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, |
719 | loff_t *ppos) | 719 | loff_t *ppos) |
720 | { | 720 | { |
721 | struct ftrace_event_file *file; | 721 | struct ftrace_event_file *file; |
722 | unsigned long val; | 722 | unsigned long val; |
723 | int ret; | 723 | int ret; |
724 | 724 | ||
725 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 725 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
726 | if (ret) | 726 | if (ret) |
727 | return ret; | 727 | return ret; |
728 | 728 | ||
729 | ret = tracing_update_buffers(); | 729 | ret = tracing_update_buffers(); |
730 | if (ret < 0) | 730 | if (ret < 0) |
731 | return ret; | 731 | return ret; |
732 | 732 | ||
733 | switch (val) { | 733 | switch (val) { |
734 | case 0: | 734 | case 0: |
735 | case 1: | 735 | case 1: |
736 | ret = -ENODEV; | 736 | ret = -ENODEV; |
737 | mutex_lock(&event_mutex); | 737 | mutex_lock(&event_mutex); |
738 | file = event_file_data(filp); | 738 | file = event_file_data(filp); |
739 | if (likely(file)) | 739 | if (likely(file)) |
740 | ret = ftrace_event_enable_disable(file, val); | 740 | ret = ftrace_event_enable_disable(file, val); |
741 | mutex_unlock(&event_mutex); | 741 | mutex_unlock(&event_mutex); |
742 | break; | 742 | break; |
743 | 743 | ||
744 | default: | 744 | default: |
745 | return -EINVAL; | 745 | return -EINVAL; |
746 | } | 746 | } |
747 | 747 | ||
748 | *ppos += cnt; | 748 | *ppos += cnt; |
749 | 749 | ||
750 | return ret ? ret : cnt; | 750 | return ret ? ret : cnt; |
751 | } | 751 | } |
752 | 752 | ||
753 | static ssize_t | 753 | static ssize_t |
754 | system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, | 754 | system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, |
755 | loff_t *ppos) | 755 | loff_t *ppos) |
756 | { | 756 | { |
757 | const char set_to_char[4] = { '?', '0', '1', 'X' }; | 757 | const char set_to_char[4] = { '?', '0', '1', 'X' }; |
758 | struct ftrace_subsystem_dir *dir = filp->private_data; | 758 | struct ftrace_subsystem_dir *dir = filp->private_data; |
759 | struct event_subsystem *system = dir->subsystem; | 759 | struct event_subsystem *system = dir->subsystem; |
760 | struct ftrace_event_call *call; | 760 | struct ftrace_event_call *call; |
761 | struct ftrace_event_file *file; | 761 | struct ftrace_event_file *file; |
762 | struct trace_array *tr = dir->tr; | 762 | struct trace_array *tr = dir->tr; |
763 | char buf[2]; | 763 | char buf[2]; |
764 | int set = 0; | 764 | int set = 0; |
765 | int ret; | 765 | int ret; |
766 | 766 | ||
767 | mutex_lock(&event_mutex); | 767 | mutex_lock(&event_mutex); |
768 | list_for_each_entry(file, &tr->events, list) { | 768 | list_for_each_entry(file, &tr->events, list) { |
769 | call = file->event_call; | 769 | call = file->event_call; |
770 | if (!call->name || !call->class || !call->class->reg) | 770 | if (!call->name || !call->class || !call->class->reg) |
771 | continue; | 771 | continue; |
772 | 772 | ||
773 | if (system && strcmp(call->class->system, system->name) != 0) | 773 | if (system && strcmp(call->class->system, system->name) != 0) |
774 | continue; | 774 | continue; |
775 | 775 | ||
776 | /* | 776 | /* |
777 | * We need to find out if all the events are set | 777 | * We need to find out if all the events are set |
778 | * or if all events or cleared, or if we have | 778 | * or if all events or cleared, or if we have |
779 | * a mixture. | 779 | * a mixture. |
780 | */ | 780 | */ |
781 | set |= (1 << !!(file->flags & FTRACE_EVENT_FL_ENABLED)); | 781 | set |= (1 << !!(file->flags & FTRACE_EVENT_FL_ENABLED)); |
782 | 782 | ||
783 | /* | 783 | /* |
784 | * If we have a mixture, no need to look further. | 784 | * If we have a mixture, no need to look further. |
785 | */ | 785 | */ |
786 | if (set == 3) | 786 | if (set == 3) |
787 | break; | 787 | break; |
788 | } | 788 | } |
789 | mutex_unlock(&event_mutex); | 789 | mutex_unlock(&event_mutex); |
790 | 790 | ||
791 | buf[0] = set_to_char[set]; | 791 | buf[0] = set_to_char[set]; |
792 | buf[1] = '\n'; | 792 | buf[1] = '\n'; |
793 | 793 | ||
794 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, 2); | 794 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, 2); |
795 | 795 | ||
796 | return ret; | 796 | return ret; |
797 | } | 797 | } |
798 | 798 | ||
799 | static ssize_t | 799 | static ssize_t |
800 | system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, | 800 | system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, |
801 | loff_t *ppos) | 801 | loff_t *ppos) |
802 | { | 802 | { |
803 | struct ftrace_subsystem_dir *dir = filp->private_data; | 803 | struct ftrace_subsystem_dir *dir = filp->private_data; |
804 | struct event_subsystem *system = dir->subsystem; | 804 | struct event_subsystem *system = dir->subsystem; |
805 | const char *name = NULL; | 805 | const char *name = NULL; |
806 | unsigned long val; | 806 | unsigned long val; |
807 | ssize_t ret; | 807 | ssize_t ret; |
808 | 808 | ||
809 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | 809 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); |
810 | if (ret) | 810 | if (ret) |
811 | return ret; | 811 | return ret; |
812 | 812 | ||
813 | ret = tracing_update_buffers(); | 813 | ret = tracing_update_buffers(); |
814 | if (ret < 0) | 814 | if (ret < 0) |
815 | return ret; | 815 | return ret; |
816 | 816 | ||
817 | if (val != 0 && val != 1) | 817 | if (val != 0 && val != 1) |
818 | return -EINVAL; | 818 | return -EINVAL; |
819 | 819 | ||
820 | /* | 820 | /* |
821 | * Opening of "enable" adds a ref count to system, | 821 | * Opening of "enable" adds a ref count to system, |
822 | * so the name is safe to use. | 822 | * so the name is safe to use. |
823 | */ | 823 | */ |
824 | if (system) | 824 | if (system) |
825 | name = system->name; | 825 | name = system->name; |
826 | 826 | ||
827 | ret = __ftrace_set_clr_event(dir->tr, NULL, name, NULL, val); | 827 | ret = __ftrace_set_clr_event(dir->tr, NULL, name, NULL, val); |
828 | if (ret) | 828 | if (ret) |
829 | goto out; | 829 | goto out; |
830 | 830 | ||
831 | ret = cnt; | 831 | ret = cnt; |
832 | 832 | ||
833 | out: | 833 | out: |
834 | *ppos += cnt; | 834 | *ppos += cnt; |
835 | 835 | ||
836 | return ret; | 836 | return ret; |
837 | } | 837 | } |
838 | 838 | ||
839 | enum { | 839 | enum { |
840 | FORMAT_HEADER = 1, | 840 | FORMAT_HEADER = 1, |
841 | FORMAT_FIELD_SEPERATOR = 2, | 841 | FORMAT_FIELD_SEPERATOR = 2, |
842 | FORMAT_PRINTFMT = 3, | 842 | FORMAT_PRINTFMT = 3, |
843 | }; | 843 | }; |
844 | 844 | ||
845 | static void *f_next(struct seq_file *m, void *v, loff_t *pos) | 845 | static void *f_next(struct seq_file *m, void *v, loff_t *pos) |
846 | { | 846 | { |
847 | struct ftrace_event_call *call = event_file_data(m->private); | 847 | struct ftrace_event_call *call = event_file_data(m->private); |
848 | struct list_head *common_head = &ftrace_common_fields; | 848 | struct list_head *common_head = &ftrace_common_fields; |
849 | struct list_head *head = trace_get_fields(call); | 849 | struct list_head *head = trace_get_fields(call); |
850 | struct list_head *node = v; | 850 | struct list_head *node = v; |
851 | 851 | ||
852 | (*pos)++; | 852 | (*pos)++; |
853 | 853 | ||
854 | switch ((unsigned long)v) { | 854 | switch ((unsigned long)v) { |
855 | case FORMAT_HEADER: | 855 | case FORMAT_HEADER: |
856 | node = common_head; | 856 | node = common_head; |
857 | break; | 857 | break; |
858 | 858 | ||
859 | case FORMAT_FIELD_SEPERATOR: | 859 | case FORMAT_FIELD_SEPERATOR: |
860 | node = head; | 860 | node = head; |
861 | break; | 861 | break; |
862 | 862 | ||
863 | case FORMAT_PRINTFMT: | 863 | case FORMAT_PRINTFMT: |
864 | /* all done */ | 864 | /* all done */ |
865 | return NULL; | 865 | return NULL; |
866 | } | 866 | } |
867 | 867 | ||
868 | node = node->prev; | 868 | node = node->prev; |
869 | if (node == common_head) | 869 | if (node == common_head) |
870 | return (void *)FORMAT_FIELD_SEPERATOR; | 870 | return (void *)FORMAT_FIELD_SEPERATOR; |
871 | else if (node == head) | 871 | else if (node == head) |
872 | return (void *)FORMAT_PRINTFMT; | 872 | return (void *)FORMAT_PRINTFMT; |
873 | else | 873 | else |
874 | return node; | 874 | return node; |
875 | } | 875 | } |
876 | 876 | ||
877 | static int f_show(struct seq_file *m, void *v) | 877 | static int f_show(struct seq_file *m, void *v) |
878 | { | 878 | { |
879 | struct ftrace_event_call *call = event_file_data(m->private); | 879 | struct ftrace_event_call *call = event_file_data(m->private); |
880 | struct ftrace_event_field *field; | 880 | struct ftrace_event_field *field; |
881 | const char *array_descriptor; | 881 | const char *array_descriptor; |
882 | 882 | ||
883 | switch ((unsigned long)v) { | 883 | switch ((unsigned long)v) { |
884 | case FORMAT_HEADER: | 884 | case FORMAT_HEADER: |
885 | seq_printf(m, "name: %s\n", call->name); | 885 | seq_printf(m, "name: %s\n", call->name); |
886 | seq_printf(m, "ID: %d\n", call->event.type); | 886 | seq_printf(m, "ID: %d\n", call->event.type); |
887 | seq_printf(m, "format:\n"); | 887 | seq_printf(m, "format:\n"); |
888 | return 0; | 888 | return 0; |
889 | 889 | ||
890 | case FORMAT_FIELD_SEPERATOR: | 890 | case FORMAT_FIELD_SEPERATOR: |
891 | seq_putc(m, '\n'); | 891 | seq_putc(m, '\n'); |
892 | return 0; | 892 | return 0; |
893 | 893 | ||
894 | case FORMAT_PRINTFMT: | 894 | case FORMAT_PRINTFMT: |
895 | seq_printf(m, "\nprint fmt: %s\n", | 895 | seq_printf(m, "\nprint fmt: %s\n", |
896 | call->print_fmt); | 896 | call->print_fmt); |
897 | return 0; | 897 | return 0; |
898 | } | 898 | } |
899 | 899 | ||
900 | field = list_entry(v, struct ftrace_event_field, link); | 900 | field = list_entry(v, struct ftrace_event_field, link); |
901 | /* | 901 | /* |
902 | * Smartly shows the array type(except dynamic array). | 902 | * Smartly shows the array type(except dynamic array). |
903 | * Normal: | 903 | * Normal: |
904 | * field:TYPE VAR | 904 | * field:TYPE VAR |
905 | * If TYPE := TYPE[LEN], it is shown: | 905 | * If TYPE := TYPE[LEN], it is shown: |
906 | * field:TYPE VAR[LEN] | 906 | * field:TYPE VAR[LEN] |
907 | */ | 907 | */ |
908 | array_descriptor = strchr(field->type, '['); | 908 | array_descriptor = strchr(field->type, '['); |
909 | 909 | ||
910 | if (!strncmp(field->type, "__data_loc", 10)) | 910 | if (!strncmp(field->type, "__data_loc", 10)) |
911 | array_descriptor = NULL; | 911 | array_descriptor = NULL; |
912 | 912 | ||
913 | if (!array_descriptor) | 913 | if (!array_descriptor) |
914 | seq_printf(m, "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n", | 914 | seq_printf(m, "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n", |
915 | field->type, field->name, field->offset, | 915 | field->type, field->name, field->offset, |
916 | field->size, !!field->is_signed); | 916 | field->size, !!field->is_signed); |
917 | else | 917 | else |
918 | seq_printf(m, "\tfield:%.*s %s%s;\toffset:%u;\tsize:%u;\tsigned:%d;\n", | 918 | seq_printf(m, "\tfield:%.*s %s%s;\toffset:%u;\tsize:%u;\tsigned:%d;\n", |
919 | (int)(array_descriptor - field->type), | 919 | (int)(array_descriptor - field->type), |
920 | field->type, field->name, | 920 | field->type, field->name, |
921 | array_descriptor, field->offset, | 921 | array_descriptor, field->offset, |
922 | field->size, !!field->is_signed); | 922 | field->size, !!field->is_signed); |
923 | 923 | ||
924 | return 0; | 924 | return 0; |
925 | } | 925 | } |
926 | 926 | ||
927 | static void *f_start(struct seq_file *m, loff_t *pos) | 927 | static void *f_start(struct seq_file *m, loff_t *pos) |
928 | { | 928 | { |
929 | void *p = (void *)FORMAT_HEADER; | 929 | void *p = (void *)FORMAT_HEADER; |
930 | loff_t l = 0; | 930 | loff_t l = 0; |
931 | 931 | ||
932 | /* ->stop() is called even if ->start() fails */ | 932 | /* ->stop() is called even if ->start() fails */ |
933 | mutex_lock(&event_mutex); | 933 | mutex_lock(&event_mutex); |
934 | if (!event_file_data(m->private)) | 934 | if (!event_file_data(m->private)) |
935 | return ERR_PTR(-ENODEV); | 935 | return ERR_PTR(-ENODEV); |
936 | 936 | ||
937 | while (l < *pos && p) | 937 | while (l < *pos && p) |
938 | p = f_next(m, p, &l); | 938 | p = f_next(m, p, &l); |
939 | 939 | ||
940 | return p; | 940 | return p; |
941 | } | 941 | } |
942 | 942 | ||
943 | static void f_stop(struct seq_file *m, void *p) | 943 | static void f_stop(struct seq_file *m, void *p) |
944 | { | 944 | { |
945 | mutex_unlock(&event_mutex); | 945 | mutex_unlock(&event_mutex); |
946 | } | 946 | } |
947 | 947 | ||
948 | static const struct seq_operations trace_format_seq_ops = { | 948 | static const struct seq_operations trace_format_seq_ops = { |
949 | .start = f_start, | 949 | .start = f_start, |
950 | .next = f_next, | 950 | .next = f_next, |
951 | .stop = f_stop, | 951 | .stop = f_stop, |
952 | .show = f_show, | 952 | .show = f_show, |
953 | }; | 953 | }; |
954 | 954 | ||
955 | static int trace_format_open(struct inode *inode, struct file *file) | 955 | static int trace_format_open(struct inode *inode, struct file *file) |
956 | { | 956 | { |
957 | struct seq_file *m; | 957 | struct seq_file *m; |
958 | int ret; | 958 | int ret; |
959 | 959 | ||
960 | ret = seq_open(file, &trace_format_seq_ops); | 960 | ret = seq_open(file, &trace_format_seq_ops); |
961 | if (ret < 0) | 961 | if (ret < 0) |
962 | return ret; | 962 | return ret; |
963 | 963 | ||
964 | m = file->private_data; | 964 | m = file->private_data; |
965 | m->private = file; | 965 | m->private = file; |
966 | 966 | ||
967 | return 0; | 967 | return 0; |
968 | } | 968 | } |
969 | 969 | ||
970 | static ssize_t | 970 | static ssize_t |
971 | event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) | 971 | event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) |
972 | { | 972 | { |
973 | int id = (long)event_file_data(filp); | 973 | int id = (long)event_file_data(filp); |
974 | char buf[32]; | 974 | char buf[32]; |
975 | int len; | 975 | int len; |
976 | 976 | ||
977 | if (*ppos) | 977 | if (*ppos) |
978 | return 0; | 978 | return 0; |
979 | 979 | ||
980 | if (unlikely(!id)) | 980 | if (unlikely(!id)) |
981 | return -ENODEV; | 981 | return -ENODEV; |
982 | 982 | ||
983 | len = sprintf(buf, "%d\n", id); | 983 | len = sprintf(buf, "%d\n", id); |
984 | 984 | ||
985 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); | 985 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); |
986 | } | 986 | } |
987 | 987 | ||
988 | static ssize_t | 988 | static ssize_t |
989 | event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, | 989 | event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, |
990 | loff_t *ppos) | 990 | loff_t *ppos) |
991 | { | 991 | { |
992 | struct ftrace_event_call *call; | 992 | struct ftrace_event_call *call; |
993 | struct trace_seq *s; | 993 | struct trace_seq *s; |
994 | int r = -ENODEV; | 994 | int r = -ENODEV; |
995 | 995 | ||
996 | if (*ppos) | 996 | if (*ppos) |
997 | return 0; | 997 | return 0; |
998 | 998 | ||
999 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 999 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
1000 | 1000 | ||
1001 | if (!s) | 1001 | if (!s) |
1002 | return -ENOMEM; | 1002 | return -ENOMEM; |
1003 | 1003 | ||
1004 | trace_seq_init(s); | 1004 | trace_seq_init(s); |
1005 | 1005 | ||
1006 | mutex_lock(&event_mutex); | 1006 | mutex_lock(&event_mutex); |
1007 | call = event_file_data(filp); | 1007 | call = event_file_data(filp); |
1008 | if (call) | 1008 | if (call) |
1009 | print_event_filter(call, s); | 1009 | print_event_filter(call, s); |
1010 | mutex_unlock(&event_mutex); | 1010 | mutex_unlock(&event_mutex); |
1011 | 1011 | ||
1012 | if (call) | 1012 | if (call) |
1013 | r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); | 1013 | r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); |
1014 | 1014 | ||
1015 | kfree(s); | 1015 | kfree(s); |
1016 | 1016 | ||
1017 | return r; | 1017 | return r; |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | static ssize_t | 1020 | static ssize_t |
1021 | event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, | 1021 | event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, |
1022 | loff_t *ppos) | 1022 | loff_t *ppos) |
1023 | { | 1023 | { |
1024 | struct ftrace_event_call *call; | 1024 | struct ftrace_event_call *call; |
1025 | char *buf; | 1025 | char *buf; |
1026 | int err = -ENODEV; | 1026 | int err = -ENODEV; |
1027 | 1027 | ||
1028 | if (cnt >= PAGE_SIZE) | 1028 | if (cnt >= PAGE_SIZE) |
1029 | return -EINVAL; | 1029 | return -EINVAL; |
1030 | 1030 | ||
1031 | buf = (char *)__get_free_page(GFP_TEMPORARY); | 1031 | buf = (char *)__get_free_page(GFP_TEMPORARY); |
1032 | if (!buf) | 1032 | if (!buf) |
1033 | return -ENOMEM; | 1033 | return -ENOMEM; |
1034 | 1034 | ||
1035 | if (copy_from_user(buf, ubuf, cnt)) { | 1035 | if (copy_from_user(buf, ubuf, cnt)) { |
1036 | free_page((unsigned long) buf); | 1036 | free_page((unsigned long) buf); |
1037 | return -EFAULT; | 1037 | return -EFAULT; |
1038 | } | 1038 | } |
1039 | buf[cnt] = '\0'; | 1039 | buf[cnt] = '\0'; |
1040 | 1040 | ||
1041 | mutex_lock(&event_mutex); | 1041 | mutex_lock(&event_mutex); |
1042 | call = event_file_data(filp); | 1042 | call = event_file_data(filp); |
1043 | if (call) | 1043 | if (call) |
1044 | err = apply_event_filter(call, buf); | 1044 | err = apply_event_filter(call, buf); |
1045 | mutex_unlock(&event_mutex); | 1045 | mutex_unlock(&event_mutex); |
1046 | 1046 | ||
1047 | free_page((unsigned long) buf); | 1047 | free_page((unsigned long) buf); |
1048 | if (err < 0) | 1048 | if (err < 0) |
1049 | return err; | 1049 | return err; |
1050 | 1050 | ||
1051 | *ppos += cnt; | 1051 | *ppos += cnt; |
1052 | 1052 | ||
1053 | return cnt; | 1053 | return cnt; |
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | static LIST_HEAD(event_subsystems); | 1056 | static LIST_HEAD(event_subsystems); |
1057 | 1057 | ||
1058 | static int subsystem_open(struct inode *inode, struct file *filp) | 1058 | static int subsystem_open(struct inode *inode, struct file *filp) |
1059 | { | 1059 | { |
1060 | struct event_subsystem *system = NULL; | 1060 | struct event_subsystem *system = NULL; |
1061 | struct ftrace_subsystem_dir *dir = NULL; /* Initialize for gcc */ | 1061 | struct ftrace_subsystem_dir *dir = NULL; /* Initialize for gcc */ |
1062 | struct trace_array *tr; | 1062 | struct trace_array *tr; |
1063 | int ret; | 1063 | int ret; |
1064 | 1064 | ||
1065 | /* Make sure the system still exists */ | 1065 | /* Make sure the system still exists */ |
1066 | mutex_lock(&trace_types_lock); | 1066 | mutex_lock(&trace_types_lock); |
1067 | mutex_lock(&event_mutex); | 1067 | mutex_lock(&event_mutex); |
1068 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 1068 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
1069 | list_for_each_entry(dir, &tr->systems, list) { | 1069 | list_for_each_entry(dir, &tr->systems, list) { |
1070 | if (dir == inode->i_private) { | 1070 | if (dir == inode->i_private) { |
1071 | /* Don't open systems with no events */ | 1071 | /* Don't open systems with no events */ |
1072 | if (dir->nr_events) { | 1072 | if (dir->nr_events) { |
1073 | __get_system_dir(dir); | 1073 | __get_system_dir(dir); |
1074 | system = dir->subsystem; | 1074 | system = dir->subsystem; |
1075 | } | 1075 | } |
1076 | goto exit_loop; | 1076 | goto exit_loop; |
1077 | } | 1077 | } |
1078 | } | 1078 | } |
1079 | } | 1079 | } |
1080 | exit_loop: | 1080 | exit_loop: |
1081 | mutex_unlock(&event_mutex); | 1081 | mutex_unlock(&event_mutex); |
1082 | mutex_unlock(&trace_types_lock); | 1082 | mutex_unlock(&trace_types_lock); |
1083 | 1083 | ||
1084 | if (!system) | 1084 | if (!system) |
1085 | return -ENODEV; | 1085 | return -ENODEV; |
1086 | 1086 | ||
1087 | /* Some versions of gcc think dir can be uninitialized here */ | 1087 | /* Some versions of gcc think dir can be uninitialized here */ |
1088 | WARN_ON(!dir); | 1088 | WARN_ON(!dir); |
1089 | 1089 | ||
1090 | /* Still need to increment the ref count of the system */ | 1090 | /* Still need to increment the ref count of the system */ |
1091 | if (trace_array_get(tr) < 0) { | 1091 | if (trace_array_get(tr) < 0) { |
1092 | put_system(dir); | 1092 | put_system(dir); |
1093 | return -ENODEV; | 1093 | return -ENODEV; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | ret = tracing_open_generic(inode, filp); | 1096 | ret = tracing_open_generic(inode, filp); |
1097 | if (ret < 0) { | 1097 | if (ret < 0) { |
1098 | trace_array_put(tr); | 1098 | trace_array_put(tr); |
1099 | put_system(dir); | 1099 | put_system(dir); |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | return ret; | 1102 | return ret; |
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | static int system_tr_open(struct inode *inode, struct file *filp) | 1105 | static int system_tr_open(struct inode *inode, struct file *filp) |
1106 | { | 1106 | { |
1107 | struct ftrace_subsystem_dir *dir; | 1107 | struct ftrace_subsystem_dir *dir; |
1108 | struct trace_array *tr = inode->i_private; | 1108 | struct trace_array *tr = inode->i_private; |
1109 | int ret; | 1109 | int ret; |
1110 | 1110 | ||
1111 | if (trace_array_get(tr) < 0) | 1111 | if (trace_array_get(tr) < 0) |
1112 | return -ENODEV; | 1112 | return -ENODEV; |
1113 | 1113 | ||
1114 | /* Make a temporary dir that has no system but points to tr */ | 1114 | /* Make a temporary dir that has no system but points to tr */ |
1115 | dir = kzalloc(sizeof(*dir), GFP_KERNEL); | 1115 | dir = kzalloc(sizeof(*dir), GFP_KERNEL); |
1116 | if (!dir) { | 1116 | if (!dir) { |
1117 | trace_array_put(tr); | 1117 | trace_array_put(tr); |
1118 | return -ENOMEM; | 1118 | return -ENOMEM; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | dir->tr = tr; | 1121 | dir->tr = tr; |
1122 | 1122 | ||
1123 | ret = tracing_open_generic(inode, filp); | 1123 | ret = tracing_open_generic(inode, filp); |
1124 | if (ret < 0) { | 1124 | if (ret < 0) { |
1125 | trace_array_put(tr); | 1125 | trace_array_put(tr); |
1126 | kfree(dir); | 1126 | kfree(dir); |
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | filp->private_data = dir; | 1129 | filp->private_data = dir; |
1130 | 1130 | ||
1131 | return ret; | 1131 | return ret; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | static int subsystem_release(struct inode *inode, struct file *file) | 1134 | static int subsystem_release(struct inode *inode, struct file *file) |
1135 | { | 1135 | { |
1136 | struct ftrace_subsystem_dir *dir = file->private_data; | 1136 | struct ftrace_subsystem_dir *dir = file->private_data; |
1137 | 1137 | ||
1138 | trace_array_put(dir->tr); | 1138 | trace_array_put(dir->tr); |
1139 | 1139 | ||
1140 | /* | 1140 | /* |
1141 | * If dir->subsystem is NULL, then this is a temporary | 1141 | * If dir->subsystem is NULL, then this is a temporary |
1142 | * descriptor that was made for a trace_array to enable | 1142 | * descriptor that was made for a trace_array to enable |
1143 | * all subsystems. | 1143 | * all subsystems. |
1144 | */ | 1144 | */ |
1145 | if (dir->subsystem) | 1145 | if (dir->subsystem) |
1146 | put_system(dir); | 1146 | put_system(dir); |
1147 | else | 1147 | else |
1148 | kfree(dir); | 1148 | kfree(dir); |
1149 | 1149 | ||
1150 | return 0; | 1150 | return 0; |
1151 | } | 1151 | } |
1152 | 1152 | ||
1153 | static ssize_t | 1153 | static ssize_t |
1154 | subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, | 1154 | subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, |
1155 | loff_t *ppos) | 1155 | loff_t *ppos) |
1156 | { | 1156 | { |
1157 | struct ftrace_subsystem_dir *dir = filp->private_data; | 1157 | struct ftrace_subsystem_dir *dir = filp->private_data; |
1158 | struct event_subsystem *system = dir->subsystem; | 1158 | struct event_subsystem *system = dir->subsystem; |
1159 | struct trace_seq *s; | 1159 | struct trace_seq *s; |
1160 | int r; | 1160 | int r; |
1161 | 1161 | ||
1162 | if (*ppos) | 1162 | if (*ppos) |
1163 | return 0; | 1163 | return 0; |
1164 | 1164 | ||
1165 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 1165 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
1166 | if (!s) | 1166 | if (!s) |
1167 | return -ENOMEM; | 1167 | return -ENOMEM; |
1168 | 1168 | ||
1169 | trace_seq_init(s); | 1169 | trace_seq_init(s); |
1170 | 1170 | ||
1171 | print_subsystem_event_filter(system, s); | 1171 | print_subsystem_event_filter(system, s); |
1172 | r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); | 1172 | r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); |
1173 | 1173 | ||
1174 | kfree(s); | 1174 | kfree(s); |
1175 | 1175 | ||
1176 | return r; | 1176 | return r; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static ssize_t | 1179 | static ssize_t |
1180 | subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, | 1180 | subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, |
1181 | loff_t *ppos) | 1181 | loff_t *ppos) |
1182 | { | 1182 | { |
1183 | struct ftrace_subsystem_dir *dir = filp->private_data; | 1183 | struct ftrace_subsystem_dir *dir = filp->private_data; |
1184 | char *buf; | 1184 | char *buf; |
1185 | int err; | 1185 | int err; |
1186 | 1186 | ||
1187 | if (cnt >= PAGE_SIZE) | 1187 | if (cnt >= PAGE_SIZE) |
1188 | return -EINVAL; | 1188 | return -EINVAL; |
1189 | 1189 | ||
1190 | buf = (char *)__get_free_page(GFP_TEMPORARY); | 1190 | buf = (char *)__get_free_page(GFP_TEMPORARY); |
1191 | if (!buf) | 1191 | if (!buf) |
1192 | return -ENOMEM; | 1192 | return -ENOMEM; |
1193 | 1193 | ||
1194 | if (copy_from_user(buf, ubuf, cnt)) { | 1194 | if (copy_from_user(buf, ubuf, cnt)) { |
1195 | free_page((unsigned long) buf); | 1195 | free_page((unsigned long) buf); |
1196 | return -EFAULT; | 1196 | return -EFAULT; |
1197 | } | 1197 | } |
1198 | buf[cnt] = '\0'; | 1198 | buf[cnt] = '\0'; |
1199 | 1199 | ||
1200 | err = apply_subsystem_event_filter(dir, buf); | 1200 | err = apply_subsystem_event_filter(dir, buf); |
1201 | free_page((unsigned long) buf); | 1201 | free_page((unsigned long) buf); |
1202 | if (err < 0) | 1202 | if (err < 0) |
1203 | return err; | 1203 | return err; |
1204 | 1204 | ||
1205 | *ppos += cnt; | 1205 | *ppos += cnt; |
1206 | 1206 | ||
1207 | return cnt; | 1207 | return cnt; |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | static ssize_t | 1210 | static ssize_t |
1211 | show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) | 1211 | show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) |
1212 | { | 1212 | { |
1213 | int (*func)(struct trace_seq *s) = filp->private_data; | 1213 | int (*func)(struct trace_seq *s) = filp->private_data; |
1214 | struct trace_seq *s; | 1214 | struct trace_seq *s; |
1215 | int r; | 1215 | int r; |
1216 | 1216 | ||
1217 | if (*ppos) | 1217 | if (*ppos) |
1218 | return 0; | 1218 | return 0; |
1219 | 1219 | ||
1220 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 1220 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
1221 | if (!s) | 1221 | if (!s) |
1222 | return -ENOMEM; | 1222 | return -ENOMEM; |
1223 | 1223 | ||
1224 | trace_seq_init(s); | 1224 | trace_seq_init(s); |
1225 | 1225 | ||
1226 | func(s); | 1226 | func(s); |
1227 | r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); | 1227 | r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); |
1228 | 1228 | ||
1229 | kfree(s); | 1229 | kfree(s); |
1230 | 1230 | ||
1231 | return r; | 1231 | return r; |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | static int ftrace_event_avail_open(struct inode *inode, struct file *file); | 1234 | static int ftrace_event_avail_open(struct inode *inode, struct file *file); |
1235 | static int ftrace_event_set_open(struct inode *inode, struct file *file); | 1235 | static int ftrace_event_set_open(struct inode *inode, struct file *file); |
1236 | static int ftrace_event_release(struct inode *inode, struct file *file); | 1236 | static int ftrace_event_release(struct inode *inode, struct file *file); |
1237 | 1237 | ||
1238 | static const struct seq_operations show_event_seq_ops = { | 1238 | static const struct seq_operations show_event_seq_ops = { |
1239 | .start = t_start, | 1239 | .start = t_start, |
1240 | .next = t_next, | 1240 | .next = t_next, |
1241 | .show = t_show, | 1241 | .show = t_show, |
1242 | .stop = t_stop, | 1242 | .stop = t_stop, |
1243 | }; | 1243 | }; |
1244 | 1244 | ||
1245 | static const struct seq_operations show_set_event_seq_ops = { | 1245 | static const struct seq_operations show_set_event_seq_ops = { |
1246 | .start = s_start, | 1246 | .start = s_start, |
1247 | .next = s_next, | 1247 | .next = s_next, |
1248 | .show = t_show, | 1248 | .show = t_show, |
1249 | .stop = t_stop, | 1249 | .stop = t_stop, |
1250 | }; | 1250 | }; |
1251 | 1251 | ||
1252 | static const struct file_operations ftrace_avail_fops = { | 1252 | static const struct file_operations ftrace_avail_fops = { |
1253 | .open = ftrace_event_avail_open, | 1253 | .open = ftrace_event_avail_open, |
1254 | .read = seq_read, | 1254 | .read = seq_read, |
1255 | .llseek = seq_lseek, | 1255 | .llseek = seq_lseek, |
1256 | .release = seq_release, | 1256 | .release = seq_release, |
1257 | }; | 1257 | }; |
1258 | 1258 | ||
1259 | static const struct file_operations ftrace_set_event_fops = { | 1259 | static const struct file_operations ftrace_set_event_fops = { |
1260 | .open = ftrace_event_set_open, | 1260 | .open = ftrace_event_set_open, |
1261 | .read = seq_read, | 1261 | .read = seq_read, |
1262 | .write = ftrace_event_write, | 1262 | .write = ftrace_event_write, |
1263 | .llseek = seq_lseek, | 1263 | .llseek = seq_lseek, |
1264 | .release = ftrace_event_release, | 1264 | .release = ftrace_event_release, |
1265 | }; | 1265 | }; |
1266 | 1266 | ||
1267 | static const struct file_operations ftrace_enable_fops = { | 1267 | static const struct file_operations ftrace_enable_fops = { |
1268 | .open = tracing_open_generic, | 1268 | .open = tracing_open_generic, |
1269 | .read = event_enable_read, | 1269 | .read = event_enable_read, |
1270 | .write = event_enable_write, | 1270 | .write = event_enable_write, |
1271 | .llseek = default_llseek, | 1271 | .llseek = default_llseek, |
1272 | }; | 1272 | }; |
1273 | 1273 | ||
1274 | static const struct file_operations ftrace_event_format_fops = { | 1274 | static const struct file_operations ftrace_event_format_fops = { |
1275 | .open = trace_format_open, | 1275 | .open = trace_format_open, |
1276 | .read = seq_read, | 1276 | .read = seq_read, |
1277 | .llseek = seq_lseek, | 1277 | .llseek = seq_lseek, |
1278 | .release = seq_release, | 1278 | .release = seq_release, |
1279 | }; | 1279 | }; |
1280 | 1280 | ||
1281 | static const struct file_operations ftrace_event_id_fops = { | 1281 | static const struct file_operations ftrace_event_id_fops = { |
1282 | .read = event_id_read, | 1282 | .read = event_id_read, |
1283 | .llseek = default_llseek, | 1283 | .llseek = default_llseek, |
1284 | }; | 1284 | }; |
1285 | 1285 | ||
1286 | static const struct file_operations ftrace_event_filter_fops = { | 1286 | static const struct file_operations ftrace_event_filter_fops = { |
1287 | .open = tracing_open_generic, | 1287 | .open = tracing_open_generic, |
1288 | .read = event_filter_read, | 1288 | .read = event_filter_read, |
1289 | .write = event_filter_write, | 1289 | .write = event_filter_write, |
1290 | .llseek = default_llseek, | 1290 | .llseek = default_llseek, |
1291 | }; | 1291 | }; |
1292 | 1292 | ||
1293 | static const struct file_operations ftrace_subsystem_filter_fops = { | 1293 | static const struct file_operations ftrace_subsystem_filter_fops = { |
1294 | .open = subsystem_open, | 1294 | .open = subsystem_open, |
1295 | .read = subsystem_filter_read, | 1295 | .read = subsystem_filter_read, |
1296 | .write = subsystem_filter_write, | 1296 | .write = subsystem_filter_write, |
1297 | .llseek = default_llseek, | 1297 | .llseek = default_llseek, |
1298 | .release = subsystem_release, | 1298 | .release = subsystem_release, |
1299 | }; | 1299 | }; |
1300 | 1300 | ||
1301 | static const struct file_operations ftrace_system_enable_fops = { | 1301 | static const struct file_operations ftrace_system_enable_fops = { |
1302 | .open = subsystem_open, | 1302 | .open = subsystem_open, |
1303 | .read = system_enable_read, | 1303 | .read = system_enable_read, |
1304 | .write = system_enable_write, | 1304 | .write = system_enable_write, |
1305 | .llseek = default_llseek, | 1305 | .llseek = default_llseek, |
1306 | .release = subsystem_release, | 1306 | .release = subsystem_release, |
1307 | }; | 1307 | }; |
1308 | 1308 | ||
1309 | static const struct file_operations ftrace_tr_enable_fops = { | 1309 | static const struct file_operations ftrace_tr_enable_fops = { |
1310 | .open = system_tr_open, | 1310 | .open = system_tr_open, |
1311 | .read = system_enable_read, | 1311 | .read = system_enable_read, |
1312 | .write = system_enable_write, | 1312 | .write = system_enable_write, |
1313 | .llseek = default_llseek, | 1313 | .llseek = default_llseek, |
1314 | .release = subsystem_release, | 1314 | .release = subsystem_release, |
1315 | }; | 1315 | }; |
1316 | 1316 | ||
1317 | static const struct file_operations ftrace_show_header_fops = { | 1317 | static const struct file_operations ftrace_show_header_fops = { |
1318 | .open = tracing_open_generic, | 1318 | .open = tracing_open_generic, |
1319 | .read = show_header, | 1319 | .read = show_header, |
1320 | .llseek = default_llseek, | 1320 | .llseek = default_llseek, |
1321 | }; | 1321 | }; |
1322 | 1322 | ||
1323 | static int | 1323 | static int |
1324 | ftrace_event_open(struct inode *inode, struct file *file, | 1324 | ftrace_event_open(struct inode *inode, struct file *file, |
1325 | const struct seq_operations *seq_ops) | 1325 | const struct seq_operations *seq_ops) |
1326 | { | 1326 | { |
1327 | struct seq_file *m; | 1327 | struct seq_file *m; |
1328 | int ret; | 1328 | int ret; |
1329 | 1329 | ||
1330 | ret = seq_open(file, seq_ops); | 1330 | ret = seq_open(file, seq_ops); |
1331 | if (ret < 0) | 1331 | if (ret < 0) |
1332 | return ret; | 1332 | return ret; |
1333 | m = file->private_data; | 1333 | m = file->private_data; |
1334 | /* copy tr over to seq ops */ | 1334 | /* copy tr over to seq ops */ |
1335 | m->private = inode->i_private; | 1335 | m->private = inode->i_private; |
1336 | 1336 | ||
1337 | return ret; | 1337 | return ret; |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | static int ftrace_event_release(struct inode *inode, struct file *file) | 1340 | static int ftrace_event_release(struct inode *inode, struct file *file) |
1341 | { | 1341 | { |
1342 | struct trace_array *tr = inode->i_private; | 1342 | struct trace_array *tr = inode->i_private; |
1343 | 1343 | ||
1344 | trace_array_put(tr); | 1344 | trace_array_put(tr); |
1345 | 1345 | ||
1346 | return seq_release(inode, file); | 1346 | return seq_release(inode, file); |
1347 | } | 1347 | } |
1348 | 1348 | ||
1349 | static int | 1349 | static int |
1350 | ftrace_event_avail_open(struct inode *inode, struct file *file) | 1350 | ftrace_event_avail_open(struct inode *inode, struct file *file) |
1351 | { | 1351 | { |
1352 | const struct seq_operations *seq_ops = &show_event_seq_ops; | 1352 | const struct seq_operations *seq_ops = &show_event_seq_ops; |
1353 | 1353 | ||
1354 | return ftrace_event_open(inode, file, seq_ops); | 1354 | return ftrace_event_open(inode, file, seq_ops); |
1355 | } | 1355 | } |
1356 | 1356 | ||
1357 | static int | 1357 | static int |
1358 | ftrace_event_set_open(struct inode *inode, struct file *file) | 1358 | ftrace_event_set_open(struct inode *inode, struct file *file) |
1359 | { | 1359 | { |
1360 | const struct seq_operations *seq_ops = &show_set_event_seq_ops; | 1360 | const struct seq_operations *seq_ops = &show_set_event_seq_ops; |
1361 | struct trace_array *tr = inode->i_private; | 1361 | struct trace_array *tr = inode->i_private; |
1362 | int ret; | 1362 | int ret; |
1363 | 1363 | ||
1364 | if (trace_array_get(tr) < 0) | 1364 | if (trace_array_get(tr) < 0) |
1365 | return -ENODEV; | 1365 | return -ENODEV; |
1366 | 1366 | ||
1367 | if ((file->f_mode & FMODE_WRITE) && | 1367 | if ((file->f_mode & FMODE_WRITE) && |
1368 | (file->f_flags & O_TRUNC)) | 1368 | (file->f_flags & O_TRUNC)) |
1369 | ftrace_clear_events(tr); | 1369 | ftrace_clear_events(tr); |
1370 | 1370 | ||
1371 | ret = ftrace_event_open(inode, file, seq_ops); | 1371 | ret = ftrace_event_open(inode, file, seq_ops); |
1372 | if (ret < 0) | 1372 | if (ret < 0) |
1373 | trace_array_put(tr); | 1373 | trace_array_put(tr); |
1374 | return ret; | 1374 | return ret; |
1375 | } | 1375 | } |
1376 | 1376 | ||
1377 | static struct event_subsystem * | 1377 | static struct event_subsystem * |
1378 | create_new_subsystem(const char *name) | 1378 | create_new_subsystem(const char *name) |
1379 | { | 1379 | { |
1380 | struct event_subsystem *system; | 1380 | struct event_subsystem *system; |
1381 | 1381 | ||
1382 | /* need to create new entry */ | 1382 | /* need to create new entry */ |
1383 | system = kmalloc(sizeof(*system), GFP_KERNEL); | 1383 | system = kmalloc(sizeof(*system), GFP_KERNEL); |
1384 | if (!system) | 1384 | if (!system) |
1385 | return NULL; | 1385 | return NULL; |
1386 | 1386 | ||
1387 | system->ref_count = 1; | 1387 | system->ref_count = 1; |
1388 | 1388 | ||
1389 | /* Only allocate if dynamic (kprobes and modules) */ | 1389 | /* Only allocate if dynamic (kprobes and modules) */ |
1390 | if (!core_kernel_data((unsigned long)name)) { | 1390 | if (!core_kernel_data((unsigned long)name)) { |
1391 | system->ref_count |= SYSTEM_FL_FREE_NAME; | 1391 | system->ref_count |= SYSTEM_FL_FREE_NAME; |
1392 | system->name = kstrdup(name, GFP_KERNEL); | 1392 | system->name = kstrdup(name, GFP_KERNEL); |
1393 | if (!system->name) | 1393 | if (!system->name) |
1394 | goto out_free; | 1394 | goto out_free; |
1395 | } else | 1395 | } else |
1396 | system->name = name; | 1396 | system->name = name; |
1397 | 1397 | ||
1398 | system->filter = NULL; | 1398 | system->filter = NULL; |
1399 | 1399 | ||
1400 | system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL); | 1400 | system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL); |
1401 | if (!system->filter) | 1401 | if (!system->filter) |
1402 | goto out_free; | 1402 | goto out_free; |
1403 | 1403 | ||
1404 | list_add(&system->list, &event_subsystems); | 1404 | list_add(&system->list, &event_subsystems); |
1405 | 1405 | ||
1406 | return system; | 1406 | return system; |
1407 | 1407 | ||
1408 | out_free: | 1408 | out_free: |
1409 | if (system->ref_count & SYSTEM_FL_FREE_NAME) | 1409 | if (system->ref_count & SYSTEM_FL_FREE_NAME) |
1410 | kfree(system->name); | 1410 | kfree(system->name); |
1411 | kfree(system); | 1411 | kfree(system); |
1412 | return NULL; | 1412 | return NULL; |
1413 | } | 1413 | } |
1414 | 1414 | ||
1415 | static struct dentry * | 1415 | static struct dentry * |
1416 | event_subsystem_dir(struct trace_array *tr, const char *name, | 1416 | event_subsystem_dir(struct trace_array *tr, const char *name, |
1417 | struct ftrace_event_file *file, struct dentry *parent) | 1417 | struct ftrace_event_file *file, struct dentry *parent) |
1418 | { | 1418 | { |
1419 | struct ftrace_subsystem_dir *dir; | 1419 | struct ftrace_subsystem_dir *dir; |
1420 | struct event_subsystem *system; | 1420 | struct event_subsystem *system; |
1421 | struct dentry *entry; | 1421 | struct dentry *entry; |
1422 | 1422 | ||
1423 | /* First see if we did not already create this dir */ | 1423 | /* First see if we did not already create this dir */ |
1424 | list_for_each_entry(dir, &tr->systems, list) { | 1424 | list_for_each_entry(dir, &tr->systems, list) { |
1425 | system = dir->subsystem; | 1425 | system = dir->subsystem; |
1426 | if (strcmp(system->name, name) == 0) { | 1426 | if (strcmp(system->name, name) == 0) { |
1427 | dir->nr_events++; | 1427 | dir->nr_events++; |
1428 | file->system = dir; | 1428 | file->system = dir; |
1429 | return dir->entry; | 1429 | return dir->entry; |
1430 | } | 1430 | } |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | /* Now see if the system itself exists. */ | 1433 | /* Now see if the system itself exists. */ |
1434 | list_for_each_entry(system, &event_subsystems, list) { | 1434 | list_for_each_entry(system, &event_subsystems, list) { |
1435 | if (strcmp(system->name, name) == 0) | 1435 | if (strcmp(system->name, name) == 0) |
1436 | break; | 1436 | break; |
1437 | } | 1437 | } |
1438 | /* Reset system variable when not found */ | 1438 | /* Reset system variable when not found */ |
1439 | if (&system->list == &event_subsystems) | 1439 | if (&system->list == &event_subsystems) |
1440 | system = NULL; | 1440 | system = NULL; |
1441 | 1441 | ||
1442 | dir = kmalloc(sizeof(*dir), GFP_KERNEL); | 1442 | dir = kmalloc(sizeof(*dir), GFP_KERNEL); |
1443 | if (!dir) | 1443 | if (!dir) |
1444 | goto out_fail; | 1444 | goto out_fail; |
1445 | 1445 | ||
1446 | if (!system) { | 1446 | if (!system) { |
1447 | system = create_new_subsystem(name); | 1447 | system = create_new_subsystem(name); |
1448 | if (!system) | 1448 | if (!system) |
1449 | goto out_free; | 1449 | goto out_free; |
1450 | } else | 1450 | } else |
1451 | __get_system(system); | 1451 | __get_system(system); |
1452 | 1452 | ||
1453 | dir->entry = debugfs_create_dir(name, parent); | 1453 | dir->entry = debugfs_create_dir(name, parent); |
1454 | if (!dir->entry) { | 1454 | if (!dir->entry) { |
1455 | pr_warning("Failed to create system directory %s\n", name); | 1455 | pr_warning("Failed to create system directory %s\n", name); |
1456 | __put_system(system); | 1456 | __put_system(system); |
1457 | goto out_free; | 1457 | goto out_free; |
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | dir->tr = tr; | 1460 | dir->tr = tr; |
1461 | dir->ref_count = 1; | 1461 | dir->ref_count = 1; |
1462 | dir->nr_events = 1; | 1462 | dir->nr_events = 1; |
1463 | dir->subsystem = system; | 1463 | dir->subsystem = system; |
1464 | file->system = dir; | 1464 | file->system = dir; |
1465 | 1465 | ||
1466 | entry = debugfs_create_file("filter", 0644, dir->entry, dir, | 1466 | entry = debugfs_create_file("filter", 0644, dir->entry, dir, |
1467 | &ftrace_subsystem_filter_fops); | 1467 | &ftrace_subsystem_filter_fops); |
1468 | if (!entry) { | 1468 | if (!entry) { |
1469 | kfree(system->filter); | 1469 | kfree(system->filter); |
1470 | system->filter = NULL; | 1470 | system->filter = NULL; |
1471 | pr_warning("Could not create debugfs '%s/filter' entry\n", name); | 1471 | pr_warning("Could not create debugfs '%s/filter' entry\n", name); |
1472 | } | 1472 | } |
1473 | 1473 | ||
1474 | trace_create_file("enable", 0644, dir->entry, dir, | 1474 | trace_create_file("enable", 0644, dir->entry, dir, |
1475 | &ftrace_system_enable_fops); | 1475 | &ftrace_system_enable_fops); |
1476 | 1476 | ||
1477 | list_add(&dir->list, &tr->systems); | 1477 | list_add(&dir->list, &tr->systems); |
1478 | 1478 | ||
1479 | return dir->entry; | 1479 | return dir->entry; |
1480 | 1480 | ||
1481 | out_free: | 1481 | out_free: |
1482 | kfree(dir); | 1482 | kfree(dir); |
1483 | out_fail: | 1483 | out_fail: |
1484 | /* Only print this message if failed on memory allocation */ | 1484 | /* Only print this message if failed on memory allocation */ |
1485 | if (!dir || !system) | 1485 | if (!dir || !system) |
1486 | pr_warning("No memory to create event subsystem %s\n", | 1486 | pr_warning("No memory to create event subsystem %s\n", |
1487 | name); | 1487 | name); |
1488 | return NULL; | 1488 | return NULL; |
1489 | } | 1489 | } |
1490 | 1490 | ||
1491 | static int | 1491 | static int |
1492 | event_create_dir(struct dentry *parent, | 1492 | event_create_dir(struct dentry *parent, struct ftrace_event_file *file) |
1493 | struct ftrace_event_file *file, | ||
1494 | const struct file_operations *id, | ||
1495 | const struct file_operations *enable, | ||
1496 | const struct file_operations *filter, | ||
1497 | const struct file_operations *format) | ||
1498 | { | 1493 | { |
1499 | struct ftrace_event_call *call = file->event_call; | 1494 | struct ftrace_event_call *call = file->event_call; |
1500 | struct trace_array *tr = file->tr; | 1495 | struct trace_array *tr = file->tr; |
1501 | struct list_head *head; | 1496 | struct list_head *head; |
1502 | struct dentry *d_events; | 1497 | struct dentry *d_events; |
1503 | int ret; | 1498 | int ret; |
1504 | 1499 | ||
1505 | /* | 1500 | /* |
1506 | * If the trace point header did not define TRACE_SYSTEM | 1501 | * If the trace point header did not define TRACE_SYSTEM |
1507 | * then the system would be called "TRACE_SYSTEM". | 1502 | * then the system would be called "TRACE_SYSTEM". |
1508 | */ | 1503 | */ |
1509 | if (strcmp(call->class->system, TRACE_SYSTEM) != 0) { | 1504 | if (strcmp(call->class->system, TRACE_SYSTEM) != 0) { |
1510 | d_events = event_subsystem_dir(tr, call->class->system, file, parent); | 1505 | d_events = event_subsystem_dir(tr, call->class->system, file, parent); |
1511 | if (!d_events) | 1506 | if (!d_events) |
1512 | return -ENOMEM; | 1507 | return -ENOMEM; |
1513 | } else | 1508 | } else |
1514 | d_events = parent; | 1509 | d_events = parent; |
1515 | 1510 | ||
1516 | file->dir = debugfs_create_dir(call->name, d_events); | 1511 | file->dir = debugfs_create_dir(call->name, d_events); |
1517 | if (!file->dir) { | 1512 | if (!file->dir) { |
1518 | pr_warning("Could not create debugfs '%s' directory\n", | 1513 | pr_warning("Could not create debugfs '%s' directory\n", |
1519 | call->name); | 1514 | call->name); |
1520 | return -1; | 1515 | return -1; |
1521 | } | 1516 | } |
1522 | 1517 | ||
1523 | if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) | 1518 | if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) |
1524 | trace_create_file("enable", 0644, file->dir, file, | 1519 | trace_create_file("enable", 0644, file->dir, file, |
1525 | enable); | 1520 | &ftrace_enable_fops); |
1526 | 1521 | ||
1527 | #ifdef CONFIG_PERF_EVENTS | 1522 | #ifdef CONFIG_PERF_EVENTS |
1528 | if (call->event.type && call->class->reg) | 1523 | if (call->event.type && call->class->reg) |
1529 | trace_create_file("id", 0444, file->dir, | 1524 | trace_create_file("id", 0444, file->dir, |
1530 | (void *)(long)call->event.type, id); | 1525 | (void *)(long)call->event.type, |
1526 | &ftrace_event_id_fops); | ||
1531 | #endif | 1527 | #endif |
1532 | 1528 | ||
1533 | /* | 1529 | /* |
1534 | * Other events may have the same class. Only update | 1530 | * Other events may have the same class. Only update |
1535 | * the fields if they are not already defined. | 1531 | * the fields if they are not already defined. |
1536 | */ | 1532 | */ |
1537 | head = trace_get_fields(call); | 1533 | head = trace_get_fields(call); |
1538 | if (list_empty(head)) { | 1534 | if (list_empty(head)) { |
1539 | ret = call->class->define_fields(call); | 1535 | ret = call->class->define_fields(call); |
1540 | if (ret < 0) { | 1536 | if (ret < 0) { |
1541 | pr_warning("Could not initialize trace point" | 1537 | pr_warning("Could not initialize trace point" |
1542 | " events/%s\n", call->name); | 1538 | " events/%s\n", call->name); |
1543 | return -1; | 1539 | return -1; |
1544 | } | 1540 | } |
1545 | } | 1541 | } |
1546 | trace_create_file("filter", 0644, file->dir, call, | 1542 | trace_create_file("filter", 0644, file->dir, call, |
1547 | filter); | 1543 | &ftrace_event_filter_fops); |
1548 | 1544 | ||
1549 | trace_create_file("format", 0444, file->dir, call, | 1545 | trace_create_file("format", 0444, file->dir, call, |
1550 | format); | 1546 | &ftrace_event_format_fops); |
1551 | 1547 | ||
1552 | return 0; | 1548 | return 0; |
1553 | } | 1549 | } |
1554 | 1550 | ||
1555 | static void remove_event_from_tracers(struct ftrace_event_call *call) | 1551 | static void remove_event_from_tracers(struct ftrace_event_call *call) |
1556 | { | 1552 | { |
1557 | struct ftrace_event_file *file; | 1553 | struct ftrace_event_file *file; |
1558 | struct trace_array *tr; | 1554 | struct trace_array *tr; |
1559 | 1555 | ||
1560 | do_for_each_event_file_safe(tr, file) { | 1556 | do_for_each_event_file_safe(tr, file) { |
1561 | if (file->event_call != call) | 1557 | if (file->event_call != call) |
1562 | continue; | 1558 | continue; |
1563 | 1559 | ||
1564 | remove_event_file_dir(file); | 1560 | remove_event_file_dir(file); |
1565 | /* | 1561 | /* |
1566 | * The do_for_each_event_file_safe() is | 1562 | * The do_for_each_event_file_safe() is |
1567 | * a double loop. After finding the call for this | 1563 | * a double loop. After finding the call for this |
1568 | * trace_array, we use break to jump to the next | 1564 | * trace_array, we use break to jump to the next |
1569 | * trace_array. | 1565 | * trace_array. |
1570 | */ | 1566 | */ |
1571 | break; | 1567 | break; |
1572 | } while_for_each_event_file(); | 1568 | } while_for_each_event_file(); |
1573 | } | 1569 | } |
1574 | 1570 | ||
1575 | static void event_remove(struct ftrace_event_call *call) | 1571 | static void event_remove(struct ftrace_event_call *call) |
1576 | { | 1572 | { |
1577 | struct trace_array *tr; | 1573 | struct trace_array *tr; |
1578 | struct ftrace_event_file *file; | 1574 | struct ftrace_event_file *file; |
1579 | 1575 | ||
1580 | do_for_each_event_file(tr, file) { | 1576 | do_for_each_event_file(tr, file) { |
1581 | if (file->event_call != call) | 1577 | if (file->event_call != call) |
1582 | continue; | 1578 | continue; |
1583 | ftrace_event_enable_disable(file, 0); | 1579 | ftrace_event_enable_disable(file, 0); |
1584 | /* | 1580 | /* |
1585 | * The do_for_each_event_file() is | 1581 | * The do_for_each_event_file() is |
1586 | * a double loop. After finding the call for this | 1582 | * a double loop. After finding the call for this |
1587 | * trace_array, we use break to jump to the next | 1583 | * trace_array, we use break to jump to the next |
1588 | * trace_array. | 1584 | * trace_array. |
1589 | */ | 1585 | */ |
1590 | break; | 1586 | break; |
1591 | } while_for_each_event_file(); | 1587 | } while_for_each_event_file(); |
1592 | 1588 | ||
1593 | if (call->event.funcs) | 1589 | if (call->event.funcs) |
1594 | __unregister_ftrace_event(&call->event); | 1590 | __unregister_ftrace_event(&call->event); |
1595 | remove_event_from_tracers(call); | 1591 | remove_event_from_tracers(call); |
1596 | list_del(&call->list); | 1592 | list_del(&call->list); |
1597 | } | 1593 | } |
1598 | 1594 | ||
1599 | static int event_init(struct ftrace_event_call *call) | 1595 | static int event_init(struct ftrace_event_call *call) |
1600 | { | 1596 | { |
1601 | int ret = 0; | 1597 | int ret = 0; |
1602 | 1598 | ||
1603 | if (WARN_ON(!call->name)) | 1599 | if (WARN_ON(!call->name)) |
1604 | return -EINVAL; | 1600 | return -EINVAL; |
1605 | 1601 | ||
1606 | if (call->class->raw_init) { | 1602 | if (call->class->raw_init) { |
1607 | ret = call->class->raw_init(call); | 1603 | ret = call->class->raw_init(call); |
1608 | if (ret < 0 && ret != -ENOSYS) | 1604 | if (ret < 0 && ret != -ENOSYS) |
1609 | pr_warn("Could not initialize trace events/%s\n", | 1605 | pr_warn("Could not initialize trace events/%s\n", |
1610 | call->name); | 1606 | call->name); |
1611 | } | 1607 | } |
1612 | 1608 | ||
1613 | return ret; | 1609 | return ret; |
1614 | } | 1610 | } |
1615 | 1611 | ||
1616 | static int | 1612 | static int |
1617 | __register_event(struct ftrace_event_call *call, struct module *mod) | 1613 | __register_event(struct ftrace_event_call *call, struct module *mod) |
1618 | { | 1614 | { |
1619 | int ret; | 1615 | int ret; |
1620 | 1616 | ||
1621 | ret = event_init(call); | 1617 | ret = event_init(call); |
1622 | if (ret < 0) | 1618 | if (ret < 0) |
1623 | return ret; | 1619 | return ret; |
1624 | 1620 | ||
1625 | list_add(&call->list, &ftrace_events); | 1621 | list_add(&call->list, &ftrace_events); |
1626 | call->mod = mod; | 1622 | call->mod = mod; |
1627 | 1623 | ||
1628 | return 0; | 1624 | return 0; |
1629 | } | 1625 | } |
1630 | 1626 | ||
1631 | static struct ftrace_event_file * | 1627 | static struct ftrace_event_file * |
1632 | trace_create_new_event(struct ftrace_event_call *call, | 1628 | trace_create_new_event(struct ftrace_event_call *call, |
1633 | struct trace_array *tr) | 1629 | struct trace_array *tr) |
1634 | { | 1630 | { |
1635 | struct ftrace_event_file *file; | 1631 | struct ftrace_event_file *file; |
1636 | 1632 | ||
1637 | file = kmem_cache_alloc(file_cachep, GFP_TRACE); | 1633 | file = kmem_cache_alloc(file_cachep, GFP_TRACE); |
1638 | if (!file) | 1634 | if (!file) |
1639 | return NULL; | 1635 | return NULL; |
1640 | 1636 | ||
1641 | file->event_call = call; | 1637 | file->event_call = call; |
1642 | file->tr = tr; | 1638 | file->tr = tr; |
1643 | atomic_set(&file->sm_ref, 0); | 1639 | atomic_set(&file->sm_ref, 0); |
1644 | list_add(&file->list, &tr->events); | 1640 | list_add(&file->list, &tr->events); |
1645 | 1641 | ||
1646 | return file; | 1642 | return file; |
1647 | } | 1643 | } |
1648 | 1644 | ||
1649 | /* Add an event to a trace directory */ | 1645 | /* Add an event to a trace directory */ |
1650 | static int | 1646 | static int |
1651 | __trace_add_new_event(struct ftrace_event_call *call, | 1647 | __trace_add_new_event(struct ftrace_event_call *call, struct trace_array *tr) |
1652 | struct trace_array *tr, | ||
1653 | const struct file_operations *id, | ||
1654 | const struct file_operations *enable, | ||
1655 | const struct file_operations *filter, | ||
1656 | const struct file_operations *format) | ||
1657 | { | 1648 | { |
1658 | struct ftrace_event_file *file; | 1649 | struct ftrace_event_file *file; |
1659 | 1650 | ||
1660 | file = trace_create_new_event(call, tr); | 1651 | file = trace_create_new_event(call, tr); |
1661 | if (!file) | 1652 | if (!file) |
1662 | return -ENOMEM; | 1653 | return -ENOMEM; |
1663 | 1654 | ||
1664 | return event_create_dir(tr->event_dir, file, id, enable, filter, format); | 1655 | return event_create_dir(tr->event_dir, file); |
1665 | } | 1656 | } |
1666 | 1657 | ||
1667 | /* | 1658 | /* |
1668 | * Just create a decriptor for early init. A descriptor is required | 1659 | * Just create a decriptor for early init. A descriptor is required |
1669 | * for enabling events at boot. We want to enable events before | 1660 | * for enabling events at boot. We want to enable events before |
1670 | * the filesystem is initialized. | 1661 | * the filesystem is initialized. |
1671 | */ | 1662 | */ |
1672 | static __init int | 1663 | static __init int |
1673 | __trace_early_add_new_event(struct ftrace_event_call *call, | 1664 | __trace_early_add_new_event(struct ftrace_event_call *call, |
1674 | struct trace_array *tr) | 1665 | struct trace_array *tr) |
1675 | { | 1666 | { |
1676 | struct ftrace_event_file *file; | 1667 | struct ftrace_event_file *file; |
1677 | 1668 | ||
1678 | file = trace_create_new_event(call, tr); | 1669 | file = trace_create_new_event(call, tr); |
1679 | if (!file) | 1670 | if (!file) |
1680 | return -ENOMEM; | 1671 | return -ENOMEM; |
1681 | 1672 | ||
1682 | return 0; | 1673 | return 0; |
1683 | } | 1674 | } |
1684 | 1675 | ||
1685 | struct ftrace_module_file_ops; | 1676 | struct ftrace_module_file_ops; |
1686 | static void __add_event_to_tracers(struct ftrace_event_call *call, | 1677 | static void __add_event_to_tracers(struct ftrace_event_call *call); |
1687 | struct ftrace_module_file_ops *file_ops); | ||
1688 | 1678 | ||
1689 | /* Add an additional event_call dynamically */ | 1679 | /* Add an additional event_call dynamically */ |
1690 | int trace_add_event_call(struct ftrace_event_call *call) | 1680 | int trace_add_event_call(struct ftrace_event_call *call) |
1691 | { | 1681 | { |
1692 | int ret; | 1682 | int ret; |
1693 | mutex_lock(&trace_types_lock); | 1683 | mutex_lock(&trace_types_lock); |
1694 | mutex_lock(&event_mutex); | 1684 | mutex_lock(&event_mutex); |
1695 | 1685 | ||
1696 | ret = __register_event(call, NULL); | 1686 | ret = __register_event(call, NULL); |
1697 | if (ret >= 0) | 1687 | if (ret >= 0) |
1698 | __add_event_to_tracers(call, NULL); | 1688 | __add_event_to_tracers(call); |
1699 | 1689 | ||
1700 | mutex_unlock(&event_mutex); | 1690 | mutex_unlock(&event_mutex); |
1701 | mutex_unlock(&trace_types_lock); | 1691 | mutex_unlock(&trace_types_lock); |
1702 | return ret; | 1692 | return ret; |
1703 | } | 1693 | } |
1704 | 1694 | ||
1705 | /* | 1695 | /* |
1706 | * Must be called under locking of trace_types_lock, event_mutex and | 1696 | * Must be called under locking of trace_types_lock, event_mutex and |
1707 | * trace_event_sem. | 1697 | * trace_event_sem. |
1708 | */ | 1698 | */ |
1709 | static void __trace_remove_event_call(struct ftrace_event_call *call) | 1699 | static void __trace_remove_event_call(struct ftrace_event_call *call) |
1710 | { | 1700 | { |
1711 | event_remove(call); | 1701 | event_remove(call); |
1712 | trace_destroy_fields(call); | 1702 | trace_destroy_fields(call); |
1713 | destroy_preds(call); | 1703 | destroy_preds(call); |
1714 | } | 1704 | } |
1715 | 1705 | ||
1716 | static int probe_remove_event_call(struct ftrace_event_call *call) | 1706 | static int probe_remove_event_call(struct ftrace_event_call *call) |
1717 | { | 1707 | { |
1718 | struct trace_array *tr; | 1708 | struct trace_array *tr; |
1719 | struct ftrace_event_file *file; | 1709 | struct ftrace_event_file *file; |
1720 | 1710 | ||
1721 | #ifdef CONFIG_PERF_EVENTS | 1711 | #ifdef CONFIG_PERF_EVENTS |
1722 | if (call->perf_refcount) | 1712 | if (call->perf_refcount) |
1723 | return -EBUSY; | 1713 | return -EBUSY; |
1724 | #endif | 1714 | #endif |
1725 | do_for_each_event_file(tr, file) { | 1715 | do_for_each_event_file(tr, file) { |
1726 | if (file->event_call != call) | 1716 | if (file->event_call != call) |
1727 | continue; | 1717 | continue; |
1728 | /* | 1718 | /* |
1729 | * We can't rely on ftrace_event_enable_disable(enable => 0) | 1719 | * We can't rely on ftrace_event_enable_disable(enable => 0) |
1730 | * we are going to do, FTRACE_EVENT_FL_SOFT_MODE can suppress | 1720 | * we are going to do, FTRACE_EVENT_FL_SOFT_MODE can suppress |
1731 | * TRACE_REG_UNREGISTER. | 1721 | * TRACE_REG_UNREGISTER. |
1732 | */ | 1722 | */ |
1733 | if (file->flags & FTRACE_EVENT_FL_ENABLED) | 1723 | if (file->flags & FTRACE_EVENT_FL_ENABLED) |
1734 | return -EBUSY; | 1724 | return -EBUSY; |
1735 | /* | 1725 | /* |
1736 | * The do_for_each_event_file_safe() is | 1726 | * The do_for_each_event_file_safe() is |
1737 | * a double loop. After finding the call for this | 1727 | * a double loop. After finding the call for this |
1738 | * trace_array, we use break to jump to the next | 1728 | * trace_array, we use break to jump to the next |
1739 | * trace_array. | 1729 | * trace_array. |
1740 | */ | 1730 | */ |
1741 | break; | 1731 | break; |
1742 | } while_for_each_event_file(); | 1732 | } while_for_each_event_file(); |
1743 | 1733 | ||
1744 | __trace_remove_event_call(call); | 1734 | __trace_remove_event_call(call); |
1745 | 1735 | ||
1746 | return 0; | 1736 | return 0; |
1747 | } | 1737 | } |
1748 | 1738 | ||
1749 | /* Remove an event_call */ | 1739 | /* Remove an event_call */ |
1750 | int trace_remove_event_call(struct ftrace_event_call *call) | 1740 | int trace_remove_event_call(struct ftrace_event_call *call) |
1751 | { | 1741 | { |
1752 | int ret; | 1742 | int ret; |
1753 | 1743 | ||
1754 | mutex_lock(&trace_types_lock); | 1744 | mutex_lock(&trace_types_lock); |
1755 | mutex_lock(&event_mutex); | 1745 | mutex_lock(&event_mutex); |
1756 | down_write(&trace_event_sem); | 1746 | down_write(&trace_event_sem); |
1757 | ret = probe_remove_event_call(call); | 1747 | ret = probe_remove_event_call(call); |
1758 | up_write(&trace_event_sem); | 1748 | up_write(&trace_event_sem); |
1759 | mutex_unlock(&event_mutex); | 1749 | mutex_unlock(&event_mutex); |
1760 | mutex_unlock(&trace_types_lock); | 1750 | mutex_unlock(&trace_types_lock); |
1761 | 1751 | ||
1762 | return ret; | 1752 | return ret; |
1763 | } | 1753 | } |
1764 | 1754 | ||
1765 | #define for_each_event(event, start, end) \ | 1755 | #define for_each_event(event, start, end) \ |
1766 | for (event = start; \ | 1756 | for (event = start; \ |
1767 | (unsigned long)event < (unsigned long)end; \ | 1757 | (unsigned long)event < (unsigned long)end; \ |
1768 | event++) | 1758 | event++) |
1769 | 1759 | ||
1770 | #ifdef CONFIG_MODULES | 1760 | #ifdef CONFIG_MODULES |
1771 | 1761 | ||
1772 | static LIST_HEAD(ftrace_module_file_list); | ||
1773 | |||
1774 | /* | ||
1775 | * Modules must own their file_operations to keep up with | ||
1776 | * reference counting. | ||
1777 | */ | ||
1778 | struct ftrace_module_file_ops { | ||
1779 | struct list_head list; | ||
1780 | struct module *mod; | ||
1781 | struct file_operations id; | ||
1782 | struct file_operations enable; | ||
1783 | struct file_operations format; | ||
1784 | struct file_operations filter; | ||
1785 | }; | ||
1786 | |||
1787 | static struct ftrace_module_file_ops * | ||
1788 | find_ftrace_file_ops(struct ftrace_module_file_ops *file_ops, struct module *mod) | ||
1789 | { | ||
1790 | /* | ||
1791 | * As event_calls are added in groups by module, | ||
1792 | * when we find one file_ops, we don't need to search for | ||
1793 | * each call in that module, as the rest should be the | ||
1794 | * same. Only search for a new one if the last one did | ||
1795 | * not match. | ||
1796 | */ | ||
1797 | if (file_ops && mod == file_ops->mod) | ||
1798 | return file_ops; | ||
1799 | |||
1800 | list_for_each_entry(file_ops, &ftrace_module_file_list, list) { | ||
1801 | if (file_ops->mod == mod) | ||
1802 | return file_ops; | ||
1803 | } | ||
1804 | return NULL; | ||
1805 | } | ||
1806 | |||
1807 | static struct ftrace_module_file_ops * | ||
1808 | trace_create_file_ops(struct module *mod) | ||
1809 | { | ||
1810 | struct ftrace_module_file_ops *file_ops; | ||
1811 | |||
1812 | /* | ||
1813 | * This is a bit of a PITA. To allow for correct reference | ||
1814 | * counting, modules must "own" their file_operations. | ||
1815 | * To do this, we allocate the file operations that will be | ||
1816 | * used in the event directory. | ||
1817 | */ | ||
1818 | |||
1819 | file_ops = kmalloc(sizeof(*file_ops), GFP_KERNEL); | ||
1820 | if (!file_ops) | ||
1821 | return NULL; | ||
1822 | |||
1823 | file_ops->mod = mod; | ||
1824 | |||
1825 | file_ops->id = ftrace_event_id_fops; | ||
1826 | file_ops->id.owner = mod; | ||
1827 | |||
1828 | file_ops->enable = ftrace_enable_fops; | ||
1829 | file_ops->enable.owner = mod; | ||
1830 | |||
1831 | file_ops->filter = ftrace_event_filter_fops; | ||
1832 | file_ops->filter.owner = mod; | ||
1833 | |||
1834 | file_ops->format = ftrace_event_format_fops; | ||
1835 | file_ops->format.owner = mod; | ||
1836 | |||
1837 | list_add(&file_ops->list, &ftrace_module_file_list); | ||
1838 | |||
1839 | return file_ops; | ||
1840 | } | ||
1841 | |||
1842 | static void trace_module_add_events(struct module *mod) | 1762 | static void trace_module_add_events(struct module *mod) |
1843 | { | 1763 | { |
1844 | struct ftrace_module_file_ops *file_ops = NULL; | ||
1845 | struct ftrace_event_call **call, **start, **end; | 1764 | struct ftrace_event_call **call, **start, **end; |
1846 | 1765 | ||
1847 | start = mod->trace_events; | 1766 | start = mod->trace_events; |
1848 | end = mod->trace_events + mod->num_trace_events; | 1767 | end = mod->trace_events + mod->num_trace_events; |
1849 | 1768 | ||
1850 | if (start == end) | ||
1851 | return; | ||
1852 | |||
1853 | file_ops = trace_create_file_ops(mod); | ||
1854 | if (!file_ops) | ||
1855 | return; | ||
1856 | |||
1857 | for_each_event(call, start, end) { | 1769 | for_each_event(call, start, end) { |
1858 | __register_event(*call, mod); | 1770 | __register_event(*call, mod); |
1859 | __add_event_to_tracers(*call, file_ops); | 1771 | __add_event_to_tracers(*call); |
1860 | } | 1772 | } |
1861 | } | 1773 | } |
1862 | 1774 | ||
1863 | static void trace_module_remove_events(struct module *mod) | 1775 | static void trace_module_remove_events(struct module *mod) |
1864 | { | 1776 | { |
1865 | struct ftrace_module_file_ops *file_ops; | ||
1866 | struct ftrace_event_call *call, *p; | 1777 | struct ftrace_event_call *call, *p; |
1867 | bool clear_trace = false; | 1778 | bool clear_trace = false; |
1868 | 1779 | ||
1869 | down_write(&trace_event_sem); | 1780 | down_write(&trace_event_sem); |
1870 | list_for_each_entry_safe(call, p, &ftrace_events, list) { | 1781 | list_for_each_entry_safe(call, p, &ftrace_events, list) { |
1871 | if (call->mod == mod) { | 1782 | if (call->mod == mod) { |
1872 | if (call->flags & TRACE_EVENT_FL_WAS_ENABLED) | 1783 | if (call->flags & TRACE_EVENT_FL_WAS_ENABLED) |
1873 | clear_trace = true; | 1784 | clear_trace = true; |
1874 | __trace_remove_event_call(call); | 1785 | __trace_remove_event_call(call); |
1875 | } | 1786 | } |
1876 | } | 1787 | } |
1877 | |||
1878 | /* Now free the file_operations */ | ||
1879 | list_for_each_entry(file_ops, &ftrace_module_file_list, list) { | ||
1880 | if (file_ops->mod == mod) | ||
1881 | break; | ||
1882 | } | ||
1883 | if (&file_ops->list != &ftrace_module_file_list) { | ||
1884 | list_del(&file_ops->list); | ||
1885 | kfree(file_ops); | ||
1886 | } | ||
1887 | up_write(&trace_event_sem); | 1788 | up_write(&trace_event_sem); |
1888 | 1789 | ||
1889 | /* | 1790 | /* |
1890 | * It is safest to reset the ring buffer if the module being unloaded | 1791 | * It is safest to reset the ring buffer if the module being unloaded |
1891 | * registered any events that were used. The only worry is if | 1792 | * registered any events that were used. The only worry is if |
1892 | * a new module gets loaded, and takes on the same id as the events | 1793 | * a new module gets loaded, and takes on the same id as the events |
1893 | * of this module. When printing out the buffer, traced events left | 1794 | * of this module. When printing out the buffer, traced events left |
1894 | * over from this module may be passed to the new module events and | 1795 | * over from this module may be passed to the new module events and |
1895 | * unexpected results may occur. | 1796 | * unexpected results may occur. |
1896 | */ | 1797 | */ |
1897 | if (clear_trace) | 1798 | if (clear_trace) |
1898 | tracing_reset_all_online_cpus(); | 1799 | tracing_reset_all_online_cpus(); |
1899 | } | 1800 | } |
1900 | 1801 | ||
1901 | static int trace_module_notify(struct notifier_block *self, | 1802 | static int trace_module_notify(struct notifier_block *self, |
1902 | unsigned long val, void *data) | 1803 | unsigned long val, void *data) |
1903 | { | 1804 | { |
1904 | struct module *mod = data; | 1805 | struct module *mod = data; |
1905 | 1806 | ||
1906 | mutex_lock(&trace_types_lock); | 1807 | mutex_lock(&trace_types_lock); |
1907 | mutex_lock(&event_mutex); | 1808 | mutex_lock(&event_mutex); |
1908 | switch (val) { | 1809 | switch (val) { |
1909 | case MODULE_STATE_COMING: | 1810 | case MODULE_STATE_COMING: |
1910 | trace_module_add_events(mod); | 1811 | trace_module_add_events(mod); |
1911 | break; | 1812 | break; |
1912 | case MODULE_STATE_GOING: | 1813 | case MODULE_STATE_GOING: |
1913 | trace_module_remove_events(mod); | 1814 | trace_module_remove_events(mod); |
1914 | break; | 1815 | break; |
1915 | } | 1816 | } |
1916 | mutex_unlock(&event_mutex); | 1817 | mutex_unlock(&event_mutex); |
1917 | mutex_unlock(&trace_types_lock); | 1818 | mutex_unlock(&trace_types_lock); |
1918 | 1819 | ||
1919 | return 0; | 1820 | return 0; |
1920 | } | 1821 | } |
1921 | 1822 | ||
1922 | static int | 1823 | static struct notifier_block trace_module_nb = { |
1923 | __trace_add_new_mod_event(struct ftrace_event_call *call, | 1824 | .notifier_call = trace_module_notify, |
1924 | struct trace_array *tr, | 1825 | .priority = 0, |
1925 | struct ftrace_module_file_ops *file_ops) | 1826 | }; |
1926 | { | ||
1927 | return __trace_add_new_event(call, tr, | ||
1928 | &file_ops->id, &file_ops->enable, | ||
1929 | &file_ops->filter, &file_ops->format); | ||
1930 | } | ||
1931 | |||
1932 | #else | ||
1933 | static inline struct ftrace_module_file_ops * | ||
1934 | find_ftrace_file_ops(struct ftrace_module_file_ops *file_ops, struct module *mod) | ||
1935 | { | ||
1936 | return NULL; | ||
1937 | } | ||
1938 | static inline int trace_module_notify(struct notifier_block *self, | ||
1939 | unsigned long val, void *data) | ||
1940 | { | ||
1941 | return 0; | ||
1942 | } | ||
1943 | static inline int | ||
1944 | __trace_add_new_mod_event(struct ftrace_event_call *call, | ||
1945 | struct trace_array *tr, | ||
1946 | struct ftrace_module_file_ops *file_ops) | ||
1947 | { | ||
1948 | return -ENODEV; | ||
1949 | } | ||
1950 | #endif /* CONFIG_MODULES */ | 1827 | #endif /* CONFIG_MODULES */ |
1951 | 1828 | ||
1952 | /* Create a new event directory structure for a trace directory. */ | 1829 | /* Create a new event directory structure for a trace directory. */ |
1953 | static void | 1830 | static void |
1954 | __trace_add_event_dirs(struct trace_array *tr) | 1831 | __trace_add_event_dirs(struct trace_array *tr) |
1955 | { | 1832 | { |
1956 | struct ftrace_module_file_ops *file_ops = NULL; | ||
1957 | struct ftrace_event_call *call; | 1833 | struct ftrace_event_call *call; |
1958 | int ret; | 1834 | int ret; |
1959 | 1835 | ||
1960 | list_for_each_entry(call, &ftrace_events, list) { | 1836 | list_for_each_entry(call, &ftrace_events, list) { |
1961 | if (call->mod) { | 1837 | ret = __trace_add_new_event(call, tr); |
1962 | /* | ||
1963 | * Directories for events by modules need to | ||
1964 | * keep module ref counts when opened (as we don't | ||
1965 | * want the module to disappear when reading one | ||
1966 | * of these files). The file_ops keep account of | ||
1967 | * the module ref count. | ||
1968 | */ | ||
1969 | file_ops = find_ftrace_file_ops(file_ops, call->mod); | ||
1970 | if (!file_ops) | ||
1971 | continue; /* Warn? */ | ||
1972 | ret = __trace_add_new_mod_event(call, tr, file_ops); | ||
1973 | if (ret < 0) | ||
1974 | pr_warning("Could not create directory for event %s\n", | ||
1975 | call->name); | ||
1976 | continue; | ||
1977 | } | ||
1978 | ret = __trace_add_new_event(call, tr, | ||
1979 | &ftrace_event_id_fops, | ||
1980 | &ftrace_enable_fops, | ||
1981 | &ftrace_event_filter_fops, | ||
1982 | &ftrace_event_format_fops); | ||
1983 | if (ret < 0) | 1838 | if (ret < 0) |
1984 | pr_warning("Could not create directory for event %s\n", | 1839 | pr_warning("Could not create directory for event %s\n", |
1985 | call->name); | 1840 | call->name); |
1986 | } | 1841 | } |
1987 | } | 1842 | } |
1988 | 1843 | ||
1989 | #ifdef CONFIG_DYNAMIC_FTRACE | 1844 | #ifdef CONFIG_DYNAMIC_FTRACE |
1990 | 1845 | ||
1991 | /* Avoid typos */ | 1846 | /* Avoid typos */ |
1992 | #define ENABLE_EVENT_STR "enable_event" | 1847 | #define ENABLE_EVENT_STR "enable_event" |
1993 | #define DISABLE_EVENT_STR "disable_event" | 1848 | #define DISABLE_EVENT_STR "disable_event" |
1994 | 1849 | ||
1995 | struct event_probe_data { | 1850 | struct event_probe_data { |
1996 | struct ftrace_event_file *file; | 1851 | struct ftrace_event_file *file; |
1997 | unsigned long count; | 1852 | unsigned long count; |
1998 | int ref; | 1853 | int ref; |
1999 | bool enable; | 1854 | bool enable; |
2000 | }; | 1855 | }; |
2001 | 1856 | ||
2002 | static struct ftrace_event_file * | 1857 | static struct ftrace_event_file * |
2003 | find_event_file(struct trace_array *tr, const char *system, const char *event) | 1858 | find_event_file(struct trace_array *tr, const char *system, const char *event) |
2004 | { | 1859 | { |
2005 | struct ftrace_event_file *file; | 1860 | struct ftrace_event_file *file; |
2006 | struct ftrace_event_call *call; | 1861 | struct ftrace_event_call *call; |
2007 | 1862 | ||
2008 | list_for_each_entry(file, &tr->events, list) { | 1863 | list_for_each_entry(file, &tr->events, list) { |
2009 | 1864 | ||
2010 | call = file->event_call; | 1865 | call = file->event_call; |
2011 | 1866 | ||
2012 | if (!call->name || !call->class || !call->class->reg) | 1867 | if (!call->name || !call->class || !call->class->reg) |
2013 | continue; | 1868 | continue; |
2014 | 1869 | ||
2015 | if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) | 1870 | if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) |
2016 | continue; | 1871 | continue; |
2017 | 1872 | ||
2018 | if (strcmp(event, call->name) == 0 && | 1873 | if (strcmp(event, call->name) == 0 && |
2019 | strcmp(system, call->class->system) == 0) | 1874 | strcmp(system, call->class->system) == 0) |
2020 | return file; | 1875 | return file; |
2021 | } | 1876 | } |
2022 | return NULL; | 1877 | return NULL; |
2023 | } | 1878 | } |
2024 | 1879 | ||
2025 | static void | 1880 | static void |
2026 | event_enable_probe(unsigned long ip, unsigned long parent_ip, void **_data) | 1881 | event_enable_probe(unsigned long ip, unsigned long parent_ip, void **_data) |
2027 | { | 1882 | { |
2028 | struct event_probe_data **pdata = (struct event_probe_data **)_data; | 1883 | struct event_probe_data **pdata = (struct event_probe_data **)_data; |
2029 | struct event_probe_data *data = *pdata; | 1884 | struct event_probe_data *data = *pdata; |
2030 | 1885 | ||
2031 | if (!data) | 1886 | if (!data) |
2032 | return; | 1887 | return; |
2033 | 1888 | ||
2034 | if (data->enable) | 1889 | if (data->enable) |
2035 | clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &data->file->flags); | 1890 | clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &data->file->flags); |
2036 | else | 1891 | else |
2037 | set_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &data->file->flags); | 1892 | set_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &data->file->flags); |
2038 | } | 1893 | } |
2039 | 1894 | ||
2040 | static void | 1895 | static void |
2041 | event_enable_count_probe(unsigned long ip, unsigned long parent_ip, void **_data) | 1896 | event_enable_count_probe(unsigned long ip, unsigned long parent_ip, void **_data) |
2042 | { | 1897 | { |
2043 | struct event_probe_data **pdata = (struct event_probe_data **)_data; | 1898 | struct event_probe_data **pdata = (struct event_probe_data **)_data; |
2044 | struct event_probe_data *data = *pdata; | 1899 | struct event_probe_data *data = *pdata; |
2045 | 1900 | ||
2046 | if (!data) | 1901 | if (!data) |
2047 | return; | 1902 | return; |
2048 | 1903 | ||
2049 | if (!data->count) | 1904 | if (!data->count) |
2050 | return; | 1905 | return; |
2051 | 1906 | ||
2052 | /* Skip if the event is in a state we want to switch to */ | 1907 | /* Skip if the event is in a state we want to switch to */ |
2053 | if (data->enable == !(data->file->flags & FTRACE_EVENT_FL_SOFT_DISABLED)) | 1908 | if (data->enable == !(data->file->flags & FTRACE_EVENT_FL_SOFT_DISABLED)) |
2054 | return; | 1909 | return; |
2055 | 1910 | ||
2056 | if (data->count != -1) | 1911 | if (data->count != -1) |
2057 | (data->count)--; | 1912 | (data->count)--; |
2058 | 1913 | ||
2059 | event_enable_probe(ip, parent_ip, _data); | 1914 | event_enable_probe(ip, parent_ip, _data); |
2060 | } | 1915 | } |
2061 | 1916 | ||
2062 | static int | 1917 | static int |
2063 | event_enable_print(struct seq_file *m, unsigned long ip, | 1918 | event_enable_print(struct seq_file *m, unsigned long ip, |
2064 | struct ftrace_probe_ops *ops, void *_data) | 1919 | struct ftrace_probe_ops *ops, void *_data) |
2065 | { | 1920 | { |
2066 | struct event_probe_data *data = _data; | 1921 | struct event_probe_data *data = _data; |
2067 | 1922 | ||
2068 | seq_printf(m, "%ps:", (void *)ip); | 1923 | seq_printf(m, "%ps:", (void *)ip); |
2069 | 1924 | ||
2070 | seq_printf(m, "%s:%s:%s", | 1925 | seq_printf(m, "%s:%s:%s", |
2071 | data->enable ? ENABLE_EVENT_STR : DISABLE_EVENT_STR, | 1926 | data->enable ? ENABLE_EVENT_STR : DISABLE_EVENT_STR, |
2072 | data->file->event_call->class->system, | 1927 | data->file->event_call->class->system, |
2073 | data->file->event_call->name); | 1928 | data->file->event_call->name); |
2074 | 1929 | ||
2075 | if (data->count == -1) | 1930 | if (data->count == -1) |
2076 | seq_printf(m, ":unlimited\n"); | 1931 | seq_printf(m, ":unlimited\n"); |
2077 | else | 1932 | else |
2078 | seq_printf(m, ":count=%ld\n", data->count); | 1933 | seq_printf(m, ":count=%ld\n", data->count); |
2079 | 1934 | ||
2080 | return 0; | 1935 | return 0; |
2081 | } | 1936 | } |
2082 | 1937 | ||
2083 | static int | 1938 | static int |
2084 | event_enable_init(struct ftrace_probe_ops *ops, unsigned long ip, | 1939 | event_enable_init(struct ftrace_probe_ops *ops, unsigned long ip, |
2085 | void **_data) | 1940 | void **_data) |
2086 | { | 1941 | { |
2087 | struct event_probe_data **pdata = (struct event_probe_data **)_data; | 1942 | struct event_probe_data **pdata = (struct event_probe_data **)_data; |
2088 | struct event_probe_data *data = *pdata; | 1943 | struct event_probe_data *data = *pdata; |
2089 | 1944 | ||
2090 | data->ref++; | 1945 | data->ref++; |
2091 | return 0; | 1946 | return 0; |
2092 | } | 1947 | } |
2093 | 1948 | ||
2094 | static void | 1949 | static void |
2095 | event_enable_free(struct ftrace_probe_ops *ops, unsigned long ip, | 1950 | event_enable_free(struct ftrace_probe_ops *ops, unsigned long ip, |
2096 | void **_data) | 1951 | void **_data) |
2097 | { | 1952 | { |
2098 | struct event_probe_data **pdata = (struct event_probe_data **)_data; | 1953 | struct event_probe_data **pdata = (struct event_probe_data **)_data; |
2099 | struct event_probe_data *data = *pdata; | 1954 | struct event_probe_data *data = *pdata; |
2100 | 1955 | ||
2101 | if (WARN_ON_ONCE(data->ref <= 0)) | 1956 | if (WARN_ON_ONCE(data->ref <= 0)) |
2102 | return; | 1957 | return; |
2103 | 1958 | ||
2104 | data->ref--; | 1959 | data->ref--; |
2105 | if (!data->ref) { | 1960 | if (!data->ref) { |
2106 | /* Remove the SOFT_MODE flag */ | 1961 | /* Remove the SOFT_MODE flag */ |
2107 | __ftrace_event_enable_disable(data->file, 0, 1); | 1962 | __ftrace_event_enable_disable(data->file, 0, 1); |
2108 | module_put(data->file->event_call->mod); | 1963 | module_put(data->file->event_call->mod); |
2109 | kfree(data); | 1964 | kfree(data); |
2110 | } | 1965 | } |
2111 | *pdata = NULL; | 1966 | *pdata = NULL; |
2112 | } | 1967 | } |
2113 | 1968 | ||
2114 | static struct ftrace_probe_ops event_enable_probe_ops = { | 1969 | static struct ftrace_probe_ops event_enable_probe_ops = { |
2115 | .func = event_enable_probe, | 1970 | .func = event_enable_probe, |
2116 | .print = event_enable_print, | 1971 | .print = event_enable_print, |
2117 | .init = event_enable_init, | 1972 | .init = event_enable_init, |
2118 | .free = event_enable_free, | 1973 | .free = event_enable_free, |
2119 | }; | 1974 | }; |
2120 | 1975 | ||
2121 | static struct ftrace_probe_ops event_enable_count_probe_ops = { | 1976 | static struct ftrace_probe_ops event_enable_count_probe_ops = { |
2122 | .func = event_enable_count_probe, | 1977 | .func = event_enable_count_probe, |
2123 | .print = event_enable_print, | 1978 | .print = event_enable_print, |
2124 | .init = event_enable_init, | 1979 | .init = event_enable_init, |
2125 | .free = event_enable_free, | 1980 | .free = event_enable_free, |
2126 | }; | 1981 | }; |
2127 | 1982 | ||
2128 | static struct ftrace_probe_ops event_disable_probe_ops = { | 1983 | static struct ftrace_probe_ops event_disable_probe_ops = { |
2129 | .func = event_enable_probe, | 1984 | .func = event_enable_probe, |
2130 | .print = event_enable_print, | 1985 | .print = event_enable_print, |
2131 | .init = event_enable_init, | 1986 | .init = event_enable_init, |
2132 | .free = event_enable_free, | 1987 | .free = event_enable_free, |
2133 | }; | 1988 | }; |
2134 | 1989 | ||
2135 | static struct ftrace_probe_ops event_disable_count_probe_ops = { | 1990 | static struct ftrace_probe_ops event_disable_count_probe_ops = { |
2136 | .func = event_enable_count_probe, | 1991 | .func = event_enable_count_probe, |
2137 | .print = event_enable_print, | 1992 | .print = event_enable_print, |
2138 | .init = event_enable_init, | 1993 | .init = event_enable_init, |
2139 | .free = event_enable_free, | 1994 | .free = event_enable_free, |
2140 | }; | 1995 | }; |
2141 | 1996 | ||
2142 | static int | 1997 | static int |
2143 | event_enable_func(struct ftrace_hash *hash, | 1998 | event_enable_func(struct ftrace_hash *hash, |
2144 | char *glob, char *cmd, char *param, int enabled) | 1999 | char *glob, char *cmd, char *param, int enabled) |
2145 | { | 2000 | { |
2146 | struct trace_array *tr = top_trace_array(); | 2001 | struct trace_array *tr = top_trace_array(); |
2147 | struct ftrace_event_file *file; | 2002 | struct ftrace_event_file *file; |
2148 | struct ftrace_probe_ops *ops; | 2003 | struct ftrace_probe_ops *ops; |
2149 | struct event_probe_data *data; | 2004 | struct event_probe_data *data; |
2150 | const char *system; | 2005 | const char *system; |
2151 | const char *event; | 2006 | const char *event; |
2152 | char *number; | 2007 | char *number; |
2153 | bool enable; | 2008 | bool enable; |
2154 | int ret; | 2009 | int ret; |
2155 | 2010 | ||
2156 | /* hash funcs only work with set_ftrace_filter */ | 2011 | /* hash funcs only work with set_ftrace_filter */ |
2157 | if (!enabled || !param) | 2012 | if (!enabled || !param) |
2158 | return -EINVAL; | 2013 | return -EINVAL; |
2159 | 2014 | ||
2160 | system = strsep(¶m, ":"); | 2015 | system = strsep(¶m, ":"); |
2161 | if (!param) | 2016 | if (!param) |
2162 | return -EINVAL; | 2017 | return -EINVAL; |
2163 | 2018 | ||
2164 | event = strsep(¶m, ":"); | 2019 | event = strsep(¶m, ":"); |
2165 | 2020 | ||
2166 | mutex_lock(&event_mutex); | 2021 | mutex_lock(&event_mutex); |
2167 | 2022 | ||
2168 | ret = -EINVAL; | 2023 | ret = -EINVAL; |
2169 | file = find_event_file(tr, system, event); | 2024 | file = find_event_file(tr, system, event); |
2170 | if (!file) | 2025 | if (!file) |
2171 | goto out; | 2026 | goto out; |
2172 | 2027 | ||
2173 | enable = strcmp(cmd, ENABLE_EVENT_STR) == 0; | 2028 | enable = strcmp(cmd, ENABLE_EVENT_STR) == 0; |
2174 | 2029 | ||
2175 | if (enable) | 2030 | if (enable) |
2176 | ops = param ? &event_enable_count_probe_ops : &event_enable_probe_ops; | 2031 | ops = param ? &event_enable_count_probe_ops : &event_enable_probe_ops; |
2177 | else | 2032 | else |
2178 | ops = param ? &event_disable_count_probe_ops : &event_disable_probe_ops; | 2033 | ops = param ? &event_disable_count_probe_ops : &event_disable_probe_ops; |
2179 | 2034 | ||
2180 | if (glob[0] == '!') { | 2035 | if (glob[0] == '!') { |
2181 | unregister_ftrace_function_probe_func(glob+1, ops); | 2036 | unregister_ftrace_function_probe_func(glob+1, ops); |
2182 | ret = 0; | 2037 | ret = 0; |
2183 | goto out; | 2038 | goto out; |
2184 | } | 2039 | } |
2185 | 2040 | ||
2186 | ret = -ENOMEM; | 2041 | ret = -ENOMEM; |
2187 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 2042 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
2188 | if (!data) | 2043 | if (!data) |
2189 | goto out; | 2044 | goto out; |
2190 | 2045 | ||
2191 | data->enable = enable; | 2046 | data->enable = enable; |
2192 | data->count = -1; | 2047 | data->count = -1; |
2193 | data->file = file; | 2048 | data->file = file; |
2194 | 2049 | ||
2195 | if (!param) | 2050 | if (!param) |
2196 | goto out_reg; | 2051 | goto out_reg; |
2197 | 2052 | ||
2198 | number = strsep(¶m, ":"); | 2053 | number = strsep(¶m, ":"); |
2199 | 2054 | ||
2200 | ret = -EINVAL; | 2055 | ret = -EINVAL; |
2201 | if (!strlen(number)) | 2056 | if (!strlen(number)) |
2202 | goto out_free; | 2057 | goto out_free; |
2203 | 2058 | ||
2204 | /* | 2059 | /* |
2205 | * We use the callback data field (which is a pointer) | 2060 | * We use the callback data field (which is a pointer) |
2206 | * as our counter. | 2061 | * as our counter. |
2207 | */ | 2062 | */ |
2208 | ret = kstrtoul(number, 0, &data->count); | 2063 | ret = kstrtoul(number, 0, &data->count); |
2209 | if (ret) | 2064 | if (ret) |
2210 | goto out_free; | 2065 | goto out_free; |
2211 | 2066 | ||
2212 | out_reg: | 2067 | out_reg: |
2213 | /* Don't let event modules unload while probe registered */ | 2068 | /* Don't let event modules unload while probe registered */ |
2214 | ret = try_module_get(file->event_call->mod); | 2069 | ret = try_module_get(file->event_call->mod); |
2215 | if (!ret) { | 2070 | if (!ret) { |
2216 | ret = -EBUSY; | 2071 | ret = -EBUSY; |
2217 | goto out_free; | 2072 | goto out_free; |
2218 | } | 2073 | } |
2219 | 2074 | ||
2220 | ret = __ftrace_event_enable_disable(file, 1, 1); | 2075 | ret = __ftrace_event_enable_disable(file, 1, 1); |
2221 | if (ret < 0) | 2076 | if (ret < 0) |
2222 | goto out_put; | 2077 | goto out_put; |
2223 | ret = register_ftrace_function_probe(glob, ops, data); | 2078 | ret = register_ftrace_function_probe(glob, ops, data); |
2224 | /* | 2079 | /* |
2225 | * The above returns on success the # of functions enabled, | 2080 | * The above returns on success the # of functions enabled, |
2226 | * but if it didn't find any functions it returns zero. | 2081 | * but if it didn't find any functions it returns zero. |
2227 | * Consider no functions a failure too. | 2082 | * Consider no functions a failure too. |
2228 | */ | 2083 | */ |
2229 | if (!ret) { | 2084 | if (!ret) { |
2230 | ret = -ENOENT; | 2085 | ret = -ENOENT; |
2231 | goto out_disable; | 2086 | goto out_disable; |
2232 | } else if (ret < 0) | 2087 | } else if (ret < 0) |
2233 | goto out_disable; | 2088 | goto out_disable; |
2234 | /* Just return zero, not the number of enabled functions */ | 2089 | /* Just return zero, not the number of enabled functions */ |
2235 | ret = 0; | 2090 | ret = 0; |
2236 | out: | 2091 | out: |
2237 | mutex_unlock(&event_mutex); | 2092 | mutex_unlock(&event_mutex); |
2238 | return ret; | 2093 | return ret; |
2239 | 2094 | ||
2240 | out_disable: | 2095 | out_disable: |
2241 | __ftrace_event_enable_disable(file, 0, 1); | 2096 | __ftrace_event_enable_disable(file, 0, 1); |
2242 | out_put: | 2097 | out_put: |
2243 | module_put(file->event_call->mod); | 2098 | module_put(file->event_call->mod); |
2244 | out_free: | 2099 | out_free: |
2245 | kfree(data); | 2100 | kfree(data); |
2246 | goto out; | 2101 | goto out; |
2247 | } | 2102 | } |
2248 | 2103 | ||
2249 | static struct ftrace_func_command event_enable_cmd = { | 2104 | static struct ftrace_func_command event_enable_cmd = { |
2250 | .name = ENABLE_EVENT_STR, | 2105 | .name = ENABLE_EVENT_STR, |
2251 | .func = event_enable_func, | 2106 | .func = event_enable_func, |
2252 | }; | 2107 | }; |
2253 | 2108 | ||
2254 | static struct ftrace_func_command event_disable_cmd = { | 2109 | static struct ftrace_func_command event_disable_cmd = { |
2255 | .name = DISABLE_EVENT_STR, | 2110 | .name = DISABLE_EVENT_STR, |
2256 | .func = event_enable_func, | 2111 | .func = event_enable_func, |
2257 | }; | 2112 | }; |
2258 | 2113 | ||
2259 | static __init int register_event_cmds(void) | 2114 | static __init int register_event_cmds(void) |
2260 | { | 2115 | { |
2261 | int ret; | 2116 | int ret; |
2262 | 2117 | ||
2263 | ret = register_ftrace_command(&event_enable_cmd); | 2118 | ret = register_ftrace_command(&event_enable_cmd); |
2264 | if (WARN_ON(ret < 0)) | 2119 | if (WARN_ON(ret < 0)) |
2265 | return ret; | 2120 | return ret; |
2266 | ret = register_ftrace_command(&event_disable_cmd); | 2121 | ret = register_ftrace_command(&event_disable_cmd); |
2267 | if (WARN_ON(ret < 0)) | 2122 | if (WARN_ON(ret < 0)) |
2268 | unregister_ftrace_command(&event_enable_cmd); | 2123 | unregister_ftrace_command(&event_enable_cmd); |
2269 | return ret; | 2124 | return ret; |
2270 | } | 2125 | } |
2271 | #else | 2126 | #else |
2272 | static inline int register_event_cmds(void) { return 0; } | 2127 | static inline int register_event_cmds(void) { return 0; } |
2273 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 2128 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
2274 | 2129 | ||
2275 | /* | 2130 | /* |
2276 | * The top level array has already had its ftrace_event_file | 2131 | * The top level array has already had its ftrace_event_file |
2277 | * descriptors created in order to allow for early events to | 2132 | * descriptors created in order to allow for early events to |
2278 | * be recorded. This function is called after the debugfs has been | 2133 | * be recorded. This function is called after the debugfs has been |
2279 | * initialized, and we now have to create the files associated | 2134 | * initialized, and we now have to create the files associated |
2280 | * to the events. | 2135 | * to the events. |
2281 | */ | 2136 | */ |
2282 | static __init void | 2137 | static __init void |
2283 | __trace_early_add_event_dirs(struct trace_array *tr) | 2138 | __trace_early_add_event_dirs(struct trace_array *tr) |
2284 | { | 2139 | { |
2285 | struct ftrace_event_file *file; | 2140 | struct ftrace_event_file *file; |
2286 | int ret; | 2141 | int ret; |
2287 | 2142 | ||
2288 | 2143 | ||
2289 | list_for_each_entry(file, &tr->events, list) { | 2144 | list_for_each_entry(file, &tr->events, list) { |
2290 | ret = event_create_dir(tr->event_dir, file, | 2145 | ret = event_create_dir(tr->event_dir, file); |
2291 | &ftrace_event_id_fops, | ||
2292 | &ftrace_enable_fops, | ||
2293 | &ftrace_event_filter_fops, | ||
2294 | &ftrace_event_format_fops); | ||
2295 | if (ret < 0) | 2146 | if (ret < 0) |
2296 | pr_warning("Could not create directory for event %s\n", | 2147 | pr_warning("Could not create directory for event %s\n", |
2297 | file->event_call->name); | 2148 | file->event_call->name); |
2298 | } | 2149 | } |
2299 | } | 2150 | } |
2300 | 2151 | ||
2301 | /* | 2152 | /* |
2302 | * For early boot up, the top trace array requires to have | 2153 | * For early boot up, the top trace array requires to have |
2303 | * a list of events that can be enabled. This must be done before | 2154 | * a list of events that can be enabled. This must be done before |
2304 | * the filesystem is set up in order to allow events to be traced | 2155 | * the filesystem is set up in order to allow events to be traced |
2305 | * early. | 2156 | * early. |
2306 | */ | 2157 | */ |
2307 | static __init void | 2158 | static __init void |
2308 | __trace_early_add_events(struct trace_array *tr) | 2159 | __trace_early_add_events(struct trace_array *tr) |
2309 | { | 2160 | { |
2310 | struct ftrace_event_call *call; | 2161 | struct ftrace_event_call *call; |
2311 | int ret; | 2162 | int ret; |
2312 | 2163 | ||
2313 | list_for_each_entry(call, &ftrace_events, list) { | 2164 | list_for_each_entry(call, &ftrace_events, list) { |
2314 | /* Early boot up should not have any modules loaded */ | 2165 | /* Early boot up should not have any modules loaded */ |
2315 | if (WARN_ON_ONCE(call->mod)) | 2166 | if (WARN_ON_ONCE(call->mod)) |
2316 | continue; | 2167 | continue; |
2317 | 2168 | ||
2318 | ret = __trace_early_add_new_event(call, tr); | 2169 | ret = __trace_early_add_new_event(call, tr); |
2319 | if (ret < 0) | 2170 | if (ret < 0) |
2320 | pr_warning("Could not create early event %s\n", | 2171 | pr_warning("Could not create early event %s\n", |
2321 | call->name); | 2172 | call->name); |
2322 | } | 2173 | } |
2323 | } | 2174 | } |
2324 | 2175 | ||
2325 | /* Remove the event directory structure for a trace directory. */ | 2176 | /* Remove the event directory structure for a trace directory. */ |
2326 | static void | 2177 | static void |
2327 | __trace_remove_event_dirs(struct trace_array *tr) | 2178 | __trace_remove_event_dirs(struct trace_array *tr) |
2328 | { | 2179 | { |
2329 | struct ftrace_event_file *file, *next; | 2180 | struct ftrace_event_file *file, *next; |
2330 | 2181 | ||
2331 | list_for_each_entry_safe(file, next, &tr->events, list) | 2182 | list_for_each_entry_safe(file, next, &tr->events, list) |
2332 | remove_event_file_dir(file); | 2183 | remove_event_file_dir(file); |
2333 | } | 2184 | } |
2334 | 2185 | ||
2335 | static void | 2186 | static void __add_event_to_tracers(struct ftrace_event_call *call) |
2336 | __add_event_to_tracers(struct ftrace_event_call *call, | ||
2337 | struct ftrace_module_file_ops *file_ops) | ||
2338 | { | 2187 | { |
2339 | struct trace_array *tr; | 2188 | struct trace_array *tr; |
2340 | 2189 | ||
2341 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 2190 | list_for_each_entry(tr, &ftrace_trace_arrays, list) |
2342 | if (file_ops) | 2191 | __trace_add_new_event(call, tr); |
2343 | __trace_add_new_mod_event(call, tr, file_ops); | ||
2344 | else | ||
2345 | __trace_add_new_event(call, tr, | ||
2346 | &ftrace_event_id_fops, | ||
2347 | &ftrace_enable_fops, | ||
2348 | &ftrace_event_filter_fops, | ||
2349 | &ftrace_event_format_fops); | ||
2350 | } | ||
2351 | } | 2192 | } |
2352 | 2193 | ||
2353 | static struct notifier_block trace_module_nb = { | ||
2354 | .notifier_call = trace_module_notify, | ||
2355 | .priority = 0, | ||
2356 | }; | ||
2357 | |||
2358 | extern struct ftrace_event_call *__start_ftrace_events[]; | 2194 | extern struct ftrace_event_call *__start_ftrace_events[]; |
2359 | extern struct ftrace_event_call *__stop_ftrace_events[]; | 2195 | extern struct ftrace_event_call *__stop_ftrace_events[]; |
2360 | 2196 | ||
2361 | static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; | 2197 | static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; |
2362 | 2198 | ||
2363 | static __init int setup_trace_event(char *str) | 2199 | static __init int setup_trace_event(char *str) |
2364 | { | 2200 | { |
2365 | strlcpy(bootup_event_buf, str, COMMAND_LINE_SIZE); | 2201 | strlcpy(bootup_event_buf, str, COMMAND_LINE_SIZE); |
2366 | ring_buffer_expanded = true; | 2202 | ring_buffer_expanded = true; |
2367 | tracing_selftest_disabled = true; | 2203 | tracing_selftest_disabled = true; |
2368 | 2204 | ||
2369 | return 1; | 2205 | return 1; |
2370 | } | 2206 | } |
2371 | __setup("trace_event=", setup_trace_event); | 2207 | __setup("trace_event=", setup_trace_event); |
2372 | 2208 | ||
2373 | /* Expects to have event_mutex held when called */ | 2209 | /* Expects to have event_mutex held when called */ |
2374 | static int | 2210 | static int |
2375 | create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) | 2211 | create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) |
2376 | { | 2212 | { |
2377 | struct dentry *d_events; | 2213 | struct dentry *d_events; |
2378 | struct dentry *entry; | 2214 | struct dentry *entry; |
2379 | 2215 | ||
2380 | entry = debugfs_create_file("set_event", 0644, parent, | 2216 | entry = debugfs_create_file("set_event", 0644, parent, |
2381 | tr, &ftrace_set_event_fops); | 2217 | tr, &ftrace_set_event_fops); |
2382 | if (!entry) { | 2218 | if (!entry) { |
2383 | pr_warning("Could not create debugfs 'set_event' entry\n"); | 2219 | pr_warning("Could not create debugfs 'set_event' entry\n"); |
2384 | return -ENOMEM; | 2220 | return -ENOMEM; |
2385 | } | 2221 | } |
2386 | 2222 | ||
2387 | d_events = debugfs_create_dir("events", parent); | 2223 | d_events = debugfs_create_dir("events", parent); |
2388 | if (!d_events) { | 2224 | if (!d_events) { |
2389 | pr_warning("Could not create debugfs 'events' directory\n"); | 2225 | pr_warning("Could not create debugfs 'events' directory\n"); |
2390 | return -ENOMEM; | 2226 | return -ENOMEM; |
2391 | } | 2227 | } |
2392 | 2228 | ||
2393 | /* ring buffer internal formats */ | 2229 | /* ring buffer internal formats */ |
2394 | trace_create_file("header_page", 0444, d_events, | 2230 | trace_create_file("header_page", 0444, d_events, |
2395 | ring_buffer_print_page_header, | 2231 | ring_buffer_print_page_header, |
2396 | &ftrace_show_header_fops); | 2232 | &ftrace_show_header_fops); |
2397 | 2233 | ||
2398 | trace_create_file("header_event", 0444, d_events, | 2234 | trace_create_file("header_event", 0444, d_events, |
2399 | ring_buffer_print_entry_header, | 2235 | ring_buffer_print_entry_header, |
2400 | &ftrace_show_header_fops); | 2236 | &ftrace_show_header_fops); |
2401 | 2237 | ||
2402 | trace_create_file("enable", 0644, d_events, | 2238 | trace_create_file("enable", 0644, d_events, |
2403 | tr, &ftrace_tr_enable_fops); | 2239 | tr, &ftrace_tr_enable_fops); |
2404 | 2240 | ||
2405 | tr->event_dir = d_events; | 2241 | tr->event_dir = d_events; |
2406 | 2242 | ||
2407 | return 0; | 2243 | return 0; |
2408 | } | 2244 | } |
2409 | 2245 | ||
2410 | /** | 2246 | /** |
2411 | * event_trace_add_tracer - add a instance of a trace_array to events | 2247 | * event_trace_add_tracer - add a instance of a trace_array to events |
2412 | * @parent: The parent dentry to place the files/directories for events in | 2248 | * @parent: The parent dentry to place the files/directories for events in |
2413 | * @tr: The trace array associated with these events | 2249 | * @tr: The trace array associated with these events |
2414 | * | 2250 | * |
2415 | * When a new instance is created, it needs to set up its events | 2251 | * When a new instance is created, it needs to set up its events |
2416 | * directory, as well as other files associated with events. It also | 2252 | * directory, as well as other files associated with events. It also |
2417 | * creates the event hierachry in the @parent/events directory. | 2253 | * creates the event hierachry in the @parent/events directory. |
2418 | * | 2254 | * |
2419 | * Returns 0 on success. | 2255 | * Returns 0 on success. |
2420 | */ | 2256 | */ |
2421 | int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr) | 2257 | int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr) |
2422 | { | 2258 | { |
2423 | int ret; | 2259 | int ret; |
2424 | 2260 | ||
2425 | mutex_lock(&event_mutex); | 2261 | mutex_lock(&event_mutex); |
2426 | 2262 | ||
2427 | ret = create_event_toplevel_files(parent, tr); | 2263 | ret = create_event_toplevel_files(parent, tr); |
2428 | if (ret) | 2264 | if (ret) |
2429 | goto out_unlock; | 2265 | goto out_unlock; |
2430 | 2266 | ||
2431 | down_write(&trace_event_sem); | 2267 | down_write(&trace_event_sem); |
2432 | __trace_add_event_dirs(tr); | 2268 | __trace_add_event_dirs(tr); |
2433 | up_write(&trace_event_sem); | 2269 | up_write(&trace_event_sem); |
2434 | 2270 | ||
2435 | out_unlock: | 2271 | out_unlock: |
2436 | mutex_unlock(&event_mutex); | 2272 | mutex_unlock(&event_mutex); |
2437 | 2273 | ||
2438 | return ret; | 2274 | return ret; |
2439 | } | 2275 | } |
2440 | 2276 | ||
2441 | /* | 2277 | /* |
2442 | * The top trace array already had its file descriptors created. | 2278 | * The top trace array already had its file descriptors created. |
2443 | * Now the files themselves need to be created. | 2279 | * Now the files themselves need to be created. |
2444 | */ | 2280 | */ |
2445 | static __init int | 2281 | static __init int |
2446 | early_event_add_tracer(struct dentry *parent, struct trace_array *tr) | 2282 | early_event_add_tracer(struct dentry *parent, struct trace_array *tr) |
2447 | { | 2283 | { |
2448 | int ret; | 2284 | int ret; |
2449 | 2285 | ||
2450 | mutex_lock(&event_mutex); | 2286 | mutex_lock(&event_mutex); |
2451 | 2287 | ||
2452 | ret = create_event_toplevel_files(parent, tr); | 2288 | ret = create_event_toplevel_files(parent, tr); |
2453 | if (ret) | 2289 | if (ret) |
2454 | goto out_unlock; | 2290 | goto out_unlock; |
2455 | 2291 | ||
2456 | down_write(&trace_event_sem); | 2292 | down_write(&trace_event_sem); |
2457 | __trace_early_add_event_dirs(tr); | 2293 | __trace_early_add_event_dirs(tr); |
2458 | up_write(&trace_event_sem); | 2294 | up_write(&trace_event_sem); |
2459 | 2295 | ||
2460 | out_unlock: | 2296 | out_unlock: |
2461 | mutex_unlock(&event_mutex); | 2297 | mutex_unlock(&event_mutex); |
2462 | 2298 | ||
2463 | return ret; | 2299 | return ret; |
2464 | } | 2300 | } |
2465 | 2301 | ||
2466 | int event_trace_del_tracer(struct trace_array *tr) | 2302 | int event_trace_del_tracer(struct trace_array *tr) |
2467 | { | 2303 | { |
2468 | mutex_lock(&event_mutex); | 2304 | mutex_lock(&event_mutex); |
2469 | 2305 | ||
2470 | /* Disable any running events */ | 2306 | /* Disable any running events */ |
2471 | __ftrace_set_clr_event_nolock(tr, NULL, NULL, NULL, 0); | 2307 | __ftrace_set_clr_event_nolock(tr, NULL, NULL, NULL, 0); |
2472 | 2308 | ||
2473 | down_write(&trace_event_sem); | 2309 | down_write(&trace_event_sem); |
2474 | __trace_remove_event_dirs(tr); | 2310 | __trace_remove_event_dirs(tr); |
2475 | debugfs_remove_recursive(tr->event_dir); | 2311 | debugfs_remove_recursive(tr->event_dir); |
2476 | up_write(&trace_event_sem); | 2312 | up_write(&trace_event_sem); |
2477 | 2313 | ||
2478 | tr->event_dir = NULL; | 2314 | tr->event_dir = NULL; |
2479 | 2315 | ||
2480 | mutex_unlock(&event_mutex); | 2316 | mutex_unlock(&event_mutex); |
2481 | 2317 | ||
2482 | return 0; | 2318 | return 0; |
2483 | } | 2319 | } |
2484 | 2320 | ||
2485 | static __init int event_trace_memsetup(void) | 2321 | static __init int event_trace_memsetup(void) |
2486 | { | 2322 | { |
2487 | field_cachep = KMEM_CACHE(ftrace_event_field, SLAB_PANIC); | 2323 | field_cachep = KMEM_CACHE(ftrace_event_field, SLAB_PANIC); |
2488 | file_cachep = KMEM_CACHE(ftrace_event_file, SLAB_PANIC); | 2324 | file_cachep = KMEM_CACHE(ftrace_event_file, SLAB_PANIC); |
2489 | return 0; | 2325 | return 0; |
2490 | } | 2326 | } |
2491 | 2327 | ||
2492 | static __init int event_trace_enable(void) | 2328 | static __init int event_trace_enable(void) |
2493 | { | 2329 | { |
2494 | struct trace_array *tr = top_trace_array(); | 2330 | struct trace_array *tr = top_trace_array(); |
2495 | struct ftrace_event_call **iter, *call; | 2331 | struct ftrace_event_call **iter, *call; |
2496 | char *buf = bootup_event_buf; | 2332 | char *buf = bootup_event_buf; |
2497 | char *token; | 2333 | char *token; |
2498 | int ret; | 2334 | int ret; |
2499 | 2335 | ||
2500 | for_each_event(iter, __start_ftrace_events, __stop_ftrace_events) { | 2336 | for_each_event(iter, __start_ftrace_events, __stop_ftrace_events) { |
2501 | 2337 | ||
2502 | call = *iter; | 2338 | call = *iter; |
2503 | ret = event_init(call); | 2339 | ret = event_init(call); |
2504 | if (!ret) | 2340 | if (!ret) |
2505 | list_add(&call->list, &ftrace_events); | 2341 | list_add(&call->list, &ftrace_events); |
2506 | } | 2342 | } |
2507 | 2343 | ||
2508 | /* | 2344 | /* |
2509 | * We need the top trace array to have a working set of trace | 2345 | * We need the top trace array to have a working set of trace |
2510 | * points at early init, before the debug files and directories | 2346 | * points at early init, before the debug files and directories |
2511 | * are created. Create the file entries now, and attach them | 2347 | * are created. Create the file entries now, and attach them |
2512 | * to the actual file dentries later. | 2348 | * to the actual file dentries later. |
2513 | */ | 2349 | */ |
2514 | __trace_early_add_events(tr); | 2350 | __trace_early_add_events(tr); |
2515 | 2351 | ||
2516 | while (true) { | 2352 | while (true) { |
2517 | token = strsep(&buf, ","); | 2353 | token = strsep(&buf, ","); |
2518 | 2354 | ||
2519 | if (!token) | 2355 | if (!token) |
2520 | break; | 2356 | break; |
2521 | if (!*token) | 2357 | if (!*token) |
2522 | continue; | 2358 | continue; |
2523 | 2359 | ||
2524 | ret = ftrace_set_clr_event(tr, token, 1); | 2360 | ret = ftrace_set_clr_event(tr, token, 1); |
2525 | if (ret) | 2361 | if (ret) |
2526 | pr_warn("Failed to enable trace event: %s\n", token); | 2362 | pr_warn("Failed to enable trace event: %s\n", token); |
2527 | } | 2363 | } |
2528 | 2364 | ||
2529 | trace_printk_start_comm(); | 2365 | trace_printk_start_comm(); |
2530 | 2366 | ||
2531 | register_event_cmds(); | 2367 | register_event_cmds(); |
2532 | 2368 | ||
2533 | return 0; | 2369 | return 0; |
2534 | } | 2370 | } |
2535 | 2371 | ||
2536 | static __init int event_trace_init(void) | 2372 | static __init int event_trace_init(void) |
2537 | { | 2373 | { |
2538 | struct trace_array *tr; | 2374 | struct trace_array *tr; |
2539 | struct dentry *d_tracer; | 2375 | struct dentry *d_tracer; |
2540 | struct dentry *entry; | 2376 | struct dentry *entry; |
2541 | int ret; | 2377 | int ret; |
2542 | 2378 | ||
2543 | tr = top_trace_array(); | 2379 | tr = top_trace_array(); |
2544 | 2380 | ||
2545 | d_tracer = tracing_init_dentry(); | 2381 | d_tracer = tracing_init_dentry(); |
2546 | if (!d_tracer) | 2382 | if (!d_tracer) |
2547 | return 0; | 2383 | return 0; |
2548 | 2384 | ||
2549 | entry = debugfs_create_file("available_events", 0444, d_tracer, | 2385 | entry = debugfs_create_file("available_events", 0444, d_tracer, |
2550 | tr, &ftrace_avail_fops); | 2386 | tr, &ftrace_avail_fops); |
2551 | if (!entry) | 2387 | if (!entry) |
2552 | pr_warning("Could not create debugfs " | 2388 | pr_warning("Could not create debugfs " |
2553 | "'available_events' entry\n"); | 2389 | "'available_events' entry\n"); |
2554 | 2390 | ||
2555 | if (trace_define_common_fields()) | 2391 | if (trace_define_common_fields()) |
2556 | pr_warning("tracing: Failed to allocate common fields"); | 2392 | pr_warning("tracing: Failed to allocate common fields"); |
2557 | 2393 | ||
2558 | ret = early_event_add_tracer(d_tracer, tr); | 2394 | ret = early_event_add_tracer(d_tracer, tr); |
2559 | if (ret) | 2395 | if (ret) |
2560 | return ret; | 2396 | return ret; |
2561 | 2397 | ||
2398 | #ifdef CONFIG_MODULES | ||
2562 | ret = register_module_notifier(&trace_module_nb); | 2399 | ret = register_module_notifier(&trace_module_nb); |
2563 | if (ret) | 2400 | if (ret) |
2564 | pr_warning("Failed to register trace events module notifier\n"); | 2401 | pr_warning("Failed to register trace events module notifier\n"); |
2565 | 2402 | #endif | |
2566 | return 0; | 2403 | return 0; |
2567 | } | 2404 | } |
2568 | early_initcall(event_trace_memsetup); | 2405 | early_initcall(event_trace_memsetup); |
2569 | core_initcall(event_trace_enable); | 2406 | core_initcall(event_trace_enable); |
2570 | fs_initcall(event_trace_init); | 2407 | fs_initcall(event_trace_init); |
2571 | 2408 | ||
2572 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 2409 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
2573 | 2410 | ||
2574 | static DEFINE_SPINLOCK(test_spinlock); | 2411 | static DEFINE_SPINLOCK(test_spinlock); |
2575 | static DEFINE_SPINLOCK(test_spinlock_irq); | 2412 | static DEFINE_SPINLOCK(test_spinlock_irq); |
2576 | static DEFINE_MUTEX(test_mutex); | 2413 | static DEFINE_MUTEX(test_mutex); |
2577 | 2414 | ||
2578 | static __init void test_work(struct work_struct *dummy) | 2415 | static __init void test_work(struct work_struct *dummy) |
2579 | { | 2416 | { |
2580 | spin_lock(&test_spinlock); | 2417 | spin_lock(&test_spinlock); |
2581 | spin_lock_irq(&test_spinlock_irq); | 2418 | spin_lock_irq(&test_spinlock_irq); |
2582 | udelay(1); | 2419 | udelay(1); |
2583 | spin_unlock_irq(&test_spinlock_irq); | 2420 | spin_unlock_irq(&test_spinlock_irq); |
2584 | spin_unlock(&test_spinlock); | 2421 | spin_unlock(&test_spinlock); |
2585 | 2422 | ||
2586 | mutex_lock(&test_mutex); | 2423 | mutex_lock(&test_mutex); |
2587 | msleep(1); | 2424 | msleep(1); |
2588 | mutex_unlock(&test_mutex); | 2425 | mutex_unlock(&test_mutex); |
2589 | } | 2426 | } |
2590 | 2427 | ||
2591 | static __init int event_test_thread(void *unused) | 2428 | static __init int event_test_thread(void *unused) |
2592 | { | 2429 | { |
2593 | void *test_malloc; | 2430 | void *test_malloc; |
2594 | 2431 | ||
2595 | test_malloc = kmalloc(1234, GFP_KERNEL); | 2432 | test_malloc = kmalloc(1234, GFP_KERNEL); |
2596 | if (!test_malloc) | 2433 | if (!test_malloc) |
2597 | pr_info("failed to kmalloc\n"); | 2434 | pr_info("failed to kmalloc\n"); |
2598 | 2435 | ||
2599 | schedule_on_each_cpu(test_work); | 2436 | schedule_on_each_cpu(test_work); |
2600 | 2437 | ||
2601 | kfree(test_malloc); | 2438 | kfree(test_malloc); |
2602 | 2439 | ||
2603 | set_current_state(TASK_INTERRUPTIBLE); | 2440 | set_current_state(TASK_INTERRUPTIBLE); |
2604 | while (!kthread_should_stop()) | 2441 | while (!kthread_should_stop()) |
2605 | schedule(); | 2442 | schedule(); |
2606 | 2443 | ||
2607 | return 0; | 2444 | return 0; |
2608 | } | 2445 | } |
2609 | 2446 | ||
2610 | /* | 2447 | /* |
2611 | * Do various things that may trigger events. | 2448 | * Do various things that may trigger events. |
2612 | */ | 2449 | */ |
2613 | static __init void event_test_stuff(void) | 2450 | static __init void event_test_stuff(void) |
2614 | { | 2451 | { |
2615 | struct task_struct *test_thread; | 2452 | struct task_struct *test_thread; |
2616 | 2453 | ||
2617 | test_thread = kthread_run(event_test_thread, NULL, "test-events"); | 2454 | test_thread = kthread_run(event_test_thread, NULL, "test-events"); |
2618 | msleep(1); | 2455 | msleep(1); |
2619 | kthread_stop(test_thread); | 2456 | kthread_stop(test_thread); |
2620 | } | 2457 | } |
2621 | 2458 | ||
2622 | /* | 2459 | /* |
2623 | * For every trace event defined, we will test each trace point separately, | 2460 | * For every trace event defined, we will test each trace point separately, |
2624 | * and then by groups, and finally all trace points. | 2461 | * and then by groups, and finally all trace points. |
2625 | */ | 2462 | */ |
2626 | static __init void event_trace_self_tests(void) | 2463 | static __init void event_trace_self_tests(void) |
2627 | { | 2464 | { |
2628 | struct ftrace_subsystem_dir *dir; | 2465 | struct ftrace_subsystem_dir *dir; |
2629 | struct ftrace_event_file *file; | 2466 | struct ftrace_event_file *file; |
2630 | struct ftrace_event_call *call; | 2467 | struct ftrace_event_call *call; |
2631 | struct event_subsystem *system; | 2468 | struct event_subsystem *system; |
2632 | struct trace_array *tr; | 2469 | struct trace_array *tr; |
2633 | int ret; | 2470 | int ret; |
2634 | 2471 | ||
2635 | tr = top_trace_array(); | 2472 | tr = top_trace_array(); |
2636 | 2473 | ||
2637 | pr_info("Running tests on trace events:\n"); | 2474 | pr_info("Running tests on trace events:\n"); |
2638 | 2475 | ||
2639 | list_for_each_entry(file, &tr->events, list) { | 2476 | list_for_each_entry(file, &tr->events, list) { |
2640 | 2477 | ||
2641 | call = file->event_call; | 2478 | call = file->event_call; |
2642 | 2479 | ||
2643 | /* Only test those that have a probe */ | 2480 | /* Only test those that have a probe */ |
2644 | if (!call->class || !call->class->probe) | 2481 | if (!call->class || !call->class->probe) |
2645 | continue; | 2482 | continue; |
2646 | 2483 | ||
2647 | /* | 2484 | /* |
2648 | * Testing syscall events here is pretty useless, but | 2485 | * Testing syscall events here is pretty useless, but |
2649 | * we still do it if configured. But this is time consuming. | 2486 | * we still do it if configured. But this is time consuming. |
2650 | * What we really need is a user thread to perform the | 2487 | * What we really need is a user thread to perform the |
2651 | * syscalls as we test. | 2488 | * syscalls as we test. |
2652 | */ | 2489 | */ |
2653 | #ifndef CONFIG_EVENT_TRACE_TEST_SYSCALLS | 2490 | #ifndef CONFIG_EVENT_TRACE_TEST_SYSCALLS |
2654 | if (call->class->system && | 2491 | if (call->class->system && |
2655 | strcmp(call->class->system, "syscalls") == 0) | 2492 | strcmp(call->class->system, "syscalls") == 0) |
2656 | continue; | 2493 | continue; |
2657 | #endif | 2494 | #endif |
2658 | 2495 | ||
2659 | pr_info("Testing event %s: ", call->name); | 2496 | pr_info("Testing event %s: ", call->name); |
2660 | 2497 | ||
2661 | /* | 2498 | /* |
2662 | * If an event is already enabled, someone is using | 2499 | * If an event is already enabled, someone is using |
2663 | * it and the self test should not be on. | 2500 | * it and the self test should not be on. |
2664 | */ | 2501 | */ |
2665 | if (file->flags & FTRACE_EVENT_FL_ENABLED) { | 2502 | if (file->flags & FTRACE_EVENT_FL_ENABLED) { |
2666 | pr_warning("Enabled event during self test!\n"); | 2503 | pr_warning("Enabled event during self test!\n"); |
2667 | WARN_ON_ONCE(1); | 2504 | WARN_ON_ONCE(1); |
2668 | continue; | 2505 | continue; |
2669 | } | 2506 | } |
2670 | 2507 | ||
2671 | ftrace_event_enable_disable(file, 1); | 2508 | ftrace_event_enable_disable(file, 1); |
2672 | event_test_stuff(); | 2509 | event_test_stuff(); |
2673 | ftrace_event_enable_disable(file, 0); | 2510 | ftrace_event_enable_disable(file, 0); |
2674 | 2511 | ||
2675 | pr_cont("OK\n"); | 2512 | pr_cont("OK\n"); |
2676 | } | 2513 | } |
2677 | 2514 | ||
2678 | /* Now test at the sub system level */ | 2515 | /* Now test at the sub system level */ |
2679 | 2516 | ||
2680 | pr_info("Running tests on trace event systems:\n"); | 2517 | pr_info("Running tests on trace event systems:\n"); |
2681 | 2518 | ||
2682 | list_for_each_entry(dir, &tr->systems, list) { | 2519 | list_for_each_entry(dir, &tr->systems, list) { |
2683 | 2520 | ||
2684 | system = dir->subsystem; | 2521 | system = dir->subsystem; |
2685 | 2522 | ||
2686 | /* the ftrace system is special, skip it */ | 2523 | /* the ftrace system is special, skip it */ |
2687 | if (strcmp(system->name, "ftrace") == 0) | 2524 | if (strcmp(system->name, "ftrace") == 0) |
2688 | continue; | 2525 | continue; |
2689 | 2526 | ||
2690 | pr_info("Testing event system %s: ", system->name); | 2527 | pr_info("Testing event system %s: ", system->name); |
2691 | 2528 | ||
2692 | ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 1); | 2529 | ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 1); |
2693 | if (WARN_ON_ONCE(ret)) { | 2530 | if (WARN_ON_ONCE(ret)) { |
2694 | pr_warning("error enabling system %s\n", | 2531 | pr_warning("error enabling system %s\n", |
2695 | system->name); | 2532 | system->name); |
2696 | continue; | 2533 | continue; |
2697 | } | 2534 | } |
2698 | 2535 | ||
2699 | event_test_stuff(); | 2536 | event_test_stuff(); |
2700 | 2537 | ||
2701 | ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 0); | 2538 | ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 0); |
2702 | if (WARN_ON_ONCE(ret)) { | 2539 | if (WARN_ON_ONCE(ret)) { |
2703 | pr_warning("error disabling system %s\n", | 2540 | pr_warning("error disabling system %s\n", |
2704 | system->name); | 2541 | system->name); |
2705 | continue; | 2542 | continue; |
2706 | } | 2543 | } |
2707 | 2544 | ||
2708 | pr_cont("OK\n"); | 2545 | pr_cont("OK\n"); |
2709 | } | 2546 | } |
2710 | 2547 | ||
2711 | /* Test with all events enabled */ | 2548 | /* Test with all events enabled */ |
2712 | 2549 | ||
2713 | pr_info("Running tests on all trace events:\n"); | 2550 | pr_info("Running tests on all trace events:\n"); |
2714 | pr_info("Testing all events: "); | 2551 | pr_info("Testing all events: "); |
2715 | 2552 | ||
2716 | ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 1); | 2553 | ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 1); |
2717 | if (WARN_ON_ONCE(ret)) { | 2554 | if (WARN_ON_ONCE(ret)) { |
2718 | pr_warning("error enabling all events\n"); | 2555 | pr_warning("error enabling all events\n"); |
2719 | return; | 2556 | return; |
2720 | } | 2557 | } |
2721 | 2558 | ||
2722 | event_test_stuff(); | 2559 | event_test_stuff(); |
2723 | 2560 | ||
2724 | /* reset sysname */ | 2561 | /* reset sysname */ |
2725 | ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 0); | 2562 | ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 0); |
2726 | if (WARN_ON_ONCE(ret)) { | 2563 | if (WARN_ON_ONCE(ret)) { |
2727 | pr_warning("error disabling all events\n"); | 2564 | pr_warning("error disabling all events\n"); |
2728 | return; | 2565 | return; |
2729 | } | 2566 | } |
2730 | 2567 | ||
2731 | pr_cont("OK\n"); | 2568 | pr_cont("OK\n"); |
2732 | } | 2569 | } |
2733 | 2570 | ||
2734 | #ifdef CONFIG_FUNCTION_TRACER | 2571 | #ifdef CONFIG_FUNCTION_TRACER |
2735 | 2572 | ||
2736 | static DEFINE_PER_CPU(atomic_t, ftrace_test_event_disable); | 2573 | static DEFINE_PER_CPU(atomic_t, ftrace_test_event_disable); |
2737 | 2574 | ||
2738 | static void | 2575 | static void |
2739 | function_test_events_call(unsigned long ip, unsigned long parent_ip, | 2576 | function_test_events_call(unsigned long ip, unsigned long parent_ip, |
2740 | struct ftrace_ops *op, struct pt_regs *pt_regs) | 2577 | struct ftrace_ops *op, struct pt_regs *pt_regs) |
2741 | { | 2578 | { |
2742 | struct ring_buffer_event *event; | 2579 | struct ring_buffer_event *event; |
2743 | struct ring_buffer *buffer; | 2580 | struct ring_buffer *buffer; |
2744 | struct ftrace_entry *entry; | 2581 | struct ftrace_entry *entry; |
2745 | unsigned long flags; | 2582 | unsigned long flags; |
2746 | long disabled; | 2583 | long disabled; |
2747 | int cpu; | 2584 | int cpu; |
2748 | int pc; | 2585 | int pc; |
2749 | 2586 | ||
2750 | pc = preempt_count(); | 2587 | pc = preempt_count(); |
2751 | preempt_disable_notrace(); | 2588 | preempt_disable_notrace(); |
2752 | cpu = raw_smp_processor_id(); | 2589 | cpu = raw_smp_processor_id(); |
2753 | disabled = atomic_inc_return(&per_cpu(ftrace_test_event_disable, cpu)); | 2590 | disabled = atomic_inc_return(&per_cpu(ftrace_test_event_disable, cpu)); |
2754 | 2591 | ||
2755 | if (disabled != 1) | 2592 | if (disabled != 1) |
2756 | goto out; | 2593 | goto out; |
2757 | 2594 | ||
2758 | local_save_flags(flags); | 2595 | local_save_flags(flags); |
2759 | 2596 | ||
2760 | event = trace_current_buffer_lock_reserve(&buffer, | 2597 | event = trace_current_buffer_lock_reserve(&buffer, |
2761 | TRACE_FN, sizeof(*entry), | 2598 | TRACE_FN, sizeof(*entry), |
2762 | flags, pc); | 2599 | flags, pc); |
2763 | if (!event) | 2600 | if (!event) |
2764 | goto out; | 2601 | goto out; |
2765 | entry = ring_buffer_event_data(event); | 2602 | entry = ring_buffer_event_data(event); |
2766 | entry->ip = ip; | 2603 | entry->ip = ip; |
2767 | entry->parent_ip = parent_ip; | 2604 | entry->parent_ip = parent_ip; |
2768 | 2605 | ||
2769 | trace_buffer_unlock_commit(buffer, event, flags, pc); | 2606 | trace_buffer_unlock_commit(buffer, event, flags, pc); |
2770 | 2607 | ||
2771 | out: | 2608 | out: |
2772 | atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); | 2609 | atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); |
2773 | preempt_enable_notrace(); | 2610 | preempt_enable_notrace(); |
2774 | } | 2611 | } |
2775 | 2612 | ||
2776 | static struct ftrace_ops trace_ops __initdata = | 2613 | static struct ftrace_ops trace_ops __initdata = |
2777 | { | 2614 | { |
2778 | .func = function_test_events_call, | 2615 | .func = function_test_events_call, |
2779 | .flags = FTRACE_OPS_FL_RECURSION_SAFE, | 2616 | .flags = FTRACE_OPS_FL_RECURSION_SAFE, |
2780 | }; | 2617 | }; |
2781 | 2618 | ||
2782 | static __init void event_trace_self_test_with_function(void) | 2619 | static __init void event_trace_self_test_with_function(void) |
2783 | { | 2620 | { |
2784 | int ret; | 2621 | int ret; |
2785 | ret = register_ftrace_function(&trace_ops); | 2622 | ret = register_ftrace_function(&trace_ops); |
2786 | if (WARN_ON(ret < 0)) { | 2623 | if (WARN_ON(ret < 0)) { |
2787 | pr_info("Failed to enable function tracer for event tests\n"); | 2624 | pr_info("Failed to enable function tracer for event tests\n"); |
2788 | return; | 2625 | return; |
2789 | } | 2626 | } |
2790 | pr_info("Running tests again, along with the function tracer\n"); | 2627 | pr_info("Running tests again, along with the function tracer\n"); |
2791 | event_trace_self_tests(); | 2628 | event_trace_self_tests(); |
2792 | unregister_ftrace_function(&trace_ops); | 2629 | unregister_ftrace_function(&trace_ops); |
2793 | } | 2630 | } |
2794 | #else | 2631 | #else |
2795 | static __init void event_trace_self_test_with_function(void) | 2632 | static __init void event_trace_self_test_with_function(void) |
2796 | { | 2633 | { |
2797 | } | 2634 | } |
2798 | #endif | 2635 | #endif |
2799 | 2636 | ||
2800 | static __init int event_trace_self_tests_init(void) | 2637 | static __init int event_trace_self_tests_init(void) |
2801 | { | 2638 | { |
2802 | if (!tracing_selftest_disabled) { | 2639 | if (!tracing_selftest_disabled) { |
2803 | event_trace_self_tests(); | 2640 | event_trace_self_tests(); |
2804 | event_trace_self_test_with_function(); | 2641 | event_trace_self_test_with_function(); |
2805 | } | 2642 | } |
2806 | 2643 | ||
2807 | return 0; | 2644 | return 0; |
2808 | } | 2645 | } |
2809 | 2646 | ||
2810 | late_initcall(event_trace_self_tests_init); | 2647 | late_initcall(event_trace_self_tests_init); |
2811 | 2648 |
kernel/trace/trace_syscalls.c
1 | #include <trace/syscall.h> | 1 | #include <trace/syscall.h> |
2 | #include <trace/events/syscalls.h> | 2 | #include <trace/events/syscalls.h> |
3 | #include <linux/syscalls.h> | 3 | #include <linux/syscalls.h> |
4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/module.h> /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */ | 6 | #include <linux/module.h> /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */ |
7 | #include <linux/ftrace.h> | 7 | #include <linux/ftrace.h> |
8 | #include <linux/perf_event.h> | 8 | #include <linux/perf_event.h> |
9 | #include <asm/syscall.h> | 9 | #include <asm/syscall.h> |
10 | 10 | ||
11 | #include "trace_output.h" | 11 | #include "trace_output.h" |
12 | #include "trace.h" | 12 | #include "trace.h" |
13 | 13 | ||
14 | static DEFINE_MUTEX(syscall_trace_lock); | 14 | static DEFINE_MUTEX(syscall_trace_lock); |
15 | 15 | ||
16 | static int syscall_enter_register(struct ftrace_event_call *event, | 16 | static int syscall_enter_register(struct ftrace_event_call *event, |
17 | enum trace_reg type, void *data); | 17 | enum trace_reg type, void *data); |
18 | static int syscall_exit_register(struct ftrace_event_call *event, | 18 | static int syscall_exit_register(struct ftrace_event_call *event, |
19 | enum trace_reg type, void *data); | 19 | enum trace_reg type, void *data); |
20 | 20 | ||
21 | static struct list_head * | 21 | static struct list_head * |
22 | syscall_get_enter_fields(struct ftrace_event_call *call) | 22 | syscall_get_enter_fields(struct ftrace_event_call *call) |
23 | { | 23 | { |
24 | struct syscall_metadata *entry = call->data; | 24 | struct syscall_metadata *entry = call->data; |
25 | 25 | ||
26 | return &entry->enter_fields; | 26 | return &entry->enter_fields; |
27 | } | 27 | } |
28 | 28 | ||
29 | extern struct syscall_metadata *__start_syscalls_metadata[]; | 29 | extern struct syscall_metadata *__start_syscalls_metadata[]; |
30 | extern struct syscall_metadata *__stop_syscalls_metadata[]; | 30 | extern struct syscall_metadata *__stop_syscalls_metadata[]; |
31 | 31 | ||
32 | static struct syscall_metadata **syscalls_metadata; | 32 | static struct syscall_metadata **syscalls_metadata; |
33 | 33 | ||
34 | #ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME | 34 | #ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME |
35 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) | 35 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) |
36 | { | 36 | { |
37 | /* | 37 | /* |
38 | * Only compare after the "sys" prefix. Archs that use | 38 | * Only compare after the "sys" prefix. Archs that use |
39 | * syscall wrappers may have syscalls symbols aliases prefixed | 39 | * syscall wrappers may have syscalls symbols aliases prefixed |
40 | * with ".SyS" or ".sys" instead of "sys", leading to an unwanted | 40 | * with ".SyS" or ".sys" instead of "sys", leading to an unwanted |
41 | * mismatch. | 41 | * mismatch. |
42 | */ | 42 | */ |
43 | return !strcmp(sym + 3, name + 3); | 43 | return !strcmp(sym + 3, name + 3); |
44 | } | 44 | } |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #ifdef ARCH_TRACE_IGNORE_COMPAT_SYSCALLS | 47 | #ifdef ARCH_TRACE_IGNORE_COMPAT_SYSCALLS |
48 | /* | 48 | /* |
49 | * Some architectures that allow for 32bit applications | 49 | * Some architectures that allow for 32bit applications |
50 | * to run on a 64bit kernel, do not map the syscalls for | 50 | * to run on a 64bit kernel, do not map the syscalls for |
51 | * the 32bit tasks the same as they do for 64bit tasks. | 51 | * the 32bit tasks the same as they do for 64bit tasks. |
52 | * | 52 | * |
53 | * *cough*x86*cough* | 53 | * *cough*x86*cough* |
54 | * | 54 | * |
55 | * In such a case, instead of reporting the wrong syscalls, | 55 | * In such a case, instead of reporting the wrong syscalls, |
56 | * simply ignore them. | 56 | * simply ignore them. |
57 | * | 57 | * |
58 | * For an arch to ignore the compat syscalls it needs to | 58 | * For an arch to ignore the compat syscalls it needs to |
59 | * define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS as well as | 59 | * define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS as well as |
60 | * define the function arch_trace_is_compat_syscall() to let | 60 | * define the function arch_trace_is_compat_syscall() to let |
61 | * the tracing system know that it should ignore it. | 61 | * the tracing system know that it should ignore it. |
62 | */ | 62 | */ |
63 | static int | 63 | static int |
64 | trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs) | 64 | trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs) |
65 | { | 65 | { |
66 | if (unlikely(arch_trace_is_compat_syscall(regs))) | 66 | if (unlikely(arch_trace_is_compat_syscall(regs))) |
67 | return -1; | 67 | return -1; |
68 | 68 | ||
69 | return syscall_get_nr(task, regs); | 69 | return syscall_get_nr(task, regs); |
70 | } | 70 | } |
71 | #else | 71 | #else |
72 | static inline int | 72 | static inline int |
73 | trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs) | 73 | trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs) |
74 | { | 74 | { |
75 | return syscall_get_nr(task, regs); | 75 | return syscall_get_nr(task, regs); |
76 | } | 76 | } |
77 | #endif /* ARCH_TRACE_IGNORE_COMPAT_SYSCALLS */ | 77 | #endif /* ARCH_TRACE_IGNORE_COMPAT_SYSCALLS */ |
78 | 78 | ||
79 | static __init struct syscall_metadata * | 79 | static __init struct syscall_metadata * |
80 | find_syscall_meta(unsigned long syscall) | 80 | find_syscall_meta(unsigned long syscall) |
81 | { | 81 | { |
82 | struct syscall_metadata **start; | 82 | struct syscall_metadata **start; |
83 | struct syscall_metadata **stop; | 83 | struct syscall_metadata **stop; |
84 | char str[KSYM_SYMBOL_LEN]; | 84 | char str[KSYM_SYMBOL_LEN]; |
85 | 85 | ||
86 | 86 | ||
87 | start = __start_syscalls_metadata; | 87 | start = __start_syscalls_metadata; |
88 | stop = __stop_syscalls_metadata; | 88 | stop = __stop_syscalls_metadata; |
89 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); | 89 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); |
90 | 90 | ||
91 | if (arch_syscall_match_sym_name(str, "sys_ni_syscall")) | 91 | if (arch_syscall_match_sym_name(str, "sys_ni_syscall")) |
92 | return NULL; | 92 | return NULL; |
93 | 93 | ||
94 | for ( ; start < stop; start++) { | 94 | for ( ; start < stop; start++) { |
95 | if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name)) | 95 | if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name)) |
96 | return *start; | 96 | return *start; |
97 | } | 97 | } |
98 | return NULL; | 98 | return NULL; |
99 | } | 99 | } |
100 | 100 | ||
101 | static struct syscall_metadata *syscall_nr_to_meta(int nr) | 101 | static struct syscall_metadata *syscall_nr_to_meta(int nr) |
102 | { | 102 | { |
103 | if (!syscalls_metadata || nr >= NR_syscalls || nr < 0) | 103 | if (!syscalls_metadata || nr >= NR_syscalls || nr < 0) |
104 | return NULL; | 104 | return NULL; |
105 | 105 | ||
106 | return syscalls_metadata[nr]; | 106 | return syscalls_metadata[nr]; |
107 | } | 107 | } |
108 | 108 | ||
109 | static enum print_line_t | 109 | static enum print_line_t |
110 | print_syscall_enter(struct trace_iterator *iter, int flags, | 110 | print_syscall_enter(struct trace_iterator *iter, int flags, |
111 | struct trace_event *event) | 111 | struct trace_event *event) |
112 | { | 112 | { |
113 | struct trace_seq *s = &iter->seq; | 113 | struct trace_seq *s = &iter->seq; |
114 | struct trace_entry *ent = iter->ent; | 114 | struct trace_entry *ent = iter->ent; |
115 | struct syscall_trace_enter *trace; | 115 | struct syscall_trace_enter *trace; |
116 | struct syscall_metadata *entry; | 116 | struct syscall_metadata *entry; |
117 | int i, ret, syscall; | 117 | int i, ret, syscall; |
118 | 118 | ||
119 | trace = (typeof(trace))ent; | 119 | trace = (typeof(trace))ent; |
120 | syscall = trace->nr; | 120 | syscall = trace->nr; |
121 | entry = syscall_nr_to_meta(syscall); | 121 | entry = syscall_nr_to_meta(syscall); |
122 | 122 | ||
123 | if (!entry) | 123 | if (!entry) |
124 | goto end; | 124 | goto end; |
125 | 125 | ||
126 | if (entry->enter_event->event.type != ent->type) { | 126 | if (entry->enter_event->event.type != ent->type) { |
127 | WARN_ON_ONCE(1); | 127 | WARN_ON_ONCE(1); |
128 | goto end; | 128 | goto end; |
129 | } | 129 | } |
130 | 130 | ||
131 | ret = trace_seq_printf(s, "%s(", entry->name); | 131 | ret = trace_seq_printf(s, "%s(", entry->name); |
132 | if (!ret) | 132 | if (!ret) |
133 | return TRACE_TYPE_PARTIAL_LINE; | 133 | return TRACE_TYPE_PARTIAL_LINE; |
134 | 134 | ||
135 | for (i = 0; i < entry->nb_args; i++) { | 135 | for (i = 0; i < entry->nb_args; i++) { |
136 | /* parameter types */ | 136 | /* parameter types */ |
137 | if (trace_flags & TRACE_ITER_VERBOSE) { | 137 | if (trace_flags & TRACE_ITER_VERBOSE) { |
138 | ret = trace_seq_printf(s, "%s ", entry->types[i]); | 138 | ret = trace_seq_printf(s, "%s ", entry->types[i]); |
139 | if (!ret) | 139 | if (!ret) |
140 | return TRACE_TYPE_PARTIAL_LINE; | 140 | return TRACE_TYPE_PARTIAL_LINE; |
141 | } | 141 | } |
142 | /* parameter values */ | 142 | /* parameter values */ |
143 | ret = trace_seq_printf(s, "%s: %lx%s", entry->args[i], | 143 | ret = trace_seq_printf(s, "%s: %lx%s", entry->args[i], |
144 | trace->args[i], | 144 | trace->args[i], |
145 | i == entry->nb_args - 1 ? "" : ", "); | 145 | i == entry->nb_args - 1 ? "" : ", "); |
146 | if (!ret) | 146 | if (!ret) |
147 | return TRACE_TYPE_PARTIAL_LINE; | 147 | return TRACE_TYPE_PARTIAL_LINE; |
148 | } | 148 | } |
149 | 149 | ||
150 | ret = trace_seq_putc(s, ')'); | 150 | ret = trace_seq_putc(s, ')'); |
151 | if (!ret) | 151 | if (!ret) |
152 | return TRACE_TYPE_PARTIAL_LINE; | 152 | return TRACE_TYPE_PARTIAL_LINE; |
153 | 153 | ||
154 | end: | 154 | end: |
155 | ret = trace_seq_putc(s, '\n'); | 155 | ret = trace_seq_putc(s, '\n'); |
156 | if (!ret) | 156 | if (!ret) |
157 | return TRACE_TYPE_PARTIAL_LINE; | 157 | return TRACE_TYPE_PARTIAL_LINE; |
158 | 158 | ||
159 | return TRACE_TYPE_HANDLED; | 159 | return TRACE_TYPE_HANDLED; |
160 | } | 160 | } |
161 | 161 | ||
162 | static enum print_line_t | 162 | static enum print_line_t |
163 | print_syscall_exit(struct trace_iterator *iter, int flags, | 163 | print_syscall_exit(struct trace_iterator *iter, int flags, |
164 | struct trace_event *event) | 164 | struct trace_event *event) |
165 | { | 165 | { |
166 | struct trace_seq *s = &iter->seq; | 166 | struct trace_seq *s = &iter->seq; |
167 | struct trace_entry *ent = iter->ent; | 167 | struct trace_entry *ent = iter->ent; |
168 | struct syscall_trace_exit *trace; | 168 | struct syscall_trace_exit *trace; |
169 | int syscall; | 169 | int syscall; |
170 | struct syscall_metadata *entry; | 170 | struct syscall_metadata *entry; |
171 | int ret; | 171 | int ret; |
172 | 172 | ||
173 | trace = (typeof(trace))ent; | 173 | trace = (typeof(trace))ent; |
174 | syscall = trace->nr; | 174 | syscall = trace->nr; |
175 | entry = syscall_nr_to_meta(syscall); | 175 | entry = syscall_nr_to_meta(syscall); |
176 | 176 | ||
177 | if (!entry) { | 177 | if (!entry) { |
178 | trace_seq_putc(s, '\n'); | 178 | trace_seq_putc(s, '\n'); |
179 | return TRACE_TYPE_HANDLED; | 179 | return TRACE_TYPE_HANDLED; |
180 | } | 180 | } |
181 | 181 | ||
182 | if (entry->exit_event->event.type != ent->type) { | 182 | if (entry->exit_event->event.type != ent->type) { |
183 | WARN_ON_ONCE(1); | 183 | WARN_ON_ONCE(1); |
184 | return TRACE_TYPE_UNHANDLED; | 184 | return TRACE_TYPE_UNHANDLED; |
185 | } | 185 | } |
186 | 186 | ||
187 | ret = trace_seq_printf(s, "%s -> 0x%lx\n", entry->name, | 187 | ret = trace_seq_printf(s, "%s -> 0x%lx\n", entry->name, |
188 | trace->ret); | 188 | trace->ret); |
189 | if (!ret) | 189 | if (!ret) |
190 | return TRACE_TYPE_PARTIAL_LINE; | 190 | return TRACE_TYPE_PARTIAL_LINE; |
191 | 191 | ||
192 | return TRACE_TYPE_HANDLED; | 192 | return TRACE_TYPE_HANDLED; |
193 | } | 193 | } |
194 | 194 | ||
195 | extern char *__bad_type_size(void); | 195 | extern char *__bad_type_size(void); |
196 | 196 | ||
197 | #define SYSCALL_FIELD(type, name) \ | 197 | #define SYSCALL_FIELD(type, name) \ |
198 | sizeof(type) != sizeof(trace.name) ? \ | 198 | sizeof(type) != sizeof(trace.name) ? \ |
199 | __bad_type_size() : \ | 199 | __bad_type_size() : \ |
200 | #type, #name, offsetof(typeof(trace), name), \ | 200 | #type, #name, offsetof(typeof(trace), name), \ |
201 | sizeof(trace.name), is_signed_type(type) | 201 | sizeof(trace.name), is_signed_type(type) |
202 | 202 | ||
203 | static | 203 | static int __init |
204 | int __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len) | 204 | __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len) |
205 | { | 205 | { |
206 | int i; | 206 | int i; |
207 | int pos = 0; | 207 | int pos = 0; |
208 | 208 | ||
209 | /* When len=0, we just calculate the needed length */ | 209 | /* When len=0, we just calculate the needed length */ |
210 | #define LEN_OR_ZERO (len ? len - pos : 0) | 210 | #define LEN_OR_ZERO (len ? len - pos : 0) |
211 | 211 | ||
212 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\""); | 212 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\""); |
213 | for (i = 0; i < entry->nb_args; i++) { | 213 | for (i = 0; i < entry->nb_args; i++) { |
214 | pos += snprintf(buf + pos, LEN_OR_ZERO, "%s: 0x%%0%zulx%s", | 214 | pos += snprintf(buf + pos, LEN_OR_ZERO, "%s: 0x%%0%zulx%s", |
215 | entry->args[i], sizeof(unsigned long), | 215 | entry->args[i], sizeof(unsigned long), |
216 | i == entry->nb_args - 1 ? "" : ", "); | 216 | i == entry->nb_args - 1 ? "" : ", "); |
217 | } | 217 | } |
218 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\""); | 218 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\""); |
219 | 219 | ||
220 | for (i = 0; i < entry->nb_args; i++) { | 220 | for (i = 0; i < entry->nb_args; i++) { |
221 | pos += snprintf(buf + pos, LEN_OR_ZERO, | 221 | pos += snprintf(buf + pos, LEN_OR_ZERO, |
222 | ", ((unsigned long)(REC->%s))", entry->args[i]); | 222 | ", ((unsigned long)(REC->%s))", entry->args[i]); |
223 | } | 223 | } |
224 | 224 | ||
225 | #undef LEN_OR_ZERO | 225 | #undef LEN_OR_ZERO |
226 | 226 | ||
227 | /* return the length of print_fmt */ | 227 | /* return the length of print_fmt */ |
228 | return pos; | 228 | return pos; |
229 | } | 229 | } |
230 | 230 | ||
231 | static int set_syscall_print_fmt(struct ftrace_event_call *call) | 231 | static int __init set_syscall_print_fmt(struct ftrace_event_call *call) |
232 | { | 232 | { |
233 | char *print_fmt; | 233 | char *print_fmt; |
234 | int len; | 234 | int len; |
235 | struct syscall_metadata *entry = call->data; | 235 | struct syscall_metadata *entry = call->data; |
236 | 236 | ||
237 | if (entry->enter_event != call) { | 237 | if (entry->enter_event != call) { |
238 | call->print_fmt = "\"0x%lx\", REC->ret"; | 238 | call->print_fmt = "\"0x%lx\", REC->ret"; |
239 | return 0; | 239 | return 0; |
240 | } | 240 | } |
241 | 241 | ||
242 | /* First: called with 0 length to calculate the needed length */ | 242 | /* First: called with 0 length to calculate the needed length */ |
243 | len = __set_enter_print_fmt(entry, NULL, 0); | 243 | len = __set_enter_print_fmt(entry, NULL, 0); |
244 | 244 | ||
245 | print_fmt = kmalloc(len + 1, GFP_KERNEL); | 245 | print_fmt = kmalloc(len + 1, GFP_KERNEL); |
246 | if (!print_fmt) | 246 | if (!print_fmt) |
247 | return -ENOMEM; | 247 | return -ENOMEM; |
248 | 248 | ||
249 | /* Second: actually write the @print_fmt */ | 249 | /* Second: actually write the @print_fmt */ |
250 | __set_enter_print_fmt(entry, print_fmt, len + 1); | 250 | __set_enter_print_fmt(entry, print_fmt, len + 1); |
251 | call->print_fmt = print_fmt; | 251 | call->print_fmt = print_fmt; |
252 | 252 | ||
253 | return 0; | 253 | return 0; |
254 | } | 254 | } |
255 | 255 | ||
256 | static void free_syscall_print_fmt(struct ftrace_event_call *call) | 256 | static void __init free_syscall_print_fmt(struct ftrace_event_call *call) |
257 | { | 257 | { |
258 | struct syscall_metadata *entry = call->data; | 258 | struct syscall_metadata *entry = call->data; |
259 | 259 | ||
260 | if (entry->enter_event == call) | 260 | if (entry->enter_event == call) |
261 | kfree(call->print_fmt); | 261 | kfree(call->print_fmt); |
262 | } | 262 | } |
263 | 263 | ||
264 | static int __init syscall_enter_define_fields(struct ftrace_event_call *call) | 264 | static int __init syscall_enter_define_fields(struct ftrace_event_call *call) |
265 | { | 265 | { |
266 | struct syscall_trace_enter trace; | 266 | struct syscall_trace_enter trace; |
267 | struct syscall_metadata *meta = call->data; | 267 | struct syscall_metadata *meta = call->data; |
268 | int ret; | 268 | int ret; |
269 | int i; | 269 | int i; |
270 | int offset = offsetof(typeof(trace), args); | 270 | int offset = offsetof(typeof(trace), args); |
271 | 271 | ||
272 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); | 272 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); |
273 | if (ret) | 273 | if (ret) |
274 | return ret; | 274 | return ret; |
275 | 275 | ||
276 | for (i = 0; i < meta->nb_args; i++) { | 276 | for (i = 0; i < meta->nb_args; i++) { |
277 | ret = trace_define_field(call, meta->types[i], | 277 | ret = trace_define_field(call, meta->types[i], |
278 | meta->args[i], offset, | 278 | meta->args[i], offset, |
279 | sizeof(unsigned long), 0, | 279 | sizeof(unsigned long), 0, |
280 | FILTER_OTHER); | 280 | FILTER_OTHER); |
281 | offset += sizeof(unsigned long); | 281 | offset += sizeof(unsigned long); |
282 | } | 282 | } |
283 | 283 | ||
284 | return ret; | 284 | return ret; |
285 | } | 285 | } |
286 | 286 | ||
287 | static int __init syscall_exit_define_fields(struct ftrace_event_call *call) | 287 | static int __init syscall_exit_define_fields(struct ftrace_event_call *call) |
288 | { | 288 | { |
289 | struct syscall_trace_exit trace; | 289 | struct syscall_trace_exit trace; |
290 | int ret; | 290 | int ret; |
291 | 291 | ||
292 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); | 292 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); |
293 | if (ret) | 293 | if (ret) |
294 | return ret; | 294 | return ret; |
295 | 295 | ||
296 | ret = trace_define_field(call, SYSCALL_FIELD(long, ret), | 296 | ret = trace_define_field(call, SYSCALL_FIELD(long, ret), |
297 | FILTER_OTHER); | 297 | FILTER_OTHER); |
298 | 298 | ||
299 | return ret; | 299 | return ret; |
300 | } | 300 | } |
301 | 301 | ||
302 | static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id) | 302 | static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id) |
303 | { | 303 | { |
304 | struct trace_array *tr = data; | 304 | struct trace_array *tr = data; |
305 | struct syscall_trace_enter *entry; | 305 | struct syscall_trace_enter *entry; |
306 | struct syscall_metadata *sys_data; | 306 | struct syscall_metadata *sys_data; |
307 | struct ring_buffer_event *event; | 307 | struct ring_buffer_event *event; |
308 | struct ring_buffer *buffer; | 308 | struct ring_buffer *buffer; |
309 | unsigned long irq_flags; | 309 | unsigned long irq_flags; |
310 | int pc; | 310 | int pc; |
311 | int syscall_nr; | 311 | int syscall_nr; |
312 | int size; | 312 | int size; |
313 | 313 | ||
314 | syscall_nr = trace_get_syscall_nr(current, regs); | 314 | syscall_nr = trace_get_syscall_nr(current, regs); |
315 | if (syscall_nr < 0) | 315 | if (syscall_nr < 0) |
316 | return; | 316 | return; |
317 | if (!test_bit(syscall_nr, tr->enabled_enter_syscalls)) | 317 | if (!test_bit(syscall_nr, tr->enabled_enter_syscalls)) |
318 | return; | 318 | return; |
319 | 319 | ||
320 | sys_data = syscall_nr_to_meta(syscall_nr); | 320 | sys_data = syscall_nr_to_meta(syscall_nr); |
321 | if (!sys_data) | 321 | if (!sys_data) |
322 | return; | 322 | return; |
323 | 323 | ||
324 | size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args; | 324 | size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args; |
325 | 325 | ||
326 | local_save_flags(irq_flags); | 326 | local_save_flags(irq_flags); |
327 | pc = preempt_count(); | 327 | pc = preempt_count(); |
328 | 328 | ||
329 | buffer = tr->trace_buffer.buffer; | 329 | buffer = tr->trace_buffer.buffer; |
330 | event = trace_buffer_lock_reserve(buffer, | 330 | event = trace_buffer_lock_reserve(buffer, |
331 | sys_data->enter_event->event.type, size, irq_flags, pc); | 331 | sys_data->enter_event->event.type, size, irq_flags, pc); |
332 | if (!event) | 332 | if (!event) |
333 | return; | 333 | return; |
334 | 334 | ||
335 | entry = ring_buffer_event_data(event); | 335 | entry = ring_buffer_event_data(event); |
336 | entry->nr = syscall_nr; | 336 | entry->nr = syscall_nr; |
337 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args); | 337 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args); |
338 | 338 | ||
339 | if (!filter_current_check_discard(buffer, sys_data->enter_event, | 339 | if (!filter_current_check_discard(buffer, sys_data->enter_event, |
340 | entry, event)) | 340 | entry, event)) |
341 | trace_current_buffer_unlock_commit(buffer, event, | 341 | trace_current_buffer_unlock_commit(buffer, event, |
342 | irq_flags, pc); | 342 | irq_flags, pc); |
343 | } | 343 | } |
344 | 344 | ||
345 | static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret) | 345 | static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret) |
346 | { | 346 | { |
347 | struct trace_array *tr = data; | 347 | struct trace_array *tr = data; |
348 | struct syscall_trace_exit *entry; | 348 | struct syscall_trace_exit *entry; |
349 | struct syscall_metadata *sys_data; | 349 | struct syscall_metadata *sys_data; |
350 | struct ring_buffer_event *event; | 350 | struct ring_buffer_event *event; |
351 | struct ring_buffer *buffer; | 351 | struct ring_buffer *buffer; |
352 | unsigned long irq_flags; | 352 | unsigned long irq_flags; |
353 | int pc; | 353 | int pc; |
354 | int syscall_nr; | 354 | int syscall_nr; |
355 | 355 | ||
356 | syscall_nr = trace_get_syscall_nr(current, regs); | 356 | syscall_nr = trace_get_syscall_nr(current, regs); |
357 | if (syscall_nr < 0) | 357 | if (syscall_nr < 0) |
358 | return; | 358 | return; |
359 | if (!test_bit(syscall_nr, tr->enabled_exit_syscalls)) | 359 | if (!test_bit(syscall_nr, tr->enabled_exit_syscalls)) |
360 | return; | 360 | return; |
361 | 361 | ||
362 | sys_data = syscall_nr_to_meta(syscall_nr); | 362 | sys_data = syscall_nr_to_meta(syscall_nr); |
363 | if (!sys_data) | 363 | if (!sys_data) |
364 | return; | 364 | return; |
365 | 365 | ||
366 | local_save_flags(irq_flags); | 366 | local_save_flags(irq_flags); |
367 | pc = preempt_count(); | 367 | pc = preempt_count(); |
368 | 368 | ||
369 | buffer = tr->trace_buffer.buffer; | 369 | buffer = tr->trace_buffer.buffer; |
370 | event = trace_buffer_lock_reserve(buffer, | 370 | event = trace_buffer_lock_reserve(buffer, |
371 | sys_data->exit_event->event.type, sizeof(*entry), | 371 | sys_data->exit_event->event.type, sizeof(*entry), |
372 | irq_flags, pc); | 372 | irq_flags, pc); |
373 | if (!event) | 373 | if (!event) |
374 | return; | 374 | return; |
375 | 375 | ||
376 | entry = ring_buffer_event_data(event); | 376 | entry = ring_buffer_event_data(event); |
377 | entry->nr = syscall_nr; | 377 | entry->nr = syscall_nr; |
378 | entry->ret = syscall_get_return_value(current, regs); | 378 | entry->ret = syscall_get_return_value(current, regs); |
379 | 379 | ||
380 | if (!filter_current_check_discard(buffer, sys_data->exit_event, | 380 | if (!filter_current_check_discard(buffer, sys_data->exit_event, |
381 | entry, event)) | 381 | entry, event)) |
382 | trace_current_buffer_unlock_commit(buffer, event, | 382 | trace_current_buffer_unlock_commit(buffer, event, |
383 | irq_flags, pc); | 383 | irq_flags, pc); |
384 | } | 384 | } |
385 | 385 | ||
386 | static int reg_event_syscall_enter(struct ftrace_event_file *file, | 386 | static int reg_event_syscall_enter(struct ftrace_event_file *file, |
387 | struct ftrace_event_call *call) | 387 | struct ftrace_event_call *call) |
388 | { | 388 | { |
389 | struct trace_array *tr = file->tr; | 389 | struct trace_array *tr = file->tr; |
390 | int ret = 0; | 390 | int ret = 0; |
391 | int num; | 391 | int num; |
392 | 392 | ||
393 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 393 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
394 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) | 394 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) |
395 | return -ENOSYS; | 395 | return -ENOSYS; |
396 | mutex_lock(&syscall_trace_lock); | 396 | mutex_lock(&syscall_trace_lock); |
397 | if (!tr->sys_refcount_enter) | 397 | if (!tr->sys_refcount_enter) |
398 | ret = register_trace_sys_enter(ftrace_syscall_enter, tr); | 398 | ret = register_trace_sys_enter(ftrace_syscall_enter, tr); |
399 | if (!ret) { | 399 | if (!ret) { |
400 | set_bit(num, tr->enabled_enter_syscalls); | 400 | set_bit(num, tr->enabled_enter_syscalls); |
401 | tr->sys_refcount_enter++; | 401 | tr->sys_refcount_enter++; |
402 | } | 402 | } |
403 | mutex_unlock(&syscall_trace_lock); | 403 | mutex_unlock(&syscall_trace_lock); |
404 | return ret; | 404 | return ret; |
405 | } | 405 | } |
406 | 406 | ||
407 | static void unreg_event_syscall_enter(struct ftrace_event_file *file, | 407 | static void unreg_event_syscall_enter(struct ftrace_event_file *file, |
408 | struct ftrace_event_call *call) | 408 | struct ftrace_event_call *call) |
409 | { | 409 | { |
410 | struct trace_array *tr = file->tr; | 410 | struct trace_array *tr = file->tr; |
411 | int num; | 411 | int num; |
412 | 412 | ||
413 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 413 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
414 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) | 414 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) |
415 | return; | 415 | return; |
416 | mutex_lock(&syscall_trace_lock); | 416 | mutex_lock(&syscall_trace_lock); |
417 | tr->sys_refcount_enter--; | 417 | tr->sys_refcount_enter--; |
418 | clear_bit(num, tr->enabled_enter_syscalls); | 418 | clear_bit(num, tr->enabled_enter_syscalls); |
419 | if (!tr->sys_refcount_enter) | 419 | if (!tr->sys_refcount_enter) |
420 | unregister_trace_sys_enter(ftrace_syscall_enter, tr); | 420 | unregister_trace_sys_enter(ftrace_syscall_enter, tr); |
421 | mutex_unlock(&syscall_trace_lock); | 421 | mutex_unlock(&syscall_trace_lock); |
422 | } | 422 | } |
423 | 423 | ||
424 | static int reg_event_syscall_exit(struct ftrace_event_file *file, | 424 | static int reg_event_syscall_exit(struct ftrace_event_file *file, |
425 | struct ftrace_event_call *call) | 425 | struct ftrace_event_call *call) |
426 | { | 426 | { |
427 | struct trace_array *tr = file->tr; | 427 | struct trace_array *tr = file->tr; |
428 | int ret = 0; | 428 | int ret = 0; |
429 | int num; | 429 | int num; |
430 | 430 | ||
431 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 431 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
432 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) | 432 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) |
433 | return -ENOSYS; | 433 | return -ENOSYS; |
434 | mutex_lock(&syscall_trace_lock); | 434 | mutex_lock(&syscall_trace_lock); |
435 | if (!tr->sys_refcount_exit) | 435 | if (!tr->sys_refcount_exit) |
436 | ret = register_trace_sys_exit(ftrace_syscall_exit, tr); | 436 | ret = register_trace_sys_exit(ftrace_syscall_exit, tr); |
437 | if (!ret) { | 437 | if (!ret) { |
438 | set_bit(num, tr->enabled_exit_syscalls); | 438 | set_bit(num, tr->enabled_exit_syscalls); |
439 | tr->sys_refcount_exit++; | 439 | tr->sys_refcount_exit++; |
440 | } | 440 | } |
441 | mutex_unlock(&syscall_trace_lock); | 441 | mutex_unlock(&syscall_trace_lock); |
442 | return ret; | 442 | return ret; |
443 | } | 443 | } |
444 | 444 | ||
445 | static void unreg_event_syscall_exit(struct ftrace_event_file *file, | 445 | static void unreg_event_syscall_exit(struct ftrace_event_file *file, |
446 | struct ftrace_event_call *call) | 446 | struct ftrace_event_call *call) |
447 | { | 447 | { |
448 | struct trace_array *tr = file->tr; | 448 | struct trace_array *tr = file->tr; |
449 | int num; | 449 | int num; |
450 | 450 | ||
451 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 451 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
452 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) | 452 | if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls)) |
453 | return; | 453 | return; |
454 | mutex_lock(&syscall_trace_lock); | 454 | mutex_lock(&syscall_trace_lock); |
455 | tr->sys_refcount_exit--; | 455 | tr->sys_refcount_exit--; |
456 | clear_bit(num, tr->enabled_exit_syscalls); | 456 | clear_bit(num, tr->enabled_exit_syscalls); |
457 | if (!tr->sys_refcount_exit) | 457 | if (!tr->sys_refcount_exit) |
458 | unregister_trace_sys_exit(ftrace_syscall_exit, tr); | 458 | unregister_trace_sys_exit(ftrace_syscall_exit, tr); |
459 | mutex_unlock(&syscall_trace_lock); | 459 | mutex_unlock(&syscall_trace_lock); |
460 | } | 460 | } |
461 | 461 | ||
462 | static int init_syscall_trace(struct ftrace_event_call *call) | 462 | static int __init init_syscall_trace(struct ftrace_event_call *call) |
463 | { | 463 | { |
464 | int id; | 464 | int id; |
465 | int num; | 465 | int num; |
466 | 466 | ||
467 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 467 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
468 | if (num < 0 || num >= NR_syscalls) { | 468 | if (num < 0 || num >= NR_syscalls) { |
469 | pr_debug("syscall %s metadata not mapped, disabling ftrace event\n", | 469 | pr_debug("syscall %s metadata not mapped, disabling ftrace event\n", |
470 | ((struct syscall_metadata *)call->data)->name); | 470 | ((struct syscall_metadata *)call->data)->name); |
471 | return -ENOSYS; | 471 | return -ENOSYS; |
472 | } | 472 | } |
473 | 473 | ||
474 | if (set_syscall_print_fmt(call) < 0) | 474 | if (set_syscall_print_fmt(call) < 0) |
475 | return -ENOMEM; | 475 | return -ENOMEM; |
476 | 476 | ||
477 | id = trace_event_raw_init(call); | 477 | id = trace_event_raw_init(call); |
478 | 478 | ||
479 | if (id < 0) { | 479 | if (id < 0) { |
480 | free_syscall_print_fmt(call); | 480 | free_syscall_print_fmt(call); |
481 | return id; | 481 | return id; |
482 | } | 482 | } |
483 | 483 | ||
484 | return id; | 484 | return id; |
485 | } | 485 | } |
486 | 486 | ||
487 | struct trace_event_functions enter_syscall_print_funcs = { | 487 | struct trace_event_functions enter_syscall_print_funcs = { |
488 | .trace = print_syscall_enter, | 488 | .trace = print_syscall_enter, |
489 | }; | 489 | }; |
490 | 490 | ||
491 | struct trace_event_functions exit_syscall_print_funcs = { | 491 | struct trace_event_functions exit_syscall_print_funcs = { |
492 | .trace = print_syscall_exit, | 492 | .trace = print_syscall_exit, |
493 | }; | 493 | }; |
494 | 494 | ||
495 | struct ftrace_event_class __refdata event_class_syscall_enter = { | 495 | struct ftrace_event_class __refdata event_class_syscall_enter = { |
496 | .system = "syscalls", | 496 | .system = "syscalls", |
497 | .reg = syscall_enter_register, | 497 | .reg = syscall_enter_register, |
498 | .define_fields = syscall_enter_define_fields, | 498 | .define_fields = syscall_enter_define_fields, |
499 | .get_fields = syscall_get_enter_fields, | 499 | .get_fields = syscall_get_enter_fields, |
500 | .raw_init = init_syscall_trace, | 500 | .raw_init = init_syscall_trace, |
501 | }; | 501 | }; |
502 | 502 | ||
503 | struct ftrace_event_class __refdata event_class_syscall_exit = { | 503 | struct ftrace_event_class __refdata event_class_syscall_exit = { |
504 | .system = "syscalls", | 504 | .system = "syscalls", |
505 | .reg = syscall_exit_register, | 505 | .reg = syscall_exit_register, |
506 | .define_fields = syscall_exit_define_fields, | 506 | .define_fields = syscall_exit_define_fields, |
507 | .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields), | 507 | .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields), |
508 | .raw_init = init_syscall_trace, | 508 | .raw_init = init_syscall_trace, |
509 | }; | 509 | }; |
510 | 510 | ||
511 | unsigned long __init __weak arch_syscall_addr(int nr) | 511 | unsigned long __init __weak arch_syscall_addr(int nr) |
512 | { | 512 | { |
513 | return (unsigned long)sys_call_table[nr]; | 513 | return (unsigned long)sys_call_table[nr]; |
514 | } | 514 | } |
515 | 515 | ||
516 | static int __init init_ftrace_syscalls(void) | 516 | static int __init init_ftrace_syscalls(void) |
517 | { | 517 | { |
518 | struct syscall_metadata *meta; | 518 | struct syscall_metadata *meta; |
519 | unsigned long addr; | 519 | unsigned long addr; |
520 | int i; | 520 | int i; |
521 | 521 | ||
522 | syscalls_metadata = kcalloc(NR_syscalls, sizeof(*syscalls_metadata), | 522 | syscalls_metadata = kcalloc(NR_syscalls, sizeof(*syscalls_metadata), |
523 | GFP_KERNEL); | 523 | GFP_KERNEL); |
524 | if (!syscalls_metadata) { | 524 | if (!syscalls_metadata) { |
525 | WARN_ON(1); | 525 | WARN_ON(1); |
526 | return -ENOMEM; | 526 | return -ENOMEM; |
527 | } | 527 | } |
528 | 528 | ||
529 | for (i = 0; i < NR_syscalls; i++) { | 529 | for (i = 0; i < NR_syscalls; i++) { |
530 | addr = arch_syscall_addr(i); | 530 | addr = arch_syscall_addr(i); |
531 | meta = find_syscall_meta(addr); | 531 | meta = find_syscall_meta(addr); |
532 | if (!meta) | 532 | if (!meta) |
533 | continue; | 533 | continue; |
534 | 534 | ||
535 | meta->syscall_nr = i; | 535 | meta->syscall_nr = i; |
536 | syscalls_metadata[i] = meta; | 536 | syscalls_metadata[i] = meta; |
537 | } | 537 | } |
538 | 538 | ||
539 | return 0; | 539 | return 0; |
540 | } | 540 | } |
541 | early_initcall(init_ftrace_syscalls); | 541 | early_initcall(init_ftrace_syscalls); |
542 | 542 | ||
543 | #ifdef CONFIG_PERF_EVENTS | 543 | #ifdef CONFIG_PERF_EVENTS |
544 | 544 | ||
545 | static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls); | 545 | static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls); |
546 | static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls); | 546 | static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls); |
547 | static int sys_perf_refcount_enter; | 547 | static int sys_perf_refcount_enter; |
548 | static int sys_perf_refcount_exit; | 548 | static int sys_perf_refcount_exit; |
549 | 549 | ||
550 | static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) | 550 | static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) |
551 | { | 551 | { |
552 | struct syscall_metadata *sys_data; | 552 | struct syscall_metadata *sys_data; |
553 | struct syscall_trace_enter *rec; | 553 | struct syscall_trace_enter *rec; |
554 | struct hlist_head *head; | 554 | struct hlist_head *head; |
555 | int syscall_nr; | 555 | int syscall_nr; |
556 | int rctx; | 556 | int rctx; |
557 | int size; | 557 | int size; |
558 | 558 | ||
559 | syscall_nr = trace_get_syscall_nr(current, regs); | 559 | syscall_nr = trace_get_syscall_nr(current, regs); |
560 | if (syscall_nr < 0) | 560 | if (syscall_nr < 0) |
561 | return; | 561 | return; |
562 | if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) | 562 | if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) |
563 | return; | 563 | return; |
564 | 564 | ||
565 | sys_data = syscall_nr_to_meta(syscall_nr); | 565 | sys_data = syscall_nr_to_meta(syscall_nr); |
566 | if (!sys_data) | 566 | if (!sys_data) |
567 | return; | 567 | return; |
568 | 568 | ||
569 | head = this_cpu_ptr(sys_data->enter_event->perf_events); | 569 | head = this_cpu_ptr(sys_data->enter_event->perf_events); |
570 | if (hlist_empty(head)) | 570 | if (hlist_empty(head)) |
571 | return; | 571 | return; |
572 | 572 | ||
573 | /* get the size after alignment with the u32 buffer size field */ | 573 | /* get the size after alignment with the u32 buffer size field */ |
574 | size = sizeof(unsigned long) * sys_data->nb_args + sizeof(*rec); | 574 | size = sizeof(unsigned long) * sys_data->nb_args + sizeof(*rec); |
575 | size = ALIGN(size + sizeof(u32), sizeof(u64)); | 575 | size = ALIGN(size + sizeof(u32), sizeof(u64)); |
576 | size -= sizeof(u32); | 576 | size -= sizeof(u32); |
577 | 577 | ||
578 | rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size, | 578 | rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size, |
579 | sys_data->enter_event->event.type, regs, &rctx); | 579 | sys_data->enter_event->event.type, regs, &rctx); |
580 | if (!rec) | 580 | if (!rec) |
581 | return; | 581 | return; |
582 | 582 | ||
583 | rec->nr = syscall_nr; | 583 | rec->nr = syscall_nr; |
584 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, | 584 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, |
585 | (unsigned long *)&rec->args); | 585 | (unsigned long *)&rec->args); |
586 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); | 586 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); |
587 | } | 587 | } |
588 | 588 | ||
589 | static int perf_sysenter_enable(struct ftrace_event_call *call) | 589 | static int perf_sysenter_enable(struct ftrace_event_call *call) |
590 | { | 590 | { |
591 | int ret = 0; | 591 | int ret = 0; |
592 | int num; | 592 | int num; |
593 | 593 | ||
594 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 594 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
595 | 595 | ||
596 | mutex_lock(&syscall_trace_lock); | 596 | mutex_lock(&syscall_trace_lock); |
597 | if (!sys_perf_refcount_enter) | 597 | if (!sys_perf_refcount_enter) |
598 | ret = register_trace_sys_enter(perf_syscall_enter, NULL); | 598 | ret = register_trace_sys_enter(perf_syscall_enter, NULL); |
599 | if (ret) { | 599 | if (ret) { |
600 | pr_info("event trace: Could not activate" | 600 | pr_info("event trace: Could not activate" |
601 | "syscall entry trace point"); | 601 | "syscall entry trace point"); |
602 | } else { | 602 | } else { |
603 | set_bit(num, enabled_perf_enter_syscalls); | 603 | set_bit(num, enabled_perf_enter_syscalls); |
604 | sys_perf_refcount_enter++; | 604 | sys_perf_refcount_enter++; |
605 | } | 605 | } |
606 | mutex_unlock(&syscall_trace_lock); | 606 | mutex_unlock(&syscall_trace_lock); |
607 | return ret; | 607 | return ret; |
608 | } | 608 | } |
609 | 609 | ||
610 | static void perf_sysenter_disable(struct ftrace_event_call *call) | 610 | static void perf_sysenter_disable(struct ftrace_event_call *call) |
611 | { | 611 | { |
612 | int num; | 612 | int num; |
613 | 613 | ||
614 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 614 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
615 | 615 | ||
616 | mutex_lock(&syscall_trace_lock); | 616 | mutex_lock(&syscall_trace_lock); |
617 | sys_perf_refcount_enter--; | 617 | sys_perf_refcount_enter--; |
618 | clear_bit(num, enabled_perf_enter_syscalls); | 618 | clear_bit(num, enabled_perf_enter_syscalls); |
619 | if (!sys_perf_refcount_enter) | 619 | if (!sys_perf_refcount_enter) |
620 | unregister_trace_sys_enter(perf_syscall_enter, NULL); | 620 | unregister_trace_sys_enter(perf_syscall_enter, NULL); |
621 | mutex_unlock(&syscall_trace_lock); | 621 | mutex_unlock(&syscall_trace_lock); |
622 | } | 622 | } |
623 | 623 | ||
624 | static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) | 624 | static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) |
625 | { | 625 | { |
626 | struct syscall_metadata *sys_data; | 626 | struct syscall_metadata *sys_data; |
627 | struct syscall_trace_exit *rec; | 627 | struct syscall_trace_exit *rec; |
628 | struct hlist_head *head; | 628 | struct hlist_head *head; |
629 | int syscall_nr; | 629 | int syscall_nr; |
630 | int rctx; | 630 | int rctx; |
631 | int size; | 631 | int size; |
632 | 632 | ||
633 | syscall_nr = trace_get_syscall_nr(current, regs); | 633 | syscall_nr = trace_get_syscall_nr(current, regs); |
634 | if (syscall_nr < 0) | 634 | if (syscall_nr < 0) |
635 | return; | 635 | return; |
636 | if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) | 636 | if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) |
637 | return; | 637 | return; |
638 | 638 | ||
639 | sys_data = syscall_nr_to_meta(syscall_nr); | 639 | sys_data = syscall_nr_to_meta(syscall_nr); |
640 | if (!sys_data) | 640 | if (!sys_data) |
641 | return; | 641 | return; |
642 | 642 | ||
643 | head = this_cpu_ptr(sys_data->exit_event->perf_events); | 643 | head = this_cpu_ptr(sys_data->exit_event->perf_events); |
644 | if (hlist_empty(head)) | 644 | if (hlist_empty(head)) |
645 | return; | 645 | return; |
646 | 646 | ||
647 | /* We can probably do that at build time */ | 647 | /* We can probably do that at build time */ |
648 | size = ALIGN(sizeof(*rec) + sizeof(u32), sizeof(u64)); | 648 | size = ALIGN(sizeof(*rec) + sizeof(u32), sizeof(u64)); |
649 | size -= sizeof(u32); | 649 | size -= sizeof(u32); |
650 | 650 | ||
651 | rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size, | 651 | rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size, |
652 | sys_data->exit_event->event.type, regs, &rctx); | 652 | sys_data->exit_event->event.type, regs, &rctx); |
653 | if (!rec) | 653 | if (!rec) |
654 | return; | 654 | return; |
655 | 655 | ||
656 | rec->nr = syscall_nr; | 656 | rec->nr = syscall_nr; |
657 | rec->ret = syscall_get_return_value(current, regs); | 657 | rec->ret = syscall_get_return_value(current, regs); |
658 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); | 658 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); |
659 | } | 659 | } |
660 | 660 | ||
661 | static int perf_sysexit_enable(struct ftrace_event_call *call) | 661 | static int perf_sysexit_enable(struct ftrace_event_call *call) |
662 | { | 662 | { |
663 | int ret = 0; | 663 | int ret = 0; |
664 | int num; | 664 | int num; |
665 | 665 | ||
666 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 666 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
667 | 667 | ||
668 | mutex_lock(&syscall_trace_lock); | 668 | mutex_lock(&syscall_trace_lock); |
669 | if (!sys_perf_refcount_exit) | 669 | if (!sys_perf_refcount_exit) |
670 | ret = register_trace_sys_exit(perf_syscall_exit, NULL); | 670 | ret = register_trace_sys_exit(perf_syscall_exit, NULL); |
671 | if (ret) { | 671 | if (ret) { |
672 | pr_info("event trace: Could not activate" | 672 | pr_info("event trace: Could not activate" |
673 | "syscall exit trace point"); | 673 | "syscall exit trace point"); |
674 | } else { | 674 | } else { |
675 | set_bit(num, enabled_perf_exit_syscalls); | 675 | set_bit(num, enabled_perf_exit_syscalls); |
676 | sys_perf_refcount_exit++; | 676 | sys_perf_refcount_exit++; |
677 | } | 677 | } |
678 | mutex_unlock(&syscall_trace_lock); | 678 | mutex_unlock(&syscall_trace_lock); |
679 | return ret; | 679 | return ret; |
680 | } | 680 | } |
681 | 681 | ||
682 | static void perf_sysexit_disable(struct ftrace_event_call *call) | 682 | static void perf_sysexit_disable(struct ftrace_event_call *call) |
683 | { | 683 | { |
684 | int num; | 684 | int num; |
685 | 685 | ||
686 | num = ((struct syscall_metadata *)call->data)->syscall_nr; | 686 | num = ((struct syscall_metadata *)call->data)->syscall_nr; |
687 | 687 | ||
688 | mutex_lock(&syscall_trace_lock); | 688 | mutex_lock(&syscall_trace_lock); |
689 | sys_perf_refcount_exit--; | 689 | sys_perf_refcount_exit--; |
690 | clear_bit(num, enabled_perf_exit_syscalls); | 690 | clear_bit(num, enabled_perf_exit_syscalls); |
691 | if (!sys_perf_refcount_exit) | 691 | if (!sys_perf_refcount_exit) |
692 | unregister_trace_sys_exit(perf_syscall_exit, NULL); | 692 | unregister_trace_sys_exit(perf_syscall_exit, NULL); |
693 | mutex_unlock(&syscall_trace_lock); | 693 | mutex_unlock(&syscall_trace_lock); |
694 | } | 694 | } |
695 | 695 | ||
696 | #endif /* CONFIG_PERF_EVENTS */ | 696 | #endif /* CONFIG_PERF_EVENTS */ |
697 | 697 | ||
698 | static int syscall_enter_register(struct ftrace_event_call *event, | 698 | static int syscall_enter_register(struct ftrace_event_call *event, |
699 | enum trace_reg type, void *data) | 699 | enum trace_reg type, void *data) |
700 | { | 700 | { |
701 | struct ftrace_event_file *file = data; | 701 | struct ftrace_event_file *file = data; |
702 | 702 | ||
703 | switch (type) { | 703 | switch (type) { |
704 | case TRACE_REG_REGISTER: | 704 | case TRACE_REG_REGISTER: |
705 | return reg_event_syscall_enter(file, event); | 705 | return reg_event_syscall_enter(file, event); |
706 | case TRACE_REG_UNREGISTER: | 706 | case TRACE_REG_UNREGISTER: |
707 | unreg_event_syscall_enter(file, event); | 707 | unreg_event_syscall_enter(file, event); |
708 | return 0; | 708 | return 0; |
709 | 709 | ||
710 | #ifdef CONFIG_PERF_EVENTS | 710 | #ifdef CONFIG_PERF_EVENTS |
711 | case TRACE_REG_PERF_REGISTER: | 711 | case TRACE_REG_PERF_REGISTER: |
712 | return perf_sysenter_enable(event); | 712 | return perf_sysenter_enable(event); |
713 | case TRACE_REG_PERF_UNREGISTER: | 713 | case TRACE_REG_PERF_UNREGISTER: |
714 | perf_sysenter_disable(event); | 714 | perf_sysenter_disable(event); |
715 | return 0; | 715 | return 0; |
716 | case TRACE_REG_PERF_OPEN: | 716 | case TRACE_REG_PERF_OPEN: |
717 | case TRACE_REG_PERF_CLOSE: | 717 | case TRACE_REG_PERF_CLOSE: |
718 | case TRACE_REG_PERF_ADD: | 718 | case TRACE_REG_PERF_ADD: |
719 | case TRACE_REG_PERF_DEL: | 719 | case TRACE_REG_PERF_DEL: |
720 | return 0; | 720 | return 0; |
721 | #endif | 721 | #endif |
722 | } | 722 | } |
723 | return 0; | 723 | return 0; |
724 | } | 724 | } |
725 | 725 | ||
726 | static int syscall_exit_register(struct ftrace_event_call *event, | 726 | static int syscall_exit_register(struct ftrace_event_call *event, |
727 | enum trace_reg type, void *data) | 727 | enum trace_reg type, void *data) |
728 | { | 728 | { |
729 | struct ftrace_event_file *file = data; | 729 | struct ftrace_event_file *file = data; |
730 | 730 | ||
731 | switch (type) { | 731 | switch (type) { |
732 | case TRACE_REG_REGISTER: | 732 | case TRACE_REG_REGISTER: |
733 | return reg_event_syscall_exit(file, event); | 733 | return reg_event_syscall_exit(file, event); |
734 | case TRACE_REG_UNREGISTER: | 734 | case TRACE_REG_UNREGISTER: |
735 | unreg_event_syscall_exit(file, event); | 735 | unreg_event_syscall_exit(file, event); |
736 | return 0; | 736 | return 0; |
737 | 737 | ||
738 | #ifdef CONFIG_PERF_EVENTS | 738 | #ifdef CONFIG_PERF_EVENTS |
739 | case TRACE_REG_PERF_REGISTER: | 739 | case TRACE_REG_PERF_REGISTER: |
740 | return perf_sysexit_enable(event); | 740 | return perf_sysexit_enable(event); |
741 | case TRACE_REG_PERF_UNREGISTER: | 741 | case TRACE_REG_PERF_UNREGISTER: |
742 | perf_sysexit_disable(event); | 742 | perf_sysexit_disable(event); |
743 | return 0; | 743 | return 0; |
744 | case TRACE_REG_PERF_OPEN: | 744 | case TRACE_REG_PERF_OPEN: |
745 | case TRACE_REG_PERF_CLOSE: | 745 | case TRACE_REG_PERF_CLOSE: |
746 | case TRACE_REG_PERF_ADD: | 746 | case TRACE_REG_PERF_ADD: |
747 | case TRACE_REG_PERF_DEL: | 747 | case TRACE_REG_PERF_DEL: |
748 | return 0; | 748 | return 0; |
749 | #endif | 749 | #endif |
750 | } | 750 | } |
751 | return 0; | 751 | return 0; |
752 | } | 752 | } |
753 | 753 |