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