diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:21:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:21:10 -0500 |
commit | b0f4b285d7ed174804658539129a834270f4829a (patch) | |
tree | be7f8dca58075aba2c6a137fcfd4d44c5c333efc /include | |
parent | be9c5ae4eeec2e85527e95647348b8ea4eb25128 (diff) | |
parent | 5250d329e38cdf7580faeb9c53c17d3588d7d19c (diff) |
Merge branch 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (241 commits)
sched, trace: update trace_sched_wakeup()
tracing/ftrace: don't trace on early stage of a secondary cpu boot, v3
Revert "x86: disable X86_PTRACE_BTS"
ring-buffer: prevent false positive warning
ring-buffer: fix dangling commit race
ftrace: enable format arguments checking
x86, bts: memory accounting
x86, bts: add fork and exit handling
ftrace: introduce tracing_reset_online_cpus() helper
tracing: fix warnings in kernel/trace/trace_sched_switch.c
tracing: fix warning in kernel/trace/trace.c
tracing/ring-buffer: remove unused ring_buffer size
trace: fix task state printout
ftrace: add not to regex on filtering functions
trace: better use of stack_trace_enabled for boot up code
trace: add a way to enable or disable the stack tracer
x86: entry_64 - introduce FTRACE_ frame macro v2
tracing/ftrace: add the printk-msg-only option
tracing/ftrace: use preempt_enable_no_resched_notrace in ring_buffer_time_stamp()
x86, bts: correctly report invalid bts records
...
Fixed up trivial conflict in scripts/recordmcount.pl due to SH bits
being already partly merged by the SH merge.
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 31 | ||||
-rw-r--r-- | include/linux/blktrace_api.h | 172 | ||||
-rw-r--r-- | include/linux/compiler.h | 84 | ||||
-rw-r--r-- | include/linux/ftrace.h | 293 | ||||
-rw-r--r-- | include/linux/ftrace_irq.h | 13 | ||||
-rw-r--r-- | include/linux/hardirq.h | 15 | ||||
-rw-r--r-- | include/linux/marker.h | 75 | ||||
-rw-r--r-- | include/linux/mm.h | 2 | ||||
-rw-r--r-- | include/linux/pid.h | 4 | ||||
-rw-r--r-- | include/linux/ptrace.h | 22 | ||||
-rw-r--r-- | include/linux/rcupdate.h | 2 | ||||
-rw-r--r-- | include/linux/ring_buffer.h | 16 | ||||
-rw-r--r-- | include/linux/sched.h | 31 | ||||
-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/tty.h | 2 | ||||
-rw-r--r-- | include/trace/block.h | 76 | ||||
-rw-r--r-- | include/trace/boot.h | 60 | ||||
-rw-r--r-- | include/trace/sched.h | 36 |
20 files changed, 744 insertions, 256 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 80744606bad1..c61fab1dd2f8 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)); \ |
@@ -269,6 +288,16 @@ | |||
269 | *(.kprobes.text) \ | 288 | *(.kprobes.text) \ |
270 | VMLINUX_SYMBOL(__kprobes_text_end) = .; | 289 | VMLINUX_SYMBOL(__kprobes_text_end) = .; |
271 | 290 | ||
291 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
292 | #define IRQENTRY_TEXT \ | ||
293 | ALIGN_FUNCTION(); \ | ||
294 | VMLINUX_SYMBOL(__irqentry_text_start) = .; \ | ||
295 | *(.irqentry.text) \ | ||
296 | VMLINUX_SYMBOL(__irqentry_text_end) = .; | ||
297 | #else | ||
298 | #define IRQENTRY_TEXT | ||
299 | #endif | ||
300 | |||
272 | /* Section used for early init (in .S files) */ | 301 | /* Section used for early init (in .S files) */ |
273 | #define HEAD_TEXT *(.head.text) | 302 | #define HEAD_TEXT *(.head.text) |
274 | 303 | ||
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index bdf505d33e77..1dba3493d520 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h | |||
@@ -160,7 +160,6 @@ struct blk_trace { | |||
160 | 160 | ||
161 | extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *); | 161 | extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *); |
162 | extern void blk_trace_shutdown(struct request_queue *); | 162 | extern void blk_trace_shutdown(struct request_queue *); |
163 | extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, void *); | ||
164 | extern int do_blk_trace_setup(struct request_queue *q, | 163 | extern int do_blk_trace_setup(struct request_queue *q, |
165 | char *name, dev_t dev, struct blk_user_trace_setup *buts); | 164 | char *name, dev_t dev, struct blk_user_trace_setup *buts); |
166 | extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); | 165 | extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); |
@@ -186,168 +185,8 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); | |||
186 | } while (0) | 185 | } while (0) |
187 | #define BLK_TN_MAX_MSG 128 | 186 | #define BLK_TN_MAX_MSG 128 |
188 | 187 | ||
189 | /** | 188 | extern void blk_add_driver_data(struct request_queue *q, struct request *rq, |
190 | * blk_add_trace_rq - Add a trace for a request oriented action | 189 | void *data, size_t len); |
191 | * @q: queue the io is for | ||
192 | * @rq: the source request | ||
193 | * @what: the action | ||
194 | * | ||
195 | * Description: | ||
196 | * Records an action against a request. Will log the bio offset + size. | ||
197 | * | ||
198 | **/ | ||
199 | static inline void blk_add_trace_rq(struct request_queue *q, struct request *rq, | ||
200 | u32 what) | ||
201 | { | ||
202 | struct blk_trace *bt = q->blk_trace; | ||
203 | int rw = rq->cmd_flags & 0x03; | ||
204 | |||
205 | if (likely(!bt)) | ||
206 | return; | ||
207 | |||
208 | if (blk_discard_rq(rq)) | ||
209 | rw |= (1 << BIO_RW_DISCARD); | ||
210 | |||
211 | if (blk_pc_request(rq)) { | ||
212 | what |= BLK_TC_ACT(BLK_TC_PC); | ||
213 | __blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors, sizeof(rq->cmd), rq->cmd); | ||
214 | } else { | ||
215 | what |= BLK_TC_ACT(BLK_TC_FS); | ||
216 | __blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9, rw, what, rq->errors, 0, NULL); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * blk_add_trace_bio - Add a trace for a bio oriented action | ||
222 | * @q: queue the io is for | ||
223 | * @bio: the source bio | ||
224 | * @what: the action | ||
225 | * | ||
226 | * Description: | ||
227 | * Records an action against a bio. Will log the bio offset + size. | ||
228 | * | ||
229 | **/ | ||
230 | static inline void blk_add_trace_bio(struct request_queue *q, struct bio *bio, | ||
231 | u32 what) | ||
232 | { | ||
233 | struct blk_trace *bt = q->blk_trace; | ||
234 | |||
235 | if (likely(!bt)) | ||
236 | return; | ||
237 | |||
238 | __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what, !bio_flagged(bio, BIO_UPTODATE), 0, NULL); | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * blk_add_trace_generic - Add a trace for a generic action | ||
243 | * @q: queue the io is for | ||
244 | * @bio: the source bio | ||
245 | * @rw: the data direction | ||
246 | * @what: the action | ||
247 | * | ||
248 | * Description: | ||
249 | * Records a simple trace | ||
250 | * | ||
251 | **/ | ||
252 | static inline void blk_add_trace_generic(struct request_queue *q, | ||
253 | struct bio *bio, int rw, u32 what) | ||
254 | { | ||
255 | struct blk_trace *bt = q->blk_trace; | ||
256 | |||
257 | if (likely(!bt)) | ||
258 | return; | ||
259 | |||
260 | if (bio) | ||
261 | blk_add_trace_bio(q, bio, what); | ||
262 | else | ||
263 | __blk_add_trace(bt, 0, 0, rw, what, 0, 0, NULL); | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * blk_add_trace_pdu_int - Add a trace for a bio with an integer payload | ||
268 | * @q: queue the io is for | ||
269 | * @what: the action | ||
270 | * @bio: the source bio | ||
271 | * @pdu: the integer payload | ||
272 | * | ||
273 | * Description: | ||
274 | * Adds a trace with some integer payload. This might be an unplug | ||
275 | * option given as the action, with the depth at unplug time given | ||
276 | * as the payload | ||
277 | * | ||
278 | **/ | ||
279 | static inline void blk_add_trace_pdu_int(struct request_queue *q, u32 what, | ||
280 | struct bio *bio, unsigned int pdu) | ||
281 | { | ||
282 | struct blk_trace *bt = q->blk_trace; | ||
283 | __be64 rpdu = cpu_to_be64(pdu); | ||
284 | |||
285 | if (likely(!bt)) | ||
286 | return; | ||
287 | |||
288 | if (bio) | ||
289 | __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what, !bio_flagged(bio, BIO_UPTODATE), sizeof(rpdu), &rpdu); | ||
290 | else | ||
291 | __blk_add_trace(bt, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * blk_add_trace_remap - Add a trace for a remap operation | ||
296 | * @q: queue the io is for | ||
297 | * @bio: the source bio | ||
298 | * @dev: target device | ||
299 | * @from: source sector | ||
300 | * @to: target sector | ||
301 | * | ||
302 | * Description: | ||
303 | * Device mapper or raid target sometimes need to split a bio because | ||
304 | * it spans a stripe (or similar). Add a trace for that action. | ||
305 | * | ||
306 | **/ | ||
307 | static inline void blk_add_trace_remap(struct request_queue *q, struct bio *bio, | ||
308 | dev_t dev, sector_t from, sector_t to) | ||
309 | { | ||
310 | struct blk_trace *bt = q->blk_trace; | ||
311 | struct blk_io_trace_remap r; | ||
312 | |||
313 | if (likely(!bt)) | ||
314 | return; | ||
315 | |||
316 | r.device = cpu_to_be32(dev); | ||
317 | r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev); | ||
318 | r.sector = cpu_to_be64(to); | ||
319 | |||
320 | __blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r); | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * blk_add_driver_data - Add binary message with driver-specific data | ||
325 | * @q: queue the io is for | ||
326 | * @rq: io request | ||
327 | * @data: driver-specific data | ||
328 | * @len: length of driver-specific data | ||
329 | * | ||
330 | * Description: | ||
331 | * Some drivers might want to write driver-specific data per request. | ||
332 | * | ||
333 | **/ | ||
334 | static inline void blk_add_driver_data(struct request_queue *q, | ||
335 | struct request *rq, | ||
336 | void *data, size_t len) | ||
337 | { | ||
338 | struct blk_trace *bt = q->blk_trace; | ||
339 | |||
340 | if (likely(!bt)) | ||
341 | return; | ||
342 | |||
343 | if (blk_pc_request(rq)) | ||
344 | __blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA, | ||
345 | rq->errors, len, data); | ||
346 | else | ||
347 | __blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9, | ||
348 | 0, BLK_TA_DRV_DATA, rq->errors, len, data); | ||
349 | } | ||
350 | |||
351 | extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | 190 | extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, |
352 | char __user *arg); | 191 | char __user *arg); |
353 | extern int blk_trace_startstop(struct request_queue *q, int start); | 192 | extern int blk_trace_startstop(struct request_queue *q, int start); |
@@ -356,13 +195,8 @@ extern int blk_trace_remove(struct request_queue *q); | |||
356 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ | 195 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ |
357 | #define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) | 196 | #define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) |
358 | #define blk_trace_shutdown(q) do { } while (0) | 197 | #define blk_trace_shutdown(q) do { } while (0) |
359 | #define blk_add_trace_rq(q, rq, what) do { } while (0) | ||
360 | #define blk_add_trace_bio(q, rq, what) do { } while (0) | ||
361 | #define blk_add_trace_generic(q, rq, rw, what) do { } while (0) | ||
362 | #define blk_add_trace_pdu_int(q, what, bio, pdu) do { } while (0) | ||
363 | #define blk_add_trace_remap(q, bio, dev, f, t) do {} while (0) | ||
364 | #define blk_add_driver_data(q, rq, data, len) do {} while (0) | ||
365 | #define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY) | 198 | #define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY) |
199 | #define blk_add_driver_data(q, rq, data, len) do {} while (0) | ||
366 | #define blk_trace_setup(q, name, dev, arg) (-ENOTTY) | 200 | #define blk_trace_setup(q, name, dev, arg) (-ENOTTY) |
367 | #define blk_trace_startstop(q, start) (-ENOTTY) | 201 | #define blk_trace_startstop(q, start) (-ENOTTY) |
368 | #define blk_trace_remove(q) (-ENOTTY) | 202 | #define blk_trace_remove(q) (-ENOTTY) |
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/ftrace.h b/include/linux/ftrace.h index 9c5bc6be2b09..677432b9cb7e 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <linux/types.h> | 8 | #include <linux/types.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/kallsyms.h> | 10 | #include <linux/kallsyms.h> |
11 | #include <linux/bitops.h> | ||
12 | #include <linux/sched.h> | ||
11 | 13 | ||
12 | #ifdef CONFIG_FUNCTION_TRACER | 14 | #ifdef CONFIG_FUNCTION_TRACER |
13 | 15 | ||
@@ -24,6 +26,45 @@ struct ftrace_ops { | |||
24 | struct ftrace_ops *next; | 26 | struct ftrace_ops *next; |
25 | }; | 27 | }; |
26 | 28 | ||
29 | extern int function_trace_stop; | ||
30 | |||
31 | /* | ||
32 | * Type of the current tracing. | ||
33 | */ | ||
34 | enum ftrace_tracing_type_t { | ||
35 | FTRACE_TYPE_ENTER = 0, /* Hook the call of the function */ | ||
36 | FTRACE_TYPE_RETURN, /* Hook the return of the function */ | ||
37 | }; | ||
38 | |||
39 | /* Current tracing type, default is FTRACE_TYPE_ENTER */ | ||
40 | extern enum ftrace_tracing_type_t ftrace_tracing_type; | ||
41 | |||
42 | /** | ||
43 | * ftrace_stop - stop function tracer. | ||
44 | * | ||
45 | * A quick way to stop the function tracer. Note this an on off switch, | ||
46 | * it is not something that is recursive like preempt_disable. | ||
47 | * This does not disable the calling of mcount, it only stops the | ||
48 | * calling of functions from mcount. | ||
49 | */ | ||
50 | static inline void ftrace_stop(void) | ||
51 | { | ||
52 | function_trace_stop = 1; | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * ftrace_start - start the function tracer. | ||
57 | * | ||
58 | * This function is the inverse of ftrace_stop. This does not enable | ||
59 | * the function tracing if the function tracer is disabled. This only | ||
60 | * sets the function tracer flag to continue calling the functions | ||
61 | * from mcount. | ||
62 | */ | ||
63 | static inline void ftrace_start(void) | ||
64 | { | ||
65 | function_trace_stop = 0; | ||
66 | } | ||
67 | |||
27 | /* | 68 | /* |
28 | * The ftrace_ops must be a static and should also | 69 | * The ftrace_ops must be a static and should also |
29 | * be read_mostly. These functions do modify read_mostly variables | 70 | * be read_mostly. These functions do modify read_mostly variables |
@@ -42,9 +83,21 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1); | |||
42 | # define unregister_ftrace_function(ops) do { } while (0) | 83 | # define unregister_ftrace_function(ops) do { } while (0) |
43 | # define clear_ftrace_function(ops) do { } while (0) | 84 | # define clear_ftrace_function(ops) do { } while (0) |
44 | static inline void ftrace_kill(void) { } | 85 | static inline void ftrace_kill(void) { } |
86 | static inline void ftrace_stop(void) { } | ||
87 | static inline void ftrace_start(void) { } | ||
45 | #endif /* CONFIG_FUNCTION_TRACER */ | 88 | #endif /* CONFIG_FUNCTION_TRACER */ |
46 | 89 | ||
90 | #ifdef CONFIG_STACK_TRACER | ||
91 | extern int stack_tracer_enabled; | ||
92 | int | ||
93 | stack_trace_sysctl(struct ctl_table *table, int write, | ||
94 | struct file *file, void __user *buffer, size_t *lenp, | ||
95 | loff_t *ppos); | ||
96 | #endif | ||
97 | |||
47 | #ifdef CONFIG_DYNAMIC_FTRACE | 98 | #ifdef CONFIG_DYNAMIC_FTRACE |
99 | /* asm/ftrace.h must be defined for archs supporting dynamic ftrace */ | ||
100 | #include <asm/ftrace.h> | ||
48 | 101 | ||
49 | enum { | 102 | enum { |
50 | FTRACE_FL_FREE = (1 << 0), | 103 | FTRACE_FL_FREE = (1 << 0), |
@@ -60,6 +113,7 @@ struct dyn_ftrace { | |||
60 | struct list_head list; | 113 | struct list_head list; |
61 | unsigned long ip; /* address of mcount call-site */ | 114 | unsigned long ip; /* address of mcount call-site */ |
62 | unsigned long flags; | 115 | unsigned long flags; |
116 | struct dyn_arch_ftrace arch; | ||
63 | }; | 117 | }; |
64 | 118 | ||
65 | int ftrace_force_update(void); | 119 | int ftrace_force_update(void); |
@@ -67,19 +121,48 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset); | |||
67 | 121 | ||
68 | /* defined in arch */ | 122 | /* defined in arch */ |
69 | extern int ftrace_ip_converted(unsigned long ip); | 123 | extern int ftrace_ip_converted(unsigned long ip); |
70 | extern unsigned char *ftrace_nop_replace(void); | ||
71 | extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); | ||
72 | extern int ftrace_dyn_arch_init(void *data); | 124 | extern int ftrace_dyn_arch_init(void *data); |
73 | extern int ftrace_update_ftrace_func(ftrace_func_t func); | 125 | extern int ftrace_update_ftrace_func(ftrace_func_t func); |
74 | extern void ftrace_caller(void); | 126 | extern void ftrace_caller(void); |
75 | extern void ftrace_call(void); | 127 | extern void ftrace_call(void); |
76 | extern void mcount_call(void); | 128 | extern void mcount_call(void); |
129 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
130 | extern void ftrace_graph_caller(void); | ||
131 | extern int ftrace_enable_ftrace_graph_caller(void); | ||
132 | extern int ftrace_disable_ftrace_graph_caller(void); | ||
133 | #else | ||
134 | static inline int ftrace_enable_ftrace_graph_caller(void) { return 0; } | ||
135 | static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; } | ||
136 | #endif | ||
137 | |||
138 | /** | ||
139 | * ftrace_make_nop - convert code into top | ||
140 | * @mod: module structure if called by module load initialization | ||
141 | * @rec: the mcount call site record | ||
142 | * @addr: the address that the call site should be calling | ||
143 | * | ||
144 | * This is a very sensitive operation and great care needs | ||
145 | * to be taken by the arch. The operation should carefully | ||
146 | * read the location, check to see if what is read is indeed | ||
147 | * what we expect it to be, and then on success of the compare, | ||
148 | * it should write to the location. | ||
149 | * | ||
150 | * The code segment at @rec->ip should be a caller to @addr | ||
151 | * | ||
152 | * Return must be: | ||
153 | * 0 on success | ||
154 | * -EFAULT on error reading the location | ||
155 | * -EINVAL on a failed compare of the contents | ||
156 | * -EPERM on error writing to the location | ||
157 | * Any other value will be considered a failure. | ||
158 | */ | ||
159 | extern int ftrace_make_nop(struct module *mod, | ||
160 | struct dyn_ftrace *rec, unsigned long addr); | ||
77 | 161 | ||
78 | /** | 162 | /** |
79 | * ftrace_modify_code - modify code segment | 163 | * ftrace_make_call - convert a nop call site into a call to addr |
80 | * @ip: the address of the code segment | 164 | * @rec: the mcount call site record |
81 | * @old_code: the contents of what is expected to be there | 165 | * @addr: the address that the call site should call |
82 | * @new_code: the code to patch in | ||
83 | * | 166 | * |
84 | * This is a very sensitive operation and great care needs | 167 | * This is a very sensitive operation and great care needs |
85 | * to be taken by the arch. The operation should carefully | 168 | * to be taken by the arch. The operation should carefully |
@@ -87,6 +170,8 @@ extern void mcount_call(void); | |||
87 | * what we expect it to be, and then on success of the compare, | 170 | * what we expect it to be, and then on success of the compare, |
88 | * it should write to the location. | 171 | * it should write to the location. |
89 | * | 172 | * |
173 | * The code segment at @rec->ip should be a nop | ||
174 | * | ||
90 | * Return must be: | 175 | * Return must be: |
91 | * 0 on success | 176 | * 0 on success |
92 | * -EFAULT on error reading the location | 177 | * -EFAULT on error reading the location |
@@ -94,8 +179,11 @@ extern void mcount_call(void); | |||
94 | * -EPERM on error writing to the location | 179 | * -EPERM on error writing to the location |
95 | * Any other value will be considered a failure. | 180 | * Any other value will be considered a failure. |
96 | */ | 181 | */ |
97 | extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, | 182 | extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr); |
98 | unsigned char *new_code); | 183 | |
184 | |||
185 | /* May be defined in arch */ | ||
186 | extern int ftrace_arch_read_dyn_info(char *buf, int size); | ||
99 | 187 | ||
100 | extern int skip_trace(unsigned long ip); | 188 | extern int skip_trace(unsigned long ip); |
101 | 189 | ||
@@ -103,7 +191,6 @@ extern void ftrace_release(void *start, unsigned long size); | |||
103 | 191 | ||
104 | extern void ftrace_disable_daemon(void); | 192 | extern void ftrace_disable_daemon(void); |
105 | extern void ftrace_enable_daemon(void); | 193 | extern void ftrace_enable_daemon(void); |
106 | |||
107 | #else | 194 | #else |
108 | # define skip_trace(ip) ({ 0; }) | 195 | # define skip_trace(ip) ({ 0; }) |
109 | # define ftrace_force_update() ({ 0; }) | 196 | # define ftrace_force_update() ({ 0; }) |
@@ -182,6 +269,12 @@ static inline void __ftrace_enabled_restore(int enabled) | |||
182 | #endif | 269 | #endif |
183 | 270 | ||
184 | #ifdef CONFIG_TRACING | 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 | |||
185 | extern void | 278 | extern void |
186 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | 279 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); |
187 | 280 | ||
@@ -210,8 +303,11 @@ extern void ftrace_dump(void); | |||
210 | static inline void | 303 | static inline void |
211 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } | 304 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } |
212 | static inline int | 305 | static inline int |
213 | ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))); | 306 | ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); |
214 | 307 | ||
308 | static inline void tracing_start(void) { } | ||
309 | static inline void tracing_stop(void) { } | ||
310 | static inline void ftrace_off_permanent(void) { } | ||
215 | static inline int | 311 | static inline int |
216 | ftrace_printk(const char *fmt, ...) | 312 | ftrace_printk(const char *fmt, ...) |
217 | { | 313 | { |
@@ -222,33 +318,178 @@ static inline void ftrace_dump(void) { } | |||
222 | 318 | ||
223 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 319 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
224 | extern void ftrace_init(void); | 320 | extern void ftrace_init(void); |
225 | extern void ftrace_init_module(unsigned long *start, unsigned long *end); | 321 | extern void ftrace_init_module(struct module *mod, |
322 | unsigned long *start, unsigned long *end); | ||
226 | #else | 323 | #else |
227 | static inline void ftrace_init(void) { } | 324 | static inline void ftrace_init(void) { } |
228 | static inline void | 325 | static inline void |
229 | ftrace_init_module(unsigned long *start, unsigned long *end) { } | 326 | ftrace_init_module(struct module *mod, |
327 | unsigned long *start, unsigned long *end) { } | ||
328 | #endif | ||
329 | |||
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; | ||
230 | #endif | 342 | #endif |
343 | }; | ||
231 | 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 | /* | ||
361 | * Structure that defines an entry function trace. | ||
362 | */ | ||
363 | struct ftrace_graph_ent { | ||
364 | unsigned long func; /* Current function */ | ||
365 | int depth; | ||
366 | }; | ||
232 | 367 | ||
233 | struct boot_trace { | 368 | /* |
234 | pid_t caller; | 369 | * Structure that defines a return function trace. |
235 | char func[KSYM_SYMBOL_LEN]; | 370 | */ |
236 | int result; | 371 | struct ftrace_graph_ret { |
237 | unsigned long long duration; /* usecs */ | 372 | unsigned long func; /* Current function */ |
238 | ktime_t calltime; | 373 | unsigned long long calltime; |
239 | ktime_t rettime; | 374 | unsigned long long rettime; |
375 | /* Number of functions that overran the depth limit for current task */ | ||
376 | unsigned long overrun; | ||
377 | int depth; | ||
240 | }; | 378 | }; |
241 | 379 | ||
242 | #ifdef CONFIG_BOOT_TRACER | 380 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
243 | extern void trace_boot(struct boot_trace *it, initcall_t fn); | 381 | |
244 | extern void start_boot_trace(void); | 382 | /* |
245 | extern void stop_boot_trace(void); | 383 | * Sometimes we don't want to trace a function with the function |
384 | * graph tracer but we want them to keep traced by the usual function | ||
385 | * tracer if the function graph tracer is not configured. | ||
386 | */ | ||
387 | #define __notrace_funcgraph notrace | ||
388 | |||
389 | /* | ||
390 | * We want to which function is an entrypoint of a hardirq. | ||
391 | * That will help us to put a signal on output. | ||
392 | */ | ||
393 | #define __irq_entry __attribute__((__section__(".irqentry.text"))) | ||
394 | |||
395 | /* Limits of hardirq entrypoints */ | ||
396 | extern char __irqentry_text_start[]; | ||
397 | extern char __irqentry_text_end[]; | ||
398 | |||
399 | #define FTRACE_RETFUNC_DEPTH 50 | ||
400 | #define FTRACE_RETSTACK_ALLOC_SIZE 32 | ||
401 | /* Type of the callback handlers for tracing function graph*/ | ||
402 | typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */ | ||
403 | typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */ | ||
404 | |||
405 | extern int register_ftrace_graph(trace_func_graph_ret_t retfunc, | ||
406 | trace_func_graph_ent_t entryfunc); | ||
407 | |||
408 | extern void ftrace_graph_stop(void); | ||
409 | |||
410 | /* The current handlers in use */ | ||
411 | extern trace_func_graph_ret_t ftrace_graph_return; | ||
412 | extern trace_func_graph_ent_t ftrace_graph_entry; | ||
413 | |||
414 | extern void unregister_ftrace_graph(void); | ||
415 | |||
416 | extern void ftrace_graph_init_task(struct task_struct *t); | ||
417 | extern void ftrace_graph_exit_task(struct task_struct *t); | ||
418 | |||
419 | static inline int task_curr_ret_stack(struct task_struct *t) | ||
420 | { | ||
421 | return t->curr_ret_stack; | ||
422 | } | ||
423 | |||
424 | static inline void pause_graph_tracing(void) | ||
425 | { | ||
426 | atomic_inc(¤t->tracing_graph_pause); | ||
427 | } | ||
428 | |||
429 | static inline void unpause_graph_tracing(void) | ||
430 | { | ||
431 | atomic_dec(¤t->tracing_graph_pause); | ||
432 | } | ||
246 | #else | 433 | #else |
247 | static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } | 434 | |
248 | static inline void start_boot_trace(void) { } | 435 | #define __notrace_funcgraph |
249 | static inline void stop_boot_trace(void) { } | 436 | #define __irq_entry |
437 | |||
438 | static inline void ftrace_graph_init_task(struct task_struct *t) { } | ||
439 | static inline void ftrace_graph_exit_task(struct task_struct *t) { } | ||
440 | |||
441 | static inline int task_curr_ret_stack(struct task_struct *tsk) | ||
442 | { | ||
443 | return -1; | ||
444 | } | ||
445 | |||
446 | static inline void pause_graph_tracing(void) { } | ||
447 | static inline void unpause_graph_tracing(void) { } | ||
250 | #endif | 448 | #endif |
251 | 449 | ||
450 | #ifdef CONFIG_TRACING | ||
451 | #include <linux/sched.h> | ||
452 | |||
453 | /* flags for current->trace */ | ||
454 | enum { | ||
455 | TSK_TRACE_FL_TRACE_BIT = 0, | ||
456 | TSK_TRACE_FL_GRAPH_BIT = 1, | ||
457 | }; | ||
458 | enum { | ||
459 | TSK_TRACE_FL_TRACE = 1 << TSK_TRACE_FL_TRACE_BIT, | ||
460 | TSK_TRACE_FL_GRAPH = 1 << TSK_TRACE_FL_GRAPH_BIT, | ||
461 | }; | ||
462 | |||
463 | static inline void set_tsk_trace_trace(struct task_struct *tsk) | ||
464 | { | ||
465 | set_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace); | ||
466 | } | ||
467 | |||
468 | static inline void clear_tsk_trace_trace(struct task_struct *tsk) | ||
469 | { | ||
470 | clear_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace); | ||
471 | } | ||
472 | |||
473 | static inline int test_tsk_trace_trace(struct task_struct *tsk) | ||
474 | { | ||
475 | return tsk->trace & TSK_TRACE_FL_TRACE; | ||
476 | } | ||
477 | |||
478 | static inline void set_tsk_trace_graph(struct task_struct *tsk) | ||
479 | { | ||
480 | set_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace); | ||
481 | } | ||
482 | |||
483 | static inline void clear_tsk_trace_graph(struct task_struct *tsk) | ||
484 | { | ||
485 | clear_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace); | ||
486 | } | ||
487 | |||
488 | static inline int test_tsk_trace_graph(struct task_struct *tsk) | ||
489 | { | ||
490 | return tsk->trace & TSK_TRACE_FL_GRAPH; | ||
491 | } | ||
252 | 492 | ||
493 | #endif /* CONFIG_TRACING */ | ||
253 | 494 | ||
254 | #endif /* _LINUX_FTRACE_H */ | 495 | #endif /* _LINUX_FTRACE_H */ |
diff --git a/include/linux/ftrace_irq.h b/include/linux/ftrace_irq.h new file mode 100644 index 000000000000..366a054d0b05 --- /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_GRAPH_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/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/marker.h b/include/linux/marker.h index 889196c7fbb1..b85e74ca782f 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. |
@@ -162,8 +211,10 @@ extern void *marker_get_private_data(const char *name, marker_probe_func *probe, | |||
162 | 211 | ||
163 | /* | 212 | /* |
164 | * marker_synchronize_unregister must be called between the last marker probe | 213 | * marker_synchronize_unregister must be called between the last marker probe |
165 | * unregistration and the end of module exit to make sure there is no caller | 214 | * unregistration and the first one of |
166 | * executing a probe when it is freed. | 215 | * - the end of module exit function |
216 | * - the free of any resource used by the probes | ||
217 | * to ensure the code and data are valid for any possibly running probes. | ||
167 | */ | 218 | */ |
168 | #define marker_synchronize_unregister() synchronize_sched() | 219 | #define marker_synchronize_unregister() synchronize_sched() |
169 | 220 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index d3ddd735e375..aaa8b843be28 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -1305,5 +1305,7 @@ int vmemmap_populate_basepages(struct page *start_page, | |||
1305 | int vmemmap_populate(struct page *start_page, unsigned long pages, int node); | 1305 | int vmemmap_populate(struct page *start_page, unsigned long pages, int node); |
1306 | void vmemmap_populate_print_last(void); | 1306 | void vmemmap_populate_print_last(void); |
1307 | 1307 | ||
1308 | extern void *alloc_locked_buffer(size_t size); | ||
1309 | extern void free_locked_buffer(void *buffer, size_t size); | ||
1308 | #endif /* __KERNEL__ */ | 1310 | #endif /* __KERNEL__ */ |
1309 | #endif /* _LINUX_MM_H */ | 1311 | #endif /* _LINUX_MM_H */ |
diff --git a/include/linux/pid.h b/include/linux/pid.h index d7e98ff8021e..bb206c56d1f0 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h | |||
@@ -147,9 +147,9 @@ pid_t pid_vnr(struct pid *pid); | |||
147 | #define do_each_pid_task(pid, type, task) \ | 147 | #define do_each_pid_task(pid, type, task) \ |
148 | do { \ | 148 | do { \ |
149 | struct hlist_node *pos___; \ | 149 | struct hlist_node *pos___; \ |
150 | if (pid != NULL) \ | 150 | if ((pid) != NULL) \ |
151 | hlist_for_each_entry_rcu((task), pos___, \ | 151 | hlist_for_each_entry_rcu((task), pos___, \ |
152 | &pid->tasks[type], pids[type].node) { | 152 | &(pid)->tasks[type], pids[type].node) { |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * Both old and new leaders may be attached to | 155 | * Both old and new leaders may be attached to |
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 22641d5d45df..98b93ca4db06 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h | |||
@@ -94,6 +94,7 @@ extern void ptrace_notify(int exit_code); | |||
94 | extern void __ptrace_link(struct task_struct *child, | 94 | extern void __ptrace_link(struct task_struct *child, |
95 | struct task_struct *new_parent); | 95 | struct task_struct *new_parent); |
96 | extern void __ptrace_unlink(struct task_struct *child); | 96 | extern void __ptrace_unlink(struct task_struct *child); |
97 | extern void ptrace_fork(struct task_struct *task, unsigned long clone_flags); | ||
97 | #define PTRACE_MODE_READ 1 | 98 | #define PTRACE_MODE_READ 1 |
98 | #define PTRACE_MODE_ATTACH 2 | 99 | #define PTRACE_MODE_ATTACH 2 |
99 | /* Returns 0 on success, -errno on denial. */ | 100 | /* Returns 0 on success, -errno on denial. */ |
@@ -313,6 +314,27 @@ static inline void user_enable_block_step(struct task_struct *task) | |||
313 | #define arch_ptrace_stop(code, info) do { } while (0) | 314 | #define arch_ptrace_stop(code, info) do { } while (0) |
314 | #endif | 315 | #endif |
315 | 316 | ||
317 | #ifndef arch_ptrace_untrace | ||
318 | /* | ||
319 | * Do machine-specific work before untracing child. | ||
320 | * | ||
321 | * This is called for a normal detach as well as from ptrace_exit() | ||
322 | * when the tracing task dies. | ||
323 | * | ||
324 | * Called with write_lock(&tasklist_lock) held. | ||
325 | */ | ||
326 | #define arch_ptrace_untrace(task) do { } while (0) | ||
327 | #endif | ||
328 | |||
329 | #ifndef arch_ptrace_fork | ||
330 | /* | ||
331 | * Do machine-specific work to initialize a new task. | ||
332 | * | ||
333 | * This is called from copy_process(). | ||
334 | */ | ||
335 | #define arch_ptrace_fork(child, clone_flags) do { } while (0) | ||
336 | #endif | ||
337 | |||
316 | extern int task_current_syscall(struct task_struct *target, long *callno, | 338 | extern int task_current_syscall(struct task_struct *target, long *callno, |
317 | unsigned long args[6], unsigned int maxargs, | 339 | unsigned long args[6], unsigned int maxargs, |
318 | unsigned long *sp, unsigned long *pc); | 340 | unsigned long *sp, unsigned long *pc); |
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..d363467c8f13 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h | |||
@@ -28,17 +28,19 @@ struct ring_buffer_event { | |||
28 | * size = 8 bytes | 28 | * size = 8 bytes |
29 | * | 29 | * |
30 | * @RINGBUF_TYPE_TIME_STAMP: Sync time stamp with external clock | 30 | * @RINGBUF_TYPE_TIME_STAMP: Sync time stamp with external clock |
31 | * array[0] = tv_nsec | 31 | * array[0] = tv_nsec |
32 | * array[1] = tv_sec | 32 | * array[1..2] = tv_sec |
33 | * size = 16 bytes | 33 | * size = 16 bytes |
34 | * | 34 | * |
35 | * @RINGBUF_TYPE_DATA: Data record | 35 | * @RINGBUF_TYPE_DATA: Data record |
36 | * If len is zero: | 36 | * If len is zero: |
37 | * array[0] holds the actual length | 37 | * array[0] holds the actual length |
38 | * array[1..(length+3)/4-1] holds data | 38 | * array[1..(length+3)/4] holds data |
39 | * size = 4 + 4 + length (bytes) | ||
39 | * else | 40 | * else |
40 | * length = len << 2 | 41 | * length = len << 2 |
41 | * array[0..(length+3)/4] holds data | 42 | * array[0..(length+3)/4-1] holds data |
43 | * size = 4 + length (bytes) | ||
42 | */ | 44 | */ |
43 | enum ring_buffer_type { | 45 | enum ring_buffer_type { |
44 | RINGBUF_TYPE_PADDING, | 46 | RINGBUF_TYPE_PADDING, |
@@ -122,6 +124,12 @@ void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); | |||
122 | 124 | ||
123 | void tracing_on(void); | 125 | void tracing_on(void); |
124 | void tracing_off(void); | 126 | void tracing_off(void); |
127 | void tracing_off_permanent(void); | ||
128 | |||
129 | void *ring_buffer_alloc_read_page(struct ring_buffer *buffer); | ||
130 | void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data); | ||
131 | int ring_buffer_read_page(struct ring_buffer *buffer, | ||
132 | void **data_page, int cpu, int full); | ||
125 | 133 | ||
126 | enum ring_buffer_flags { | 134 | enum ring_buffer_flags { |
127 | RB_FL_OVERWRITE = 1 << 0, | 135 | RB_FL_OVERWRITE = 1 << 0, |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 9624e2cfc2dc..0a1094d84b77 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -96,6 +96,7 @@ struct exec_domain; | |||
96 | struct futex_pi_state; | 96 | struct futex_pi_state; |
97 | struct robust_list_head; | 97 | struct robust_list_head; |
98 | struct bio; | 98 | struct bio; |
99 | struct bts_tracer; | ||
99 | 100 | ||
100 | /* | 101 | /* |
101 | * List of flags we want to share for kernel threads, | 102 | * List of flags we want to share for kernel threads, |
@@ -1130,6 +1131,19 @@ struct task_struct { | |||
1130 | struct list_head ptraced; | 1131 | struct list_head ptraced; |
1131 | struct list_head ptrace_entry; | 1132 | struct list_head ptrace_entry; |
1132 | 1133 | ||
1134 | #ifdef CONFIG_X86_PTRACE_BTS | ||
1135 | /* | ||
1136 | * This is the tracer handle for the ptrace BTS extension. | ||
1137 | * This field actually belongs to the ptracer task. | ||
1138 | */ | ||
1139 | struct bts_tracer *bts; | ||
1140 | /* | ||
1141 | * The buffer to hold the BTS data. | ||
1142 | */ | ||
1143 | void *bts_buffer; | ||
1144 | size_t bts_size; | ||
1145 | #endif /* CONFIG_X86_PTRACE_BTS */ | ||
1146 | |||
1133 | /* PID/PID hash table linkage. */ | 1147 | /* PID/PID hash table linkage. */ |
1134 | struct pid_link pids[PIDTYPE_MAX]; | 1148 | struct pid_link pids[PIDTYPE_MAX]; |
1135 | struct list_head thread_group; | 1149 | struct list_head thread_group; |
@@ -1313,6 +1327,23 @@ struct task_struct { | |||
1313 | unsigned long default_timer_slack_ns; | 1327 | unsigned long default_timer_slack_ns; |
1314 | 1328 | ||
1315 | struct list_head *scm_work_list; | 1329 | struct list_head *scm_work_list; |
1330 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
1331 | /* Index of current stored adress in ret_stack */ | ||
1332 | int curr_ret_stack; | ||
1333 | /* Stack of return addresses for return function tracing */ | ||
1334 | struct ftrace_ret_stack *ret_stack; | ||
1335 | /* | ||
1336 | * Number of functions that haven't been traced | ||
1337 | * because of depth overrun. | ||
1338 | */ | ||
1339 | atomic_t trace_overrun; | ||
1340 | /* Pause for the tracing */ | ||
1341 | atomic_t tracing_graph_pause; | ||
1342 | #endif | ||
1343 | #ifdef CONFIG_TRACING | ||
1344 | /* state flags for use by tracers */ | ||
1345 | unsigned long trace; | ||
1346 | #endif | ||
1316 | }; | 1347 | }; |
1317 | 1348 | ||
1318 | /* | 1349 | /* |
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/tty.h b/include/linux/tty.h index 580700f20a1c..3f4954c55e53 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -325,7 +325,7 @@ extern struct class *tty_class; | |||
325 | * go away | 325 | * go away |
326 | */ | 326 | */ |
327 | 327 | ||
328 | extern inline struct tty_struct *tty_kref_get(struct tty_struct *tty) | 328 | static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) |
329 | { | 329 | { |
330 | if (tty) | 330 | if (tty) |
331 | kref_get(&tty->kref); | 331 | kref_get(&tty->kref); |
diff --git a/include/trace/block.h b/include/trace/block.h new file mode 100644 index 000000000000..25c6a1fd5b77 --- /dev/null +++ b/include/trace/block.h | |||
@@ -0,0 +1,76 @@ | |||
1 | #ifndef _TRACE_BLOCK_H | ||
2 | #define _TRACE_BLOCK_H | ||
3 | |||
4 | #include <linux/blkdev.h> | ||
5 | #include <linux/tracepoint.h> | ||
6 | |||
7 | DECLARE_TRACE(block_rq_abort, | ||
8 | TPPROTO(struct request_queue *q, struct request *rq), | ||
9 | TPARGS(q, rq)); | ||
10 | |||
11 | DECLARE_TRACE(block_rq_insert, | ||
12 | TPPROTO(struct request_queue *q, struct request *rq), | ||
13 | TPARGS(q, rq)); | ||
14 | |||
15 | DECLARE_TRACE(block_rq_issue, | ||
16 | TPPROTO(struct request_queue *q, struct request *rq), | ||
17 | TPARGS(q, rq)); | ||
18 | |||
19 | DECLARE_TRACE(block_rq_requeue, | ||
20 | TPPROTO(struct request_queue *q, struct request *rq), | ||
21 | TPARGS(q, rq)); | ||
22 | |||
23 | DECLARE_TRACE(block_rq_complete, | ||
24 | TPPROTO(struct request_queue *q, struct request *rq), | ||
25 | TPARGS(q, rq)); | ||
26 | |||
27 | DECLARE_TRACE(block_bio_bounce, | ||
28 | TPPROTO(struct request_queue *q, struct bio *bio), | ||
29 | TPARGS(q, bio)); | ||
30 | |||
31 | DECLARE_TRACE(block_bio_complete, | ||
32 | TPPROTO(struct request_queue *q, struct bio *bio), | ||
33 | TPARGS(q, bio)); | ||
34 | |||
35 | DECLARE_TRACE(block_bio_backmerge, | ||
36 | TPPROTO(struct request_queue *q, struct bio *bio), | ||
37 | TPARGS(q, bio)); | ||
38 | |||
39 | DECLARE_TRACE(block_bio_frontmerge, | ||
40 | TPPROTO(struct request_queue *q, struct bio *bio), | ||
41 | TPARGS(q, bio)); | ||
42 | |||
43 | DECLARE_TRACE(block_bio_queue, | ||
44 | TPPROTO(struct request_queue *q, struct bio *bio), | ||
45 | TPARGS(q, bio)); | ||
46 | |||
47 | DECLARE_TRACE(block_getrq, | ||
48 | TPPROTO(struct request_queue *q, struct bio *bio, int rw), | ||
49 | TPARGS(q, bio, rw)); | ||
50 | |||
51 | DECLARE_TRACE(block_sleeprq, | ||
52 | TPPROTO(struct request_queue *q, struct bio *bio, int rw), | ||
53 | TPARGS(q, bio, rw)); | ||
54 | |||
55 | DECLARE_TRACE(block_plug, | ||
56 | TPPROTO(struct request_queue *q), | ||
57 | TPARGS(q)); | ||
58 | |||
59 | DECLARE_TRACE(block_unplug_timer, | ||
60 | TPPROTO(struct request_queue *q), | ||
61 | TPARGS(q)); | ||
62 | |||
63 | DECLARE_TRACE(block_unplug_io, | ||
64 | TPPROTO(struct request_queue *q), | ||
65 | TPARGS(q)); | ||
66 | |||
67 | DECLARE_TRACE(block_split, | ||
68 | TPPROTO(struct request_queue *q, struct bio *bio, unsigned int pdu), | ||
69 | TPARGS(q, bio, pdu)); | ||
70 | |||
71 | DECLARE_TRACE(block_remap, | ||
72 | TPPROTO(struct request_queue *q, struct bio *bio, dev_t dev, | ||
73 | sector_t from, sector_t to), | ||
74 | TPARGS(q, bio, dev, from, to)); | ||
75 | |||
76 | #endif | ||
diff --git a/include/trace/boot.h b/include/trace/boot.h new file mode 100644 index 000000000000..088ea089e31d --- /dev/null +++ b/include/trace/boot.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef _LINUX_TRACE_BOOT_H | ||
2 | #define _LINUX_TRACE_BOOT_H | ||
3 | |||
4 | #include <linux/module.h> | ||
5 | #include <linux/kallsyms.h> | ||
6 | #include <linux/init.h> | ||
7 | |||
8 | /* | ||
9 | * Structure which defines the trace of an initcall | ||
10 | * while it is called. | ||
11 | * You don't have to fill the func field since it is | ||
12 | * only used internally by the tracer. | ||
13 | */ | ||
14 | struct boot_trace_call { | ||
15 | pid_t caller; | ||
16 | char func[KSYM_SYMBOL_LEN]; | ||
17 | }; | ||
18 | |||
19 | /* | ||
20 | * Structure which defines the trace of an initcall | ||
21 | * while it returns. | ||
22 | */ | ||
23 | struct boot_trace_ret { | ||
24 | char func[KSYM_SYMBOL_LEN]; | ||
25 | int result; | ||
26 | unsigned long long duration; /* nsecs */ | ||
27 | }; | ||
28 | |||
29 | #ifdef CONFIG_BOOT_TRACER | ||
30 | /* Append the traces on the ring-buffer */ | ||
31 | extern void trace_boot_call(struct boot_trace_call *bt, initcall_t fn); | ||
32 | extern void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn); | ||
33 | |||
34 | /* Tells the tracer that smp_pre_initcall is finished. | ||
35 | * So we can start the tracing | ||
36 | */ | ||
37 | extern void start_boot_trace(void); | ||
38 | |||
39 | /* Resume the tracing of other necessary events | ||
40 | * such as sched switches | ||
41 | */ | ||
42 | extern void enable_boot_trace(void); | ||
43 | |||
44 | /* Suspend this tracing. Actually, only sched_switches tracing have | ||
45 | * to be suspended. Initcalls doesn't need it.) | ||
46 | */ | ||
47 | extern void disable_boot_trace(void); | ||
48 | #else | ||
49 | static inline | ||
50 | void trace_boot_call(struct boot_trace_call *bt, initcall_t fn) { } | ||
51 | |||
52 | static inline | ||
53 | void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn) { } | ||
54 | |||
55 | static inline void start_boot_trace(void) { } | ||
56 | static inline void enable_boot_trace(void) { } | ||
57 | static inline void disable_boot_trace(void) { } | ||
58 | #endif /* CONFIG_BOOT_TRACER */ | ||
59 | |||
60 | #endif /* __LINUX_TRACE_BOOT_H */ | ||
diff --git a/include/trace/sched.h b/include/trace/sched.h index ad47369d01b5..0d81098ee9fc 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, int success), |
21 | TPARGS(rq, p)); | 21 | TPARGS(rq, p, success)); |
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, int success), |
25 | TPARGS(rq, p)); | 25 | TPARGS(rq, p, success)); |
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 task_struct *p, int orig_cpu, int dest_cpu), |
34 | TPARGS(rq, p, dest_cpu)); | 34 | TPARGS(p, orig_cpu, 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 | ||