From 4289ffd14c43be2d6c9d95b0812ee080dd26b36e Mon Sep 17 00:00:00 2001 Message-Id: <4289ffd14c43be2d6c9d95b0812ee080dd26b36e.1357726992.git.minovotn@redhat.com> In-Reply-To: <4f8efce613a639a3c1e3022c521d6c70b7154de8.1357726992.git.minovotn@redhat.com> References: <4f8efce613a639a3c1e3022c521d6c70b7154de8.1357726992.git.minovotn@redhat.com> From: Stefan Hajnoczi Date: Wed, 2 Jan 2013 15:02:38 +0100 Subject: [PATCH 15/16] virtio-blk: add x-data-plane=on|off performance feature RH-Author: Stefan Hajnoczi Message-id: <1357138959-1918-16-git-send-email-stefanha@redhat.com> Patchwork-id: 45528 O-Subject: [RHEL6.4 qemu-kvm PATCH v5 15/16] virtio-blk: add x-data-plane=on|off performance feature Bugzilla: 877836 RH-Acked-by: Laszlo Ersek RH-Acked-by: Asias He RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Paolo Bonzini 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 | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/virtio-pci.c | 4 ++++ 2 files changed, 58 insertions(+) Signed-off-by: Michal Novotny --- hw/virtio-blk.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/virtio-pci.c | 4 ++++ 2 files changed, 58 insertions(+) diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index d6e8423..5ea0ddb 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -15,6 +15,9 @@ #include "qemu-error.h" #include "trace.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 @@ -31,6 +34,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) @@ -422,6 +428,16 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) .old_bs = NULL, }; +#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); } @@ -476,6 +492,14 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running, RunState state) 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. @@ -527,6 +551,17 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features) return features; } +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE +static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) +{ + VirtIOBlock *s = to_virtio_blk(vdev); + + if (s->dataplane && !(status & VIRTIO_CONFIG_S_DRIVER)) { + virtio_blk_data_plane_stop(s->dataplane); + } +} +#endif + static void virtio_blk_save(QEMUFile *f, void *opaque) { VirtIOBlock *s = opaque; @@ -621,6 +656,9 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk) s->vdev.get_config = virtio_blk_update_config; s->vdev.get_features = virtio_blk_get_features; +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + s->vdev.set_status = virtio_blk_set_status; +#endif s->vdev.reset = virtio_blk_reset; s->bs = blk->conf.bs; s->conf = &blk->conf; @@ -631,11 +669,22 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk) bdrv_set_geometry_hint(s->bs, cylinders, heads, secs); 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; register_savevm(dev, "virtio-blk", virtio_blk_id++, 2, virtio_blk_save, virtio_blk_load, s); +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + if (s->dataplane) { + register_device_unmigratable(dev, "virtio-blk", s); + } +#endif bdrv_set_dev_ops(s->bs, &virtio_block_ops, s); s->bs->buffer_alignment = s->conf->logical_block_size; @@ -648,6 +697,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); virtio_cleanup(vdev); } diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index cdcc14d..28c48c7 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -992,6 +992,10 @@ static PCIDeviceInfo virtio_info[] = { DEFINE_PROP_STRING("serial", VirtIOPCIProxy, blk.serial), 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(), -- 1.7.11.7