|
|
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 |
|