On (03/24/17 10:59), Sergey Senozhatsky wrote: [..] > and we can jump between rescue-normal printk modes, so this should > also return back the throttling of tasks which printk() a lot (item > (2) in patch set cover letter) that we used to have.
ok, I obviously lied here "this should also return back the throttling". throttling is a bit hard to implement properly. automatic printk rescue mode on console output stall [when we can't wake_up printk_kthread] is not so difficult. something like below. may be it's too simple minded. // it does not handle throttling. --- kernel/printk/printk.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index e84b9fbb298f..005741486376 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -447,6 +447,12 @@ static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); static char *log_buf = __log_buf; static u32 log_buf_len = __LOG_BUF_LEN; +/* + * How many pending messages we can have in the logbuf before we + * switch to printk rescue mode (stop waking up printk_kthread). + */ +#define CONSOLE_STALL_MESSAGES_LIMIT 50 + static struct task_struct *printk_kthread __read_mostly; /* * We can't call into the scheduler (wake_up() printk kthread) during @@ -1739,6 +1745,11 @@ static size_t log_output(int facility, int level, enum log_flags lflags, const c return log_store(facility, level, lflags, 0, dict, dictlen, text, text_len); } +static bool console_output_stall(void) +{ + return (log_next_seq - console_seq) > CONSOLE_STALL_MESSAGES_LIMIT; +} + asmlinkage int vprintk_emit(int facility, int level, const char *dict, size_t dictlen, const char *fmt, va_list args) @@ -1750,6 +1761,7 @@ asmlinkage int vprintk_emit(int facility, int level, unsigned long flags; int printed_len = 0; bool in_sched = false; + bool printk_stall; if (level == LOGLEVEL_SCHED) { level = LOGLEVEL_DEFAULT; @@ -1811,6 +1823,7 @@ asmlinkage int vprintk_emit(int facility, int level, printed_len += log_output(facility, level, lflags, dict, dictlen, text, text_len); + printk_stall = console_output_stall(); set_bit(PRINTK_PENDING_OUTPUT, &printk_pending); logbuf_unlock_irqrestore(flags); @@ -1824,7 +1837,7 @@ asmlinkage int vprintk_emit(int facility, int level, * from a dedicated printk_kthread, which always runs in * schedulable context. */ - if (printk_kthread_enabled()) { + if (!printk_stall && printk_kthread_enabled()) { printk_safe_enter_irqsave(flags); wake_up_process(printk_kthread); printk_safe_exit_irqrestore(flags); -- 2.12.1