]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Store XA_RETRY_ENTRY on erase
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 2 Aug 2019 15:21:12 +0000 (11:21 -0400)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 2 Aug 2019 15:21:12 +0000 (11:21 -0400)
Avoid using slots again until an RCU freeing cycle is complete by storing XA_RETRY_ENTRY

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

index e8c055d67249edd5ceca2f98d427051643e86f29..07be6c796b088daf14f134a12463c01322919d4b 100644 (file)
@@ -3307,9 +3307,11 @@ static inline bool mas_skip_node(struct ma_state *mas)
        return true;
 }
 /* Private
- * Find the range in which index resides and erase the entire range
+ * ma_erase() - Find the range in which index resides and erase the entire
+ * range.
+ *
  * Any previous pivots with no value will be set to the same pivot value.
- * returns the number of slots that have been erased.
+ * Return: the number of concurrent slots that are NULL or XA_RETRY_ENTRY.
  */
 static inline int ma_erase(struct ma_state *mas)
 {
@@ -3321,7 +3323,7 @@ static inline int ma_erase(struct ma_state *mas)
 
        slot = ma_get_slot(mas);
 
-       ma_update_rcu_slot(mas->node, slot, NULL);
+       ma_update_rcu_slot(mas->node, slot, XA_RETRY_ENTRY);
 
        if ((slot >= slot_cnt - 1))
                return ret;
@@ -3347,14 +3349,18 @@ static inline int ma_erase(struct ma_state *mas)
        }
 
        /* Walk down and set all the previous pivots with NULLs to piv_val */
-       while (--slot >= 0 && ma_get_rcu_slot(mas->node, slot) == NULL) {
+       while (--slot >= 0) {
+               void *entry =  ma_get_rcu_slot(mas->node, slot);
+
+               if (entry && entry != XA_RETRY_ENTRY)
+                       break;
+
                ma_set_pivot(mas->node, slot, piv_val);
                ret++;
        }
 
        /* The error on allocation failure can be ignored */
        mas_coalesce(mas, ++slot);
-
        return ret;
 }