* Sidhartha Kumar <sidhartha.kumar@xxxxxxxxxx> [250221 11:36]: > For the maple tree, the root node is defined to have a depth of 0 with a > height of 1. Each level down from the node, these values are incremented > by 1. Various code paths define a root with depth 1 which is inconsisent > with the definition. Modify the code to be consistent with this > definition. > > Signed-off-by: Sidhartha Kumar <sidhartha.kumar@xxxxxxxxxx> > --- > lib/maple_tree.c | 85 +++++++++++++++++++++++++----------------------- > 1 file changed, 45 insertions(+), 40 deletions(-) > > diff --git a/lib/maple_tree.c b/lib/maple_tree.c > index 0410e13a099e..d7dac3119748 100644 > --- a/lib/maple_tree.c > +++ b/lib/maple_tree.c > @@ -211,14 +211,14 @@ static void ma_free_rcu(struct maple_node *node) > call_rcu(&node->rcu, mt_free_rcu); > } > > -static void mas_set_height(struct ma_state *mas) > +static void mt_set_height(struct maple_tree *mt, unsigned char height) > { > - unsigned int new_flags = mas->tree->ma_flags; > + unsigned int new_flags = mt->ma_flags; > > new_flags &= ~MT_FLAGS_HEIGHT_MASK; > - MAS_BUG_ON(mas, mas->depth > MAPLE_HEIGHT_MAX); > - new_flags |= mas->depth << MT_FLAGS_HEIGHT_OFFSET; > - mas->tree->ma_flags = new_flags; > + MT_BUG_ON(mt, height > MAPLE_HEIGHT_MAX); > + new_flags |= height << MT_FLAGS_HEIGHT_OFFSET; > + mt->ma_flags = new_flags; > } > > static unsigned int mas_mt_height(struct ma_state *mas) > @@ -1375,7 +1375,7 @@ static inline struct maple_enode *mas_start(struct ma_state *mas) > root = mas_root(mas); > /* Tree with nodes */ > if (likely(xa_is_node(root))) { > - mas->depth = 1; > + mas->depth = 0; > mas->status = ma_active; > mas->node = mte_safe_root(root); > mas->offset = 0; > @@ -1716,9 +1716,10 @@ static inline void mas_adopt_children(struct ma_state *mas, > * node as dead. > * @mas: the maple state with the new node > * @old_enode: The old maple encoded node to replace. > + * @new_height: if we are inserting a root node, update the height of the tree > */ > static inline void mas_put_in_tree(struct ma_state *mas, > - struct maple_enode *old_enode) > + struct maple_enode *old_enode, char new_height) > __must_hold(mas->tree->ma_lock) > { > unsigned char offset; > @@ -1727,7 +1728,7 @@ static inline void mas_put_in_tree(struct ma_state *mas, > if (mte_is_root(mas->node)) { > mas_mn(mas)->parent = ma_parent_ptr(mas_tree_parent(mas)); > rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node)); > - mas_set_height(mas); > + mt_set_height(mas->tree, new_height); > } else { > > offset = mte_parent_slot(mas->node); > @@ -1747,10 +1748,10 @@ static inline void mas_put_in_tree(struct ma_state *mas, > * @old_enode: The old maple encoded node. > */ > static inline void mas_replace_node(struct ma_state *mas, > - struct maple_enode *old_enode) > + struct maple_enode *old_enode, unsigned char new_height) > __must_hold(mas->tree->ma_lock) > { > - mas_put_in_tree(mas, old_enode); > + mas_put_in_tree(mas, old_enode, new_height); > mas_free(mas, old_enode); > } > > @@ -2543,7 +2544,7 @@ static inline void mas_topiary_node(struct ma_state *mas, > * > */ > static inline void mas_topiary_replace(struct ma_state *mas, > - struct maple_enode *old_enode) > + struct maple_enode *old_enode, unsigned char new_height) > { > struct ma_state tmp[3], tmp_next[3]; > MA_TOPIARY(subtrees, mas->tree); > @@ -2551,7 +2552,7 @@ static inline void mas_topiary_replace(struct ma_state *mas, > int i, n; > > /* Place data in tree & then mark node as old */ > - mas_put_in_tree(mas, old_enode); > + mas_put_in_tree(mas, old_enode, new_height); > > /* Update the parent pointers in the tree */ > tmp[0] = *mas; > @@ -2639,10 +2640,10 @@ static inline void mas_topiary_replace(struct ma_state *mas, > * Updates gap as necessary. > */ > static inline void mas_wmb_replace(struct ma_state *mas, > - struct maple_enode *old_enode) > + struct maple_enode *old_enode, unsigned char new_height) > { > /* Insert the new data in the tree */ > - mas_topiary_replace(mas, old_enode); > + mas_topiary_replace(mas, old_enode, new_height); > > if (mte_is_leaf(mas->node)) > return; > @@ -2828,6 +2829,7 @@ static void mas_spanning_rebalance(struct ma_state *mas, > { > unsigned char split, mid_split; > unsigned char slot = 0; > + unsigned char new_height = 0; /* used if node is a new root */ > struct maple_enode *left = NULL, *middle = NULL, *right = NULL; > struct maple_enode *old_enode; > > @@ -2877,7 +2879,7 @@ static void mas_spanning_rebalance(struct ma_state *mas, > */ > memset(mast->bn, 0, sizeof(struct maple_big_node)); > mast->bn->type = mte_node_type(left); > - l_mas.depth++; > + new_height++; > > /* Root already stored in l->node. */ > if (mas_is_root_limits(mast->l)) > @@ -2901,8 +2903,10 @@ static void mas_spanning_rebalance(struct ma_state *mas, > continue; > > /* May be a new root stored in mast->bn */ > - if (mas_is_root_limits(mast->orig_l)) > + if (mas_is_root_limits(mast->orig_l)) { > + new_height++; > break; > + } > > mast_spanning_rebalance(mast); > > @@ -2913,7 +2917,7 @@ static void mas_spanning_rebalance(struct ma_state *mas, > > l_mas.node = mt_mk_node(ma_mnode_ptr(mas_pop_node(mas)), > mte_node_type(mast->orig_l->node)); > - l_mas.depth++; > + > mab_mas_cp(mast->bn, 0, mt_slots[mast->bn->type] - 1, &l_mas, true); > mas_set_parent(mas, left, l_mas.node, slot); > if (middle) > @@ -2937,7 +2941,7 @@ static void mas_spanning_rebalance(struct ma_state *mas, > mas->min = l_mas.min; > mas->max = l_mas.max; > mas->offset = l_mas.offset; > - mas_wmb_replace(mas, old_enode); > + mas_wmb_replace(mas, old_enode, new_height); > mtree_range_walk(mas); > return; > } > @@ -3013,6 +3017,7 @@ static inline void mas_destroy_rebalance(struct ma_state *mas, unsigned char end > void __rcu **l_slots, **slots; > unsigned long *l_pivs, *pivs, gap; > bool in_rcu = mt_in_rcu(mas->tree); > + unsigned char new_height = mas_mt_height(mas); > > MA_STATE(l_mas, mas->tree, mas->index, mas->last); > > @@ -3107,7 +3112,7 @@ static inline void mas_destroy_rebalance(struct ma_state *mas, unsigned char end > mas_ascend(mas); > > if (in_rcu) { > - mas_replace_node(mas, old_eparent); > + mas_replace_node(mas, old_eparent, new_height); > mas_adopt_children(mas, mas->node); > } > > @@ -3118,10 +3123,9 @@ static inline void mas_destroy_rebalance(struct ma_state *mas, unsigned char end > * mas_split_final_node() - Split the final node in a subtree operation. > * @mast: the maple subtree state > * @mas: The maple state > - * @height: The height of the tree in case it's a new root. > */ > static inline void mas_split_final_node(struct maple_subtree_state *mast, > - struct ma_state *mas, int height) > + struct ma_state *mas) > { > struct maple_enode *ancestor; > > @@ -3130,7 +3134,6 @@ static inline void mas_split_final_node(struct maple_subtree_state *mast, > mast->bn->type = maple_arange_64; > else > mast->bn->type = maple_range_64; > - mas->depth = height; > } > /* > * Only a single node is used here, could be root. > @@ -3153,8 +3156,7 @@ static inline void mas_split_final_node(struct maple_subtree_state *mast, > * @skip: The number of entries to skip for new nodes insertion. > */ > static inline void mast_fill_bnode(struct maple_subtree_state *mast, > - struct ma_state *mas, > - unsigned char skip) > + struct ma_state *mas, unsigned char skip, int *height) Update the argument list in the comments? > { > bool cp = true; > unsigned char split; > @@ -3226,7 +3228,7 @@ static inline void mast_split_data(struct maple_subtree_state *mast, > * > * Return: True if pushed, false otherwise. > */ > -static inline bool mas_push_data(struct ma_state *mas, int height, > +static inline bool mas_push_data(struct ma_state *mas, int *height, > struct maple_subtree_state *mast, bool left) Update the argument list in the comments? > { > unsigned char slot_total = mast->bn->b_end; > @@ -3283,8 +3285,8 @@ static inline bool mas_push_data(struct ma_state *mas, int height, > mast->orig_l->offset += end + 1; > > mast_split_data(mast, mas, split); > - mast_fill_bnode(mast, mas, 2); > - mas_split_final_node(mast, mas, height + 1); > + mast_fill_bnode(mast, mas, 2, height); > + mas_split_final_node(mast, mas); > return true; > } > > @@ -3297,6 +3299,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) > { > struct maple_subtree_state mast; > int height = 0; > + unsigned int orig_height = mas_mt_height(mas); > unsigned char mid_split, split = 0; > struct maple_enode *old; > > @@ -3323,7 +3326,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) > MA_STATE(prev_r_mas, mas->tree, mas->index, mas->last); > > trace_ma_op(__func__, mas); > - mas->depth = mas_mt_height(mas); > + mas->depth = orig_height; Why is this still needed? It might be worth adding a comment or removing it? > > mast.l = &l_mas; > mast.r = &r_mas; > @@ -3333,7 +3336,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) > > while (height++ <= mas->depth) { > if (mt_slots[b_node->type] > b_node->b_end) { > - mas_split_final_node(&mast, mas, height); > + mas_split_final_node(&mast, mas); > break; > } > > @@ -3348,11 +3351,15 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) > * is a significant savings. > */ > /* Try to push left. */ > - if (mas_push_data(mas, height, &mast, true)) > + if (mas_push_data(mas, &height, &mast, true)) { > + height++; > break; > + } > /* Try to push right. */ > - if (mas_push_data(mas, height, &mast, false)) > + if (mas_push_data(mas, &height, &mast, false)) { > + height++; > break; > + } > > split = mab_calc_split(mas, b_node, &mid_split); > mast_split_data(&mast, mas, split); > @@ -3361,7 +3368,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) > * r->max. > */ > mast.r->max = mas->max; > - mast_fill_bnode(&mast, mas, 1); > + mast_fill_bnode(&mast, mas, 1, &height); > prev_l_mas = *mast.l; > prev_r_mas = *mast.r; > } > @@ -3369,7 +3376,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) > /* Set the original node as dead */ > old = mas->node; > mas->node = l_mas.node; > - mas_wmb_replace(mas, old); > + mas_wmb_replace(mas, old, height); > mtree_range_walk(mas); > return; > } > @@ -3428,8 +3435,7 @@ static inline void mas_root_expand(struct ma_state *mas, void *entry) > if (mas->last != ULONG_MAX) > pivots[++slot] = ULONG_MAX; > > - mas->depth = 1; > - mas_set_height(mas); > + mt_set_height(mas->tree, 1); > ma_set_meta(node, maple_leaf_64, 0, slot); > /* swap the new root into the tree */ > rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node)); > @@ -3673,8 +3679,7 @@ static inline void mas_new_root(struct ma_state *mas, void *entry) > WARN_ON_ONCE(mas->index || mas->last != ULONG_MAX); > > if (!entry) { > - mas->depth = 0; > - mas_set_height(mas); > + mt_set_height(mas->tree, 0); > rcu_assign_pointer(mas->tree->ma_root, entry); > mas->status = ma_start; > goto done; > @@ -3688,8 +3693,7 @@ static inline void mas_new_root(struct ma_state *mas, void *entry) > mas->status = ma_active; > rcu_assign_pointer(slots[0], entry); > pivots[0] = mas->last; > - mas->depth = 1; > - mas_set_height(mas); > + mt_set_height(mas->tree, 1); > rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node)); > > done: > @@ -3808,6 +3812,7 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas, > struct maple_node reuse, *newnode; > unsigned char copy_size, node_pivots = mt_pivots[wr_mas->type]; > bool in_rcu = mt_in_rcu(mas->tree); > + unsigned char height = mas_mt_height(mas); > > if (mas->last == wr_mas->end_piv) > offset_end++; /* don't copy this offset */ > @@ -3864,7 +3869,7 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas, > struct maple_enode *old_enode = mas->node; > > mas->node = mt_mk_node(newnode, wr_mas->type); > - mas_replace_node(mas, old_enode); > + mas_replace_node(mas, old_enode, height); > } else { > memcpy(wr_mas->node, newnode, sizeof(struct maple_node)); > } > -- > 2.43.0 >