> -----Original Message----- > From: Adrian Moreno <amore...@redhat.com> > Sent: Friday, July 3, 2020 11:57 PM > To: dev@dpdk.org > Cc: Xia, Chenbo <chenbo....@intel.com>; Wang, Zhihong > <zhihong.w...@intel.com>; Wang, Xiao W <xiao.w.w...@intel.com>; Yigit, > Ferruh <ferruh.yi...@intel.com>; maxime.coque...@redhat.com > Subject: [PATCH v4 1/2] net/virtio: add vhost-user protocol features support > > From: Maxime Coquelin <maxime.coque...@redhat.com> > > This patch adds support for Vhost-user protocol features. > It is required to support protocol features that were not in initial > Vhost-user > specification, such as reply-ack, MTU... > > Also, this patch prevents Virtio multiqueue feature negotiation if the slave > does > not support MQ protocol feature as stated in Vhost-user specification: > "The multiple queues feature is supported only when the protocol feature > ``VHOST_USER_PROTOCOL_F_MQ`` (bit 0) is set." > > Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com> > --- > drivers/net/virtio/virtio_user/vhost.h | 9 +++++ > drivers/net/virtio/virtio_user/vhost_user.c | 5 +++ > .../net/virtio/virtio_user/virtio_user_dev.c | 40 ++++++++++++++++++- > .../net/virtio/virtio_user/virtio_user_dev.h | 3 ++ > drivers/net/virtio/virtio_user_ethdev.c | 20 ++++++++++ > 5 files changed, 75 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/virtio/virtio_user/vhost.h > b/drivers/net/virtio/virtio_user/vhost.h > index 1e784e58e..9ace1a90c 100644 > --- a/drivers/net/virtio/virtio_user/vhost.h > +++ b/drivers/net/virtio/virtio_user/vhost.h > @@ -44,6 +44,15 @@ struct vhost_vring_addr { > uint64_t log_guest_addr; > }; > > +#ifndef VHOST_USER_F_PROTOCOL_FEATURES > +#define VHOST_USER_F_PROTOCOL_FEATURES 30 #endif > + > +/** Protocol features. */ > +#ifndef VHOST_USER_PROTOCOL_F_MQ > +#define VHOST_USER_PROTOCOL_F_MQ 0 > +#endif > + > enum vhost_user_request { > VHOST_USER_NONE = 0, > VHOST_USER_GET_FEATURES = 1, > diff --git a/drivers/net/virtio/virtio_user/vhost_user.c > b/drivers/net/virtio/virtio_user/vhost_user.c > index 74b82e56e..e33067561 100644 > --- a/drivers/net/virtio/virtio_user/vhost_user.c > +++ b/drivers/net/virtio/virtio_user/vhost_user.c > @@ -241,6 +241,8 @@ 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", > }; > > static int > @@ -269,10 +271,12 @@ vhost_user_sock(struct virtio_user_dev *dev, > > switch (req) { > case VHOST_USER_GET_FEATURES: > + case VHOST_USER_GET_PROTOCOL_FEATURES: > need_reply = 1; > break; > > case VHOST_USER_SET_FEATURES: > + case VHOST_USER_SET_PROTOCOL_FEATURES: > case VHOST_USER_SET_LOG_BASE: > msg.payload.u64 = *((__u64 *)arg); > msg.size = sizeof(m.payload.u64); > @@ -351,6 +355,7 @@ vhost_user_sock(struct virtio_user_dev *dev, > > switch (req) { > case VHOST_USER_GET_FEATURES: > + case VHOST_USER_GET_PROTOCOL_FEATURES: > if (msg.size != sizeof(m.payload.u64)) { > PMD_DRV_LOG(ERR, "Received bad msg size"); > return -1; > diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c > b/drivers/net/virtio/virtio_user/virtio_user_dev.c > index 7fb135f49..105536d35 100644 > --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c > +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c > @@ -151,8 +151,10 @@ virtio_user_start_device(struct virtio_user_dev *dev) > if (virtio_user_queue_setup(dev, virtio_user_create_queue) < 0) > goto error; > > - /* Step 1: set features */ > + /* Step 1: negotiate protocol features & set features */ > features = dev->features; > + > + > /* Strip VIRTIO_NET_F_MAC, as MAC address is handled in vdev init */ > features &= ~(1ull << VIRTIO_NET_F_MAC); > /* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know > */ @@ -417,13 +419,19 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) > 1ULL << VIRTIO_NET_F_GUEST_TSO6 | \ > 1ULL << VIRTIO_F_IN_ORDER | \ > 1ULL << VIRTIO_F_VERSION_1 | \ > - 1ULL << VIRTIO_F_RING_PACKED) > + 1ULL << VIRTIO_F_RING_PACKED | \ > + 1ULL << VHOST_USER_F_PROTOCOL_FEATURES) > + > +#define VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES \ > + (1ULL << VHOST_USER_PROTOCOL_F_MQ) > > int > virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, > int cq, int queue_size, const char *mac, char **ifname, > int server, int mrg_rxbuf, int in_order, int packed_vq) { > + uint64_t protocol_features = 0; > + > pthread_mutex_init(&dev->mutex, NULL); > strlcpy(dev->path, path, PATH_MAX); > dev->started = 0; > @@ -434,6 +442,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char > *path, int queues, > dev->mac_specified = 0; > dev->frontend_features = 0; > dev->unsupported_features = ~VIRTIO_USER_SUPPORTED_FEATURES; > + dev->protocol_features = > VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES; > parse_mac(dev, mac); > > if (*ifname) { > @@ -446,6 +455,10 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char > *path, int queues, > return -1; > } > > + if (!is_vhost_user_by_type(dev->path)) > + dev->unsupported_features |= > + (1ULL << VHOST_USER_F_PROTOCOL_FEATURES); > + > if (!dev->is_server) { > if (dev->ops->send_request(dev, VHOST_USER_SET_OWNER, > NULL) < 0) { > @@ -460,6 +473,27 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char > *path, int queues, > strerror(errno)); > return -1; > } > + > + > + if (dev->device_features & > + (1ULL << > VHOST_USER_F_PROTOCOL_FEATURES)) { > + if (dev->ops->send_request(dev, > + > VHOST_USER_GET_PROTOCOL_FEATURES, > + &protocol_features)) > + return -1; > + > + dev->protocol_features &= protocol_features; > + > + if (dev->ops->send_request(dev, > + > VHOST_USER_SET_PROTOCOL_FEATURES, > + &dev->protocol_features)) > + return -1; > + > + 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. > * Note that this could be problematic that if some feature is > @@ -469,6 +503,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char > *path, int queues, > dev->device_features = VIRTIO_USER_SUPPORTED_FEATURES; > } > > + > + > if (!mrg_rxbuf) > dev->unsupported_features |= (1ull << > VIRTIO_NET_F_MRG_RXBUF); > > diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h > b/drivers/net/virtio/virtio_user/virtio_user_dev.h > index 3b6b6065a..56e638f8a 100644 > --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h > +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h > @@ -40,6 +40,9 @@ struct virtio_user_dev { > uint64_t device_features; /* supported features by device */ > uint64_t frontend_features; /* enabled frontend features */ > uint64_t unsupported_features; /* unsupported features mask > */ > + uint64_t protocol_features; /* negotiated protocol features > + * (Vhost-user only) > + */ > uint8_t status; > uint16_t port_id; > uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; > diff --git a/drivers/net/virtio/virtio_user_ethdev.c > b/drivers/net/virtio/virtio_user_ethdev.c > index 798f191c3..e51425c4f 100644 > --- a/drivers/net/virtio/virtio_user_ethdev.c > +++ b/drivers/net/virtio/virtio_user_ethdev.c > @@ -68,6 +68,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) > int connectfd; > struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id]; > struct virtio_hw *hw = eth_dev->data->dev_private; > + uint64_t protocol_features; > > connectfd = accept(dev->listenfd, NULL, NULL); > if (connectfd < 0) > @@ -81,6 +82,25 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) > return -1; > } > > + if (dev->device_features & > + (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) { > + if (dev->ops->send_request(dev, > + > VHOST_USER_GET_PROTOCOL_FEATURES, > + &protocol_features)) > + return -1; > + > + dev->protocol_features &= protocol_features; > + > + if (dev->ops->send_request(dev, > + > VHOST_USER_SET_PROTOCOL_FEATURES, > + &dev->protocol_features)) > + return -1; > + > + if (!(dev->protocol_features & > + (1ULL << VHOST_USER_PROTOCOL_F_MQ))) > + dev->unsupported_features |= (1ull << > VIRTIO_NET_F_MQ); > + } > + > dev->device_features |= dev->frontend_features; > > /* umask vhost-user unsupported features */ > -- > 2.26.2
Reviewed-by: Chenbo Xia <chenbo....@intel.com>