mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'nohz/printk-v8' into irq/core
Conflicts: kernel/irq_work.c Add support for printk in full dynticks CPU. * Don't stop tick with irq works pending. This fix is generally useful and concerns archs that can't raise self IPIs. * Flush irq works before CPU offlining. * Introduce "lazy" irq works that can wait for the next tick to be executed, unless it's stopped. * Implement klogd wake up using irq work. This removes the ad-hoc printk_tick()/printk_needs_cpu() hooks and make it working even in dynticks mode. Signed-off-by: Frederic Weisbecker <[email protected]>
This commit is contained in:
commit
077931446b
8 changed files with 147 additions and 50 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
if (pending & PRINTK_PENDING_WAKEUP)
|
||||
wake_up_interruptible(&log_wait);
|
||||
}
|
||||
|
||||
int printk_needs_cpu(int cpu)
|
||||
{
|
||||
if (cpu_is_offline(cpu))
|
||||
printk_tick();
|
||||
return __this_cpu_read(printk_pending);
|
||||
}
|
||||
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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue