1 From dc7588c1eb3008bda53dde1d6b890cd299758155 Mon Sep 17 00:00:00 2001
2 From: Josh Durgin <josh.durgin@inktank.com>
3 Date: Fri, 29 Mar 2013 13:03:23 -0700
4 Subject: [PATCH] rbd: add an asynchronous flush
6 The existing bdrv_co_flush_to_disk implementation uses rbd_flush(),
7 which is sychronous and causes the main qemu thread to block until it
8 is complete. This results in unresponsiveness and extra latency for
11 Fix this by using an asynchronous version of flush. This was added to
12 librbd with a special #define to indicate its presence, since it will
13 be backported to stable versions. Thus, there is no need to check the
16 Implement this as bdrv_aio_flush, since it matches other aio functions
17 in the rbd block driver, and leave out bdrv_co_flush_to_disk when the
18 asynchronous version is available.
20 Reported-by: Oliver Francke <oliver@filoo.de>
21 Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
22 Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24 block/rbd.c | 37 +++++++++++++++++++++++++++++++++----
25 1 files changed, 33 insertions(+), 4 deletions(-)
27 diff --git a/block/rbd.c b/block/rbd.c
28 index 1a8ea6d..141b488 100644
40 typedef struct RBDAIOCB {
41 @@ -379,8 +380,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
45 - if (acb->cmd == RBD_AIO_WRITE ||
46 - acb->cmd == RBD_AIO_DISCARD) {
47 + if (acb->cmd != RBD_AIO_READ) {
51 @@ -659,6 +659,16 @@ static int rbd_aio_discard_wrapper(rbd_image_t image,
55 +static int rbd_aio_flush_wrapper(rbd_image_t image,
56 + rbd_completion_t comp)
58 +#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
59 + return rbd_aio_flush(image, comp);
65 static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
68 @@ -679,7 +689,7 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
69 acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque);
72 - if (cmd == RBD_AIO_DISCARD) {
73 + if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
76 acb->bounce = qemu_blockalign(bs, qiov->size);
77 @@ -723,6 +733,9 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
79 r = rbd_aio_discard_wrapper(s->image, off, size, c);
82 + r = rbd_aio_flush_wrapper(s->image, c);
87 @@ -762,6 +775,16 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
91 +#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
92 +static BlockDriverAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs,
93 + BlockDriverCompletionFunc *cb,
96 + return rbd_start_aio(bs, 0, NULL, 0, cb, opaque, RBD_AIO_FLUSH);
101 static int qemu_rbd_co_flush(BlockDriverState *bs)
103 #if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
104 @@ -772,6 +795,7 @@ static int qemu_rbd_co_flush(BlockDriverState *bs)
110 static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
112 @@ -949,7 +973,12 @@ static BlockDriver bdrv_rbd = {
114 .bdrv_aio_readv = qemu_rbd_aio_readv,
115 .bdrv_aio_writev = qemu_rbd_aio_writev,
117 +#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
118 + .bdrv_aio_flush = qemu_rbd_aio_flush,
120 .bdrv_co_flush_to_disk = qemu_rbd_co_flush,
123 #ifdef LIBRBD_SUPPORTS_DISCARD
124 .bdrv_aio_discard = qemu_rbd_aio_discard,