[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 03/25] block: protect BlockBackend->queued_requests with a lock
From: |
Kevin Wolf |
Subject: |
[PULL 03/25] block: protect BlockBackend->queued_requests with a lock |
Date: |
Tue, 25 Apr 2023 15:13:37 +0200 |
From: Stefan Hajnoczi <stefanha@redhat.com>
The CoQueue API offers thread-safety via the lock argument that
qemu_co_queue_wait() and qemu_co_enter_next() take. BlockBackend
currently does not make use of the lock argument. This means that
multiple threads submitting I/O requests can corrupt the CoQueue's
QSIMPLEQ.
Add a QemuMutex and pass it to CoQueue APIs so that the queue is
protected. While we're at it, also assert that the queue is empty when
the BlockBackend is deleted.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230307210427.269214-4-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 8552b6dfd0..47e006c645 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -81,6 +81,7 @@ struct BlockBackend {
QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers;
int quiesce_counter; /* atomic: written under BQL, read by other threads */
+ QemuMutex queued_requests_lock; /* protects queued_requests */
CoQueue queued_requests;
bool disable_request_queuing; /* atomic */
@@ -368,6 +369,7 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm,
uint64_t shared_perm)
block_acct_init(&blk->stats);
+ qemu_mutex_init(&blk->queued_requests_lock);
qemu_co_queue_init(&blk->queued_requests);
notifier_list_init(&blk->remove_bs_notifiers);
notifier_list_init(&blk->insert_bs_notifiers);
@@ -485,6 +487,8 @@ static void blk_delete(BlockBackend *blk)
assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers));
assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers));
assert(QLIST_EMPTY(&blk->aio_notifiers));
+ assert(qemu_co_queue_empty(&blk->queued_requests));
+ qemu_mutex_destroy(&blk->queued_requests_lock);
QTAILQ_REMOVE(&block_backends, blk, link);
drive_info_del(blk->legacy_dinfo);
block_acct_cleanup(&blk->stats);
@@ -1273,9 +1277,16 @@ static void coroutine_fn
blk_wait_while_drained(BlockBackend *blk)
if (qatomic_read(&blk->quiesce_counter) &&
!qatomic_read(&blk->disable_request_queuing)) {
+ /*
+ * Take lock before decrementing in flight counter so main loop thread
+ * waits for us to enqueue ourselves before it can leave the drained
+ * section.
+ */
+ qemu_mutex_lock(&blk->queued_requests_lock);
blk_dec_in_flight(blk);
- qemu_co_queue_wait(&blk->queued_requests, NULL);
+ qemu_co_queue_wait(&blk->queued_requests, &blk->queued_requests_lock);
blk_inc_in_flight(blk);
+ qemu_mutex_unlock(&blk->queued_requests_lock);
}
}
@@ -2634,9 +2645,12 @@ static void blk_root_drained_end(BdrvChild *child)
if (blk->dev_ops && blk->dev_ops->drained_end) {
blk->dev_ops->drained_end(blk->dev_opaque);
}
- while (qemu_co_enter_next(&blk->queued_requests, NULL)) {
+ qemu_mutex_lock(&blk->queued_requests_lock);
+ while (qemu_co_enter_next(&blk->queued_requests,
+ &blk->queued_requests_lock)) {
/* Resume all queued requests */
}
+ qemu_mutex_unlock(&blk->queued_requests_lock);
}
}
--
2.40.0
- [PULL 00/25] Block layer patches, Kevin Wolf, 2023/04/25
- [PULL 01/25] block: make BlockBackend->quiesce_counter atomic, Kevin Wolf, 2023/04/25
- [PULL 03/25] block: protect BlockBackend->queued_requests with a lock,
Kevin Wolf <=
- [PULL 04/25] block: don't acquire AioContext lock in bdrv_drain_all(), Kevin Wolf, 2023/04/25
- [PULL 08/25] hmp: convert handle_hmp_command() to AIO_WAIT_WHILE_UNLOCKED(), Kevin Wolf, 2023/04/25
- [PULL 09/25] monitor: convert monitor_cleanup() to AIO_WAIT_WHILE_UNLOCKED(), Kevin Wolf, 2023/04/25
- [PULL 02/25] block: make BlockBackend->disable_request_queuing atomic, Kevin Wolf, 2023/04/25
- [PULL 06/25] block: convert bdrv_graph_wrlock() to AIO_WAIT_WHILE_UNLOCKED(), Kevin Wolf, 2023/04/25
- [PULL 10/25] include/block: fixup typos, Kevin Wolf, 2023/04/25
- [PULL 07/25] block: convert bdrv_drain_all_begin() to AIO_WAIT_WHILE_UNLOCKED(), Kevin Wolf, 2023/04/25
- [PULL 11/25] block: add missing coroutine_fn to bdrv_sum_allocated_file_size(), Kevin Wolf, 2023/04/25
- [PULL 22/25] tests: mark more coroutine_fns, Kevin Wolf, 2023/04/25
- [PULL 15/25] thread-pool: avoid passing the pool parameter every time, Kevin Wolf, 2023/04/25