|
|
@@ -55,6 +55,7 @@
|
|
|
#include <linux/string.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/miscdevice.h>
|
|
|
+#include <linux/workqueue.h>
|
|
|
|
|
|
#include <xen/xenbus.h>
|
|
|
#include <xen/xen.h>
|
|
|
@@ -116,6 +117,8 @@ struct xenbus_file_priv {
|
|
|
wait_queue_head_t read_waitq;
|
|
|
|
|
|
struct kref kref;
|
|
|
+
|
|
|
+ struct work_struct wq;
|
|
|
};
|
|
|
|
|
|
/* Read out any raw xenbus messages queued up. */
|
|
|
@@ -300,14 +303,14 @@ static void watch_fired(struct xenbus_watch *watch,
|
|
|
mutex_unlock(&adap->dev_data->reply_mutex);
|
|
|
}
|
|
|
|
|
|
-static void xenbus_file_free(struct kref *kref)
|
|
|
+static void xenbus_worker(struct work_struct *wq)
|
|
|
{
|
|
|
struct xenbus_file_priv *u;
|
|
|
struct xenbus_transaction_holder *trans, *tmp;
|
|
|
struct watch_adapter *watch, *tmp_watch;
|
|
|
struct read_buffer *rb, *tmp_rb;
|
|
|
|
|
|
- u = container_of(kref, struct xenbus_file_priv, kref);
|
|
|
+ u = container_of(wq, struct xenbus_file_priv, wq);
|
|
|
|
|
|
/*
|
|
|
* No need for locking here because there are no other users,
|
|
|
@@ -333,6 +336,18 @@ static void xenbus_file_free(struct kref *kref)
|
|
|
kfree(u);
|
|
|
}
|
|
|
|
|
|
+static void xenbus_file_free(struct kref *kref)
|
|
|
+{
|
|
|
+ struct xenbus_file_priv *u;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We might be called in xenbus_thread().
|
|
|
+ * Use workqueue to avoid deadlock.
|
|
|
+ */
|
|
|
+ u = container_of(kref, struct xenbus_file_priv, kref);
|
|
|
+ schedule_work(&u->wq);
|
|
|
+}
|
|
|
+
|
|
|
static struct xenbus_transaction_holder *xenbus_get_transaction(
|
|
|
struct xenbus_file_priv *u, uint32_t tx_id)
|
|
|
{
|
|
|
@@ -652,6 +667,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
|
|
|
INIT_LIST_HEAD(&u->watches);
|
|
|
INIT_LIST_HEAD(&u->read_buffers);
|
|
|
init_waitqueue_head(&u->read_waitq);
|
|
|
+ INIT_WORK(&u->wq, xenbus_worker);
|
|
|
|
|
|
mutex_init(&u->reply_mutex);
|
|
|
mutex_init(&u->msgbuffer_mutex);
|