diff options
Diffstat (limited to 'kernel/printk.c')
-rw-r--r-- | kernel/printk.c | 81 |
1 files changed, 20 insertions, 61 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index b51b1567bb55..f492f1583d77 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * Fixed SMP synchronization, 08/08/99, Manfred Spraul | 13 | * Fixed SMP synchronization, 08/08/99, Manfred Spraul |
14 | * manfred@colorfullife.com | 14 | * manfred@colorfullife.com |
15 | * Rewrote bits to get rid of console_lock | 15 | * Rewrote bits to get rid of console_lock |
16 | * 01Mar01 Andrew Morton <andrewm@uow.edu.au> | 16 | * 01Mar01 Andrew Morton |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
@@ -233,45 +233,6 @@ static inline void boot_delay_msec(void) | |||
233 | #endif | 233 | #endif |
234 | 234 | ||
235 | /* | 235 | /* |
236 | * Return the number of unread characters in the log buffer. | ||
237 | */ | ||
238 | static int log_buf_get_len(void) | ||
239 | { | ||
240 | return logged_chars; | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * Copy a range of characters from the log buffer. | ||
245 | */ | ||
246 | int log_buf_copy(char *dest, int idx, int len) | ||
247 | { | ||
248 | int ret, max; | ||
249 | bool took_lock = false; | ||
250 | |||
251 | if (!oops_in_progress) { | ||
252 | spin_lock_irq(&logbuf_lock); | ||
253 | took_lock = true; | ||
254 | } | ||
255 | |||
256 | max = log_buf_get_len(); | ||
257 | if (idx < 0 || idx >= max) { | ||
258 | ret = -1; | ||
259 | } else { | ||
260 | if (len > max) | ||
261 | len = max; | ||
262 | ret = len; | ||
263 | idx += (log_end - max); | ||
264 | while (len-- > 0) | ||
265 | dest[len] = LOG_BUF(idx + len); | ||
266 | } | ||
267 | |||
268 | if (took_lock) | ||
269 | spin_unlock_irq(&logbuf_lock); | ||
270 | |||
271 | return ret; | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * Commands to do_syslog: | 236 | * Commands to do_syslog: |
276 | * | 237 | * |
277 | * 0 -- Close the log. Currently a NOP. | 238 | * 0 -- Close the log. Currently a NOP. |
@@ -577,9 +538,6 @@ static int have_callable_console(void) | |||
577 | * @fmt: format string | 538 | * @fmt: format string |
578 | * | 539 | * |
579 | * This is printk(). It can be called from any context. We want it to work. | 540 | * This is printk(). It can be called from any context. We want it to work. |
580 | * Be aware of the fact that if oops_in_progress is not set, we might try to | ||
581 | * wake klogd up which could deadlock on runqueue lock if printk() is called | ||
582 | * from scheduler code. | ||
583 | * | 541 | * |
584 | * We try to grab the console_sem. If we succeed, it's easy - we log the output and | 542 | * We try to grab the console_sem. If we succeed, it's easy - we log the output and |
585 | * call the console drivers. If we fail to get the semaphore we place the output | 543 | * call the console drivers. If we fail to get the semaphore we place the output |
@@ -593,6 +551,8 @@ static int have_callable_console(void) | |||
593 | * | 551 | * |
594 | * See also: | 552 | * See also: |
595 | * printf(3) | 553 | * printf(3) |
554 | * | ||
555 | * See the vsnprintf() documentation for format string extensions over C99. | ||
596 | */ | 556 | */ |
597 | 557 | ||
598 | asmlinkage int printk(const char *fmt, ...) | 558 | asmlinkage int printk(const char *fmt, ...) |
@@ -982,10 +942,25 @@ int is_console_locked(void) | |||
982 | return console_locked; | 942 | return console_locked; |
983 | } | 943 | } |
984 | 944 | ||
985 | void wake_up_klogd(void) | 945 | static DEFINE_PER_CPU(int, printk_pending); |
946 | |||
947 | void printk_tick(void) | ||
986 | { | 948 | { |
987 | if (!oops_in_progress && waitqueue_active(&log_wait)) | 949 | if (__get_cpu_var(printk_pending)) { |
950 | __get_cpu_var(printk_pending) = 0; | ||
988 | wake_up_interruptible(&log_wait); | 951 | wake_up_interruptible(&log_wait); |
952 | } | ||
953 | } | ||
954 | |||
955 | int printk_needs_cpu(int cpu) | ||
956 | { | ||
957 | return per_cpu(printk_pending, cpu); | ||
958 | } | ||
959 | |||
960 | void wake_up_klogd(void) | ||
961 | { | ||
962 | if (waitqueue_active(&log_wait)) | ||
963 | __raw_get_cpu_var(printk_pending) = 1; | ||
989 | } | 964 | } |
990 | 965 | ||
991 | /** | 966 | /** |
@@ -1291,22 +1266,6 @@ static int __init disable_boot_consoles(void) | |||
1291 | } | 1266 | } |
1292 | late_initcall(disable_boot_consoles); | 1267 | late_initcall(disable_boot_consoles); |
1293 | 1268 | ||
1294 | /** | ||
1295 | * tty_write_message - write a message to a certain tty, not just the console. | ||
1296 | * @tty: the destination tty_struct | ||
1297 | * @msg: the message to write | ||
1298 | * | ||
1299 | * This is used for messages that need to be redirected to a specific tty. | ||
1300 | * We don't put it into the syslog queue right now maybe in the future if | ||
1301 | * really needed. | ||
1302 | */ | ||
1303 | void tty_write_message(struct tty_struct *tty, char *msg) | ||
1304 | { | ||
1305 | if (tty && tty->ops->write) | ||
1306 | tty->ops->write(tty, msg, strlen(msg)); | ||
1307 | return; | ||
1308 | } | ||
1309 | |||
1310 | #if defined CONFIG_PRINTK | 1269 | #if defined CONFIG_PRINTK |
1311 | 1270 | ||
1312 | /* | 1271 | /* |