From: Stefan Hajnoczi Date: Wed, 31 Jan 2018 17:46:50 +0000 (+0000) Subject: vhost: add flag for built-in virtio driver X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=1c717af4c699e60081feb1d645f86189551f9a9c;p=dpdk.git vhost: add flag for built-in virtio driver 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 Reviewed-by: Maxime Coquelin Acked-by: Yuanhan Liu --- diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c index 6e3857e7a7..83befdced5 100644 --- a/lib/librte_vhost/socket.c +++ b/lib/librte_vhost/socket.c @@ -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; diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index 1dd9adbc78..a31ca50025 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -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) { diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 646aad30d9..d947bc9e3b 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -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 @@ -357,6 +359,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); diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index edfab3ba61..700aca7ce5 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -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);