From 6538692e2802666926e62d9309ddddda5ec9dc3b Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Thu, 3 Mar 2022 10:15:46 -0500 Subject: main-loop.h: introduce qemu_in_main_thread() When invoked from the main loop, this function is the same as qemu_mutex_iothread_locked, and returns true if the BQL is held. When invoked from iothreads or tests, it returns true only if the current AioContext is the Main Loop. This essentially just extends qemu_mutex_iothread_locked to work also in unit tests or other users like storage-daemon, that run in the Main Loop but end up using the implementation in stubs/iothread-lock.c. Using qemu_mutex_iothread_locked in unit tests defaults to false because they use the implementation in stubs/iothread-lock, making all assertions added in next patches fail despite the AioContext is still the main loop. See the comment in the function header for more information. Signed-off-by: Emanuele Giuseppe Esposito Message-Id: <20220303151616.325444-2-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- include/qemu/main-loop.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include/qemu/main-loop.h') diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index 8dbc6fcb89..bc42b5939d 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -242,9 +242,33 @@ AioContext *iohandler_get_aio_context(void); * must always be taken outside other locks. This function helps * functions take different paths depending on whether the current * thread is running within the main loop mutex. + * + * This function should never be used in the block layer, because + * unit tests, block layer tools and qemu-storage-daemon do not + * have a BQL. + * Please instead refer to qemu_in_main_thread(). */ bool qemu_mutex_iothread_locked(void); +/** + * qemu_in_main_thread: return whether it's possible to safely access + * the global state of the block layer. + * + * Global state of the block layer is not accessible from I/O threads + * or worker threads; only from threads that "own" the default + * AioContext that qemu_get_aio_context() returns. For tests, block + * layer tools and qemu-storage-daemon there is a designated thread that + * runs the event loop for qemu_get_aio_context(), and that is the + * main thread. + * + * For emulators, however, any thread that holds the BQL can act + * as the block layer main thread; this will be any of the actual + * main thread, the vCPU threads or the RCU thread. + * + * For clarity, do not use this function outside the block layer. + */ +bool qemu_in_main_thread(void); + /** * qemu_mutex_lock_iothread: Lock the main loop mutex. * -- cgit v1.2.3-55-g7522 From ac7798f280b716701489594fe5bc7864b26a99e6 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Thu, 3 Mar 2022 10:15:47 -0500 Subject: main loop: macros to mark GS and I/O functions Righ now, IO_CODE and IO_OR_GS_CODE are nop, as there isn't really a way to check that a function is only called in I/O. On the other side, we can use qemu_in_main_thread() to check if we are in the main loop. The usage of macros makes easy to extend them in the future without making changes in all callers. They will also visually help understanding in which category each function is, without looking at the header. Signed-off-by: Emanuele Giuseppe Esposito Message-Id: <20220303151616.325444-3-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- include/qemu/main-loop.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/qemu/main-loop.h') diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index bc42b5939d..7a4d6a0920 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -269,6 +269,24 @@ bool qemu_mutex_iothread_locked(void); */ bool qemu_in_main_thread(void); +/* Mark and check that the function is part of the global state API. */ +#define GLOBAL_STATE_CODE() \ + do { \ + assert(qemu_in_main_thread()); \ + } while (0) + +/* Mark and check that the function is part of the I/O API. */ +#define IO_CODE() \ + do { \ + /* nop */ \ + } while (0) + +/* Mark and check that the function is part of the "I/O OR GS" API. */ +#define IO_OR_GS_CODE() \ + do { \ + /* nop */ \ + } while (0) + /** * qemu_mutex_lock_iothread: Lock the main loop mutex. * -- cgit v1.2.3-55-g7522