Merge branch 'core/printk' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Jul 2008 22:27:43 +0000 (15:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Jul 2008 22:27:43 +0000 (15:27 -0700)
* '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

1  2 
kernel/printk.c

diff --combined kernel/printk.c
@@@ -38,7 -38,7 +38,7 @@@
  /*
   * Architectures can override it:
   */
- void __attribute__((weak)) early_printk(const char *fmt, ...)
+ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
  {
  }
  
@@@ -123,8 -123,6 +123,8 @@@ struct console_cmdlin
  static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
  static int selected_console = -1;
  static int preferred_console = -1;
 +int console_set_on_cmdline;
 +EXPORT_SYMBOL(console_set_on_cmdline);
  
  /* Flag: console code may call schedule() */
  static int console_may_schedule;
@@@ -235,7 -233,7 +235,7 @@@ static inline void boot_delay_msec(void
  /*
   * Return the number of unread characters in the log buffer.
   */
- int log_buf_get_len(void)
static int log_buf_get_len(void)
  {
        return logged_chars;
  }
@@@ -271,19 -269,6 +271,6 @@@ int log_buf_copy(char *dest, int idx, i
        return ret;
  }
  
- /*
-  * Extract a single character from the log buffer.
-  */
- int log_buf_read(int idx)
- {
-       char ret;
-       if (log_buf_copy(&ret, idx, 1) == 1)
-               return ret;
-       else
-               return -1;
- }
  /*
   * Commands to do_syslog:
   *
@@@ -669,18 -654,17 +656,17 @@@ static int acquire_console_semaphore_fo
        spin_unlock(&logbuf_lock);
        return retval;
  }
- static const char printk_recursion_bug_msg [] =
-                       KERN_CRIT "BUG: recent printk recursion!\n";
- static int printk_recursion_bug;
+ static const char recursion_bug_msg [] =
+               KERN_CRIT "BUG: recent printk recursion!\n";
+ static int recursion_bug;
+       static int new_text_line = 1;
+ static char printk_buf[1024];
  
  asmlinkage int vprintk(const char *fmt, va_list args)
  {
-       static int log_level_unknown = 1;
-       static char printk_buf[1024];
-       unsigned long flags;
        int printed_len = 0;
+       int current_log_level = default_message_loglevel;
+       unsigned long flags;
        int this_cpu;
        char *p;
  
                 * it can be printed at the next appropriate moment:
                 */
                if (!oops_in_progress) {
-                       printk_recursion_bug = 1;
+                       recursion_bug = 1;
                        goto out_restore_irqs;
                }
                zap_locks();
        spin_lock(&logbuf_lock);
        printk_cpu = this_cpu;
  
-       if (printk_recursion_bug) {
-               printk_recursion_bug = 0;
-               strcpy(printk_buf, printk_recursion_bug_msg);
-               printed_len = sizeof(printk_recursion_bug_msg);
+       if (recursion_bug) {
+               recursion_bug = 0;
+               strcpy(printk_buf, recursion_bug_msg);
+               printed_len = sizeof(recursion_bug_msg);
        }
        /* Emit the output into the temporary buffer */
        printed_len += vscnprintf(printk_buf + printed_len,
                                  sizeof(printk_buf) - printed_len, fmt, args);
  
        /*
         * Copy the output into log_buf.  If the caller didn't provide
         * appropriate log level tags, we insert them here
         */
        for (p = printk_buf; *p; p++) {
-               if (log_level_unknown) {
-                         /* log_level_unknown signals the start of a new line */
+               if (new_text_line) {
+                       /* If a token, set current_log_level and skip over */
+                       if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' &&
+                           p[2] == '>') {
+                               current_log_level = p[1] - '0';
+                               p += 3;
+                               printed_len -= 3;
+                       }
+                       /* Always output the token */
+                       emit_log_char('<');
+                       emit_log_char(current_log_level + '0');
+                       emit_log_char('>');
+                       printed_len += 3;
+                       new_text_line = 0;
                        if (printk_time) {
-                               int loglev_char;
+                               /* Follow the token with the time */
                                char tbuf[50], *tp;
                                unsigned tlen;
                                unsigned long long t;
                                unsigned long nanosec_rem;
  
-                               /*
-                                * force the log level token to be
-                                * before the time output.
-                                */
-                               if (p[0] == '<' && p[1] >='0' &&
-                                  p[1] <= '7' && p[2] == '>') {
-                                       loglev_char = p[1];
-                                       p += 3;
-                                       printed_len -= 3;
-                               } else {
-                                       loglev_char = default_message_loglevel
-                                               + '0';
-                               }
                                t = cpu_clock(printk_cpu);
                                nanosec_rem = do_div(t, 1000000000);
-                               tlen = sprintf(tbuf,
-                                               "<%c>[%5lu.%06lu] ",
-                                               loglev_char,
-                                               (unsigned long)t,
-                                               nanosec_rem/1000);
+                               tlen = sprintf(tbuf, "[%5lu.%06lu] ",
+                                               (unsigned long) t,
+                                               nanosec_rem / 1000);
  
                                for (tp = tbuf; tp < tbuf + tlen; tp++)
                                        emit_log_char(*tp);
                                printed_len += tlen;
-                       } else {
-                               if (p[0] != '<' || p[1] < '0' ||
-                                  p[1] > '7' || p[2] != '>') {
-                                       emit_log_char('<');
-                                       emit_log_char(default_message_loglevel
-                                               + '0');
-                                       emit_log_char('>');
-                                       printed_len += 3;
-                               }
                        }
-                       log_level_unknown = 0;
                        if (!*p)
                                break;
                }
                emit_log_char(*p);
                if (*p == '\n')
-                       log_level_unknown = 1;
+                       new_text_line = 1;
        }
  
        /*
@@@ -894,7 -870,6 +872,7 @@@ static int __init console_setup(char *s
        *s = 0;
  
        __add_preferred_console(buf, idx, options, brl_options);
 +      console_set_on_cmdline = 1;
        return 1;
  }
  __setup("console=", console_setup);
@@@ -1046,9 -1021,7 +1024,9 @@@ void release_console_sem(void
                _log_end = log_end;
                con_start = log_end;            /* Flush */
                spin_unlock(&logbuf_lock);
 +              stop_critical_timings();        /* don't trace print latency */
                call_console_drivers(_con_start, _log_end);
 +              start_critical_timings();
                local_irq_restore(flags);
        }
        console_locked = 0;
@@@ -1179,8 -1152,11 +1157,11 @@@ void register_console(struct console *c
                        console->index = 0;
                if (console->setup == NULL ||
                    console->setup(console, NULL) == 0) {
-                       console->flags |= CON_ENABLED | CON_CONSDEV;
-                       preferred_console = 0;
+                       console->flags |= CON_ENABLED;
+                       if (console->device) {
+                               console->flags |= CON_CONSDEV;
+                               preferred_console = 0;
+                       }
                }
        }