diff options
Diffstat (limited to 'include')
36 files changed, 1361 insertions, 272 deletions
diff --git a/include/asm-frv/ftrace.h b/include/asm-frv/ftrace.h new file mode 100644 index 000000000000..40a8c178f10d --- /dev/null +++ b/include/asm-frv/ftrace.h | |||
@@ -0,0 +1 @@ | |||
/* empty */ | |||
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index a654d724d3b0..7fa660fd449c 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -61,6 +61,30 @@ | |||
61 | #define BRANCH_PROFILE() | 61 | #define BRANCH_PROFILE() |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | #ifdef CONFIG_EVENT_TRACER | ||
65 | #define FTRACE_EVENTS() VMLINUX_SYMBOL(__start_ftrace_events) = .; \ | ||
66 | *(_ftrace_events) \ | ||
67 | VMLINUX_SYMBOL(__stop_ftrace_events) = .; | ||
68 | #else | ||
69 | #define FTRACE_EVENTS() | ||
70 | #endif | ||
71 | |||
72 | #ifdef CONFIG_TRACING | ||
73 | #define TRACE_PRINTKS() VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .; \ | ||
74 | *(__trace_printk_fmt) /* Trace_printk fmt' pointer */ \ | ||
75 | VMLINUX_SYMBOL(__stop___trace_bprintk_fmt) = .; | ||
76 | #else | ||
77 | #define TRACE_PRINTKS() | ||
78 | #endif | ||
79 | |||
80 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
81 | #define TRACE_SYSCALLS() VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ | ||
82 | *(__syscalls_metadata) \ | ||
83 | VMLINUX_SYMBOL(__stop_syscalls_metadata) = .; | ||
84 | #else | ||
85 | #define TRACE_SYSCALLS() | ||
86 | #endif | ||
87 | |||
64 | /* .data section */ | 88 | /* .data section */ |
65 | #define DATA_DATA \ | 89 | #define DATA_DATA \ |
66 | *(.data) \ | 90 | *(.data) \ |
@@ -86,7 +110,10 @@ | |||
86 | *(__verbose) \ | 110 | *(__verbose) \ |
87 | VMLINUX_SYMBOL(__stop___verbose) = .; \ | 111 | VMLINUX_SYMBOL(__stop___verbose) = .; \ |
88 | LIKELY_PROFILE() \ | 112 | LIKELY_PROFILE() \ |
89 | BRANCH_PROFILE() | 113 | BRANCH_PROFILE() \ |
114 | TRACE_PRINTKS() \ | ||
115 | FTRACE_EVENTS() \ | ||
116 | TRACE_SYSCALLS() | ||
90 | 117 | ||
91 | #define RO_DATA(align) \ | 118 | #define RO_DATA(align) \ |
92 | . = ALIGN((align)); \ | 119 | . = ALIGN((align)); \ |
diff --git a/include/asm-m32r/ftrace.h b/include/asm-m32r/ftrace.h new file mode 100644 index 000000000000..40a8c178f10d --- /dev/null +++ b/include/asm-m32r/ftrace.h | |||
@@ -0,0 +1 @@ | |||
/* empty */ | |||
diff --git a/include/asm-mn10300/ftrace.h b/include/asm-mn10300/ftrace.h new file mode 100644 index 000000000000..40a8c178f10d --- /dev/null +++ b/include/asm-mn10300/ftrace.h | |||
@@ -0,0 +1 @@ | |||
/* empty */ | |||
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 6e915878e88c..d960889e92ef 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h | |||
@@ -144,6 +144,9 @@ struct blk_user_trace_setup { | |||
144 | 144 | ||
145 | #ifdef __KERNEL__ | 145 | #ifdef __KERNEL__ |
146 | #if defined(CONFIG_BLK_DEV_IO_TRACE) | 146 | #if defined(CONFIG_BLK_DEV_IO_TRACE) |
147 | |||
148 | #include <linux/sysfs.h> | ||
149 | |||
147 | struct blk_trace { | 150 | struct blk_trace { |
148 | int trace_state; | 151 | int trace_state; |
149 | struct rchan *rchan; | 152 | struct rchan *rchan; |
@@ -194,6 +197,8 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
194 | extern int blk_trace_startstop(struct request_queue *q, int start); | 197 | extern int blk_trace_startstop(struct request_queue *q, int start); |
195 | extern int blk_trace_remove(struct request_queue *q); | 198 | extern int blk_trace_remove(struct request_queue *q); |
196 | 199 | ||
200 | extern struct attribute_group blk_trace_attr_group; | ||
201 | |||
197 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ | 202 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ |
198 | #define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) | 203 | #define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) |
199 | #define blk_trace_shutdown(q) do { } while (0) | 204 | #define blk_trace_shutdown(q) do { } while (0) |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index d95da1020f1c..6faa7e549de4 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -68,6 +68,7 @@ struct ftrace_branch_data { | |||
68 | unsigned long miss; | 68 | unsigned long miss; |
69 | unsigned long hit; | 69 | unsigned long hit; |
70 | }; | 70 | }; |
71 | unsigned long miss_hit[2]; | ||
71 | }; | 72 | }; |
72 | }; | 73 | }; |
73 | 74 | ||
@@ -125,10 +126,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); | |||
125 | .line = __LINE__, \ | 126 | .line = __LINE__, \ |
126 | }; \ | 127 | }; \ |
127 | ______r = !!(cond); \ | 128 | ______r = !!(cond); \ |
128 | if (______r) \ | 129 | ______f.miss_hit[______r]++; \ |
129 | ______f.hit++; \ | ||
130 | else \ | ||
131 | ______f.miss++; \ | ||
132 | ______r; \ | 130 | ______r; \ |
133 | })) | 131 | })) |
134 | #endif /* CONFIG_PROFILE_ALL_BRANCHES */ | 132 | #endif /* CONFIG_PROFILE_ALL_BRANCHES */ |
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index af0e01d4c663..eb5c2ba2f81a 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h | |||
@@ -71,6 +71,9 @@ struct dentry *debugfs_create_bool(const char *name, mode_t mode, | |||
71 | struct dentry *debugfs_create_blob(const char *name, mode_t mode, | 71 | struct dentry *debugfs_create_blob(const char *name, mode_t mode, |
72 | struct dentry *parent, | 72 | struct dentry *parent, |
73 | struct debugfs_blob_wrapper *blob); | 73 | struct debugfs_blob_wrapper *blob); |
74 | |||
75 | bool debugfs_initialized(void); | ||
76 | |||
74 | #else | 77 | #else |
75 | 78 | ||
76 | #include <linux/err.h> | 79 | #include <linux/err.h> |
@@ -183,6 +186,11 @@ static inline struct dentry *debugfs_create_blob(const char *name, mode_t mode, | |||
183 | return ERR_PTR(-ENODEV); | 186 | return ERR_PTR(-ENODEV); |
184 | } | 187 | } |
185 | 188 | ||
189 | static inline bool debugfs_initialized(void) | ||
190 | { | ||
191 | return false; | ||
192 | } | ||
193 | |||
186 | #endif | 194 | #endif |
187 | 195 | ||
188 | #endif | 196 | #endif |
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index a7f8134c594e..015a3d22cf74 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
@@ -1,15 +1,18 @@ | |||
1 | #ifndef _LINUX_FTRACE_H | 1 | #ifndef _LINUX_FTRACE_H |
2 | #define _LINUX_FTRACE_H | 2 | #define _LINUX_FTRACE_H |
3 | 3 | ||
4 | #include <linux/linkage.h> | 4 | #include <linux/trace_clock.h> |
5 | #include <linux/fs.h> | ||
6 | #include <linux/ktime.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/types.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/kallsyms.h> | 5 | #include <linux/kallsyms.h> |
6 | #include <linux/linkage.h> | ||
11 | #include <linux/bitops.h> | 7 | #include <linux/bitops.h> |
8 | #include <linux/module.h> | ||
9 | #include <linux/ktime.h> | ||
12 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/types.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/fs.h> | ||
14 | |||
15 | #include <asm/ftrace.h> | ||
13 | 16 | ||
14 | #ifdef CONFIG_FUNCTION_TRACER | 17 | #ifdef CONFIG_FUNCTION_TRACER |
15 | 18 | ||
@@ -95,9 +98,41 @@ stack_trace_sysctl(struct ctl_table *table, int write, | |||
95 | loff_t *ppos); | 98 | loff_t *ppos); |
96 | #endif | 99 | #endif |
97 | 100 | ||
101 | struct ftrace_func_command { | ||
102 | struct list_head list; | ||
103 | char *name; | ||
104 | int (*func)(char *func, char *cmd, | ||
105 | char *params, int enable); | ||
106 | }; | ||
107 | |||
98 | #ifdef CONFIG_DYNAMIC_FTRACE | 108 | #ifdef CONFIG_DYNAMIC_FTRACE |
99 | /* asm/ftrace.h must be defined for archs supporting dynamic ftrace */ | 109 | |
100 | #include <asm/ftrace.h> | 110 | int ftrace_arch_code_modify_prepare(void); |
111 | int ftrace_arch_code_modify_post_process(void); | ||
112 | |||
113 | struct seq_file; | ||
114 | |||
115 | struct ftrace_probe_ops { | ||
116 | void (*func)(unsigned long ip, | ||
117 | unsigned long parent_ip, | ||
118 | void **data); | ||
119 | int (*callback)(unsigned long ip, void **data); | ||
120 | void (*free)(void **data); | ||
121 | int (*print)(struct seq_file *m, | ||
122 | unsigned long ip, | ||
123 | struct ftrace_probe_ops *ops, | ||
124 | void *data); | ||
125 | }; | ||
126 | |||
127 | extern int | ||
128 | register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, | ||
129 | void *data); | ||
130 | extern void | ||
131 | unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, | ||
132 | void *data); | ||
133 | extern void | ||
134 | unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops); | ||
135 | extern void unregister_ftrace_function_probe_all(char *glob); | ||
101 | 136 | ||
102 | enum { | 137 | enum { |
103 | FTRACE_FL_FREE = (1 << 0), | 138 | FTRACE_FL_FREE = (1 << 0), |
@@ -110,15 +145,23 @@ enum { | |||
110 | }; | 145 | }; |
111 | 146 | ||
112 | struct dyn_ftrace { | 147 | struct dyn_ftrace { |
113 | struct list_head list; | 148 | union { |
114 | unsigned long ip; /* address of mcount call-site */ | 149 | unsigned long ip; /* address of mcount call-site */ |
115 | unsigned long flags; | 150 | struct dyn_ftrace *freelist; |
116 | struct dyn_arch_ftrace arch; | 151 | }; |
152 | union { | ||
153 | unsigned long flags; | ||
154 | struct dyn_ftrace *newlist; | ||
155 | }; | ||
156 | struct dyn_arch_ftrace arch; | ||
117 | }; | 157 | }; |
118 | 158 | ||
119 | int ftrace_force_update(void); | 159 | int ftrace_force_update(void); |
120 | void ftrace_set_filter(unsigned char *buf, int len, int reset); | 160 | void ftrace_set_filter(unsigned char *buf, int len, int reset); |
121 | 161 | ||
162 | int register_ftrace_command(struct ftrace_func_command *cmd); | ||
163 | int unregister_ftrace_command(struct ftrace_func_command *cmd); | ||
164 | |||
122 | /* defined in arch */ | 165 | /* defined in arch */ |
123 | extern int ftrace_ip_converted(unsigned long ip); | 166 | extern int ftrace_ip_converted(unsigned long ip); |
124 | extern int ftrace_dyn_arch_init(void *data); | 167 | extern int ftrace_dyn_arch_init(void *data); |
@@ -126,6 +169,10 @@ extern int ftrace_update_ftrace_func(ftrace_func_t func); | |||
126 | extern void ftrace_caller(void); | 169 | extern void ftrace_caller(void); |
127 | extern void ftrace_call(void); | 170 | extern void ftrace_call(void); |
128 | extern void mcount_call(void); | 171 | extern void mcount_call(void); |
172 | |||
173 | #ifndef FTRACE_ADDR | ||
174 | #define FTRACE_ADDR ((unsigned long)ftrace_caller) | ||
175 | #endif | ||
129 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 176 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
130 | extern void ftrace_graph_caller(void); | 177 | extern void ftrace_graph_caller(void); |
131 | extern int ftrace_enable_ftrace_graph_caller(void); | 178 | extern int ftrace_enable_ftrace_graph_caller(void); |
@@ -136,7 +183,7 @@ static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; } | |||
136 | #endif | 183 | #endif |
137 | 184 | ||
138 | /** | 185 | /** |
139 | * ftrace_make_nop - convert code into top | 186 | * ftrace_make_nop - convert code into nop |
140 | * @mod: module structure if called by module load initialization | 187 | * @mod: module structure if called by module load initialization |
141 | * @rec: the mcount call site record | 188 | * @rec: the mcount call site record |
142 | * @addr: the address that the call site should be calling | 189 | * @addr: the address that the call site should be calling |
@@ -181,7 +228,6 @@ extern int ftrace_make_nop(struct module *mod, | |||
181 | */ | 228 | */ |
182 | extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr); | 229 | extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr); |
183 | 230 | ||
184 | |||
185 | /* May be defined in arch */ | 231 | /* May be defined in arch */ |
186 | extern int ftrace_arch_read_dyn_info(char *buf, int size); | 232 | extern int ftrace_arch_read_dyn_info(char *buf, int size); |
187 | 233 | ||
@@ -198,6 +244,14 @@ extern void ftrace_enable_daemon(void); | |||
198 | # define ftrace_disable_daemon() do { } while (0) | 244 | # define ftrace_disable_daemon() do { } while (0) |
199 | # define ftrace_enable_daemon() do { } while (0) | 245 | # define ftrace_enable_daemon() do { } while (0) |
200 | static inline void ftrace_release(void *start, unsigned long size) { } | 246 | static inline void ftrace_release(void *start, unsigned long size) { } |
247 | static inline int register_ftrace_command(struct ftrace_func_command *cmd) | ||
248 | { | ||
249 | return -EINVAL; | ||
250 | } | ||
251 | static inline int unregister_ftrace_command(char *cmd_name) | ||
252 | { | ||
253 | return -EINVAL; | ||
254 | } | ||
201 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 255 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
202 | 256 | ||
203 | /* totally disable ftrace - can not re-enable after this */ | 257 | /* totally disable ftrace - can not re-enable after this */ |
@@ -233,24 +287,25 @@ static inline void __ftrace_enabled_restore(int enabled) | |||
233 | #endif | 287 | #endif |
234 | } | 288 | } |
235 | 289 | ||
236 | #ifdef CONFIG_FRAME_POINTER | 290 | #ifndef HAVE_ARCH_CALLER_ADDR |
237 | /* TODO: need to fix this for ARM */ | 291 | # ifdef CONFIG_FRAME_POINTER |
238 | # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) | 292 | # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) |
239 | # define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1)) | 293 | # define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1)) |
240 | # define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2)) | 294 | # define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2)) |
241 | # define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3)) | 295 | # define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3)) |
242 | # define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4)) | 296 | # define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4)) |
243 | # define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5)) | 297 | # define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5)) |
244 | # define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6)) | 298 | # define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6)) |
245 | #else | 299 | # else |
246 | # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) | 300 | # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) |
247 | # define CALLER_ADDR1 0UL | 301 | # define CALLER_ADDR1 0UL |
248 | # define CALLER_ADDR2 0UL | 302 | # define CALLER_ADDR2 0UL |
249 | # define CALLER_ADDR3 0UL | 303 | # define CALLER_ADDR3 0UL |
250 | # define CALLER_ADDR4 0UL | 304 | # define CALLER_ADDR4 0UL |
251 | # define CALLER_ADDR5 0UL | 305 | # define CALLER_ADDR5 0UL |
252 | # define CALLER_ADDR6 0UL | 306 | # define CALLER_ADDR6 0UL |
253 | #endif | 307 | # endif |
308 | #endif /* ifndef HAVE_ARCH_CALLER_ADDR */ | ||
254 | 309 | ||
255 | #ifdef CONFIG_IRQSOFF_TRACER | 310 | #ifdef CONFIG_IRQSOFF_TRACER |
256 | extern void time_hardirqs_on(unsigned long a0, unsigned long a1); | 311 | extern void time_hardirqs_on(unsigned long a0, unsigned long a1); |
@@ -268,54 +323,6 @@ static inline void __ftrace_enabled_restore(int enabled) | |||
268 | # define trace_preempt_off(a0, a1) do { } while (0) | 323 | # define trace_preempt_off(a0, a1) do { } while (0) |
269 | #endif | 324 | #endif |
270 | 325 | ||
271 | #ifdef CONFIG_TRACING | ||
272 | extern int ftrace_dump_on_oops; | ||
273 | |||
274 | extern void tracing_start(void); | ||
275 | extern void tracing_stop(void); | ||
276 | extern void ftrace_off_permanent(void); | ||
277 | |||
278 | extern void | ||
279 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | ||
280 | |||
281 | /** | ||
282 | * ftrace_printk - printf formatting in the ftrace buffer | ||
283 | * @fmt: the printf format for printing | ||
284 | * | ||
285 | * Note: __ftrace_printk is an internal function for ftrace_printk and | ||
286 | * the @ip is passed in via the ftrace_printk macro. | ||
287 | * | ||
288 | * This function allows a kernel developer to debug fast path sections | ||
289 | * that printk is not appropriate for. By scattering in various | ||
290 | * printk like tracing in the code, a developer can quickly see | ||
291 | * where problems are occurring. | ||
292 | * | ||
293 | * This is intended as a debugging tool for the developer only. | ||
294 | * Please refrain from leaving ftrace_printks scattered around in | ||
295 | * your code. | ||
296 | */ | ||
297 | # define ftrace_printk(fmt...) __ftrace_printk(_THIS_IP_, fmt) | ||
298 | extern int | ||
299 | __ftrace_printk(unsigned long ip, const char *fmt, ...) | ||
300 | __attribute__ ((format (printf, 2, 3))); | ||
301 | extern void ftrace_dump(void); | ||
302 | #else | ||
303 | static inline void | ||
304 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } | ||
305 | static inline int | ||
306 | ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); | ||
307 | |||
308 | static inline void tracing_start(void) { } | ||
309 | static inline void tracing_stop(void) { } | ||
310 | static inline void ftrace_off_permanent(void) { } | ||
311 | static inline int | ||
312 | ftrace_printk(const char *fmt, ...) | ||
313 | { | ||
314 | return 0; | ||
315 | } | ||
316 | static inline void ftrace_dump(void) { } | ||
317 | #endif | ||
318 | |||
319 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 326 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
320 | extern void ftrace_init(void); | 327 | extern void ftrace_init(void); |
321 | extern void ftrace_init_module(struct module *mod, | 328 | extern void ftrace_init_module(struct module *mod, |
@@ -327,36 +334,6 @@ ftrace_init_module(struct module *mod, | |||
327 | unsigned long *start, unsigned long *end) { } | 334 | unsigned long *start, unsigned long *end) { } |
328 | #endif | 335 | #endif |
329 | 336 | ||
330 | enum { | ||
331 | POWER_NONE = 0, | ||
332 | POWER_CSTATE = 1, | ||
333 | POWER_PSTATE = 2, | ||
334 | }; | ||
335 | |||
336 | struct power_trace { | ||
337 | #ifdef CONFIG_POWER_TRACER | ||
338 | ktime_t stamp; | ||
339 | ktime_t end; | ||
340 | int type; | ||
341 | int state; | ||
342 | #endif | ||
343 | }; | ||
344 | |||
345 | #ifdef CONFIG_POWER_TRACER | ||
346 | extern void trace_power_start(struct power_trace *it, unsigned int type, | ||
347 | unsigned int state); | ||
348 | extern void trace_power_mark(struct power_trace *it, unsigned int type, | ||
349 | unsigned int state); | ||
350 | extern void trace_power_end(struct power_trace *it); | ||
351 | #else | ||
352 | static inline void trace_power_start(struct power_trace *it, unsigned int type, | ||
353 | unsigned int state) { } | ||
354 | static inline void trace_power_mark(struct power_trace *it, unsigned int type, | ||
355 | unsigned int state) { } | ||
356 | static inline void trace_power_end(struct power_trace *it) { } | ||
357 | #endif | ||
358 | |||
359 | |||
360 | /* | 337 | /* |
361 | * Structure that defines an entry function trace. | 338 | * Structure that defines an entry function trace. |
362 | */ | 339 | */ |
@@ -398,8 +375,7 @@ struct ftrace_ret_stack { | |||
398 | extern void return_to_handler(void); | 375 | extern void return_to_handler(void); |
399 | 376 | ||
400 | extern int | 377 | extern int |
401 | ftrace_push_return_trace(unsigned long ret, unsigned long long time, | 378 | ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth); |
402 | unsigned long func, int *depth); | ||
403 | extern void | 379 | extern void |
404 | ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret); | 380 | ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret); |
405 | 381 | ||
@@ -514,6 +490,50 @@ static inline int test_tsk_trace_graph(struct task_struct *tsk) | |||
514 | return tsk->trace & TSK_TRACE_FL_GRAPH; | 490 | return tsk->trace & TSK_TRACE_FL_GRAPH; |
515 | } | 491 | } |
516 | 492 | ||
493 | extern int ftrace_dump_on_oops; | ||
494 | |||
517 | #endif /* CONFIG_TRACING */ | 495 | #endif /* CONFIG_TRACING */ |
518 | 496 | ||
497 | |||
498 | #ifdef CONFIG_HW_BRANCH_TRACER | ||
499 | |||
500 | void trace_hw_branch(u64 from, u64 to); | ||
501 | void trace_hw_branch_oops(void); | ||
502 | |||
503 | #else /* CONFIG_HW_BRANCH_TRACER */ | ||
504 | |||
505 | static inline void trace_hw_branch(u64 from, u64 to) {} | ||
506 | static inline void trace_hw_branch_oops(void) {} | ||
507 | |||
508 | #endif /* CONFIG_HW_BRANCH_TRACER */ | ||
509 | |||
510 | /* | ||
511 | * A syscall entry in the ftrace syscalls array. | ||
512 | * | ||
513 | * @name: name of the syscall | ||
514 | * @nb_args: number of parameters it takes | ||
515 | * @types: list of types as strings | ||
516 | * @args: list of args as strings (args[i] matches types[i]) | ||
517 | */ | ||
518 | struct syscall_metadata { | ||
519 | const char *name; | ||
520 | int nb_args; | ||
521 | const char **types; | ||
522 | const char **args; | ||
523 | }; | ||
524 | |||
525 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
526 | extern void arch_init_ftrace_syscalls(void); | ||
527 | extern struct syscall_metadata *syscall_nr_to_meta(int nr); | ||
528 | extern void start_ftrace_syscalls(void); | ||
529 | extern void stop_ftrace_syscalls(void); | ||
530 | extern void ftrace_syscall_enter(struct pt_regs *regs); | ||
531 | extern void ftrace_syscall_exit(struct pt_regs *regs); | ||
532 | #else | ||
533 | static inline void start_ftrace_syscalls(void) { } | ||
534 | static inline void stop_ftrace_syscalls(void) { } | ||
535 | static inline void ftrace_syscall_enter(struct pt_regs *regs) { } | ||
536 | static inline void ftrace_syscall_exit(struct pt_regs *regs) { } | ||
537 | #endif | ||
538 | |||
519 | #endif /* _LINUX_FTRACE_H */ | 539 | #endif /* _LINUX_FTRACE_H */ |
diff --git a/include/linux/ftrace_irq.h b/include/linux/ftrace_irq.h index 366a054d0b05..dca7bf8cffe2 100644 --- a/include/linux/ftrace_irq.h +++ b/include/linux/ftrace_irq.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _LINUX_FTRACE_IRQ_H | 2 | #define _LINUX_FTRACE_IRQ_H |
3 | 3 | ||
4 | 4 | ||
5 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_FUNCTION_GRAPH_TRACER) | 5 | #ifdef CONFIG_FTRACE_NMI_ENTER |
6 | extern void ftrace_nmi_enter(void); | 6 | extern void ftrace_nmi_enter(void); |
7 | extern void ftrace_nmi_exit(void); | 7 | extern void ftrace_nmi_exit(void); |
8 | #else | 8 | #else |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index f83288347dda..faa1cf848bcd 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -15,55 +15,61 @@ | |||
15 | * - bits 0-7 are the preemption count (max preemption depth: 256) | 15 | * - bits 0-7 are the preemption count (max preemption depth: 256) |
16 | * - bits 8-15 are the softirq count (max # of softirqs: 256) | 16 | * - bits 8-15 are the softirq count (max # of softirqs: 256) |
17 | * | 17 | * |
18 | * The hardirq count can be overridden per architecture, the default is: | 18 | * The hardirq count can in theory reach the same as NR_IRQS. |
19 | * In reality, the number of nested IRQS is limited to the stack | ||
20 | * size as well. For archs with over 1000 IRQS it is not practical | ||
21 | * to expect that they will all nest. We give a max of 10 bits for | ||
22 | * hardirq nesting. An arch may choose to give less than 10 bits. | ||
23 | * m68k expects it to be 8. | ||
19 | * | 24 | * |
20 | * - bits 16-27 are the hardirq count (max # of hardirqs: 4096) | 25 | * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024) |
21 | * - ( bit 28 is the PREEMPT_ACTIVE flag. ) | 26 | * - bit 26 is the NMI_MASK |
27 | * - bit 28 is the PREEMPT_ACTIVE flag | ||
22 | * | 28 | * |
23 | * PREEMPT_MASK: 0x000000ff | 29 | * PREEMPT_MASK: 0x000000ff |
24 | * SOFTIRQ_MASK: 0x0000ff00 | 30 | * SOFTIRQ_MASK: 0x0000ff00 |
25 | * HARDIRQ_MASK: 0x0fff0000 | 31 | * HARDIRQ_MASK: 0x03ff0000 |
32 | * NMI_MASK: 0x04000000 | ||
26 | */ | 33 | */ |
27 | #define PREEMPT_BITS 8 | 34 | #define PREEMPT_BITS 8 |
28 | #define SOFTIRQ_BITS 8 | 35 | #define SOFTIRQ_BITS 8 |
36 | #define NMI_BITS 1 | ||
29 | 37 | ||
30 | #ifndef HARDIRQ_BITS | 38 | #define MAX_HARDIRQ_BITS 10 |
31 | #define HARDIRQ_BITS 12 | ||
32 | 39 | ||
33 | #ifndef MAX_HARDIRQS_PER_CPU | 40 | #ifndef HARDIRQ_BITS |
34 | #define MAX_HARDIRQS_PER_CPU NR_IRQS | 41 | # define HARDIRQ_BITS MAX_HARDIRQ_BITS |
35 | #endif | 42 | #endif |
36 | 43 | ||
37 | /* | 44 | #if HARDIRQ_BITS > MAX_HARDIRQ_BITS |
38 | * The hardirq mask has to be large enough to have space for potentially | 45 | #error HARDIRQ_BITS too high! |
39 | * all IRQ sources in the system nesting on a single CPU. | ||
40 | */ | ||
41 | #if (1 << HARDIRQ_BITS) < MAX_HARDIRQS_PER_CPU | ||
42 | # error HARDIRQ_BITS is too low! | ||
43 | #endif | ||
44 | #endif | 46 | #endif |
45 | 47 | ||
46 | #define PREEMPT_SHIFT 0 | 48 | #define PREEMPT_SHIFT 0 |
47 | #define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) | 49 | #define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) |
48 | #define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) | 50 | #define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) |
51 | #define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS) | ||
49 | 52 | ||
50 | #define __IRQ_MASK(x) ((1UL << (x))-1) | 53 | #define __IRQ_MASK(x) ((1UL << (x))-1) |
51 | 54 | ||
52 | #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) | 55 | #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) |
53 | #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | 56 | #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) |
54 | #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) | 57 | #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) |
58 | #define NMI_MASK (__IRQ_MASK(NMI_BITS) << NMI_SHIFT) | ||
55 | 59 | ||
56 | #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) | 60 | #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) |
57 | #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) | 61 | #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) |
58 | #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) | 62 | #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) |
63 | #define NMI_OFFSET (1UL << NMI_SHIFT) | ||
59 | 64 | ||
60 | #if PREEMPT_ACTIVE < (1 << (HARDIRQ_SHIFT + HARDIRQ_BITS)) | 65 | #if PREEMPT_ACTIVE < (1 << (NMI_SHIFT + NMI_BITS)) |
61 | #error PREEMPT_ACTIVE is too low! | 66 | #error PREEMPT_ACTIVE is too low! |
62 | #endif | 67 | #endif |
63 | 68 | ||
64 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) | 69 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) |
65 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) | 70 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) |
66 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) | 71 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \ |
72 | | NMI_MASK)) | ||
67 | 73 | ||
68 | /* | 74 | /* |
69 | * Are we doing bottom half or hardware interrupt processing? | 75 | * Are we doing bottom half or hardware interrupt processing? |
@@ -73,6 +79,11 @@ | |||
73 | #define in_softirq() (softirq_count()) | 79 | #define in_softirq() (softirq_count()) |
74 | #define in_interrupt() (irq_count()) | 80 | #define in_interrupt() (irq_count()) |
75 | 81 | ||
82 | /* | ||
83 | * Are we in NMI context? | ||
84 | */ | ||
85 | #define in_nmi() (preempt_count() & NMI_MASK) | ||
86 | |||
76 | #if defined(CONFIG_PREEMPT) | 87 | #if defined(CONFIG_PREEMPT) |
77 | # define PREEMPT_INATOMIC_BASE kernel_locked() | 88 | # define PREEMPT_INATOMIC_BASE kernel_locked() |
78 | # define PREEMPT_CHECK_OFFSET 1 | 89 | # define PREEMPT_CHECK_OFFSET 1 |
@@ -164,20 +175,24 @@ extern void irq_enter(void); | |||
164 | */ | 175 | */ |
165 | extern void irq_exit(void); | 176 | extern void irq_exit(void); |
166 | 177 | ||
167 | #define nmi_enter() \ | 178 | #define nmi_enter() \ |
168 | do { \ | 179 | do { \ |
169 | ftrace_nmi_enter(); \ | 180 | ftrace_nmi_enter(); \ |
170 | lockdep_off(); \ | 181 | BUG_ON(in_nmi()); \ |
171 | rcu_nmi_enter(); \ | 182 | add_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \ |
172 | __irq_enter(); \ | 183 | lockdep_off(); \ |
184 | rcu_nmi_enter(); \ | ||
185 | trace_hardirq_enter(); \ | ||
173 | } while (0) | 186 | } while (0) |
174 | 187 | ||
175 | #define nmi_exit() \ | 188 | #define nmi_exit() \ |
176 | do { \ | 189 | do { \ |
177 | __irq_exit(); \ | 190 | trace_hardirq_exit(); \ |
178 | rcu_nmi_exit(); \ | 191 | rcu_nmi_exit(); \ |
179 | lockdep_on(); \ | 192 | lockdep_on(); \ |
180 | ftrace_nmi_exit(); \ | 193 | BUG_ON(!in_nmi()); \ |
194 | sub_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \ | ||
195 | ftrace_nmi_exit(); \ | ||
181 | } while (0) | 196 | } while (0) |
182 | 197 | ||
183 | #endif /* LINUX_HARDIRQ_H */ | 198 | #endif /* LINUX_HARDIRQ_H */ |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c68bffd182bb..ce2c07d99fc3 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -278,6 +278,11 @@ enum | |||
278 | NR_SOFTIRQS | 278 | NR_SOFTIRQS |
279 | }; | 279 | }; |
280 | 280 | ||
281 | /* map softirq index to softirq name. update 'softirq_to_name' in | ||
282 | * kernel/softirq.c when adding a new softirq. | ||
283 | */ | ||
284 | extern char *softirq_to_name[NR_SOFTIRQS]; | ||
285 | |||
281 | /* softirq mask and active fields moved to irq_cpustat_t in | 286 | /* softirq mask and active fields moved to irq_cpustat_t in |
282 | * asm/hardirq.h to get better cache usage. KAO | 287 | * asm/hardirq.h to get better cache usage. KAO |
283 | */ | 288 | */ |
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 74bde13224c9..b02a3f1d46a0 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h | |||
@@ -24,8 +24,8 @@ | |||
24 | # define trace_softirqs_enabled(p) ((p)->softirqs_enabled) | 24 | # define trace_softirqs_enabled(p) ((p)->softirqs_enabled) |
25 | # define trace_hardirq_enter() do { current->hardirq_context++; } while (0) | 25 | # define trace_hardirq_enter() do { current->hardirq_context++; } while (0) |
26 | # define trace_hardirq_exit() do { current->hardirq_context--; } while (0) | 26 | # define trace_hardirq_exit() do { current->hardirq_context--; } while (0) |
27 | # define trace_softirq_enter() do { current->softirq_context++; } while (0) | 27 | # define lockdep_softirq_enter() do { current->softirq_context++; } while (0) |
28 | # define trace_softirq_exit() do { current->softirq_context--; } while (0) | 28 | # define lockdep_softirq_exit() do { current->softirq_context--; } while (0) |
29 | # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, | 29 | # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, |
30 | #else | 30 | #else |
31 | # define trace_hardirqs_on() do { } while (0) | 31 | # define trace_hardirqs_on() do { } while (0) |
@@ -38,8 +38,8 @@ | |||
38 | # define trace_softirqs_enabled(p) 0 | 38 | # define trace_softirqs_enabled(p) 0 |
39 | # define trace_hardirq_enter() do { } while (0) | 39 | # define trace_hardirq_enter() do { } while (0) |
40 | # define trace_hardirq_exit() do { } while (0) | 40 | # define trace_hardirq_exit() do { } while (0) |
41 | # define trace_softirq_enter() do { } while (0) | 41 | # define lockdep_softirq_enter() do { } while (0) |
42 | # define trace_softirq_exit() do { } while (0) | 42 | # define lockdep_softirq_exit() do { } while (0) |
43 | # define INIT_TRACE_IRQFLAGS | 43 | # define INIT_TRACE_IRQFLAGS |
44 | #endif | 44 | #endif |
45 | 45 | ||
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e720b0da7751..e81f2637fdef 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -242,6 +242,19 @@ extern struct ratelimit_state printk_ratelimit_state; | |||
242 | extern int printk_ratelimit(void); | 242 | extern int printk_ratelimit(void); |
243 | extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, | 243 | extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, |
244 | unsigned int interval_msec); | 244 | unsigned int interval_msec); |
245 | |||
246 | /* | ||
247 | * Print a one-time message (analogous to WARN_ONCE() et al): | ||
248 | */ | ||
249 | #define printk_once(x...) ({ \ | ||
250 | static int __print_once = 1; \ | ||
251 | \ | ||
252 | if (__print_once) { \ | ||
253 | __print_once = 0; \ | ||
254 | printk(x); \ | ||
255 | } \ | ||
256 | }) | ||
257 | |||
245 | #else | 258 | #else |
246 | static inline int vprintk(const char *s, va_list args) | 259 | static inline int vprintk(const char *s, va_list args) |
247 | __attribute__ ((format (printf, 1, 0))); | 260 | __attribute__ ((format (printf, 1, 0))); |
@@ -253,6 +266,10 @@ static inline int printk_ratelimit(void) { return 0; } | |||
253 | static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ | 266 | static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ |
254 | unsigned int interval_msec) \ | 267 | unsigned int interval_msec) \ |
255 | { return false; } | 268 | { return false; } |
269 | |||
270 | /* No effect, but we still get type checking even in the !PRINTK case: */ | ||
271 | #define printk_once(x...) printk(x) | ||
272 | |||
256 | #endif | 273 | #endif |
257 | 274 | ||
258 | extern int printk_needs_cpu(int cpu); | 275 | extern int printk_needs_cpu(int cpu); |
@@ -371,6 +388,139 @@ static inline char *pack_hex_byte(char *buf, u8 byte) | |||
371 | #endif | 388 | #endif |
372 | 389 | ||
373 | /* | 390 | /* |
391 | * General tracing related utility functions - trace_printk(), | ||
392 | * tracing_on/tracing_off and tracing_start()/tracing_stop | ||
393 | * | ||
394 | * Use tracing_on/tracing_off when you want to quickly turn on or off | ||
395 | * tracing. It simply enables or disables the recording of the trace events. | ||
396 | * This also corresponds to the user space debugfs/tracing/tracing_on | ||
397 | * file, which gives a means for the kernel and userspace to interact. | ||
398 | * Place a tracing_off() in the kernel where you want tracing to end. | ||
399 | * From user space, examine the trace, and then echo 1 > tracing_on | ||
400 | * to continue tracing. | ||
401 | * | ||
402 | * tracing_stop/tracing_start has slightly more overhead. It is used | ||
403 | * by things like suspend to ram where disabling the recording of the | ||
404 | * trace is not enough, but tracing must actually stop because things | ||
405 | * like calling smp_processor_id() may crash the system. | ||
406 | * | ||
407 | * Most likely, you want to use tracing_on/tracing_off. | ||
408 | */ | ||
409 | #ifdef CONFIG_RING_BUFFER | ||
410 | void tracing_on(void); | ||
411 | void tracing_off(void); | ||
412 | /* trace_off_permanent stops recording with no way to bring it back */ | ||
413 | void tracing_off_permanent(void); | ||
414 | int tracing_is_on(void); | ||
415 | #else | ||
416 | static inline void tracing_on(void) { } | ||
417 | static inline void tracing_off(void) { } | ||
418 | static inline void tracing_off_permanent(void) { } | ||
419 | static inline int tracing_is_on(void) { return 0; } | ||
420 | #endif | ||
421 | #ifdef CONFIG_TRACING | ||
422 | extern void tracing_start(void); | ||
423 | extern void tracing_stop(void); | ||
424 | extern void ftrace_off_permanent(void); | ||
425 | |||
426 | extern void | ||
427 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | ||
428 | |||
429 | static inline void __attribute__ ((format (printf, 1, 2))) | ||
430 | ____trace_printk_check_format(const char *fmt, ...) | ||
431 | { | ||
432 | } | ||
433 | #define __trace_printk_check_format(fmt, args...) \ | ||
434 | do { \ | ||
435 | if (0) \ | ||
436 | ____trace_printk_check_format(fmt, ##args); \ | ||
437 | } while (0) | ||
438 | |||
439 | /** | ||
440 | * trace_printk - printf formatting in the ftrace buffer | ||
441 | * @fmt: the printf format for printing | ||
442 | * | ||
443 | * Note: __trace_printk is an internal function for trace_printk and | ||
444 | * the @ip is passed in via the trace_printk macro. | ||
445 | * | ||
446 | * This function allows a kernel developer to debug fast path sections | ||
447 | * that printk is not appropriate for. By scattering in various | ||
448 | * printk like tracing in the code, a developer can quickly see | ||
449 | * where problems are occurring. | ||
450 | * | ||
451 | * This is intended as a debugging tool for the developer only. | ||
452 | * Please refrain from leaving trace_printks scattered around in | ||
453 | * your code. | ||
454 | */ | ||
455 | |||
456 | #define trace_printk(fmt, args...) \ | ||
457 | do { \ | ||
458 | __trace_printk_check_format(fmt, ##args); \ | ||
459 | if (__builtin_constant_p(fmt)) { \ | ||
460 | static const char *trace_printk_fmt \ | ||
461 | __attribute__((section("__trace_printk_fmt"))) = \ | ||
462 | __builtin_constant_p(fmt) ? fmt : NULL; \ | ||
463 | \ | ||
464 | __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \ | ||
465 | } else \ | ||
466 | __trace_printk(_THIS_IP_, fmt, ##args); \ | ||
467 | } while (0) | ||
468 | |||
469 | extern int | ||
470 | __trace_bprintk(unsigned long ip, const char *fmt, ...) | ||
471 | __attribute__ ((format (printf, 2, 3))); | ||
472 | |||
473 | extern int | ||
474 | __trace_printk(unsigned long ip, const char *fmt, ...) | ||
475 | __attribute__ ((format (printf, 2, 3))); | ||
476 | |||
477 | /* | ||
478 | * The double __builtin_constant_p is because gcc will give us an error | ||
479 | * if we try to allocate the static variable to fmt if it is not a | ||
480 | * constant. Even with the outer if statement. | ||
481 | */ | ||
482 | #define ftrace_vprintk(fmt, vargs) \ | ||
483 | do { \ | ||
484 | if (__builtin_constant_p(fmt)) { \ | ||
485 | static const char *trace_printk_fmt \ | ||
486 | __attribute__((section("__trace_printk_fmt"))) = \ | ||
487 | __builtin_constant_p(fmt) ? fmt : NULL; \ | ||
488 | \ | ||
489 | __ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \ | ||
490 | } else \ | ||
491 | __ftrace_vprintk(_THIS_IP_, fmt, vargs); \ | ||
492 | } while (0) | ||
493 | |||
494 | extern int | ||
495 | __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap); | ||
496 | |||
497 | extern int | ||
498 | __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); | ||
499 | |||
500 | extern void ftrace_dump(void); | ||
501 | #else | ||
502 | static inline void | ||
503 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } | ||
504 | static inline int | ||
505 | trace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); | ||
506 | |||
507 | static inline void tracing_start(void) { } | ||
508 | static inline void tracing_stop(void) { } | ||
509 | static inline void ftrace_off_permanent(void) { } | ||
510 | static inline int | ||
511 | trace_printk(const char *fmt, ...) | ||
512 | { | ||
513 | return 0; | ||
514 | } | ||
515 | static inline int | ||
516 | ftrace_vprintk(const char *fmt, va_list ap) | ||
517 | { | ||
518 | return 0; | ||
519 | } | ||
520 | static inline void ftrace_dump(void) { } | ||
521 | #endif /* CONFIG_TRACING */ | ||
522 | |||
523 | /* | ||
374 | * Display an IP address in readable format. | 524 | * Display an IP address in readable format. |
375 | */ | 525 | */ |
376 | 526 | ||
diff --git a/include/linux/memory.h b/include/linux/memory.h index 3fdc10806d31..86a6c0f0518d 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h | |||
@@ -99,4 +99,10 @@ enum mem_add_context { BOOT, HOTPLUG }; | |||
99 | #define hotplug_memory_notifier(fn, pri) do { } while (0) | 99 | #define hotplug_memory_notifier(fn, pri) do { } while (0) |
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | /* | ||
103 | * Kernel text modification mutex, used for code patching. Users of this lock | ||
104 | * can sleep. | ||
105 | */ | ||
106 | extern struct mutex text_mutex; | ||
107 | |||
102 | #endif /* _LINUX_MEMORY_H_ */ | 108 | #endif /* _LINUX_MEMORY_H_ */ |
diff --git a/include/linux/module.h b/include/linux/module.h index 145a75528cc1..22d9878e868c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -329,6 +329,11 @@ struct module | |||
329 | unsigned int num_tracepoints; | 329 | unsigned int num_tracepoints; |
330 | #endif | 330 | #endif |
331 | 331 | ||
332 | #ifdef CONFIG_TRACING | ||
333 | const char **trace_bprintk_fmt_start; | ||
334 | unsigned int num_trace_bprintk_fmt; | ||
335 | #endif | ||
336 | |||
332 | #ifdef CONFIG_MODULE_UNLOAD | 337 | #ifdef CONFIG_MODULE_UNLOAD |
333 | /* What modules depend on me? */ | 338 | /* What modules depend on me? */ |
334 | struct list_head modules_which_use_me; | 339 | struct list_head modules_which_use_me; |
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index b3b359660082..e1b7b2173885 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h | |||
@@ -8,7 +8,7 @@ struct ring_buffer; | |||
8 | struct ring_buffer_iter; | 8 | struct ring_buffer_iter; |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Don't reference this struct directly, use functions below. | 11 | * Don't refer to this struct directly, use functions below. |
12 | */ | 12 | */ |
13 | struct ring_buffer_event { | 13 | struct ring_buffer_event { |
14 | u32 type:2, len:3, time_delta:27; | 14 | u32 type:2, len:3, time_delta:27; |
@@ -18,10 +18,13 @@ struct ring_buffer_event { | |||
18 | /** | 18 | /** |
19 | * enum ring_buffer_type - internal ring buffer types | 19 | * enum ring_buffer_type - internal ring buffer types |
20 | * | 20 | * |
21 | * @RINGBUF_TYPE_PADDING: Left over page padding | 21 | * @RINGBUF_TYPE_PADDING: Left over page padding or discarded event |
22 | * array is ignored | 22 | * If time_delta is 0: |
23 | * size is variable depending on how much | 23 | * array is ignored |
24 | * size is variable depending on how much | ||
24 | * padding is needed | 25 | * padding is needed |
26 | * If time_delta is non zero: | ||
27 | * everything else same as RINGBUF_TYPE_DATA | ||
25 | * | 28 | * |
26 | * @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta | 29 | * @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta |
27 | * array[0] = time delta (28 .. 59) | 30 | * array[0] = time delta (28 .. 59) |
@@ -65,6 +68,8 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event) | |||
65 | return event->time_delta; | 68 | return event->time_delta; |
66 | } | 69 | } |
67 | 70 | ||
71 | void ring_buffer_event_discard(struct ring_buffer_event *event); | ||
72 | |||
68 | /* | 73 | /* |
69 | * size is in bytes for each per CPU buffer. | 74 | * size is in bytes for each per CPU buffer. |
70 | */ | 75 | */ |
@@ -74,13 +79,10 @@ void ring_buffer_free(struct ring_buffer *buffer); | |||
74 | 79 | ||
75 | int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size); | 80 | int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size); |
76 | 81 | ||
77 | struct ring_buffer_event * | 82 | struct ring_buffer_event *ring_buffer_lock_reserve(struct ring_buffer *buffer, |
78 | ring_buffer_lock_reserve(struct ring_buffer *buffer, | 83 | unsigned long length); |
79 | unsigned long length, | ||
80 | unsigned long *flags); | ||
81 | int ring_buffer_unlock_commit(struct ring_buffer *buffer, | 84 | int ring_buffer_unlock_commit(struct ring_buffer *buffer, |
82 | struct ring_buffer_event *event, | 85 | struct ring_buffer_event *event); |
83 | unsigned long flags); | ||
84 | int ring_buffer_write(struct ring_buffer *buffer, | 86 | int ring_buffer_write(struct ring_buffer *buffer, |
85 | unsigned long length, void *data); | 87 | unsigned long length, void *data); |
86 | 88 | ||
@@ -121,17 +123,19 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer); | |||
121 | unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu); | 123 | unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu); |
122 | unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu); | 124 | unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu); |
123 | 125 | ||
124 | u64 ring_buffer_time_stamp(int cpu); | 126 | u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu); |
125 | void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); | 127 | void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer, |
128 | int cpu, u64 *ts); | ||
129 | void ring_buffer_set_clock(struct ring_buffer *buffer, | ||
130 | u64 (*clock)(void)); | ||
131 | |||
132 | size_t ring_buffer_page_len(void *page); | ||
126 | 133 | ||
127 | void tracing_on(void); | ||
128 | void tracing_off(void); | ||
129 | void tracing_off_permanent(void); | ||
130 | 134 | ||
131 | void *ring_buffer_alloc_read_page(struct ring_buffer *buffer); | 135 | void *ring_buffer_alloc_read_page(struct ring_buffer *buffer); |
132 | void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data); | 136 | void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data); |
133 | int ring_buffer_read_page(struct ring_buffer *buffer, | 137 | int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page, |
134 | void **data_page, int cpu, int full); | 138 | size_t len, int cpu, int full); |
135 | 139 | ||
136 | enum ring_buffer_flags { | 140 | enum ring_buffer_flags { |
137 | RB_FL_OVERWRITE = 1 << 0, | 141 | RB_FL_OVERWRITE = 1 << 0, |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 481fad3a9b42..5a50fdef5be5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -137,6 +137,8 @@ extern unsigned long nr_uninterruptible(void); | |||
137 | extern unsigned long nr_active(void); | 137 | extern unsigned long nr_active(void); |
138 | extern unsigned long nr_iowait(void); | 138 | extern unsigned long nr_iowait(void); |
139 | 139 | ||
140 | extern unsigned long get_parent_ip(unsigned long addr); | ||
141 | |||
140 | struct seq_file; | 142 | struct seq_file; |
141 | struct cfs_rq; | 143 | struct cfs_rq; |
142 | struct task_group; | 144 | struct task_group; |
@@ -1421,6 +1423,8 @@ struct task_struct { | |||
1421 | int curr_ret_stack; | 1423 | int curr_ret_stack; |
1422 | /* Stack of return addresses for return function tracing */ | 1424 | /* Stack of return addresses for return function tracing */ |
1423 | struct ftrace_ret_stack *ret_stack; | 1425 | struct ftrace_ret_stack *ret_stack; |
1426 | /* time stamp for last schedule */ | ||
1427 | unsigned long long ftrace_timestamp; | ||
1424 | /* | 1428 | /* |
1425 | * Number of functions that haven't been traced | 1429 | * Number of functions that haven't been traced |
1426 | * because of depth overrun. | 1430 | * because of depth overrun. |
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 6ca6a7b66d75..f4523651fa42 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */ | 14 | #include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */ |
15 | #include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */ | 15 | #include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */ |
16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
17 | #include <trace/kmemtrace.h> | ||
17 | 18 | ||
18 | /* Size description struct for general caches. */ | 19 | /* Size description struct for general caches. */ |
19 | struct cache_sizes { | 20 | struct cache_sizes { |
@@ -28,8 +29,26 @@ extern struct cache_sizes malloc_sizes[]; | |||
28 | void *kmem_cache_alloc(struct kmem_cache *, gfp_t); | 29 | void *kmem_cache_alloc(struct kmem_cache *, gfp_t); |
29 | void *__kmalloc(size_t size, gfp_t flags); | 30 | void *__kmalloc(size_t size, gfp_t flags); |
30 | 31 | ||
31 | static inline void *kmalloc(size_t size, gfp_t flags) | 32 | #ifdef CONFIG_KMEMTRACE |
33 | extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags); | ||
34 | extern size_t slab_buffer_size(struct kmem_cache *cachep); | ||
35 | #else | ||
36 | static __always_inline void * | ||
37 | kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) | ||
32 | { | 38 | { |
39 | return kmem_cache_alloc(cachep, flags); | ||
40 | } | ||
41 | static inline size_t slab_buffer_size(struct kmem_cache *cachep) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | #endif | ||
46 | |||
47 | static __always_inline void *kmalloc(size_t size, gfp_t flags) | ||
48 | { | ||
49 | struct kmem_cache *cachep; | ||
50 | void *ret; | ||
51 | |||
33 | if (__builtin_constant_p(size)) { | 52 | if (__builtin_constant_p(size)) { |
34 | int i = 0; | 53 | int i = 0; |
35 | 54 | ||
@@ -47,10 +66,17 @@ static inline void *kmalloc(size_t size, gfp_t flags) | |||
47 | found: | 66 | found: |
48 | #ifdef CONFIG_ZONE_DMA | 67 | #ifdef CONFIG_ZONE_DMA |
49 | if (flags & GFP_DMA) | 68 | if (flags & GFP_DMA) |
50 | return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep, | 69 | cachep = malloc_sizes[i].cs_dmacachep; |
51 | flags); | 70 | else |
52 | #endif | 71 | #endif |
53 | return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags); | 72 | cachep = malloc_sizes[i].cs_cachep; |
73 | |||
74 | ret = kmem_cache_alloc_notrace(cachep, flags); | ||
75 | |||
76 | kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, ret, | ||
77 | size, slab_buffer_size(cachep), flags); | ||
78 | |||
79 | return ret; | ||
54 | } | 80 | } |
55 | return __kmalloc(size, flags); | 81 | return __kmalloc(size, flags); |
56 | } | 82 | } |
@@ -59,8 +85,25 @@ found: | |||
59 | extern void *__kmalloc_node(size_t size, gfp_t flags, int node); | 85 | extern void *__kmalloc_node(size_t size, gfp_t flags, int node); |
60 | extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); | 86 | extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); |
61 | 87 | ||
62 | static inline void *kmalloc_node(size_t size, gfp_t flags, int node) | 88 | #ifdef CONFIG_KMEMTRACE |
89 | extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, | ||
90 | gfp_t flags, | ||
91 | int nodeid); | ||
92 | #else | ||
93 | static __always_inline void * | ||
94 | kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, | ||
95 | gfp_t flags, | ||
96 | int nodeid) | ||
97 | { | ||
98 | return kmem_cache_alloc_node(cachep, flags, nodeid); | ||
99 | } | ||
100 | #endif | ||
101 | |||
102 | static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) | ||
63 | { | 103 | { |
104 | struct kmem_cache *cachep; | ||
105 | void *ret; | ||
106 | |||
64 | if (__builtin_constant_p(size)) { | 107 | if (__builtin_constant_p(size)) { |
65 | int i = 0; | 108 | int i = 0; |
66 | 109 | ||
@@ -78,11 +121,18 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node) | |||
78 | found: | 121 | found: |
79 | #ifdef CONFIG_ZONE_DMA | 122 | #ifdef CONFIG_ZONE_DMA |
80 | if (flags & GFP_DMA) | 123 | if (flags & GFP_DMA) |
81 | return kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep, | 124 | cachep = malloc_sizes[i].cs_dmacachep; |
82 | flags, node); | 125 | else |
83 | #endif | 126 | #endif |
84 | return kmem_cache_alloc_node(malloc_sizes[i].cs_cachep, | 127 | cachep = malloc_sizes[i].cs_cachep; |
85 | flags, node); | 128 | |
129 | ret = kmem_cache_alloc_node_notrace(cachep, flags, node); | ||
130 | |||
131 | kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, | ||
132 | ret, size, slab_buffer_size(cachep), | ||
133 | flags, node); | ||
134 | |||
135 | return ret; | ||
86 | } | 136 | } |
87 | return __kmalloc_node(size, flags, node); | 137 | return __kmalloc_node(size, flags, node); |
88 | } | 138 | } |
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h index 59a3fa476ab9..0ec00b39d006 100644 --- a/include/linux/slob_def.h +++ b/include/linux/slob_def.h | |||
@@ -3,14 +3,15 @@ | |||
3 | 3 | ||
4 | void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); | 4 | void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); |
5 | 5 | ||
6 | static inline void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) | 6 | static __always_inline void *kmem_cache_alloc(struct kmem_cache *cachep, |
7 | gfp_t flags) | ||
7 | { | 8 | { |
8 | return kmem_cache_alloc_node(cachep, flags, -1); | 9 | return kmem_cache_alloc_node(cachep, flags, -1); |
9 | } | 10 | } |
10 | 11 | ||
11 | void *__kmalloc_node(size_t size, gfp_t flags, int node); | 12 | void *__kmalloc_node(size_t size, gfp_t flags, int node); |
12 | 13 | ||
13 | static inline void *kmalloc_node(size_t size, gfp_t flags, int node) | 14 | static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) |
14 | { | 15 | { |
15 | return __kmalloc_node(size, flags, node); | 16 | return __kmalloc_node(size, flags, node); |
16 | } | 17 | } |
@@ -23,12 +24,12 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node) | |||
23 | * kmalloc is the normal method of allocating memory | 24 | * kmalloc is the normal method of allocating memory |
24 | * in the kernel. | 25 | * in the kernel. |
25 | */ | 26 | */ |
26 | static inline void *kmalloc(size_t size, gfp_t flags) | 27 | static __always_inline void *kmalloc(size_t size, gfp_t flags) |
27 | { | 28 | { |
28 | return __kmalloc_node(size, flags, -1); | 29 | return __kmalloc_node(size, flags, -1); |
29 | } | 30 | } |
30 | 31 | ||
31 | static inline void *__kmalloc(size_t size, gfp_t flags) | 32 | static __always_inline void *__kmalloc(size_t size, gfp_t flags) |
32 | { | 33 | { |
33 | return kmalloc(size, flags); | 34 | return kmalloc(size, flags); |
34 | } | 35 | } |
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index e37b6aa8a9fb..a1f90528e70b 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/gfp.h> | 10 | #include <linux/gfp.h> |
11 | #include <linux/workqueue.h> | 11 | #include <linux/workqueue.h> |
12 | #include <linux/kobject.h> | 12 | #include <linux/kobject.h> |
13 | #include <trace/kmemtrace.h> | ||
13 | 14 | ||
14 | enum stat_item { | 15 | enum stat_item { |
15 | ALLOC_FASTPATH, /* Allocation from cpu slab */ | 16 | ALLOC_FASTPATH, /* Allocation from cpu slab */ |
@@ -217,13 +218,31 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size) | |||
217 | void *kmem_cache_alloc(struct kmem_cache *, gfp_t); | 218 | void *kmem_cache_alloc(struct kmem_cache *, gfp_t); |
218 | void *__kmalloc(size_t size, gfp_t flags); | 219 | void *__kmalloc(size_t size, gfp_t flags); |
219 | 220 | ||
221 | #ifdef CONFIG_KMEMTRACE | ||
222 | extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags); | ||
223 | #else | ||
224 | static __always_inline void * | ||
225 | kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags) | ||
226 | { | ||
227 | return kmem_cache_alloc(s, gfpflags); | ||
228 | } | ||
229 | #endif | ||
230 | |||
220 | static __always_inline void *kmalloc_large(size_t size, gfp_t flags) | 231 | static __always_inline void *kmalloc_large(size_t size, gfp_t flags) |
221 | { | 232 | { |
222 | return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size)); | 233 | unsigned int order = get_order(size); |
234 | void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order); | ||
235 | |||
236 | kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, ret, | ||
237 | size, PAGE_SIZE << order, flags); | ||
238 | |||
239 | return ret; | ||
223 | } | 240 | } |
224 | 241 | ||
225 | static __always_inline void *kmalloc(size_t size, gfp_t flags) | 242 | static __always_inline void *kmalloc(size_t size, gfp_t flags) |
226 | { | 243 | { |
244 | void *ret; | ||
245 | |||
227 | if (__builtin_constant_p(size)) { | 246 | if (__builtin_constant_p(size)) { |
228 | if (size > SLUB_MAX_SIZE) | 247 | if (size > SLUB_MAX_SIZE) |
229 | return kmalloc_large(size, flags); | 248 | return kmalloc_large(size, flags); |
@@ -234,7 +253,13 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) | |||
234 | if (!s) | 253 | if (!s) |
235 | return ZERO_SIZE_PTR; | 254 | return ZERO_SIZE_PTR; |
236 | 255 | ||
237 | return kmem_cache_alloc(s, flags); | 256 | ret = kmem_cache_alloc_notrace(s, flags); |
257 | |||
258 | kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, | ||
259 | _THIS_IP_, ret, | ||
260 | size, s->size, flags); | ||
261 | |||
262 | return ret; | ||
238 | } | 263 | } |
239 | } | 264 | } |
240 | return __kmalloc(size, flags); | 265 | return __kmalloc(size, flags); |
@@ -244,8 +269,24 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) | |||
244 | void *__kmalloc_node(size_t size, gfp_t flags, int node); | 269 | void *__kmalloc_node(size_t size, gfp_t flags, int node); |
245 | void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); | 270 | void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); |
246 | 271 | ||
272 | #ifdef CONFIG_KMEMTRACE | ||
273 | extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, | ||
274 | gfp_t gfpflags, | ||
275 | int node); | ||
276 | #else | ||
277 | static __always_inline void * | ||
278 | kmem_cache_alloc_node_notrace(struct kmem_cache *s, | ||
279 | gfp_t gfpflags, | ||
280 | int node) | ||
281 | { | ||
282 | return kmem_cache_alloc_node(s, gfpflags, node); | ||
283 | } | ||
284 | #endif | ||
285 | |||
247 | static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) | 286 | static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) |
248 | { | 287 | { |
288 | void *ret; | ||
289 | |||
249 | if (__builtin_constant_p(size) && | 290 | if (__builtin_constant_p(size) && |
250 | size <= SLUB_MAX_SIZE && !(flags & SLUB_DMA)) { | 291 | size <= SLUB_MAX_SIZE && !(flags & SLUB_DMA)) { |
251 | struct kmem_cache *s = kmalloc_slab(size); | 292 | struct kmem_cache *s = kmalloc_slab(size); |
@@ -253,7 +294,13 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) | |||
253 | if (!s) | 294 | if (!s) |
254 | return ZERO_SIZE_PTR; | 295 | return ZERO_SIZE_PTR; |
255 | 296 | ||
256 | return kmem_cache_alloc_node(s, flags, node); | 297 | ret = kmem_cache_alloc_node_notrace(s, flags, node); |
298 | |||
299 | kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, | ||
300 | _THIS_IP_, ret, | ||
301 | size, s->size, flags, node); | ||
302 | |||
303 | return ret; | ||
257 | } | 304 | } |
258 | return __kmalloc_node(size, flags, node); | 305 | return __kmalloc_node(size, flags, node); |
259 | } | 306 | } |
diff --git a/include/linux/string.h b/include/linux/string.h index 8852739f36df..3c877d686375 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/compiler.h> /* for inline */ | 10 | #include <linux/compiler.h> /* for inline */ |
11 | #include <linux/types.h> /* for size_t */ | 11 | #include <linux/types.h> /* for size_t */ |
12 | #include <linux/stddef.h> /* for NULL */ | 12 | #include <linux/stddef.h> /* for NULL */ |
13 | #include <stdarg.h> | ||
13 | 14 | ||
14 | extern char *strndup_user(const char __user *, long); | 15 | extern char *strndup_user(const char __user *, long); |
15 | extern void *memdup_user(const void __user *, size_t); | 16 | extern void *memdup_user(const void __user *, size_t); |
@@ -112,6 +113,12 @@ extern void argv_free(char **argv); | |||
112 | 113 | ||
113 | extern bool sysfs_streq(const char *s1, const char *s2); | 114 | extern bool sysfs_streq(const char *s1, const char *s2); |
114 | 115 | ||
116 | #ifdef CONFIG_BINARY_PRINTF | ||
117 | int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args); | ||
118 | int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf); | ||
119 | int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4); | ||
120 | #endif | ||
121 | |||
115 | extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, | 122 | extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, |
116 | const void *from, size_t available); | 123 | const void *from, size_t available); |
117 | 124 | ||
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index f9f900cfd066..0cff9bb80b02 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -65,6 +65,7 @@ struct old_linux_dirent; | |||
65 | #include <asm/signal.h> | 65 | #include <asm/signal.h> |
66 | #include <linux/quota.h> | 66 | #include <linux/quota.h> |
67 | #include <linux/key.h> | 67 | #include <linux/key.h> |
68 | #include <linux/ftrace.h> | ||
68 | 69 | ||
69 | #define __SC_DECL1(t1, a1) t1 a1 | 70 | #define __SC_DECL1(t1, a1) t1 a1 |
70 | #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__) | 71 | #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__) |
@@ -95,7 +96,46 @@ struct old_linux_dirent; | |||
95 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) | 96 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) |
96 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) | 97 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) |
97 | 98 | ||
99 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
100 | #define __SC_STR_ADECL1(t, a) #a | ||
101 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) | ||
102 | #define __SC_STR_ADECL3(t, a, ...) #a, __SC_STR_ADECL2(__VA_ARGS__) | ||
103 | #define __SC_STR_ADECL4(t, a, ...) #a, __SC_STR_ADECL3(__VA_ARGS__) | ||
104 | #define __SC_STR_ADECL5(t, a, ...) #a, __SC_STR_ADECL4(__VA_ARGS__) | ||
105 | #define __SC_STR_ADECL6(t, a, ...) #a, __SC_STR_ADECL5(__VA_ARGS__) | ||
106 | |||
107 | #define __SC_STR_TDECL1(t, a) #t | ||
108 | #define __SC_STR_TDECL2(t, a, ...) #t, __SC_STR_TDECL1(__VA_ARGS__) | ||
109 | #define __SC_STR_TDECL3(t, a, ...) #t, __SC_STR_TDECL2(__VA_ARGS__) | ||
110 | #define __SC_STR_TDECL4(t, a, ...) #t, __SC_STR_TDECL3(__VA_ARGS__) | ||
111 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) | ||
112 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) | ||
113 | |||
114 | #define SYSCALL_METADATA(sname, nb) \ | ||
115 | static const struct syscall_metadata __used \ | ||
116 | __attribute__((__aligned__(4))) \ | ||
117 | __attribute__((section("__syscalls_metadata"))) \ | ||
118 | __syscall_meta_##sname = { \ | ||
119 | .name = "sys"#sname, \ | ||
120 | .nb_args = nb, \ | ||
121 | .types = types_##sname, \ | ||
122 | .args = args_##sname, \ | ||
123 | } | ||
124 | |||
125 | #define SYSCALL_DEFINE0(sname) \ | ||
126 | static const struct syscall_metadata __used \ | ||
127 | __attribute__((__aligned__(4))) \ | ||
128 | __attribute__((section("__syscalls_metadata"))) \ | ||
129 | __syscall_meta_##sname = { \ | ||
130 | .name = "sys_"#sname, \ | ||
131 | .nb_args = 0, \ | ||
132 | }; \ | ||
133 | asmlinkage long sys_##sname(void) | ||
134 | |||
135 | #else | ||
98 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) | 136 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) |
137 | #endif | ||
138 | |||
99 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) | 139 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) |
100 | #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) | 140 | #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) |
101 | #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) | 141 | #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) |
@@ -117,10 +157,26 @@ struct old_linux_dirent; | |||
117 | #endif | 157 | #endif |
118 | #endif | 158 | #endif |
119 | 159 | ||
160 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
161 | #define SYSCALL_DEFINEx(x, sname, ...) \ | ||
162 | static const char *types_##sname[] = { \ | ||
163 | __SC_STR_TDECL##x(__VA_ARGS__) \ | ||
164 | }; \ | ||
165 | static const char *args_##sname[] = { \ | ||
166 | __SC_STR_ADECL##x(__VA_ARGS__) \ | ||
167 | }; \ | ||
168 | SYSCALL_METADATA(sname, x); \ | ||
169 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) | ||
170 | #else | ||
171 | #define SYSCALL_DEFINEx(x, sname, ...) \ | ||
172 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) | ||
173 | #endif | ||
174 | |||
120 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | 175 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS |
121 | 176 | ||
122 | #define SYSCALL_DEFINE(name) static inline long SYSC_##name | 177 | #define SYSCALL_DEFINE(name) static inline long SYSC_##name |
123 | #define SYSCALL_DEFINEx(x, name, ...) \ | 178 | |
179 | #define __SYSCALL_DEFINEx(x, name, ...) \ | ||
124 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ | 180 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ |
125 | static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ | 181 | static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ |
126 | asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ | 182 | asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ |
@@ -134,7 +190,7 @@ struct old_linux_dirent; | |||
134 | #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ | 190 | #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ |
135 | 191 | ||
136 | #define SYSCALL_DEFINE(name) asmlinkage long sys_##name | 192 | #define SYSCALL_DEFINE(name) asmlinkage long sys_##name |
137 | #define SYSCALL_DEFINEx(x, name, ...) \ | 193 | #define __SYSCALL_DEFINEx(x, name, ...) \ |
138 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) | 194 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) |
139 | 195 | ||
140 | #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ | 196 | #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ |
diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h new file mode 100644 index 000000000000..7a8130384087 --- /dev/null +++ b/include/linux/trace_clock.h | |||
@@ -0,0 +1,19 @@ | |||
1 | #ifndef _LINUX_TRACE_CLOCK_H | ||
2 | #define _LINUX_TRACE_CLOCK_H | ||
3 | |||
4 | /* | ||
5 | * 3 trace clock variants, with differing scalability/precision | ||
6 | * tradeoffs: | ||
7 | * | ||
8 | * - local: CPU-local trace clock | ||
9 | * - medium: scalable global clock with some jitter | ||
10 | * - global: globally monotonic, serialized clock | ||
11 | */ | ||
12 | #include <linux/compiler.h> | ||
13 | #include <linux/types.h> | ||
14 | |||
15 | extern u64 notrace trace_clock_local(void); | ||
16 | extern u64 notrace trace_clock(void); | ||
17 | extern u64 notrace trace_clock_global(void); | ||
18 | |||
19 | #endif /* _LINUX_TRACE_CLOCK_H */ | ||
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 757005458366..d35a7ee7611f 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
@@ -31,8 +31,8 @@ struct tracepoint { | |||
31 | * Keep in sync with vmlinux.lds.h. | 31 | * Keep in sync with vmlinux.lds.h. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #define TPPROTO(args...) args | 34 | #define TP_PROTO(args...) args |
35 | #define TPARGS(args...) args | 35 | #define TP_ARGS(args...) args |
36 | 36 | ||
37 | #ifdef CONFIG_TRACEPOINTS | 37 | #ifdef CONFIG_TRACEPOINTS |
38 | 38 | ||
@@ -65,7 +65,7 @@ struct tracepoint { | |||
65 | { \ | 65 | { \ |
66 | if (unlikely(__tracepoint_##name.state)) \ | 66 | if (unlikely(__tracepoint_##name.state)) \ |
67 | __DO_TRACE(&__tracepoint_##name, \ | 67 | __DO_TRACE(&__tracepoint_##name, \ |
68 | TPPROTO(proto), TPARGS(args)); \ | 68 | TP_PROTO(proto), TP_ARGS(args)); \ |
69 | } \ | 69 | } \ |
70 | static inline int register_trace_##name(void (*probe)(proto)) \ | 70 | static inline int register_trace_##name(void (*probe)(proto)) \ |
71 | { \ | 71 | { \ |
@@ -153,4 +153,114 @@ static inline void tracepoint_synchronize_unregister(void) | |||
153 | synchronize_sched(); | 153 | synchronize_sched(); |
154 | } | 154 | } |
155 | 155 | ||
156 | #define PARAMS(args...) args | ||
157 | #define TRACE_FORMAT(name, proto, args, fmt) \ | ||
158 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | ||
159 | |||
160 | |||
161 | /* | ||
162 | * For use with the TRACE_EVENT macro: | ||
163 | * | ||
164 | * We define a tracepoint, its arguments, its printk format | ||
165 | * and its 'fast binay record' layout. | ||
166 | * | ||
167 | * Firstly, name your tracepoint via TRACE_EVENT(name : the | ||
168 | * 'subsystem_event' notation is fine. | ||
169 | * | ||
170 | * Think about this whole construct as the | ||
171 | * 'trace_sched_switch() function' from now on. | ||
172 | * | ||
173 | * | ||
174 | * TRACE_EVENT(sched_switch, | ||
175 | * | ||
176 | * * | ||
177 | * * A function has a regular function arguments | ||
178 | * * prototype, declare it via TP_PROTO(): | ||
179 | * * | ||
180 | * | ||
181 | * TP_PROTO(struct rq *rq, struct task_struct *prev, | ||
182 | * struct task_struct *next), | ||
183 | * | ||
184 | * * | ||
185 | * * Define the call signature of the 'function'. | ||
186 | * * (Design sidenote: we use this instead of a | ||
187 | * * TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.) | ||
188 | * * | ||
189 | * | ||
190 | * TP_ARGS(rq, prev, next), | ||
191 | * | ||
192 | * * | ||
193 | * * Fast binary tracing: define the trace record via | ||
194 | * * TP_STRUCT__entry(). You can think about it like a | ||
195 | * * regular C structure local variable definition. | ||
196 | * * | ||
197 | * * This is how the trace record is structured and will | ||
198 | * * be saved into the ring buffer. These are the fields | ||
199 | * * that will be exposed to user-space in | ||
200 | * * /debug/tracing/events/<*>/format. | ||
201 | * * | ||
202 | * * The declared 'local variable' is called '__entry' | ||
203 | * * | ||
204 | * * __field(pid_t, prev_prid) is equivalent to a standard declariton: | ||
205 | * * | ||
206 | * * pid_t prev_pid; | ||
207 | * * | ||
208 | * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to: | ||
209 | * * | ||
210 | * * char prev_comm[TASK_COMM_LEN]; | ||
211 | * * | ||
212 | * | ||
213 | * TP_STRUCT__entry( | ||
214 | * __array( char, prev_comm, TASK_COMM_LEN ) | ||
215 | * __field( pid_t, prev_pid ) | ||
216 | * __field( int, prev_prio ) | ||
217 | * __array( char, next_comm, TASK_COMM_LEN ) | ||
218 | * __field( pid_t, next_pid ) | ||
219 | * __field( int, next_prio ) | ||
220 | * ), | ||
221 | * | ||
222 | * * | ||
223 | * * Assign the entry into the trace record, by embedding | ||
224 | * * a full C statement block into TP_fast_assign(). You | ||
225 | * * can refer to the trace record as '__entry' - | ||
226 | * * otherwise you can put arbitrary C code in here. | ||
227 | * * | ||
228 | * * Note: this C code will execute every time a trace event | ||
229 | * * happens, on an active tracepoint. | ||
230 | * * | ||
231 | * | ||
232 | * TP_fast_assign( | ||
233 | * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); | ||
234 | * __entry->prev_pid = prev->pid; | ||
235 | * __entry->prev_prio = prev->prio; | ||
236 | * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); | ||
237 | * __entry->next_pid = next->pid; | ||
238 | * __entry->next_prio = next->prio; | ||
239 | * ) | ||
240 | * | ||
241 | * * | ||
242 | * * Formatted output of a trace record via TP_printk(). | ||
243 | * * This is how the tracepoint will appear under ftrace | ||
244 | * * plugins that make use of this tracepoint. | ||
245 | * * | ||
246 | * * (raw-binary tracing wont actually perform this step.) | ||
247 | * * | ||
248 | * | ||
249 | * TP_printk("task %s:%d [%d] ==> %s:%d [%d]", | ||
250 | * __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, | ||
251 | * __entry->next_comm, __entry->next_pid, __entry->next_prio), | ||
252 | * | ||
253 | * ); | ||
254 | * | ||
255 | * This macro construct is thus used for the regular printk format | ||
256 | * tracing setup, it is used to construct a function pointer based | ||
257 | * tracepoint callback (this is used by programmatic plugins and | ||
258 | * can also by used by generic instrumentation like SystemTap), and | ||
259 | * it is also used to expose a structured trace record in | ||
260 | * /debug/tracing/events/. | ||
261 | */ | ||
262 | |||
263 | #define TRACE_EVENT(name, proto, args, struct, assign, print) \ | ||
264 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | ||
265 | |||
156 | #endif | 266 | #endif |
diff --git a/include/trace/block.h b/include/trace/block.h index 25c6a1fd5b77..25b7068b819e 100644 --- a/include/trace/block.h +++ b/include/trace/block.h | |||
@@ -5,72 +5,72 @@ | |||
5 | #include <linux/tracepoint.h> | 5 | #include <linux/tracepoint.h> |
6 | 6 | ||
7 | DECLARE_TRACE(block_rq_abort, | 7 | DECLARE_TRACE(block_rq_abort, |
8 | TPPROTO(struct request_queue *q, struct request *rq), | 8 | TP_PROTO(struct request_queue *q, struct request *rq), |
9 | TPARGS(q, rq)); | 9 | TP_ARGS(q, rq)); |
10 | 10 | ||
11 | DECLARE_TRACE(block_rq_insert, | 11 | DECLARE_TRACE(block_rq_insert, |
12 | TPPROTO(struct request_queue *q, struct request *rq), | 12 | TP_PROTO(struct request_queue *q, struct request *rq), |
13 | TPARGS(q, rq)); | 13 | TP_ARGS(q, rq)); |
14 | 14 | ||
15 | DECLARE_TRACE(block_rq_issue, | 15 | DECLARE_TRACE(block_rq_issue, |
16 | TPPROTO(struct request_queue *q, struct request *rq), | 16 | TP_PROTO(struct request_queue *q, struct request *rq), |
17 | TPARGS(q, rq)); | 17 | TP_ARGS(q, rq)); |
18 | 18 | ||
19 | DECLARE_TRACE(block_rq_requeue, | 19 | DECLARE_TRACE(block_rq_requeue, |
20 | TPPROTO(struct request_queue *q, struct request *rq), | 20 | TP_PROTO(struct request_queue *q, struct request *rq), |
21 | TPARGS(q, rq)); | 21 | TP_ARGS(q, rq)); |
22 | 22 | ||
23 | DECLARE_TRACE(block_rq_complete, | 23 | DECLARE_TRACE(block_rq_complete, |
24 | TPPROTO(struct request_queue *q, struct request *rq), | 24 | TP_PROTO(struct request_queue *q, struct request *rq), |
25 | TPARGS(q, rq)); | 25 | TP_ARGS(q, rq)); |
26 | 26 | ||
27 | DECLARE_TRACE(block_bio_bounce, | 27 | DECLARE_TRACE(block_bio_bounce, |
28 | TPPROTO(struct request_queue *q, struct bio *bio), | 28 | TP_PROTO(struct request_queue *q, struct bio *bio), |
29 | TPARGS(q, bio)); | 29 | TP_ARGS(q, bio)); |
30 | 30 | ||
31 | DECLARE_TRACE(block_bio_complete, | 31 | DECLARE_TRACE(block_bio_complete, |
32 | TPPROTO(struct request_queue *q, struct bio *bio), | 32 | TP_PROTO(struct request_queue *q, struct bio *bio), |
33 | TPARGS(q, bio)); | 33 | TP_ARGS(q, bio)); |
34 | 34 | ||
35 | DECLARE_TRACE(block_bio_backmerge, | 35 | DECLARE_TRACE(block_bio_backmerge, |
36 | TPPROTO(struct request_queue *q, struct bio *bio), | 36 | TP_PROTO(struct request_queue *q, struct bio *bio), |
37 | TPARGS(q, bio)); | 37 | TP_ARGS(q, bio)); |
38 | 38 | ||
39 | DECLARE_TRACE(block_bio_frontmerge, | 39 | DECLARE_TRACE(block_bio_frontmerge, |
40 | TPPROTO(struct request_queue *q, struct bio *bio), | 40 | TP_PROTO(struct request_queue *q, struct bio *bio), |
41 | TPARGS(q, bio)); | 41 | TP_ARGS(q, bio)); |
42 | 42 | ||
43 | DECLARE_TRACE(block_bio_queue, | 43 | DECLARE_TRACE(block_bio_queue, |
44 | TPPROTO(struct request_queue *q, struct bio *bio), | 44 | TP_PROTO(struct request_queue *q, struct bio *bio), |
45 | TPARGS(q, bio)); | 45 | TP_ARGS(q, bio)); |
46 | 46 | ||
47 | DECLARE_TRACE(block_getrq, | 47 | DECLARE_TRACE(block_getrq, |
48 | TPPROTO(struct request_queue *q, struct bio *bio, int rw), | 48 | TP_PROTO(struct request_queue *q, struct bio *bio, int rw), |
49 | TPARGS(q, bio, rw)); | 49 | TP_ARGS(q, bio, rw)); |
50 | 50 | ||
51 | DECLARE_TRACE(block_sleeprq, | 51 | DECLARE_TRACE(block_sleeprq, |
52 | TPPROTO(struct request_queue *q, struct bio *bio, int rw), | 52 | TP_PROTO(struct request_queue *q, struct bio *bio, int rw), |
53 | TPARGS(q, bio, rw)); | 53 | TP_ARGS(q, bio, rw)); |
54 | 54 | ||
55 | DECLARE_TRACE(block_plug, | 55 | DECLARE_TRACE(block_plug, |
56 | TPPROTO(struct request_queue *q), | 56 | TP_PROTO(struct request_queue *q), |
57 | TPARGS(q)); | 57 | TP_ARGS(q)); |
58 | 58 | ||
59 | DECLARE_TRACE(block_unplug_timer, | 59 | DECLARE_TRACE(block_unplug_timer, |
60 | TPPROTO(struct request_queue *q), | 60 | TP_PROTO(struct request_queue *q), |
61 | TPARGS(q)); | 61 | TP_ARGS(q)); |
62 | 62 | ||
63 | DECLARE_TRACE(block_unplug_io, | 63 | DECLARE_TRACE(block_unplug_io, |
64 | TPPROTO(struct request_queue *q), | 64 | TP_PROTO(struct request_queue *q), |
65 | TPARGS(q)); | 65 | TP_ARGS(q)); |
66 | 66 | ||
67 | DECLARE_TRACE(block_split, | 67 | DECLARE_TRACE(block_split, |
68 | TPPROTO(struct request_queue *q, struct bio *bio, unsigned int pdu), | 68 | TP_PROTO(struct request_queue *q, struct bio *bio, unsigned int pdu), |
69 | TPARGS(q, bio, pdu)); | 69 | TP_ARGS(q, bio, pdu)); |
70 | 70 | ||
71 | DECLARE_TRACE(block_remap, | 71 | DECLARE_TRACE(block_remap, |
72 | TPPROTO(struct request_queue *q, struct bio *bio, dev_t dev, | 72 | TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev, |
73 | sector_t from, sector_t to), | 73 | sector_t from, sector_t to), |
74 | TPARGS(q, bio, dev, from, to)); | 74 | TP_ARGS(q, bio, dev, from, to)); |
75 | 75 | ||
76 | #endif | 76 | #endif |
diff --git a/include/trace/irq.h b/include/trace/irq.h new file mode 100644 index 000000000000..ff5d4495dc37 --- /dev/null +++ b/include/trace/irq.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef _TRACE_IRQ_H | ||
2 | #define _TRACE_IRQ_H | ||
3 | |||
4 | #include <linux/interrupt.h> | ||
5 | #include <linux/tracepoint.h> | ||
6 | |||
7 | #include <trace/irq_event_types.h> | ||
8 | |||
9 | #endif | ||
diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h new file mode 100644 index 000000000000..85964ebd47ec --- /dev/null +++ b/include/trace/irq_event_types.h | |||
@@ -0,0 +1,55 @@ | |||
1 | |||
2 | /* use <trace/irq.h> instead */ | ||
3 | #ifndef TRACE_FORMAT | ||
4 | # error Do not include this file directly. | ||
5 | # error Unless you know what you are doing. | ||
6 | #endif | ||
7 | |||
8 | #undef TRACE_SYSTEM | ||
9 | #define TRACE_SYSTEM irq | ||
10 | |||
11 | /* | ||
12 | * Tracepoint for entry of interrupt handler: | ||
13 | */ | ||
14 | TRACE_FORMAT(irq_handler_entry, | ||
15 | TP_PROTO(int irq, struct irqaction *action), | ||
16 | TP_ARGS(irq, action), | ||
17 | TP_FMT("irq=%d handler=%s", irq, action->name) | ||
18 | ); | ||
19 | |||
20 | /* | ||
21 | * Tracepoint for return of an interrupt handler: | ||
22 | */ | ||
23 | TRACE_EVENT(irq_handler_exit, | ||
24 | |||
25 | TP_PROTO(int irq, struct irqaction *action, int ret), | ||
26 | |||
27 | TP_ARGS(irq, action, ret), | ||
28 | |||
29 | TP_STRUCT__entry( | ||
30 | __field( int, irq ) | ||
31 | __field( int, ret ) | ||
32 | ), | ||
33 | |||
34 | TP_fast_assign( | ||
35 | __entry->irq = irq; | ||
36 | __entry->ret = ret; | ||
37 | ), | ||
38 | |||
39 | TP_printk("irq=%d return=%s", | ||
40 | __entry->irq, __entry->ret ? "handled" : "unhandled") | ||
41 | ); | ||
42 | |||
43 | TRACE_FORMAT(softirq_entry, | ||
44 | TP_PROTO(struct softirq_action *h, struct softirq_action *vec), | ||
45 | TP_ARGS(h, vec), | ||
46 | TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) | ||
47 | ); | ||
48 | |||
49 | TRACE_FORMAT(softirq_exit, | ||
50 | TP_PROTO(struct softirq_action *h, struct softirq_action *vec), | ||
51 | TP_ARGS(h, vec), | ||
52 | TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) | ||
53 | ); | ||
54 | |||
55 | #undef TRACE_SYSTEM | ||
diff --git a/include/trace/kmemtrace.h b/include/trace/kmemtrace.h new file mode 100644 index 000000000000..ad8b7857855a --- /dev/null +++ b/include/trace/kmemtrace.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Eduard - Gabriel Munteanu | ||
3 | * | ||
4 | * This file is released under GPL version 2. | ||
5 | */ | ||
6 | |||
7 | #ifndef _LINUX_KMEMTRACE_H | ||
8 | #define _LINUX_KMEMTRACE_H | ||
9 | |||
10 | #ifdef __KERNEL__ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/marker.h> | ||
14 | |||
15 | enum kmemtrace_type_id { | ||
16 | KMEMTRACE_TYPE_KMALLOC = 0, /* kmalloc() or kfree(). */ | ||
17 | KMEMTRACE_TYPE_CACHE, /* kmem_cache_*(). */ | ||
18 | KMEMTRACE_TYPE_PAGES, /* __get_free_pages() and friends. */ | ||
19 | }; | ||
20 | |||
21 | #ifdef CONFIG_KMEMTRACE | ||
22 | |||
23 | extern void kmemtrace_init(void); | ||
24 | |||
25 | extern void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id, | ||
26 | unsigned long call_site, | ||
27 | const void *ptr, | ||
28 | size_t bytes_req, | ||
29 | size_t bytes_alloc, | ||
30 | gfp_t gfp_flags, | ||
31 | int node); | ||
32 | |||
33 | extern void kmemtrace_mark_free(enum kmemtrace_type_id type_id, | ||
34 | unsigned long call_site, | ||
35 | const void *ptr); | ||
36 | |||
37 | #else /* CONFIG_KMEMTRACE */ | ||
38 | |||
39 | static inline void kmemtrace_init(void) | ||
40 | { | ||
41 | } | ||
42 | |||
43 | static inline void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id, | ||
44 | unsigned long call_site, | ||
45 | const void *ptr, | ||
46 | size_t bytes_req, | ||
47 | size_t bytes_alloc, | ||
48 | gfp_t gfp_flags, | ||
49 | int node) | ||
50 | { | ||
51 | } | ||
52 | |||
53 | static inline void kmemtrace_mark_free(enum kmemtrace_type_id type_id, | ||
54 | unsigned long call_site, | ||
55 | const void *ptr) | ||
56 | { | ||
57 | } | ||
58 | |||
59 | #endif /* CONFIG_KMEMTRACE */ | ||
60 | |||
61 | static inline void kmemtrace_mark_alloc(enum kmemtrace_type_id type_id, | ||
62 | unsigned long call_site, | ||
63 | const void *ptr, | ||
64 | size_t bytes_req, | ||
65 | size_t bytes_alloc, | ||
66 | gfp_t gfp_flags) | ||
67 | { | ||
68 | kmemtrace_mark_alloc_node(type_id, call_site, ptr, | ||
69 | bytes_req, bytes_alloc, gfp_flags, -1); | ||
70 | } | ||
71 | |||
72 | #endif /* __KERNEL__ */ | ||
73 | |||
74 | #endif /* _LINUX_KMEMTRACE_H */ | ||
75 | |||
diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h new file mode 100644 index 000000000000..5ca67df87f2a --- /dev/null +++ b/include/trace/lockdep.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef _TRACE_LOCKDEP_H | ||
2 | #define _TRACE_LOCKDEP_H | ||
3 | |||
4 | #include <linux/lockdep.h> | ||
5 | #include <linux/tracepoint.h> | ||
6 | |||
7 | #include <trace/lockdep_event_types.h> | ||
8 | |||
9 | #endif | ||
diff --git a/include/trace/lockdep_event_types.h b/include/trace/lockdep_event_types.h new file mode 100644 index 000000000000..adccfcd2ec8f --- /dev/null +++ b/include/trace/lockdep_event_types.h | |||
@@ -0,0 +1,44 @@ | |||
1 | |||
2 | #ifndef TRACE_FORMAT | ||
3 | # error Do not include this file directly. | ||
4 | # error Unless you know what you are doing. | ||
5 | #endif | ||
6 | |||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM lock | ||
9 | |||
10 | #ifdef CONFIG_LOCKDEP | ||
11 | |||
12 | TRACE_FORMAT(lock_acquire, | ||
13 | TP_PROTO(struct lockdep_map *lock, unsigned int subclass, | ||
14 | int trylock, int read, int check, | ||
15 | struct lockdep_map *next_lock, unsigned long ip), | ||
16 | TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), | ||
17 | TP_FMT("%s%s%s", trylock ? "try " : "", | ||
18 | read ? "read " : "", lock->name) | ||
19 | ); | ||
20 | |||
21 | TRACE_FORMAT(lock_release, | ||
22 | TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip), | ||
23 | TP_ARGS(lock, nested, ip), | ||
24 | TP_FMT("%s", lock->name) | ||
25 | ); | ||
26 | |||
27 | #ifdef CONFIG_LOCK_STAT | ||
28 | |||
29 | TRACE_FORMAT(lock_contended, | ||
30 | TP_PROTO(struct lockdep_map *lock, unsigned long ip), | ||
31 | TP_ARGS(lock, ip), | ||
32 | TP_FMT("%s", lock->name) | ||
33 | ); | ||
34 | |||
35 | TRACE_FORMAT(lock_acquired, | ||
36 | TP_PROTO(struct lockdep_map *lock, unsigned long ip), | ||
37 | TP_ARGS(lock, ip), | ||
38 | TP_FMT("%s", lock->name) | ||
39 | ); | ||
40 | |||
41 | #endif | ||
42 | #endif | ||
43 | |||
44 | #undef TRACE_SYSTEM | ||
diff --git a/include/trace/power.h b/include/trace/power.h new file mode 100644 index 000000000000..ef204666e983 --- /dev/null +++ b/include/trace/power.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef _TRACE_POWER_H | ||
2 | #define _TRACE_POWER_H | ||
3 | |||
4 | #include <linux/ktime.h> | ||
5 | #include <linux/tracepoint.h> | ||
6 | |||
7 | enum { | ||
8 | POWER_NONE = 0, | ||
9 | POWER_CSTATE = 1, | ||
10 | POWER_PSTATE = 2, | ||
11 | }; | ||
12 | |||
13 | struct power_trace { | ||
14 | ktime_t stamp; | ||
15 | ktime_t end; | ||
16 | int type; | ||
17 | int state; | ||
18 | }; | ||
19 | |||
20 | DECLARE_TRACE(power_start, | ||
21 | TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state), | ||
22 | TP_ARGS(it, type, state)); | ||
23 | |||
24 | DECLARE_TRACE(power_mark, | ||
25 | TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state), | ||
26 | TP_ARGS(it, type, state)); | ||
27 | |||
28 | DECLARE_TRACE(power_end, | ||
29 | TP_PROTO(struct power_trace *it), | ||
30 | TP_ARGS(it)); | ||
31 | |||
32 | #endif /* _TRACE_POWER_H */ | ||
diff --git a/include/trace/sched.h b/include/trace/sched.h index 0d81098ee9fc..4e372a1a29bf 100644 --- a/include/trace/sched.h +++ b/include/trace/sched.h | |||
@@ -4,53 +4,6 @@ | |||
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/tracepoint.h> | 5 | #include <linux/tracepoint.h> |
6 | 6 | ||
7 | DECLARE_TRACE(sched_kthread_stop, | 7 | #include <trace/sched_event_types.h> |
8 | TPPROTO(struct task_struct *t), | ||
9 | TPARGS(t)); | ||
10 | |||
11 | DECLARE_TRACE(sched_kthread_stop_ret, | ||
12 | TPPROTO(int ret), | ||
13 | TPARGS(ret)); | ||
14 | |||
15 | DECLARE_TRACE(sched_wait_task, | ||
16 | TPPROTO(struct rq *rq, struct task_struct *p), | ||
17 | TPARGS(rq, p)); | ||
18 | |||
19 | DECLARE_TRACE(sched_wakeup, | ||
20 | TPPROTO(struct rq *rq, struct task_struct *p, int success), | ||
21 | TPARGS(rq, p, success)); | ||
22 | |||
23 | DECLARE_TRACE(sched_wakeup_new, | ||
24 | TPPROTO(struct rq *rq, struct task_struct *p, int success), | ||
25 | TPARGS(rq, p, success)); | ||
26 | |||
27 | DECLARE_TRACE(sched_switch, | ||
28 | TPPROTO(struct rq *rq, struct task_struct *prev, | ||
29 | struct task_struct *next), | ||
30 | TPARGS(rq, prev, next)); | ||
31 | |||
32 | DECLARE_TRACE(sched_migrate_task, | ||
33 | TPPROTO(struct task_struct *p, int orig_cpu, int dest_cpu), | ||
34 | TPARGS(p, orig_cpu, dest_cpu)); | ||
35 | |||
36 | DECLARE_TRACE(sched_process_free, | ||
37 | TPPROTO(struct task_struct *p), | ||
38 | TPARGS(p)); | ||
39 | |||
40 | DECLARE_TRACE(sched_process_exit, | ||
41 | TPPROTO(struct task_struct *p), | ||
42 | TPARGS(p)); | ||
43 | |||
44 | DECLARE_TRACE(sched_process_wait, | ||
45 | TPPROTO(struct pid *pid), | ||
46 | TPARGS(pid)); | ||
47 | |||
48 | DECLARE_TRACE(sched_process_fork, | ||
49 | TPPROTO(struct task_struct *parent, struct task_struct *child), | ||
50 | TPARGS(parent, child)); | ||
51 | |||
52 | DECLARE_TRACE(sched_signal_send, | ||
53 | TPPROTO(int sig, struct task_struct *p), | ||
54 | TPARGS(sig, p)); | ||
55 | 8 | ||
56 | #endif | 9 | #endif |
diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h new file mode 100644 index 000000000000..63547dc1125f --- /dev/null +++ b/include/trace/sched_event_types.h | |||
@@ -0,0 +1,337 @@ | |||
1 | |||
2 | /* use <trace/sched.h> instead */ | ||
3 | #ifndef TRACE_EVENT | ||
4 | # error Do not include this file directly. | ||
5 | # error Unless you know what you are doing. | ||
6 | #endif | ||
7 | |||
8 | #undef TRACE_SYSTEM | ||
9 | #define TRACE_SYSTEM sched | ||
10 | |||
11 | /* | ||
12 | * Tracepoint for calling kthread_stop, performed to end a kthread: | ||
13 | */ | ||
14 | TRACE_EVENT(sched_kthread_stop, | ||
15 | |||
16 | TP_PROTO(struct task_struct *t), | ||
17 | |||
18 | TP_ARGS(t), | ||
19 | |||
20 | TP_STRUCT__entry( | ||
21 | __array( char, comm, TASK_COMM_LEN ) | ||
22 | __field( pid_t, pid ) | ||
23 | ), | ||
24 | |||
25 | TP_fast_assign( | ||
26 | memcpy(__entry->comm, t->comm, TASK_COMM_LEN); | ||
27 | __entry->pid = t->pid; | ||
28 | ), | ||
29 | |||
30 | TP_printk("task %s:%d", __entry->comm, __entry->pid) | ||
31 | ); | ||
32 | |||
33 | /* | ||
34 | * Tracepoint for the return value of the kthread stopping: | ||
35 | */ | ||
36 | TRACE_EVENT(sched_kthread_stop_ret, | ||
37 | |||
38 | TP_PROTO(int ret), | ||
39 | |||
40 | TP_ARGS(ret), | ||
41 | |||
42 | TP_STRUCT__entry( | ||
43 | __field( int, ret ) | ||
44 | ), | ||
45 | |||
46 | TP_fast_assign( | ||
47 | __entry->ret = ret; | ||
48 | ), | ||
49 | |||
50 | TP_printk("ret %d", __entry->ret) | ||
51 | ); | ||
52 | |||
53 | /* | ||
54 | * Tracepoint for waiting on task to unschedule: | ||
55 | * | ||
56 | * (NOTE: the 'rq' argument is not used by generic trace events, | ||
57 | * but used by the latency tracer plugin. ) | ||
58 | */ | ||
59 | TRACE_EVENT(sched_wait_task, | ||
60 | |||
61 | TP_PROTO(struct rq *rq, struct task_struct *p), | ||
62 | |||
63 | TP_ARGS(rq, p), | ||
64 | |||
65 | TP_STRUCT__entry( | ||
66 | __array( char, comm, TASK_COMM_LEN ) | ||
67 | __field( pid_t, pid ) | ||
68 | __field( int, prio ) | ||
69 | ), | ||
70 | |||
71 | TP_fast_assign( | ||
72 | memcpy(__entry->comm, p->comm, TASK_COMM_LEN); | ||
73 | __entry->pid = p->pid; | ||
74 | __entry->prio = p->prio; | ||
75 | ), | ||
76 | |||
77 | TP_printk("task %s:%d [%d]", | ||
78 | __entry->comm, __entry->pid, __entry->prio) | ||
79 | ); | ||
80 | |||
81 | /* | ||
82 | * Tracepoint for waking up a task: | ||
83 | * | ||
84 | * (NOTE: the 'rq' argument is not used by generic trace events, | ||
85 | * but used by the latency tracer plugin. ) | ||
86 | */ | ||
87 | TRACE_EVENT(sched_wakeup, | ||
88 | |||
89 | TP_PROTO(struct rq *rq, struct task_struct *p, int success), | ||
90 | |||
91 | TP_ARGS(rq, p, success), | ||
92 | |||
93 | TP_STRUCT__entry( | ||
94 | __array( char, comm, TASK_COMM_LEN ) | ||
95 | __field( pid_t, pid ) | ||
96 | __field( int, prio ) | ||
97 | __field( int, success ) | ||
98 | ), | ||
99 | |||
100 | TP_fast_assign( | ||
101 | memcpy(__entry->comm, p->comm, TASK_COMM_LEN); | ||
102 | __entry->pid = p->pid; | ||
103 | __entry->prio = p->prio; | ||
104 | __entry->success = success; | ||
105 | ), | ||
106 | |||
107 | TP_printk("task %s:%d [%d] success=%d", | ||
108 | __entry->comm, __entry->pid, __entry->prio, | ||
109 | __entry->success) | ||
110 | ); | ||
111 | |||
112 | /* | ||
113 | * Tracepoint for waking up a new task: | ||
114 | * | ||
115 | * (NOTE: the 'rq' argument is not used by generic trace events, | ||
116 | * but used by the latency tracer plugin. ) | ||
117 | */ | ||
118 | TRACE_EVENT(sched_wakeup_new, | ||
119 | |||
120 | TP_PROTO(struct rq *rq, struct task_struct *p, int success), | ||
121 | |||
122 | TP_ARGS(rq, p, success), | ||
123 | |||
124 | TP_STRUCT__entry( | ||
125 | __array( char, comm, TASK_COMM_LEN ) | ||
126 | __field( pid_t, pid ) | ||
127 | __field( int, prio ) | ||
128 | __field( int, success ) | ||
129 | ), | ||
130 | |||
131 | TP_fast_assign( | ||
132 | memcpy(__entry->comm, p->comm, TASK_COMM_LEN); | ||
133 | __entry->pid = p->pid; | ||
134 | __entry->prio = p->prio; | ||
135 | __entry->success = success; | ||
136 | ), | ||
137 | |||
138 | TP_printk("task %s:%d [%d] success=%d", | ||
139 | __entry->comm, __entry->pid, __entry->prio, | ||
140 | __entry->success) | ||
141 | ); | ||
142 | |||
143 | /* | ||
144 | * Tracepoint for task switches, performed by the scheduler: | ||
145 | * | ||
146 | * (NOTE: the 'rq' argument is not used by generic trace events, | ||
147 | * but used by the latency tracer plugin. ) | ||
148 | */ | ||
149 | TRACE_EVENT(sched_switch, | ||
150 | |||
151 | TP_PROTO(struct rq *rq, struct task_struct *prev, | ||
152 | struct task_struct *next), | ||
153 | |||
154 | TP_ARGS(rq, prev, next), | ||
155 | |||
156 | TP_STRUCT__entry( | ||
157 | __array( char, prev_comm, TASK_COMM_LEN ) | ||
158 | __field( pid_t, prev_pid ) | ||
159 | __field( int, prev_prio ) | ||
160 | __array( char, next_comm, TASK_COMM_LEN ) | ||
161 | __field( pid_t, next_pid ) | ||
162 | __field( int, next_prio ) | ||
163 | ), | ||
164 | |||
165 | TP_fast_assign( | ||
166 | memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); | ||
167 | __entry->prev_pid = prev->pid; | ||
168 | __entry->prev_prio = prev->prio; | ||
169 | memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); | ||
170 | __entry->next_pid = next->pid; | ||
171 | __entry->next_prio = next->prio; | ||
172 | ), | ||
173 | |||
174 | TP_printk("task %s:%d [%d] ==> %s:%d [%d]", | ||
175 | __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, | ||
176 | __entry->next_comm, __entry->next_pid, __entry->next_prio) | ||
177 | ); | ||
178 | |||
179 | /* | ||
180 | * Tracepoint for a task being migrated: | ||
181 | */ | ||
182 | TRACE_EVENT(sched_migrate_task, | ||
183 | |||
184 | TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu), | ||
185 | |||
186 | TP_ARGS(p, orig_cpu, dest_cpu), | ||
187 | |||
188 | TP_STRUCT__entry( | ||
189 | __array( char, comm, TASK_COMM_LEN ) | ||
190 | __field( pid_t, pid ) | ||
191 | __field( int, prio ) | ||
192 | __field( int, orig_cpu ) | ||
193 | __field( int, dest_cpu ) | ||
194 | ), | ||
195 | |||
196 | TP_fast_assign( | ||
197 | memcpy(__entry->comm, p->comm, TASK_COMM_LEN); | ||
198 | __entry->pid = p->pid; | ||
199 | __entry->prio = p->prio; | ||
200 | __entry->orig_cpu = orig_cpu; | ||
201 | __entry->dest_cpu = dest_cpu; | ||
202 | ), | ||
203 | |||
204 | TP_printk("task %s:%d [%d] from: %d to: %d", | ||
205 | __entry->comm, __entry->pid, __entry->prio, | ||
206 | __entry->orig_cpu, __entry->dest_cpu) | ||
207 | ); | ||
208 | |||
209 | /* | ||
210 | * Tracepoint for freeing a task: | ||
211 | */ | ||
212 | TRACE_EVENT(sched_process_free, | ||
213 | |||
214 | TP_PROTO(struct task_struct *p), | ||
215 | |||
216 | TP_ARGS(p), | ||
217 | |||
218 | TP_STRUCT__entry( | ||
219 | __array( char, comm, TASK_COMM_LEN ) | ||
220 | __field( pid_t, pid ) | ||
221 | __field( int, prio ) | ||
222 | ), | ||
223 | |||
224 | TP_fast_assign( | ||
225 | memcpy(__entry->comm, p->comm, TASK_COMM_LEN); | ||
226 | __entry->pid = p->pid; | ||
227 | __entry->prio = p->prio; | ||
228 | ), | ||
229 | |||
230 | TP_printk("task %s:%d [%d]", | ||
231 | __entry->comm, __entry->pid, __entry->prio) | ||
232 | ); | ||
233 | |||
234 | /* | ||
235 | * Tracepoint for a task exiting: | ||
236 | */ | ||
237 | TRACE_EVENT(sched_process_exit, | ||
238 | |||
239 | TP_PROTO(struct task_struct *p), | ||
240 | |||
241 | TP_ARGS(p), | ||
242 | |||
243 | TP_STRUCT__entry( | ||
244 | __array( char, comm, TASK_COMM_LEN ) | ||
245 | __field( pid_t, pid ) | ||
246 | __field( int, prio ) | ||
247 | ), | ||
248 | |||
249 | TP_fast_assign( | ||
250 | memcpy(__entry->comm, p->comm, TASK_COMM_LEN); | ||
251 | __entry->pid = p->pid; | ||
252 | __entry->prio = p->prio; | ||
253 | ), | ||
254 | |||
255 | TP_printk("task %s:%d [%d]", | ||
256 | __entry->comm, __entry->pid, __entry->prio) | ||
257 | ); | ||
258 | |||
259 | /* | ||
260 | * Tracepoint for a waiting task: | ||
261 | */ | ||
262 | TRACE_EVENT(sched_process_wait, | ||
263 | |||
264 | TP_PROTO(struct pid *pid), | ||
265 | |||
266 | TP_ARGS(pid), | ||
267 | |||
268 | TP_STRUCT__entry( | ||
269 | __array( char, comm, TASK_COMM_LEN ) | ||
270 | __field( pid_t, pid ) | ||
271 | __field( int, prio ) | ||
272 | ), | ||
273 | |||
274 | TP_fast_assign( | ||
275 | memcpy(__entry->comm, current->comm, TASK_COMM_LEN); | ||
276 | __entry->pid = pid_nr(pid); | ||
277 | __entry->prio = current->prio; | ||
278 | ), | ||
279 | |||
280 | TP_printk("task %s:%d [%d]", | ||
281 | __entry->comm, __entry->pid, __entry->prio) | ||
282 | ); | ||
283 | |||
284 | /* | ||
285 | * Tracepoint for do_fork: | ||
286 | */ | ||
287 | TRACE_EVENT(sched_process_fork, | ||
288 | |||
289 | TP_PROTO(struct task_struct *parent, struct task_struct *child), | ||
290 | |||
291 | TP_ARGS(parent, child), | ||
292 | |||
293 | TP_STRUCT__entry( | ||
294 | __array( char, parent_comm, TASK_COMM_LEN ) | ||
295 | __field( pid_t, parent_pid ) | ||
296 | __array( char, child_comm, TASK_COMM_LEN ) | ||
297 | __field( pid_t, child_pid ) | ||
298 | ), | ||
299 | |||
300 | TP_fast_assign( | ||
301 | memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN); | ||
302 | __entry->parent_pid = parent->pid; | ||
303 | memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN); | ||
304 | __entry->child_pid = child->pid; | ||
305 | ), | ||
306 | |||
307 | TP_printk("parent %s:%d child %s:%d", | ||
308 | __entry->parent_comm, __entry->parent_pid, | ||
309 | __entry->child_comm, __entry->child_pid) | ||
310 | ); | ||
311 | |||
312 | /* | ||
313 | * Tracepoint for sending a signal: | ||
314 | */ | ||
315 | TRACE_EVENT(sched_signal_send, | ||
316 | |||
317 | TP_PROTO(int sig, struct task_struct *p), | ||
318 | |||
319 | TP_ARGS(sig, p), | ||
320 | |||
321 | TP_STRUCT__entry( | ||
322 | __field( int, sig ) | ||
323 | __array( char, comm, TASK_COMM_LEN ) | ||
324 | __field( pid_t, pid ) | ||
325 | ), | ||
326 | |||
327 | TP_fast_assign( | ||
328 | memcpy(__entry->comm, p->comm, TASK_COMM_LEN); | ||
329 | __entry->pid = p->pid; | ||
330 | __entry->sig = sig; | ||
331 | ), | ||
332 | |||
333 | TP_printk("sig: %d task %s:%d", | ||
334 | __entry->sig, __entry->comm, __entry->pid) | ||
335 | ); | ||
336 | |||
337 | #undef TRACE_SYSTEM | ||
diff --git a/include/trace/trace_event_types.h b/include/trace/trace_event_types.h new file mode 100644 index 000000000000..df56f5694be6 --- /dev/null +++ b/include/trace/trace_event_types.h | |||
@@ -0,0 +1,5 @@ | |||
1 | /* trace/<type>_event_types.h here */ | ||
2 | |||
3 | #include <trace/sched_event_types.h> | ||
4 | #include <trace/irq_event_types.h> | ||
5 | #include <trace/lockdep_event_types.h> | ||
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h new file mode 100644 index 000000000000..fd13750ca4ba --- /dev/null +++ b/include/trace/trace_events.h | |||
@@ -0,0 +1,5 @@ | |||
1 | /* trace/<type>.h here */ | ||
2 | |||
3 | #include <trace/sched.h> | ||
4 | #include <trace/irq.h> | ||
5 | #include <trace/lockdep.h> | ||
diff --git a/include/trace/workqueue.h b/include/trace/workqueue.h new file mode 100644 index 000000000000..7626523deeba --- /dev/null +++ b/include/trace/workqueue.h | |||
@@ -0,0 +1,25 @@ | |||
1 | #ifndef __TRACE_WORKQUEUE_H | ||
2 | #define __TRACE_WORKQUEUE_H | ||
3 | |||
4 | #include <linux/tracepoint.h> | ||
5 | #include <linux/workqueue.h> | ||
6 | #include <linux/sched.h> | ||
7 | |||
8 | DECLARE_TRACE(workqueue_insertion, | ||
9 | TP_PROTO(struct task_struct *wq_thread, struct work_struct *work), | ||
10 | TP_ARGS(wq_thread, work)); | ||
11 | |||
12 | DECLARE_TRACE(workqueue_execution, | ||
13 | TP_PROTO(struct task_struct *wq_thread, struct work_struct *work), | ||
14 | TP_ARGS(wq_thread, work)); | ||
15 | |||
16 | /* Trace the creation of one workqueue thread on a cpu */ | ||
17 | DECLARE_TRACE(workqueue_creation, | ||
18 | TP_PROTO(struct task_struct *wq_thread, int cpu), | ||
19 | TP_ARGS(wq_thread, cpu)); | ||
20 | |||
21 | DECLARE_TRACE(workqueue_destruction, | ||
22 | TP_PROTO(struct task_struct *wq_thread), | ||
23 | TP_ARGS(wq_thread)); | ||
24 | |||
25 | #endif /* __TRACE_WORKQUEUE_H */ | ||