Blame SOURCES/0001-vhost-fix-IOTLB-pool-out-of-memory-handling.patch

c7ffa4
From 37771844a05c7b0a7b039dcae1b4b0a69b4acced Mon Sep 17 00:00:00 2001
c7ffa4
From: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
Date: Mon, 5 Feb 2018 16:04:56 +0100
c7ffa4
Subject: [PATCH] vhost: fix IOTLB pool out-of-memory handling
c7ffa4
c7ffa4
In the unlikely case the IOTLB memory pool runs out of memory,
c7ffa4
an issue may happen if all entries are used by the IOTLB cache,
c7ffa4
and an IOTLB miss happen. If the iotlb pending list is empty,
c7ffa4
then no memory is freed and allocation fails a second time.
c7ffa4
c7ffa4
This patch fixes this by doing an IOTLB cache random evict if
c7ffa4
the IOTLB pending list is empty, ensuring the second allocation
c7ffa4
try will succeed.
c7ffa4
c7ffa4
In the same spirit, the opposite is done when inserting an
c7ffa4
IOTLB entry in the IOTLB cache fails due to out of memory. In
c7ffa4
this case, the IOTLB pending is flushed if the IOTLB cache is
c7ffa4
empty to ensure the new entry can be inserted.
c7ffa4
c7ffa4
Fixes: d012d1f293f4 ("vhost: add IOTLB helper functions")
c7ffa4
Fixes: f72c2ad63aeb ("vhost: add pending IOTLB miss request list and helpers")
c7ffa4
Cc: stable@dpdk.org
c7ffa4
c7ffa4
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
---
c7ffa4
 lib/librte_vhost/iotlb.c | 18 +++++++++++++-----
c7ffa4
 1 file changed, 13 insertions(+), 5 deletions(-)
c7ffa4
c7ffa4
diff --git a/lib/librte_vhost/iotlb.c b/lib/librte_vhost/iotlb.c
c7ffa4
index b74cc6a78..72cd27df8 100644
c7ffa4
--- a/lib/librte_vhost/iotlb.c
c7ffa4
+++ b/lib/librte_vhost/iotlb.c
c7ffa4
@@ -50,6 +50,9 @@ struct vhost_iotlb_entry {
c7ffa4
 
c7ffa4
 #define IOTLB_CACHE_SIZE 2048
c7ffa4
 
c7ffa4
+static void
c7ffa4
+vhost_user_iotlb_cache_random_evict(struct vhost_virtqueue *vq);
c7ffa4
+
c7ffa4
 static void
c7ffa4
 vhost_user_iotlb_pending_remove_all(struct vhost_virtqueue *vq)
c7ffa4
 {
c7ffa4
@@ -95,9 +98,11 @@ vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq,
c7ffa4
 
c7ffa4
 	ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
c7ffa4
 	if (ret) {
c7ffa4
-		RTE_LOG(INFO, VHOST_CONFIG,
c7ffa4
-				"IOTLB pool empty, clear pending misses\n");
c7ffa4
-		vhost_user_iotlb_pending_remove_all(vq);
c7ffa4
+		RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
c7ffa4
+		if (!TAILQ_EMPTY(&vq->iotlb_pending_list))
c7ffa4
+			vhost_user_iotlb_pending_remove_all(vq);
c7ffa4
+		else
c7ffa4
+			vhost_user_iotlb_cache_random_evict(vq);
c7ffa4
 		ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
c7ffa4
 		if (ret) {
c7ffa4
 			RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
c7ffa4
@@ -186,8 +191,11 @@ vhost_user_iotlb_cache_insert(struct vhost_virtqueue *vq, uint64_t iova,
c7ffa4
 
c7ffa4
 	ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
c7ffa4
 	if (ret) {
c7ffa4
-		RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, evict one entry\n");
c7ffa4
-		vhost_user_iotlb_cache_random_evict(vq);
c7ffa4
+		RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
c7ffa4
+		if (!TAILQ_EMPTY(&vq->iotlb_list))
c7ffa4
+			vhost_user_iotlb_cache_random_evict(vq);
c7ffa4
+		else
c7ffa4
+			vhost_user_iotlb_pending_remove_all(vq);
c7ffa4
 		ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
c7ffa4
 		if (ret) {
c7ffa4
 			RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
c7ffa4
-- 
c7ffa4
2.14.3
c7ffa4