aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 19c0d7bcf24a..0b31715f335a 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -42,6 +42,7 @@
42#include <linux/notifier.h> 42#include <linux/notifier.h>
43#include <linux/rculist.h> 43#include <linux/rculist.h>
44#include <linux/poll.h> 44#include <linux/poll.h>
45#include <linux/irq_work.h>
45 46
46#include <asm/uaccess.h> 47#include <asm/uaccess.h>
47 48
@@ -870,10 +871,11 @@ static size_t print_time(u64 ts, char *buf)
870 if (!printk_time) 871 if (!printk_time)
871 return 0; 872 return 0;
872 873
874 rem_nsec = do_div(ts, 1000000000);
875
873 if (!buf) 876 if (!buf)
874 return 15; 877 return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts);
875 878
876 rem_nsec = do_div(ts, 1000000000);
877 return sprintf(buf, "[%5lu.%06lu] ", 879 return sprintf(buf, "[%5lu.%06lu] ",
878 (unsigned long)ts, rem_nsec / 1000); 880 (unsigned long)ts, rem_nsec / 1000);
879} 881}
@@ -1966,30 +1968,32 @@ int is_console_locked(void)
1966static DEFINE_PER_CPU(int, printk_pending); 1968static DEFINE_PER_CPU(int, printk_pending);
1967static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf); 1969static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf);
1968 1970
1969void printk_tick(void) 1971static void wake_up_klogd_work_func(struct irq_work *irq_work)
1970{ 1972{
1971 if (__this_cpu_read(printk_pending)) { 1973 int pending = __this_cpu_xchg(printk_pending, 0);
1972 int pending = __this_cpu_xchg(printk_pending, 0); 1974
1973 if (pending & PRINTK_PENDING_SCHED) { 1975 if (pending & PRINTK_PENDING_SCHED) {
1974 char *buf = __get_cpu_var(printk_sched_buf); 1976 char *buf = __get_cpu_var(printk_sched_buf);
1975 printk(KERN_WARNING "[sched_delayed] %s", buf); 1977 printk(KERN_WARNING "[sched_delayed] %s", buf);
1976 }
1977 if (pending & PRINTK_PENDING_WAKEUP)
1978 wake_up_interruptible(&log_wait);
1979 } 1978 }
1980}
1981 1979
1982int printk_needs_cpu(int cpu) 1980 if (pending & PRINTK_PENDING_WAKEUP)
1983{ 1981 wake_up_interruptible(&log_wait);
1984 if (cpu_is_offline(cpu))
1985 printk_tick();
1986 return __this_cpu_read(printk_pending);
1987} 1982}
1988 1983
1984static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = {
1985 .func = wake_up_klogd_work_func,
1986 .flags = IRQ_WORK_LAZY,
1987};
1988
1989void wake_up_klogd(void) 1989void wake_up_klogd(void)
1990{ 1990{
1991 if (waitqueue_active(&log_wait)) 1991 preempt_disable();
1992 if (waitqueue_active(&log_wait)) {
1992 this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); 1993 this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
1994 irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
1995 }
1996 preempt_enable();
1993} 1997}
1994 1998
1995static void console_cont_flush(char *text, size_t size) 1999static void console_cont_flush(char *text, size_t size)
@@ -2470,6 +2474,7 @@ int printk_sched(const char *fmt, ...)
2470 va_end(args); 2474 va_end(args);
2471 2475
2472 __this_cpu_or(printk_pending, PRINTK_PENDING_SCHED); 2476 __this_cpu_or(printk_pending, PRINTK_PENDING_SCHED);
2477 irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
2473 local_irq_restore(flags); 2478 local_irq_restore(flags);
2474 2479
2475 return r; 2480 return r;