sched: guest CPU accounting: add guest-CPU /proc/<pid>/stat fields
[safe/jmp/linux-2.6] / kernel / printk.c
index c3d90a5..8451dfc 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/mm.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
-#include <linux/smp_lock.h>
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -54,7 +53,7 @@ int console_printk[4] = {
 };
 
 /*
- * Low lever drivers may need that to know if they can schedule in
+ * Low level drivers may need that to know if they can schedule in
  * their unblank() callback or not. So let's export it.
  */
 int oops_in_progress;
@@ -333,13 +332,25 @@ static void __call_console_drivers(unsigned long start, unsigned long end)
        }
 }
 
+static int __read_mostly ignore_loglevel;
+
+static int __init ignore_loglevel_setup(char *str)
+{
+       ignore_loglevel = 1;
+       printk(KERN_INFO "debug: ignoring loglevel setting.\n");
+
+       return 1;
+}
+
+__setup("ignore_loglevel", ignore_loglevel_setup);
+
 /*
  * Write out chars from start to end - 1 inclusive
  */
 static void _call_console_drivers(unsigned long start,
                                unsigned long end, int msg_log_level)
 {
-       if (msg_log_level < console_loglevel &&
+       if ((msg_log_level < console_loglevel || ignore_loglevel) &&
                        console_drivers && start != end) {
                if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
                        /* wrapped write */
@@ -438,13 +449,16 @@ static int printk_time = 1;
 #else
 static int printk_time = 0;
 #endif
-module_param(printk_time, int, S_IRUGO | S_IWUSR);
+module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
 
 static int __init printk_time_setup(char *str)
 {
        if (*str)
                return 0;
        printk_time = 1;
+       printk(KERN_NOTICE "The 'time' option is deprecated and "
+               "is scheduled for removal in early 2008\n");
+       printk(KERN_NOTICE "Use 'printk.time=<value>' instead\n");
        return 1;
 }
 
@@ -471,7 +485,10 @@ static int have_callable_console(void)
  * printk - print a kernel message
  * @fmt: format string
  *
- * This is printk.  It can be called from any context.  We want it to work.
+ * This is printk().  It can be called from any context.  We want it to work.
+ * Be aware of the fact that if oops_in_progress is not set, we might try to
+ * wake klogd up which could deadlock on runqueue lock if printk() is called
+ * from scheduler code.
  *
  * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
  * call the console drivers.  If we fail to get the semaphore we place the output
@@ -517,7 +534,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                zap_locks();
 
        /* This stops the holder of console_sem just where we want him */
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        lockdep_off();
        spin_lock(&logbuf_lock);
        printk_cpu = smp_processor_id();
@@ -606,7 +623,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                        up(&console_sem);
                }
                lockdep_on();
-               local_irq_restore(flags);
+               raw_local_irq_restore(flags);
        } else {
                /*
                 * Someone else owns the drivers.  We drop the spinlock, which
@@ -616,7 +633,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                printk_cpu = UINT_MAX;
                spin_unlock(&logbuf_lock);
                lockdep_on();
-               local_irq_restore(flags);
+               raw_local_irq_restore(flags);
        }
 
        preempt_enable();
@@ -643,7 +660,7 @@ static void call_console_drivers(unsigned long start, unsigned long end)
  */
 static int __init console_setup(char *str)
 {
-       char name[sizeof(console_cmdline[0].name)];
+       char buf[sizeof(console_cmdline[0].name) + 4]; /* 4 for index */
        char *s, *options;
        int idx;
 
@@ -651,27 +668,27 @@ static int __init console_setup(char *str)
         * Decode str into name, index, options.
         */
        if (str[0] >= '0' && str[0] <= '9') {
-               strcpy(name, "ttyS");
-               strncpy(name + 4, str, sizeof(name) - 5);
+               strcpy(buf, "ttyS");
+               strncpy(buf + 4, str, sizeof(buf) - 5);
        } else {
-               strncpy(name, str, sizeof(name) - 1);
+               strncpy(buf, str, sizeof(buf) - 1);
        }
-       name[sizeof(name) - 1] = 0;
+       buf[sizeof(buf) - 1] = 0;
        if ((options = strchr(str, ',')) != NULL)
                *(options++) = 0;
 #ifdef __sparc__
        if (!strcmp(str, "ttya"))
-               strcpy(name, "ttyS0");
+               strcpy(buf, "ttyS0");
        if (!strcmp(str, "ttyb"))
-               strcpy(name, "ttyS1");
+               strcpy(buf, "ttyS1");
 #endif
-       for (s = name; *s; s++)
+       for (s = buf; *s; s++)
                if ((*s >= '0' && *s <= '9') || *s == ',')
                        break;
        idx = simple_strtoul(s, NULL, 10);
        *s = 0;
 
-       add_preferred_console(name, idx, options);
+       add_preferred_console(buf, idx, options);
        return 1;
 }
 __setup("console=", console_setup);
@@ -698,7 +715,7 @@ int __init add_preferred_console(char *name, int idx, char *options)
         *      See if this tty is not yet registered, and
         *      if we have a slot free.
         */
-       for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+       for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
                if (strcmp(console_cmdline[i].name, name) == 0 &&
                          console_cmdline[i].index == idx) {
                                selected_console = i;
@@ -715,6 +732,25 @@ int __init add_preferred_console(char *name, int idx, char *options)
        return 0;
 }
 
+int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options)
+{
+       struct console_cmdline *c;
+       int i;
+
+       for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+               if (strcmp(console_cmdline[i].name, name) == 0 &&
+                         console_cmdline[i].index == idx) {
+                               c = &console_cmdline[i];
+                               memcpy(c->name, name_new, sizeof(c->name));
+                               c->name[sizeof(c->name) - 1] = 0;
+                               c->options = options;
+                               c->index = idx_new;
+                               return i;
+               }
+       /* not found */
+       return -1;
+}
+
 #ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
 /**
  * suspend_console - suspend the console subsystem
@@ -771,6 +807,12 @@ int is_console_locked(void)
        return console_locked;
 }
 
+void wake_up_klogd(void)
+{
+       if (!oops_in_progress && waitqueue_active(&log_wait))
+               wake_up_interruptible(&log_wait);
+}
+
 /**
  * release_console_sem - unlock the console system
  *
@@ -813,8 +855,8 @@ void release_console_sem(void)
        console_locked = 0;
        up(&console_sem);
        spin_unlock_irqrestore(&logbuf_lock, flags);
-       if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait))
-               wake_up_interruptible(&log_wait);
+       if (wake_klogd)
+               wake_up_klogd();
 }
 EXPORT_SYMBOL(release_console_sem);
 
@@ -913,10 +955,21 @@ void register_console(struct console *console)
 {
        int i;
        unsigned long flags;
+       struct console *bootconsole = NULL;
 
-       if (preferred_console < 0)
+       if (console_drivers) {
+               if (console->flags & CON_BOOT)
+                       return;
+               if (console_drivers->flags & CON_BOOT)
+                       bootconsole = console_drivers;
+       }
+
+       if (preferred_console < 0 || bootconsole || !console_drivers)
                preferred_console = selected_console;
 
+       if (console->early_setup)
+               console->early_setup();
+
        /*
         *      See if we want to use this console driver. If we
         *      didn't select a console we take the first one
@@ -960,9 +1013,15 @@ void register_console(struct console *console)
        if (!(console->flags & CON_ENABLED))
                return;
 
-       if (console_drivers && (console_drivers->flags & CON_BOOT)) {
-               unregister_console(console_drivers);
+       if (bootconsole && (console->flags & CON_CONSDEV)) {
+               printk(KERN_INFO "console handover: boot [%s%d] -> real [%s%d]\n",
+                      bootconsole->name, bootconsole->index,
+                      console->name, console->index);
+               unregister_console(bootconsole);
                console->flags &= ~CON_PRINTBUFFER;
+       } else {
+               printk(KERN_INFO "console [%s%d] enabled\n",
+                      console->name, console->index);
        }
 
        /*
@@ -1012,16 +1071,11 @@ int unregister_console(struct console *console)
                }
        }
 
-       /* If last console is removed, we re-enable picking the first
-        * one that gets registered. Without that, pmac early boot console
-        * would prevent fbcon from taking over.
-        *
+       /*
         * If this isn't the last console and it has CON_CONSDEV set, we
         * need to set it on the next preferred console.
         */
-       if (console_drivers == NULL)
-               preferred_console = selected_console;
-       else if (console->flags & CON_CONSDEV)
+       if (console_drivers != NULL && console->flags & CON_CONSDEV)
                console_drivers->flags |= CON_CONSDEV;
 
        release_console_sem();
@@ -1029,6 +1083,19 @@ int unregister_console(struct console *console)
 }
 EXPORT_SYMBOL(unregister_console);
 
+static int __init disable_boot_consoles(void)
+{
+       if (console_drivers != NULL) {
+               if (console_drivers->flags & CON_BOOT) {
+                       printk(KERN_INFO "turn off boot console %s%d\n",
+                               console_drivers->name, console_drivers->index);
+                       return unregister_console(console_drivers);
+               }
+       }
+       return 0;
+}
+late_initcall(disable_boot_consoles);
+
 /**
  * tty_write_message - write a message to a certain tty, not just the console.
  * @tty: the destination tty_struct