diff options
-rw-r--r-- | include/linux/printk.h | 3 | ||||
-rw-r--r-- | init/Kconfig | 1 | ||||
-rw-r--r-- | kernel/printk.c | 36 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 2 | ||||
-rw-r--r-- | kernel/timer.c | 1 |
5 files changed, 22 insertions, 21 deletions
diff --git a/include/linux/printk.h b/include/linux/printk.h index 9afc01e5a0a6..86c4b6294713 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h | |||
@@ -98,9 +98,6 @@ int no_printk(const char *fmt, ...) | |||
98 | extern asmlinkage __printf(1, 2) | 98 | extern asmlinkage __printf(1, 2) |
99 | void early_printk(const char *fmt, ...); | 99 | void early_printk(const char *fmt, ...); |
100 | 100 | ||
101 | extern int printk_needs_cpu(int cpu); | ||
102 | extern void printk_tick(void); | ||
103 | |||
104 | #ifdef CONFIG_PRINTK | 101 | #ifdef CONFIG_PRINTK |
105 | asmlinkage __printf(5, 0) | 102 | asmlinkage __printf(5, 0) |
106 | int vprintk_emit(int facility, int level, | 103 | int vprintk_emit(int facility, int level, |
diff --git a/init/Kconfig b/init/Kconfig index cdc152c75727..c575566be47d 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1196,6 +1196,7 @@ config HOTPLUG | |||
1196 | config PRINTK | 1196 | config PRINTK |
1197 | default y | 1197 | default y |
1198 | bool "Enable support for printk" if EXPERT | 1198 | bool "Enable support for printk" if EXPERT |
1199 | select IRQ_WORK | ||
1199 | help | 1200 | help |
1200 | This option enables normal printk support. Removing it | 1201 | This option enables normal printk support. Removing it |
1201 | eliminates most of the message strings from the kernel image | 1202 | eliminates most of the message strings from the kernel image |
diff --git a/kernel/printk.c b/kernel/printk.c index 2d607f4d1797..c9104feba5ec 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 | ||
@@ -1955,30 +1956,32 @@ int is_console_locked(void) | |||
1955 | static DEFINE_PER_CPU(int, printk_pending); | 1956 | static DEFINE_PER_CPU(int, printk_pending); |
1956 | static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf); | 1957 | static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf); |
1957 | 1958 | ||
1958 | void printk_tick(void) | 1959 | static void wake_up_klogd_work_func(struct irq_work *irq_work) |
1959 | { | 1960 | { |
1960 | if (__this_cpu_read(printk_pending)) { | 1961 | int pending = __this_cpu_xchg(printk_pending, 0); |
1961 | int pending = __this_cpu_xchg(printk_pending, 0); | 1962 | |
1962 | if (pending & PRINTK_PENDING_SCHED) { | 1963 | if (pending & PRINTK_PENDING_SCHED) { |
1963 | char *buf = __get_cpu_var(printk_sched_buf); | 1964 | char *buf = __get_cpu_var(printk_sched_buf); |
1964 | printk(KERN_WARNING "[sched_delayed] %s", buf); | 1965 | printk(KERN_WARNING "[sched_delayed] %s", buf); |
1965 | } | ||
1966 | if (pending & PRINTK_PENDING_WAKEUP) | ||
1967 | wake_up_interruptible(&log_wait); | ||
1968 | } | 1966 | } |
1969 | } | ||
1970 | 1967 | ||
1971 | int printk_needs_cpu(int cpu) | 1968 | if (pending & PRINTK_PENDING_WAKEUP) |
1972 | { | 1969 | wake_up_interruptible(&log_wait); |
1973 | if (cpu_is_offline(cpu)) | ||
1974 | printk_tick(); | ||
1975 | return __this_cpu_read(printk_pending); | ||
1976 | } | 1970 | } |
1977 | 1971 | ||
1972 | static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = { | ||
1973 | .func = wake_up_klogd_work_func, | ||
1974 | .flags = IRQ_WORK_LAZY, | ||
1975 | }; | ||
1976 | |||
1978 | void wake_up_klogd(void) | 1977 | void wake_up_klogd(void) |
1979 | { | 1978 | { |
1980 | if (waitqueue_active(&log_wait)) | 1979 | preempt_disable(); |
1980 | if (waitqueue_active(&log_wait)) { | ||
1981 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); | 1981 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); |
1982 | irq_work_queue(&__get_cpu_var(wake_up_klogd_work)); | ||
1983 | } | ||
1984 | preempt_enable(); | ||
1982 | } | 1985 | } |
1983 | 1986 | ||
1984 | static void console_cont_flush(char *text, size_t size) | 1987 | static void console_cont_flush(char *text, size_t size) |
@@ -2458,6 +2461,7 @@ int printk_sched(const char *fmt, ...) | |||
2458 | va_end(args); | 2461 | va_end(args); |
2459 | 2462 | ||
2460 | __this_cpu_or(printk_pending, PRINTK_PENDING_SCHED); | 2463 | __this_cpu_or(printk_pending, PRINTK_PENDING_SCHED); |
2464 | irq_work_queue(&__get_cpu_var(wake_up_klogd_work)); | ||
2461 | local_irq_restore(flags); | 2465 | local_irq_restore(flags); |
2462 | 2466 | ||
2463 | return r; | 2467 | return r; |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f249e8c3e58e..822d7572bf2d 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -289,7 +289,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
289 | time_delta = timekeeping_max_deferment(); | 289 | time_delta = timekeeping_max_deferment(); |
290 | } while (read_seqretry(&xtime_lock, seq)); | 290 | } while (read_seqretry(&xtime_lock, seq)); |
291 | 291 | ||
292 | if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || printk_needs_cpu(cpu) || | 292 | if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || |
293 | arch_needs_cpu(cpu) || irq_work_needs_cpu()) { | 293 | arch_needs_cpu(cpu) || irq_work_needs_cpu()) { |
294 | next_jiffies = last_jiffies + 1; | 294 | next_jiffies = last_jiffies + 1; |
295 | delta_jiffies = 1; | 295 | delta_jiffies = 1; |
diff --git a/kernel/timer.c b/kernel/timer.c index 367d00858482..ff3b5165737b 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1351,7 +1351,6 @@ void update_process_times(int user_tick) | |||
1351 | account_process_tick(p, user_tick); | 1351 | account_process_tick(p, user_tick); |
1352 | run_local_timers(); | 1352 | run_local_timers(); |
1353 | rcu_check_callbacks(cpu, user_tick); | 1353 | rcu_check_callbacks(cpu, user_tick); |
1354 | printk_tick(); | ||
1355 | #ifdef CONFIG_IRQ_WORK | 1354 | #ifdef CONFIG_IRQ_WORK |
1356 | if (in_irq()) | 1355 | if (in_irq()) |
1357 | irq_work_run(); | 1356 | irq_work_run(); |