]> git.openfabrics.org - ~shefty/libibverbs.git/commitdiff
Factor out range handling in ibv_madvise_range()
authorAlex Vainman <alexonlists@gmail.com>
Mon, 1 Feb 2010 05:58:04 +0000 (07:58 +0200)
committerRoland Dreier <rolandd@cisco.com>
Fri, 19 Mar 2010 18:04:10 +0000 (11:04 -0700)
Clean up some code in ibv_madvise_range() by adding functions
merge_ranges(), split_range() and get_start_node().

Signed-off-by: Alex Vainman <alexv@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
src/memory.c

index 53d86b70ef7ba0aa16243a8a724a34665ccbdeb2..51839e2ac340208560d3ab39d636e6a7e03f6ff9 100644 (file)
@@ -446,6 +446,49 @@ static struct ibv_mem_node *__mm_find_start(uintptr_t start, uintptr_t end)
        return node;
 }
 
+static struct ibv_mem_node *merge_ranges(struct ibv_mem_node *node,
+                                        struct ibv_mem_node *prev)
+{
+       prev->end = node->end;
+       prev->refcnt = node->refcnt;
+       __mm_remove(node);
+
+       return prev;
+}
+
+static struct ibv_mem_node *split_range(struct ibv_mem_node *node,
+                                       uintptr_t cut_line)
+{
+       struct ibv_mem_node *new_node = NULL;
+
+       new_node = malloc(sizeof *new_node);
+       if (!new_node)
+               return NULL;
+       new_node->start  = cut_line;
+       new_node->end    = node->end;
+       new_node->refcnt = node->refcnt;
+       node->end  = cut_line - 1;
+       __mm_add(new_node);
+
+       return new_node;
+}
+
+static struct ibv_mem_node *get_start_node(uintptr_t start, uintptr_t end,
+                                          int inc)
+{
+       struct ibv_mem_node *node, *tmp = NULL;
+
+       node = __mm_find_start(start, end);
+       if (node->start < start)
+               node = split_range(node, start);
+       else {
+               tmp = __mm_prev(node);
+               if (tmp && tmp->refcnt == node->refcnt + inc)
+                       node = merge_ranges(node, tmp);
+       }
+       return node;
+}
+
 static int ibv_madvise_range(void *base, size_t size, int advice)
 {
        uintptr_t start, end;
@@ -464,46 +507,18 @@ static int ibv_madvise_range(void *base, size_t size, int advice)
 
        pthread_mutex_lock(&mm_mutex);
 
-       node = __mm_find_start(start, end);
-
-       if (node->start < start) {
-               tmp = malloc(sizeof *tmp);
-               if (!tmp) {
-                       ret = -1;
-                       goto out;
-               }
-
-               tmp->start  = start;
-               tmp->end    = node->end;
-               tmp->refcnt = node->refcnt;
-               node->end   = start - 1;
-
-               __mm_add(tmp);
-               node = tmp;
-       } else {
-               tmp = __mm_prev(node);
-               if (tmp && tmp->refcnt == node->refcnt + inc) {
-                       tmp->end = node->end;
-                       tmp->refcnt = node->refcnt;
-                       __mm_remove(node);
-                       node = tmp;
-               }
+       node = get_start_node(start, end, inc);
+       if (!node) {
+               ret = -1;
+               goto out;
        }
 
        while (node && node->start <= end) {
                if (node->end > end) {
-                       tmp = malloc(sizeof *tmp);
-                       if (!tmp) {
+                       if (!split_range(node, end + 1)) {
                                ret = -1;
                                goto out;
                        }
-
-                       tmp->start  = end + 1;
-                       tmp->end    = node->end;
-                       tmp->refcnt = node->refcnt;
-                       node->end   = end;
-
-                       __mm_add(tmp);
                }
 
                node->refcnt += inc;
@@ -537,10 +552,8 @@ static int ibv_madvise_range(void *base, size_t size, int advice)
 
        if (node) {
                tmp = __mm_prev(node);
-               if (tmp && node->refcnt == tmp->refcnt) {
-                       tmp->end = node->end;
-                       __mm_remove(node);
-               }
+               if (tmp && node->refcnt == tmp->refcnt)
+                       node = merge_ranges(node, tmp);
        }
 
 out: