Re: [RFC][PATCH 0/4] printk: introduce printing kernel thread

From: Sergey Senozhatsky
Date: Fri Mar 24 2017 - 00:44:11 EST


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