git.samba.org
/
sfrench
/
cifs-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6
[sfrench/cifs-2.6.git]
/
kernel
/
printk.c
diff --git
a/kernel/printk.c
b/kernel/printk.c
index 5092397fac29926bfab6da75fc273882b14e905d..a967605bc2e358cbcf95dd7fe60f7870fe9dd14b 100644
(file)
--- a/
kernel/printk.c
+++ b/
kernel/printk.c
@@
-514,6
+514,9
@@
asmlinkage int printk(const char *fmt, ...)
return r;
}
return r;
}
+/* cpu currently holding logbuf_lock */
+static volatile unsigned int printk_cpu = UINT_MAX;
+
asmlinkage int vprintk(const char *fmt, va_list args)
{
unsigned long flags;
asmlinkage int vprintk(const char *fmt, va_list args)
{
unsigned long flags;
@@
-522,11
+525,15
@@
asmlinkage int vprintk(const char *fmt, va_list args)
static char printk_buf[1024];
static int log_level_unknown = 1;
static char printk_buf[1024];
static int log_level_unknown = 1;
- if (unlikely(oops_in_progress))
+ preempt_disable();
+ if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
+ /* If a crash is occurring during printk() on this CPU,
+ * make sure we can't deadlock */
zap_locks();
/* This stops the holder of console_sem just where we want him */
spin_lock_irqsave(&logbuf_lock, flags);
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 */
printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
/* Emit the output into the temporary buffer */
printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
@@
-595,6
+602,7
@@
asmlinkage int vprintk(const char *fmt, va_list args)
* CPU until it is officially up. We shouldn't be calling into
* random console drivers on a CPU which doesn't exist yet..
*/
* CPU until it is officially up. We shouldn't be calling into
* random console drivers on a CPU which doesn't exist yet..
*/
+ printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
goto out;
}
spin_unlock_irqrestore(&logbuf_lock, flags);
goto out;
}
@@
-604,6
+612,7
@@
asmlinkage int vprintk(const char *fmt, va_list args)
* We own the drivers. We can drop the spinlock and let
* release_console_sem() print the text
*/
* We own the drivers. We can drop the spinlock and let
* release_console_sem() print the text
*/
+ printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
console_may_schedule = 0;
release_console_sem();
spin_unlock_irqrestore(&logbuf_lock, flags);
console_may_schedule = 0;
release_console_sem();
@@
-613,9
+622,11
@@
asmlinkage int vprintk(const char *fmt, va_list args)
* allows the semaphore holder to proceed and to call the
* console drivers with the output which we just produced.
*/
* allows the semaphore holder to proceed and to call the
* console drivers with the output which we just produced.
*/
+ printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
}
out:
spin_unlock_irqrestore(&logbuf_lock, flags);
}
out:
+ preempt_enable();
return printed_len;
}
EXPORT_SYMBOL(printk);
return printed_len;
}
EXPORT_SYMBOL(printk);