Message ID | 20200702074332.1211465-2-amorenoz@redhat.com (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Maxime Coquelin |
Headers | show |
Series | net/virtio: add vhost-user protocol features support | expand |
Context | Check | Description |
---|---|---|
ci/iol-testing | success | Testing PASS |
ci/Intel-compilation | success | Compilation OK |
ci/iol-mellanox-Performance | success | Performance Testing PASS |
ci/iol-intel-Performance | success | Performance Testing PASS |
ci/iol-broadcom-Performance | success | Performance Testing PASS |
ci/checkpatch | warning | coding style issues |
Hi Adrian, > -----Original Message----- > From: Adrian Moreno <amorenoz@redhat.com> > Sent: Thursday, July 2, 2020 3:44 PM > To: dev@dpdk.org > Cc: Xia, Chenbo <chenbo.xia@intel.com>; Wang, Zhihong > <zhihong.wang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Yigit, > Ferruh <ferruh.yigit@intel.com>; maxime.coquelin@redhat.com > Subject: [PATCH v3 1/2] net/virtio: add vhost-user protocol features support > > From: Maxime Coquelin <maxime.coquelin@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.coquelin@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 | 39 ++++++++++++++++++- > .../net/virtio/virtio_user/virtio_user_dev.h | 3 ++ > drivers/net/virtio/virtio_user_ethdev.c | 19 +++++++++ > 5 files changed, 73 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; > }; [snip] > @@ -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,26 @@ 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 +502,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..ccb5a18e2 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,24 @@ 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); > + Should this 'if' be put into above '{}' ? This should be under the condition that VHOST_USER_F_PROTOCOL_FEATURES is supported, right? Like the code change in 'virtio_user_dev_init'. Thanks, Chenbo > dev->device_features |= dev->frontend_features; > > /* umask vhost-user unsupported features */ > -- > 2.26.2
On 7/3/20 10:40 AM, Xia, Chenbo wrote: > Hi Adrian, > >> -----Original Message----- >> From: Adrian Moreno <amorenoz@redhat.com> >> Sent: Thursday, July 2, 2020 3:44 PM >> To: dev@dpdk.org >> Cc: Xia, Chenbo <chenbo.xia@intel.com>; Wang, Zhihong >> <zhihong.wang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Yigit, >> Ferruh <ferruh.yigit@intel.com>; maxime.coquelin@redhat.com >> Subject: [PATCH v3 1/2] net/virtio: add vhost-user protocol features support >> >> From: Maxime Coquelin <maxime.coquelin@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.coquelin@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 | 39 ++++++++++++++++++- >> .../net/virtio/virtio_user/virtio_user_dev.h | 3 ++ >> drivers/net/virtio/virtio_user_ethdev.c | 19 +++++++++ >> 5 files changed, 73 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; >> }; > > [snip] > >> @@ -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,26 @@ 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 +502,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..ccb5a18e2 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,24 @@ 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); >> + > > Should this 'if' be put into above '{}' ? This should be under the condition that > VHOST_USER_F_PROTOCOL_FEATURES is supported, right? Like the code > change in 'virtio_user_dev_init'. > You're right. I'll re-send Thanks > Thanks, > Chenbo > >> dev->device_features |= dev->frontend_features; >> >> /* umask vhost-user unsupported features */ >> -- >> 2.26.2 >
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..c35c11fe5 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..e45159ddd 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,26 @@ 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 +502,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..ccb5a18e2 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,24 @@ 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 */