aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/printk/printk.c97
1 files changed, 42 insertions, 55 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index c963ba534a78..2523332bd998 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1483,58 +1483,6 @@ static void zap_locks(void)
1483 sema_init(&console_sem, 1); 1483 sema_init(&console_sem, 1);
1484} 1484}
1485 1485
1486/*
1487 * Check if we have any console that is capable of printing while cpu is
1488 * booting or shutting down. Requires console_sem.
1489 */
1490static int have_callable_console(void)
1491{
1492 struct console *con;
1493
1494 for_each_console(con)
1495 if (con->flags & CON_ANYTIME)
1496 return 1;
1497
1498 return 0;
1499}
1500
1501/*
1502 * Can we actually use the console at this time on this cpu?
1503 *
1504 * Console drivers may assume that per-cpu resources have been allocated. So
1505 * unless they're explicitly marked as being able to cope (CON_ANYTIME) don't
1506 * call them until this CPU is officially up.
1507 */
1508static inline int can_use_console(unsigned int cpu)
1509{
1510 return cpu_online(cpu) || have_callable_console();
1511}
1512
1513/*
1514 * Try to get console ownership to actually show the kernel
1515 * messages from a 'printk'. Return true (and with the
1516 * console_lock held, and 'console_locked' set) if it
1517 * is successful, false otherwise.
1518 */
1519static int console_trylock_for_printk(void)
1520{
1521 unsigned int cpu = smp_processor_id();
1522
1523 if (!console_trylock())
1524 return 0;
1525 /*
1526 * If we can't use the console, we need to release the console
1527 * semaphore by hand to avoid flushing the buffer. We need to hold the
1528 * console semaphore in order to do this test safely.
1529 */
1530 if (!can_use_console(cpu)) {
1531 console_locked = 0;
1532 up_console_sem();
1533 return 0;
1534 }
1535 return 1;
1536}
1537
1538int printk_delay_msec __read_mostly; 1486int printk_delay_msec __read_mostly;
1539 1487
1540static inline void printk_delay(void) 1488static inline void printk_delay(void)
@@ -1681,7 +1629,6 @@ asmlinkage int vprintk_emit(int facility, int level,
1681 boot_delay_msec(level); 1629 boot_delay_msec(level);
1682 printk_delay(); 1630 printk_delay();
1683 1631
1684 /* This stops the holder of console_sem just where we want him */
1685 local_irq_save(flags); 1632 local_irq_save(flags);
1686 this_cpu = smp_processor_id(); 1633 this_cpu = smp_processor_id();
1687 1634
@@ -1705,6 +1652,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1705 } 1652 }
1706 1653
1707 lockdep_off(); 1654 lockdep_off();
1655 /* This stops the holder of console_sem just where we want him */
1708 raw_spin_lock(&logbuf_lock); 1656 raw_spin_lock(&logbuf_lock);
1709 logbuf_cpu = this_cpu; 1657 logbuf_cpu = this_cpu;
1710 1658
@@ -1821,7 +1769,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1821 * semaphore. The release will print out buffers and wake up 1769 * semaphore. The release will print out buffers and wake up
1822 * /dev/kmsg and syslog() users. 1770 * /dev/kmsg and syslog() users.
1823 */ 1771 */
1824 if (console_trylock_for_printk()) 1772 if (console_trylock())
1825 console_unlock(); 1773 console_unlock();
1826 preempt_enable(); 1774 preempt_enable();
1827 lockdep_on(); 1775 lockdep_on();
@@ -2184,6 +2132,33 @@ int is_console_locked(void)
2184 return console_locked; 2132 return console_locked;
2185} 2133}
2186 2134
2135/*
2136 * Check if we have any console that is capable of printing while cpu is
2137 * booting or shutting down. Requires console_sem.
2138 */
2139static int have_callable_console(void)
2140{
2141 struct console *con;
2142
2143 for_each_console(con)
2144 if (con->flags & CON_ANYTIME)
2145 return 1;
2146
2147 return 0;
2148}
2149
2150/*
2151 * Can we actually use the console at this time on this cpu?
2152 *
2153 * Console drivers may assume that per-cpu resources have been allocated. So
2154 * unless they're explicitly marked as being able to cope (CON_ANYTIME) don't
2155 * call them until this CPU is officially up.
2156 */
2157static inline int can_use_console(void)
2158{
2159 return cpu_online(raw_smp_processor_id()) || have_callable_console();
2160}
2161
2187static void console_cont_flush(char *text, size_t size) 2162static void console_cont_flush(char *text, size_t size)
2188{ 2163{
2189 unsigned long flags; 2164 unsigned long flags;
@@ -2254,9 +2229,21 @@ void console_unlock(void)
2254 do_cond_resched = console_may_schedule; 2229 do_cond_resched = console_may_schedule;
2255 console_may_schedule = 0; 2230 console_may_schedule = 0;
2256 2231
2232again:
2233 /*
2234 * We released the console_sem lock, so we need to recheck if
2235 * cpu is online and (if not) is there at least one CON_ANYTIME
2236 * console.
2237 */
2238 if (!can_use_console()) {
2239 console_locked = 0;
2240 up_console_sem();
2241 return;
2242 }
2243
2257 /* flush buffered message fragment immediately to console */ 2244 /* flush buffered message fragment immediately to console */
2258 console_cont_flush(text, sizeof(text)); 2245 console_cont_flush(text, sizeof(text));
2259again: 2246
2260 for (;;) { 2247 for (;;) {
2261 struct printk_log *msg; 2248 struct printk_log *msg;
2262 size_t ext_len = 0; 2249 size_t ext_len = 0;