From: Liam R. Howlett Date: Thu, 3 Mar 2022 15:47:07 +0000 (-0500) Subject: Fix clearing of implied pivot at end of node in node reuse X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=af169139a3fbb61a4d2ca51a52faea88d7e01c8e;p=users%2Fjedix%2Flinux-maple.git Fix clearing of implied pivot at end of node in node reuse Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index f1fdb441ead7..bb7fa9727378 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -2116,8 +2116,7 @@ static inline unsigned char mas_store_b_node(struct ma_wr_state *wr_mas, /* Copy end data to the end of the node. */ mas_mab_cp(mas, slot, wr_mas->node_end + 1, b_node, ++b_end); - b_end = b_node->b_end - 1; - return b_end; + return b_node->b_end - 1; } /* @@ -3429,27 +3428,25 @@ static int mas_split(struct ma_state *mas, struct maple_big_node *b_node) * * Return: True if node was reused, false otherwise. */ -static inline bool mas_reuse_node(struct ma_state *mas, +static inline bool mas_reuse_node(struct ma_wr_state *wr_mas, struct maple_big_node *bn, unsigned char end) { /* Need to be rcu safe. */ - if (mt_in_rcu(mas->tree)) + if (mt_in_rcu(wr_mas->mas->tree)) return false; - mab_mas_cp(bn, 0, bn->b_end, mas, false); - + mab_mas_cp(bn, 0, bn->b_end, wr_mas->mas, false); if (end > bn->b_end) { - /* Zero end of node. */ - enum maple_type mt = mte_node_type(mas->node); - struct maple_node *mn = mas_mn(mas); - unsigned long *pivots = ma_pivots(mn, mt); - void __rcu **slots = ma_slots(mn, mt); - char clear = mt_slots[mt] - bn->b_end - 2; + char clear = mt_slots[wr_mas->type] - bn->b_end - 2; + if (bn->pivot[bn->b_end] != wr_mas->mas->max) + clear++; + + /* Zero end of node. */ if (clear > 0) { - memset(slots + bn->b_end + 1, 0, + memset(wr_mas->slots + bn->b_end+1, 0, sizeof(void *) * clear); - memset(pivots + bn->b_end + 1, 0, + memset(wr_mas->pivots + bn->b_end+1, 0, sizeof(unsigned long *) * clear); } } @@ -3463,7 +3460,7 @@ static inline bool mas_reuse_node(struct ma_state *mas, * @b_node: The maple big node * @end: The end of the data. */ -static inline int mas_commit_b_node(struct ma_state *mas, +static inline int mas_commit_b_node(struct ma_wr_state *wr_mas, struct maple_big_node *b_node, unsigned char end) { struct maple_node *node; @@ -3471,27 +3468,28 @@ static inline int mas_commit_b_node(struct ma_state *mas, enum maple_type b_type = b_node->type; if ((b_end < mt_min_slots[b_type]) && - (!mte_is_root(mas->node)) && (mas_mt_height(mas) > 1)) - return mas_rebalance(mas, b_node); + (!mte_is_root(wr_mas->mas->node)) && + (mas_mt_height(wr_mas->mas) > 1)) + return mas_rebalance(wr_mas->mas, b_node); if (b_end >= mt_slots[b_type]) - return mas_split(mas, b_node); + return mas_split(wr_mas->mas, b_node); - if (mas_reuse_node(mas, b_node, end)) + if (mas_reuse_node(wr_mas, b_node, end)) goto reuse_node; - mas_node_count(mas, 1); - if (mas_is_err(mas)) + mas_node_count(wr_mas->mas, 1); + if (mas_is_err(wr_mas->mas)) return 0; - node = mas_pop_node(mas); - node->parent = mas_mn(mas)->parent; - mas->node = mt_mk_node(node, b_type); - mab_mas_cp(b_node, 0, b_end, mas, true); + node = mas_pop_node(wr_mas->mas); + node->parent = mas_mn(wr_mas->mas)->parent; + wr_mas->mas->node = mt_mk_node(node, b_type); + mab_mas_cp(b_node, 0, b_end, wr_mas->mas, true); - mas_replace(mas, false); + mas_replace(wr_mas->mas, false); reuse_node: - mas_update_gap(mas); + mas_update_gap(wr_mas->mas); return 1; } @@ -4227,7 +4225,7 @@ slow_path: sizeof(unsigned long) * zero); trace_ma_write(__func__, mas, 0, wr_mas->entry); - mas_commit_b_node(mas, &b_node, wr_mas->node_end); + mas_commit_b_node(wr_mas, &b_node, wr_mas->node_end); } /*