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