printk: avoid double lock acquire
[pandora-kernel.git] / kernel / printk.c
index 28a40d8..7982a0a 100644 (file)
@@ -100,7 +100,7 @@ static int console_locked, console_suspended;
  * It is also used in interesting ways to provide interlocking in
  * console_unlock();.
  */
  * It is also used in interesting ways to provide interlocking in
  * console_unlock();.
  */
-static DEFINE_SPINLOCK(logbuf_lock);
+static DEFINE_RAW_SPINLOCK(logbuf_lock);
 
 #define LOG_BUF_MASK (log_buf_len-1)
 #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
 
 #define LOG_BUF_MASK (log_buf_len-1)
 #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
@@ -212,7 +212,7 @@ void __init setup_log_buf(int early)
                return;
        }
 
                return;
        }
 
-       spin_lock_irqsave(&logbuf_lock, flags);
+       raw_spin_lock_irqsave(&logbuf_lock, flags);
        log_buf_len = new_log_buf_len;
        log_buf = new_log_buf;
        new_log_buf_len = 0;
        log_buf_len = new_log_buf_len;
        log_buf = new_log_buf;
        new_log_buf_len = 0;
@@ -230,7 +230,7 @@ void __init setup_log_buf(int early)
        log_start -= offset;
        con_start -= offset;
        log_end -= offset;
        log_start -= offset;
        con_start -= offset;
        log_end -= offset;
-       spin_unlock_irqrestore(&logbuf_lock, flags);
+       raw_spin_unlock_irqrestore(&logbuf_lock, flags);
 
        pr_info("log_buf_len: %d\n", log_buf_len);
        pr_info("early log buf free: %d(%d%%)\n",
 
        pr_info("log_buf_len: %d\n", log_buf_len);
        pr_info("early log buf free: %d(%d%%)\n",
@@ -365,18 +365,18 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
                if (error)
                        goto out;
                i = 0;
                if (error)
                        goto out;
                i = 0;
-               spin_lock_irq(&logbuf_lock);
+               raw_spin_lock_irq(&logbuf_lock);
                while (!error && (log_start != log_end) && i < len) {
                        c = LOG_BUF(log_start);
                        log_start++;
                while (!error && (log_start != log_end) && i < len) {
                        c = LOG_BUF(log_start);
                        log_start++;
-                       spin_unlock_irq(&logbuf_lock);
+                       raw_spin_unlock_irq(&logbuf_lock);
                        error = __put_user(c,buf);
                        buf++;
                        i++;
                        cond_resched();
                        error = __put_user(c,buf);
                        buf++;
                        i++;
                        cond_resched();
-                       spin_lock_irq(&logbuf_lock);
+                       raw_spin_lock_irq(&logbuf_lock);
                }
                }
-               spin_unlock_irq(&logbuf_lock);
+               raw_spin_unlock_irq(&logbuf_lock);
                if (!error)
                        error = i;
                break;
                if (!error)
                        error = i;
                break;
@@ -399,7 +399,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
                count = len;
                if (count > log_buf_len)
                        count = log_buf_len;
                count = len;
                if (count > log_buf_len)
                        count = log_buf_len;
-               spin_lock_irq(&logbuf_lock);
+               raw_spin_lock_irq(&logbuf_lock);
                if (count > logged_chars)
                        count = logged_chars;
                if (do_clear)
                if (count > logged_chars)
                        count = logged_chars;
                if (do_clear)
@@ -416,12 +416,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
                        if (j + log_buf_len < log_end)
                                break;
                        c = LOG_BUF(j);
                        if (j + log_buf_len < log_end)
                                break;
                        c = LOG_BUF(j);
-                       spin_unlock_irq(&logbuf_lock);
+                       raw_spin_unlock_irq(&logbuf_lock);
                        error = __put_user(c,&buf[count-1-i]);
                        cond_resched();
                        error = __put_user(c,&buf[count-1-i]);
                        cond_resched();
-                       spin_lock_irq(&logbuf_lock);
+                       raw_spin_lock_irq(&logbuf_lock);
                }
                }
-               spin_unlock_irq(&logbuf_lock);
+               raw_spin_unlock_irq(&logbuf_lock);
                if (error)
                        break;
                error = i;
                if (error)
                        break;
                error = i;
@@ -532,6 +532,9 @@ static int __init ignore_loglevel_setup(char *str)
 }
 
 early_param("ignore_loglevel", ignore_loglevel_setup);
 }
 
 early_param("ignore_loglevel", ignore_loglevel_setup);
+module_param_named(ignore_loglevel, ignore_loglevel, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to"
+       "print all kernel messages to the console.");
 
 /*
  * Write out chars from start to end - 1 inclusive
 
 /*
  * Write out chars from start to end - 1 inclusive
@@ -592,9 +595,6 @@ static size_t log_prefix(const char *p, unsigned int *level, char *special)
                /* multi digit including the level and facility number */
                char *endp = NULL;
 
                /* multi digit including the level and facility number */
                char *endp = NULL;
 
-               if (p[1] < '0' && p[1] > '9')
-                       return 0;
-
                lev = (simple_strtoul(&p[1], &endp, 10) & 7);
                if (endp == NULL || endp[0] != '>')
                        return 0;
                lev = (simple_strtoul(&p[1], &endp, 10) & 7);
                if (endp == NULL || endp[0] != '>')
                        return 0;
@@ -689,7 +689,7 @@ static void zap_locks(void)
        oops_timestamp = jiffies;
 
        /* If a crash is occurring, make sure we can't deadlock */
        oops_timestamp = jiffies;
 
        /* If a crash is occurring, make sure we can't deadlock */
