diff options
Diffstat (limited to 'include/linux/kernel.h')
| -rw-r--r-- | include/linux/kernel.h | 80 | 
1 files changed, 76 insertions, 4 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 08bf5da86676..4e726b9a71ec 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h  | |||
| @@ -242,6 +242,19 @@ extern struct ratelimit_state printk_ratelimit_state; | |||
| 242 | extern int printk_ratelimit(void); | 242 | extern int printk_ratelimit(void); | 
| 243 | extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, | 243 | extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, | 
| 244 | unsigned int interval_msec); | 244 | unsigned int interval_msec); | 
| 245 | |||
| 246 | /* | ||
| 247 | * Print a one-time message (analogous to WARN_ONCE() et al): | ||
| 248 | */ | ||
| 249 | #define printk_once(x...) ({ \ | ||
| 250 | static int __print_once = 1; \ | ||
| 251 | \ | ||
| 252 | if (__print_once) { \ | ||
| 253 | __print_once = 0; \ | ||
| 254 | printk(x); \ | ||
| 255 | } \ | ||
| 256 | }) | ||
| 257 | |||
| 245 | #else | 258 | #else | 
| 246 | static inline int vprintk(const char *s, va_list args) | 259 | static inline int vprintk(const char *s, va_list args) | 
| 247 | __attribute__ ((format (printf, 1, 0))); | 260 | __attribute__ ((format (printf, 1, 0))); | 
| @@ -253,6 +266,10 @@ static inline int printk_ratelimit(void) { return 0; } | |||
| 253 | static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ | 266 | static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ | 
| 254 | unsigned int interval_msec) \ | 267 | unsigned int interval_msec) \ | 
| 255 | { return false; } | 268 | { return false; } | 
| 269 | |||
| 270 | /* No effect, but we still get type checking even in the !PRINTK case: */ | ||
| 271 | #define printk_once(x...) printk(x) | ||
| 272 | |||
| 256 | #endif | 273 | #endif | 
| 257 | 274 | ||
| 258 | extern int printk_needs_cpu(int cpu); | 275 | extern int printk_needs_cpu(int cpu); | 
| @@ -369,8 +386,35 @@ static inline char *pack_hex_byte(char *buf, u8 byte) | |||
| 369 | 386 | ||
| 370 | /* | 387 | /* | 
| 371 | * General tracing related utility functions - trace_printk(), | 388 | * General tracing related utility functions - trace_printk(), | 
| 372 | * tracing_start()/tracing_stop: | 389 | * tracing_on/tracing_off and tracing_start()/tracing_stop | 
| 390 | * | ||
| 391 | * Use tracing_on/tracing_off when you want to quickly turn on or off | ||
| 392 | * tracing. It simply enables or disables the recording of the trace events. | ||
| 393 | * This also corresponds to the user space debugfs/tracing/tracing_on | ||
| 394 | * file, which gives a means for the kernel and userspace to interact. | ||
| 395 | * Place a tracing_off() in the kernel where you want tracing to end. | ||
| 396 | * From user space, examine the trace, and then echo 1 > tracing_on | ||
| 397 | * to continue tracing. | ||
| 398 | * | ||
| 399 | * tracing_stop/tracing_start has slightly more overhead. It is used | ||
| 400 | * by things like suspend to ram where disabling the recording of the | ||
| 401 | * trace is not enough, but tracing must actually stop because things | ||
| 402 | * like calling smp_processor_id() may crash the system. | ||
| 403 | * | ||
| 404 | * Most likely, you want to use tracing_on/tracing_off. | ||
| 373 | */ | 405 | */ | 
| 406 | #ifdef CONFIG_RING_BUFFER | ||
| 407 | void tracing_on(void); | ||
| 408 | void tracing_off(void); | ||
| 409 | /* trace_off_permanent stops recording with no way to bring it back */ | ||
| 410 | void tracing_off_permanent(void); | ||
| 411 | int tracing_is_on(void); | ||
| 412 | #else | ||
| 413 | static inline void tracing_on(void) { } | ||
| 414 | static inline void tracing_off(void) { } | ||
| 415 | static inline void tracing_off_permanent(void) { } | ||
| 416 | static inline int tracing_is_on(void) { return 0; } | ||
| 417 | #endif | ||
| 374 | #ifdef CONFIG_TRACING | 418 | #ifdef CONFIG_TRACING | 
| 375 | extern void tracing_start(void); | 419 | extern void tracing_start(void); | 
| 376 | extern void tracing_stop(void); | 420 | extern void tracing_stop(void); | 
| @@ -379,6 +423,16 @@ extern void ftrace_off_permanent(void); | |||
| 379 | extern void | 423 | extern void | 
| 380 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | 424 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | 
| 381 | 425 | ||
| 426 | static inline void __attribute__ ((format (printf, 1, 2))) | ||
| 427 | ____trace_printk_check_format(const char *fmt, ...) | ||
| 428 | { | ||
| 429 | } | ||
| 430 | #define __trace_printk_check_format(fmt, args...) \ | ||
| 431 | do { \ | ||
| 432 | if (0) \ | ||
| 433 | ____trace_printk_check_format(fmt, ##args); \ | ||
| 434 | } while (0) | ||
| 435 | |||
| 382 | /** | 436 | /** | 
| 383 | * trace_printk - printf formatting in the ftrace buffer | 437 | * trace_printk - printf formatting in the ftrace buffer | 
| 384 | * @fmt: the printf format for printing | 438 | * @fmt: the printf format for printing | 
| @@ -395,13 +449,31 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | |||
| 395 | * Please refrain from leaving trace_printks scattered around in | 449 | * Please refrain from leaving trace_printks scattered around in | 
| 396 | * your code. | 450 | * your code. | 
| 397 | */ | 451 | */ | 
| 398 | # define trace_printk(fmt...) __trace_printk(_THIS_IP_, fmt) | 452 | |
| 453 | #define trace_printk(fmt, args...) \ | ||
| 454 | do { \ | ||
| 455 | static const char *trace_printk_fmt \ | ||
| 456 | __attribute__((section("__trace_printk_fmt"))); \ | ||
| 457 | trace_printk_fmt = fmt; \ | ||
| 458 | __trace_printk_check_format(fmt, ##args); \ | ||
| 459 | __trace_printk(_THIS_IP_, trace_printk_fmt, ##args); \ | ||
| 460 | } while (0) | ||
| 461 | |||
| 399 | extern int | 462 | extern int | 
| 400 | __trace_printk(unsigned long ip, const char *fmt, ...) | 463 | __trace_printk(unsigned long ip, const char *fmt, ...) | 
| 401 | __attribute__ ((format (printf, 2, 3))); | 464 | __attribute__ ((format (printf, 2, 3))); | 
| 402 | # define ftrace_vprintk(fmt, ap) __trace_printk(_THIS_IP_, fmt, ap) | 465 | |
| 466 | #define ftrace_vprintk(fmt, vargs) \ | ||
| 467 | do { \ | ||
| 468 | static const char *trace_printk_fmt \ | ||
| 469 | __attribute__((section("__trace_printk_fmt"))); \ | ||
| 470 | trace_printk_fmt = fmt; \ | ||
| 471 | __ftrace_vprintk(_THIS_IP_, trace_printk_fmt, vargs); \ | ||
| 472 | } while (0) | ||
| 473 | |||
| 403 | extern int | 474 | extern int | 
| 404 | __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); | 475 | __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); | 
| 476 | |||
| 405 | extern void ftrace_dump(void); | 477 | extern void ftrace_dump(void); | 
| 406 | #else | 478 | #else | 
| 407 | static inline void | 479 | static inline void | 
| @@ -423,7 +495,7 @@ ftrace_vprintk(const char *fmt, va_list ap) | |||
| 423 | return 0; | 495 | return 0; | 
| 424 | } | 496 | } | 
| 425 | static inline void ftrace_dump(void) { } | 497 | static inline void ftrace_dump(void) { } | 
| 426 | #endif | 498 | #endif /* CONFIG_TRACING */ | 
| 427 | 499 | ||
| 428 | /* | 500 | /* | 
| 429 | * Display an IP address in readable format. | 501 | * Display an IP address in readable format. | 
