]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Add restarts for interaters on dead nodes.
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Thu, 1 Aug 2019 01:08:19 +0000 (21:08 -0400)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 30 Oct 2020 18:56:09 +0000 (14:56 -0400)
also fix the testcase for the iterators for the zero entry test.

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

index e88a09faaabfd9c45975ffab9d70d7e85d8037f4..140735796602d6dfc399bbc7c2b1e5676808a49b 100644 (file)
@@ -559,7 +559,7 @@ static inline struct maple_enode *_ma_get_rcu_slot(
        struct maple_enode *p = __ma_get_rcu_slot(mn, slot, type);
 
        if (mt_dead_node(mn))
-               return NULL;
+               return MAS_START;
        return p;
 }
 
@@ -2237,6 +2237,7 @@ mas_next_nentry (struct ma_state *mas, unsigned long max, unsigned long *piv)
 no_entry:
        return false;
 }
+
 static inline unsigned long
 mas_next_entry (struct ma_state *mas, unsigned long max)
 {
@@ -2262,6 +2263,18 @@ mas_next_entry (struct ma_state *mas, unsigned long max)
        }
        return pivot;
 }
+static inline unsigned long
+mas_safe_next_entry (struct ma_state *mas, unsigned long max)
+{
+       unsigned long piv;
+retry:
+       piv = mas_next_entry(mas, max);
+       if (mas->node == MAS_NONE)
+               return piv;
+       if (mas_dead_node(mas, mas->index))
+               goto retry;
+       return piv;
+}
 /* Private
  * Combine nulls with the same pivot value
  *
@@ -2699,7 +2712,10 @@ void *mas_find(struct ma_state *mas, unsigned long max)
 
        if (mas->node == MAS_START) {
                _mas_walk(mas);
+               do {} while(mas_dead_node(mas, mas->index));
+
                slot = ma_get_slot(mas);
+
                last_piv = ma_get_safe_pivot(mas, slot);
                if (slot != MAPLE_NODE_SLOTS)
                        entry = ma_get_rcu_slot(mas->node, slot);
@@ -2712,16 +2728,17 @@ void *mas_find(struct ma_state *mas, unsigned long max)
                }
        }
 
-       last_piv = mas_next_entry(mas, max);
-       if (mas->node == MAS_NONE) {
+       last_piv = mas_safe_next_entry(mas, max);
+       if (mas->node == MAS_NONE)
                goto not_found;
-       }
+
 
        slot = ma_get_slot(mas);
        entry = ma_get_rcu_slot(mas->node, slot);
        if (!entry)
                goto not_found;
 
+
        mas->index = ma_get_prev_pivot(mas, slot) + 1;
 done:
        mas->last = last_piv;
@@ -2749,10 +2766,13 @@ static inline void *mt_find(struct maple_tree *mt, unsigned long start,
 
        rcu_read_lock();
        _mas_walk(&mas);
+       do {} while (mas_dead_node(&mas, mas.index));
+
        slot = ma_get_slot(&mas);
        if (slot != MAPLE_NODE_SLOTS)
                entry = ma_get_rcu_slot(mas.node, slot);
 
+
        if (xa_is_zero(entry))
                entry = NULL;
 
@@ -2760,10 +2780,11 @@ static inline void *mt_find(struct maple_tree *mt, unsigned long start,
                goto done;
 
 retry:
-       mas_next_entry(&mas, max);
+       mas_safe_next_entry(&mas, max);
        if (mas.node == MAS_NONE)
                goto done;
 
+
        slot = ma_get_slot(&mas);
        entry = ma_get_rcu_slot(mas.node, slot);
        if (xa_is_zero(entry))
@@ -2791,7 +2812,7 @@ static inline void *mt_find_after(struct maple_tree *mt, unsigned long *index,
        _mas_walk(&mas);
 retry:
        ma_set_slot(&mas, ma_get_slot(&mas) + 1);
-       mas_next_entry(&mas, max);
+       mas_safe_next_entry(&mas, max);
        if (mas.node == MAS_NONE)
                goto done;
 
index 103ac70cf239b479893c5a9f80db53db252936a1..4b4998cc829133e2993335421a3e609139fc2185 100644 (file)
@@ -412,9 +412,16 @@ static noinline void check_find(struct maple_tree *mt)
                        val = 1;
        }
 
+       val = 0;
        max = 300; // A value big enough to include XA_ZERO_ENTRY at 64.
        mt_for_each(mt, entry, index, max) {
                MT_BUG_ON(mt, xa_mk_value(val) != entry);
+               val <<= 2;
+               if (val == 64) // Skip zero entry.
+                       val <<= 2;
+               // For zero check.
+               if (!val)
+                       val = 1;
        }