]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Avoid coalescing on insert if it is not needed.
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Thu, 10 Jan 2019 20:18:01 +0000 (15:18 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Wed, 31 Jul 2019 14:52:35 +0000 (10:52 -0400)
On insert, iterate over the pivots looking for matching ones to
determine if slots need to be coalesced.
Erase always needs to coalesce, so don't check there.

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

index 343a7996765b4bf6b383a04b849098717f034bd8..c088620ffad72439ccef8c7ddaa606b1cdc0825a 100644 (file)
@@ -564,7 +564,12 @@ bool ma_reserved(void *entry)
  */
 void mt_replace(struct ma_state *mas, void *p_entry, bool leaf)
 {
-       struct maple_node *mn = mt_to_node(mas->node);
+       struct maple_node *mn;
+
+       if (mas->node == p_entry)
+               return;
+
+       mn = mt_to_node(mas->node);
        mn->parent = mt_to_node(p_entry)->parent;
        if (!leaf)
                ma_adopt_children(mn);
@@ -579,13 +584,18 @@ void mt_replace(struct ma_state *mas, void *p_entry, bool leaf)
 
                RCU_INIT_POINTER(parent->slot[slot], mas->node);
        }
-       mt_free(mt_to_node(p_entry));
 
+       mt_free(mt_to_node(p_entry));
 }
+
 void *ma_insert(struct ma_state *mas, void *entry)
 {
        void *p_entry; // Previous entry.
        unsigned char slot = MAPLE_NODE_SLOTS;
+       unsigned long last = mas->max;
+       struct maple_range_64 *src;
+       bool coalesce = false;
+       unsigned char s_slot;
        bool leaf;
 
 
@@ -608,17 +618,28 @@ void *ma_insert(struct ma_state *mas, void *entry)
 
        leaf = _mas_walk(mas);
        slot = ma_get_slot(mas);
+       src = mt_to_node(mas->node);
        if (leaf == true && slot != MAPLE_NODE_SLOTS) {
-               if (mt_to_node(mas->node)->slot[slot]) {
+               if (src->slot[slot]) {
                        mas_set_err(mas, -EEXIST);
                        goto exists;
                }
        }
 
        p_entry = mas->node;
-       mas_coalesce(mas);
-       if (mas_is_err(mas))
-               goto error;
+       for (s_slot = 0; s_slot < MAPLE_RANGE64_SLOTS - 1; s_slot++) {
+               if (last == src->pivot[s_slot]) {
+                       coalesce = true;
+                       break;
+               }
+               last = src->pivot[s_slot];
+       }
+
+       if (coalesce) {
+               mas_coalesce(mas);
+               if (mas_is_err(mas))
+                       goto error;
+       }
 
        /* Do the insert */
        _ma_insert(mas, entry, slot);
@@ -711,6 +732,7 @@ int ma_erase(struct ma_state *mas)
        mas_coalesce(mas);
        if (mas_is_err(mas))
                goto error;
+
        mt_replace(mas, p_entry, leaf);
 
 error:
@@ -940,6 +962,7 @@ void mt_dump(const struct maple_tree *mt)
        else
                mt_dump_node(entry, 0, mt_max[mt_node_type(entry)], 0);
 }
+
 void mt_set_non_kernel(unsigned int val)
 {
        kmem_cache_set_non_kernel(maple_node_cache, val);