[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 14/19] block: Generalise and optimise COR serial
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [RFC PATCH 14/19] block: Generalise and optimise COR serialisation |
Date: |
Fri, 6 Dec 2013 18:22:55 +0100 |
Change the API so that specific requests can be marked serialising. Only
these requests are checked for overlaps then.
This means that during a Copy on Read operation, not all requests
overlapping other requests are serialised any more, but only those that
actually overlap with the specific COR request.
Also remove COR from function and variable names because this
functionality can be useful in other contexts.
Signed-off-by: Kevin Wolf <address@hidden>
---
block.c | 40 +++++++++++++++++++++++++---------------
include/block/block_int.h | 5 +++--
2 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/block.c b/block.c
index 0b1f08a..53c19a8 100644
--- a/block.c
+++ b/block.c
@@ -2005,6 +2005,10 @@ int bdrv_commit_all(void)
*/
static void tracked_request_end(BdrvTrackedRequest *req)
{
+ if (req->serialising) {
+ req->bs->serialising_in_flight--;
+ }
+
QLIST_REMOVE(req, list);
qemu_co_queue_restart_all(&req->wait_queue);
}
@@ -2023,6 +2027,7 @@ static void tracked_request_begin(BdrvTrackedRequest *req,
.bytes = bytes,
.is_write = is_write,
.co = qemu_coroutine_self(),
+ .serialising = false,
};
qemu_co_queue_init(&req->wait_queue);
@@ -2030,6 +2035,14 @@ static void tracked_request_begin(BdrvTrackedRequest
*req,
QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
}
+static void mark_request_serialising(BdrvTrackedRequest *req)
+{
+ if (!req->serialising) {
+ req->bs->serialising_in_flight++;
+ req->serialising = true;
+ }
+}
+
/**
* Round a region to cluster boundaries
*/
@@ -2082,26 +2095,31 @@ static bool tracked_request_overlaps(BdrvTrackedRequest
*req,
return true;
}
-static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
- BdrvTrackedRequest *self, int64_t offset, unsigned int bytes)
+static void coroutine_fn wait_serialising_requests(BdrvTrackedRequest *self)
{
+ BlockDriverState *bs = self->bs;
BdrvTrackedRequest *req;
int64_t cluster_offset;
unsigned int cluster_bytes;
bool retry;
+ if (!bs->serialising_in_flight) {
+ return;
+ }
+
/* If we touch the same cluster it counts as an overlap. This guarantees
* that allocating writes will be serialized and not race with each other
* for the same cluster. For example, in copy-on-read it ensures that the
* CoR read and write operations are atomic and guest writes cannot
* interleave between them.
*/
- round_bytes_to_clusters(bs, offset, bytes, &cluster_offset,
&cluster_bytes);
+ round_bytes_to_clusters(bs, self->offset, self->bytes,
+ &cluster_offset, &cluster_bytes);
do {
retry = false;
QLIST_FOREACH(req, &bs->tracked_requests, list) {
- if (req == self) {
+ if (req == self || (!req->serialising && !self->serialising)) {
continue;
}
if (tracked_request_overlaps(req, cluster_offset, cluster_bytes)) {
@@ -2676,12 +2694,10 @@ static int coroutine_fn
bdrv_aligned_preadv(BlockDriverState *bs,
/* Handle Copy on Read and associated serialisation */
if (flags & BDRV_REQ_COPY_ON_READ) {
- bs->copy_on_read_in_flight++;
+ mark_request_serialising(req);
}
- if (bs->copy_on_read_in_flight) {
- wait_for_overlapping_requests(bs, req, offset, bytes);
- }
+ wait_serialising_requests(req);
if (flags & BDRV_REQ_COPY_ON_READ) {
int pnum;
@@ -2729,10 +2745,6 @@ static int coroutine_fn
bdrv_aligned_preadv(BlockDriverState *bs,
}
out:
- if (flags & BDRV_REQ_COPY_ON_READ) {
- bs->copy_on_read_in_flight--;
- }
-
return ret;
}
@@ -2886,9 +2898,7 @@ static int coroutine_fn
bdrv_aligned_pwritev(BlockDriverState *bs,
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
- if (bs->copy_on_read_in_flight) {
- wait_for_overlapping_requests(bs, req, offset, bytes);
- }
+ wait_serialising_requests(req);
ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index ec4f121..6ba058a 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -59,6 +59,7 @@ typedef struct BdrvTrackedRequest {
int64_t offset;
unsigned int bytes;
bool is_write;
+ bool serialising;
QLIST_ENTRY(BdrvTrackedRequest) list;
Coroutine *co; /* owner, used for deadlock detection */
CoQueue wait_queue; /* coroutines blocked on this request */
@@ -273,8 +274,8 @@ struct BlockDriverState {
/* Callback before write request is processed */
NotifierWithReturnList before_write_notifiers;
- /* number of in-flight copy-on-read requests */
- unsigned int copy_on_read_in_flight;
+ /* number of in-flight serialising requests */
+ unsigned int serialising_in_flight;
/* I/O throttling */
ThrottleState throttle_state;
--
1.8.1.4
- Re: [Qemu-devel] [RFC PATCH 05/19] raw: Probe required direct I/O alignment, (continued)
- [Qemu-devel] [RFC PATCH 06/19] block: Introduce bdrv_aligned_preadv(), Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 07/19] block: Introduce bdrv_co_do_preadv(), Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 08/19] block: Introduce bdrv_aligned_pwritev(), Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 09/19] block: write: Handle COR dependency after I/O throttling, Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 10/19] block: Introduce bdrv_co_do_pwritev(), Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 11/19] block: Switch BdrvTrackedRequest to byte granularity, Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 12/19] block: Allow waiting for overlapping requests between begin/end, Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 13/19] block: Make zero-after-EOF work with larger alignment, Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 14/19] block: Generalise and optimise COR serialisation,
Kevin Wolf <=
- [Qemu-devel] [RFC PATCH 15/19] block: Make overlap range for serialisation dynamic, Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 16/19] block: Align requests in bdrv_co_do_pwritev(), Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 17/19] block: Change coroutine wrapper to byte granularity, Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 18/19] block: Make bdrv_pread() a bdrv_prwv_co() wrapper, Kevin Wolf, 2013/12/06
- [Qemu-devel] [RFC PATCH 19/19] block: Make bdrv_pwrite() a bdrv_prwv_co() wrapper, Kevin Wolf, 2013/12/06
- Re: [Qemu-devel] [RFC PATCH 00/19] block: Support for 512b-on-4k emulation, Paolo Bonzini, 2013/12/06
- Re: [Qemu-devel] [RFC PATCH 00/19] block: Support for 512b-on-4k emulation, Stefan Hajnoczi, 2013/12/09