All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] console: make printk() line continuation tracking per-CPU
@ 2015-11-24 17:36 Jan Beulich
  2015-11-25 10:39 ` Ian Campbell
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Beulich @ 2015-11-24 17:36 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Keir Fraser, Ian Jackson, Tim Deegan

[-- Attachment #1: Type: text/plain, Size: 2621 bytes --]

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@oracle.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>

--- 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 #2: console-state-per-CPU.patch --]
[-- Type: text/plain, Size: 2676 bytes --]

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@oracle.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>

--- 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 #3: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] console: make printk() line continuation tracking per-CPU
  2015-11-24 17:36 [PATCH] console: make printk() line continuation tracking per-CPU Jan Beulich
@ 2015-11-25 10:39 ` Ian Campbell
  0 siblings, 0 replies; 2+ messages in thread
From: Ian Campbell @ 2015-11-25 10:39 UTC (permalink / raw)
  To: Jan Beulich, xen-devel; +Cc: Keir Fraser, Ian Jackson, Tim Deegan

On Tue, 2015-11-24 at 10:36 -0700, Jan Beulich wrote:
> 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@oracle.com>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-11-25 10:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-24 17:36 [PATCH] console: make printk() line continuation tracking per-CPU Jan Beulich
2015-11-25 10:39 ` Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.