docs: remove AioContext lock from IOThread docs
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>
This commit is contained in:
parent
9f8d2fdcce
commit
e0444c276a
@ -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.
|
||||
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
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user