vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
/*
|
|
|
|
* vhost-user-blk host device
|
|
|
|
*
|
|
|
|
* Copyright(C) 2017 Intel Corporation.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Changpeng Liu <changpeng.liu@intel.com>
|
|
|
|
*
|
|
|
|
* Largely based on the "vhost-user-scsi.c" and "vhost-scsi.c" implemented by:
|
|
|
|
* Felipe Franciosi <felipe@nutanix.com>
|
|
|
|
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
|
|
|
* Nicholas Bellinger <nab@risingtidesystems.com>
|
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
|
|
|
* See the COPYING.LIB file in the top-level directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "qemu/osdep.h"
|
|
|
|
#include "qapi/error.h"
|
|
|
|
#include "qemu/error-report.h"
|
|
|
|
#include "qemu/cutils.h"
|
|
|
|
#include "hw/qdev-core.h"
|
2019-08-12 08:23:51 +03:00
|
|
|
#include "hw/qdev-properties.h"
|
2020-12-12 01:05:12 +03:00
|
|
|
#include "hw/qdev-properties-system.h"
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
#include "hw/virtio/vhost.h"
|
|
|
|
#include "hw/virtio/vhost-user-blk.h"
|
|
|
|
#include "hw/virtio/virtio.h"
|
|
|
|
#include "hw/virtio/virtio-bus.h"
|
|
|
|
#include "hw/virtio/virtio-access.h"
|
2019-08-12 08:23:58 +03:00
|
|
|
#include "sysemu/sysemu.h"
|
2019-08-12 08:23:59 +03:00
|
|
|
#include "sysemu/runstate.h"
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
|
|
|
|
static const int user_feature_bits[] = {
|
|
|
|
VIRTIO_BLK_F_SIZE_MAX,
|
|
|
|
VIRTIO_BLK_F_SEG_MAX,
|
|
|
|
VIRTIO_BLK_F_GEOMETRY,
|
|
|
|
VIRTIO_BLK_F_BLK_SIZE,
|
|
|
|
VIRTIO_BLK_F_TOPOLOGY,
|
|
|
|
VIRTIO_BLK_F_MQ,
|
|
|
|
VIRTIO_BLK_F_RO,
|
|
|
|
VIRTIO_BLK_F_FLUSH,
|
|
|
|
VIRTIO_BLK_F_CONFIG_WCE,
|
2019-01-16 08:19:30 +03:00
|
|
|
VIRTIO_BLK_F_DISCARD,
|
|
|
|
VIRTIO_BLK_F_WRITE_ZEROES,
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
VIRTIO_F_VERSION_1,
|
|
|
|
VIRTIO_RING_F_INDIRECT_DESC,
|
|
|
|
VIRTIO_RING_F_EVENT_IDX,
|
|
|
|
VIRTIO_F_NOTIFY_ON_EMPTY,
|
|
|
|
VHOST_INVALID_FEATURE_BIT
|
|
|
|
};
|
|
|
|
|
|
|
|
static void vhost_user_blk_update_config(VirtIODevice *vdev, uint8_t *config)
|
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
|
|
|
|
memcpy(config, &s->blkcfg, sizeof(struct virtio_blk_config));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vhost_user_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
|
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
struct virtio_blk_config *blkcfg = (struct virtio_blk_config *)config;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (blkcfg->wce == s->blkcfg.wce) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = vhost_dev_set_config(&s->dev, &blkcfg->wce,
|
|
|
|
offsetof(struct virtio_blk_config, wce),
|
|
|
|
sizeof(blkcfg->wce),
|
|
|
|
VHOST_SET_CONFIG_TYPE_MASTER);
|
|
|
|
if (ret) {
|
|
|
|
error_report("set device config space failed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
s->blkcfg.wce = blkcfg->wce;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct virtio_blk_config blkcfg;
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(dev->vdev);
|
|
|
|
|
|
|
|
ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg,
|
|
|
|
sizeof(struct virtio_blk_config));
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("get config space failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* valid for resize only */
|
|
|
|
if (blkcfg.capacity != s->blkcfg.capacity) {
|
|
|
|
s->blkcfg.capacity = blkcfg.capacity;
|
|
|
|
memcpy(dev->vdev->config, &s->blkcfg, sizeof(struct virtio_blk_config));
|
|
|
|
virtio_notify_config(dev->vdev);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const VhostDevConfigOps blk_ops = {
|
|
|
|
.vhost_dev_config_notifier = vhost_user_blk_handle_config_change,
|
|
|
|
};
|
|
|
|
|
2019-03-20 14:26:44 +03:00
|
|
|
static int vhost_user_blk_start(VirtIODevice *vdev)
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
|
|
|
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
|
|
|
int i, ret;
|
|
|
|
|
|
|
|
if (!k->set_guest_notifiers) {
|
|
|
|
error_report("binding does not support guest notifiers");
|
2019-03-20 14:26:44 +03:00
|
|
|
return -ENOSYS;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = vhost_dev_enable_notifiers(&s->dev, vdev);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("Error enabling host notifiers: %d", -ret);
|
2019-03-20 14:26:44 +03:00
|
|
|
return ret;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, true);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("Error binding guest notifier: %d", -ret);
|
|
|
|
goto err_host_notifiers;
|
|
|
|
}
|
|
|
|
|
|
|
|
s->dev.acked_features = vdev->guest_features;
|
2019-02-28 11:53:53 +03:00
|
|
|
|
2020-11-03 15:36:17 +03:00
|
|
|
ret = vhost_dev_prepare_inflight(&s->dev, vdev);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("Error set inflight format: %d", -ret);
|
|
|
|
goto err_guest_notifiers;
|
|
|
|
}
|
|
|
|
|
2019-02-28 11:53:53 +03:00
|
|
|
if (!s->inflight->addr) {
|
|
|
|
ret = vhost_dev_get_inflight(&s->dev, s->queue_size, s->inflight);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("Error get inflight: %d", -ret);
|
|
|
|
goto err_guest_notifiers;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = vhost_dev_set_inflight(&s->dev, s->inflight);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("Error set inflight: %d", -ret);
|
|
|
|
goto err_guest_notifiers;
|
|
|
|
}
|
|
|
|
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
ret = vhost_dev_start(&s->dev, vdev);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("Error starting vhost: %d", -ret);
|
|
|
|
goto err_guest_notifiers;
|
|
|
|
}
|
vhost: recheck dev state in the vhost_migration_log routine
vhost-user devices can get a disconnect in the middle of the VHOST-USER
handshake on the migration start. If disconnect event happened right
before sending next VHOST-USER command, then the vhost_dev_set_log()
call in the vhost_migration_log() function will return error. This error
will lead to the assert() and close the QEMU migration source process.
For the vhost-user devices the disconnect event should not break the
migration process, because:
- the device will be in the stopped state, so it will not be changed
during migration
- if reconnect will be made the migration log will be reinitialized as
part of reconnect/init process:
#0 vhost_log_global_start (listener=0x563989cf7be0)
at hw/virtio/vhost.c:920
#1 0x000056398603d8bc in listener_add_address_space (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2664
#2 0x000056398603dd30 in memory_listener_register (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2740
#3 0x0000563985fd6956 in vhost_dev_init (hdev=0x563989cf7bd8,
opaque=0x563989cf7e30, backend_type=VHOST_BACKEND_TYPE_USER,
busyloop_timeout=0)
at hw/virtio/vhost.c:1385
#4 0x0000563985f7d0b8 in vhost_user_blk_connect (dev=0x563989cf7990)
at hw/block/vhost-user-blk.c:315
#5 0x0000563985f7d3f6 in vhost_user_blk_event (opaque=0x563989cf7990,
event=CHR_EVENT_OPENED)
at hw/block/vhost-user-blk.c:379
Update the vhost-user-blk device with the internal started_vu field which
will be used for initialization (vhost_user_blk_start) and clean up
(vhost_user_blk_stop). This additional flag in the VhostUserBlk structure
will be used to track whether the device really needs to be stopped and
cleaned up on a vhost-user level.
The disconnect event will set the overall VHOST device (not vhost-user) to
the stopped state, so it can be used by the general vhost_migration_log
routine.
Such approach could be propogated to the other vhost-user devices, but
better idea is just to make the same connect/disconnect code for all the
vhost-user devices.
This migration issue was slightly discussed earlier:
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg01509.html
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg05241.html
Signed-off-by: Dima Stepanov <dimastep@yandex-team.ru>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <9fbfba06791a87813fcee3e2315f0b904cc6789a.1599813294.git.dimastep@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2020-09-11 11:39:43 +03:00
|
|
|
s->started_vu = true;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
|
|
|
|
/* guest_notifier_mask/pending not used yet, so just unmask
|
|
|
|
* everything here. virtio-pci will do the right thing by
|
|
|
|
* enabling/disabling irqfd.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < s->dev.nvqs; i++) {
|
|
|
|
vhost_virtqueue_mask(&s->dev, vdev, i, false);
|
|
|
|
}
|
|
|
|
|
2019-03-20 14:26:44 +03:00
|
|
|
return ret;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
|
|
|
|
err_guest_notifiers:
|
|
|
|
k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
|
|
|
|
err_host_notifiers:
|
|
|
|
vhost_dev_disable_notifiers(&s->dev, vdev);
|
2019-03-20 14:26:44 +03:00
|
|
|
return ret;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vhost_user_blk_stop(VirtIODevice *vdev)
|
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
|
|
|
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
|
|
|
int ret;
|
|
|
|
|
vhost: recheck dev state in the vhost_migration_log routine
vhost-user devices can get a disconnect in the middle of the VHOST-USER
handshake on the migration start. If disconnect event happened right
before sending next VHOST-USER command, then the vhost_dev_set_log()
call in the vhost_migration_log() function will return error. This error
will lead to the assert() and close the QEMU migration source process.
For the vhost-user devices the disconnect event should not break the
migration process, because:
- the device will be in the stopped state, so it will not be changed
during migration
- if reconnect will be made the migration log will be reinitialized as
part of reconnect/init process:
#0 vhost_log_global_start (listener=0x563989cf7be0)
at hw/virtio/vhost.c:920
#1 0x000056398603d8bc in listener_add_address_space (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2664
#2 0x000056398603dd30 in memory_listener_register (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2740
#3 0x0000563985fd6956 in vhost_dev_init (hdev=0x563989cf7bd8,
opaque=0x563989cf7e30, backend_type=VHOST_BACKEND_TYPE_USER,
busyloop_timeout=0)
at hw/virtio/vhost.c:1385
#4 0x0000563985f7d0b8 in vhost_user_blk_connect (dev=0x563989cf7990)
at hw/block/vhost-user-blk.c:315
#5 0x0000563985f7d3f6 in vhost_user_blk_event (opaque=0x563989cf7990,
event=CHR_EVENT_OPENED)
at hw/block/vhost-user-blk.c:379
Update the vhost-user-blk device with the internal started_vu field which
will be used for initialization (vhost_user_blk_start) and clean up
(vhost_user_blk_stop). This additional flag in the VhostUserBlk structure
will be used to track whether the device really needs to be stopped and
cleaned up on a vhost-user level.
The disconnect event will set the overall VHOST device (not vhost-user) to
the stopped state, so it can be used by the general vhost_migration_log
routine.
Such approach could be propogated to the other vhost-user devices, but
better idea is just to make the same connect/disconnect code for all the
vhost-user devices.
This migration issue was slightly discussed earlier:
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg01509.html
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg05241.html
Signed-off-by: Dima Stepanov <dimastep@yandex-team.ru>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <9fbfba06791a87813fcee3e2315f0b904cc6789a.1599813294.git.dimastep@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2020-09-11 11:39:43 +03:00
|
|
|
if (!s->started_vu) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
s->started_vu = false;
|
|
|
|
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
if (!k->set_guest_notifiers) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vhost_dev_stop(&s->dev, vdev);
|
|
|
|
|
|
|
|
ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("vhost guest notifier cleanup failed: %d", ret);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vhost_dev_disable_notifiers(&s->dev, vdev);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status)
|
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
2019-06-26 05:31:26 +03:00
|
|
|
bool should_start = virtio_device_started(vdev, status);
|
2019-03-20 14:26:45 +03:00
|
|
|
int ret;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
|
|
|
|
if (!vdev->vm_running) {
|
|
|
|
should_start = false;
|
|
|
|
}
|
|
|
|
|
2019-03-20 14:26:45 +03:00
|
|
|
if (!s->connected) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
if (s->dev.started == should_start) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (should_start) {
|
2019-03-20 14:26:45 +03:00
|
|
|
ret = vhost_user_blk_start(vdev);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("vhost-user-blk: vhost start failed: %s",
|
|
|
|
strerror(-ret));
|
|
|
|
qemu_chr_fe_disconnect(&s->chardev);
|
|
|
|
}
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
} else {
|
|
|
|
vhost_user_blk_stop(vdev);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev,
|
|
|
|
uint64_t features,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
|
|
|
|
/* Turn on pre-defined features */
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_FLUSH);
|
2018-05-29 04:24:35 +03:00
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_RO);
|
2019-01-16 08:19:30 +03:00
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_DISCARD);
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_WRITE_ZEROES);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
|
|
|
|
if (s->config_wce) {
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
|
|
|
|
}
|
|
|
|
if (s->num_queues > 1) {
|
|
|
|
virtio_add_feature(&features, VIRTIO_BLK_F_MQ);
|
|
|
|
}
|
|
|
|
|
2018-03-23 17:32:02 +03:00
|
|
|
return vhost_get_features(&s->dev, user_feature_bits, features);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vhost_user_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
|
|
|
{
|
2018-06-06 16:24:48 +03:00
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
2019-03-20 14:26:45 +03:00
|
|
|
int i, ret;
|
2018-06-06 16:24:48 +03:00
|
|
|
|
2019-03-20 14:26:43 +03:00
|
|
|
if (!vdev->start_on_kick) {
|
2018-06-06 16:24:48 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-20 14:26:45 +03:00
|
|
|
if (!s->connected) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-06 16:24:48 +03:00
|
|
|
if (s->dev.started) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
|
|
|
|
* vhost here instead of waiting for .set_status().
|
|
|
|
*/
|
2019-03-20 14:26:45 +03:00
|
|
|
ret = vhost_user_blk_start(vdev);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("vhost-user-blk: vhost start failed: %s",
|
|
|
|
strerror(-ret));
|
|
|
|
qemu_chr_fe_disconnect(&s->chardev);
|
|
|
|
return;
|
|
|
|
}
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
|
2018-06-06 16:24:48 +03:00
|
|
|
/* Kick right away to begin processing requests already in vring */
|
|
|
|
for (i = 0; i < s->dev.nvqs; i++) {
|
|
|
|
VirtQueue *kick_vq = virtio_get_queue(vdev, i);
|
|
|
|
|
|
|
|
if (!virtio_queue_get_desc_addr(vdev, i)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
event_notifier_set(virtio_queue_get_host_notifier(kick_vq));
|
|
|
|
}
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
2019-02-28 11:53:53 +03:00
|
|
|
static void vhost_user_blk_reset(VirtIODevice *vdev)
|
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
|
|
|
|
vhost_dev_free_inflight(s->inflight);
|
|
|
|
}
|
|
|
|
|
2019-03-20 14:26:45 +03:00
|
|
|
static int vhost_user_blk_connect(DeviceState *dev)
|
|
|
|
{
|
|
|
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (s->connected) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
s->connected = true;
|
|
|
|
|
|
|
|
s->dev.nvqs = s->num_queues;
|
2020-02-24 07:13:36 +03:00
|
|
|
s->dev.vqs = s->vhost_vqs;
|
2019-03-20 14:26:45 +03:00
|
|
|
s->dev.vq_index = 0;
|
|
|
|
s->dev.backend_features = 0;
|
|
|
|
|
|
|
|
vhost_dev_set_config_notifier(&s->dev, &blk_ops);
|
|
|
|
|
|
|
|
ret = vhost_dev_init(&s->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("vhost-user-blk: vhost initialization failed: %s",
|
|
|
|
strerror(-ret));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* restore vhost state */
|
2019-06-26 05:31:26 +03:00
|
|
|
if (virtio_device_started(vdev, vdev->status)) {
|
2019-03-20 14:26:45 +03:00
|
|
|
ret = vhost_user_blk_start(vdev);
|
|
|
|
if (ret < 0) {
|
|
|
|
error_report("vhost-user-blk: vhost start failed: %s",
|
|
|
|
strerror(-ret));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vhost_user_blk_disconnect(DeviceState *dev)
|
|
|
|
{
|
|
|
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
|
|
|
|
if (!s->connected) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
s->connected = false;
|
|
|
|
|
vhost: recheck dev state in the vhost_migration_log routine
vhost-user devices can get a disconnect in the middle of the VHOST-USER
handshake on the migration start. If disconnect event happened right
before sending next VHOST-USER command, then the vhost_dev_set_log()
call in the vhost_migration_log() function will return error. This error
will lead to the assert() and close the QEMU migration source process.
For the vhost-user devices the disconnect event should not break the
migration process, because:
- the device will be in the stopped state, so it will not be changed
during migration
- if reconnect will be made the migration log will be reinitialized as
part of reconnect/init process:
#0 vhost_log_global_start (listener=0x563989cf7be0)
at hw/virtio/vhost.c:920
#1 0x000056398603d8bc in listener_add_address_space (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2664
#2 0x000056398603dd30 in memory_listener_register (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2740
#3 0x0000563985fd6956 in vhost_dev_init (hdev=0x563989cf7bd8,
opaque=0x563989cf7e30, backend_type=VHOST_BACKEND_TYPE_USER,
busyloop_timeout=0)
at hw/virtio/vhost.c:1385
#4 0x0000563985f7d0b8 in vhost_user_blk_connect (dev=0x563989cf7990)
at hw/block/vhost-user-blk.c:315
#5 0x0000563985f7d3f6 in vhost_user_blk_event (opaque=0x563989cf7990,
event=CHR_EVENT_OPENED)
at hw/block/vhost-user-blk.c:379
Update the vhost-user-blk device with the internal started_vu field which
will be used for initialization (vhost_user_blk_start) and clean up
(vhost_user_blk_stop). This additional flag in the VhostUserBlk structure
will be used to track whether the device really needs to be stopped and
cleaned up on a vhost-user level.
The disconnect event will set the overall VHOST device (not vhost-user) to
the stopped state, so it can be used by the general vhost_migration_log
routine.
Such approach could be propogated to the other vhost-user devices, but
better idea is just to make the same connect/disconnect code for all the
vhost-user devices.
This migration issue was slightly discussed earlier:
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg01509.html
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg05241.html
Signed-off-by: Dima Stepanov <dimastep@yandex-team.ru>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <9fbfba06791a87813fcee3e2315f0b904cc6789a.1599813294.git.dimastep@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2020-09-11 11:39:43 +03:00
|
|
|
vhost_user_blk_stop(vdev);
|
2019-03-20 14:26:45 +03:00
|
|
|
|
|
|
|
vhost_dev_cleanup(&s->dev);
|
|
|
|
}
|
|
|
|
|
2020-05-28 12:11:19 +03:00
|
|
|
static void vhost_user_blk_event(void *opaque, QEMUChrEvent event);
|
|
|
|
|
|
|
|
static void vhost_user_blk_chr_closed_bh(void *opaque)
|
|
|
|
{
|
|
|
|
DeviceState *dev = opaque;
|
|
|
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
|
|
|
|
vhost_user_blk_disconnect(dev);
|
|
|
|
qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event,
|
|
|
|
NULL, opaque, NULL, true);
|
|
|
|
}
|
|
|
|
|
chardev: Use QEMUChrEvent enum in IOEventHandler typedef
The Chardev events are listed in the QEMUChrEvent enum.
By using the enum in the IOEventHandler typedef we:
- make the IOEventHandler type more explicit (this handler
process out-of-band information, while the IOReadHandler
is in-band),
- help static code analyzers.
This patch was produced with the following spatch script:
@match@
expression backend, opaque, context, set_open;
identifier fd_can_read, fd_read, fd_event, be_change;
@@
qemu_chr_fe_set_handlers(backend, fd_can_read, fd_read, fd_event,
be_change, opaque, context, set_open);
@depends on match@
identifier opaque, event;
identifier match.fd_event;
@@
static
-void fd_event(void *opaque, int event)
+void fd_event(void *opaque, QEMUChrEvent event)
{
...
}
Then the typedef was modified manually in
include/chardev/char-fe.h.
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20191218172009.8868-15-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-12-18 20:20:09 +03:00
|
|
|
static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
|
2019-03-20 14:26:45 +03:00
|
|
|
{
|
|
|
|
DeviceState *dev = opaque;
|
|
|
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
|
|
|
|
|
|
|
switch (event) {
|
|
|
|
case CHR_EVENT_OPENED:
|
|
|
|
if (vhost_user_blk_connect(dev) < 0) {
|
|
|
|
qemu_chr_fe_disconnect(&s->chardev);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CHR_EVENT_CLOSED:
|
2020-05-28 12:11:19 +03:00
|
|
|
/*
|
|
|
|
* A close event may happen during a read/write, but vhost
|
|
|
|
* code assumes the vhost_dev remains setup, so delay the
|
|
|
|
* stop & clear. There are two possible paths to hit this
|
|
|
|
* disconnect event:
|
|
|
|
* 1. When VM is in the RUN_STATE_PRELAUNCH state. The
|
|
|
|
* vhost_user_blk_device_realize() is a caller.
|
|
|
|
* 2. In tha main loop phase after VM start.
|
|
|
|
*
|
|
|
|
* For p2 the disconnect event will be delayed. We can't
|
|
|
|
* do the same for p1, because we are not running the loop
|
|
|
|
* at this moment. So just skip this step and perform
|
|
|
|
* disconnect in the caller function.
|
|
|
|
*
|
|
|
|
* TODO: maybe it is a good idea to make the same fix
|
|
|
|
* for other vhost-user devices.
|
|
|
|
*/
|
|
|
|
if (runstate_is_running()) {
|
|
|
|
AioContext *ctx = qemu_get_current_aio_context();
|
|
|
|
|
|
|
|
qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, NULL, NULL,
|
|
|
|
NULL, NULL, false);
|
|
|
|
aio_bh_schedule_oneshot(ctx, vhost_user_blk_chr_closed_bh, opaque);
|
|
|
|
}
|
vhost: recheck dev state in the vhost_migration_log routine
vhost-user devices can get a disconnect in the middle of the VHOST-USER
handshake on the migration start. If disconnect event happened right
before sending next VHOST-USER command, then the vhost_dev_set_log()
call in the vhost_migration_log() function will return error. This error
will lead to the assert() and close the QEMU migration source process.
For the vhost-user devices the disconnect event should not break the
migration process, because:
- the device will be in the stopped state, so it will not be changed
during migration
- if reconnect will be made the migration log will be reinitialized as
part of reconnect/init process:
#0 vhost_log_global_start (listener=0x563989cf7be0)
at hw/virtio/vhost.c:920
#1 0x000056398603d8bc in listener_add_address_space (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2664
#2 0x000056398603dd30 in memory_listener_register (listener=0x563989cf7be0,
as=0x563986ea4340 <address_space_memory>)
at softmmu/memory.c:2740
#3 0x0000563985fd6956 in vhost_dev_init (hdev=0x563989cf7bd8,
opaque=0x563989cf7e30, backend_type=VHOST_BACKEND_TYPE_USER,
busyloop_timeout=0)
at hw/virtio/vhost.c:1385
#4 0x0000563985f7d0b8 in vhost_user_blk_connect (dev=0x563989cf7990)
at hw/block/vhost-user-blk.c:315
#5 0x0000563985f7d3f6 in vhost_user_blk_event (opaque=0x563989cf7990,
event=CHR_EVENT_OPENED)
at hw/block/vhost-user-blk.c:379
Update the vhost-user-blk device with the internal started_vu field which
will be used for initialization (vhost_user_blk_start) and clean up
(vhost_user_blk_stop). This additional flag in the VhostUserBlk structure
will be used to track whether the device really needs to be stopped and
cleaned up on a vhost-user level.
The disconnect event will set the overall VHOST device (not vhost-user) to
the stopped state, so it can be used by the general vhost_migration_log
routine.
Such approach could be propogated to the other vhost-user devices, but
better idea is just to make the same connect/disconnect code for all the
vhost-user devices.
This migration issue was slightly discussed earlier:
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg01509.html
- https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg05241.html
Signed-off-by: Dima Stepanov <dimastep@yandex-team.ru>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <9fbfba06791a87813fcee3e2315f0b904cc6789a.1599813294.git.dimastep@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2020-09-11 11:39:43 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Move vhost device to the stopped state. The vhost-user device
|
|
|
|
* will be clean up and disconnected in BH. This can be useful in
|
|
|
|
* the vhost migration code. If disconnect was caught there is an
|
|
|
|
* option for the general vhost code to get the dev state without
|
|
|
|
* knowing its type (in this case vhost-user).
|
|
|
|
*/
|
|
|
|
s->dev.started = false;
|
2019-03-20 14:26:45 +03:00
|
|
|
break;
|
2019-12-18 20:20:04 +03:00
|
|
|
case CHR_EVENT_BREAK:
|
|
|
|
case CHR_EVENT_MUX_IN:
|
|
|
|
case CHR_EVENT_MUX_OUT:
|
|
|
|
/* Ignore */
|
|
|
|
break;
|
2019-03-20 14:26:45 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
|
|
|
|
{
|
|
|
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
2019-03-20 14:26:45 +03:00
|
|
|
Error *err = NULL;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
int i, ret;
|
|
|
|
|
|
|
|
if (!s->chardev.chr) {
|
|
|
|
error_setg(errp, "vhost-user-blk: chardev is mandatory");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-18 17:33:48 +03:00
|
|
|
if (s->num_queues == VHOST_USER_BLK_AUTO_NUM_QUEUES) {
|
|
|
|
s->num_queues = 1;
|
|
|
|
}
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
if (!s->num_queues || s->num_queues > VIRTIO_QUEUE_MAX) {
|
|
|
|
error_setg(errp, "vhost-user-blk: invalid number of IO queues");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!s->queue_size) {
|
|
|
|
error_setg(errp, "vhost-user-blk: queue size must be non-zero");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-08 17:04:45 +03:00
|
|
|
if (!vhost_user_init(&s->vhost_user, &s->chardev, errp)) {
|
2018-05-24 13:33:33 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
|
|
|
|
sizeof(struct virtio_blk_config));
|
|
|
|
|
2020-02-24 07:13:36 +03:00
|
|
|
s->virtqs = g_new(VirtQueue *, s->num_queues);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
for (i = 0; i < s->num_queues; i++) {
|
2020-02-24 07:13:36 +03:00
|
|
|
s->virtqs[i] = virtio_add_queue(vdev, s->queue_size,
|
|
|
|
vhost_user_blk_handle_output);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
2019-02-28 11:53:53 +03:00
|
|
|
s->inflight = g_new0(struct vhost_inflight, 1);
|
2020-02-24 07:13:36 +03:00
|
|
|
s->vhost_vqs = g_new0(struct vhost_virtqueue, s->num_queues);
|
2019-03-20 14:26:45 +03:00
|
|
|
s->connected = false;
|
2019-02-28 11:53:53 +03:00
|
|
|
|
2019-03-20 14:26:45 +03:00
|
|
|
qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event,
|
|
|
|
NULL, (void *)dev, NULL, true);
|
2018-03-29 10:52:32 +03:00
|
|
|
|
2019-03-20 14:26:45 +03:00
|
|
|
reconnect:
|
|
|
|
if (qemu_chr_fe_wait_connected(&s->chardev, &err) < 0) {
|
|
|
|
error_report_err(err);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
goto virtio_err;
|
|
|
|
}
|
|
|
|
|
2019-03-20 14:26:45 +03:00
|
|
|
/* check whether vhost_user_blk_connect() failed or not */
|
|
|
|
if (!s->connected) {
|
|
|
|
goto reconnect;
|
|
|
|
}
|
|
|
|
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
ret = vhost_dev_get_config(&s->dev, (uint8_t *)&s->blkcfg,
|
2019-03-20 14:26:45 +03:00
|
|
|
sizeof(struct virtio_blk_config));
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
if (ret < 0) {
|
2019-03-20 14:26:45 +03:00
|
|
|
error_report("vhost-user-blk: get block config failed");
|
|
|
|
goto reconnect;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (s->blkcfg.num_queues != s->num_queues) {
|
|
|
|
s->blkcfg.num_queues = s->num_queues;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
virtio_err:
|
2020-02-24 07:13:36 +03:00
|
|
|
g_free(s->vhost_vqs);
|
2020-04-17 13:17:07 +03:00
|
|
|
s->vhost_vqs = NULL;
|
2019-02-28 11:53:53 +03:00
|
|
|
g_free(s->inflight);
|
2020-04-17 13:17:07 +03:00
|
|
|
s->inflight = NULL;
|
2020-02-24 07:13:35 +03:00
|
|
|
for (i = 0; i < s->num_queues; i++) {
|
2020-02-24 07:13:36 +03:00
|
|
|
virtio_delete_queue(s->virtqs[i]);
|
2020-02-24 07:13:35 +03:00
|
|
|
}
|
2020-02-24 07:13:36 +03:00
|
|
|
g_free(s->virtqs);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
virtio_cleanup(vdev);
|
2019-03-08 17:04:45 +03:00
|
|
|
vhost_user_cleanup(&s->vhost_user);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
qdev: Unrealize must not fail
Devices may have component devices and buses.
Device realization may fail. Realization is recursive: a device's
realize() method realizes its components, and device_set_realized()
realizes its buses (which should in turn realize the devices on that
bus, except bus_set_realized() doesn't implement that, yet).
When realization of a component or bus fails, we need to roll back:
unrealize everything we realized so far. If any of these unrealizes
failed, the device would be left in an inconsistent state. Must not
happen.
device_set_realized() lets it happen: it ignores errors in the roll
back code starting at label child_realize_fail.
Since realization is recursive, unrealization must be recursive, too.
But how could a partly failed unrealize be rolled back? We'd have to
re-realize, which can fail. This design is fundamentally broken.
device_set_realized() does not roll back at all. Instead, it keeps
unrealizing, ignoring further errors.
It can screw up even for a device with no buses: if the lone
dc->unrealize() fails, it still unregisters vmstate, and calls
listeners' unrealize() callback.
bus_set_realized() does not roll back either. Instead, it stops
unrealizing.
Fortunately, no unrealize method can fail, as we'll see below.
To fix the design error, drop parameter @errp from all the unrealize
methods.
Any unrealize method that uses @errp now needs an update. This leads
us to unrealize() methods that can fail. Merely passing it to another
unrealize method cannot cause failure, though. Here are the ones that
do other things with @errp:
* virtio_serial_device_unrealize()
Fails when qbus_set_hotplug_handler() fails, but still does all the
other work. On failure, the device would stay realized with its
resources completely gone. Oops. Can't happen, because
qbus_set_hotplug_handler() can't actually fail here. Pass
&error_abort to qbus_set_hotplug_handler() instead.
* hw/ppc/spapr_drc.c's unrealize()
Fails when object_property_del() fails, but all the other work is
already done. On failure, the device would stay realized with its
vmstate registration gone. Oops. Can't happen, because
object_property_del() can't actually fail here. Pass &error_abort
to object_property_del() instead.
* spapr_phb_unrealize()
Fails and bails out when remove_drcs() fails, but other work is
already done. On failure, the device would stay realized with some
of its resources gone. Oops. remove_drcs() fails only when
chassis_from_bus()'s object_property_get_uint() fails, and it can't
here. Pass &error_abort to remove_drcs() instead.
Therefore, no unrealize method can fail before this patch.
device_set_realized()'s recursive unrealization via bus uses
object_property_set_bool(). Can't drop @errp there, so pass
&error_abort.
We similarly unrealize with object_property_set_bool() elsewhere,
always ignoring errors. Pass &error_abort instead.
Several unrealize methods no longer handle errors from other unrealize
methods: virtio_9p_device_unrealize(),
virtio_input_device_unrealize(), scsi_qdev_unrealize(), ...
Much of the deleted error handling looks wrong anyway.
One unrealize methods no longer ignore such errors:
usb_ehci_pci_exit().
Several realize methods no longer ignore errors when rolling back:
v9fs_device_realize_common(), pci_qdev_unrealize(),
spapr_phb_realize(), usb_qdev_realize(), vfio_ccw_realize(),
virtio_device_realize().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200505152926.18877-17-armbru@redhat.com>
2020-05-05 18:29:24 +03:00
|
|
|
static void vhost_user_blk_device_unrealize(DeviceState *dev)
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
{
|
|
|
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(dev);
|
2020-02-24 07:13:35 +03:00
|
|
|
int i;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
|
2019-03-20 14:26:42 +03:00
|
|
|
virtio_set_status(vdev, 0);
|
2019-03-20 14:26:45 +03:00
|
|
|
qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, false);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
vhost_dev_cleanup(&s->dev);
|
2019-02-28 11:53:53 +03:00
|
|
|
vhost_dev_free_inflight(s->inflight);
|
2020-02-24 07:13:36 +03:00
|
|
|
g_free(s->vhost_vqs);
|
2020-04-17 13:17:07 +03:00
|
|
|
s->vhost_vqs = NULL;
|
2019-02-28 11:53:53 +03:00
|
|
|
g_free(s->inflight);
|
2020-04-17 13:17:07 +03:00
|
|
|
s->inflight = NULL;
|
2020-02-24 07:13:35 +03:00
|
|
|
|
|
|
|
for (i = 0; i < s->num_queues; i++) {
|
2020-02-24 07:13:36 +03:00
|
|
|
virtio_delete_queue(s->virtqs[i]);
|
2020-02-24 07:13:35 +03:00
|
|
|
}
|
2020-02-24 07:13:36 +03:00
|
|
|
g_free(s->virtqs);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
virtio_cleanup(vdev);
|
2019-03-08 17:04:45 +03:00
|
|
|
vhost_user_cleanup(&s->vhost_user);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vhost_user_blk_instance_init(Object *obj)
|
|
|
|
{
|
|
|
|
VHostUserBlk *s = VHOST_USER_BLK(obj);
|
|
|
|
|
|
|
|
device_add_bootindex_property(obj, &s->bootindex, "bootindex",
|
2020-05-05 18:29:23 +03:00
|
|
|
"/disk@0,0", DEVICE(obj));
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static const VMStateDescription vmstate_vhost_user_blk = {
|
|
|
|
.name = "vhost-user-blk",
|
|
|
|
.minimum_version_id = 1,
|
|
|
|
.version_id = 1,
|
|
|
|
.fields = (VMStateField[]) {
|
|
|
|
VMSTATE_VIRTIO_DEVICE,
|
|
|
|
VMSTATE_END_OF_LIST()
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static Property vhost_user_blk_properties[] = {
|
|
|
|
DEFINE_PROP_CHR("chardev", VHostUserBlk, chardev),
|
2020-08-18 17:33:48 +03:00
|
|
|
DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues,
|
|
|
|
VHOST_USER_BLK_AUTO_NUM_QUEUES),
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
|
|
|
|
DEFINE_PROP_BIT("config-wce", VHostUserBlk, config_wce, 0, true),
|
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
|
|
|
|
|
|
|
static void vhost_user_blk_class_init(ObjectClass *klass, void *data)
|
|
|
|
{
|
|
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
|
|
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
|
|
|
|
|
2020-01-10 18:30:32 +03:00
|
|
|
device_class_set_props(dc, vhost_user_blk_properties);
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
dc->vmsd = &vmstate_vhost_user_blk;
|
|
|
|
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
|
|
|
vdc->realize = vhost_user_blk_device_realize;
|
|
|
|
vdc->unrealize = vhost_user_blk_device_unrealize;
|
|
|
|
vdc->get_config = vhost_user_blk_update_config;
|
|
|
|
vdc->set_config = vhost_user_blk_set_config;
|
|
|
|
vdc->get_features = vhost_user_blk_get_features;
|
|
|
|
vdc->set_status = vhost_user_blk_set_status;
|
2019-02-28 11:53:53 +03:00
|
|
|
vdc->reset = vhost_user_blk_reset;
|
vhost-user-blk: introduce a new vhost-user-blk host device
This commit introduces a new vhost-user device for block, it uses a
chardev to connect with the backend, same with Qemu virito-blk device,
Guest OS still uses the virtio-blk frontend driver.
To use it, start QEMU with command line like this:
qemu-system-x86_64 \
-chardev socket,id=char0,path=/path/vhost.socket \
-device vhost-user-blk-pci,chardev=char0,num-queues=2, \
bootindex=2... \
Users can use different parameters for `num-queues` and `bootindex`.
Different with exist Qemu virtio-blk host device, it makes more easy
for users to implement their own I/O processing logic, such as all
user space I/O stack against hardware block device. It uses the new
vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
information from backend process.
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2018-01-04 04:53:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static const TypeInfo vhost_user_blk_info = {
|
|
|
|
.name = TYPE_VHOST_USER_BLK,
|
|
|
|
.parent = TYPE_VIRTIO_DEVICE,
|
|
|
|
.instance_size = sizeof(VHostUserBlk),
|
|
|
|
.instance_init = vhost_user_blk_instance_init,
|
|
|
|
.class_init = vhost_user_blk_class_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void virtio_register_types(void)
|
|
|
|
{
|
|
|
|
type_register_static(&vhost_user_blk_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
type_init(virtio_register_types)
|