diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-05-11 18:28:09 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-05-11 18:28:09 -0400 |
commit | 1b0b2b02697583bbe3aa6060e3f28d0a75c66ab6 (patch) | |
tree | 381eef92a9331e10ecff9d6c97a33719f2309221 | |
parent | d6c62a40cd5378f816a81ef62b34357614c5d21e (diff) |
TRACE(): facilitate debugging
- don't deadlock on a runqueue lock in case of a bug inside
the scheduler
- write printk() messages to TRACE()
- tell user of TRACE() buffer
-rw-r--r-- | kernel/printk.c | 10 | ||||
-rw-r--r-- | litmus/sched_trace.c | 32 |
2 files changed, 39 insertions, 3 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 89011bf8c1..9eb2dc5e27 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -54,6 +54,12 @@ int console_printk[4] = { | |||
54 | DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ | 54 | DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* divert printk() messages when we have a LITMUS^RT | ||
58 | * debug listener | ||
59 | */ | ||
60 | #include <litmus/litmus.h> | ||
61 | int trace_override = 0; | ||
62 | |||
57 | /* | 63 | /* |
58 | * Low level drivers may need that to know if they can schedule in | 64 | * Low level drivers may need that to know if they can schedule in |
59 | * their unblank() callback or not. So let's export it. | 65 | * their unblank() callback or not. So let's export it. |
@@ -652,6 +658,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
652 | 658 | ||
653 | /* Emit the output into the temporary buffer */ | 659 | /* Emit the output into the temporary buffer */ |
654 | printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); | 660 | printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); |
661 | if (trace_override) | ||
662 | TRACE("%s", printk_buf); | ||
655 | 663 | ||
656 | /* | 664 | /* |
657 | * Copy the output into log_buf. If the caller didn't provide | 665 | * Copy the output into log_buf. If the caller didn't provide |
@@ -932,7 +940,7 @@ int is_console_locked(void) | |||
932 | 940 | ||
933 | void wake_up_klogd(void) | 941 | void wake_up_klogd(void) |
934 | { | 942 | { |
935 | if (!oops_in_progress && waitqueue_active(&log_wait)) | 943 | if (!trace_override && !oops_in_progress && waitqueue_active(&log_wait)) |
936 | wake_up_interruptible(&log_wait); | 944 | wake_up_interruptible(&log_wait); |
937 | } | 945 | } |
938 | 946 | ||
diff --git a/litmus/sched_trace.c b/litmus/sched_trace.c index 0976e830ad..43447851da 100644 --- a/litmus/sched_trace.c +++ b/litmus/sched_trace.c | |||
@@ -373,6 +373,9 @@ static int trace_open(struct inode *in, struct file *filp) | |||
373 | return error; | 373 | return error; |
374 | } | 374 | } |
375 | 375 | ||
376 | |||
377 | extern int trace_override; | ||
378 | |||
376 | /* log_open - open the global log message ring buffer. | 379 | /* log_open - open the global log message ring buffer. |
377 | */ | 380 | */ |
378 | static int log_open(struct inode *in, struct file *filp) | 381 | static int log_open(struct inode *in, struct file *filp) |
@@ -398,13 +401,38 @@ static int log_open(struct inode *in, struct file *filp) | |||
398 | 401 | ||
399 | error = 0; | 402 | error = 0; |
400 | filp->private_data = buf; | 403 | filp->private_data = buf; |
401 | 404 | printk(KERN_DEBUG "sched_trace buf: from 0x%p to 0x%p length: %lx\n", | |
405 | buf->buf.buf, buf->buf.end, buf->buf.end - buf->buf.buf); | ||
406 | trace_override++; | ||
402 | out_unlock: | 407 | out_unlock: |
403 | up(&buf->reader_mutex); | 408 | up(&buf->reader_mutex); |
404 | out: | 409 | out: |
405 | return error; | 410 | return error; |
406 | } | 411 | } |
407 | 412 | ||
413 | static int log_release(struct inode *in, struct file *filp) | ||
414 | { | ||
415 | int error = -EINVAL; | ||
416 | trace_buffer_t* buf = filp->private_data; | ||
417 | |||
418 | BUG_ON(!filp->private_data); | ||
419 | |||
420 | if (down_interruptible(&buf->reader_mutex)) { | ||
421 | error = -ERESTARTSYS; | ||
422 | goto out; | ||
423 | } | ||
424 | |||
425 | /* last release must deallocate buffers */ | ||
426 | if (atomic_dec_return(&buf->reader_cnt) == 0) { | ||
427 | error = rb_free_buf(&buf->buf); | ||
428 | } | ||
429 | |||
430 | trace_override--; | ||
431 | up(&buf->reader_mutex); | ||
432 | out: | ||
433 | return error; | ||
434 | } | ||
435 | |||
408 | /******************************************************************************/ | 436 | /******************************************************************************/ |
409 | /* Device Registration */ | 437 | /* Device Registration */ |
410 | /******************************************************************************/ | 438 | /******************************************************************************/ |
@@ -434,7 +462,7 @@ struct file_operations trace_fops = { | |||
434 | struct file_operations log_fops = { | 462 | struct file_operations log_fops = { |
435 | .owner = THIS_MODULE, | 463 | .owner = THIS_MODULE, |
436 | .open = log_open, | 464 | .open = log_open, |
437 | .release = trace_release, | 465 | .release = log_release, |
438 | .read = trace_read, | 466 | .read = trace_read, |
439 | }; | 467 | }; |
440 | 468 | ||