Commit 1238f6a2 authored by Liam R. Howlett's avatar Liam R. Howlett Committed by Andrew Morton

maple_tree: introduce mas_put_in_tree()

mas_replace() has a single user that takes a flag which is now always
true.  Replace this function with mas_put_in_tree() to better align with
mas_replace_node().  Inline the remaining logic into the only caller;
mas_wmb_replace().

Link: https://lkml.kernel.org/r/20230804165951.2661157-4-Liam.Howlett@oracle.comSigned-off-by: default avatarLiam R. Howlett <Liam.Howlett@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 72bcf4aa
...@@ -1715,45 +1715,32 @@ static inline void mas_adopt_children(struct ma_state *mas, ...@@ -1715,45 +1715,32 @@ static inline void mas_adopt_children(struct ma_state *mas,
} }
/* /*
* mas_replace() - Replace a maple node in the tree with mas->node. Uses the * mas_put_in_tree() - Put a new node in the tree, smp_wmb(), and mark the old
* parent encoding to locate the maple node in the tree. * node as dead.
* @mas - the ma_state to use for operations. * @mas - the maple state with the new node
* @advanced - boolean to adopt the child nodes and free the old node (false) or * @old_enode - The old maple encoded node to replace.
* leave the node (true) and handle the adoption and free elsewhere.
*/ */
static inline void mas_replace(struct ma_state *mas, bool advanced) static inline void mas_put_in_tree(struct ma_state *mas,
struct maple_enode *old_enode)
__must_hold(mas->tree->ma_lock) __must_hold(mas->tree->ma_lock)
{ {
struct maple_node *mn = mas_mn(mas); unsigned char offset;
struct maple_enode *old_enode; void __rcu **slots;
unsigned char offset = 0;
void __rcu **slots = NULL;
if (ma_is_root(mn)) {
old_enode = mas_root_locked(mas);
} else {
offset = mte_parent_slot(mas->node);
slots = ma_slots(mte_parent(mas->node),
mas_parent_type(mas, mas->node));
old_enode = mas_slot_locked(mas, slots, offset);
}
if (!advanced && !mte_is_leaf(mas->node))
mas_adopt_children(mas, mas->node);
if (mte_is_root(mas->node)) { if (mte_is_root(mas->node)) {
mn->parent = ma_parent_ptr( mas_mn(mas)->parent = ma_parent_ptr(
((unsigned long)mas->tree | MA_ROOT_PARENT)); ((unsigned long)mas->tree | MA_ROOT_PARENT));
rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node)); rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
mas_set_height(mas); mas_set_height(mas);
} else { } else {
offset = mte_parent_slot(mas->node);
slots = ma_slots(mte_parent(mas->node),
mas_parent_type(mas, mas->node));
rcu_assign_pointer(slots[offset], mas->node); rcu_assign_pointer(slots[offset], mas->node);
} }
if (!advanced) { mte_set_node_dead(old_enode);
mte_set_node_dead(old_enode);
mas_free(mas, old_enode);
}
} }
/* /*
...@@ -1767,22 +1754,7 @@ static inline void mas_replace_node(struct ma_state *mas, ...@@ -1767,22 +1754,7 @@ static inline void mas_replace_node(struct ma_state *mas,
struct maple_enode *old_enode) struct maple_enode *old_enode)
__must_hold(mas->tree->ma_lock) __must_hold(mas->tree->ma_lock)
{ {
if (mte_is_root(mas->node)) { mas_put_in_tree(mas, old_enode);
mas_mn(mas)->parent = ma_parent_ptr(
((unsigned long)mas->tree | MA_ROOT_PARENT));
rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
mas_set_height(mas);
} else {
unsigned char offset = 0;
void __rcu **slots = NULL;
offset = mte_parent_slot(mas->node);
slots = ma_slots(mte_parent(mas->node),
mas_parent_type(mas, mas->node));
rcu_assign_pointer(slots[offset], mas->node);
}
mte_set_node_dead(old_enode);
mas_free(mas, old_enode); mas_free(mas, old_enode);
} }
...@@ -2789,11 +2761,20 @@ static inline void mas_wmb_replace(struct ma_state *mas, ...@@ -2789,11 +2761,20 @@ static inline void mas_wmb_replace(struct ma_state *mas,
struct ma_topiary *free, struct ma_topiary *free,
struct ma_topiary *destroy) struct ma_topiary *destroy)
{ {
/* All nodes must see old data as dead prior to replacing that data */ struct maple_enode *old_enode;
smp_wmb(); /* Needed for RCU */
if (mte_is_root(mas->node)) {
old_enode = mas_root_locked(mas);
} else {
unsigned char offset = mte_parent_slot(mas->node);
void __rcu **slots = ma_slots(mte_parent(mas->node),
mas_parent_type(mas, mas->node));
old_enode = mas_slot_locked(mas, slots, offset);
}
/* Insert the new data in the tree */ /* Insert the new data in the tree */
mas_replace(mas, true); mas_put_in_tree(mas, old_enode);
if (!mte_is_leaf(mas->node)) if (!mte_is_leaf(mas->node))
mas_descend_adopt(mas); mas_descend_adopt(mas);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment