mirror of https://github.com/xqemu/xqemu.git
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 <stefanha@redhat.com>
This commit is contained in:
parent
e72f66a0a2
commit
392808b49b
|
@ -17,6 +17,9 @@
|
||||||
#include "hw/block-common.h"
|
#include "hw/block-common.h"
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include "virtio-blk.h"
|
#include "virtio-blk.h"
|
||||||
|
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
|
||||||
|
#include "hw/dataplane/virtio-blk.h"
|
||||||
|
#endif
|
||||||
#include "scsi-defs.h"
|
#include "scsi-defs.h"
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
# include <scsi/sg.h>
|
# include <scsi/sg.h>
|
||||||
|
@ -33,6 +36,9 @@ typedef struct VirtIOBlock
|
||||||
VirtIOBlkConf *blk;
|
VirtIOBlkConf *blk;
|
||||||
unsigned short sector_mask;
|
unsigned short sector_mask;
|
||||||
DeviceState *qdev;
|
DeviceState *qdev;
|
||||||
|
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
|
||||||
|
VirtIOBlockDataPlane *dataplane;
|
||||||
|
#endif
|
||||||
} VirtIOBlock;
|
} VirtIOBlock;
|
||||||
|
|
||||||
static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
|
static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
|
||||||
|
@ -407,6 +413,16 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
.num_writes = 0,
|
.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))) {
|
while ((req = virtio_blk_get_request(s))) {
|
||||||
virtio_blk_handle_request(req, &mrb);
|
virtio_blk_handle_request(req, &mrb);
|
||||||
}
|
}
|
||||||
|
@ -446,8 +462,9 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running,
|
||||||
{
|
{
|
||||||
VirtIOBlock *s = opaque;
|
VirtIOBlock *s = opaque;
|
||||||
|
|
||||||
if (!running)
|
if (!running) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!s->bh) {
|
if (!s->bh) {
|
||||||
s->bh = qemu_bh_new(virtio_blk_dma_restart_bh, s);
|
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)
|
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
|
* This should cancel pending requests, but can't do nicely until there
|
||||||
* are per-device request lists.
|
* 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);
|
VirtIOBlock *s = to_virtio_blk(vdev);
|
||||||
uint32_t features;
|
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)) {
|
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
||||||
return;
|
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->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
|
||||||
|
|
||||||
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
|
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);
|
qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
|
||||||
s->qdev = dev;
|
s->qdev = dev;
|
||||||
|
@ -655,6 +692,11 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
|
||||||
void virtio_blk_exit(VirtIODevice *vdev)
|
void virtio_blk_exit(VirtIODevice *vdev)
|
||||||
{
|
{
|
||||||
VirtIOBlock *s = to_virtio_blk(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);
|
unregister_savevm(s->qdev, "virtio-blk", s);
|
||||||
blockdev_mark_auto_del(s->bs);
|
blockdev_mark_auto_del(s->bs);
|
||||||
virtio_cleanup(vdev);
|
virtio_cleanup(vdev);
|
||||||
|
|
|
@ -896,6 +896,9 @@ static Property virtio_blk_properties[] = {
|
||||||
#endif
|
#endif
|
||||||
DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true),
|
DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true),
|
||||||
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, 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_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
|
||||||
DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
|
DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
|
Loading…
Reference in New Issue