aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-05-02 12:52:01 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-05-02 12:52:01 -0400
commit8cb836469d2ace489857d90c4856e97c255128b9 (patch)
tree81e0af4a810c563d36dd3de1899256214bb965fd
parent41301f22043f92a0a3ee0b7cea8c717555fbe796 (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.h2
-rw-r--r--kernel/printk.c3
-rw-r--r--litmus/sched_trace.c47
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
181void sched_trace_log_message(const char* fmt, ...); 181void sched_trace_log_message(const char* fmt, ...);
182 182void 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>
61int trace_override = 0; 61int trace_override = 0;
62int 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 */
303extern int trace_override; 305extern int trace_override;
306extern 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
425static void sysrq_dump_trace_buffer(int key, struct tty_struct *tty)
426{
427 dump_trace_buffer(100);
428}
429
430static 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
418static int __init init_sched_trace(void) 438static 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
493void 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}