From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
Anthony Liguori <aliguori@us.ibm.com>,
Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>,
Adam Litke <agl@us.ibm.com>
Subject: [Qemu-devel] [PATCH 05/15] qed: add support for copy-on-read
Date: Wed, 27 Jul 2011 14:44:45 +0100 [thread overview]
Message-ID: <1311774295-8696-6-git-send-email-stefanha@linux.vnet.ibm.com> (raw)
In-Reply-To: <1311774295-8696-1-git-send-email-stefanha@linux.vnet.ibm.com>
From: Anthony Liguori <aliguori@us.ibm.com>
This patch implements copy-on-read in QED. Once a read request reaches
the copy-on-read state it adds itself to the allocating write queue in
order to avoid race conditions with write requests.
If an allocating write request manages to sneak in before the
copy-on-read request, then the copy-on-read will notice that the cluster
has been allocated when qed_find_cluster() is re-run. This works
because only one allocating request is active at any time and when the
next request is activated it will re-run qed_find_cluster().
[Originally by Anthony. Stefan added allocating write queuing and
factored out the QED_CF_COPY_ON_READ header flag.]
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
block/qed.c | 35 +++++++++++++++++++++++++++++++++--
block/qed.h | 3 ++-
trace-events | 1 +
3 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/block/qed.c b/block/qed.c
index 4f535aa..6ca57f2 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1189,6 +1189,25 @@ static void qed_aio_write_data(void *opaque, int ret,
}
/**
+ * Copy on read callback
+ *
+ * Write data from backing file to QED that's been read if CoR is enabled.
+ */
+static void qed_copy_on_read_cb(void *opaque, int ret)
+{
+ QEDAIOCB *acb = opaque;
+
+ trace_qed_copy_on_read_cb(acb, ret);
+
+ if (ret < 0) {
+ qed_aio_complete(acb, ret);
+ return;
+ }
+
+ qed_aio_write_alloc(acb);
+}
+
+/**
* Read data cluster
*
* @opaque: Read request
@@ -1216,6 +1235,7 @@ static void qed_aio_read_data(void *opaque, int ret,
goto err;
}
+ acb->find_cluster_ret = ret;
qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
/* Handle zero cluster and backing file reads */
@@ -1224,8 +1244,17 @@ static void qed_aio_read_data(void *opaque, int ret,
qed_aio_next_io(acb, 0);
return;
} else if (ret != QED_CLUSTER_FOUND) {
+ BlockDriverCompletionFunc *cb = qed_aio_next_io;
+
+ if (bs->backing_hd && (acb->flags & QED_AIOCB_COPY_ON_READ)) {
+ if (!qed_start_allocating_write(acb)) {
+ qemu_iovec_reset(&acb->cur_qiov);
+ return; /* wait for current allocating write to complete */
+ }
+ cb = qed_copy_on_read_cb;
+ }
qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,
- qed_aio_next_io, acb);
+ cb, acb);
return;
}
@@ -1309,7 +1338,9 @@ static BlockDriverAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs,
BlockDriverCompletionFunc *cb,
void *opaque)
{
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
+ int flags = bs->copy_on_read ? QED_AIOCB_COPY_ON_READ : 0;
+
+ return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, flags);
}
static BlockDriverAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
diff --git a/block/qed.h b/block/qed.h
index dbc00be..16f4bd9 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -124,7 +124,8 @@ typedef struct QEDRequest {
} QEDRequest;
enum {
- QED_AIOCB_WRITE = 0x0001, /* read or write? */
+ QED_AIOCB_WRITE = 0x0001, /* read or write? */
+ QED_AIOCB_COPY_ON_READ = 0x0002,
};
typedef struct QEDAIOCB {
diff --git a/trace-events b/trace-events
index 73a8592..2c7c6dc 100644
--- a/trace-events
+++ b/trace-events
@@ -271,6 +271,7 @@ disable qed_aio_complete(void *s, void *acb, int ret) "s %p acb %p ret %d"
disable qed_aio_setup(void *s, void *acb, int64_t sector_num, int nb_sectors, void *opaque, int flags) "s %p acb %p sector_num %"PRId64" nb_sectors %d opaque %p flags %#x"
disable qed_aio_next_io(void *s, void *acb, int ret, uint64_t cur_pos) "s %p acb %p ret %d cur_pos %"PRIu64""
disable qed_aio_read_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+disable qed_copy_on_read_cb(void *acb, int ret) "acb %p ret %d"
disable qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
disable qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
disable qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
--
1.7.5.4
next prev parent reply other threads:[~2011-07-27 13:45 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-27 13:44 [Qemu-devel] [RFC v2 00/15] QED image streaming Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 01/15] block: add -drive copy-on-read=on|off Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 02/15] qed: replace is_write with flags field Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 03/15] qed: extract qed_start_allocating_write() Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 04/15] qed: make qed_aio_write_alloc() reusable Stefan Hajnoczi
2011-07-27 13:44 ` Stefan Hajnoczi [this message]
2011-07-27 13:44 ` [Qemu-devel] [PATCH 06/15] qed: avoid deadlock on emulated synchronous I/O Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 07/15] block: add bdrv_aio_copy_backing() Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 08/15] qmp: add block_stream command Stefan Hajnoczi
2011-07-28 15:53 ` Marcelo Tosatti
2011-07-28 15:57 ` Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 09/15] qmp: add block_job_cancel command Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 10/15] qmp: add query-block-jobs command Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 11/15] qmp: add block_job_set_speed command Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 12/15] block: add -drive stream=on|off Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 13/15] qed: intelligent streaming implementation Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 14/15] trace: trace bdrv_aio_readv/writev error paths Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 15/15] tests: add image streaming QMP interface tests Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1311774295-8696-6-git-send-email-stefanha@linux.vnet.ibm.com \
--to=stefanha@linux.vnet.ibm.com \
--cc=agl@us.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).