[dpdk-dev,RFC,09/19] vhost: implement IOTLB events notification mechanism
Checks
Commit Message
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(+)
@@ -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);
@@ -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);
}
@@ -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_ */
@@ -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);
}