From e835ffdfbc9365ff0d33dd5a09fe384d8e6d4ce3 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Mon, 12 Jun 2023 16:39:52 -0400 Subject: [PATCH] FROMLIST: maple_tree: Reduce resets during store setup mas_prealloc() may walk partially down the tree before finding that a split or spanning store is needed. When the write occurs, relax the logic on resetting the walk so that partial walks will not restart, but walks that have gone too far (a store that affects beyond the current node) should be restarted. Signed-off-by: Liam R. Howlett Link: https://lore.kernel.org/all/20230612203953.2093911-16-Liam.Howlett@oracle.com/ Bug: 274059236 Change-Id: I87dedebae085f067b08caeaf1bd19bb343ff305f Signed-off-by: Suren Baghdasaryan --- lib/maple_tree.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/maple_tree.c b/lib/maple_tree.c index f7a2cf3a5eeb..bcce83fa5537 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -5607,20 +5607,34 @@ static inline void mte_destroy_walk(struct maple_enode *enode, static void mas_wr_store_setup(struct ma_wr_state *wr_mas) { + if (mas_is_start(wr_mas->mas)) + return; + if (unlikely(mas_is_paused(wr_mas->mas))) - mas_reset(wr_mas->mas); + goto reset; - if (!mas_is_start(wr_mas->mas)) { - if (mas_is_none(wr_mas->mas)) { - mas_reset(wr_mas->mas); - } else { - wr_mas->r_max = wr_mas->mas->max; - wr_mas->type = mte_node_type(wr_mas->mas->node); - if (mas_is_span_wr(wr_mas)) - mas_reset(wr_mas->mas); - } - } + if (unlikely(mas_is_none(wr_mas->mas))) + goto reset; + /* + * A less strict version of mas_is_span_wr() where we allow spanning + * writes within this node. This is to stop partial walks in + * mas_prealloc() from being reset. + */ + if (wr_mas->mas->last > wr_mas->mas->max) + goto reset; + + if (wr_mas->entry) + return; + + if (mte_is_leaf(wr_mas->mas->node) && + wr_mas->mas->last == wr_mas->mas->max) + goto reset; + + return; + +reset: + mas_reset(wr_mas->mas); } /* Interface */