New upstream version 17.11.1
[deb_dpdk.git] / lib / librte_vhost / iotlb.c
index b74cc6a..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");