ia64/linux-2.6.18-xen.hg

changeset 306:5a6837bc5808

netback accel: locking bug fix

There was a call to xenbus_read() while a spinlock was held, and as
xenbus_read() can block this was clearly wrong. The spinlock is
replaced by a mutex.

Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
author Keir Fraser <keir@xensource.com>
date Mon Nov 05 15:02:50 2007 +0000 (2007-11-05)
parents a37a8c474d8b
children 6db518f1a141
files drivers/xen/netback/accel.c
line diff
     1.1 --- a/drivers/xen/netback/accel.c	Mon Nov 05 10:42:26 2007 +0000
     1.2 +++ b/drivers/xen/netback/accel.c	Mon Nov 05 15:02:50 2007 +0000
     1.3 @@ -33,6 +33,7 @@
     1.4  #include <linux/list.h>
     1.5  #include <asm/atomic.h>
     1.6  #include <xen/xenbus.h>
     1.7 +#include <linux/mutex.h>
     1.8  
     1.9  #include "common.h"
    1.10  
    1.11 @@ -48,7 +49,7 @@
    1.12   */ 
    1.13  static struct list_head accelerators_list;
    1.14  /* Lock used to protect access to accelerators_list */
    1.15 -static spinlock_t accelerators_lock;
    1.16 +DEFINE_MUTEX(accelerators_mutex);
    1.17  
    1.18  /* 
    1.19   * Compare a backend to an accelerator, and decide if they are
    1.20 @@ -107,7 +108,7 @@ int netback_connect_accelerator(unsigned
    1.21  				struct netback_accel_hooks *hooks)
    1.22  {
    1.23  	struct netback_accelerator *new_accelerator;
    1.24 -	unsigned eth_name_len, flags;
    1.25 +	unsigned eth_name_len;
    1.26  
    1.27  	if (version != NETBACK_ACCEL_VERSION) {
    1.28  		if (version > NETBACK_ACCEL_VERSION) {
    1.29 @@ -149,9 +150,9 @@ int netback_connect_accelerator(unsigned
    1.30  
    1.31  	atomic_set(&new_accelerator->use_count, 0);
    1.32  	
    1.33 -	spin_lock_irqsave(&accelerators_lock, flags);
    1.34 +	mutex_lock(&accelerators_mutex);
    1.35  	list_add(&new_accelerator->link, &accelerators_list);
    1.36 -	spin_unlock_irqrestore(&accelerators_lock, flags);
    1.37 +	mutex_unlock(&accelerators_mutex);
    1.38  	
    1.39  	/* tell existing backends about new plugin */
    1.40  	xenbus_for_each_backend(new_accelerator, 
    1.41 @@ -195,12 +196,12 @@ void netback_disconnect_accelerator(int 
    1.42  	struct netback_accelerator *accelerator, *next;
    1.43  	unsigned flags;
    1.44  
    1.45 -	spin_lock_irqsave(&accelerators_lock, flags);
    1.46 +	mutex_lock(&accelerators_mutex);
    1.47  	list_for_each_entry_safe(accelerator, next, &accelerators_list, link) {
    1.48  		if (strcmp(eth_name, accelerator->eth_name)) {
    1.49  			BUG_ON(atomic_read(&accelerator->use_count) != 0);
    1.50  			list_del(&accelerator->link);
    1.51 -			spin_unlock_irqrestore(&accelerators_lock, flags);
    1.52 +			mutex_unlock(&accelerators_mutex);
    1.53  
    1.54  			xenbus_for_each_backend(accelerator, 
    1.55  						netback_accelerator_cleanup_backend);
    1.56 @@ -210,7 +211,7 @@ void netback_disconnect_accelerator(int 
    1.57  			return;
    1.58  		}
    1.59  	}
    1.60 -	spin_unlock_irqrestore(&accelerators_lock, flags);
    1.61 +	mutex_unlock(&accelerators_mutex);
    1.62  }
    1.63  EXPORT_SYMBOL_GPL(netback_disconnect_accelerator);
    1.64  
    1.65 @@ -219,13 +220,12 @@ void netback_probe_accelerators(struct b
    1.66  				struct xenbus_device *dev)
    1.67  {
    1.68  	struct netback_accelerator *accelerator;
    1.69 -	unsigned flags;
    1.70  
    1.71  	/* 
    1.72  	 * Check list of accelerators to see if any is suitable, and
    1.73  	 * use it if it is.
    1.74  	 */
    1.75 -	spin_lock_irqsave(&accelerators_lock, flags);
    1.76 +	mutex_lock(&accelerators_mutex);
    1.77  	list_for_each_entry(accelerator, &accelerators_list, link) { 
    1.78  		if (match_accelerator(dev, be, accelerator) &&
    1.79  		    try_module_get(accelerator->hooks->owner)) {
    1.80 @@ -235,7 +235,7 @@ void netback_probe_accelerators(struct b
    1.81  			break;
    1.82  		}
    1.83  	}
    1.84 -	spin_unlock_irqrestore(&accelerators_lock, flags);
    1.85 +	mutex_unlock(&accelerators_mutex);
    1.86  }
    1.87  
    1.88  
    1.89 @@ -255,5 +255,4 @@ void netback_remove_accelerators(struct 
    1.90  void netif_accel_init(void)
    1.91  {
    1.92  	INIT_LIST_HEAD(&accelerators_list);
    1.93 -	spin_lock_init(&accelerators_lock);
    1.94  }