aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Vainman <alexonlists@gmail.com>2010-03-28 20:06:16 +0300
committerRoland Dreier <rolandd@cisco.com>2010-04-21 15:11:38 -0700
commit69c9d02748975807593615934f632e48b4e6f70c (patch)
treec3636aae150f82daa68b729cd12f6ca98a2fdfdd
parent52a27b09fc6b7384c7dd0d7697ce5fe100d9652c (diff)
downloadlibibverbs-69c9d02748975807593615934f632e48b4e6f70c.tar.gz
Undo changes in memory range tree when madvise() fails
ibv_madvise_range() doesn't cleanup if madvise() fails. This patch rolls back changes already made in the memory range tracking tree by madvise() calls before the one that failed. We can do this fairly simply by simply restarting ibv_madvise_range() from the original start to the current location with the opposite advice/inc values. Signed-off-by: Alex Vainman <alexv@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--src/memory.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/memory.c b/src/memory.c
index 03f49c8..ce58ae8 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -527,18 +527,19 @@ static int ibv_madvise_range(void *base, size_t size, int advice)
uintptr_t start, end;
struct ibv_mem_node *node, *tmp;
int inc;
+ int rolling_back = 0;
int ret = 0;
if (!size)
return 0;
- inc = advice == MADV_DONTFORK ? 1 : -1;
-
start = (uintptr_t) base & ~(page_size - 1);
end = ((uintptr_t) (base + size + page_size - 1) &
~(page_size - 1)) - 1;
pthread_mutex_lock(&mm_mutex);
+again:
+ inc = advice == MADV_DONTFORK ? 1 : -1;
node = get_start_node(start, end, inc);
if (!node) {
@@ -576,7 +577,19 @@ static int ibv_madvise_range(void *base, size_t size, int advice)
advice);
if (ret) {
node = undo_node(node, start, inc);
- goto out;
+
+ if (rolling_back || !node)
+ goto out;
+
+ /* madvise failed, roll back previous changes */
+ rolling_back = 1;
+ advice = advice == MADV_DONTFORK ?
+ MADV_DOFORK : MADV_DONTFORK;
+ tmp = __mm_prev(node);
+ if (!tmp || start > tmp->end)
+ goto out;
+ end = tmp->end;
+ goto again;
}
}
@@ -591,6 +604,9 @@ static int ibv_madvise_range(void *base, size_t size, int advice)
}
out:
+ if (rolling_back)
+ ret = -1;
+
pthread_mutex_unlock(&mm_mutex);
return ret;