On Thu 31-03-16 13:12:29, Petr Mladek wrote: > > #if defined CONFIG_PRINTK > > +static int printk_kthread_func(void *data) > > +{ > > + while (1) { > > + set_current_state(TASK_INTERRUPTIBLE); > > + if (!need_flush_console) > > + schedule(); > > + > > + __set_current_state(TASK_RUNNING); > > > We still must do here: > > need_flush_console = false; > > Othrerwise, we might start "busy" cycling. cosole_unlock() > sometimes returns earlly, e.g. when console_suspended is set > or !can_use_console() returns true. > > Sigh, the handling of "need_flush_console" is a bit strange. > Part of the logic depends on logbuf_lock and the other part > must be lockless.
Frankly, I think we are overcomplicating this. What we really need to detect in printk_kthread_func() is whether someone appended something to the console since we woken up. Sure, console_unlock() may have already printed that and we would unnecessarily make one more loop over console_lock() and console_unlock() but who cares... So what about having printk_kthread_func() like: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (!need_flush_console) schedule(); __set_current_state(TASK_RUNNING); need_flush_console = false; console_lock(); console_unlock(); } In vprintk_emit() we do: if (!in_panic && printk_kthread) { /* Offload printing to a schedulable context. */ need_flush_console = true; wake_up_process(printk_kthread); } else { ... This guarantees that after message was appended to the buffer in vprintk_emit(), the message got either printed by console_unlock() or printk_kthread is in TASK_RUNNING state and will call console_unlock() once scheduled. It also guarantees that printk_kthread_func() won't loop forever when there's nothing to print. And that is all we need... I think the simplicity of this is worth the possible extra loops in printk_kthread_func(). Honza -- Jan Kara <j...@suse.com> SUSE Labs, CR