summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/xenbus/xenbus_dev_frontend.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 08adc590f631..597af455a522 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -55,6 +55,7 @@
55#include <linux/string.h> 55#include <linux/string.h>
56#include <linux/slab.h> 56#include <linux/slab.h>
57#include <linux/miscdevice.h> 57#include <linux/miscdevice.h>
58#include <linux/workqueue.h>
58 59
59#include <xen/xenbus.h> 60#include <xen/xenbus.h>
60#include <xen/xen.h> 61#include <xen/xen.h>
@@ -116,6 +117,8 @@ struct xenbus_file_priv {
116 wait_queue_head_t read_waitq; 117 wait_queue_head_t read_waitq;
117 118
118 struct kref kref; 119 struct kref kref;
120
121 struct work_struct wq;
119}; 122};
120 123
121/* Read out any raw xenbus messages queued up. */ 124/* Read out any raw xenbus messages queued up. */
@@ -300,14 +303,14 @@ static void watch_fired(struct xenbus_watch *watch,
300 mutex_unlock(&adap->dev_data->reply_mutex); 303 mutex_unlock(&adap->dev_data->reply_mutex);
301} 304}
302 305
303static void xenbus_file_free(struct kref *kref) 306static void xenbus_worker(struct work_struct *wq)
304{ 307{
305 struct xenbus_file_priv *u; 308 struct xenbus_file_priv *u;
306 struct xenbus_transaction_holder *trans, *tmp; 309 struct xenbus_transaction_holder *trans, *tmp;
307 struct watch_adapter *watch, *tmp_watch; 310 struct watch_adapter *watch, *tmp_watch;
308 struct read_buffer *rb, *tmp_rb; 311 struct read_buffer *rb, *tmp_rb;
309 312
310 u = container_of(kref, struct xenbus_file_priv, kref); 313 u = container_of(wq, struct xenbus_file_priv, wq);
311 314
312 /* 315 /*
313 * No need for locking here because there are no other users, 316 * No need for locking here because there are no other users,
@@ -333,6 +336,18 @@ static void xenbus_file_free(struct kref *kref)
333 kfree(u); 336 kfree(u);
334} 337}
335 338
339static void xenbus_file_free(struct kref *kref)
340{
341 struct xenbus_file_priv *u;
342
343 /*
344 * We might be called in xenbus_thread().
345 * Use workqueue to avoid deadlock.
346 */
347 u = container_of(kref, struct xenbus_file_priv, kref);
348 schedule_work(&u->wq);
349}
350
336static struct xenbus_transaction_holder *xenbus_get_transaction( 351static struct xenbus_transaction_holder *xenbus_get_transaction(
337 struct xenbus_file_priv *u, uint32_t tx_id) 352 struct xenbus_file_priv *u, uint32_t tx_id)
338{ 353{
@@ -650,6 +665,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
650 INIT_LIST_HEAD(&u->watches); 665 INIT_LIST_HEAD(&u->watches);
651 INIT_LIST_HEAD(&u->read_buffers); 666 INIT_LIST_HEAD(&u->read_buffers);
652 init_waitqueue_head(&u->read_waitq); 667 init_waitqueue_head(&u->read_waitq);
668 INIT_WORK(&u->wq, xenbus_worker);
653 669
654 mutex_init(&u->reply_mutex); 670 mutex_init(&u->reply_mutex);
655 mutex_init(&u->msgbuffer_mutex); 671 mutex_init(&u->msgbuffer_mutex);