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-devel

[Xen-devel] [PATCH] kmalloc with spinlock held bug

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] kmalloc with spinlock held bug
From: Kieran Mansley <kmansley@xxxxxxxxxxxxxx>
Date: Thu, 20 Dec 2007 16:54:01 +0000
Delivery-date: Thu, 20 Dec 2007 08:54:30 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
I'm not sure how I didn't spot this sooner, but some of the code I wrote
for netfront acceleration was calling kmalloc(GFP_KERNEL) with a spin
lock held, and so irqs disabled, which is bad.  This patch fixes it by
making it a bit less eager to hold the spin lock.

Signed-off-by Kieran Mansley <kmansley@xxxxxxxxxxxxxx>

Over-eager locking meant kmalloc at GFP_KERNEL with irqs disabled

diff -r b65a76ffb4bb drivers/xen/netfront/accel.c
--- a/drivers/xen/netfront/accel.c      Tue Dec 18 13:11:39 2007 +0000
+++ b/drivers/xen/netfront/accel.c      Thu Dec 20 11:21:09 2007 +0000
@@ -273,6 +273,7 @@ static int init_accelerator(const char *
 {
        struct netfront_accelerator *accelerator = 
                kmalloc(sizeof(struct netfront_accelerator), GFP_KERNEL);
+       unsigned long flags;
        int frontend_len;
 
        if (!accelerator) {
@@ -294,7 +295,9 @@ static int init_accelerator(const char *
 
        accelerator->hooks = hooks;
 
+       spin_lock_irqsave(&accelerators_lock, flags);
        list_add(&accelerator->link, &accelerators_list);
+       spin_unlock_irqrestore(&accelerators_lock, flags);
 
        *result = accelerator;
 
@@ -365,11 +368,8 @@ static int netfront_load_accelerator(str
 {
        struct netfront_accelerator *accelerator;
        int rc = 0;
-       unsigned long flags;
 
        DPRINTK(" %s\n", frontend);
-
-       spin_lock_irqsave(&accelerators_lock, flags);
 
        /* 
         * Look at list of loaded accelerators to see if the requested
@@ -377,8 +377,6 @@ static int netfront_load_accelerator(str
         */
        list_for_each_entry(accelerator, &accelerators_list, link) {
                if (match_accelerator(frontend, accelerator)) {
-                       spin_unlock_irqrestore(&accelerators_lock, flags);
-
                        accelerator_probe_new_vif(np, dev, accelerator);
                        return 0;
                }
@@ -386,11 +384,8 @@ static int netfront_load_accelerator(str
 
        /* Couldn't find it, so create a new one and load the module */
        if ((rc = init_accelerator(frontend, &accelerator, NULL)) < 0) {
-               spin_unlock_irqrestore(&accelerators_lock, flags);
                return rc;
        }
-
-       spin_unlock_irqrestore(&accelerators_lock, flags);
 
        /* Include this frontend device on the accelerator's list */
        add_accelerator_vif(accelerator, np);
@@ -450,7 +445,6 @@ int netfront_accelerator_loaded(int vers
                                struct netfront_accel_hooks *hooks)
 {
        struct netfront_accelerator *accelerator;
-       unsigned long flags;
 
        if (version != NETFRONT_ACCEL_VERSION) {
                if (version > NETFRONT_ACCEL_VERSION) {
@@ -469,18 +463,13 @@ int netfront_accelerator_loaded(int vers
 
        mutex_lock(&accelerator_mutex);
 
-       spin_lock_irqsave(&accelerators_lock, flags);
-
        /* 
         * Look through list of accelerators to see if it has already
         * been requested
         */
        list_for_each_entry(accelerator, &accelerators_list, link) {
                if (match_accelerator(frontend, accelerator)) {
-                       spin_unlock_irqrestore(&accelerators_lock, flags);
-
                        accelerator_probe_vifs(accelerator, hooks);
-
                        goto out;
                }
        }
@@ -493,8 +482,6 @@ int netfront_accelerator_loaded(int vers
                frontend);
 
        init_accelerator(frontend, &accelerator, hooks);
-
-       spin_unlock_irqrestore(&accelerators_lock, flags);
 
  out:
        mutex_unlock(&accelerator_mutex);


Attachment: kmalloc_spinlock_fix
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] kmalloc with spinlock held bug, Kieran Mansley <=