As of now we don't `offload' printing from printk_kthread and print all pending logbuf messages. This, however, may have a negative effect. We still hold console_sem as long as we have got messages to print, and there might be other console_lock() callers sleeping on console_sem in TASK_UNINTERRUPTIBLE, including user space processes (tty_open, drm IOCTL, etc.). So we need to up() console_sem every once in a while, even if current console_sem owner is printk_kthread, just in order to wake up those other processes that can sleep on console_sem.
If there are no tasks skeeping on console_sem, then printk_kthread will immediately return back to console_unclok(), because we don't clear the PRINTK_PENDING_OUTPUT bit and printk_kthread checks it before it decides to schedule(). Signed-off-by: Sergey Senozhatsky <sergey.senozhat...@gmail.com> --- kernel/printk/printk.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 71950bd85eac..6da4e21c3b45 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -600,15 +600,29 @@ static inline bool console_offload_printing(void) return false; } - /* Once we offloaded to printk_ktread - keep printing */ - if (current == printk_kthread) - return false; - adj_atomic_print_limit(); if (!time_after_eq(now, printing_start_ts + atomic_print_limit)) return false; + if (current == printk_kthread) { + /* + * All tasks are equal, all tasks must offload. However, + * printk_kthread may be the only process left willing to + * down(). So we may return here immediately after we leave, + * because of positive PRINTK_PENDING_OUTPUT check in + * printk_kthread_func() loop. However, we obviously don't + * want to declare printk emergency in this case, so that's + * why we update `printing_start_ts' here. + * + * In case if `printk_kthread' will immediately return + * back to console_unlock(), it will have another full + * `atomic_print_limit' time slice. + */ + printing_start_ts = local_clock() >> 30LL; + return true; + } + /* * A trivial emergency enforcement - give up on printk_kthread if * we can't wake it up. -- 2.14.1