virtio/user: support protocol features
rte_vhost doesn't respect those, but any other implementation should. Change-Id: Id0a0fa031b7c6e9d572cdffeeb3a1e40d824826d Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/417456 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
9aff546b7f
commit
5910855c68
@ -48,6 +48,10 @@
|
|||||||
#include "spdk/pci_ids.h"
|
#include "spdk/pci_ids.h"
|
||||||
#include "spdk/env.h"
|
#include "spdk/env.h"
|
||||||
|
|
||||||
|
#ifndef VHOST_USER_F_PROTOCOL_FEATURES
|
||||||
|
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum virtqueue size is 2^15. Use that value as the end of
|
* The maximum virtqueue size is 2^15. Use that value as the end of
|
||||||
* descriptor chain terminator since it will never be a valid index
|
* descriptor chain terminator since it will never be a valid index
|
||||||
|
@ -80,7 +80,8 @@ struct bdev_virtio_blk_io_channel {
|
|||||||
1ULL << VIRTIO_BLK_F_TOPOLOGY | \
|
1ULL << VIRTIO_BLK_F_TOPOLOGY | \
|
||||||
1ULL << VIRTIO_BLK_F_MQ | \
|
1ULL << VIRTIO_BLK_F_MQ | \
|
||||||
1ULL << VIRTIO_BLK_F_RO | \
|
1ULL << VIRTIO_BLK_F_RO | \
|
||||||
1ULL << VIRTIO_RING_F_EVENT_IDX)
|
1ULL << VIRTIO_RING_F_EVENT_IDX | \
|
||||||
|
1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
|
||||||
|
|
||||||
static int bdev_virtio_initialize(void);
|
static int bdev_virtio_initialize(void);
|
||||||
static int bdev_virtio_blk_get_ctx_size(void);
|
static int bdev_virtio_blk_get_ctx_size(void);
|
||||||
|
@ -193,7 +193,8 @@ static bool g_bdev_virtio_finish = false;
|
|||||||
#define VIRTIO_SCSI_DEV_SUPPORTED_FEATURES \
|
#define VIRTIO_SCSI_DEV_SUPPORTED_FEATURES \
|
||||||
(1ULL << VIRTIO_SCSI_F_INOUT | \
|
(1ULL << VIRTIO_SCSI_F_INOUT | \
|
||||||
1ULL << VIRTIO_SCSI_F_HOTPLUG | \
|
1ULL << VIRTIO_SCSI_F_HOTPLUG | \
|
||||||
1ULL << VIRTIO_RING_F_EVENT_IDX)
|
1ULL << VIRTIO_RING_F_EVENT_IDX | \
|
||||||
|
1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
|
||||||
|
|
||||||
static void virtio_scsi_dev_unregister_cb(void *io_device);
|
static void virtio_scsi_dev_unregister_cb(void *io_device);
|
||||||
static void virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev,
|
static void virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev,
|
||||||
|
@ -46,6 +46,9 @@
|
|||||||
|
|
||||||
#include "spdk_internal/virtio.h"
|
#include "spdk_internal/virtio.h"
|
||||||
|
|
||||||
|
#define VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES \
|
||||||
|
(0)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virtio_user_create_queue(struct virtio_dev *vdev, uint32_t queue_sel)
|
virtio_user_create_queue(struct virtio_dev *vdev, uint32_t queue_sel)
|
||||||
{
|
{
|
||||||
@ -286,6 +289,7 @@ static int
|
|||||||
virtio_user_set_features(struct virtio_dev *vdev, uint64_t features)
|
virtio_user_set_features(struct virtio_dev *vdev, uint64_t features)
|
||||||
{
|
{
|
||||||
struct virtio_user_dev *dev = vdev->ctx;
|
struct virtio_user_dev *dev = vdev->ctx;
|
||||||
|
uint64_t protocol_features;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features);
|
ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features);
|
||||||
@ -296,6 +300,23 @@ virtio_user_set_features(struct virtio_dev *vdev, uint64_t features)
|
|||||||
vdev->negotiated_features = features;
|
vdev->negotiated_features = features;
|
||||||
vdev->modern = virtio_dev_has_feature(vdev, VIRTIO_F_VERSION_1);
|
vdev->modern = virtio_dev_has_feature(vdev, VIRTIO_F_VERSION_1);
|
||||||
|
|
||||||
|
if (!virtio_dev_has_feature(vdev, VHOST_USER_F_PROTOCOL_FEATURES)) {
|
||||||
|
/* nothing else to do */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dev->ops->send_request(dev, VHOST_USER_GET_PROTOCOL_FEATURES, &protocol_features);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_features &= VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES;
|
||||||
|
ret = dev->ops->send_request(dev, VHOST_USER_SET_PROTOCOL_FEATURES, &protocol_features);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->protocol_features = protocol_features;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +333,7 @@ static int
|
|||||||
virtio_user_setup_queue(struct virtio_dev *vdev, struct virtqueue *vq)
|
virtio_user_setup_queue(struct virtio_dev *vdev, struct virtqueue *vq)
|
||||||
{
|
{
|
||||||
struct virtio_user_dev *dev = vdev->ctx;
|
struct virtio_user_dev *dev = vdev->ctx;
|
||||||
|
struct vhost_vring_state state;
|
||||||
uint16_t queue_idx = vq->vq_queue_index;
|
uint16_t queue_idx = vq->vq_queue_index;
|
||||||
uint64_t desc_addr, avail_addr, used_addr;
|
uint64_t desc_addr, avail_addr, used_addr;
|
||||||
int callfd;
|
int callfd;
|
||||||
@ -339,6 +361,16 @@ virtio_user_setup_queue(struct virtio_dev *vdev, struct virtqueue *vq)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.index = vq->vq_queue_index;
|
||||||
|
state.num = 0;
|
||||||
|
|
||||||
|
if (virtio_dev_has_feature(vdev, VHOST_USER_F_PROTOCOL_FEATURES) &&
|
||||||
|
dev->ops->send_request(dev, VHOST_USER_SET_VRING_ENABLE, &state) < 0) {
|
||||||
|
SPDK_ERRLOG("failed to send VHOST_USER_SET_VRING_ENABLE: %s\n",
|
||||||
|
spdk_strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
dev->callfds[queue_idx] = callfd;
|
dev->callfds[queue_idx] = callfd;
|
||||||
dev->kickfds[queue_idx] = kickfd;
|
dev->kickfds[queue_idx] = kickfd;
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ struct virtio_user_dev {
|
|||||||
|
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
uint64_t protocol_features;
|
||||||
struct vring vrings[SPDK_VIRTIO_MAX_VIRTQUEUES];
|
struct vring vrings[SPDK_VIRTIO_MAX_VIRTQUEUES];
|
||||||
struct virtio_user_backend_ops *ops;
|
struct virtio_user_backend_ops *ops;
|
||||||
};
|
};
|
||||||
|
@ -314,12 +314,14 @@ vhost_user_sock(struct virtio_user_dev *dev,
|
|||||||
|
|
||||||
switch (req) {
|
switch (req) {
|
||||||
case VHOST_USER_GET_FEATURES:
|
case VHOST_USER_GET_FEATURES:
|
||||||
|
case VHOST_USER_GET_PROTOCOL_FEATURES:
|
||||||
case VHOST_USER_GET_QUEUE_NUM:
|
case VHOST_USER_GET_QUEUE_NUM:
|
||||||
need_reply = 1;
|
need_reply = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VHOST_USER_SET_FEATURES:
|
case VHOST_USER_SET_FEATURES:
|
||||||
case VHOST_USER_SET_LOG_BASE:
|
case VHOST_USER_SET_LOG_BASE:
|
||||||
|
case VHOST_USER_SET_PROTOCOL_FEATURES:
|
||||||
msg.payload.u64 = *((__u64 *)arg);
|
msg.payload.u64 = *((__u64 *)arg);
|
||||||
msg.size = sizeof(msg.payload.u64);
|
msg.size = sizeof(msg.payload.u64);
|
||||||
break;
|
break;
|
||||||
@ -414,6 +416,7 @@ vhost_user_sock(struct virtio_user_dev *dev,
|
|||||||
|
|
||||||
switch (req) {
|
switch (req) {
|
||||||
case VHOST_USER_GET_FEATURES:
|
case VHOST_USER_GET_FEATURES:
|
||||||
|
case VHOST_USER_GET_PROTOCOL_FEATURES:
|
||||||
case VHOST_USER_GET_QUEUE_NUM:
|
case VHOST_USER_GET_QUEUE_NUM:
|
||||||
if (msg.size != sizeof(msg.payload.u64)) {
|
if (msg.size != sizeof(msg.payload.u64)) {
|
||||||
SPDK_WARNLOG("Received bad msg size\n");
|
SPDK_WARNLOG("Received bad msg size\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user