From patchwork Fri Jul 18 06:15:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Pestov X-Patchwork-Id: 371594 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id F1EA214008C for ; Sat, 19 Jul 2014 01:19:10 +1000 (EST) Received: from localhost ([::1]:50309 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X89wD-0002Ri-2e for incoming@patchwork.ozlabs.org; Fri, 18 Jul 2014 11:19:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54798) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X81XK-0004rs-4y for qemu-devel@nongnu.org; Fri, 18 Jul 2014 02:21:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X81XC-00050d-VK for qemu-devel@nongnu.org; Fri, 18 Jul 2014 02:20:53 -0400 Received: from indium.canonical.com ([91.189.90.7]:37571) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X81XC-00050J-PG for qemu-devel@nongnu.org; Fri, 18 Jul 2014 02:20:46 -0400 Received: from loganberry.canonical.com ([91.189.90.37]) by indium.canonical.com with esmtp (Exim 4.76 #1 (Debian)) id 1X81XC-0006Zw-3F for ; Fri, 18 Jul 2014 06:20:46 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id 071F72E80C1 for ; Fri, 18 Jul 2014 06:20:46 +0000 (UTC) MIME-Version: 1.0 Date: Fri, 18 Jul 2014 06:15:00 -0000 From: Slava Pestov To: qemu-devel@nongnu.org X-Launchpad-Bug: product=qemu; status=New; importance=Undecided; assignee=None; X-Launchpad-Bug-Information-Type: Public X-Launchpad-Bug-Private: no X-Launchpad-Bug-Security-Vulnerability: no X-Launchpad-Bug-Commenters: sviatoslav-pestov X-Launchpad-Bug-Reporter: Slava Pestov (sviatoslav-pestov) X-Launchpad-Bug-Modifier: Slava Pestov (sviatoslav-pestov) References: <20140718061500.9209.75334.malonedeb@gac.canonical.com> Message-Id: <20140718061500.9209.75334.malonedeb@gac.canonical.com> X-Launchpad-Message-Rationale: Subscriber (QEMU) @qemu-devel-ml Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="17114"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 8878da656df4f0e358f7b292fc69a2c21766fa2d X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 91.189.90.7 X-Mailman-Approved-At: Fri, 18 Jul 2014 11:18:43 -0400 Subject: [Qemu-devel] [Bug 1343827] [NEW] block.c: multiwrite_merge() truncates overlapping requests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Reply-To: Bug 1343827 <1343827@bugs.launchpad.net> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Public bug reported: If the list of requests passed to multiwrite_merge() contains two requests where the first is for a range of sectors that is a strict subset of the second's, the second request is truncated to end where the first starts, so the second half of the second request is lost. This is easy to reproduce by running fio against a virtio-blk device running on qemu 2.1.0-rc1 with the below fio script. At least with fio 2.0.13, the randwrite pass will issue overlapping bios to the block driver, which the kernel is happy to pass along to qemu: [global] randrepeat=0 ioengine=libaio iodepth=64 direct=1 size=1M numjobs=1 verify_fatal=1 verify_dump=1 filename=$dev [seqwrite] blocksize_range=4k-1M rw=write verify=crc32c-intel [randwrite] stonewall blocksize_range=4k-1M rw=randwrite verify=meta Here is a naive fix for the problem that simply avoids merging problematic requests. I guess a better solution would be to redo qemu_iovec_concat() to do the right thing. ** Affects: qemu Importance: Undecided Status: New diff -ur old/qemu-2.1.0-rc2/block.c qemu-2.1.0-rc2/block.c --- old/qemu-2.1.0-rc2/block.c 2014-07-15 14:49:14.000000000 -0700 +++ qemu-2.1.0-rc2/block.c 2014-07-17 23:03:14.224169741 -0700 @@ -4460,7 +4460,9 @@ int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors; // Handle exactly sequential writes and overlapping writes. - if (reqs[i].sector <= oldreq_last) { + // If this request ends before the previous one, don't merge. + if (reqs[i].sector <= oldreq_last && + reqs[i].sector + reqs[i].nb_sectors >= oldreq_last) { merge = 1; }