aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-11-28 12:46:22 -0500
committerTejun Heo <tj@kernel.org>2011-11-28 12:46:22 -0500
commitd4bbf7e7759afc172e2bfbc5c416324590049cdd (patch)
tree7eab5ee5481cd3dcf1162329fec827177640018a /kernel/printk.c
parenta150439c4a97db379f0ed6faa46fbbb6e7bf3cb2 (diff)
parent401d0069cb344f401bc9d264c31db55876ff78c0 (diff)
Merge branch 'master' into x86/memblock
Conflicts & resolutions: * arch/x86/xen/setup.c dc91c728fd "xen: allow extra memory to be in multiple regions" 24aa07882b "memblock, x86: Replace memblock_x86_reserve/free..." conflicted on xen_add_extra_mem() updates. The resolution is trivial as the latter just want to replace memblock_x86_reserve_range() with memblock_reserve(). * drivers/pci/intel-iommu.c 166e9278a3f "x86/ia64: intel-iommu: move to drivers/iommu/" 5dfe8660a3d "bootmem: Replace work_with_active_regions() with..." conflicted as the former moved the file under drivers/iommu/. Resolved by applying the chnages from the latter on the moved file. * mm/Kconfig 6661672053a "memblock: add NO_BOOTMEM config symbol" c378ddd53f9 "memblock, x86: Make ARCH_DISCARD_MEMBLOCK a config option" conflicted trivially. Both added config options. Just letting both add their own options resolves the conflict. * mm/memblock.c d1f0ece6cdc "mm/memblock.c: small function definition fixes" ed7b56a799c "memblock: Remove memblock_memory_can_coalesce()" confliected. The former updates function removed by the latter. Resolution is trivial. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c84
1 files changed, 54 insertions, 30 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index b1d5a6174d65..baf2aebd6970 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -100,7 +100,7 @@ static int console_locked, console_suspended;
100 * It is also used in interesting ways to provide interlocking in 100 * It is also used in interesting ways to provide interlocking in
101 * console_unlock();. 101 * console_unlock();.
102 */ 102 */
103static DEFINE_SPINLOCK(logbuf_lock); 103static DEFINE_RAW_SPINLOCK(logbuf_lock);
104 104
105#define LOG_BUF_MASK (log_buf_len-1) 105#define LOG_BUF_MASK (log_buf_len-1)
106#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) 106#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
@@ -212,7 +212,7 @@ void __init setup_log_buf(int early)
212 return; 212 return;
213 } 213 }
214 214
215 spin_lock_irqsave(&logbuf_lock, flags); 215 raw_spin_lock_irqsave(&logbuf_lock, flags);
216 log_buf_len = new_log_buf_len; 216 log_buf_len = new_log_buf_len;
217 log_buf = new_log_buf; 217 log_buf = new_log_buf;
218 new_log_buf_len = 0; 218 new_log_buf_len = 0;
@@ -230,7 +230,7 @@ void __init setup_log_buf(int early)
230 log_start -= offset; 230 log_start -= offset;
231 con_start -= offset; 231 con_start -= offset;
232 log_end -= offset; 232 log_end -= offset;
233 spin_unlock_irqrestore(&logbuf_lock, flags); 233 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
234 234
235 pr_info("log_buf_len: %d\n", log_buf_len); 235 pr_info("log_buf_len: %d\n", log_buf_len);
236 pr_info("early log buf free: %d(%d%%)\n", 236 pr_info("early log buf free: %d(%d%%)\n",
@@ -318,8 +318,10 @@ static int check_syslog_permissions(int type, bool from_file)
318 return 0; 318 return 0;
319 /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ 319 /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
320 if (capable(CAP_SYS_ADMIN)) { 320 if (capable(CAP_SYS_ADMIN)) {
321 WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " 321 printk_once(KERN_WARNING "%s (%d): "
322 "but no CAP_SYSLOG (deprecated).\n"); 322 "Attempt to access syslog with CAP_SYS_ADMIN "
323 "but no CAP_SYSLOG (deprecated).\n",
324 current->comm, task_pid_nr(current));
323 return 0; 325 return 0;
324 } 326 }
325 return -EPERM; 327 return -EPERM;
@@ -363,18 +365,18 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
363 if (error) 365 if (error)
364 goto out; 366 goto out;
365 i = 0; 367 i = 0;
366 spin_lock_irq(&logbuf_lock); 368 raw_spin_lock_irq(&logbuf_lock);
367 while (!error && (log_start != log_end) && i < len) { 369 while (!error && (log_start != log_end) && i < len) {
368 c = LOG_BUF(log_start); 370 c = LOG_BUF(log_start);
369 log_start++; 371 log_start++;
370 spin_unlock_irq(&logbuf_lock); 372 raw_spin_unlock_irq(&logbuf_lock);
371 error = __put_user(c,buf); 373 error = __put_user(c,buf);
372 buf++; 374 buf++;
373 i++; 375 i++;
374 cond_resched(); 376 cond_resched();
375 spin_lock_irq(&logbuf_lock); 377 raw_spin_lock_irq(&logbuf_lock);
376 } 378 }
377 spin_unlock_irq(&logbuf_lock); 379 raw_spin_unlock_irq(&logbuf_lock);
378 if (!error) 380 if (!error)
379 error = i; 381 error = i;
380 break; 382 break;
@@ -397,7 +399,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
397 count = len; 399 count = len;
398 if (count > log_buf_len) 400 if (count > log_buf_len)
399 count = log_buf_len; 401 count = log_buf_len;
400 spin_lock_irq(&logbuf_lock); 402 raw_spin_lock_irq(&logbuf_lock);
401 if (count > logged_chars) 403 if (count > logged_chars)
402 count = logged_chars; 404 count = logged_chars;
403 if (do_clear) 405 if (do_clear)
@@ -414,12 +416,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
414 if (j + log_buf_len < log_end) 416 if (j + log_buf_len < log_end)
415 break; 417 break;
416 c = LOG_BUF(j); 418 c = LOG_BUF(j);
417 spin_unlock_irq(&logbuf_lock); 419 raw_spin_unlock_irq(&logbuf_lock);
418 error = __put_user(c,&buf[count-1-i]); 420 error = __put_user(c,&buf[count-1-i]);
419 cond_resched(); 421 cond_resched();
420 spin_lock_irq(&logbuf_lock); 422 raw_spin_lock_irq(&logbuf_lock);
421 } 423 }
422 spin_unlock_irq(&logbuf_lock); 424 raw_spin_unlock_irq(&logbuf_lock);
423 if (error) 425 if (error)
424 break; 426 break;
425 error = i; 427 error = i;
@@ -530,6 +532,9 @@ static int __init ignore_loglevel_setup(char *str)
530} 532}
531 533
532early_param("ignore_loglevel", ignore_loglevel_setup); 534early_param("ignore_loglevel", ignore_loglevel_setup);
535module_param_named(ignore_loglevel, ignore_loglevel, bool, S_IRUGO | S_IWUSR);
536MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to"
537 "print all kernel messages to the console.");
533 538
534/* 539/*
535 * Write out chars from start to end - 1 inclusive 540 * Write out chars from start to end - 1 inclusive
@@ -590,9 +595,6 @@ static size_t log_prefix(const char *p, unsigned int *level, char *special)
590 /* multi digit including the level and facility number */ 595 /* multi digit including the level and facility number */
591 char *endp = NULL; 596 char *endp = NULL;
592 597
593 if (p[1] < '0' && p[1] > '9')
594 return 0;
595
596 lev = (simple_strtoul(&p[1], &endp, 10) & 7); 598 lev = (simple_strtoul(&p[1], &endp, 10) & 7);
597 if (endp == NULL || endp[0] != '>') 599 if (endp == NULL || endp[0] != '>')
598 return 0; 600 return 0;
@@ -687,7 +689,7 @@ static void zap_locks(void)
687 oops_timestamp = jiffies; 689 oops_timestamp = jiffies;
688 690
689 /* If a crash is occurring, make sure we can't deadlock */ 691 /* If a crash is occurring, make sure we can't deadlock */
690 spin_lock_init(&logbuf_lock); 692 raw_spin_lock_init(&logbuf_lock);
691 /* And make sure that we print immediately */ 693 /* And make sure that we print immediately */
692 sema_init(&console_sem, 1); 694 sema_init(&console_sem, 1);
693} 695}
@@ -782,7 +784,7 @@ static inline int can_use_console(unsigned int cpu)
782static int console_trylock_for_printk(unsigned int cpu) 784static int console_trylock_for_printk(unsigned int cpu)
783 __releases(&logbuf_lock) 785 __releases(&logbuf_lock)
784{ 786{
785 int retval = 0; 787 int retval = 0, wake = 0;
786 788
787 if (console_trylock()) { 789 if (console_trylock()) {
788 retval = 1; 790 retval = 1;
@@ -795,12 +797,14 @@ static int console_trylock_for_printk(unsigned int cpu)
795 */ 797 */
796 if (!can_use_console(cpu)) { 798 if (!can_use_console(cpu)) {
797 console_locked = 0; 799 console_locked = 0;
798 up(&console_sem); 800 wake = 1;
799 retval = 0; 801 retval = 0;
800 } 802 }
801 } 803 }
802 printk_cpu = UINT_MAX; 804 printk_cpu = UINT_MAX;
803 spin_unlock(&logbuf_lock); 805 if (wake)
806 up(&console_sem);
807 raw_spin_unlock(&logbuf_lock);
804 return retval; 808 return retval;
805} 809}
806static const char recursion_bug_msg [] = 810static const char recursion_bug_msg [] =
@@ -860,7 +864,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
860 } 864 }
861 865
862 lockdep_off(); 866 lockdep_off();
863 spin_lock(&logbuf_lock); 867 raw_spin_lock(&logbuf_lock);
864 printk_cpu = this_cpu; 868 printk_cpu = this_cpu;
865 869
866 if (recursion_bug) { 870 if (recursion_bug) {
@@ -1104,6 +1108,10 @@ static int __init console_suspend_disable(char *str)
1104 return 1; 1108 return 1;
1105} 1109}
1106__setup("no_console_suspend", console_suspend_disable); 1110__setup("no_console_suspend", console_suspend_disable);
1111module_param_named(console_suspend, console_suspend_enabled,
1112 bool, S_IRUGO | S_IWUSR);
1113MODULE_PARM_DESC(console_suspend, "suspend console during suspend"
1114 " and hibernate operations");
1107 1115
1108/** 1116/**
1109 * suspend_console - suspend the console subsystem 1117 * suspend_console - suspend the console subsystem
@@ -1242,7 +1250,7 @@ void console_unlock(void)
1242{ 1250{
1243 unsigned long flags; 1251 unsigned long flags;
1244 unsigned _con_start, _log_end; 1252 unsigned _con_start, _log_end;
1245 unsigned wake_klogd = 0; 1253 unsigned wake_klogd = 0, retry = 0;
1246 1254
1247 if (console_suspended) { 1255 if (console_suspended) {
1248 up(&console_sem); 1256 up(&console_sem);
@@ -1251,15 +1259,16 @@ void console_unlock(void)
1251 1259
1252 console_may_schedule = 0; 1260 console_may_schedule = 0;
1253 1261
1262again:
1254 for ( ; ; ) { 1263 for ( ; ; ) {
1255 spin_lock_irqsave(&logbuf_lock, flags); 1264 raw_spin_lock_irqsave(&logbuf_lock, flags);
1256 wake_klogd |= log_start - log_end; 1265 wake_klogd |= log_start - log_end;
1257 if (con_start == log_end) 1266 if (con_start == log_end)
1258 break; /* Nothing to print */ 1267 break; /* Nothing to print */
1259 _con_start = con_start; 1268 _con_start = con_start;
1260 _log_end = log_end; 1269 _log_end = log_end;
1261 con_start = log_end; /* Flush */ 1270 con_start = log_end; /* Flush */
1262 spin_unlock(&logbuf_lock); 1271 raw_spin_unlock(&logbuf_lock);
1263 stop_critical_timings(); /* don't trace print latency */ 1272 stop_critical_timings(); /* don't trace print latency */
1264 call_console_drivers(_con_start, _log_end); 1273 call_console_drivers(_con_start, _log_end);
1265 start_critical_timings(); 1274 start_critical_timings();
@@ -1271,8 +1280,23 @@ void console_unlock(void)
1271 if (unlikely(exclusive_console)) 1280 if (unlikely(exclusive_console))
1272 exclusive_console = NULL; 1281 exclusive_console = NULL;
1273 1282
1283 raw_spin_unlock(&logbuf_lock);
1284
1274 up(&console_sem); 1285 up(&console_sem);
1275 spin_unlock_irqrestore(&logbuf_lock, flags); 1286
1287 /*
1288 * Someone could have filled up the buffer again, so re-check if there's
1289 * something to flush. In case we cannot trylock the console_sem again,
1290 * there's a new owner and the console_unlock() from them will do the
1291 * flush, no worries.
1292 */
1293 raw_spin_lock(&logbuf_lock);
1294 if (con_start != log_end)
1295 retry = 1;
1296 if (retry && console_trylock())
1297 goto again;
1298
1299 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
1276 if (wake_klogd) 1300 if (wake_klogd)
1277 wake_up_klogd(); 1301 wake_up_klogd();
1278} 1302}
@@ -1502,9 +1526,9 @@ void register_console(struct console *newcon)
1502 * console_unlock(); will print out the buffered messages 1526 * console_unlock(); will print out the buffered messages
1503 * for us. 1527 * for us.
1504 */ 1528 */
1505 spin_lock_irqsave(&logbuf_lock, flags); 1529 raw_spin_lock_irqsave(&logbuf_lock, flags);
1506 con_start = log_start; 1530 con_start = log_start;
1507 spin_unlock_irqrestore(&logbuf_lock, flags); 1531 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
1508 /* 1532 /*
1509 * We're about to replay the log buffer. Only do this to the 1533 * We're about to replay the log buffer. Only do this to the
1510 * just-registered console to avoid excessive message spam to 1534 * just-registered console to avoid excessive message spam to
@@ -1584,7 +1608,7 @@ static int __init printk_late_init(void)
1584 struct console *con; 1608 struct console *con;
1585 1609
1586 for_each_console(con) { 1610 for_each_console(con) {
1587 if (con->flags & CON_BOOT) { 1611 if (!keep_bootcon && con->flags & CON_BOOT) {
1588 printk(KERN_INFO "turn off boot console %s%d\n", 1612 printk(KERN_INFO "turn off boot console %s%d\n",
1589 con->name, con->index); 1613 con->name, con->index);
1590 unregister_console(con); 1614 unregister_console(con);
@@ -1711,10 +1735,10 @@ void kmsg_dump(enum kmsg_dump_reason reason)
1711 /* Theoretically, the log could move on after we do this, but 1735 /* Theoretically, the log could move on after we do this, but
1712 there's not a lot we can do about that. The new messages 1736 there's not a lot we can do about that. The new messages
1713 will overwrite the start of what we dump. */ 1737 will overwrite the start of what we dump. */
1714 spin_lock_irqsave(&logbuf_lock, flags); 1738 raw_spin_lock_irqsave(&logbuf_lock, flags);
1715 end = log_end & LOG_BUF_MASK; 1739 end = log_end & LOG_BUF_MASK;
1716 chars = logged_chars; 1740 chars = logged_chars;
1717 spin_unlock_irqrestore(&logbuf_lock, flags); 1741 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
1718 1742
1719 if (chars > end) { 1743 if (chars > end) {
1720 s1 = log_buf + log_buf_len - chars + end; 1744 s1 = log_buf + log_buf_len - chars + end;