xref: /linux-6.15/lib/test_maple_tree.c (revision b02fcc08)
1e15e06a8SLiam R. Howlett // SPDX-License-Identifier: GPL-2.0+
2e15e06a8SLiam R. Howlett /*
3e15e06a8SLiam R. Howlett  * test_maple_tree.c: Test the maple tree API
4120b1162SLiam Howlett  * Copyright (c) 2018-2022 Oracle Corporation
5e15e06a8SLiam R. Howlett  * Author: Liam R. Howlett <[email protected]>
6120b1162SLiam Howlett  *
7120b1162SLiam Howlett  * Any tests that only require the interface of the tree.
8e15e06a8SLiam R. Howlett  */
9e15e06a8SLiam R. Howlett 
10e15e06a8SLiam R. Howlett #include <linux/maple_tree.h>
11e15e06a8SLiam R. Howlett #include <linux/module.h>
12099d7439SLiam R. Howlett #include <linux/rwsem.h>
13e15e06a8SLiam R. Howlett 
14e15e06a8SLiam R. Howlett #define MTREE_ALLOC_MAX 0x2000000000000Ul
15e15e06a8SLiam R. Howlett #define CONFIG_MAPLE_SEARCH
16120b1162SLiam Howlett #define MAPLE_32BIT (MAPLE_NODE_SLOTS > 31)
17120b1162SLiam Howlett 
18a5199577SLiam R. Howlett #ifndef CONFIG_DEBUG_MAPLE_TREE
19a5199577SLiam R. Howlett #define mt_dump(mt, fmt)		do {} while (0)
20a5199577SLiam R. Howlett #define mt_validate(mt)			do {} while (0)
21a5199577SLiam R. Howlett #define mt_cache_shrink()		do {} while (0)
22a5199577SLiam R. Howlett #define mas_dump(mas)			do {} while (0)
23a5199577SLiam R. Howlett #define mas_wr_dump(mas)		do {} while (0)
24a5199577SLiam R. Howlett atomic_t maple_tree_tests_run;
25a5199577SLiam R. Howlett atomic_t maple_tree_tests_passed;
26a5199577SLiam R. Howlett #undef MT_BUG_ON
27a5199577SLiam R. Howlett 
28a5199577SLiam R. Howlett #define MT_BUG_ON(__tree, __x) do {					\
29a5199577SLiam R. Howlett 	atomic_inc(&maple_tree_tests_run);				\
30a5199577SLiam R. Howlett 	if (__x) {							\
31a5199577SLiam R. Howlett 		pr_info("BUG at %s:%d (%u)\n",				\
32a5199577SLiam R. Howlett 		__func__, __LINE__, __x);				\
33a5199577SLiam R. Howlett 		pr_info("Pass: %u Run:%u\n",				\
34a5199577SLiam R. Howlett 			atomic_read(&maple_tree_tests_passed),		\
35a5199577SLiam R. Howlett 			atomic_read(&maple_tree_tests_run));		\
36a5199577SLiam R. Howlett 	} else {							\
37a5199577SLiam R. Howlett 		atomic_inc(&maple_tree_tests_passed);			\
38a5199577SLiam R. Howlett 	}								\
39a5199577SLiam R. Howlett } while (0)
40a5199577SLiam R. Howlett #endif
41a5199577SLiam R. Howlett 
42e15e06a8SLiam R. Howlett /* #define BENCH_SLOT_STORE */
43e15e06a8SLiam R. Howlett /* #define BENCH_NODE_STORE */
44e15e06a8SLiam R. Howlett /* #define BENCH_AWALK */
45e15e06a8SLiam R. Howlett /* #define BENCH_WALK */
4624662decSLiam R. Howlett /* #define BENCH_LOAD */
47e15e06a8SLiam R. Howlett /* #define BENCH_MT_FOR_EACH */
48e15e06a8SLiam R. Howlett /* #define BENCH_FORK */
49361c678bSLiam R. Howlett /* #define BENCH_MAS_FOR_EACH */
508c314f3bSLiam R. Howlett /* #define BENCH_MAS_PREV */
51120b1162SLiam Howlett 
52120b1162SLiam Howlett #ifdef __KERNEL__
53120b1162SLiam Howlett #define mt_set_non_kernel(x)		do {} while (0)
54120b1162SLiam Howlett #define mt_zero_nr_tallocated(x)	do {} while (0)
55120b1162SLiam Howlett #else
56120b1162SLiam Howlett #define cond_resched()			do {} while (0)
57120b1162SLiam Howlett #endif
58067311d3SLiam R. Howlett 
59067311d3SLiam R. Howlett #define mas_is_none(x)		((x)->status == ma_none)
60067311d3SLiam R. Howlett #define mas_is_overflow(x)	((x)->status == ma_overflow)
61067311d3SLiam R. Howlett #define mas_is_underflow(x)	((x)->status == ma_underflow)
62067311d3SLiam R. Howlett 
mtree_insert_index(struct maple_tree * mt,unsigned long index,gfp_t gfp)63eaf9790dSLiam R. Howlett static int __init mtree_insert_index(struct maple_tree *mt,
64eaf9790dSLiam R. Howlett 				     unsigned long index, gfp_t gfp)
65e15e06a8SLiam R. Howlett {
66e15e06a8SLiam R. Howlett 	return mtree_insert(mt, index, xa_mk_value(index & LONG_MAX), gfp);
67e15e06a8SLiam R. Howlett }
68e15e06a8SLiam R. Howlett 
mtree_erase_index(struct maple_tree * mt,unsigned long index)69eaf9790dSLiam R. Howlett static void __init mtree_erase_index(struct maple_tree *mt, unsigned long index)
70e15e06a8SLiam R. Howlett {
71e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_erase(mt, index) != xa_mk_value(index & LONG_MAX));
72e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_load(mt, index) != NULL);
73e15e06a8SLiam R. Howlett }
74e15e06a8SLiam R. Howlett 
mtree_test_insert(struct maple_tree * mt,unsigned long index,void * ptr)75eaf9790dSLiam R. Howlett static int __init mtree_test_insert(struct maple_tree *mt, unsigned long index,
76e15e06a8SLiam R. Howlett 				void *ptr)
77e15e06a8SLiam R. Howlett {
78e15e06a8SLiam R. Howlett 	return mtree_insert(mt, index, ptr, GFP_KERNEL);
79e15e06a8SLiam R. Howlett }
80e15e06a8SLiam R. Howlett 
mtree_test_store_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr)81eaf9790dSLiam R. Howlett static int __init mtree_test_store_range(struct maple_tree *mt,
82eaf9790dSLiam R. Howlett 			unsigned long start, unsigned long end, void *ptr)
83e15e06a8SLiam R. Howlett {
84e15e06a8SLiam R. Howlett 	return mtree_store_range(mt, start, end, ptr, GFP_KERNEL);
85e15e06a8SLiam R. Howlett }
86e15e06a8SLiam R. Howlett 
mtree_test_store(struct maple_tree * mt,unsigned long start,void * ptr)87eaf9790dSLiam R. Howlett static int __init mtree_test_store(struct maple_tree *mt, unsigned long start,
88e15e06a8SLiam R. Howlett 				void *ptr)
89e15e06a8SLiam R. Howlett {
90e15e06a8SLiam R. Howlett 	return mtree_test_store_range(mt, start, start, ptr);
91e15e06a8SLiam R. Howlett }
92e15e06a8SLiam R. Howlett 
mtree_test_insert_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr)93eaf9790dSLiam R. Howlett static int __init mtree_test_insert_range(struct maple_tree *mt,
94eaf9790dSLiam R. Howlett 			unsigned long start, unsigned long end, void *ptr)
95e15e06a8SLiam R. Howlett {
96e15e06a8SLiam R. Howlett 	return mtree_insert_range(mt, start, end, ptr, GFP_KERNEL);
97e15e06a8SLiam R. Howlett }
98e15e06a8SLiam R. Howlett 
mtree_test_load(struct maple_tree * mt,unsigned long index)99eaf9790dSLiam R. Howlett static void __init *mtree_test_load(struct maple_tree *mt, unsigned long index)
100e15e06a8SLiam R. Howlett {
101e15e06a8SLiam R. Howlett 	return mtree_load(mt, index);
102e15e06a8SLiam R. Howlett }
103e15e06a8SLiam R. Howlett 
mtree_test_erase(struct maple_tree * mt,unsigned long index)104eaf9790dSLiam R. Howlett static void __init *mtree_test_erase(struct maple_tree *mt, unsigned long index)
105e15e06a8SLiam R. Howlett {
106e15e06a8SLiam R. Howlett 	return mtree_erase(mt, index);
107e15e06a8SLiam R. Howlett }
108e15e06a8SLiam R. Howlett 
109120b1162SLiam Howlett #if defined(CONFIG_64BIT)
check_mtree_alloc_range(struct maple_tree * mt,unsigned long start,unsigned long end,unsigned long size,unsigned long expected,int eret,void * ptr)110eaf9790dSLiam R. Howlett static noinline void __init check_mtree_alloc_range(struct maple_tree *mt,
111e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, unsigned long size,
112e15e06a8SLiam R. Howlett 		unsigned long expected, int eret, void *ptr)
113e15e06a8SLiam R. Howlett {
114e15e06a8SLiam R. Howlett 
115e15e06a8SLiam R. Howlett 	unsigned long result = expected + 1;
116e15e06a8SLiam R. Howlett 	int ret;
117e15e06a8SLiam R. Howlett 
118e15e06a8SLiam R. Howlett 	ret = mtree_alloc_range(mt, &result, ptr, size, start, end,
119e15e06a8SLiam R. Howlett 			GFP_KERNEL);
120e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != eret);
121e15e06a8SLiam R. Howlett 	if (ret)
122e15e06a8SLiam R. Howlett 		return;
123e15e06a8SLiam R. Howlett 
124e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, result != expected);
125e15e06a8SLiam R. Howlett }
126e15e06a8SLiam R. Howlett 
check_mtree_alloc_rrange(struct maple_tree * mt,unsigned long start,unsigned long end,unsigned long size,unsigned long expected,int eret,void * ptr)127eaf9790dSLiam R. Howlett static noinline void __init check_mtree_alloc_rrange(struct maple_tree *mt,
128e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, unsigned long size,
129e15e06a8SLiam R. Howlett 		unsigned long expected, int eret, void *ptr)
130e15e06a8SLiam R. Howlett {
131e15e06a8SLiam R. Howlett 
132e15e06a8SLiam R. Howlett 	unsigned long result = expected + 1;
133e15e06a8SLiam R. Howlett 	int ret;
134e15e06a8SLiam R. Howlett 
135ba997212SLiam R. Howlett 	ret = mtree_alloc_rrange(mt, &result, ptr, size, start, end,
136e15e06a8SLiam R. Howlett 			GFP_KERNEL);
137e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != eret);
138e15e06a8SLiam R. Howlett 	if (ret)
139e15e06a8SLiam R. Howlett 		return;
140e15e06a8SLiam R. Howlett 
141e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, result != expected);
142e15e06a8SLiam R. Howlett }
143120b1162SLiam Howlett #endif
144e15e06a8SLiam R. Howlett 
check_load(struct maple_tree * mt,unsigned long index,void * ptr)145eaf9790dSLiam R. Howlett static noinline void __init check_load(struct maple_tree *mt,
146eaf9790dSLiam R. Howlett 				       unsigned long index, void *ptr)
147e15e06a8SLiam R. Howlett {
148e15e06a8SLiam R. Howlett 	void *ret = mtree_test_load(mt, index);
149e15e06a8SLiam R. Howlett 
150e15e06a8SLiam R. Howlett 	if (ret != ptr)
151e15e06a8SLiam R. Howlett 		pr_err("Load %lu returned %p expect %p\n", index, ret, ptr);
152e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != ptr);
153e15e06a8SLiam R. Howlett }
154e15e06a8SLiam R. Howlett 
check_store_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr,int expected)155eaf9790dSLiam R. Howlett static noinline void __init check_store_range(struct maple_tree *mt,
156e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, void *ptr, int expected)
157e15e06a8SLiam R. Howlett {
158e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
159e15e06a8SLiam R. Howlett 	unsigned long i;
160e15e06a8SLiam R. Howlett 
161e15e06a8SLiam R. Howlett 	ret = mtree_test_store_range(mt, start, end, ptr);
162e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != expected);
163e15e06a8SLiam R. Howlett 
164e15e06a8SLiam R. Howlett 	if (ret)
165e15e06a8SLiam R. Howlett 		return;
166e15e06a8SLiam R. Howlett 
167e15e06a8SLiam R. Howlett 	for (i = start; i <= end; i++)
168e15e06a8SLiam R. Howlett 		check_load(mt, i, ptr);
169e15e06a8SLiam R. Howlett }
170e15e06a8SLiam R. Howlett 
check_insert_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr,int expected)171eaf9790dSLiam R. Howlett static noinline void __init check_insert_range(struct maple_tree *mt,
172e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, void *ptr, int expected)
173e15e06a8SLiam R. Howlett {
174e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
175e15e06a8SLiam R. Howlett 	unsigned long i;
176e15e06a8SLiam R. Howlett 
177e15e06a8SLiam R. Howlett 	ret = mtree_test_insert_range(mt, start, end, ptr);
178e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != expected);
179e15e06a8SLiam R. Howlett 
180e15e06a8SLiam R. Howlett 	if (ret)
181e15e06a8SLiam R. Howlett 		return;
182e15e06a8SLiam R. Howlett 
183e15e06a8SLiam R. Howlett 	for (i = start; i <= end; i++)
184e15e06a8SLiam R. Howlett 		check_load(mt, i, ptr);
185e15e06a8SLiam R. Howlett }
186e15e06a8SLiam R. Howlett 
check_insert(struct maple_tree * mt,unsigned long index,void * ptr)187eaf9790dSLiam R. Howlett static noinline void __init check_insert(struct maple_tree *mt,
188eaf9790dSLiam R. Howlett 					 unsigned long index, void *ptr)
189e15e06a8SLiam R. Howlett {
190e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
191e15e06a8SLiam R. Howlett 
192e15e06a8SLiam R. Howlett 	ret = mtree_test_insert(mt, index, ptr);
193e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != 0);
194e15e06a8SLiam R. Howlett }
195e15e06a8SLiam R. Howlett 
check_dup_insert(struct maple_tree * mt,unsigned long index,void * ptr)196eaf9790dSLiam R. Howlett static noinline void __init check_dup_insert(struct maple_tree *mt,
197e15e06a8SLiam R. Howlett 				      unsigned long index, void *ptr)
198e15e06a8SLiam R. Howlett {
199e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
200e15e06a8SLiam R. Howlett 
201e15e06a8SLiam R. Howlett 	ret = mtree_test_insert(mt, index, ptr);
202e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != -EEXIST);
203e15e06a8SLiam R. Howlett }
204e15e06a8SLiam R. Howlett 
205e15e06a8SLiam R. Howlett 
check_index_load(struct maple_tree * mt,unsigned long index)206eaf9790dSLiam R. Howlett static noinline void __init check_index_load(struct maple_tree *mt,
207eaf9790dSLiam R. Howlett 					     unsigned long index)
208e15e06a8SLiam R. Howlett {
209e15e06a8SLiam R. Howlett 	return check_load(mt, index, xa_mk_value(index & LONG_MAX));
210e15e06a8SLiam R. Howlett }
211e15e06a8SLiam R. Howlett 
not_empty(struct maple_node * node)212eaf9790dSLiam R. Howlett static inline __init int not_empty(struct maple_node *node)
213e15e06a8SLiam R. Howlett {
214e15e06a8SLiam R. Howlett 	int i;
215e15e06a8SLiam R. Howlett 
216e15e06a8SLiam R. Howlett 	if (node->parent)
217e15e06a8SLiam R. Howlett 		return 1;
218e15e06a8SLiam R. Howlett 
219e15e06a8SLiam R. Howlett 	for (i = 0; i < ARRAY_SIZE(node->slot); i++)
220e15e06a8SLiam R. Howlett 		if (node->slot[i])
221e15e06a8SLiam R. Howlett 			return 1;
222e15e06a8SLiam R. Howlett 
223e15e06a8SLiam R. Howlett 	return 0;
224e15e06a8SLiam R. Howlett }
225e15e06a8SLiam R. Howlett 
226e15e06a8SLiam R. Howlett 
check_rev_seq(struct maple_tree * mt,unsigned long max,bool verbose)227eaf9790dSLiam R. Howlett static noinline void __init check_rev_seq(struct maple_tree *mt,
228eaf9790dSLiam R. Howlett 					  unsigned long max, bool verbose)
229e15e06a8SLiam R. Howlett {
230e15e06a8SLiam R. Howlett 	unsigned long i = max, j;
231e15e06a8SLiam R. Howlett 
232e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
233e15e06a8SLiam R. Howlett 
234e15e06a8SLiam R. Howlett 	mt_zero_nr_tallocated();
235e15e06a8SLiam R. Howlett 	while (i) {
236e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
237e15e06a8SLiam R. Howlett 		for (j = i; j <= max; j++)
238e15e06a8SLiam R. Howlett 			check_index_load(mt, j);
239e15e06a8SLiam R. Howlett 
240e15e06a8SLiam R. Howlett 		check_load(mt, i - 1, NULL);
241e15e06a8SLiam R. Howlett 		mt_set_in_rcu(mt);
242e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, !mt_height(mt));
243e15e06a8SLiam R. Howlett 		mt_clear_in_rcu(mt);
244e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, !mt_height(mt));
245e15e06a8SLiam R. Howlett 		i--;
246e15e06a8SLiam R. Howlett 	}
247e15e06a8SLiam R. Howlett 	check_load(mt, max + 1, NULL);
248e15e06a8SLiam R. Howlett 
249120b1162SLiam Howlett #ifndef __KERNEL__
250e15e06a8SLiam R. Howlett 	if (verbose) {
251e15e06a8SLiam R. Howlett 		rcu_barrier();
25289f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_dec);
253e15e06a8SLiam R. Howlett 		pr_info(" %s test of 0-%lu %luK in %d active (%d total)\n",
254e15e06a8SLiam R. Howlett 			__func__, max, mt_get_alloc_size()/1024, mt_nr_allocated(),
255e15e06a8SLiam R. Howlett 			mt_nr_tallocated());
256e15e06a8SLiam R. Howlett 	}
257120b1162SLiam Howlett #endif
258e15e06a8SLiam R. Howlett }
259e15e06a8SLiam R. Howlett 
check_seq(struct maple_tree * mt,unsigned long max,bool verbose)260eaf9790dSLiam R. Howlett static noinline void __init check_seq(struct maple_tree *mt, unsigned long max,
261e15e06a8SLiam R. Howlett 		bool verbose)
262e15e06a8SLiam R. Howlett {
263e15e06a8SLiam R. Howlett 	unsigned long i, j;
264e15e06a8SLiam R. Howlett 
265e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
266e15e06a8SLiam R. Howlett 
267e15e06a8SLiam R. Howlett 	mt_zero_nr_tallocated();
268e15e06a8SLiam R. Howlett 	for (i = 0; i <= max; i++) {
269e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
270e15e06a8SLiam R. Howlett 		for (j = 0; j <= i; j++)
271e15e06a8SLiam R. Howlett 			check_index_load(mt, j);
272e15e06a8SLiam R. Howlett 
273e15e06a8SLiam R. Howlett 		if (i)
274e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, !mt_height(mt));
275e15e06a8SLiam R. Howlett 		check_load(mt, i + 1, NULL);
276e15e06a8SLiam R. Howlett 	}
277120b1162SLiam Howlett 
278120b1162SLiam Howlett #ifndef __KERNEL__
279e15e06a8SLiam R. Howlett 	if (verbose) {
280e15e06a8SLiam R. Howlett 		rcu_barrier();
28189f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_dec);
282e15e06a8SLiam R. Howlett 		pr_info(" seq test of 0-%lu %luK in %d active (%d total)\n",
283e15e06a8SLiam R. Howlett 			max, mt_get_alloc_size()/1024, mt_nr_allocated(),
284e15e06a8SLiam R. Howlett 			mt_nr_tallocated());
285e15e06a8SLiam R. Howlett 	}
286120b1162SLiam Howlett #endif
287e15e06a8SLiam R. Howlett }
288e15e06a8SLiam R. Howlett 
check_lb_not_empty(struct maple_tree * mt)289eaf9790dSLiam R. Howlett static noinline void __init check_lb_not_empty(struct maple_tree *mt)
290e15e06a8SLiam R. Howlett {
291e15e06a8SLiam R. Howlett 	unsigned long i, j;
292e15e06a8SLiam R. Howlett 	unsigned long huge = 4000UL * 1000 * 1000;
293e15e06a8SLiam R. Howlett 
294e15e06a8SLiam R. Howlett 
295e15e06a8SLiam R. Howlett 	i = huge;
296e15e06a8SLiam R. Howlett 	while (i > 4096) {
297e15e06a8SLiam R. Howlett 		check_insert(mt, i, (void *) i);
298e15e06a8SLiam R. Howlett 		for (j = huge; j >= i; j /= 2) {
299e15e06a8SLiam R. Howlett 			check_load(mt, j-1, NULL);
300e15e06a8SLiam R. Howlett 			check_load(mt, j, (void *) j);
301e15e06a8SLiam R. Howlett 			check_load(mt, j+1, NULL);
302e15e06a8SLiam R. Howlett 		}
303e15e06a8SLiam R. Howlett 		i /= 2;
304e15e06a8SLiam R. Howlett 	}
305e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
306e15e06a8SLiam R. Howlett }
307e15e06a8SLiam R. Howlett 
check_lower_bound_split(struct maple_tree * mt)308eaf9790dSLiam R. Howlett static noinline void __init check_lower_bound_split(struct maple_tree *mt)
309e15e06a8SLiam R. Howlett {
310e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
311e15e06a8SLiam R. Howlett 	check_lb_not_empty(mt);
312e15e06a8SLiam R. Howlett }
313e15e06a8SLiam R. Howlett 
check_upper_bound_split(struct maple_tree * mt)314eaf9790dSLiam R. Howlett static noinline void __init check_upper_bound_split(struct maple_tree *mt)
315e15e06a8SLiam R. Howlett {
316e15e06a8SLiam R. Howlett 	unsigned long i, j;
317120b1162SLiam Howlett 	unsigned long huge;
318e15e06a8SLiam R. Howlett 
319e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
320e15e06a8SLiam R. Howlett 
321120b1162SLiam Howlett 	if (MAPLE_32BIT)
322120b1162SLiam Howlett 		huge = 2147483647UL;
323120b1162SLiam Howlett 	else
324120b1162SLiam Howlett 		huge = 4000UL * 1000 * 1000;
325120b1162SLiam Howlett 
326e15e06a8SLiam R. Howlett 	i = 4096;
327e15e06a8SLiam R. Howlett 	while (i < huge) {
328e15e06a8SLiam R. Howlett 		check_insert(mt, i, (void *) i);
329e15e06a8SLiam R. Howlett 		for (j = i; j >= huge; j *= 2) {
330e15e06a8SLiam R. Howlett 			check_load(mt, j-1, NULL);
331e15e06a8SLiam R. Howlett 			check_load(mt, j, (void *) j);
332e15e06a8SLiam R. Howlett 			check_load(mt, j+1, NULL);
333e15e06a8SLiam R. Howlett 		}
334e15e06a8SLiam R. Howlett 		i *= 2;
335e15e06a8SLiam R. Howlett 	}
336e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
337e15e06a8SLiam R. Howlett }
338e15e06a8SLiam R. Howlett 
check_mid_split(struct maple_tree * mt)339eaf9790dSLiam R. Howlett static noinline void __init check_mid_split(struct maple_tree *mt)
340e15e06a8SLiam R. Howlett {
341e15e06a8SLiam R. Howlett 	unsigned long huge = 8000UL * 1000 * 1000;
342e15e06a8SLiam R. Howlett 
343e15e06a8SLiam R. Howlett 	check_insert(mt, huge, (void *) huge);
344e15e06a8SLiam R. Howlett 	check_insert(mt, 0, xa_mk_value(0));
345e15e06a8SLiam R. Howlett 	check_lb_not_empty(mt);
346e15e06a8SLiam R. Howlett }
347e15e06a8SLiam R. Howlett 
check_rev_find(struct maple_tree * mt)348eaf9790dSLiam R. Howlett static noinline void __init check_rev_find(struct maple_tree *mt)
349e15e06a8SLiam R. Howlett {
350e15e06a8SLiam R. Howlett 	int i, nr_entries = 200;
351e15e06a8SLiam R. Howlett 	void *val;
352e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
353e15e06a8SLiam R. Howlett 
354e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
355e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
356e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
357e15e06a8SLiam R. Howlett 
358120b1162SLiam Howlett 	rcu_read_lock();
359e15e06a8SLiam R. Howlett 	mas_set(&mas, 1000);
360e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 1000);
361e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(100));
362e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 1000);
363e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
364e15e06a8SLiam R. Howlett 
365e15e06a8SLiam R. Howlett 	mas_set(&mas, 999);
366e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 997);
367e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
368e15e06a8SLiam R. Howlett 
369e15e06a8SLiam R. Howlett 	mas_set(&mas, 1000);
370e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 900);
371e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(100));
372e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 900);
373e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(99));
374e15e06a8SLiam R. Howlett 
375e15e06a8SLiam R. Howlett 	mas_set(&mas, 20);
376e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
377e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(2));
378e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
379e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(1));
380e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
381e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(0));
382e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
383e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
384120b1162SLiam Howlett 	rcu_read_unlock();
385e15e06a8SLiam R. Howlett }
386e15e06a8SLiam R. Howlett 
check_find(struct maple_tree * mt)387eaf9790dSLiam R. Howlett static noinline void __init check_find(struct maple_tree *mt)
388e15e06a8SLiam R. Howlett {
389e15e06a8SLiam R. Howlett 	unsigned long val = 0;
390120b1162SLiam Howlett 	unsigned long count;
391e15e06a8SLiam R. Howlett 	unsigned long max;
392120b1162SLiam Howlett 	unsigned long top;
393e15e06a8SLiam R. Howlett 	unsigned long last = 0, index = 0;
394e15e06a8SLiam R. Howlett 	void *entry, *entry2;
395e15e06a8SLiam R. Howlett 
396e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
397e15e06a8SLiam R. Howlett 
398e15e06a8SLiam R. Howlett 	/* Insert 0. */
399e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_insert_index(mt, val++, GFP_KERNEL));
400e15e06a8SLiam R. Howlett 
401120b1162SLiam Howlett #if defined(CONFIG_64BIT)
402120b1162SLiam Howlett 	top = 4398046511104UL;
403120b1162SLiam Howlett #else
404120b1162SLiam Howlett 	top = ULONG_MAX;
405120b1162SLiam Howlett #endif
406120b1162SLiam Howlett 
407120b1162SLiam Howlett 	if (MAPLE_32BIT) {
408120b1162SLiam Howlett 		count = 15;
409120b1162SLiam Howlett 	} else {
410120b1162SLiam Howlett 		count = 20;
411120b1162SLiam Howlett 	}
412120b1162SLiam Howlett 
413e15e06a8SLiam R. Howlett 	for (int i = 0; i <= count; i++) {
414e15e06a8SLiam R. Howlett 		if (val != 64)
415e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, mtree_insert_index(mt, val, GFP_KERNEL));
416e15e06a8SLiam R. Howlett 		else
417e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, mtree_insert(mt, val,
418e15e06a8SLiam R. Howlett 				XA_ZERO_ENTRY, GFP_KERNEL));
419e15e06a8SLiam R. Howlett 
420e15e06a8SLiam R. Howlett 		val <<= 2;
421e15e06a8SLiam R. Howlett 	}
422e15e06a8SLiam R. Howlett 
423e15e06a8SLiam R. Howlett 	val = 0;
424e15e06a8SLiam R. Howlett 	mas_set(&mas, val);
425e15e06a8SLiam R. Howlett 	mas_lock(&mas);
426e15e06a8SLiam R. Howlett 	while ((entry = mas_find(&mas, 268435456)) != NULL) {
427e15e06a8SLiam R. Howlett 		if (val != 64)
428e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
429e15e06a8SLiam R. Howlett 		else
430e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
431e15e06a8SLiam R. Howlett 
432e15e06a8SLiam R. Howlett 		val <<= 2;
433e15e06a8SLiam R. Howlett 		/* For zero check. */
434e15e06a8SLiam R. Howlett 		if (!val)
435e15e06a8SLiam R. Howlett 			val = 1;
436e15e06a8SLiam R. Howlett 	}
437e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
438e15e06a8SLiam R. Howlett 
439e15e06a8SLiam R. Howlett 	val = 0;
440e15e06a8SLiam R. Howlett 	mas_set(&mas, val);
441e15e06a8SLiam R. Howlett 	mas_lock(&mas);
442e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX) {
443e15e06a8SLiam R. Howlett 		if (val != 64)
444e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
445e15e06a8SLiam R. Howlett 		else
446e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
447e15e06a8SLiam R. Howlett 		val <<= 2;
448e15e06a8SLiam R. Howlett 		/* For zero check. */
449e15e06a8SLiam R. Howlett 		if (!val)
450e15e06a8SLiam R. Howlett 			val = 1;
451e15e06a8SLiam R. Howlett 	}
452e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
453e15e06a8SLiam R. Howlett 
454e15e06a8SLiam R. Howlett 	/* Test mas_pause */
455e15e06a8SLiam R. Howlett 	val = 0;
456e15e06a8SLiam R. Howlett 	mas_set(&mas, val);
457e15e06a8SLiam R. Howlett 	mas_lock(&mas);
458e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX) {
459e15e06a8SLiam R. Howlett 		if (val != 64)
460e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
461e15e06a8SLiam R. Howlett 		else
462e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
463e15e06a8SLiam R. Howlett 		val <<= 2;
464e15e06a8SLiam R. Howlett 		/* For zero check. */
465e15e06a8SLiam R. Howlett 		if (!val)
466e15e06a8SLiam R. Howlett 			val = 1;
467e15e06a8SLiam R. Howlett 
468e15e06a8SLiam R. Howlett 		mas_pause(&mas);
469e15e06a8SLiam R. Howlett 		mas_unlock(&mas);
470e15e06a8SLiam R. Howlett 		mas_lock(&mas);
471e15e06a8SLiam R. Howlett 	}
472e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
473e15e06a8SLiam R. Howlett 
474e15e06a8SLiam R. Howlett 	val = 0;
475e15e06a8SLiam R. Howlett 	max = 300; /* A value big enough to include XA_ZERO_ENTRY at 64. */
476e15e06a8SLiam R. Howlett 	mt_for_each(mt, entry, index, max) {
477e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, xa_mk_value(val) != entry);
478e15e06a8SLiam R. Howlett 		val <<= 2;
479e15e06a8SLiam R. Howlett 		if (val == 64) /* Skip zero entry. */
480e15e06a8SLiam R. Howlett 			val <<= 2;
481e15e06a8SLiam R. Howlett 		/* For zero check. */
482e15e06a8SLiam R. Howlett 		if (!val)
483e15e06a8SLiam R. Howlett 			val = 1;
484e15e06a8SLiam R. Howlett 	}
485e15e06a8SLiam R. Howlett 
486e15e06a8SLiam R. Howlett 	val = 0;
487e15e06a8SLiam R. Howlett 	max = 0;
488e15e06a8SLiam R. Howlett 	index = 0;
489e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
490e15e06a8SLiam R. Howlett 	mt_for_each(mt, entry, index, ULONG_MAX) {
491120b1162SLiam Howlett 		if (val == top)
492120b1162SLiam Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(LONG_MAX));
493e15e06a8SLiam R. Howlett 		else
494e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
495120b1162SLiam Howlett 
496120b1162SLiam Howlett 		/* Workaround for 32bit */
497120b1162SLiam Howlett 		if ((val << 2) < val)
498120b1162SLiam Howlett 			val = ULONG_MAX;
499120b1162SLiam Howlett 		else
500e15e06a8SLiam R. Howlett 			val <<= 2;
501120b1162SLiam Howlett 
502e15e06a8SLiam R. Howlett 		if (val == 64) /* Skip zero entry. */
503e15e06a8SLiam R. Howlett 			val <<= 2;
504e15e06a8SLiam R. Howlett 		/* For zero check. */
505e15e06a8SLiam R. Howlett 		if (!val)
506e15e06a8SLiam R. Howlett 			val = 1;
507e15e06a8SLiam R. Howlett 		max++;
508e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, max > 25);
509e15e06a8SLiam R. Howlett 	}
510e15e06a8SLiam R. Howlett 	mtree_erase_index(mt, ULONG_MAX);
511e15e06a8SLiam R. Howlett 
512e15e06a8SLiam R. Howlett 	mas_reset(&mas);
513e15e06a8SLiam R. Howlett 	index = 17;
514e15e06a8SLiam R. Howlett 	entry = mt_find(mt, &index, 512);
515e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, xa_mk_value(256) != entry);
516e15e06a8SLiam R. Howlett 
517e15e06a8SLiam R. Howlett 	mas_reset(&mas);
518e15e06a8SLiam R. Howlett 	index = 17;
519e15e06a8SLiam R. Howlett 	entry = mt_find(mt, &index, 20);
520e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
521e15e06a8SLiam R. Howlett 
522e15e06a8SLiam R. Howlett 
523e15e06a8SLiam R. Howlett 	/* Range check.. */
524e15e06a8SLiam R. Howlett 	/* Insert ULONG_MAX */
525e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
526e15e06a8SLiam R. Howlett 
527e15e06a8SLiam R. Howlett 	val = 0;
528e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
529e15e06a8SLiam R. Howlett 	mas_lock(&mas);
530e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX) {
531e15e06a8SLiam R. Howlett 		if (val == 64)
532e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
533120b1162SLiam Howlett 		else if (val == top)
534120b1162SLiam Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(LONG_MAX));
535e15e06a8SLiam R. Howlett 		else
536e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
537120b1162SLiam Howlett 
538120b1162SLiam Howlett 		/* Workaround for 32bit */
539120b1162SLiam Howlett 		if ((val << 2) < val)
540120b1162SLiam Howlett 			val = ULONG_MAX;
541120b1162SLiam Howlett 		else
542e15e06a8SLiam R. Howlett 			val <<= 2;
543e15e06a8SLiam R. Howlett 
544e15e06a8SLiam R. Howlett 		/* For zero check. */
545e15e06a8SLiam R. Howlett 		if (!val)
546e15e06a8SLiam R. Howlett 			val = 1;
547e15e06a8SLiam R. Howlett 		mas_pause(&mas);
548e15e06a8SLiam R. Howlett 		mas_unlock(&mas);
549e15e06a8SLiam R. Howlett 		mas_lock(&mas);
550e15e06a8SLiam R. Howlett 	}
551e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
552e15e06a8SLiam R. Howlett 
553e15e06a8SLiam R. Howlett 	mas_set(&mas, 1048576);
554e15e06a8SLiam R. Howlett 	mas_lock(&mas);
555e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, 1048576);
556e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
557e15e06a8SLiam R. Howlett 	MT_BUG_ON(mas.tree, entry == NULL);
558e15e06a8SLiam R. Howlett 
559e15e06a8SLiam R. Howlett 	/*
560e15e06a8SLiam R. Howlett 	 * Find last value.
561e15e06a8SLiam R. Howlett 	 * 1. get the expected value, leveraging the existence of an end entry
562e15e06a8SLiam R. Howlett 	 * 2. delete end entry
563e15e06a8SLiam R. Howlett 	 * 3. find the last value but searching for ULONG_MAX and then using
564e15e06a8SLiam R. Howlett 	 * prev
565e15e06a8SLiam R. Howlett 	 */
566e15e06a8SLiam R. Howlett 	/* First, get the expected result. */
567e15e06a8SLiam R. Howlett 	mas_lock(&mas);
568e15e06a8SLiam R. Howlett 	mas_reset(&mas);
569e15e06a8SLiam R. Howlett 	mas.index = ULONG_MAX; /* start at max.. */
570e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
571e15e06a8SLiam R. Howlett 	entry = mas_prev(&mas, 0);
572e15e06a8SLiam R. Howlett 	index = mas.index;
573e15e06a8SLiam R. Howlett 	last = mas.last;
574e15e06a8SLiam R. Howlett 
575e15e06a8SLiam R. Howlett 	/* Erase the last entry. */
576e15e06a8SLiam R. Howlett 	mas_reset(&mas);
577e15e06a8SLiam R. Howlett 	mas.index = ULONG_MAX;
578e15e06a8SLiam R. Howlett 	mas.last = ULONG_MAX;
579e15e06a8SLiam R. Howlett 	mas_erase(&mas);
580e15e06a8SLiam R. Howlett 
581e15e06a8SLiam R. Howlett 	/* Get the previous value from MAS_START */
582e15e06a8SLiam R. Howlett 	mas_reset(&mas);
583e15e06a8SLiam R. Howlett 	entry2 = mas_prev(&mas, 0);
584e15e06a8SLiam R. Howlett 
585e15e06a8SLiam R. Howlett 	/* Check results. */
586e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != entry2);
587e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, index != mas.index);
588e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, last != mas.last);
589e15e06a8SLiam R. Howlett 
590e15e06a8SLiam R. Howlett 
591067311d3SLiam R. Howlett 	mas.status = ma_none;
592e15e06a8SLiam R. Howlett 	mas.index = ULONG_MAX;
593e15e06a8SLiam R. Howlett 	mas.last = ULONG_MAX;
594e15e06a8SLiam R. Howlett 	entry2 = mas_prev(&mas, 0);
595e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != entry2);
596e15e06a8SLiam R. Howlett 
597e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
598e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_prev(&mas, 0) != NULL);
599e15e06a8SLiam R. Howlett 
600e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
601e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
602e15e06a8SLiam R. Howlett }
603e15e06a8SLiam R. Howlett 
check_find_2(struct maple_tree * mt)604eaf9790dSLiam R. Howlett static noinline void __init check_find_2(struct maple_tree *mt)
605e15e06a8SLiam R. Howlett {
606e15e06a8SLiam R. Howlett 	unsigned long i, j;
607e15e06a8SLiam R. Howlett 	void *entry;
608e15e06a8SLiam R. Howlett 
609e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
610e15e06a8SLiam R. Howlett 	rcu_read_lock();
611e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX)
612e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, true);
613e15e06a8SLiam R. Howlett 	rcu_read_unlock();
614e15e06a8SLiam R. Howlett 
615e15e06a8SLiam R. Howlett 	for (i = 0; i < 256; i++) {
616e15e06a8SLiam R. Howlett 		mtree_insert_index(mt, i, GFP_KERNEL);
617e15e06a8SLiam R. Howlett 		j = 0;
618e15e06a8SLiam R. Howlett 		mas_set(&mas, 0);
619e15e06a8SLiam R. Howlett 		rcu_read_lock();
620e15e06a8SLiam R. Howlett 		mas_for_each(&mas, entry, ULONG_MAX) {
621e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
622e15e06a8SLiam R. Howlett 			j++;
623e15e06a8SLiam R. Howlett 		}
624e15e06a8SLiam R. Howlett 		rcu_read_unlock();
625e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, j != i + 1);
626e15e06a8SLiam R. Howlett 	}
627e15e06a8SLiam R. Howlett 
628e15e06a8SLiam R. Howlett 	for (i = 0; i < 256; i++) {
629e15e06a8SLiam R. Howlett 		mtree_erase_index(mt, i);
630e15e06a8SLiam R. Howlett 		j = i + 1;
631e15e06a8SLiam R. Howlett 		mas_set(&mas, 0);
632e15e06a8SLiam R. Howlett 		rcu_read_lock();
633e15e06a8SLiam R. Howlett 		mas_for_each(&mas, entry, ULONG_MAX) {
634e15e06a8SLiam R. Howlett 			if (xa_is_zero(entry))
635e15e06a8SLiam R. Howlett 				continue;
636e15e06a8SLiam R. Howlett 
637e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
638e15e06a8SLiam R. Howlett 			j++;
639e15e06a8SLiam R. Howlett 		}
640e15e06a8SLiam R. Howlett 		rcu_read_unlock();
641e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, j != 256);
642e15e06a8SLiam R. Howlett 	}
643e15e06a8SLiam R. Howlett 
644e15e06a8SLiam R. Howlett 	/*MT_BUG_ON(mt, !mtree_empty(mt)); */
645e15e06a8SLiam R. Howlett }
646e15e06a8SLiam R. Howlett 
647e15e06a8SLiam R. Howlett 
648120b1162SLiam Howlett #if defined(CONFIG_64BIT)
check_alloc_rev_range(struct maple_tree * mt)649eaf9790dSLiam R. Howlett static noinline void __init check_alloc_rev_range(struct maple_tree *mt)
650e15e06a8SLiam R. Howlett {
651e15e06a8SLiam R. Howlett 	/*
652e15e06a8SLiam R. Howlett 	 * Generated by:
653e15e06a8SLiam R. Howlett 	 * cat /proc/self/maps | awk '{print $1}'|
654e15e06a8SLiam R. Howlett 	 * awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}'
655e15e06a8SLiam R. Howlett 	 */
656e15e06a8SLiam R. Howlett 
657eaf9790dSLiam R. Howlett 	static const unsigned long range[] = {
658e15e06a8SLiam R. Howlett 	/*      Inclusive     , Exclusive. */
659e15e06a8SLiam R. Howlett 		0x565234af2000, 0x565234af4000,
660e15e06a8SLiam R. Howlett 		0x565234af4000, 0x565234af9000,
661e15e06a8SLiam R. Howlett 		0x565234af9000, 0x565234afb000,
662e15e06a8SLiam R. Howlett 		0x565234afc000, 0x565234afd000,
663e15e06a8SLiam R. Howlett 		0x565234afd000, 0x565234afe000,
664e15e06a8SLiam R. Howlett 		0x565235def000, 0x565235e10000,
665e15e06a8SLiam R. Howlett 		0x7f36d4bfd000, 0x7f36d4ee2000,
666e15e06a8SLiam R. Howlett 		0x7f36d4ee2000, 0x7f36d4f04000,
667e15e06a8SLiam R. Howlett 		0x7f36d4f04000, 0x7f36d504c000,
668e15e06a8SLiam R. Howlett 		0x7f36d504c000, 0x7f36d5098000,
669e15e06a8SLiam R. Howlett 		0x7f36d5098000, 0x7f36d5099000,
670e15e06a8SLiam R. Howlett 		0x7f36d5099000, 0x7f36d509d000,
671e15e06a8SLiam R. Howlett 		0x7f36d509d000, 0x7f36d509f000,
672e15e06a8SLiam R. Howlett 		0x7f36d509f000, 0x7f36d50a5000,
673e15e06a8SLiam R. Howlett 		0x7f36d50b9000, 0x7f36d50db000,
674e15e06a8SLiam R. Howlett 		0x7f36d50db000, 0x7f36d50dc000,
675e15e06a8SLiam R. Howlett 		0x7f36d50dc000, 0x7f36d50fa000,
676e15e06a8SLiam R. Howlett 		0x7f36d50fa000, 0x7f36d5102000,
677e15e06a8SLiam R. Howlett 		0x7f36d5102000, 0x7f36d5103000,
678e15e06a8SLiam R. Howlett 		0x7f36d5103000, 0x7f36d5104000,
679e15e06a8SLiam R. Howlett 		0x7f36d5104000, 0x7f36d5105000,
680e15e06a8SLiam R. Howlett 		0x7fff5876b000, 0x7fff5878d000,
681e15e06a8SLiam R. Howlett 		0x7fff5878e000, 0x7fff58791000,
682e15e06a8SLiam R. Howlett 		0x7fff58791000, 0x7fff58793000,
683e15e06a8SLiam R. Howlett 	};
684e15e06a8SLiam R. Howlett 
685eaf9790dSLiam R. Howlett 	static const unsigned long holes[] = {
686e15e06a8SLiam R. Howlett 		/*
687e15e06a8SLiam R. Howlett 		 * Note: start of hole is INCLUSIVE
688e15e06a8SLiam R. Howlett 		 *        end of hole is EXCLUSIVE
689e15e06a8SLiam R. Howlett 		 *        (opposite of the above table.)
690e15e06a8SLiam R. Howlett 		 * Start of hole, end of hole,  size of hole (+1)
691e15e06a8SLiam R. Howlett 		 */
692e15e06a8SLiam R. Howlett 		0x565234afb000, 0x565234afc000, 0x1000,
693e15e06a8SLiam R. Howlett 		0x565234afe000, 0x565235def000, 0x12F1000,
694e15e06a8SLiam R. Howlett 		0x565235e10000, 0x7f36d4bfd000, 0x28E49EDED000,
695e15e06a8SLiam R. Howlett 	};
696e15e06a8SLiam R. Howlett 
697e15e06a8SLiam R. Howlett 	/*
698e15e06a8SLiam R. Howlett 	 * req_range consists of 4 values.
699e15e06a8SLiam R. Howlett 	 * 1. min index
700e15e06a8SLiam R. Howlett 	 * 2. max index
701e15e06a8SLiam R. Howlett 	 * 3. size
702e15e06a8SLiam R. Howlett 	 * 4. number that should be returned.
703e15e06a8SLiam R. Howlett 	 * 5. return value
704e15e06a8SLiam R. Howlett 	 */
705eaf9790dSLiam R. Howlett 	static const unsigned long req_range[] = {
706e15e06a8SLiam R. Howlett 		0x565234af9000, /* Min */
707e15e06a8SLiam R. Howlett 		0x7fff58791000, /* Max */
708e15e06a8SLiam R. Howlett 		0x1000,         /* Size */
709e15e06a8SLiam R. Howlett 		0x7fff5878d << 12,  /* First rev hole of size 0x1000 */
710e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
711e15e06a8SLiam R. Howlett 
712e15e06a8SLiam R. Howlett 		0x0,            /* Min */
713ba997212SLiam R. Howlett 		0x565234AF0 << 12,    /* Max */
714e15e06a8SLiam R. Howlett 		0x3000,         /* Size */
715e15e06a8SLiam R. Howlett 		0x565234AEE << 12,  /* max - 3. */
716e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
717e15e06a8SLiam R. Howlett 
718e15e06a8SLiam R. Howlett 		0x0,            /* Min */
719e15e06a8SLiam R. Howlett 		-1,             /* Max */
720e15e06a8SLiam R. Howlett 		0x1000,         /* Size */
721e15e06a8SLiam R. Howlett 		562949953421311 << 12,/* First rev hole of size 0x1000 */
722e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
723e15e06a8SLiam R. Howlett 
724e15e06a8SLiam R. Howlett 		0x0,            /* Min */
725ba997212SLiam R. Howlett 		0x7F36D5109 << 12,    /* Max */
726e15e06a8SLiam R. Howlett 		0x4000,         /* Size */
727e15e06a8SLiam R. Howlett 		0x7F36D5106 << 12,    /* First rev hole of size 0x4000 */
728e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
729e15e06a8SLiam R. Howlett 
730e15e06a8SLiam R. Howlett 		/* Ascend test. */
731e15e06a8SLiam R. Howlett 		0x0,
732ba997212SLiam R. Howlett 		34148798628 << 12,
733e15e06a8SLiam R. Howlett 		19 << 12,
734e15e06a8SLiam R. Howlett 		34148797418 << 12,
735e15e06a8SLiam R. Howlett 		0x0,
736e15e06a8SLiam R. Howlett 
737e15e06a8SLiam R. Howlett 		/* Too big test. */
738e15e06a8SLiam R. Howlett 		0x0,
739e15e06a8SLiam R. Howlett 		18446744073709551615UL,
740e15e06a8SLiam R. Howlett 		562915594369134UL << 12,
741e15e06a8SLiam R. Howlett 		0x0,
742e15e06a8SLiam R. Howlett 		-EBUSY,
743e15e06a8SLiam R. Howlett 
744ba997212SLiam R. Howlett 		/* Single space test. */
745ba997212SLiam R. Howlett 		34148798725 << 12,
746ba997212SLiam R. Howlett 		34148798725 << 12,
747ba997212SLiam R. Howlett 		1 << 12,
748ba997212SLiam R. Howlett 		34148798725 << 12,
749ba997212SLiam R. Howlett 		0,
750e15e06a8SLiam R. Howlett 	};
751e15e06a8SLiam R. Howlett 
752e15e06a8SLiam R. Howlett 	int i, range_count = ARRAY_SIZE(range);
753e15e06a8SLiam R. Howlett 	int req_range_count = ARRAY_SIZE(req_range);
754e15e06a8SLiam R. Howlett 	unsigned long min = 0;
755e15e06a8SLiam R. Howlett 
756e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
757e15e06a8SLiam R. Howlett 
758e15e06a8SLiam R. Howlett 	mtree_store_range(mt, MTREE_ALLOC_MAX, ULONG_MAX, XA_ZERO_ENTRY,
759e15e06a8SLiam R. Howlett 			  GFP_KERNEL);
760e15e06a8SLiam R. Howlett #define DEBUG_REV_RANGE 0
761e15e06a8SLiam R. Howlett 	for (i = 0; i < range_count; i += 2) {
762e15e06a8SLiam R. Howlett 		/* Inclusive, Inclusive (with the -1) */
763e15e06a8SLiam R. Howlett 
764e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
765e15e06a8SLiam R. Howlett 		pr_debug("\t%s: Insert %lu-%lu\n", __func__, range[i] >> 12,
766e15e06a8SLiam R. Howlett 				(range[i + 1] >> 12) - 1);
767e15e06a8SLiam R. Howlett #endif
768e15e06a8SLiam R. Howlett 		check_insert_range(mt, range[i] >> 12, (range[i + 1] >> 12) - 1,
769e15e06a8SLiam R. Howlett 				xa_mk_value(range[i] >> 12), 0);
770e15e06a8SLiam R. Howlett 		mt_validate(mt);
771e15e06a8SLiam R. Howlett 	}
772e15e06a8SLiam R. Howlett 
773e15e06a8SLiam R. Howlett 
774120b1162SLiam Howlett 	mas_lock(&mas);
775e15e06a8SLiam R. Howlett 	for (i = 0; i < ARRAY_SIZE(holes); i += 3) {
776e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
777e15e06a8SLiam R. Howlett 		pr_debug("Search from %lu-%lu for gap %lu should be at %lu\n",
778e15e06a8SLiam R. Howlett 				min, holes[i+1]>>12, holes[i+2]>>12,
779e15e06a8SLiam R. Howlett 				holes[i] >> 12);
780e15e06a8SLiam R. Howlett #endif
781e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas_empty_area_rev(&mas, min,
782e15e06a8SLiam R. Howlett 					holes[i+1] >> 12,
783e15e06a8SLiam R. Howlett 					holes[i+2] >> 12));
784e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
785e15e06a8SLiam R. Howlett 		pr_debug("Found %lu %lu\n", mas.index, mas.last);
786e15e06a8SLiam R. Howlett 		pr_debug("gap %lu %lu\n", (holes[i] >> 12),
787e15e06a8SLiam R. Howlett 				(holes[i+1] >> 12));
788e15e06a8SLiam R. Howlett #endif
789e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas.last + 1 != (holes[i+1] >> 12));
790e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas.index != (holes[i+1] >> 12) - (holes[i+2] >> 12));
791e15e06a8SLiam R. Howlett 		min = holes[i+1] >> 12;
792e15e06a8SLiam R. Howlett 		mas_reset(&mas);
793e15e06a8SLiam R. Howlett 	}
794e15e06a8SLiam R. Howlett 
795120b1162SLiam Howlett 	mas_unlock(&mas);
796e15e06a8SLiam R. Howlett 	for (i = 0; i < req_range_count; i += 5) {
797e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
798ba997212SLiam R. Howlett 		pr_debug("\tReverse request %d between %lu-%lu size %lu, should get %lu\n",
799ba997212SLiam R. Howlett 				i, req_range[i] >> 12,
800ba997212SLiam R. Howlett 				(req_range[i + 1] >> 12),
801e15e06a8SLiam R. Howlett 				req_range[i+2] >> 12,
802e15e06a8SLiam R. Howlett 				req_range[i+3] >> 12);
803e15e06a8SLiam R. Howlett #endif
804e15e06a8SLiam R. Howlett 		check_mtree_alloc_rrange(mt,
805e15e06a8SLiam R. Howlett 				req_range[i]   >> 12, /* start */
806e15e06a8SLiam R. Howlett 				req_range[i+1] >> 12, /* end */
807e15e06a8SLiam R. Howlett 				req_range[i+2] >> 12, /* size */
808e15e06a8SLiam R. Howlett 				req_range[i+3] >> 12, /* expected address */
809e15e06a8SLiam R. Howlett 				req_range[i+4],       /* expected return */
810e15e06a8SLiam R. Howlett 				xa_mk_value(req_range[i] >> 12)); /* pointer */
811e15e06a8SLiam R. Howlett 		mt_validate(mt);
812e15e06a8SLiam R. Howlett 	}
813e15e06a8SLiam R. Howlett 
814e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
815e15e06a8SLiam R. Howlett 	mtree_erase(mt, 34148798727); /* create a deleted range. */
816ba997212SLiam R. Howlett 	mtree_erase(mt, 34148798725);
817e15e06a8SLiam R. Howlett 	check_mtree_alloc_rrange(mt, 0, 34359052173, 210253414,
818e15e06a8SLiam R. Howlett 			34148798725, 0, mt);
819e15e06a8SLiam R. Howlett 
820e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
821e15e06a8SLiam R. Howlett }
822e15e06a8SLiam R. Howlett 
check_alloc_range(struct maple_tree * mt)823eaf9790dSLiam R. Howlett static noinline void __init check_alloc_range(struct maple_tree *mt)
824e15e06a8SLiam R. Howlett {
825e15e06a8SLiam R. Howlett 	/*
826e15e06a8SLiam R. Howlett 	 * Generated by:
827e15e06a8SLiam R. Howlett 	 * cat /proc/self/maps|awk '{print $1}'|
828e15e06a8SLiam R. Howlett 	 * awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}'
829e15e06a8SLiam R. Howlett 	 */
830e15e06a8SLiam R. Howlett 
831eaf9790dSLiam R. Howlett 	static const unsigned long range[] = {
832e15e06a8SLiam R. Howlett 	/*      Inclusive     , Exclusive. */
833e15e06a8SLiam R. Howlett 		0x565234af2000, 0x565234af4000,
834e15e06a8SLiam R. Howlett 		0x565234af4000, 0x565234af9000,
835e15e06a8SLiam R. Howlett 		0x565234af9000, 0x565234afb000,
836e15e06a8SLiam R. Howlett 		0x565234afc000, 0x565234afd000,
837e15e06a8SLiam R. Howlett 		0x565234afd000, 0x565234afe000,
838e15e06a8SLiam R. Howlett 		0x565235def000, 0x565235e10000,
839e15e06a8SLiam R. Howlett 		0x7f36d4bfd000, 0x7f36d4ee2000,
840e15e06a8SLiam R. Howlett 		0x7f36d4ee2000, 0x7f36d4f04000,
841e15e06a8SLiam R. Howlett 		0x7f36d4f04000, 0x7f36d504c000,
842e15e06a8SLiam R. Howlett 		0x7f36d504c000, 0x7f36d5098000,
843e15e06a8SLiam R. Howlett 		0x7f36d5098000, 0x7f36d5099000,
844e15e06a8SLiam R. Howlett 		0x7f36d5099000, 0x7f36d509d000,
845e15e06a8SLiam R. Howlett 		0x7f36d509d000, 0x7f36d509f000,
846e15e06a8SLiam R. Howlett 		0x7f36d509f000, 0x7f36d50a5000,
847e15e06a8SLiam R. Howlett 		0x7f36d50b9000, 0x7f36d50db000,
848e15e06a8SLiam R. Howlett 		0x7f36d50db000, 0x7f36d50dc000,
849e15e06a8SLiam R. Howlett 		0x7f36d50dc000, 0x7f36d50fa000,
850e15e06a8SLiam R. Howlett 		0x7f36d50fa000, 0x7f36d5102000,
851e15e06a8SLiam R. Howlett 		0x7f36d5102000, 0x7f36d5103000,
852e15e06a8SLiam R. Howlett 		0x7f36d5103000, 0x7f36d5104000,
853e15e06a8SLiam R. Howlett 		0x7f36d5104000, 0x7f36d5105000,
854e15e06a8SLiam R. Howlett 		0x7fff5876b000, 0x7fff5878d000,
855e15e06a8SLiam R. Howlett 		0x7fff5878e000, 0x7fff58791000,
856e15e06a8SLiam R. Howlett 		0x7fff58791000, 0x7fff58793000,
857e15e06a8SLiam R. Howlett 	};
858eaf9790dSLiam R. Howlett 	static const unsigned long holes[] = {
859e15e06a8SLiam R. Howlett 		/* Start of hole, end of hole,  size of hole (+1) */
860e15e06a8SLiam R. Howlett 		0x565234afb000, 0x565234afc000, 0x1000,
861e15e06a8SLiam R. Howlett 		0x565234afe000, 0x565235def000, 0x12F1000,
862e15e06a8SLiam R. Howlett 		0x565235e10000, 0x7f36d4bfd000, 0x28E49EDED000,
863e15e06a8SLiam R. Howlett 	};
864e15e06a8SLiam R. Howlett 
865e15e06a8SLiam R. Howlett 	/*
866e15e06a8SLiam R. Howlett 	 * req_range consists of 4 values.
867e15e06a8SLiam R. Howlett 	 * 1. min index
868e15e06a8SLiam R. Howlett 	 * 2. max index
869e15e06a8SLiam R. Howlett 	 * 3. size
870e15e06a8SLiam R. Howlett 	 * 4. number that should be returned.
871e15e06a8SLiam R. Howlett 	 * 5. return value
872e15e06a8SLiam R. Howlett 	 */
873eaf9790dSLiam R. Howlett 	static const unsigned long req_range[] = {
874e15e06a8SLiam R. Howlett 		0x565234af9000, /* Min */
875e15e06a8SLiam R. Howlett 		0x7fff58791000, /* Max */
876e15e06a8SLiam R. Howlett 		0x1000,         /* Size */
877e15e06a8SLiam R. Howlett 		0x565234afb000, /* First hole in our data of size 1000. */
878e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
879e15e06a8SLiam R. Howlett 
880e15e06a8SLiam R. Howlett 		0x0,            /* Min */
881e15e06a8SLiam R. Howlett 		0x7fff58791000, /* Max */
882e15e06a8SLiam R. Howlett 		0x1F00,         /* Size */
883e15e06a8SLiam R. Howlett 		0x0,            /* First hole in our data of size 2000. */
884e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
885e15e06a8SLiam R. Howlett 
886e15e06a8SLiam R. Howlett 		/* Test ascend. */
887e15e06a8SLiam R. Howlett 		34148797436 << 12, /* Min */
888e15e06a8SLiam R. Howlett 		0x7fff587AF000,    /* Max */
889e15e06a8SLiam R. Howlett 		0x3000,         /* Size */
890e15e06a8SLiam R. Howlett 		34148798629 << 12,             /* Expected location */
891e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
892e15e06a8SLiam R. Howlett 
893e15e06a8SLiam R. Howlett 		/* Test failing. */
894e15e06a8SLiam R. Howlett 		34148798623 << 12,  /* Min */
895e15e06a8SLiam R. Howlett 		34148798683 << 12,  /* Max */
896e15e06a8SLiam R. Howlett 		0x15000,            /* Size */
897e15e06a8SLiam R. Howlett 		0,             /* Expected location */
898e15e06a8SLiam R. Howlett 		-EBUSY,              /* Return value failed. */
899e15e06a8SLiam R. Howlett 
900e15e06a8SLiam R. Howlett 		/* Test filling entire gap. */
901e15e06a8SLiam R. Howlett 		34148798623 << 12,  /* Min */
902e15e06a8SLiam R. Howlett 		0x7fff587AF000,    /* Max */
903e15e06a8SLiam R. Howlett 		0x10000,           /* Size */
904e15e06a8SLiam R. Howlett 		34148798632 << 12,             /* Expected location */
905e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
906e15e06a8SLiam R. Howlett 
907e15e06a8SLiam R. Howlett 		/* Test walking off the end of root. */
908e15e06a8SLiam R. Howlett 		0,                  /* Min */
909e15e06a8SLiam R. Howlett 		-1,                 /* Max */
910e15e06a8SLiam R. Howlett 		-1,                 /* Size */
911e15e06a8SLiam R. Howlett 		0,                  /* Expected location */
912e15e06a8SLiam R. Howlett 		-EBUSY,             /* Return value failure. */
913e15e06a8SLiam R. Howlett 
914e15e06a8SLiam R. Howlett 		/* Test looking for too large a hole across entire range. */
915e15e06a8SLiam R. Howlett 		0,                  /* Min */
916e15e06a8SLiam R. Howlett 		-1,                 /* Max */
917e15e06a8SLiam R. Howlett 		4503599618982063UL << 12,  /* Size */
918e15e06a8SLiam R. Howlett 		34359052178 << 12,  /* Expected location */
919e15e06a8SLiam R. Howlett 		-EBUSY,             /* Return failure. */
920ba997212SLiam R. Howlett 
921ba997212SLiam R. Howlett 		/* Test a single entry */
922ba997212SLiam R. Howlett 		34148798648 << 12,		/* Min */
923ba997212SLiam R. Howlett 		34148798648 << 12,		/* Max */
924ba997212SLiam R. Howlett 		4096,			/* Size of 1 */
925ba997212SLiam R. Howlett 		34148798648 << 12,	/* Location is the same as min/max */
926ba997212SLiam R. Howlett 		0,			/* Success */
927e15e06a8SLiam R. Howlett 	};
928e15e06a8SLiam R. Howlett 	int i, range_count = ARRAY_SIZE(range);
929e15e06a8SLiam R. Howlett 	int req_range_count = ARRAY_SIZE(req_range);
930e15e06a8SLiam R. Howlett 	unsigned long min = 0x565234af2000;
931120b1162SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
932e15e06a8SLiam R. Howlett 
933e15e06a8SLiam R. Howlett 	mtree_store_range(mt, MTREE_ALLOC_MAX, ULONG_MAX, XA_ZERO_ENTRY,
934e15e06a8SLiam R. Howlett 			  GFP_KERNEL);
935e15e06a8SLiam R. Howlett 	for (i = 0; i < range_count; i += 2) {
936e15e06a8SLiam R. Howlett #define DEBUG_ALLOC_RANGE 0
937e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
938e15e06a8SLiam R. Howlett 		pr_debug("\tInsert %lu-%lu\n", range[i] >> 12,
939e15e06a8SLiam R. Howlett 			 (range[i + 1] >> 12) - 1);
94089f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_hex);
941e15e06a8SLiam R. Howlett #endif
942e15e06a8SLiam R. Howlett 		check_insert_range(mt, range[i] >> 12, (range[i + 1] >> 12) - 1,
943e15e06a8SLiam R. Howlett 				xa_mk_value(range[i] >> 12), 0);
944e15e06a8SLiam R. Howlett 		mt_validate(mt);
945e15e06a8SLiam R. Howlett 	}
946e15e06a8SLiam R. Howlett 
947e15e06a8SLiam R. Howlett 
948e15e06a8SLiam R. Howlett 
949120b1162SLiam Howlett 	mas_lock(&mas);
950e15e06a8SLiam R. Howlett 	for (i = 0; i < ARRAY_SIZE(holes); i += 3) {
951e15e06a8SLiam R. Howlett 
952e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
953e15e06a8SLiam R. Howlett 		pr_debug("\tGet empty %lu-%lu size %lu (%lx-%lx)\n", min >> 12,
954e15e06a8SLiam R. Howlett 			holes[i+1] >> 12, holes[i+2] >> 12,
955e15e06a8SLiam R. Howlett 			min, holes[i+1]);
956e15e06a8SLiam R. Howlett #endif
957e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas_empty_area(&mas, min >> 12,
958e15e06a8SLiam R. Howlett 					holes[i+1] >> 12,
959e15e06a8SLiam R. Howlett 					holes[i+2] >> 12));
960e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas.index != holes[i] >> 12);
961e15e06a8SLiam R. Howlett 		min = holes[i+1];
962e15e06a8SLiam R. Howlett 		mas_reset(&mas);
963e15e06a8SLiam R. Howlett 	}
964120b1162SLiam Howlett 	mas_unlock(&mas);
965e15e06a8SLiam R. Howlett 	for (i = 0; i < req_range_count; i += 5) {
966e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
967e15e06a8SLiam R. Howlett 		pr_debug("\tTest %d: %lu-%lu size %lu expected %lu (%lu-%lu)\n",
968e15e06a8SLiam R. Howlett 			 i/5, req_range[i]   >> 12, req_range[i + 1]   >> 12,
969e15e06a8SLiam R. Howlett 			 req_range[i + 2]   >> 12, req_range[i + 3]   >> 12,
970e15e06a8SLiam R. Howlett 			 req_range[i], req_range[i+1]);
971e15e06a8SLiam R. Howlett #endif
972e15e06a8SLiam R. Howlett 		check_mtree_alloc_range(mt,
973e15e06a8SLiam R. Howlett 				req_range[i]   >> 12, /* start */
974e15e06a8SLiam R. Howlett 				req_range[i+1] >> 12, /* end */
975e15e06a8SLiam R. Howlett 				req_range[i+2] >> 12, /* size */
976e15e06a8SLiam R. Howlett 				req_range[i+3] >> 12, /* expected address */
977e15e06a8SLiam R. Howlett 				req_range[i+4],       /* expected return */
978e15e06a8SLiam R. Howlett 				xa_mk_value(req_range[i] >> 12)); /* pointer */
979e15e06a8SLiam R. Howlett 		mt_validate(mt);
980e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
98189f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_hex);
982e15e06a8SLiam R. Howlett #endif
983e15e06a8SLiam R. Howlett 	}
984e15e06a8SLiam R. Howlett 
985e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
986e15e06a8SLiam R. Howlett }
987120b1162SLiam Howlett #endif
988e15e06a8SLiam R. Howlett 
check_ranges(struct maple_tree * mt)989eaf9790dSLiam R. Howlett static noinline void __init check_ranges(struct maple_tree *mt)
990e15e06a8SLiam R. Howlett {
991e15e06a8SLiam R. Howlett 	int i, val, val2;
992eaf9790dSLiam R. Howlett 	static const unsigned long r[] = {
993e15e06a8SLiam R. Howlett 		10, 15,
994e15e06a8SLiam R. Howlett 		20, 25,
995e15e06a8SLiam R. Howlett 		17, 22, /* Overlaps previous range. */
996e15e06a8SLiam R. Howlett 		9, 1000, /* Huge. */
997e15e06a8SLiam R. Howlett 		100, 200,
998e15e06a8SLiam R. Howlett 		45, 168,
999e15e06a8SLiam R. Howlett 		118, 128,
1000e15e06a8SLiam R. Howlett 			};
1001e15e06a8SLiam R. Howlett 
1002e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
1003e15e06a8SLiam R. Howlett 	check_insert_range(mt, r[0], r[1], xa_mk_value(r[0]), 0);
1004e15e06a8SLiam R. Howlett 	check_insert_range(mt, r[2], r[3], xa_mk_value(r[2]), 0);
1005e15e06a8SLiam R. Howlett 	check_insert_range(mt, r[4], r[5], xa_mk_value(r[4]), -EEXIST);
1006e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1007e15e06a8SLiam R. Howlett 	/* Store */
1008e15e06a8SLiam R. Howlett 	check_store_range(mt, r[4], r[5], xa_mk_value(r[4]), 0);
1009e15e06a8SLiam R. Howlett 	check_store_range(mt, r[6], r[7], xa_mk_value(r[6]), 0);
1010e15e06a8SLiam R. Howlett 	check_store_range(mt, r[8], r[9], xa_mk_value(r[8]), 0);
1011e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1012e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1013e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mt_height(mt));
1014e15e06a8SLiam R. Howlett 
1015e15e06a8SLiam R. Howlett 	check_seq(mt, 50, false);
1016e15e06a8SLiam R. Howlett 	mt_set_non_kernel(4);
1017e15e06a8SLiam R. Howlett 	check_store_range(mt, 5, 47,  xa_mk_value(47), 0);
1018e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1019e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1020e15e06a8SLiam R. Howlett 
1021e15e06a8SLiam R. Howlett 	/* Create tree of 1-100 */
1022e15e06a8SLiam R. Howlett 	check_seq(mt, 100, false);
1023e15e06a8SLiam R. Howlett 	/* Store 45-168 */
1024e15e06a8SLiam R. Howlett 	mt_set_non_kernel(10);
1025e15e06a8SLiam R. Howlett 	check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
1026e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1027e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1028e15e06a8SLiam R. Howlett 
1029e15e06a8SLiam R. Howlett 	/* Create tree of 1-200 */
1030e15e06a8SLiam R. Howlett 	check_seq(mt, 200, false);
1031e15e06a8SLiam R. Howlett 	/* Store 45-168 */
1032e15e06a8SLiam R. Howlett 	check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
1033e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1034e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1035e15e06a8SLiam R. Howlett 
1036e15e06a8SLiam R. Howlett 	check_seq(mt, 30, false);
1037e15e06a8SLiam R. Howlett 	check_store_range(mt, 6, 18, xa_mk_value(6), 0);
1038e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1039e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1040e15e06a8SLiam R. Howlett 
1041e15e06a8SLiam R. Howlett 	/* Overwrite across multiple levels. */
1042e15e06a8SLiam R. Howlett 	/* Create tree of 1-400 */
1043e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1044e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1045e15e06a8SLiam R. Howlett 	/* Store 118-128 */
1046e15e06a8SLiam R. Howlett 	check_store_range(mt, r[12], r[13], xa_mk_value(r[12]), 0);
1047e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1048e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 140);
1049e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 141);
1050e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 142);
1051e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 143);
1052e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 130);
1053e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 131);
1054e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 132);
1055e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 133);
1056e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 134);
1057e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 135);
1058e15e06a8SLiam R. Howlett 	check_load(mt, r[12], xa_mk_value(r[12]));
1059e15e06a8SLiam R. Howlett 	check_load(mt, r[13], xa_mk_value(r[12]));
1060e15e06a8SLiam R. Howlett 	check_load(mt, r[13] - 1, xa_mk_value(r[12]));
1061e15e06a8SLiam R. Howlett 	check_load(mt, r[13] + 1, xa_mk_value(r[13] + 1));
1062e15e06a8SLiam R. Howlett 	check_load(mt, 135, NULL);
1063e15e06a8SLiam R. Howlett 	check_load(mt, 140, NULL);
1064e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1065e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1066e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1067e15e06a8SLiam R. Howlett 
1068e15e06a8SLiam R. Howlett 
1069e15e06a8SLiam R. Howlett 
1070e15e06a8SLiam R. Howlett 	/* Overwrite multiple levels at the end of the tree (slot 7) */
1071e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1072e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1073e15e06a8SLiam R. Howlett 	check_store_range(mt, 353, 361, xa_mk_value(353), 0);
1074e15e06a8SLiam R. Howlett 	check_store_range(mt, 347, 352, xa_mk_value(347), 0);
1075e15e06a8SLiam R. Howlett 
1076e15e06a8SLiam R. Howlett 	check_load(mt, 346, xa_mk_value(346));
1077e15e06a8SLiam R. Howlett 	for (i = 347; i <= 352; i++)
1078e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(347));
1079e15e06a8SLiam R. Howlett 	for (i = 353; i <= 361; i++)
1080e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(353));
1081e15e06a8SLiam R. Howlett 	check_load(mt, 362, xa_mk_value(362));
1082e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1083e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1084e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1085e15e06a8SLiam R. Howlett 
1086e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1087e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1088e15e06a8SLiam R. Howlett 	check_store_range(mt, 352, 364, NULL, 0);
1089e15e06a8SLiam R. Howlett 	check_store_range(mt, 351, 363, xa_mk_value(352), 0);
1090e15e06a8SLiam R. Howlett 	check_load(mt, 350, xa_mk_value(350));
1091e15e06a8SLiam R. Howlett 	check_load(mt, 351, xa_mk_value(352));
1092e15e06a8SLiam R. Howlett 	for (i = 352; i <= 363; i++)
1093e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(352));
1094e15e06a8SLiam R. Howlett 	check_load(mt, 364, NULL);
1095e15e06a8SLiam R. Howlett 	check_load(mt, 365, xa_mk_value(365));
1096e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1097e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1098e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1099e15e06a8SLiam R. Howlett 
1100e15e06a8SLiam R. Howlett 	mt_set_non_kernel(5);
1101e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1102e15e06a8SLiam R. Howlett 	check_store_range(mt, 352, 364, NULL, 0);
1103e15e06a8SLiam R. Howlett 	check_store_range(mt, 351, 364, xa_mk_value(352), 0);
1104e15e06a8SLiam R. Howlett 	check_load(mt, 350, xa_mk_value(350));
1105e15e06a8SLiam R. Howlett 	check_load(mt, 351, xa_mk_value(352));
1106e15e06a8SLiam R. Howlett 	for (i = 352; i <= 364; i++)
1107e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(352));
1108e15e06a8SLiam R. Howlett 	check_load(mt, 365, xa_mk_value(365));
1109e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1110e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1111e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1112e15e06a8SLiam R. Howlett 
1113e15e06a8SLiam R. Howlett 
1114e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1115e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1116e15e06a8SLiam R. Howlett 	check_store_range(mt, 362, 367, xa_mk_value(362), 0);
1117e15e06a8SLiam R. Howlett 	check_store_range(mt, 353, 361, xa_mk_value(353), 0);
1118e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1119e15e06a8SLiam R. Howlett 	mt_validate(mt);
1120e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1121e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1122e15e06a8SLiam R. Howlett 	/*
1123e15e06a8SLiam R. Howlett 	 * Interesting cases:
1124e15e06a8SLiam R. Howlett 	 * 1. Overwrite the end of a node and end in the first entry of the next
1125e15e06a8SLiam R. Howlett 	 * node.
1126e15e06a8SLiam R. Howlett 	 * 2. Split a single range
1127e15e06a8SLiam R. Howlett 	 * 3. Overwrite the start of a range
1128e15e06a8SLiam R. Howlett 	 * 4. Overwrite the end of a range
1129e15e06a8SLiam R. Howlett 	 * 5. Overwrite the entire range
1130e15e06a8SLiam R. Howlett 	 * 6. Overwrite a range that causes multiple parent nodes to be
1131e15e06a8SLiam R. Howlett 	 * combined
1132e15e06a8SLiam R. Howlett 	 * 7. Overwrite a range that causes multiple parent nodes and part of
1133e15e06a8SLiam R. Howlett 	 * root to be combined
1134e15e06a8SLiam R. Howlett 	 * 8. Overwrite the whole tree
1135e15e06a8SLiam R. Howlett 	 * 9. Try to overwrite the zero entry of an alloc tree.
1136e15e06a8SLiam R. Howlett 	 * 10. Write a range larger than a nodes current pivot
1137e15e06a8SLiam R. Howlett 	 */
1138e15e06a8SLiam R. Howlett 
1139e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1140e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1141e15e06a8SLiam R. Howlett 		val = i*5;
1142e15e06a8SLiam R. Howlett 		val2 = (i+1)*5;
1143e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1144e15e06a8SLiam R. Howlett 	}
1145e15e06a8SLiam R. Howlett 	check_store_range(mt, 2400, 2400, xa_mk_value(2400), 0);
1146e15e06a8SLiam R. Howlett 	check_store_range(mt, 2411, 2411, xa_mk_value(2411), 0);
1147e15e06a8SLiam R. Howlett 	check_store_range(mt, 2412, 2412, xa_mk_value(2412), 0);
1148e15e06a8SLiam R. Howlett 	check_store_range(mt, 2396, 2400, xa_mk_value(4052020), 0);
1149e15e06a8SLiam R. Howlett 	check_store_range(mt, 2402, 2402, xa_mk_value(2402), 0);
1150e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1151e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1152e15e06a8SLiam R. Howlett 
1153e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1154e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1155e15e06a8SLiam R. Howlett 		val = i*5;
1156e15e06a8SLiam R. Howlett 		val2 = (i+1)*5;
1157e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1158e15e06a8SLiam R. Howlett 	}
1159e15e06a8SLiam R. Howlett 	check_store_range(mt, 2422, 2422, xa_mk_value(2422), 0);
1160e15e06a8SLiam R. Howlett 	check_store_range(mt, 2424, 2424, xa_mk_value(2424), 0);
1161e15e06a8SLiam R. Howlett 	check_store_range(mt, 2425, 2425, xa_mk_value(2), 0);
1162e15e06a8SLiam R. Howlett 	check_store_range(mt, 2460, 2470, NULL, 0);
1163e15e06a8SLiam R. Howlett 	check_store_range(mt, 2435, 2460, xa_mk_value(2435), 0);
1164e15e06a8SLiam R. Howlett 	check_store_range(mt, 2461, 2470, xa_mk_value(2461), 0);
1165e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1166e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1167e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1168e15e06a8SLiam R. Howlett 
1169d6e8d0dcSPeng Zhang 	/* Check in-place modifications */
1170d6e8d0dcSPeng Zhang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1171d6e8d0dcSPeng Zhang 	/* Append to the start of last range */
1172d6e8d0dcSPeng Zhang 	mt_set_non_kernel(50);
1173d6e8d0dcSPeng Zhang 	for (i = 0; i <= 500; i++) {
1174d6e8d0dcSPeng Zhang 		val = i * 5 + 1;
1175d6e8d0dcSPeng Zhang 		val2 = val + 4;
1176d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1177d6e8d0dcSPeng Zhang 	}
1178d6e8d0dcSPeng Zhang 
1179d6e8d0dcSPeng Zhang 	/* Append to the last range without touching any boundaries */
1180d6e8d0dcSPeng Zhang 	for (i = 0; i < 10; i++) {
1181d6e8d0dcSPeng Zhang 		val = val2 + 5;
1182d6e8d0dcSPeng Zhang 		val2 = val + 4;
1183d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1184d6e8d0dcSPeng Zhang 	}
1185d6e8d0dcSPeng Zhang 
1186d6e8d0dcSPeng Zhang 	/* Append to the end of last range */
1187d6e8d0dcSPeng Zhang 	val = val2;
1188d6e8d0dcSPeng Zhang 	for (i = 0; i < 10; i++) {
1189d6e8d0dcSPeng Zhang 		val += 5;
1190d6e8d0dcSPeng Zhang 		MT_BUG_ON(mt, mtree_test_store_range(mt, val, ULONG_MAX,
1191d6e8d0dcSPeng Zhang 						     xa_mk_value(val)) != 0);
1192d6e8d0dcSPeng Zhang 	}
1193d6e8d0dcSPeng Zhang 
1194d6e8d0dcSPeng Zhang 	/* Overwriting the range and over a part of the next range */
1195d6e8d0dcSPeng Zhang 	for (i = 10; i < 30; i += 2) {
1196d6e8d0dcSPeng Zhang 		val = i * 5 + 1;
1197d6e8d0dcSPeng Zhang 		val2 = val + 5;
1198d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1199d6e8d0dcSPeng Zhang 	}
1200d6e8d0dcSPeng Zhang 
1201d6e8d0dcSPeng Zhang 	/* Overwriting a part of the range and over the next range */
1202d6e8d0dcSPeng Zhang 	for (i = 50; i < 70; i += 2) {
1203d6e8d0dcSPeng Zhang 		val2 = i * 5;
1204d6e8d0dcSPeng Zhang 		val = val2 - 5;
1205d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1206d6e8d0dcSPeng Zhang 	}
1207d6e8d0dcSPeng Zhang 
1208d6e8d0dcSPeng Zhang 	/*
1209d6e8d0dcSPeng Zhang 	 * Expand the range, only partially overwriting the previous and
1210d6e8d0dcSPeng Zhang 	 * next ranges
1211d6e8d0dcSPeng Zhang 	 */
1212d6e8d0dcSPeng Zhang 	for (i = 100; i < 130; i += 3) {
1213d6e8d0dcSPeng Zhang 		val = i * 5 - 5;
1214d6e8d0dcSPeng Zhang 		val2 = i * 5 + 1;
1215d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1216d6e8d0dcSPeng Zhang 	}
1217d6e8d0dcSPeng Zhang 
1218d6e8d0dcSPeng Zhang 	/*
1219d6e8d0dcSPeng Zhang 	 * Expand the range, only partially overwriting the previous and
1220d6e8d0dcSPeng Zhang 	 * next ranges, in RCU mode
1221d6e8d0dcSPeng Zhang 	 */
1222d6e8d0dcSPeng Zhang 	mt_set_in_rcu(mt);
1223d6e8d0dcSPeng Zhang 	for (i = 150; i < 180; i += 3) {
1224d6e8d0dcSPeng Zhang 		val = i * 5 - 5;
1225d6e8d0dcSPeng Zhang 		val2 = i * 5 + 1;
1226d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1227d6e8d0dcSPeng Zhang 	}
1228d6e8d0dcSPeng Zhang 
1229d6e8d0dcSPeng Zhang 	MT_BUG_ON(mt, !mt_height(mt));
1230d6e8d0dcSPeng Zhang 	mt_validate(mt);
1231d6e8d0dcSPeng Zhang 	mt_set_non_kernel(0);
1232d6e8d0dcSPeng Zhang 	mtree_destroy(mt);
1233d6e8d0dcSPeng Zhang 
1234e15e06a8SLiam R. Howlett 	/* Test rebalance gaps */
1235e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1236e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1237e15e06a8SLiam R. Howlett 	for (i = 0; i <= 50; i++) {
1238e15e06a8SLiam R. Howlett 		val = i*10;
1239e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1240e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1241e15e06a8SLiam R. Howlett 	}
1242e15e06a8SLiam R. Howlett 	check_store_range(mt, 161, 161, xa_mk_value(161), 0);
1243e15e06a8SLiam R. Howlett 	check_store_range(mt, 162, 162, xa_mk_value(162), 0);
1244e15e06a8SLiam R. Howlett 	check_store_range(mt, 163, 163, xa_mk_value(163), 0);
1245e15e06a8SLiam R. Howlett 	check_store_range(mt, 240, 249, NULL, 0);
1246e15e06a8SLiam R. Howlett 	mtree_erase(mt, 200);
1247e15e06a8SLiam R. Howlett 	mtree_erase(mt, 210);
1248e15e06a8SLiam R. Howlett 	mtree_erase(mt, 220);
1249e15e06a8SLiam R. Howlett 	mtree_erase(mt, 230);
1250e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1251e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1252e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1253e15e06a8SLiam R. Howlett 
1254e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1255e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1256e15e06a8SLiam R. Howlett 		val = i*10;
1257e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1258e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1259e15e06a8SLiam R. Howlett 	}
1260e15e06a8SLiam R. Howlett 	check_store_range(mt, 4600, 4959, xa_mk_value(1), 0);
1261e15e06a8SLiam R. Howlett 	mt_validate(mt);
1262e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1263e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1264e15e06a8SLiam R. Howlett 
1265e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1266e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1267e15e06a8SLiam R. Howlett 		val = i*10;
1268e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1269e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1270e15e06a8SLiam R. Howlett 	}
1271e15e06a8SLiam R. Howlett 	check_store_range(mt, 4811, 4811, xa_mk_value(4811), 0);
1272e15e06a8SLiam R. Howlett 	check_store_range(mt, 4812, 4812, xa_mk_value(4812), 0);
1273e15e06a8SLiam R. Howlett 	check_store_range(mt, 4861, 4861, xa_mk_value(4861), 0);
1274e15e06a8SLiam R. Howlett 	check_store_range(mt, 4862, 4862, xa_mk_value(4862), 0);
1275e15e06a8SLiam R. Howlett 	check_store_range(mt, 4842, 4849, NULL, 0);
1276e15e06a8SLiam R. Howlett 	mt_validate(mt);
1277e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1278e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1279e15e06a8SLiam R. Howlett 
1280e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1281e15e06a8SLiam R. Howlett 	for (i = 0; i <= 1300; i++) {
1282e15e06a8SLiam R. Howlett 		val = i*10;
1283e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1284e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1285e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) >= 4);
1286e15e06a8SLiam R. Howlett 	}
1287e15e06a8SLiam R. Howlett 	/*  Cause a 3 child split all the way up the tree. */
1288e15e06a8SLiam R. Howlett 	for (i = 5; i < 215; i += 10)
1289e15e06a8SLiam R. Howlett 		check_store_range(mt, 11450 + i, 11450 + i + 1, NULL, 0);
1290e15e06a8SLiam R. Howlett 	for (i = 5; i < 65; i += 10)
1291e15e06a8SLiam R. Howlett 		check_store_range(mt, 11770 + i, 11770 + i + 1, NULL, 0);
1292e15e06a8SLiam R. Howlett 
1293e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mt_height(mt) >= 4);
1294e15e06a8SLiam R. Howlett 	for (i = 5; i < 45; i += 10)
1295e15e06a8SLiam R. Howlett 		check_store_range(mt, 11700 + i, 11700 + i + 1, NULL, 0);
1296120b1162SLiam Howlett 	if (!MAPLE_32BIT)
1297e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) < 4);
1298e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1299e15e06a8SLiam R. Howlett 
1300e15e06a8SLiam R. Howlett 
1301e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1302e15e06a8SLiam R. Howlett 	for (i = 0; i <= 1200; i++) {
1303e15e06a8SLiam R. Howlett 		val = i*10;
1304e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1305e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1306e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) >= 4);
1307e15e06a8SLiam R. Howlett 	}
1308e15e06a8SLiam R. Howlett 	/* Fill parents and leaves before split. */
1309e15e06a8SLiam R. Howlett 	for (i = 5; i < 455; i += 10)
1310e15e06a8SLiam R. Howlett 		check_store_range(mt, 7800 + i, 7800 + i + 1, NULL, 0);
1311e15e06a8SLiam R. Howlett 
1312e15e06a8SLiam R. Howlett 	for (i = 1; i < 16; i++)
1313e15e06a8SLiam R. Howlett 		check_store_range(mt, 8185 + i, 8185 + i + 1,
1314e15e06a8SLiam R. Howlett 				  xa_mk_value(8185+i), 0);
1315e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mt_height(mt) >= 4);
1316e15e06a8SLiam R. Howlett 	/* triple split across multiple levels. */
1317e15e06a8SLiam R. Howlett 	check_store_range(mt, 8184, 8184, xa_mk_value(8184), 0);
1318120b1162SLiam Howlett 	if (!MAPLE_32BIT)
1319e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) != 4);
1320e15e06a8SLiam R. Howlett }
1321e15e06a8SLiam R. Howlett 
check_next_entry(struct maple_tree * mt)1322eaf9790dSLiam R. Howlett static noinline void __init check_next_entry(struct maple_tree *mt)
1323e15e06a8SLiam R. Howlett {
1324e15e06a8SLiam R. Howlett 	void *entry = NULL;
1325e15e06a8SLiam R. Howlett 	unsigned long limit = 30, i = 0;
1326120b1162SLiam Howlett 	MA_STATE(mas, mt, i, i);
1327e15e06a8SLiam R. Howlett 
1328e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
1329e15e06a8SLiam R. Howlett 
1330e15e06a8SLiam R. Howlett 	check_seq(mt, limit, false);
1331e15e06a8SLiam R. Howlett 	rcu_read_lock();
1332e15e06a8SLiam R. Howlett 
1333e15e06a8SLiam R. Howlett 	/* Check the first one and get ma_state in the correct state. */
1334e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_walk(&mas) != xa_mk_value(i++));
1335e15e06a8SLiam R. Howlett 	for ( ; i <= limit + 1; i++) {
1336e15e06a8SLiam R. Howlett 		entry = mas_next(&mas, limit);
1337e15e06a8SLiam R. Howlett 		if (i > limit)
1338e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != NULL);
1339e15e06a8SLiam R. Howlett 		else
1340e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(i) != entry);
1341e15e06a8SLiam R. Howlett 	}
1342e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1343e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1344e15e06a8SLiam R. Howlett }
1345e15e06a8SLiam R. Howlett 
check_prev_entry(struct maple_tree * mt)1346eaf9790dSLiam R. Howlett static noinline void __init check_prev_entry(struct maple_tree *mt)
1347e15e06a8SLiam R. Howlett {
1348e15e06a8SLiam R. Howlett 	unsigned long index = 16;
1349e15e06a8SLiam R. Howlett 	void *value;
1350e15e06a8SLiam R. Howlett 	int i;
1351e15e06a8SLiam R. Howlett 
1352e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, index, index);
1353e15e06a8SLiam R. Howlett 
1354e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
1355e15e06a8SLiam R. Howlett 	check_seq(mt, 30, false);
1356e15e06a8SLiam R. Howlett 
1357e15e06a8SLiam R. Howlett 	rcu_read_lock();
1358e15e06a8SLiam R. Howlett 	value = mas_find(&mas, ULONG_MAX);
1359e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(index));
1360e15e06a8SLiam R. Howlett 	value = mas_prev(&mas, 0);
1361e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(index - 1));
1362e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1363e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1364e15e06a8SLiam R. Howlett 
1365e15e06a8SLiam R. Howlett 	/* Check limits on prev */
1366e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1367e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1368e15e06a8SLiam R. Howlett 	for (i = 0; i <= index; i++) {
1369e15e06a8SLiam R. Howlett 		mas_set_range(&mas, i*10, i*10+5);
1370e15e06a8SLiam R. Howlett 		mas_store_gfp(&mas, xa_mk_value(i), GFP_KERNEL);
1371e15e06a8SLiam R. Howlett 	}
1372e15e06a8SLiam R. Howlett 
1373e15e06a8SLiam R. Howlett 	mas_set(&mas, 20);
1374e15e06a8SLiam R. Howlett 	value = mas_walk(&mas);
1375e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(2));
1376e15e06a8SLiam R. Howlett 
1377e15e06a8SLiam R. Howlett 	value = mas_prev(&mas, 19);
1378e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != NULL);
1379e15e06a8SLiam R. Howlett 
1380e15e06a8SLiam R. Howlett 	mas_set(&mas, 80);
1381e15e06a8SLiam R. Howlett 	value = mas_walk(&mas);
1382e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(8));
1383e15e06a8SLiam R. Howlett 
1384e15e06a8SLiam R. Howlett 	value = mas_prev(&mas, 76);
1385e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != NULL);
1386e15e06a8SLiam R. Howlett 
1387e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1388e15e06a8SLiam R. Howlett }
1389e15e06a8SLiam R. Howlett 
check_store_null(struct maple_tree * mt)1390431e1060SWei Yang static noinline void __init check_store_null(struct maple_tree *mt)
1391431e1060SWei Yang {
1392431e1060SWei Yang 	MA_STATE(mas, mt, 0, ULONG_MAX);
1393431e1060SWei Yang 
1394431e1060SWei Yang 	/*
1395431e1060SWei Yang 	 * Store NULL at range [0, ULONG_MAX] to an empty tree should result
1396431e1060SWei Yang 	 * in an empty tree
1397431e1060SWei Yang 	 */
1398431e1060SWei Yang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1399431e1060SWei Yang 	mas_lock(&mas);
1400431e1060SWei Yang 	mas_store_gfp(&mas, NULL, GFP_KERNEL);
1401431e1060SWei Yang 	MT_BUG_ON(mt, !mtree_empty(mt));
1402431e1060SWei Yang 	mas_unlock(&mas);
1403431e1060SWei Yang 	mtree_destroy(mt);
1404431e1060SWei Yang 
1405431e1060SWei Yang 	/*
1406431e1060SWei Yang 	 * Store NULL at any range to an empty tree should result in an empty
1407431e1060SWei Yang 	 * tree
1408431e1060SWei Yang 	 */
1409431e1060SWei Yang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1410431e1060SWei Yang 	mas_lock(&mas);
1411431e1060SWei Yang 	mas_set_range(&mas, 3, 10);
1412431e1060SWei Yang 	mas_store_gfp(&mas, NULL, GFP_KERNEL);
1413431e1060SWei Yang 	MT_BUG_ON(mt, !mtree_empty(mt));
1414431e1060SWei Yang 	mas_unlock(&mas);
1415431e1060SWei Yang 	mtree_destroy(mt);
1416431e1060SWei Yang 
1417431e1060SWei Yang 	/*
1418431e1060SWei Yang 	 * Store NULL at range [0, ULONG_MAX] to a single entry tree should
1419431e1060SWei Yang 	 * result in an empty tree
1420431e1060SWei Yang 	 */
1421431e1060SWei Yang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1422431e1060SWei Yang 	mas_lock(&mas);
1423431e1060SWei Yang 	mas_set(&mas, 0);
1424431e1060SWei Yang 	mas_store_gfp(&mas, &mas, GFP_KERNEL);
1425431e1060SWei Yang 	mas_set_range(&mas, 0, ULONG_MAX);
1426431e1060SWei Yang 	mas_store_gfp(&mas, NULL, GFP_KERNEL);
1427431e1060SWei Yang 	MT_BUG_ON(mt, !mtree_empty(mt));
1428431e1060SWei Yang 	mas_unlock(&mas);
1429431e1060SWei Yang 	mtree_destroy(mt);
1430431e1060SWei Yang 
1431431e1060SWei Yang 	/*
1432431e1060SWei Yang 	 * Store NULL at range [0, n] to a single entry tree should
1433431e1060SWei Yang 	 * result in an empty tree
1434431e1060SWei Yang 	 */
1435431e1060SWei Yang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1436431e1060SWei Yang 	mas_lock(&mas);
1437431e1060SWei Yang 	mas_set(&mas, 0);
1438431e1060SWei Yang 	mas_store_gfp(&mas, &mas, GFP_KERNEL);
1439431e1060SWei Yang 	mas_set_range(&mas, 0, 5);
1440431e1060SWei Yang 	mas_store_gfp(&mas, NULL, GFP_KERNEL);
1441431e1060SWei Yang 	MT_BUG_ON(mt, !mtree_empty(mt));
1442431e1060SWei Yang 	mas_unlock(&mas);
1443431e1060SWei Yang 	mtree_destroy(mt);
1444431e1060SWei Yang 
1445431e1060SWei Yang 	/*
1446431e1060SWei Yang 	 * Store NULL at range [m, n] where m > 0 to a single entry tree
1447431e1060SWei Yang 	 * should still be a single entry tree
1448431e1060SWei Yang 	 */
1449431e1060SWei Yang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1450431e1060SWei Yang 	mas_lock(&mas);
1451431e1060SWei Yang 	mas_set(&mas, 0);
1452431e1060SWei Yang 	mas_store_gfp(&mas, &mas, GFP_KERNEL);
1453431e1060SWei Yang 	mas_set_range(&mas, 2, 5);
1454431e1060SWei Yang 	mas_store_gfp(&mas, NULL, GFP_KERNEL);
1455431e1060SWei Yang 	MT_BUG_ON(mt, mtree_empty(mt));
1456431e1060SWei Yang //	MT_BUG_ON(mt, xa_is_node(mas_root(&mas)));
1457431e1060SWei Yang 	mas_unlock(&mas);
1458431e1060SWei Yang 	mtree_destroy(mt);
1459431e1060SWei Yang 
1460431e1060SWei Yang 	/*
1461431e1060SWei Yang 	 * Store NULL at range [0, ULONG_MAX] to a tree with node should
1462431e1060SWei Yang 	 * result in an empty tree
1463431e1060SWei Yang 	 */
1464431e1060SWei Yang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1465431e1060SWei Yang 	mas_lock(&mas);
1466431e1060SWei Yang 	mas_set_range(&mas, 1, 3);
1467431e1060SWei Yang 	mas_store_gfp(&mas, &mas, GFP_KERNEL);
1468431e1060SWei Yang //	MT_BUG_ON(mt, !xa_is_node(mas_root(&mas)));
1469431e1060SWei Yang 	mas_set_range(&mas, 0, ULONG_MAX);
1470431e1060SWei Yang 	mas_store_gfp(&mas, NULL, GFP_KERNEL);
1471431e1060SWei Yang 	MT_BUG_ON(mt, !mtree_empty(mt));
1472431e1060SWei Yang 	mas_unlock(&mas);
1473431e1060SWei Yang 	mtree_destroy(mt);
1474431e1060SWei Yang }
1475431e1060SWei Yang 
check_root_expand(struct maple_tree * mt)1476eaf9790dSLiam R. Howlett static noinline void __init check_root_expand(struct maple_tree *mt)
1477e15e06a8SLiam R. Howlett {
1478e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1479e15e06a8SLiam R. Howlett 	void *ptr;
1480e15e06a8SLiam R. Howlett 
1481e15e06a8SLiam R. Howlett 
1482e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1483e15e06a8SLiam R. Howlett 	mas_set(&mas, 3);
1484e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1485eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
1486e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1487e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
1488e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
1489e15e06a8SLiam R. Howlett 
1490e15e06a8SLiam R. Howlett 	ptr = &check_prev_entry;
1491e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1492e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1493e15e06a8SLiam R. Howlett 
1494e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1495e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1496e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1497e15e06a8SLiam R. Howlett 
1498e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1499e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1500e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != &check_prev_entry);
1501e15e06a8SLiam R. Howlett 
1502e15e06a8SLiam R. Howlett 	mas_set(&mas, 2);
1503e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1504e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1505e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1506e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1507e15e06a8SLiam R. Howlett 
1508e15e06a8SLiam R. Howlett 
1509e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
1510e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1511e15e06a8SLiam R. Howlett 
1512e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1513e15e06a8SLiam R. Howlett 	ptr = &check_prev_entry;
1514e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1515e15e06a8SLiam R. Howlett 
1516e15e06a8SLiam R. Howlett 	mas_set(&mas, 5);
1517e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1518e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1519e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
1520e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
1521e15e06a8SLiam R. Howlett 
1522e15e06a8SLiam R. Howlett 	mas_set_range(&mas, 0, 100);
1523e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1524e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != &check_prev_entry);
1525e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
1526e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1527e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1528e15e06a8SLiam R. Howlett 
1529e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
1530e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1531e15e06a8SLiam R. Howlett 
1532e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1533e15e06a8SLiam R. Howlett 	ptr = (void *)((unsigned long) check_prev_entry | 1UL);
1534e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1535e15e06a8SLiam R. Howlett 	ptr = mas_next(&mas, ULONG_MAX);
1536e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1537e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != 1) && (mas.last != ULONG_MAX));
1538e15e06a8SLiam R. Howlett 
1539e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1540e15e06a8SLiam R. Howlett 	ptr = mas_prev(&mas, 0);
1541e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != 0) && (mas.last != 0));
1542e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != (void *)((unsigned long) check_prev_entry | 1UL));
1543e15e06a8SLiam R. Howlett 
1544e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1545e15e06a8SLiam R. Howlett 
1546e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1547e15e06a8SLiam R. Howlett 
1548e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
1549e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1550e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1551e15e06a8SLiam R. Howlett 	ptr = (void *)((unsigned long) check_prev_entry | 2UL);
1552e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1553e15e06a8SLiam R. Howlett 	ptr = mas_next(&mas, ULONG_MAX);
1554e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1555eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != ULONG_MAX) && (mas.last != ULONG_MAX));
1556e15e06a8SLiam R. Howlett 
1557e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1558e15e06a8SLiam R. Howlett 	ptr = mas_prev(&mas, 0);
1559e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != 0) && (mas.last != 0));
1560e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != (void *)((unsigned long) check_prev_entry | 2UL));
1561e15e06a8SLiam R. Howlett 
1562e15e06a8SLiam R. Howlett 
1563e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1564e15e06a8SLiam R. Howlett }
1565e15e06a8SLiam R. Howlett 
check_deficient_node(struct maple_tree * mt)1566c38279d4SWei Yang static noinline void __init check_deficient_node(struct maple_tree *mt)
1567c38279d4SWei Yang {
1568c38279d4SWei Yang 	MA_STATE(mas, mt, 0, 0);
1569c38279d4SWei Yang 	int count;
1570c38279d4SWei Yang 
1571c38279d4SWei Yang 	mas_lock(&mas);
1572c38279d4SWei Yang 	for (count = 0; count < 10; count++) {
1573c38279d4SWei Yang 		mas_set(&mas, count);
1574c38279d4SWei Yang 		mas_store_gfp(&mas, xa_mk_value(count), GFP_KERNEL);
1575c38279d4SWei Yang 	}
1576c38279d4SWei Yang 
1577c38279d4SWei Yang 	for (count = 20; count < 39; count++) {
1578c38279d4SWei Yang 		mas_set(&mas, count);
1579c38279d4SWei Yang 		mas_store_gfp(&mas, xa_mk_value(count), GFP_KERNEL);
1580c38279d4SWei Yang 	}
1581c38279d4SWei Yang 
1582c38279d4SWei Yang 	for (count = 10; count < 12; count++) {
1583c38279d4SWei Yang 		mas_set(&mas, count);
1584c38279d4SWei Yang 		mas_store_gfp(&mas, xa_mk_value(count), GFP_KERNEL);
1585c38279d4SWei Yang 	}
1586c38279d4SWei Yang 	mas_unlock(&mas);
1587c38279d4SWei Yang 	mt_validate(mt);
1588c38279d4SWei Yang }
1589c38279d4SWei Yang 
check_gap_combining(struct maple_tree * mt)1590eaf9790dSLiam R. Howlett static noinline void __init check_gap_combining(struct maple_tree *mt)
1591e15e06a8SLiam R. Howlett {
1592e15e06a8SLiam R. Howlett 	struct maple_enode *mn1, *mn2;
1593e15e06a8SLiam R. Howlett 	void *entry;
1594120b1162SLiam Howlett 	unsigned long singletons = 100;
1595eaf9790dSLiam R. Howlett 	static const unsigned long *seq100;
1596eaf9790dSLiam R. Howlett 	static const unsigned long seq100_64[] = {
1597e15e06a8SLiam R. Howlett 		/* 0-5 */
1598e15e06a8SLiam R. Howlett 		74, 75, 76,
1599e15e06a8SLiam R. Howlett 		50, 100, 2,
1600e15e06a8SLiam R. Howlett 
1601e15e06a8SLiam R. Howlett 		/* 6-12 */
1602e15e06a8SLiam R. Howlett 		44, 45, 46, 43,
1603e15e06a8SLiam R. Howlett 		20, 50, 3,
1604e15e06a8SLiam R. Howlett 
1605e15e06a8SLiam R. Howlett 		/* 13-20*/
1606e15e06a8SLiam R. Howlett 		80, 81, 82,
1607e15e06a8SLiam R. Howlett 		76, 2, 79, 85, 4,
1608e15e06a8SLiam R. Howlett 	};
1609120b1162SLiam Howlett 
1610eaf9790dSLiam R. Howlett 	static const unsigned long seq100_32[] = {
1611120b1162SLiam Howlett 		/* 0-5 */
1612120b1162SLiam Howlett 		61, 62, 63,
1613120b1162SLiam Howlett 		50, 100, 2,
1614120b1162SLiam Howlett 
1615120b1162SLiam Howlett 		/* 6-12 */
1616120b1162SLiam Howlett 		31, 32, 33, 30,
1617120b1162SLiam Howlett 		20, 50, 3,
1618120b1162SLiam Howlett 
1619120b1162SLiam Howlett 		/* 13-20*/
1620120b1162SLiam Howlett 		80, 81, 82,
1621120b1162SLiam Howlett 		76, 2, 79, 85, 4,
1622120b1162SLiam Howlett 	};
1623120b1162SLiam Howlett 
1624eaf9790dSLiam R. Howlett 	static const unsigned long seq2000[] = {
1625e15e06a8SLiam R. Howlett 		1152, 1151,
1626e15e06a8SLiam R. Howlett 		1100, 1200, 2,
1627e15e06a8SLiam R. Howlett 	};
1628eaf9790dSLiam R. Howlett 	static const unsigned long seq400[] = {
1629e15e06a8SLiam R. Howlett 		286, 318,
1630e15e06a8SLiam R. Howlett 		256, 260, 266, 270, 275, 280, 290, 398,
1631e15e06a8SLiam R. Howlett 		286, 310,
1632e15e06a8SLiam R. Howlett 	};
1633e15e06a8SLiam R. Howlett 
1634120b1162SLiam Howlett 	unsigned long index;
1635e15e06a8SLiam R. Howlett 
1636120b1162SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
1637e15e06a8SLiam R. Howlett 
1638120b1162SLiam Howlett 	if (MAPLE_32BIT)
1639120b1162SLiam Howlett 		seq100 = seq100_32;
1640120b1162SLiam Howlett 	else
1641120b1162SLiam Howlett 		seq100 = seq100_64;
1642120b1162SLiam Howlett 
1643120b1162SLiam Howlett 	index = seq100[0];
1644120b1162SLiam Howlett 	mas_set(&mas, index);
1645e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
1646120b1162SLiam Howlett 	check_seq(mt, singletons, false); /* create 100 singletons. */
1647e15e06a8SLiam R. Howlett 
1648e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1649e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[2]);
1650e15e06a8SLiam R. Howlett 	check_load(mt, seq100[2], NULL);
1651e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[1]);
1652e15e06a8SLiam R. Howlett 	check_load(mt, seq100[1], NULL);
1653e15e06a8SLiam R. Howlett 
1654e15e06a8SLiam R. Howlett 	rcu_read_lock();
1655e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
1656e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index));
1657e15e06a8SLiam R. Howlett 	mn1 = mas.node;
1658e15e06a8SLiam R. Howlett 	mas_next(&mas, ULONG_MAX);
1659e15e06a8SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
1660e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index + 4));
1661e15e06a8SLiam R. Howlett 	mn2 = mas.node;
1662e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mn1 == mn2); /* test the test. */
1663e15e06a8SLiam R. Howlett 
1664e15e06a8SLiam R. Howlett 	/*
1665e15e06a8SLiam R. Howlett 	 * At this point, there is a gap of 2 at index + 1 between seq100[3] and
1666e15e06a8SLiam R. Howlett 	 * seq100[4]. Search for the gap.
1667e15e06a8SLiam R. Howlett 	 */
1668e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1669e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1670e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[3], seq100[4],
1671e15e06a8SLiam R. Howlett 					     seq100[5]));
1672e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != index + 1);
1673e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1674e15e06a8SLiam R. Howlett 
1675e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[6]);
1676e15e06a8SLiam R. Howlett 	check_load(mt, seq100[6], NULL);
1677e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[7]);
1678e15e06a8SLiam R. Howlett 	check_load(mt, seq100[7], NULL);
1679e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[8]);
1680e15e06a8SLiam R. Howlett 	index = seq100[9];
1681e15e06a8SLiam R. Howlett 
1682e15e06a8SLiam R. Howlett 	rcu_read_lock();
1683e15e06a8SLiam R. Howlett 	mas.index = index;
1684e15e06a8SLiam R. Howlett 	mas.last = index;
1685e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1686e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
1687e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index));
1688e15e06a8SLiam R. Howlett 	mn1 = mas.node;
1689e15e06a8SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
1690e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index + 4));
1691e15e06a8SLiam R. Howlett 	mas_next(&mas, ULONG_MAX); /* go to the next entry. */
1692e15e06a8SLiam R. Howlett 	mn2 = mas.node;
1693e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mn1 == mn2); /* test the next entry is in the next node. */
1694e15e06a8SLiam R. Howlett 
1695e15e06a8SLiam R. Howlett 	/*
1696e15e06a8SLiam R. Howlett 	 * At this point, there is a gap of 3 at seq100[6].  Find it by
1697e15e06a8SLiam R. Howlett 	 * searching 20 - 50 for size 3.
1698e15e06a8SLiam R. Howlett 	 */
1699e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1700e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[10], seq100[11],
1701e15e06a8SLiam R. Howlett 					     seq100[12]));
1702e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq100[6]);
1703e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1704e15e06a8SLiam R. Howlett 
1705e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1706e15e06a8SLiam R. Howlett 	mtree_store(mt, seq100[13], NULL, GFP_KERNEL);
1707e15e06a8SLiam R. Howlett 	check_load(mt, seq100[13], NULL);
1708e15e06a8SLiam R. Howlett 	check_load(mt, seq100[14], xa_mk_value(seq100[14]));
1709e15e06a8SLiam R. Howlett 	mtree_store(mt, seq100[14], NULL, GFP_KERNEL);
1710e15e06a8SLiam R. Howlett 	check_load(mt, seq100[13], NULL);
1711e15e06a8SLiam R. Howlett 	check_load(mt, seq100[14], NULL);
1712e15e06a8SLiam R. Howlett 
1713e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1714e15e06a8SLiam R. Howlett 	rcu_read_lock();
1715e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[16], seq100[15],
1716e15e06a8SLiam R. Howlett 					     seq100[17]));
1717e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq100[13]);
1718e15e06a8SLiam R. Howlett 	mt_validate(mt);
1719e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1720e15e06a8SLiam R. Howlett 
1721e15e06a8SLiam R. Howlett 	/*
1722e15e06a8SLiam R. Howlett 	 * *DEPRECATED: no retries anymore* Test retry entry in the start of a
1723e15e06a8SLiam R. Howlett 	 * gap.
1724e15e06a8SLiam R. Howlett 	 */
1725e15e06a8SLiam R. Howlett 	mt_set_non_kernel(2);
1726e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq100[18], seq100[14], NULL);
1727e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[15]);
1728e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1729e15e06a8SLiam R. Howlett 	rcu_read_lock();
1730e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[16], seq100[19],
1731e15e06a8SLiam R. Howlett 					     seq100[20]));
1732e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1733e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq100[18]);
1734e15e06a8SLiam R. Howlett 	mt_validate(mt);
1735e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1736e15e06a8SLiam R. Howlett 
1737e15e06a8SLiam R. Howlett 	/* seq 2000 tests are for multi-level tree gaps */
1738e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1739e15e06a8SLiam R. Howlett 	check_seq(mt, 2000, false);
1740e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1741e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq2000[0]);
1742e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq2000[1]);
1743e15e06a8SLiam R. Howlett 
1744e15e06a8SLiam R. Howlett 	mt_set_non_kernel(2);
1745e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1746e15e06a8SLiam R. Howlett 	rcu_read_lock();
1747e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq2000[2], seq2000[3],
1748e15e06a8SLiam R. Howlett 					     seq2000[4]));
1749e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq2000[1]);
1750e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1751e15e06a8SLiam R. Howlett 	mt_validate(mt);
1752e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1753e15e06a8SLiam R. Howlett 
1754e15e06a8SLiam R. Howlett 	/* seq 400 tests rebalancing over two levels. */
1755e15e06a8SLiam R. Howlett 	mt_set_non_kernel(99);
1756e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1757e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1758e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[0], seq400[1], NULL);
1759e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1760e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1761e15e06a8SLiam R. Howlett 
1762e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1763e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1764e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1765e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[2], seq400[9],
1766e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[2]));
1767e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[3], seq400[9],
1768e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[3]));
1769e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[4], seq400[9],
1770e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[4]));
1771e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[5], seq400[9],
1772e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[5]));
1773e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[0], seq400[9],
1774e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[0]));
1775e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[6], seq400[9],
1776e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[6]));
1777e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[7], seq400[9],
1778e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[7]));
1779e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[8], seq400[9],
1780e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[8]));
1781e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[10], seq400[11],
1782e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[10]));
1783e15e06a8SLiam R. Howlett 	mt_validate(mt);
1784e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1785e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1786e15e06a8SLiam R. Howlett }
check_node_overwrite(struct maple_tree * mt)1787eaf9790dSLiam R. Howlett static noinline void __init check_node_overwrite(struct maple_tree *mt)
1788e15e06a8SLiam R. Howlett {
1789e15e06a8SLiam R. Howlett 	int i, max = 4000;
1790e15e06a8SLiam R. Howlett 
1791e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i++)
1792e15e06a8SLiam R. Howlett 		mtree_test_store_range(mt, i*100, i*100 + 50, xa_mk_value(i*100));
1793e15e06a8SLiam R. Howlett 
1794e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 319951, 367950, NULL);
179589f499f3SLiam R. Howlett 	/*mt_dump(mt, mt_dump_dec); */
1796e15e06a8SLiam R. Howlett 	mt_validate(mt);
1797e15e06a8SLiam R. Howlett }
1798e15e06a8SLiam R. Howlett 
1799e15e06a8SLiam R. Howlett #if defined(BENCH_SLOT_STORE)
bench_slot_store(struct maple_tree * mt)1800eaf9790dSLiam R. Howlett static noinline void __init bench_slot_store(struct maple_tree *mt)
1801e15e06a8SLiam R. Howlett {
1802e15e06a8SLiam R. Howlett 	int i, brk = 105, max = 1040, brk_start = 100, count = 20000000;
1803e15e06a8SLiam R. Howlett 
1804e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1805e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1806e15e06a8SLiam R. Howlett 
1807e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1808e15e06a8SLiam R. Howlett 		mtree_store_range(mt, brk, brk, NULL, GFP_KERNEL);
1809e15e06a8SLiam R. Howlett 		mtree_store_range(mt, brk_start, brk, xa_mk_value(brk),
1810e15e06a8SLiam R. Howlett 				  GFP_KERNEL);
1811e15e06a8SLiam R. Howlett 	}
1812e15e06a8SLiam R. Howlett }
1813e15e06a8SLiam R. Howlett #endif
1814e15e06a8SLiam R. Howlett 
1815e15e06a8SLiam R. Howlett #if defined(BENCH_NODE_STORE)
bench_node_store(struct maple_tree * mt)1816eaf9790dSLiam R. Howlett static noinline void __init bench_node_store(struct maple_tree *mt)
1817e15e06a8SLiam R. Howlett {
1818e15e06a8SLiam R. Howlett 	int i, overwrite = 76, max = 240, count = 20000000;
1819e15e06a8SLiam R. Howlett 
1820e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1821e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1822e15e06a8SLiam R. Howlett 
1823e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1824e15e06a8SLiam R. Howlett 		mtree_store_range(mt, overwrite,  overwrite + 15,
1825e15e06a8SLiam R. Howlett 				  xa_mk_value(overwrite), GFP_KERNEL);
1826e15e06a8SLiam R. Howlett 
1827e15e06a8SLiam R. Howlett 		overwrite += 5;
1828e15e06a8SLiam R. Howlett 		if (overwrite >= 135)
1829e15e06a8SLiam R. Howlett 			overwrite = 76;
1830e15e06a8SLiam R. Howlett 	}
1831e15e06a8SLiam R. Howlett }
1832e15e06a8SLiam R. Howlett #endif
1833e15e06a8SLiam R. Howlett 
1834e15e06a8SLiam R. Howlett #if defined(BENCH_AWALK)
bench_awalk(struct maple_tree * mt)1835eaf9790dSLiam R. Howlett static noinline void __init bench_awalk(struct maple_tree *mt)
1836e15e06a8SLiam R. Howlett {
1837e15e06a8SLiam R. Howlett 	int i, max = 2500, count = 50000000;
1838e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 1470, 1470);
1839e15e06a8SLiam R. Howlett 
1840e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1841e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1842e15e06a8SLiam R. Howlett 
1843e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 1470, 1475, NULL, GFP_KERNEL);
1844e15e06a8SLiam R. Howlett 
1845e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1846e15e06a8SLiam R. Howlett 		mas_empty_area_rev(&mas, 0, 2000, 10);
1847e15e06a8SLiam R. Howlett 		mas_reset(&mas);
1848e15e06a8SLiam R. Howlett 	}
1849e15e06a8SLiam R. Howlett }
1850e15e06a8SLiam R. Howlett #endif
1851e15e06a8SLiam R. Howlett #if defined(BENCH_WALK)
bench_walk(struct maple_tree * mt)1852eaf9790dSLiam R. Howlett static noinline void __init bench_walk(struct maple_tree *mt)
1853e15e06a8SLiam R. Howlett {
1854e15e06a8SLiam R. Howlett 	int i, max = 2500, count = 550000000;
1855e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 1470, 1470);
1856e15e06a8SLiam R. Howlett 
1857e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1858e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1859e15e06a8SLiam R. Howlett 
1860e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1861e15e06a8SLiam R. Howlett 		mas_walk(&mas);
1862e15e06a8SLiam R. Howlett 		mas_reset(&mas);
1863e15e06a8SLiam R. Howlett 	}
1864e15e06a8SLiam R. Howlett 
1865e15e06a8SLiam R. Howlett }
1866e15e06a8SLiam R. Howlett #endif
1867e15e06a8SLiam R. Howlett 
186824662decSLiam R. Howlett #if defined(BENCH_LOAD)
bench_load(struct maple_tree * mt)186924662decSLiam R. Howlett static noinline void __init bench_load(struct maple_tree *mt)
187024662decSLiam R. Howlett {
187124662decSLiam R. Howlett 	int i, max = 2500, count = 550000000;
187224662decSLiam R. Howlett 
187324662decSLiam R. Howlett 	for (i = 0; i < max; i += 10)
187424662decSLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
187524662decSLiam R. Howlett 
187624662decSLiam R. Howlett 	for (i = 0; i < count; i++)
187724662decSLiam R. Howlett 		mtree_load(mt, 1470);
187824662decSLiam R. Howlett }
187924662decSLiam R. Howlett #endif
188024662decSLiam R. Howlett 
1881e15e06a8SLiam R. Howlett #if defined(BENCH_MT_FOR_EACH)
bench_mt_for_each(struct maple_tree * mt)1882eaf9790dSLiam R. Howlett static noinline void __init bench_mt_for_each(struct maple_tree *mt)
1883e15e06a8SLiam R. Howlett {
1884e15e06a8SLiam R. Howlett 	int i, count = 1000000;
1885e15e06a8SLiam R. Howlett 	unsigned long max = 2500, index = 0;
1886e15e06a8SLiam R. Howlett 	void *entry;
1887e15e06a8SLiam R. Howlett 
1888e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 5)
1889e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 4, xa_mk_value(i), GFP_KERNEL);
1890e15e06a8SLiam R. Howlett 
1891e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1892e15e06a8SLiam R. Howlett 		unsigned long j = 0;
1893e15e06a8SLiam R. Howlett 
1894e15e06a8SLiam R. Howlett 		mt_for_each(mt, entry, index, max) {
1895e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
1896e15e06a8SLiam R. Howlett 			j += 5;
1897e15e06a8SLiam R. Howlett 		}
1898e15e06a8SLiam R. Howlett 
1899e15e06a8SLiam R. Howlett 		index = 0;
1900e15e06a8SLiam R. Howlett 	}
1901e15e06a8SLiam R. Howlett 
1902e15e06a8SLiam R. Howlett }
1903e15e06a8SLiam R. Howlett #endif
1904e15e06a8SLiam R. Howlett 
1905361c678bSLiam R. Howlett #if defined(BENCH_MAS_FOR_EACH)
bench_mas_for_each(struct maple_tree * mt)1906361c678bSLiam R. Howlett static noinline void __init bench_mas_for_each(struct maple_tree *mt)
1907361c678bSLiam R. Howlett {
1908361c678bSLiam R. Howlett 	int i, count = 1000000;
1909361c678bSLiam R. Howlett 	unsigned long max = 2500;
1910361c678bSLiam R. Howlett 	void *entry;
1911361c678bSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1912361c678bSLiam R. Howlett 
1913361c678bSLiam R. Howlett 	for (i = 0; i < max; i += 5) {
1914361c678bSLiam R. Howlett 		int gap = 4;
1915361c678bSLiam R. Howlett 
1916361c678bSLiam R. Howlett 		if (i % 30 == 0)
1917361c678bSLiam R. Howlett 			gap = 3;
1918361c678bSLiam R. Howlett 		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL);
1919361c678bSLiam R. Howlett 	}
1920361c678bSLiam R. Howlett 
1921361c678bSLiam R. Howlett 	rcu_read_lock();
1922361c678bSLiam R. Howlett 	for (i = 0; i < count; i++) {
1923361c678bSLiam R. Howlett 		unsigned long j = 0;
1924361c678bSLiam R. Howlett 
1925361c678bSLiam R. Howlett 		mas_for_each(&mas, entry, max) {
1926361c678bSLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
1927361c678bSLiam R. Howlett 			j += 5;
1928361c678bSLiam R. Howlett 		}
1929361c678bSLiam R. Howlett 		mas_set(&mas, 0);
1930361c678bSLiam R. Howlett 	}
1931361c678bSLiam R. Howlett 	rcu_read_unlock();
1932361c678bSLiam R. Howlett 
1933361c678bSLiam R. Howlett }
1934361c678bSLiam R. Howlett #endif
19358c314f3bSLiam R. Howlett #if defined(BENCH_MAS_PREV)
bench_mas_prev(struct maple_tree * mt)19368c314f3bSLiam R. Howlett static noinline void __init bench_mas_prev(struct maple_tree *mt)
19378c314f3bSLiam R. Howlett {
19388c314f3bSLiam R. Howlett 	int i, count = 1000000;
19398c314f3bSLiam R. Howlett 	unsigned long max = 2500;
19408c314f3bSLiam R. Howlett 	void *entry;
19418c314f3bSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1942361c678bSLiam R. Howlett 
19438c314f3bSLiam R. Howlett 	for (i = 0; i < max; i += 5) {
19448c314f3bSLiam R. Howlett 		int gap = 4;
19458c314f3bSLiam R. Howlett 
19468c314f3bSLiam R. Howlett 		if (i % 30 == 0)
19478c314f3bSLiam R. Howlett 			gap = 3;
19488c314f3bSLiam R. Howlett 		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL);
19498c314f3bSLiam R. Howlett 	}
19508c314f3bSLiam R. Howlett 
19518c314f3bSLiam R. Howlett 	rcu_read_lock();
19528c314f3bSLiam R. Howlett 	for (i = 0; i < count; i++) {
19538c314f3bSLiam R. Howlett 		unsigned long j = 2495;
19548c314f3bSLiam R. Howlett 
19558c314f3bSLiam R. Howlett 		mas_set(&mas, ULONG_MAX);
19568c314f3bSLiam R. Howlett 		while ((entry = mas_prev(&mas, 0)) != NULL) {
19578c314f3bSLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
19588c314f3bSLiam R. Howlett 			j -= 5;
19598c314f3bSLiam R. Howlett 		}
19608c314f3bSLiam R. Howlett 	}
19618c314f3bSLiam R. Howlett 	rcu_read_unlock();
19628c314f3bSLiam R. Howlett 
19638c314f3bSLiam R. Howlett }
19648c314f3bSLiam R. Howlett #endif
1965120b1162SLiam Howlett /* check_forking - simulate the kernel forking sequence with the tree. */
check_forking(void)1966446e1867SPeng Zhang static noinline void __init check_forking(void)
1967e15e06a8SLiam R. Howlett {
1968446e1867SPeng Zhang 	struct maple_tree mt, newmt;
1969446e1867SPeng Zhang 	int i, nr_entries = 134, ret;
1970e15e06a8SLiam R. Howlett 	void *val;
1971446e1867SPeng Zhang 	MA_STATE(mas, &mt, 0, 0);
1972446e1867SPeng Zhang 	MA_STATE(newmas, &newmt, 0, 0);
1973446e1867SPeng Zhang 	struct rw_semaphore mt_lock, newmt_lock;
1974099d7439SLiam R. Howlett 
1975446e1867SPeng Zhang 	init_rwsem(&mt_lock);
1976099d7439SLiam R. Howlett 	init_rwsem(&newmt_lock);
1977e15e06a8SLiam R. Howlett 
1978446e1867SPeng Zhang 	mt_init_flags(&mt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
1979446e1867SPeng Zhang 	mt_set_external_lock(&mt, &mt_lock);
1980e15e06a8SLiam R. Howlett 
1981099d7439SLiam R. Howlett 	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
1982099d7439SLiam R. Howlett 	mt_set_external_lock(&newmt, &newmt_lock);
1983446e1867SPeng Zhang 
1984446e1867SPeng Zhang 	down_write(&mt_lock);
1985446e1867SPeng Zhang 	for (i = 0; i <= nr_entries; i++) {
1986446e1867SPeng Zhang 		mas_set_range(&mas, i*10, i*10 + 5);
1987446e1867SPeng Zhang 		mas_store_gfp(&mas, xa_mk_value(i), GFP_KERNEL);
1988446e1867SPeng Zhang 	}
1989446e1867SPeng Zhang 
1990446e1867SPeng Zhang 	down_write_nested(&newmt_lock, SINGLE_DEPTH_NESTING);
1991446e1867SPeng Zhang 	ret = __mt_dup(&mt, &newmt, GFP_KERNEL);
1992446e1867SPeng Zhang 	if (ret) {
1993e15e06a8SLiam R. Howlett 		pr_err("OOM!");
1994e15e06a8SLiam R. Howlett 		BUG_ON(1);
1995e15e06a8SLiam R. Howlett 	}
1996446e1867SPeng Zhang 
1997446e1867SPeng Zhang 	mas_set(&newmas, 0);
1998446e1867SPeng Zhang 	mas_for_each(&newmas, val, ULONG_MAX)
1999e15e06a8SLiam R. Howlett 		mas_store(&newmas, val);
2000446e1867SPeng Zhang 
2001e15e06a8SLiam R. Howlett 	mas_destroy(&newmas);
2002446e1867SPeng Zhang 	mas_destroy(&mas);
2003e15e06a8SLiam R. Howlett 	mt_validate(&newmt);
2004099d7439SLiam R. Howlett 	__mt_destroy(&newmt);
2005446e1867SPeng Zhang 	__mt_destroy(&mt);
2006099d7439SLiam R. Howlett 	up_write(&newmt_lock);
2007446e1867SPeng Zhang 	up_write(&mt_lock);
2008e15e06a8SLiam R. Howlett }
2009e15e06a8SLiam R. Howlett 
check_iteration(struct maple_tree * mt)2010eaf9790dSLiam R. Howlett static noinline void __init check_iteration(struct maple_tree *mt)
20115159d64bSLiam R. Howlett {
20125159d64bSLiam R. Howlett 	int i, nr_entries = 125;
20135159d64bSLiam R. Howlett 	void *val;
20145159d64bSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
20155159d64bSLiam R. Howlett 
20165159d64bSLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
20175159d64bSLiam R. Howlett 		mtree_store_range(mt, i * 10, i * 10 + 9,
20185159d64bSLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
20195159d64bSLiam R. Howlett 
20205159d64bSLiam R. Howlett 	mt_set_non_kernel(99999);
20215159d64bSLiam R. Howlett 
20225159d64bSLiam R. Howlett 	i = 0;
20235159d64bSLiam R. Howlett 	mas_lock(&mas);
20245159d64bSLiam R. Howlett 	mas_for_each(&mas, val, 925) {
20255159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.index != i * 10);
20265159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.last != i * 10 + 9);
20275159d64bSLiam R. Howlett 		/* Overwrite end of entry 92 */
20285159d64bSLiam R. Howlett 		if (i == 92) {
20295159d64bSLiam R. Howlett 			mas.index = 925;
20305159d64bSLiam R. Howlett 			mas.last = 929;
20315159d64bSLiam R. Howlett 			mas_store(&mas, val);
20325159d64bSLiam R. Howlett 		}
20335159d64bSLiam R. Howlett 		i++;
20345159d64bSLiam R. Howlett 	}
20355159d64bSLiam R. Howlett 	/* Ensure mas_find() gets the next value */
20365159d64bSLiam R. Howlett 	val = mas_find(&mas, ULONG_MAX);
20375159d64bSLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(i));
20385159d64bSLiam R. Howlett 
20395159d64bSLiam R. Howlett 	mas_set(&mas, 0);
20405159d64bSLiam R. Howlett 	i = 0;
20415159d64bSLiam R. Howlett 	mas_for_each(&mas, val, 785) {
20425159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.index != i * 10);
20435159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.last != i * 10 + 9);
20445159d64bSLiam R. Howlett 		/* Overwrite start of entry 78 */
20455159d64bSLiam R. Howlett 		if (i == 78) {
20465159d64bSLiam R. Howlett 			mas.index = 780;
20475159d64bSLiam R. Howlett 			mas.last = 785;
20485159d64bSLiam R. Howlett 			mas_store(&mas, val);
20495159d64bSLiam R. Howlett 		} else {
20505159d64bSLiam R. Howlett 			i++;
20515159d64bSLiam R. Howlett 		}
20525159d64bSLiam R. Howlett 	}
20535159d64bSLiam R. Howlett 	val = mas_find(&mas, ULONG_MAX);
20545159d64bSLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(i));
20555159d64bSLiam R. Howlett 
20565159d64bSLiam R. Howlett 	mas_set(&mas, 0);
20575159d64bSLiam R. Howlett 	i = 0;
20585159d64bSLiam R. Howlett 	mas_for_each(&mas, val, 765) {
20595159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.index != i * 10);
20605159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.last != i * 10 + 9);
20615159d64bSLiam R. Howlett 		/* Overwrite end of entry 76 and advance to the end */
20625159d64bSLiam R. Howlett 		if (i == 76) {
20635159d64bSLiam R. Howlett 			mas.index = 760;
20645159d64bSLiam R. Howlett 			mas.last = 765;
20655159d64bSLiam R. Howlett 			mas_store(&mas, val);
20665159d64bSLiam R. Howlett 		}
20675159d64bSLiam R. Howlett 		i++;
20685159d64bSLiam R. Howlett 	}
20695159d64bSLiam R. Howlett 	/* Make sure the next find returns the one after 765, 766-769 */
20705159d64bSLiam R. Howlett 	val = mas_find(&mas, ULONG_MAX);
20715159d64bSLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(76));
20725159d64bSLiam R. Howlett 	mas_unlock(&mas);
20735159d64bSLiam R. Howlett 	mas_destroy(&mas);
20745159d64bSLiam R. Howlett 	mt_set_non_kernel(0);
20755159d64bSLiam R. Howlett }
20765159d64bSLiam R. Howlett 
check_mas_store_gfp(struct maple_tree * mt)2077eaf9790dSLiam R. Howlett static noinline void __init check_mas_store_gfp(struct maple_tree *mt)
2078e15e06a8SLiam R. Howlett {
2079e15e06a8SLiam R. Howlett 
2080e15e06a8SLiam R. Howlett 	struct maple_tree newmt;
2081e15e06a8SLiam R. Howlett 	int i, nr_entries = 135;
2082e15e06a8SLiam R. Howlett 	void *val;
2083e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
2084e15e06a8SLiam R. Howlett 	MA_STATE(newmas, mt, 0, 0);
2085e15e06a8SLiam R. Howlett 
2086e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
2087e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
2088e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
2089e15e06a8SLiam R. Howlett 
2090e15e06a8SLiam R. Howlett 	mt_set_non_kernel(99999);
2091e15e06a8SLiam R. Howlett 	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE);
2092e15e06a8SLiam R. Howlett 	newmas.tree = &newmt;
2093120b1162SLiam Howlett 	rcu_read_lock();
2094120b1162SLiam Howlett 	mas_lock(&newmas);
2095e15e06a8SLiam R. Howlett 	mas_reset(&newmas);
2096e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
2097e15e06a8SLiam R. Howlett 	mas_for_each(&mas, val, ULONG_MAX) {
2098e15e06a8SLiam R. Howlett 		newmas.index = mas.index;
2099e15e06a8SLiam R. Howlett 		newmas.last = mas.last;
2100e15e06a8SLiam R. Howlett 		mas_store_gfp(&newmas, val, GFP_KERNEL);
2101e15e06a8SLiam R. Howlett 	}
2102120b1162SLiam Howlett 	mas_unlock(&newmas);
2103120b1162SLiam Howlett 	rcu_read_unlock();
2104e15e06a8SLiam R. Howlett 	mt_validate(&newmt);
2105e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
2106e15e06a8SLiam R. Howlett 	mtree_destroy(&newmt);
2107e15e06a8SLiam R. Howlett }
2108e15e06a8SLiam R. Howlett 
2109e15e06a8SLiam R. Howlett #if defined(BENCH_FORK)
bench_forking(void)2110446e1867SPeng Zhang static noinline void __init bench_forking(void)
2111e15e06a8SLiam R. Howlett {
2112446e1867SPeng Zhang 	struct maple_tree mt, newmt;
2113446e1867SPeng Zhang 	int i, nr_entries = 134, nr_fork = 80000, ret;
2114e15e06a8SLiam R. Howlett 	void *val;
2115446e1867SPeng Zhang 	MA_STATE(mas, &mt, 0, 0);
2116446e1867SPeng Zhang 	MA_STATE(newmas, &newmt, 0, 0);
2117446e1867SPeng Zhang 	struct rw_semaphore mt_lock, newmt_lock;
2118099d7439SLiam R. Howlett 
2119446e1867SPeng Zhang 	init_rwsem(&mt_lock);
2120099d7439SLiam R. Howlett 	init_rwsem(&newmt_lock);
2121e15e06a8SLiam R. Howlett 
2122446e1867SPeng Zhang 	mt_init_flags(&mt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
2123446e1867SPeng Zhang 	mt_set_external_lock(&mt, &mt_lock);
2124446e1867SPeng Zhang 
2125446e1867SPeng Zhang 	down_write(&mt_lock);
2126446e1867SPeng Zhang 	for (i = 0; i <= nr_entries; i++) {
2127446e1867SPeng Zhang 		mas_set_range(&mas, i*10, i*10 + 5);
2128446e1867SPeng Zhang 		mas_store_gfp(&mas, xa_mk_value(i), GFP_KERNEL);
2129446e1867SPeng Zhang 	}
2130e15e06a8SLiam R. Howlett 
2131e15e06a8SLiam R. Howlett 	for (i = 0; i < nr_fork; i++) {
2132446e1867SPeng Zhang 		mt_init_flags(&newmt,
2133446e1867SPeng Zhang 			      MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
2134446e1867SPeng Zhang 		mt_set_external_lock(&newmt, &newmt_lock);
2135446e1867SPeng Zhang 
2136446e1867SPeng Zhang 		down_write_nested(&newmt_lock, SINGLE_DEPTH_NESTING);
2137446e1867SPeng Zhang 		ret = __mt_dup(&mt, &newmt, GFP_KERNEL);
2138446e1867SPeng Zhang 		if (ret) {
2139446e1867SPeng Zhang 			pr_err("OOM!");
2140e15e06a8SLiam R. Howlett 			BUG_ON(1);
2141e15e06a8SLiam R. Howlett 		}
2142446e1867SPeng Zhang 
2143446e1867SPeng Zhang 		mas_set(&newmas, 0);
2144446e1867SPeng Zhang 		mas_for_each(&newmas, val, ULONG_MAX)
2145e15e06a8SLiam R. Howlett 			mas_store(&newmas, val);
2146446e1867SPeng Zhang 
2147e15e06a8SLiam R. Howlett 		mas_destroy(&newmas);
2148e15e06a8SLiam R. Howlett 		mt_validate(&newmt);
2149099d7439SLiam R. Howlett 		__mt_destroy(&newmt);
2150099d7439SLiam R. Howlett 		up_write(&newmt_lock);
2151e15e06a8SLiam R. Howlett 	}
2152446e1867SPeng Zhang 	mas_destroy(&mas);
2153446e1867SPeng Zhang 	__mt_destroy(&mt);
2154446e1867SPeng Zhang 	up_write(&mt_lock);
2155e15e06a8SLiam R. Howlett }
2156e15e06a8SLiam R. Howlett #endif
2157e15e06a8SLiam R. Howlett 
next_prev_test(struct maple_tree * mt)2158eaf9790dSLiam R. Howlett static noinline void __init next_prev_test(struct maple_tree *mt)
2159e15e06a8SLiam R. Howlett {
2160120b1162SLiam Howlett 	int i, nr_entries;
2161e15e06a8SLiam R. Howlett 	void *val;
2162e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
2163e15e06a8SLiam R. Howlett 	struct maple_enode *mn;
2164eaf9790dSLiam R. Howlett 	static const unsigned long *level2;
2165eaf9790dSLiam R. Howlett 	static const unsigned long level2_64[] = { 707, 1000, 710, 715, 720,
2166eaf9790dSLiam R. Howlett 						   725};
2167eaf9790dSLiam R. Howlett 	static const unsigned long level2_32[] = { 1747, 2000, 1750, 1755,
2168eaf9790dSLiam R. Howlett 						   1760, 1765};
21697a93c71aSLiam R. Howlett 	unsigned long last_index;
2170120b1162SLiam Howlett 
2171120b1162SLiam Howlett 	if (MAPLE_32BIT) {
2172120b1162SLiam Howlett 		nr_entries = 500;
2173120b1162SLiam Howlett 		level2 = level2_32;
21747a93c71aSLiam R. Howlett 		last_index = 0x138e;
2175120b1162SLiam Howlett 	} else {
2176120b1162SLiam Howlett 		nr_entries = 200;
2177120b1162SLiam Howlett 		level2 = level2_64;
21787a93c71aSLiam R. Howlett 		last_index = 0x7d6;
2179120b1162SLiam Howlett 	}
2180e15e06a8SLiam R. Howlett 
2181e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
2182e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
2183e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
2184e15e06a8SLiam R. Howlett 
2185120b1162SLiam Howlett 	mas_lock(&mas);
2186e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries / 2; i++) {
2187e15e06a8SLiam R. Howlett 		mas_next(&mas, 1000);
2188e15e06a8SLiam R. Howlett 		if (mas_is_none(&mas))
2189e15e06a8SLiam R. Howlett 			break;
2190e15e06a8SLiam R. Howlett 
2191e15e06a8SLiam R. Howlett 	}
2192e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2193e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
2194e15e06a8SLiam R. Howlett 	i = 0;
2195e15e06a8SLiam R. Howlett 	mas_for_each(&mas, val, 1000) {
2196e15e06a8SLiam R. Howlett 		i++;
2197e15e06a8SLiam R. Howlett 	}
2198e15e06a8SLiam R. Howlett 
2199e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2200e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
2201e15e06a8SLiam R. Howlett 	i = 0;
2202e15e06a8SLiam R. Howlett 	mas_for_each(&mas, val, 1000) {
2203e15e06a8SLiam R. Howlett 		mas_pause(&mas);
2204e15e06a8SLiam R. Howlett 		i++;
2205e15e06a8SLiam R. Howlett 	}
2206e15e06a8SLiam R. Howlett 
2207e15e06a8SLiam R. Howlett 	/*
2208e15e06a8SLiam R. Howlett 	 * 680 - 685 = 0x61a00001930c
2209e15e06a8SLiam R. Howlett 	 * 686 - 689 = NULL;
2210e15e06a8SLiam R. Howlett 	 * 690 - 695 = 0x61a00001930c
2211e15e06a8SLiam R. Howlett 	 * Check simple next/prev
2212e15e06a8SLiam R. Howlett 	 */
2213e15e06a8SLiam R. Howlett 	mas_set(&mas, 686);
2214e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2215e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2216e15e06a8SLiam R. Howlett 
2217e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2218e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(690 / 10));
2219e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 690);
2220e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 695);
2221e15e06a8SLiam R. Howlett 
2222e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2223e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(680 / 10));
2224e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 680);
2225e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 685);
2226e15e06a8SLiam R. Howlett 
2227e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2228e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(690 / 10));
2229e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 690);
2230e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 695);
2231e15e06a8SLiam R. Howlett 
2232e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2233e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(700 / 10));
2234e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 700);
2235e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 705);
2236e15e06a8SLiam R. Howlett 
2237e15e06a8SLiam R. Howlett 	/* Check across node boundaries of the tree */
2238e15e06a8SLiam R. Howlett 	mas_set(&mas, 70);
2239e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2240e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(70 / 10));
2241e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 70);
2242e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 75);
2243e15e06a8SLiam R. Howlett 
2244e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2245e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(80 / 10));
2246e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 80);
2247e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 85);
2248e15e06a8SLiam R. Howlett 
2249e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 70);
2250e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(70 / 10));
2251e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 70);
2252e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 75);
2253e15e06a8SLiam R. Howlett 
2254e15e06a8SLiam R. Howlett 	/* Check across two levels of the tree */
2255e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2256120b1162SLiam Howlett 	mas_set(&mas, level2[0]);
2257e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2258e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2259120b1162SLiam Howlett 	val = mas_next(&mas, level2[1]);
2260120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(level2[2] / 10));
2261120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != level2[2]);
2262120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != level2[3]);
2263e15e06a8SLiam R. Howlett 	mn = mas.node;
2264e15e06a8SLiam R. Howlett 
2265120b1162SLiam Howlett 	val = mas_next(&mas, level2[1]);
2266120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(level2[4] / 10));
2267120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != level2[4]);
2268120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != level2[5]);
2269e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mn == mas.node);
2270e15e06a8SLiam R. Howlett 
2271e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2272120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(level2[2] / 10));
2273120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != level2[2]);
2274120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != level2[3]);
2275e15e06a8SLiam R. Howlett 
2276e15e06a8SLiam R. Howlett 	/* Check running off the end and back on */
2277120b1162SLiam Howlett 	mas_set(&mas, nr_entries * 10);
2278e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2279120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(nr_entries));
2280120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != (nr_entries * 10));
2281120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != (nr_entries * 10 + 5));
2282e15e06a8SLiam R. Howlett 
2283e15e06a8SLiam R. Howlett 	val = mas_next(&mas, ULONG_MAX);
2284e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
22857a93c71aSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != last_index);
2286e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
2287e15e06a8SLiam R. Howlett 
2288e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2289120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(nr_entries));
2290120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != (nr_entries * 10));
2291120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != (nr_entries * 10 + 5));
2292e15e06a8SLiam R. Howlett 
2293e15e06a8SLiam R. Howlett 	/* Check running off the start and back on */
2294e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2295e15e06a8SLiam R. Howlett 	mas_set(&mas, 10);
2296e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2297e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(1));
2298e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 10);
2299e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 15);
2300e15e06a8SLiam R. Howlett 
2301e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2302e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(0));
2303e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
2304e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 5);
2305e15e06a8SLiam R. Howlett 
2306e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2307e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2308e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
2309eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 5);
2310067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
2311e15e06a8SLiam R. Howlett 
2312e15e06a8SLiam R. Howlett 	mas.index = 0;
2313e15e06a8SLiam R. Howlett 	mas.last = 5;
2314e15e06a8SLiam R. Howlett 	mas_store(&mas, NULL);
2315e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2316e15e06a8SLiam R. Howlett 	mas_set(&mas, 10);
2317e15e06a8SLiam R. Howlett 	mas_walk(&mas);
2318e15e06a8SLiam R. Howlett 
2319e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2320e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2321e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
2322eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 9);
2323120b1162SLiam Howlett 	mas_unlock(&mas);
2324e15e06a8SLiam R. Howlett 
2325e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2326e15e06a8SLiam R. Howlett 
2327e15e06a8SLiam R. Howlett 	mt_init(mt);
2328e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 0, 0, xa_mk_value(0), GFP_KERNEL);
2329e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 5, 5, xa_mk_value(5), GFP_KERNEL);
2330120b1162SLiam Howlett 	rcu_read_lock();
2331e15e06a8SLiam R. Howlett 	mas_set(&mas, 5);
2332e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 4);
2333e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2334e15e06a8SLiam R. Howlett 	rcu_read_unlock();
2335e15e06a8SLiam R. Howlett }
2336e15e06a8SLiam R. Howlett 
2337e15e06a8SLiam R. Howlett 
2338e15e06a8SLiam R. Howlett 
2339e15e06a8SLiam R. Howlett /* Test spanning writes that require balancing right sibling or right cousin */
check_spanning_relatives(struct maple_tree * mt)2340eaf9790dSLiam R. Howlett static noinline void __init check_spanning_relatives(struct maple_tree *mt)
2341e15e06a8SLiam R. Howlett {
2342e15e06a8SLiam R. Howlett 
2343e15e06a8SLiam R. Howlett 	unsigned long i, nr_entries = 1000;
2344e15e06a8SLiam R. Howlett 
2345e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
2346e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
2347e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
2348e15e06a8SLiam R. Howlett 
2349e15e06a8SLiam R. Howlett 
2350e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 9365, 9955, NULL, GFP_KERNEL);
2351e15e06a8SLiam R. Howlett }
2352e15e06a8SLiam R. Howlett 
check_fuzzer(struct maple_tree * mt)2353eaf9790dSLiam R. Howlett static noinline void __init check_fuzzer(struct maple_tree *mt)
2354e15e06a8SLiam R. Howlett {
2355e15e06a8SLiam R. Howlett 	/*
2356e15e06a8SLiam R. Howlett 	 * 1. Causes a spanning rebalance of a single root node.
2357e15e06a8SLiam R. Howlett 	 * Fixed by setting the correct limit in mast_cp_to_nodes() when the
2358e15e06a8SLiam R. Howlett 	 * entire right side is consumed.
2359e15e06a8SLiam R. Howlett 	 */
2360e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 88, (void *)0xb1);
2361e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 84, (void *)0xa9);
2362e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2,  (void *)0x5);
2363e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4,  (void *)0x9);
2364e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 14, (void *)0x1d);
2365e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 7,  (void *)0xf);
2366e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2367e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 18, (void *)0x25);
2368e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 8, 18, (void *)0x11);
2369e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2370e15e06a8SLiam R. Howlett 
2371e15e06a8SLiam R. Howlett 
2372e15e06a8SLiam R. Howlett 	/*
2373e15e06a8SLiam R. Howlett 	 * 2. Cause a spanning rebalance of two nodes in root.
2374e15e06a8SLiam R. Howlett 	 * Fixed by setting mast->r->max correctly.
2375e15e06a8SLiam R. Howlett 	 */
2376e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2377e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 87, (void *)0xaf);
2378e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2379e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 4);
2380e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2381e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 8, (void *)0x11);
2382e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 44, (void *)0x59);
2383e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 68, (void *)0x89);
2384e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2385e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 43, (void *)0x57);
2386e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 24, (void *)0x31);
2387e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 844, (void *)0x699);
2388e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 84, (void *)0xa9);
2389e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2390e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 4);
2391e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 5);
2392e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2393e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2394e15e06a8SLiam R. Howlett 
2395e15e06a8SLiam R. Howlett 	/*
2396e15e06a8SLiam R. Howlett 	 * 3. Cause a node overflow on copy
2397e15e06a8SLiam R. Howlett 	 * Fixed by using the correct check for node size in mas_wr_modify()
2398e15e06a8SLiam R. Howlett 	 * Also discovered issue with metadata setting.
2399e15e06a8SLiam R. Howlett 	 */
2400e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2401120b1162SLiam Howlett 	mtree_test_store_range(mt, 0, ULONG_MAX, (void *)0x1);
2402e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2403e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2404e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2405e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 4);
2406e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 5, (void *)0xb);
2407e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2408e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 5, (void *)0xb);
2409e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2410e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 4);
2411e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2412e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 444, (void *)0x379);
2413e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2414e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2415e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 5, (void *)0xb);
2416e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2417e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2418e15e06a8SLiam R. Howlett 
2419e15e06a8SLiam R. Howlett 	/*
2420e15e06a8SLiam R. Howlett 	 * 4. spanning store failure due to writing incorrect pivot value at
2421e15e06a8SLiam R. Howlett 	 * last slot.
2422e15e06a8SLiam R. Howlett 	 * Fixed by setting mast->r->max correctly in mast_cp_to_nodes()
2423e15e06a8SLiam R. Howlett 	 *
2424e15e06a8SLiam R. Howlett 	 */
2425e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2426e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 261, (void *)0x20b);
2427e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 516, (void *)0x409);
2428e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 6, (void *)0xd);
2429e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2430e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1256, (void *)0x9d1);
2431e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2432e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2433e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 56, (void *)0x71);
2434e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2435e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 24, (void *)0x31);
2436e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2437e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2263, (void *)0x11af);
2438e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 446, (void *)0x37d);
2439e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 6, 45, (void *)0xd);
2440e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 3, 446, (void *)0x7);
2441e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2442e15e06a8SLiam R. Howlett 
2443e15e06a8SLiam R. Howlett 	/*
2444e15e06a8SLiam R. Howlett 	 * 5. mas_wr_extend_null() may overflow slots.
2445e15e06a8SLiam R. Howlett 	 * Fix by checking against wr_mas->node_end.
2446e15e06a8SLiam R. Howlett 	 */
2447e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2448e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 48, (void *)0x61);
2449e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 3, (void *)0x7);
2450e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2451e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 88, (void *)0xb1);
2452e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 81, (void *)0xa3);
2453e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2454e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2455e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2456e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2480, (void *)0x1361);
2457120b1162SLiam Howlett 	mtree_test_insert(mt, ULONG_MAX,
2458e15e06a8SLiam R. Howlett 			  (void *)0xffffffffffffffff);
2459120b1162SLiam Howlett 	mtree_test_erase(mt, ULONG_MAX);
2460e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2461e15e06a8SLiam R. Howlett 
2462e15e06a8SLiam R. Howlett 	/*
2463e15e06a8SLiam R. Howlett 	 * 6.  When reusing a node with an implied pivot and the node is
2464e15e06a8SLiam R. Howlett 	 * shrinking, old data would be left in the implied slot
2465e15e06a8SLiam R. Howlett 	 * Fixed by checking the last pivot for the mas->max and clear
2466e15e06a8SLiam R. Howlett 	 * accordingly.  This only affected the left-most node as that node is
2467e15e06a8SLiam R. Howlett 	 * the only one allowed to end in NULL.
2468e15e06a8SLiam R. Howlett 	 */
2469e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2470e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 3);
2471e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2472e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2473e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 2);
2474e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2475e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2476e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2477e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2478e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2479e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2480e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2481e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2482e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2483e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2484e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 3);
2485e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2486e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2487e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2488e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2489e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2490e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 2);
2491e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2492e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2493e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2494e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2495e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2496e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2497e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2498e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2499e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2500e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2501e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2502e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 3);
2503e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2504e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2505e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2506e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2507e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2508e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2509e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2510e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 4, 62, (void *)0x9);
2511e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2512e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 0, (void *)0x3);
2513e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 11, (void *)0x17);
2514e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2515e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2516e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 62, (void *)0x7d);
2517e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2518e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 15, (void *)0x3);
2519e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2520e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2521e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2522e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2523e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2524e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 62, (void *)0x7d);
2525e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2526e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 122, (void *)0xf5);
2527e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 3, (void *)0x7);
2528e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2529e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 1, (void *)0x1);
2530e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 85, (void *)0xab);
2531e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 72, (void *)0x91);
2532e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 81, (void *)0xa3);
2533e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 726, (void *)0x5ad);
2534e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2535e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2536e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 51, (void *)0x67);
2537e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 611, (void *)0x4c7);
2538e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 485, (void *)0x3cb);
2539e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2540e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2541e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2542e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2543e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 26, 1, (void *)0x35);
2544e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2545e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 22, (void *)0x3);
2546e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2547e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2548e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 53);
2549e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2550e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 1, (void *)0x3);
2551e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 222, (void *)0x1bd);
2552e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 485, (void *)0x3cb);
2553e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2554e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2555e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2556e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2557e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2558e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 621, (void *)0x4db);
2559e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2560e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2561e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2562e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 62, (void *)0x7d);
2563e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2564e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 0, (void *)0x3);
2565e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2566e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2567e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2568e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2569e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 4, 62, (void *)0x9);
2570e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2571e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2572e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2573e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 22, (void *)0x3);
2574e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2575e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2576e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 53);
2577e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2578e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 1, (void *)0x3);
2579e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 222, (void *)0x1bd);
2580e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 485, (void *)0x3cb);
2581e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2582e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2583e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2584e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2585e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2586e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2587e15e06a8SLiam R. Howlett 
2588e15e06a8SLiam R. Howlett 	/*
2589e15e06a8SLiam R. Howlett 	 * 7. Previous fix was incomplete, fix mas_resuse_node() clearing of old
2590e15e06a8SLiam R. Howlett 	 * data by overwriting it first - that way metadata is of no concern.
2591e15e06a8SLiam R. Howlett 	 */
2592e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2593e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2594e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 102, (void *)0xcd);
2595e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2596e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2597e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2598e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2599e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2600e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 110, (void *)0xdd);
2601e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2602e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 5, 0, (void *)0xb);
2603e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2604e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2605e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 112, (void *)0xe1);
2606e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2607e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2608e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 110, 2, (void *)0xdd);
2609e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2610e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 22);
2611e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2612e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 210, (void *)0x1a5);
2613e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 2, (void *)0x1);
2614e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2615e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2616e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 22);
2617e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2618e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2619e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2620e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 112);
2621e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2622e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2623e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2624e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 1, 2, (void *)0x3);
2625e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2626e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2627e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2628e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2629e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2630e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2631e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2632e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2633e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2634e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2635e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2636e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 1, 2, (void *)0x3);
2637e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2638e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2639e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2640e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 112);
2641e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 110, 12, (void *)0xdd);
2642e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2643e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 110);
2644e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 4, 71, (void *)0x9);
2645e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 2);
2646e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2647e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 11, 22, (void *)0x17);
2648e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 12);
2649e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2650e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 22);
2651e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2652e15e06a8SLiam R. Howlett 
2653e15e06a8SLiam R. Howlett 
2654e15e06a8SLiam R. Howlett 	/*
2655e15e06a8SLiam R. Howlett 	 * 8.  When rebalancing or spanning_rebalance(), the max of the new node
2656e15e06a8SLiam R. Howlett 	 * may be set incorrectly to the final pivot and not the right max.
2657e15e06a8SLiam R. Howlett 	 * Fix by setting the left max to orig right max if the entire node is
2658e15e06a8SLiam R. Howlett 	 * consumed.
2659e15e06a8SLiam R. Howlett 	 */
2660e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2661e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 6, (void *)0xd);
2662e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 67, (void *)0x87);
2663e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2664e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6716, (void *)0x3479);
2665e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 61, (void *)0x7b);
2666e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 13, (void *)0x1b);
2667e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 8, (void *)0x11);
2668e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2669e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2670e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67167);
2671e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 6, 7167, (void *)0xd);
2672e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2673e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67);
2674e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2675e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 667167);
2676e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2677e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 67, (void *)0x87);
2678e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2679e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2680e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2681e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67);
2682e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2683e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 67167, (void *)0x20cbf);
2684e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2685e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 7);
2686e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 16, (void *)0x21);
2687e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 36, (void *)0x49);
2688e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 67, (void *)0x87);
2689e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 6, (void *)0xd);
2690e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 367, (void *)0x2df);
2691e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 115, (void *)0xe7);
2692e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2693e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 3, (void *)0x3);
2694e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2695e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67167);
2696e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 6, 47, (void *)0xd);
2697e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2698e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 1, 67, (void *)0x3);
2699e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 67);
2700e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2701e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67167);
2702e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2703e15e06a8SLiam R. Howlett 
2704e15e06a8SLiam R. Howlett 	/*
2705e15e06a8SLiam R. Howlett 	 * 9. spanning store to the end of data caused an invalid metadata
2706e15e06a8SLiam R. Howlett 	 * length which resulted in a crash eventually.
2707e15e06a8SLiam R. Howlett 	 * Fix by checking if there is a value in pivot before incrementing the
2708e15e06a8SLiam R. Howlett 	 * metadata end in mab_mas_cp().  To ensure this doesn't happen again,
2709e15e06a8SLiam R. Howlett 	 * abstract the two locations this happens into a function called
2710e15e06a8SLiam R. Howlett 	 * mas_leaf_set_meta().
2711e15e06a8SLiam R. Howlett 	 */
2712e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2713e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2714e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2715e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2716e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2717e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2718e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 91, (void *)0xb7);
2719e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 18, (void *)0x25);
2720e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 81, (void *)0xa3);
2721e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 128, (void *)0x1);
2722e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2723e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 8);
2724e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 11, (void *)0x17);
2725e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2726e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2727e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2728120b1162SLiam Howlett 	mtree_test_insert(mt, ULONG_MAX - 10, (void *)0xffffffffffffffeb);
2729120b1162SLiam Howlett 	mtree_test_erase(mt, ULONG_MAX - 10);
2730e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 281, (void *)0x1);
2731e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2732e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1211, (void *)0x977);
2733e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 111, (void *)0xdf);
2734e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 13, (void *)0x1b);
2735e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 211, (void *)0x1a7);
2736e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 11, (void *)0x17);
2737e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2738e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1218, (void *)0x985);
2739e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 61, (void *)0x7b);
2740e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2741e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 121, (void *)0xf3);
2742e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2743e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2744e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2745120b1162SLiam Howlett 	mtree_test_insert(mt, ULONG_MAX - 10, (void *)0xffffffffffffffeb);
2746120b1162SLiam Howlett 	mtree_test_erase(mt, ULONG_MAX - 10);
2747e15e06a8SLiam R. Howlett }
2748120b1162SLiam Howlett 
2749120b1162SLiam Howlett /* duplicate the tree with a specific gap */
check_dup_gaps(struct maple_tree * mt,unsigned long nr_entries,bool zero_start,unsigned long gap)2750eaf9790dSLiam R. Howlett static noinline void __init check_dup_gaps(struct maple_tree *mt,
2751e15e06a8SLiam R. Howlett 				    unsigned long nr_entries, bool zero_start,
2752e15e06a8SLiam R. Howlett 				    unsigned long gap)
2753e15e06a8SLiam R. Howlett {
2754e15e06a8SLiam R. Howlett 	unsigned long i = 0;
2755e15e06a8SLiam R. Howlett 	struct maple_tree newmt;
2756e15e06a8SLiam R. Howlett 	int ret;
2757e15e06a8SLiam R. Howlett 	void *tmp;
2758e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
2759e15e06a8SLiam R. Howlett 	MA_STATE(newmas, &newmt, 0, 0);
2760099d7439SLiam R. Howlett 	struct rw_semaphore newmt_lock;
2761099d7439SLiam R. Howlett 
2762099d7439SLiam R. Howlett 	init_rwsem(&newmt_lock);
2763099d7439SLiam R. Howlett 	mt_set_external_lock(&newmt, &newmt_lock);
2764e15e06a8SLiam R. Howlett 
2765e15e06a8SLiam R. Howlett 	if (!zero_start)
2766e15e06a8SLiam R. Howlett 		i = 1;
2767e15e06a8SLiam R. Howlett 
2768e15e06a8SLiam R. Howlett 	mt_zero_nr_tallocated();
2769e15e06a8SLiam R. Howlett 	for (; i <= nr_entries; i++)
2770e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, (i+1)*10 - gap,
2771e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
2772e15e06a8SLiam R. Howlett 
2773099d7439SLiam R. Howlett 	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
2774e15e06a8SLiam R. Howlett 	mt_set_non_kernel(99999);
2775099d7439SLiam R. Howlett 	down_write(&newmt_lock);
2776e15e06a8SLiam R. Howlett 	ret = mas_expected_entries(&newmas, nr_entries);
2777e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
2778e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != 0);
2779e15e06a8SLiam R. Howlett 
2780120b1162SLiam Howlett 	rcu_read_lock();
2781e15e06a8SLiam R. Howlett 	mas_for_each(&mas, tmp, ULONG_MAX) {
2782e15e06a8SLiam R. Howlett 		newmas.index = mas.index;
2783e15e06a8SLiam R. Howlett 		newmas.last = mas.last;
2784e15e06a8SLiam R. Howlett 		mas_store(&newmas, tmp);
2785e15e06a8SLiam R. Howlett 	}
2786120b1162SLiam Howlett 	rcu_read_unlock();
2787e15e06a8SLiam R. Howlett 	mas_destroy(&newmas);
2788120b1162SLiam Howlett 
2789099d7439SLiam R. Howlett 	__mt_destroy(&newmt);
2790099d7439SLiam R. Howlett 	up_write(&newmt_lock);
2791e15e06a8SLiam R. Howlett }
2792e15e06a8SLiam R. Howlett 
2793120b1162SLiam Howlett /* Duplicate many sizes of trees.  Mainly to test expected entry values */
check_dup(struct maple_tree * mt)2794eaf9790dSLiam R. Howlett static noinline void __init check_dup(struct maple_tree *mt)
2795e15e06a8SLiam R. Howlett {
2796e15e06a8SLiam R. Howlett 	int i;
2797120b1162SLiam Howlett 	int big_start = 100010;
2798e15e06a8SLiam R. Howlett 
2799e15e06a8SLiam R. Howlett 	/* Check with a value at zero */
2800e15e06a8SLiam R. Howlett 	for (i = 10; i < 1000; i++) {
2801e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2802e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2803e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2804120b1162SLiam Howlett 		rcu_barrier();
2805e15e06a8SLiam R. Howlett 	}
2806e15e06a8SLiam R. Howlett 
2807120b1162SLiam Howlett 	cond_resched();
2808120b1162SLiam Howlett 	mt_cache_shrink();
2809e15e06a8SLiam R. Howlett 	/* Check with a value at zero, no gap */
2810e15e06a8SLiam R. Howlett 	for (i = 1000; i < 2000; i++) {
2811e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2812e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 0);
2813e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2814120b1162SLiam Howlett 		rcu_barrier();
2815e15e06a8SLiam R. Howlett 	}
2816e15e06a8SLiam R. Howlett 
2817120b1162SLiam Howlett 	cond_resched();
2818120b1162SLiam Howlett 	mt_cache_shrink();
2819e15e06a8SLiam R. Howlett 	/* Check with a value at zero and unreasonably large */
2820120b1162SLiam Howlett 	for (i = big_start; i < big_start + 10; i++) {
2821e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2822e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2823e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2824120b1162SLiam Howlett 		rcu_barrier();
2825e15e06a8SLiam R. Howlett 	}
2826e15e06a8SLiam R. Howlett 
2827120b1162SLiam Howlett 	cond_resched();
2828120b1162SLiam Howlett 	mt_cache_shrink();
2829e15e06a8SLiam R. Howlett 	/* Small to medium size not starting at zero*/
2830e15e06a8SLiam R. Howlett 	for (i = 200; i < 1000; i++) {
2831e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2832e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, false, 5);
2833e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2834120b1162SLiam Howlett 		rcu_barrier();
2835e15e06a8SLiam R. Howlett 	}
2836e15e06a8SLiam R. Howlett 
2837120b1162SLiam Howlett 	cond_resched();
2838120b1162SLiam Howlett 	mt_cache_shrink();
2839e15e06a8SLiam R. Howlett 	/* Unreasonably large not starting at zero*/
2840120b1162SLiam Howlett 	for (i = big_start; i < big_start + 10; i++) {
2841e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2842e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, false, 5);
2843e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2844120b1162SLiam Howlett 		rcu_barrier();
2845120b1162SLiam Howlett 		cond_resched();
2846120b1162SLiam Howlett 		mt_cache_shrink();
2847e15e06a8SLiam R. Howlett 	}
2848e15e06a8SLiam R. Howlett 
2849e15e06a8SLiam R. Howlett 	/* Check non-allocation tree not starting at zero */
2850e15e06a8SLiam R. Howlett 	for (i = 1500; i < 3000; i++) {
2851e15e06a8SLiam R. Howlett 		mt_init_flags(mt, 0);
2852e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, false, 5);
2853e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2854120b1162SLiam Howlett 		rcu_barrier();
2855120b1162SLiam Howlett 		cond_resched();
2856120b1162SLiam Howlett 		if (i % 2 == 0)
2857120b1162SLiam Howlett 			mt_cache_shrink();
2858e15e06a8SLiam R. Howlett 	}
2859e15e06a8SLiam R. Howlett 
2860120b1162SLiam Howlett 	mt_cache_shrink();
2861e15e06a8SLiam R. Howlett 	/* Check non-allocation tree starting at zero */
2862e15e06a8SLiam R. Howlett 	for (i = 200; i < 1000; i++) {
2863e15e06a8SLiam R. Howlett 		mt_init_flags(mt, 0);
2864e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2865e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2866120b1162SLiam Howlett 		rcu_barrier();
2867120b1162SLiam Howlett 		cond_resched();
2868e15e06a8SLiam R. Howlett 	}
2869e15e06a8SLiam R. Howlett 
2870120b1162SLiam Howlett 	mt_cache_shrink();
2871e15e06a8SLiam R. Howlett 	/* Unreasonably large */
2872120b1162SLiam Howlett 	for (i = big_start + 5; i < big_start + 10; i++) {
2873e15e06a8SLiam R. Howlett 		mt_init_flags(mt, 0);
2874e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2875e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2876120b1162SLiam Howlett 		rcu_barrier();
2877120b1162SLiam Howlett 		mt_cache_shrink();
2878120b1162SLiam Howlett 		cond_resched();
2879e15e06a8SLiam R. Howlett 	}
2880e15e06a8SLiam R. Howlett }
2881e15e06a8SLiam R. Howlett 
check_bnode_min_spanning(struct maple_tree * mt)2882eaf9790dSLiam R. Howlett static noinline void __init check_bnode_min_spanning(struct maple_tree *mt)
2883c5651b31SLiam Howlett {
2884c5651b31SLiam Howlett 	int i = 50;
2885c5651b31SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
2886c5651b31SLiam Howlett 
2887c5651b31SLiam Howlett 	mt_set_non_kernel(9999);
2888c5651b31SLiam Howlett 	mas_lock(&mas);
2889c5651b31SLiam Howlett 	do {
2890c5651b31SLiam Howlett 		mas_set_range(&mas, i*10, i*10+9);
2891c5651b31SLiam Howlett 		mas_store(&mas, check_bnode_min_spanning);
2892c5651b31SLiam Howlett 	} while (i--);
2893c5651b31SLiam Howlett 
2894c5651b31SLiam Howlett 	mas_set_range(&mas, 240, 509);
2895c5651b31SLiam Howlett 	mas_store(&mas, NULL);
2896c5651b31SLiam Howlett 	mas_unlock(&mas);
2897c5651b31SLiam Howlett 	mas_destroy(&mas);
2898c5651b31SLiam Howlett 	mt_set_non_kernel(0);
2899c5651b31SLiam Howlett }
2900c5651b31SLiam Howlett 
check_empty_area_window(struct maple_tree * mt)2901eaf9790dSLiam R. Howlett static noinline void __init check_empty_area_window(struct maple_tree *mt)
29027327e811SLiam Howlett {
29037327e811SLiam Howlett 	unsigned long i, nr_entries = 20;
29047327e811SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
29057327e811SLiam Howlett 
29067327e811SLiam Howlett 	for (i = 1; i <= nr_entries; i++)
29077327e811SLiam Howlett 		mtree_store_range(mt, i*10, i*10 + 9,
29087327e811SLiam Howlett 				  xa_mk_value(i), GFP_KERNEL);
29097327e811SLiam Howlett 
29107327e811SLiam Howlett 	/* Create another hole besides the one at 0 */
29117327e811SLiam Howlett 	mtree_store_range(mt, 160, 169, NULL, GFP_KERNEL);
29127327e811SLiam Howlett 
29137327e811SLiam Howlett 	/* Check lower bounds that don't fit */
29147327e811SLiam Howlett 	rcu_read_lock();
29157327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 10) != -EBUSY);
29167327e811SLiam Howlett 
29177327e811SLiam Howlett 	mas_reset(&mas);
29187327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 6, 90, 5) != -EBUSY);
29197327e811SLiam Howlett 
29207327e811SLiam Howlett 	/* Check lower bound that does fit */
29217327e811SLiam Howlett 	mas_reset(&mas);
29227327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 5) != 0);
29237327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 5);
29247327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 9);
29257327e811SLiam Howlett 	rcu_read_unlock();
29267327e811SLiam Howlett 
29277327e811SLiam Howlett 	/* Check one gap that doesn't fit and one that does */
29287327e811SLiam Howlett 	rcu_read_lock();
29297327e811SLiam Howlett 	mas_reset(&mas);
29307327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 217, 9) != 0);
29317327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 161);
29327327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 169);
29337327e811SLiam Howlett 
29347327e811SLiam Howlett 	/* Check one gap that does fit above the min */
29357327e811SLiam Howlett 	mas_reset(&mas);
29367327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 3) != 0);
29377327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 216);
29387327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 218);
29397327e811SLiam Howlett 
29407327e811SLiam Howlett 	/* Check size that doesn't fit any gap */
29417327e811SLiam Howlett 	mas_reset(&mas);
29427327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 16) != -EBUSY);
29437327e811SLiam Howlett 
29447327e811SLiam Howlett 	/*
29457327e811SLiam Howlett 	 * Check size that doesn't fit the lower end of the window but
29467327e811SLiam Howlett 	 * does fit the gap
29477327e811SLiam Howlett 	 */
29487327e811SLiam Howlett 	mas_reset(&mas);
29497327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 167, 200, 4) != -EBUSY);
29507327e811SLiam Howlett 
29517327e811SLiam Howlett 	/*
29527327e811SLiam Howlett 	 * Check size that doesn't fit the upper end of the window but
29537327e811SLiam Howlett 	 * does fit the gap
29547327e811SLiam Howlett 	 */
29557327e811SLiam Howlett 	mas_reset(&mas);
29567327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 162, 4) != -EBUSY);
29577327e811SLiam Howlett 
29587327e811SLiam Howlett 	/* Check mas_empty_area forward */
29597327e811SLiam Howlett 	mas_reset(&mas);
29607327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 9) != 0);
29617327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 0);
29627327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 8);
29637327e811SLiam Howlett 
29647327e811SLiam Howlett 	mas_reset(&mas);
29657327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 4) != 0);
29667327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 0);
29677327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 3);
29687327e811SLiam Howlett 
29697327e811SLiam Howlett 	mas_reset(&mas);
29707327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 11) != -EBUSY);
29717327e811SLiam Howlett 
29727327e811SLiam Howlett 	mas_reset(&mas);
29737327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 5, 100, 6) != -EBUSY);
29747327e811SLiam Howlett 
29757327e811SLiam Howlett 	mas_reset(&mas);
297617e7436bSLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 8, 10) != -EINVAL);
29777327e811SLiam Howlett 
29787327e811SLiam Howlett 	mas_reset(&mas);
29797327e811SLiam Howlett 	mas_empty_area(&mas, 100, 165, 3);
29807327e811SLiam Howlett 
29817327e811SLiam Howlett 	mas_reset(&mas);
29827327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 100, 163, 6) != -EBUSY);
29837327e811SLiam Howlett 	rcu_read_unlock();
29847327e811SLiam Howlett }
29857327e811SLiam Howlett 
check_empty_area_fill(struct maple_tree * mt)2986eaf9790dSLiam R. Howlett static noinline void __init check_empty_area_fill(struct maple_tree *mt)
29874bd6ddedSLiam R. Howlett {
29884bd6ddedSLiam R. Howlett 	const unsigned long max = 0x25D78000;
29894bd6ddedSLiam R. Howlett 	unsigned long size;
29904bd6ddedSLiam R. Howlett 	int loop, shift;
29914bd6ddedSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
29924bd6ddedSLiam R. Howlett 
29934bd6ddedSLiam R. Howlett 	mt_set_non_kernel(99999);
29944bd6ddedSLiam R. Howlett 	for (shift = 12; shift <= 16; shift++) {
29954bd6ddedSLiam R. Howlett 		loop = 5000;
29964bd6ddedSLiam R. Howlett 		size = 1 << shift;
29974bd6ddedSLiam R. Howlett 		while (loop--) {
29984bd6ddedSLiam R. Howlett 			mas_set(&mas, 0);
29994bd6ddedSLiam R. Howlett 			mas_lock(&mas);
30004bd6ddedSLiam R. Howlett 			MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != 0);
30014bd6ddedSLiam R. Howlett 			MT_BUG_ON(mt, mas.last != mas.index + size - 1);
30024bd6ddedSLiam R. Howlett 			mas_store_gfp(&mas, (void *)size, GFP_KERNEL);
30034bd6ddedSLiam R. Howlett 			mas_unlock(&mas);
30044bd6ddedSLiam R. Howlett 			mas_reset(&mas);
30054bd6ddedSLiam R. Howlett 		}
30064bd6ddedSLiam R. Howlett 	}
30074bd6ddedSLiam R. Howlett 
30084bd6ddedSLiam R. Howlett 	/* No space left. */
30094bd6ddedSLiam R. Howlett 	size = 0x1000;
30104bd6ddedSLiam R. Howlett 	rcu_read_lock();
30114bd6ddedSLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != -EBUSY);
30124bd6ddedSLiam R. Howlett 	rcu_read_unlock();
30134bd6ddedSLiam R. Howlett 
30144bd6ddedSLiam R. Howlett 	/* Fill a depth 3 node to the maximum */
30154bd6ddedSLiam R. Howlett 	for (unsigned long i = 629440511; i <= 629440800; i += 6)
30164bd6ddedSLiam R. Howlett 		mtree_store_range(mt, i, i + 5, (void *)i, GFP_KERNEL);
30174bd6ddedSLiam R. Howlett 	/* Make space in the second-last depth 4 node */
30184bd6ddedSLiam R. Howlett 	mtree_erase(mt, 631668735);
30194bd6ddedSLiam R. Howlett 	/* Make space in the last depth 4 node */
30204bd6ddedSLiam R. Howlett 	mtree_erase(mt, 629506047);
30214bd6ddedSLiam R. Howlett 	mas_reset(&mas);
30224bd6ddedSLiam R. Howlett 	/* Search from just after the gap in the second-last depth 4 */
30234bd6ddedSLiam R. Howlett 	rcu_read_lock();
30244bd6ddedSLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 629506048, 690000000, 0x5000) != 0);
30254bd6ddedSLiam R. Howlett 	rcu_read_unlock();
30264bd6ddedSLiam R. Howlett 	mt_set_non_kernel(0);
30274bd6ddedSLiam R. Howlett }
30284bd6ddedSLiam R. Howlett 
3029eb2e817fSLiam R. Howlett /*
3030eb2e817fSLiam R. Howlett  * Check MAS_START, MAS_PAUSE, active (implied), and MAS_NONE transitions.
3031eb2e817fSLiam R. Howlett  *
3032eb2e817fSLiam R. Howlett  * The table below shows the single entry tree (0-0 pointer) and normal tree
3033eb2e817fSLiam R. Howlett  * with nodes.
3034eb2e817fSLiam R. Howlett  *
3035eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
3036eb2e817fSLiam R. Howlett  *     ┬          ┬       ┬               ┬                ┬
3037eb2e817fSLiam R. Howlett  *     │          │       │               │                └─ the final range
3038eb2e817fSLiam R. Howlett  *     │          │       │               └─ The node value after execution
3039eb2e817fSLiam R. Howlett  *     │          │       └─ The node value before execution
3040eb2e817fSLiam R. Howlett  *     │          └─ If the entry exists or does not exists (DNE)
3041eb2e817fSLiam R. Howlett  *     └─ The function name
3042eb2e817fSLiam R. Howlett  *
3043eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
3044eb2e817fSLiam R. Howlett  * mas_next()
3045eb2e817fSLiam R. Howlett  *  - after last
3046eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
3047eb2e817fSLiam R. Howlett  *			------------------------
3048eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	1 - oo
3049eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	1 - oo
3050eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	1 - oo
3051eb2e817fSLiam R. Howlett  *			when index = 0
3052eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_ROOT	0
3053eb2e817fSLiam R. Howlett  *			when index > 0
3054eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	1 - oo
3055eb2e817fSLiam R. Howlett  *
3056eb2e817fSLiam R. Howlett  *			Normal tree
3057eb2e817fSLiam R. Howlett  *			-----------
3058eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
3059eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to last range
3060eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
3061eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to last range
3062eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	active		range
3063eb2e817fSLiam R. Howlett  *		exists	active		active		range
3064eb2e817fSLiam R. Howlett  *		DNE	active		active		set to last range
3065a8091f03SLiam R. Howlett  *		ERANGE	active		MAS_OVERFLOW	last range
3066eb2e817fSLiam R. Howlett  *
3067eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
3068eb2e817fSLiam R. Howlett  * mas_prev()
3069eb2e817fSLiam R. Howlett  * - before index
3070eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
3071eb2e817fSLiam R. Howlett  *			------------------------
3072eb2e817fSLiam R. Howlett  *				if index > 0
3073eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
3074eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
3075eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
3076eb2e817fSLiam R. Howlett  *
3077eb2e817fSLiam R. Howlett  *				if index == 0
3078eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	0
3079eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	0
3080eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	0
3081eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	0
3082eb2e817fSLiam R. Howlett  *
3083eb2e817fSLiam R. Howlett  *			Normal tree
3084eb2e817fSLiam R. Howlett  *			-----------
3085eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
3086eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to min
3087eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
3088eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to min
3089eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	active		range
3090eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	set to min
3091eb2e817fSLiam R. Howlett  *		any	MAS_ROOT	MAS_NONE	0
3092eb2e817fSLiam R. Howlett  *		exists	active		active		range
3093eb2e817fSLiam R. Howlett  *		DNE	active		active		last range
3094a8091f03SLiam R. Howlett  *		ERANGE	active		MAS_UNDERFLOW	last range
3095eb2e817fSLiam R. Howlett  *
3096eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
3097eb2e817fSLiam R. Howlett  * mas_find()
3098eb2e817fSLiam R. Howlett  *  - at index or next
3099eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
3100eb2e817fSLiam R. Howlett  *			------------------------
3101eb2e817fSLiam R. Howlett  *				if index >  0
3102eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	0
3103eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	0
3104eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	0
3105a8091f03SLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	1
3106eb2e817fSLiam R. Howlett  *				if index ==  0
3107eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
3108eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
3109eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
3110eb2e817fSLiam R. Howlett  *
3111eb2e817fSLiam R. Howlett  *			Normal tree
3112eb2e817fSLiam R. Howlett  *			-----------
3113eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
3114eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to max
3115eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
3116eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to max
3117a8091f03SLiam R. Howlett  *		exists	MAS_NONE	active		range (start at last)
3118eb2e817fSLiam R. Howlett  *		exists	active		active		range
3119eb2e817fSLiam R. Howlett  *		DNE	active		active		last range (max < last)
3120eb2e817fSLiam R. Howlett  *
3121eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
3122eb2e817fSLiam R. Howlett  * mas_find_rev()
3123eb2e817fSLiam R. Howlett  *  - at index or before
3124eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
3125eb2e817fSLiam R. Howlett  *			------------------------
3126eb2e817fSLiam R. Howlett  *				if index >  0
3127eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
3128eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
3129eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
3130eb2e817fSLiam R. Howlett  *				if index ==  0
3131eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	0
3132eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	0
3133eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	0
3134eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	0
3135eb2e817fSLiam R. Howlett  *
3136eb2e817fSLiam R. Howlett  *			Normal tree
3137eb2e817fSLiam R. Howlett  *			-----------
3138eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
3139eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to min
3140eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
3141eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to min
3142a8091f03SLiam R. Howlett  *		exists	MAS_NONE	active		range (start at index)
3143eb2e817fSLiam R. Howlett  *		exists	active		active		range
3144eb2e817fSLiam R. Howlett  *		DNE	active		active		last range (min > index)
3145eb2e817fSLiam R. Howlett  *
3146eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
3147eb2e817fSLiam R. Howlett  * mas_walk()
3148eb2e817fSLiam R. Howlett  * - Look up index
3149eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
3150eb2e817fSLiam R. Howlett  *			------------------------
3151eb2e817fSLiam R. Howlett  *				if index >  0
3152eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_ROOT	1 - oo
3153eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_ROOT	1 - oo
3154eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_ROOT	1 - oo
3155eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_ROOT	1 - oo
3156eb2e817fSLiam R. Howlett  *				if index ==  0
3157eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
3158eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
3159eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
3160eb2e817fSLiam R. Howlett  *		exists	MAS_ROOT	MAS_ROOT	0
3161eb2e817fSLiam R. Howlett  *
3162eb2e817fSLiam R. Howlett  *			Normal tree
3163eb2e817fSLiam R. Howlett  *			-----------
3164eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
3165eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		range of NULL
3166eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
3167eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		range of NULL
3168eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	active		range
3169eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	active		range of NULL
3170eb2e817fSLiam R. Howlett  *		exists	active		active		range
3171eb2e817fSLiam R. Howlett  *		DNE	active		active		range of NULL
3172eb2e817fSLiam R. Howlett  */
3173eb2e817fSLiam R. Howlett 
check_state_handling(struct maple_tree * mt)3174eb2e817fSLiam R. Howlett static noinline void __init check_state_handling(struct maple_tree *mt)
3175eb2e817fSLiam R. Howlett {
3176eb2e817fSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
3177eb2e817fSLiam R. Howlett 	void *entry, *ptr = (void *) 0x1234500;
3178eb2e817fSLiam R. Howlett 	void *ptr2 = &ptr;
3179eb2e817fSLiam R. Howlett 	void *ptr3 = &ptr2;
3180eb2e817fSLiam R. Howlett 
3181eb2e817fSLiam R. Howlett 	/* Check MAS_ROOT First */
3182eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0, 0, ptr, GFP_KERNEL);
3183eb2e817fSLiam R. Howlett 
3184eb2e817fSLiam R. Howlett 	mas_lock(&mas);
3185a8091f03SLiam R. Howlett 	/* prev: Start -> underflow*/
3186eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3187eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3188067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_underflow);
3189eb2e817fSLiam R. Howlett 
3190eb2e817fSLiam R. Howlett 	/* prev: Start -> root */
3191eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3192eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3193eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3194eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3195eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3196067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3197eb2e817fSLiam R. Howlett 
3198eb2e817fSLiam R. Howlett 	/* prev: pause -> root */
3199eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3200eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3201eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3202eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3203eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3204eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3205067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3206eb2e817fSLiam R. Howlett 
3207eb2e817fSLiam R. Howlett 	/* next: start -> none */
3208eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3209eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3210eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3211eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3212eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3213067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3214eb2e817fSLiam R. Howlett 
3215eb2e817fSLiam R. Howlett 	/* next: start -> none*/
3216eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3217eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3218eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3219eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3220eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3221067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3222eb2e817fSLiam R. Howlett 
3223eb2e817fSLiam R. Howlett 	/* find: start -> root */
3224eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3225eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3226eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3227eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3228eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3229067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3230eb2e817fSLiam R. Howlett 
3231eb2e817fSLiam R. Howlett 	/* find: root -> none */
3232eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3233eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3234eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3235eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3236067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3237eb2e817fSLiam R. Howlett 
3238eb2e817fSLiam R. Howlett 	/* find: none -> none */
3239eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3240eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3241eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3242eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3243067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3244eb2e817fSLiam R. Howlett 
3245eb2e817fSLiam R. Howlett 	/* find: start -> none */
3246eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3247eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3248eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3249eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3250eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3251067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3252eb2e817fSLiam R. Howlett 
3253eb2e817fSLiam R. Howlett 	/* find_rev: none -> root */
3254eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3255eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3256eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3257eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3258067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3259eb2e817fSLiam R. Howlett 
3260eb2e817fSLiam R. Howlett 	/* find_rev: start -> root */
3261eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3262eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3263eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3264eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3265eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3266067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3267eb2e817fSLiam R. Howlett 
3268eb2e817fSLiam R. Howlett 	/* find_rev: root -> none */
3269eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3270eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3271eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3272eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3273067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3274eb2e817fSLiam R. Howlett 
3275eb2e817fSLiam R. Howlett 	/* find_rev: none -> none */
3276eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3277eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3278eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3279eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3280067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3281eb2e817fSLiam R. Howlett 
3282eb2e817fSLiam R. Howlett 	/* find_rev: start -> root */
3283eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3284eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3285eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3286eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3287eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3288067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3289eb2e817fSLiam R. Howlett 
3290eb2e817fSLiam R. Howlett 	/* walk: start -> none */
3291eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3292eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3293eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3294eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3295eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3296067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3297eb2e817fSLiam R. Howlett 
3298eb2e817fSLiam R. Howlett 	/* walk: pause -> none*/
3299eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3300eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3301eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3302eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3303eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3304eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3305067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3306eb2e817fSLiam R. Howlett 
3307eb2e817fSLiam R. Howlett 	/* walk: none -> none */
3308eb2e817fSLiam R. Howlett 	mas.index = mas.last = 10;
3309eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3310eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3311eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3312eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3313067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3314eb2e817fSLiam R. Howlett 
3315eb2e817fSLiam R. Howlett 	/* walk: none -> none */
3316eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3317eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3318eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3319eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3320067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3321eb2e817fSLiam R. Howlett 
3322eb2e817fSLiam R. Howlett 	/* walk: start -> root */
3323eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3324eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3325eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3326eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3327eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3328067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3329eb2e817fSLiam R. Howlett 
3330eb2e817fSLiam R. Howlett 	/* walk: pause -> root */
3331eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3332eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3333eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3334eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3335eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3336eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3337067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3338eb2e817fSLiam R. Howlett 
3339eb2e817fSLiam R. Howlett 	/* walk: none -> root */
3340067311d3SLiam R. Howlett 	mas.status = ma_none;
3341eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3342eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3343eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3344eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3345067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3346eb2e817fSLiam R. Howlett 
3347eb2e817fSLiam R. Howlett 	/* walk: root -> root */
3348eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3349eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3350eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3351eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3352067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3353eb2e817fSLiam R. Howlett 
3354eb2e817fSLiam R. Howlett 	/* walk: root -> none */
3355eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3356eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3357eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3358eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3359eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3360067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_none);
3361eb2e817fSLiam R. Howlett 
3362eb2e817fSLiam R. Howlett 	/* walk: none -> root */
3363eb2e817fSLiam R. Howlett 	mas.index = mas.last = 0;
3364eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3365eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3366eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3367eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3368067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.status != ma_root);
3369eb2e817fSLiam R. Howlett 
3370eb2e817fSLiam R. Howlett 	mas_unlock(&mas);
3371eb2e817fSLiam R. Howlett 
3372eb2e817fSLiam R. Howlett 	/* Check when there is an actual node */
3373eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0, 0, NULL, GFP_KERNEL);
3374eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0x1000, 0x1500, ptr, GFP_KERNEL);
3375eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0x2000, 0x2500, ptr2, GFP_KERNEL);
3376eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0x3000, 0x3500, ptr3, GFP_KERNEL);
3377eb2e817fSLiam R. Howlett 
3378eb2e817fSLiam R. Howlett 	mas_lock(&mas);
3379eb2e817fSLiam R. Howlett 
3380eb2e817fSLiam R. Howlett 	/* next: start ->active */
3381eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3382eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3383eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3384eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3385eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3386067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3387eb2e817fSLiam R. Howlett 
3388eb2e817fSLiam R. Howlett 	/* next: pause ->active */
3389eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3390eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3391eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3392eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3393eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3394eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3395067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3396eb2e817fSLiam R. Howlett 
3397eb2e817fSLiam R. Howlett 	/* next: none ->active */
3398eb2e817fSLiam R. Howlett 	mas.index = mas.last = 0;
3399eb2e817fSLiam R. Howlett 	mas.offset = 0;
3400067311d3SLiam R. Howlett 	mas.status = ma_none;
3401eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3402eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3403eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3404eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3405067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3406eb2e817fSLiam R. Howlett 
3407067311d3SLiam R. Howlett 	/* next:active ->active (spanning limit) */
3408067311d3SLiam R. Howlett 	entry = mas_next(&mas, 0x2100);
3409eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3410eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3411eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3412067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3413eb2e817fSLiam R. Howlett 
3414067311d3SLiam R. Howlett 	/* next:active -> overflow (limit reached) beyond data */
3415eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, 0x2999);
3416eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3417eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2501);
3418eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2fff);
3419067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_overflow(&mas));
3420eb2e817fSLiam R. Howlett 
3421067311d3SLiam R. Howlett 	/* next:overflow -> active (limit changed) */
3422eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3423eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3424eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3425eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3426067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3427eb2e817fSLiam R. Howlett 
3428067311d3SLiam R. Howlett 	/* next:active ->  overflow (limit reached) */
3429eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3430eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3431eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3501);
3432eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3433067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_overflow(&mas));
3434a8091f03SLiam R. Howlett 
3435a8091f03SLiam R. Howlett 	/* next:overflow -> overflow  */
3436a8091f03SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3437a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3438a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3501);
3439a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3440067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_overflow(&mas));
3441a8091f03SLiam R. Howlett 
3442a8091f03SLiam R. Howlett 	/* prev:overflow -> active  */
3443a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0);
3444a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3445a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3446a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3447067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3448a8091f03SLiam R. Howlett 
3449eb2e817fSLiam R. Howlett 	/* next: none -> active, skip value at location */
3450eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3451eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3452067311d3SLiam R. Howlett 	mas.status = ma_none;
3453eb2e817fSLiam R. Howlett 	mas.offset = 0;
3454eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3455eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3456eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3457eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3458067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3459eb2e817fSLiam R. Howlett 
3460eb2e817fSLiam R. Howlett 	/* prev:active ->active */
3461eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3462eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3463eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3464eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3465067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3466eb2e817fSLiam R. Howlett 
3467067311d3SLiam R. Howlett 	/* prev:active -> underflow (span limit) */
3468067311d3SLiam R. Howlett 	mas_next(&mas, ULONG_MAX);
3469067311d3SLiam R. Howlett 	entry = mas_prev(&mas, 0x1200);
3470067311d3SLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3471067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3472067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3473067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas)); /* spanning limit */
3474067311d3SLiam R. Howlett 	entry = mas_prev(&mas, 0x1200); /* underflow */
3475067311d3SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3476067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3477067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3478067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
3479067311d3SLiam R. Howlett 
3480067311d3SLiam R. Howlett 	/* prev:underflow -> underflow (lower limit) spanning end range */
3481a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0x0100);
3482a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3483a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3484a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3485067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
3486a8091f03SLiam R. Howlett 
3487a8091f03SLiam R. Howlett 	/* prev:underflow -> underflow */
3488a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0);
3489a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3490a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3491a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3492067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
3493067311d3SLiam R. Howlett 
3494067311d3SLiam R. Howlett 	/* prev:underflow -> underflow */
3495067311d3SLiam R. Howlett 	entry = mas_prev(&mas, 0);
3496067311d3SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3497067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3498067311d3SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3499067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
3500a8091f03SLiam R. Howlett 
3501a8091f03SLiam R. Howlett 	/* next:underflow -> active */
3502a8091f03SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3503a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3504a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3505a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3506067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3507a8091f03SLiam R. Howlett 
3508a8091f03SLiam R. Howlett 	/* prev:first value -> underflow */
3509a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0x1000);
3510a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3511a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3512a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3513067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
3514a8091f03SLiam R. Howlett 
3515a8091f03SLiam R. Howlett 	/* find:underflow -> first value */
3516a8091f03SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3517a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3518a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3519a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3520067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3521eb2e817fSLiam R. Howlett 
3522eb2e817fSLiam R. Howlett 	/* prev: pause ->active */
3523eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x3600);
3524eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3525eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3526eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3527eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3528eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3529eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3530eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3531067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3532eb2e817fSLiam R. Howlett 
3533067311d3SLiam R. Howlett 	/* prev:active -> underflow spanning min */
3534eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0x1600);
3535eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3536eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3537eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1FFF);
3538067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
3539eb2e817fSLiam R. Howlett 
3540eb2e817fSLiam R. Howlett 	/* prev: active ->active, continue */
3541eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3542eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3543eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3544eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3545067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3546eb2e817fSLiam R. Howlett 
3547eb2e817fSLiam R. Howlett 	/* find: start ->active */
3548eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3549eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3550eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3551eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3552eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3553067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3554eb2e817fSLiam R. Howlett 
3555eb2e817fSLiam R. Howlett 	/* find: pause ->active */
3556eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3557eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3558eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3559eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3560eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3561eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3562067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3563eb2e817fSLiam R. Howlett 
3564eb2e817fSLiam R. Howlett 	/* find: start ->active on value */;
3565eb2e817fSLiam R. Howlett 	mas_set(&mas, 1200);
3566eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3567eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3568eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3569eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3570067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3571eb2e817fSLiam R. Howlett 
3572eb2e817fSLiam R. Howlett 	/* find:active ->active */
3573eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3574eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3575eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3576eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3577067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3578eb2e817fSLiam R. Howlett 
3579eb2e817fSLiam R. Howlett 
3580eb2e817fSLiam R. Howlett 	/* find:active -> active (NULL)*/
3581eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, 0x2700);
3582eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3583eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2501);
3584eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2FFF);
3585067311d3SLiam R. Howlett 	MAS_BUG_ON(&mas, !mas_is_active(&mas));
3586eb2e817fSLiam R. Howlett 
3587a8091f03SLiam R. Howlett 	/* find: overflow ->active */
3588eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, 0x5000);
3589eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3590eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3591eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3592067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3593eb2e817fSLiam R. Howlett 
3594eb2e817fSLiam R. Howlett 	/* find:active -> active (NULL) end*/
3595eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3596eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3597eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3501);
3598eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3599067311d3SLiam R. Howlett 	MAS_BUG_ON(&mas, !mas_is_active(&mas));
3600eb2e817fSLiam R. Howlett 
3601eb2e817fSLiam R. Howlett 	/* find_rev: active (END) ->active */
3602eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3603eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3604eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3605eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3606067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3607eb2e817fSLiam R. Howlett 
3608eb2e817fSLiam R. Howlett 	/* find_rev:active ->active */
3609eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3610eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3611eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3612eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3613067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3614eb2e817fSLiam R. Howlett 
3615eb2e817fSLiam R. Howlett 	/* find_rev: pause ->active */
3616eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3617eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3618eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3619eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3620eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3621067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3622eb2e817fSLiam R. Howlett 
3623067311d3SLiam R. Howlett 	/* find_rev:active -> underflow */
3624eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3625eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3626eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3627eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3628067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_underflow(&mas));
3629eb2e817fSLiam R. Howlett 
3630eb2e817fSLiam R. Howlett 	/* find_rev: start ->active */
3631eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3632eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3633eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3634eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3635eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3636067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3637eb2e817fSLiam R. Howlett 
3638eb2e817fSLiam R. Howlett 	/* mas_walk start ->active */
3639eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3640eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3641eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3642eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3643eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3644067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3645eb2e817fSLiam R. Howlett 
3646eb2e817fSLiam R. Howlett 	/* mas_walk start ->active */
3647eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1600);
3648eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3649eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3650eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3651eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3652067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3653eb2e817fSLiam R. Howlett 
3654eb2e817fSLiam R. Howlett 	/* mas_walk pause ->active */
3655eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3656eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3657eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3658eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3659eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3660eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3661067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3662eb2e817fSLiam R. Howlett 
3663eb2e817fSLiam R. Howlett 	/* mas_walk pause -> active */
3664eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1600);
3665eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3666eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3667eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3668eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3669eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3670067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3671eb2e817fSLiam R. Howlett 
3672eb2e817fSLiam R. Howlett 	/* mas_walk none -> active */
3673eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3674067311d3SLiam R. Howlett 	mas.status = ma_none;
3675eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3676eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3677eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3678eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3679067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3680eb2e817fSLiam R. Howlett 
3681eb2e817fSLiam R. Howlett 	/* mas_walk none -> active */
3682eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1600);
3683067311d3SLiam R. Howlett 	mas.status = ma_none;
3684eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3685eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3686eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3687eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3688067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3689eb2e817fSLiam R. Howlett 
3690eb2e817fSLiam R. Howlett 	/* mas_walk active -> active */
3691eb2e817fSLiam R. Howlett 	mas.index = 0x1200;
3692eb2e817fSLiam R. Howlett 	mas.last = 0x1200;
3693eb2e817fSLiam R. Howlett 	mas.offset = 0;
3694eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3695eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3696eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3697eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3698067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3699eb2e817fSLiam R. Howlett 
3700eb2e817fSLiam R. Howlett 	/* mas_walk active -> active */
3701eb2e817fSLiam R. Howlett 	mas.index = 0x1600;
3702eb2e817fSLiam R. Howlett 	mas.last = 0x1600;
3703eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3704eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3705eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3706eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3707067311d3SLiam R. Howlett 	MT_BUG_ON(mt, !mas_is_active(&mas));
3708eb2e817fSLiam R. Howlett 
3709eb2e817fSLiam R. Howlett 	mas_unlock(&mas);
3710eb2e817fSLiam R. Howlett }
3711eb2e817fSLiam R. Howlett 
alloc_cyclic_testing(struct maple_tree * mt)3712f92e1a82SLiam R. Howlett static noinline void __init alloc_cyclic_testing(struct maple_tree *mt)
3713f92e1a82SLiam R. Howlett {
3714f92e1a82SLiam R. Howlett 	unsigned long location;
3715f92e1a82SLiam R. Howlett 	unsigned long next;
3716f92e1a82SLiam R. Howlett 	int ret = 0;
3717f92e1a82SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
3718f92e1a82SLiam R. Howlett 
3719f92e1a82SLiam R. Howlett 	next = 0;
3720f92e1a82SLiam R. Howlett 	mtree_lock(mt);
3721f92e1a82SLiam R. Howlett 	for (int i = 0; i < 100; i++) {
3722f92e1a82SLiam R. Howlett 		mas_alloc_cyclic(&mas, &location, mt, 2, ULONG_MAX, &next, GFP_KERNEL);
3723f92e1a82SLiam R. Howlett 		MAS_BUG_ON(&mas, i != location - 2);
3724f92e1a82SLiam R. Howlett 		MAS_BUG_ON(&mas, mas.index != location);
3725f92e1a82SLiam R. Howlett 		MAS_BUG_ON(&mas, mas.last != location);
3726f92e1a82SLiam R. Howlett 		MAS_BUG_ON(&mas, i != next - 3);
3727f92e1a82SLiam R. Howlett 	}
3728f92e1a82SLiam R. Howlett 
3729f92e1a82SLiam R. Howlett 	mtree_unlock(mt);
3730f92e1a82SLiam R. Howlett 	mtree_destroy(mt);
3731f92e1a82SLiam R. Howlett 	next = 0;
3732f92e1a82SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
3733f92e1a82SLiam R. Howlett 	for (int i = 0; i < 100; i++) {
3734f92e1a82SLiam R. Howlett 		mtree_alloc_cyclic(mt, &location, mt, 2, ULONG_MAX, &next, GFP_KERNEL);
3735f92e1a82SLiam R. Howlett 		MT_BUG_ON(mt, i != location - 2);
3736f92e1a82SLiam R. Howlett 		MT_BUG_ON(mt, i != next - 3);
3737f92e1a82SLiam R. Howlett 		MT_BUG_ON(mt, mtree_load(mt, location) != mt);
3738f92e1a82SLiam R. Howlett 	}
3739f92e1a82SLiam R. Howlett 
3740f92e1a82SLiam R. Howlett 	mtree_destroy(mt);
3741*b02fcc08SLiam R. Howlett 
3742*b02fcc08SLiam R. Howlett 	/*
3743*b02fcc08SLiam R. Howlett 	 * Issue with reverse search was discovered
3744*b02fcc08SLiam R. Howlett 	 * https://lore.kernel.org/all/[email protected]/
3745*b02fcc08SLiam R. Howlett 	 * Exhausting the allocation area and forcing the search to wrap needs a
3746*b02fcc08SLiam R. Howlett 	 * mas_reset() in mas_alloc_cyclic().
3747*b02fcc08SLiam R. Howlett 	 */
3748*b02fcc08SLiam R. Howlett 	next = 0;
3749*b02fcc08SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
3750*b02fcc08SLiam R. Howlett 	for (int i = 0; i < 1023; i++) {
3751*b02fcc08SLiam R. Howlett 		mtree_alloc_cyclic(mt, &location, mt, 2, 1024, &next, GFP_KERNEL);
3752*b02fcc08SLiam R. Howlett 		MT_BUG_ON(mt, i != location - 2);
3753*b02fcc08SLiam R. Howlett 		MT_BUG_ON(mt, i != next - 3);
3754*b02fcc08SLiam R. Howlett 		MT_BUG_ON(mt, mtree_load(mt, location) != mt);
3755*b02fcc08SLiam R. Howlett 	}
3756*b02fcc08SLiam R. Howlett 	mtree_erase(mt, 123);
3757*b02fcc08SLiam R. Howlett 	MT_BUG_ON(mt, mtree_load(mt, 123) != NULL);
3758*b02fcc08SLiam R. Howlett 	mtree_alloc_cyclic(mt, &location, mt, 2, 1024, &next, GFP_KERNEL);
3759*b02fcc08SLiam R. Howlett 	MT_BUG_ON(mt, 123 != location);
3760*b02fcc08SLiam R. Howlett 	MT_BUG_ON(mt, 124 != next);
3761*b02fcc08SLiam R. Howlett 	MT_BUG_ON(mt, mtree_load(mt, location) != mt);
3762*b02fcc08SLiam R. Howlett 	mtree_erase(mt, 100);
3763*b02fcc08SLiam R. Howlett 	mtree_alloc_cyclic(mt, &location, mt, 2, 1024, &next, GFP_KERNEL);
3764*b02fcc08SLiam R. Howlett 	MT_BUG_ON(mt, 100 != location);
3765*b02fcc08SLiam R. Howlett 	MT_BUG_ON(mt, 101 != next);
3766*b02fcc08SLiam R. Howlett 	MT_BUG_ON(mt, mtree_load(mt, location) != mt);
3767*b02fcc08SLiam R. Howlett 	mtree_destroy(mt);
3768*b02fcc08SLiam R. Howlett 
3769f92e1a82SLiam R. Howlett 	/* Overflow test */
3770f92e1a82SLiam R. Howlett 	next = ULONG_MAX - 1;
3771f92e1a82SLiam R. Howlett 	ret = mtree_alloc_cyclic(mt, &location, mt, 2, ULONG_MAX, &next, GFP_KERNEL);
3772f92e1a82SLiam R. Howlett 	MT_BUG_ON(mt, ret != 0);
3773f92e1a82SLiam R. Howlett 	ret = mtree_alloc_cyclic(mt, &location, mt, 2, ULONG_MAX, &next, GFP_KERNEL);
3774f92e1a82SLiam R. Howlett 	MT_BUG_ON(mt, ret != 0);
3775f92e1a82SLiam R. Howlett 	ret = mtree_alloc_cyclic(mt, &location, mt, 2, ULONG_MAX, &next, GFP_KERNEL);
3776f92e1a82SLiam R. Howlett 	MT_BUG_ON(mt, ret != 1);
3777f92e1a82SLiam R. Howlett }
3778f92e1a82SLiam R. Howlett 
3779e15e06a8SLiam R. Howlett static DEFINE_MTREE(tree);
maple_tree_seed(void)3780eaf9790dSLiam R. Howlett static int __init maple_tree_seed(void)
3781e15e06a8SLiam R. Howlett {
3782e15e06a8SLiam R. Howlett 	unsigned long set[] = { 5015, 5014, 5017, 25, 1000,
3783e15e06a8SLiam R. Howlett 				1001, 1002, 1003, 1005, 0,
3784e15e06a8SLiam R. Howlett 				5003, 5002};
3785e15e06a8SLiam R. Howlett 	void *ptr = &set;
3786e15e06a8SLiam R. Howlett 
3787e15e06a8SLiam R. Howlett 	pr_info("\nTEST STARTING\n\n");
3788e15e06a8SLiam R. Howlett 
3789e15e06a8SLiam R. Howlett #if defined(BENCH_SLOT_STORE)
3790e15e06a8SLiam R. Howlett #define BENCH
3791e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3792e15e06a8SLiam R. Howlett 	bench_slot_store(&tree);
3793e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3794e15e06a8SLiam R. Howlett 	goto skip;
3795e15e06a8SLiam R. Howlett #endif
3796e15e06a8SLiam R. Howlett #if defined(BENCH_NODE_STORE)
3797e15e06a8SLiam R. Howlett #define BENCH
3798e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3799e15e06a8SLiam R. Howlett 	bench_node_store(&tree);
3800e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3801e15e06a8SLiam R. Howlett 	goto skip;
3802e15e06a8SLiam R. Howlett #endif
3803e15e06a8SLiam R. Howlett #if defined(BENCH_AWALK)
3804e15e06a8SLiam R. Howlett #define BENCH
3805e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3806e15e06a8SLiam R. Howlett 	bench_awalk(&tree);
3807e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3808e15e06a8SLiam R. Howlett 	goto skip;
3809e15e06a8SLiam R. Howlett #endif
3810e15e06a8SLiam R. Howlett #if defined(BENCH_WALK)
3811e15e06a8SLiam R. Howlett #define BENCH
3812e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3813e15e06a8SLiam R. Howlett 	bench_walk(&tree);
3814e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3815e15e06a8SLiam R. Howlett 	goto skip;
3816e15e06a8SLiam R. Howlett #endif
381724662decSLiam R. Howlett #if defined(BENCH_LOAD)
381824662decSLiam R. Howlett #define BENCH
381924662decSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
382024662decSLiam R. Howlett 	bench_load(&tree);
382124662decSLiam R. Howlett 	mtree_destroy(&tree);
382224662decSLiam R. Howlett 	goto skip;
382324662decSLiam R. Howlett #endif
3824e15e06a8SLiam R. Howlett #if defined(BENCH_FORK)
3825e15e06a8SLiam R. Howlett #define BENCH
3826446e1867SPeng Zhang 	bench_forking();
3827e15e06a8SLiam R. Howlett 	goto skip;
3828e15e06a8SLiam R. Howlett #endif
3829e15e06a8SLiam R. Howlett #if defined(BENCH_MT_FOR_EACH)
3830e15e06a8SLiam R. Howlett #define BENCH
3831e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3832e15e06a8SLiam R. Howlett 	bench_mt_for_each(&tree);
3833e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3834e15e06a8SLiam R. Howlett 	goto skip;
3835e15e06a8SLiam R. Howlett #endif
3836361c678bSLiam R. Howlett #if defined(BENCH_MAS_FOR_EACH)
3837361c678bSLiam R. Howlett #define BENCH
3838361c678bSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3839361c678bSLiam R. Howlett 	bench_mas_for_each(&tree);
3840361c678bSLiam R. Howlett 	mtree_destroy(&tree);
3841361c678bSLiam R. Howlett 	goto skip;
3842361c678bSLiam R. Howlett #endif
38438c314f3bSLiam R. Howlett #if defined(BENCH_MAS_PREV)
38448c314f3bSLiam R. Howlett #define BENCH
38458c314f3bSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
38468c314f3bSLiam R. Howlett 	bench_mas_prev(&tree);
38478c314f3bSLiam R. Howlett 	mtree_destroy(&tree);
38488c314f3bSLiam R. Howlett 	goto skip;
38498c314f3bSLiam R. Howlett #endif
3850e15e06a8SLiam R. Howlett 
3851e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3852c38279d4SWei Yang 	check_deficient_node(&tree);
3853c38279d4SWei Yang 	mtree_destroy(&tree);
3854c38279d4SWei Yang 
3855c38279d4SWei Yang 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3856431e1060SWei Yang 	check_store_null(&tree);
3857431e1060SWei Yang 	mtree_destroy(&tree);
3858431e1060SWei Yang 
3859431e1060SWei Yang 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3860f670fa1cSPeng Zhang 	check_root_expand(&tree);
3861f670fa1cSPeng Zhang 	mtree_destroy(&tree);
3862f670fa1cSPeng Zhang 
3863f670fa1cSPeng Zhang 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
38645159d64bSLiam R. Howlett 	check_iteration(&tree);
38655159d64bSLiam R. Howlett 	mtree_destroy(&tree);
38665159d64bSLiam R. Howlett 
3867446e1867SPeng Zhang 	check_forking();
3868e15e06a8SLiam R. Howlett 
3869e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3870e15e06a8SLiam R. Howlett 	check_mas_store_gfp(&tree);
3871e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3872e15e06a8SLiam R. Howlett 
3873e15e06a8SLiam R. Howlett 	/* Test ranges (store and insert) */
3874e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3875e15e06a8SLiam R. Howlett 	check_ranges(&tree);
3876e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3877e15e06a8SLiam R. Howlett 
3878120b1162SLiam Howlett #if defined(CONFIG_64BIT)
3879120b1162SLiam Howlett 	/* These tests have ranges outside of 4GB */
3880e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3881e15e06a8SLiam R. Howlett 	check_alloc_range(&tree);
3882e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3883e15e06a8SLiam R. Howlett 
3884e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3885e15e06a8SLiam R. Howlett 	check_alloc_rev_range(&tree);
3886e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3887120b1162SLiam Howlett #endif
3888e15e06a8SLiam R. Howlett 
3889e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3890e15e06a8SLiam R. Howlett 
3891e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], NULL);       /* See if 5015 -> NULL */
3892e15e06a8SLiam R. Howlett 
3893e15e06a8SLiam R. Howlett 	check_insert(&tree, set[9], &tree);     /* Insert 0 */
3894e15e06a8SLiam R. Howlett 	check_load(&tree, set[9], &tree);       /* See if 0 -> &tree */
3895e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], NULL);       /* See if 5015 -> NULL */
3896e15e06a8SLiam R. Howlett 
3897e15e06a8SLiam R. Howlett 	check_insert(&tree, set[10], ptr);      /* Insert 5003 */
3898e15e06a8SLiam R. Howlett 	check_load(&tree, set[9], &tree);       /* See if 0 -> &tree */
3899e15e06a8SLiam R. Howlett 	check_load(&tree, set[11], NULL);       /* See if 5002 -> NULL */
3900e15e06a8SLiam R. Howlett 	check_load(&tree, set[10], ptr);       /* See if 5003 -> ptr */
3901e15e06a8SLiam R. Howlett 
3902e15e06a8SLiam R. Howlett 	/* Clear out the tree */
3903e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3904e15e06a8SLiam R. Howlett 
3905e15e06a8SLiam R. Howlett 	/* Try to insert, insert a dup, and load back what was inserted. */
3906e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3907e15e06a8SLiam R. Howlett 	check_insert(&tree, set[0], &tree);     /* Insert 5015 */
3908e15e06a8SLiam R. Howlett 	check_dup_insert(&tree, set[0], &tree); /* Insert 5015 again */
3909e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
3910e15e06a8SLiam R. Howlett 
3911e15e06a8SLiam R. Howlett 	/*
3912e15e06a8SLiam R. Howlett 	 * Second set of tests try to load a value that doesn't exist, inserts
3913e15e06a8SLiam R. Howlett 	 * a second value, then loads the value again
3914e15e06a8SLiam R. Howlett 	 */
3915e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], NULL);        /* See if 5014 -> NULL */
3916e15e06a8SLiam R. Howlett 	check_insert(&tree, set[1], ptr);       /* insert 5014 -> ptr */
3917e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], ptr);         /* See if 5014 -> ptr */
3918e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
3919e15e06a8SLiam R. Howlett 	/*
3920e15e06a8SLiam R. Howlett 	 * Tree currently contains:
3921e15e06a8SLiam R. Howlett 	 * p[0]: 14 -> (nil) p[1]: 15 -> ptr p[2]: 16 -> &tree p[3]: 0 -> (nil)
3922e15e06a8SLiam R. Howlett 	 */
3923e15e06a8SLiam R. Howlett 	check_insert(&tree, set[6], ptr);       /* insert 1002 -> ptr */
3924e15e06a8SLiam R. Howlett 	check_insert(&tree, set[7], &tree);       /* insert 1003 -> &tree */
3925e15e06a8SLiam R. Howlett 
3926e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
3927e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], ptr);         /* See if 5014 -> ptr */
3928e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);         /* See if 1002 -> ptr */
3929e15e06a8SLiam R. Howlett 	check_load(&tree, set[7], &tree);       /* 1003 = &tree ? */
3930e15e06a8SLiam R. Howlett 
3931e15e06a8SLiam R. Howlett 	/* Clear out tree */
3932e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3933e15e06a8SLiam R. Howlett 
3934e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3935e15e06a8SLiam R. Howlett 	/* Test inserting into a NULL hole. */
3936e15e06a8SLiam R. Howlett 	check_insert(&tree, set[5], ptr);       /* insert 1001 -> ptr */
3937e15e06a8SLiam R. Howlett 	check_insert(&tree, set[7], &tree);       /* insert 1003 -> &tree */
3938e15e06a8SLiam R. Howlett 	check_insert(&tree, set[6], ptr);       /* insert 1002 -> ptr */
3939e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], ptr);         /* See if 1001 -> ptr */
3940e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);         /* See if 1002 -> ptr */
3941e15e06a8SLiam R. Howlett 	check_load(&tree, set[7], &tree);       /* See if 1003 -> &tree */
3942e15e06a8SLiam R. Howlett 
3943e15e06a8SLiam R. Howlett 	/* Clear out the tree */
3944e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3945e15e06a8SLiam R. Howlett 
3946e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3947e15e06a8SLiam R. Howlett 	/*
3948e15e06a8SLiam R. Howlett 	 *       set[] = {5015, 5014, 5017, 25, 1000,
3949e15e06a8SLiam R. Howlett 	 *                1001, 1002, 1003, 1005, 0,
3950e15e06a8SLiam R. Howlett 	 *                5003, 5002};
3951e15e06a8SLiam R. Howlett 	 */
3952e15e06a8SLiam R. Howlett 
3953e15e06a8SLiam R. Howlett 	check_insert(&tree, set[0], ptr); /* 5015 */
3954e15e06a8SLiam R. Howlett 	check_insert(&tree, set[1], &tree); /* 5014 */
3955e15e06a8SLiam R. Howlett 	check_insert(&tree, set[2], ptr); /* 5017 */
3956e15e06a8SLiam R. Howlett 	check_insert(&tree, set[3], &tree); /* 25 */
3957e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3958e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3959e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3960e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3961e15e06a8SLiam R. Howlett 	check_insert(&tree, set[4], ptr); /* 1000 < Should split. */
3962e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3963e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3964e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3965e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree); /*25 */
3966e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3967e15e06a8SLiam R. Howlett 	check_insert(&tree, set[5], &tree); /* 1001 */
3968e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3969e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3970e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3971e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3972e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3973e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], &tree);
3974e15e06a8SLiam R. Howlett 	check_insert(&tree, set[6], ptr);
3975e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3976e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3977e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3978e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3979e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3980e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], &tree);
3981e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);
3982e15e06a8SLiam R. Howlett 	check_insert(&tree, set[7], &tree);
3983e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3984e15e06a8SLiam R. Howlett 	check_insert(&tree, set[8], ptr);
3985e15e06a8SLiam R. Howlett 
3986e15e06a8SLiam R. Howlett 	check_insert(&tree, set[9], &tree);
3987e15e06a8SLiam R. Howlett 
3988e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3989e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3990e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3991e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3992e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3993e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], &tree);
3994e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);
3995e15e06a8SLiam R. Howlett 	check_load(&tree, set[9], &tree);
3996e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3997e15e06a8SLiam R. Howlett 
3998e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3999e15e06a8SLiam R. Howlett 	check_seq(&tree, 16, false);
4000e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4001e15e06a8SLiam R. Howlett 
4002e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
4003e15e06a8SLiam R. Howlett 	check_seq(&tree, 1000, true);
4004e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4005e15e06a8SLiam R. Howlett 
4006e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4007e15e06a8SLiam R. Howlett 	check_rev_seq(&tree, 1000, true);
4008e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4009e15e06a8SLiam R. Howlett 
4010e15e06a8SLiam R. Howlett 	check_lower_bound_split(&tree);
4011e15e06a8SLiam R. Howlett 	check_upper_bound_split(&tree);
4012e15e06a8SLiam R. Howlett 	check_mid_split(&tree);
4013e15e06a8SLiam R. Howlett 
4014e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
4015e15e06a8SLiam R. Howlett 	check_next_entry(&tree);
4016e15e06a8SLiam R. Howlett 	check_find(&tree);
4017e15e06a8SLiam R. Howlett 	check_find_2(&tree);
4018e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4019e15e06a8SLiam R. Howlett 
4020e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4021e15e06a8SLiam R. Howlett 	check_prev_entry(&tree);
4022e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4023e15e06a8SLiam R. Howlett 
4024e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4025e15e06a8SLiam R. Howlett 	check_gap_combining(&tree);
4026e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4027e15e06a8SLiam R. Howlett 
4028e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4029e15e06a8SLiam R. Howlett 	check_node_overwrite(&tree);
4030e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4031e15e06a8SLiam R. Howlett 
4032e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4033e15e06a8SLiam R. Howlett 	next_prev_test(&tree);
4034e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4035e15e06a8SLiam R. Howlett 
4036e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4037e15e06a8SLiam R. Howlett 	check_spanning_relatives(&tree);
4038e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4039e15e06a8SLiam R. Howlett 
4040e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4041e15e06a8SLiam R. Howlett 	check_rev_find(&tree);
4042e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4043e15e06a8SLiam R. Howlett 
4044e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
4045e15e06a8SLiam R. Howlett 	check_fuzzer(&tree);
4046e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4047e15e06a8SLiam R. Howlett 
4048e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4049e15e06a8SLiam R. Howlett 	check_dup(&tree);
4050e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
4051e15e06a8SLiam R. Howlett 
4052c5651b31SLiam Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4053c5651b31SLiam Howlett 	check_bnode_min_spanning(&tree);
4054c5651b31SLiam Howlett 	mtree_destroy(&tree);
4055c5651b31SLiam Howlett 
40567327e811SLiam Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
40577327e811SLiam Howlett 	check_empty_area_window(&tree);
40587327e811SLiam Howlett 	mtree_destroy(&tree);
40597327e811SLiam Howlett 
40604bd6ddedSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
40614bd6ddedSLiam R. Howlett 	check_empty_area_fill(&tree);
40624bd6ddedSLiam R. Howlett 	mtree_destroy(&tree);
40634bd6ddedSLiam R. Howlett 
4064eb2e817fSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4065eb2e817fSLiam R. Howlett 	check_state_handling(&tree);
4066eb2e817fSLiam R. Howlett 	mtree_destroy(&tree);
4067eb2e817fSLiam R. Howlett 
4068f92e1a82SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
4069f92e1a82SLiam R. Howlett 	alloc_cyclic_testing(&tree);
4070f92e1a82SLiam R. Howlett 	mtree_destroy(&tree);
4071f92e1a82SLiam R. Howlett 
4072f92e1a82SLiam R. Howlett 
4073e15e06a8SLiam R. Howlett #if defined(BENCH)
4074e15e06a8SLiam R. Howlett skip:
4075e15e06a8SLiam R. Howlett #endif
4076e15e06a8SLiam R. Howlett 	rcu_barrier();
4077e15e06a8SLiam R. Howlett 	pr_info("maple_tree: %u of %u tests passed\n",
4078e15e06a8SLiam R. Howlett 			atomic_read(&maple_tree_tests_passed),
4079e15e06a8SLiam R. Howlett 			atomic_read(&maple_tree_tests_run));
4080e15e06a8SLiam R. Howlett 	if (atomic_read(&maple_tree_tests_run) ==
4081e15e06a8SLiam R. Howlett 	    atomic_read(&maple_tree_tests_passed))
4082e15e06a8SLiam R. Howlett 		return 0;
4083e15e06a8SLiam R. Howlett 
4084e15e06a8SLiam R. Howlett 	return -EINVAL;
4085e15e06a8SLiam R. Howlett }
4086e15e06a8SLiam R. Howlett 
maple_tree_harvest(void)4087eaf9790dSLiam R. Howlett static void __exit maple_tree_harvest(void)
4088e15e06a8SLiam R. Howlett {
4089e15e06a8SLiam R. Howlett 
4090e15e06a8SLiam R. Howlett }
4091e15e06a8SLiam R. Howlett 
4092e15e06a8SLiam R. Howlett module_init(maple_tree_seed);
4093e15e06a8SLiam R. Howlett module_exit(maple_tree_harvest);
4094e15e06a8SLiam R. Howlett MODULE_AUTHOR("Liam R. Howlett <[email protected]>");
4095a619dd39SJeff Johnson MODULE_DESCRIPTION("maple tree API test module");
4096e15e06a8SLiam R. Howlett MODULE_LICENSE("GPL");
4097