[dpdk-dev] [RFC 09/19] vhost: implement IOTLB events notification mechanism

Maxime Coquelin maxime.coquelin at redhat.com
Tue Jul 4 11:49:12 CEST 2017


In case of IOTLB miss, the processing threads wait for the
IOTLB events to parse the IOTLB cache and find requested
entries.

This event is to be raised on IOTLB update as it might match
the awaited entry, on IOTLB invalidate to stop the ring if the
invalidate matches ring addresses and on vring stop to be able
to destroy the ring.

Signed-off-by: Maxime Coquelin <maxime.coquelin at redhat.com>
---
 lib/librte_vhost/iotlb.c      |  1 +
 lib/librte_vhost/vhost.c      | 16 ++++++++++++++++
 lib/librte_vhost/vhost.h      |  2 ++
 lib/librte_vhost/vhost_user.c | 10 ++++++++++
 4 files changed, 29 insertions(+)

diff --git a/lib/librte_vhost/iotlb.c b/lib/librte_vhost/iotlb.c
index 02457fa..025d6c6 100644
--- a/lib/librte_vhost/iotlb.c
+++ b/lib/librte_vhost/iotlb.c
@@ -206,6 +206,7 @@ int vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
 		socket = 0;
 
 	rte_rwlock_init(&vq->iotlb_lock);
+	rte_atomic16_init(&vq->iotlb_event);
 
 	TAILQ_INIT(&vq->iotlb_list);
 
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 06b8f20..3897f9c 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -191,6 +191,17 @@ free_device(struct virtio_net *dev)
 	rte_free(dev);
 }
 
+void notify_iotlb_event(struct virtio_net *dev)
+{
+	struct vhost_virtqueue *vq;
+	uint32_t i;
+
+	for (i = 0; i < dev->nr_vring; i++) {
+		vq = dev->virtqueue[i];
+		rte_atomic16_set(&vq->iotlb_event, 1);
+	}
+}
+
 static void
 init_vring_queue(struct virtio_net *dev, uint32_t vring_idx)
 {
@@ -313,6 +324,11 @@ vhost_destroy_device(int vid)
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
+		/*
+		 * Unblock processing threads waiting for
+		 * IOTLB updates, if any.
+		 */
+		notify_iotlb_event(dev);
 		dev->notify_ops->destroy_device(vid);
 	}
 
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 7816a92..3242658 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -119,6 +119,7 @@ struct vhost_virtqueue {
 	rte_rwlock_t	iotlb_lock;
 	struct rte_mempool *iotlb_pool;
 	TAILQ_HEAD(, vhost_iotlb_entry) iotlb_list;
+	rte_atomic16_t		iotlb_event;
 } __rte_cache_aligned;
 
 /* Old kernels have no such macros defined */
@@ -350,5 +351,6 @@ struct vhost_device_ops const *vhost_driver_callback_get(const char *path);
  * TODO: fix it; we have one backend now
  */
 void vhost_backend_cleanup(struct virtio_net *dev);
+void notify_iotlb_event(struct virtio_net *dev);
 
 #endif /* _VHOST_NET_CDEV_H_ */
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 8b4a2b3..6b41fea 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -145,6 +145,11 @@ vhost_user_reset_owner(struct virtio_net *dev)
 {
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
+		/*
+		 * Unblock processing threads waiting for
+		 * IOTLB updates, if any.
+		 */
+		notify_iotlb_event(dev);
 		dev->notify_ops->destroy_device(dev->vid);
 	}
 
@@ -691,6 +696,11 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 	/* We have to stop the queue (virtio) if it is running. */
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
+		/*
+		 * Unblock processing threads waiting for
+		 * IOTLB updates, if any.
+		 */
+		notify_iotlb_event(dev);
 		dev->notify_ops->destroy_device(dev->vid);
 	}
 
-- 
2.9.4



More information about the dev mailing list