From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41412) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UnQd3-0001uA-Fp for qemu-devel@nongnu.org; Fri, 14 Jun 2013 05:49:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UnQcr-0000gm-Un for qemu-devel@nongnu.org; Fri, 14 Jun 2013 05:49:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:61323) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UnQcr-0000gO-K2 for qemu-devel@nongnu.org; Fri, 14 Jun 2013 05:48:57 -0400 From: Stefan Hajnoczi Date: Fri, 14 Jun 2013 11:48:27 +0200 Message-Id: <1371203313-26490-8-git-send-email-stefanha@redhat.com> In-Reply-To: <1371203313-26490-1-git-send-email-stefanha@redhat.com> References: <1371203313-26490-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [RFC 07/13] block: add thread_aio_context TLS variable List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Paolo Bonzini , Anthony Liguori , Ping Fan Liu , Stefan Hajnoczi BH and fd handler APIs need to know which AioContext (event loop) to run inside. Passing it around everywhere is not feasible since it would require adding arguments to any call-chain that invokes BH and fd handler APIs (hint: there are many and they change). Instead make the AioContext pointer thread-local. This way, any function that needs to use an AioContext can find it. In particular: the iothread and vcpu threads share the main AioContext since they hold the global mutex while running. Dataplane threads will use their own AioContexts. Signed-off-by: Stefan Hajnoczi --- async.c | 2 ++ cpus.c | 2 ++ include/block/aio.h | 4 ++++ main-loop.c | 1 + 4 files changed, 9 insertions(+) diff --git a/async.c b/async.c index 90fe906..765cbc0 100644 --- a/async.c +++ b/async.c @@ -27,6 +27,8 @@ #include "block/thread-pool.h" #include "qemu/main-loop.h" +DEFINE_TLS(AioContext*, thread_aio_context); + /***********************************************************/ /* bottom halves (can be seen as timers which expire ASAP) */ diff --git a/cpus.c b/cpus.c index c232265..529d612 100644 --- a/cpus.c +++ b/cpus.c @@ -741,6 +741,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) qemu_thread_get_self(cpu->thread); cpu->thread_id = qemu_get_thread_id(); cpu_single_env = env; + *alloc_thread_aio_context() = qemu_get_aio_context(); r = kvm_init_vcpu(cpu); if (r < 0) { @@ -815,6 +816,7 @@ static void tcg_exec_all(void); static void tcg_signal_cpu_creation(CPUState *cpu, void *data) { cpu->thread_id = qemu_get_thread_id(); + *alloc_thread_aio_context() = qemu_get_aio_context(); cpu->created = true; } diff --git a/include/block/aio.h b/include/block/aio.h index 1836793..6ee9369 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -17,6 +17,7 @@ #include "qemu-common.h" #include "qemu/queue.h" #include "qemu/event_notifier.h" +#include "qemu/tls.h" typedef struct BlockDriverAIOCB BlockDriverAIOCB; typedef void BlockDriverCompletionFunc(void *opaque, int ret); @@ -74,6 +75,9 @@ typedef struct AioContext { /* Returns 1 if there are still outstanding AIO requests; 0 otherwise */ typedef int (AioFlushEventNotifierHandler)(EventNotifier *e); +/* Each thread can have a default AioContext */ +DECLARE_TLS(AioContext*, thread_aio_context); + /** * aio_context_new: Allocate a new AioContext. * diff --git a/main-loop.c b/main-loop.c index cf36645..51eeb0f 100644 --- a/main-loop.c +++ b/main-loop.c @@ -142,6 +142,7 @@ int qemu_init_main_loop(void) gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD)); qemu_aio_context = aio_context_new(); + *get_thread_aio_context() = qemu_aio_context; src = aio_get_g_source(qemu_aio_context); g_source_attach(src, NULL); g_source_unref(src); -- 1.8.1.4