vserver 1.9.3
[linux-2.6.git] / kernel / printk.c
index 9b1f825..11c6681 100644 (file)
@@ -193,6 +193,8 @@ static int __init log_buf_len_setup(char *str)
        unsigned long size = memparse(str, &str);
        unsigned long flags;
 
+       if (size)
+               size = roundup_pow_of_two(size);
        if (size > log_buf_len) {
                unsigned long start, dest_idx, offset;
                char * new_log_buf;
@@ -512,22 +514,34 @@ static void zap_locks(void)
 asmlinkage int printk(const char *fmt, ...)
 {
        va_list args;
+       int r;
+
+       va_start(args, fmt);
+       r = vprintk(fmt, args);
+       va_end(args);
+
+       return r;
+}
+
+static volatile int printk_cpu = -1;
+
+asmlinkage int vprintk(const char *fmt, va_list args)
+{
        unsigned long flags;
        int printed_len;
        char *p;
        static char printk_buf[1024];
        static int log_level_unknown = 1;
 
-       if (unlikely(oops_in_progress))
+       if (unlikely(oops_in_progress && printk_cpu == smp_processor_id()))
                zap_locks();
 
        /* This stops the holder of console_sem just where we want him */
        spin_lock_irqsave(&logbuf_lock, flags);
+       printk_cpu = smp_processor_id();
 
        /* Emit the output into the temporary buffer */
-       va_start(args, fmt);
        printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
-       va_end(args);
 
        /*
         * Copy the output into log_buf.  If the caller didn't provide
@@ -579,6 +593,7 @@ out:
        return printed_len;
 }
 EXPORT_SYMBOL(printk);
+EXPORT_SYMBOL(vprintk);
 
 /**
  * acquire_console_sem - lock the console system for exclusive use.