Messages in this thread | | | Date | Wed, 20 Feb 2019 13:18:25 +0100 | From | Petr Mladek <> | Subject | Re: [PATCH] printk: Pass caller information to log_store(). |
| |
On Sat 2019-02-16 19:59:33, Tetsuo Handa wrote: > When thread1 called printk() which did not end with '\n', and then thread2 > called printk() which ends with '\n' before thread1 calls pr_cont(), the > partial content saved into "struct cont" is flushed by thread2 despite the > partial content was generated by thread1. This leads to confusing output > as if the partial content was generated by thread2. Fix this problem by > passing correct caller information to log_store(). > > Before: > > [ T8533] abcdefghijklm > [ T8533] ABCDEFGHIJKLMNOPQRSTUVWXYZ > [ T8532] nopqrstuvwxyz > [ T8532] abcdefghijklmnopqrstuvwxyz > [ T8533] abcdefghijklm > [ T8533] ABCDEFGHIJKLMNOPQRSTUVWXYZ > [ T8532] nopqrstuvwxyz > > After: > > [ T8507] abcdefghijklm > [ T8508] ABCDEFGHIJKLMNOPQRSTUVWXYZ > [ T8507] nopqrstuvwxyz > [ T8507] abcdefghijklmnopqrstuvwxyz > [ T8507] abcdefghijklm > [ T8508] ABCDEFGHIJKLMNOPQRSTUVWXYZ > [ T8507] nopqrstuvwxyz
Great catch!
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
The patch looks fine to me:
Reviewed-by: Petr Mladek <pmladek@suse.com>
There are just two cosmetic changes that I might do when pushing the patch, see below.
> --- > kernel/printk/printk.c | 39 ++++++++++++++++++++++++--------------- > 1 file changed, 24 insertions(+), 15 deletions(-) > > diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c > index 33c0359..6547a88 100644 > --- a/kernel/printk/printk.c > +++ b/kernel/printk/printk.c > @@ -1850,13 +1854,16 @@ static bool cont_add(int facility, int level, enum log_flags flags, const char * > > static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len) > { > + const u32 caller_id = printk_caller_id(); > + > /* > * If an earlier line was buffered, and we're a continuation > - * write from the same process, try to add it to the buffer. > + * write from the same context, try to add it to the buffer. > */ > if (cont.len) { > - if (cont.owner == current && (lflags & LOG_CONT)) { > - if (cont_add(facility, level, lflags, text, text_len)) > + if (cont.caller_id == caller_id && (lflags & LOG_CONT)) { > + if (cont_add(caller_id, facility, level, lflags, text, > + text_len))
I think that this is the case when it is better to break the 80-character per-line rule.
> return text_len; > } > /* Otherwise, make sure it's flushed */ > @@ -1869,12 +1876,14 @@ static size_t log_output(int facility, int level, enum log_flags lflags, const c > > /* If it doesn't end in a newline, try to buffer the current line */ > if (!(lflags & LOG_NEWLINE)) { > - if (cont_add(facility, level, lflags, text, text_len)) > + if (cont_add(caller_id, facility, level, lflags, text, > + text_len))
Same here.
> return text_len; > } >
Best Regards, Petr
| |