ia64/xen-unstable

changeset 14179:aac0a4b8e328

linux: Split suspend_mutex into watch_mutex and transaction_mutex.
This clarifies their usage and relationship with request_mutex and
response_mutex.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Feb 28 14:26:26 2007 +0000 (2007-02-28)
parents 1ec0d322402e
children 868c28c0a4f4
files linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Wed Feb 28 14:13:09 2007 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Wed Feb 28 14:26:26 2007 +0000
     1.3 @@ -77,6 +77,11 @@ struct xs_handle {
     1.4  	spinlock_t reply_lock;
     1.5  	wait_queue_head_t reply_waitq;
     1.6  
     1.7 +	/*
     1.8 +	 * Mutex ordering: transaction_mutex -> watch_mutex -> request_mutex.
     1.9 +	 * response_mutex is never taken simultaneously with the other three.
    1.10 +	 */
    1.11 +
    1.12  	/* One request at a time. */
    1.13  	struct mutex request_mutex;
    1.14  
    1.15 @@ -84,7 +89,10 @@ struct xs_handle {
    1.16  	struct mutex response_mutex;
    1.17  
    1.18  	/* Protect transactions against save/restore. */
    1.19 -	struct rw_semaphore suspend_mutex;
    1.20 +	struct rw_semaphore transaction_mutex;
    1.21 +
    1.22 +	/* Protect watch (de)register against save/restore. */
    1.23 +	struct rw_semaphore watch_mutex;
    1.24  };
    1.25  
    1.26  static struct xs_handle xs_state;
    1.27 @@ -160,7 +168,7 @@ void *xenbus_dev_request_and_reply(struc
    1.28  	int err;
    1.29  
    1.30  	if (req_msg.type == XS_TRANSACTION_START)
    1.31 -		down_read(&xs_state.suspend_mutex);
    1.32 +		down_read(&xs_state.transaction_mutex);
    1.33  
    1.34  	mutex_lock(&xs_state.request_mutex);
    1.35  
    1.36 @@ -176,7 +184,7 @@ void *xenbus_dev_request_and_reply(struc
    1.37  	if ((req_msg.type == XS_TRANSACTION_END) ||
    1.38  	    ((req_msg.type == XS_TRANSACTION_START) &&
    1.39  	     (msg->type == XS_ERROR)))
    1.40 -		up_read(&xs_state.suspend_mutex);
    1.41 +		up_read(&xs_state.transaction_mutex);
    1.42  
    1.43  	return ret;
    1.44  }
    1.45 @@ -427,11 +435,11 @@ int xenbus_transaction_start(struct xenb
    1.46  {
    1.47  	char *id_str;
    1.48  
    1.49 -	down_read(&xs_state.suspend_mutex);
    1.50 +	down_read(&xs_state.transaction_mutex);
    1.51  
    1.52  	id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
    1.53  	if (IS_ERR(id_str)) {
    1.54 -		up_read(&xs_state.suspend_mutex);
    1.55 +		up_read(&xs_state.transaction_mutex);
    1.56  		return PTR_ERR(id_str);
    1.57  	}
    1.58  
    1.59 @@ -456,7 +464,7 @@ int xenbus_transaction_end(struct xenbus
    1.60  
    1.61  	err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
    1.62  
    1.63 -	up_read(&xs_state.suspend_mutex);
    1.64 +	up_read(&xs_state.transaction_mutex);
    1.65  
    1.66  	return err;
    1.67  }
    1.68 @@ -589,7 +597,7 @@ int register_xenbus_watch(struct xenbus_
    1.69  
    1.70  	sprintf(token, "%lX", (long)watch);
    1.71  
    1.72 -	down_read(&xs_state.suspend_mutex);
    1.73 +	down_read(&xs_state.watch_mutex);
    1.74  
    1.75  	spin_lock(&watches_lock);
    1.76  	BUG_ON(find_watch(token));
    1.77 @@ -605,7 +613,7 @@ int register_xenbus_watch(struct xenbus_
    1.78  		spin_unlock(&watches_lock);
    1.79  	}
    1.80  
    1.81 -	up_read(&xs_state.suspend_mutex);
    1.82 +	up_read(&xs_state.watch_mutex);
    1.83  
    1.84  	return err;
    1.85  }
    1.86 @@ -619,7 +627,7 @@ void unregister_xenbus_watch(struct xenb
    1.87  
    1.88  	sprintf(token, "%lX", (long)watch);
    1.89  
    1.90 -	down_read(&xs_state.suspend_mutex);
    1.91 +	down_read(&xs_state.watch_mutex);
    1.92  
    1.93  	spin_lock(&watches_lock);
    1.94  	BUG_ON(!find_watch(token));
    1.95 @@ -632,7 +640,7 @@ void unregister_xenbus_watch(struct xenb
    1.96  		       "XENBUS Failed to release watch %s: %i\n",
    1.97  		       watch->node, err);
    1.98  
    1.99 -	up_read(&xs_state.suspend_mutex);
   1.100 +	up_read(&xs_state.watch_mutex);
   1.101  
   1.102  	/* Cancel pending watch events. */
   1.103  	spin_lock(&watch_events_lock);
   1.104 @@ -655,7 +663,8 @@ EXPORT_SYMBOL_GPL(unregister_xenbus_watc
   1.105  
   1.106  void xs_suspend(void)
   1.107  {
   1.108 -	down_write(&xs_state.suspend_mutex);
   1.109 +	down_write(&xs_state.transaction_mutex);
   1.110 +	down_write(&xs_state.watch_mutex);
   1.111  	mutex_lock(&xs_state.request_mutex);
   1.112  	mutex_lock(&xs_state.response_mutex);
   1.113  }
   1.114 @@ -667,21 +676,23 @@ void xs_resume(void)
   1.115  
   1.116  	mutex_unlock(&xs_state.response_mutex);
   1.117  	mutex_unlock(&xs_state.request_mutex);
   1.118 +	up_write(&xs_state.transaction_mutex);
   1.119  
   1.120 -	/* No need for watches_lock: the suspend_mutex is sufficient. */
   1.121 +	/* No need for watches_lock: the watch_mutex is sufficient. */
   1.122  	list_for_each_entry(watch, &watches, list) {
   1.123  		sprintf(token, "%lX", (long)watch);
   1.124  		xs_watch(watch->node, token);
   1.125  	}
   1.126  
   1.127 -	up_write(&xs_state.suspend_mutex);
   1.128 +	up_write(&xs_state.watch_mutex);
   1.129  }
   1.130  
   1.131  void xs_suspend_cancel(void)
   1.132  {
   1.133  	mutex_unlock(&xs_state.response_mutex);
   1.134  	mutex_unlock(&xs_state.request_mutex);
   1.135 -	up_write(&xs_state.suspend_mutex);
   1.136 +	up_write(&xs_state.watch_mutex);
   1.137 +	up_write(&xs_state.transaction_mutex);
   1.138  }
   1.139  
   1.140  static int xenwatch_handle_callback(void *data)
   1.141 @@ -848,7 +859,8 @@ int xs_init(void)
   1.142  
   1.143  	mutex_init(&xs_state.request_mutex);
   1.144  	mutex_init(&xs_state.response_mutex);
   1.145 -	init_rwsem(&xs_state.suspend_mutex);
   1.146 +	init_rwsem(&xs_state.transaction_mutex);
   1.147 +	init_rwsem(&xs_state.watch_mutex);
   1.148  
   1.149  	/* Initialize the shared memory rings to talk to xenstored */
   1.150  	err = xb_init_comms();