diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 18:27:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 18:27:43 -0400 |
commit | 4bb0057f996b1491f93a64879f4c53c83bc0f0c7 (patch) | |
tree | f216e244a6f88ede277a3687499dbb1762a3c37a /kernel/printk.c | |
parent | 116a9fb3ed98c19d1ee0c6c55971f5b753949393 (diff) | |
parent | 9e4144abf8a30ae221311368bbb10690ebdb4b76 (diff) |
Merge branch 'core/printk' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core/printk' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86, generic: mark early_printk as asmlinkage
printk: export console_drivers
printk: remember the message level for multi-line output
printk: refactor processing of line severity tokens
printk: don't prefer unsuited consoles on registration
printk: clean up recursion check related static variables
namespacecheck: more kernel/printk.c fixes
namespacecheck: fix kernel printk.c
Diffstat (limited to 'kernel/printk.c')
-rw-r--r-- | kernel/printk.c | 105 |
1 files changed, 43 insertions, 62 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 5d81a11321fd..07ad9e7f7a66 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -38,7 +38,7 @@ | |||
38 | /* | 38 | /* |
39 | * Architectures can override it: | 39 | * Architectures can override it: |
40 | */ | 40 | */ |
41 | void __attribute__((weak)) early_printk(const char *fmt, ...) | 41 | void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) |
42 | { | 42 | { |
43 | } | 43 | } |
44 | 44 | ||
@@ -235,7 +235,7 @@ static inline void boot_delay_msec(void) | |||
235 | /* | 235 | /* |
236 | * Return the number of unread characters in the log buffer. | 236 | * Return the number of unread characters in the log buffer. |
237 | */ | 237 | */ |
238 | int log_buf_get_len(void) | 238 | static int log_buf_get_len(void) |
239 | { | 239 | { |
240 | return logged_chars; | 240 | return logged_chars; |
241 | } | 241 | } |
@@ -272,19 +272,6 @@ int log_buf_copy(char *dest, int idx, int len) | |||
272 | } | 272 | } |
273 | 273 | ||
274 | /* | 274 | /* |
275 | * Extract a single character from the log buffer. | ||
276 | */ | ||
277 | int log_buf_read(int idx) | ||
278 | { | ||
279 | char ret; | ||
280 | |||
281 | if (log_buf_copy(&ret, idx, 1) == 1) | ||
282 | return ret; | ||
283 | else | ||
284 | return -1; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Commands to do_syslog: | 275 | * Commands to do_syslog: |
289 | * | 276 | * |
290 | * 0 -- Close the log. Currently a NOP. | 277 | * 0 -- Close the log. Currently a NOP. |
@@ -669,18 +656,17 @@ static int acquire_console_semaphore_for_printk(unsigned int cpu) | |||
669 | spin_unlock(&logbuf_lock); | 656 | spin_unlock(&logbuf_lock); |
670 | return retval; | 657 | return retval; |
671 | } | 658 | } |
672 | 659 | static const char recursion_bug_msg [] = | |
673 | static const char printk_recursion_bug_msg [] = | 660 | KERN_CRIT "BUG: recent printk recursion!\n"; |
674 | KERN_CRIT "BUG: recent printk recursion!\n"; | 661 | static int recursion_bug; |
675 | static int printk_recursion_bug; | 662 | static int new_text_line = 1; |
663 | static char printk_buf[1024]; | ||
676 | 664 | ||
677 | asmlinkage int vprintk(const char *fmt, va_list args) | 665 | asmlinkage int vprintk(const char *fmt, va_list args) |
678 | { | 666 | { |
679 | static int log_level_unknown = 1; | ||
680 | static char printk_buf[1024]; | ||
681 | |||
682 | unsigned long flags; | ||
683 | int printed_len = 0; | 667 | int printed_len = 0; |
668 | int current_log_level = default_message_loglevel; | ||
669 | unsigned long flags; | ||
684 | int this_cpu; | 670 | int this_cpu; |
685 | char *p; | 671 | char *p; |
686 | 672 | ||
@@ -703,7 +689,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
703 | * it can be printed at the next appropriate moment: | 689 | * it can be printed at the next appropriate moment: |
704 | */ | 690 | */ |
705 | if (!oops_in_progress) { | 691 | if (!oops_in_progress) { |
706 | printk_recursion_bug = 1; | 692 | recursion_bug = 1; |
707 | goto out_restore_irqs; | 693 | goto out_restore_irqs; |
708 | } | 694 | } |
709 | zap_locks(); | 695 | zap_locks(); |
@@ -713,70 +699,62 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
713 | spin_lock(&logbuf_lock); | 699 | spin_lock(&logbuf_lock); |
714 | printk_cpu = this_cpu; | 700 | printk_cpu = this_cpu; |
715 | 701 | ||
716 | if (printk_recursion_bug) { | 702 | if (recursion_bug) { |
717 | printk_recursion_bug = 0; | 703 | recursion_bug = 0; |
718 | strcpy(printk_buf, printk_recursion_bug_msg); | 704 | strcpy(printk_buf, recursion_bug_msg); |
719 | printed_len = sizeof(printk_recursion_bug_msg); | 705 | printed_len = sizeof(recursion_bug_msg); |
720 | } | 706 | } |
721 | /* Emit the output into the temporary buffer */ | 707 | /* Emit the output into the temporary buffer */ |
722 | printed_len += vscnprintf(printk_buf + printed_len, | 708 | printed_len += vscnprintf(printk_buf + printed_len, |
723 | sizeof(printk_buf) - printed_len, fmt, args); | 709 | sizeof(printk_buf) - printed_len, fmt, args); |
724 | 710 | ||
711 | |||
725 | /* | 712 | /* |
726 | * Copy the output into log_buf. If the caller didn't provide | 713 | * Copy the output into log_buf. If the caller didn't provide |
727 | * appropriate log level tags, we insert them here | 714 | * appropriate log level tags, we insert them here |
728 | */ | 715 | */ |
729 | for (p = printk_buf; *p; p++) { | 716 | for (p = printk_buf; *p; p++) { |
730 | if (log_level_unknown) { | 717 | if (new_text_line) { |
731 | /* log_level_unknown signals the start of a new line */ | 718 | /* If a token, set current_log_level and skip over */ |
719 | if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' && | ||
720 | p[2] == '>') { | ||
721 | current_log_level = p[1] - '0'; | ||
722 | p += 3; | ||
723 | printed_len -= 3; | ||
724 | } | ||
725 | |||
726 | /* Always output the token */ | ||
727 | emit_log_char('<'); | ||
728 | emit_log_char(current_log_level + '0'); | ||
729 | emit_log_char('>'); | ||
730 | printed_len += 3; | ||
731 | new_text_line = 0; | ||
732 | |||
732 | if (printk_time) { | 733 | if (printk_time) { |
733 | int loglev_char; | 734 | /* Follow the token with the time */ |
734 | char tbuf[50], *tp; | 735 | char tbuf[50], *tp; |
735 | unsigned tlen; | 736 | unsigned tlen; |
736 | unsigned long long t; | 737 | unsigned long long t; |
737 | unsigned long nanosec_rem; | 738 | unsigned long nanosec_rem; |
738 | 739 | ||
739 | /* | ||
740 | * force the log level token to be | ||
741 | * before the time output. | ||
742 | */ | ||
743 | if (p[0] == '<' && p[1] >='0' && | ||
744 | p[1] <= '7' && p[2] == '>') { | ||
745 | loglev_char = p[1]; | ||
746 | p += 3; | ||
747 | printed_len -= 3; | ||
748 | } else { | ||
749 | loglev_char = default_message_loglevel | ||
750 | + '0'; | ||
751 | } | ||
752 | t = cpu_clock(printk_cpu); | 740 | t = cpu_clock(printk_cpu); |
753 | nanosec_rem = do_div(t, 1000000000); | 741 | nanosec_rem = do_div(t, 1000000000); |
754 | tlen = sprintf(tbuf, | 742 | tlen = sprintf(tbuf, "[%5lu.%06lu] ", |
755 | "<%c>[%5lu.%06lu] ", | 743 | (unsigned long) t, |
756 | loglev_char, | 744 | nanosec_rem / 1000); |
757 | (unsigned long)t, | ||
758 | nanosec_rem/1000); | ||
759 | 745 | ||
760 | for (tp = tbuf; tp < tbuf + tlen; tp++) | 746 | for (tp = tbuf; tp < tbuf + tlen; tp++) |
761 | emit_log_char(*tp); | 747 | emit_log_char(*tp); |
762 | printed_len += tlen; | 748 | printed_len += tlen; |
763 | } else { | ||
764 | if (p[0] != '<' || p[1] < '0' || | ||
765 | p[1] > '7' || p[2] != '>') { | ||
766 | emit_log_char('<'); | ||
767 | emit_log_char(default_message_loglevel | ||
768 | + '0'); | ||
769 | emit_log_char('>'); | ||
770 | printed_len += 3; | ||
771 | } | ||
772 | } | 749 | } |
773 | log_level_unknown = 0; | 750 | |
774 | if (!*p) | 751 | if (!*p) |
775 | break; | 752 | break; |
776 | } | 753 | } |
754 | |||
777 | emit_log_char(*p); | 755 | emit_log_char(*p); |
778 | if (*p == '\n') | 756 | if (*p == '\n') |
779 | log_level_unknown = 1; | 757 | new_text_line = 1; |
780 | } | 758 | } |
781 | 759 | ||
782 | /* | 760 | /* |
@@ -1179,8 +1157,11 @@ void register_console(struct console *console) | |||
1179 | console->index = 0; | 1157 | console->index = 0; |
1180 | if (console->setup == NULL || | 1158 | if (console->setup == NULL || |
1181 | console->setup(console, NULL) == 0) { | 1159 | console->setup(console, NULL) == 0) { |
1182 | console->flags |= CON_ENABLED | CON_CONSDEV; | 1160 | console->flags |= CON_ENABLED; |
1183 | preferred_console = 0; | 1161 | if (console->device) { |
1162 | console->flags |= CON_CONSDEV; | ||
1163 | preferred_console = 0; | ||
1164 | } | ||
1184 | } | 1165 | } |
1185 | } | 1166 | } |
1186 | 1167 | ||