Skip to content

Commit

Permalink
virtio/user: support protocol features
Browse files Browse the repository at this point in the history
rte_vhost doesn't respect those, but any other
implementation should.

Change-Id: Id0a0fa031b7c6e9d572cdffeeb3a1e40d824826d
Signed-off-by: Dariusz Stojaczyk <[email protected]>
Reviewed-on: https://review.gerrithub.io/417456
Tested-by: SPDK Automated Test System <[email protected]>
Reviewed-by: Jim Harris <[email protected]>
Reviewed-by: Ben Walker <[email protected]>
Reviewed-by: Daniel Verkamp <[email protected]>
  • Loading branch information
darsto authored and jimharris committed Jul 5, 2018
1 parent 9aff546 commit 5910855
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 2 deletions.
4 changes: 4 additions & 0 deletions include/spdk_internal/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
#include "spdk/pci_ids.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
* descriptor chain terminator since it will never be a valid index
Expand Down
3 changes: 2 additions & 1 deletion lib/bdev/virtio/bdev_virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ struct bdev_virtio_blk_io_channel {
1ULL << VIRTIO_BLK_F_TOPOLOGY | \
1ULL << VIRTIO_BLK_F_MQ | \
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_blk_get_ctx_size(void);
Expand Down
3 changes: 2 additions & 1 deletion lib/bdev/virtio/bdev_virtio_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ static bool g_bdev_virtio_finish = false;
#define VIRTIO_SCSI_DEV_SUPPORTED_FEATURES \
(1ULL << VIRTIO_SCSI_F_INOUT | \
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_remove(struct virtio_scsi_dev *svdev,
Expand Down
32 changes: 32 additions & 0 deletions lib/virtio/virtio_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@

#include "spdk_internal/virtio.h"

#define VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES \
(0)

static int
virtio_user_create_queue(struct virtio_dev *vdev, uint32_t queue_sel)
{
Expand Down Expand Up @@ -286,6 +289,7 @@ static int
virtio_user_set_features(struct virtio_dev *vdev, uint64_t features)
{
struct virtio_user_dev *dev = vdev->ctx;
uint64_t protocol_features;
int ret;

ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features);
Expand All @@ -296,6 +300,23 @@ virtio_user_set_features(struct virtio_dev *vdev, uint64_t features)
vdev->negotiated_features = features;
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;
}

Expand All @@ -312,6 +333,7 @@ static int
virtio_user_setup_queue(struct virtio_dev *vdev, struct virtqueue *vq)
{
struct virtio_user_dev *dev = vdev->ctx;
struct vhost_vring_state state;
uint16_t queue_idx = vq->vq_queue_index;
uint64_t desc_addr, avail_addr, used_addr;
int callfd;
Expand Down Expand Up @@ -339,6 +361,16 @@ virtio_user_setup_queue(struct virtio_dev *vdev, struct virtqueue *vq)
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->kickfds[queue_idx] = kickfd;

Expand Down
1 change: 1 addition & 0 deletions lib/virtio/virtio_user/vhost.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct virtio_user_dev {

uint8_t status;
char path[PATH_MAX];
uint64_t protocol_features;
struct vring vrings[SPDK_VIRTIO_MAX_VIRTQUEUES];
struct virtio_user_backend_ops *ops;
};
Expand Down
3 changes: 3 additions & 0 deletions lib/virtio/virtio_user/vhost_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,14 @@ vhost_user_sock(struct virtio_user_dev *dev,

switch (req) {
case VHOST_USER_GET_FEATURES:
case VHOST_USER_GET_PROTOCOL_FEATURES:
case VHOST_USER_GET_QUEUE_NUM:
need_reply = 1;
break;

case VHOST_USER_SET_FEATURES:
case VHOST_USER_SET_LOG_BASE:
case VHOST_USER_SET_PROTOCOL_FEATURES:
msg.payload.u64 = *((__u64 *)arg);
msg.size = sizeof(msg.payload.u64);
break;
Expand Down Expand Up @@ -414,6 +416,7 @@ vhost_user_sock(struct virtio_user_dev *dev,

switch (req) {
case VHOST_USER_GET_FEATURES:
case VHOST_USER_GET_PROTOCOL_FEATURES:
case VHOST_USER_GET_QUEUE_NUM:
if (msg.size != sizeof(msg.payload.u64)) {
SPDK_WARNLOG("Received bad msg size\n");
Expand Down

0 comments on commit 5910855

Please sign in to comment.