diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/bhyve/block_if.c | 5 | ||||
-rw-r--r-- | usr/src/cmd/bhyve/block_if.h | 7 | ||||
-rw-r--r-- | usr/src/cmd/bhyve/pci_virtio_block.c | 16 |
3 files changed, 27 insertions, 1 deletions
diff --git a/usr/src/cmd/bhyve/block_if.c b/usr/src/cmd/bhyve/block_if.c index c8ec96690c..010f010c38 100644 --- a/usr/src/cmd/bhyve/block_if.c +++ b/usr/src/cmd/bhyve/block_if.c @@ -66,7 +66,12 @@ __FBSDID("$FreeBSD$"); #define BLOCKIF_SIG 0xb109b109 #define BLOCKIF_NUMTHR 8 +#ifdef __FreeBSD__ #define BLOCKIF_MAXREQ (64 + BLOCKIF_NUMTHR) +#else +/* Enlarge to keep pace with the virtio-block ring size */ +#define BLOCKIF_MAXREQ (128 + BLOCKIF_NUMTHR) +#endif enum blockop { BOP_READ, diff --git a/usr/src/cmd/bhyve/block_if.h b/usr/src/cmd/bhyve/block_if.h index 930cd62e83..265048d90f 100644 --- a/usr/src/cmd/bhyve/block_if.h +++ b/usr/src/cmd/bhyve/block_if.h @@ -44,7 +44,12 @@ #ifdef __FreeBSD__ #define BLOCKIF_IOV_MAX 33 /* not practical to be IOV_MAX */ #else -#define BLOCKIF_IOV_MAX 17 /* not practical to be IOV_MAX */ +/* + * Upstream is in the process of bumping this up to 128 for several reasons, + * including Windows compatibility. For the sake of our Windows support, we + * will use the higher value now. + */ +#define BLOCKIF_IOV_MAX 128 #endif struct blockif_req { diff --git a/usr/src/cmd/bhyve/pci_virtio_block.c b/usr/src/cmd/bhyve/pci_virtio_block.c index 63f59e6468..d2f6ac7785 100644 --- a/usr/src/cmd/bhyve/pci_virtio_block.c +++ b/usr/src/cmd/bhyve/pci_virtio_block.c @@ -68,7 +68,12 @@ __FBSDID("$FreeBSD$"); #include "virtio.h" #include "block_if.h" +#ifdef __FreeBSD__ #define VTBLK_RINGSZ 64 +#else +/* Enlarge to match bigger BLOCKIF_IOV_MAX */ +#define VTBLK_RINGSZ 128 +#endif #define VTBLK_S_OK 0 #define VTBLK_S_IOERR 1 @@ -376,7 +381,18 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) /* 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 */ +#ifdef __FreeBSD__ sc->vbsc_cfg.vbc_seg_max = BLOCKIF_IOV_MAX; +#else + /* + * If Linux is presented with a seg_max greater than the virtio queue + * size, it can stumble into situations where it violates its own + * invariants and panics. For safety, we keep seg_max clamped, paying + * heed to the two extra descriptors needed for the header and status + * of a request. + */ + sc->vbsc_cfg.vbc_seg_max = MIN(VTBLK_RINGSZ - 2, BLOCKIF_IOV_MAX); +#endif sc->vbsc_cfg.vbc_geometry.cylinders = 0; /* no geometry */ sc->vbsc_cfg.vbc_geometry.heads = 0; sc->vbsc_cfg.vbc_geometry.sectors = 0; |