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

Message ID 20170704094922.11405-10-maxime.coquelin@redhat.com (mailing list archive)
State Superseded, archived
Delegated to: Yuanhan Liu
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Maxime Coquelin July 4, 2017, 9:49 a.m. UTC
  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@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(+)
  

Patch

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);
 	}