From 0ac05e2c872360a8bed7bff44b43fc937bd8affd Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Tue, 5 May 2020 23:17:52 -0400 Subject: [PATCH] maple_tree: Reset mas location before walking in mas_rebalance_gaps. After rebalancing, the mas node may not be in the correct location to find the mas->index, so reset to MAS_START prior to starting the walk. Added test case for this issue as well. Signed-off-by: Liam R. Howlett --- lib/maple_tree.c | 2 +- lib/test_maple_tree.c | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 84c064be71b0..f2125125c91b 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -2684,7 +2684,7 @@ static inline void mas_rebalance_gaps(struct ma_state *mas) { if (mt_is_alloc(mas->tree)) { MA_STATE(r_mas, mas->tree, mas->index, mas->last); - + mas->node = MAS_START; _mas_walk(mas); // return to the updated location in the tree. mas_dup_state(&r_mas, mas); mas_update_gap(mas, true); diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index 2285297a29f2..4a6f3aa53afa 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -22430,12 +22430,12 @@ STORE, 140249682087936, 140249710600191, mt_validate(mt); mtree_destroy(mt); + mt_set_non_kernel(99); mtree_init(mt, MAPLE_ALLOC_RANGE); check_erase2_testset(mt, set25, ARRAY_SIZE(set25)); rcu_barrier(); mt_validate(mt); - mtree_destroy(mt); } @@ -22890,10 +22890,6 @@ static noinline void check_ranges(struct maple_tree *mt) mtree_destroy(mt); mt_set_non_kernel(0); - - return; - - mt_set_non_kernel(50); for (i = 0; i <= 500; i++) { int val = i*5; @@ -22906,10 +22902,27 @@ static noinline void check_ranges(struct maple_tree *mt) check_store_range(mt, 2460, 2470, NULL, 0); check_store_range(mt, 2435, 2460, xa_mk_value(2435), 0); check_store_range(mt, 2461, 2470, xa_mk_value(2461), 0); - mt_dump(mt); mt_set_non_kernel(0); mtree_destroy(mt); - exit(0); + + // Test rebalance gaps + mtree_init(mt, MAPLE_ALLOC_RANGE); + mt_set_non_kernel(50); + for (i = 0; i <= 50; i++) { + int val = i*10; + int val2 = (i+1)*10; + check_store_range(mt, val, val2, xa_mk_value(val), 0); + } + check_store_range(mt, 161, 161, xa_mk_value(161), 0); + check_store_range(mt, 162, 162, xa_mk_value(162), 0); + check_store_range(mt, 163, 163, xa_mk_value(163), 0); + check_store_range(mt, 240, 249, NULL, 0); + mtree_erase(mt, 200); + mtree_erase(mt, 210); + mtree_erase(mt, 220); + mtree_erase(mt, 230); + mt_set_non_kernel(0); + mtree_destroy(mt); } static noinline void check_next_entry(struct maple_tree *mt) -- 2.50.1