summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLiam R. Howlett (Oracle) <liam@infradead.org>2026-06-30 15:08:33 -0400
committerAndrew Morton <akpm@linux-foundation.org>2026-07-22 21:11:55 -0700
commit679515dda4078f412ed72c2fc7c5ad7e70849ca8 (patch)
treea3c807f7897b4dfe2f541e2cc57ca40077c0a19b /lib
parent79f3244ffe77d7cf21bfb0d209647bb02d9ee83c (diff)
downloadlinux-next-679515dda4078f412ed72c2fc7c5ad7e70849ca8.tar.gz
linux-next-679515dda4078f412ed72c2fc7c5ad7e70849ca8.zip
maple_tree: optimise mas_wr_node_store() when not in rcu mode
Clearing the entire node on the stack is unnecessary since most of the node will be overwritten anyways. Just clear what isn't used after the data is in place. Benchmarking shows a speedup of 0.67% on a height 4 tree with 2048 entries. Link: https://lore.kernel.org/20260630190843.3563858-10-liam@infradead.org Signed-off-by: Liam R. Howlett (Oracle) <liam@infradead.org> Cc: Boqun Feng <boqun.feng@gmail.com> 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>
Diffstat (limited to 'lib')
-rw-r--r--lib/maple_tree.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index 8f5a7fa10cf4..1c96b3a5dab6 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -3186,7 +3186,7 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
static inline void mas_wr_node_store(struct ma_wr_state *wr_mas)
{
unsigned char dst_offset, offset_end;
- unsigned char copy_size, node_pivots;
+ unsigned char copy_size, node_pivots, node_slots;
struct maple_node reuse, *newnode;
unsigned long *dst_pivots;
void __rcu **dst_slots;
@@ -3199,6 +3199,7 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas)
in_rcu = mt_in_rcu(mas->tree);
offset_end = wr_mas->offset_end;
node_pivots = mt_pivots[wr_mas->type];
+ node_slots = mt_slots[wr_mas->type];
/* Assume last adds an entry */
new_end = mas->end + 1 - offset_end + mas->offset;
if (mas->last == wr_mas->end_piv) {
@@ -3210,7 +3211,6 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas)
if (in_rcu) {
newnode = mas_pop_node(mas);
} else {
- memset(&reuse, 0, sizeof(struct maple_node));
newnode = &reuse;
}
@@ -3254,7 +3254,21 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas)
dst_pivots[new_end] = mas->max;
done:
- mas_leaf_set_meta(newnode, maple_leaf_64, new_end);
+ if (!in_rcu && new_end + 2 < node_slots) {
+ unsigned char clear_from = new_end + 1;
+
+ /*
+ * Note that the last slot is never cleared, since the metadata
+ * will be stored there or it has a value.
+ */
+ memset(dst_slots + clear_from, 0,
+ sizeof(void __rcu *) * (node_slots - clear_from));
+ if (clear_from < node_pivots)
+ memset(dst_pivots + clear_from, 0,
+ sizeof(unsigned long) * (node_pivots - clear_from));
+ }
+
+ mas_leaf_set_meta(newnode, wr_mas->type, new_end);
if (in_rcu) {
struct maple_enode *old_enode = mas->node;