xref: /openbmc/linux/lib/test_maple_tree.c (revision 4f82870119a46b0d04d91ef4697ac4977a255a9d)
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 <Liam.Howlett@Oracle.com>
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>
12*099d7439SLiam 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 */
46e15e06a8SLiam R. Howlett /* #define BENCH_MT_FOR_EACH */
47e15e06a8SLiam R. Howlett /* #define BENCH_FORK */
48361c678bSLiam R. Howlett /* #define BENCH_MAS_FOR_EACH */
498c314f3bSLiam R. Howlett /* #define BENCH_MAS_PREV */
50120b1162SLiam Howlett 
51120b1162SLiam Howlett #ifdef __KERNEL__
52120b1162SLiam Howlett #define mt_set_non_kernel(x)		do {} while (0)
53120b1162SLiam Howlett #define mt_zero_nr_tallocated(x)	do {} while (0)
54120b1162SLiam Howlett #else
55120b1162SLiam Howlett #define cond_resched()			do {} while (0)
56120b1162SLiam Howlett #endif
mtree_insert_index(struct maple_tree * mt,unsigned long index,gfp_t gfp)57eaf9790dSLiam R. Howlett static int __init mtree_insert_index(struct maple_tree *mt,
58eaf9790dSLiam R. Howlett 				     unsigned long index, gfp_t gfp)
59e15e06a8SLiam R. Howlett {
60e15e06a8SLiam R. Howlett 	return mtree_insert(mt, index, xa_mk_value(index & LONG_MAX), gfp);
61e15e06a8SLiam R. Howlett }
62e15e06a8SLiam R. Howlett 
mtree_erase_index(struct maple_tree * mt,unsigned long index)63eaf9790dSLiam R. Howlett static void __init mtree_erase_index(struct maple_tree *mt, unsigned long index)
64e15e06a8SLiam R. Howlett {
65e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_erase(mt, index) != xa_mk_value(index & LONG_MAX));
66e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_load(mt, index) != NULL);
67e15e06a8SLiam R. Howlett }
68e15e06a8SLiam R. Howlett 
mtree_test_insert(struct maple_tree * mt,unsigned long index,void * ptr)69eaf9790dSLiam R. Howlett static int __init mtree_test_insert(struct maple_tree *mt, unsigned long index,
70e15e06a8SLiam R. Howlett 				void *ptr)
71e15e06a8SLiam R. Howlett {
72e15e06a8SLiam R. Howlett 	return mtree_insert(mt, index, ptr, GFP_KERNEL);
73e15e06a8SLiam R. Howlett }
74e15e06a8SLiam R. Howlett 
mtree_test_store_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr)75eaf9790dSLiam R. Howlett static int __init mtree_test_store_range(struct maple_tree *mt,
76eaf9790dSLiam R. Howlett 			unsigned long start, unsigned long end, void *ptr)
77e15e06a8SLiam R. Howlett {
78e15e06a8SLiam R. Howlett 	return mtree_store_range(mt, start, end, ptr, GFP_KERNEL);
79e15e06a8SLiam R. Howlett }
80e15e06a8SLiam R. Howlett 
mtree_test_store(struct maple_tree * mt,unsigned long start,void * ptr)81eaf9790dSLiam R. Howlett static int __init mtree_test_store(struct maple_tree *mt, unsigned long start,
82e15e06a8SLiam R. Howlett 				void *ptr)
83e15e06a8SLiam R. Howlett {
84e15e06a8SLiam R. Howlett 	return mtree_test_store_range(mt, start, start, ptr);
85e15e06a8SLiam R. Howlett }
86e15e06a8SLiam R. Howlett 
mtree_test_insert_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr)87eaf9790dSLiam R. Howlett static int __init mtree_test_insert_range(struct maple_tree *mt,
88eaf9790dSLiam R. Howlett 			unsigned long start, unsigned long end, void *ptr)
89e15e06a8SLiam R. Howlett {
90e15e06a8SLiam R. Howlett 	return mtree_insert_range(mt, start, end, ptr, GFP_KERNEL);
91e15e06a8SLiam R. Howlett }
92e15e06a8SLiam R. Howlett 
mtree_test_load(struct maple_tree * mt,unsigned long index)93eaf9790dSLiam R. Howlett static void __init *mtree_test_load(struct maple_tree *mt, unsigned long index)
94e15e06a8SLiam R. Howlett {
95e15e06a8SLiam R. Howlett 	return mtree_load(mt, index);
96e15e06a8SLiam R. Howlett }
97e15e06a8SLiam R. Howlett 
mtree_test_erase(struct maple_tree * mt,unsigned long index)98eaf9790dSLiam R. Howlett static void __init *mtree_test_erase(struct maple_tree *mt, unsigned long index)
99e15e06a8SLiam R. Howlett {
100e15e06a8SLiam R. Howlett 	return mtree_erase(mt, index);
101e15e06a8SLiam R. Howlett }
102e15e06a8SLiam R. Howlett 
103120b1162SLiam 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)104eaf9790dSLiam R. Howlett static noinline void __init check_mtree_alloc_range(struct maple_tree *mt,
105e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, unsigned long size,
106e15e06a8SLiam R. Howlett 		unsigned long expected, int eret, void *ptr)
107e15e06a8SLiam R. Howlett {
108e15e06a8SLiam R. Howlett 
109e15e06a8SLiam R. Howlett 	unsigned long result = expected + 1;
110e15e06a8SLiam R. Howlett 	int ret;
111e15e06a8SLiam R. Howlett 
112e15e06a8SLiam R. Howlett 	ret = mtree_alloc_range(mt, &result, ptr, size, start, end,
113e15e06a8SLiam R. Howlett 			GFP_KERNEL);
114e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != eret);
115e15e06a8SLiam R. Howlett 	if (ret)
116e15e06a8SLiam R. Howlett 		return;
117e15e06a8SLiam R. Howlett 
118e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, result != expected);
119e15e06a8SLiam R. Howlett }
120e15e06a8SLiam 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)121eaf9790dSLiam R. Howlett static noinline void __init check_mtree_alloc_rrange(struct maple_tree *mt,
122e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, unsigned long size,
123e15e06a8SLiam R. Howlett 		unsigned long expected, int eret, void *ptr)
124e15e06a8SLiam R. Howlett {
125e15e06a8SLiam R. Howlett 
126e15e06a8SLiam R. Howlett 	unsigned long result = expected + 1;
127e15e06a8SLiam R. Howlett 	int ret;
128e15e06a8SLiam R. Howlett 
129ba997212SLiam R. Howlett 	ret = mtree_alloc_rrange(mt, &result, ptr, size, start, end,
130e15e06a8SLiam R. Howlett 			GFP_KERNEL);
131e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != eret);
132e15e06a8SLiam R. Howlett 	if (ret)
133e15e06a8SLiam R. Howlett 		return;
134e15e06a8SLiam R. Howlett 
135e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, result != expected);
136e15e06a8SLiam R. Howlett }
137120b1162SLiam Howlett #endif
138e15e06a8SLiam R. Howlett 
check_load(struct maple_tree * mt,unsigned long index,void * ptr)139eaf9790dSLiam R. Howlett static noinline void __init check_load(struct maple_tree *mt,
140eaf9790dSLiam R. Howlett 				       unsigned long index, void *ptr)
141e15e06a8SLiam R. Howlett {
142e15e06a8SLiam R. Howlett 	void *ret = mtree_test_load(mt, index);
143e15e06a8SLiam R. Howlett 
144e15e06a8SLiam R. Howlett 	if (ret != ptr)
145e15e06a8SLiam R. Howlett 		pr_err("Load %lu returned %p expect %p\n", index, ret, ptr);
146e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != ptr);
147e15e06a8SLiam R. Howlett }
148e15e06a8SLiam R. Howlett 
check_store_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr,int expected)149eaf9790dSLiam R. Howlett static noinline void __init check_store_range(struct maple_tree *mt,
150e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, void *ptr, int expected)
151e15e06a8SLiam R. Howlett {
152e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
153e15e06a8SLiam R. Howlett 	unsigned long i;
154e15e06a8SLiam R. Howlett 
155e15e06a8SLiam R. Howlett 	ret = mtree_test_store_range(mt, start, end, ptr);
156e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != expected);
157e15e06a8SLiam R. Howlett 
158e15e06a8SLiam R. Howlett 	if (ret)
159e15e06a8SLiam R. Howlett 		return;
160e15e06a8SLiam R. Howlett 
161e15e06a8SLiam R. Howlett 	for (i = start; i <= end; i++)
162e15e06a8SLiam R. Howlett 		check_load(mt, i, ptr);
163e15e06a8SLiam R. Howlett }
164e15e06a8SLiam R. Howlett 
check_insert_range(struct maple_tree * mt,unsigned long start,unsigned long end,void * ptr,int expected)165eaf9790dSLiam R. Howlett static noinline void __init check_insert_range(struct maple_tree *mt,
166e15e06a8SLiam R. Howlett 		unsigned long start, unsigned long end, void *ptr, int expected)
167e15e06a8SLiam R. Howlett {
168e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
169e15e06a8SLiam R. Howlett 	unsigned long i;
170e15e06a8SLiam R. Howlett 
171e15e06a8SLiam R. Howlett 	ret = mtree_test_insert_range(mt, start, end, ptr);
172e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != expected);
173e15e06a8SLiam R. Howlett 
174e15e06a8SLiam R. Howlett 	if (ret)
175e15e06a8SLiam R. Howlett 		return;
176e15e06a8SLiam R. Howlett 
177e15e06a8SLiam R. Howlett 	for (i = start; i <= end; i++)
178e15e06a8SLiam R. Howlett 		check_load(mt, i, ptr);
179e15e06a8SLiam R. Howlett }
180e15e06a8SLiam R. Howlett 
check_insert(struct maple_tree * mt,unsigned long index,void * ptr)181eaf9790dSLiam R. Howlett static noinline void __init check_insert(struct maple_tree *mt,
182eaf9790dSLiam R. Howlett 					 unsigned long index, void *ptr)
183e15e06a8SLiam R. Howlett {
184e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
185e15e06a8SLiam R. Howlett 
186e15e06a8SLiam R. Howlett 	ret = mtree_test_insert(mt, index, ptr);
187e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != 0);
188e15e06a8SLiam R. Howlett }
189e15e06a8SLiam R. Howlett 
check_dup_insert(struct maple_tree * mt,unsigned long index,void * ptr)190eaf9790dSLiam R. Howlett static noinline void __init check_dup_insert(struct maple_tree *mt,
191e15e06a8SLiam R. Howlett 				      unsigned long index, void *ptr)
192e15e06a8SLiam R. Howlett {
193e15e06a8SLiam R. Howlett 	int ret = -EINVAL;
194e15e06a8SLiam R. Howlett 
195e15e06a8SLiam R. Howlett 	ret = mtree_test_insert(mt, index, ptr);
196e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != -EEXIST);
197e15e06a8SLiam R. Howlett }
198e15e06a8SLiam R. Howlett 
199e15e06a8SLiam R. Howlett 
check_index_load(struct maple_tree * mt,unsigned long index)200eaf9790dSLiam R. Howlett static noinline void __init check_index_load(struct maple_tree *mt,
201eaf9790dSLiam R. Howlett 					     unsigned long index)
202e15e06a8SLiam R. Howlett {
203e15e06a8SLiam R. Howlett 	return check_load(mt, index, xa_mk_value(index & LONG_MAX));
204e15e06a8SLiam R. Howlett }
205e15e06a8SLiam R. Howlett 
not_empty(struct maple_node * node)206eaf9790dSLiam R. Howlett static inline __init int not_empty(struct maple_node *node)
207e15e06a8SLiam R. Howlett {
208e15e06a8SLiam R. Howlett 	int i;
209e15e06a8SLiam R. Howlett 
210e15e06a8SLiam R. Howlett 	if (node->parent)
211e15e06a8SLiam R. Howlett 		return 1;
212e15e06a8SLiam R. Howlett 
213e15e06a8SLiam R. Howlett 	for (i = 0; i < ARRAY_SIZE(node->slot); i++)
214e15e06a8SLiam R. Howlett 		if (node->slot[i])
215e15e06a8SLiam R. Howlett 			return 1;
216e15e06a8SLiam R. Howlett 
217e15e06a8SLiam R. Howlett 	return 0;
218e15e06a8SLiam R. Howlett }
219e15e06a8SLiam R. Howlett 
220e15e06a8SLiam R. Howlett 
check_rev_seq(struct maple_tree * mt,unsigned long max,bool verbose)221eaf9790dSLiam R. Howlett static noinline void __init check_rev_seq(struct maple_tree *mt,
222eaf9790dSLiam R. Howlett 					  unsigned long max, bool verbose)
223e15e06a8SLiam R. Howlett {
224e15e06a8SLiam R. Howlett 	unsigned long i = max, j;
225e15e06a8SLiam R. Howlett 
226e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
227e15e06a8SLiam R. Howlett 
228e15e06a8SLiam R. Howlett 	mt_zero_nr_tallocated();
229e15e06a8SLiam R. Howlett 	while (i) {
230e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
231e15e06a8SLiam R. Howlett 		for (j = i; j <= max; j++)
232e15e06a8SLiam R. Howlett 			check_index_load(mt, j);
233e15e06a8SLiam R. Howlett 
234e15e06a8SLiam R. Howlett 		check_load(mt, i - 1, NULL);
235e15e06a8SLiam R. Howlett 		mt_set_in_rcu(mt);
236e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, !mt_height(mt));
237e15e06a8SLiam R. Howlett 		mt_clear_in_rcu(mt);
238e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, !mt_height(mt));
239e15e06a8SLiam R. Howlett 		i--;
240e15e06a8SLiam R. Howlett 	}
241e15e06a8SLiam R. Howlett 	check_load(mt, max + 1, NULL);
242e15e06a8SLiam R. Howlett 
243120b1162SLiam Howlett #ifndef __KERNEL__
244e15e06a8SLiam R. Howlett 	if (verbose) {
245e15e06a8SLiam R. Howlett 		rcu_barrier();
24689f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_dec);
247e15e06a8SLiam R. Howlett 		pr_info(" %s test of 0-%lu %luK in %d active (%d total)\n",
248e15e06a8SLiam R. Howlett 			__func__, max, mt_get_alloc_size()/1024, mt_nr_allocated(),
249e15e06a8SLiam R. Howlett 			mt_nr_tallocated());
250e15e06a8SLiam R. Howlett 	}
251120b1162SLiam Howlett #endif
252e15e06a8SLiam R. Howlett }
253e15e06a8SLiam R. Howlett 
check_seq(struct maple_tree * mt,unsigned long max,bool verbose)254eaf9790dSLiam R. Howlett static noinline void __init check_seq(struct maple_tree *mt, unsigned long max,
255e15e06a8SLiam R. Howlett 		bool verbose)
256e15e06a8SLiam R. Howlett {
257e15e06a8SLiam R. Howlett 	unsigned long i, j;
258e15e06a8SLiam R. Howlett 
259e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
260e15e06a8SLiam R. Howlett 
261e15e06a8SLiam R. Howlett 	mt_zero_nr_tallocated();
262e15e06a8SLiam R. Howlett 	for (i = 0; i <= max; i++) {
263e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
264e15e06a8SLiam R. Howlett 		for (j = 0; j <= i; j++)
265e15e06a8SLiam R. Howlett 			check_index_load(mt, j);
266e15e06a8SLiam R. Howlett 
267e15e06a8SLiam R. Howlett 		if (i)
268e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, !mt_height(mt));
269e15e06a8SLiam R. Howlett 		check_load(mt, i + 1, NULL);
270e15e06a8SLiam R. Howlett 	}
271120b1162SLiam Howlett 
272120b1162SLiam Howlett #ifndef __KERNEL__
273e15e06a8SLiam R. Howlett 	if (verbose) {
274e15e06a8SLiam R. Howlett 		rcu_barrier();
27589f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_dec);
276e15e06a8SLiam R. Howlett 		pr_info(" seq test of 0-%lu %luK in %d active (%d total)\n",
277e15e06a8SLiam R. Howlett 			max, mt_get_alloc_size()/1024, mt_nr_allocated(),
278e15e06a8SLiam R. Howlett 			mt_nr_tallocated());
279e15e06a8SLiam R. Howlett 	}
280120b1162SLiam Howlett #endif
281e15e06a8SLiam R. Howlett }
282e15e06a8SLiam R. Howlett 
check_lb_not_empty(struct maple_tree * mt)283eaf9790dSLiam R. Howlett static noinline void __init check_lb_not_empty(struct maple_tree *mt)
284e15e06a8SLiam R. Howlett {
285e15e06a8SLiam R. Howlett 	unsigned long i, j;
286e15e06a8SLiam R. Howlett 	unsigned long huge = 4000UL * 1000 * 1000;
287e15e06a8SLiam R. Howlett 
288e15e06a8SLiam R. Howlett 
289e15e06a8SLiam R. Howlett 	i = huge;
290e15e06a8SLiam R. Howlett 	while (i > 4096) {
291e15e06a8SLiam R. Howlett 		check_insert(mt, i, (void *) i);
292e15e06a8SLiam R. Howlett 		for (j = huge; j >= i; j /= 2) {
293e15e06a8SLiam R. Howlett 			check_load(mt, j-1, NULL);
294e15e06a8SLiam R. Howlett 			check_load(mt, j, (void *) j);
295e15e06a8SLiam R. Howlett 			check_load(mt, j+1, NULL);
296e15e06a8SLiam R. Howlett 		}
297e15e06a8SLiam R. Howlett 		i /= 2;
298e15e06a8SLiam R. Howlett 	}
299e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
300e15e06a8SLiam R. Howlett }
301e15e06a8SLiam R. Howlett 
check_lower_bound_split(struct maple_tree * mt)302eaf9790dSLiam R. Howlett static noinline void __init check_lower_bound_split(struct maple_tree *mt)
303e15e06a8SLiam R. Howlett {
304e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
305e15e06a8SLiam R. Howlett 	check_lb_not_empty(mt);
306e15e06a8SLiam R. Howlett }
307e15e06a8SLiam R. Howlett 
check_upper_bound_split(struct maple_tree * mt)308eaf9790dSLiam R. Howlett static noinline void __init check_upper_bound_split(struct maple_tree *mt)
309e15e06a8SLiam R. Howlett {
310e15e06a8SLiam R. Howlett 	unsigned long i, j;
311120b1162SLiam Howlett 	unsigned long huge;
312e15e06a8SLiam R. Howlett 
313e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
314e15e06a8SLiam R. Howlett 
315120b1162SLiam Howlett 	if (MAPLE_32BIT)
316120b1162SLiam Howlett 		huge = 2147483647UL;
317120b1162SLiam Howlett 	else
318120b1162SLiam Howlett 		huge = 4000UL * 1000 * 1000;
319120b1162SLiam Howlett 
320e15e06a8SLiam R. Howlett 	i = 4096;
321e15e06a8SLiam R. Howlett 	while (i < huge) {
322e15e06a8SLiam R. Howlett 		check_insert(mt, i, (void *) i);
323e15e06a8SLiam R. Howlett 		for (j = i; j >= huge; j *= 2) {
324e15e06a8SLiam R. Howlett 			check_load(mt, j-1, NULL);
325e15e06a8SLiam R. Howlett 			check_load(mt, j, (void *) j);
326e15e06a8SLiam R. Howlett 			check_load(mt, j+1, NULL);
327e15e06a8SLiam R. Howlett 		}
328e15e06a8SLiam R. Howlett 		i *= 2;
329e15e06a8SLiam R. Howlett 	}
330e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
331e15e06a8SLiam R. Howlett }
332e15e06a8SLiam R. Howlett 
check_mid_split(struct maple_tree * mt)333eaf9790dSLiam R. Howlett static noinline void __init check_mid_split(struct maple_tree *mt)
334e15e06a8SLiam R. Howlett {
335e15e06a8SLiam R. Howlett 	unsigned long huge = 8000UL * 1000 * 1000;
336e15e06a8SLiam R. Howlett 
337e15e06a8SLiam R. Howlett 	check_insert(mt, huge, (void *) huge);
338e15e06a8SLiam R. Howlett 	check_insert(mt, 0, xa_mk_value(0));
339e15e06a8SLiam R. Howlett 	check_lb_not_empty(mt);
340e15e06a8SLiam R. Howlett }
341e15e06a8SLiam R. Howlett 
check_rev_find(struct maple_tree * mt)342eaf9790dSLiam R. Howlett static noinline void __init check_rev_find(struct maple_tree *mt)
343e15e06a8SLiam R. Howlett {
344e15e06a8SLiam R. Howlett 	int i, nr_entries = 200;
345e15e06a8SLiam R. Howlett 	void *val;
346e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
347e15e06a8SLiam R. Howlett 
348e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
349e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
350e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
351e15e06a8SLiam R. Howlett 
352120b1162SLiam Howlett 	rcu_read_lock();
353e15e06a8SLiam R. Howlett 	mas_set(&mas, 1000);
354e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 1000);
355e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(100));
356e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 1000);
357e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
358e15e06a8SLiam R. Howlett 
359e15e06a8SLiam R. Howlett 	mas_set(&mas, 999);
360e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 997);
361e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
362e15e06a8SLiam R. Howlett 
363e15e06a8SLiam R. Howlett 	mas_set(&mas, 1000);
364e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 900);
365e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(100));
366e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 900);
367e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(99));
368e15e06a8SLiam R. Howlett 
369e15e06a8SLiam R. Howlett 	mas_set(&mas, 20);
370e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
371e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(2));
372e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
373e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(1));
374e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
375e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(0));
376e15e06a8SLiam R. Howlett 	val = mas_find_rev(&mas, 0);
377e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
378120b1162SLiam Howlett 	rcu_read_unlock();
379e15e06a8SLiam R. Howlett }
380e15e06a8SLiam R. Howlett 
check_find(struct maple_tree * mt)381eaf9790dSLiam R. Howlett static noinline void __init check_find(struct maple_tree *mt)
382e15e06a8SLiam R. Howlett {
383e15e06a8SLiam R. Howlett 	unsigned long val = 0;
384120b1162SLiam Howlett 	unsigned long count;
385e15e06a8SLiam R. Howlett 	unsigned long max;
386120b1162SLiam Howlett 	unsigned long top;
387e15e06a8SLiam R. Howlett 	unsigned long last = 0, index = 0;
388e15e06a8SLiam R. Howlett 	void *entry, *entry2;
389e15e06a8SLiam R. Howlett 
390e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
391e15e06a8SLiam R. Howlett 
392e15e06a8SLiam R. Howlett 	/* Insert 0. */
393e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_insert_index(mt, val++, GFP_KERNEL));
394e15e06a8SLiam R. Howlett 
395120b1162SLiam Howlett #if defined(CONFIG_64BIT)
396120b1162SLiam Howlett 	top = 4398046511104UL;
397120b1162SLiam Howlett #else
398120b1162SLiam Howlett 	top = ULONG_MAX;
399120b1162SLiam Howlett #endif
400120b1162SLiam Howlett 
401120b1162SLiam Howlett 	if (MAPLE_32BIT) {
402120b1162SLiam Howlett 		count = 15;
403120b1162SLiam Howlett 	} else {
404120b1162SLiam Howlett 		count = 20;
405120b1162SLiam Howlett 	}
406120b1162SLiam Howlett 
407e15e06a8SLiam R. Howlett 	for (int i = 0; i <= count; i++) {
408e15e06a8SLiam R. Howlett 		if (val != 64)
409e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, mtree_insert_index(mt, val, GFP_KERNEL));
410e15e06a8SLiam R. Howlett 		else
411e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, mtree_insert(mt, val,
412e15e06a8SLiam R. Howlett 				XA_ZERO_ENTRY, GFP_KERNEL));
413e15e06a8SLiam R. Howlett 
414e15e06a8SLiam R. Howlett 		val <<= 2;
415e15e06a8SLiam R. Howlett 	}
416e15e06a8SLiam R. Howlett 
417e15e06a8SLiam R. Howlett 	val = 0;
418e15e06a8SLiam R. Howlett 	mas_set(&mas, val);
419e15e06a8SLiam R. Howlett 	mas_lock(&mas);
420e15e06a8SLiam R. Howlett 	while ((entry = mas_find(&mas, 268435456)) != NULL) {
421e15e06a8SLiam R. Howlett 		if (val != 64)
422e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
423e15e06a8SLiam R. Howlett 		else
424e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
425e15e06a8SLiam R. Howlett 
426e15e06a8SLiam R. Howlett 		val <<= 2;
427e15e06a8SLiam R. Howlett 		/* For zero check. */
428e15e06a8SLiam R. Howlett 		if (!val)
429e15e06a8SLiam R. Howlett 			val = 1;
430e15e06a8SLiam R. Howlett 	}
431e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
432e15e06a8SLiam R. Howlett 
433e15e06a8SLiam R. Howlett 	val = 0;
434e15e06a8SLiam R. Howlett 	mas_set(&mas, val);
435e15e06a8SLiam R. Howlett 	mas_lock(&mas);
436e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX) {
437e15e06a8SLiam R. Howlett 		if (val != 64)
438e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
439e15e06a8SLiam R. Howlett 		else
440e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
441e15e06a8SLiam R. Howlett 		val <<= 2;
442e15e06a8SLiam R. Howlett 		/* For zero check. */
443e15e06a8SLiam R. Howlett 		if (!val)
444e15e06a8SLiam R. Howlett 			val = 1;
445e15e06a8SLiam R. Howlett 	}
446e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
447e15e06a8SLiam R. Howlett 
448e15e06a8SLiam R. Howlett 	/* Test mas_pause */
449e15e06a8SLiam R. Howlett 	val = 0;
450e15e06a8SLiam R. Howlett 	mas_set(&mas, val);
451e15e06a8SLiam R. Howlett 	mas_lock(&mas);
452e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX) {
453e15e06a8SLiam R. Howlett 		if (val != 64)
454e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
455e15e06a8SLiam R. Howlett 		else
456e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
457e15e06a8SLiam R. Howlett 		val <<= 2;
458e15e06a8SLiam R. Howlett 		/* For zero check. */
459e15e06a8SLiam R. Howlett 		if (!val)
460e15e06a8SLiam R. Howlett 			val = 1;
461e15e06a8SLiam R. Howlett 
462e15e06a8SLiam R. Howlett 		mas_pause(&mas);
463e15e06a8SLiam R. Howlett 		mas_unlock(&mas);
464e15e06a8SLiam R. Howlett 		mas_lock(&mas);
465e15e06a8SLiam R. Howlett 	}
466e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
467e15e06a8SLiam R. Howlett 
468e15e06a8SLiam R. Howlett 	val = 0;
469e15e06a8SLiam R. Howlett 	max = 300; /* A value big enough to include XA_ZERO_ENTRY at 64. */
470e15e06a8SLiam R. Howlett 	mt_for_each(mt, entry, index, max) {
471e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, xa_mk_value(val) != entry);
472e15e06a8SLiam R. Howlett 		val <<= 2;
473e15e06a8SLiam R. Howlett 		if (val == 64) /* Skip zero entry. */
474e15e06a8SLiam R. Howlett 			val <<= 2;
475e15e06a8SLiam R. Howlett 		/* For zero check. */
476e15e06a8SLiam R. Howlett 		if (!val)
477e15e06a8SLiam R. Howlett 			val = 1;
478e15e06a8SLiam R. Howlett 	}
479e15e06a8SLiam R. Howlett 
480e15e06a8SLiam R. Howlett 	val = 0;
481e15e06a8SLiam R. Howlett 	max = 0;
482e15e06a8SLiam R. Howlett 	index = 0;
483e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
484e15e06a8SLiam R. Howlett 	mt_for_each(mt, entry, index, ULONG_MAX) {
485120b1162SLiam Howlett 		if (val == top)
486120b1162SLiam Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(LONG_MAX));
487e15e06a8SLiam R. Howlett 		else
488e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
489120b1162SLiam Howlett 
490120b1162SLiam Howlett 		/* Workaround for 32bit */
491120b1162SLiam Howlett 		if ((val << 2) < val)
492120b1162SLiam Howlett 			val = ULONG_MAX;
493120b1162SLiam Howlett 		else
494e15e06a8SLiam R. Howlett 			val <<= 2;
495120b1162SLiam Howlett 
496e15e06a8SLiam R. Howlett 		if (val == 64) /* Skip zero entry. */
497e15e06a8SLiam R. Howlett 			val <<= 2;
498e15e06a8SLiam R. Howlett 		/* For zero check. */
499e15e06a8SLiam R. Howlett 		if (!val)
500e15e06a8SLiam R. Howlett 			val = 1;
501e15e06a8SLiam R. Howlett 		max++;
502e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, max > 25);
503e15e06a8SLiam R. Howlett 	}
504e15e06a8SLiam R. Howlett 	mtree_erase_index(mt, ULONG_MAX);
505e15e06a8SLiam R. Howlett 
506e15e06a8SLiam R. Howlett 	mas_reset(&mas);
507e15e06a8SLiam R. Howlett 	index = 17;
508e15e06a8SLiam R. Howlett 	entry = mt_find(mt, &index, 512);
509e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, xa_mk_value(256) != entry);
510e15e06a8SLiam R. Howlett 
511e15e06a8SLiam R. Howlett 	mas_reset(&mas);
512e15e06a8SLiam R. Howlett 	index = 17;
513e15e06a8SLiam R. Howlett 	entry = mt_find(mt, &index, 20);
514e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
515e15e06a8SLiam R. Howlett 
516e15e06a8SLiam R. Howlett 
517e15e06a8SLiam R. Howlett 	/* Range check.. */
518e15e06a8SLiam R. Howlett 	/* Insert ULONG_MAX */
519e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
520e15e06a8SLiam R. Howlett 
521e15e06a8SLiam R. Howlett 	val = 0;
522e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
523e15e06a8SLiam R. Howlett 	mas_lock(&mas);
524e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX) {
525e15e06a8SLiam R. Howlett 		if (val == 64)
526e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
527120b1162SLiam Howlett 		else if (val == top)
528120b1162SLiam Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(LONG_MAX));
529e15e06a8SLiam R. Howlett 		else
530e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(val) != entry);
531120b1162SLiam Howlett 
532120b1162SLiam Howlett 		/* Workaround for 32bit */
533120b1162SLiam Howlett 		if ((val << 2) < val)
534120b1162SLiam Howlett 			val = ULONG_MAX;
535120b1162SLiam Howlett 		else
536e15e06a8SLiam R. Howlett 			val <<= 2;
537e15e06a8SLiam R. Howlett 
538e15e06a8SLiam R. Howlett 		/* For zero check. */
539e15e06a8SLiam R. Howlett 		if (!val)
540e15e06a8SLiam R. Howlett 			val = 1;
541e15e06a8SLiam R. Howlett 		mas_pause(&mas);
542e15e06a8SLiam R. Howlett 		mas_unlock(&mas);
543e15e06a8SLiam R. Howlett 		mas_lock(&mas);
544e15e06a8SLiam R. Howlett 	}
545e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
546e15e06a8SLiam R. Howlett 
547e15e06a8SLiam R. Howlett 	mas_set(&mas, 1048576);
548e15e06a8SLiam R. Howlett 	mas_lock(&mas);
549e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, 1048576);
550e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
551e15e06a8SLiam R. Howlett 	MT_BUG_ON(mas.tree, entry == NULL);
552e15e06a8SLiam R. Howlett 
553e15e06a8SLiam R. Howlett 	/*
554e15e06a8SLiam R. Howlett 	 * Find last value.
555e15e06a8SLiam R. Howlett 	 * 1. get the expected value, leveraging the existence of an end entry
556e15e06a8SLiam R. Howlett 	 * 2. delete end entry
557e15e06a8SLiam R. Howlett 	 * 3. find the last value but searching for ULONG_MAX and then using
558e15e06a8SLiam R. Howlett 	 * prev
559e15e06a8SLiam R. Howlett 	 */
560e15e06a8SLiam R. Howlett 	/* First, get the expected result. */
561e15e06a8SLiam R. Howlett 	mas_lock(&mas);
562e15e06a8SLiam R. Howlett 	mas_reset(&mas);
563e15e06a8SLiam R. Howlett 	mas.index = ULONG_MAX; /* start at max.. */
564e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
565e15e06a8SLiam R. Howlett 	entry = mas_prev(&mas, 0);
566e15e06a8SLiam R. Howlett 	index = mas.index;
567e15e06a8SLiam R. Howlett 	last = mas.last;
568e15e06a8SLiam R. Howlett 
569e15e06a8SLiam R. Howlett 	/* Erase the last entry. */
570e15e06a8SLiam R. Howlett 	mas_reset(&mas);
571e15e06a8SLiam R. Howlett 	mas.index = ULONG_MAX;
572e15e06a8SLiam R. Howlett 	mas.last = ULONG_MAX;
573e15e06a8SLiam R. Howlett 	mas_erase(&mas);
574e15e06a8SLiam R. Howlett 
575e15e06a8SLiam R. Howlett 	/* Get the previous value from MAS_START */
576e15e06a8SLiam R. Howlett 	mas_reset(&mas);
577e15e06a8SLiam R. Howlett 	entry2 = mas_prev(&mas, 0);
578e15e06a8SLiam R. Howlett 
579e15e06a8SLiam R. Howlett 	/* Check results. */
580e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != entry2);
581e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, index != mas.index);
582e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, last != mas.last);
583e15e06a8SLiam R. Howlett 
584e15e06a8SLiam R. Howlett 
585e15e06a8SLiam R. Howlett 	mas.node = MAS_NONE;
586e15e06a8SLiam R. Howlett 	mas.index = ULONG_MAX;
587e15e06a8SLiam R. Howlett 	mas.last = ULONG_MAX;
588e15e06a8SLiam R. Howlett 	entry2 = mas_prev(&mas, 0);
589e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != entry2);
590e15e06a8SLiam R. Howlett 
591e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
592e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_prev(&mas, 0) != NULL);
593e15e06a8SLiam R. Howlett 
594e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
595e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
596e15e06a8SLiam R. Howlett }
597e15e06a8SLiam R. Howlett 
check_find_2(struct maple_tree * mt)598eaf9790dSLiam R. Howlett static noinline void __init check_find_2(struct maple_tree *mt)
599e15e06a8SLiam R. Howlett {
600e15e06a8SLiam R. Howlett 	unsigned long i, j;
601e15e06a8SLiam R. Howlett 	void *entry;
602e15e06a8SLiam R. Howlett 
603e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
604e15e06a8SLiam R. Howlett 	rcu_read_lock();
605e15e06a8SLiam R. Howlett 	mas_for_each(&mas, entry, ULONG_MAX)
606e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, true);
607e15e06a8SLiam R. Howlett 	rcu_read_unlock();
608e15e06a8SLiam R. Howlett 
609e15e06a8SLiam R. Howlett 	for (i = 0; i < 256; i++) {
610e15e06a8SLiam R. Howlett 		mtree_insert_index(mt, i, GFP_KERNEL);
611e15e06a8SLiam R. Howlett 		j = 0;
612e15e06a8SLiam R. Howlett 		mas_set(&mas, 0);
613e15e06a8SLiam R. Howlett 		rcu_read_lock();
614e15e06a8SLiam R. Howlett 		mas_for_each(&mas, entry, ULONG_MAX) {
615e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
616e15e06a8SLiam R. Howlett 			j++;
617e15e06a8SLiam R. Howlett 		}
618e15e06a8SLiam R. Howlett 		rcu_read_unlock();
619e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, j != i + 1);
620e15e06a8SLiam R. Howlett 	}
621e15e06a8SLiam R. Howlett 
622e15e06a8SLiam R. Howlett 	for (i = 0; i < 256; i++) {
623e15e06a8SLiam R. Howlett 		mtree_erase_index(mt, i);
624e15e06a8SLiam R. Howlett 		j = i + 1;
625e15e06a8SLiam R. Howlett 		mas_set(&mas, 0);
626e15e06a8SLiam R. Howlett 		rcu_read_lock();
627e15e06a8SLiam R. Howlett 		mas_for_each(&mas, entry, ULONG_MAX) {
628e15e06a8SLiam R. Howlett 			if (xa_is_zero(entry))
629e15e06a8SLiam R. Howlett 				continue;
630e15e06a8SLiam R. Howlett 
631e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
632e15e06a8SLiam R. Howlett 			j++;
633e15e06a8SLiam R. Howlett 		}
634e15e06a8SLiam R. Howlett 		rcu_read_unlock();
635e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, j != 256);
636e15e06a8SLiam R. Howlett 	}
637e15e06a8SLiam R. Howlett 
638e15e06a8SLiam R. Howlett 	/*MT_BUG_ON(mt, !mtree_empty(mt)); */
639e15e06a8SLiam R. Howlett }
640e15e06a8SLiam R. Howlett 
641e15e06a8SLiam R. Howlett 
642120b1162SLiam Howlett #if defined(CONFIG_64BIT)
check_alloc_rev_range(struct maple_tree * mt)643eaf9790dSLiam R. Howlett static noinline void __init check_alloc_rev_range(struct maple_tree *mt)
644e15e06a8SLiam R. Howlett {
645e15e06a8SLiam R. Howlett 	/*
646e15e06a8SLiam R. Howlett 	 * Generated by:
647e15e06a8SLiam R. Howlett 	 * cat /proc/self/maps | awk '{print $1}'|
648e15e06a8SLiam R. Howlett 	 * awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}'
649e15e06a8SLiam R. Howlett 	 */
650e15e06a8SLiam R. Howlett 
651eaf9790dSLiam R. Howlett 	static const unsigned long range[] = {
652e15e06a8SLiam R. Howlett 	/*      Inclusive     , Exclusive. */
653e15e06a8SLiam R. Howlett 		0x565234af2000, 0x565234af4000,
654e15e06a8SLiam R. Howlett 		0x565234af4000, 0x565234af9000,
655e15e06a8SLiam R. Howlett 		0x565234af9000, 0x565234afb000,
656e15e06a8SLiam R. Howlett 		0x565234afc000, 0x565234afd000,
657e15e06a8SLiam R. Howlett 		0x565234afd000, 0x565234afe000,
658e15e06a8SLiam R. Howlett 		0x565235def000, 0x565235e10000,
659e15e06a8SLiam R. Howlett 		0x7f36d4bfd000, 0x7f36d4ee2000,
660e15e06a8SLiam R. Howlett 		0x7f36d4ee2000, 0x7f36d4f04000,
661e15e06a8SLiam R. Howlett 		0x7f36d4f04000, 0x7f36d504c000,
662e15e06a8SLiam R. Howlett 		0x7f36d504c000, 0x7f36d5098000,
663e15e06a8SLiam R. Howlett 		0x7f36d5098000, 0x7f36d5099000,
664e15e06a8SLiam R. Howlett 		0x7f36d5099000, 0x7f36d509d000,
665e15e06a8SLiam R. Howlett 		0x7f36d509d000, 0x7f36d509f000,
666e15e06a8SLiam R. Howlett 		0x7f36d509f000, 0x7f36d50a5000,
667e15e06a8SLiam R. Howlett 		0x7f36d50b9000, 0x7f36d50db000,
668e15e06a8SLiam R. Howlett 		0x7f36d50db000, 0x7f36d50dc000,
669e15e06a8SLiam R. Howlett 		0x7f36d50dc000, 0x7f36d50fa000,
670e15e06a8SLiam R. Howlett 		0x7f36d50fa000, 0x7f36d5102000,
671e15e06a8SLiam R. Howlett 		0x7f36d5102000, 0x7f36d5103000,
672e15e06a8SLiam R. Howlett 		0x7f36d5103000, 0x7f36d5104000,
673e15e06a8SLiam R. Howlett 		0x7f36d5104000, 0x7f36d5105000,
674e15e06a8SLiam R. Howlett 		0x7fff5876b000, 0x7fff5878d000,
675e15e06a8SLiam R. Howlett 		0x7fff5878e000, 0x7fff58791000,
676e15e06a8SLiam R. Howlett 		0x7fff58791000, 0x7fff58793000,
677e15e06a8SLiam R. Howlett 	};
678e15e06a8SLiam R. Howlett 
679eaf9790dSLiam R. Howlett 	static const unsigned long holes[] = {
680e15e06a8SLiam R. Howlett 		/*
681e15e06a8SLiam R. Howlett 		 * Note: start of hole is INCLUSIVE
682e15e06a8SLiam R. Howlett 		 *        end of hole is EXCLUSIVE
683e15e06a8SLiam R. Howlett 		 *        (opposite of the above table.)
684e15e06a8SLiam R. Howlett 		 * Start of hole, end of hole,  size of hole (+1)
685e15e06a8SLiam R. Howlett 		 */
686e15e06a8SLiam R. Howlett 		0x565234afb000, 0x565234afc000, 0x1000,
687e15e06a8SLiam R. Howlett 		0x565234afe000, 0x565235def000, 0x12F1000,
688e15e06a8SLiam R. Howlett 		0x565235e10000, 0x7f36d4bfd000, 0x28E49EDED000,
689e15e06a8SLiam R. Howlett 	};
690e15e06a8SLiam R. Howlett 
691e15e06a8SLiam R. Howlett 	/*
692e15e06a8SLiam R. Howlett 	 * req_range consists of 4 values.
693e15e06a8SLiam R. Howlett 	 * 1. min index
694e15e06a8SLiam R. Howlett 	 * 2. max index
695e15e06a8SLiam R. Howlett 	 * 3. size
696e15e06a8SLiam R. Howlett 	 * 4. number that should be returned.
697e15e06a8SLiam R. Howlett 	 * 5. return value
698e15e06a8SLiam R. Howlett 	 */
699eaf9790dSLiam R. Howlett 	static const unsigned long req_range[] = {
700e15e06a8SLiam R. Howlett 		0x565234af9000, /* Min */
701e15e06a8SLiam R. Howlett 		0x7fff58791000, /* Max */
702e15e06a8SLiam R. Howlett 		0x1000,         /* Size */
703e15e06a8SLiam R. Howlett 		0x7fff5878d << 12,  /* First rev hole of size 0x1000 */
704e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
705e15e06a8SLiam R. Howlett 
706e15e06a8SLiam R. Howlett 		0x0,            /* Min */
707ba997212SLiam R. Howlett 		0x565234AF0 << 12,    /* Max */
708e15e06a8SLiam R. Howlett 		0x3000,         /* Size */
709e15e06a8SLiam R. Howlett 		0x565234AEE << 12,  /* max - 3. */
710e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
711e15e06a8SLiam R. Howlett 
712e15e06a8SLiam R. Howlett 		0x0,            /* Min */
713e15e06a8SLiam R. Howlett 		-1,             /* Max */
714e15e06a8SLiam R. Howlett 		0x1000,         /* Size */
715e15e06a8SLiam R. Howlett 		562949953421311 << 12,/* First rev hole of size 0x1000 */
716e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
717e15e06a8SLiam R. Howlett 
718e15e06a8SLiam R. Howlett 		0x0,            /* Min */
719ba997212SLiam R. Howlett 		0x7F36D5109 << 12,    /* Max */
720e15e06a8SLiam R. Howlett 		0x4000,         /* Size */
721e15e06a8SLiam R. Howlett 		0x7F36D5106 << 12,    /* First rev hole of size 0x4000 */
722e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
723e15e06a8SLiam R. Howlett 
724e15e06a8SLiam R. Howlett 		/* Ascend test. */
725e15e06a8SLiam R. Howlett 		0x0,
726ba997212SLiam R. Howlett 		34148798628 << 12,
727e15e06a8SLiam R. Howlett 		19 << 12,
728e15e06a8SLiam R. Howlett 		34148797418 << 12,
729e15e06a8SLiam R. Howlett 		0x0,
730e15e06a8SLiam R. Howlett 
731e15e06a8SLiam R. Howlett 		/* Too big test. */
732e15e06a8SLiam R. Howlett 		0x0,
733e15e06a8SLiam R. Howlett 		18446744073709551615UL,
734e15e06a8SLiam R. Howlett 		562915594369134UL << 12,
735e15e06a8SLiam R. Howlett 		0x0,
736e15e06a8SLiam R. Howlett 		-EBUSY,
737e15e06a8SLiam R. Howlett 
738ba997212SLiam R. Howlett 		/* Single space test. */
739ba997212SLiam R. Howlett 		34148798725 << 12,
740ba997212SLiam R. Howlett 		34148798725 << 12,
741ba997212SLiam R. Howlett 		1 << 12,
742ba997212SLiam R. Howlett 		34148798725 << 12,
743ba997212SLiam R. Howlett 		0,
744e15e06a8SLiam R. Howlett 	};
745e15e06a8SLiam R. Howlett 
746e15e06a8SLiam R. Howlett 	int i, range_count = ARRAY_SIZE(range);
747e15e06a8SLiam R. Howlett 	int req_range_count = ARRAY_SIZE(req_range);
748e15e06a8SLiam R. Howlett 	unsigned long min = 0;
749e15e06a8SLiam R. Howlett 
750e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
751e15e06a8SLiam R. Howlett 
752e15e06a8SLiam R. Howlett 	mtree_store_range(mt, MTREE_ALLOC_MAX, ULONG_MAX, XA_ZERO_ENTRY,
753e15e06a8SLiam R. Howlett 			  GFP_KERNEL);
754e15e06a8SLiam R. Howlett #define DEBUG_REV_RANGE 0
755e15e06a8SLiam R. Howlett 	for (i = 0; i < range_count; i += 2) {
756e15e06a8SLiam R. Howlett 		/* Inclusive, Inclusive (with the -1) */
757e15e06a8SLiam R. Howlett 
758e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
759e15e06a8SLiam R. Howlett 		pr_debug("\t%s: Insert %lu-%lu\n", __func__, range[i] >> 12,
760e15e06a8SLiam R. Howlett 				(range[i + 1] >> 12) - 1);
761e15e06a8SLiam R. Howlett #endif
762e15e06a8SLiam R. Howlett 		check_insert_range(mt, range[i] >> 12, (range[i + 1] >> 12) - 1,
763e15e06a8SLiam R. Howlett 				xa_mk_value(range[i] >> 12), 0);
764e15e06a8SLiam R. Howlett 		mt_validate(mt);
765e15e06a8SLiam R. Howlett 	}
766e15e06a8SLiam R. Howlett 
767e15e06a8SLiam R. Howlett 
768120b1162SLiam Howlett 	mas_lock(&mas);
769e15e06a8SLiam R. Howlett 	for (i = 0; i < ARRAY_SIZE(holes); i += 3) {
770e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
771e15e06a8SLiam R. Howlett 		pr_debug("Search from %lu-%lu for gap %lu should be at %lu\n",
772e15e06a8SLiam R. Howlett 				min, holes[i+1]>>12, holes[i+2]>>12,
773e15e06a8SLiam R. Howlett 				holes[i] >> 12);
774e15e06a8SLiam R. Howlett #endif
775e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas_empty_area_rev(&mas, min,
776e15e06a8SLiam R. Howlett 					holes[i+1] >> 12,
777e15e06a8SLiam R. Howlett 					holes[i+2] >> 12));
778e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
779e15e06a8SLiam R. Howlett 		pr_debug("Found %lu %lu\n", mas.index, mas.last);
780e15e06a8SLiam R. Howlett 		pr_debug("gap %lu %lu\n", (holes[i] >> 12),
781e15e06a8SLiam R. Howlett 				(holes[i+1] >> 12));
782e15e06a8SLiam R. Howlett #endif
783e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas.last + 1 != (holes[i+1] >> 12));
784e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas.index != (holes[i+1] >> 12) - (holes[i+2] >> 12));
785e15e06a8SLiam R. Howlett 		min = holes[i+1] >> 12;
786e15e06a8SLiam R. Howlett 		mas_reset(&mas);
787e15e06a8SLiam R. Howlett 	}
788e15e06a8SLiam R. Howlett 
789120b1162SLiam Howlett 	mas_unlock(&mas);
790e15e06a8SLiam R. Howlett 	for (i = 0; i < req_range_count; i += 5) {
791e15e06a8SLiam R. Howlett #if DEBUG_REV_RANGE
792ba997212SLiam R. Howlett 		pr_debug("\tReverse request %d between %lu-%lu size %lu, should get %lu\n",
793ba997212SLiam R. Howlett 				i, req_range[i] >> 12,
794ba997212SLiam R. Howlett 				(req_range[i + 1] >> 12),
795e15e06a8SLiam R. Howlett 				req_range[i+2] >> 12,
796e15e06a8SLiam R. Howlett 				req_range[i+3] >> 12);
797e15e06a8SLiam R. Howlett #endif
798e15e06a8SLiam R. Howlett 		check_mtree_alloc_rrange(mt,
799e15e06a8SLiam R. Howlett 				req_range[i]   >> 12, /* start */
800e15e06a8SLiam R. Howlett 				req_range[i+1] >> 12, /* end */
801e15e06a8SLiam R. Howlett 				req_range[i+2] >> 12, /* size */
802e15e06a8SLiam R. Howlett 				req_range[i+3] >> 12, /* expected address */
803e15e06a8SLiam R. Howlett 				req_range[i+4],       /* expected return */
804e15e06a8SLiam R. Howlett 				xa_mk_value(req_range[i] >> 12)); /* pointer */
805e15e06a8SLiam R. Howlett 		mt_validate(mt);
806e15e06a8SLiam R. Howlett 	}
807e15e06a8SLiam R. Howlett 
808e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
809e15e06a8SLiam R. Howlett 	mtree_erase(mt, 34148798727); /* create a deleted range. */
810ba997212SLiam R. Howlett 	mtree_erase(mt, 34148798725);
811e15e06a8SLiam R. Howlett 	check_mtree_alloc_rrange(mt, 0, 34359052173, 210253414,
812e15e06a8SLiam R. Howlett 			34148798725, 0, mt);
813e15e06a8SLiam R. Howlett 
814e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
815e15e06a8SLiam R. Howlett }
816e15e06a8SLiam R. Howlett 
check_alloc_range(struct maple_tree * mt)817eaf9790dSLiam R. Howlett static noinline void __init check_alloc_range(struct maple_tree *mt)
818e15e06a8SLiam R. Howlett {
819e15e06a8SLiam R. Howlett 	/*
820e15e06a8SLiam R. Howlett 	 * Generated by:
821e15e06a8SLiam R. Howlett 	 * cat /proc/self/maps|awk '{print $1}'|
822e15e06a8SLiam R. Howlett 	 * awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}'
823e15e06a8SLiam R. Howlett 	 */
824e15e06a8SLiam R. Howlett 
825eaf9790dSLiam R. Howlett 	static const unsigned long range[] = {
826e15e06a8SLiam R. Howlett 	/*      Inclusive     , Exclusive. */
827e15e06a8SLiam R. Howlett 		0x565234af2000, 0x565234af4000,
828e15e06a8SLiam R. Howlett 		0x565234af4000, 0x565234af9000,
829e15e06a8SLiam R. Howlett 		0x565234af9000, 0x565234afb000,
830e15e06a8SLiam R. Howlett 		0x565234afc000, 0x565234afd000,
831e15e06a8SLiam R. Howlett 		0x565234afd000, 0x565234afe000,
832e15e06a8SLiam R. Howlett 		0x565235def000, 0x565235e10000,
833e15e06a8SLiam R. Howlett 		0x7f36d4bfd000, 0x7f36d4ee2000,
834e15e06a8SLiam R. Howlett 		0x7f36d4ee2000, 0x7f36d4f04000,
835e15e06a8SLiam R. Howlett 		0x7f36d4f04000, 0x7f36d504c000,
836e15e06a8SLiam R. Howlett 		0x7f36d504c000, 0x7f36d5098000,
837e15e06a8SLiam R. Howlett 		0x7f36d5098000, 0x7f36d5099000,
838e15e06a8SLiam R. Howlett 		0x7f36d5099000, 0x7f36d509d000,
839e15e06a8SLiam R. Howlett 		0x7f36d509d000, 0x7f36d509f000,
840e15e06a8SLiam R. Howlett 		0x7f36d509f000, 0x7f36d50a5000,
841e15e06a8SLiam R. Howlett 		0x7f36d50b9000, 0x7f36d50db000,
842e15e06a8SLiam R. Howlett 		0x7f36d50db000, 0x7f36d50dc000,
843e15e06a8SLiam R. Howlett 		0x7f36d50dc000, 0x7f36d50fa000,
844e15e06a8SLiam R. Howlett 		0x7f36d50fa000, 0x7f36d5102000,
845e15e06a8SLiam R. Howlett 		0x7f36d5102000, 0x7f36d5103000,
846e15e06a8SLiam R. Howlett 		0x7f36d5103000, 0x7f36d5104000,
847e15e06a8SLiam R. Howlett 		0x7f36d5104000, 0x7f36d5105000,
848e15e06a8SLiam R. Howlett 		0x7fff5876b000, 0x7fff5878d000,
849e15e06a8SLiam R. Howlett 		0x7fff5878e000, 0x7fff58791000,
850e15e06a8SLiam R. Howlett 		0x7fff58791000, 0x7fff58793000,
851e15e06a8SLiam R. Howlett 	};
852eaf9790dSLiam R. Howlett 	static const unsigned long holes[] = {
853e15e06a8SLiam R. Howlett 		/* Start of hole, end of hole,  size of hole (+1) */
854e15e06a8SLiam R. Howlett 		0x565234afb000, 0x565234afc000, 0x1000,
855e15e06a8SLiam R. Howlett 		0x565234afe000, 0x565235def000, 0x12F1000,
856e15e06a8SLiam R. Howlett 		0x565235e10000, 0x7f36d4bfd000, 0x28E49EDED000,
857e15e06a8SLiam R. Howlett 	};
858e15e06a8SLiam R. Howlett 
859e15e06a8SLiam R. Howlett 	/*
860e15e06a8SLiam R. Howlett 	 * req_range consists of 4 values.
861e15e06a8SLiam R. Howlett 	 * 1. min index
862e15e06a8SLiam R. Howlett 	 * 2. max index
863e15e06a8SLiam R. Howlett 	 * 3. size
864e15e06a8SLiam R. Howlett 	 * 4. number that should be returned.
865e15e06a8SLiam R. Howlett 	 * 5. return value
866e15e06a8SLiam R. Howlett 	 */
867eaf9790dSLiam R. Howlett 	static const unsigned long req_range[] = {
868e15e06a8SLiam R. Howlett 		0x565234af9000, /* Min */
869e15e06a8SLiam R. Howlett 		0x7fff58791000, /* Max */
870e15e06a8SLiam R. Howlett 		0x1000,         /* Size */
871e15e06a8SLiam R. Howlett 		0x565234afb000, /* First hole in our data of size 1000. */
872e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
873e15e06a8SLiam R. Howlett 
874e15e06a8SLiam R. Howlett 		0x0,            /* Min */
875e15e06a8SLiam R. Howlett 		0x7fff58791000, /* Max */
876e15e06a8SLiam R. Howlett 		0x1F00,         /* Size */
877e15e06a8SLiam R. Howlett 		0x0,            /* First hole in our data of size 2000. */
878e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
879e15e06a8SLiam R. Howlett 
880e15e06a8SLiam R. Howlett 		/* Test ascend. */
881e15e06a8SLiam R. Howlett 		34148797436 << 12, /* Min */
882e15e06a8SLiam R. Howlett 		0x7fff587AF000,    /* Max */
883e15e06a8SLiam R. Howlett 		0x3000,         /* Size */
884e15e06a8SLiam R. Howlett 		34148798629 << 12,             /* Expected location */
885e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
886e15e06a8SLiam R. Howlett 
887e15e06a8SLiam R. Howlett 		/* Test failing. */
888e15e06a8SLiam R. Howlett 		34148798623 << 12,  /* Min */
889e15e06a8SLiam R. Howlett 		34148798683 << 12,  /* Max */
890e15e06a8SLiam R. Howlett 		0x15000,            /* Size */
891e15e06a8SLiam R. Howlett 		0,             /* Expected location */
892e15e06a8SLiam R. Howlett 		-EBUSY,              /* Return value failed. */
893e15e06a8SLiam R. Howlett 
894e15e06a8SLiam R. Howlett 		/* Test filling entire gap. */
895e15e06a8SLiam R. Howlett 		34148798623 << 12,  /* Min */
896e15e06a8SLiam R. Howlett 		0x7fff587AF000,    /* Max */
897e15e06a8SLiam R. Howlett 		0x10000,           /* Size */
898e15e06a8SLiam R. Howlett 		34148798632 << 12,             /* Expected location */
899e15e06a8SLiam R. Howlett 		0,              /* Return value success. */
900e15e06a8SLiam R. Howlett 
901e15e06a8SLiam R. Howlett 		/* Test walking off the end of root. */
902e15e06a8SLiam R. Howlett 		0,                  /* Min */
903e15e06a8SLiam R. Howlett 		-1,                 /* Max */
904e15e06a8SLiam R. Howlett 		-1,                 /* Size */
905e15e06a8SLiam R. Howlett 		0,                  /* Expected location */
906e15e06a8SLiam R. Howlett 		-EBUSY,             /* Return value failure. */
907e15e06a8SLiam R. Howlett 
908e15e06a8SLiam R. Howlett 		/* Test looking for too large a hole across entire range. */
909e15e06a8SLiam R. Howlett 		0,                  /* Min */
910e15e06a8SLiam R. Howlett 		-1,                 /* Max */
911e15e06a8SLiam R. Howlett 		4503599618982063UL << 12,  /* Size */
912e15e06a8SLiam R. Howlett 		34359052178 << 12,  /* Expected location */
913e15e06a8SLiam R. Howlett 		-EBUSY,             /* Return failure. */
914ba997212SLiam R. Howlett 
915ba997212SLiam R. Howlett 		/* Test a single entry */
916ba997212SLiam R. Howlett 		34148798648 << 12,		/* Min */
917ba997212SLiam R. Howlett 		34148798648 << 12,		/* Max */
918ba997212SLiam R. Howlett 		4096,			/* Size of 1 */
919ba997212SLiam R. Howlett 		34148798648 << 12,	/* Location is the same as min/max */
920ba997212SLiam R. Howlett 		0,			/* Success */
921e15e06a8SLiam R. Howlett 	};
922e15e06a8SLiam R. Howlett 	int i, range_count = ARRAY_SIZE(range);
923e15e06a8SLiam R. Howlett 	int req_range_count = ARRAY_SIZE(req_range);
924e15e06a8SLiam R. Howlett 	unsigned long min = 0x565234af2000;
925120b1162SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
926e15e06a8SLiam R. Howlett 
927e15e06a8SLiam R. Howlett 	mtree_store_range(mt, MTREE_ALLOC_MAX, ULONG_MAX, XA_ZERO_ENTRY,
928e15e06a8SLiam R. Howlett 			  GFP_KERNEL);
929e15e06a8SLiam R. Howlett 	for (i = 0; i < range_count; i += 2) {
930e15e06a8SLiam R. Howlett #define DEBUG_ALLOC_RANGE 0
931e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
932e15e06a8SLiam R. Howlett 		pr_debug("\tInsert %lu-%lu\n", range[i] >> 12,
933e15e06a8SLiam R. Howlett 			 (range[i + 1] >> 12) - 1);
93489f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_hex);
935e15e06a8SLiam R. Howlett #endif
936e15e06a8SLiam R. Howlett 		check_insert_range(mt, range[i] >> 12, (range[i + 1] >> 12) - 1,
937e15e06a8SLiam R. Howlett 				xa_mk_value(range[i] >> 12), 0);
938e15e06a8SLiam R. Howlett 		mt_validate(mt);
939e15e06a8SLiam R. Howlett 	}
940e15e06a8SLiam R. Howlett 
941e15e06a8SLiam R. Howlett 
942e15e06a8SLiam R. Howlett 
943120b1162SLiam Howlett 	mas_lock(&mas);
944e15e06a8SLiam R. Howlett 	for (i = 0; i < ARRAY_SIZE(holes); i += 3) {
945e15e06a8SLiam R. Howlett 
946e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
947e15e06a8SLiam R. Howlett 		pr_debug("\tGet empty %lu-%lu size %lu (%lx-%lx)\n", min >> 12,
948e15e06a8SLiam R. Howlett 			holes[i+1] >> 12, holes[i+2] >> 12,
949e15e06a8SLiam R. Howlett 			min, holes[i+1]);
950e15e06a8SLiam R. Howlett #endif
951e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas_empty_area(&mas, min >> 12,
952e15e06a8SLiam R. Howlett 					holes[i+1] >> 12,
953e15e06a8SLiam R. Howlett 					holes[i+2] >> 12));
954e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mas.index != holes[i] >> 12);
955e15e06a8SLiam R. Howlett 		min = holes[i+1];
956e15e06a8SLiam R. Howlett 		mas_reset(&mas);
957e15e06a8SLiam R. Howlett 	}
958120b1162SLiam Howlett 	mas_unlock(&mas);
959e15e06a8SLiam R. Howlett 	for (i = 0; i < req_range_count; i += 5) {
960e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
961e15e06a8SLiam R. Howlett 		pr_debug("\tTest %d: %lu-%lu size %lu expected %lu (%lu-%lu)\n",
962e15e06a8SLiam R. Howlett 			 i/5, req_range[i]   >> 12, req_range[i + 1]   >> 12,
963e15e06a8SLiam R. Howlett 			 req_range[i + 2]   >> 12, req_range[i + 3]   >> 12,
964e15e06a8SLiam R. Howlett 			 req_range[i], req_range[i+1]);
965e15e06a8SLiam R. Howlett #endif
966e15e06a8SLiam R. Howlett 		check_mtree_alloc_range(mt,
967e15e06a8SLiam R. Howlett 				req_range[i]   >> 12, /* start */
968e15e06a8SLiam R. Howlett 				req_range[i+1] >> 12, /* end */
969e15e06a8SLiam R. Howlett 				req_range[i+2] >> 12, /* size */
970e15e06a8SLiam R. Howlett 				req_range[i+3] >> 12, /* expected address */
971e15e06a8SLiam R. Howlett 				req_range[i+4],       /* expected return */
972e15e06a8SLiam R. Howlett 				xa_mk_value(req_range[i] >> 12)); /* pointer */
973e15e06a8SLiam R. Howlett 		mt_validate(mt);
974e15e06a8SLiam R. Howlett #if DEBUG_ALLOC_RANGE
97589f499f3SLiam R. Howlett 		mt_dump(mt, mt_dump_hex);
976e15e06a8SLiam R. Howlett #endif
977e15e06a8SLiam R. Howlett 	}
978e15e06a8SLiam R. Howlett 
979e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
980e15e06a8SLiam R. Howlett }
981120b1162SLiam Howlett #endif
982e15e06a8SLiam R. Howlett 
check_ranges(struct maple_tree * mt)983eaf9790dSLiam R. Howlett static noinline void __init check_ranges(struct maple_tree *mt)
984e15e06a8SLiam R. Howlett {
985e15e06a8SLiam R. Howlett 	int i, val, val2;
986eaf9790dSLiam R. Howlett 	static const unsigned long r[] = {
987e15e06a8SLiam R. Howlett 		10, 15,
988e15e06a8SLiam R. Howlett 		20, 25,
989e15e06a8SLiam R. Howlett 		17, 22, /* Overlaps previous range. */
990e15e06a8SLiam R. Howlett 		9, 1000, /* Huge. */
991e15e06a8SLiam R. Howlett 		100, 200,
992e15e06a8SLiam R. Howlett 		45, 168,
993e15e06a8SLiam R. Howlett 		118, 128,
994e15e06a8SLiam R. Howlett 			};
995e15e06a8SLiam R. Howlett 
996e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
997e15e06a8SLiam R. Howlett 	check_insert_range(mt, r[0], r[1], xa_mk_value(r[0]), 0);
998e15e06a8SLiam R. Howlett 	check_insert_range(mt, r[2], r[3], xa_mk_value(r[2]), 0);
999e15e06a8SLiam R. Howlett 	check_insert_range(mt, r[4], r[5], xa_mk_value(r[4]), -EEXIST);
1000e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1001e15e06a8SLiam R. Howlett 	/* Store */
1002e15e06a8SLiam R. Howlett 	check_store_range(mt, r[4], r[5], xa_mk_value(r[4]), 0);
1003e15e06a8SLiam R. Howlett 	check_store_range(mt, r[6], r[7], xa_mk_value(r[6]), 0);
1004e15e06a8SLiam R. Howlett 	check_store_range(mt, r[8], r[9], xa_mk_value(r[8]), 0);
1005e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1006e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1007e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mt_height(mt));
1008e15e06a8SLiam R. Howlett 
1009e15e06a8SLiam R. Howlett 	check_seq(mt, 50, false);
1010e15e06a8SLiam R. Howlett 	mt_set_non_kernel(4);
1011e15e06a8SLiam R. Howlett 	check_store_range(mt, 5, 47,  xa_mk_value(47), 0);
1012e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1013e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1014e15e06a8SLiam R. Howlett 
1015e15e06a8SLiam R. Howlett 	/* Create tree of 1-100 */
1016e15e06a8SLiam R. Howlett 	check_seq(mt, 100, false);
1017e15e06a8SLiam R. Howlett 	/* Store 45-168 */
1018e15e06a8SLiam R. Howlett 	mt_set_non_kernel(10);
1019e15e06a8SLiam R. Howlett 	check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
1020e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1021e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1022e15e06a8SLiam R. Howlett 
1023e15e06a8SLiam R. Howlett 	/* Create tree of 1-200 */
1024e15e06a8SLiam R. Howlett 	check_seq(mt, 200, false);
1025e15e06a8SLiam R. Howlett 	/* Store 45-168 */
1026e15e06a8SLiam R. Howlett 	check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
1027e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1028e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1029e15e06a8SLiam R. Howlett 
1030e15e06a8SLiam R. Howlett 	check_seq(mt, 30, false);
1031e15e06a8SLiam R. Howlett 	check_store_range(mt, 6, 18, xa_mk_value(6), 0);
1032e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1033e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1034e15e06a8SLiam R. Howlett 
1035e15e06a8SLiam R. Howlett 	/* Overwrite across multiple levels. */
1036e15e06a8SLiam R. Howlett 	/* Create tree of 1-400 */
1037e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1038e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1039e15e06a8SLiam R. Howlett 	/* Store 118-128 */
1040e15e06a8SLiam R. Howlett 	check_store_range(mt, r[12], r[13], xa_mk_value(r[12]), 0);
1041e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1042e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 140);
1043e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 141);
1044e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 142);
1045e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 143);
1046e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 130);
1047e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 131);
1048e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 132);
1049e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 133);
1050e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 134);
1051e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 135);
1052e15e06a8SLiam R. Howlett 	check_load(mt, r[12], xa_mk_value(r[12]));
1053e15e06a8SLiam R. Howlett 	check_load(mt, r[13], xa_mk_value(r[12]));
1054e15e06a8SLiam R. Howlett 	check_load(mt, r[13] - 1, xa_mk_value(r[12]));
1055e15e06a8SLiam R. Howlett 	check_load(mt, r[13] + 1, xa_mk_value(r[13] + 1));
1056e15e06a8SLiam R. Howlett 	check_load(mt, 135, NULL);
1057e15e06a8SLiam R. Howlett 	check_load(mt, 140, NULL);
1058e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1059e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1060e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1061e15e06a8SLiam R. Howlett 
1062e15e06a8SLiam R. Howlett 
1063e15e06a8SLiam R. Howlett 
1064e15e06a8SLiam R. Howlett 	/* Overwrite multiple levels at the end of the tree (slot 7) */
1065e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1066e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1067e15e06a8SLiam R. Howlett 	check_store_range(mt, 353, 361, xa_mk_value(353), 0);
1068e15e06a8SLiam R. Howlett 	check_store_range(mt, 347, 352, xa_mk_value(347), 0);
1069e15e06a8SLiam R. Howlett 
1070e15e06a8SLiam R. Howlett 	check_load(mt, 346, xa_mk_value(346));
1071e15e06a8SLiam R. Howlett 	for (i = 347; i <= 352; i++)
1072e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(347));
1073e15e06a8SLiam R. Howlett 	for (i = 353; i <= 361; i++)
1074e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(353));
1075e15e06a8SLiam R. Howlett 	check_load(mt, 362, xa_mk_value(362));
1076e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1077e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1078e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1079e15e06a8SLiam R. Howlett 
1080e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1081e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1082e15e06a8SLiam R. Howlett 	check_store_range(mt, 352, 364, NULL, 0);
1083e15e06a8SLiam R. Howlett 	check_store_range(mt, 351, 363, xa_mk_value(352), 0);
1084e15e06a8SLiam R. Howlett 	check_load(mt, 350, xa_mk_value(350));
1085e15e06a8SLiam R. Howlett 	check_load(mt, 351, xa_mk_value(352));
1086e15e06a8SLiam R. Howlett 	for (i = 352; i <= 363; i++)
1087e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(352));
1088e15e06a8SLiam R. Howlett 	check_load(mt, 364, NULL);
1089e15e06a8SLiam R. Howlett 	check_load(mt, 365, xa_mk_value(365));
1090e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1091e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1092e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1093e15e06a8SLiam R. Howlett 
1094e15e06a8SLiam R. Howlett 	mt_set_non_kernel(5);
1095e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1096e15e06a8SLiam R. Howlett 	check_store_range(mt, 352, 364, NULL, 0);
1097e15e06a8SLiam R. Howlett 	check_store_range(mt, 351, 364, xa_mk_value(352), 0);
1098e15e06a8SLiam R. Howlett 	check_load(mt, 350, xa_mk_value(350));
1099e15e06a8SLiam R. Howlett 	check_load(mt, 351, xa_mk_value(352));
1100e15e06a8SLiam R. Howlett 	for (i = 352; i <= 364; i++)
1101e15e06a8SLiam R. Howlett 		check_load(mt, i, xa_mk_value(352));
1102e15e06a8SLiam R. Howlett 	check_load(mt, 365, xa_mk_value(365));
1103e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1104e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1105e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1106e15e06a8SLiam R. Howlett 
1107e15e06a8SLiam R. Howlett 
1108e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1109e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1110e15e06a8SLiam R. Howlett 	check_store_range(mt, 362, 367, xa_mk_value(362), 0);
1111e15e06a8SLiam R. Howlett 	check_store_range(mt, 353, 361, xa_mk_value(353), 0);
1112e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1113e15e06a8SLiam R. Howlett 	mt_validate(mt);
1114e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1115e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1116e15e06a8SLiam R. Howlett 	/*
1117e15e06a8SLiam R. Howlett 	 * Interesting cases:
1118e15e06a8SLiam R. Howlett 	 * 1. Overwrite the end of a node and end in the first entry of the next
1119e15e06a8SLiam R. Howlett 	 * node.
1120e15e06a8SLiam R. Howlett 	 * 2. Split a single range
1121e15e06a8SLiam R. Howlett 	 * 3. Overwrite the start of a range
1122e15e06a8SLiam R. Howlett 	 * 4. Overwrite the end of a range
1123e15e06a8SLiam R. Howlett 	 * 5. Overwrite the entire range
1124e15e06a8SLiam R. Howlett 	 * 6. Overwrite a range that causes multiple parent nodes to be
1125e15e06a8SLiam R. Howlett 	 * combined
1126e15e06a8SLiam R. Howlett 	 * 7. Overwrite a range that causes multiple parent nodes and part of
1127e15e06a8SLiam R. Howlett 	 * root to be combined
1128e15e06a8SLiam R. Howlett 	 * 8. Overwrite the whole tree
1129e15e06a8SLiam R. Howlett 	 * 9. Try to overwrite the zero entry of an alloc tree.
1130e15e06a8SLiam R. Howlett 	 * 10. Write a range larger than a nodes current pivot
1131e15e06a8SLiam R. Howlett 	 */
1132e15e06a8SLiam R. Howlett 
1133e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1134e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1135e15e06a8SLiam R. Howlett 		val = i*5;
1136e15e06a8SLiam R. Howlett 		val2 = (i+1)*5;
1137e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1138e15e06a8SLiam R. Howlett 	}
1139e15e06a8SLiam R. Howlett 	check_store_range(mt, 2400, 2400, xa_mk_value(2400), 0);
1140e15e06a8SLiam R. Howlett 	check_store_range(mt, 2411, 2411, xa_mk_value(2411), 0);
1141e15e06a8SLiam R. Howlett 	check_store_range(mt, 2412, 2412, xa_mk_value(2412), 0);
1142e15e06a8SLiam R. Howlett 	check_store_range(mt, 2396, 2400, xa_mk_value(4052020), 0);
1143e15e06a8SLiam R. Howlett 	check_store_range(mt, 2402, 2402, xa_mk_value(2402), 0);
1144e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1145e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1146e15e06a8SLiam R. Howlett 
1147e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1148e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1149e15e06a8SLiam R. Howlett 		val = i*5;
1150e15e06a8SLiam R. Howlett 		val2 = (i+1)*5;
1151e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1152e15e06a8SLiam R. Howlett 	}
1153e15e06a8SLiam R. Howlett 	check_store_range(mt, 2422, 2422, xa_mk_value(2422), 0);
1154e15e06a8SLiam R. Howlett 	check_store_range(mt, 2424, 2424, xa_mk_value(2424), 0);
1155e15e06a8SLiam R. Howlett 	check_store_range(mt, 2425, 2425, xa_mk_value(2), 0);
1156e15e06a8SLiam R. Howlett 	check_store_range(mt, 2460, 2470, NULL, 0);
1157e15e06a8SLiam R. Howlett 	check_store_range(mt, 2435, 2460, xa_mk_value(2435), 0);
1158e15e06a8SLiam R. Howlett 	check_store_range(mt, 2461, 2470, xa_mk_value(2461), 0);
1159e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1160e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1161e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1162e15e06a8SLiam R. Howlett 
1163d6e8d0dcSPeng Zhang 	/* Check in-place modifications */
1164d6e8d0dcSPeng Zhang 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1165d6e8d0dcSPeng Zhang 	/* Append to the start of last range */
1166d6e8d0dcSPeng Zhang 	mt_set_non_kernel(50);
1167d6e8d0dcSPeng Zhang 	for (i = 0; i <= 500; i++) {
1168d6e8d0dcSPeng Zhang 		val = i * 5 + 1;
1169d6e8d0dcSPeng Zhang 		val2 = val + 4;
1170d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1171d6e8d0dcSPeng Zhang 	}
1172d6e8d0dcSPeng Zhang 
1173d6e8d0dcSPeng Zhang 	/* Append to the last range without touching any boundaries */
1174d6e8d0dcSPeng Zhang 	for (i = 0; i < 10; i++) {
1175d6e8d0dcSPeng Zhang 		val = val2 + 5;
1176d6e8d0dcSPeng Zhang 		val2 = val + 4;
1177d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1178d6e8d0dcSPeng Zhang 	}
1179d6e8d0dcSPeng Zhang 
1180d6e8d0dcSPeng Zhang 	/* Append to the end of last range */
1181d6e8d0dcSPeng Zhang 	val = val2;
1182d6e8d0dcSPeng Zhang 	for (i = 0; i < 10; i++) {
1183d6e8d0dcSPeng Zhang 		val += 5;
1184d6e8d0dcSPeng Zhang 		MT_BUG_ON(mt, mtree_test_store_range(mt, val, ULONG_MAX,
1185d6e8d0dcSPeng Zhang 						     xa_mk_value(val)) != 0);
1186d6e8d0dcSPeng Zhang 	}
1187d6e8d0dcSPeng Zhang 
1188d6e8d0dcSPeng Zhang 	/* Overwriting the range and over a part of the next range */
1189d6e8d0dcSPeng Zhang 	for (i = 10; i < 30; i += 2) {
1190d6e8d0dcSPeng Zhang 		val = i * 5 + 1;
1191d6e8d0dcSPeng Zhang 		val2 = val + 5;
1192d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1193d6e8d0dcSPeng Zhang 	}
1194d6e8d0dcSPeng Zhang 
1195d6e8d0dcSPeng Zhang 	/* Overwriting a part of the range and over the next range */
1196d6e8d0dcSPeng Zhang 	for (i = 50; i < 70; i += 2) {
1197d6e8d0dcSPeng Zhang 		val2 = i * 5;
1198d6e8d0dcSPeng Zhang 		val = val2 - 5;
1199d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1200d6e8d0dcSPeng Zhang 	}
1201d6e8d0dcSPeng Zhang 
1202d6e8d0dcSPeng Zhang 	/*
1203d6e8d0dcSPeng Zhang 	 * Expand the range, only partially overwriting the previous and
1204d6e8d0dcSPeng Zhang 	 * next ranges
1205d6e8d0dcSPeng Zhang 	 */
1206d6e8d0dcSPeng Zhang 	for (i = 100; i < 130; i += 3) {
1207d6e8d0dcSPeng Zhang 		val = i * 5 - 5;
1208d6e8d0dcSPeng Zhang 		val2 = i * 5 + 1;
1209d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1210d6e8d0dcSPeng Zhang 	}
1211d6e8d0dcSPeng Zhang 
1212d6e8d0dcSPeng Zhang 	/*
1213d6e8d0dcSPeng Zhang 	 * Expand the range, only partially overwriting the previous and
1214d6e8d0dcSPeng Zhang 	 * next ranges, in RCU mode
1215d6e8d0dcSPeng Zhang 	 */
1216d6e8d0dcSPeng Zhang 	mt_set_in_rcu(mt);
1217d6e8d0dcSPeng Zhang 	for (i = 150; i < 180; i += 3) {
1218d6e8d0dcSPeng Zhang 		val = i * 5 - 5;
1219d6e8d0dcSPeng Zhang 		val2 = i * 5 + 1;
1220d6e8d0dcSPeng Zhang 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1221d6e8d0dcSPeng Zhang 	}
1222d6e8d0dcSPeng Zhang 
1223d6e8d0dcSPeng Zhang 	MT_BUG_ON(mt, !mt_height(mt));
1224d6e8d0dcSPeng Zhang 	mt_validate(mt);
1225d6e8d0dcSPeng Zhang 	mt_set_non_kernel(0);
1226d6e8d0dcSPeng Zhang 	mtree_destroy(mt);
1227d6e8d0dcSPeng Zhang 
1228e15e06a8SLiam R. Howlett 	/* Test rebalance gaps */
1229e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1230e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1231e15e06a8SLiam R. Howlett 	for (i = 0; i <= 50; i++) {
1232e15e06a8SLiam R. Howlett 		val = i*10;
1233e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1234e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1235e15e06a8SLiam R. Howlett 	}
1236e15e06a8SLiam R. Howlett 	check_store_range(mt, 161, 161, xa_mk_value(161), 0);
1237e15e06a8SLiam R. Howlett 	check_store_range(mt, 162, 162, xa_mk_value(162), 0);
1238e15e06a8SLiam R. Howlett 	check_store_range(mt, 163, 163, xa_mk_value(163), 0);
1239e15e06a8SLiam R. Howlett 	check_store_range(mt, 240, 249, NULL, 0);
1240e15e06a8SLiam R. Howlett 	mtree_erase(mt, 200);
1241e15e06a8SLiam R. Howlett 	mtree_erase(mt, 210);
1242e15e06a8SLiam R. Howlett 	mtree_erase(mt, 220);
1243e15e06a8SLiam R. Howlett 	mtree_erase(mt, 230);
1244e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1245e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1246e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1247e15e06a8SLiam R. Howlett 
1248e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1249e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1250e15e06a8SLiam R. Howlett 		val = i*10;
1251e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1252e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1253e15e06a8SLiam R. Howlett 	}
1254e15e06a8SLiam R. Howlett 	check_store_range(mt, 4600, 4959, xa_mk_value(1), 0);
1255e15e06a8SLiam R. Howlett 	mt_validate(mt);
1256e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1257e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1258e15e06a8SLiam R. Howlett 
1259e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1260e15e06a8SLiam R. Howlett 	for (i = 0; i <= 500; i++) {
1261e15e06a8SLiam R. Howlett 		val = i*10;
1262e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1263e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1264e15e06a8SLiam R. Howlett 	}
1265e15e06a8SLiam R. Howlett 	check_store_range(mt, 4811, 4811, xa_mk_value(4811), 0);
1266e15e06a8SLiam R. Howlett 	check_store_range(mt, 4812, 4812, xa_mk_value(4812), 0);
1267e15e06a8SLiam R. Howlett 	check_store_range(mt, 4861, 4861, xa_mk_value(4861), 0);
1268e15e06a8SLiam R. Howlett 	check_store_range(mt, 4862, 4862, xa_mk_value(4862), 0);
1269e15e06a8SLiam R. Howlett 	check_store_range(mt, 4842, 4849, NULL, 0);
1270e15e06a8SLiam R. Howlett 	mt_validate(mt);
1271e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mt_height(mt));
1272e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1273e15e06a8SLiam R. Howlett 
1274e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1275e15e06a8SLiam R. Howlett 	for (i = 0; i <= 1300; i++) {
1276e15e06a8SLiam R. Howlett 		val = i*10;
1277e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1278e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1279e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) >= 4);
1280e15e06a8SLiam R. Howlett 	}
1281e15e06a8SLiam R. Howlett 	/*  Cause a 3 child split all the way up the tree. */
1282e15e06a8SLiam R. Howlett 	for (i = 5; i < 215; i += 10)
1283e15e06a8SLiam R. Howlett 		check_store_range(mt, 11450 + i, 11450 + i + 1, NULL, 0);
1284e15e06a8SLiam R. Howlett 	for (i = 5; i < 65; i += 10)
1285e15e06a8SLiam R. Howlett 		check_store_range(mt, 11770 + i, 11770 + i + 1, NULL, 0);
1286e15e06a8SLiam R. Howlett 
1287e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mt_height(mt) >= 4);
1288e15e06a8SLiam R. Howlett 	for (i = 5; i < 45; i += 10)
1289e15e06a8SLiam R. Howlett 		check_store_range(mt, 11700 + i, 11700 + i + 1, NULL, 0);
1290120b1162SLiam Howlett 	if (!MAPLE_32BIT)
1291e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) < 4);
1292e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1293e15e06a8SLiam R. Howlett 
1294e15e06a8SLiam R. Howlett 
1295e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1296e15e06a8SLiam R. Howlett 	for (i = 0; i <= 1200; i++) {
1297e15e06a8SLiam R. Howlett 		val = i*10;
1298e15e06a8SLiam R. Howlett 		val2 = (i+1)*10;
1299e15e06a8SLiam R. Howlett 		check_store_range(mt, val, val2, xa_mk_value(val), 0);
1300e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) >= 4);
1301e15e06a8SLiam R. Howlett 	}
1302e15e06a8SLiam R. Howlett 	/* Fill parents and leaves before split. */
1303e15e06a8SLiam R. Howlett 	for (i = 5; i < 455; i += 10)
1304e15e06a8SLiam R. Howlett 		check_store_range(mt, 7800 + i, 7800 + i + 1, NULL, 0);
1305e15e06a8SLiam R. Howlett 
1306e15e06a8SLiam R. Howlett 	for (i = 1; i < 16; i++)
1307e15e06a8SLiam R. Howlett 		check_store_range(mt, 8185 + i, 8185 + i + 1,
1308e15e06a8SLiam R. Howlett 				  xa_mk_value(8185+i), 0);
1309e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mt_height(mt) >= 4);
1310e15e06a8SLiam R. Howlett 	/* triple split across multiple levels. */
1311e15e06a8SLiam R. Howlett 	check_store_range(mt, 8184, 8184, xa_mk_value(8184), 0);
1312120b1162SLiam Howlett 	if (!MAPLE_32BIT)
1313e15e06a8SLiam R. Howlett 		MT_BUG_ON(mt, mt_height(mt) != 4);
1314e15e06a8SLiam R. Howlett }
1315e15e06a8SLiam R. Howlett 
check_next_entry(struct maple_tree * mt)1316eaf9790dSLiam R. Howlett static noinline void __init check_next_entry(struct maple_tree *mt)
1317e15e06a8SLiam R. Howlett {
1318e15e06a8SLiam R. Howlett 	void *entry = NULL;
1319e15e06a8SLiam R. Howlett 	unsigned long limit = 30, i = 0;
1320120b1162SLiam Howlett 	MA_STATE(mas, mt, i, i);
1321e15e06a8SLiam R. Howlett 
1322e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
1323e15e06a8SLiam R. Howlett 
1324e15e06a8SLiam R. Howlett 	check_seq(mt, limit, false);
1325e15e06a8SLiam R. Howlett 	rcu_read_lock();
1326e15e06a8SLiam R. Howlett 
1327e15e06a8SLiam R. Howlett 	/* Check the first one and get ma_state in the correct state. */
1328e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_walk(&mas) != xa_mk_value(i++));
1329e15e06a8SLiam R. Howlett 	for ( ; i <= limit + 1; i++) {
1330e15e06a8SLiam R. Howlett 		entry = mas_next(&mas, limit);
1331e15e06a8SLiam R. Howlett 		if (i > limit)
1332e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != NULL);
1333e15e06a8SLiam R. Howlett 		else
1334e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, xa_mk_value(i) != entry);
1335e15e06a8SLiam R. Howlett 	}
1336e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1337e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1338e15e06a8SLiam R. Howlett }
1339e15e06a8SLiam R. Howlett 
check_prev_entry(struct maple_tree * mt)1340eaf9790dSLiam R. Howlett static noinline void __init check_prev_entry(struct maple_tree *mt)
1341e15e06a8SLiam R. Howlett {
1342e15e06a8SLiam R. Howlett 	unsigned long index = 16;
1343e15e06a8SLiam R. Howlett 	void *value;
1344e15e06a8SLiam R. Howlett 	int i;
1345e15e06a8SLiam R. Howlett 
1346e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, index, index);
1347e15e06a8SLiam R. Howlett 
1348e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
1349e15e06a8SLiam R. Howlett 	check_seq(mt, 30, false);
1350e15e06a8SLiam R. Howlett 
1351e15e06a8SLiam R. Howlett 	rcu_read_lock();
1352e15e06a8SLiam R. Howlett 	value = mas_find(&mas, ULONG_MAX);
1353e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(index));
1354e15e06a8SLiam R. Howlett 	value = mas_prev(&mas, 0);
1355e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(index - 1));
1356e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1357e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1358e15e06a8SLiam R. Howlett 
1359e15e06a8SLiam R. Howlett 	/* Check limits on prev */
1360e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1361e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1362e15e06a8SLiam R. Howlett 	for (i = 0; i <= index; i++) {
1363e15e06a8SLiam R. Howlett 		mas_set_range(&mas, i*10, i*10+5);
1364e15e06a8SLiam R. Howlett 		mas_store_gfp(&mas, xa_mk_value(i), GFP_KERNEL);
1365e15e06a8SLiam R. Howlett 	}
1366e15e06a8SLiam R. Howlett 
1367e15e06a8SLiam R. Howlett 	mas_set(&mas, 20);
1368e15e06a8SLiam R. Howlett 	value = mas_walk(&mas);
1369e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(2));
1370e15e06a8SLiam R. Howlett 
1371e15e06a8SLiam R. Howlett 	value = mas_prev(&mas, 19);
1372e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != NULL);
1373e15e06a8SLiam R. Howlett 
1374e15e06a8SLiam R. Howlett 	mas_set(&mas, 80);
1375e15e06a8SLiam R. Howlett 	value = mas_walk(&mas);
1376e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != xa_mk_value(8));
1377e15e06a8SLiam R. Howlett 
1378e15e06a8SLiam R. Howlett 	value = mas_prev(&mas, 76);
1379e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, value != NULL);
1380e15e06a8SLiam R. Howlett 
1381e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1382e15e06a8SLiam R. Howlett }
1383e15e06a8SLiam R. Howlett 
check_root_expand(struct maple_tree * mt)1384eaf9790dSLiam R. Howlett static noinline void __init check_root_expand(struct maple_tree *mt)
1385e15e06a8SLiam R. Howlett {
1386e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1387e15e06a8SLiam R. Howlett 	void *ptr;
1388e15e06a8SLiam R. Howlett 
1389e15e06a8SLiam R. Howlett 
1390e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1391e15e06a8SLiam R. Howlett 	mas_set(&mas, 3);
1392e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1393eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
1394e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1395e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
1396e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
1397e15e06a8SLiam R. Howlett 
1398e15e06a8SLiam R. Howlett 	ptr = &check_prev_entry;
1399e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1400e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1401e15e06a8SLiam R. Howlett 
1402e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1403e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1404e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1405e15e06a8SLiam R. Howlett 
1406e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1407e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1408e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != &check_prev_entry);
1409e15e06a8SLiam R. Howlett 
1410e15e06a8SLiam R. Howlett 	mas_set(&mas, 2);
1411e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1412e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1413e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1414e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1415e15e06a8SLiam R. Howlett 
1416e15e06a8SLiam R. Howlett 
1417e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
1418e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1419e15e06a8SLiam R. Howlett 
1420e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1421e15e06a8SLiam R. Howlett 	ptr = &check_prev_entry;
1422e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1423e15e06a8SLiam R. Howlett 
1424e15e06a8SLiam R. Howlett 	mas_set(&mas, 5);
1425e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1426e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1427e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
1428e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
1429e15e06a8SLiam R. Howlett 
1430e15e06a8SLiam R. Howlett 	mas_set_range(&mas, 0, 100);
1431e15e06a8SLiam R. Howlett 	ptr = mas_walk(&mas);
1432e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != &check_prev_entry);
1433e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
1434e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1435e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1436e15e06a8SLiam R. Howlett 
1437e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
1438e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1439e15e06a8SLiam R. Howlett 
1440e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1441e15e06a8SLiam R. Howlett 	ptr = (void *)((unsigned long) check_prev_entry | 1UL);
1442e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1443e15e06a8SLiam R. Howlett 	ptr = mas_next(&mas, ULONG_MAX);
1444e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1445e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != 1) && (mas.last != ULONG_MAX));
1446e15e06a8SLiam R. Howlett 
1447e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1448e15e06a8SLiam R. Howlett 	ptr = mas_prev(&mas, 0);
1449e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != 0) && (mas.last != 0));
1450e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != (void *)((unsigned long) check_prev_entry | 1UL));
1451e15e06a8SLiam R. Howlett 
1452e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1453e15e06a8SLiam R. Howlett 
1454e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1455e15e06a8SLiam R. Howlett 
1456e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
1457e15e06a8SLiam R. Howlett 	mas_lock(&mas);
1458e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1459e15e06a8SLiam R. Howlett 	ptr = (void *)((unsigned long) check_prev_entry | 2UL);
1460e15e06a8SLiam R. Howlett 	mas_store_gfp(&mas, ptr, GFP_KERNEL);
1461e15e06a8SLiam R. Howlett 	ptr = mas_next(&mas, ULONG_MAX);
1462e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != NULL);
1463eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != ULONG_MAX) && (mas.last != ULONG_MAX));
1464e15e06a8SLiam R. Howlett 
1465e15e06a8SLiam R. Howlett 	mas_set(&mas, 1);
1466e15e06a8SLiam R. Howlett 	ptr = mas_prev(&mas, 0);
1467e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, (mas.index != 0) && (mas.last != 0));
1468e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ptr != (void *)((unsigned long) check_prev_entry | 2UL));
1469e15e06a8SLiam R. Howlett 
1470e15e06a8SLiam R. Howlett 
1471e15e06a8SLiam R. Howlett 	mas_unlock(&mas);
1472e15e06a8SLiam R. Howlett }
1473e15e06a8SLiam R. Howlett 
check_gap_combining(struct maple_tree * mt)1474eaf9790dSLiam R. Howlett static noinline void __init check_gap_combining(struct maple_tree *mt)
1475e15e06a8SLiam R. Howlett {
1476e15e06a8SLiam R. Howlett 	struct maple_enode *mn1, *mn2;
1477e15e06a8SLiam R. Howlett 	void *entry;
1478120b1162SLiam Howlett 	unsigned long singletons = 100;
1479eaf9790dSLiam R. Howlett 	static const unsigned long *seq100;
1480eaf9790dSLiam R. Howlett 	static const unsigned long seq100_64[] = {
1481e15e06a8SLiam R. Howlett 		/* 0-5 */
1482e15e06a8SLiam R. Howlett 		74, 75, 76,
1483e15e06a8SLiam R. Howlett 		50, 100, 2,
1484e15e06a8SLiam R. Howlett 
1485e15e06a8SLiam R. Howlett 		/* 6-12 */
1486e15e06a8SLiam R. Howlett 		44, 45, 46, 43,
1487e15e06a8SLiam R. Howlett 		20, 50, 3,
1488e15e06a8SLiam R. Howlett 
1489e15e06a8SLiam R. Howlett 		/* 13-20*/
1490e15e06a8SLiam R. Howlett 		80, 81, 82,
1491e15e06a8SLiam R. Howlett 		76, 2, 79, 85, 4,
1492e15e06a8SLiam R. Howlett 	};
1493120b1162SLiam Howlett 
1494eaf9790dSLiam R. Howlett 	static const unsigned long seq100_32[] = {
1495120b1162SLiam Howlett 		/* 0-5 */
1496120b1162SLiam Howlett 		61, 62, 63,
1497120b1162SLiam Howlett 		50, 100, 2,
1498120b1162SLiam Howlett 
1499120b1162SLiam Howlett 		/* 6-12 */
1500120b1162SLiam Howlett 		31, 32, 33, 30,
1501120b1162SLiam Howlett 		20, 50, 3,
1502120b1162SLiam Howlett 
1503120b1162SLiam Howlett 		/* 13-20*/
1504120b1162SLiam Howlett 		80, 81, 82,
1505120b1162SLiam Howlett 		76, 2, 79, 85, 4,
1506120b1162SLiam Howlett 	};
1507120b1162SLiam Howlett 
1508eaf9790dSLiam R. Howlett 	static const unsigned long seq2000[] = {
1509e15e06a8SLiam R. Howlett 		1152, 1151,
1510e15e06a8SLiam R. Howlett 		1100, 1200, 2,
1511e15e06a8SLiam R. Howlett 	};
1512eaf9790dSLiam R. Howlett 	static const unsigned long seq400[] = {
1513e15e06a8SLiam R. Howlett 		286, 318,
1514e15e06a8SLiam R. Howlett 		256, 260, 266, 270, 275, 280, 290, 398,
1515e15e06a8SLiam R. Howlett 		286, 310,
1516e15e06a8SLiam R. Howlett 	};
1517e15e06a8SLiam R. Howlett 
1518120b1162SLiam Howlett 	unsigned long index;
1519e15e06a8SLiam R. Howlett 
1520120b1162SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
1521e15e06a8SLiam R. Howlett 
1522120b1162SLiam Howlett 	if (MAPLE_32BIT)
1523120b1162SLiam Howlett 		seq100 = seq100_32;
1524120b1162SLiam Howlett 	else
1525120b1162SLiam Howlett 		seq100 = seq100_64;
1526120b1162SLiam Howlett 
1527120b1162SLiam Howlett 	index = seq100[0];
1528120b1162SLiam Howlett 	mas_set(&mas, index);
1529e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, !mtree_empty(mt));
1530120b1162SLiam Howlett 	check_seq(mt, singletons, false); /* create 100 singletons. */
1531e15e06a8SLiam R. Howlett 
1532e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1533e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[2]);
1534e15e06a8SLiam R. Howlett 	check_load(mt, seq100[2], NULL);
1535e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[1]);
1536e15e06a8SLiam R. Howlett 	check_load(mt, seq100[1], NULL);
1537e15e06a8SLiam R. Howlett 
1538e15e06a8SLiam R. Howlett 	rcu_read_lock();
1539e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
1540e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index));
1541e15e06a8SLiam R. Howlett 	mn1 = mas.node;
1542e15e06a8SLiam R. Howlett 	mas_next(&mas, ULONG_MAX);
1543e15e06a8SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
1544e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index + 4));
1545e15e06a8SLiam R. Howlett 	mn2 = mas.node;
1546e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mn1 == mn2); /* test the test. */
1547e15e06a8SLiam R. Howlett 
1548e15e06a8SLiam R. Howlett 	/*
1549e15e06a8SLiam R. Howlett 	 * At this point, there is a gap of 2 at index + 1 between seq100[3] and
1550e15e06a8SLiam R. Howlett 	 * seq100[4]. Search for the gap.
1551e15e06a8SLiam R. Howlett 	 */
1552e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1553e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1554e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[3], seq100[4],
1555e15e06a8SLiam R. Howlett 					     seq100[5]));
1556e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != index + 1);
1557e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1558e15e06a8SLiam R. Howlett 
1559e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[6]);
1560e15e06a8SLiam R. Howlett 	check_load(mt, seq100[6], NULL);
1561e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[7]);
1562e15e06a8SLiam R. Howlett 	check_load(mt, seq100[7], NULL);
1563e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[8]);
1564e15e06a8SLiam R. Howlett 	index = seq100[9];
1565e15e06a8SLiam R. Howlett 
1566e15e06a8SLiam R. Howlett 	rcu_read_lock();
1567e15e06a8SLiam R. Howlett 	mas.index = index;
1568e15e06a8SLiam R. Howlett 	mas.last = index;
1569e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1570e15e06a8SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
1571e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index));
1572e15e06a8SLiam R. Howlett 	mn1 = mas.node;
1573e15e06a8SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
1574e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, entry != xa_mk_value(index + 4));
1575e15e06a8SLiam R. Howlett 	mas_next(&mas, ULONG_MAX); /* go to the next entry. */
1576e15e06a8SLiam R. Howlett 	mn2 = mas.node;
1577e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mn1 == mn2); /* test the next entry is in the next node. */
1578e15e06a8SLiam R. Howlett 
1579e15e06a8SLiam R. Howlett 	/*
1580e15e06a8SLiam R. Howlett 	 * At this point, there is a gap of 3 at seq100[6].  Find it by
1581e15e06a8SLiam R. Howlett 	 * searching 20 - 50 for size 3.
1582e15e06a8SLiam R. Howlett 	 */
1583e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1584e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[10], seq100[11],
1585e15e06a8SLiam R. Howlett 					     seq100[12]));
1586e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq100[6]);
1587e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1588e15e06a8SLiam R. Howlett 
1589e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1590e15e06a8SLiam R. Howlett 	mtree_store(mt, seq100[13], NULL, GFP_KERNEL);
1591e15e06a8SLiam R. Howlett 	check_load(mt, seq100[13], NULL);
1592e15e06a8SLiam R. Howlett 	check_load(mt, seq100[14], xa_mk_value(seq100[14]));
1593e15e06a8SLiam R. Howlett 	mtree_store(mt, seq100[14], NULL, GFP_KERNEL);
1594e15e06a8SLiam R. Howlett 	check_load(mt, seq100[13], NULL);
1595e15e06a8SLiam R. Howlett 	check_load(mt, seq100[14], NULL);
1596e15e06a8SLiam R. Howlett 
1597e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1598e15e06a8SLiam R. Howlett 	rcu_read_lock();
1599e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[16], seq100[15],
1600e15e06a8SLiam R. Howlett 					     seq100[17]));
1601e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq100[13]);
1602e15e06a8SLiam R. Howlett 	mt_validate(mt);
1603e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1604e15e06a8SLiam R. Howlett 
1605e15e06a8SLiam R. Howlett 	/*
1606e15e06a8SLiam R. Howlett 	 * *DEPRECATED: no retries anymore* Test retry entry in the start of a
1607e15e06a8SLiam R. Howlett 	 * gap.
1608e15e06a8SLiam R. Howlett 	 */
1609e15e06a8SLiam R. Howlett 	mt_set_non_kernel(2);
1610e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq100[18], seq100[14], NULL);
1611e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq100[15]);
1612e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1613e15e06a8SLiam R. Howlett 	rcu_read_lock();
1614e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[16], seq100[19],
1615e15e06a8SLiam R. Howlett 					     seq100[20]));
1616e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1617e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq100[18]);
1618e15e06a8SLiam R. Howlett 	mt_validate(mt);
1619e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1620e15e06a8SLiam R. Howlett 
1621e15e06a8SLiam R. Howlett 	/* seq 2000 tests are for multi-level tree gaps */
1622e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1623e15e06a8SLiam R. Howlett 	check_seq(mt, 2000, false);
1624e15e06a8SLiam R. Howlett 	mt_set_non_kernel(1);
1625e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq2000[0]);
1626e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, seq2000[1]);
1627e15e06a8SLiam R. Howlett 
1628e15e06a8SLiam R. Howlett 	mt_set_non_kernel(2);
1629e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1630e15e06a8SLiam R. Howlett 	rcu_read_lock();
1631e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq2000[2], seq2000[3],
1632e15e06a8SLiam R. Howlett 					     seq2000[4]));
1633e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != seq2000[1]);
1634e15e06a8SLiam R. Howlett 	rcu_read_unlock();
1635e15e06a8SLiam R. Howlett 	mt_validate(mt);
1636e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1637e15e06a8SLiam R. Howlett 
1638e15e06a8SLiam R. Howlett 	/* seq 400 tests rebalancing over two levels. */
1639e15e06a8SLiam R. Howlett 	mt_set_non_kernel(99);
1640e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1641e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1642e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[0], seq400[1], NULL);
1643e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1644e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1645e15e06a8SLiam R. Howlett 
1646e15e06a8SLiam R. Howlett 	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
1647e15e06a8SLiam R. Howlett 	check_seq(mt, 400, false);
1648e15e06a8SLiam R. Howlett 	mt_set_non_kernel(50);
1649e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[2], seq400[9],
1650e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[2]));
1651e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[3], seq400[9],
1652e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[3]));
1653e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[4], seq400[9],
1654e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[4]));
1655e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[5], seq400[9],
1656e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[5]));
1657e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[0], seq400[9],
1658e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[0]));
1659e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[6], seq400[9],
1660e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[6]));
1661e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[7], seq400[9],
1662e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[7]));
1663e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[8], seq400[9],
1664e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[8]));
1665e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, seq400[10], seq400[11],
1666e15e06a8SLiam R. Howlett 			       xa_mk_value(seq400[10]));
1667e15e06a8SLiam R. Howlett 	mt_validate(mt);
1668e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1669e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
1670e15e06a8SLiam R. Howlett }
check_node_overwrite(struct maple_tree * mt)1671eaf9790dSLiam R. Howlett static noinline void __init check_node_overwrite(struct maple_tree *mt)
1672e15e06a8SLiam R. Howlett {
1673e15e06a8SLiam R. Howlett 	int i, max = 4000;
1674e15e06a8SLiam R. Howlett 
1675e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i++)
1676e15e06a8SLiam R. Howlett 		mtree_test_store_range(mt, i*100, i*100 + 50, xa_mk_value(i*100));
1677e15e06a8SLiam R. Howlett 
1678e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 319951, 367950, NULL);
167989f499f3SLiam R. Howlett 	/*mt_dump(mt, mt_dump_dec); */
1680e15e06a8SLiam R. Howlett 	mt_validate(mt);
1681e15e06a8SLiam R. Howlett }
1682e15e06a8SLiam R. Howlett 
1683e15e06a8SLiam R. Howlett #if defined(BENCH_SLOT_STORE)
bench_slot_store(struct maple_tree * mt)1684eaf9790dSLiam R. Howlett static noinline void __init bench_slot_store(struct maple_tree *mt)
1685e15e06a8SLiam R. Howlett {
1686e15e06a8SLiam R. Howlett 	int i, brk = 105, max = 1040, brk_start = 100, count = 20000000;
1687e15e06a8SLiam R. Howlett 
1688e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1689e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1690e15e06a8SLiam R. Howlett 
1691e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1692e15e06a8SLiam R. Howlett 		mtree_store_range(mt, brk, brk, NULL, GFP_KERNEL);
1693e15e06a8SLiam R. Howlett 		mtree_store_range(mt, brk_start, brk, xa_mk_value(brk),
1694e15e06a8SLiam R. Howlett 				  GFP_KERNEL);
1695e15e06a8SLiam R. Howlett 	}
1696e15e06a8SLiam R. Howlett }
1697e15e06a8SLiam R. Howlett #endif
1698e15e06a8SLiam R. Howlett 
1699e15e06a8SLiam R. Howlett #if defined(BENCH_NODE_STORE)
bench_node_store(struct maple_tree * mt)1700eaf9790dSLiam R. Howlett static noinline void __init bench_node_store(struct maple_tree *mt)
1701e15e06a8SLiam R. Howlett {
1702e15e06a8SLiam R. Howlett 	int i, overwrite = 76, max = 240, count = 20000000;
1703e15e06a8SLiam R. Howlett 
1704e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1705e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1706e15e06a8SLiam R. Howlett 
1707e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1708e15e06a8SLiam R. Howlett 		mtree_store_range(mt, overwrite,  overwrite + 15,
1709e15e06a8SLiam R. Howlett 				  xa_mk_value(overwrite), GFP_KERNEL);
1710e15e06a8SLiam R. Howlett 
1711e15e06a8SLiam R. Howlett 		overwrite += 5;
1712e15e06a8SLiam R. Howlett 		if (overwrite >= 135)
1713e15e06a8SLiam R. Howlett 			overwrite = 76;
1714e15e06a8SLiam R. Howlett 	}
1715e15e06a8SLiam R. Howlett }
1716e15e06a8SLiam R. Howlett #endif
1717e15e06a8SLiam R. Howlett 
1718e15e06a8SLiam R. Howlett #if defined(BENCH_AWALK)
bench_awalk(struct maple_tree * mt)1719eaf9790dSLiam R. Howlett static noinline void __init bench_awalk(struct maple_tree *mt)
1720e15e06a8SLiam R. Howlett {
1721e15e06a8SLiam R. Howlett 	int i, max = 2500, count = 50000000;
1722e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 1470, 1470);
1723e15e06a8SLiam R. Howlett 
1724e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1725e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1726e15e06a8SLiam R. Howlett 
1727e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 1470, 1475, NULL, GFP_KERNEL);
1728e15e06a8SLiam R. Howlett 
1729e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1730e15e06a8SLiam R. Howlett 		mas_empty_area_rev(&mas, 0, 2000, 10);
1731e15e06a8SLiam R. Howlett 		mas_reset(&mas);
1732e15e06a8SLiam R. Howlett 	}
1733e15e06a8SLiam R. Howlett }
1734e15e06a8SLiam R. Howlett #endif
1735e15e06a8SLiam R. Howlett #if defined(BENCH_WALK)
bench_walk(struct maple_tree * mt)1736eaf9790dSLiam R. Howlett static noinline void __init bench_walk(struct maple_tree *mt)
1737e15e06a8SLiam R. Howlett {
1738e15e06a8SLiam R. Howlett 	int i, max = 2500, count = 550000000;
1739e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 1470, 1470);
1740e15e06a8SLiam R. Howlett 
1741e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 10)
1742e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
1743e15e06a8SLiam R. Howlett 
1744e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1745e15e06a8SLiam R. Howlett 		mas_walk(&mas);
1746e15e06a8SLiam R. Howlett 		mas_reset(&mas);
1747e15e06a8SLiam R. Howlett 	}
1748e15e06a8SLiam R. Howlett 
1749e15e06a8SLiam R. Howlett }
1750e15e06a8SLiam R. Howlett #endif
1751e15e06a8SLiam R. Howlett 
1752e15e06a8SLiam R. Howlett #if defined(BENCH_MT_FOR_EACH)
bench_mt_for_each(struct maple_tree * mt)1753eaf9790dSLiam R. Howlett static noinline void __init bench_mt_for_each(struct maple_tree *mt)
1754e15e06a8SLiam R. Howlett {
1755e15e06a8SLiam R. Howlett 	int i, count = 1000000;
1756e15e06a8SLiam R. Howlett 	unsigned long max = 2500, index = 0;
1757e15e06a8SLiam R. Howlett 	void *entry;
1758e15e06a8SLiam R. Howlett 
1759e15e06a8SLiam R. Howlett 	for (i = 0; i < max; i += 5)
1760e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i, i + 4, xa_mk_value(i), GFP_KERNEL);
1761e15e06a8SLiam R. Howlett 
1762e15e06a8SLiam R. Howlett 	for (i = 0; i < count; i++) {
1763e15e06a8SLiam R. Howlett 		unsigned long j = 0;
1764e15e06a8SLiam R. Howlett 
1765e15e06a8SLiam R. Howlett 		mt_for_each(mt, entry, index, max) {
1766e15e06a8SLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
1767e15e06a8SLiam R. Howlett 			j += 5;
1768e15e06a8SLiam R. Howlett 		}
1769e15e06a8SLiam R. Howlett 
1770e15e06a8SLiam R. Howlett 		index = 0;
1771e15e06a8SLiam R. Howlett 	}
1772e15e06a8SLiam R. Howlett 
1773e15e06a8SLiam R. Howlett }
1774e15e06a8SLiam R. Howlett #endif
1775e15e06a8SLiam R. Howlett 
1776361c678bSLiam R. Howlett #if defined(BENCH_MAS_FOR_EACH)
bench_mas_for_each(struct maple_tree * mt)1777361c678bSLiam R. Howlett static noinline void __init bench_mas_for_each(struct maple_tree *mt)
1778361c678bSLiam R. Howlett {
1779361c678bSLiam R. Howlett 	int i, count = 1000000;
1780361c678bSLiam R. Howlett 	unsigned long max = 2500;
1781361c678bSLiam R. Howlett 	void *entry;
1782361c678bSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1783361c678bSLiam R. Howlett 
1784361c678bSLiam R. Howlett 	for (i = 0; i < max; i += 5) {
1785361c678bSLiam R. Howlett 		int gap = 4;
1786361c678bSLiam R. Howlett 
1787361c678bSLiam R. Howlett 		if (i % 30 == 0)
1788361c678bSLiam R. Howlett 			gap = 3;
1789361c678bSLiam R. Howlett 		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL);
1790361c678bSLiam R. Howlett 	}
1791361c678bSLiam R. Howlett 
1792361c678bSLiam R. Howlett 	rcu_read_lock();
1793361c678bSLiam R. Howlett 	for (i = 0; i < count; i++) {
1794361c678bSLiam R. Howlett 		unsigned long j = 0;
1795361c678bSLiam R. Howlett 
1796361c678bSLiam R. Howlett 		mas_for_each(&mas, entry, max) {
1797361c678bSLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
1798361c678bSLiam R. Howlett 			j += 5;
1799361c678bSLiam R. Howlett 		}
1800361c678bSLiam R. Howlett 		mas_set(&mas, 0);
1801361c678bSLiam R. Howlett 	}
1802361c678bSLiam R. Howlett 	rcu_read_unlock();
1803361c678bSLiam R. Howlett 
1804361c678bSLiam R. Howlett }
1805361c678bSLiam R. Howlett #endif
18068c314f3bSLiam R. Howlett #if defined(BENCH_MAS_PREV)
bench_mas_prev(struct maple_tree * mt)18078c314f3bSLiam R. Howlett static noinline void __init bench_mas_prev(struct maple_tree *mt)
18088c314f3bSLiam R. Howlett {
18098c314f3bSLiam R. Howlett 	int i, count = 1000000;
18108c314f3bSLiam R. Howlett 	unsigned long max = 2500;
18118c314f3bSLiam R. Howlett 	void *entry;
18128c314f3bSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1813361c678bSLiam R. Howlett 
18148c314f3bSLiam R. Howlett 	for (i = 0; i < max; i += 5) {
18158c314f3bSLiam R. Howlett 		int gap = 4;
18168c314f3bSLiam R. Howlett 
18178c314f3bSLiam R. Howlett 		if (i % 30 == 0)
18188c314f3bSLiam R. Howlett 			gap = 3;
18198c314f3bSLiam R. Howlett 		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL);
18208c314f3bSLiam R. Howlett 	}
18218c314f3bSLiam R. Howlett 
18228c314f3bSLiam R. Howlett 	rcu_read_lock();
18238c314f3bSLiam R. Howlett 	for (i = 0; i < count; i++) {
18248c314f3bSLiam R. Howlett 		unsigned long j = 2495;
18258c314f3bSLiam R. Howlett 
18268c314f3bSLiam R. Howlett 		mas_set(&mas, ULONG_MAX);
18278c314f3bSLiam R. Howlett 		while ((entry = mas_prev(&mas, 0)) != NULL) {
18288c314f3bSLiam R. Howlett 			MT_BUG_ON(mt, entry != xa_mk_value(j));
18298c314f3bSLiam R. Howlett 			j -= 5;
18308c314f3bSLiam R. Howlett 		}
18318c314f3bSLiam R. Howlett 	}
18328c314f3bSLiam R. Howlett 	rcu_read_unlock();
18338c314f3bSLiam R. Howlett 
18348c314f3bSLiam R. Howlett }
18358c314f3bSLiam R. Howlett #endif
1836120b1162SLiam Howlett /* check_forking - simulate the kernel forking sequence with the tree. */
check_forking(struct maple_tree * mt)1837eaf9790dSLiam R. Howlett static noinline void __init check_forking(struct maple_tree *mt)
1838e15e06a8SLiam R. Howlett {
1839e15e06a8SLiam R. Howlett 
1840e15e06a8SLiam R. Howlett 	struct maple_tree newmt;
1841e15e06a8SLiam R. Howlett 	int i, nr_entries = 134;
1842e15e06a8SLiam R. Howlett 	void *val;
1843e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1844e15e06a8SLiam R. Howlett 	MA_STATE(newmas, mt, 0, 0);
1845*099d7439SLiam R. Howlett 	struct rw_semaphore newmt_lock;
1846*099d7439SLiam R. Howlett 
1847*099d7439SLiam R. Howlett 	init_rwsem(&newmt_lock);
1848e15e06a8SLiam R. Howlett 
1849e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
1850e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
1851e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
1852e15e06a8SLiam R. Howlett 
1853e15e06a8SLiam R. Howlett 	mt_set_non_kernel(99999);
1854*099d7439SLiam R. Howlett 	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
1855*099d7439SLiam R. Howlett 	mt_set_external_lock(&newmt, &newmt_lock);
1856e15e06a8SLiam R. Howlett 	newmas.tree = &newmt;
1857e15e06a8SLiam R. Howlett 	mas_reset(&newmas);
1858e15e06a8SLiam R. Howlett 	mas_reset(&mas);
1859*099d7439SLiam R. Howlett 	down_write(&newmt_lock);
1860e15e06a8SLiam R. Howlett 	mas.index = 0;
1861e15e06a8SLiam R. Howlett 	mas.last = 0;
1862e15e06a8SLiam R. Howlett 	if (mas_expected_entries(&newmas, nr_entries)) {
1863e15e06a8SLiam R. Howlett 		pr_err("OOM!");
1864e15e06a8SLiam R. Howlett 		BUG_ON(1);
1865e15e06a8SLiam R. Howlett 	}
1866120b1162SLiam Howlett 	rcu_read_lock();
1867e15e06a8SLiam R. Howlett 	mas_for_each(&mas, val, ULONG_MAX) {
1868e15e06a8SLiam R. Howlett 		newmas.index = mas.index;
1869e15e06a8SLiam R. Howlett 		newmas.last = mas.last;
1870e15e06a8SLiam R. Howlett 		mas_store(&newmas, val);
1871e15e06a8SLiam R. Howlett 	}
1872120b1162SLiam Howlett 	rcu_read_unlock();
1873e15e06a8SLiam R. Howlett 	mas_destroy(&newmas);
1874e15e06a8SLiam R. Howlett 	mt_validate(&newmt);
1875e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1876*099d7439SLiam R. Howlett 	__mt_destroy(&newmt);
1877*099d7439SLiam R. Howlett 	up_write(&newmt_lock);
1878e15e06a8SLiam R. Howlett }
1879e15e06a8SLiam R. Howlett 
check_iteration(struct maple_tree * mt)1880eaf9790dSLiam R. Howlett static noinline void __init check_iteration(struct maple_tree *mt)
18815159d64bSLiam R. Howlett {
18825159d64bSLiam R. Howlett 	int i, nr_entries = 125;
18835159d64bSLiam R. Howlett 	void *val;
18845159d64bSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
18855159d64bSLiam R. Howlett 
18865159d64bSLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
18875159d64bSLiam R. Howlett 		mtree_store_range(mt, i * 10, i * 10 + 9,
18885159d64bSLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
18895159d64bSLiam R. Howlett 
18905159d64bSLiam R. Howlett 	mt_set_non_kernel(99999);
18915159d64bSLiam R. Howlett 
18925159d64bSLiam R. Howlett 	i = 0;
18935159d64bSLiam R. Howlett 	mas_lock(&mas);
18945159d64bSLiam R. Howlett 	mas_for_each(&mas, val, 925) {
18955159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.index != i * 10);
18965159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.last != i * 10 + 9);
18975159d64bSLiam R. Howlett 		/* Overwrite end of entry 92 */
18985159d64bSLiam R. Howlett 		if (i == 92) {
18995159d64bSLiam R. Howlett 			mas.index = 925;
19005159d64bSLiam R. Howlett 			mas.last = 929;
19015159d64bSLiam R. Howlett 			mas_store(&mas, val);
19025159d64bSLiam R. Howlett 		}
19035159d64bSLiam R. Howlett 		i++;
19045159d64bSLiam R. Howlett 	}
19055159d64bSLiam R. Howlett 	/* Ensure mas_find() gets the next value */
19065159d64bSLiam R. Howlett 	val = mas_find(&mas, ULONG_MAX);
19075159d64bSLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(i));
19085159d64bSLiam R. Howlett 
19095159d64bSLiam R. Howlett 	mas_set(&mas, 0);
19105159d64bSLiam R. Howlett 	i = 0;
19115159d64bSLiam R. Howlett 	mas_for_each(&mas, val, 785) {
19125159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.index != i * 10);
19135159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.last != i * 10 + 9);
19145159d64bSLiam R. Howlett 		/* Overwrite start of entry 78 */
19155159d64bSLiam R. Howlett 		if (i == 78) {
19165159d64bSLiam R. Howlett 			mas.index = 780;
19175159d64bSLiam R. Howlett 			mas.last = 785;
19185159d64bSLiam R. Howlett 			mas_store(&mas, val);
19195159d64bSLiam R. Howlett 		} else {
19205159d64bSLiam R. Howlett 			i++;
19215159d64bSLiam R. Howlett 		}
19225159d64bSLiam R. Howlett 	}
19235159d64bSLiam R. Howlett 	val = mas_find(&mas, ULONG_MAX);
19245159d64bSLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(i));
19255159d64bSLiam R. Howlett 
19265159d64bSLiam R. Howlett 	mas_set(&mas, 0);
19275159d64bSLiam R. Howlett 	i = 0;
19285159d64bSLiam R. Howlett 	mas_for_each(&mas, val, 765) {
19295159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.index != i * 10);
19305159d64bSLiam R. Howlett 		MT_BUG_ON(mt, mas.last != i * 10 + 9);
19315159d64bSLiam R. Howlett 		/* Overwrite end of entry 76 and advance to the end */
19325159d64bSLiam R. Howlett 		if (i == 76) {
19335159d64bSLiam R. Howlett 			mas.index = 760;
19345159d64bSLiam R. Howlett 			mas.last = 765;
19355159d64bSLiam R. Howlett 			mas_store(&mas, val);
19365159d64bSLiam R. Howlett 		}
19375159d64bSLiam R. Howlett 		i++;
19385159d64bSLiam R. Howlett 	}
19395159d64bSLiam R. Howlett 	/* Make sure the next find returns the one after 765, 766-769 */
19405159d64bSLiam R. Howlett 	val = mas_find(&mas, ULONG_MAX);
19415159d64bSLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(76));
19425159d64bSLiam R. Howlett 	mas_unlock(&mas);
19435159d64bSLiam R. Howlett 	mas_destroy(&mas);
19445159d64bSLiam R. Howlett 	mt_set_non_kernel(0);
19455159d64bSLiam R. Howlett }
19465159d64bSLiam R. Howlett 
check_mas_store_gfp(struct maple_tree * mt)1947eaf9790dSLiam R. Howlett static noinline void __init check_mas_store_gfp(struct maple_tree *mt)
1948e15e06a8SLiam R. Howlett {
1949e15e06a8SLiam R. Howlett 
1950e15e06a8SLiam R. Howlett 	struct maple_tree newmt;
1951e15e06a8SLiam R. Howlett 	int i, nr_entries = 135;
1952e15e06a8SLiam R. Howlett 	void *val;
1953e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1954e15e06a8SLiam R. Howlett 	MA_STATE(newmas, mt, 0, 0);
1955e15e06a8SLiam R. Howlett 
1956e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
1957e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
1958e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
1959e15e06a8SLiam R. Howlett 
1960e15e06a8SLiam R. Howlett 	mt_set_non_kernel(99999);
1961e15e06a8SLiam R. Howlett 	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE);
1962e15e06a8SLiam R. Howlett 	newmas.tree = &newmt;
1963120b1162SLiam Howlett 	rcu_read_lock();
1964120b1162SLiam Howlett 	mas_lock(&newmas);
1965e15e06a8SLiam R. Howlett 	mas_reset(&newmas);
1966e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
1967e15e06a8SLiam R. Howlett 	mas_for_each(&mas, val, ULONG_MAX) {
1968e15e06a8SLiam R. Howlett 		newmas.index = mas.index;
1969e15e06a8SLiam R. Howlett 		newmas.last = mas.last;
1970e15e06a8SLiam R. Howlett 		mas_store_gfp(&newmas, val, GFP_KERNEL);
1971e15e06a8SLiam R. Howlett 	}
1972120b1162SLiam Howlett 	mas_unlock(&newmas);
1973120b1162SLiam Howlett 	rcu_read_unlock();
1974e15e06a8SLiam R. Howlett 	mt_validate(&newmt);
1975e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
1976e15e06a8SLiam R. Howlett 	mtree_destroy(&newmt);
1977e15e06a8SLiam R. Howlett }
1978e15e06a8SLiam R. Howlett 
1979e15e06a8SLiam R. Howlett #if defined(BENCH_FORK)
bench_forking(struct maple_tree * mt)1980eaf9790dSLiam R. Howlett static noinline void __init bench_forking(struct maple_tree *mt)
1981e15e06a8SLiam R. Howlett {
1982e15e06a8SLiam R. Howlett 
1983e15e06a8SLiam R. Howlett 	struct maple_tree newmt;
1984e15e06a8SLiam R. Howlett 	int i, nr_entries = 134, nr_fork = 80000;
1985e15e06a8SLiam R. Howlett 	void *val;
1986e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
1987e15e06a8SLiam R. Howlett 	MA_STATE(newmas, mt, 0, 0);
1988*099d7439SLiam R. Howlett 	struct rw_semaphore newmt_lock;
1989*099d7439SLiam R. Howlett 
1990*099d7439SLiam R. Howlett 	init_rwsem(&newmt_lock);
1991*099d7439SLiam R. Howlett 	mt_set_external_lock(&newmt, &newmt_lock);
1992e15e06a8SLiam R. Howlett 
1993e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
1994e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
1995e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
1996e15e06a8SLiam R. Howlett 
1997e15e06a8SLiam R. Howlett 	for (i = 0; i < nr_fork; i++) {
1998e15e06a8SLiam R. Howlett 		mt_set_non_kernel(99999);
1999e15e06a8SLiam R. Howlett 		mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE);
2000e15e06a8SLiam R. Howlett 		newmas.tree = &newmt;
2001e15e06a8SLiam R. Howlett 		mas_reset(&newmas);
2002e15e06a8SLiam R. Howlett 		mas_reset(&mas);
2003e15e06a8SLiam R. Howlett 		mas.index = 0;
2004e15e06a8SLiam R. Howlett 		mas.last = 0;
2005120b1162SLiam Howlett 		rcu_read_lock();
2006*099d7439SLiam R. Howlett 		down_write(&newmt_lock);
2007e15e06a8SLiam R. Howlett 		if (mas_expected_entries(&newmas, nr_entries)) {
2008e15e06a8SLiam R. Howlett 			printk("OOM!");
2009e15e06a8SLiam R. Howlett 			BUG_ON(1);
2010e15e06a8SLiam R. Howlett 		}
2011e15e06a8SLiam R. Howlett 		mas_for_each(&mas, val, ULONG_MAX) {
2012e15e06a8SLiam R. Howlett 			newmas.index = mas.index;
2013e15e06a8SLiam R. Howlett 			newmas.last = mas.last;
2014e15e06a8SLiam R. Howlett 			mas_store(&newmas, val);
2015e15e06a8SLiam R. Howlett 		}
2016e15e06a8SLiam R. Howlett 		mas_destroy(&newmas);
2017120b1162SLiam Howlett 		rcu_read_unlock();
2018e15e06a8SLiam R. Howlett 		mt_validate(&newmt);
2019e15e06a8SLiam R. Howlett 		mt_set_non_kernel(0);
2020*099d7439SLiam R. Howlett 		__mt_destroy(&newmt);
2021*099d7439SLiam R. Howlett 		up_write(&newmt_lock);
2022e15e06a8SLiam R. Howlett 	}
2023e15e06a8SLiam R. Howlett }
2024e15e06a8SLiam R. Howlett #endif
2025e15e06a8SLiam R. Howlett 
next_prev_test(struct maple_tree * mt)2026eaf9790dSLiam R. Howlett static noinline void __init next_prev_test(struct maple_tree *mt)
2027e15e06a8SLiam R. Howlett {
2028120b1162SLiam Howlett 	int i, nr_entries;
2029e15e06a8SLiam R. Howlett 	void *val;
2030e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
2031e15e06a8SLiam R. Howlett 	struct maple_enode *mn;
2032eaf9790dSLiam R. Howlett 	static const unsigned long *level2;
2033eaf9790dSLiam R. Howlett 	static const unsigned long level2_64[] = { 707, 1000, 710, 715, 720,
2034eaf9790dSLiam R. Howlett 						   725};
2035eaf9790dSLiam R. Howlett 	static const unsigned long level2_32[] = { 1747, 2000, 1750, 1755,
2036eaf9790dSLiam R. Howlett 						   1760, 1765};
20377a93c71aSLiam R. Howlett 	unsigned long last_index;
2038120b1162SLiam Howlett 
2039120b1162SLiam Howlett 	if (MAPLE_32BIT) {
2040120b1162SLiam Howlett 		nr_entries = 500;
2041120b1162SLiam Howlett 		level2 = level2_32;
20427a93c71aSLiam R. Howlett 		last_index = 0x138e;
2043120b1162SLiam Howlett 	} else {
2044120b1162SLiam Howlett 		nr_entries = 200;
2045120b1162SLiam Howlett 		level2 = level2_64;
20467a93c71aSLiam R. Howlett 		last_index = 0x7d6;
2047120b1162SLiam Howlett 	}
2048e15e06a8SLiam R. Howlett 
2049e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
2050e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
2051e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
2052e15e06a8SLiam R. Howlett 
2053120b1162SLiam Howlett 	mas_lock(&mas);
2054e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries / 2; i++) {
2055e15e06a8SLiam R. Howlett 		mas_next(&mas, 1000);
2056e15e06a8SLiam R. Howlett 		if (mas_is_none(&mas))
2057e15e06a8SLiam R. Howlett 			break;
2058e15e06a8SLiam R. Howlett 
2059e15e06a8SLiam R. Howlett 	}
2060e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2061e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
2062e15e06a8SLiam R. Howlett 	i = 0;
2063e15e06a8SLiam R. Howlett 	mas_for_each(&mas, val, 1000) {
2064e15e06a8SLiam R. Howlett 		i++;
2065e15e06a8SLiam R. Howlett 	}
2066e15e06a8SLiam R. Howlett 
2067e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2068e15e06a8SLiam R. Howlett 	mas_set(&mas, 0);
2069e15e06a8SLiam R. Howlett 	i = 0;
2070e15e06a8SLiam R. Howlett 	mas_for_each(&mas, val, 1000) {
2071e15e06a8SLiam R. Howlett 		mas_pause(&mas);
2072e15e06a8SLiam R. Howlett 		i++;
2073e15e06a8SLiam R. Howlett 	}
2074e15e06a8SLiam R. Howlett 
2075e15e06a8SLiam R. Howlett 	/*
2076e15e06a8SLiam R. Howlett 	 * 680 - 685 = 0x61a00001930c
2077e15e06a8SLiam R. Howlett 	 * 686 - 689 = NULL;
2078e15e06a8SLiam R. Howlett 	 * 690 - 695 = 0x61a00001930c
2079e15e06a8SLiam R. Howlett 	 * Check simple next/prev
2080e15e06a8SLiam R. Howlett 	 */
2081e15e06a8SLiam R. Howlett 	mas_set(&mas, 686);
2082e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2083e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2084e15e06a8SLiam R. Howlett 
2085e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2086e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(690 / 10));
2087e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 690);
2088e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 695);
2089e15e06a8SLiam R. Howlett 
2090e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2091e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(680 / 10));
2092e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 680);
2093e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 685);
2094e15e06a8SLiam R. Howlett 
2095e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2096e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(690 / 10));
2097e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 690);
2098e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 695);
2099e15e06a8SLiam R. Howlett 
2100e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2101e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(700 / 10));
2102e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 700);
2103e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 705);
2104e15e06a8SLiam R. Howlett 
2105e15e06a8SLiam R. Howlett 	/* Check across node boundaries of the tree */
2106e15e06a8SLiam R. Howlett 	mas_set(&mas, 70);
2107e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2108e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(70 / 10));
2109e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 70);
2110e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 75);
2111e15e06a8SLiam R. Howlett 
2112e15e06a8SLiam R. Howlett 	val = mas_next(&mas, 1000);
2113e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(80 / 10));
2114e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 80);
2115e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 85);
2116e15e06a8SLiam R. Howlett 
2117e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 70);
2118e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(70 / 10));
2119e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 70);
2120e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 75);
2121e15e06a8SLiam R. Howlett 
2122e15e06a8SLiam R. Howlett 	/* Check across two levels of the tree */
2123e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2124120b1162SLiam Howlett 	mas_set(&mas, level2[0]);
2125e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2126e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2127120b1162SLiam Howlett 	val = mas_next(&mas, level2[1]);
2128120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(level2[2] / 10));
2129120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != level2[2]);
2130120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != level2[3]);
2131e15e06a8SLiam R. Howlett 	mn = mas.node;
2132e15e06a8SLiam R. Howlett 
2133120b1162SLiam Howlett 	val = mas_next(&mas, level2[1]);
2134120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(level2[4] / 10));
2135120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != level2[4]);
2136120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != level2[5]);
2137e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mn == mas.node);
2138e15e06a8SLiam R. Howlett 
2139e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2140120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(level2[2] / 10));
2141120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != level2[2]);
2142120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != level2[3]);
2143e15e06a8SLiam R. Howlett 
2144e15e06a8SLiam R. Howlett 	/* Check running off the end and back on */
2145120b1162SLiam Howlett 	mas_set(&mas, nr_entries * 10);
2146e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2147120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(nr_entries));
2148120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != (nr_entries * 10));
2149120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != (nr_entries * 10 + 5));
2150e15e06a8SLiam R. Howlett 
2151e15e06a8SLiam R. Howlett 	val = mas_next(&mas, ULONG_MAX);
2152e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
21537a93c71aSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != last_index);
2154e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
2155e15e06a8SLiam R. Howlett 
2156e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2157120b1162SLiam Howlett 	MT_BUG_ON(mt, val != xa_mk_value(nr_entries));
2158120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.index != (nr_entries * 10));
2159120b1162SLiam Howlett 	MT_BUG_ON(mt, mas.last != (nr_entries * 10 + 5));
2160e15e06a8SLiam R. Howlett 
2161e15e06a8SLiam R. Howlett 	/* Check running off the start and back on */
2162e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2163e15e06a8SLiam R. Howlett 	mas_set(&mas, 10);
2164e15e06a8SLiam R. Howlett 	val = mas_walk(&mas);
2165e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(1));
2166e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 10);
2167e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 15);
2168e15e06a8SLiam R. Howlett 
2169e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2170e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != xa_mk_value(0));
2171e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
2172e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 5);
2173e15e06a8SLiam R. Howlett 
2174e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2175e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2176e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
2177eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 5);
2178a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
2179e15e06a8SLiam R. Howlett 
2180e15e06a8SLiam R. Howlett 	mas.index = 0;
2181e15e06a8SLiam R. Howlett 	mas.last = 5;
2182e15e06a8SLiam R. Howlett 	mas_store(&mas, NULL);
2183e15e06a8SLiam R. Howlett 	mas_reset(&mas);
2184e15e06a8SLiam R. Howlett 	mas_set(&mas, 10);
2185e15e06a8SLiam R. Howlett 	mas_walk(&mas);
2186e15e06a8SLiam R. Howlett 
2187e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 0);
2188e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2189e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
2190eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 9);
2191120b1162SLiam Howlett 	mas_unlock(&mas);
2192e15e06a8SLiam R. Howlett 
2193e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2194e15e06a8SLiam R. Howlett 
2195e15e06a8SLiam R. Howlett 	mt_init(mt);
2196e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 0, 0, xa_mk_value(0), GFP_KERNEL);
2197e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 5, 5, xa_mk_value(5), GFP_KERNEL);
2198120b1162SLiam Howlett 	rcu_read_lock();
2199e15e06a8SLiam R. Howlett 	mas_set(&mas, 5);
2200e15e06a8SLiam R. Howlett 	val = mas_prev(&mas, 4);
2201e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, val != NULL);
2202e15e06a8SLiam R. Howlett 	rcu_read_unlock();
2203e15e06a8SLiam R. Howlett }
2204e15e06a8SLiam R. Howlett 
2205e15e06a8SLiam R. Howlett 
2206e15e06a8SLiam R. Howlett 
2207e15e06a8SLiam R. Howlett /* Test spanning writes that require balancing right sibling or right cousin */
check_spanning_relatives(struct maple_tree * mt)2208eaf9790dSLiam R. Howlett static noinline void __init check_spanning_relatives(struct maple_tree *mt)
2209e15e06a8SLiam R. Howlett {
2210e15e06a8SLiam R. Howlett 
2211e15e06a8SLiam R. Howlett 	unsigned long i, nr_entries = 1000;
2212e15e06a8SLiam R. Howlett 
2213e15e06a8SLiam R. Howlett 	for (i = 0; i <= nr_entries; i++)
2214e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, i*10 + 5,
2215e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
2216e15e06a8SLiam R. Howlett 
2217e15e06a8SLiam R. Howlett 
2218e15e06a8SLiam R. Howlett 	mtree_store_range(mt, 9365, 9955, NULL, GFP_KERNEL);
2219e15e06a8SLiam R. Howlett }
2220e15e06a8SLiam R. Howlett 
check_fuzzer(struct maple_tree * mt)2221eaf9790dSLiam R. Howlett static noinline void __init check_fuzzer(struct maple_tree *mt)
2222e15e06a8SLiam R. Howlett {
2223e15e06a8SLiam R. Howlett 	/*
2224e15e06a8SLiam R. Howlett 	 * 1. Causes a spanning rebalance of a single root node.
2225e15e06a8SLiam R. Howlett 	 * Fixed by setting the correct limit in mast_cp_to_nodes() when the
2226e15e06a8SLiam R. Howlett 	 * entire right side is consumed.
2227e15e06a8SLiam R. Howlett 	 */
2228e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 88, (void *)0xb1);
2229e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 84, (void *)0xa9);
2230e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2,  (void *)0x5);
2231e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4,  (void *)0x9);
2232e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 14, (void *)0x1d);
2233e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 7,  (void *)0xf);
2234e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2235e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 18, (void *)0x25);
2236e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 8, 18, (void *)0x11);
2237e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2238e15e06a8SLiam R. Howlett 
2239e15e06a8SLiam R. Howlett 
2240e15e06a8SLiam R. Howlett 	/*
2241e15e06a8SLiam R. Howlett 	 * 2. Cause a spanning rebalance of two nodes in root.
2242e15e06a8SLiam R. Howlett 	 * Fixed by setting mast->r->max correctly.
2243e15e06a8SLiam R. Howlett 	 */
2244e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2245e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 87, (void *)0xaf);
2246e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2247e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 4);
2248e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2249e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 8, (void *)0x11);
2250e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 44, (void *)0x59);
2251e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 68, (void *)0x89);
2252e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2253e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 43, (void *)0x57);
2254e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 24, (void *)0x31);
2255e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 844, (void *)0x699);
2256e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 84, (void *)0xa9);
2257e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2258e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 4);
2259e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 5);
2260e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2261e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2262e15e06a8SLiam R. Howlett 
2263e15e06a8SLiam R. Howlett 	/*
2264e15e06a8SLiam R. Howlett 	 * 3. Cause a node overflow on copy
2265e15e06a8SLiam R. Howlett 	 * Fixed by using the correct check for node size in mas_wr_modify()
2266e15e06a8SLiam R. Howlett 	 * Also discovered issue with metadata setting.
2267e15e06a8SLiam R. Howlett 	 */
2268e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2269120b1162SLiam Howlett 	mtree_test_store_range(mt, 0, ULONG_MAX, (void *)0x1);
2270e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2271e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2272e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2273e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 4);
2274e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 5, (void *)0xb);
2275e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2276e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 5, (void *)0xb);
2277e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2278e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 4);
2279e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2280e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 444, (void *)0x379);
2281e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2282e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2283e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 5, (void *)0xb);
2284e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2285e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2286e15e06a8SLiam R. Howlett 
2287e15e06a8SLiam R. Howlett 	/*
2288e15e06a8SLiam R. Howlett 	 * 4. spanning store failure due to writing incorrect pivot value at
2289e15e06a8SLiam R. Howlett 	 * last slot.
2290e15e06a8SLiam R. Howlett 	 * Fixed by setting mast->r->max correctly in mast_cp_to_nodes()
2291e15e06a8SLiam R. Howlett 	 *
2292e15e06a8SLiam R. Howlett 	 */
2293e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2294e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 261, (void *)0x20b);
2295e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 516, (void *)0x409);
2296e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 6, (void *)0xd);
2297e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2298e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1256, (void *)0x9d1);
2299e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 4, (void *)0x9);
2300e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2301e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 56, (void *)0x71);
2302e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2303e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 24, (void *)0x31);
2304e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2305e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2263, (void *)0x11af);
2306e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 446, (void *)0x37d);
2307e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 6, 45, (void *)0xd);
2308e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 3, 446, (void *)0x7);
2309e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2310e15e06a8SLiam R. Howlett 
2311e15e06a8SLiam R. Howlett 	/*
2312e15e06a8SLiam R. Howlett 	 * 5. mas_wr_extend_null() may overflow slots.
2313e15e06a8SLiam R. Howlett 	 * Fix by checking against wr_mas->node_end.
2314e15e06a8SLiam R. Howlett 	 */
2315e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2316e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 48, (void *)0x61);
2317e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 3, (void *)0x7);
2318e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2319e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 88, (void *)0xb1);
2320e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 81, (void *)0xa3);
2321e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2322e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2323e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2324e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2480, (void *)0x1361);
2325120b1162SLiam Howlett 	mtree_test_insert(mt, ULONG_MAX,
2326e15e06a8SLiam R. Howlett 			  (void *)0xffffffffffffffff);
2327120b1162SLiam Howlett 	mtree_test_erase(mt, ULONG_MAX);
2328e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2329e15e06a8SLiam R. Howlett 
2330e15e06a8SLiam R. Howlett 	/*
2331e15e06a8SLiam R. Howlett 	 * 6.  When reusing a node with an implied pivot and the node is
2332e15e06a8SLiam R. Howlett 	 * shrinking, old data would be left in the implied slot
2333e15e06a8SLiam R. Howlett 	 * Fixed by checking the last pivot for the mas->max and clear
2334e15e06a8SLiam R. Howlett 	 * accordingly.  This only affected the left-most node as that node is
2335e15e06a8SLiam R. Howlett 	 * the only one allowed to end in NULL.
2336e15e06a8SLiam R. Howlett 	 */
2337e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2338e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 3);
2339e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2340e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2341e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 2);
2342e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2343e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2344e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2345e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2346e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2347e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2348e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2349e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2350e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2351e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2352e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 3);
2353e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2354e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2355e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2356e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2357e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2358e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 2);
2359e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2360e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2361e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2362e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2363e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2364e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2365e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2366e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2367e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2368e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2369e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2370e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 3);
2371e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2372e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2373e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2374e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2375e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2376e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2377e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2378e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 4, 62, (void *)0x9);
2379e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2380e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 0, (void *)0x3);
2381e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 11, (void *)0x17);
2382e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2383e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2384e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 62, (void *)0x7d);
2385e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2386e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 15, (void *)0x3);
2387e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2388e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2389e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2390e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2391e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2392e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 62, (void *)0x7d);
2393e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2394e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 122, (void *)0xf5);
2395e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 3, (void *)0x7);
2396e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2397e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 1, (void *)0x1);
2398e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 85, (void *)0xab);
2399e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 72, (void *)0x91);
2400e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 81, (void *)0xa3);
2401e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 726, (void *)0x5ad);
2402e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2403e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2404e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 51, (void *)0x67);
2405e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 611, (void *)0x4c7);
2406e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 485, (void *)0x3cb);
2407e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2408e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2409e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2410e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2411e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 26, 1, (void *)0x35);
2412e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2413e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 22, (void *)0x3);
2414e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2415e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2416e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 53);
2417e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2418e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 1, (void *)0x3);
2419e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 222, (void *)0x1bd);
2420e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 485, (void *)0x3cb);
2421e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2422e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2423e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2424e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2425e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 3, (void *)0x7);
2426e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 621, (void *)0x4db);
2427e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 0, (void *)0x1);
2428e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 5);
2429e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2430e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 62, (void *)0x7d);
2431e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2432e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 0, (void *)0x3);
2433e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 22, (void *)0x2d);
2434e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2435e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2436e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2437e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 4, 62, (void *)0x9);
2438e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 62);
2439e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2440e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2441e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 22, (void *)0x3);
2442e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2443e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2444e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 53);
2445e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2446e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 1, (void *)0x3);
2447e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 222, (void *)0x1bd);
2448e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 485, (void *)0x3cb);
2449e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2450e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2451e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2452e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2453e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2454e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2455e15e06a8SLiam R. Howlett 
2456e15e06a8SLiam R. Howlett 	/*
2457e15e06a8SLiam R. Howlett 	 * 7. Previous fix was incomplete, fix mas_resuse_node() clearing of old
2458e15e06a8SLiam R. Howlett 	 * data by overwriting it first - that way metadata is of no concern.
2459e15e06a8SLiam R. Howlett 	 */
2460e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2461e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 1);
2462e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 102, (void *)0xcd);
2463e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2464e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2465e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2466e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 4, (void *)0x9);
2467e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2468e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 110, (void *)0xdd);
2469e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2470e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 5, 0, (void *)0xb);
2471e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2472e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2473e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 112, (void *)0xe1);
2474e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2475e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2476e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 110, 2, (void *)0xdd);
2477e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2478e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 22);
2479e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2480e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 210, (void *)0x1a5);
2481e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 2, (void *)0x1);
2482e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2483e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2484e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 22);
2485e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2486e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2487e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2488e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 112);
2489e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2490e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2491e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2492e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 1, 2, (void *)0x3);
2493e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2494e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2495e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2496e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2497e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2498e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2499e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2500e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2501e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2502e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2503e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2504e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 1, 2, (void *)0x3);
2505e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 0);
2506e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2507e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2508e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 112);
2509e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 110, 12, (void *)0xdd);
2510e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2511e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 110);
2512e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 4, 71, (void *)0x9);
2513e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 2);
2514e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2515e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 11, 22, (void *)0x17);
2516e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 12);
2517e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 2, (void *)0x5);
2518e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 22);
2519e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2520e15e06a8SLiam R. Howlett 
2521e15e06a8SLiam R. Howlett 
2522e15e06a8SLiam R. Howlett 	/*
2523e15e06a8SLiam R. Howlett 	 * 8.  When rebalancing or spanning_rebalance(), the max of the new node
2524e15e06a8SLiam R. Howlett 	 * may be set incorrectly to the final pivot and not the right max.
2525e15e06a8SLiam R. Howlett 	 * Fix by setting the left max to orig right max if the entire node is
2526e15e06a8SLiam R. Howlett 	 * consumed.
2527e15e06a8SLiam R. Howlett 	 */
2528e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2529e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 6, (void *)0xd);
2530e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 67, (void *)0x87);
2531e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2532e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6716, (void *)0x3479);
2533e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 61, (void *)0x7b);
2534e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 13, (void *)0x1b);
2535e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 8, (void *)0x11);
2536e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2537e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 0);
2538e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67167);
2539e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 6, 7167, (void *)0xd);
2540e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2541e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67);
2542e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2543e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 667167);
2544e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2545e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 67, (void *)0x87);
2546e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2547e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 1);
2548e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2549e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67);
2550e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 15, (void *)0x1f);
2551e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 67167, (void *)0x20cbf);
2552e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2553e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 7);
2554e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 16, (void *)0x21);
2555e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 36, (void *)0x49);
2556e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 67, (void *)0x87);
2557e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 6, (void *)0xd);
2558e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 367, (void *)0x2df);
2559e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 115, (void *)0xe7);
2560e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 0, (void *)0x1);
2561e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 1, 3, (void *)0x3);
2562e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2563e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67167);
2564e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 6, 47, (void *)0xd);
2565e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2566e15e06a8SLiam R. Howlett 	mtree_test_insert_range(mt, 1, 67, (void *)0x3);
2567e15e06a8SLiam R. Howlett 	mtree_test_load(mt, 67);
2568e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1, (void *)0x3);
2569e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 67167);
2570e15e06a8SLiam R. Howlett 	mtree_destroy(mt);
2571e15e06a8SLiam R. Howlett 
2572e15e06a8SLiam R. Howlett 	/*
2573e15e06a8SLiam R. Howlett 	 * 9. spanning store to the end of data caused an invalid metadata
2574e15e06a8SLiam R. Howlett 	 * length which resulted in a crash eventually.
2575e15e06a8SLiam R. Howlett 	 * Fix by checking if there is a value in pivot before incrementing the
2576e15e06a8SLiam R. Howlett 	 * metadata end in mab_mas_cp().  To ensure this doesn't happen again,
2577e15e06a8SLiam R. Howlett 	 * abstract the two locations this happens into a function called
2578e15e06a8SLiam R. Howlett 	 * mas_leaf_set_meta().
2579e15e06a8SLiam R. Howlett 	 */
2580e15e06a8SLiam R. Howlett 	mt_init_flags(mt, 0);
2581e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2582e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 12, (void *)0x19);
2583e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 6, (void *)0xd);
2584e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2585e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2586e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 91, (void *)0xb7);
2587e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 18, (void *)0x25);
2588e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 81, (void *)0xa3);
2589e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 128, (void *)0x1);
2590e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2591e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 8);
2592e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 11, (void *)0x17);
2593e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2594e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2595e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2596120b1162SLiam Howlett 	mtree_test_insert(mt, ULONG_MAX - 10, (void *)0xffffffffffffffeb);
2597120b1162SLiam Howlett 	mtree_test_erase(mt, ULONG_MAX - 10);
2598e15e06a8SLiam R. Howlett 	mtree_test_store_range(mt, 0, 281, (void *)0x1);
2599e15e06a8SLiam R. Howlett 	mtree_test_erase(mt, 2);
2600e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1211, (void *)0x977);
2601e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 111, (void *)0xdf);
2602e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 13, (void *)0x1b);
2603e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 211, (void *)0x1a7);
2604e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 11, (void *)0x17);
2605e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 5, (void *)0xb);
2606e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 1218, (void *)0x985);
2607e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 61, (void *)0x7b);
2608e15e06a8SLiam R. Howlett 	mtree_test_store(mt, 1, (void *)0x3);
2609e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 121, (void *)0xf3);
2610e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 8, (void *)0x11);
2611e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 21, (void *)0x2b);
2612e15e06a8SLiam R. Howlett 	mtree_test_insert(mt, 2, (void *)0x5);
2613120b1162SLiam Howlett 	mtree_test_insert(mt, ULONG_MAX - 10, (void *)0xffffffffffffffeb);
2614120b1162SLiam Howlett 	mtree_test_erase(mt, ULONG_MAX - 10);
2615e15e06a8SLiam R. Howlett }
2616120b1162SLiam Howlett 
2617120b1162SLiam 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)2618eaf9790dSLiam R. Howlett static noinline void __init check_dup_gaps(struct maple_tree *mt,
2619e15e06a8SLiam R. Howlett 				    unsigned long nr_entries, bool zero_start,
2620e15e06a8SLiam R. Howlett 				    unsigned long gap)
2621e15e06a8SLiam R. Howlett {
2622e15e06a8SLiam R. Howlett 	unsigned long i = 0;
2623e15e06a8SLiam R. Howlett 	struct maple_tree newmt;
2624e15e06a8SLiam R. Howlett 	int ret;
2625e15e06a8SLiam R. Howlett 	void *tmp;
2626e15e06a8SLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
2627e15e06a8SLiam R. Howlett 	MA_STATE(newmas, &newmt, 0, 0);
2628*099d7439SLiam R. Howlett 	struct rw_semaphore newmt_lock;
2629*099d7439SLiam R. Howlett 
2630*099d7439SLiam R. Howlett 	init_rwsem(&newmt_lock);
2631*099d7439SLiam R. Howlett 	mt_set_external_lock(&newmt, &newmt_lock);
2632e15e06a8SLiam R. Howlett 
2633e15e06a8SLiam R. Howlett 	if (!zero_start)
2634e15e06a8SLiam R. Howlett 		i = 1;
2635e15e06a8SLiam R. Howlett 
2636e15e06a8SLiam R. Howlett 	mt_zero_nr_tallocated();
2637e15e06a8SLiam R. Howlett 	for (; i <= nr_entries; i++)
2638e15e06a8SLiam R. Howlett 		mtree_store_range(mt, i*10, (i+1)*10 - gap,
2639e15e06a8SLiam R. Howlett 				  xa_mk_value(i), GFP_KERNEL);
2640e15e06a8SLiam R. Howlett 
2641*099d7439SLiam R. Howlett 	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
2642e15e06a8SLiam R. Howlett 	mt_set_non_kernel(99999);
2643*099d7439SLiam R. Howlett 	down_write(&newmt_lock);
2644e15e06a8SLiam R. Howlett 	ret = mas_expected_entries(&newmas, nr_entries);
2645e15e06a8SLiam R. Howlett 	mt_set_non_kernel(0);
2646e15e06a8SLiam R. Howlett 	MT_BUG_ON(mt, ret != 0);
2647e15e06a8SLiam R. Howlett 
2648120b1162SLiam Howlett 	rcu_read_lock();
2649e15e06a8SLiam R. Howlett 	mas_for_each(&mas, tmp, ULONG_MAX) {
2650e15e06a8SLiam R. Howlett 		newmas.index = mas.index;
2651e15e06a8SLiam R. Howlett 		newmas.last = mas.last;
2652e15e06a8SLiam R. Howlett 		mas_store(&newmas, tmp);
2653e15e06a8SLiam R. Howlett 	}
2654120b1162SLiam Howlett 	rcu_read_unlock();
2655e15e06a8SLiam R. Howlett 	mas_destroy(&newmas);
2656120b1162SLiam Howlett 
2657*099d7439SLiam R. Howlett 	__mt_destroy(&newmt);
2658*099d7439SLiam R. Howlett 	up_write(&newmt_lock);
2659e15e06a8SLiam R. Howlett }
2660e15e06a8SLiam R. Howlett 
2661120b1162SLiam Howlett /* Duplicate many sizes of trees.  Mainly to test expected entry values */
check_dup(struct maple_tree * mt)2662eaf9790dSLiam R. Howlett static noinline void __init check_dup(struct maple_tree *mt)
2663e15e06a8SLiam R. Howlett {
2664e15e06a8SLiam R. Howlett 	int i;
2665120b1162SLiam Howlett 	int big_start = 100010;
2666e15e06a8SLiam R. Howlett 
2667e15e06a8SLiam R. Howlett 	/* Check with a value at zero */
2668e15e06a8SLiam R. Howlett 	for (i = 10; i < 1000; i++) {
2669e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2670e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2671e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2672120b1162SLiam Howlett 		rcu_barrier();
2673e15e06a8SLiam R. Howlett 	}
2674e15e06a8SLiam R. Howlett 
2675120b1162SLiam Howlett 	cond_resched();
2676120b1162SLiam Howlett 	mt_cache_shrink();
2677e15e06a8SLiam R. Howlett 	/* Check with a value at zero, no gap */
2678e15e06a8SLiam R. Howlett 	for (i = 1000; i < 2000; i++) {
2679e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2680e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 0);
2681e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2682120b1162SLiam Howlett 		rcu_barrier();
2683e15e06a8SLiam R. Howlett 	}
2684e15e06a8SLiam R. Howlett 
2685120b1162SLiam Howlett 	cond_resched();
2686120b1162SLiam Howlett 	mt_cache_shrink();
2687e15e06a8SLiam R. Howlett 	/* Check with a value at zero and unreasonably large */
2688120b1162SLiam Howlett 	for (i = big_start; i < big_start + 10; i++) {
2689e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2690e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2691e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2692120b1162SLiam Howlett 		rcu_barrier();
2693e15e06a8SLiam R. Howlett 	}
2694e15e06a8SLiam R. Howlett 
2695120b1162SLiam Howlett 	cond_resched();
2696120b1162SLiam Howlett 	mt_cache_shrink();
2697e15e06a8SLiam R. Howlett 	/* Small to medium size not starting at zero*/
2698e15e06a8SLiam R. Howlett 	for (i = 200; i < 1000; i++) {
2699e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2700e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, false, 5);
2701e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2702120b1162SLiam Howlett 		rcu_barrier();
2703e15e06a8SLiam R. Howlett 	}
2704e15e06a8SLiam R. Howlett 
2705120b1162SLiam Howlett 	cond_resched();
2706120b1162SLiam Howlett 	mt_cache_shrink();
2707e15e06a8SLiam R. Howlett 	/* Unreasonably large not starting at zero*/
2708120b1162SLiam Howlett 	for (i = big_start; i < big_start + 10; i++) {
2709e15e06a8SLiam R. Howlett 		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
2710e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, false, 5);
2711e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2712120b1162SLiam Howlett 		rcu_barrier();
2713120b1162SLiam Howlett 		cond_resched();
2714120b1162SLiam Howlett 		mt_cache_shrink();
2715e15e06a8SLiam R. Howlett 	}
2716e15e06a8SLiam R. Howlett 
2717e15e06a8SLiam R. Howlett 	/* Check non-allocation tree not starting at zero */
2718e15e06a8SLiam R. Howlett 	for (i = 1500; i < 3000; i++) {
2719e15e06a8SLiam R. Howlett 		mt_init_flags(mt, 0);
2720e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, false, 5);
2721e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2722120b1162SLiam Howlett 		rcu_barrier();
2723120b1162SLiam Howlett 		cond_resched();
2724120b1162SLiam Howlett 		if (i % 2 == 0)
2725120b1162SLiam Howlett 			mt_cache_shrink();
2726e15e06a8SLiam R. Howlett 	}
2727e15e06a8SLiam R. Howlett 
2728120b1162SLiam Howlett 	mt_cache_shrink();
2729e15e06a8SLiam R. Howlett 	/* Check non-allocation tree starting at zero */
2730e15e06a8SLiam R. Howlett 	for (i = 200; i < 1000; i++) {
2731e15e06a8SLiam R. Howlett 		mt_init_flags(mt, 0);
2732e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2733e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2734120b1162SLiam Howlett 		rcu_barrier();
2735120b1162SLiam Howlett 		cond_resched();
2736e15e06a8SLiam R. Howlett 	}
2737e15e06a8SLiam R. Howlett 
2738120b1162SLiam Howlett 	mt_cache_shrink();
2739e15e06a8SLiam R. Howlett 	/* Unreasonably large */
2740120b1162SLiam Howlett 	for (i = big_start + 5; i < big_start + 10; i++) {
2741e15e06a8SLiam R. Howlett 		mt_init_flags(mt, 0);
2742e15e06a8SLiam R. Howlett 		check_dup_gaps(mt, i, true, 5);
2743e15e06a8SLiam R. Howlett 		mtree_destroy(mt);
2744120b1162SLiam Howlett 		rcu_barrier();
2745120b1162SLiam Howlett 		mt_cache_shrink();
2746120b1162SLiam Howlett 		cond_resched();
2747e15e06a8SLiam R. Howlett 	}
2748e15e06a8SLiam R. Howlett }
2749e15e06a8SLiam R. Howlett 
check_bnode_min_spanning(struct maple_tree * mt)2750eaf9790dSLiam R. Howlett static noinline void __init check_bnode_min_spanning(struct maple_tree *mt)
2751c5651b31SLiam Howlett {
2752c5651b31SLiam Howlett 	int i = 50;
2753c5651b31SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
2754c5651b31SLiam Howlett 
2755c5651b31SLiam Howlett 	mt_set_non_kernel(9999);
2756c5651b31SLiam Howlett 	mas_lock(&mas);
2757c5651b31SLiam Howlett 	do {
2758c5651b31SLiam Howlett 		mas_set_range(&mas, i*10, i*10+9);
2759c5651b31SLiam Howlett 		mas_store(&mas, check_bnode_min_spanning);
2760c5651b31SLiam Howlett 	} while (i--);
2761c5651b31SLiam Howlett 
2762c5651b31SLiam Howlett 	mas_set_range(&mas, 240, 509);
2763c5651b31SLiam Howlett 	mas_store(&mas, NULL);
2764c5651b31SLiam Howlett 	mas_unlock(&mas);
2765c5651b31SLiam Howlett 	mas_destroy(&mas);
2766c5651b31SLiam Howlett 	mt_set_non_kernel(0);
2767c5651b31SLiam Howlett }
2768c5651b31SLiam Howlett 
check_empty_area_window(struct maple_tree * mt)2769eaf9790dSLiam R. Howlett static noinline void __init check_empty_area_window(struct maple_tree *mt)
27707327e811SLiam Howlett {
27717327e811SLiam Howlett 	unsigned long i, nr_entries = 20;
27727327e811SLiam Howlett 	MA_STATE(mas, mt, 0, 0);
27737327e811SLiam Howlett 
27747327e811SLiam Howlett 	for (i = 1; i <= nr_entries; i++)
27757327e811SLiam Howlett 		mtree_store_range(mt, i*10, i*10 + 9,
27767327e811SLiam Howlett 				  xa_mk_value(i), GFP_KERNEL);
27777327e811SLiam Howlett 
27787327e811SLiam Howlett 	/* Create another hole besides the one at 0 */
27797327e811SLiam Howlett 	mtree_store_range(mt, 160, 169, NULL, GFP_KERNEL);
27807327e811SLiam Howlett 
27817327e811SLiam Howlett 	/* Check lower bounds that don't fit */
27827327e811SLiam Howlett 	rcu_read_lock();
27837327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 10) != -EBUSY);
27847327e811SLiam Howlett 
27857327e811SLiam Howlett 	mas_reset(&mas);
27867327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 6, 90, 5) != -EBUSY);
27877327e811SLiam Howlett 
27887327e811SLiam Howlett 	/* Check lower bound that does fit */
27897327e811SLiam Howlett 	mas_reset(&mas);
27907327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 5) != 0);
27917327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 5);
27927327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 9);
27937327e811SLiam Howlett 	rcu_read_unlock();
27947327e811SLiam Howlett 
27957327e811SLiam Howlett 	/* Check one gap that doesn't fit and one that does */
27967327e811SLiam Howlett 	rcu_read_lock();
27977327e811SLiam Howlett 	mas_reset(&mas);
27987327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 217, 9) != 0);
27997327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 161);
28007327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 169);
28017327e811SLiam Howlett 
28027327e811SLiam Howlett 	/* Check one gap that does fit above the min */
28037327e811SLiam Howlett 	mas_reset(&mas);
28047327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 3) != 0);
28057327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 216);
28067327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 218);
28077327e811SLiam Howlett 
28087327e811SLiam Howlett 	/* Check size that doesn't fit any gap */
28097327e811SLiam Howlett 	mas_reset(&mas);
28107327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 16) != -EBUSY);
28117327e811SLiam Howlett 
28127327e811SLiam Howlett 	/*
28137327e811SLiam Howlett 	 * Check size that doesn't fit the lower end of the window but
28147327e811SLiam Howlett 	 * does fit the gap
28157327e811SLiam Howlett 	 */
28167327e811SLiam Howlett 	mas_reset(&mas);
28177327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 167, 200, 4) != -EBUSY);
28187327e811SLiam Howlett 
28197327e811SLiam Howlett 	/*
28207327e811SLiam Howlett 	 * Check size that doesn't fit the upper end of the window but
28217327e811SLiam Howlett 	 * does fit the gap
28227327e811SLiam Howlett 	 */
28237327e811SLiam Howlett 	mas_reset(&mas);
28247327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 162, 4) != -EBUSY);
28257327e811SLiam Howlett 
28267327e811SLiam Howlett 	/* Check mas_empty_area forward */
28277327e811SLiam Howlett 	mas_reset(&mas);
28287327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 9) != 0);
28297327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 0);
28307327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 8);
28317327e811SLiam Howlett 
28327327e811SLiam Howlett 	mas_reset(&mas);
28337327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 4) != 0);
28347327e811SLiam Howlett 	MT_BUG_ON(mt, mas.index != 0);
28357327e811SLiam Howlett 	MT_BUG_ON(mt, mas.last != 3);
28367327e811SLiam Howlett 
28377327e811SLiam Howlett 	mas_reset(&mas);
28387327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 11) != -EBUSY);
28397327e811SLiam Howlett 
28407327e811SLiam Howlett 	mas_reset(&mas);
28417327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 5, 100, 6) != -EBUSY);
28427327e811SLiam Howlett 
28437327e811SLiam Howlett 	mas_reset(&mas);
284417e7436bSLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 8, 10) != -EINVAL);
28457327e811SLiam Howlett 
28467327e811SLiam Howlett 	mas_reset(&mas);
28477327e811SLiam Howlett 	mas_empty_area(&mas, 100, 165, 3);
28487327e811SLiam Howlett 
28497327e811SLiam Howlett 	mas_reset(&mas);
28507327e811SLiam Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 100, 163, 6) != -EBUSY);
28517327e811SLiam Howlett 	rcu_read_unlock();
28527327e811SLiam Howlett }
28537327e811SLiam Howlett 
check_empty_area_fill(struct maple_tree * mt)2854eaf9790dSLiam R. Howlett static noinline void __init check_empty_area_fill(struct maple_tree *mt)
28554bd6ddedSLiam R. Howlett {
28564bd6ddedSLiam R. Howlett 	const unsigned long max = 0x25D78000;
28574bd6ddedSLiam R. Howlett 	unsigned long size;
28584bd6ddedSLiam R. Howlett 	int loop, shift;
28594bd6ddedSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
28604bd6ddedSLiam R. Howlett 
28614bd6ddedSLiam R. Howlett 	mt_set_non_kernel(99999);
28624bd6ddedSLiam R. Howlett 	for (shift = 12; shift <= 16; shift++) {
28634bd6ddedSLiam R. Howlett 		loop = 5000;
28644bd6ddedSLiam R. Howlett 		size = 1 << shift;
28654bd6ddedSLiam R. Howlett 		while (loop--) {
28664bd6ddedSLiam R. Howlett 			mas_set(&mas, 0);
28674bd6ddedSLiam R. Howlett 			mas_lock(&mas);
28684bd6ddedSLiam R. Howlett 			MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != 0);
28694bd6ddedSLiam R. Howlett 			MT_BUG_ON(mt, mas.last != mas.index + size - 1);
28704bd6ddedSLiam R. Howlett 			mas_store_gfp(&mas, (void *)size, GFP_KERNEL);
28714bd6ddedSLiam R. Howlett 			mas_unlock(&mas);
28724bd6ddedSLiam R. Howlett 			mas_reset(&mas);
28734bd6ddedSLiam R. Howlett 		}
28744bd6ddedSLiam R. Howlett 	}
28754bd6ddedSLiam R. Howlett 
28764bd6ddedSLiam R. Howlett 	/* No space left. */
28774bd6ddedSLiam R. Howlett 	size = 0x1000;
28784bd6ddedSLiam R. Howlett 	rcu_read_lock();
28794bd6ddedSLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != -EBUSY);
28804bd6ddedSLiam R. Howlett 	rcu_read_unlock();
28814bd6ddedSLiam R. Howlett 
28824bd6ddedSLiam R. Howlett 	/* Fill a depth 3 node to the maximum */
28834bd6ddedSLiam R. Howlett 	for (unsigned long i = 629440511; i <= 629440800; i += 6)
28844bd6ddedSLiam R. Howlett 		mtree_store_range(mt, i, i + 5, (void *)i, GFP_KERNEL);
28854bd6ddedSLiam R. Howlett 	/* Make space in the second-last depth 4 node */
28864bd6ddedSLiam R. Howlett 	mtree_erase(mt, 631668735);
28874bd6ddedSLiam R. Howlett 	/* Make space in the last depth 4 node */
28884bd6ddedSLiam R. Howlett 	mtree_erase(mt, 629506047);
28894bd6ddedSLiam R. Howlett 	mas_reset(&mas);
28904bd6ddedSLiam R. Howlett 	/* Search from just after the gap in the second-last depth 4 */
28914bd6ddedSLiam R. Howlett 	rcu_read_lock();
28924bd6ddedSLiam R. Howlett 	MT_BUG_ON(mt, mas_empty_area(&mas, 629506048, 690000000, 0x5000) != 0);
28934bd6ddedSLiam R. Howlett 	rcu_read_unlock();
28944bd6ddedSLiam R. Howlett 	mt_set_non_kernel(0);
28954bd6ddedSLiam R. Howlett }
28964bd6ddedSLiam R. Howlett 
2897eb2e817fSLiam R. Howlett /*
2898eb2e817fSLiam R. Howlett  * Check MAS_START, MAS_PAUSE, active (implied), and MAS_NONE transitions.
2899eb2e817fSLiam R. Howlett  *
2900eb2e817fSLiam R. Howlett  * The table below shows the single entry tree (0-0 pointer) and normal tree
2901eb2e817fSLiam R. Howlett  * with nodes.
2902eb2e817fSLiam R. Howlett  *
2903eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
2904eb2e817fSLiam R. Howlett  *     ┬          ┬       ┬               ┬                ┬
2905eb2e817fSLiam R. Howlett  *     │          │       │               │                └─ the final range
2906eb2e817fSLiam R. Howlett  *     │          │       │               └─ The node value after execution
2907eb2e817fSLiam R. Howlett  *     │          │       └─ The node value before execution
2908eb2e817fSLiam R. Howlett  *     │          └─ If the entry exists or does not exists (DNE)
2909eb2e817fSLiam R. Howlett  *     └─ The function name
2910eb2e817fSLiam R. Howlett  *
2911eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
2912eb2e817fSLiam R. Howlett  * mas_next()
2913eb2e817fSLiam R. Howlett  *  - after last
2914eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
2915eb2e817fSLiam R. Howlett  *			------------------------
2916eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	1 - oo
2917eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	1 - oo
2918eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	1 - oo
2919eb2e817fSLiam R. Howlett  *			when index = 0
2920eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_ROOT	0
2921eb2e817fSLiam R. Howlett  *			when index > 0
2922eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	1 - oo
2923eb2e817fSLiam R. Howlett  *
2924eb2e817fSLiam R. Howlett  *			Normal tree
2925eb2e817fSLiam R. Howlett  *			-----------
2926eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
2927eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to last range
2928eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
2929eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to last range
2930eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	active		range
2931eb2e817fSLiam R. Howlett  *		exists	active		active		range
2932eb2e817fSLiam R. Howlett  *		DNE	active		active		set to last range
2933a8091f03SLiam R. Howlett  *		ERANGE	active		MAS_OVERFLOW	last range
2934eb2e817fSLiam R. Howlett  *
2935eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
2936eb2e817fSLiam R. Howlett  * mas_prev()
2937eb2e817fSLiam R. Howlett  * - before index
2938eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
2939eb2e817fSLiam R. Howlett  *			------------------------
2940eb2e817fSLiam R. Howlett  *				if index > 0
2941eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
2942eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
2943eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
2944eb2e817fSLiam R. Howlett  *
2945eb2e817fSLiam R. Howlett  *				if index == 0
2946eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	0
2947eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	0
2948eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	0
2949eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	0
2950eb2e817fSLiam R. Howlett  *
2951eb2e817fSLiam R. Howlett  *			Normal tree
2952eb2e817fSLiam R. Howlett  *			-----------
2953eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
2954eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to min
2955eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
2956eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to min
2957eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	active		range
2958eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	set to min
2959eb2e817fSLiam R. Howlett  *		any	MAS_ROOT	MAS_NONE	0
2960eb2e817fSLiam R. Howlett  *		exists	active		active		range
2961eb2e817fSLiam R. Howlett  *		DNE	active		active		last range
2962a8091f03SLiam R. Howlett  *		ERANGE	active		MAS_UNDERFLOW	last range
2963eb2e817fSLiam R. Howlett  *
2964eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
2965eb2e817fSLiam R. Howlett  * mas_find()
2966eb2e817fSLiam R. Howlett  *  - at index or next
2967eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
2968eb2e817fSLiam R. Howlett  *			------------------------
2969eb2e817fSLiam R. Howlett  *				if index >  0
2970eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	0
2971eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	0
2972eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	0
2973a8091f03SLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	1
2974eb2e817fSLiam R. Howlett  *				if index ==  0
2975eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
2976eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
2977eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
2978eb2e817fSLiam R. Howlett  *
2979eb2e817fSLiam R. Howlett  *			Normal tree
2980eb2e817fSLiam R. Howlett  *			-----------
2981eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
2982eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to max
2983eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
2984eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to max
2985a8091f03SLiam R. Howlett  *		exists	MAS_NONE	active		range (start at last)
2986eb2e817fSLiam R. Howlett  *		exists	active		active		range
2987eb2e817fSLiam R. Howlett  *		DNE	active		active		last range (max < last)
2988eb2e817fSLiam R. Howlett  *
2989eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
2990eb2e817fSLiam R. Howlett  * mas_find_rev()
2991eb2e817fSLiam R. Howlett  *  - at index or before
2992eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
2993eb2e817fSLiam R. Howlett  *			------------------------
2994eb2e817fSLiam R. Howlett  *				if index >  0
2995eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
2996eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
2997eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
2998eb2e817fSLiam R. Howlett  *				if index ==  0
2999eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_NONE	0
3000eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_NONE	0
3001eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_NONE	0
3002eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_NONE	0
3003eb2e817fSLiam R. Howlett  *
3004eb2e817fSLiam R. Howlett  *			Normal tree
3005eb2e817fSLiam R. Howlett  *			-----------
3006eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
3007eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		set to min
3008eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
3009eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		set to min
3010a8091f03SLiam R. Howlett  *		exists	MAS_NONE	active		range (start at index)
3011eb2e817fSLiam R. Howlett  *		exists	active		active		range
3012eb2e817fSLiam R. Howlett  *		DNE	active		active		last range (min > index)
3013eb2e817fSLiam R. Howlett  *
3014eb2e817fSLiam R. Howlett  * Function	ENTRY	Start		Result		index & last
3015eb2e817fSLiam R. Howlett  * mas_walk()
3016eb2e817fSLiam R. Howlett  * - Look up index
3017eb2e817fSLiam R. Howlett  *			Single entry tree at 0-0
3018eb2e817fSLiam R. Howlett  *			------------------------
3019eb2e817fSLiam R. Howlett  *				if index >  0
3020eb2e817fSLiam R. Howlett  *		DNE	MAS_START	MAS_ROOT	1 - oo
3021eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	MAS_ROOT	1 - oo
3022eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	MAS_ROOT	1 - oo
3023eb2e817fSLiam R. Howlett  *		DNE	MAS_ROOT	MAS_ROOT	1 - oo
3024eb2e817fSLiam R. Howlett  *				if index ==  0
3025eb2e817fSLiam R. Howlett  *		exists	MAS_START	MAS_ROOT	0
3026eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	MAS_ROOT	0
3027eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	MAS_ROOT	0
3028eb2e817fSLiam R. Howlett  *		exists	MAS_ROOT	MAS_ROOT	0
3029eb2e817fSLiam R. Howlett  *
3030eb2e817fSLiam R. Howlett  *			Normal tree
3031eb2e817fSLiam R. Howlett  *			-----------
3032eb2e817fSLiam R. Howlett  *		exists	MAS_START	active		range
3033eb2e817fSLiam R. Howlett  *		DNE	MAS_START	active		range of NULL
3034eb2e817fSLiam R. Howlett  *		exists	MAS_PAUSE	active		range
3035eb2e817fSLiam R. Howlett  *		DNE	MAS_PAUSE	active		range of NULL
3036eb2e817fSLiam R. Howlett  *		exists	MAS_NONE	active		range
3037eb2e817fSLiam R. Howlett  *		DNE	MAS_NONE	active		range of NULL
3038eb2e817fSLiam R. Howlett  *		exists	active		active		range
3039eb2e817fSLiam R. Howlett  *		DNE	active		active		range of NULL
3040eb2e817fSLiam R. Howlett  */
3041eb2e817fSLiam R. Howlett 
3042eb2e817fSLiam R. Howlett #define mas_active(x)		(((x).node != MAS_ROOT) && \
3043eb2e817fSLiam R. Howlett 				 ((x).node != MAS_START) && \
3044eb2e817fSLiam R. Howlett 				 ((x).node != MAS_PAUSE) && \
3045eb2e817fSLiam R. Howlett 				 ((x).node != MAS_NONE))
check_state_handling(struct maple_tree * mt)3046eb2e817fSLiam R. Howlett static noinline void __init check_state_handling(struct maple_tree *mt)
3047eb2e817fSLiam R. Howlett {
3048eb2e817fSLiam R. Howlett 	MA_STATE(mas, mt, 0, 0);
3049eb2e817fSLiam R. Howlett 	void *entry, *ptr = (void *) 0x1234500;
3050eb2e817fSLiam R. Howlett 	void *ptr2 = &ptr;
3051eb2e817fSLiam R. Howlett 	void *ptr3 = &ptr2;
3052eb2e817fSLiam R. Howlett 
3053eb2e817fSLiam R. Howlett 	/* Check MAS_ROOT First */
3054eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0, 0, ptr, GFP_KERNEL);
3055eb2e817fSLiam R. Howlett 
3056eb2e817fSLiam R. Howlett 	mas_lock(&mas);
3057a8091f03SLiam R. Howlett 	/* prev: Start -> underflow*/
3058eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3059eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3060a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
3061eb2e817fSLiam R. Howlett 
3062eb2e817fSLiam R. Howlett 	/* prev: Start -> root */
3063eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3064eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3065eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3066eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3067eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3068eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3069eb2e817fSLiam R. Howlett 
3070eb2e817fSLiam R. Howlett 	/* prev: pause -> root */
3071eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3072eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3073eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3074eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3075eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3076eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3077eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3078eb2e817fSLiam R. Howlett 
3079eb2e817fSLiam R. Howlett 	/* next: start -> none */
3080eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3081eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3082eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3083eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3084eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3085eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3086eb2e817fSLiam R. Howlett 
3087eb2e817fSLiam R. Howlett 	/* next: start -> none*/
3088eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3089eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3090eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3091eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3092eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3093eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3094eb2e817fSLiam R. Howlett 
3095eb2e817fSLiam R. Howlett 	/* find: start -> root */
3096eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3097eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3098eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3099eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3100eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3101eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3102eb2e817fSLiam R. Howlett 
3103eb2e817fSLiam R. Howlett 	/* find: root -> none */
3104eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3105eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3106eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3107eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3108eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3109eb2e817fSLiam R. Howlett 
3110eb2e817fSLiam R. Howlett 	/* find: none -> none */
3111eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3112eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3113eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3114eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3115eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3116eb2e817fSLiam R. Howlett 
3117eb2e817fSLiam R. Howlett 	/* find: start -> none */
3118eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3119eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3120eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3121eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3122eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3123eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3124eb2e817fSLiam R. Howlett 
3125eb2e817fSLiam R. Howlett 	/* find_rev: none -> root */
3126eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3127eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3128eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3129eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3130eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3131eb2e817fSLiam R. Howlett 
3132eb2e817fSLiam R. Howlett 	/* find_rev: start -> root */
3133eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3134eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3135eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3136eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3137eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3138eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3139eb2e817fSLiam R. Howlett 
3140eb2e817fSLiam R. Howlett 	/* find_rev: root -> none */
3141eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3142eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3143eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3144eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3145eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3146eb2e817fSLiam R. Howlett 
3147eb2e817fSLiam R. Howlett 	/* find_rev: none -> none */
3148eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3149eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3150eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3151eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3152eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3153eb2e817fSLiam R. Howlett 
3154eb2e817fSLiam R. Howlett 	/* find_rev: start -> root */
3155eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3156eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3157eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3158eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3159eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3160eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3161eb2e817fSLiam R. Howlett 
3162eb2e817fSLiam R. Howlett 	/* walk: start -> none */
3163eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3164eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3165eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3166eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3167eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3168eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3169eb2e817fSLiam R. Howlett 
3170eb2e817fSLiam R. Howlett 	/* walk: pause -> none*/
3171eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3172eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3173eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3174eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3175eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3176eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3177eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3178eb2e817fSLiam R. Howlett 
3179eb2e817fSLiam R. Howlett 	/* walk: none -> none */
3180eb2e817fSLiam R. Howlett 	mas.index = mas.last = 10;
3181eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3182eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3183eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3184eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3185eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3186eb2e817fSLiam R. Howlett 
3187eb2e817fSLiam R. Howlett 	/* walk: none -> none */
3188eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3189eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3190eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3191eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3192eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3193eb2e817fSLiam R. Howlett 
3194eb2e817fSLiam R. Howlett 	/* walk: start -> root */
3195eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3196eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3197eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3198eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3199eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3200eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3201eb2e817fSLiam R. Howlett 
3202eb2e817fSLiam R. Howlett 	/* walk: pause -> root */
3203eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3204eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3205eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3206eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3207eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3208eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3209eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3210eb2e817fSLiam R. Howlett 
3211eb2e817fSLiam R. Howlett 	/* walk: none -> root */
3212eb2e817fSLiam R. Howlett 	mas.node = MAS_NONE;
3213eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3214eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3215eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3216eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3217eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3218eb2e817fSLiam R. Howlett 
3219eb2e817fSLiam R. Howlett 	/* walk: root -> root */
3220eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3221eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3222eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3223eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3224eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3225eb2e817fSLiam R. Howlett 
3226eb2e817fSLiam R. Howlett 	/* walk: root -> none */
3227eb2e817fSLiam R. Howlett 	mas_set(&mas, 10);
3228eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3229eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3230eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 1);
3231eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3232eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_NONE);
3233eb2e817fSLiam R. Howlett 
3234eb2e817fSLiam R. Howlett 	/* walk: none -> root */
3235eb2e817fSLiam R. Howlett 	mas.index = mas.last = 0;
3236eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3237eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3238eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3239eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0);
3240eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_ROOT);
3241eb2e817fSLiam R. Howlett 
3242eb2e817fSLiam R. Howlett 	mas_unlock(&mas);
3243eb2e817fSLiam R. Howlett 
3244eb2e817fSLiam R. Howlett 	/* Check when there is an actual node */
3245eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0, 0, NULL, GFP_KERNEL);
3246eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0x1000, 0x1500, ptr, GFP_KERNEL);
3247eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0x2000, 0x2500, ptr2, GFP_KERNEL);
3248eb2e817fSLiam R. Howlett 	mtree_store_range(mt, 0x3000, 0x3500, ptr3, GFP_KERNEL);
3249eb2e817fSLiam R. Howlett 
3250eb2e817fSLiam R. Howlett 	mas_lock(&mas);
3251eb2e817fSLiam R. Howlett 
3252eb2e817fSLiam R. Howlett 	/* next: start ->active */
3253eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3254eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3255eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3256eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3257eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3258eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3259eb2e817fSLiam R. Howlett 
3260eb2e817fSLiam R. Howlett 	/* next: pause ->active */
3261eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3262eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3263eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3264eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3265eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3266eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3267eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3268eb2e817fSLiam R. Howlett 
3269eb2e817fSLiam R. Howlett 	/* next: none ->active */
3270eb2e817fSLiam R. Howlett 	mas.index = mas.last = 0;
3271eb2e817fSLiam R. Howlett 	mas.offset = 0;
3272eb2e817fSLiam R. Howlett 	mas.node = MAS_NONE;
3273eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3274eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3275eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3276eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3277eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3278eb2e817fSLiam R. Howlett 
3279eb2e817fSLiam R. Howlett 	/* next:active ->active */
3280eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3281eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3282eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3283eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3284eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3285eb2e817fSLiam R. Howlett 
3286a8091f03SLiam R. Howlett 	/* next:active -> active beyond data */
3287eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, 0x2999);
3288eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3289eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2501);
3290eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2fff);
3291eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3292eb2e817fSLiam R. Howlett 
3293a8091f03SLiam R. Howlett 	/* Continue after last range ends after max */
3294eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3295eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3296eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3297eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3298eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3299eb2e817fSLiam R. Howlett 
3300a8091f03SLiam R. Howlett 	/* next:active -> active continued */
3301eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3302eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3303eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3501);
3304eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3305eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3306eb2e817fSLiam R. Howlett 
3307a8091f03SLiam R. Howlett 	/* next:active -> overflow  */
3308a8091f03SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3309a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3310a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3501);
3311a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3312a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_OVERFLOW);
3313a8091f03SLiam R. Howlett 
3314a8091f03SLiam R. Howlett 	/* next:overflow -> overflow  */
3315a8091f03SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3316a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3317a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3501);
3318a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3319a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_OVERFLOW);
3320a8091f03SLiam R. Howlett 
3321a8091f03SLiam R. Howlett 	/* prev:overflow -> active  */
3322a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0);
3323a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3324a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3325a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3326a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3327a8091f03SLiam R. Howlett 
3328eb2e817fSLiam R. Howlett 	/* next: none -> active, skip value at location */
3329eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3330eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3331eb2e817fSLiam R. Howlett 	mas.node = MAS_NONE;
3332eb2e817fSLiam R. Howlett 	mas.offset = 0;
3333eb2e817fSLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3334eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3335eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3336eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3337eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3338eb2e817fSLiam R. Howlett 
3339eb2e817fSLiam R. Howlett 	/* prev:active ->active */
3340eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3341eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3342eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3343eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3344eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3345eb2e817fSLiam R. Howlett 
3346a8091f03SLiam R. Howlett 	/* prev:active -> active spanning end range */
3347a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0x0100);
3348a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3349a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3350a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3351a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3352a8091f03SLiam R. Howlett 
3353a8091f03SLiam R. Howlett 	/* prev:active -> underflow */
3354eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3355eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3356eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3357eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3358a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
3359a8091f03SLiam R. Howlett 
3360a8091f03SLiam R. Howlett 	/* prev:underflow -> underflow */
3361a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0);
3362a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3363a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3364a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3365a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
3366a8091f03SLiam R. Howlett 
3367a8091f03SLiam R. Howlett 	/* next:underflow -> active */
3368a8091f03SLiam R. Howlett 	entry = mas_next(&mas, ULONG_MAX);
3369a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3370a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3371a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3372a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3373a8091f03SLiam R. Howlett 
3374a8091f03SLiam R. Howlett 	/* prev:first value -> underflow */
3375a8091f03SLiam R. Howlett 	entry = mas_prev(&mas, 0x1000);
3376a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3377a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3378a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3379a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
3380a8091f03SLiam R. Howlett 
3381a8091f03SLiam R. Howlett 	/* find:underflow -> first value */
3382a8091f03SLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3383a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3384a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3385a8091f03SLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3386eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3387eb2e817fSLiam R. Howlett 
3388eb2e817fSLiam R. Howlett 	/* prev: pause ->active */
3389eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x3600);
3390eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3391eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3392eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3393eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3394eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3395eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3396eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3397eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3398eb2e817fSLiam R. Howlett 
3399a8091f03SLiam R. Howlett 	/* prev:active -> active spanning min */
3400eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0x1600);
3401eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3402eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3403eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1FFF);
3404eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3405eb2e817fSLiam R. Howlett 
3406eb2e817fSLiam R. Howlett 	/* prev: active ->active, continue */
3407eb2e817fSLiam R. Howlett 	entry = mas_prev(&mas, 0);
3408eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3409eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3410eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3411eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3412eb2e817fSLiam R. Howlett 
3413eb2e817fSLiam R. Howlett 	/* find: start ->active */
3414eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3415eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3416eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3417eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3418eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3419eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3420eb2e817fSLiam R. Howlett 
3421eb2e817fSLiam R. Howlett 	/* find: pause ->active */
3422eb2e817fSLiam R. Howlett 	mas_set(&mas, 0);
3423eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3424eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3425eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3426eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3427eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3428eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3429eb2e817fSLiam R. Howlett 
3430eb2e817fSLiam R. Howlett 	/* find: start ->active on value */;
3431eb2e817fSLiam R. Howlett 	mas_set(&mas, 1200);
3432eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3433eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3434eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3435eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3436eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3437eb2e817fSLiam R. Howlett 
3438eb2e817fSLiam R. Howlett 	/* find:active ->active */
3439eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3440eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3441eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3442eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3443eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3444eb2e817fSLiam R. Howlett 
3445eb2e817fSLiam R. Howlett 
3446eb2e817fSLiam R. Howlett 	/* find:active -> active (NULL)*/
3447eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, 0x2700);
3448eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3449eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2501);
3450eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2FFF);
3451eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3452eb2e817fSLiam R. Howlett 
3453a8091f03SLiam R. Howlett 	/* find: overflow ->active */
3454eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, 0x5000);
3455eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3456eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3457eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3458eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3459eb2e817fSLiam R. Howlett 
3460eb2e817fSLiam R. Howlett 	/* find:active -> active (NULL) end*/
3461eb2e817fSLiam R. Howlett 	entry = mas_find(&mas, ULONG_MAX);
3462eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3463eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3501);
3464eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != ULONG_MAX);
3465eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3466eb2e817fSLiam R. Howlett 
3467eb2e817fSLiam R. Howlett 	/* find_rev: active (END) ->active */
3468eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3469eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr3);
3470eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x3000);
3471eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x3500);
3472eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3473eb2e817fSLiam R. Howlett 
3474eb2e817fSLiam R. Howlett 	/* find_rev:active ->active */
3475eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3476eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr2);
3477eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x2000);
3478eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x2500);
3479eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3480eb2e817fSLiam R. Howlett 
3481eb2e817fSLiam R. Howlett 	/* find_rev: pause ->active */
3482eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3483eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3484eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3485eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3486eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3487eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3488eb2e817fSLiam R. Howlett 
3489eb2e817fSLiam R. Howlett 	/* find_rev:active -> active */
3490eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3491eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3492eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0);
3493eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x0FFF);
3494eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3495eb2e817fSLiam R. Howlett 
3496eb2e817fSLiam R. Howlett 	/* find_rev: start ->active */
3497eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3498eb2e817fSLiam R. Howlett 	entry = mas_find_rev(&mas, 0);
3499eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3500eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3501eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3502eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3503eb2e817fSLiam R. Howlett 
3504eb2e817fSLiam R. Howlett 	/* mas_walk start ->active */
3505eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3506eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3507eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3508eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3509eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3510eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3511eb2e817fSLiam R. Howlett 
3512eb2e817fSLiam R. Howlett 	/* mas_walk start ->active */
3513eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1600);
3514eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3515eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3516eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3517eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3518eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3519eb2e817fSLiam R. Howlett 
3520eb2e817fSLiam R. Howlett 	/* mas_walk pause ->active */
3521eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3522eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3523eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3524eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3525eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3526eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3527eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3528eb2e817fSLiam R. Howlett 
3529eb2e817fSLiam R. Howlett 	/* mas_walk pause -> active */
3530eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1600);
3531eb2e817fSLiam R. Howlett 	mas_pause(&mas);
3532eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3533eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3534eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3535eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3536eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3537eb2e817fSLiam R. Howlett 
3538eb2e817fSLiam R. Howlett 	/* mas_walk none -> active */
3539eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1200);
3540eb2e817fSLiam R. Howlett 	mas.node = MAS_NONE;
3541eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
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);
3545eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3546eb2e817fSLiam R. Howlett 
3547eb2e817fSLiam R. Howlett 	/* mas_walk none -> active */
3548eb2e817fSLiam R. Howlett 	mas_set(&mas, 0x1600);
3549eb2e817fSLiam R. Howlett 	mas.node = MAS_NONE;
3550eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3551eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3552eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3553eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3554eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3555eb2e817fSLiam R. Howlett 
3556eb2e817fSLiam R. Howlett 	/* mas_walk active -> active */
3557eb2e817fSLiam R. Howlett 	mas.index = 0x1200;
3558eb2e817fSLiam R. Howlett 	mas.last = 0x1200;
3559eb2e817fSLiam R. Howlett 	mas.offset = 0;
3560eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3561eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != ptr);
3562eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1000);
3563eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1500);
3564eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3565eb2e817fSLiam R. Howlett 
3566eb2e817fSLiam R. Howlett 	/* mas_walk active -> active */
3567eb2e817fSLiam R. Howlett 	mas.index = 0x1600;
3568eb2e817fSLiam R. Howlett 	mas.last = 0x1600;
3569eb2e817fSLiam R. Howlett 	entry = mas_walk(&mas);
3570eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, entry != NULL);
3571eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.index != 0x1501);
3572eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, mas.last != 0x1fff);
3573eb2e817fSLiam R. Howlett 	MT_BUG_ON(mt, !mas_active(mas));
3574eb2e817fSLiam R. Howlett 
3575eb2e817fSLiam R. Howlett 	mas_unlock(&mas);
3576eb2e817fSLiam R. Howlett }
3577eb2e817fSLiam R. Howlett 
3578e15e06a8SLiam R. Howlett static DEFINE_MTREE(tree);
maple_tree_seed(void)3579eaf9790dSLiam R. Howlett static int __init maple_tree_seed(void)
3580e15e06a8SLiam R. Howlett {
3581e15e06a8SLiam R. Howlett 	unsigned long set[] = { 5015, 5014, 5017, 25, 1000,
3582e15e06a8SLiam R. Howlett 				1001, 1002, 1003, 1005, 0,
3583e15e06a8SLiam R. Howlett 				5003, 5002};
3584e15e06a8SLiam R. Howlett 	void *ptr = &set;
3585e15e06a8SLiam R. Howlett 
3586e15e06a8SLiam R. Howlett 	pr_info("\nTEST STARTING\n\n");
3587e15e06a8SLiam R. Howlett 
3588e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3589e15e06a8SLiam R. Howlett 	check_root_expand(&tree);
3590e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3591e15e06a8SLiam R. Howlett 
3592e15e06a8SLiam R. Howlett #if defined(BENCH_SLOT_STORE)
3593e15e06a8SLiam R. Howlett #define BENCH
3594e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3595e15e06a8SLiam R. Howlett 	bench_slot_store(&tree);
3596e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3597e15e06a8SLiam R. Howlett 	goto skip;
3598e15e06a8SLiam R. Howlett #endif
3599e15e06a8SLiam R. Howlett #if defined(BENCH_NODE_STORE)
3600e15e06a8SLiam R. Howlett #define BENCH
3601e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3602e15e06a8SLiam R. Howlett 	bench_node_store(&tree);
3603e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3604e15e06a8SLiam R. Howlett 	goto skip;
3605e15e06a8SLiam R. Howlett #endif
3606e15e06a8SLiam R. Howlett #if defined(BENCH_AWALK)
3607e15e06a8SLiam R. Howlett #define BENCH
3608e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3609e15e06a8SLiam R. Howlett 	bench_awalk(&tree);
3610e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3611e15e06a8SLiam R. Howlett 	goto skip;
3612e15e06a8SLiam R. Howlett #endif
3613e15e06a8SLiam R. Howlett #if defined(BENCH_WALK)
3614e15e06a8SLiam R. Howlett #define BENCH
3615e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3616e15e06a8SLiam R. Howlett 	bench_walk(&tree);
3617e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3618e15e06a8SLiam R. Howlett 	goto skip;
3619e15e06a8SLiam R. Howlett #endif
3620e15e06a8SLiam R. Howlett #if defined(BENCH_FORK)
3621e15e06a8SLiam R. Howlett #define BENCH
3622e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3623e15e06a8SLiam R. Howlett 	bench_forking(&tree);
3624e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3625e15e06a8SLiam R. Howlett 	goto skip;
3626e15e06a8SLiam R. Howlett #endif
3627e15e06a8SLiam R. Howlett #if defined(BENCH_MT_FOR_EACH)
3628e15e06a8SLiam R. Howlett #define BENCH
3629e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3630e15e06a8SLiam R. Howlett 	bench_mt_for_each(&tree);
3631e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3632e15e06a8SLiam R. Howlett 	goto skip;
3633e15e06a8SLiam R. Howlett #endif
3634361c678bSLiam R. Howlett #if defined(BENCH_MAS_FOR_EACH)
3635361c678bSLiam R. Howlett #define BENCH
3636361c678bSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3637361c678bSLiam R. Howlett 	bench_mas_for_each(&tree);
3638361c678bSLiam R. Howlett 	mtree_destroy(&tree);
3639361c678bSLiam R. Howlett 	goto skip;
3640361c678bSLiam R. Howlett #endif
36418c314f3bSLiam R. Howlett #if defined(BENCH_MAS_PREV)
36428c314f3bSLiam R. Howlett #define BENCH
36438c314f3bSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
36448c314f3bSLiam R. Howlett 	bench_mas_prev(&tree);
36458c314f3bSLiam R. Howlett 	mtree_destroy(&tree);
36468c314f3bSLiam R. Howlett 	goto skip;
36478c314f3bSLiam R. Howlett #endif
3648e15e06a8SLiam R. Howlett 
3649e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
36505159d64bSLiam R. Howlett 	check_iteration(&tree);
36515159d64bSLiam R. Howlett 	mtree_destroy(&tree);
36525159d64bSLiam R. Howlett 
36535159d64bSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3654e15e06a8SLiam R. Howlett 	check_forking(&tree);
3655e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3656e15e06a8SLiam R. Howlett 
3657e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3658e15e06a8SLiam R. Howlett 	check_mas_store_gfp(&tree);
3659e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3660e15e06a8SLiam R. Howlett 
3661e15e06a8SLiam R. Howlett 	/* Test ranges (store and insert) */
3662e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3663e15e06a8SLiam R. Howlett 	check_ranges(&tree);
3664e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3665e15e06a8SLiam R. Howlett 
3666120b1162SLiam Howlett #if defined(CONFIG_64BIT)
3667120b1162SLiam Howlett 	/* These tests have ranges outside of 4GB */
3668e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3669e15e06a8SLiam R. Howlett 	check_alloc_range(&tree);
3670e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3671e15e06a8SLiam R. Howlett 
3672e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3673e15e06a8SLiam R. Howlett 	check_alloc_rev_range(&tree);
3674e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3675120b1162SLiam Howlett #endif
3676e15e06a8SLiam R. Howlett 
3677e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3678e15e06a8SLiam R. Howlett 
3679e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], NULL);       /* See if 5015 -> NULL */
3680e15e06a8SLiam R. Howlett 
3681e15e06a8SLiam R. Howlett 	check_insert(&tree, set[9], &tree);     /* Insert 0 */
3682e15e06a8SLiam R. Howlett 	check_load(&tree, set[9], &tree);       /* See if 0 -> &tree */
3683e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], NULL);       /* See if 5015 -> NULL */
3684e15e06a8SLiam R. Howlett 
3685e15e06a8SLiam R. Howlett 	check_insert(&tree, set[10], ptr);      /* Insert 5003 */
3686e15e06a8SLiam R. Howlett 	check_load(&tree, set[9], &tree);       /* See if 0 -> &tree */
3687e15e06a8SLiam R. Howlett 	check_load(&tree, set[11], NULL);       /* See if 5002 -> NULL */
3688e15e06a8SLiam R. Howlett 	check_load(&tree, set[10], ptr);       /* See if 5003 -> ptr */
3689e15e06a8SLiam R. Howlett 
3690e15e06a8SLiam R. Howlett 	/* Clear out the tree */
3691e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3692e15e06a8SLiam R. Howlett 
3693e15e06a8SLiam R. Howlett 	/* Try to insert, insert a dup, and load back what was inserted. */
3694e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3695e15e06a8SLiam R. Howlett 	check_insert(&tree, set[0], &tree);     /* Insert 5015 */
3696e15e06a8SLiam R. Howlett 	check_dup_insert(&tree, set[0], &tree); /* Insert 5015 again */
3697e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
3698e15e06a8SLiam R. Howlett 
3699e15e06a8SLiam R. Howlett 	/*
3700e15e06a8SLiam R. Howlett 	 * Second set of tests try to load a value that doesn't exist, inserts
3701e15e06a8SLiam R. Howlett 	 * a second value, then loads the value again
3702e15e06a8SLiam R. Howlett 	 */
3703e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], NULL);        /* See if 5014 -> NULL */
3704e15e06a8SLiam R. Howlett 	check_insert(&tree, set[1], ptr);       /* insert 5014 -> ptr */
3705e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], ptr);         /* See if 5014 -> ptr */
3706e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
3707e15e06a8SLiam R. Howlett 	/*
3708e15e06a8SLiam R. Howlett 	 * Tree currently contains:
3709e15e06a8SLiam R. Howlett 	 * p[0]: 14 -> (nil) p[1]: 15 -> ptr p[2]: 16 -> &tree p[3]: 0 -> (nil)
3710e15e06a8SLiam R. Howlett 	 */
3711e15e06a8SLiam R. Howlett 	check_insert(&tree, set[6], ptr);       /* insert 1002 -> ptr */
3712e15e06a8SLiam R. Howlett 	check_insert(&tree, set[7], &tree);       /* insert 1003 -> &tree */
3713e15e06a8SLiam R. Howlett 
3714e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
3715e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], ptr);         /* See if 5014 -> ptr */
3716e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);         /* See if 1002 -> ptr */
3717e15e06a8SLiam R. Howlett 	check_load(&tree, set[7], &tree);       /* 1003 = &tree ? */
3718e15e06a8SLiam R. Howlett 
3719e15e06a8SLiam R. Howlett 	/* Clear out tree */
3720e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3721e15e06a8SLiam R. Howlett 
3722e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3723e15e06a8SLiam R. Howlett 	/* Test inserting into a NULL hole. */
3724e15e06a8SLiam R. Howlett 	check_insert(&tree, set[5], ptr);       /* insert 1001 -> ptr */
3725e15e06a8SLiam R. Howlett 	check_insert(&tree, set[7], &tree);       /* insert 1003 -> &tree */
3726e15e06a8SLiam R. Howlett 	check_insert(&tree, set[6], ptr);       /* insert 1002 -> ptr */
3727e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], ptr);         /* See if 1001 -> ptr */
3728e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);         /* See if 1002 -> ptr */
3729e15e06a8SLiam R. Howlett 	check_load(&tree, set[7], &tree);       /* See if 1003 -> &tree */
3730e15e06a8SLiam R. Howlett 
3731e15e06a8SLiam R. Howlett 	/* Clear out the tree */
3732e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3733e15e06a8SLiam R. Howlett 
3734e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3735e15e06a8SLiam R. Howlett 	/*
3736e15e06a8SLiam R. Howlett 	 *       set[] = {5015, 5014, 5017, 25, 1000,
3737e15e06a8SLiam R. Howlett 	 *                1001, 1002, 1003, 1005, 0,
3738e15e06a8SLiam R. Howlett 	 *                5003, 5002};
3739e15e06a8SLiam R. Howlett 	 */
3740e15e06a8SLiam R. Howlett 
3741e15e06a8SLiam R. Howlett 	check_insert(&tree, set[0], ptr); /* 5015 */
3742e15e06a8SLiam R. Howlett 	check_insert(&tree, set[1], &tree); /* 5014 */
3743e15e06a8SLiam R. Howlett 	check_insert(&tree, set[2], ptr); /* 5017 */
3744e15e06a8SLiam R. Howlett 	check_insert(&tree, set[3], &tree); /* 25 */
3745e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3746e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3747e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3748e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3749e15e06a8SLiam R. Howlett 	check_insert(&tree, set[4], ptr); /* 1000 < Should split. */
3750e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3751e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3752e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3753e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree); /*25 */
3754e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3755e15e06a8SLiam R. Howlett 	check_insert(&tree, set[5], &tree); /* 1001 */
3756e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3757e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3758e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3759e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3760e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3761e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], &tree);
3762e15e06a8SLiam R. Howlett 	check_insert(&tree, set[6], ptr);
3763e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3764e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3765e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3766e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3767e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3768e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], &tree);
3769e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);
3770e15e06a8SLiam R. Howlett 	check_insert(&tree, set[7], &tree);
3771e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3772e15e06a8SLiam R. Howlett 	check_insert(&tree, set[8], ptr);
3773e15e06a8SLiam R. Howlett 
3774e15e06a8SLiam R. Howlett 	check_insert(&tree, set[9], &tree);
3775e15e06a8SLiam R. Howlett 
3776e15e06a8SLiam R. Howlett 	check_load(&tree, set[0], ptr);
3777e15e06a8SLiam R. Howlett 	check_load(&tree, set[1], &tree);
3778e15e06a8SLiam R. Howlett 	check_load(&tree, set[2], ptr);
3779e15e06a8SLiam R. Howlett 	check_load(&tree, set[3], &tree);
3780e15e06a8SLiam R. Howlett 	check_load(&tree, set[4], ptr);
3781e15e06a8SLiam R. Howlett 	check_load(&tree, set[5], &tree);
3782e15e06a8SLiam R. Howlett 	check_load(&tree, set[6], ptr);
3783e15e06a8SLiam R. Howlett 	check_load(&tree, set[9], &tree);
3784e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3785e15e06a8SLiam R. Howlett 
3786e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3787e15e06a8SLiam R. Howlett 	check_seq(&tree, 16, false);
3788e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3789e15e06a8SLiam R. Howlett 
3790e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3791e15e06a8SLiam R. Howlett 	check_seq(&tree, 1000, true);
3792e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3793e15e06a8SLiam R. Howlett 
3794e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3795e15e06a8SLiam R. Howlett 	check_rev_seq(&tree, 1000, true);
3796e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3797e15e06a8SLiam R. Howlett 
3798e15e06a8SLiam R. Howlett 	check_lower_bound_split(&tree);
3799e15e06a8SLiam R. Howlett 	check_upper_bound_split(&tree);
3800e15e06a8SLiam R. Howlett 	check_mid_split(&tree);
3801e15e06a8SLiam R. Howlett 
3802e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3803e15e06a8SLiam R. Howlett 	check_next_entry(&tree);
3804e15e06a8SLiam R. Howlett 	check_find(&tree);
3805e15e06a8SLiam R. Howlett 	check_find_2(&tree);
3806e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3807e15e06a8SLiam R. Howlett 
3808e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3809e15e06a8SLiam R. Howlett 	check_prev_entry(&tree);
3810e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3811e15e06a8SLiam R. Howlett 
3812e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3813e15e06a8SLiam R. Howlett 	check_gap_combining(&tree);
3814e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3815e15e06a8SLiam R. Howlett 
3816e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3817e15e06a8SLiam R. Howlett 	check_node_overwrite(&tree);
3818e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3819e15e06a8SLiam R. Howlett 
3820e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3821e15e06a8SLiam R. Howlett 	next_prev_test(&tree);
3822e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3823e15e06a8SLiam R. Howlett 
3824e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3825e15e06a8SLiam R. Howlett 	check_spanning_relatives(&tree);
3826e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3827e15e06a8SLiam R. Howlett 
3828e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3829e15e06a8SLiam R. Howlett 	check_rev_find(&tree);
3830e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3831e15e06a8SLiam R. Howlett 
3832e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, 0);
3833e15e06a8SLiam R. Howlett 	check_fuzzer(&tree);
3834e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3835e15e06a8SLiam R. Howlett 
3836e15e06a8SLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3837e15e06a8SLiam R. Howlett 	check_dup(&tree);
3838e15e06a8SLiam R. Howlett 	mtree_destroy(&tree);
3839e15e06a8SLiam R. Howlett 
3840c5651b31SLiam Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3841c5651b31SLiam Howlett 	check_bnode_min_spanning(&tree);
3842c5651b31SLiam Howlett 	mtree_destroy(&tree);
3843c5651b31SLiam Howlett 
38447327e811SLiam Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
38457327e811SLiam Howlett 	check_empty_area_window(&tree);
38467327e811SLiam Howlett 	mtree_destroy(&tree);
38477327e811SLiam Howlett 
38484bd6ddedSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
38494bd6ddedSLiam R. Howlett 	check_empty_area_fill(&tree);
38504bd6ddedSLiam R. Howlett 	mtree_destroy(&tree);
38514bd6ddedSLiam R. Howlett 
3852eb2e817fSLiam R. Howlett 	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
3853eb2e817fSLiam R. Howlett 	check_state_handling(&tree);
3854eb2e817fSLiam R. Howlett 	mtree_destroy(&tree);
3855eb2e817fSLiam R. Howlett 
3856e15e06a8SLiam R. Howlett #if defined(BENCH)
3857e15e06a8SLiam R. Howlett skip:
3858e15e06a8SLiam R. Howlett #endif
3859e15e06a8SLiam R. Howlett 	rcu_barrier();
3860e15e06a8SLiam R. Howlett 	pr_info("maple_tree: %u of %u tests passed\n",
3861e15e06a8SLiam R. Howlett 			atomic_read(&maple_tree_tests_passed),
3862e15e06a8SLiam R. Howlett 			atomic_read(&maple_tree_tests_run));
3863e15e06a8SLiam R. Howlett 	if (atomic_read(&maple_tree_tests_run) ==
3864e15e06a8SLiam R. Howlett 	    atomic_read(&maple_tree_tests_passed))
3865e15e06a8SLiam R. Howlett 		return 0;
3866e15e06a8SLiam R. Howlett 
3867e15e06a8SLiam R. Howlett 	return -EINVAL;
3868e15e06a8SLiam R. Howlett }
3869e15e06a8SLiam R. Howlett 
maple_tree_harvest(void)3870eaf9790dSLiam R. Howlett static void __exit maple_tree_harvest(void)
3871e15e06a8SLiam R. Howlett {
3872e15e06a8SLiam R. Howlett 
3873e15e06a8SLiam R. Howlett }
3874e15e06a8SLiam R. Howlett 
3875e15e06a8SLiam R. Howlett module_init(maple_tree_seed);
3876e15e06a8SLiam R. Howlett module_exit(maple_tree_harvest);
3877e15e06a8SLiam R. Howlett MODULE_AUTHOR("Liam R. Howlett <Liam.Howlett@Oracle.com>");
3878e15e06a8SLiam R. Howlett MODULE_LICENSE("GPL");
3879