vhost: remove pending IOTLB entry if miss request failed
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Mon, 5 Feb 2018 15:04:57 +0000 (16:04 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 5 Feb 2018 18:56:04 +0000 (19:56 +0100)
In case vhost_user_iotlb_miss returns an error, the pending IOTLB
entry has to be removed from the list as no IOTLB update will be
received.

Fixes: fed67a20ac94 ("vhost: introduce guest IOVA to backend VA helper")
Cc: stable@dpdk.org
Suggested-by: Tiwei Bie <tiwei.bie@intel.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
lib/librte_vhost/iotlb.c
lib/librte_vhost/iotlb.h
lib/librte_vhost/vhost.c

index 72cd27d..c11ebca 100644 (file)
@@ -120,7 +120,7 @@ vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq,
        rte_rwlock_write_unlock(&vq->iotlb_pending_lock);
 }
 
-static void
+void
 vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq,
                                uint64_t iova, uint64_t size, uint8_t perm)
 {
index f1a050e..e7083e3 100644 (file)
@@ -71,6 +71,9 @@ bool vhost_user_iotlb_pending_miss(struct vhost_virtqueue *vq, uint64_t iova,
                                                uint8_t perm);
 void vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq, uint64_t iova,
                                                uint8_t perm);
+void vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq, uint64_t iova,
+                                               uint64_t size, uint8_t perm);
+
 int vhost_user_iotlb_init(struct virtio_net *dev, int vq_index);
 
 #endif /* _VHOST_IOTLB_H_ */
index a31ca50..a407067 100644 (file)
@@ -42,7 +42,9 @@ __vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
        if (tmp_size == size)
                return vva;
 
-       if (!vhost_user_iotlb_pending_miss(vq, iova + tmp_size, perm)) {
+       iova += tmp_size;
+
+       if (!vhost_user_iotlb_pending_miss(vq, iova, perm)) {
                /*
                 * iotlb_lock is read-locked for a full burst,
                 * but it only protects the iotlb cache.
@@ -52,8 +54,13 @@ __vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
                 */
                vhost_user_iotlb_rd_unlock(vq);
 
-               vhost_user_iotlb_pending_insert(vq, iova + tmp_size, perm);
-               vhost_user_iotlb_miss(dev, iova + tmp_size, perm);
+               vhost_user_iotlb_pending_insert(vq, iova, perm);
+               if (vhost_user_iotlb_miss(dev, iova, perm)) {
+                       RTE_LOG(ERR, VHOST_CONFIG,
+                               "IOTLB miss req failed for IOVA 0x%" PRIx64 "\n",
+                               iova);
+                       vhost_user_iotlb_pending_remove(vq, iova, 1, perm);
+               }
 
                vhost_user_iotlb_rd_lock(vq);
        }