@@ -55,7 +55,7 @@ int v9fs_init_worker_threads(void)
V9fsThPool *p = &v9fs_pool;
sigset_t set, oldset;
- if (p->pool) {
+ if (p->refcount++) {
return 0;
}
@@ -81,3 +81,16 @@ err_out:
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
return ret;
}
+
+void v9fs_release_worker_threads(void)
+{
+ V9fsThPool *p = &v9fs_pool;
+
+ if (--p->refcount) {
+ return;
+ }
+
+ g_thread_pool_free(p->pool, TRUE, TRUE);
+ g_async_queue_unref(p->completed);
+ event_notifier_set_handler(&p->e, NULL);
+}
@@ -25,6 +25,7 @@ typedef struct V9fsThPool {
GThreadPool *pool;
GAsyncQueue *completed;
+ unsigned refcount;
} V9fsThPool;
/*
@@ -56,6 +57,7 @@ typedef struct V9fsThPool {
extern void co_run_in_worker_bh(void *);
extern int v9fs_init_worker_threads(void);
+extern void v9fs_release_worker_threads(void);
extern int v9fs_co_readlink(V9fsPDU *, V9fsPath *, V9fsString *);
extern int v9fs_co_readdir_r(V9fsPDU *, V9fsFidState *,
struct dirent *, struct dirent **result);
@@ -138,6 +138,17 @@ out:
v9fs_path_free(&path);
}
+static void virtio_9p_device_unrealize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ V9fsState *s = VIRTIO_9P(dev);
+
+ v9fs_release_worker_threads();
+ g_free(s->ctx.fs_root);
+ g_free(s->tag);
+ virtio_cleanup(vdev);
+}
+
/* virtio-9p device */
static Property virtio_9p_properties[] = {
@@ -154,6 +165,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
dc->props = virtio_9p_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->realize = virtio_9p_device_realize;
+ vdc->unrealize = virtio_9p_device_unrealize;
vdc->get_features = virtio_9p_get_features;
vdc->get_config = virtio_9p_get_config;
}
This patch allows to hot-unplug a quiescent virtio-9p device, and free its allocated resources. A refcount is added to the v9fs thread pool, so that its resources are freed as well when the last virtio-9p device is unplugged. Note that we have an unplug blocker which prevents this code to be reached if the 9p share is mounted in the guest. No need to bother about in-flight I/O requests in this case. This patch fixes a QEMU crash on the source node if the user device_add a virtio-9p device and then migrate. Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> --- hw/9pfs/virtio-9p-coth.c | 15 ++++++++++++++- hw/9pfs/virtio-9p-coth.h | 2 ++ hw/9pfs/virtio-9p-device.c | 12 ++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-)