]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Avoid allocating a node in coalescing until necessary
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 11 Jan 2019 02:01:25 +0000 (21:01 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Tue, 5 Jan 2021 17:28:00 +0000 (12:28 -0500)
When looping through a node, don't create a new node if there is no need
to do so.

Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c

index c088620ffad72439ccef8c7ddaa606b1cdc0825a..13958fa73eb99ceeffd929e6d9c0a787d626d5c6 100644 (file)
@@ -446,31 +446,47 @@ static int mas_coalesce(struct ma_state *mas)
        struct maple_range_64 *src = &mt_to_node(mas->node)->mr64;
        unsigned char s_slot, d_slot = 0;
        unsigned long last = mas->max;
-       struct maple_range_64 *dst;
+       struct maple_range_64 *dst = NULL;
        struct maple_node *mn;
 
-       /* Allocate a new node */
-       mas_node_cnt(mas, 1);
-       if (mas_is_err(mas))
-               return 0;
-
-       mn = ma_next_alloc(mas);
-       dst = &mn->mr64;
-       mas->node = mt_mk_node(mn, maple_leaf_64);
 
        for (s_slot = 0; s_slot < MAPLE_RANGE64_SLOTS; s_slot++) {
                if (s_slot < MAPLE_RANGE64_SLOTS - 1) {
-                       if (last == src->pivot[s_slot])
+                       if (last == src->pivot[s_slot]) {
+                               if (!dst) {
+                                       int i = 0;
+                                       /* Allocate a new node */
+                                       mas_node_cnt(mas, 1);
+                                       if (mas_is_err(mas))
+                                               return 0;
+
+                                       mn = ma_next_alloc(mas);
+                                       dst = &mn->mr64;
+                                       mn->parent = src->parent;
+                                       for (i = 0; i <= s_slot;i++)
+                                       {
+                                               RCU_INIT_POINTER(dst->slot[i],
+                                                                src->slot[i]);
+                                               dst->pivot[i] = src->pivot[i];
+                                       }
+                                       d_slot = s_slot;
+                                       mas->node = mt_mk_node(mn,
+                                                              maple_leaf_64);
+                               }
                                continue;
+                       }
 
                        if (s_slot != 0 && src->pivot[s_slot] == 0)
                                break;
 
-                       dst->pivot[d_slot] = src->pivot[s_slot];
-               }
+                       last = src->pivot[s_slot];
 
-               RCU_INIT_POINTER(dst->slot[d_slot], src->slot[s_slot]);
-               last = dst->pivot[d_slot++];
+                       if (dst)
+                               dst->pivot[d_slot] = src->pivot[s_slot];
+               }
+               if (dst)
+                       RCU_INIT_POINTER(dst->slot[d_slot++],
+                                        src->slot[s_slot]);
        }
        return s_slot - d_slot;
 }