On (06/30/17 22:38), Sergey Senozhatsky wrote: > On (06/30/17 15:16), Petr Mladek wrote: > > Anyway, the handshake during offloading might be pretty > > problematic. To be honest, I do not have much experience > > with it. I have shared some my fears in the other mail[1]. > > Jan Kara spent a lot of time on this and probably could > > say more. > > > > Maybe, we could try to look into the throotling path. Slowing down > > massive printk() callers looks necessary when things gets > > out of control. > > throttling, in some form, is already there. I think. > > there is a printk_delay() function. which we can silently activate > when things don't look cool anymore. and printk_delay() is already > getting called on every vprintk_emit() entry. the question is -- how > big should be our delay value, and... when do we need to activate > printk_delay()? > > when the distance between console_seq and log_next_seq... suggests > that we will drop (overwrite) un-flushed messages sooner than console_seq > reaches log_next_seq? so log_next_seq is closer to log_first_seq than > console_seq to log_next_seq.
something like below, may be. a sketch, just to demonstrate the idea. but, once polished, can go to printk out of series. ===8<===8<===8<=== Throttle printk() callers when we detect that consoles are far behind the logbuf: we printed to the consoles 4 times less messages than we still have to print. Signed-off-by: Sergey Senozhatsky <sergey.senozhat...@gmail.com> --- kernel/printk/printk.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index f24d3789faa0..fd546bd95207 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1758,17 +1758,43 @@ static void call_console_drivers(const char *ext_text, size_t ext_len, } } +#define PRINTK_FLOOD_DEFAULT_DELAY 10 + int printk_delay_msec __read_mostly; +static inline void __printk_delay(int m) +{ + while (m--) { + mdelay(1); + touch_nmi_watchdog(); + } +} + static inline void printk_delay(void) { - if (unlikely(printk_delay_msec)) { - int m = printk_delay_msec; + unsigned long flags; + u64 console_seen = 0, console_to_see; - while (m--) { - mdelay(1); - touch_nmi_watchdog(); - } + if (printk_delay_msec) { + __printk_delay(printk_delay_msec); + return; + } + + /* + * Check if consoles are far behind the loguf head and + * throttle printk() callers if so. + */ + logbuf_lock_irqsave(flags); + if (console_seq > log_first_seq) + console_seen = console_seq - log_first_seq; + console_to_see = log_next_seq - console_seq; + logbuf_unlock_irqrestore(flags); + + if (console_seen < 4 * console_to_see) { + if (printk_delay_msec) + __printk_delay(printk_delay_msec); + else + __printk_delay(PRINTK_FLOOD_DEFAULT_DELAY); } } -- 2.13.2