[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 06/15] qed: avoid deadlock on emulated synchronous I
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PATCH 06/15] qed: avoid deadlock on emulated synchronous I/O |
Date: |
Wed, 27 Jul 2011 14:44:46 +0100 |
The block layer emulates synchronous bdrv_read()/bdrv_write() for
drivers that only provide the asynchronous interfaces. The emulation
issues an asynchronous request inside a new "async context" and waits
for that request to complete. If currently outstanding requests
complete during this time, their completion functions are not invoked
until the async context is popped again.
This can lead to deadlock if an allocating write is being processed when
synchronous I/O emulation starts. The emulated synchronous write will
be queued because an existing request is being processed. But the
existing request on cannot complete until the async context is popped.
The result is that qemu_aio_wait() sits in a deadlock.
Address this problem in two ways:
1. Add an assertion so that we instantly know if this corner case is
hit. This saves us time by giving a clear failure indication.
2. Ignore the copy-on-read hint for emulated synchronous reads. This
allows us to do emulated synchronous reads without hitting the
deadlock.
Keep this as a separate commit instead of merging with previous QED
patches so it is easy to drop when coroutines are introduced and
eliminate async contexts.
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/qed.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/block/qed.c b/block/qed.c
index 6ca57f2..ffdbc2d 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1120,6 +1120,14 @@ static bool qed_start_allocating_write(QEDAIOCB *acb)
}
if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) ||
s->allocating_write_reqs_plugged) {
+ /* Queuing an emulated synchronous write causes deadlock since
+ * currently outstanding requests are not in the current async context
+ * and their completion will never be invoked. Once the block layer
+ * moves to truly asynchronous semantics this failure case will be
+ * eliminated.
+ */
+ assert(get_async_context_id() == 0);
+
return false;
}
return true;
@@ -1246,7 +1254,9 @@ static void qed_aio_read_data(void *opaque, int ret,
} else if (ret != QED_CLUSTER_FOUND) {
BlockDriverCompletionFunc *cb = qed_aio_next_io;
- if (bs->backing_hd && (acb->flags & QED_AIOCB_COPY_ON_READ)) {
+ /* See qed_start_allocating_write() for get_async_context_id() hack */
+ if (bs->backing_hd && (acb->flags & QED_AIOCB_COPY_ON_READ) &&
+ get_async_context_id() == 0) {
if (!qed_start_allocating_write(acb)) {
qemu_iovec_reset(&acb->cur_qiov);
return; /* wait for current allocating write to complete */
--
1.7.5.4
- [Qemu-devel] [RFC v2 00/15] QED image streaming, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 05/15] qed: add support for copy-on-read, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 03/15] qed: extract qed_start_allocating_write(), Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 10/15] qmp: add query-block-jobs command, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 09/15] qmp: add block_job_cancel command, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 06/15] qed: avoid deadlock on emulated synchronous I/O,
Stefan Hajnoczi <=
- [Qemu-devel] [PATCH 02/15] qed: replace is_write with flags field, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 04/15] qed: make qed_aio_write_alloc() reusable, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 11/15] qmp: add block_job_set_speed command, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 07/15] block: add bdrv_aio_copy_backing(), Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 08/15] qmp: add block_stream command, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 01/15] block: add -drive copy-on-read=on|off, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 13/15] qed: intelligent streaming implementation, Stefan Hajnoczi, 2011/07/27
- [Qemu-devel] [PATCH 12/15] block: add -drive stream=on|off, Stefan Hajnoczi, 2011/07/27