Re: [RFC PATCH v4 0/9] printk: new ringbuffer implementation

Sergey Senozhatsky
2019-09-06T10:09:50Z

On (09/06/19 11:06), Peter Zijlstra wrote:
> Another approach is something like:
>
> DEFINE_PER_CPU(int, printk_nest);
> DEFINE_PER_CPU(char, printk_line[4][256]);
>
> int vprintk(const char *fmt, va_list args)
> {
> int c, n, i;
> char *buf;
>
> preempt_disable();
> i = min(3, this_cpu_inc_return(printk_nest) - 1);
> buf = this_cpu_ptr(printk_line[i]);
> n = vscnprintf(buf, 256, fmt, args);
>
> c = cpu_lock();
> printk_buffer_store(buf, n);
> if (early_console)
> early_console->write(early_console, buf, n);
> cpu_unlock(c);
>
> this_cpu_dec(printk_nest);
> preempt_enable();
>
> return n;
> }
>
> Again, simple and straight forward (and I'm sure it's been mentioned
> before too).

:)

---
diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c
index 139c310049b1..9c73eb6259ce 100644
--- a/kernel/printk/printk_safe.c
+++ b/kernel/printk/printk_safe.c
@@ -103,7 +103,10 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s,
if (atomic_cmpxchg(&s->len, len, len + add) != len)
goto again;

- queue_flush_work(s);
+ if (early_console)
+ early_console->write(early_console, s->buffer + len, add);
+ else
+ queue_flush_work(s);
return add;
}
---

-ss