diff options
Diffstat (limited to 'kernel/printk.c')
-rw-r--r-- | kernel/printk.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 69188f226a93..5052b5497c67 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/security.h> | 32 | #include <linux/security.h> |
33 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
34 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
35 | #include <linux/kexec.h> | ||
35 | 36 | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | 38 | ||
@@ -73,7 +74,6 @@ EXPORT_SYMBOL(oops_in_progress); | |||
73 | * driver system. | 74 | * driver system. |
74 | */ | 75 | */ |
75 | static DECLARE_MUTEX(console_sem); | 76 | static DECLARE_MUTEX(console_sem); |
76 | static DECLARE_MUTEX(secondary_console_sem); | ||
77 | struct console *console_drivers; | 77 | struct console *console_drivers; |
78 | EXPORT_SYMBOL_GPL(console_drivers); | 78 | EXPORT_SYMBOL_GPL(console_drivers); |
79 | 79 | ||
@@ -136,6 +136,24 @@ static char *log_buf = __log_buf; | |||
136 | static int log_buf_len = __LOG_BUF_LEN; | 136 | static int log_buf_len = __LOG_BUF_LEN; |
137 | static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ | 137 | static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ |
138 | 138 | ||
139 | #ifdef CONFIG_KEXEC | ||
140 | /* | ||
141 | * This appends the listed symbols to /proc/vmcoreinfo | ||
142 | * | ||
143 | * /proc/vmcoreinfo is used by various utiilties, like crash and makedumpfile to | ||
144 | * obtain access to symbols that are otherwise very difficult to locate. These | ||
145 | * symbols are specifically used so that utilities can access and extract the | ||
146 | * dmesg log from a vmcore file after a crash. | ||
147 | */ | ||
148 | void log_buf_kexec_setup(void) | ||
149 | { | ||
150 | VMCOREINFO_SYMBOL(log_buf); | ||
151 | VMCOREINFO_SYMBOL(log_end); | ||
152 | VMCOREINFO_SYMBOL(log_buf_len); | ||
153 | VMCOREINFO_SYMBOL(logged_chars); | ||
154 | } | ||
155 | #endif | ||
156 | |||
139 | static int __init log_buf_len_setup(char *str) | 157 | static int __init log_buf_len_setup(char *str) |
140 | { | 158 | { |
141 | unsigned size = memparse(str, &str); | 159 | unsigned size = memparse(str, &str); |
@@ -891,12 +909,14 @@ void suspend_console(void) | |||
891 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); | 909 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); |
892 | acquire_console_sem(); | 910 | acquire_console_sem(); |
893 | console_suspended = 1; | 911 | console_suspended = 1; |
912 | up(&console_sem); | ||
894 | } | 913 | } |
895 | 914 | ||
896 | void resume_console(void) | 915 | void resume_console(void) |
897 | { | 916 | { |
898 | if (!console_suspend_enabled) | 917 | if (!console_suspend_enabled) |
899 | return; | 918 | return; |
919 | down(&console_sem); | ||
900 | console_suspended = 0; | 920 | console_suspended = 0; |
901 | release_console_sem(); | 921 | release_console_sem(); |
902 | } | 922 | } |
@@ -912,11 +932,9 @@ void resume_console(void) | |||
912 | void acquire_console_sem(void) | 932 | void acquire_console_sem(void) |
913 | { | 933 | { |
914 | BUG_ON(in_interrupt()); | 934 | BUG_ON(in_interrupt()); |
915 | if (console_suspended) { | ||
916 | down(&secondary_console_sem); | ||
917 | return; | ||
918 | } | ||
919 | down(&console_sem); | 935 | down(&console_sem); |
936 | if (console_suspended) | ||
937 | return; | ||
920 | console_locked = 1; | 938 | console_locked = 1; |
921 | console_may_schedule = 1; | 939 | console_may_schedule = 1; |
922 | } | 940 | } |
@@ -926,6 +944,10 @@ int try_acquire_console_sem(void) | |||
926 | { | 944 | { |
927 | if (down_trylock(&console_sem)) | 945 | if (down_trylock(&console_sem)) |
928 | return -1; | 946 | return -1; |
947 | if (console_suspended) { | ||
948 | up(&console_sem); | ||
949 | return -1; | ||
950 | } | ||
929 | console_locked = 1; | 951 | console_locked = 1; |
930 | console_may_schedule = 0; | 952 | console_may_schedule = 0; |
931 | return 0; | 953 | return 0; |
@@ -979,7 +1001,7 @@ void release_console_sem(void) | |||
979 | unsigned wake_klogd = 0; | 1001 | unsigned wake_klogd = 0; |
980 | 1002 | ||
981 | if (console_suspended) { | 1003 | if (console_suspended) { |
982 | up(&secondary_console_sem); | 1004 | up(&console_sem); |
983 | return; | 1005 | return; |
984 | } | 1006 | } |
985 | 1007 | ||
@@ -1289,8 +1311,11 @@ EXPORT_SYMBOL(printk_ratelimit); | |||
1289 | bool printk_timed_ratelimit(unsigned long *caller_jiffies, | 1311 | bool printk_timed_ratelimit(unsigned long *caller_jiffies, |
1290 | unsigned int interval_msecs) | 1312 | unsigned int interval_msecs) |
1291 | { | 1313 | { |
1292 | if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) { | 1314 | if (*caller_jiffies == 0 |
1293 | *caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs); | 1315 | || !time_in_range(jiffies, *caller_jiffies, |
1316 | *caller_jiffies | ||
1317 | + msecs_to_jiffies(interval_msecs))) { | ||
1318 | *caller_jiffies = jiffies; | ||
1294 | return true; | 1319 | return true; |
1295 | } | 1320 | } |
1296 | return false; | 1321 | return false; |