diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2011-08-27 09:43:54 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2011-08-27 10:06:11 -0400 |
commit | 7b1bb388bc879ffcc6c69b567816d5c354afe42b (patch) | |
tree | 5a217fdfb0b5e5a327bdcd624506337c1ae1fe32 /kernel/printk.c | |
parent | 7d754596756240fa918b94cd0c3011c77a638987 (diff) | |
parent | 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe (diff) |
Merge 'Linux v3.0' into Litmus
Some notes:
* Litmus^RT scheduling class is the topmost scheduling class
(above stop_sched_class).
* scheduler_ipi() function (e.g., in smp_reschedule_interrupt())
may increase IPI latencies.
* Added path into schedule() to quickly re-evaluate scheduling
decision without becoming preemptive again. This used to be
a standard path before the removal of BKL.
Conflicts:
Makefile
arch/arm/kernel/calls.S
arch/arm/kernel/smp.c
arch/x86/include/asm/unistd_32.h
arch/x86/kernel/smp.c
arch/x86/kernel/syscall_table_32.S
include/linux/hrtimer.h
kernel/printk.c
kernel/sched.c
kernel/sched_fair.c
Diffstat (limited to 'kernel/printk.c')
-rw-r--r-- | kernel/printk.c | 461 |
1 files changed, 312 insertions, 149 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 9dc8ea140426..b799a2ee96e5 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/smp.h> | 31 | #include <linux/smp.h> |
32 | #include <linux/security.h> | 32 | #include <linux/security.h> |
33 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
34 | #include <linux/memblock.h> | ||
34 | #include <linux/syscalls.h> | 35 | #include <linux/syscalls.h> |
35 | #include <linux/kexec.h> | 36 | #include <linux/kexec.h> |
36 | #include <linux/kdb.h> | 37 | #include <linux/kdb.h> |
@@ -39,16 +40,11 @@ | |||
39 | #include <linux/syslog.h> | 40 | #include <linux/syslog.h> |
40 | #include <linux/cpu.h> | 41 | #include <linux/cpu.h> |
41 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
43 | #include <linux/rculist.h> | ||
42 | 44 | ||
43 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
44 | 46 | ||
45 | /* | 47 | /* |
46 | * for_each_console() allows you to iterate on each console | ||
47 | */ | ||
48 | #define for_each_console(con) \ | ||
49 | for (con = console_drivers; con != NULL; con = con->next) | ||
50 | |||
51 | /* | ||
52 | * Architectures can override it: | 48 | * Architectures can override it: |
53 | */ | 49 | */ |
54 | void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) | 50 | void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) |
@@ -58,7 +54,7 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) | |||
58 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | 54 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) |
59 | 55 | ||
60 | /* printk's without a loglevel use this.. */ | 56 | /* printk's without a loglevel use this.. */ |
61 | #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ | 57 | #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL |
62 | 58 | ||
63 | /* We show everything that is MORE important than this.. */ | 59 | /* We show everything that is MORE important than this.. */ |
64 | #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ | 60 | #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ |
@@ -92,7 +88,7 @@ EXPORT_SYMBOL(oops_in_progress); | |||
92 | * provides serialisation for access to the entire console | 88 | * provides serialisation for access to the entire console |
93 | * driver system. | 89 | * driver system. |
94 | */ | 90 | */ |
95 | static DECLARE_MUTEX(console_sem); | 91 | static DEFINE_SEMAPHORE(console_sem); |
96 | struct console *console_drivers; | 92 | struct console *console_drivers; |
97 | EXPORT_SYMBOL_GPL(console_drivers); | 93 | EXPORT_SYMBOL_GPL(console_drivers); |
98 | 94 | ||
@@ -109,7 +105,7 @@ static int console_locked, console_suspended; | |||
109 | /* | 105 | /* |
110 | * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars | 106 | * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars |
111 | * It is also used in interesting ways to provide interlocking in | 107 | * It is also used in interesting ways to provide interlocking in |
112 | * release_console_sem(). | 108 | * console_unlock();. |
113 | */ | 109 | */ |
114 | static DEFINE_SPINLOCK(logbuf_lock); | 110 | static DEFINE_SPINLOCK(logbuf_lock); |
115 | 111 | ||
@@ -125,6 +121,11 @@ static unsigned con_start; /* Index into log_buf: next char to be sent to consol | |||
125 | static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */ | 121 | static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */ |
126 | 122 | ||
127 | /* | 123 | /* |
124 | * If exclusive_console is non-NULL then only this console is to be printed to. | ||
125 | */ | ||
126 | static struct console *exclusive_console; | ||
127 | |||
128 | /* | ||
128 | * Array of consoles built from command line options (console=) | 129 | * Array of consoles built from command line options (console=) |
129 | */ | 130 | */ |
130 | struct console_cmdline | 131 | struct console_cmdline |
@@ -174,50 +175,78 @@ void log_buf_kexec_setup(void) | |||
174 | } | 175 | } |
175 | #endif | 176 | #endif |
176 | 177 | ||
178 | /* requested log_buf_len from kernel cmdline */ | ||
179 | static unsigned long __initdata new_log_buf_len; | ||
180 | |||
181 | /* save requested log_buf_len since it's too early to process it */ | ||
177 | static int __init log_buf_len_setup(char *str) | 182 | static int __init log_buf_len_setup(char *str) |
178 | { | 183 | { |
179 | unsigned size = memparse(str, &str); | 184 | unsigned size = memparse(str, &str); |
180 | unsigned long flags; | ||
181 | 185 | ||
182 | if (size) | 186 | if (size) |
183 | size = roundup_pow_of_two(size); | 187 | size = roundup_pow_of_two(size); |
184 | if (size > log_buf_len) { | 188 | if (size > log_buf_len) |
185 | unsigned start, dest_idx, offset; | 189 | new_log_buf_len = size; |
186 | char *new_log_buf; | ||
187 | 190 | ||
188 | new_log_buf = alloc_bootmem(size); | 191 | return 0; |
189 | if (!new_log_buf) { | 192 | } |
190 | printk(KERN_WARNING "log_buf_len: allocation failed\n"); | 193 | early_param("log_buf_len", log_buf_len_setup); |
191 | goto out; | ||
192 | } | ||
193 | 194 | ||
194 | spin_lock_irqsave(&logbuf_lock, flags); | 195 | void __init setup_log_buf(int early) |
195 | log_buf_len = size; | 196 | { |
196 | log_buf = new_log_buf; | 197 | unsigned long flags; |
197 | 198 | unsigned start, dest_idx, offset; | |
198 | offset = start = min(con_start, log_start); | 199 | char *new_log_buf; |
199 | dest_idx = 0; | 200 | int free; |
200 | while (start != log_end) { | 201 | |
201 | log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)]; | 202 | if (!new_log_buf_len) |
202 | start++; | 203 | return; |
203 | dest_idx++; | 204 | |
204 | } | 205 | if (early) { |
205 | log_start -= offset; | 206 | unsigned long mem; |
206 | con_start -= offset; | ||
207 | log_end -= offset; | ||
208 | spin_unlock_irqrestore(&logbuf_lock, flags); | ||
209 | 207 | ||
210 | printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len); | 208 | mem = memblock_alloc(new_log_buf_len, PAGE_SIZE); |
209 | if (mem == MEMBLOCK_ERROR) | ||
210 | return; | ||
211 | new_log_buf = __va(mem); | ||
212 | } else { | ||
213 | new_log_buf = alloc_bootmem_nopanic(new_log_buf_len); | ||
211 | } | 214 | } |
212 | out: | ||
213 | return 1; | ||
214 | } | ||
215 | 215 | ||
216 | __setup("log_buf_len=", log_buf_len_setup); | 216 | if (unlikely(!new_log_buf)) { |
217 | pr_err("log_buf_len: %ld bytes not available\n", | ||
218 | new_log_buf_len); | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | spin_lock_irqsave(&logbuf_lock, flags); | ||
223 | log_buf_len = new_log_buf_len; | ||
224 | log_buf = new_log_buf; | ||
225 | new_log_buf_len = 0; | ||
226 | free = __LOG_BUF_LEN - log_end; | ||
227 | |||
228 | offset = start = min(con_start, log_start); | ||
229 | dest_idx = 0; | ||
230 | while (start != log_end) { | ||
231 | unsigned log_idx_mask = start & (__LOG_BUF_LEN - 1); | ||
232 | |||
233 | log_buf[dest_idx] = __log_buf[log_idx_mask]; | ||
234 | start++; | ||
235 | dest_idx++; | ||
236 | } | ||
237 | log_start -= offset; | ||
238 | con_start -= offset; | ||
239 | log_end -= offset; | ||
240 | spin_unlock_irqrestore(&logbuf_lock, flags); | ||
241 | |||
242 | pr_info("log_buf_len: %d\n", log_buf_len); | ||
243 | pr_info("early log buf free: %d(%d%%)\n", | ||
244 | free, (free * 100) / __LOG_BUF_LEN); | ||
245 | } | ||
217 | 246 | ||
218 | #ifdef CONFIG_BOOT_PRINTK_DELAY | 247 | #ifdef CONFIG_BOOT_PRINTK_DELAY |
219 | 248 | ||
220 | static unsigned int boot_delay; /* msecs delay after each printk during bootup */ | 249 | static int boot_delay; /* msecs delay after each printk during bootup */ |
221 | static unsigned long long loops_per_msec; /* based on boot_delay */ | 250 | static unsigned long long loops_per_msec; /* based on boot_delay */ |
222 | 251 | ||
223 | static int __init boot_delay_setup(char *str) | 252 | static int __init boot_delay_setup(char *str) |
@@ -268,14 +297,55 @@ static inline void boot_delay_msec(void) | |||
268 | } | 297 | } |
269 | #endif | 298 | #endif |
270 | 299 | ||
300 | #ifdef CONFIG_SECURITY_DMESG_RESTRICT | ||
301 | int dmesg_restrict = 1; | ||
302 | #else | ||
303 | int dmesg_restrict; | ||
304 | #endif | ||
305 | |||
306 | static int syslog_action_restricted(int type) | ||
307 | { | ||
308 | if (dmesg_restrict) | ||
309 | return 1; | ||
310 | /* Unless restricted, we allow "read all" and "get buffer size" for everybody */ | ||
311 | return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; | ||
312 | } | ||
313 | |||
314 | static int check_syslog_permissions(int type, bool from_file) | ||
315 | { | ||
316 | /* | ||
317 | * If this is from /proc/kmsg and we've already opened it, then we've | ||
318 | * already done the capabilities checks at open time. | ||
319 | */ | ||
320 | if (from_file && type != SYSLOG_ACTION_OPEN) | ||
321 | return 0; | ||
322 | |||
323 | if (syslog_action_restricted(type)) { | ||
324 | if (capable(CAP_SYSLOG)) | ||
325 | return 0; | ||
326 | /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ | ||
327 | if (capable(CAP_SYS_ADMIN)) { | ||
328 | WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " | ||
329 | "but no CAP_SYSLOG (deprecated).\n"); | ||
330 | return 0; | ||
331 | } | ||
332 | return -EPERM; | ||
333 | } | ||
334 | return 0; | ||
335 | } | ||
336 | |||
271 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 337 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
272 | { | 338 | { |
273 | unsigned i, j, limit, count; | 339 | unsigned i, j, limit, count; |
274 | int do_clear = 0; | 340 | int do_clear = 0; |
275 | char c; | 341 | char c; |
276 | int error = 0; | 342 | int error; |
343 | |||
344 | error = check_syslog_permissions(type, from_file); | ||
345 | if (error) | ||
346 | goto out; | ||
277 | 347 | ||
278 | error = security_syslog(type, from_file); | 348 | error = security_syslog(type); |
279 | if (error) | 349 | if (error) |
280 | return error; | 350 | return error; |
281 | 351 | ||
@@ -447,6 +517,8 @@ static void __call_console_drivers(unsigned start, unsigned end) | |||
447 | struct console *con; | 517 | struct console *con; |
448 | 518 | ||
449 | for_each_console(con) { | 519 | for_each_console(con) { |
520 | if (exclusive_console && con != exclusive_console) | ||
521 | continue; | ||
450 | if ((con->flags & CON_ENABLED) && con->write && | 522 | if ((con->flags & CON_ENABLED) && con->write && |
451 | (cpu_online(smp_processor_id()) || | 523 | (cpu_online(smp_processor_id()) || |
452 | (con->flags & CON_ANYTIME))) | 524 | (con->flags & CON_ANYTIME))) |
@@ -486,9 +558,74 @@ static void _call_console_drivers(unsigned start, | |||
486 | } | 558 | } |
487 | 559 | ||
488 | /* | 560 | /* |
561 | * Parse the syslog header <[0-9]*>. The decimal value represents 32bit, the | ||
562 | * lower 3 bit are the log level, the rest are the log facility. In case | ||
563 | * userspace passes usual userspace syslog messages to /dev/kmsg or | ||
564 | * /dev/ttyprintk, the log prefix might contain the facility. Printk needs | ||
565 | * to extract the correct log level for in-kernel processing, and not mangle | ||
566 | * the original value. | ||
567 | * | ||
568 | * If a prefix is found, the length of the prefix is returned. If 'level' is | ||
569 | * passed, it will be filled in with the log level without a possible facility | ||
570 | * value. If 'special' is passed, the special printk prefix chars are accepted | ||
571 | * and returned. If no valid header is found, 0 is returned and the passed | ||
572 | * variables are not touched. | ||
573 | */ | ||
574 | static size_t log_prefix(const char *p, unsigned int *level, char *special) | ||
575 | { | ||
576 | unsigned int lev = 0; | ||
577 | char sp = '\0'; | ||
578 | size_t len; | ||
579 | |||
580 | if (p[0] != '<' || !p[1]) | ||
581 | return 0; | ||
582 | if (p[2] == '>') { | ||
583 | /* usual single digit level number or special char */ | ||
584 | switch (p[1]) { | ||
585 | case '0' ... '7': | ||
586 | lev = p[1] - '0'; | ||
587 | break; | ||
588 | case 'c': /* KERN_CONT */ | ||
589 | case 'd': /* KERN_DEFAULT */ | ||
590 | sp = p[1]; | ||
591 | break; | ||
592 | default: | ||
593 | return 0; | ||
594 | } | ||
595 | len = 3; | ||
596 | } else { | ||
597 | /* multi digit including the level and facility number */ | ||
598 | char *endp = NULL; | ||
599 | |||
600 | if (p[1] < '0' && p[1] > '9') | ||
601 | return 0; | ||
602 | |||
603 | lev = (simple_strtoul(&p[1], &endp, 10) & 7); | ||
604 | if (endp == NULL || endp[0] != '>') | ||
605 | return 0; | ||
606 | len = (endp + 1) - p; | ||
607 | } | ||
608 | |||
609 | /* do not accept special char if not asked for */ | ||
610 | if (sp && !special) | ||
611 | return 0; | ||
612 | |||
613 | if (special) { | ||
614 | *special = sp; | ||
615 | /* return special char, do not touch level */ | ||
616 | if (sp) | ||
617 | return len; | ||
618 | } | ||
619 | |||
620 | if (level) | ||
621 | *level = lev; | ||
622 | return len; | ||
623 | } | ||
624 | |||
625 | /* | ||
489 | * Call the console drivers, asking them to write out | 626 | * Call the console drivers, asking them to write out |
490 | * log_buf[start] to log_buf[end - 1]. | 627 | * log_buf[start] to log_buf[end - 1]. |
491 | * The console_sem must be held. | 628 | * The console_lock must be held. |
492 | */ | 629 | */ |
493 | static void call_console_drivers(unsigned start, unsigned end) | 630 | static void call_console_drivers(unsigned start, unsigned end) |
494 | { | 631 | { |
@@ -500,13 +637,9 @@ static void call_console_drivers(unsigned start, unsigned end) | |||
500 | cur_index = start; | 637 | cur_index = start; |
501 | start_print = start; | 638 | start_print = start; |
502 | while (cur_index != end) { | 639 | while (cur_index != end) { |
503 | if (msg_level < 0 && ((end - cur_index) > 2) && | 640 | if (msg_level < 0 && ((end - cur_index) > 2)) { |
504 | LOG_BUF(cur_index + 0) == '<' && | 641 | /* strip log prefix */ |
505 | LOG_BUF(cur_index + 1) >= '0' && | 642 | cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL); |
506 | LOG_BUF(cur_index + 1) <= '7' && | ||
507 | LOG_BUF(cur_index + 2) == '>') { | ||
508 | msg_level = LOG_BUF(cur_index + 1) - '0'; | ||
509 | cur_index += 3; | ||
510 | start_print = cur_index; | 643 | start_print = cur_index; |
511 | } | 644 | } |
512 | while (cur_index != end) { | 645 | while (cur_index != end) { |
@@ -563,7 +696,7 @@ static void zap_locks(void) | |||
563 | /* If a crash is occurring, make sure we can't deadlock */ | 696 | /* If a crash is occurring, make sure we can't deadlock */ |
564 | spin_lock_init(&logbuf_lock); | 697 | spin_lock_init(&logbuf_lock); |
565 | /* And make sure that we print immediately */ | 698 | /* And make sure that we print immediately */ |
566 | init_MUTEX(&console_sem); | 699 | sema_init(&console_sem, 1); |
567 | } | 700 | } |
568 | 701 | ||
569 | #if defined(CONFIG_PRINTK_TIME) | 702 | #if defined(CONFIG_PRINTK_TIME) |
@@ -591,11 +724,11 @@ static int have_callable_console(void) | |||
591 | * | 724 | * |
592 | * This is printk(). It can be called from any context. We want it to work. | 725 | * This is printk(). It can be called from any context. We want it to work. |
593 | * | 726 | * |
594 | * We try to grab the console_sem. If we succeed, it's easy - we log the output and | 727 | * We try to grab the console_lock. If we succeed, it's easy - we log the output and |
595 | * call the console drivers. If we fail to get the semaphore we place the output | 728 | * call the console drivers. If we fail to get the semaphore we place the output |
596 | * into the log buffer and return. The current holder of the console_sem will | 729 | * into the log buffer and return. The current holder of the console_sem will |
597 | * notice the new output in release_console_sem() and will send it to the | 730 | * notice the new output in console_unlock(); and will send it to the |
598 | * consoles before releasing the semaphore. | 731 | * consoles before releasing the lock. |
599 | * | 732 | * |
600 | * One effect of this deferred printing is that code which calls printk() and | 733 | * One effect of this deferred printing is that code which calls printk() and |
601 | * then changes console_loglevel may break. This is because console_loglevel | 734 | * then changes console_loglevel may break. This is because console_loglevel |
@@ -646,18 +779,19 @@ static inline int can_use_console(unsigned int cpu) | |||
646 | /* | 779 | /* |
647 | * Try to get console ownership to actually show the kernel | 780 | * Try to get console ownership to actually show the kernel |
648 | * messages from a 'printk'. Return true (and with the | 781 | * messages from a 'printk'. Return true (and with the |
649 | * console_semaphore held, and 'console_locked' set) if it | 782 | * console_lock held, and 'console_locked' set) if it |
650 | * is successful, false otherwise. | 783 | * is successful, false otherwise. |
651 | * | 784 | * |
652 | * This gets called with the 'logbuf_lock' spinlock held and | 785 | * This gets called with the 'logbuf_lock' spinlock held and |
653 | * interrupts disabled. It should return with 'lockbuf_lock' | 786 | * interrupts disabled. It should return with 'lockbuf_lock' |
654 | * released but interrupts still disabled. | 787 | * released but interrupts still disabled. |
655 | */ | 788 | */ |
656 | static int acquire_console_semaphore_for_printk(unsigned int cpu) | 789 | static int console_trylock_for_printk(unsigned int cpu) |
790 | __releases(&logbuf_lock) | ||
657 | { | 791 | { |
658 | int retval = 0; | 792 | int retval = 0; |
659 | 793 | ||
660 | if (!try_acquire_console_sem()) { | 794 | if (console_trylock()) { |
661 | retval = 1; | 795 | retval = 1; |
662 | 796 | ||
663 | /* | 797 | /* |
@@ -703,6 +837,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
703 | unsigned long flags; | 837 | unsigned long flags; |
704 | int this_cpu; | 838 | int this_cpu; |
705 | char *p; | 839 | char *p; |
840 | size_t plen; | ||
841 | char special; | ||
706 | 842 | ||
707 | boot_delay_msec(); | 843 | boot_delay_msec(); |
708 | printk_delay(); | 844 | printk_delay(); |
@@ -746,45 +882,52 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
746 | if (trace_override && !trace_recurse) | 882 | if (trace_override && !trace_recurse) |
747 | TRACE("%s", printk_buf); | 883 | TRACE("%s", printk_buf); |
748 | 884 | ||
749 | |||
750 | p = printk_buf; | 885 | p = printk_buf; |
751 | 886 | ||
752 | /* Do we have a loglevel in the string? */ | 887 | /* Read log level and handle special printk prefix */ |
753 | if (p[0] == '<') { | 888 | plen = log_prefix(p, ¤t_log_level, &special); |
754 | unsigned char c = p[1]; | 889 | if (plen) { |
755 | if (c && p[2] == '>') { | 890 | p += plen; |
756 | switch (c) { | 891 | |
757 | case '0' ... '7': /* loglevel */ | 892 | switch (special) { |
758 | current_log_level = c - '0'; | 893 | case 'c': /* Strip <c> KERN_CONT, continue line */ |
759 | /* Fallthrough - make sure we're on a new line */ | 894 | plen = 0; |
760 | case 'd': /* KERN_DEFAULT */ | 895 | break; |
761 | if (!new_text_line) { | 896 | case 'd': /* Strip <d> KERN_DEFAULT, start new line */ |
762 | emit_log_char('\n'); | 897 | plen = 0; |
763 | new_text_line = 1; | 898 | default: |
764 | } | 899 | if (!new_text_line) { |
765 | /* Fallthrough - skip the loglevel */ | 900 | emit_log_char('\n'); |
766 | case 'c': /* KERN_CONT */ | 901 | new_text_line = 1; |
767 | p += 3; | ||
768 | break; | ||
769 | } | 902 | } |
770 | } | 903 | } |
771 | } | 904 | } |
772 | 905 | ||
773 | /* | 906 | /* |
774 | * Copy the output into log_buf. If the caller didn't provide | 907 | * Copy the output into log_buf. If the caller didn't provide |
775 | * appropriate log level tags, we insert them here | 908 | * the appropriate log prefix, we insert them here |
776 | */ | 909 | */ |
777 | for ( ; *p; p++) { | 910 | for (; *p; p++) { |
778 | if (new_text_line) { | 911 | if (new_text_line) { |
779 | /* Always output the token */ | ||
780 | emit_log_char('<'); | ||
781 | emit_log_char(current_log_level + '0'); | ||
782 | emit_log_char('>'); | ||
783 | printed_len += 3; | ||
784 | new_text_line = 0; | 912 | new_text_line = 0; |
785 | 913 | ||
914 | if (plen) { | ||
915 | /* Copy original log prefix */ | ||
916 | int i; | ||
917 | |||
918 | for (i = 0; i < plen; i++) | ||
919 | emit_log_char(printk_buf[i]); | ||
920 | printed_len += plen; | ||
921 | } else { | ||
922 | /* Add log prefix */ | ||
923 | emit_log_char('<'); | ||
924 | emit_log_char(current_log_level + '0'); | ||
925 | emit_log_char('>'); | ||
926 | printed_len += 3; | ||
927 | } | ||
928 | |||
786 | if (printk_time) { | 929 | if (printk_time) { |
787 | /* Follow the token with the time */ | 930 | /* Add the current time stamp */ |
788 | char tbuf[50], *tp; | 931 | char tbuf[50], *tp; |
789 | unsigned tlen; | 932 | unsigned tlen; |
790 | unsigned long long t; | 933 | unsigned long long t; |
@@ -816,12 +959,12 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
816 | * actual magic (print out buffers, wake up klogd, | 959 | * actual magic (print out buffers, wake up klogd, |
817 | * etc). | 960 | * etc). |
818 | * | 961 | * |
819 | * The acquire_console_semaphore_for_printk() function | 962 | * The console_trylock_for_printk() function |
820 | * will release 'logbuf_lock' regardless of whether it | 963 | * will release 'logbuf_lock' regardless of whether it |
821 | * actually gets the semaphore or not. | 964 | * actually gets the semaphore or not. |
822 | */ | 965 | */ |
823 | if (acquire_console_semaphore_for_printk(this_cpu)) | 966 | if (console_trylock_for_printk(this_cpu)) |
824 | release_console_sem(); | 967 | console_unlock(); |
825 | 968 | ||
826 | lockdep_on(); | 969 | lockdep_on(); |
827 | out_restore_irqs: | 970 | out_restore_irqs: |
@@ -982,7 +1125,7 @@ void suspend_console(void) | |||
982 | if (!console_suspend_enabled) | 1125 | if (!console_suspend_enabled) |
983 | return; | 1126 | return; |
984 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); | 1127 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); |
985 | acquire_console_sem(); | 1128 | console_lock(); |
986 | console_suspended = 1; | 1129 | console_suspended = 1; |
987 | up(&console_sem); | 1130 | up(&console_sem); |
988 | } | 1131 | } |
@@ -993,7 +1136,7 @@ void resume_console(void) | |||
993 | return; | 1136 | return; |
994 | down(&console_sem); | 1137 | down(&console_sem); |
995 | console_suspended = 0; | 1138 | console_suspended = 0; |
996 | release_console_sem(); | 1139 | console_unlock(); |
997 | } | 1140 | } |
998 | 1141 | ||
999 | /** | 1142 | /** |
@@ -1016,21 +1159,21 @@ static int __cpuinit console_cpu_notify(struct notifier_block *self, | |||
1016 | case CPU_DYING: | 1159 | case CPU_DYING: |
1017 | case CPU_DOWN_FAILED: | 1160 | case CPU_DOWN_FAILED: |
1018 | case CPU_UP_CANCELED: | 1161 | case CPU_UP_CANCELED: |
1019 | acquire_console_sem(); | 1162 | console_lock(); |
1020 | release_console_sem(); | 1163 | console_unlock(); |
1021 | } | 1164 | } |
1022 | return NOTIFY_OK; | 1165 | return NOTIFY_OK; |
1023 | } | 1166 | } |
1024 | 1167 | ||
1025 | /** | 1168 | /** |
1026 | * acquire_console_sem - lock the console system for exclusive use. | 1169 | * console_lock - lock the console system for exclusive use. |
1027 | * | 1170 | * |
1028 | * Acquires a semaphore which guarantees that the caller has | 1171 | * Acquires a lock which guarantees that the caller has |
1029 | * exclusive access to the console system and the console_drivers list. | 1172 | * exclusive access to the console system and the console_drivers list. |
1030 | * | 1173 | * |
1031 | * Can sleep, returns nothing. | 1174 | * Can sleep, returns nothing. |
1032 | */ | 1175 | */ |
1033 | void acquire_console_sem(void) | 1176 | void console_lock(void) |
1034 | { | 1177 | { |
1035 | BUG_ON(in_interrupt()); | 1178 | BUG_ON(in_interrupt()); |
1036 | down(&console_sem); | 1179 | down(&console_sem); |
@@ -1039,21 +1182,29 @@ void acquire_console_sem(void) | |||
1039 | console_locked = 1; | 1182 | console_locked = 1; |
1040 | console_may_schedule = 1; | 1183 | console_may_schedule = 1; |
1041 | } | 1184 | } |
1042 | EXPORT_SYMBOL(acquire_console_sem); | 1185 | EXPORT_SYMBOL(console_lock); |
1043 | 1186 | ||
1044 | int try_acquire_console_sem(void) | 1187 | /** |
1188 | * console_trylock - try to lock the console system for exclusive use. | ||
1189 | * | ||
1190 | * Tried to acquire a lock which guarantees that the caller has | ||
1191 | * exclusive access to the console system and the console_drivers list. | ||
1192 | * | ||
1193 | * returns 1 on success, and 0 on failure to acquire the lock. | ||
1194 | */ | ||
1195 | int console_trylock(void) | ||
1045 | { | 1196 | { |
1046 | if (down_trylock(&console_sem)) | 1197 | if (down_trylock(&console_sem)) |
1047 | return -1; | 1198 | return 0; |
1048 | if (console_suspended) { | 1199 | if (console_suspended) { |
1049 | up(&console_sem); | 1200 | up(&console_sem); |
1050 | return -1; | 1201 | return 0; |
1051 | } | 1202 | } |
1052 | console_locked = 1; | 1203 | console_locked = 1; |
1053 | console_may_schedule = 0; | 1204 | console_may_schedule = 0; |
1054 | return 0; | 1205 | return 1; |
1055 | } | 1206 | } |
1056 | EXPORT_SYMBOL(try_acquire_console_sem); | 1207 | EXPORT_SYMBOL(console_trylock); |
1057 | 1208 | ||
1058 | int is_console_locked(void) | 1209 | int is_console_locked(void) |
1059 | { | 1210 | { |
@@ -1064,38 +1215,40 @@ static DEFINE_PER_CPU(int, printk_pending); | |||
1064 | 1215 | ||
1065 | void printk_tick(void) | 1216 | void printk_tick(void) |
1066 | { | 1217 | { |
1067 | if (__get_cpu_var(printk_pending)) { | 1218 | if (__this_cpu_read(printk_pending)) { |
1068 | __get_cpu_var(printk_pending) = 0; | 1219 | __this_cpu_write(printk_pending, 0); |
1069 | wake_up_interruptible(&log_wait); | 1220 | wake_up_interruptible(&log_wait); |
1070 | } | 1221 | } |
1071 | } | 1222 | } |
1072 | 1223 | ||
1073 | int printk_needs_cpu(int cpu) | 1224 | int printk_needs_cpu(int cpu) |
1074 | { | 1225 | { |
1075 | return per_cpu(printk_pending, cpu); | 1226 | if (cpu_is_offline(cpu)) |
1227 | printk_tick(); | ||
1228 | return __this_cpu_read(printk_pending); | ||
1076 | } | 1229 | } |
1077 | 1230 | ||
1078 | void wake_up_klogd(void) | 1231 | void wake_up_klogd(void) |
1079 | { | 1232 | { |
1080 | if (!trace_override && waitqueue_active(&log_wait)) | 1233 | if (!trace_override && waitqueue_active(&log_wait)) |
1081 | __raw_get_cpu_var(printk_pending) = 1; | 1234 | this_cpu_write(printk_pending, 1); |
1082 | } | 1235 | } |
1083 | 1236 | ||
1084 | /** | 1237 | /** |
1085 | * release_console_sem - unlock the console system | 1238 | * console_unlock - unlock the console system |
1086 | * | 1239 | * |
1087 | * Releases the semaphore which the caller holds on the console system | 1240 | * Releases the console_lock which the caller holds on the console system |
1088 | * and the console driver list. | 1241 | * and the console driver list. |
1089 | * | 1242 | * |
1090 | * While the semaphore was held, console output may have been buffered | 1243 | * While the console_lock was held, console output may have been buffered |
1091 | * by printk(). If this is the case, release_console_sem() emits | 1244 | * by printk(). If this is the case, console_unlock(); emits |
1092 | * the output prior to releasing the semaphore. | 1245 | * the output prior to releasing the lock. |
1093 | * | 1246 | * |
1094 | * If there is output waiting for klogd, we wake it up. | 1247 | * If there is output waiting for klogd, we wake it up. |
1095 | * | 1248 | * |
1096 | * release_console_sem() may be called from any context. | 1249 | * console_unlock(); may be called from any context. |
1097 | */ | 1250 | */ |
1098 | void release_console_sem(void) | 1251 | void console_unlock(void) |
1099 | { | 1252 | { |
1100 | unsigned long flags; | 1253 | unsigned long flags; |
1101 | unsigned _con_start, _log_end; | 1254 | unsigned _con_start, _log_end; |
@@ -1123,12 +1276,17 @@ void release_console_sem(void) | |||
1123 | local_irq_restore(flags); | 1276 | local_irq_restore(flags); |
1124 | } | 1277 | } |
1125 | console_locked = 0; | 1278 | console_locked = 0; |
1279 | |||
1280 | /* Release the exclusive_console once it is used */ | ||
1281 | if (unlikely(exclusive_console)) | ||
1282 | exclusive_console = NULL; | ||
1283 | |||
1126 | up(&console_sem); | 1284 | up(&console_sem); |
1127 | spin_unlock_irqrestore(&logbuf_lock, flags); | 1285 | spin_unlock_irqrestore(&logbuf_lock, flags); |
1128 | if (wake_klogd) | 1286 | if (wake_klogd) |
1129 | wake_up_klogd(); | 1287 | wake_up_klogd(); |
1130 | } | 1288 | } |
1131 | EXPORT_SYMBOL(release_console_sem); | 1289 | EXPORT_SYMBOL(console_unlock); |
1132 | 1290 | ||
1133 | /** | 1291 | /** |
1134 | * console_conditional_schedule - yield the CPU if required | 1292 | * console_conditional_schedule - yield the CPU if required |
@@ -1137,7 +1295,7 @@ EXPORT_SYMBOL(release_console_sem); | |||
1137 | * if this CPU should yield the CPU to another task, do | 1295 | * if this CPU should yield the CPU to another task, do |
1138 | * so here. | 1296 | * so here. |
1139 | * | 1297 | * |
1140 | * Must be called within acquire_console_sem(). | 1298 | * Must be called within console_lock();. |
1141 | */ | 1299 | */ |
1142 | void __sched console_conditional_schedule(void) | 1300 | void __sched console_conditional_schedule(void) |
1143 | { | 1301 | { |
@@ -1158,14 +1316,14 @@ void console_unblank(void) | |||
1158 | if (down_trylock(&console_sem) != 0) | 1316 | if (down_trylock(&console_sem) != 0) |
1159 | return; | 1317 | return; |
1160 | } else | 1318 | } else |
1161 | acquire_console_sem(); | 1319 | console_lock(); |
1162 | 1320 | ||
1163 | console_locked = 1; | 1321 | console_locked = 1; |
1164 | console_may_schedule = 0; | 1322 | console_may_schedule = 0; |
1165 | for_each_console(c) | 1323 | for_each_console(c) |
1166 | if ((c->flags & CON_ENABLED) && c->unblank) | 1324 | if ((c->flags & CON_ENABLED) && c->unblank) |
1167 | c->unblank(); | 1325 | c->unblank(); |
1168 | release_console_sem(); | 1326 | console_unlock(); |
1169 | } | 1327 | } |
1170 | 1328 | ||
1171 | /* | 1329 | /* |
@@ -1176,7 +1334,7 @@ struct tty_driver *console_device(int *index) | |||
1176 | struct console *c; | 1334 | struct console *c; |
1177 | struct tty_driver *driver = NULL; | 1335 | struct tty_driver *driver = NULL; |
1178 | 1336 | ||
1179 | acquire_console_sem(); | 1337 | console_lock(); |
1180 | for_each_console(c) { | 1338 | for_each_console(c) { |
1181 | if (!c->device) | 1339 | if (!c->device) |
1182 | continue; | 1340 | continue; |
@@ -1184,7 +1342,7 @@ struct tty_driver *console_device(int *index) | |||
1184 | if (driver) | 1342 | if (driver) |
1185 | break; | 1343 | break; |
1186 | } | 1344 | } |
1187 | release_console_sem(); | 1345 | console_unlock(); |
1188 | return driver; | 1346 | return driver; |
1189 | } | 1347 | } |
1190 | 1348 | ||
@@ -1195,20 +1353,32 @@ struct tty_driver *console_device(int *index) | |||
1195 | */ | 1353 | */ |
1196 | void console_stop(struct console *console) | 1354 | void console_stop(struct console *console) |
1197 | { | 1355 | { |
1198 | acquire_console_sem(); | 1356 | console_lock(); |
1199 | console->flags &= ~CON_ENABLED; | 1357 | console->flags &= ~CON_ENABLED; |
1200 | release_console_sem(); | 1358 | console_unlock(); |
1201 | } | 1359 | } |
1202 | EXPORT_SYMBOL(console_stop); | 1360 | EXPORT_SYMBOL(console_stop); |
1203 | 1361 | ||
1204 | void console_start(struct console *console) | 1362 | void console_start(struct console *console) |
1205 | { | 1363 | { |
1206 | acquire_console_sem(); | 1364 | console_lock(); |
1207 | console->flags |= CON_ENABLED; | 1365 | console->flags |= CON_ENABLED; |
1208 | release_console_sem(); | 1366 | console_unlock(); |
1209 | } | 1367 | } |
1210 | EXPORT_SYMBOL(console_start); | 1368 | EXPORT_SYMBOL(console_start); |
1211 | 1369 | ||
1370 | static int __read_mostly keep_bootcon; | ||
1371 | |||
1372 | static int __init keep_bootcon_setup(char *str) | ||
1373 | { | ||
1374 | keep_bootcon = 1; | ||
1375 | printk(KERN_INFO "debug: skip boot console de-registration.\n"); | ||
1376 | |||
1377 | return 0; | ||
1378 | } | ||
1379 | |||
1380 | early_param("keep_bootcon", keep_bootcon_setup); | ||
1381 | |||
1212 | /* | 1382 | /* |
1213 | * The console driver calls this routine during kernel initialization | 1383 | * The console driver calls this routine during kernel initialization |
1214 | * to register the console printing procedure with printk() and to | 1384 | * to register the console printing procedure with printk() and to |
@@ -1327,7 +1497,7 @@ void register_console(struct console *newcon) | |||
1327 | * Put this console in the list - keep the | 1497 | * Put this console in the list - keep the |
1328 | * preferred driver at the head of the list. | 1498 | * preferred driver at the head of the list. |
1329 | */ | 1499 | */ |
1330 | acquire_console_sem(); | 1500 | console_lock(); |
1331 | if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) { | 1501 | if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) { |
1332 | newcon->next = console_drivers; | 1502 | newcon->next = console_drivers; |
1333 | console_drivers = newcon; | 1503 | console_drivers = newcon; |
@@ -1339,14 +1509,21 @@ void register_console(struct console *newcon) | |||
1339 | } | 1509 | } |
1340 | if (newcon->flags & CON_PRINTBUFFER) { | 1510 | if (newcon->flags & CON_PRINTBUFFER) { |
1341 | /* | 1511 | /* |
1342 | * release_console_sem() will print out the buffered messages | 1512 | * console_unlock(); will print out the buffered messages |
1343 | * for us. | 1513 | * for us. |
1344 | */ | 1514 | */ |
1345 | spin_lock_irqsave(&logbuf_lock, flags); | 1515 | spin_lock_irqsave(&logbuf_lock, flags); |
1346 | con_start = log_start; | 1516 | con_start = log_start; |
1347 | spin_unlock_irqrestore(&logbuf_lock, flags); | 1517 | spin_unlock_irqrestore(&logbuf_lock, flags); |
1518 | /* | ||
1519 | * We're about to replay the log buffer. Only do this to the | ||
1520 | * just-registered console to avoid excessive message spam to | ||
1521 | * the already-registered consoles. | ||
1522 | */ | ||
1523 | exclusive_console = newcon; | ||
1348 | } | 1524 | } |
1349 | release_console_sem(); | 1525 | console_unlock(); |
1526 | console_sysfs_notify(); | ||
1350 | 1527 | ||
1351 | /* | 1528 | /* |
1352 | * By unregistering the bootconsoles after we enable the real console | 1529 | * By unregistering the bootconsoles after we enable the real console |
@@ -1355,7 +1532,9 @@ void register_console(struct console *newcon) | |||
1355 | * users know there might be something in the kernel's log buffer that | 1532 | * users know there might be something in the kernel's log buffer that |
1356 | * went to the bootconsole (that they do not see on the real console) | 1533 | * went to the bootconsole (that they do not see on the real console) |
1357 | */ | 1534 | */ |
1358 | if (bcon && ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV)) { | 1535 | if (bcon && |
1536 | ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) && | ||
1537 | !keep_bootcon) { | ||
1359 | /* we need to iterate through twice, to make sure we print | 1538 | /* we need to iterate through twice, to make sure we print |
1360 | * everything out, before we unregister the console(s) | 1539 | * everything out, before we unregister the console(s) |
1361 | */ | 1540 | */ |
@@ -1382,7 +1561,7 @@ int unregister_console(struct console *console) | |||
1382 | return braille_unregister_console(console); | 1561 | return braille_unregister_console(console); |
1383 | #endif | 1562 | #endif |
1384 | 1563 | ||
1385 | acquire_console_sem(); | 1564 | console_lock(); |
1386 | if (console_drivers == console) { | 1565 | if (console_drivers == console) { |
1387 | console_drivers=console->next; | 1566 | console_drivers=console->next; |
1388 | res = 0; | 1567 | res = 0; |
@@ -1404,7 +1583,8 @@ int unregister_console(struct console *console) | |||
1404 | if (console_drivers != NULL && console->flags & CON_CONSDEV) | 1583 | if (console_drivers != NULL && console->flags & CON_CONSDEV) |
1405 | console_drivers->flags |= CON_CONSDEV; | 1584 | console_drivers->flags |= CON_CONSDEV; |
1406 | 1585 | ||
1407 | release_console_sem(); | 1586 | console_unlock(); |
1587 | console_sysfs_notify(); | ||
1408 | return res; | 1588 | return res; |
1409 | } | 1589 | } |
1410 | EXPORT_SYMBOL(unregister_console); | 1590 | EXPORT_SYMBOL(unregister_console); |
@@ -1488,7 +1668,7 @@ int kmsg_dump_register(struct kmsg_dumper *dumper) | |||
1488 | /* Don't allow registering multiple times */ | 1668 | /* Don't allow registering multiple times */ |
1489 | if (!dumper->registered) { | 1669 | if (!dumper->registered) { |
1490 | dumper->registered = 1; | 1670 | dumper->registered = 1; |
1491 | list_add_tail(&dumper->list, &dump_list); | 1671 | list_add_tail_rcu(&dumper->list, &dump_list); |
1492 | err = 0; | 1672 | err = 0; |
1493 | } | 1673 | } |
1494 | spin_unlock_irqrestore(&dump_list_lock, flags); | 1674 | spin_unlock_irqrestore(&dump_list_lock, flags); |
@@ -1512,29 +1692,16 @@ int kmsg_dump_unregister(struct kmsg_dumper *dumper) | |||
1512 | spin_lock_irqsave(&dump_list_lock, flags); | 1692 | spin_lock_irqsave(&dump_list_lock, flags); |
1513 | if (dumper->registered) { | 1693 | if (dumper->registered) { |
1514 | dumper->registered = 0; | 1694 | dumper->registered = 0; |
1515 | list_del(&dumper->list); | 1695 | list_del_rcu(&dumper->list); |
1516 | err = 0; | 1696 | err = 0; |
1517 | } | 1697 | } |
1518 | spin_unlock_irqrestore(&dump_list_lock, flags); | 1698 | spin_unlock_irqrestore(&dump_list_lock, flags); |
1699 | synchronize_rcu(); | ||
1519 | 1700 | ||
1520 | return err; | 1701 | return err; |
1521 | } | 1702 | } |
1522 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); | 1703 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); |
1523 | 1704 | ||
1524 | static const char const *kmsg_reasons[] = { | ||
1525 | [KMSG_DUMP_OOPS] = "oops", | ||
1526 | [KMSG_DUMP_PANIC] = "panic", | ||
1527 | [KMSG_DUMP_KEXEC] = "kexec", | ||
1528 | }; | ||
1529 | |||
1530 | static const char *kmsg_to_str(enum kmsg_dump_reason reason) | ||
1531 | { | ||
1532 | if (reason >= ARRAY_SIZE(kmsg_reasons) || reason < 0) | ||
1533 | return "unknown"; | ||
1534 | |||
1535 | return kmsg_reasons[reason]; | ||
1536 | } | ||
1537 | |||
1538 | /** | 1705 | /** |
1539 | * kmsg_dump - dump kernel log to kernel message dumpers. | 1706 | * kmsg_dump - dump kernel log to kernel message dumpers. |
1540 | * @reason: the reason (oops, panic etc) for dumping | 1707 | * @reason: the reason (oops, panic etc) for dumping |
@@ -1573,13 +1740,9 @@ void kmsg_dump(enum kmsg_dump_reason reason) | |||
1573 | l2 = chars; | 1740 | l2 = chars; |
1574 | } | 1741 | } |
1575 | 1742 | ||
1576 | if (!spin_trylock_irqsave(&dump_list_lock, flags)) { | 1743 | rcu_read_lock(); |
1577 | printk(KERN_ERR "dump_kmsg: dump list lock is held during %s, skipping dump\n", | 1744 | list_for_each_entry_rcu(dumper, &dump_list, list) |
1578 | kmsg_to_str(reason)); | ||
1579 | return; | ||
1580 | } | ||
1581 | list_for_each_entry(dumper, &dump_list, list) | ||
1582 | dumper->dump(dumper, reason, s1, l1, s2, l2); | 1745 | dumper->dump(dumper, reason, s1, l1, s2, l2); |
1583 | spin_unlock_irqrestore(&dump_list_lock, flags); | 1746 | rcu_read_unlock(); |
1584 | } | 1747 | } |
1585 | #endif | 1748 | #endif |