-       spin_lock_init(&logbuf_lock);
+       raw_spin_lock_init(&logbuf_lock);
        /* And make sure that we print immediately */
        sema_init(&console_sem, 1);
 }
        /* And make sure that we print immediately */
        sema_init(&console_sem, 1);
 }
@@ -802,9 +802,9 @@ static int console_trylock_for_printk(unsigned int cpu)
                }
        }
        printk_cpu = UINT_MAX;
                }
        }
        printk_cpu = UINT_MAX;
-       spin_unlock(&logbuf_lock);
        if (wake)
                up(&console_sem);
        if (wake)
                up(&console_sem);
+       raw_spin_unlock(&logbuf_lock);
        return retval;
 }
 static const char recursion_bug_msg [] =
        return retval;
 }
 static const char recursion_bug_msg [] =
@@ -864,7 +864,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
        }
 
        lockdep_off();
        }
 
        lockdep_off();
-       spin_lock(&logbuf_lock);
+       raw_spin_lock(&logbuf_lock);
        printk_cpu = this_cpu;
 
        if (recursion_bug) {
        printk_cpu = this_cpu;
 
        if (recursion_bug) {
@@ -1108,6 +1108,10 @@ static int __init console_suspend_disable(char *str)
        return 1;
 }
 __setup("no_console_suspend", console_suspend_disable);
        return 1;
 }
 __setup("no_console_suspend", console_suspend_disable);
+module_param_named(console_suspend, console_suspend_enabled,
+               bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(console_suspend, "suspend console during suspend"
+       " and hibernate operations");
 
 /**
  * suspend_console - suspend the console subsystem
 
 /**
  * suspend_console - suspend the console subsystem
@@ -1257,14 +1261,14 @@ void console_unlock(void)
 
 again:
        for ( ; ; ) {
 
 again:
        for ( ; ; ) {
-               spin_lock_irqsave(&logbuf_lock, flags);
+               raw_spin_lock_irqsave(&logbuf_lock, flags);
                wake_klogd |= log_start - log_end;
                if (con_start == log_end)
                        break;                  /* Nothing to print */
                _con_start = con_start;
                _log_end = log_end;
                con_start = log_end;            /* Flush */
                wake_klogd |= log_start - log_end;
                if (con_start == log_end)
                        break;                  /* Nothing to print */
                _con_start = con_start;
                _log_end = log_end;
                con_start = log_end;            /* Flush */
-               spin_unlock(&logbuf_lock);
+               raw_spin_unlock(&logbuf_lock);
                stop_critical_timings();        /* don't trace print latency */
                call_console_drivers(_con_start, _log_end);
                start_critical_timings();
                stop_critical_timings();        /* don't trace print latency */
                call_console_drivers(_con_start, _log_end);
                start_critical_timings();
@@ -1276,7 +1280,7 @@ again:
        if (unlikely(exclusive_console))
                exclusive_console = NULL;
 
        if (unlikely(exclusive_console))
                exclusive_console = NULL;
 
-       spin_unlock(&logbuf_lock);
+       raw_spin_unlock(&logbuf_lock);
 
        up(&console_sem);
 
 
        up(&console_sem);
 
@@ -1286,10 +1290,11 @@ again:
         * there's a new owner and the console_unlock() from them will do the
         * flush, no worries.
         */
         * there's a new owner and the console_unlock() from them will do the
         * flush, no worries.
         */
-       spin_lock(&logbuf_lock);
+       raw_spin_lock(&logbuf_lock);
        if (con_start != log_end)
                retry = 1;
        if (con_start != log_end)
                retry = 1;
-       spin_unlock_irqrestore(&logbuf_lock, flags);
+       raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+
        if (retry && console_trylock())
                goto again;
 
        if (retry && console_trylock())
                goto again;
 
@@ -1522,9 +1527,9 @@ void register_console(struct console *newcon)
                 * console_unlock(); will print out the buffered messages
                 * for us.
                 */
                 * console_unlock(); will print out the buffered messages
                 * for us.
                 */
-               spin_lock_irqsave(&logbuf_lock, flags);
+               raw_spin_lock_irqsave(&logbuf_lock, flags);
                con_start = log_start;
                con_start = log_start;
-               spin_unlock_irqrestore(&logbuf_lock, flags);
+               raw_spin_unlock_irqrestore(&logbuf_lock, flags);
                /*
                 * We're about to replay the log buffer.  Only do this to the
                 * just-registered console to avoid excessive message spam to
                /*
                 * We're about to replay the log buffer.  Only do this to the
                 * just-registered console to avoid excessive message spam to
@@ -1731,10 +1736,10 @@ void kmsg_dump(enum kmsg_dump_reason reason)
        /* Theoretically, the log could move on after we do this, but
           there's not a lot we can do about that. The new messages
           will overwrite the start of what we dump. */
        /* Theoretically, the log could move on after we do this, but
           there's not a lot we can do about that. The new messages
           will overwrite the start of what we dump. */
-       spin_lock_irqsave(&logbuf_lock, flags);
+       raw_spin_lock_irqsave(&logbuf_lock, flags);
        end = log_end & LOG_BUF_MASK;
        chars = logged_chars;
        end = log_end & LOG_BUF_MASK;
        chars = logged_chars;
-       spin_unlock_irqrestore(&logbuf_lock, flags);
+       raw_spin_unlock_irqrestore(&logbuf_lock, flags);
 
        if (chars > end) {
                s1 = log_buf + log_buf_len - chars + end;
 
        if (chars > end) {
                s1 = log_buf + log_buf_len - chars + end;