99 lines
4.6 KiB
Diff
99 lines
4.6 KiB
Diff
|
From fc69df3a70bed5722643cc16828ca20beae3a20d Mon Sep 17 00:00:00 2001
|
||
|
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||
|
Date: Tue, 5 Dec 2023 13:20:08 -0500
|
||
|
Subject: [PATCH 091/101] docs: remove AioContext lock from IOThread docs
|
||
|
|
||
|
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||
|
RH-MergeRequest: 214: Remove AioContext lock
|
||
|
RH-Jira: RHEL-15965
|
||
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||
|
RH-Commit: [22/26] ab89cda483e74ded983d26e1c6e50217405e0a55 (kmwolf/centos-qemu-kvm)
|
||
|
|
||
|
Encourage the use of locking primitives and stop mentioning the
|
||
|
AioContext lock since it is being removed.
|
||
|
|
||
|
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||
|
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||
|
Message-ID: <20231205182011.1976568-12-stefanha@redhat.com>
|
||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
---
|
||
|
docs/devel/multiple-iothreads.txt | 47 +++++++++++--------------------
|
||
|
1 file changed, 16 insertions(+), 31 deletions(-)
|
||
|
|
||
|
diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt
|
||
|
index a3e949f6b3..4865196bde 100644
|
||
|
--- a/docs/devel/multiple-iothreads.txt
|
||
|
+++ b/docs/devel/multiple-iothreads.txt
|
||
|
@@ -88,27 +88,18 @@ loop, depending on which AioContext instance the caller passes in.
|
||
|
|
||
|
How to synchronize with an IOThread
|
||
|
-----------------------------------
|
||
|
-AioContext is not thread-safe so some rules must be followed when using file
|
||
|
-descriptors, event notifiers, timers, or BHs across threads:
|
||
|
+Variables that can be accessed by multiple threads require some form of
|
||
|
+synchronization such as qemu_mutex_lock(), rcu_read_lock(), etc.
|
||
|
|
||
|
-1. AioContext functions can always be called safely. They handle their
|
||
|
-own locking internally.
|
||
|
-
|
||
|
-2. Other threads wishing to access the AioContext must use
|
||
|
-aio_context_acquire()/aio_context_release() for mutual exclusion. Once the
|
||
|
-context is acquired no other thread can access it or run event loop iterations
|
||
|
-in this AioContext.
|
||
|
-
|
||
|
-Legacy code sometimes nests aio_context_acquire()/aio_context_release() calls.
|
||
|
-Do not use nesting anymore, it is incompatible with the BDRV_POLL_WHILE() macro
|
||
|
-used in the block layer and can lead to hangs.
|
||
|
-
|
||
|
-There is currently no lock ordering rule if a thread needs to acquire multiple
|
||
|
-AioContexts simultaneously. Therefore, it is only safe for code holding the
|
||
|
-QEMU global mutex to acquire other AioContexts.
|
||
|
+AioContext functions like aio_set_fd_handler(), aio_set_event_notifier(),
|
||
|
+aio_bh_new(), and aio_timer_new() are thread-safe. They can be used to trigger
|
||
|
+activity in an IOThread.
|
||
|
|
||
|
Side note: the best way to schedule a function call across threads is to call
|
||
|
-aio_bh_schedule_oneshot(). No acquire/release or locking is needed.
|
||
|
+aio_bh_schedule_oneshot().
|
||
|
+
|
||
|
+The main loop thread can wait synchronously for a condition using
|
||
|
+AIO_WAIT_WHILE().
|
||
|
|
||
|
AioContext and the block layer
|
||
|
------------------------------
|
||
|
@@ -124,22 +115,16 @@ Block layer code must therefore expect to run in an IOThread and avoid using
|
||
|
old APIs that implicitly use the main loop. See the "How to program for
|
||
|
IOThreads" above for information on how to do that.
|
||
|
|
||
|
-If main loop code such as a QMP function wishes to access a BlockDriverState
|
||
|
-it must first call aio_context_acquire(bdrv_get_aio_context(bs)) to ensure
|
||
|
-that callbacks in the IOThread do not run in parallel.
|
||
|
-
|
||
|
Code running in the monitor typically needs to ensure that past
|
||
|
requests from the guest are completed. When a block device is running
|
||
|
in an IOThread, the IOThread can also process requests from the guest
|
||
|
(via ioeventfd). To achieve both objects, wrap the code between
|
||
|
bdrv_drained_begin() and bdrv_drained_end(), thus creating a "drained
|
||
|
-section". The functions must be called between aio_context_acquire()
|
||
|
-and aio_context_release(). You can freely release and re-acquire the
|
||
|
-AioContext within a drained section.
|
||
|
-
|
||
|
-Long-running jobs (usually in the form of coroutines) are best scheduled in
|
||
|
-the BlockDriverState's AioContext to avoid the need to acquire/release around
|
||
|
-each bdrv_*() call. The functions bdrv_add/remove_aio_context_notifier,
|
||
|
-or alternatively blk_add/remove_aio_context_notifier if you use BlockBackends,
|
||
|
-can be used to get a notification whenever bdrv_try_change_aio_context() moves a
|
||
|
+section".
|
||
|
+
|
||
|
+Long-running jobs (usually in the form of coroutines) are often scheduled in
|
||
|
+the BlockDriverState's AioContext. The functions
|
||
|
+bdrv_add/remove_aio_context_notifier, or alternatively
|
||
|
+blk_add/remove_aio_context_notifier if you use BlockBackends, can be used to
|
||
|
+get a notification whenever bdrv_try_change_aio_context() moves a
|
||
|
BlockDriverState to a different AioContext.
|
||
|
--
|
||
|
2.39.3
|
||
|
|