From f3f7438965670f3809cff37b023d1e3172318aab Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Fri, 4 Sep 2020 11:26:58 -0400 Subject: [PATCH] maple_tree: Fix rcu flag again. Signed-off-by: Liam R. Howlett --- include/linux/maple_tree.h | 12 ++++++++---- lib/maple_tree.c | 34 ++++++++-------------------------- lib/test_maple_tree.c | 11 +---------- 3 files changed, 17 insertions(+), 40 deletions(-) diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h index cb1195fe1a04..d30038669523 100644 --- a/include/linux/maple_tree.h +++ b/include/linux/maple_tree.h @@ -442,16 +442,20 @@ static inline void mt_init(struct maple_tree *mt) mt_init_flags(mt, 0); } +static inline bool mt_in_rcu(struct maple_tree *mt) +{ + return mt->ma_flags & MAPLE_USE_RCU; +} /** * mt_clear_in_rcu() - Switch the tree to non-RCU mode. */ static inline void mt_clear_in_rcu(struct maple_tree *mt) { - if ((mt->ma_flags & MAPLE_USE_RCU) == 0) + if (!mt_in_rcu(mt)) return; mtree_lock(mt); - mt->ma_flags &= ~(1 <ma_flags &= ~MAPLE_USE_RCU; mtree_unlock(mt); } @@ -460,11 +464,11 @@ static inline void mt_clear_in_rcu(struct maple_tree *mt) */ static inline void mt_set_in_rcu(struct maple_tree *mt) { - if (mt->ma_flags & MAPLE_USE_RCU) + if (mt_in_rcu(mt)) return; mtree_lock(mt); - mt->ma_flags |= (1 << MAPLE_USE_RCU); + mt->ma_flags |= MAPLE_USE_RCU; mtree_unlock(mt); } diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 205afdaee3d3..9baa67d7b408 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -147,10 +147,6 @@ static unsigned int mt_height(const struct maple_tree *mt) return (mt->ma_flags & MAPLE_HEIGHT_MASK) >> MAPLE_HEIGHT_OFFSET; } -static bool mas_in_rcu(struct ma_state *mas) -{ - return mas->tree->ma_flags & (1 << MAPLE_USE_RCU); -} static void mas_set_height(struct ma_state *mas) { @@ -2699,19 +2695,20 @@ static inline bool mas_reuse_node(struct ma_state *mas, { int i; - if (mas_in_rcu(mas)) + if (mt_in_rcu(mas->tree)) return false; // Need to be rcu safe. mab_mas_cp(bn, 0, bn->b_end, mas); + // Zero end of node. if (end > bn->b_end) { for (i = bn->b_end + 1; i < mt_slot_count(mas->node); i++) { mte_set_rcu_slot(mas->node, i, NULL); if (i < mt_pivot_count(mas->node)) mte_set_pivot(mas->node, i, 0); - //if (!mte_is_leaf(mas->node) && mt_is_alloc(mas->tree)) - // mte_set_gap(mas->node, j, b_node->gap[i]); + // if (!mte_is_leaf(mas->node) && mt_is_alloc(mas->tree)) + // mte_set_gap(mas->node, i, 0); } } @@ -4694,7 +4691,10 @@ void mte_destroy_walk(struct maple_enode *enode, struct maple_tree *mt) node->type = mte_node_type(enode); node->mt.ma_flags = mt->ma_flags; mte_set_node_dead(enode); - call_rcu(&node->rcu, mt_destroy_walk); + if (mt_in_rcu(mt)) + call_rcu(&node->rcu, mt_destroy_walk); + else + mt_destroy_walk(&node->rcu); } /* Interface */ void __init maple_tree_init(void) @@ -4885,24 +4885,6 @@ void *mtree_erase(struct maple_tree *mt, unsigned long index) } EXPORT_SYMBOL(mtree_erase); -void mtree_direct_destroy(struct maple_tree *mt) -{ - mtree_lock(mt); - if (xa_is_node(mt->ma_root)) { - struct maple_node *node = mte_to_node(mt->ma_root); - - node->type = mte_node_type(mt->ma_root); - node->mt.ma_flags = mt->ma_flags; - mte_set_node_dead(mt->ma_root); - mt_destroy_walk(&node->rcu); - } - - mt->ma_flags = 0; - mt->ma_root = NULL; - mtree_unlock(mt); -} -/* mtree_direct_destroy is unsafe to export as it is not rcu safe. */ - void mtree_destroy(struct maple_tree *mt) { mtree_lock(mt); diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index 1a1761f6053e..1da0a048e2d4 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -32438,7 +32438,7 @@ static void check_dup_tree(struct maple_tree *oldmt) check_index_load(&mt, i); check_load(&mt, max + 1, NULL); - mtree_direct_destroy(&mt); + mtree_destroy(&mt); mtree_destroy(oldmt); } @@ -32471,15 +32471,6 @@ static int maple_tree_seed(void) check_new_node(&tree); mtree_destroy(&tree); - - mtree_init(&tree, 0); - check_dfs_preorder(&tree); - mtree_destroy(&tree); - - mtree_init(&tree, 0); - check_dup_tree(&tree); - mtree_destroy(&tree); - mtree_init(&tree, 0); check_dfs_preorder(&tree); mtree_destroy(&tree); -- 2.50.1