|
@@ -1483,58 +1483,6 @@ static void zap_locks(void)
|
|
|
sema_init(&console_sem, 1);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Check if we have any console that is capable of printing while cpu is
|
|
|
- * booting or shutting down. Requires console_sem.
|
|
|
- */
|
|
|
-static int have_callable_console(void)
|
|
|
-{
|
|
|
- struct console *con;
|
|
|
-
|
|
|
- for_each_console(con)
|
|
|
- if (con->flags & CON_ANYTIME)
|
|
|
- return 1;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Can we actually use the console at this time on this cpu?
|
|
|
- *
|
|
|
- * Console drivers may assume that per-cpu resources have been allocated. So
|
|
|
- * unless they're explicitly marked as being able to cope (CON_ANYTIME) don't
|
|
|
- * call them until this CPU is officially up.
|
|
|
- */
|
|
|
-static inline int can_use_console(unsigned int cpu)
|
|
|
-{
|
|
|
- return cpu_online(cpu) || have_callable_console();
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Try to get console ownership to actually show the kernel
|
|
|
- * messages from a 'printk'. Return true (and with the
|
|
|
- * console_lock held, and 'console_locked' set) if it
|
|
|
- * is successful, false otherwise.
|
|
|
- */
|
|
|
-static int console_trylock_for_printk(void)
|
|
|
-{
|
|
|
- unsigned int cpu = smp_processor_id();
|
|
|
-
|
|
|
- if (!console_trylock())
|
|
|
- return 0;
|
|
|
- /*
|
|
|
- * If we can't use the console, we need to release the console
|
|
|
- * semaphore by hand to avoid flushing the buffer. We need to hold the
|
|
|
- * console semaphore in order to do this test safely.
|
|
|
- */
|
|
|
- if (!can_use_console(cpu)) {
|
|
|
- console_locked = 0;
|
|
|
- up_console_sem();
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
int printk_delay_msec __read_mostly;
|
|
|
|
|
|
static inline void printk_delay(void)
|
|
@@ -1681,7 +1629,6 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|
|
boot_delay_msec(level);
|
|
|
printk_delay();
|
|
|
|
|
|
- /* This stops the holder of console_sem just where we want him */
|
|
|
local_irq_save(flags);
|
|
|
this_cpu = smp_processor_id();
|
|
|
|
|
@@ -1705,6 +1652,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|
|
}
|
|
|
|
|
|
lockdep_off();
|
|
|
+ /* This stops the holder of console_sem just where we want him */
|
|
|
raw_spin_lock(&logbuf_lock);
|
|
|
logbuf_cpu = this_cpu;
|
|
|
|
|
@@ -1821,7 +1769,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|
|
* semaphore. The release will print out buffers and wake up
|
|
|
* /dev/kmsg and syslog() users.
|
|
|
*/
|
|
|
- if (console_trylock_for_printk())
|
|
|
+ if (console_trylock())
|
|
|
console_unlock();
|
|
|
preempt_enable();
|
|
|
lockdep_on();
|
|
@@ -2184,6 +2132,33 @@ int is_console_locked(void)
|
|
|
return console_locked;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Check if we have any console that is capable of printing while cpu is
|
|
|
+ * booting or shutting down. Requires console_sem.
|
|
|
+ */
|
|
|
+static int have_callable_console(void)
|
|
|
+{
|
|
|
+ struct console *con;
|
|
|
+
|
|
|
+ for_each_console(con)
|
|
|
+ if (con->flags & CON_ANYTIME)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Can we actually use the console at this time on this cpu?
|
|
|
+ *
|
|
|
+ * Console drivers may assume that per-cpu resources have been allocated. So
|
|
|
+ * unless they're explicitly marked as being able to cope (CON_ANYTIME) don't
|
|
|
+ * call them until this CPU is officially up.
|
|
|
+ */
|
|
|
+static inline int can_use_console(void)
|
|
|
+{
|
|
|
+ return cpu_online(raw_smp_processor_id()) || have_callable_console();
|
|
|
+}
|
|
|
+
|
|
|
static void console_cont_flush(char *text, size_t size)
|
|
|
{
|
|
|
unsigned long flags;
|
|
@@ -2254,9 +2229,21 @@ void console_unlock(void)
|
|
|
do_cond_resched = console_may_schedule;
|
|
|
console_may_schedule = 0;
|
|
|
|
|
|
+again:
|
|
|
+ /*
|
|
|
+ * We released the console_sem lock, so we need to recheck if
|
|
|
+ * cpu is online and (if not) is there at least one CON_ANYTIME
|
|
|
+ * console.
|
|
|
+ */
|
|
|
+ if (!can_use_console()) {
|
|
|
+ console_locked = 0;
|
|
|
+ up_console_sem();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
/* flush buffered message fragment immediately to console */
|
|
|
console_cont_flush(text, sizeof(text));
|
|
|
-again:
|
|
|
+
|
|
|
for (;;) {
|
|
|
struct printk_log *msg;
|
|
|
size_t ext_len = 0;
|