WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [XEN] Fix deadlock in printk().

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Fix deadlock in printk().
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 01 Nov 2006 11:40:14 +0000
Delivery-date: Thu, 02 Nov 2006 13:52:56 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 874cc0ff214daac1fec3890e083a6ca36b79dbfa
# Parent  0a3d7dacff4ccce72b42ac791971bee86d70e736
[XEN] Fix deadlock in printk().
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/drivers/char/console.c |   56 ++++++++++++++++++++++++++++-----------------
 xen/include/xen/config.h   |    2 -
 2 files changed, 36 insertions(+), 22 deletions(-)

diff -r 0a3d7dacff4c -r 874cc0ff214d xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Tue Oct 31 18:24:57 2006 +0000
+++ b/xen/drivers/char/console.c        Wed Nov 01 09:55:43 2006 +0000
@@ -338,12 +338,14 @@ void printk(const char *fmt, ...)
     va_list       args;
     char         *p, *q;
     unsigned long flags;
-    int           level = XENLOG_DEFAULT;
+    int           level = -1;
     int           upper_thresh = xenlog_upper_thresh;
     int           lower_thresh = xenlog_lower_thresh;
     int           print_regardless = xen_startup;
 
-    spin_lock_irqsave(&console_lock, flags);
+    /* console_lock can be acquired recursively from __printk_ratelimit(). */
+    local_irq_save(flags);
+    spin_lock_recursive(&console_lock);
 
     va_start(args, fmt);
     (void)vsnprintf(buf, sizeof(buf), fmt, args);
@@ -351,22 +353,25 @@ void printk(const char *fmt, ...)
 
     p = buf;
 
-    /* Is this print caused by a guest? */
-    if ( strncmp("<G>", p, 3) == 0 )
-    {
-        upper_thresh = xenlog_guest_upper_thresh;
-        lower_thresh = xenlog_guest_lower_thresh;
-        level = XENLOG_GUEST_DEFAULT;
+    while ( (p[0] == '<') && (p[1] != '\0') && (p[2] == '>') )
+    {
+        switch ( p[1] )
+        {
+        case 'G':
+            upper_thresh = xenlog_guest_upper_thresh;
+            lower_thresh = xenlog_guest_lower_thresh;
+            if ( level == -1 )
+                level = XENLOG_GUEST_DEFAULT;
+            break;
+        case '0' ... '3':
+            level = p[1] - '0';
+            break;
+        }
         p += 3;
     }
 
-    if ( (p[0] == '<') &&
-         (p[1] >= '0') && (p[1] <= ('0' + XENLOG_MAX)) &&
-         (p[2] == '>') )
-    {
-        level = p[1] - '0';
-        p += 3;
-    }
+    if ( level == -1 )
+        level = XENLOG_DEFAULT;
 
     if ( !print_regardless )
     {
@@ -396,7 +401,8 @@ void printk(const char *fmt, ...)
     }
 
  out:
-    spin_unlock_irqrestore(&console_lock, flags);
+    spin_unlock_recursive(&console_lock);
+    local_irq_restore(flags);
 }
 
 void set_printk_prefix(const char *prefix)
@@ -547,9 +553,20 @@ int __printk_ratelimit(int ratelimit_ms,
         int lost = missed;
         missed = 0;
         toks -= ratelimit_ms;
-        spin_unlock_irqrestore(&ratelimit_lock, flags);
+        spin_unlock(&ratelimit_lock);
         if ( lost )
-            printk("printk: %d messages suppressed.\n", lost);
+        {
+            char lost_str[8];
+            snprintf(lost_str, sizeof(lost_str), "%d", lost);
+            /* console_lock may already be acquired by printk(). */
+            spin_lock_recursive(&console_lock);
+            __putstr(printk_prefix);
+            __putstr("printk: ");
+            __putstr(lost_str);
+            __putstr(" messages suppressed.\n");
+            spin_unlock_recursive(&console_lock);
+        }
+        local_irq_restore(flags);
         return 1;
     }
     missed++;
@@ -565,8 +582,7 @@ int printk_ratelimit_burst = 10;
 
 int printk_ratelimit(void)
 {
-    return __printk_ratelimit(printk_ratelimit_ms,
-                              printk_ratelimit_burst);
+    return __printk_ratelimit(printk_ratelimit_ms, printk_ratelimit_burst);
 }
 
 /*
diff -r 0a3d7dacff4c -r 874cc0ff214d xen/include/xen/config.h
--- a/xen/include/xen/config.h  Tue Oct 31 18:24:57 2006 +0000
+++ b/xen/include/xen/config.h  Wed Nov 01 09:55:43 2006 +0000
@@ -47,8 +47,6 @@
 #define XENLOG_G_WARNING XENLOG_GUEST XENLOG_WARNING
 #define XENLOG_G_INFO    XENLOG_GUEST XENLOG_INFO
 #define XENLOG_G_DEBUG   XENLOG_GUEST XENLOG_DEBUG
-
-#define XENLOG_MAX 3
 
 /*
  * Some code is copied directly from Linux.

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEN] Fix deadlock in printk()., Xen patchbot-unstable <=