From 8a873ba78069ef81c4ef073a0bd703172c8b3312 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Mon, 10 Dec 2012 13:14:39 +0100 Subject: virtio-blk: restore VirtIOBlkConf->config_wce flag Two slightly different versions of a patch to conditionally set VIRTIO_BLK_F_CONFIG_WCE through the "config-wce" qdev property have been applied (ea776abca and eec7f96c2). David Gibson noticed that the "config-wce" property is broken as a result and fixed it recently. The fix sets the host_features VIRTIO_BLK_F_CONFIG_WCE bit from a qdev property. Unfortunately, the virtio device then has no chance to test for the presence of the feature bit during virtio_blk_init(). Therefore, reinstate the VirtIOBlkConf->config_wce flag. Drop the duplicate qdev property to set the host_features bit. The VirtIOBlkConf->config_wce flag will be used by virtio-blk-data-plane in a later patch. Signed-off-by: Stefan Hajnoczi --- hw/virtio-blk.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'hw/virtio-blk.c') diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 90cfa246db..f004148e3e 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -524,6 +524,9 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features) features |= (1 << VIRTIO_BLK_F_BLK_SIZE); features |= (1 << VIRTIO_BLK_F_SCSI); + if (s->blk->config_wce) { + features |= (1 << VIRTIO_BLK_F_CONFIG_WCE); + } if (bdrv_enable_write_cache(s->bs)) features |= (1 << VIRTIO_BLK_F_WCE); -- cgit 1.4.1 From 392808b49b6aee066d0c1d200e72fc3dc11c9d0f Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 15:45:38 +0100 Subject: virtio-blk: add x-data-plane=on|off performance feature The virtio-blk-data-plane feature is easy to integrate into hw/virtio-blk.c. The data plane can be started and stopped similar to vhost-net. Users can take advantage of the virtio-blk-data-plane feature using the new -device virtio-blk-pci,x-data-plane=on property. The x-data-plane name was chosen because at this stage the feature is experimental and likely to see changes in the future. If the VM configuration does not support virtio-blk-data-plane an error message is printed. Although we could fall back to regular virtio-blk, I prefer the explicit approach since it prompts the user to fix their configuration if they want the performance benefit of virtio-blk-data-plane. Limitations: * Only format=raw is supported * Live migration is not supported * Block jobs, hot unplug, and other operations fail with -EBUSY * I/O throttling limits are ignored * Only Linux hosts are supported due to Linux AIO usage Signed-off-by: Stefan Hajnoczi --- hw/virtio-blk.c | 44 +++++++++++++++++++++++++++++++++++++++++++- hw/virtio-pci.c | 3 +++ 2 files changed, 46 insertions(+), 1 deletion(-) (limited to 'hw/virtio-blk.c') diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index f004148e3e..92c745a316 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -17,6 +17,9 @@ #include "hw/block-common.h" #include "sysemu/blockdev.h" #include "virtio-blk.h" +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE +#include "hw/dataplane/virtio-blk.h" +#endif #include "scsi-defs.h" #ifdef __linux__ # include @@ -33,6 +36,9 @@ typedef struct VirtIOBlock VirtIOBlkConf *blk; unsigned short sector_mask; DeviceState *qdev; +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + VirtIOBlockDataPlane *dataplane; +#endif } VirtIOBlock; static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev) @@ -407,6 +413,16 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) .num_writes = 0, }; +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start + * dataplane here instead of waiting for .set_status(). + */ + if (s->dataplane) { + virtio_blk_data_plane_start(s->dataplane); + return; + } +#endif + while ((req = virtio_blk_get_request(s))) { virtio_blk_handle_request(req, &mrb); } @@ -446,8 +462,9 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running, { VirtIOBlock *s = opaque; - if (!running) + if (!running) { return; + } if (!s->bh) { s->bh = qemu_bh_new(virtio_blk_dma_restart_bh, s); @@ -457,6 +474,14 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running, static void virtio_blk_reset(VirtIODevice *vdev) { +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + VirtIOBlock *s = to_virtio_blk(vdev); + + if (s->dataplane) { + virtio_blk_data_plane_stop(s->dataplane); + } +#endif + /* * This should cancel pending requests, but can't do nicely until there * are per-device request lists. @@ -541,6 +566,12 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) VirtIOBlock *s = to_virtio_blk(vdev); uint32_t features; +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + if (s->dataplane && !(status & VIRTIO_CONFIG_S_DRIVER)) { + virtio_blk_data_plane_stop(s->dataplane); + } +#endif + if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) { return; } @@ -638,6 +669,12 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk) s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1; s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output); +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + if (!virtio_blk_data_plane_create(&s->vdev, blk, &s->dataplane)) { + virtio_cleanup(&s->vdev); + return NULL; + } +#endif qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s); s->qdev = dev; @@ -655,6 +692,11 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk) void virtio_blk_exit(VirtIODevice *vdev) { VirtIOBlock *s = to_virtio_blk(vdev); + +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + virtio_blk_data_plane_destroy(s->dataplane); + s->dataplane = NULL; +#endif unregister_savevm(s->qdev, "virtio-blk", s); blockdev_mark_auto_del(s->bs); virtio_cleanup(vdev); diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 3cab783804..82761cf7f7 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -896,6 +896,9 @@ static Property virtio_blk_properties[] = { #endif DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true), DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + DEFINE_PROP_BIT("x-data-plane", VirtIOPCIProxy, blk.data_plane, 0, false), +#endif DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), DEFINE_PROP_END_OF_LIST(), -- cgit 1.4.1 From 9e72c45033770b81b536ac6091e91807247cc25a Mon Sep 17 00:00:00 2001 From: Alexey Zaytsev Date: Thu, 13 Dec 2012 09:03:43 +0200 Subject: virtio-blk: Return UNSUPP for unknown request types Currently, all unknown requests are treated as VIRTIO_BLK_T_IN Signed-off-by: Alexey Zaytsev Signed-off-by: Stefan Hajnoczi --- hw/virtio-blk.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'hw/virtio-blk.c') diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 92c745a316..df57b35f1b 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -398,10 +398,14 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1], req->elem.out_num - 1); virtio_blk_handle_write(req, mrb); - } else { + } else if (type == VIRTIO_BLK_T_IN || type == VIRTIO_BLK_T_BARRIER) { + /* VIRTIO_BLK_T_IN is 0, so we can't just & it. */ qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0], req->elem.in_num - 1); virtio_blk_handle_read(req); + } else { + virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP); + g_free(req); } } -- cgit 1.4.1