|
|
0a122b |
From e0f594c3eac9fb0a89c76de3b77bce03c235b36e Mon Sep 17 00:00:00 2001
|
|
|
0a122b |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
0a122b |
Date: Tue, 3 Dec 2013 15:31:25 +0100
|
|
|
0a122b |
Subject: [PATCH 16/37] block: Switch BdrvTrackedRequest to byte granularity
|
|
|
0a122b |
|
|
|
0a122b |
Message-id: <1392117622-28812-17-git-send-email-kwolf@redhat.com>
|
|
|
0a122b |
Patchwork-id: 57181
|
|
|
0a122b |
O-Subject: [RHEL-7.0 qemu-kvm PATCH v2 16/37] block: Switch BdrvTrackedRequest to byte granularity
|
|
|
0a122b |
Bugzilla: 748906
|
|
|
0a122b |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
0a122b |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
0a122b |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
0a122b |
|
|
|
0a122b |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
0a122b |
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
|
|
0a122b |
Reviewed-by: Benoit Canet <benoit@irqsave.net>
|
|
|
0a122b |
(cherry picked from commit 793ed47a7a2b09b67cb2a8863dff531436532b5c)
|
|
|
0a122b |
|
|
|
0a122b |
Conflicts:
|
|
|
0a122b |
block/backup.c
|
|
|
0a122b |
include/block/block_int.h
|
|
|
0a122b |
|
|
|
0a122b |
Conflicts because in RHEL 7...
|
|
|
0a122b |
- ...block-backup doesn't exist
|
|
|
0a122b |
- ...BdrvTrackedRequest is in block.c rather than block_int.h
|
|
|
0a122b |
|
|
|
0a122b |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
0a122b |
---
|
|
|
0a122b |
block.c | 56 ++++++++++++++++++++++++++++++++++++--------------------
|
|
|
0a122b |
1 file changed, 36 insertions(+), 20 deletions(-)
|
|
|
0a122b |
---
|
|
|
0a122b |
block.c | 56 ++++++++++++++++++++++++++++++++++++--------------------
|
|
|
0a122b |
1 files changed, 36 insertions(+), 20 deletions(-)
|
|
|
0a122b |
|
|
|
0a122b |
diff --git a/block.c b/block.c
|
|
|
0a122b |
index 7b8131c..09bb127 100644
|
|
|
0a122b |
--- a/block.c
|
|
|
0a122b |
+++ b/block.c
|
|
|
0a122b |
@@ -2036,8 +2036,8 @@ int bdrv_commit_all(void)
|
|
|
0a122b |
|
|
|
0a122b |
struct BdrvTrackedRequest {
|
|
|
0a122b |
BlockDriverState *bs;
|
|
|
0a122b |
- int64_t sector_num;
|
|
|
0a122b |
- int nb_sectors;
|
|
|
0a122b |
+ int64_t offset;
|
|
|
0a122b |
+ unsigned int bytes;
|
|
|
0a122b |
bool is_write;
|
|
|
0a122b |
QLIST_ENTRY(BdrvTrackedRequest) list;
|
|
|
0a122b |
Coroutine *co; /* owner, used for deadlock detection */
|
|
|
0a122b |
@@ -2060,13 +2060,13 @@ static void tracked_request_end(BdrvTrackedRequest *req)
|
|
|
0a122b |
*/
|
|
|
0a122b |
static void tracked_request_begin(BdrvTrackedRequest *req,
|
|
|
0a122b |
BlockDriverState *bs,
|
|
|
0a122b |
- int64_t sector_num,
|
|
|
0a122b |
- int nb_sectors, bool is_write)
|
|
|
0a122b |
+ int64_t offset,
|
|
|
0a122b |
+ unsigned int bytes, bool is_write)
|
|
|
0a122b |
{
|
|
|
0a122b |
*req = (BdrvTrackedRequest){
|
|
|
0a122b |
.bs = bs,
|
|
|
0a122b |
- .sector_num = sector_num,
|
|
|
0a122b |
- .nb_sectors = nb_sectors,
|
|
|
0a122b |
+ .offset = offset,
|
|
|
0a122b |
+ .bytes = bytes,
|
|
|
0a122b |
.is_write = is_write,
|
|
|
0a122b |
.co = qemu_coroutine_self(),
|
|
|
0a122b |
};
|
|
|
0a122b |
@@ -2097,25 +2097,43 @@ void bdrv_round_to_clusters(BlockDriverState *bs,
|
|
|
0a122b |
}
|
|
|
0a122b |
}
|
|
|
0a122b |
|
|
|
0a122b |
+static void round_bytes_to_clusters(BlockDriverState *bs,
|
|
|
0a122b |
+ int64_t offset, unsigned int bytes,
|
|
|
0a122b |
+ int64_t *cluster_offset,
|
|
|
0a122b |
+ unsigned int *cluster_bytes)
|
|
|
0a122b |
+{
|
|
|
0a122b |
+ BlockDriverInfo bdi;
|
|
|
0a122b |
+
|
|
|
0a122b |
+ if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
|
|
|
0a122b |
+ *cluster_offset = offset;
|
|
|
0a122b |
+ *cluster_bytes = bytes;
|
|
|
0a122b |
+ } else {
|
|
|
0a122b |
+ *cluster_offset = QEMU_ALIGN_DOWN(offset, bdi.cluster_size);
|
|
|
0a122b |
+ *cluster_bytes = QEMU_ALIGN_UP(offset - *cluster_offset + bytes,
|
|
|
0a122b |
+ bdi.cluster_size);
|
|
|
0a122b |
+ }
|
|
|
0a122b |
+}
|
|
|
0a122b |
+
|
|
|
0a122b |
static bool tracked_request_overlaps(BdrvTrackedRequest *req,
|
|
|
0a122b |
- int64_t sector_num, int nb_sectors) {
|
|
|
0a122b |
+ int64_t offset, unsigned int bytes)
|
|
|
0a122b |
+{
|
|
|
0a122b |
/* aaaa bbbb */
|
|
|
0a122b |
- if (sector_num >= req->sector_num + req->nb_sectors) {
|
|
|
0a122b |
+ if (offset >= req->offset + req->bytes) {
|
|
|
0a122b |
return false;
|
|
|
0a122b |
}
|
|
|
0a122b |
/* bbbb aaaa */
|
|
|
0a122b |
- if (req->sector_num >= sector_num + nb_sectors) {
|
|
|
0a122b |
+ if (req->offset >= offset + bytes) {
|
|
|
0a122b |
return false;
|
|
|
0a122b |
}
|
|
|
0a122b |
return true;
|
|
|
0a122b |
}
|
|
|
0a122b |
|
|
|
0a122b |
static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
|
|
|
0a122b |
- int64_t sector_num, int nb_sectors)
|
|
|
0a122b |
+ int64_t offset, unsigned int bytes)
|
|
|
0a122b |
{
|
|
|
0a122b |
BdrvTrackedRequest *req;
|
|
|
0a122b |
- int64_t cluster_sector_num;
|
|
|
0a122b |
- int cluster_nb_sectors;
|
|
|
0a122b |
+ int64_t cluster_offset;
|
|
|
0a122b |
+ unsigned int cluster_bytes;
|
|
|
0a122b |
bool retry;
|
|
|
0a122b |
|
|
|
0a122b |
/* If we touch the same cluster it counts as an overlap. This guarantees
|
|
|
0a122b |
@@ -2124,14 +2142,12 @@ static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
|
|
|
0a122b |
* CoR read and write operations are atomic and guest writes cannot
|
|
|
0a122b |
* interleave between them.
|
|
|
0a122b |
*/
|
|
|
0a122b |
- bdrv_round_to_clusters(bs, sector_num, nb_sectors,
|
|
|
0a122b |
- &cluster_sector_num, &cluster_nb_sectors);
|
|
|
0a122b |
+ round_bytes_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);
|
|
|
0a122b |
|
|
|
0a122b |
do {
|
|
|
0a122b |
retry = false;
|
|
|
0a122b |
QLIST_FOREACH(req, &bs->tracked_requests, list) {
|
|
|
0a122b |
- if (tracked_request_overlaps(req, cluster_sector_num,
|
|
|
0a122b |
- cluster_nb_sectors)) {
|
|
|
0a122b |
+ if (tracked_request_overlaps(req, cluster_offset, cluster_bytes)) {
|
|
|
0a122b |
/* Hitting this means there was a reentrant request, for
|
|
|
0a122b |
* example, a block driver issuing nested requests. This must
|
|
|
0a122b |
* never happen since it means deadlock.
|
|
|
0a122b |
@@ -2746,10 +2762,10 @@ static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs,
|
|
|
0a122b |
}
|
|
|
0a122b |
|
|
|
0a122b |
if (bs->copy_on_read_in_flight) {
|
|
|
0a122b |
- wait_for_overlapping_requests(bs, sector_num, nb_sectors);
|
|
|
0a122b |
+ wait_for_overlapping_requests(bs, offset, bytes);
|
|
|
0a122b |
}
|
|
|
0a122b |
|
|
|
0a122b |
- tracked_request_begin(&req, bs, sector_num, nb_sectors, false);
|
|
|
0a122b |
+ tracked_request_begin(&req, bs, offset, bytes, false);
|
|
|
0a122b |
|
|
|
0a122b |
if (flags & BDRV_REQ_COPY_ON_READ) {
|
|
|
0a122b |
int pnum;
|
|
|
0a122b |
@@ -2998,10 +3014,10 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
|
|
|
0a122b |
assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
|
|
|
0a122b |
|
|
|
0a122b |
if (bs->copy_on_read_in_flight) {
|
|
|
0a122b |
- wait_for_overlapping_requests(bs, sector_num, nb_sectors);
|
|
|
0a122b |
+ wait_for_overlapping_requests(bs, offset, bytes);
|
|
|
0a122b |
}
|
|
|
0a122b |
|
|
|
0a122b |
- tracked_request_begin(&req, bs, sector_num, nb_sectors, true);
|
|
|
0a122b |
+ tracked_request_begin(&req, bs, offset, bytes, true);
|
|
|
0a122b |
|
|
|
0a122b |
if (flags & BDRV_REQ_ZERO_WRITE) {
|
|
|
0a122b |
ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors, flags);
|
|
|
0a122b |
--
|
|
|
0a122b |
1.7.1
|
|
|
0a122b |
|