aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/early_printk.c2
-rw-r--r--include/linux/kernel.h8
-rw-r--r--kernel/printk.c105
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 = {
196static struct console *early_console = &early_vga_console; 196static struct console *early_console = &early_vga_console;
197static int early_console_initialized; 197static int early_console_initialized;
198 198
199void early_printk(const char *fmt, ...) 199asmlinkage 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)));
188asmlinkage int printk(const char * fmt, ...) 188asmlinkage int printk(const char * fmt, ...)
189 __attribute__ ((format (printf, 1, 2))) __cold; 189 __attribute__ ((format (printf, 1, 2))) __cold;
190extern int log_buf_get_len(void);
191extern int log_buf_read(int idx);
192extern int log_buf_copy(char *dest, int idx, int len);
193 190
194extern int printk_ratelimit_jiffies; 191extern int printk_ratelimit_jiffies;
195extern int printk_ratelimit_burst; 192extern int printk_ratelimit_burst;
@@ -205,9 +202,6 @@ static inline int vprintk(const char *s, va_list args) { return 0; }
205static inline int printk(const char *s, ...) 202static inline int printk(const char *s, ...)
206 __attribute__ ((format (printf, 1, 2))); 203 __attribute__ ((format (printf, 1, 2)));
207static inline int __cold printk(const char *s, ...) { return 0; } 204static inline int __cold printk(const char *s, ...) { return 0; }
208static inline int log_buf_get_len(void) { return 0; }
209static inline int log_buf_read(int idx) { return 0; }
210static inline int log_buf_copy(char *dest, int idx, int len) { return 0; }
211static inline int printk_ratelimit(void) { return 0; } 205static inline int printk_ratelimit(void) { return 0; }
212static inline int __printk_ratelimit(int ratelimit_jiffies, \ 206static 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
219extern void __attribute__((format(printf, 1, 2))) 213extern void asmlinkage __attribute__((format(printf, 1, 2)))
220 early_printk(const char *fmt, ...); 214 early_printk(const char *fmt, ...);
221 215
222unsigned long int_sqrt(unsigned long); 216unsigned 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 */
41void __attribute__((weak)) early_printk(const char *fmt, ...) 41void 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 */
238int log_buf_get_len(void) 238static 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 */
277int 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 659static const char recursion_bug_msg [] =
673static const char printk_recursion_bug_msg [] = 660 KERN_CRIT "BUG: recent printk recursion!\n";
674 KERN_CRIT "BUG: recent printk recursion!\n"; 661static int recursion_bug;
675static int printk_recursion_bug; 662 static int new_text_line = 1;
663static char printk_buf[1024];
676 664
677asmlinkage int vprintk(const char *fmt, va_list args) 665asmlinkage 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