net/virtio: add virtio-user protocol features ops
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Tue, 26 Jan 2021 10:16:23 +0000 (11:16 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 29 Jan 2021 17:16:09 +0000 (18:16 +0100)
This patch introduces new callbacks for getting
and setting Vhost-user protocol features.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
drivers/net/virtio/virtio_user/vhost.h
drivers/net/virtio/virtio_user/vhost_user.c
drivers/net/virtio/virtio_user/vhost_vdpa.c
drivers/net/virtio/virtio_user/virtio_user_dev.c
drivers/net/virtio/virtio_user_ethdev.c

index 13a88c7..d805526 100644 (file)
@@ -112,6 +112,8 @@ struct virtio_user_backend_ops {
        int (*set_owner)(struct virtio_user_dev *dev);
        int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
        int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
+       int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t *features);
+       int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t features);
        int (*send_request)(struct virtio_user_dev *dev,
                            enum vhost_user_request req,
                            void *arg);
index 8e5bf33..4877574 100644 (file)
@@ -201,6 +201,62 @@ vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
        return 0;
 }
 
+static int
+vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+       int ret;
+       struct vhost_user_msg msg = {
+               .request = VHOST_USER_GET_PROTOCOL_FEATURES,
+               .flags = VHOST_USER_VERSION,
+       };
+
+       ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+       if (ret < 0)
+               goto err;
+
+       ret = vhost_user_read(dev->vhostfd, &msg);
+       if (ret < 0)
+               goto err;
+
+       if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
+               PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
+               goto err;
+       }
+
+       if (msg.size != sizeof(*features)) {
+               PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
+               goto err;
+       }
+
+       *features = msg.payload.u64;
+
+       return 0;
+err:
+       PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
+
+       return -1;
+}
+
+static int
+vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
+{
+       int ret;
+       struct vhost_user_msg msg = {
+               .request = VHOST_USER_SET_PROTOCOL_FEATURES,
+               .flags = VHOST_USER_VERSION,
+               .size = sizeof(features),
+               .payload.u64 = features,
+       };
+
+       ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR, "Failed to set protocol features");
+               return -1;
+       }
+
+       return 0;
+}
+
 struct walk_arg {
        struct vhost_memory *vm;
        int *fds;
@@ -315,8 +371,6 @@ const char * const vhost_msg_strings[] = {
        [VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
        [VHOST_USER_SET_MEM_TABLE] = "VHOST_SET_MEM_TABLE",
        [VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
-       [VHOST_USER_GET_PROTOCOL_FEATURES] = "VHOST_USER_GET_PROTOCOL_FEATURES",
-       [VHOST_USER_SET_PROTOCOL_FEATURES] = "VHOST_USER_SET_PROTOCOL_FEATURES",
        [VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
        [VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
 };
@@ -354,8 +408,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
                    (!(dev->protocol_features &
                                (1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
                        return -ENOTSUP;
-               /* Fallthrough */
-       case VHOST_USER_GET_PROTOCOL_FEATURES:
                need_reply = 1;
                break;
 
@@ -368,7 +420,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
                if (has_reply_ack)
                        msg.flags |= VHOST_USER_NEED_REPLY_MASK;
                /* Fallthrough */
-       case VHOST_USER_SET_PROTOCOL_FEATURES:
        case VHOST_USER_SET_LOG_BASE:
                msg.payload.u64 = *((__u64 *)arg);
                msg.size = sizeof(m.payload.u64);
@@ -454,7 +505,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 
                switch (req) {
                case VHOST_USER_GET_STATUS:
-               case VHOST_USER_GET_PROTOCOL_FEATURES:
                        if (msg.size != sizeof(m.payload.u64)) {
                                PMD_DRV_LOG(ERR, "Received bad msg size");
                                return -1;
@@ -592,6 +642,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
        .set_owner = vhost_user_set_owner,
        .get_features = vhost_user_get_features,
        .set_features = vhost_user_set_features,
+       .get_protocol_features = vhost_user_get_protocol_features,
+       .set_protocol_features = vhost_user_set_protocol_features,
        .send_request = vhost_user_sock,
        .enable_qp = vhost_user_enable_queue_pair
 };
index 22a3295..f627afb 100644 (file)
@@ -105,6 +105,18 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev)
        return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
 }
 
+static int
+vhost_vdpa_get_backend_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+       return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_BACKEND_FEATURES, features);
+}
+
+static int
+vhost_vdpa_set_backend_features(struct virtio_user_dev *dev, uint64_t features)
+{
+       return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_BACKEND_FEATURES, &features);
+}
+
 static int
 vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
 {
@@ -447,6 +459,8 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
        .set_owner = vhost_vdpa_set_owner,
        .get_features = vhost_vdpa_get_features,
        .set_features = vhost_vdpa_set_features,
+       .get_protocol_features = vhost_vdpa_get_backend_features,
+       .set_protocol_features = vhost_vdpa_set_backend_features,
        .send_request = vhost_vdpa_send_request,
        .enable_qp = vhost_vdpa_enable_queue_pair,
        .dma_map = vhost_vdpa_dma_map_batch,
index 1f3bbae..45417bb 100644 (file)
@@ -505,22 +505,16 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 
                if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
                                (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)) {
-                       if (dev->ops->send_request(dev,
-                                       VHOST_USER_GET_PROTOCOL_FEATURES,
-                                       &protocol_features))
+                       if (dev->ops->get_protocol_features(dev, &protocol_features))
                                return -1;
 
                        dev->protocol_features &= protocol_features;
 
-                       if (dev->ops->send_request(dev,
-                                       VHOST_USER_SET_PROTOCOL_FEATURES,
-                                       &dev->protocol_features))
+                       if (dev->ops->set_protocol_features(dev, dev->protocol_features))
                                return -1;
 
-                       if (!(dev->protocol_features &
-                                       (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
-                               dev->unsupported_features |=
-                                       (1ull << VIRTIO_NET_F_MQ);
+                       if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+                               dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
                }
        } else {
                /* We just pretend vhost-user can support all these features.
index 8bbf4cf..9110e29 100644 (file)
@@ -93,23 +93,17 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 
        if (dev->device_features &
                        (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
-               if (dev->ops->send_request(dev,
-                                       VHOST_USER_GET_PROTOCOL_FEATURES,
-                                       &protocol_features))
+               if (dev->ops->get_protocol_features(dev, &protocol_features))
                        return -1;
 
                /* Offer VHOST_USER_PROTOCOL_F_STATUS */
-               dev->protocol_features |=
-                       (1ULL << VHOST_USER_PROTOCOL_F_STATUS);
+               dev->protocol_features |= (1ULL << VHOST_USER_PROTOCOL_F_STATUS);
                dev->protocol_features &= protocol_features;
 
-               if (dev->ops->send_request(dev,
-                                       VHOST_USER_SET_PROTOCOL_FEATURES,
-                                       &dev->protocol_features))
+               if (dev->ops->set_protocol_features(dev, dev->protocol_features))
                        return -1;
 
-               if (!(dev->protocol_features &
-                               (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+               if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
                        dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
        }