From 7c47c4ead75d0b733ee8f2f51fd1de0644cc1308 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Thu, 28 Sep 2017 10:59:54 +0800 Subject: qom: provide root container for internal objs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have object_get_objects_root() to keep user created objects, however no place for objects that will be used internally. Create such a container for internal objects. CC: Andreas Färber CC: Markus Armbruster CC: Paolo Bonzini Suggested-by: Daniel P. Berrange Signed-off-by: Peter Xu Reviewed-by: Fam Zheng Message-id: 20170928025958.1420-2-peterx@redhat.com Signed-off-by: Stefan Hajnoczi --- include/qom/object.h | 11 +++++++++++ qom/object.c | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index f3e5cff..e0d9824 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1214,6 +1214,17 @@ Object *object_get_root(void); Object *object_get_objects_root(void); /** + * object_get_internal_root: + * + * Get the container object that holds internally used object + * instances. Any object which is put into this container must not be + * user visible, and it will not be exposed in the QOM tree. + * + * Returns: the internal object container + */ +Object *object_get_internal_root(void); + +/** * object_get_canonical_path_component: * * Returns: The final component in the object's canonical path. The canonical diff --git a/qom/object.c b/qom/object.c index 3e18537..6a7bd92 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1370,6 +1370,17 @@ Object *object_get_objects_root(void) return container_get(object_get_root(), "/objects"); } +Object *object_get_internal_root(void) +{ + static Object *internal_root; + + if (!internal_root) { + internal_root = object_new("container"); + } + + return internal_root; +} + static void object_get_child_property(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) -- cgit v1.1 From 0173e21b617d3de1fcfa917e329bb9194ab332a4 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Thu, 28 Sep 2017 10:59:55 +0800 Subject: iothread: provide helpers for internal use IOThread is a general framework that contains IO loop environment and a real thread behind. It's also good to be used internally inside qemu. Provide some helpers for it to create iothreads to be used internally. Put all the internal used iothreads into the internal object container. Reviewed-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Signed-off-by: Peter Xu Message-id: 20170928025958.1420-3-peterx@redhat.com Signed-off-by: Stefan Hajnoczi --- include/sysemu/iothread.h | 8 ++++++++ iothread.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h index d2985b3..b07663f 100644 --- a/include/sysemu/iothread.h +++ b/include/sysemu/iothread.h @@ -46,4 +46,12 @@ AioContext *iothread_get_aio_context(IOThread *iothread); void iothread_stop_all(void); GMainContext *iothread_get_g_main_context(IOThread *iothread); +/* + * Helpers used to allocate iothreads for internal use. These + * iothreads will not be seen by monitor clients when query using + * "query-iothreads". + */ +IOThread *iothread_create(const char *id, Error **errp); +void iothread_destroy(IOThread *iothread); + #endif /* IOTHREAD_H */ diff --git a/iothread.c b/iothread.c index 59d0850..0672a91 100644 --- a/iothread.c +++ b/iothread.c @@ -354,3 +354,19 @@ GMainContext *iothread_get_g_main_context(IOThread *iothread) return iothread->worker_context; } + +IOThread *iothread_create(const char *id, Error **errp) +{ + Object *obj; + + obj = object_new_with_props(TYPE_IOTHREAD, + object_get_internal_root(), + id, errp, NULL); + + return IOTHREAD(obj); +} + +void iothread_destroy(IOThread *iothread) +{ + object_unparent(OBJECT(iothread)); +} -- cgit v1.1 From 82d90705fe203cc6e150c10bd61f0dbe6979e8f4 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Thu, 28 Sep 2017 10:59:56 +0800 Subject: iothread: export iothread_stop() So that internal iothread users can explicitly stop one iothread without destroying it. Since at it, fix iothread_stop() to allow it to be called multiple times. Before this patch we may call iothread_stop() more than once on single iothread, while that may not be correct since qemu_thread_join() is not allowed to run twice. From manual of pthread_join(): Joining with a thread that has previously been joined results in undefined behavior. Reviewed-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Signed-off-by: Peter Xu Message-id: 20170928025958.1420-4-peterx@redhat.com Signed-off-by: Stefan Hajnoczi --- include/sysemu/iothread.h | 1 + iothread.c | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h index b07663f..110329b 100644 --- a/include/sysemu/iothread.h +++ b/include/sysemu/iothread.h @@ -52,6 +52,7 @@ GMainContext *iothread_get_g_main_context(IOThread *iothread); * "query-iothreads". */ IOThread *iothread_create(const char *id, Error **errp); +void iothread_stop(IOThread *iothread); void iothread_destroy(IOThread *iothread); #endif /* IOTHREAD_H */ diff --git a/iothread.c b/iothread.c index 0672a91..b3c092b 100644 --- a/iothread.c +++ b/iothread.c @@ -80,13 +80,10 @@ static void *iothread_run(void *opaque) return NULL; } -static int iothread_stop(Object *object, void *opaque) +void iothread_stop(IOThread *iothread) { - IOThread *iothread; - - iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD); - if (!iothread || !iothread->ctx || iothread->stopping) { - return 0; + if (!iothread->ctx || iothread->stopping) { + return; } iothread->stopping = true; aio_notify(iothread->ctx); @@ -94,6 +91,17 @@ static int iothread_stop(Object *object, void *opaque) g_main_loop_quit(iothread->main_loop); } qemu_thread_join(&iothread->thread); +} + +static int iothread_stop_iter(Object *object, void *opaque) +{ + IOThread *iothread; + + iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD); + if (!iothread) { + return 0; + } + iothread_stop(iothread); return 0; } @@ -108,7 +116,7 @@ static void iothread_instance_finalize(Object *obj) { IOThread *iothread = IOTHREAD(obj); - iothread_stop(obj, NULL); + iothread_stop(iothread); qemu_cond_destroy(&iothread->init_done_cond); qemu_mutex_destroy(&iothread->init_done_lock); if (!iothread->ctx) { @@ -328,7 +336,7 @@ void iothread_stop_all(void) aio_context_release(ctx); } - object_child_foreach(container, iothread_stop, NULL); + object_child_foreach(container, iothread_stop_iter, NULL); } static gpointer iothread_g_main_context_init(gpointer opaque) -- cgit v1.1 From 5b3ac23fee97fc1a79ad2bb1cf3a1ce518d27905 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Thu, 28 Sep 2017 10:59:57 +0800 Subject: iothread: delay the context release to finalize When gcontext is used with iothread, the context will be destroyed during iothread_stop(). That's not good since sometimes we would like to keep the resources until iothread is destroyed, but we may want to stop the thread before that point. Delay the destruction of gcontext to iothread finalize. Then we can do: iothread_stop(thread); some_cleanup_on_resources(); iothread_destroy(thread); We may need this patch if we want to run chardev IOs in iothreads and hopefully clean them up correctly. For more specific information, please see 2b316774f6 ("qemu-char: do not operate on sources from finalize callbacks"). Reviewed-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Signed-off-by: Peter Xu Message-id: 20170928025958.1420-5-peterx@redhat.com Signed-off-by: Stefan Hajnoczi --- iothread.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iothread.c b/iothread.c index b3c092b..27a4288 100644 --- a/iothread.c +++ b/iothread.c @@ -71,8 +71,6 @@ static void *iothread_run(void *opaque) g_main_loop_unref(loop); g_main_context_pop_thread_default(iothread->worker_context); - g_main_context_unref(iothread->worker_context); - iothread->worker_context = NULL; } } @@ -117,6 +115,10 @@ static void iothread_instance_finalize(Object *obj) IOThread *iothread = IOTHREAD(obj); iothread_stop(iothread); + if (iothread->worker_context) { + g_main_context_unref(iothread->worker_context); + iothread->worker_context = NULL; + } qemu_cond_destroy(&iothread->init_done_cond); qemu_mutex_destroy(&iothread->init_done_lock); if (!iothread->ctx) { -- cgit v1.1 From f708a5e71cba0d784e307334c07ade5f56f827ab Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 28 Sep 2017 10:59:58 +0800 Subject: aio: fix assert when remove poll during destroy After iothread is enabled internally inside QEMU with GMainContext, we may encounter this warning when destroying the iothread: (qemu-system-x86_64:19925): GLib-CRITICAL **: g_source_remove_poll: assertion '!SOURCE_DESTROYED (source)' failed The problem is that g_source_remove_poll() does not allow to remove one source from array if the source is detached from its owner context. (peterx: which IMHO does not make much sense) Fix it on QEMU side by avoid calling g_source_remove_poll() if we know the object is during destruction, and we won't leak anything after all since the array will be gone soon cleanly even with that fd. Signed-off-by: Stefan Hajnoczi Reviewed-by: Fam Zheng Signed-off-by: Peter Xu Message-id: 20170928025958.1420-6-peterx@redhat.com [peterx: write the commit message] Signed-off-by: Peter Xu Signed-off-by: Stefan Hajnoczi --- util/aio-posix.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/util/aio-posix.c b/util/aio-posix.c index 2d51239..5946ac0 100644 --- a/util/aio-posix.c +++ b/util/aio-posix.c @@ -223,7 +223,14 @@ void aio_set_fd_handler(AioContext *ctx, return; } - g_source_remove_poll(&ctx->source, &node->pfd); + /* If the GSource is in the process of being destroyed then + * g_source_remove_poll() causes an assertion failure. Skip + * removal in that case, because glib cleans up its state during + * destruction anyway. + */ + if (!g_source_is_destroyed(&ctx->source)) { + g_source_remove_poll(&ctx->source, &node->pfd); + } /* If the lock is held, just mark the node as deleted */ if (qemu_lockcnt_count(&ctx->list_lock)) { -- cgit v1.1