[dpdk-dev,1/2] vhost: add flag for built-in virtio_net.c driver
Checks
Commit Message
The librte_vhost API is used in two ways:
1. As a vhost net device backend via rte_vhost_enqueue/dequeue_burst().
2. As a library for implementing vhost device backends.
There is no distinction between the two at the API level or in the
librte_vhost implementation. For example, device state is kept in
"struct virtio_net" regardless of whether this is actually a net device
backend or whether the built-in virtio_net.c driver is in use.
The virtio_net.c driver should be a librte_vhost API client just like
the vhost-scsi code and have no special access to vhost.h internals.
Unfortunately, fixing this requires significant librte_vhost API
changes.
This patch takes a different approach: keep the librte_vhost API
unchanged but track whether the built-in virtio_net.c driver is in use.
See the next patch for a bug fix that requires knowledge of whether
virtio_net.c is in use.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
lib/librte_vhost/vhost.h | 3 +++
lib/librte_vhost/socket.c | 15 +++++++++++++++
lib/librte_vhost/vhost.c | 17 ++++++++++++++++-
lib/librte_vhost/virtio_net.c | 14 ++++++++++++++
4 files changed, 48 insertions(+), 1 deletion(-)
Comments
Hi Stefan,
On Wed, Jan 31, 2018 at 05:46:50PM +0000, Stefan Hajnoczi wrote:
> The librte_vhost API is used in two ways:
> 1. As a vhost net device backend via rte_vhost_enqueue/dequeue_burst().
This is how DPDK vhost-user firstly implemented.
> 2. As a library for implementing vhost device backends.
This is how DPDK vhost-use extended later, and vhost-user scsi is
the first one being added.
> There is no distinction between the two at the API level or in the
> librte_vhost implementation. For example, device state is kept in
> "struct virtio_net" regardless of whether this is actually a net device
> backend or whether the built-in virtio_net.c driver is in use.
Indeed. virtio_net should be renamed to "vhost_dev" or something like
this. It's part of something un-finished in the last vhost-user extension
refactoring.
>
> The virtio_net.c driver should be a librte_vhost API client just like
> the vhost-scsi code and have no special access to vhost.h internals.
> Unfortunately, fixing this requires significant librte_vhost API
> changes.
The way I thought was to move the virtio_net.c completely to vhost
pmd (drivers/net/vhost). And let vhost-user just be a generic lib
without any device specific stuff.
Unfortunately, it can not be done recently, as there are still a lot
of applications using rte_vhost_enqueue/dequeue_burst directly, for
example, OVS.
> This patch takes a different approach: keep the librte_vhost API
> unchanged but track whether the built-in virtio_net.c driver is in use.
> See the next patch for a bug fix that requires knowledge of whether
> virtio_net.c is in use.
LGTM.
Thanks.
--yliu
@@ -24,6 +24,8 @@
#define VIRTIO_DEV_RUNNING 1
/* Used to indicate that the device is ready to operate */
#define VIRTIO_DEV_READY 2
+/* Used to indicate that the built-in vhost net device backend is enabled */
+#define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
/* Backend value set by guest. */
#define VIRTIO_DEV_STOPPED -1
@@ -353,6 +355,7 @@ int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
void vhost_enable_dequeue_zero_copy(int vid);
+void vhost_set_builtin_virtio_net(int vid, bool enable);
struct vhost_device_ops const *vhost_driver_callback_get(const char *path);
@@ -40,6 +40,7 @@ struct vhost_user_socket {
bool reconnect;
bool dequeue_zero_copy;
bool iommu_support;
+ bool use_builtin_virtio_net;
/*
* The "supported_features" indicates the feature bits the
@@ -195,6 +196,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
size = strnlen(vsocket->path, PATH_MAX);
vhost_set_ifname(vid, vsocket->path, size);
+ vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
+
if (vsocket->dequeue_zero_copy)
vhost_enable_dequeue_zero_copy(vid);
@@ -527,6 +530,12 @@ rte_vhost_driver_disable_features(const char *path, uint64_t features)
pthread_mutex_lock(&vhost_user.mutex);
vsocket = find_vhost_user_socket(path);
+
+ /* Note that use_builtin_virtio_net is not affected by this function
+ * since callers may want to selectively disable features of the
+ * built-in vhost net device backend.
+ */
+
if (vsocket)
vsocket->features &= ~features;
pthread_mutex_unlock(&vhost_user.mutex);
@@ -567,6 +576,11 @@ rte_vhost_driver_set_features(const char *path, uint64_t features)
if (vsocket) {
vsocket->supported_features = features;
vsocket->features = features;
+
+ /* Anyone setting feature bits is implementing their own vhost
+ * device backend.
+ */
+ vsocket->use_builtin_virtio_net = false;
}
pthread_mutex_unlock(&vhost_user.mutex);
@@ -647,6 +661,7 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
* rte_vhost_driver_set_features(), which will overwrite following
* two values.
*/
+ vsocket->use_builtin_virtio_net = true;
vsocket->supported_features = VIRTIO_NET_SUPPORTED_FEATURES;
vsocket->features = VIRTIO_NET_SUPPORTED_FEATURES;
@@ -251,7 +251,7 @@ reset_device(struct virtio_net *dev)
dev->features = 0;
dev->protocol_features = 0;
- dev->flags = 0;
+ dev->flags &= VIRTIO_DEV_BUILTIN_VIRTIO_NET;
for (i = 0; i < dev->nr_vring; i++)
reset_vring_queue(dev, i);
@@ -287,6 +287,7 @@ vhost_new_device(void)
vhost_devices[i] = dev;
dev->vid = i;
+ dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
dev->slave_req_fd = -1;
return i;
@@ -343,6 +344,20 @@ vhost_enable_dequeue_zero_copy(int vid)
dev->dequeue_zero_copy = 1;
}
+void
+vhost_set_builtin_virtio_net(int vid, bool enable)
+{
+ struct virtio_net *dev = get_device(vid);
+
+ if (dev == NULL)
+ return;
+
+ if (enable)
+ dev->flags |= VIRTIO_DEV_BUILTIN_VIRTIO_NET;
+ else
+ dev->flags &= ~VIRTIO_DEV_BUILTIN_VIRTIO_NET;
+}
+
int
rte_vhost_get_mtu(int vid, uint16_t *mtu)
{
@@ -703,6 +703,13 @@ rte_vhost_enqueue_burst(int vid, uint16_t queue_id,
if (!dev)
return 0;
+ if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+ RTE_LOG(ERR, VHOST_DATA,
+ "(%d) %s: built-in vhost net backend is disabled.\n",
+ dev->vid, __func__);
+ return 0;
+ }
+
if (dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF))
return virtio_dev_merge_rx(dev, queue_id, pkts, count);
else
@@ -1128,6 +1135,13 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
if (!dev)
return 0;
+ if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+ RTE_LOG(ERR, VHOST_DATA,
+ "(%d) %s: built-in vhost net backend is disabled.\n",
+ dev->vid, __func__);
+ return 0;
+ }
+
if (unlikely(!is_valid_virt_queue_idx(queue_id, 1, dev->nr_vring))) {
RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
dev->vid, __func__, queue_id);