Messages in this thread Patch in this message | | | Subject | Re: [PATCH RESEND 1/3] printk: convert byte-buffer to variable-length record buffer | From | Kay Sievers <> | Date | Thu, 10 May 2012 04:32:53 +0200 |
| |
On Wed, 2012-05-09 at 18:18 -0700, Linus Torvalds wrote: > On Wed, May 9, 2012 at 5:54 PM, Kay Sievers <kay@vrfy.org> wrote: > > > > How about this? It relaxes the need for KERN_CONT, but it limits > > continuation lines to repeated calls of the same thread. > > Fair enough, looks reasonable. > > Except your case-statement sucks. Having a "case 'c':" that basically > then immediately has an "if (it was not 'c')" is just disturbing. Just > move the code that is common to all the cases outside the case > statement entirely, and make the 'c' case not do anything at all, and > remove that crazy extraneous if-statement.
From: Kay Sievers <kay@vrfy.org> Subject: printk() - do not merge continuation lines of different threads
This prevents the merging of printk() continuation lines of different threads, in the case they race against each other.
It should properly isolate "atomic" single-line printk() users from continuation users, to make sure the single-line users will never be merged with the racy continuation ones.
Signed-off-by: Kay Sievers <kay@vrfy.org> ---
kernel/printk.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
--- a/kernel/printk.c +++ b/kernel/printk.c @@ -1230,12 +1230,13 @@ asmlinkage int vprintk_emit(int facility static size_t buflen; static int buflevel; static char textbuf[LOG_LINE_MAX]; + static struct task_struct *cont; char *text = textbuf; size_t textlen; unsigned long flags; int this_cpu; bool newline = false; - bool cont = false; + bool prefix = false; int printed_len = 0; boot_delay_msec(); @@ -1295,20 +1296,16 @@ asmlinkage int vprintk_emit(int facility case '0' ... '7': if (level == -1) level = text[1] - '0'; - text += 3; - textlen -= 3; - break; - case 'c': /* KERN_CONT */ - cont = true; case 'd': /* KERN_DEFAULT */ + prefix = true; + case 'c': /* KERN_CONT */ text += 3; textlen -= 3; - break; } } - if (buflen && (!cont || dict)) { - /* no continuation; flush existing buffer */ + if (buflen && (prefix || dict || cont != current)) { + /* flush existing buffer */ log_store(facility, buflevel, NULL, 0, buf, buflen); printed_len += buflen; buflen = 0; @@ -1342,6 +1339,10 @@ asmlinkage int vprintk_emit(int facility dict, dictlen, text, textlen); printed_len += textlen; } + cont = NULL; + } else { + /* remember thread which filled the buffer */ + cont = current; } /*
| |