From: Liam R. Howlett Date: Fri, 10 Feb 2023 21:49:09 +0000 (-0500) Subject: test_maple_tree: Add testing for maple state handling X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=ee65687b04503d28154c8f24db688cbb44358f89;p=users%2Fjedix%2Flinux-maple.git test_maple_tree: Add testing for maple state handling This adds testing for both a tree with multiple entries and a tree with just one entry at 0 - 0 (single entry tree). Signed-off-by: Liam R. Howlett --- diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index fd50ba062499..a9627cea1443 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -2675,6 +2675,648 @@ static noinline void __init check_empty_area_window(struct maple_tree *mt) rcu_read_unlock(); } +/* + * Check MAS_START, MAS_PAUSE, active (implied), and MAS_NONE transitions. + * + * The table below shows the single entry tree (0-0 pointer) and normal tree + * with nodes. + * + * Function ENTRY Start Result index & last + * ┬ ┬ ┬ ┬ ┬ + * │ │ │ │ └─ the final range + * │ │ │ └─ The node value after execution + * │ │ └─ The node value before execution + * │ └─ If the entry exists of does not exists (DNE) + * └─ The function name + * + * Function ENTRY Start Result index & last + * mas_next() + * - after last + * Single entry tree at 0-0 + * ------------------------ + * DNE MAS_START MAS_NONE 1 - ULONG_MAX + * DNE MAS_PAUSE MAS_NONE 1 - ULONG_MAX + * DNE MAS_ROOT MAS_NONE 1 - ULONG_MAX + * DNE MAS_NONE MAS_NONE 1 - ULONG_MAX + * + * Normal tree + * ----------- + * exists MAS_START active range + * DNE MAS_START MAS_NONE set to max + * exists MAS_PAUSE active range + * DNE MAS_PAUSE MAS_NONE set to max + * exists MAS_NONE active range + * exists active active range + * DNE active MAS_NONE max + * --or-- + * DNE active active last range (max < last) + * + * Function ENTRY Start Result index & last + * mas_prev() + * - before index + * Single entry tree at 0-0 + * ------------------------ + * if index > 0 + * exists MAS_START MAS_ROOT 0 - 0 + * exists MAS_PAUSE MAS_ROOT 0 - 0 + * exists MAS_NONE MAS_ROOT 0 - 0 + * + * if index == 0 + * DNE MAS_START MAS_NONE 0 - 0 + * DNE MAS_PAUSE MAS_NONE 0 - 0 + * DNE MAS_NONE MAS_NONE 0 - 0 + * DNE MAS_ROOT MAS_NONE 0 - 0 + * + * Normal tree + * ----------- + * exists MAS_START active range + * DNE MAS_START MAS_NONE set to min + * exists MAS_PAUSE active range + * DNE MAS_PAUSE active set to min + * exists MAS_NONE active range + * DNE MAS_NONE MAS_NONE set to min + * any MAS_ROOT MAS_NONE 0 - 0 + * exists active active range + * DNE active MAS_NONE min + * --or-- + * DNE active active last range (min > index) + * + * Function ENTRY Start Result index & last + * mas_find() + * - at index or next + * Single entry tree at 0-0 + * ------------------------ + * if index > 0 + * DNE MAS_START MAS_NONE 1 - ULONG_MAX + * DNE MAS_PAUSE MAS_NONE 1 - ULONG_MAX + * DNE MAS_ROOT MAS_NONE 1 - ULONG_MAX + * DNE MAS_NONE MAS_NONE 1 - ULONG_MAX + * if index == 0 + * exists MAS_START MAS_ROOT 0 - 0 + * exists MAS_PAUSE MAS_ROOT 0 - 0 + * exists MAS_NONE MAS_ROOT 0 - 0 + * + * Normal tree + * ----------- + * exists MAS_START active range + * DNE MAS_START MAS_NONE set to max + * exists MAS_PAUSE active range + * DNE MAS_PAUSE MAS_NONE set to max + * exists MAS_NONE active range + * exists active active range + * DNE active MAS_NONE max + * --or-- + * DNE active active last range (max < last) + * + * Function ENTRY Start Result index & last + * mas_find_rev() + * - at index or before + * Single entry tree at 0-0 + * ------------------------ + * if index > 0 + * exists MAS_START MAS_ROOT 0 - 0 + * exists MAS_PAUSE MAS_ROOT 0 - 0 + * exists MAS_NONE MAS_ROOT 0 - 0 + * if index == 0 + * DNE MAS_START MAS_NONE 0 - 0 + * DNE MAS_PAUSE MAS_NONE 0 - 0 + * DNE MAS_NONE MAS_NONE 0 - 0 + * DNE MAS_ROOT MAS_NONE 0 - 0 + * + * Normal tree + * ----------- + * exists MAS_START active range + * DNE MAS_START MAS_NONE set to min + * exists MAS_PAUSE active range + * DNE MAS_PAUSE MAS_NONE set to min + * exists MAS_NONE active range + * DNE MAS_NONE MAS_NONE set to min + * exists active active range + * DNE active MAS_NONE min + * --or-- + * DNE active active last range (min > index) + * + * Function ENTRY Start Result index & last + * mas_walk() + * - Look up index + * Single entry tree at 0-0 + * ------------------------ + * if index > 0 + * DNE MAS_START MAS_ROOT 1 - ULONG_MAX + * DNE MAS_PAUSE MAS_ROOT 1 - ULONG_MAX + * DNE MAS_NONE MAS_ROOT 1 - ULONG_MAX + * DNE MAS_ROOT MAS_ROOT 1 - ULONG_MAX + * if index == 0 + * exists MAS_START MAS_ROOT 0 - 0 + * exists MAS_PAUSE MAS_ROOT 0 - 0 + * exists MAS_NONE MAS_ROOT 0 - 0 + * exists MAS_ROOT MAS_ROOT 0 - 0 + * + * Normal tree + * ----------- + * exists MAS_START active range + * DNE MAS_START active range of NULL + * exists MAS_PAUSE active range + * DNE MAS_PAUSE active range of NULL + * exists MAS_NONE active range + * DNE MAS_NONE active unchanged + * exists active active range + * DNE active active range of NULL + */ +static noinline void __init check_state_handling(struct maple_tree *mt) +{ + MA_STATE(mas, mt, 0, 0); + void *entry, *ptr = (void *) 0x1234500; + void *ptr2 = &ptr; + void *ptr3 = &ptr2; + + /* Check MAS_ROOT First */ + mtree_store_range(mt, 0, 0, ptr, GFP_KERNEL); + + mas_lock(&mas); + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + mas_set(&mas, 10); + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + + mas_set(&mas, 10); + mas_pause(&mas); + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + + mas_set(&mas, 0); + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + mas_set(&mas, 10); + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, mas.index != 1); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + mas_set(&mas, 0); + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + mas_set(&mas, 10); + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 1); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_set(&mas, 0); + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + mas_set(&mas, 10); + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_set(&mas, 10); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 1); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_set(&mas, 10); + mas_pause(&mas); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 1); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_set(&mas, 10); + mas.node = MAS_NONE; + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 1); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 1); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_set(&mas, 0); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_set(&mas, 0); + mas_pause(&mas); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas.node = MAS_NONE; + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_set(&mas, 10); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 1); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas.index = mas.last = 0; + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_ROOT); + + mas_unlock(&mas); + + /* Check when there is an actual node */ + mtree_store_range(mt, 0, 0, NULL, GFP_KERNEL); + mtree_store_range(mt, 0x1000, 0x1500, ptr, GFP_KERNEL); + mtree_store_range(mt, 0x2000, 0x2500, ptr2, GFP_KERNEL); + mtree_store_range(mt, 0x3000, 0x3500, ptr3, GFP_KERNEL); + + mas_lock(&mas); + + /* next: start ->active */ + mas_set(&mas, 0); + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* next: pause ->active */ + mas_set(&mas, 0); + mas_pause(&mas); + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* next: none ->active */ + mas.index = mas.last = 0; + mas.offset = 0; + mas.node = MAS_NONE; + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* next:active ->active */ + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr2); + MAS_BUG_ON(&mas, mas.index != 0x2000); + MAS_BUG_ON(&mas, mas.last != 0x2500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* next:active -> none */ + entry = mas_next(&mas, 0x2999); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0x2999); + MAS_BUG_ON(&mas, mas.last != 0x2999); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + /* Continue after none */ + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr3); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* next:active -> none */ + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != ULONG_MAX); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + /* next: none ->active, skip value at location */ + mas_set(&mas, 0); + entry = mas_next(&mas, ULONG_MAX); + mas.node = MAS_NONE; + mas.offset = 0; + entry = mas_next(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr2); + MAS_BUG_ON(&mas, mas.index != 0x2000); + MAS_BUG_ON(&mas, mas.last != 0x2500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* prev:active ->active */ + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* prev:active -> none */ + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + /* prev: pause ->active */ + mas_set(&mas, 0x3600); + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr3); + mas_pause(&mas); + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr2); + MAS_BUG_ON(&mas, mas.index != 0x2000); + MAS_BUG_ON(&mas, mas.last != 0x2500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* prev:active -> none */ + entry = mas_prev(&mas, 0x1600); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0x1600); + MAS_BUG_ON(&mas, mas.last != 0x1600); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + /* prev: none ->active */ + entry = mas_prev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find: start ->active */ + mas_set(&mas, 0); + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find: pause ->active */ + mas_set(&mas, 0); + mas_pause(&mas); + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find: start ->active on value */; + mas_set(&mas, 1200); + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find:active ->active */ + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != ptr2); + MAS_BUG_ON(&mas, mas.index != 0x2000); + MAS_BUG_ON(&mas, mas.last != 0x2500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + + /* find:active -> none */ + entry = mas_find(&mas, 0x2700); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0x2700); + MAS_BUG_ON(&mas, mas.last != 0x2700); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + /* find: none ->active */ + entry = mas_find(&mas, 0x5000); + MAS_BUG_ON(&mas, entry != ptr3); + MAS_BUG_ON(&mas, mas.index != 0x3000); + MAS_BUG_ON(&mas, mas.last != 0x3500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find:active -> none */ + entry = mas_find(&mas, ULONG_MAX); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != ULONG_MAX); + MAS_BUG_ON(&mas, mas.last != ULONG_MAX); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + /* find_rev: none ->active */ + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr3); + MAS_BUG_ON(&mas, mas.index != 0x3000); + MAS_BUG_ON(&mas, mas.last != 0x3500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find_rev:active ->active */ + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr2); + MAS_BUG_ON(&mas, mas.index != 0x2000); + MAS_BUG_ON(&mas, mas.last != 0x2500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find_rev: pause ->active */ + mas_pause(&mas); + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* find_rev:active -> none */ + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0); + MAS_BUG_ON(&mas, mas.last != 0); + MAS_BUG_ON(&mas, mas.node != MAS_NONE); + + /* find_rev: start ->active */ + mas_set(&mas, 0x1200); + entry = mas_find_rev(&mas, 0); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk start ->active */ + mas_set(&mas, 0x1200); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk start ->active */ + mas_set(&mas, 0x1600); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0x1501); + MAS_BUG_ON(&mas, mas.last != 0x1fff); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk pause ->active */ + mas_set(&mas, 0x1200); + mas_pause(&mas); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk pause -> active */ + mas_set(&mas, 0x1600); + mas_pause(&mas); + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0x1501); + MAS_BUG_ON(&mas, mas.last != 0x1fff); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk none -> active */ + mas_set(&mas, 0x1200); + mas.node = MAS_NONE; + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk none -> active */ + mas_set(&mas, 0x1600); + mas.node = MAS_NONE; + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0x1501); + MAS_BUG_ON(&mas, mas.last != 0x1fff); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk active -> active */ + mas.index = 0x1200; + mas.last = 0x1200; + mas.offset = 0; + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != ptr); + MAS_BUG_ON(&mas, mas.index != 0x1000); + MAS_BUG_ON(&mas, mas.last != 0x1500); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + /* mas_walk active -> active */ + mas.index = 0x1600; + mas.last = 0x1600; + entry = mas_walk(&mas); + MAS_BUG_ON(&mas, entry != NULL); + MAS_BUG_ON(&mas, mas.index != 0x1501); + MAS_BUG_ON(&mas, mas.last != 0x1fff); + MAS_BUG_ON(&mas, mas.node == MAS_PAUSE); + MAS_BUG_ON(&mas, mas.node == MAS_NONE); + MAS_BUG_ON(&mas, mas.node == MAS_START); + + mas_unlock(&mas); +} + static DEFINE_MTREE(tree); static int __init maple_tree_seed(void) { @@ -2931,6 +3573,10 @@ static int __init maple_tree_seed(void) check_empty_area_window(&tree); mtree_destroy(&tree); + mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); + check_state_handling(&tree); + mtree_destroy(&tree); + #if defined(BENCH) skip: #endif