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/linux | |
| 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/linux')
| -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 |
16 files changed, 560 insertions, 237 deletions
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); |
