Thread (23 messages) 23 messages, 2 authors, 2017-08-31

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

From: Maxime Coquelin <hidden>
Date: 2017-07-04 09:50:17
Subsystem: library code, the rest · Maintainers: Andrew Morton, Linus Torvalds

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 <redacted>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help