vhost: remove pending IOTLB entry if miss request failed
[dpdk.git] / lib / librte_vhost / iotlb.c
index 066c37a..c11ebca 100644 (file)
@@ -50,6 +50,9 @@ struct vhost_iotlb_entry {
 
 #define IOTLB_CACHE_SIZE 2048
 
+static void
+vhost_user_iotlb_cache_random_evict(struct vhost_virtqueue *vq);
+
 static void
 vhost_user_iotlb_pending_remove_all(struct vhost_virtqueue *vq)
 {
@@ -95,9 +98,11 @@ vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq,
 
        ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
        if (ret) {
-               RTE_LOG(INFO, VHOST_CONFIG,
-                               "IOTLB pool empty, clear pending misses\n");
-               vhost_user_iotlb_pending_remove_all(vq);
+               RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
+               if (!TAILQ_EMPTY(&vq->iotlb_pending_list))
+                       vhost_user_iotlb_pending_remove_all(vq);
+               else
+                       vhost_user_iotlb_cache_random_evict(vq);
                ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
                if (ret) {
                        RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
@@ -115,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)
 {
@@ -186,8 +191,11 @@ vhost_user_iotlb_cache_insert(struct vhost_virtqueue *vq, uint64_t iova,
 
        ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
        if (ret) {
-               RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, evict one entry\n");
-               vhost_user_iotlb_cache_random_evict(vq);
+               RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
+               if (!TAILQ_EMPTY(&vq->iotlb_list))
+                       vhost_user_iotlb_cache_random_evict(vq);
+               else
+                       vhost_user_iotlb_pending_remove_all(vq);
                ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
                if (ret) {
                        RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
@@ -300,7 +308,7 @@ vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
 {
        char pool_name[RTE_MEMPOOL_NAMESIZE];
        struct vhost_virtqueue *vq = dev->virtqueue[vq_index];
-       int ret = -1, socket;
+       int socket = 0;
 
        if (vq->iotlb_pool) {
                /*
@@ -309,14 +317,12 @@ vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
                 */
                vhost_user_iotlb_cache_remove_all(vq);
                vhost_user_iotlb_pending_remove_all(vq);
-               return 0;
        }
 
 #ifdef RTE_LIBRTE_VHOST_NUMA
-       ret = get_mempolicy(&socket, NULL, 0, vq, MPOL_F_NODE | MPOL_F_ADDR);
-#endif
-       if (ret)
+       if (get_mempolicy(&socket, NULL, 0, vq, MPOL_F_NODE | MPOL_F_ADDR) != 0)
                socket = 0;
+#endif
 
        rte_rwlock_init(&vq->iotlb_lock);
        rte_rwlock_init(&vq->iotlb_pending_lock);