Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Jan 2013 07:40:55 +0000 (UTC)
From:      Bryan Venteicher <bryanv@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r246063 - projects/virtio/sys/dev/virtio/block
Message-ID:  <201301290740.r0T7etsJ009037@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bryanv
Date: Tue Jan 29 07:40:54 2013
New Revision: 246063
URL: http://svnweb.freebsd.org/changeset/base/246063

Log:
  virtio_blk: Add support for write cache enable feature
  
  Later revisions of the VirtIO spec renamed the block flush
  feature to writecache-enable, and allowed the guest to set
  the caching mode to writeback or writethrough at init time.
  
  Approved by:	grehan (implicit)

Modified:
  projects/virtio/sys/dev/virtio/block/virtio_blk.c
  projects/virtio/sys/dev/virtio/block/virtio_blk.h

Modified: projects/virtio/sys/dev/virtio/block/virtio_blk.c
==============================================================================
--- projects/virtio/sys/dev/virtio/block/virtio_blk.c	Tue Jan 29 07:36:32 2013	(r246062)
+++ projects/virtio/sys/dev/virtio/block/virtio_blk.c	Tue Jan 29 07:40:54 2013	(r246063)
@@ -96,8 +96,9 @@ static struct virtio_feature_desc vtblk_
 	{ VIRTIO_BLK_F_RO,		"ReadOnly"	},
 	{ VIRTIO_BLK_F_BLK_SIZE,	"BlockSize"	},
 	{ VIRTIO_BLK_F_SCSI,		"SCSICmds"	},
-	{ VIRTIO_BLK_F_FLUSH,		"FlushCmd"	},
+	{ VIRTIO_BLK_F_WCE,		"WriteCache"	},
 	{ VIRTIO_BLK_F_TOPOLOGY,	"Topology"	},
+	{ VIRTIO_BLK_F_CONFIG_WCE,	"ConfigWCE"	},
 
 	{ 0, NULL }
 };
@@ -124,6 +125,8 @@ static int	vtblk_maximum_segments(struct
 		    struct virtio_blk_config *);
 static int	vtblk_alloc_virtqueue(struct vtblk_softc *);
 static void	vtblk_resize_disk(struct vtblk_softc *, uint64_t);
+static int	vtblk_write_cache_enabled(struct vtblk_softc *sc,
+		    struct virtio_blk_config *);
 static void	vtblk_alloc_disk(struct vtblk_softc *,
 		    struct virtio_blk_config *);
 static void	vtblk_create_disk(struct vtblk_softc *);
@@ -167,6 +170,8 @@ static void	vtblk_finish_bio(struct bio 
 /* Tunables. */
 static int vtblk_no_ident = 0;
 TUNABLE_INT("hw.vtblk.no_ident", &vtblk_no_ident);
+static int vtblk_write_cache = 1;
+TUNABLE_INT("hw.vtblk.write_cache", &vtblk_write_cache);
 
 /* Features desired/implemented by this driver. */
 #define VTBLK_FEATURES \
@@ -176,7 +181,8 @@ TUNABLE_INT("hw.vtblk.no_ident", &vtblk_
      VIRTIO_BLK_F_GEOMETRY		| \
      VIRTIO_BLK_F_RO			| \
      VIRTIO_BLK_F_BLK_SIZE		| \
-     VIRTIO_BLK_F_FLUSH			| \
+     VIRTIO_BLK_F_WCE			| \
+     VIRTIO_BLK_F_CONFIG_WCE		| \
      VIRTIO_RING_F_INDIRECT_DESC)
 
 #define VTBLK_MTX(_sc)		&(_sc)->vtblk_mtx
@@ -630,6 +636,37 @@ vtblk_resize_disk(struct vtblk_softc *sc
 	}
 }
 
+static int
+vtblk_write_cache_enabled(struct vtblk_softc *sc,
+    struct virtio_blk_config *blkcfg)
+{
+	device_t dev;
+	char buf[32];
+	int wc;
+
+	dev = sc->vtblk_dev;
+
+	if (!virtio_with_feature(dev, VIRTIO_BLK_F_WCE))
+		return (0);
+	if (!virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE))
+		return (1);
+
+	wc = vtblk_write_cache;
+	snprintf(buf, sizeof(buf), "hw.vtblk.%d.write_cache",
+	    device_get_unit(dev));
+	TUNABLE_INT_FETCH(buf, &wc);
+
+	if (wc != -1) {
+		/* Set either writeback or writethrough mode. */
+		blkcfg->writeback = !!wc;
+		virtio_write_dev_config_1(dev,
+		    offsetof(struct virtio_blk_config, writeback),
+		    blkcfg->writeback);
+	}
+
+	return (blkcfg->writeback);
+}
+
 static void
 vtblk_alloc_disk(struct vtblk_softc *sc, struct virtio_blk_config *blkcfg)
 {
@@ -692,7 +729,7 @@ vtblk_alloc_disk(struct vtblk_softc *sc,
 		    blkcfg->topology.alignment_offset;
 	}
 
-	if (virtio_with_feature(dev, VIRTIO_BLK_F_FLUSH))
+	if (vtblk_write_cache_enabled(sc, blkcfg) != 0)
 		dp->d_flags |= DISKFLAG_CANFLUSHCACHE;
 }
 
@@ -911,6 +948,7 @@ vtblk_read_config(struct vtblk_softc *sc
 	VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_GEOMETRY, geometry, blkcfg);
 	VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_BLK_SIZE, blk_size, blkcfg);
 	VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_TOPOLOGY, topology, blkcfg);
+	VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_CONFIG_WCE, writeback, blkcfg);
 }
 
 #undef VTBLK_GET_CONFIG

Modified: projects/virtio/sys/dev/virtio/block/virtio_blk.h
==============================================================================
--- projects/virtio/sys/dev/virtio/block/virtio_blk.h	Tue Jan 29 07:36:32 2013	(r246062)
+++ projects/virtio/sys/dev/virtio/block/virtio_blk.h	Tue Jan 29 07:40:54 2013	(r246063)
@@ -39,8 +39,9 @@
 #define VIRTIO_BLK_F_RO		0x0020	/* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE	0x0040	/* Block size of disk is available*/
 #define VIRTIO_BLK_F_SCSI	0x0080	/* Supports scsi command passthru */
-#define VIRTIO_BLK_F_FLUSH	0x0200	/* Cache flush command support */
+#define VIRTIO_BLK_F_WCE	0x0200	/* Writeback mode enabled after reset */
 #define VIRTIO_BLK_F_TOPOLOGY	0x0400	/* Topology information is available */
+#define VIRTIO_BLK_F_CONFIG_WCE 0x0800	/* Writeback mode available in config */
 
 #define VIRTIO_BLK_ID_BYTES	20	/* ID string length */
 
@@ -69,6 +70,9 @@ struct virtio_blk_config {
 		uint16_t opt_io_size;
 	} topology;
 
+	/* Writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
+	uint8_t writeback;
+
 } __packed;
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201301290740.r0T7etsJ009037>