Re: [PATCH v6 1/3] printk: Add line-buffered printk() API.

From: Sergey Senozhatsky
Date: Thu Nov 08 2018 - 07:30:57 EST


On (11/08/18 12:24), Petr Mladek wrote:
> I believe that I mentioned this more times. 16 buffers is the first
> attempt. We could improve it later in several ways

Sure. Like I said - maybe it is a normal development pattern; I really
don't know.

> > Let's have one more look at what we will fix and what we will break.
> >
> > 'cont' has premature flushes.
> >
> > Why is it good.
> > It preserves the correct order of events.
> >
> > pr_cont("calling foo->init()....");
> > foo->init()
> > printk("Can't allocate buffer\n"); // premature flush
> > pr_cont("...blah\h");
> >
> > Will end up in the logbuf as:
> > [12345.123] calling foo->init()....
> > [12345.124] Can't allocate buffer
> > [12345.125] ...blah
> >
> > Where buffered printk will endup as:
> > [12345.123] Can't allocate buffer
> > [12345.124] calling foo->init().......blah
>
> We will always have this problem with API using explicit buffers.

Exactly.

> What do you suggest instead, please?

So this is why "let's not remove 'cont'" thing. Buffered printk
is not 100% identical to 'cont'. And 'cont' does a good job sometimes,
Because 'cont' looks like a buffered printk, but it behaves like a
normal printk when things go bad. Buffered printk is always buffered;
and not even aware of the fact that things go bad around.

> > If our problem is OOM and lockdep print outs, then let's address only
> > those two; let's not "fix" the rest of the kernel, especially the early
> > boot, - we can break more things than we can mend.
>
> Do you have any alternative proposal how to handle OOM and lockdep, please?

You misunderstood me. I'm not against the buffered printk in lockdep and
OOM. Albeit I must admit that lockdep patch looks quite big. I don't like
the idea of "we will remove 'cont' and replace it with buffered printk
through out the kernel".

[..]
> > - It seems that buffered printk attempts to solve too many problems.
> > I'd prefer it to address just one.
>
> This API tries to handle continuous lines more reliably.
> Do I miss anything, please?

This part:

+ /* Flush already completed lines if any. */
+ for (pos = ptr->len - 1; pos >= 0; pos--) {
+ if (ptr->buf[pos] != '\n')
+ continue;
+ ptr->buf[pos++] = '\0';
+ printk("%s\n", ptr->buf);
+ ptr->len -= pos;
+ memmove(ptr->buf, ptr->buf + pos, ptr->len);
+ /* This '\0' will be overwritten by next vsnprintf() above. */
+ ptr->buf[ptr->len] = '\0';
+ break;
+ }
+ return r;

If I'm not mistaken, this is for the futute "printk injection" work.

Right now printk("foo\nbar\n") will end up to be a single logbuf
entry, with \n in the middle and at the end. So it will look like
two lines on the serial console:

[123.123] foo
bar

Tetsuo does this \n lookup (on every vprintk_buffered) and split lines
(via memove) for "printk injection", so the output will be

[123.123] foo
[123.124] bar

Which makes it simpler to "inject" printk origin into every printed
line.

Without it we can just do

len = vsprintf();
if (len && text[len - 1] == '\n' || overflow)
flush();

Can't we?

-ss