Author: mav
Date: Thu Mar  5 10:40:45 2015
New Revision: 279652
URL: https://svnweb.freebsd.org/changeset/base/279652

Log:
  Add support for TOPOLOGY feature of virtio block device.
  
  Passing through physical block size/offset from underlying storage allows
  guest to manage proper data and I/O alignment to improve performance.
  
  MFC after:    2 weeks

Modified:
  head/usr.sbin/bhyve/pci_virtio_block.c

Modified: head/usr.sbin/bhyve/pci_virtio_block.c
==============================================================================
--- head/usr.sbin/bhyve/pci_virtio_block.c      Thu Mar  5 10:29:46 2015        
(r279651)
+++ head/usr.sbin/bhyve/pci_virtio_block.c      Thu Mar  5 10:40:45 2015        
(r279652)
@@ -64,7 +64,8 @@ __FBSDID("$FreeBSD$");
 
 /* Capability bits */
 #define        VTBLK_F_SEG_MAX         (1 << 2)        /* Maximum request 
segments */
-#define        VTBLK_F_BLK_SIZE        (1 << 6)        /* cfg block size valid 
*/
+#define        VTBLK_F_BLK_SIZE        (1 << 6)        /* cfg block size valid 
*/
+#define        VTBLK_F_TOPOLOGY        (1 << 10)       /* Optimal I/O 
alignment */
 
 /*
  * Host capabilities
@@ -72,6 +73,7 @@ __FBSDID("$FreeBSD$");
 #define VTBLK_S_HOSTCAPS      \
   ( VTBLK_F_SEG_MAX  |                                             \
     VTBLK_F_BLK_SIZE |                                             \
+    VTBLK_F_TOPOLOGY |                                             \
     VIRTIO_RING_F_INDIRECT_DESC )      /* indirect descriptors */
 
 /*
@@ -81,11 +83,19 @@ struct vtblk_config {
        uint64_t        vbc_capacity;
        uint32_t        vbc_size_max;
        uint32_t        vbc_seg_max;
-       uint16_t        vbc_geom_c;
-       uint8_t         vbc_geom_h;
-       uint8_t         vbc_geom_s;
+       struct {
+               uint16_t cylinders;
+               uint8_t heads;
+               uint8_t sectors;
+       } vbc_geometry;
        uint32_t        vbc_blk_size;
-       uint32_t        vbc_sectors_max;
+       struct {
+               uint8_t physical_block_exp;
+               uint8_t alignment_offset;
+               uint16_t min_io_size;
+               uint32_t opt_io_size;
+       } vbc_topology;
+       uint8_t         vbc_writeback;
 } __packed;
 
 /*
@@ -262,7 +272,7 @@ pci_vtblk_init(struct vmctx *ctx, struct
        MD5_CTX mdctx;
        u_char digest[16];
        struct pci_vtblk_softc *sc;
-       off_t size;     
+       off_t size, sts, sto;
        int fd;
        int sectsz;
 
@@ -291,6 +301,7 @@ pci_vtblk_init(struct vmctx *ctx, struct
         */
        size = sbuf.st_size;
        sectsz = DEV_BSIZE;
+       sts = sto = 0;
        if (S_ISCHR(sbuf.st_mode)) {
                if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 ||
                    ioctl(fd, DIOCGSECTORSIZE, &sectsz)) {
@@ -300,7 +311,10 @@ pci_vtblk_init(struct vmctx *ctx, struct
                }
                assert(size != 0);
                assert(sectsz != 0);
-       }
+               if (ioctl(fd, DIOCGSTRIPESIZE, &sts) == 0)
+                       ioctl(fd, DIOCGSTRIPEOFFSET, &sto);
+       } else
+               sts = sbuf.st_blksize;
 
        sc = calloc(1, sizeof(struct pci_vtblk_softc));
 
@@ -328,13 +342,19 @@ pci_vtblk_init(struct vmctx *ctx, struct
 
        /* setup virtio block config space */
        sc->vbsc_cfg.vbc_capacity = size / DEV_BSIZE; /* 512-byte units */
+       sc->vbsc_cfg.vbc_size_max = 0;  /* not negotiated */
        sc->vbsc_cfg.vbc_seg_max = VTBLK_MAXSEGS;
+       sc->vbsc_cfg.vbc_geometry.cylinders = 0;        /* no geometry */
+       sc->vbsc_cfg.vbc_geometry.heads = 0;
+       sc->vbsc_cfg.vbc_geometry.sectors = 0;
        sc->vbsc_cfg.vbc_blk_size = sectsz;
-       sc->vbsc_cfg.vbc_size_max = 0;  /* not negotiated */
-       sc->vbsc_cfg.vbc_geom_c = 0;    /* no geometry */
-       sc->vbsc_cfg.vbc_geom_h = 0;
-       sc->vbsc_cfg.vbc_geom_s = 0;
-       sc->vbsc_cfg.vbc_sectors_max = 0;
+       sc->vbsc_cfg.vbc_topology.physical_block_exp =
+           (sts > sectsz) ? (ffsll(sts / sectsz) - 1) : 0;
+       sc->vbsc_cfg.vbc_topology.alignment_offset =
+           (sto != 0) ? ((sts - sto) / sectsz) : 0;
+       sc->vbsc_cfg.vbc_topology.min_io_size = 0;
+       sc->vbsc_cfg.vbc_topology.opt_io_size = 0;
+       sc->vbsc_cfg.vbc_writeback = 0;
 
        /*
         * Should we move some of this into virtio.c?  Could
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to