[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] console: make printk() line continuation tracking per-CPU



This avoids cases where split messages (with other than the initial
part not carrying a log level; single line messages only of course)
issued on multiple CPUs interfere with each other, causing messages to
be issued which are supposed to be suppressed due to the log level
setting. E.g.

        CPU A                   CPU B
XENLOG_G_DEBUG "abc"
                        XENLOG_G_DEBUG "def\n"
"xyz\n"

would cause the last message to be logged despite this obviously not
being intended (at default log levels).

Suggested-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Tested-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>

--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -620,15 +620,18 @@ static void printk_start_of_line(const c
 
 static void vprintk_common(const char *prefix, const char *fmt, va_list args)
 {
+    struct vps {
+        bool_t continued, do_print;
+    }            *state;
+    static DEFINE_PER_CPU(struct vps, state);
     static char   buf[1024];
-    static int    start_of_line = 1, do_print;
-
     char         *p, *q;
     unsigned long flags;
 
     /* console_lock can be acquired recursively from __printk_ratelimit(). */
     local_irq_save(flags);
     spin_lock_recursive(&console_lock);
+    state = &this_cpu(state);
 
     (void)vsnprintf(buf, sizeof(buf), fmt, args);
 
@@ -637,30 +640,30 @@ static void vprintk_common(const char *p
     while ( (q = strchr(p, '\n')) != NULL )
     {
         *q = '\0';
-        if ( start_of_line )
-            do_print = printk_prefix_check(p, &p);
-        if ( do_print )
+        if ( !state->continued )
+            state->do_print = printk_prefix_check(p, &p);
+        if ( state->do_print )
         {
-            if ( start_of_line )
+            if ( !state->continued )
                 printk_start_of_line(prefix);
             __putstr(p);
             __putstr("\n");
         }
-        start_of_line = 1;
+        state->continued = 0;
         p = q + 1;
     }
 
     if ( *p != '\0' )
     {
-        if ( start_of_line )
-            do_print = printk_prefix_check(p, &p);
-        if ( do_print )
+        if ( !state->continued )
+            state->do_print = printk_prefix_check(p, &p);
+        if ( state->do_print )
         {
-            if ( start_of_line )
+            if ( !state->continued )
                 printk_start_of_line(prefix);
             __putstr(p);
         }
-        start_of_line = 0;
+        state->continued = 1;
     }
 
     spin_unlock_recursive(&console_lock);



Attachment: console-state-per-CPU.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.