diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-05-02 12:52:01 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-05-02 12:52:01 -0400 |
commit | 8cb836469d2ace489857d90c4856e97c255128b9 (patch) | |
tree | 81e0af4a810c563d36dd3de1899256214bb965fd | |
parent | 41301f22043f92a0a3ee0b7cea8c717555fbe796 (diff) |
litmus core: add dump-trace-buffer magic sysrq
Pump stuff from the TRACE() buffer to printk() on demand.
-rw-r--r-- | include/litmus/sched_trace.h | 2 | ||||
-rw-r--r-- | kernel/printk.c | 3 | ||||
-rw-r--r-- | litmus/sched_trace.c | 47 |
3 files changed, 49 insertions, 3 deletions
diff --git a/include/litmus/sched_trace.h b/include/litmus/sched_trace.h index 28feee82dc..afd0391d12 100644 --- a/include/litmus/sched_trace.h +++ b/include/litmus/sched_trace.h | |||
@@ -179,7 +179,7 @@ feather_callback void do_sched_trace_sys_release(unsigned long id, | |||
179 | 179 | ||
180 | #ifdef CONFIG_SCHED_DEBUG_TRACE | 180 | #ifdef CONFIG_SCHED_DEBUG_TRACE |
181 | void sched_trace_log_message(const char* fmt, ...); | 181 | void sched_trace_log_message(const char* fmt, ...); |
182 | 182 | void dump_trace_buffer(int max); | |
183 | #else | 183 | #else |
184 | 184 | ||
185 | #define sched_trace_log_message(fmt, ...) | 185 | #define sched_trace_log_message(fmt, ...) |
diff --git a/kernel/printk.c b/kernel/printk.c index 9eb2dc5e27..4423a5542e 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -59,6 +59,7 @@ int console_printk[4] = { | |||
59 | */ | 59 | */ |
60 | #include <litmus/litmus.h> | 60 | #include <litmus/litmus.h> |
61 | int trace_override = 0; | 61 | int trace_override = 0; |
62 | int trace_recurse = 0; | ||
62 | 63 | ||
63 | /* | 64 | /* |
64 | * Low level drivers may need that to know if they can schedule in | 65 | * Low level drivers may need that to know if they can schedule in |
@@ -658,7 +659,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
658 | 659 | ||
659 | /* Emit the output into the temporary buffer */ | 660 | /* Emit the output into the temporary buffer */ |
660 | printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); | 661 | printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); |
661 | if (trace_override) | 662 | if (trace_override && !trace_recurse) |
662 | TRACE("%s", printk_buf); | 663 | TRACE("%s", printk_buf); |
663 | 664 | ||
664 | /* | 665 | /* |
diff --git a/litmus/sched_trace.c b/litmus/sched_trace.c index 527a58b696..9ee6f02a61 100644 --- a/litmus/sched_trace.c +++ b/litmus/sched_trace.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <asm/semaphore.h> | 9 | #include <asm/semaphore.h> |
10 | #include <asm/uaccess.h> | 10 | #include <asm/uaccess.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sysrq.h> | ||
12 | 13 | ||
13 | #include <litmus/sched_trace.h> | 14 | #include <litmus/sched_trace.h> |
14 | #include <litmus/litmus.h> | 15 | #include <litmus/litmus.h> |
@@ -300,7 +301,10 @@ static ssize_t log_read(struct file *filp, char __user *to, size_t len, | |||
300 | 301 | ||
301 | 302 | ||
302 | 303 | ||
304 | /* in kernel/printk.c */ | ||
303 | extern int trace_override; | 305 | extern int trace_override; |
306 | extern int trace_recurse; | ||
307 | |||
304 | 308 | ||
305 | /* log_open - open the global log message ring buffer. | 309 | /* log_open - open the global log message ring buffer. |
306 | */ | 310 | */ |
@@ -328,7 +332,8 @@ static int log_open(struct inode *in, struct file *filp) | |||
328 | error = 0; | 332 | error = 0; |
329 | filp->private_data = buf; | 333 | filp->private_data = buf; |
330 | printk(KERN_DEBUG "sched_trace buf: from 0x%p to 0x%p length: %x\n", | 334 | printk(KERN_DEBUG "sched_trace buf: from 0x%p to 0x%p length: %x\n", |
331 | buf->buf.buf, buf->buf.end, buf->buf.end - buf->buf.buf); | 335 | buf->buf.buf, buf->buf.end, |
336 | (unsigned int) (buf->buf.end - buf->buf.buf)); | ||
332 | trace_override++; | 337 | trace_override++; |
333 | out_unlock: | 338 | out_unlock: |
334 | up(&buf->reader_mutex); | 339 | up(&buf->reader_mutex); |
@@ -415,11 +420,35 @@ static int __init register_buffer_dev(const char* name, | |||
415 | 420 | ||
416 | } | 421 | } |
417 | 422 | ||
423 | #ifdef CONFIG_MAGIC_SYSRQ | ||
424 | |||
425 | static void sysrq_dump_trace_buffer(int key, struct tty_struct *tty) | ||
426 | { | ||
427 | dump_trace_buffer(100); | ||
428 | } | ||
429 | |||
430 | static struct sysrq_key_op sysrq_dump_trace_buffer_op = { | ||
431 | .handler = sysrq_dump_trace_buffer, | ||
432 | .help_msg = "dump-trace-buffer(Y)", | ||
433 | .action_msg = "writing content of TRACE() buffer", | ||
434 | }; | ||
435 | |||
436 | #endif | ||
437 | |||
418 | static int __init init_sched_trace(void) | 438 | static int __init init_sched_trace(void) |
419 | { | 439 | { |
420 | printk("Initializing TRACE() device\n"); | 440 | printk("Initializing TRACE() device\n"); |
421 | init_log_buffer(); | 441 | init_log_buffer(); |
422 | 442 | ||
443 | #ifdef CONFIG_MAGIC_SYSRQ | ||
444 | /* offer some debugging help */ | ||
445 | if (!register_sysrq_key('y', &sysrq_dump_trace_buffer_op)) | ||
446 | printk("Registered dump-trace-buffer(Y) magic sysrq.\n"); | ||
447 | else | ||
448 | printk("Could not register dump-trace-buffer(Y) magic sysrq.\n"); | ||
449 | #endif | ||
450 | |||
451 | |||
423 | return register_buffer_dev("litmus_log", &log_fops, | 452 | return register_buffer_dev("litmus_log", &log_fops, |
424 | LOG_MAJOR, 1); | 453 | LOG_MAJOR, 1); |
425 | } | 454 | } |
@@ -460,3 +489,19 @@ void sched_trace_log_message(const char* fmt, ...) | |||
460 | local_irq_restore(flags); | 489 | local_irq_restore(flags); |
461 | va_end(args); | 490 | va_end(args); |
462 | } | 491 | } |
492 | |||
493 | void dump_trace_buffer(int max) | ||
494 | { | ||
495 | char line[80]; | ||
496 | int len; | ||
497 | int count = 0; | ||
498 | |||
499 | /* potential but very unlikely race... */ | ||
500 | trace_recurse = 1; | ||
501 | while ((max == 0 || count++ < max) && | ||
502 | (len = rb_get(&log_buffer.buf, line, sizeof(line) - 1)) > 0) { | ||
503 | line[len] = '\0'; | ||
504 | printk("%s", line); | ||
505 | } | ||
506 | trace_recurse = 0; | ||
507 | } | ||