[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 49/61] qed: Implement .bdrv_co_readv/writev
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PULL 49/61] qed: Implement .bdrv_co_readv/writev |
Date: |
Fri, 23 Jun 2017 18:21:47 +0200 |
Most of the qed code is now synchronous and matches the coroutine model.
One notable exception is the serialisation between requests which can
still schedule a callback. Before we can replace this with coroutine
locks, let's convert the driver's external interfaces to the coroutine
versions.
We need to be careful to handle both requests that call the completion
callback directly from the calling coroutine (i.e. fully synchronous
code) and requests that involve some callback, so that we need to yield
and wait for the completion callback coming from outside the coroutine.
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Manos Pitsidianakis <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
---
block/qed.c | 97 ++++++++++++++++++++++++++-----------------------------------
1 file changed, 42 insertions(+), 55 deletions(-)
diff --git a/block/qed.c b/block/qed.c
index e762169..a5111fd 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1322,16 +1322,32 @@ static void qed_aio_next_io(QEDAIOCB *acb)
}
}
-static BlockAIOCB *qed_aio_setup(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockCompletionFunc *cb,
- void *opaque, int flags)
+typedef struct QEDRequestCo {
+ Coroutine *co;
+ bool done;
+ int ret;
+} QEDRequestCo;
+
+static void qed_co_request_cb(void *opaque, int ret)
{
- QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, cb, opaque);
+ QEDRequestCo *co = opaque;
- trace_qed_aio_setup(bs->opaque, acb, sector_num, nb_sectors,
- opaque, flags);
+ co->done = true;
+ co->ret = ret;
+ qemu_coroutine_enter_if_inactive(co->co);
+}
+
+static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t
sector_num,
+ QEMUIOVector *qiov, int nb_sectors,
+ int flags)
+{
+ QEDRequestCo co = {
+ .co = qemu_coroutine_self(),
+ .done = false,
+ };
+ QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, qed_co_request_cb, &co);
+
+ trace_qed_aio_setup(bs->opaque, acb, sector_num, nb_sectors, &co, flags);
acb->flags = flags;
acb->qiov = qiov;
@@ -1344,43 +1360,26 @@ static BlockAIOCB *qed_aio_setup(BlockDriverState *bs,
/* Start request */
qed_aio_start_io(acb);
- return &acb->common;
-}
-static BlockAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockCompletionFunc *cb,
- void *opaque)
-{
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
+ if (!co.done) {
+ qemu_coroutine_yield();
+ }
+
+ return co.ret;
}
-static BlockAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockCompletionFunc *cb,
- void *opaque)
+static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ QEMUIOVector *qiov)
{
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb,
- opaque, QED_AIOCB_WRITE);
+ return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
}
-typedef struct {
- Coroutine *co;
- int ret;
- bool done;
-} QEDWriteZeroesCB;
-
-static void coroutine_fn qed_co_pwrite_zeroes_cb(void *opaque, int ret)
+static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ QEMUIOVector *qiov)
{
- QEDWriteZeroesCB *cb = opaque;
-
- cb->done = true;
- cb->ret = ret;
- if (cb->co) {
- aio_co_wake(cb->co);
- }
+ return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
}
static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
@@ -1388,9 +1387,7 @@ static int coroutine_fn
bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
int count,
BdrvRequestFlags flags)
{
- BlockAIOCB *blockacb;
BDRVQEDState *s = bs->opaque;
- QEDWriteZeroesCB cb = { .done = false };
QEMUIOVector qiov;
struct iovec iov;
@@ -1407,19 +1404,9 @@ static int coroutine_fn
bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
iov.iov_len = count;
qemu_iovec_init_external(&qiov, &iov, 1);
- blockacb = qed_aio_setup(bs, offset >> BDRV_SECTOR_BITS, &qiov,
- count >> BDRV_SECTOR_BITS,
- qed_co_pwrite_zeroes_cb, &cb,
- QED_AIOCB_WRITE | QED_AIOCB_ZERO);
- if (!blockacb) {
- return -EIO;
- }
- if (!cb.done) {
- cb.co = qemu_coroutine_self();
- qemu_coroutine_yield();
- }
- assert(cb.done);
- return cb.ret;
+ return qed_co_request(bs, offset >> BDRV_SECTOR_BITS, &qiov,
+ count >> BDRV_SECTOR_BITS,
+ QED_AIOCB_WRITE | QED_AIOCB_ZERO);
}
static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error
**errp)
@@ -1615,8 +1602,8 @@ static BlockDriver bdrv_qed = {
.bdrv_create = bdrv_qed_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_co_get_block_status = bdrv_qed_co_get_block_status,
- .bdrv_aio_readv = bdrv_qed_aio_readv,
- .bdrv_aio_writev = bdrv_qed_aio_writev,
+ .bdrv_co_readv = bdrv_qed_co_readv,
+ .bdrv_co_writev = bdrv_qed_co_writev,
.bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes,
.bdrv_truncate = bdrv_qed_truncate,
.bdrv_getlength = bdrv_qed_getlength,
--
1.8.3.1
- [Qemu-devel] [PULL 37/61] qed: Remove callback from qed_write_table(), (continued)
- [Qemu-devel] [PULL 37/61] qed: Remove callback from qed_write_table(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 43/61] qed: Add return value to qed_aio_write_main(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 45/61] qed: Add return value to qed_aio_write_inplace/alloc(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 47/61] qed: Remove ret argument from qed_aio_next_io(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 48/61] qed: Remove recursion in qed_aio_next_io(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 46/61] qed: Add return value to qed_aio_read/write_data(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 39/61] qed: Make qed_aio_write_main() synchronous, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 42/61] qed: Add return value to qed_aio_write_l2_update(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 44/61] qed: Add return value to qed_aio_write_cow(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 50/61] qed: Use CoQueue for serialising allocations, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 49/61] qed: Implement .bdrv_co_readv/writev,
Kevin Wolf <=
- [Qemu-devel] [PULL 51/61] qed: Simplify request handling, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 52/61] qed: Use a coroutine for need_check_timer, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 54/61] qed: Use bdrv_co_* for coroutine_fns, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 53/61] qed: Add coroutine_fn to I/O path functions, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 57/61] fix: avoid an infinite loop or a dangling pointer problem in img_commit, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 55/61] block: Remove bdrv_aio_readv/writev/flush(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 58/61] blkdebug: Catch bs->exact_filename overflow, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 61/61] qemu-img: don't shadow opts variable in img_dd(), Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 59/61] blkverify: Catch bs->exact_filename overflow, Kevin Wolf, 2017/06/23
- [Qemu-devel] [PULL 60/61] block: Do not strcmp() with NULL uri->scheme, Kevin Wolf, 2017/06/23