lkml.org 
[lkml]   [2012]   [May]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRe: [PATCH RESEND 1/3] printk: convert byte-buffer to variable-length record buffer
From
Date
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;
}

/*



\
 
 \ /
  Last update: 2012-05-10 05:01    [W:0.698 / U:0.920 seconds]
©2003-2014 Jasper Spaans. Advertise on this site