Re: printk: what is going on with additional newlines?

Sergey Senozhatsky
2017-09-04T05:25:35Z

Hello,

I'll answer to both Linus and Joe, just to keep it all one place.

On (09/01/17 13:21), Linus Torvalds wrote:
> On Fri, Sep 1, 2017 at 10:32 AM, Joe Perches <joe@perches.com> wrote:
> >
> > Yes, it's a poor name. At least keep using a pr_ prefix.
>
> I'd suggest perhaps just "pr_line()".

ok, pr_line sound good.

> And instead of having those "err/info/cont" variations, the severity
> level should just be set at initialization time. Not different
> versions of "pr_line()".
>
> There's no point to having different severity variations, since the
> *only* reason for this would be for buffering. So "pr_cont()" is kind
> of assumed for everything but the first.
>
> And even if you end up doing multiple lines, if you actually do
> different severities, you damn well shouldn't buffer them together.
> They are clearly different things!

hm... may be.
the main point of prbuf is not the support of cont lines, but the
fact that buffered messages are added to the logbuf atomically,
and thus are printed in consequent lines, not the usual way:

CPU0 because
CPU1 this
CPU0 it's easier
CPU1 might
CPU0 to read
CPU1 be
CPU1 inconvenient.
CPU0 seq messages.

some people want to be able to make it to look less spaghetti-like:

CPU0 because
CPU0 it's easier
CPU0 to read
CPU0 seq messages.
CPU1 this
CPU1 might
CPU1 be
CPU1 inconvenient.

and it's not something completely wrong to ask for, I think.
well, who knows.

there is only way to serialize printks against other printks -- take
the logbuf lock. and that's what pr_line/prbuf flush is doing.

now, pr_line/prbuf/pr_buf is, of course, very limited. it should NOT
be used for things that are really important and absolutely must [if
possible] appear in serial logs/on screens/etc. simply because panic
can happen on CPUA before we flush any pending pr_line/prbuf buffers
on other CPUs. and that's exactly the reason why I initially wanted
(and still do) to implement pr_line/prbuf using printk-safe
mechanism - because we flush printk-safe buffers from panic(). so
utilizing printk-safe buffers can make pr_line less fragile. apart
from that printk-safe buffers are always there, so OOM is not a show
stopper anymore. but, like I said in another email, printk-safe buffer
is per-CPU and is also used for actual printk-safe, hence it must be
used with local IRQs disabled when we "borrow" the buffer for pr_line
(disabled preemption is not enough due to possible IRQ printk-safe
print out). this can be a bit annoying.

in it's current form, pr_line/pr_buf is NOT a replacement for pr_cont
or printk(KERN_CONT). because pr_cont has no such thing as "we were
unable to flush the buffer from CPUB because of panic on CPUA". so
pr_cont/printk(KERN_CONT) beats pr_line/pr_buf here. This can be a
major limitation. am I wrong?

another thing,
if we eventually will decide to stick to "use a seq_buf with stack
allocated char buffer to hold a single line only" design, then I'm
not entirely sure I get it why do we want to add a new API at all.
I mean, the new API does not make anything simpler or shorter. we
need to declare the buffer, seq_buf, init seq_buf, append chars to
seq_buf, flush it:

char buf[80];
struct seq_buf cont_line;

pr_line_init(&cont_line, buf, sizeof(buf));
pr_line_printf(&cont_line, "....");
pr_line_printf(&cont_line, "....");
pr_line_flush(&cont_line);

this asks for s/pr_line_/seq_buf_/g, no? well, except for the flush()
part. it can be replaced with printk("%s\n", cont_line->buffer).

so it seems that we need to re-think it.

-ss