mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 15:22:21 -04:00
maple_tree: add bulk parent set helper
Instead of calculating the parent pointer each time for a child, cache the majority of the parent pointer and only change the slot per child. Drop the mas_set_parent() function since the last user has been removed. Testing on a tree containing 2048 entries of height 4 had an increased gain of 3.51% on nodes tracking gaps. Link: https://lore.kernel.org/20260821192627.4085470-12-liam@infradead.org Signed-off-by: Liam R. Howlett (Oracle) <liam@infradead.org> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Breno Leitao <leitao@debian.org> Cc: Chris Mason <clm@meta.com> Cc: Chuck Lever <cel@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Joe Perches <joe@perches.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@surriel.com> Cc: Waiman Long <longman@redhat.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
f0a3892cd7
commit
cf1f9bae5d
@@ -450,46 +450,6 @@ enum maple_type mas_parent_type(struct ma_state *mas, struct maple_enode *enode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mas_set_parent() - Set the parent node and encode the slot
|
||||
* @mas: The maple state
|
||||
* @enode: The encoded maple node.
|
||||
* @parent: The encoded maple node that is the parent of @enode.
|
||||
* @slot: The slot that @enode resides in @parent.
|
||||
*
|
||||
* Slot number is encoded in the enode->parent bit 3-6 or 2-6, depending on the
|
||||
* parent type.
|
||||
*/
|
||||
static inline
|
||||
void mas_set_parent(struct ma_state *mas, struct maple_enode *enode,
|
||||
const struct maple_enode *parent, unsigned char slot)
|
||||
{
|
||||
unsigned long val = (unsigned long)parent;
|
||||
unsigned long shift;
|
||||
unsigned long type;
|
||||
enum maple_type p_type = mte_node_type(parent);
|
||||
|
||||
MAS_BUG_ON(mas, p_type == maple_dense);
|
||||
MAS_BUG_ON(mas, p_type == maple_leaf_64);
|
||||
|
||||
switch (p_type) {
|
||||
case maple_range_64:
|
||||
case maple_arange_64:
|
||||
shift = MAPLE_PARENT_SLOT_SHIFT;
|
||||
type = MAPLE_PARENT_RANGE64;
|
||||
break;
|
||||
default:
|
||||
case maple_dense:
|
||||
case maple_leaf_64:
|
||||
shift = type = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
val &= ~MAPLE_NODE_MASK; /* Clear all node metadata in parent */
|
||||
val |= (slot << shift) | type;
|
||||
mte_to_node(enode)->parent = ma_parent_ptr(val);
|
||||
}
|
||||
|
||||
/*
|
||||
* mte_parent_slot() - get the parent slot of @enode.
|
||||
* @enode: The encoded maple node.
|
||||
@@ -871,6 +831,42 @@ static inline void ma_set_meta_gap(struct maple_node *mn, enum maple_type mt,
|
||||
meta->gap = offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* mas_set_parent_slots() - Bulk operation to set many slot parent pointers
|
||||
* @mas: The maple state
|
||||
* @parent: The encoded maple node that is the parent of @enode.
|
||||
* @slot: The slot that of the @enode.
|
||||
* @start_slot: The offset into @slot
|
||||
* @count: The number of slots to set (eg: exclusive)
|
||||
*/
|
||||
static inline
|
||||
void mas_set_parent_slots(struct ma_state *mas, struct maple_enode *parent,
|
||||
void __rcu **slots, unsigned char start_slot, unsigned char count)
|
||||
{
|
||||
unsigned long val;
|
||||
unsigned long shift;
|
||||
unsigned long type;
|
||||
enum maple_type p_type = mte_node_type(parent);
|
||||
unsigned char i;
|
||||
|
||||
MAS_BUG_ON(mas, p_type != maple_range_64 &&
|
||||
p_type != maple_arange_64);
|
||||
|
||||
shift = MAPLE_PARENT_SLOT_SHIFT;
|
||||
type = MAPLE_PARENT_RANGE64;
|
||||
|
||||
val = (unsigned long)parent;
|
||||
val &= ~MAPLE_NODE_MASK;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned long pval = val | ((start_slot + i) << shift) | type;
|
||||
struct maple_enode *child;
|
||||
|
||||
child = mt_slot_locked(mas->tree, slots, i);
|
||||
mte_to_node(child)->parent = ma_parent_ptr(pval);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mat_add() - Add a @dead_enode to the ma_topiary of a list of dead nodes.
|
||||
* @mat: the ma_topiary, a linked list of dead nodes.
|
||||
@@ -1609,14 +1605,10 @@ static inline void mas_adopt_children(struct ma_state *mas,
|
||||
struct maple_node *node = mte_to_node(parent);
|
||||
void __rcu **slots = ma_slots(node, type);
|
||||
unsigned long *pivots = ma_pivots(node, type);
|
||||
struct maple_enode *child;
|
||||
unsigned char offset;
|
||||
unsigned char end;
|
||||
|
||||
offset = ma_data_end(node, type, pivots, mas->max);
|
||||
do {
|
||||
child = mas_slot_locked(mas, slots, offset);
|
||||
mas_set_parent(mas, child, parent, offset);
|
||||
} while (offset--);
|
||||
end = ma_data_end(node, type, pivots, mas->max);
|
||||
mas_set_parent_slots(mas, parent, slots, 0, end + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1998,15 +1990,10 @@ unsigned long node_copy(struct ma_state *mas, struct maple_node *src,
|
||||
s_slots = ma_slots(src, s_mt) + start;
|
||||
s_pivots = ma_pivots(src, s_mt) + start;
|
||||
memcpy(d_slots, s_slots, size * sizeof(void __rcu *));
|
||||
if (!ma_is_leaf(d_mt) && s_mt == maple_copy) {
|
||||
struct maple_enode *edst = mt_mk_node(dst, d_mt);
|
||||
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
mas_set_parent(mas,
|
||||
mt_slot_locked(mas->tree, d_slots, i),
|
||||
edst, d_start + i);
|
||||
}
|
||||
if (!ma_is_leaf(d_mt) && s_mt == maple_copy)
|
||||
mas_set_parent_slots(mas, mt_mk_node(dst, d_mt),
|
||||
d_slots, d_start, size);
|
||||
|
||||
d_gaps = ma_gaps(dst, d_mt);
|
||||
if (d_gaps) {
|
||||
|
||||
Reference in New Issue
Block a user