From: Liam R. Howlett Date: Wed, 9 Sep 2020 19:40:57 +0000 (-0400) Subject: maple_tree: Rewrite mas_next_node to be less complex. X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=657fd9442644fa93b51ce3009e5e2332edd53dfe;p=users%2Fjedix%2Flinux-maple.git maple_tree: Rewrite mas_next_node to be less complex. Remove double while (1) loop, pull in parent slot lookup. Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index ff4fc500c640..8647337a66df 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -1818,8 +1818,6 @@ static inline bool mast_cousin_rebalance_right(struct maple_subtree_state *mast) MA_STATE(tmp, mast->orig_r->tree, mast->orig_r->index, mast->orig_r->last); mas_dup_state(&tmp, mast->orig_r); - mas_set_offset(mast->orig_r, - mte_parent_slot(mast->orig_r->node)); mas_next_node(mast->orig_r, ULONG_MAX); if (!mas_is_none(mast->orig_r)) { mast_rebalance_next(mast, old_r); @@ -3239,76 +3237,57 @@ no_entry: static inline unsigned long mas_next_node(struct ma_state *mas, unsigned long max) { - int level; - unsigned long start_piv; + unsigned long start_piv, prev_piv, pivot; + int offset, level = 0; + enum maple_type mt; + void **slots; restart_next_node: level = 0; - while (1) { - int offset; - struct maple_enode *mn; - unsigned long prev_piv; - enum maple_type mt; - void **slots; - - if (mte_is_root(mas->node) || mas->node == MAS_NONE) + while (!mas_is_none(mas)) { + if (mte_is_root(mas->node)) goto no_entry; - mn = mas->node; - offset= mas_offset(mas); - start_piv = mas_safe_pivot(mas, offset); - level++; + offset = mte_parent_slot(mas->node); mas_ascend(mas); - + start_piv = mas_safe_pivot(mas, offset); if (mas_dead_node(mas, start_piv)) goto restart_next_node; + level++; mt = mte_node_type(mas->node); slots = ma_get_slots(mas_mn(mas), mt); prev_piv = mas_safe_pivot(mas, offset); - while (++offset< mt_slots[mt]) { - unsigned long pivot = mas_safe_pivot(mas, offset); - - if (prev_piv > max) - goto no_entry; - - if (!pivot && offset) - break; - - mn = rcu_dereference(slots[offset]); - if (!mn) { - prev_piv = pivot; - continue; - } + if (prev_piv > max) + goto no_entry; - mas->min = prev_piv + 1; - mas->max = pivot; + if (prev_piv == mas->max) // last in node. + continue; - if (level == 1) { - mas_set_offset(mas, offset); - mas->node = mn; - if (mas_dead_node(mas, start_piv)) - goto restart_next_node; + if (++offset >= mt_slots[mt]) + continue; - return pivot; - } + pivot = mas_safe_pivot(mas, offset); + // Descend, if necessary. + while (level > 1) { level--; - mas->node = mn; - offset = -1; + mas->node = rcu_dereference(slots[offset]); mt = mte_node_type(mas->node); slots = ma_get_slots(mas_mn(mas), mt); + offset = 0; + pivot = mas_safe_pivot(mas, offset); } - if (mte_is_root(mas->node)) - goto no_entry; - mas_set_offset(mas, mte_parent_slot(mas->node)); + mas->node = rcu_dereference(slots[offset]); + mas->min = prev_piv + 1; + mas->max = pivot; + return mas->max; } no_entry: mas->node = MAS_NONE; return mas->max; - } /* @@ -3459,7 +3438,6 @@ retry: *range_start = mas->last + 1; while (!mas_is_none(mas)) { - unsigned char p_slot = 0; struct maple_enode *last_node = mas->node; slot = mas_offset(mas); @@ -3483,8 +3461,6 @@ retry: } next_node: - p_slot = mte_parent_slot(mas->node); - mas_set_offset(mas, p_slot); mas_next_node(mas, limit); mas_set_offset(mas, 0); } @@ -5175,7 +5151,6 @@ static inline void mas_dfs_postorder(struct ma_state *mas, unsigned long max) struct maple_enode *p = MAS_NONE, *mn = mas->node; unsigned long p_min, p_max; - mas_set_offset(mas, mte_parent_slot(mas->node)); mas_next_node(mas, max); if (!mas_is_none(mas)) return;