From patchwork Mon Aug 31 20:16:51 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 32678 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id A45F6B7B65 for ; Tue, 1 Sep 2009 06:20:05 +1000 (EST) Received: from localhost ([127.0.0.1]:34617 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MiDM9-0004VF-S1 for incoming@patchwork.ozlabs.org; Mon, 31 Aug 2009 16:20:01 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MiDJC-0003mB-5h for qemu-devel@nongnu.org; Mon, 31 Aug 2009 16:16:58 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MiDJ7-0003kF-IW for qemu-devel@nongnu.org; Mon, 31 Aug 2009 16:16:57 -0400 Received: from [199.232.76.173] (port=51907 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MiDJ7-0003k7-AB for qemu-devel@nongnu.org; Mon, 31 Aug 2009 16:16:53 -0400 Received: from verein.lst.de ([213.95.11.210]:33972) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA1:24) (Exim 4.60) (envelope-from ) id 1MiDJ6-0001B4-RF for qemu-devel@nongnu.org; Mon, 31 Aug 2009 16:16:53 -0400 Received: from verein.lst.de (localhost [127.0.0.1]) by verein.lst.de (8.12.3/8.12.3/Debian-7.1) with ESMTP id n7VKGpVL004895 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Mon, 31 Aug 2009 22:16:51 +0200 Received: (from hch@localhost) by verein.lst.de (8.12.3/8.12.3/Debian-7.2) id n7VKGpEv004894 for qemu-devel@nongnu.org; Mon, 31 Aug 2009 22:16:51 +0200 Date: Mon, 31 Aug 2009 22:16:51 +0200 From: Christoph Hellwig To: qemu-devel@nongnu.org Message-ID: <20090831201651.GA4874@lst.de> References: <20090831201627.GA4811@lst.de> Mime-Version: 1.0 Content-Disposition: inline In-Reply-To: <20090831201627.GA4811@lst.de> User-Agent: Mutt/1.3.28i X-Spam-Score: 0 () X-Scanned-By: MIMEDefang 2.39 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 1/4] block: add enable_write_cache flag X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add a enable_write_cache flag in the block driver state, and use it to decide if we claim to have a volatile write cache that needs controlled flushing from the guest. Currently we only claim to have it when cache=none is specified. While that might seem wrong it actually is the case as we still have outstanding block allocations and host drive caches to flush. We do not need to claim a write cache when we use cache=writethrough because O_SYNC writes are guaranteed to have data on stable storage. We would have to claim one for data=writeback to be safe, but for I will follow Avi's opinion that it is a useless mode and should be our dedicated unsafe mode. If anyone disagrees please start the flame thrower now and I will change it. Otherwise a documentation patch will follow to explicitly document data=writeback as unsafe. Both scsi-disk and ide now use the new flage, changing from their defaults of always off (ide) or always on (scsi-disk). Signed-off-by: Christoph Hellwig Index: qemu-kvm/hw/scsi-disk.c =================================================================== --- qemu-kvm.orig/hw/scsi-disk.c +++ qemu-kvm/hw/scsi-disk.c @@ -710,7 +710,9 @@ static int32_t scsi_send_command(SCSIDev memset(p,0,20); p[0] = 8; p[1] = 0x12; - p[2] = 4; /* WCE */ + if (bdrv_enable_write_cache(s->bdrv)) { + p[2] = 4; /* WCE */ + } p += 20; } if ((page == 0x3f || page == 0x2a) Index: qemu-kvm/block.c =================================================================== --- qemu-kvm.orig/block.c +++ qemu-kvm/block.c @@ -408,6 +408,16 @@ int bdrv_open2(BlockDriverState *bs, con } bs->drv = drv; bs->opaque = qemu_mallocz(drv->instance_size); + + /* + * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a + * write cache to the guest. We do need the fdatasync to flush + * out transactions for block allocations, and we maybe have a + * volatile write cache in our backing device to deal with. + */ + if (flags & BDRV_O_NOCACHE) + bs->enable_write_cache = 1; + /* Note: for compatibility, we open disk image files as RDWR, and RDONLY as fallback */ if (!(flags & BDRV_O_FILE)) @@ -918,6 +928,11 @@ int bdrv_is_sg(BlockDriverState *bs) return bs->sg; } +int bdrv_enable_write_cache(BlockDriverState *bs) +{ + return bs->enable_write_cache; +} + /* XXX: no longer used */ void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque) Index: qemu-kvm/block_int.h =================================================================== --- qemu-kvm.orig/block_int.h +++ qemu-kvm/block_int.h @@ -152,6 +152,9 @@ struct BlockDriverState { /* the memory alignment required for the buffers handled by this driver */ int buffer_alignment; + /* do we need to tell the quest if we have a volatile write cache? */ + int enable_write_cache; + /* NOTE: the following infos are only hints for real hardware drivers. They are not used by the block driver */ int cyls, heads, secs, translation; Index: qemu-kvm/block.h =================================================================== --- qemu-kvm.orig/block.h +++ qemu-kvm/block.h @@ -120,6 +120,7 @@ int bdrv_get_translation_hint(BlockDrive int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); int bdrv_is_sg(BlockDriverState *bs); +int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); int bdrv_is_locked(BlockDriverState *bs); Index: qemu-kvm/hw/ide/core.c =================================================================== --- qemu-kvm.orig/hw/ide/core.c +++ qemu-kvm/hw/ide/core.c @@ -148,8 +148,11 @@ static void ide_identify(IDEState *s) put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); /* 14=set to 1, 1=SMART self test, 0=SMART error logging */ put_le16(p + 84, (1 << 14) | 0); - /* 14 = NOP supported, 0=SMART feature set enabled */ - put_le16(p + 85, (1 << 14) | 1); + /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */ + if (bdrv_enable_write_cache(s->bs)) + put_le16(p + 85, (1 << 14) | (1 << 5) | 1); + else + put_le16(p + 85, (1 << 14) | 1); /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); /* 14=set to 1, 1=smart self test, 0=smart error logging */