Blame SOURCES/kvm-block-Don-t-use-guest-sector-size-for-qemu_blockalig.patch

0a122b
From 8603c409443521f98a73652ebf30233da879c7de Mon Sep 17 00:00:00 2001
0a122b
From: Kevin Wolf <kwolf@redhat.com>
0a122b
Date: Thu, 28 Nov 2013 10:23:32 +0100
0a122b
Subject: [PATCH 08/37] block: Don't use guest sector size for qemu_blockalign()
0a122b
0a122b
Message-id: <1392117622-28812-9-git-send-email-kwolf@redhat.com>
0a122b
Patchwork-id: 57173
0a122b
O-Subject: [RHEL-7.0 qemu-kvm PATCH v2 08/37] block: Don't use guest sector size for qemu_blockalign()
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
bs->buffer_alignment is set by the device emulation and contains the
0a122b
logical block size of the guest device. This isn't something that the
0a122b
block layer should know, and even less something to use for determining
0a122b
the right alignment of buffers to be used for the host.
0a122b
0a122b
The new BlockLimits field opt_mem_alignment tells the qemu block layer
0a122b
the optimal alignment to be used so that no bounce buffer must be used
0a122b
in the driver.
0a122b
0a122b
This patch may change the buffer alignment from 4k to 512 for all
0a122b
callers that used qemu_blockalign() with the top-level image format
0a122b
BlockDriverState. The value was never propagated to other levels in the
0a122b
tree, so in particular raw-posix never required anything else than 512.
0a122b
0a122b
While on disks with 4k sectors direct I/O requires a 4k alignment,
0a122b
memory may still be okay when aligned to 512 byte boundaries. This is
0a122b
what must have happened in practice, because otherwise this would
0a122b
already have failed earlier. Therefore I don't expect regressions even
0a122b
with this intermediate state. Later, raw-posix can implement the hook
0a122b
and expose a different memory alignment requirement.
0a122b
0a122b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
0a122b
Reviewed-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
0a122b
Reviewed-by: Max Reitz <mreitz@redhat.com>
0a122b
(cherry picked from commit 339064d5063924e5176842abbf6c8089f3479c5b)
0a122b
0a122b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
0a122b
---
0a122b
 block.c                   | 23 ++++++++++++++++++++---
0a122b
 include/block/block.h     |  3 +++
0a122b
 include/block/block_int.h |  3 +++
0a122b
 3 files changed, 26 insertions(+), 3 deletions(-)
0a122b
---
0a122b
 block.c                   |   23 ++++++++++++++++++++---
0a122b
 include/block/block.h     |    3 +++
0a122b
 include/block/block_int.h |    3 +++
0a122b
 3 files changed, 26 insertions(+), 3 deletions(-)
0a122b
0a122b
diff --git a/block.c b/block.c
0a122b
index 6c98ff7..c85f43e 100644
0a122b
--- a/block.c
0a122b
+++ b/block.c
0a122b
@@ -185,6 +185,16 @@ static void bdrv_io_limits_intercept(BlockDriverState *bs,
0a122b
     qemu_co_queue_next(&bs->throttled_reqs);
0a122b
 }
0a122b
 
0a122b
+size_t bdrv_opt_mem_align(BlockDriverState *bs)
0a122b
+{
0a122b
+    if (!bs || !bs->drv) {
0a122b
+        /* 4k should be on the safe side */
0a122b
+        return 4096;
0a122b
+    }
0a122b
+
0a122b
+    return bs->bl.opt_mem_alignment;
0a122b
+}
0a122b
+
0a122b
 /* check if the path starts with "<protocol>:" */
0a122b
 static int path_has_protocol(const char *path)
0a122b
 {
0a122b
@@ -460,6 +470,9 @@ int bdrv_refresh_limits(BlockDriverState *bs)
0a122b
     if (bs->file) {
0a122b
         bdrv_refresh_limits(bs->file);
0a122b
         bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
0a122b
+        bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
0a122b
+    } else {
0a122b
+        bs->bl.opt_mem_alignment = 512;
0a122b
     }
0a122b
 
0a122b
     if (bs->backing_hd) {
0a122b
@@ -467,6 +480,9 @@ int bdrv_refresh_limits(BlockDriverState *bs)
0a122b
         bs->bl.opt_transfer_length =
0a122b
             MAX(bs->bl.opt_transfer_length,
0a122b
                 bs->backing_hd->bl.opt_transfer_length);
0a122b
+        bs->bl.opt_mem_alignment =
0a122b
+            MAX(bs->bl.opt_mem_alignment,
0a122b
+                bs->backing_hd->bl.opt_mem_alignment);
0a122b
     }
0a122b
 
0a122b
     /* Then let the driver override it */
0a122b
@@ -4729,7 +4745,7 @@ void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
0a122b
 
0a122b
 void *qemu_blockalign(BlockDriverState *bs, size_t size)
0a122b
 {
0a122b
-    return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
0a122b
+    return qemu_memalign(bdrv_opt_mem_align(bs), size);
0a122b
 }
0a122b
 
0a122b
 /*
0a122b
@@ -4738,12 +4754,13 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size)
0a122b
 bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
0a122b
 {
0a122b
     int i;
0a122b
+    size_t alignment = bdrv_opt_mem_align(bs);
0a122b
 
0a122b
     for (i = 0; i < qiov->niov; i++) {
0a122b
-        if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
0a122b
+        if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
0a122b
             return false;
0a122b
         }
0a122b
-        if (qiov->iov[i].iov_len % bs->buffer_alignment) {
0a122b
+        if (qiov->iov[i].iov_len % alignment) {
0a122b
             return false;
0a122b
         }
0a122b
     }
0a122b
diff --git a/include/block/block.h b/include/block/block.h
0a122b
index 3e22fc2..9d1ce59 100644
0a122b
--- a/include/block/block.h
0a122b
+++ b/include/block/block.h
0a122b
@@ -406,6 +406,9 @@ void bdrv_img_create(const char *filename, const char *fmt,
0a122b
                      char *options, uint64_t img_size, int flags,
0a122b
                      Error **errp, bool quiet);
0a122b
 
0a122b
+/* Returns the alignment in bytes that is required so that no bounce buffer
0a122b
+ * is required throughout the stack */
0a122b
+size_t bdrv_opt_mem_align(BlockDriverState *bs);
0a122b
 void bdrv_set_buffer_alignment(BlockDriverState *bs, int align);
0a122b
 void *qemu_blockalign(BlockDriverState *bs, size_t size);
0a122b
 bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
0a122b
diff --git a/include/block/block_int.h b/include/block/block_int.h
0a122b
index 13a52e8..ddbd53d 100644
0a122b
--- a/include/block/block_int.h
0a122b
+++ b/include/block/block_int.h
0a122b
@@ -239,6 +239,9 @@ typedef struct BlockLimits {
0a122b
 
0a122b
     /* optimal transfer length in sectors */
0a122b
     int opt_transfer_length;
0a122b
+
0a122b
+    /* memory alignment so that no bounce buffer is needed */
0a122b
+    size_t opt_mem_alignment;
0a122b
 } BlockLimits;
0a122b
 
0a122b
 /*
0a122b
-- 
0a122b
1.7.1
0a122b