diff options
-rw-r--r-- | arch/x86/kernel/early_printk.c | 2 | ||||
-rw-r--r-- | include/linux/kernel.h | 8 | ||||
-rw-r--r-- | kernel/printk.c | 105 |
3 files changed, 45 insertions, 70 deletions
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 643fd861b724..ff9e7350da54 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
@@ -196,7 +196,7 @@ static struct console simnow_console = { | |||
196 | static struct console *early_console = &early_vga_console; | 196 | static struct console *early_console = &early_vga_console; |
197 | static int early_console_initialized; | 197 | static int early_console_initialized; |
198 | 198 | ||
199 | void early_printk(const char *fmt, ...) | 199 | asmlinkage void early_printk(const char *fmt, ...) |
200 | { | 200 | { |
201 | char buf[512]; | 201 | char buf[512]; |
202 | int n; | 202 | int n; |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 2e70006c7fa8..f9cd7a513f9c 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -187,9 +187,6 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
187 | __attribute__ ((format (printf, 1, 0))); | 187 | __attribute__ ((format (printf, 1, 0))); |
188 | asmlinkage int printk(const char * fmt, ...) | 188 | asmlinkage int printk(const char * fmt, ...) |
189 | __attribute__ ((format (printf, 1, 2))) __cold; | 189 | __attribute__ ((format (printf, 1, 2))) __cold; |
190 | extern int log_buf_get_len(void); | ||
191 | extern int log_buf_read(int idx); | ||
192 | extern int log_buf_copy(char *dest, int idx, int len); | ||
193 | 190 | ||
194 | extern int printk_ratelimit_jiffies; | 191 | extern int printk_ratelimit_jiffies; |
195 | extern int printk_ratelimit_burst; | 192 | extern int printk_ratelimit_burst; |
@@ -205,9 +202,6 @@ static inline int vprintk(const char *s, va_list args) { return 0; } | |||
205 | static inline int printk(const char *s, ...) | 202 | static inline int printk(const char *s, ...) |
206 | __attribute__ ((format (printf, 1, 2))); | 203 | __attribute__ ((format (printf, 1, 2))); |
207 | static inline int __cold printk(const char *s, ...) { return 0; } | 204 | static inline int __cold printk(const char *s, ...) { return 0; } |
208 | static inline int log_buf_get_len(void) { return 0; } | ||
209 | static inline int log_buf_read(int idx) { return 0; } | ||
210 | static inline int log_buf_copy(char *dest, int idx, int len) { return 0; } | ||
211 | static inline int printk_ratelimit(void) { return 0; } | 205 | static inline int printk_ratelimit(void) { return 0; } |
212 | static inline int __printk_ratelimit(int ratelimit_jiffies, \ | 206 | static inline int __printk_ratelimit(int ratelimit_jiffies, \ |
213 | int ratelimit_burst) { return 0; } | 207 | int ratelimit_burst) { return 0; } |
@@ -216,7 +210,7 @@ static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ | |||
216 | { return false; } | 210 | { return false; } |
217 | #endif | 211 | #endif |
218 | 212 | ||
219 | extern void __attribute__((format(printf, 1, 2))) | 213 | extern void asmlinkage __attribute__((format(printf, 1, 2))) |
220 | early_printk(const char *fmt, ...); | 214 | early_printk(const char *fmt, ...); |
221 | 215 | ||
222 | unsigned long int_sqrt(unsigned long); | 216 | unsigned long int_sqrt(unsigned long); |
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 | ||