yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
9ae3a8
From b72ee3ebf0f00962872c69ad3576e1c8c0a208d9 Mon Sep 17 00:00:00 2001
9ae3a8
From: Fam Zheng <famz@redhat.com>
9ae3a8
Date: Thu, 21 Sep 2017 14:23:45 -0300
9ae3a8
Subject: [PATCH] block: Limit multiwrite merge (downstream only)
9ae3a8
9ae3a8
RH-Author: Fam Zheng <famz@redhat.com>
9ae3a8
Message-id: <20170921142345.22892-1-famz@redhat.com>
9ae3a8
Patchwork-id: 76502
9ae3a8
O-Subject: [RHEL-7.4 qemu-kvm PATCH] block: Limit multiwrite merge (downstream only)
9ae3a8
Bugzilla: 1492559
9ae3a8
RH-Acked-by: Max Reitz <mreitz@redhat.com>
9ae3a8
RH-Acked-by: John Snow <jsnow@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
9ae3a8
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1492559
9ae3a8
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14090140
9ae3a8
Upstream: Fixed since 2.3, see below.
9ae3a8
9ae3a8
We don't limit the size of the final request of multiwrite_merge. The BZ
9ae3a8
has a relatively stable reproducer: Attach an iscsi:// lun as
9ae3a8
virtio-blk, then mkfs.ext4. When the guest kernel flushes the page
9ae3a8
cache, iscsi driver gets two huge requests that are rejected by the LIO
9ae3a8
iscsi target, then reports EIO.
9ae3a8
9ae3a8
Upstream QEMU and qemu-kvm-rhev don't have this problem because of two
9ae3a8
things:
9ae3a8
9ae3a8
1) multiread feature in virtio-blk added in 2.3 (95f7142abc8).
9ae3a8
9ae3a8
2) request fragmentation in block layer I/O in 2.7 (04ed95f484 and
9ae3a8
   1a62d0accd).
9ae3a8
9ae3a8
For 1), we cannot do a faithful backport because it is a new feature,
9ae3a8
and is invasive. The change of this patch can be seen as doing a small
9ae3a8
part from it, though the implementation is totally different.
9ae3a8
9ae3a8
For 2), we would have a serious context conflict because upstream has a
9ae3a8
lot of intermediate changes. The patch could possibly be rewritten in
9ae3a8
downstream but is on the one hand much more risky than this patch as it
9ae3a8
touches the very center of the block I/O code, and on the other hand
9ae3a8
loses the meaning because the diff will completely deviate from
9ae3a8
upstream.
9ae3a8
9ae3a8
Signed-off-by: Fam Zheng <famz@redhat.com>
9ae3a8
Signed-off-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
9ae3a8
---
9ae3a8
 block.c | 5 +++++
9ae3a8
 1 file changed, 5 insertions(+)
9ae3a8
9ae3a8
diff --git a/block.c b/block.c
9ae3a8
index bdcd741389..b0373d0c16 100644
9ae3a8
--- a/block.c
9ae3a8
+++ b/block.c
9ae3a8
@@ -4303,6 +4303,11 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
9ae3a8
             merge = 0;
9ae3a8
         }
9ae3a8
 
9ae3a8
+        if (reqs[outidx].qiov->size + reqs[i].qiov->size >=
9ae3a8
+            bs->bl.max_transfer_length * BDRV_SECTOR_SIZE) {
9ae3a8
+            merge = 0;
9ae3a8
+        }
9ae3a8
+
9ae3a8
         if (merge) {
9ae3a8
             size_t size;
9ae3a8
             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
9ae3a8
-- 
9ae3a8
2.13.5
9ae3a8