diff options
Diffstat (limited to 'kernel/printk.c')
| -rw-r--r-- | kernel/printk.c | 36 | 
1 files changed, 20 insertions, 16 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 357f714ddd4..0b31715f335 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -42,6 +42,7 @@  #include <linux/notifier.h>  #include <linux/rculist.h>  #include <linux/poll.h> +#include <linux/irq_work.h>  #include <asm/uaccess.h> @@ -1967,30 +1968,32 @@ int is_console_locked(void)  static DEFINE_PER_CPU(int, printk_pending);  static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf); -void printk_tick(void) +static void wake_up_klogd_work_func(struct irq_work *irq_work)  { -	if (__this_cpu_read(printk_pending)) { -		int pending = __this_cpu_xchg(printk_pending, 0); -		if (pending & PRINTK_PENDING_SCHED) { -			char *buf = __get_cpu_var(printk_sched_buf); -			printk(KERN_WARNING "[sched_delayed] %s", buf); -		} -		if (pending & PRINTK_PENDING_WAKEUP) -			wake_up_interruptible(&log_wait); +	int pending = __this_cpu_xchg(printk_pending, 0); + +	if (pending & PRINTK_PENDING_SCHED) { +		char *buf = __get_cpu_var(printk_sched_buf); +		printk(KERN_WARNING "[sched_delayed] %s", buf);  	} -} -int printk_needs_cpu(int cpu) -{ -	if (cpu_is_offline(cpu)) -		printk_tick(); -	return __this_cpu_read(printk_pending); +	if (pending & PRINTK_PENDING_WAKEUP) +		wake_up_interruptible(&log_wait);  } +static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = { +	.func = wake_up_klogd_work_func, +	.flags = IRQ_WORK_LAZY, +}; +  void wake_up_klogd(void)  { -	if (waitqueue_active(&log_wait)) +	preempt_disable(); +	if (waitqueue_active(&log_wait)) {  		this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); +		irq_work_queue(&__get_cpu_var(wake_up_klogd_work)); +	} +	preempt_enable();  }  static void console_cont_flush(char *text, size_t size) @@ -2471,6 +2474,7 @@ int printk_sched(const char *fmt, ...)  	va_end(args);  	__this_cpu_or(printk_pending, PRINTK_PENDING_SCHED); +	irq_work_queue(&__get_cpu_var(wake_up_klogd_work));  	local_irq_restore(flags);  	return r;  |