diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 21 | ||||
-rw-r--r-- | include/linux/compiler.h | 84 | ||||
-rw-r--r-- | include/linux/debug_locks.h | 2 | ||||
-rw-r--r-- | include/linux/ftrace.h | 146 | ||||
-rw-r--r-- | include/linux/ftrace_irq.h | 13 | ||||
-rw-r--r-- | include/linux/futex.h | 2 | ||||
-rw-r--r-- | include/linux/hardirq.h | 15 | ||||
-rw-r--r-- | include/linux/kernel.h | 11 | ||||
-rw-r--r-- | include/linux/lockdep.h | 31 | ||||
-rw-r--r-- | include/linux/marker.h | 69 | ||||
-rw-r--r-- | include/linux/mutex.h | 2 | ||||
-rw-r--r-- | include/linux/rcuclassic.h | 2 | ||||
-rw-r--r-- | include/linux/rcupdate.h | 2 | ||||
-rw-r--r-- | include/linux/ring_buffer.h | 1 | ||||
-rw-r--r-- | include/linux/sched.h | 11 | ||||
-rw-r--r-- | include/linux/seq_file.h | 1 | ||||
-rw-r--r-- | include/linux/stacktrace.h | 8 | ||||
-rw-r--r-- | include/linux/tracepoint.h | 57 | ||||
-rw-r--r-- | include/linux/uaccess.h | 2 | ||||
-rw-r--r-- | include/trace/boot.h | 56 | ||||
-rw-r--r-- | include/trace/sched.h | 24 |
21 files changed, 480 insertions, 80 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 80744606bad1..eba835a2c2cd 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -45,6 +45,22 @@ | |||
45 | #define MCOUNT_REC() | 45 | #define MCOUNT_REC() |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | #ifdef CONFIG_TRACE_BRANCH_PROFILING | ||
49 | #define LIKELY_PROFILE() VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \ | ||
50 | *(_ftrace_annotated_branch) \ | ||
51 | VMLINUX_SYMBOL(__stop_annotated_branch_profile) = .; | ||
52 | #else | ||
53 | #define LIKELY_PROFILE() | ||
54 | #endif | ||
55 | |||
56 | #ifdef CONFIG_PROFILE_ALL_BRANCHES | ||
57 | #define BRANCH_PROFILE() VMLINUX_SYMBOL(__start_branch_profile) = .; \ | ||
58 | *(_ftrace_branch) \ | ||
59 | VMLINUX_SYMBOL(__stop_branch_profile) = .; | ||
60 | #else | ||
61 | #define BRANCH_PROFILE() | ||
62 | #endif | ||
63 | |||
48 | /* .data section */ | 64 | /* .data section */ |
49 | #define DATA_DATA \ | 65 | #define DATA_DATA \ |
50 | *(.data) \ | 66 | *(.data) \ |
@@ -60,9 +76,12 @@ | |||
60 | VMLINUX_SYMBOL(__start___markers) = .; \ | 76 | VMLINUX_SYMBOL(__start___markers) = .; \ |
61 | *(__markers) \ | 77 | *(__markers) \ |
62 | VMLINUX_SYMBOL(__stop___markers) = .; \ | 78 | VMLINUX_SYMBOL(__stop___markers) = .; \ |
79 | . = ALIGN(32); \ | ||
63 | VMLINUX_SYMBOL(__start___tracepoints) = .; \ | 80 | VMLINUX_SYMBOL(__start___tracepoints) = .; \ |
64 | *(__tracepoints) \ | 81 | *(__tracepoints) \ |
65 | VMLINUX_SYMBOL(__stop___tracepoints) = .; | 82 | VMLINUX_SYMBOL(__stop___tracepoints) = .; \ |
83 | LIKELY_PROFILE() \ | ||
84 | BRANCH_PROFILE() | ||
66 | 85 | ||
67 | #define RO_DATA(align) \ | 86 | #define RO_DATA(align) \ |
68 | . = ALIGN((align)); \ | 87 | . = ALIGN((align)); \ |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 98115d9d04da..ea7c6be354b7 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -59,8 +59,88 @@ extern void __chk_io_ptr(const volatile void __iomem *); | |||
59 | * specific implementations come from the above header files | 59 | * specific implementations come from the above header files |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #define likely(x) __builtin_expect(!!(x), 1) | 62 | struct ftrace_branch_data { |
63 | #define unlikely(x) __builtin_expect(!!(x), 0) | 63 | const char *func; |
64 | const char *file; | ||
65 | unsigned line; | ||
66 | union { | ||
67 | struct { | ||
68 | unsigned long correct; | ||
69 | unsigned long incorrect; | ||
70 | }; | ||
71 | struct { | ||
72 | unsigned long miss; | ||
73 | unsigned long hit; | ||
74 | }; | ||
75 | }; | ||
76 | }; | ||
77 | |||
78 | /* | ||
79 | * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code | ||
80 | * to disable branch tracing on a per file basis. | ||
81 | */ | ||
82 | #if defined(CONFIG_TRACE_BRANCH_PROFILING) && !defined(DISABLE_BRANCH_PROFILING) | ||
83 | void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); | ||
84 | |||
85 | #define likely_notrace(x) __builtin_expect(!!(x), 1) | ||
86 | #define unlikely_notrace(x) __builtin_expect(!!(x), 0) | ||
87 | |||
88 | #define __branch_check__(x, expect) ({ \ | ||
89 | int ______r; \ | ||
90 | static struct ftrace_branch_data \ | ||
91 | __attribute__((__aligned__(4))) \ | ||
92 | __attribute__((section("_ftrace_annotated_branch"))) \ | ||
93 | ______f = { \ | ||
94 | .func = __func__, \ | ||
95 | .file = __FILE__, \ | ||
96 | .line = __LINE__, \ | ||
97 | }; \ | ||
98 | ______r = likely_notrace(x); \ | ||
99 | ftrace_likely_update(&______f, ______r, expect); \ | ||
100 | ______r; \ | ||
101 | }) | ||
102 | |||
103 | /* | ||
104 | * Using __builtin_constant_p(x) to ignore cases where the return | ||
105 | * value is always the same. This idea is taken from a similar patch | ||
106 | * written by Daniel Walker. | ||
107 | */ | ||
108 | # ifndef likely | ||
109 | # define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1)) | ||
110 | # endif | ||
111 | # ifndef unlikely | ||
112 | # define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0)) | ||
113 | # endif | ||
114 | |||
115 | #ifdef CONFIG_PROFILE_ALL_BRANCHES | ||
116 | /* | ||
117 | * "Define 'is'", Bill Clinton | ||
118 | * "Define 'if'", Steven Rostedt | ||
119 | */ | ||
120 | #define if(cond) if (__builtin_constant_p((cond)) ? !!(cond) : \ | ||
121 | ({ \ | ||
122 | int ______r; \ | ||
123 | static struct ftrace_branch_data \ | ||
124 | __attribute__((__aligned__(4))) \ | ||
125 | __attribute__((section("_ftrace_branch"))) \ | ||
126 | ______f = { \ | ||
127 | .func = __func__, \ | ||
128 | .file = __FILE__, \ | ||
129 | .line = __LINE__, \ | ||
130 | }; \ | ||
131 | ______r = !!(cond); \ | ||
132 | if (______r) \ | ||
133 | ______f.hit++; \ | ||
134 | else \ | ||
135 | ______f.miss++; \ | ||
136 | ______r; \ | ||
137 | })) | ||
138 | #endif /* CONFIG_PROFILE_ALL_BRANCHES */ | ||
139 | |||
140 | #else | ||
141 | # define likely(x) __builtin_expect(!!(x), 1) | ||
142 | # define unlikely(x) __builtin_expect(!!(x), 0) | ||
143 | #endif | ||
64 | 144 | ||
65 | /* Optimization barrier */ | 145 | /* Optimization barrier */ |
66 | #ifndef barrier | 146 | #ifndef barrier |
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h index 4aaa4afb1cb9..096476f1fb35 100644 --- a/include/linux/debug_locks.h +++ b/include/linux/debug_locks.h | |||
@@ -17,7 +17,7 @@ extern int debug_locks_off(void); | |||
17 | ({ \ | 17 | ({ \ |
18 | int __ret = 0; \ | 18 | int __ret = 0; \ |
19 | \ | 19 | \ |
20 | if (unlikely(c)) { \ | 20 | if (!oops_in_progress && unlikely(c)) { \ |
21 | if (debug_locks_off() && !debug_locks_silent) \ | 21 | if (debug_locks_off() && !debug_locks_silent) \ |
22 | WARN_ON(1); \ | 22 | WARN_ON(1); \ |
23 | __ret = 1; \ | 23 | __ret = 1; \ |
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 703eb53cfa2b..7854d87b97b2 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
@@ -23,6 +23,45 @@ struct ftrace_ops { | |||
23 | struct ftrace_ops *next; | 23 | struct ftrace_ops *next; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | extern int function_trace_stop; | ||
27 | |||
28 | /* | ||
29 | * Type of the current tracing. | ||
30 | */ | ||
31 | enum ftrace_tracing_type_t { | ||
32 | FTRACE_TYPE_ENTER = 0, /* Hook the call of the function */ | ||
33 | FTRACE_TYPE_RETURN, /* Hook the return of the function */ | ||
34 | }; | ||
35 | |||
36 | /* Current tracing type, default is FTRACE_TYPE_ENTER */ | ||
37 | extern enum ftrace_tracing_type_t ftrace_tracing_type; | ||
38 | |||
39 | /** | ||
40 | * ftrace_stop - stop function tracer. | ||
41 | * | ||
42 | * A quick way to stop the function tracer. Note this an on off switch, | ||
43 | * it is not something that is recursive like preempt_disable. | ||
44 | * This does not disable the calling of mcount, it only stops the | ||
45 | * calling of functions from mcount. | ||
46 | */ | ||
47 | static inline void ftrace_stop(void) | ||
48 | { | ||
49 | function_trace_stop = 1; | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * ftrace_start - start the function tracer. | ||
54 | * | ||
55 | * This function is the inverse of ftrace_stop. This does not enable | ||
56 | * the function tracing if the function tracer is disabled. This only | ||
57 | * sets the function tracer flag to continue calling the functions | ||
58 | * from mcount. | ||
59 | */ | ||
60 | static inline void ftrace_start(void) | ||
61 | { | ||
62 | function_trace_stop = 0; | ||
63 | } | ||
64 | |||
26 | /* | 65 | /* |
27 | * The ftrace_ops must be a static and should also | 66 | * The ftrace_ops must be a static and should also |
28 | * be read_mostly. These functions do modify read_mostly variables | 67 | * be read_mostly. These functions do modify read_mostly variables |
@@ -41,9 +80,13 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1); | |||
41 | # define unregister_ftrace_function(ops) do { } while (0) | 80 | # define unregister_ftrace_function(ops) do { } while (0) |
42 | # define clear_ftrace_function(ops) do { } while (0) | 81 | # define clear_ftrace_function(ops) do { } while (0) |
43 | static inline void ftrace_kill(void) { } | 82 | static inline void ftrace_kill(void) { } |
83 | static inline void ftrace_stop(void) { } | ||
84 | static inline void ftrace_start(void) { } | ||
44 | #endif /* CONFIG_FUNCTION_TRACER */ | 85 | #endif /* CONFIG_FUNCTION_TRACER */ |
45 | 86 | ||
46 | #ifdef CONFIG_DYNAMIC_FTRACE | 87 | #ifdef CONFIG_DYNAMIC_FTRACE |
88 | /* asm/ftrace.h must be defined for archs supporting dynamic ftrace */ | ||
89 | #include <asm/ftrace.h> | ||
47 | 90 | ||
48 | enum { | 91 | enum { |
49 | FTRACE_FL_FREE = (1 << 0), | 92 | FTRACE_FL_FREE = (1 << 0), |
@@ -59,6 +102,7 @@ struct dyn_ftrace { | |||
59 | struct list_head list; | 102 | struct list_head list; |
60 | unsigned long ip; /* address of mcount call-site */ | 103 | unsigned long ip; /* address of mcount call-site */ |
61 | unsigned long flags; | 104 | unsigned long flags; |
105 | struct dyn_arch_ftrace arch; | ||
62 | }; | 106 | }; |
63 | 107 | ||
64 | int ftrace_force_update(void); | 108 | int ftrace_force_update(void); |
@@ -66,19 +110,43 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset); | |||
66 | 110 | ||
67 | /* defined in arch */ | 111 | /* defined in arch */ |
68 | extern int ftrace_ip_converted(unsigned long ip); | 112 | extern int ftrace_ip_converted(unsigned long ip); |
69 | extern unsigned char *ftrace_nop_replace(void); | ||
70 | extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); | ||
71 | extern int ftrace_dyn_arch_init(void *data); | 113 | extern int ftrace_dyn_arch_init(void *data); |
72 | extern int ftrace_update_ftrace_func(ftrace_func_t func); | 114 | extern int ftrace_update_ftrace_func(ftrace_func_t func); |
73 | extern void ftrace_caller(void); | 115 | extern void ftrace_caller(void); |
74 | extern void ftrace_call(void); | 116 | extern void ftrace_call(void); |
75 | extern void mcount_call(void); | 117 | extern void mcount_call(void); |
118 | #ifdef CONFIG_FUNCTION_RET_TRACER | ||
119 | extern void ftrace_return_caller(void); | ||
120 | #endif | ||
121 | |||
122 | /** | ||
123 | * ftrace_make_nop - convert code into top | ||
124 | * @mod: module structure if called by module load initialization | ||
125 | * @rec: the mcount call site record | ||
126 | * @addr: the address that the call site should be calling | ||
127 | * | ||
128 | * This is a very sensitive operation and great care needs | ||
129 | * to be taken by the arch. The operation should carefully | ||
130 | * read the location, check to see if what is read is indeed | ||
131 | * what we expect it to be, and then on success of the compare, | ||
132 | * it should write to the location. | ||
133 | * | ||
134 | * The code segment at @rec->ip should be a caller to @addr | ||
135 | * | ||
136 | * Return must be: | ||
137 | * 0 on success | ||
138 | * -EFAULT on error reading the location | ||
139 | * -EINVAL on a failed compare of the contents | ||
140 | * -EPERM on error writing to the location | ||
141 | * Any other value will be considered a failure. | ||
142 | */ | ||
143 | extern int ftrace_make_nop(struct module *mod, | ||
144 | struct dyn_ftrace *rec, unsigned long addr); | ||
76 | 145 | ||
77 | /** | 146 | /** |
78 | * ftrace_modify_code - modify code segment | 147 | * ftrace_make_call - convert a nop call site into a call to addr |
79 | * @ip: the address of the code segment | 148 | * @rec: the mcount call site record |
80 | * @old_code: the contents of what is expected to be there | 149 | * @addr: the address that the call site should call |
81 | * @new_code: the code to patch in | ||
82 | * | 150 | * |
83 | * This is a very sensitive operation and great care needs | 151 | * This is a very sensitive operation and great care needs |
84 | * to be taken by the arch. The operation should carefully | 152 | * to be taken by the arch. The operation should carefully |
@@ -86,6 +154,8 @@ extern void mcount_call(void); | |||
86 | * what we expect it to be, and then on success of the compare, | 154 | * what we expect it to be, and then on success of the compare, |
87 | * it should write to the location. | 155 | * it should write to the location. |
88 | * | 156 | * |
157 | * The code segment at @rec->ip should be a nop | ||
158 | * | ||
89 | * Return must be: | 159 | * Return must be: |
90 | * 0 on success | 160 | * 0 on success |
91 | * -EFAULT on error reading the location | 161 | * -EFAULT on error reading the location |
@@ -93,8 +163,11 @@ extern void mcount_call(void); | |||
93 | * -EPERM on error writing to the location | 163 | * -EPERM on error writing to the location |
94 | * Any other value will be considered a failure. | 164 | * Any other value will be considered a failure. |
95 | */ | 165 | */ |
96 | extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, | 166 | extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr); |
97 | unsigned char *new_code); | 167 | |
168 | |||
169 | /* May be defined in arch */ | ||
170 | extern int ftrace_arch_read_dyn_info(char *buf, int size); | ||
98 | 171 | ||
99 | extern int skip_trace(unsigned long ip); | 172 | extern int skip_trace(unsigned long ip); |
100 | 173 | ||
@@ -102,7 +175,6 @@ extern void ftrace_release(void *start, unsigned long size); | |||
102 | 175 | ||
103 | extern void ftrace_disable_daemon(void); | 176 | extern void ftrace_disable_daemon(void); |
104 | extern void ftrace_enable_daemon(void); | 177 | extern void ftrace_enable_daemon(void); |
105 | |||
106 | #else | 178 | #else |
107 | # define skip_trace(ip) ({ 0; }) | 179 | # define skip_trace(ip) ({ 0; }) |
108 | # define ftrace_force_update() ({ 0; }) | 180 | # define ftrace_force_update() ({ 0; }) |
@@ -181,6 +253,12 @@ static inline void __ftrace_enabled_restore(int enabled) | |||
181 | #endif | 253 | #endif |
182 | 254 | ||
183 | #ifdef CONFIG_TRACING | 255 | #ifdef CONFIG_TRACING |
256 | extern int ftrace_dump_on_oops; | ||
257 | |||
258 | extern void tracing_start(void); | ||
259 | extern void tracing_stop(void); | ||
260 | extern void ftrace_off_permanent(void); | ||
261 | |||
184 | extern void | 262 | extern void |
185 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | 263 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); |
186 | 264 | ||
@@ -211,6 +289,9 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } | |||
211 | static inline int | 289 | static inline int |
212 | ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))); | 290 | ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))); |
213 | 291 | ||
292 | static inline void tracing_start(void) { } | ||
293 | static inline void tracing_stop(void) { } | ||
294 | static inline void ftrace_off_permanent(void) { } | ||
214 | static inline int | 295 | static inline int |
215 | ftrace_printk(const char *fmt, ...) | 296 | ftrace_printk(const char *fmt, ...) |
216 | { | 297 | { |
@@ -221,33 +302,44 @@ static inline void ftrace_dump(void) { } | |||
221 | 302 | ||
222 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 303 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
223 | extern void ftrace_init(void); | 304 | extern void ftrace_init(void); |
224 | extern void ftrace_init_module(unsigned long *start, unsigned long *end); | 305 | extern void ftrace_init_module(struct module *mod, |
306 | unsigned long *start, unsigned long *end); | ||
225 | #else | 307 | #else |
226 | static inline void ftrace_init(void) { } | 308 | static inline void ftrace_init(void) { } |
227 | static inline void | 309 | static inline void |
228 | ftrace_init_module(unsigned long *start, unsigned long *end) { } | 310 | ftrace_init_module(struct module *mod, |
311 | unsigned long *start, unsigned long *end) { } | ||
229 | #endif | 312 | #endif |
230 | 313 | ||
231 | 314 | ||
232 | struct boot_trace { | 315 | /* |
233 | pid_t caller; | 316 | * Structure that defines a return function trace. |
234 | char func[KSYM_NAME_LEN]; | 317 | */ |
235 | int result; | 318 | struct ftrace_retfunc { |
236 | unsigned long long duration; /* usecs */ | 319 | unsigned long ret; /* Return address */ |
237 | ktime_t calltime; | 320 | unsigned long func; /* Current function */ |
238 | ktime_t rettime; | 321 | unsigned long long calltime; |
322 | unsigned long long rettime; | ||
323 | /* Number of functions that overran the depth limit for current task */ | ||
324 | unsigned long overrun; | ||
239 | }; | 325 | }; |
240 | 326 | ||
241 | #ifdef CONFIG_BOOT_TRACER | 327 | #ifdef CONFIG_FUNCTION_RET_TRACER |
242 | extern void trace_boot(struct boot_trace *it, initcall_t fn); | 328 | #define FTRACE_RETFUNC_DEPTH 50 |
243 | extern void start_boot_trace(void); | 329 | #define FTRACE_RETSTACK_ALLOC_SIZE 32 |
244 | extern void stop_boot_trace(void); | 330 | /* Type of a callback handler of tracing return function */ |
245 | #else | 331 | typedef void (*trace_function_return_t)(struct ftrace_retfunc *); |
246 | static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } | ||
247 | static inline void start_boot_trace(void) { } | ||
248 | static inline void stop_boot_trace(void) { } | ||
249 | #endif | ||
250 | 332 | ||
333 | extern int register_ftrace_return(trace_function_return_t func); | ||
334 | /* The current handler in use */ | ||
335 | extern trace_function_return_t ftrace_function_return; | ||
336 | extern void unregister_ftrace_return(void); | ||
251 | 337 | ||
338 | extern void ftrace_retfunc_init_task(struct task_struct *t); | ||
339 | extern void ftrace_retfunc_exit_task(struct task_struct *t); | ||
340 | #else | ||
341 | static inline void ftrace_retfunc_init_task(struct task_struct *t) { } | ||
342 | static inline void ftrace_retfunc_exit_task(struct task_struct *t) { } | ||
343 | #endif | ||
252 | 344 | ||
253 | #endif /* _LINUX_FTRACE_H */ | 345 | #endif /* _LINUX_FTRACE_H */ |
diff --git a/include/linux/ftrace_irq.h b/include/linux/ftrace_irq.h new file mode 100644 index 000000000000..0b4df55d7a74 --- /dev/null +++ b/include/linux/ftrace_irq.h | |||
@@ -0,0 +1,13 @@ | |||
1 | #ifndef _LINUX_FTRACE_IRQ_H | ||
2 | #define _LINUX_FTRACE_IRQ_H | ||
3 | |||
4 | |||
5 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_FUNCTION_RET_TRACER) | ||
6 | extern void ftrace_nmi_enter(void); | ||
7 | extern void ftrace_nmi_exit(void); | ||
8 | #else | ||
9 | static inline void ftrace_nmi_enter(void) { } | ||
10 | static inline void ftrace_nmi_exit(void) { } | ||
11 | #endif | ||
12 | |||
13 | #endif /* _LINUX_FTRACE_IRQ_H */ | ||
diff --git a/include/linux/futex.h b/include/linux/futex.h index 586ab56a3ec3..8f627b9ae2b1 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h | |||
@@ -164,6 +164,8 @@ union futex_key { | |||
164 | } both; | 164 | } both; |
165 | }; | 165 | }; |
166 | 166 | ||
167 | #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = NULL } } | ||
168 | |||
167 | #ifdef CONFIG_FUTEX | 169 | #ifdef CONFIG_FUTEX |
168 | extern void exit_robust_list(struct task_struct *curr); | 170 | extern void exit_robust_list(struct task_struct *curr); |
169 | extern void exit_pi_state_list(struct task_struct *curr); | 171 | extern void exit_pi_state_list(struct task_struct *curr); |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 181006cc94a0..89a56d79e4c6 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/preempt.h> | 4 | #include <linux/preempt.h> |
5 | #include <linux/smp_lock.h> | 5 | #include <linux/smp_lock.h> |
6 | #include <linux/lockdep.h> | 6 | #include <linux/lockdep.h> |
7 | #include <linux/ftrace_irq.h> | ||
7 | #include <asm/hardirq.h> | 8 | #include <asm/hardirq.h> |
8 | #include <asm/system.h> | 9 | #include <asm/system.h> |
9 | 10 | ||
@@ -161,7 +162,17 @@ extern void irq_enter(void); | |||
161 | */ | 162 | */ |
162 | extern void irq_exit(void); | 163 | extern void irq_exit(void); |
163 | 164 | ||
164 | #define nmi_enter() do { lockdep_off(); __irq_enter(); } while (0) | 165 | #define nmi_enter() \ |
165 | #define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) | 166 | do { \ |
167 | ftrace_nmi_enter(); \ | ||
168 | lockdep_off(); \ | ||
169 | __irq_enter(); \ | ||
170 | } while (0) | ||
171 | #define nmi_exit() \ | ||
172 | do { \ | ||
173 | __irq_exit(); \ | ||
174 | lockdep_on(); \ | ||
175 | ftrace_nmi_exit(); \ | ||
176 | } while (0) | ||
166 | 177 | ||
167 | #endif /* LINUX_HARDIRQ_H */ | 178 | #endif /* LINUX_HARDIRQ_H */ |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index dc7e0d0a6474..269df5a17b30 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -141,6 +141,15 @@ extern int _cond_resched(void); | |||
141 | (__x < 0) ? -__x : __x; \ | 141 | (__x < 0) ? -__x : __x; \ |
142 | }) | 142 | }) |
143 | 143 | ||
144 | #ifdef CONFIG_PROVE_LOCKING | ||
145 | void might_fault(void); | ||
146 | #else | ||
147 | static inline void might_fault(void) | ||
148 | { | ||
149 | might_sleep(); | ||
150 | } | ||
151 | #endif | ||
152 | |||
144 | extern struct atomic_notifier_head panic_notifier_list; | 153 | extern struct atomic_notifier_head panic_notifier_list; |
145 | extern long (*panic_blink)(long time); | 154 | extern long (*panic_blink)(long time); |
146 | NORET_TYPE void panic(const char * fmt, ...) | 155 | NORET_TYPE void panic(const char * fmt, ...) |
@@ -188,6 +197,8 @@ extern unsigned long long memparse(const char *ptr, char **retptr); | |||
188 | extern int core_kernel_text(unsigned long addr); | 197 | extern int core_kernel_text(unsigned long addr); |
189 | extern int __kernel_text_address(unsigned long addr); | 198 | extern int __kernel_text_address(unsigned long addr); |
190 | extern int kernel_text_address(unsigned long addr); | 199 | extern int kernel_text_address(unsigned long addr); |
200 | extern int func_ptr_is_kernel_text(void *ptr); | ||
201 | |||
191 | struct pid; | 202 | struct pid; |
192 | extern struct pid *session_of_pgrp(struct pid *pgrp); | 203 | extern struct pid *session_of_pgrp(struct pid *pgrp); |
193 | 204 | ||
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 29aec6e10020..8956daf64abd 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h | |||
@@ -73,6 +73,8 @@ struct lock_class_key { | |||
73 | struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES]; | 73 | struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES]; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | #define LOCKSTAT_POINTS 4 | ||
77 | |||
76 | /* | 78 | /* |
77 | * The lock-class itself: | 79 | * The lock-class itself: |
78 | */ | 80 | */ |
@@ -119,7 +121,8 @@ struct lock_class { | |||
119 | int name_version; | 121 | int name_version; |
120 | 122 | ||
121 | #ifdef CONFIG_LOCK_STAT | 123 | #ifdef CONFIG_LOCK_STAT |
122 | unsigned long contention_point[4]; | 124 | unsigned long contention_point[LOCKSTAT_POINTS]; |
125 | unsigned long contending_point[LOCKSTAT_POINTS]; | ||
123 | #endif | 126 | #endif |
124 | }; | 127 | }; |
125 | 128 | ||
@@ -144,6 +147,7 @@ enum bounce_type { | |||
144 | 147 | ||
145 | struct lock_class_stats { | 148 | struct lock_class_stats { |
146 | unsigned long contention_point[4]; | 149 | unsigned long contention_point[4]; |
150 | unsigned long contending_point[4]; | ||
147 | struct lock_time read_waittime; | 151 | struct lock_time read_waittime; |
148 | struct lock_time write_waittime; | 152 | struct lock_time write_waittime; |
149 | struct lock_time read_holdtime; | 153 | struct lock_time read_holdtime; |
@@ -165,6 +169,7 @@ struct lockdep_map { | |||
165 | const char *name; | 169 | const char *name; |
166 | #ifdef CONFIG_LOCK_STAT | 170 | #ifdef CONFIG_LOCK_STAT |
167 | int cpu; | 171 | int cpu; |
172 | unsigned long ip; | ||
168 | #endif | 173 | #endif |
169 | }; | 174 | }; |
170 | 175 | ||
@@ -356,7 +361,7 @@ struct lock_class_key { }; | |||
356 | #ifdef CONFIG_LOCK_STAT | 361 | #ifdef CONFIG_LOCK_STAT |
357 | 362 | ||
358 | extern void lock_contended(struct lockdep_map *lock, unsigned long ip); | 363 | extern void lock_contended(struct lockdep_map *lock, unsigned long ip); |
359 | extern void lock_acquired(struct lockdep_map *lock); | 364 | extern void lock_acquired(struct lockdep_map *lock, unsigned long ip); |
360 | 365 | ||
361 | #define LOCK_CONTENDED(_lock, try, lock) \ | 366 | #define LOCK_CONTENDED(_lock, try, lock) \ |
362 | do { \ | 367 | do { \ |
@@ -364,13 +369,13 @@ do { \ | |||
364 | lock_contended(&(_lock)->dep_map, _RET_IP_); \ | 369 | lock_contended(&(_lock)->dep_map, _RET_IP_); \ |
365 | lock(_lock); \ | 370 | lock(_lock); \ |
366 | } \ | 371 | } \ |
367 | lock_acquired(&(_lock)->dep_map); \ | 372 | lock_acquired(&(_lock)->dep_map, _RET_IP_); \ |
368 | } while (0) | 373 | } while (0) |
369 | 374 | ||
370 | #else /* CONFIG_LOCK_STAT */ | 375 | #else /* CONFIG_LOCK_STAT */ |
371 | 376 | ||
372 | #define lock_contended(lockdep_map, ip) do {} while (0) | 377 | #define lock_contended(lockdep_map, ip) do {} while (0) |
373 | #define lock_acquired(lockdep_map) do {} while (0) | 378 | #define lock_acquired(lockdep_map, ip) do {} while (0) |
374 | 379 | ||
375 | #define LOCK_CONTENDED(_lock, try, lock) \ | 380 | #define LOCK_CONTENDED(_lock, try, lock) \ |
376 | lock(_lock) | 381 | lock(_lock) |
@@ -481,4 +486,22 @@ static inline void print_irqtrace_events(struct task_struct *curr) | |||
481 | # define lock_map_release(l) do { } while (0) | 486 | # define lock_map_release(l) do { } while (0) |
482 | #endif | 487 | #endif |
483 | 488 | ||
489 | #ifdef CONFIG_PROVE_LOCKING | ||
490 | # define might_lock(lock) \ | ||
491 | do { \ | ||
492 | typecheck(struct lockdep_map *, &(lock)->dep_map); \ | ||
493 | lock_acquire(&(lock)->dep_map, 0, 0, 0, 2, NULL, _THIS_IP_); \ | ||
494 | lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ | ||
495 | } while (0) | ||
496 | # define might_lock_read(lock) \ | ||
497 | do { \ | ||
498 | typecheck(struct lockdep_map *, &(lock)->dep_map); \ | ||
499 | lock_acquire(&(lock)->dep_map, 0, 0, 1, 2, NULL, _THIS_IP_); \ | ||
500 | lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ | ||
501 | } while (0) | ||
502 | #else | ||
503 | # define might_lock(lock) do { } while (0) | ||
504 | # define might_lock_read(lock) do { } while (0) | ||
505 | #endif | ||
506 | |||
484 | #endif /* __LINUX_LOCKDEP_H */ | 507 | #endif /* __LINUX_LOCKDEP_H */ |
diff --git a/include/linux/marker.h b/include/linux/marker.h index 889196c7fbb1..34c14bc957f5 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h | |||
@@ -12,6 +12,7 @@ | |||
12 | * See the file COPYING for more details. | 12 | * See the file COPYING for more details. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <stdarg.h> | ||
15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
16 | 17 | ||
17 | struct module; | 18 | struct module; |
@@ -48,10 +49,28 @@ struct marker { | |||
48 | void (*call)(const struct marker *mdata, void *call_private, ...); | 49 | void (*call)(const struct marker *mdata, void *call_private, ...); |
49 | struct marker_probe_closure single; | 50 | struct marker_probe_closure single; |
50 | struct marker_probe_closure *multi; | 51 | struct marker_probe_closure *multi; |
52 | const char *tp_name; /* Optional tracepoint name */ | ||
53 | void *tp_cb; /* Optional tracepoint callback */ | ||
51 | } __attribute__((aligned(8))); | 54 | } __attribute__((aligned(8))); |
52 | 55 | ||
53 | #ifdef CONFIG_MARKERS | 56 | #ifdef CONFIG_MARKERS |
54 | 57 | ||
58 | #define _DEFINE_MARKER(name, tp_name_str, tp_cb, format) \ | ||
59 | static const char __mstrtab_##name[] \ | ||
60 | __attribute__((section("__markers_strings"))) \ | ||
61 | = #name "\0" format; \ | ||
62 | static struct marker __mark_##name \ | ||
63 | __attribute__((section("__markers"), aligned(8))) = \ | ||
64 | { __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \ | ||
65 | 0, 0, marker_probe_cb, { __mark_empty_function, NULL},\ | ||
66 | NULL, tp_name_str, tp_cb } | ||
67 | |||
68 | #define DEFINE_MARKER(name, format) \ | ||
69 | _DEFINE_MARKER(name, NULL, NULL, format) | ||
70 | |||
71 | #define DEFINE_MARKER_TP(name, tp_name, tp_cb, format) \ | ||
72 | _DEFINE_MARKER(name, #tp_name, tp_cb, format) | ||
73 | |||
55 | /* | 74 | /* |
56 | * Note : the empty asm volatile with read constraint is used here instead of a | 75 | * Note : the empty asm volatile with read constraint is used here instead of a |
57 | * "used" attribute to fix a gcc 4.1.x bug. | 76 | * "used" attribute to fix a gcc 4.1.x bug. |
@@ -65,14 +84,7 @@ struct marker { | |||
65 | */ | 84 | */ |
66 | #define __trace_mark(generic, name, call_private, format, args...) \ | 85 | #define __trace_mark(generic, name, call_private, format, args...) \ |
67 | do { \ | 86 | do { \ |
68 | static const char __mstrtab_##name[] \ | 87 | DEFINE_MARKER(name, format); \ |
69 | __attribute__((section("__markers_strings"))) \ | ||
70 | = #name "\0" format; \ | ||
71 | static struct marker __mark_##name \ | ||
72 | __attribute__((section("__markers"), aligned(8))) = \ | ||
73 | { __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \ | ||
74 | 0, 0, marker_probe_cb, \ | ||
75 | { __mark_empty_function, NULL}, NULL }; \ | ||
76 | __mark_check_format(format, ## args); \ | 88 | __mark_check_format(format, ## args); \ |
77 | if (unlikely(__mark_##name.state)) { \ | 89 | if (unlikely(__mark_##name.state)) { \ |
78 | (*__mark_##name.call) \ | 90 | (*__mark_##name.call) \ |
@@ -80,14 +92,39 @@ struct marker { | |||
80 | } \ | 92 | } \ |
81 | } while (0) | 93 | } while (0) |
82 | 94 | ||
95 | #define __trace_mark_tp(name, call_private, tp_name, tp_cb, format, args...) \ | ||
96 | do { \ | ||
97 | void __check_tp_type(void) \ | ||
98 | { \ | ||
99 | register_trace_##tp_name(tp_cb); \ | ||
100 | } \ | ||
101 | DEFINE_MARKER_TP(name, tp_name, tp_cb, format); \ | ||
102 | __mark_check_format(format, ## args); \ | ||
103 | (*__mark_##name.call)(&__mark_##name, call_private, \ | ||
104 | ## args); \ | ||
105 | } while (0) | ||
106 | |||
83 | extern void marker_update_probe_range(struct marker *begin, | 107 | extern void marker_update_probe_range(struct marker *begin, |
84 | struct marker *end); | 108 | struct marker *end); |
109 | |||
110 | #define GET_MARKER(name) (__mark_##name) | ||
111 | |||
85 | #else /* !CONFIG_MARKERS */ | 112 | #else /* !CONFIG_MARKERS */ |
113 | #define DEFINE_MARKER(name, tp_name, tp_cb, format) | ||
86 | #define __trace_mark(generic, name, call_private, format, args...) \ | 114 | #define __trace_mark(generic, name, call_private, format, args...) \ |
87 | __mark_check_format(format, ## args) | 115 | __mark_check_format(format, ## args) |
116 | #define __trace_mark_tp(name, call_private, tp_name, tp_cb, format, args...) \ | ||
117 | do { \ | ||
118 | void __check_tp_type(void) \ | ||
119 | { \ | ||
120 | register_trace_##tp_name(tp_cb); \ | ||
121 | } \ | ||
122 | __mark_check_format(format, ## args); \ | ||
123 | } while (0) | ||
88 | static inline void marker_update_probe_range(struct marker *begin, | 124 | static inline void marker_update_probe_range(struct marker *begin, |
89 | struct marker *end) | 125 | struct marker *end) |
90 | { } | 126 | { } |
127 | #define GET_MARKER(name) | ||
91 | #endif /* CONFIG_MARKERS */ | 128 | #endif /* CONFIG_MARKERS */ |
92 | 129 | ||
93 | /** | 130 | /** |
@@ -117,6 +154,20 @@ static inline void marker_update_probe_range(struct marker *begin, | |||
117 | __trace_mark(1, name, NULL, format, ## args) | 154 | __trace_mark(1, name, NULL, format, ## args) |
118 | 155 | ||
119 | /** | 156 | /** |
157 | * trace_mark_tp - Marker in a tracepoint callback | ||
158 | * @name: marker name, not quoted. | ||
159 | * @tp_name: tracepoint name, not quoted. | ||
160 | * @tp_cb: tracepoint callback. Should have an associated global symbol so it | ||
161 | * is not optimized away by the compiler (should not be static). | ||
162 | * @format: format string | ||
163 | * @args...: variable argument list | ||
164 | * | ||
165 | * Places a marker in a tracepoint callback. | ||
166 | */ | ||
167 | #define trace_mark_tp(name, tp_name, tp_cb, format, args...) \ | ||
168 | __trace_mark_tp(name, NULL, tp_name, tp_cb, format, ## args) | ||
169 | |||
170 | /** | ||
120 | * MARK_NOARGS - Format string for a marker with no argument. | 171 | * MARK_NOARGS - Format string for a marker with no argument. |
121 | */ | 172 | */ |
122 | #define MARK_NOARGS " " | 173 | #define MARK_NOARGS " " |
@@ -136,8 +187,6 @@ extern marker_probe_func __mark_empty_function; | |||
136 | 187 | ||
137 | extern void marker_probe_cb(const struct marker *mdata, | 188 | extern void marker_probe_cb(const struct marker *mdata, |
138 | void *call_private, ...); | 189 | void *call_private, ...); |
139 | extern void marker_probe_cb_noarg(const struct marker *mdata, | ||
140 | void *call_private, ...); | ||
141 | 190 | ||
142 | /* | 191 | /* |
143 | * Connect a probe to a marker. | 192 | * Connect a probe to a marker. |
diff --git a/include/linux/mutex.h b/include/linux/mutex.h index bc6da10ceee0..7a0e5c4f8072 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h | |||
@@ -144,6 +144,8 @@ extern int __must_check mutex_lock_killable(struct mutex *lock); | |||
144 | /* | 144 | /* |
145 | * NOTE: mutex_trylock() follows the spin_trylock() convention, | 145 | * NOTE: mutex_trylock() follows the spin_trylock() convention, |
146 | * not the down_trylock() convention! | 146 | * not the down_trylock() convention! |
147 | * | ||
148 | * Returns 1 if the mutex has been acquired successfully, and 0 on contention. | ||
147 | */ | 149 | */ |
148 | extern int mutex_trylock(struct mutex *lock); | 150 | extern int mutex_trylock(struct mutex *lock); |
149 | extern void mutex_unlock(struct mutex *lock); | 151 | extern void mutex_unlock(struct mutex *lock); |
diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 5f89b62e6983..301dda829e37 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <linux/seqlock.h> | 41 | #include <linux/seqlock.h> |
42 | 42 | ||
43 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR | 43 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR |
44 | #define RCU_SECONDS_TILL_STALL_CHECK ( 3 * HZ) /* for rcp->jiffies_stall */ | 44 | #define RCU_SECONDS_TILL_STALL_CHECK (10 * HZ) /* for rcp->jiffies_stall */ |
45 | #define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ) /* for rcp->jiffies_stall */ | 45 | #define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ) /* for rcp->jiffies_stall */ |
46 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | 46 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ |
47 | 47 | ||
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 86f1f5e43e33..895dc9c1088c 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -142,6 +142,7 @@ struct rcu_head { | |||
142 | * on the write-side to insure proper synchronization. | 142 | * on the write-side to insure proper synchronization. |
143 | */ | 143 | */ |
144 | #define rcu_read_lock_sched() preempt_disable() | 144 | #define rcu_read_lock_sched() preempt_disable() |
145 | #define rcu_read_lock_sched_notrace() preempt_disable_notrace() | ||
145 | 146 | ||
146 | /* | 147 | /* |
147 | * rcu_read_unlock_sched - marks the end of a RCU-classic critical section | 148 | * rcu_read_unlock_sched - marks the end of a RCU-classic critical section |
@@ -149,6 +150,7 @@ struct rcu_head { | |||
149 | * See rcu_read_lock_sched for more information. | 150 | * See rcu_read_lock_sched for more information. |
150 | */ | 151 | */ |
151 | #define rcu_read_unlock_sched() preempt_enable() | 152 | #define rcu_read_unlock_sched() preempt_enable() |
153 | #define rcu_read_unlock_sched_notrace() preempt_enable_notrace() | ||
152 | 154 | ||
153 | 155 | ||
154 | 156 | ||
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index e097c2e6b6dc..3bb87a753fa3 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h | |||
@@ -122,6 +122,7 @@ void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); | |||
122 | 122 | ||
123 | void tracing_on(void); | 123 | void tracing_on(void); |
124 | void tracing_off(void); | 124 | void tracing_off(void); |
125 | void tracing_off_permanent(void); | ||
125 | 126 | ||
126 | enum ring_buffer_flags { | 127 | enum ring_buffer_flags { |
127 | RB_FL_OVERWRITE = 1 << 0, | 128 | RB_FL_OVERWRITE = 1 << 0, |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 7a69c4d224ee..4ce5c603c51a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1350,6 +1350,17 @@ struct task_struct { | |||
1350 | unsigned long default_timer_slack_ns; | 1350 | unsigned long default_timer_slack_ns; |
1351 | 1351 | ||
1352 | struct list_head *scm_work_list; | 1352 | struct list_head *scm_work_list; |
1353 | #ifdef CONFIG_FUNCTION_RET_TRACER | ||
1354 | /* Index of current stored adress in ret_stack */ | ||
1355 | int curr_ret_stack; | ||
1356 | /* Stack of return addresses for return function tracing */ | ||
1357 | struct ftrace_ret_stack *ret_stack; | ||
1358 | /* | ||
1359 | * Number of functions that haven't been traced | ||
1360 | * because of depth overrun. | ||
1361 | */ | ||
1362 | atomic_t trace_overrun; | ||
1363 | #endif | ||
1353 | }; | 1364 | }; |
1354 | 1365 | ||
1355 | /* | 1366 | /* |
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index dc50bcc282a8..b3dfa72f13b9 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h | |||
@@ -34,6 +34,7 @@ struct seq_operations { | |||
34 | 34 | ||
35 | #define SEQ_SKIP 1 | 35 | #define SEQ_SKIP 1 |
36 | 36 | ||
37 | char *mangle_path(char *s, char *p, char *esc); | ||
37 | int seq_open(struct file *, const struct seq_operations *); | 38 | int seq_open(struct file *, const struct seq_operations *); |
38 | ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); | 39 | ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); |
39 | loff_t seq_lseek(struct file *, loff_t, int); | 40 | loff_t seq_lseek(struct file *, loff_t, int); |
diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index b106fd8e0d5c..1a8cecc4f38c 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h | |||
@@ -15,9 +15,17 @@ extern void save_stack_trace_tsk(struct task_struct *tsk, | |||
15 | struct stack_trace *trace); | 15 | struct stack_trace *trace); |
16 | 16 | ||
17 | extern void print_stack_trace(struct stack_trace *trace, int spaces); | 17 | extern void print_stack_trace(struct stack_trace *trace, int spaces); |
18 | |||
19 | #ifdef CONFIG_USER_STACKTRACE_SUPPORT | ||
20 | extern void save_stack_trace_user(struct stack_trace *trace); | ||
21 | #else | ||
22 | # define save_stack_trace_user(trace) do { } while (0) | ||
23 | #endif | ||
24 | |||
18 | #else | 25 | #else |
19 | # define save_stack_trace(trace) do { } while (0) | 26 | # define save_stack_trace(trace) do { } while (0) |
20 | # define save_stack_trace_tsk(tsk, trace) do { } while (0) | 27 | # define save_stack_trace_tsk(tsk, trace) do { } while (0) |
28 | # define save_stack_trace_user(trace) do { } while (0) | ||
21 | # define print_stack_trace(trace, spaces) do { } while (0) | 29 | # define print_stack_trace(trace, spaces) do { } while (0) |
22 | #endif | 30 | #endif |
23 | 31 | ||
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index c5bb39c7a770..757005458366 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
@@ -24,8 +24,12 @@ struct tracepoint { | |||
24 | const char *name; /* Tracepoint name */ | 24 | const char *name; /* Tracepoint name */ |
25 | int state; /* State. */ | 25 | int state; /* State. */ |
26 | void **funcs; | 26 | void **funcs; |
27 | } __attribute__((aligned(8))); | 27 | } __attribute__((aligned(32))); /* |
28 | 28 | * Aligned on 32 bytes because it is | |
29 | * globally visible and gcc happily | ||
30 | * align these on the structure size. | ||
31 | * Keep in sync with vmlinux.lds.h. | ||
32 | */ | ||
29 | 33 | ||
30 | #define TPPROTO(args...) args | 34 | #define TPPROTO(args...) args |
31 | #define TPARGS(args...) args | 35 | #define TPARGS(args...) args |
@@ -40,14 +44,14 @@ struct tracepoint { | |||
40 | do { \ | 44 | do { \ |
41 | void **it_func; \ | 45 | void **it_func; \ |
42 | \ | 46 | \ |
43 | rcu_read_lock_sched(); \ | 47 | rcu_read_lock_sched_notrace(); \ |
44 | it_func = rcu_dereference((tp)->funcs); \ | 48 | it_func = rcu_dereference((tp)->funcs); \ |
45 | if (it_func) { \ | 49 | if (it_func) { \ |
46 | do { \ | 50 | do { \ |
47 | ((void(*)(proto))(*it_func))(args); \ | 51 | ((void(*)(proto))(*it_func))(args); \ |
48 | } while (*(++it_func)); \ | 52 | } while (*(++it_func)); \ |
49 | } \ | 53 | } \ |
50 | rcu_read_unlock_sched(); \ | 54 | rcu_read_unlock_sched_notrace(); \ |
51 | } while (0) | 55 | } while (0) |
52 | 56 | ||
53 | /* | 57 | /* |
@@ -55,35 +59,40 @@ struct tracepoint { | |||
55 | * not add unwanted padding between the beginning of the section and the | 59 | * not add unwanted padding between the beginning of the section and the |
56 | * structure. Force alignment to the same alignment as the section start. | 60 | * structure. Force alignment to the same alignment as the section start. |
57 | */ | 61 | */ |
58 | #define DEFINE_TRACE(name, proto, args) \ | 62 | #define DECLARE_TRACE(name, proto, args) \ |
63 | extern struct tracepoint __tracepoint_##name; \ | ||
59 | static inline void trace_##name(proto) \ | 64 | static inline void trace_##name(proto) \ |
60 | { \ | 65 | { \ |
61 | static const char __tpstrtab_##name[] \ | ||
62 | __attribute__((section("__tracepoints_strings"))) \ | ||
63 | = #name ":" #proto; \ | ||
64 | static struct tracepoint __tracepoint_##name \ | ||
65 | __attribute__((section("__tracepoints"), aligned(8))) = \ | ||
66 | { __tpstrtab_##name, 0, NULL }; \ | ||
67 | if (unlikely(__tracepoint_##name.state)) \ | 66 | if (unlikely(__tracepoint_##name.state)) \ |
68 | __DO_TRACE(&__tracepoint_##name, \ | 67 | __DO_TRACE(&__tracepoint_##name, \ |
69 | TPPROTO(proto), TPARGS(args)); \ | 68 | TPPROTO(proto), TPARGS(args)); \ |
70 | } \ | 69 | } \ |
71 | static inline int register_trace_##name(void (*probe)(proto)) \ | 70 | static inline int register_trace_##name(void (*probe)(proto)) \ |
72 | { \ | 71 | { \ |
73 | return tracepoint_probe_register(#name ":" #proto, \ | 72 | return tracepoint_probe_register(#name, (void *)probe); \ |
74 | (void *)probe); \ | ||
75 | } \ | 73 | } \ |
76 | static inline void unregister_trace_##name(void (*probe)(proto))\ | 74 | static inline int unregister_trace_##name(void (*probe)(proto)) \ |
77 | { \ | 75 | { \ |
78 | tracepoint_probe_unregister(#name ":" #proto, \ | 76 | return tracepoint_probe_unregister(#name, (void *)probe);\ |
79 | (void *)probe); \ | ||
80 | } | 77 | } |
81 | 78 | ||
79 | #define DEFINE_TRACE(name) \ | ||
80 | static const char __tpstrtab_##name[] \ | ||
81 | __attribute__((section("__tracepoints_strings"))) = #name; \ | ||
82 | struct tracepoint __tracepoint_##name \ | ||
83 | __attribute__((section("__tracepoints"), aligned(32))) = \ | ||
84 | { __tpstrtab_##name, 0, NULL } | ||
85 | |||
86 | #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ | ||
87 | EXPORT_SYMBOL_GPL(__tracepoint_##name) | ||
88 | #define EXPORT_TRACEPOINT_SYMBOL(name) \ | ||
89 | EXPORT_SYMBOL(__tracepoint_##name) | ||
90 | |||
82 | extern void tracepoint_update_probe_range(struct tracepoint *begin, | 91 | extern void tracepoint_update_probe_range(struct tracepoint *begin, |
83 | struct tracepoint *end); | 92 | struct tracepoint *end); |
84 | 93 | ||
85 | #else /* !CONFIG_TRACEPOINTS */ | 94 | #else /* !CONFIG_TRACEPOINTS */ |
86 | #define DEFINE_TRACE(name, proto, args) \ | 95 | #define DECLARE_TRACE(name, proto, args) \ |
87 | static inline void _do_trace_##name(struct tracepoint *tp, proto) \ | 96 | static inline void _do_trace_##name(struct tracepoint *tp, proto) \ |
88 | { } \ | 97 | { } \ |
89 | static inline void trace_##name(proto) \ | 98 | static inline void trace_##name(proto) \ |
@@ -92,8 +101,14 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin, | |||
92 | { \ | 101 | { \ |
93 | return -ENOSYS; \ | 102 | return -ENOSYS; \ |
94 | } \ | 103 | } \ |
95 | static inline void unregister_trace_##name(void (*probe)(proto))\ | 104 | static inline int unregister_trace_##name(void (*probe)(proto)) \ |
96 | { } | 105 | { \ |
106 | return -ENOSYS; \ | ||
107 | } | ||
108 | |||
109 | #define DEFINE_TRACE(name) | ||
110 | #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) | ||
111 | #define EXPORT_TRACEPOINT_SYMBOL(name) | ||
97 | 112 | ||
98 | static inline void tracepoint_update_probe_range(struct tracepoint *begin, | 113 | static inline void tracepoint_update_probe_range(struct tracepoint *begin, |
99 | struct tracepoint *end) | 114 | struct tracepoint *end) |
@@ -112,6 +127,10 @@ extern int tracepoint_probe_register(const char *name, void *probe); | |||
112 | */ | 127 | */ |
113 | extern int tracepoint_probe_unregister(const char *name, void *probe); | 128 | extern int tracepoint_probe_unregister(const char *name, void *probe); |
114 | 129 | ||
130 | extern int tracepoint_probe_register_noupdate(const char *name, void *probe); | ||
131 | extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe); | ||
132 | extern void tracepoint_probe_update_all(void); | ||
133 | |||
115 | struct tracepoint_iter { | 134 | struct tracepoint_iter { |
116 | struct module *module; | 135 | struct module *module; |
117 | struct tracepoint *tracepoint; | 136 | struct tracepoint *tracepoint; |
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index fec6decfb983..6b58367d145e 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h | |||
@@ -78,7 +78,7 @@ static inline unsigned long __copy_from_user_nocache(void *to, | |||
78 | \ | 78 | \ |
79 | set_fs(KERNEL_DS); \ | 79 | set_fs(KERNEL_DS); \ |
80 | pagefault_disable(); \ | 80 | pagefault_disable(); \ |
81 | ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \ | 81 | ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \ |
82 | pagefault_enable(); \ | 82 | pagefault_enable(); \ |
83 | set_fs(old_fs); \ | 83 | set_fs(old_fs); \ |
84 | ret; \ | 84 | ret; \ |
diff --git a/include/trace/boot.h b/include/trace/boot.h new file mode 100644 index 000000000000..6b54537eab02 --- /dev/null +++ b/include/trace/boot.h | |||
@@ -0,0 +1,56 @@ | |||
1 | #ifndef _LINUX_TRACE_BOOT_H | ||
2 | #define _LINUX_TRACE_BOOT_H | ||
3 | |||
4 | /* | ||
5 | * Structure which defines the trace of an initcall | ||
6 | * while it is called. | ||
7 | * You don't have to fill the func field since it is | ||
8 | * only used internally by the tracer. | ||
9 | */ | ||
10 | struct boot_trace_call { | ||
11 | pid_t caller; | ||
12 | char func[KSYM_NAME_LEN]; | ||
13 | }; | ||
14 | |||
15 | /* | ||
16 | * Structure which defines the trace of an initcall | ||
17 | * while it returns. | ||
18 | */ | ||
19 | struct boot_trace_ret { | ||
20 | char func[KSYM_NAME_LEN]; | ||
21 | int result; | ||
22 | unsigned long long duration; /* nsecs */ | ||
23 | }; | ||
24 | |||
25 | #ifdef CONFIG_BOOT_TRACER | ||
26 | /* Append the traces on the ring-buffer */ | ||
27 | extern void trace_boot_call(struct boot_trace_call *bt, initcall_t fn); | ||
28 | extern void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn); | ||
29 | |||
30 | /* Tells the tracer that smp_pre_initcall is finished. | ||
31 | * So we can start the tracing | ||
32 | */ | ||
33 | extern void start_boot_trace(void); | ||
34 | |||
35 | /* Resume the tracing of other necessary events | ||
36 | * such as sched switches | ||
37 | */ | ||
38 | extern void enable_boot_trace(void); | ||
39 | |||
40 | /* Suspend this tracing. Actually, only sched_switches tracing have | ||
41 | * to be suspended. Initcalls doesn't need it.) | ||
42 | */ | ||
43 | extern void disable_boot_trace(void); | ||
44 | #else | ||
45 | static inline | ||
46 | void trace_boot_call(struct boot_trace_call *bt, initcall_t fn) { } | ||
47 | |||
48 | static inline | ||
49 | void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn) { } | ||
50 | |||
51 | static inline void start_boot_trace(void) { } | ||
52 | static inline void enable_boot_trace(void) { } | ||
53 | static inline void disable_boot_trace(void) { } | ||
54 | #endif /* CONFIG_BOOT_TRACER */ | ||
55 | |||
56 | #endif /* __LINUX_TRACE_BOOT_H */ | ||
diff --git a/include/trace/sched.h b/include/trace/sched.h index ad47369d01b5..9b2854abf7e2 100644 --- a/include/trace/sched.h +++ b/include/trace/sched.h | |||
@@ -4,52 +4,52 @@ | |||
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/tracepoint.h> | 5 | #include <linux/tracepoint.h> |
6 | 6 | ||
7 | DEFINE_TRACE(sched_kthread_stop, | 7 | DECLARE_TRACE(sched_kthread_stop, |
8 | TPPROTO(struct task_struct *t), | 8 | TPPROTO(struct task_struct *t), |
9 | TPARGS(t)); | 9 | TPARGS(t)); |
10 | 10 | ||
11 | DEFINE_TRACE(sched_kthread_stop_ret, | 11 | DECLARE_TRACE(sched_kthread_stop_ret, |
12 | TPPROTO(int ret), | 12 | TPPROTO(int ret), |
13 | TPARGS(ret)); | 13 | TPARGS(ret)); |
14 | 14 | ||
15 | DEFINE_TRACE(sched_wait_task, | 15 | DECLARE_TRACE(sched_wait_task, |
16 | TPPROTO(struct rq *rq, struct task_struct *p), | 16 | TPPROTO(struct rq *rq, struct task_struct *p), |
17 | TPARGS(rq, p)); | 17 | TPARGS(rq, p)); |
18 | 18 | ||
19 | DEFINE_TRACE(sched_wakeup, | 19 | DECLARE_TRACE(sched_wakeup, |
20 | TPPROTO(struct rq *rq, struct task_struct *p), | 20 | TPPROTO(struct rq *rq, struct task_struct *p), |
21 | TPARGS(rq, p)); | 21 | TPARGS(rq, p)); |
22 | 22 | ||
23 | DEFINE_TRACE(sched_wakeup_new, | 23 | DECLARE_TRACE(sched_wakeup_new, |
24 | TPPROTO(struct rq *rq, struct task_struct *p), | 24 | TPPROTO(struct rq *rq, struct task_struct *p), |
25 | TPARGS(rq, p)); | 25 | TPARGS(rq, p)); |
26 | 26 | ||
27 | DEFINE_TRACE(sched_switch, | 27 | DECLARE_TRACE(sched_switch, |
28 | TPPROTO(struct rq *rq, struct task_struct *prev, | 28 | TPPROTO(struct rq *rq, struct task_struct *prev, |
29 | struct task_struct *next), | 29 | struct task_struct *next), |
30 | TPARGS(rq, prev, next)); | 30 | TPARGS(rq, prev, next)); |
31 | 31 | ||
32 | DEFINE_TRACE(sched_migrate_task, | 32 | DECLARE_TRACE(sched_migrate_task, |
33 | TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu), | 33 | TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu), |
34 | TPARGS(rq, p, dest_cpu)); | 34 | TPARGS(rq, p, dest_cpu)); |
35 | 35 | ||
36 | DEFINE_TRACE(sched_process_free, | 36 | DECLARE_TRACE(sched_process_free, |
37 | TPPROTO(struct task_struct *p), | 37 | TPPROTO(struct task_struct *p), |
38 | TPARGS(p)); | 38 | TPARGS(p)); |
39 | 39 | ||
40 | DEFINE_TRACE(sched_process_exit, | 40 | DECLARE_TRACE(sched_process_exit, |
41 | TPPROTO(struct task_struct *p), | 41 | TPPROTO(struct task_struct *p), |
42 | TPARGS(p)); | 42 | TPARGS(p)); |
43 | 43 | ||
44 | DEFINE_TRACE(sched_process_wait, | 44 | DECLARE_TRACE(sched_process_wait, |
45 | TPPROTO(struct pid *pid), | 45 | TPPROTO(struct pid *pid), |
46 | TPARGS(pid)); | 46 | TPARGS(pid)); |
47 | 47 | ||
48 | DEFINE_TRACE(sched_process_fork, | 48 | DECLARE_TRACE(sched_process_fork, |
49 | TPPROTO(struct task_struct *parent, struct task_struct *child), | 49 | TPPROTO(struct task_struct *parent, struct task_struct *child), |
50 | TPARGS(parent, child)); | 50 | TPARGS(parent, child)); |
51 | 51 | ||
52 | DEFINE_TRACE(sched_signal_send, | 52 | DECLARE_TRACE(sched_signal_send, |
53 | TPPROTO(int sig, struct task_struct *p), | 53 | TPPROTO(int sig, struct task_struct *p), |
54 | TPARGS(sig, p)); | 54 | TPARGS(sig, p)); |
55 | 55 | ||