aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/printk/printk.c54
1 files changed, 21 insertions, 33 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 5bc54478c963..6e1b21a8a497 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -249,9 +249,6 @@ static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
249static char *log_buf = __log_buf; 249static char *log_buf = __log_buf;
250static u32 log_buf_len = __LOG_BUF_LEN; 250static u32 log_buf_len = __LOG_BUF_LEN;
251 251
252/* cpu currently holding logbuf_lock */
253static volatile unsigned int logbuf_cpu = UINT_MAX;
254
255/* human readable text of the record */ 252/* human readable text of the record */
256static char *log_text(const struct printk_log *msg) 253static char *log_text(const struct printk_log *msg)
257{ 254{
@@ -1380,7 +1377,10 @@ static void zap_locks(void)
1380 sema_init(&console_sem, 1); 1377 sema_init(&console_sem, 1);
1381} 1378}
1382 1379
1383/* Check if we have any console registered that can be called early in boot. */ 1380/*
1381 * Check if we have any console that is capable of printing while cpu is
1382 * booting or shutting down. Requires console_sem.
1383 */
1384static int have_callable_console(void) 1384static int have_callable_console(void)
1385{ 1385{
1386 struct console *con; 1386 struct console *con;
@@ -1410,36 +1410,22 @@ static inline int can_use_console(unsigned int cpu)
1410 * messages from a 'printk'. Return true (and with the 1410 * messages from a 'printk'. Return true (and with the
1411 * console_lock held, and 'console_locked' set) if it 1411 * console_lock held, and 'console_locked' set) if it
1412 * is successful, false otherwise. 1412 * is successful, false otherwise.
1413 *
1414 * This gets called with the 'logbuf_lock' spinlock held and
1415 * interrupts disabled. It should return with 'lockbuf_lock'
1416 * released but interrupts still disabled.
1417 */ 1413 */
1418static int console_trylock_for_printk(unsigned int cpu) 1414static int console_trylock_for_printk(unsigned int cpu)
1419 __releases(&logbuf_lock)
1420{ 1415{
1421 int retval = 0, wake = 0; 1416 if (!console_trylock())
1422 1417 return 0;
1423 if (console_trylock()) { 1418 /*
1424 retval = 1; 1419 * If we can't use the console, we need to release the console
1425 1420 * semaphore by hand to avoid flushing the buffer. We need to hold the
1426 /* 1421 * console semaphore in order to do this test safely.
1427 * If we can't use the console, we need to release 1422 */
1428 * the console semaphore by hand to avoid flushing 1423 if (!can_use_console(cpu)) {
1429 * the buffer. We need to hold the console semaphore 1424 console_locked = 0;
1430 * in order to do this test safely.
1431 */
1432 if (!can_use_console(cpu)) {
1433 console_locked = 0;
1434 wake = 1;
1435 retval = 0;
1436 }
1437 }
1438 logbuf_cpu = UINT_MAX;
1439 raw_spin_unlock(&logbuf_lock);
1440 if (wake)
1441 up(&console_sem); 1425 up(&console_sem);
1442 return retval; 1426 return 0;
1427 }
1428 return 1;
1443} 1429}
1444 1430
1445int printk_delay_msec __read_mostly; 1431int printk_delay_msec __read_mostly;
@@ -1572,6 +1558,9 @@ asmlinkage int vprintk_emit(int facility, int level,
1572 unsigned long flags; 1558 unsigned long flags;
1573 int this_cpu; 1559 int this_cpu;
1574 int printed_len = 0; 1560 int printed_len = 0;
1561 /* cpu currently holding logbuf_lock in this function */
1562 static volatile unsigned int logbuf_cpu = UINT_MAX;
1563
1575 1564
1576 boot_delay_msec(level); 1565 boot_delay_msec(level);
1577 printk_delay(); 1566 printk_delay();
@@ -1694,13 +1683,12 @@ asmlinkage int vprintk_emit(int facility, int level,
1694 dict, dictlen, text, text_len); 1683 dict, dictlen, text, text_len);
1695 } 1684 }
1696 1685
1686 logbuf_cpu = UINT_MAX;
1687 raw_spin_unlock(&logbuf_lock);
1697 /* 1688 /*
1698 * Try to acquire and then immediately release the console semaphore. 1689 * Try to acquire and then immediately release the console semaphore.
1699 * The release will print out buffers and wake up /dev/kmsg and syslog() 1690 * The release will print out buffers and wake up /dev/kmsg and syslog()
1700 * users. 1691 * users.
1701 *
1702 * The console_trylock_for_printk() function will release 'logbuf_lock'
1703 * regardless of whether it actually gets the console semaphore or not.
1704 */ 1692 */
1705 if (console_trylock_for_printk(this_cpu)) 1693 if (console_trylock_for_printk(this_cpu))
1706 console_unlock(); 1694 console_unlock();