162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * test_maple_tree.c: Test the maple tree API
462306a36Sopenharmony_ci * Copyright (c) 2018-2022 Oracle Corporation
562306a36Sopenharmony_ci * Author: Liam R. Howlett <Liam.Howlett@Oracle.com>
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Any tests that only require the interface of the tree.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/maple_tree.h>
1162306a36Sopenharmony_ci#include <linux/module.h>
1262306a36Sopenharmony_ci#include <linux/rwsem.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#define MTREE_ALLOC_MAX 0x2000000000000Ul
1562306a36Sopenharmony_ci#define CONFIG_MAPLE_SEARCH
1662306a36Sopenharmony_ci#define MAPLE_32BIT (MAPLE_NODE_SLOTS > 31)
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#ifndef CONFIG_DEBUG_MAPLE_TREE
1962306a36Sopenharmony_ci#define mt_dump(mt, fmt)		do {} while (0)
2062306a36Sopenharmony_ci#define mt_validate(mt)			do {} while (0)
2162306a36Sopenharmony_ci#define mt_cache_shrink()		do {} while (0)
2262306a36Sopenharmony_ci#define mas_dump(mas)			do {} while (0)
2362306a36Sopenharmony_ci#define mas_wr_dump(mas)		do {} while (0)
2462306a36Sopenharmony_ciatomic_t maple_tree_tests_run;
2562306a36Sopenharmony_ciatomic_t maple_tree_tests_passed;
2662306a36Sopenharmony_ci#undef MT_BUG_ON
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define MT_BUG_ON(__tree, __x) do {					\
2962306a36Sopenharmony_ci	atomic_inc(&maple_tree_tests_run);				\
3062306a36Sopenharmony_ci	if (__x) {							\
3162306a36Sopenharmony_ci		pr_info("BUG at %s:%d (%u)\n",				\
3262306a36Sopenharmony_ci		__func__, __LINE__, __x);				\
3362306a36Sopenharmony_ci		pr_info("Pass: %u Run:%u\n",				\
3462306a36Sopenharmony_ci			atomic_read(&maple_tree_tests_passed),		\
3562306a36Sopenharmony_ci			atomic_read(&maple_tree_tests_run));		\
3662306a36Sopenharmony_ci	} else {							\
3762306a36Sopenharmony_ci		atomic_inc(&maple_tree_tests_passed);			\
3862306a36Sopenharmony_ci	}								\
3962306a36Sopenharmony_ci} while (0)
4062306a36Sopenharmony_ci#endif
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci/* #define BENCH_SLOT_STORE */
4362306a36Sopenharmony_ci/* #define BENCH_NODE_STORE */
4462306a36Sopenharmony_ci/* #define BENCH_AWALK */
4562306a36Sopenharmony_ci/* #define BENCH_WALK */
4662306a36Sopenharmony_ci/* #define BENCH_MT_FOR_EACH */
4762306a36Sopenharmony_ci/* #define BENCH_FORK */
4862306a36Sopenharmony_ci/* #define BENCH_MAS_FOR_EACH */
4962306a36Sopenharmony_ci/* #define BENCH_MAS_PREV */
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#ifdef __KERNEL__
5262306a36Sopenharmony_ci#define mt_set_non_kernel(x)		do {} while (0)
5362306a36Sopenharmony_ci#define mt_zero_nr_tallocated(x)	do {} while (0)
5462306a36Sopenharmony_ci#else
5562306a36Sopenharmony_ci#define cond_resched()			do {} while (0)
5662306a36Sopenharmony_ci#endif
5762306a36Sopenharmony_cistatic int __init mtree_insert_index(struct maple_tree *mt,
5862306a36Sopenharmony_ci				     unsigned long index, gfp_t gfp)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	return mtree_insert(mt, index, xa_mk_value(index & LONG_MAX), gfp);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic void __init mtree_erase_index(struct maple_tree *mt, unsigned long index)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	MT_BUG_ON(mt, mtree_erase(mt, index) != xa_mk_value(index & LONG_MAX));
6662306a36Sopenharmony_ci	MT_BUG_ON(mt, mtree_load(mt, index) != NULL);
6762306a36Sopenharmony_ci}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic int __init mtree_test_insert(struct maple_tree *mt, unsigned long index,
7062306a36Sopenharmony_ci				void *ptr)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	return mtree_insert(mt, index, ptr, GFP_KERNEL);
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic int __init mtree_test_store_range(struct maple_tree *mt,
7662306a36Sopenharmony_ci			unsigned long start, unsigned long end, void *ptr)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	return mtree_store_range(mt, start, end, ptr, GFP_KERNEL);
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic int __init mtree_test_store(struct maple_tree *mt, unsigned long start,
8262306a36Sopenharmony_ci				void *ptr)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	return mtree_test_store_range(mt, start, start, ptr);
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic int __init mtree_test_insert_range(struct maple_tree *mt,
8862306a36Sopenharmony_ci			unsigned long start, unsigned long end, void *ptr)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	return mtree_insert_range(mt, start, end, ptr, GFP_KERNEL);
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic void __init *mtree_test_load(struct maple_tree *mt, unsigned long index)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	return mtree_load(mt, index);
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic void __init *mtree_test_erase(struct maple_tree *mt, unsigned long index)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	return mtree_erase(mt, index);
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci#if defined(CONFIG_64BIT)
10462306a36Sopenharmony_cistatic noinline void __init check_mtree_alloc_range(struct maple_tree *mt,
10562306a36Sopenharmony_ci		unsigned long start, unsigned long end, unsigned long size,
10662306a36Sopenharmony_ci		unsigned long expected, int eret, void *ptr)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	unsigned long result = expected + 1;
11062306a36Sopenharmony_ci	int ret;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	ret = mtree_alloc_range(mt, &result, ptr, size, start, end,
11362306a36Sopenharmony_ci			GFP_KERNEL);
11462306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != eret);
11562306a36Sopenharmony_ci	if (ret)
11662306a36Sopenharmony_ci		return;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	MT_BUG_ON(mt, result != expected);
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic noinline void __init check_mtree_alloc_rrange(struct maple_tree *mt,
12262306a36Sopenharmony_ci		unsigned long start, unsigned long end, unsigned long size,
12362306a36Sopenharmony_ci		unsigned long expected, int eret, void *ptr)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	unsigned long result = expected + 1;
12762306a36Sopenharmony_ci	int ret;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	ret = mtree_alloc_rrange(mt, &result, ptr, size, start, end,
13062306a36Sopenharmony_ci			GFP_KERNEL);
13162306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != eret);
13262306a36Sopenharmony_ci	if (ret)
13362306a36Sopenharmony_ci		return;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	MT_BUG_ON(mt, result != expected);
13662306a36Sopenharmony_ci}
13762306a36Sopenharmony_ci#endif
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_cistatic noinline void __init check_load(struct maple_tree *mt,
14062306a36Sopenharmony_ci				       unsigned long index, void *ptr)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	void *ret = mtree_test_load(mt, index);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	if (ret != ptr)
14562306a36Sopenharmony_ci		pr_err("Load %lu returned %p expect %p\n", index, ret, ptr);
14662306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != ptr);
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic noinline void __init check_store_range(struct maple_tree *mt,
15062306a36Sopenharmony_ci		unsigned long start, unsigned long end, void *ptr, int expected)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	int ret = -EINVAL;
15362306a36Sopenharmony_ci	unsigned long i;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	ret = mtree_test_store_range(mt, start, end, ptr);
15662306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != expected);
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	if (ret)
15962306a36Sopenharmony_ci		return;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	for (i = start; i <= end; i++)
16262306a36Sopenharmony_ci		check_load(mt, i, ptr);
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistatic noinline void __init check_insert_range(struct maple_tree *mt,
16662306a36Sopenharmony_ci		unsigned long start, unsigned long end, void *ptr, int expected)
16762306a36Sopenharmony_ci{
16862306a36Sopenharmony_ci	int ret = -EINVAL;
16962306a36Sopenharmony_ci	unsigned long i;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	ret = mtree_test_insert_range(mt, start, end, ptr);
17262306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != expected);
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	if (ret)
17562306a36Sopenharmony_ci		return;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	for (i = start; i <= end; i++)
17862306a36Sopenharmony_ci		check_load(mt, i, ptr);
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistatic noinline void __init check_insert(struct maple_tree *mt,
18262306a36Sopenharmony_ci					 unsigned long index, void *ptr)
18362306a36Sopenharmony_ci{
18462306a36Sopenharmony_ci	int ret = -EINVAL;
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	ret = mtree_test_insert(mt, index, ptr);
18762306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != 0);
18862306a36Sopenharmony_ci}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_cistatic noinline void __init check_dup_insert(struct maple_tree *mt,
19162306a36Sopenharmony_ci				      unsigned long index, void *ptr)
19262306a36Sopenharmony_ci{
19362306a36Sopenharmony_ci	int ret = -EINVAL;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	ret = mtree_test_insert(mt, index, ptr);
19662306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != -EEXIST);
19762306a36Sopenharmony_ci}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic noinline void __init check_index_load(struct maple_tree *mt,
20162306a36Sopenharmony_ci					     unsigned long index)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	return check_load(mt, index, xa_mk_value(index & LONG_MAX));
20462306a36Sopenharmony_ci}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_cistatic inline __init int not_empty(struct maple_node *node)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	int i;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	if (node->parent)
21162306a36Sopenharmony_ci		return 1;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(node->slot); i++)
21462306a36Sopenharmony_ci		if (node->slot[i])
21562306a36Sopenharmony_ci			return 1;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	return 0;
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistatic noinline void __init check_rev_seq(struct maple_tree *mt,
22262306a36Sopenharmony_ci					  unsigned long max, bool verbose)
22362306a36Sopenharmony_ci{
22462306a36Sopenharmony_ci	unsigned long i = max, j;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	mt_zero_nr_tallocated();
22962306a36Sopenharmony_ci	while (i) {
23062306a36Sopenharmony_ci		MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
23162306a36Sopenharmony_ci		for (j = i; j <= max; j++)
23262306a36Sopenharmony_ci			check_index_load(mt, j);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci		check_load(mt, i - 1, NULL);
23562306a36Sopenharmony_ci		mt_set_in_rcu(mt);
23662306a36Sopenharmony_ci		MT_BUG_ON(mt, !mt_height(mt));
23762306a36Sopenharmony_ci		mt_clear_in_rcu(mt);
23862306a36Sopenharmony_ci		MT_BUG_ON(mt, !mt_height(mt));
23962306a36Sopenharmony_ci		i--;
24062306a36Sopenharmony_ci	}
24162306a36Sopenharmony_ci	check_load(mt, max + 1, NULL);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci#ifndef __KERNEL__
24462306a36Sopenharmony_ci	if (verbose) {
24562306a36Sopenharmony_ci		rcu_barrier();
24662306a36Sopenharmony_ci		mt_dump(mt, mt_dump_dec);
24762306a36Sopenharmony_ci		pr_info(" %s test of 0-%lu %luK in %d active (%d total)\n",
24862306a36Sopenharmony_ci			__func__, max, mt_get_alloc_size()/1024, mt_nr_allocated(),
24962306a36Sopenharmony_ci			mt_nr_tallocated());
25062306a36Sopenharmony_ci	}
25162306a36Sopenharmony_ci#endif
25262306a36Sopenharmony_ci}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic noinline void __init check_seq(struct maple_tree *mt, unsigned long max,
25562306a36Sopenharmony_ci		bool verbose)
25662306a36Sopenharmony_ci{
25762306a36Sopenharmony_ci	unsigned long i, j;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	mt_zero_nr_tallocated();
26262306a36Sopenharmony_ci	for (i = 0; i <= max; i++) {
26362306a36Sopenharmony_ci		MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
26462306a36Sopenharmony_ci		for (j = 0; j <= i; j++)
26562306a36Sopenharmony_ci			check_index_load(mt, j);
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci		if (i)
26862306a36Sopenharmony_ci			MT_BUG_ON(mt, !mt_height(mt));
26962306a36Sopenharmony_ci		check_load(mt, i + 1, NULL);
27062306a36Sopenharmony_ci	}
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci#ifndef __KERNEL__
27362306a36Sopenharmony_ci	if (verbose) {
27462306a36Sopenharmony_ci		rcu_barrier();
27562306a36Sopenharmony_ci		mt_dump(mt, mt_dump_dec);
27662306a36Sopenharmony_ci		pr_info(" seq test of 0-%lu %luK in %d active (%d total)\n",
27762306a36Sopenharmony_ci			max, mt_get_alloc_size()/1024, mt_nr_allocated(),
27862306a36Sopenharmony_ci			mt_nr_tallocated());
27962306a36Sopenharmony_ci	}
28062306a36Sopenharmony_ci#endif
28162306a36Sopenharmony_ci}
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_cistatic noinline void __init check_lb_not_empty(struct maple_tree *mt)
28462306a36Sopenharmony_ci{
28562306a36Sopenharmony_ci	unsigned long i, j;
28662306a36Sopenharmony_ci	unsigned long huge = 4000UL * 1000 * 1000;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	i = huge;
29062306a36Sopenharmony_ci	while (i > 4096) {
29162306a36Sopenharmony_ci		check_insert(mt, i, (void *) i);
29262306a36Sopenharmony_ci		for (j = huge; j >= i; j /= 2) {
29362306a36Sopenharmony_ci			check_load(mt, j-1, NULL);
29462306a36Sopenharmony_ci			check_load(mt, j, (void *) j);
29562306a36Sopenharmony_ci			check_load(mt, j+1, NULL);
29662306a36Sopenharmony_ci		}
29762306a36Sopenharmony_ci		i /= 2;
29862306a36Sopenharmony_ci	}
29962306a36Sopenharmony_ci	mtree_destroy(mt);
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_cistatic noinline void __init check_lower_bound_split(struct maple_tree *mt)
30362306a36Sopenharmony_ci{
30462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
30562306a36Sopenharmony_ci	check_lb_not_empty(mt);
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_cistatic noinline void __init check_upper_bound_split(struct maple_tree *mt)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	unsigned long i, j;
31162306a36Sopenharmony_ci	unsigned long huge;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	if (MAPLE_32BIT)
31662306a36Sopenharmony_ci		huge = 2147483647UL;
31762306a36Sopenharmony_ci	else
31862306a36Sopenharmony_ci		huge = 4000UL * 1000 * 1000;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	i = 4096;
32162306a36Sopenharmony_ci	while (i < huge) {
32262306a36Sopenharmony_ci		check_insert(mt, i, (void *) i);
32362306a36Sopenharmony_ci		for (j = i; j >= huge; j *= 2) {
32462306a36Sopenharmony_ci			check_load(mt, j-1, NULL);
32562306a36Sopenharmony_ci			check_load(mt, j, (void *) j);
32662306a36Sopenharmony_ci			check_load(mt, j+1, NULL);
32762306a36Sopenharmony_ci		}
32862306a36Sopenharmony_ci		i *= 2;
32962306a36Sopenharmony_ci	}
33062306a36Sopenharmony_ci	mtree_destroy(mt);
33162306a36Sopenharmony_ci}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic noinline void __init check_mid_split(struct maple_tree *mt)
33462306a36Sopenharmony_ci{
33562306a36Sopenharmony_ci	unsigned long huge = 8000UL * 1000 * 1000;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	check_insert(mt, huge, (void *) huge);
33862306a36Sopenharmony_ci	check_insert(mt, 0, xa_mk_value(0));
33962306a36Sopenharmony_ci	check_lb_not_empty(mt);
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cistatic noinline void __init check_rev_find(struct maple_tree *mt)
34362306a36Sopenharmony_ci{
34462306a36Sopenharmony_ci	int i, nr_entries = 200;
34562306a36Sopenharmony_ci	void *val;
34662306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	for (i = 0; i <= nr_entries; i++)
34962306a36Sopenharmony_ci		mtree_store_range(mt, i*10, i*10 + 5,
35062306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	rcu_read_lock();
35362306a36Sopenharmony_ci	mas_set(&mas, 1000);
35462306a36Sopenharmony_ci	val = mas_find_rev(&mas, 1000);
35562306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(100));
35662306a36Sopenharmony_ci	val = mas_find_rev(&mas, 1000);
35762306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	mas_set(&mas, 999);
36062306a36Sopenharmony_ci	val = mas_find_rev(&mas, 997);
36162306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	mas_set(&mas, 1000);
36462306a36Sopenharmony_ci	val = mas_find_rev(&mas, 900);
36562306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(100));
36662306a36Sopenharmony_ci	val = mas_find_rev(&mas, 900);
36762306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(99));
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	mas_set(&mas, 20);
37062306a36Sopenharmony_ci	val = mas_find_rev(&mas, 0);
37162306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(2));
37262306a36Sopenharmony_ci	val = mas_find_rev(&mas, 0);
37362306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(1));
37462306a36Sopenharmony_ci	val = mas_find_rev(&mas, 0);
37562306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(0));
37662306a36Sopenharmony_ci	val = mas_find_rev(&mas, 0);
37762306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
37862306a36Sopenharmony_ci	rcu_read_unlock();
37962306a36Sopenharmony_ci}
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_cistatic noinline void __init check_find(struct maple_tree *mt)
38262306a36Sopenharmony_ci{
38362306a36Sopenharmony_ci	unsigned long val = 0;
38462306a36Sopenharmony_ci	unsigned long count;
38562306a36Sopenharmony_ci	unsigned long max;
38662306a36Sopenharmony_ci	unsigned long top;
38762306a36Sopenharmony_ci	unsigned long last = 0, index = 0;
38862306a36Sopenharmony_ci	void *entry, *entry2;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	/* Insert 0. */
39362306a36Sopenharmony_ci	MT_BUG_ON(mt, mtree_insert_index(mt, val++, GFP_KERNEL));
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci#if defined(CONFIG_64BIT)
39662306a36Sopenharmony_ci	top = 4398046511104UL;
39762306a36Sopenharmony_ci#else
39862306a36Sopenharmony_ci	top = ULONG_MAX;
39962306a36Sopenharmony_ci#endif
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	if (MAPLE_32BIT) {
40262306a36Sopenharmony_ci		count = 15;
40362306a36Sopenharmony_ci	} else {
40462306a36Sopenharmony_ci		count = 20;
40562306a36Sopenharmony_ci	}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	for (int i = 0; i <= count; i++) {
40862306a36Sopenharmony_ci		if (val != 64)
40962306a36Sopenharmony_ci			MT_BUG_ON(mt, mtree_insert_index(mt, val, GFP_KERNEL));
41062306a36Sopenharmony_ci		else
41162306a36Sopenharmony_ci			MT_BUG_ON(mt, mtree_insert(mt, val,
41262306a36Sopenharmony_ci				XA_ZERO_ENTRY, GFP_KERNEL));
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci		val <<= 2;
41562306a36Sopenharmony_ci	}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	val = 0;
41862306a36Sopenharmony_ci	mas_set(&mas, val);
41962306a36Sopenharmony_ci	mas_lock(&mas);
42062306a36Sopenharmony_ci	while ((entry = mas_find(&mas, 268435456)) != NULL) {
42162306a36Sopenharmony_ci		if (val != 64)
42262306a36Sopenharmony_ci			MT_BUG_ON(mt, xa_mk_value(val) != entry);
42362306a36Sopenharmony_ci		else
42462306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci		val <<= 2;
42762306a36Sopenharmony_ci		/* For zero check. */
42862306a36Sopenharmony_ci		if (!val)
42962306a36Sopenharmony_ci			val = 1;
43062306a36Sopenharmony_ci	}
43162306a36Sopenharmony_ci	mas_unlock(&mas);
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	val = 0;
43462306a36Sopenharmony_ci	mas_set(&mas, val);
43562306a36Sopenharmony_ci	mas_lock(&mas);
43662306a36Sopenharmony_ci	mas_for_each(&mas, entry, ULONG_MAX) {
43762306a36Sopenharmony_ci		if (val != 64)
43862306a36Sopenharmony_ci			MT_BUG_ON(mt, xa_mk_value(val) != entry);
43962306a36Sopenharmony_ci		else
44062306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
44162306a36Sopenharmony_ci		val <<= 2;
44262306a36Sopenharmony_ci		/* For zero check. */
44362306a36Sopenharmony_ci		if (!val)
44462306a36Sopenharmony_ci			val = 1;
44562306a36Sopenharmony_ci	}
44662306a36Sopenharmony_ci	mas_unlock(&mas);
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	/* Test mas_pause */
44962306a36Sopenharmony_ci	val = 0;
45062306a36Sopenharmony_ci	mas_set(&mas, val);
45162306a36Sopenharmony_ci	mas_lock(&mas);
45262306a36Sopenharmony_ci	mas_for_each(&mas, entry, ULONG_MAX) {
45362306a36Sopenharmony_ci		if (val != 64)
45462306a36Sopenharmony_ci			MT_BUG_ON(mt, xa_mk_value(val) != entry);
45562306a36Sopenharmony_ci		else
45662306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
45762306a36Sopenharmony_ci		val <<= 2;
45862306a36Sopenharmony_ci		/* For zero check. */
45962306a36Sopenharmony_ci		if (!val)
46062306a36Sopenharmony_ci			val = 1;
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci		mas_pause(&mas);
46362306a36Sopenharmony_ci		mas_unlock(&mas);
46462306a36Sopenharmony_ci		mas_lock(&mas);
46562306a36Sopenharmony_ci	}
46662306a36Sopenharmony_ci	mas_unlock(&mas);
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	val = 0;
46962306a36Sopenharmony_ci	max = 300; /* A value big enough to include XA_ZERO_ENTRY at 64. */
47062306a36Sopenharmony_ci	mt_for_each(mt, entry, index, max) {
47162306a36Sopenharmony_ci		MT_BUG_ON(mt, xa_mk_value(val) != entry);
47262306a36Sopenharmony_ci		val <<= 2;
47362306a36Sopenharmony_ci		if (val == 64) /* Skip zero entry. */
47462306a36Sopenharmony_ci			val <<= 2;
47562306a36Sopenharmony_ci		/* For zero check. */
47662306a36Sopenharmony_ci		if (!val)
47762306a36Sopenharmony_ci			val = 1;
47862306a36Sopenharmony_ci	}
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	val = 0;
48162306a36Sopenharmony_ci	max = 0;
48262306a36Sopenharmony_ci	index = 0;
48362306a36Sopenharmony_ci	MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
48462306a36Sopenharmony_ci	mt_for_each(mt, entry, index, ULONG_MAX) {
48562306a36Sopenharmony_ci		if (val == top)
48662306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != xa_mk_value(LONG_MAX));
48762306a36Sopenharmony_ci		else
48862306a36Sopenharmony_ci			MT_BUG_ON(mt, xa_mk_value(val) != entry);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci		/* Workaround for 32bit */
49162306a36Sopenharmony_ci		if ((val << 2) < val)
49262306a36Sopenharmony_ci			val = ULONG_MAX;
49362306a36Sopenharmony_ci		else
49462306a36Sopenharmony_ci			val <<= 2;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci		if (val == 64) /* Skip zero entry. */
49762306a36Sopenharmony_ci			val <<= 2;
49862306a36Sopenharmony_ci		/* For zero check. */
49962306a36Sopenharmony_ci		if (!val)
50062306a36Sopenharmony_ci			val = 1;
50162306a36Sopenharmony_ci		max++;
50262306a36Sopenharmony_ci		MT_BUG_ON(mt, max > 25);
50362306a36Sopenharmony_ci	}
50462306a36Sopenharmony_ci	mtree_erase_index(mt, ULONG_MAX);
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	mas_reset(&mas);
50762306a36Sopenharmony_ci	index = 17;
50862306a36Sopenharmony_ci	entry = mt_find(mt, &index, 512);
50962306a36Sopenharmony_ci	MT_BUG_ON(mt, xa_mk_value(256) != entry);
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	mas_reset(&mas);
51262306a36Sopenharmony_ci	index = 17;
51362306a36Sopenharmony_ci	entry = mt_find(mt, &index, 20);
51462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	/* Range check.. */
51862306a36Sopenharmony_ci	/* Insert ULONG_MAX */
51962306a36Sopenharmony_ci	MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	val = 0;
52262306a36Sopenharmony_ci	mas_set(&mas, 0);
52362306a36Sopenharmony_ci	mas_lock(&mas);
52462306a36Sopenharmony_ci	mas_for_each(&mas, entry, ULONG_MAX) {
52562306a36Sopenharmony_ci		if (val == 64)
52662306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
52762306a36Sopenharmony_ci		else if (val == top)
52862306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != xa_mk_value(LONG_MAX));
52962306a36Sopenharmony_ci		else
53062306a36Sopenharmony_ci			MT_BUG_ON(mt, xa_mk_value(val) != entry);
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci		/* Workaround for 32bit */
53362306a36Sopenharmony_ci		if ((val << 2) < val)
53462306a36Sopenharmony_ci			val = ULONG_MAX;
53562306a36Sopenharmony_ci		else
53662306a36Sopenharmony_ci			val <<= 2;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci		/* For zero check. */
53962306a36Sopenharmony_ci		if (!val)
54062306a36Sopenharmony_ci			val = 1;
54162306a36Sopenharmony_ci		mas_pause(&mas);
54262306a36Sopenharmony_ci		mas_unlock(&mas);
54362306a36Sopenharmony_ci		mas_lock(&mas);
54462306a36Sopenharmony_ci	}
54562306a36Sopenharmony_ci	mas_unlock(&mas);
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci	mas_set(&mas, 1048576);
54862306a36Sopenharmony_ci	mas_lock(&mas);
54962306a36Sopenharmony_ci	entry = mas_find(&mas, 1048576);
55062306a36Sopenharmony_ci	mas_unlock(&mas);
55162306a36Sopenharmony_ci	MT_BUG_ON(mas.tree, entry == NULL);
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	/*
55462306a36Sopenharmony_ci	 * Find last value.
55562306a36Sopenharmony_ci	 * 1. get the expected value, leveraging the existence of an end entry
55662306a36Sopenharmony_ci	 * 2. delete end entry
55762306a36Sopenharmony_ci	 * 3. find the last value but searching for ULONG_MAX and then using
55862306a36Sopenharmony_ci	 * prev
55962306a36Sopenharmony_ci	 */
56062306a36Sopenharmony_ci	/* First, get the expected result. */
56162306a36Sopenharmony_ci	mas_lock(&mas);
56262306a36Sopenharmony_ci	mas_reset(&mas);
56362306a36Sopenharmony_ci	mas.index = ULONG_MAX; /* start at max.. */
56462306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
56562306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
56662306a36Sopenharmony_ci	index = mas.index;
56762306a36Sopenharmony_ci	last = mas.last;
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	/* Erase the last entry. */
57062306a36Sopenharmony_ci	mas_reset(&mas);
57162306a36Sopenharmony_ci	mas.index = ULONG_MAX;
57262306a36Sopenharmony_ci	mas.last = ULONG_MAX;
57362306a36Sopenharmony_ci	mas_erase(&mas);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	/* Get the previous value from MAS_START */
57662306a36Sopenharmony_ci	mas_reset(&mas);
57762306a36Sopenharmony_ci	entry2 = mas_prev(&mas, 0);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	/* Check results. */
58062306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != entry2);
58162306a36Sopenharmony_ci	MT_BUG_ON(mt, index != mas.index);
58262306a36Sopenharmony_ci	MT_BUG_ON(mt, last != mas.last);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	mas.node = MAS_NONE;
58662306a36Sopenharmony_ci	mas.index = ULONG_MAX;
58762306a36Sopenharmony_ci	mas.last = ULONG_MAX;
58862306a36Sopenharmony_ci	entry2 = mas_prev(&mas, 0);
58962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != entry2);
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci	mas_set(&mas, 0);
59262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_prev(&mas, 0) != NULL);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	mas_unlock(&mas);
59562306a36Sopenharmony_ci	mtree_destroy(mt);
59662306a36Sopenharmony_ci}
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_cistatic noinline void __init check_find_2(struct maple_tree *mt)
59962306a36Sopenharmony_ci{
60062306a36Sopenharmony_ci	unsigned long i, j;
60162306a36Sopenharmony_ci	void *entry;
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
60462306a36Sopenharmony_ci	rcu_read_lock();
60562306a36Sopenharmony_ci	mas_for_each(&mas, entry, ULONG_MAX)
60662306a36Sopenharmony_ci		MT_BUG_ON(mt, true);
60762306a36Sopenharmony_ci	rcu_read_unlock();
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci	for (i = 0; i < 256; i++) {
61062306a36Sopenharmony_ci		mtree_insert_index(mt, i, GFP_KERNEL);
61162306a36Sopenharmony_ci		j = 0;
61262306a36Sopenharmony_ci		mas_set(&mas, 0);
61362306a36Sopenharmony_ci		rcu_read_lock();
61462306a36Sopenharmony_ci		mas_for_each(&mas, entry, ULONG_MAX) {
61562306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != xa_mk_value(j));
61662306a36Sopenharmony_ci			j++;
61762306a36Sopenharmony_ci		}
61862306a36Sopenharmony_ci		rcu_read_unlock();
61962306a36Sopenharmony_ci		MT_BUG_ON(mt, j != i + 1);
62062306a36Sopenharmony_ci	}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	for (i = 0; i < 256; i++) {
62362306a36Sopenharmony_ci		mtree_erase_index(mt, i);
62462306a36Sopenharmony_ci		j = i + 1;
62562306a36Sopenharmony_ci		mas_set(&mas, 0);
62662306a36Sopenharmony_ci		rcu_read_lock();
62762306a36Sopenharmony_ci		mas_for_each(&mas, entry, ULONG_MAX) {
62862306a36Sopenharmony_ci			if (xa_is_zero(entry))
62962306a36Sopenharmony_ci				continue;
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != xa_mk_value(j));
63262306a36Sopenharmony_ci			j++;
63362306a36Sopenharmony_ci		}
63462306a36Sopenharmony_ci		rcu_read_unlock();
63562306a36Sopenharmony_ci		MT_BUG_ON(mt, j != 256);
63662306a36Sopenharmony_ci	}
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	/*MT_BUG_ON(mt, !mtree_empty(mt)); */
63962306a36Sopenharmony_ci}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci#if defined(CONFIG_64BIT)
64362306a36Sopenharmony_cistatic noinline void __init check_alloc_rev_range(struct maple_tree *mt)
64462306a36Sopenharmony_ci{
64562306a36Sopenharmony_ci	/*
64662306a36Sopenharmony_ci	 * Generated by:
64762306a36Sopenharmony_ci	 * cat /proc/self/maps | awk '{print $1}'|
64862306a36Sopenharmony_ci	 * awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}'
64962306a36Sopenharmony_ci	 */
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci	static const unsigned long range[] = {
65262306a36Sopenharmony_ci	/*      Inclusive     , Exclusive. */
65362306a36Sopenharmony_ci		0x565234af2000, 0x565234af4000,
65462306a36Sopenharmony_ci		0x565234af4000, 0x565234af9000,
65562306a36Sopenharmony_ci		0x565234af9000, 0x565234afb000,
65662306a36Sopenharmony_ci		0x565234afc000, 0x565234afd000,
65762306a36Sopenharmony_ci		0x565234afd000, 0x565234afe000,
65862306a36Sopenharmony_ci		0x565235def000, 0x565235e10000,
65962306a36Sopenharmony_ci		0x7f36d4bfd000, 0x7f36d4ee2000,
66062306a36Sopenharmony_ci		0x7f36d4ee2000, 0x7f36d4f04000,
66162306a36Sopenharmony_ci		0x7f36d4f04000, 0x7f36d504c000,
66262306a36Sopenharmony_ci		0x7f36d504c000, 0x7f36d5098000,
66362306a36Sopenharmony_ci		0x7f36d5098000, 0x7f36d5099000,
66462306a36Sopenharmony_ci		0x7f36d5099000, 0x7f36d509d000,
66562306a36Sopenharmony_ci		0x7f36d509d000, 0x7f36d509f000,
66662306a36Sopenharmony_ci		0x7f36d509f000, 0x7f36d50a5000,
66762306a36Sopenharmony_ci		0x7f36d50b9000, 0x7f36d50db000,
66862306a36Sopenharmony_ci		0x7f36d50db000, 0x7f36d50dc000,
66962306a36Sopenharmony_ci		0x7f36d50dc000, 0x7f36d50fa000,
67062306a36Sopenharmony_ci		0x7f36d50fa000, 0x7f36d5102000,
67162306a36Sopenharmony_ci		0x7f36d5102000, 0x7f36d5103000,
67262306a36Sopenharmony_ci		0x7f36d5103000, 0x7f36d5104000,
67362306a36Sopenharmony_ci		0x7f36d5104000, 0x7f36d5105000,
67462306a36Sopenharmony_ci		0x7fff5876b000, 0x7fff5878d000,
67562306a36Sopenharmony_ci		0x7fff5878e000, 0x7fff58791000,
67662306a36Sopenharmony_ci		0x7fff58791000, 0x7fff58793000,
67762306a36Sopenharmony_ci	};
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	static const unsigned long holes[] = {
68062306a36Sopenharmony_ci		/*
68162306a36Sopenharmony_ci		 * Note: start of hole is INCLUSIVE
68262306a36Sopenharmony_ci		 *        end of hole is EXCLUSIVE
68362306a36Sopenharmony_ci		 *        (opposite of the above table.)
68462306a36Sopenharmony_ci		 * Start of hole, end of hole,  size of hole (+1)
68562306a36Sopenharmony_ci		 */
68662306a36Sopenharmony_ci		0x565234afb000, 0x565234afc000, 0x1000,
68762306a36Sopenharmony_ci		0x565234afe000, 0x565235def000, 0x12F1000,
68862306a36Sopenharmony_ci		0x565235e10000, 0x7f36d4bfd000, 0x28E49EDED000,
68962306a36Sopenharmony_ci	};
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci	/*
69262306a36Sopenharmony_ci	 * req_range consists of 4 values.
69362306a36Sopenharmony_ci	 * 1. min index
69462306a36Sopenharmony_ci	 * 2. max index
69562306a36Sopenharmony_ci	 * 3. size
69662306a36Sopenharmony_ci	 * 4. number that should be returned.
69762306a36Sopenharmony_ci	 * 5. return value
69862306a36Sopenharmony_ci	 */
69962306a36Sopenharmony_ci	static const unsigned long req_range[] = {
70062306a36Sopenharmony_ci		0x565234af9000, /* Min */
70162306a36Sopenharmony_ci		0x7fff58791000, /* Max */
70262306a36Sopenharmony_ci		0x1000,         /* Size */
70362306a36Sopenharmony_ci		0x7fff5878d << 12,  /* First rev hole of size 0x1000 */
70462306a36Sopenharmony_ci		0,              /* Return value success. */
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci		0x0,            /* Min */
70762306a36Sopenharmony_ci		0x565234AF0 << 12,    /* Max */
70862306a36Sopenharmony_ci		0x3000,         /* Size */
70962306a36Sopenharmony_ci		0x565234AEE << 12,  /* max - 3. */
71062306a36Sopenharmony_ci		0,              /* Return value success. */
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci		0x0,            /* Min */
71362306a36Sopenharmony_ci		-1,             /* Max */
71462306a36Sopenharmony_ci		0x1000,         /* Size */
71562306a36Sopenharmony_ci		562949953421311 << 12,/* First rev hole of size 0x1000 */
71662306a36Sopenharmony_ci		0,              /* Return value success. */
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci		0x0,            /* Min */
71962306a36Sopenharmony_ci		0x7F36D5109 << 12,    /* Max */
72062306a36Sopenharmony_ci		0x4000,         /* Size */
72162306a36Sopenharmony_ci		0x7F36D5106 << 12,    /* First rev hole of size 0x4000 */
72262306a36Sopenharmony_ci		0,              /* Return value success. */
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci		/* Ascend test. */
72562306a36Sopenharmony_ci		0x0,
72662306a36Sopenharmony_ci		34148798628 << 12,
72762306a36Sopenharmony_ci		19 << 12,
72862306a36Sopenharmony_ci		34148797418 << 12,
72962306a36Sopenharmony_ci		0x0,
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci		/* Too big test. */
73262306a36Sopenharmony_ci		0x0,
73362306a36Sopenharmony_ci		18446744073709551615UL,
73462306a36Sopenharmony_ci		562915594369134UL << 12,
73562306a36Sopenharmony_ci		0x0,
73662306a36Sopenharmony_ci		-EBUSY,
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci		/* Single space test. */
73962306a36Sopenharmony_ci		34148798725 << 12,
74062306a36Sopenharmony_ci		34148798725 << 12,
74162306a36Sopenharmony_ci		1 << 12,
74262306a36Sopenharmony_ci		34148798725 << 12,
74362306a36Sopenharmony_ci		0,
74462306a36Sopenharmony_ci	};
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	int i, range_count = ARRAY_SIZE(range);
74762306a36Sopenharmony_ci	int req_range_count = ARRAY_SIZE(req_range);
74862306a36Sopenharmony_ci	unsigned long min = 0;
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	mtree_store_range(mt, MTREE_ALLOC_MAX, ULONG_MAX, XA_ZERO_ENTRY,
75362306a36Sopenharmony_ci			  GFP_KERNEL);
75462306a36Sopenharmony_ci#define DEBUG_REV_RANGE 0
75562306a36Sopenharmony_ci	for (i = 0; i < range_count; i += 2) {
75662306a36Sopenharmony_ci		/* Inclusive, Inclusive (with the -1) */
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci#if DEBUG_REV_RANGE
75962306a36Sopenharmony_ci		pr_debug("\t%s: Insert %lu-%lu\n", __func__, range[i] >> 12,
76062306a36Sopenharmony_ci				(range[i + 1] >> 12) - 1);
76162306a36Sopenharmony_ci#endif
76262306a36Sopenharmony_ci		check_insert_range(mt, range[i] >> 12, (range[i + 1] >> 12) - 1,
76362306a36Sopenharmony_ci				xa_mk_value(range[i] >> 12), 0);
76462306a36Sopenharmony_ci		mt_validate(mt);
76562306a36Sopenharmony_ci	}
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci	mas_lock(&mas);
76962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(holes); i += 3) {
77062306a36Sopenharmony_ci#if DEBUG_REV_RANGE
77162306a36Sopenharmony_ci		pr_debug("Search from %lu-%lu for gap %lu should be at %lu\n",
77262306a36Sopenharmony_ci				min, holes[i+1]>>12, holes[i+2]>>12,
77362306a36Sopenharmony_ci				holes[i] >> 12);
77462306a36Sopenharmony_ci#endif
77562306a36Sopenharmony_ci		MT_BUG_ON(mt, mas_empty_area_rev(&mas, min,
77662306a36Sopenharmony_ci					holes[i+1] >> 12,
77762306a36Sopenharmony_ci					holes[i+2] >> 12));
77862306a36Sopenharmony_ci#if DEBUG_REV_RANGE
77962306a36Sopenharmony_ci		pr_debug("Found %lu %lu\n", mas.index, mas.last);
78062306a36Sopenharmony_ci		pr_debug("gap %lu %lu\n", (holes[i] >> 12),
78162306a36Sopenharmony_ci				(holes[i+1] >> 12));
78262306a36Sopenharmony_ci#endif
78362306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.last + 1 != (holes[i+1] >> 12));
78462306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.index != (holes[i+1] >> 12) - (holes[i+2] >> 12));
78562306a36Sopenharmony_ci		min = holes[i+1] >> 12;
78662306a36Sopenharmony_ci		mas_reset(&mas);
78762306a36Sopenharmony_ci	}
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci	mas_unlock(&mas);
79062306a36Sopenharmony_ci	for (i = 0; i < req_range_count; i += 5) {
79162306a36Sopenharmony_ci#if DEBUG_REV_RANGE
79262306a36Sopenharmony_ci		pr_debug("\tReverse request %d between %lu-%lu size %lu, should get %lu\n",
79362306a36Sopenharmony_ci				i, req_range[i] >> 12,
79462306a36Sopenharmony_ci				(req_range[i + 1] >> 12),
79562306a36Sopenharmony_ci				req_range[i+2] >> 12,
79662306a36Sopenharmony_ci				req_range[i+3] >> 12);
79762306a36Sopenharmony_ci#endif
79862306a36Sopenharmony_ci		check_mtree_alloc_rrange(mt,
79962306a36Sopenharmony_ci				req_range[i]   >> 12, /* start */
80062306a36Sopenharmony_ci				req_range[i+1] >> 12, /* end */
80162306a36Sopenharmony_ci				req_range[i+2] >> 12, /* size */
80262306a36Sopenharmony_ci				req_range[i+3] >> 12, /* expected address */
80362306a36Sopenharmony_ci				req_range[i+4],       /* expected return */
80462306a36Sopenharmony_ci				xa_mk_value(req_range[i] >> 12)); /* pointer */
80562306a36Sopenharmony_ci		mt_validate(mt);
80662306a36Sopenharmony_ci	}
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci	mt_set_non_kernel(1);
80962306a36Sopenharmony_ci	mtree_erase(mt, 34148798727); /* create a deleted range. */
81062306a36Sopenharmony_ci	mtree_erase(mt, 34148798725);
81162306a36Sopenharmony_ci	check_mtree_alloc_rrange(mt, 0, 34359052173, 210253414,
81262306a36Sopenharmony_ci			34148798725, 0, mt);
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci	mtree_destroy(mt);
81562306a36Sopenharmony_ci}
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_cistatic noinline void __init check_alloc_range(struct maple_tree *mt)
81862306a36Sopenharmony_ci{
81962306a36Sopenharmony_ci	/*
82062306a36Sopenharmony_ci	 * Generated by:
82162306a36Sopenharmony_ci	 * cat /proc/self/maps|awk '{print $1}'|
82262306a36Sopenharmony_ci	 * awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}'
82362306a36Sopenharmony_ci	 */
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	static const unsigned long range[] = {
82662306a36Sopenharmony_ci	/*      Inclusive     , Exclusive. */
82762306a36Sopenharmony_ci		0x565234af2000, 0x565234af4000,
82862306a36Sopenharmony_ci		0x565234af4000, 0x565234af9000,
82962306a36Sopenharmony_ci		0x565234af9000, 0x565234afb000,
83062306a36Sopenharmony_ci		0x565234afc000, 0x565234afd000,
83162306a36Sopenharmony_ci		0x565234afd000, 0x565234afe000,
83262306a36Sopenharmony_ci		0x565235def000, 0x565235e10000,
83362306a36Sopenharmony_ci		0x7f36d4bfd000, 0x7f36d4ee2000,
83462306a36Sopenharmony_ci		0x7f36d4ee2000, 0x7f36d4f04000,
83562306a36Sopenharmony_ci		0x7f36d4f04000, 0x7f36d504c000,
83662306a36Sopenharmony_ci		0x7f36d504c000, 0x7f36d5098000,
83762306a36Sopenharmony_ci		0x7f36d5098000, 0x7f36d5099000,
83862306a36Sopenharmony_ci		0x7f36d5099000, 0x7f36d509d000,
83962306a36Sopenharmony_ci		0x7f36d509d000, 0x7f36d509f000,
84062306a36Sopenharmony_ci		0x7f36d509f000, 0x7f36d50a5000,
84162306a36Sopenharmony_ci		0x7f36d50b9000, 0x7f36d50db000,
84262306a36Sopenharmony_ci		0x7f36d50db000, 0x7f36d50dc000,
84362306a36Sopenharmony_ci		0x7f36d50dc000, 0x7f36d50fa000,
84462306a36Sopenharmony_ci		0x7f36d50fa000, 0x7f36d5102000,
84562306a36Sopenharmony_ci		0x7f36d5102000, 0x7f36d5103000,
84662306a36Sopenharmony_ci		0x7f36d5103000, 0x7f36d5104000,
84762306a36Sopenharmony_ci		0x7f36d5104000, 0x7f36d5105000,
84862306a36Sopenharmony_ci		0x7fff5876b000, 0x7fff5878d000,
84962306a36Sopenharmony_ci		0x7fff5878e000, 0x7fff58791000,
85062306a36Sopenharmony_ci		0x7fff58791000, 0x7fff58793000,
85162306a36Sopenharmony_ci	};
85262306a36Sopenharmony_ci	static const unsigned long holes[] = {
85362306a36Sopenharmony_ci		/* Start of hole, end of hole,  size of hole (+1) */
85462306a36Sopenharmony_ci		0x565234afb000, 0x565234afc000, 0x1000,
85562306a36Sopenharmony_ci		0x565234afe000, 0x565235def000, 0x12F1000,
85662306a36Sopenharmony_ci		0x565235e10000, 0x7f36d4bfd000, 0x28E49EDED000,
85762306a36Sopenharmony_ci	};
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	/*
86062306a36Sopenharmony_ci	 * req_range consists of 4 values.
86162306a36Sopenharmony_ci	 * 1. min index
86262306a36Sopenharmony_ci	 * 2. max index
86362306a36Sopenharmony_ci	 * 3. size
86462306a36Sopenharmony_ci	 * 4. number that should be returned.
86562306a36Sopenharmony_ci	 * 5. return value
86662306a36Sopenharmony_ci	 */
86762306a36Sopenharmony_ci	static const unsigned long req_range[] = {
86862306a36Sopenharmony_ci		0x565234af9000, /* Min */
86962306a36Sopenharmony_ci		0x7fff58791000, /* Max */
87062306a36Sopenharmony_ci		0x1000,         /* Size */
87162306a36Sopenharmony_ci		0x565234afb000, /* First hole in our data of size 1000. */
87262306a36Sopenharmony_ci		0,              /* Return value success. */
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci		0x0,            /* Min */
87562306a36Sopenharmony_ci		0x7fff58791000, /* Max */
87662306a36Sopenharmony_ci		0x1F00,         /* Size */
87762306a36Sopenharmony_ci		0x0,            /* First hole in our data of size 2000. */
87862306a36Sopenharmony_ci		0,              /* Return value success. */
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci		/* Test ascend. */
88162306a36Sopenharmony_ci		34148797436 << 12, /* Min */
88262306a36Sopenharmony_ci		0x7fff587AF000,    /* Max */
88362306a36Sopenharmony_ci		0x3000,         /* Size */
88462306a36Sopenharmony_ci		34148798629 << 12,             /* Expected location */
88562306a36Sopenharmony_ci		0,              /* Return value success. */
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci		/* Test failing. */
88862306a36Sopenharmony_ci		34148798623 << 12,  /* Min */
88962306a36Sopenharmony_ci		34148798683 << 12,  /* Max */
89062306a36Sopenharmony_ci		0x15000,            /* Size */
89162306a36Sopenharmony_ci		0,             /* Expected location */
89262306a36Sopenharmony_ci		-EBUSY,              /* Return value failed. */
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci		/* Test filling entire gap. */
89562306a36Sopenharmony_ci		34148798623 << 12,  /* Min */
89662306a36Sopenharmony_ci		0x7fff587AF000,    /* Max */
89762306a36Sopenharmony_ci		0x10000,           /* Size */
89862306a36Sopenharmony_ci		34148798632 << 12,             /* Expected location */
89962306a36Sopenharmony_ci		0,              /* Return value success. */
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci		/* Test walking off the end of root. */
90262306a36Sopenharmony_ci		0,                  /* Min */
90362306a36Sopenharmony_ci		-1,                 /* Max */
90462306a36Sopenharmony_ci		-1,                 /* Size */
90562306a36Sopenharmony_ci		0,                  /* Expected location */
90662306a36Sopenharmony_ci		-EBUSY,             /* Return value failure. */
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci		/* Test looking for too large a hole across entire range. */
90962306a36Sopenharmony_ci		0,                  /* Min */
91062306a36Sopenharmony_ci		-1,                 /* Max */
91162306a36Sopenharmony_ci		4503599618982063UL << 12,  /* Size */
91262306a36Sopenharmony_ci		34359052178 << 12,  /* Expected location */
91362306a36Sopenharmony_ci		-EBUSY,             /* Return failure. */
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci		/* Test a single entry */
91662306a36Sopenharmony_ci		34148798648 << 12,		/* Min */
91762306a36Sopenharmony_ci		34148798648 << 12,		/* Max */
91862306a36Sopenharmony_ci		4096,			/* Size of 1 */
91962306a36Sopenharmony_ci		34148798648 << 12,	/* Location is the same as min/max */
92062306a36Sopenharmony_ci		0,			/* Success */
92162306a36Sopenharmony_ci	};
92262306a36Sopenharmony_ci	int i, range_count = ARRAY_SIZE(range);
92362306a36Sopenharmony_ci	int req_range_count = ARRAY_SIZE(req_range);
92462306a36Sopenharmony_ci	unsigned long min = 0x565234af2000;
92562306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci	mtree_store_range(mt, MTREE_ALLOC_MAX, ULONG_MAX, XA_ZERO_ENTRY,
92862306a36Sopenharmony_ci			  GFP_KERNEL);
92962306a36Sopenharmony_ci	for (i = 0; i < range_count; i += 2) {
93062306a36Sopenharmony_ci#define DEBUG_ALLOC_RANGE 0
93162306a36Sopenharmony_ci#if DEBUG_ALLOC_RANGE
93262306a36Sopenharmony_ci		pr_debug("\tInsert %lu-%lu\n", range[i] >> 12,
93362306a36Sopenharmony_ci			 (range[i + 1] >> 12) - 1);
93462306a36Sopenharmony_ci		mt_dump(mt, mt_dump_hex);
93562306a36Sopenharmony_ci#endif
93662306a36Sopenharmony_ci		check_insert_range(mt, range[i] >> 12, (range[i + 1] >> 12) - 1,
93762306a36Sopenharmony_ci				xa_mk_value(range[i] >> 12), 0);
93862306a36Sopenharmony_ci		mt_validate(mt);
93962306a36Sopenharmony_ci	}
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci	mas_lock(&mas);
94462306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(holes); i += 3) {
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci#if DEBUG_ALLOC_RANGE
94762306a36Sopenharmony_ci		pr_debug("\tGet empty %lu-%lu size %lu (%lx-%lx)\n", min >> 12,
94862306a36Sopenharmony_ci			holes[i+1] >> 12, holes[i+2] >> 12,
94962306a36Sopenharmony_ci			min, holes[i+1]);
95062306a36Sopenharmony_ci#endif
95162306a36Sopenharmony_ci		MT_BUG_ON(mt, mas_empty_area(&mas, min >> 12,
95262306a36Sopenharmony_ci					holes[i+1] >> 12,
95362306a36Sopenharmony_ci					holes[i+2] >> 12));
95462306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.index != holes[i] >> 12);
95562306a36Sopenharmony_ci		min = holes[i+1];
95662306a36Sopenharmony_ci		mas_reset(&mas);
95762306a36Sopenharmony_ci	}
95862306a36Sopenharmony_ci	mas_unlock(&mas);
95962306a36Sopenharmony_ci	for (i = 0; i < req_range_count; i += 5) {
96062306a36Sopenharmony_ci#if DEBUG_ALLOC_RANGE
96162306a36Sopenharmony_ci		pr_debug("\tTest %d: %lu-%lu size %lu expected %lu (%lu-%lu)\n",
96262306a36Sopenharmony_ci			 i/5, req_range[i]   >> 12, req_range[i + 1]   >> 12,
96362306a36Sopenharmony_ci			 req_range[i + 2]   >> 12, req_range[i + 3]   >> 12,
96462306a36Sopenharmony_ci			 req_range[i], req_range[i+1]);
96562306a36Sopenharmony_ci#endif
96662306a36Sopenharmony_ci		check_mtree_alloc_range(mt,
96762306a36Sopenharmony_ci				req_range[i]   >> 12, /* start */
96862306a36Sopenharmony_ci				req_range[i+1] >> 12, /* end */
96962306a36Sopenharmony_ci				req_range[i+2] >> 12, /* size */
97062306a36Sopenharmony_ci				req_range[i+3] >> 12, /* expected address */
97162306a36Sopenharmony_ci				req_range[i+4],       /* expected return */
97262306a36Sopenharmony_ci				xa_mk_value(req_range[i] >> 12)); /* pointer */
97362306a36Sopenharmony_ci		mt_validate(mt);
97462306a36Sopenharmony_ci#if DEBUG_ALLOC_RANGE
97562306a36Sopenharmony_ci		mt_dump(mt, mt_dump_hex);
97662306a36Sopenharmony_ci#endif
97762306a36Sopenharmony_ci	}
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	mtree_destroy(mt);
98062306a36Sopenharmony_ci}
98162306a36Sopenharmony_ci#endif
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_cistatic noinline void __init check_ranges(struct maple_tree *mt)
98462306a36Sopenharmony_ci{
98562306a36Sopenharmony_ci	int i, val, val2;
98662306a36Sopenharmony_ci	static const unsigned long r[] = {
98762306a36Sopenharmony_ci		10, 15,
98862306a36Sopenharmony_ci		20, 25,
98962306a36Sopenharmony_ci		17, 22, /* Overlaps previous range. */
99062306a36Sopenharmony_ci		9, 1000, /* Huge. */
99162306a36Sopenharmony_ci		100, 200,
99262306a36Sopenharmony_ci		45, 168,
99362306a36Sopenharmony_ci		118, 128,
99462306a36Sopenharmony_ci			};
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
99762306a36Sopenharmony_ci	check_insert_range(mt, r[0], r[1], xa_mk_value(r[0]), 0);
99862306a36Sopenharmony_ci	check_insert_range(mt, r[2], r[3], xa_mk_value(r[2]), 0);
99962306a36Sopenharmony_ci	check_insert_range(mt, r[4], r[5], xa_mk_value(r[4]), -EEXIST);
100062306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
100162306a36Sopenharmony_ci	/* Store */
100262306a36Sopenharmony_ci	check_store_range(mt, r[4], r[5], xa_mk_value(r[4]), 0);
100362306a36Sopenharmony_ci	check_store_range(mt, r[6], r[7], xa_mk_value(r[6]), 0);
100462306a36Sopenharmony_ci	check_store_range(mt, r[8], r[9], xa_mk_value(r[8]), 0);
100562306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
100662306a36Sopenharmony_ci	mtree_destroy(mt);
100762306a36Sopenharmony_ci	MT_BUG_ON(mt, mt_height(mt));
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	check_seq(mt, 50, false);
101062306a36Sopenharmony_ci	mt_set_non_kernel(4);
101162306a36Sopenharmony_ci	check_store_range(mt, 5, 47,  xa_mk_value(47), 0);
101262306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
101362306a36Sopenharmony_ci	mtree_destroy(mt);
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	/* Create tree of 1-100 */
101662306a36Sopenharmony_ci	check_seq(mt, 100, false);
101762306a36Sopenharmony_ci	/* Store 45-168 */
101862306a36Sopenharmony_ci	mt_set_non_kernel(10);
101962306a36Sopenharmony_ci	check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
102062306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
102162306a36Sopenharmony_ci	mtree_destroy(mt);
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	/* Create tree of 1-200 */
102462306a36Sopenharmony_ci	check_seq(mt, 200, false);
102562306a36Sopenharmony_ci	/* Store 45-168 */
102662306a36Sopenharmony_ci	check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
102762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
102862306a36Sopenharmony_ci	mtree_destroy(mt);
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	check_seq(mt, 30, false);
103162306a36Sopenharmony_ci	check_store_range(mt, 6, 18, xa_mk_value(6), 0);
103262306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
103362306a36Sopenharmony_ci	mtree_destroy(mt);
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ci	/* Overwrite across multiple levels. */
103662306a36Sopenharmony_ci	/* Create tree of 1-400 */
103762306a36Sopenharmony_ci	check_seq(mt, 400, false);
103862306a36Sopenharmony_ci	mt_set_non_kernel(50);
103962306a36Sopenharmony_ci	/* Store 118-128 */
104062306a36Sopenharmony_ci	check_store_range(mt, r[12], r[13], xa_mk_value(r[12]), 0);
104162306a36Sopenharmony_ci	mt_set_non_kernel(50);
104262306a36Sopenharmony_ci	mtree_test_erase(mt, 140);
104362306a36Sopenharmony_ci	mtree_test_erase(mt, 141);
104462306a36Sopenharmony_ci	mtree_test_erase(mt, 142);
104562306a36Sopenharmony_ci	mtree_test_erase(mt, 143);
104662306a36Sopenharmony_ci	mtree_test_erase(mt, 130);
104762306a36Sopenharmony_ci	mtree_test_erase(mt, 131);
104862306a36Sopenharmony_ci	mtree_test_erase(mt, 132);
104962306a36Sopenharmony_ci	mtree_test_erase(mt, 133);
105062306a36Sopenharmony_ci	mtree_test_erase(mt, 134);
105162306a36Sopenharmony_ci	mtree_test_erase(mt, 135);
105262306a36Sopenharmony_ci	check_load(mt, r[12], xa_mk_value(r[12]));
105362306a36Sopenharmony_ci	check_load(mt, r[13], xa_mk_value(r[12]));
105462306a36Sopenharmony_ci	check_load(mt, r[13] - 1, xa_mk_value(r[12]));
105562306a36Sopenharmony_ci	check_load(mt, r[13] + 1, xa_mk_value(r[13] + 1));
105662306a36Sopenharmony_ci	check_load(mt, 135, NULL);
105762306a36Sopenharmony_ci	check_load(mt, 140, NULL);
105862306a36Sopenharmony_ci	mt_set_non_kernel(0);
105962306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
106062306a36Sopenharmony_ci	mtree_destroy(mt);
106162306a36Sopenharmony_ci
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_ci	/* Overwrite multiple levels at the end of the tree (slot 7) */
106562306a36Sopenharmony_ci	mt_set_non_kernel(50);
106662306a36Sopenharmony_ci	check_seq(mt, 400, false);
106762306a36Sopenharmony_ci	check_store_range(mt, 353, 361, xa_mk_value(353), 0);
106862306a36Sopenharmony_ci	check_store_range(mt, 347, 352, xa_mk_value(347), 0);
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci	check_load(mt, 346, xa_mk_value(346));
107162306a36Sopenharmony_ci	for (i = 347; i <= 352; i++)
107262306a36Sopenharmony_ci		check_load(mt, i, xa_mk_value(347));
107362306a36Sopenharmony_ci	for (i = 353; i <= 361; i++)
107462306a36Sopenharmony_ci		check_load(mt, i, xa_mk_value(353));
107562306a36Sopenharmony_ci	check_load(mt, 362, xa_mk_value(362));
107662306a36Sopenharmony_ci	mt_set_non_kernel(0);
107762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
107862306a36Sopenharmony_ci	mtree_destroy(mt);
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci	mt_set_non_kernel(50);
108162306a36Sopenharmony_ci	check_seq(mt, 400, false);
108262306a36Sopenharmony_ci	check_store_range(mt, 352, 364, NULL, 0);
108362306a36Sopenharmony_ci	check_store_range(mt, 351, 363, xa_mk_value(352), 0);
108462306a36Sopenharmony_ci	check_load(mt, 350, xa_mk_value(350));
108562306a36Sopenharmony_ci	check_load(mt, 351, xa_mk_value(352));
108662306a36Sopenharmony_ci	for (i = 352; i <= 363; i++)
108762306a36Sopenharmony_ci		check_load(mt, i, xa_mk_value(352));
108862306a36Sopenharmony_ci	check_load(mt, 364, NULL);
108962306a36Sopenharmony_ci	check_load(mt, 365, xa_mk_value(365));
109062306a36Sopenharmony_ci	mt_set_non_kernel(0);
109162306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
109262306a36Sopenharmony_ci	mtree_destroy(mt);
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci	mt_set_non_kernel(5);
109562306a36Sopenharmony_ci	check_seq(mt, 400, false);
109662306a36Sopenharmony_ci	check_store_range(mt, 352, 364, NULL, 0);
109762306a36Sopenharmony_ci	check_store_range(mt, 351, 364, xa_mk_value(352), 0);
109862306a36Sopenharmony_ci	check_load(mt, 350, xa_mk_value(350));
109962306a36Sopenharmony_ci	check_load(mt, 351, xa_mk_value(352));
110062306a36Sopenharmony_ci	for (i = 352; i <= 364; i++)
110162306a36Sopenharmony_ci		check_load(mt, i, xa_mk_value(352));
110262306a36Sopenharmony_ci	check_load(mt, 365, xa_mk_value(365));
110362306a36Sopenharmony_ci	mt_set_non_kernel(0);
110462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
110562306a36Sopenharmony_ci	mtree_destroy(mt);
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci	mt_set_non_kernel(50);
110962306a36Sopenharmony_ci	check_seq(mt, 400, false);
111062306a36Sopenharmony_ci	check_store_range(mt, 362, 367, xa_mk_value(362), 0);
111162306a36Sopenharmony_ci	check_store_range(mt, 353, 361, xa_mk_value(353), 0);
111262306a36Sopenharmony_ci	mt_set_non_kernel(0);
111362306a36Sopenharmony_ci	mt_validate(mt);
111462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
111562306a36Sopenharmony_ci	mtree_destroy(mt);
111662306a36Sopenharmony_ci	/*
111762306a36Sopenharmony_ci	 * Interesting cases:
111862306a36Sopenharmony_ci	 * 1. Overwrite the end of a node and end in the first entry of the next
111962306a36Sopenharmony_ci	 * node.
112062306a36Sopenharmony_ci	 * 2. Split a single range
112162306a36Sopenharmony_ci	 * 3. Overwrite the start of a range
112262306a36Sopenharmony_ci	 * 4. Overwrite the end of a range
112362306a36Sopenharmony_ci	 * 5. Overwrite the entire range
112462306a36Sopenharmony_ci	 * 6. Overwrite a range that causes multiple parent nodes to be
112562306a36Sopenharmony_ci	 * combined
112662306a36Sopenharmony_ci	 * 7. Overwrite a range that causes multiple parent nodes and part of
112762306a36Sopenharmony_ci	 * root to be combined
112862306a36Sopenharmony_ci	 * 8. Overwrite the whole tree
112962306a36Sopenharmony_ci	 * 9. Try to overwrite the zero entry of an alloc tree.
113062306a36Sopenharmony_ci	 * 10. Write a range larger than a nodes current pivot
113162306a36Sopenharmony_ci	 */
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	mt_set_non_kernel(50);
113462306a36Sopenharmony_ci	for (i = 0; i <= 500; i++) {
113562306a36Sopenharmony_ci		val = i*5;
113662306a36Sopenharmony_ci		val2 = (i+1)*5;
113762306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
113862306a36Sopenharmony_ci	}
113962306a36Sopenharmony_ci	check_store_range(mt, 2400, 2400, xa_mk_value(2400), 0);
114062306a36Sopenharmony_ci	check_store_range(mt, 2411, 2411, xa_mk_value(2411), 0);
114162306a36Sopenharmony_ci	check_store_range(mt, 2412, 2412, xa_mk_value(2412), 0);
114262306a36Sopenharmony_ci	check_store_range(mt, 2396, 2400, xa_mk_value(4052020), 0);
114362306a36Sopenharmony_ci	check_store_range(mt, 2402, 2402, xa_mk_value(2402), 0);
114462306a36Sopenharmony_ci	mtree_destroy(mt);
114562306a36Sopenharmony_ci	mt_set_non_kernel(0);
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_ci	mt_set_non_kernel(50);
114862306a36Sopenharmony_ci	for (i = 0; i <= 500; i++) {
114962306a36Sopenharmony_ci		val = i*5;
115062306a36Sopenharmony_ci		val2 = (i+1)*5;
115162306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
115262306a36Sopenharmony_ci	}
115362306a36Sopenharmony_ci	check_store_range(mt, 2422, 2422, xa_mk_value(2422), 0);
115462306a36Sopenharmony_ci	check_store_range(mt, 2424, 2424, xa_mk_value(2424), 0);
115562306a36Sopenharmony_ci	check_store_range(mt, 2425, 2425, xa_mk_value(2), 0);
115662306a36Sopenharmony_ci	check_store_range(mt, 2460, 2470, NULL, 0);
115762306a36Sopenharmony_ci	check_store_range(mt, 2435, 2460, xa_mk_value(2435), 0);
115862306a36Sopenharmony_ci	check_store_range(mt, 2461, 2470, xa_mk_value(2461), 0);
115962306a36Sopenharmony_ci	mt_set_non_kernel(0);
116062306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
116162306a36Sopenharmony_ci	mtree_destroy(mt);
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci	/* Check in-place modifications */
116462306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
116562306a36Sopenharmony_ci	/* Append to the start of last range */
116662306a36Sopenharmony_ci	mt_set_non_kernel(50);
116762306a36Sopenharmony_ci	for (i = 0; i <= 500; i++) {
116862306a36Sopenharmony_ci		val = i * 5 + 1;
116962306a36Sopenharmony_ci		val2 = val + 4;
117062306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
117162306a36Sopenharmony_ci	}
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci	/* Append to the last range without touching any boundaries */
117462306a36Sopenharmony_ci	for (i = 0; i < 10; i++) {
117562306a36Sopenharmony_ci		val = val2 + 5;
117662306a36Sopenharmony_ci		val2 = val + 4;
117762306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
117862306a36Sopenharmony_ci	}
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci	/* Append to the end of last range */
118162306a36Sopenharmony_ci	val = val2;
118262306a36Sopenharmony_ci	for (i = 0; i < 10; i++) {
118362306a36Sopenharmony_ci		val += 5;
118462306a36Sopenharmony_ci		MT_BUG_ON(mt, mtree_test_store_range(mt, val, ULONG_MAX,
118562306a36Sopenharmony_ci						     xa_mk_value(val)) != 0);
118662306a36Sopenharmony_ci	}
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci	/* Overwriting the range and over a part of the next range */
118962306a36Sopenharmony_ci	for (i = 10; i < 30; i += 2) {
119062306a36Sopenharmony_ci		val = i * 5 + 1;
119162306a36Sopenharmony_ci		val2 = val + 5;
119262306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
119362306a36Sopenharmony_ci	}
119462306a36Sopenharmony_ci
119562306a36Sopenharmony_ci	/* Overwriting a part of the range and over the next range */
119662306a36Sopenharmony_ci	for (i = 50; i < 70; i += 2) {
119762306a36Sopenharmony_ci		val2 = i * 5;
119862306a36Sopenharmony_ci		val = val2 - 5;
119962306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
120062306a36Sopenharmony_ci	}
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	/*
120362306a36Sopenharmony_ci	 * Expand the range, only partially overwriting the previous and
120462306a36Sopenharmony_ci	 * next ranges
120562306a36Sopenharmony_ci	 */
120662306a36Sopenharmony_ci	for (i = 100; i < 130; i += 3) {
120762306a36Sopenharmony_ci		val = i * 5 - 5;
120862306a36Sopenharmony_ci		val2 = i * 5 + 1;
120962306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
121062306a36Sopenharmony_ci	}
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ci	/*
121362306a36Sopenharmony_ci	 * Expand the range, only partially overwriting the previous and
121462306a36Sopenharmony_ci	 * next ranges, in RCU mode
121562306a36Sopenharmony_ci	 */
121662306a36Sopenharmony_ci	mt_set_in_rcu(mt);
121762306a36Sopenharmony_ci	for (i = 150; i < 180; i += 3) {
121862306a36Sopenharmony_ci		val = i * 5 - 5;
121962306a36Sopenharmony_ci		val2 = i * 5 + 1;
122062306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
122162306a36Sopenharmony_ci	}
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
122462306a36Sopenharmony_ci	mt_validate(mt);
122562306a36Sopenharmony_ci	mt_set_non_kernel(0);
122662306a36Sopenharmony_ci	mtree_destroy(mt);
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	/* Test rebalance gaps */
122962306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
123062306a36Sopenharmony_ci	mt_set_non_kernel(50);
123162306a36Sopenharmony_ci	for (i = 0; i <= 50; i++) {
123262306a36Sopenharmony_ci		val = i*10;
123362306a36Sopenharmony_ci		val2 = (i+1)*10;
123462306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
123562306a36Sopenharmony_ci	}
123662306a36Sopenharmony_ci	check_store_range(mt, 161, 161, xa_mk_value(161), 0);
123762306a36Sopenharmony_ci	check_store_range(mt, 162, 162, xa_mk_value(162), 0);
123862306a36Sopenharmony_ci	check_store_range(mt, 163, 163, xa_mk_value(163), 0);
123962306a36Sopenharmony_ci	check_store_range(mt, 240, 249, NULL, 0);
124062306a36Sopenharmony_ci	mtree_erase(mt, 200);
124162306a36Sopenharmony_ci	mtree_erase(mt, 210);
124262306a36Sopenharmony_ci	mtree_erase(mt, 220);
124362306a36Sopenharmony_ci	mtree_erase(mt, 230);
124462306a36Sopenharmony_ci	mt_set_non_kernel(0);
124562306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
124662306a36Sopenharmony_ci	mtree_destroy(mt);
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
124962306a36Sopenharmony_ci	for (i = 0; i <= 500; i++) {
125062306a36Sopenharmony_ci		val = i*10;
125162306a36Sopenharmony_ci		val2 = (i+1)*10;
125262306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
125362306a36Sopenharmony_ci	}
125462306a36Sopenharmony_ci	check_store_range(mt, 4600, 4959, xa_mk_value(1), 0);
125562306a36Sopenharmony_ci	mt_validate(mt);
125662306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
125762306a36Sopenharmony_ci	mtree_destroy(mt);
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
126062306a36Sopenharmony_ci	for (i = 0; i <= 500; i++) {
126162306a36Sopenharmony_ci		val = i*10;
126262306a36Sopenharmony_ci		val2 = (i+1)*10;
126362306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
126462306a36Sopenharmony_ci	}
126562306a36Sopenharmony_ci	check_store_range(mt, 4811, 4811, xa_mk_value(4811), 0);
126662306a36Sopenharmony_ci	check_store_range(mt, 4812, 4812, xa_mk_value(4812), 0);
126762306a36Sopenharmony_ci	check_store_range(mt, 4861, 4861, xa_mk_value(4861), 0);
126862306a36Sopenharmony_ci	check_store_range(mt, 4862, 4862, xa_mk_value(4862), 0);
126962306a36Sopenharmony_ci	check_store_range(mt, 4842, 4849, NULL, 0);
127062306a36Sopenharmony_ci	mt_validate(mt);
127162306a36Sopenharmony_ci	MT_BUG_ON(mt, !mt_height(mt));
127262306a36Sopenharmony_ci	mtree_destroy(mt);
127362306a36Sopenharmony_ci
127462306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
127562306a36Sopenharmony_ci	for (i = 0; i <= 1300; i++) {
127662306a36Sopenharmony_ci		val = i*10;
127762306a36Sopenharmony_ci		val2 = (i+1)*10;
127862306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
127962306a36Sopenharmony_ci		MT_BUG_ON(mt, mt_height(mt) >= 4);
128062306a36Sopenharmony_ci	}
128162306a36Sopenharmony_ci	/*  Cause a 3 child split all the way up the tree. */
128262306a36Sopenharmony_ci	for (i = 5; i < 215; i += 10)
128362306a36Sopenharmony_ci		check_store_range(mt, 11450 + i, 11450 + i + 1, NULL, 0);
128462306a36Sopenharmony_ci	for (i = 5; i < 65; i += 10)
128562306a36Sopenharmony_ci		check_store_range(mt, 11770 + i, 11770 + i + 1, NULL, 0);
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ci	MT_BUG_ON(mt, mt_height(mt) >= 4);
128862306a36Sopenharmony_ci	for (i = 5; i < 45; i += 10)
128962306a36Sopenharmony_ci		check_store_range(mt, 11700 + i, 11700 + i + 1, NULL, 0);
129062306a36Sopenharmony_ci	if (!MAPLE_32BIT)
129162306a36Sopenharmony_ci		MT_BUG_ON(mt, mt_height(mt) < 4);
129262306a36Sopenharmony_ci	mtree_destroy(mt);
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
129662306a36Sopenharmony_ci	for (i = 0; i <= 1200; i++) {
129762306a36Sopenharmony_ci		val = i*10;
129862306a36Sopenharmony_ci		val2 = (i+1)*10;
129962306a36Sopenharmony_ci		check_store_range(mt, val, val2, xa_mk_value(val), 0);
130062306a36Sopenharmony_ci		MT_BUG_ON(mt, mt_height(mt) >= 4);
130162306a36Sopenharmony_ci	}
130262306a36Sopenharmony_ci	/* Fill parents and leaves before split. */
130362306a36Sopenharmony_ci	for (i = 5; i < 455; i += 10)
130462306a36Sopenharmony_ci		check_store_range(mt, 7800 + i, 7800 + i + 1, NULL, 0);
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	for (i = 1; i < 16; i++)
130762306a36Sopenharmony_ci		check_store_range(mt, 8185 + i, 8185 + i + 1,
130862306a36Sopenharmony_ci				  xa_mk_value(8185+i), 0);
130962306a36Sopenharmony_ci	MT_BUG_ON(mt, mt_height(mt) >= 4);
131062306a36Sopenharmony_ci	/* triple split across multiple levels. */
131162306a36Sopenharmony_ci	check_store_range(mt, 8184, 8184, xa_mk_value(8184), 0);
131262306a36Sopenharmony_ci	if (!MAPLE_32BIT)
131362306a36Sopenharmony_ci		MT_BUG_ON(mt, mt_height(mt) != 4);
131462306a36Sopenharmony_ci}
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_cistatic noinline void __init check_next_entry(struct maple_tree *mt)
131762306a36Sopenharmony_ci{
131862306a36Sopenharmony_ci	void *entry = NULL;
131962306a36Sopenharmony_ci	unsigned long limit = 30, i = 0;
132062306a36Sopenharmony_ci	MA_STATE(mas, mt, i, i);
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci	check_seq(mt, limit, false);
132562306a36Sopenharmony_ci	rcu_read_lock();
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_ci	/* Check the first one and get ma_state in the correct state. */
132862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_walk(&mas) != xa_mk_value(i++));
132962306a36Sopenharmony_ci	for ( ; i <= limit + 1; i++) {
133062306a36Sopenharmony_ci		entry = mas_next(&mas, limit);
133162306a36Sopenharmony_ci		if (i > limit)
133262306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != NULL);
133362306a36Sopenharmony_ci		else
133462306a36Sopenharmony_ci			MT_BUG_ON(mt, xa_mk_value(i) != entry);
133562306a36Sopenharmony_ci	}
133662306a36Sopenharmony_ci	rcu_read_unlock();
133762306a36Sopenharmony_ci	mtree_destroy(mt);
133862306a36Sopenharmony_ci}
133962306a36Sopenharmony_ci
134062306a36Sopenharmony_cistatic noinline void __init check_prev_entry(struct maple_tree *mt)
134162306a36Sopenharmony_ci{
134262306a36Sopenharmony_ci	unsigned long index = 16;
134362306a36Sopenharmony_ci	void *value;
134462306a36Sopenharmony_ci	int i;
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci	MA_STATE(mas, mt, index, index);
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
134962306a36Sopenharmony_ci	check_seq(mt, 30, false);
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	rcu_read_lock();
135262306a36Sopenharmony_ci	value = mas_find(&mas, ULONG_MAX);
135362306a36Sopenharmony_ci	MT_BUG_ON(mt, value != xa_mk_value(index));
135462306a36Sopenharmony_ci	value = mas_prev(&mas, 0);
135562306a36Sopenharmony_ci	MT_BUG_ON(mt, value != xa_mk_value(index - 1));
135662306a36Sopenharmony_ci	rcu_read_unlock();
135762306a36Sopenharmony_ci	mtree_destroy(mt);
135862306a36Sopenharmony_ci
135962306a36Sopenharmony_ci	/* Check limits on prev */
136062306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
136162306a36Sopenharmony_ci	mas_lock(&mas);
136262306a36Sopenharmony_ci	for (i = 0; i <= index; i++) {
136362306a36Sopenharmony_ci		mas_set_range(&mas, i*10, i*10+5);
136462306a36Sopenharmony_ci		mas_store_gfp(&mas, xa_mk_value(i), GFP_KERNEL);
136562306a36Sopenharmony_ci	}
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	mas_set(&mas, 20);
136862306a36Sopenharmony_ci	value = mas_walk(&mas);
136962306a36Sopenharmony_ci	MT_BUG_ON(mt, value != xa_mk_value(2));
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	value = mas_prev(&mas, 19);
137262306a36Sopenharmony_ci	MT_BUG_ON(mt, value != NULL);
137362306a36Sopenharmony_ci
137462306a36Sopenharmony_ci	mas_set(&mas, 80);
137562306a36Sopenharmony_ci	value = mas_walk(&mas);
137662306a36Sopenharmony_ci	MT_BUG_ON(mt, value != xa_mk_value(8));
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	value = mas_prev(&mas, 76);
137962306a36Sopenharmony_ci	MT_BUG_ON(mt, value != NULL);
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci	mas_unlock(&mas);
138262306a36Sopenharmony_ci}
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_cistatic noinline void __init check_root_expand(struct maple_tree *mt)
138562306a36Sopenharmony_ci{
138662306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
138762306a36Sopenharmony_ci	void *ptr;
138862306a36Sopenharmony_ci
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	mas_lock(&mas);
139162306a36Sopenharmony_ci	mas_set(&mas, 3);
139262306a36Sopenharmony_ci	ptr = mas_walk(&mas);
139362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
139462306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != NULL);
139562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
139662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	ptr = &check_prev_entry;
139962306a36Sopenharmony_ci	mas_set(&mas, 1);
140062306a36Sopenharmony_ci	mas_store_gfp(&mas, ptr, GFP_KERNEL);
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci	mas_set(&mas, 0);
140362306a36Sopenharmony_ci	ptr = mas_walk(&mas);
140462306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != NULL);
140562306a36Sopenharmony_ci
140662306a36Sopenharmony_ci	mas_set(&mas, 1);
140762306a36Sopenharmony_ci	ptr = mas_walk(&mas);
140862306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != &check_prev_entry);
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	mas_set(&mas, 2);
141162306a36Sopenharmony_ci	ptr = mas_walk(&mas);
141262306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != NULL);
141362306a36Sopenharmony_ci	mas_unlock(&mas);
141462306a36Sopenharmony_ci	mtree_destroy(mt);
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ci
141762306a36Sopenharmony_ci	mt_init_flags(mt, 0);
141862306a36Sopenharmony_ci	mas_lock(&mas);
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci	mas_set(&mas, 0);
142162306a36Sopenharmony_ci	ptr = &check_prev_entry;
142262306a36Sopenharmony_ci	mas_store_gfp(&mas, ptr, GFP_KERNEL);
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_ci	mas_set(&mas, 5);
142562306a36Sopenharmony_ci	ptr = mas_walk(&mas);
142662306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != NULL);
142762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
142862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	mas_set_range(&mas, 0, 100);
143162306a36Sopenharmony_ci	ptr = mas_walk(&mas);
143262306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != &check_prev_entry);
143362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
143462306a36Sopenharmony_ci	mas_unlock(&mas);
143562306a36Sopenharmony_ci	mtree_destroy(mt);
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	mt_init_flags(mt, 0);
143862306a36Sopenharmony_ci	mas_lock(&mas);
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci	mas_set(&mas, 0);
144162306a36Sopenharmony_ci	ptr = (void *)((unsigned long) check_prev_entry | 1UL);
144262306a36Sopenharmony_ci	mas_store_gfp(&mas, ptr, GFP_KERNEL);
144362306a36Sopenharmony_ci	ptr = mas_next(&mas, ULONG_MAX);
144462306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != NULL);
144562306a36Sopenharmony_ci	MT_BUG_ON(mt, (mas.index != 1) && (mas.last != ULONG_MAX));
144662306a36Sopenharmony_ci
144762306a36Sopenharmony_ci	mas_set(&mas, 1);
144862306a36Sopenharmony_ci	ptr = mas_prev(&mas, 0);
144962306a36Sopenharmony_ci	MT_BUG_ON(mt, (mas.index != 0) && (mas.last != 0));
145062306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != (void *)((unsigned long) check_prev_entry | 1UL));
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_ci	mas_unlock(&mas);
145362306a36Sopenharmony_ci
145462306a36Sopenharmony_ci	mtree_destroy(mt);
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_ci	mt_init_flags(mt, 0);
145762306a36Sopenharmony_ci	mas_lock(&mas);
145862306a36Sopenharmony_ci	mas_set(&mas, 0);
145962306a36Sopenharmony_ci	ptr = (void *)((unsigned long) check_prev_entry | 2UL);
146062306a36Sopenharmony_ci	mas_store_gfp(&mas, ptr, GFP_KERNEL);
146162306a36Sopenharmony_ci	ptr = mas_next(&mas, ULONG_MAX);
146262306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != NULL);
146362306a36Sopenharmony_ci	MT_BUG_ON(mt, (mas.index != ULONG_MAX) && (mas.last != ULONG_MAX));
146462306a36Sopenharmony_ci
146562306a36Sopenharmony_ci	mas_set(&mas, 1);
146662306a36Sopenharmony_ci	ptr = mas_prev(&mas, 0);
146762306a36Sopenharmony_ci	MT_BUG_ON(mt, (mas.index != 0) && (mas.last != 0));
146862306a36Sopenharmony_ci	MT_BUG_ON(mt, ptr != (void *)((unsigned long) check_prev_entry | 2UL));
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ci	mas_unlock(&mas);
147262306a36Sopenharmony_ci}
147362306a36Sopenharmony_ci
147462306a36Sopenharmony_cistatic noinline void __init check_gap_combining(struct maple_tree *mt)
147562306a36Sopenharmony_ci{
147662306a36Sopenharmony_ci	struct maple_enode *mn1, *mn2;
147762306a36Sopenharmony_ci	void *entry;
147862306a36Sopenharmony_ci	unsigned long singletons = 100;
147962306a36Sopenharmony_ci	static const unsigned long *seq100;
148062306a36Sopenharmony_ci	static const unsigned long seq100_64[] = {
148162306a36Sopenharmony_ci		/* 0-5 */
148262306a36Sopenharmony_ci		74, 75, 76,
148362306a36Sopenharmony_ci		50, 100, 2,
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ci		/* 6-12 */
148662306a36Sopenharmony_ci		44, 45, 46, 43,
148762306a36Sopenharmony_ci		20, 50, 3,
148862306a36Sopenharmony_ci
148962306a36Sopenharmony_ci		/* 13-20*/
149062306a36Sopenharmony_ci		80, 81, 82,
149162306a36Sopenharmony_ci		76, 2, 79, 85, 4,
149262306a36Sopenharmony_ci	};
149362306a36Sopenharmony_ci
149462306a36Sopenharmony_ci	static const unsigned long seq100_32[] = {
149562306a36Sopenharmony_ci		/* 0-5 */
149662306a36Sopenharmony_ci		61, 62, 63,
149762306a36Sopenharmony_ci		50, 100, 2,
149862306a36Sopenharmony_ci
149962306a36Sopenharmony_ci		/* 6-12 */
150062306a36Sopenharmony_ci		31, 32, 33, 30,
150162306a36Sopenharmony_ci		20, 50, 3,
150262306a36Sopenharmony_ci
150362306a36Sopenharmony_ci		/* 13-20*/
150462306a36Sopenharmony_ci		80, 81, 82,
150562306a36Sopenharmony_ci		76, 2, 79, 85, 4,
150662306a36Sopenharmony_ci	};
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_ci	static const unsigned long seq2000[] = {
150962306a36Sopenharmony_ci		1152, 1151,
151062306a36Sopenharmony_ci		1100, 1200, 2,
151162306a36Sopenharmony_ci	};
151262306a36Sopenharmony_ci	static const unsigned long seq400[] = {
151362306a36Sopenharmony_ci		286, 318,
151462306a36Sopenharmony_ci		256, 260, 266, 270, 275, 280, 290, 398,
151562306a36Sopenharmony_ci		286, 310,
151662306a36Sopenharmony_ci	};
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ci	unsigned long index;
151962306a36Sopenharmony_ci
152062306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci	if (MAPLE_32BIT)
152362306a36Sopenharmony_ci		seq100 = seq100_32;
152462306a36Sopenharmony_ci	else
152562306a36Sopenharmony_ci		seq100 = seq100_64;
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_ci	index = seq100[0];
152862306a36Sopenharmony_ci	mas_set(&mas, index);
152962306a36Sopenharmony_ci	MT_BUG_ON(mt, !mtree_empty(mt));
153062306a36Sopenharmony_ci	check_seq(mt, singletons, false); /* create 100 singletons. */
153162306a36Sopenharmony_ci
153262306a36Sopenharmony_ci	mt_set_non_kernel(1);
153362306a36Sopenharmony_ci	mtree_test_erase(mt, seq100[2]);
153462306a36Sopenharmony_ci	check_load(mt, seq100[2], NULL);
153562306a36Sopenharmony_ci	mtree_test_erase(mt, seq100[1]);
153662306a36Sopenharmony_ci	check_load(mt, seq100[1], NULL);
153762306a36Sopenharmony_ci
153862306a36Sopenharmony_ci	rcu_read_lock();
153962306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
154062306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != xa_mk_value(index));
154162306a36Sopenharmony_ci	mn1 = mas.node;
154262306a36Sopenharmony_ci	mas_next(&mas, ULONG_MAX);
154362306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
154462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != xa_mk_value(index + 4));
154562306a36Sopenharmony_ci	mn2 = mas.node;
154662306a36Sopenharmony_ci	MT_BUG_ON(mt, mn1 == mn2); /* test the test. */
154762306a36Sopenharmony_ci
154862306a36Sopenharmony_ci	/*
154962306a36Sopenharmony_ci	 * At this point, there is a gap of 2 at index + 1 between seq100[3] and
155062306a36Sopenharmony_ci	 * seq100[4]. Search for the gap.
155162306a36Sopenharmony_ci	 */
155262306a36Sopenharmony_ci	mt_set_non_kernel(1);
155362306a36Sopenharmony_ci	mas_reset(&mas);
155462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[3], seq100[4],
155562306a36Sopenharmony_ci					     seq100[5]));
155662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != index + 1);
155762306a36Sopenharmony_ci	rcu_read_unlock();
155862306a36Sopenharmony_ci
155962306a36Sopenharmony_ci	mtree_test_erase(mt, seq100[6]);
156062306a36Sopenharmony_ci	check_load(mt, seq100[6], NULL);
156162306a36Sopenharmony_ci	mtree_test_erase(mt, seq100[7]);
156262306a36Sopenharmony_ci	check_load(mt, seq100[7], NULL);
156362306a36Sopenharmony_ci	mtree_test_erase(mt, seq100[8]);
156462306a36Sopenharmony_ci	index = seq100[9];
156562306a36Sopenharmony_ci
156662306a36Sopenharmony_ci	rcu_read_lock();
156762306a36Sopenharmony_ci	mas.index = index;
156862306a36Sopenharmony_ci	mas.last = index;
156962306a36Sopenharmony_ci	mas_reset(&mas);
157062306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
157162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != xa_mk_value(index));
157262306a36Sopenharmony_ci	mn1 = mas.node;
157362306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
157462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != xa_mk_value(index + 4));
157562306a36Sopenharmony_ci	mas_next(&mas, ULONG_MAX); /* go to the next entry. */
157662306a36Sopenharmony_ci	mn2 = mas.node;
157762306a36Sopenharmony_ci	MT_BUG_ON(mt, mn1 == mn2); /* test the next entry is in the next node. */
157862306a36Sopenharmony_ci
157962306a36Sopenharmony_ci	/*
158062306a36Sopenharmony_ci	 * At this point, there is a gap of 3 at seq100[6].  Find it by
158162306a36Sopenharmony_ci	 * searching 20 - 50 for size 3.
158262306a36Sopenharmony_ci	 */
158362306a36Sopenharmony_ci	mas_reset(&mas);
158462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[10], seq100[11],
158562306a36Sopenharmony_ci					     seq100[12]));
158662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != seq100[6]);
158762306a36Sopenharmony_ci	rcu_read_unlock();
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_ci	mt_set_non_kernel(1);
159062306a36Sopenharmony_ci	mtree_store(mt, seq100[13], NULL, GFP_KERNEL);
159162306a36Sopenharmony_ci	check_load(mt, seq100[13], NULL);
159262306a36Sopenharmony_ci	check_load(mt, seq100[14], xa_mk_value(seq100[14]));
159362306a36Sopenharmony_ci	mtree_store(mt, seq100[14], NULL, GFP_KERNEL);
159462306a36Sopenharmony_ci	check_load(mt, seq100[13], NULL);
159562306a36Sopenharmony_ci	check_load(mt, seq100[14], NULL);
159662306a36Sopenharmony_ci
159762306a36Sopenharmony_ci	mas_reset(&mas);
159862306a36Sopenharmony_ci	rcu_read_lock();
159962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[16], seq100[15],
160062306a36Sopenharmony_ci					     seq100[17]));
160162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != seq100[13]);
160262306a36Sopenharmony_ci	mt_validate(mt);
160362306a36Sopenharmony_ci	rcu_read_unlock();
160462306a36Sopenharmony_ci
160562306a36Sopenharmony_ci	/*
160662306a36Sopenharmony_ci	 * *DEPRECATED: no retries anymore* Test retry entry in the start of a
160762306a36Sopenharmony_ci	 * gap.
160862306a36Sopenharmony_ci	 */
160962306a36Sopenharmony_ci	mt_set_non_kernel(2);
161062306a36Sopenharmony_ci	mtree_test_store_range(mt, seq100[18], seq100[14], NULL);
161162306a36Sopenharmony_ci	mtree_test_erase(mt, seq100[15]);
161262306a36Sopenharmony_ci	mas_reset(&mas);
161362306a36Sopenharmony_ci	rcu_read_lock();
161462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq100[16], seq100[19],
161562306a36Sopenharmony_ci					     seq100[20]));
161662306a36Sopenharmony_ci	rcu_read_unlock();
161762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != seq100[18]);
161862306a36Sopenharmony_ci	mt_validate(mt);
161962306a36Sopenharmony_ci	mtree_destroy(mt);
162062306a36Sopenharmony_ci
162162306a36Sopenharmony_ci	/* seq 2000 tests are for multi-level tree gaps */
162262306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
162362306a36Sopenharmony_ci	check_seq(mt, 2000, false);
162462306a36Sopenharmony_ci	mt_set_non_kernel(1);
162562306a36Sopenharmony_ci	mtree_test_erase(mt, seq2000[0]);
162662306a36Sopenharmony_ci	mtree_test_erase(mt, seq2000[1]);
162762306a36Sopenharmony_ci
162862306a36Sopenharmony_ci	mt_set_non_kernel(2);
162962306a36Sopenharmony_ci	mas_reset(&mas);
163062306a36Sopenharmony_ci	rcu_read_lock();
163162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, seq2000[2], seq2000[3],
163262306a36Sopenharmony_ci					     seq2000[4]));
163362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != seq2000[1]);
163462306a36Sopenharmony_ci	rcu_read_unlock();
163562306a36Sopenharmony_ci	mt_validate(mt);
163662306a36Sopenharmony_ci	mtree_destroy(mt);
163762306a36Sopenharmony_ci
163862306a36Sopenharmony_ci	/* seq 400 tests rebalancing over two levels. */
163962306a36Sopenharmony_ci	mt_set_non_kernel(99);
164062306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
164162306a36Sopenharmony_ci	check_seq(mt, 400, false);
164262306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[0], seq400[1], NULL);
164362306a36Sopenharmony_ci	mt_set_non_kernel(0);
164462306a36Sopenharmony_ci	mtree_destroy(mt);
164562306a36Sopenharmony_ci
164662306a36Sopenharmony_ci	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
164762306a36Sopenharmony_ci	check_seq(mt, 400, false);
164862306a36Sopenharmony_ci	mt_set_non_kernel(50);
164962306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[2], seq400[9],
165062306a36Sopenharmony_ci			       xa_mk_value(seq400[2]));
165162306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[3], seq400[9],
165262306a36Sopenharmony_ci			       xa_mk_value(seq400[3]));
165362306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[4], seq400[9],
165462306a36Sopenharmony_ci			       xa_mk_value(seq400[4]));
165562306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[5], seq400[9],
165662306a36Sopenharmony_ci			       xa_mk_value(seq400[5]));
165762306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[0], seq400[9],
165862306a36Sopenharmony_ci			       xa_mk_value(seq400[0]));
165962306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[6], seq400[9],
166062306a36Sopenharmony_ci			       xa_mk_value(seq400[6]));
166162306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[7], seq400[9],
166262306a36Sopenharmony_ci			       xa_mk_value(seq400[7]));
166362306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[8], seq400[9],
166462306a36Sopenharmony_ci			       xa_mk_value(seq400[8]));
166562306a36Sopenharmony_ci	mtree_test_store_range(mt, seq400[10], seq400[11],
166662306a36Sopenharmony_ci			       xa_mk_value(seq400[10]));
166762306a36Sopenharmony_ci	mt_validate(mt);
166862306a36Sopenharmony_ci	mt_set_non_kernel(0);
166962306a36Sopenharmony_ci	mtree_destroy(mt);
167062306a36Sopenharmony_ci}
167162306a36Sopenharmony_cistatic noinline void __init check_node_overwrite(struct maple_tree *mt)
167262306a36Sopenharmony_ci{
167362306a36Sopenharmony_ci	int i, max = 4000;
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_ci	for (i = 0; i < max; i++)
167662306a36Sopenharmony_ci		mtree_test_store_range(mt, i*100, i*100 + 50, xa_mk_value(i*100));
167762306a36Sopenharmony_ci
167862306a36Sopenharmony_ci	mtree_test_store_range(mt, 319951, 367950, NULL);
167962306a36Sopenharmony_ci	/*mt_dump(mt, mt_dump_dec); */
168062306a36Sopenharmony_ci	mt_validate(mt);
168162306a36Sopenharmony_ci}
168262306a36Sopenharmony_ci
168362306a36Sopenharmony_ci#if defined(BENCH_SLOT_STORE)
168462306a36Sopenharmony_cistatic noinline void __init bench_slot_store(struct maple_tree *mt)
168562306a36Sopenharmony_ci{
168662306a36Sopenharmony_ci	int i, brk = 105, max = 1040, brk_start = 100, count = 20000000;
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ci	for (i = 0; i < max; i += 10)
168962306a36Sopenharmony_ci		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
169262306a36Sopenharmony_ci		mtree_store_range(mt, brk, brk, NULL, GFP_KERNEL);
169362306a36Sopenharmony_ci		mtree_store_range(mt, brk_start, brk, xa_mk_value(brk),
169462306a36Sopenharmony_ci				  GFP_KERNEL);
169562306a36Sopenharmony_ci	}
169662306a36Sopenharmony_ci}
169762306a36Sopenharmony_ci#endif
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_ci#if defined(BENCH_NODE_STORE)
170062306a36Sopenharmony_cistatic noinline void __init bench_node_store(struct maple_tree *mt)
170162306a36Sopenharmony_ci{
170262306a36Sopenharmony_ci	int i, overwrite = 76, max = 240, count = 20000000;
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_ci	for (i = 0; i < max; i += 10)
170562306a36Sopenharmony_ci		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
170662306a36Sopenharmony_ci
170762306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
170862306a36Sopenharmony_ci		mtree_store_range(mt, overwrite,  overwrite + 15,
170962306a36Sopenharmony_ci				  xa_mk_value(overwrite), GFP_KERNEL);
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci		overwrite += 5;
171262306a36Sopenharmony_ci		if (overwrite >= 135)
171362306a36Sopenharmony_ci			overwrite = 76;
171462306a36Sopenharmony_ci	}
171562306a36Sopenharmony_ci}
171662306a36Sopenharmony_ci#endif
171762306a36Sopenharmony_ci
171862306a36Sopenharmony_ci#if defined(BENCH_AWALK)
171962306a36Sopenharmony_cistatic noinline void __init bench_awalk(struct maple_tree *mt)
172062306a36Sopenharmony_ci{
172162306a36Sopenharmony_ci	int i, max = 2500, count = 50000000;
172262306a36Sopenharmony_ci	MA_STATE(mas, mt, 1470, 1470);
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci	for (i = 0; i < max; i += 10)
172562306a36Sopenharmony_ci		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_ci	mtree_store_range(mt, 1470, 1475, NULL, GFP_KERNEL);
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
173062306a36Sopenharmony_ci		mas_empty_area_rev(&mas, 0, 2000, 10);
173162306a36Sopenharmony_ci		mas_reset(&mas);
173262306a36Sopenharmony_ci	}
173362306a36Sopenharmony_ci}
173462306a36Sopenharmony_ci#endif
173562306a36Sopenharmony_ci#if defined(BENCH_WALK)
173662306a36Sopenharmony_cistatic noinline void __init bench_walk(struct maple_tree *mt)
173762306a36Sopenharmony_ci{
173862306a36Sopenharmony_ci	int i, max = 2500, count = 550000000;
173962306a36Sopenharmony_ci	MA_STATE(mas, mt, 1470, 1470);
174062306a36Sopenharmony_ci
174162306a36Sopenharmony_ci	for (i = 0; i < max; i += 10)
174262306a36Sopenharmony_ci		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
174562306a36Sopenharmony_ci		mas_walk(&mas);
174662306a36Sopenharmony_ci		mas_reset(&mas);
174762306a36Sopenharmony_ci	}
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci}
175062306a36Sopenharmony_ci#endif
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_ci#if defined(BENCH_MT_FOR_EACH)
175362306a36Sopenharmony_cistatic noinline void __init bench_mt_for_each(struct maple_tree *mt)
175462306a36Sopenharmony_ci{
175562306a36Sopenharmony_ci	int i, count = 1000000;
175662306a36Sopenharmony_ci	unsigned long max = 2500, index = 0;
175762306a36Sopenharmony_ci	void *entry;
175862306a36Sopenharmony_ci
175962306a36Sopenharmony_ci	for (i = 0; i < max; i += 5)
176062306a36Sopenharmony_ci		mtree_store_range(mt, i, i + 4, xa_mk_value(i), GFP_KERNEL);
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
176362306a36Sopenharmony_ci		unsigned long j = 0;
176462306a36Sopenharmony_ci
176562306a36Sopenharmony_ci		mt_for_each(mt, entry, index, max) {
176662306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != xa_mk_value(j));
176762306a36Sopenharmony_ci			j += 5;
176862306a36Sopenharmony_ci		}
176962306a36Sopenharmony_ci
177062306a36Sopenharmony_ci		index = 0;
177162306a36Sopenharmony_ci	}
177262306a36Sopenharmony_ci
177362306a36Sopenharmony_ci}
177462306a36Sopenharmony_ci#endif
177562306a36Sopenharmony_ci
177662306a36Sopenharmony_ci#if defined(BENCH_MAS_FOR_EACH)
177762306a36Sopenharmony_cistatic noinline void __init bench_mas_for_each(struct maple_tree *mt)
177862306a36Sopenharmony_ci{
177962306a36Sopenharmony_ci	int i, count = 1000000;
178062306a36Sopenharmony_ci	unsigned long max = 2500;
178162306a36Sopenharmony_ci	void *entry;
178262306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
178362306a36Sopenharmony_ci
178462306a36Sopenharmony_ci	for (i = 0; i < max; i += 5) {
178562306a36Sopenharmony_ci		int gap = 4;
178662306a36Sopenharmony_ci
178762306a36Sopenharmony_ci		if (i % 30 == 0)
178862306a36Sopenharmony_ci			gap = 3;
178962306a36Sopenharmony_ci		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL);
179062306a36Sopenharmony_ci	}
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci	rcu_read_lock();
179362306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
179462306a36Sopenharmony_ci		unsigned long j = 0;
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci		mas_for_each(&mas, entry, max) {
179762306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != xa_mk_value(j));
179862306a36Sopenharmony_ci			j += 5;
179962306a36Sopenharmony_ci		}
180062306a36Sopenharmony_ci		mas_set(&mas, 0);
180162306a36Sopenharmony_ci	}
180262306a36Sopenharmony_ci	rcu_read_unlock();
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_ci}
180562306a36Sopenharmony_ci#endif
180662306a36Sopenharmony_ci#if defined(BENCH_MAS_PREV)
180762306a36Sopenharmony_cistatic noinline void __init bench_mas_prev(struct maple_tree *mt)
180862306a36Sopenharmony_ci{
180962306a36Sopenharmony_ci	int i, count = 1000000;
181062306a36Sopenharmony_ci	unsigned long max = 2500;
181162306a36Sopenharmony_ci	void *entry;
181262306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
181362306a36Sopenharmony_ci
181462306a36Sopenharmony_ci	for (i = 0; i < max; i += 5) {
181562306a36Sopenharmony_ci		int gap = 4;
181662306a36Sopenharmony_ci
181762306a36Sopenharmony_ci		if (i % 30 == 0)
181862306a36Sopenharmony_ci			gap = 3;
181962306a36Sopenharmony_ci		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL);
182062306a36Sopenharmony_ci	}
182162306a36Sopenharmony_ci
182262306a36Sopenharmony_ci	rcu_read_lock();
182362306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
182462306a36Sopenharmony_ci		unsigned long j = 2495;
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_ci		mas_set(&mas, ULONG_MAX);
182762306a36Sopenharmony_ci		while ((entry = mas_prev(&mas, 0)) != NULL) {
182862306a36Sopenharmony_ci			MT_BUG_ON(mt, entry != xa_mk_value(j));
182962306a36Sopenharmony_ci			j -= 5;
183062306a36Sopenharmony_ci		}
183162306a36Sopenharmony_ci	}
183262306a36Sopenharmony_ci	rcu_read_unlock();
183362306a36Sopenharmony_ci
183462306a36Sopenharmony_ci}
183562306a36Sopenharmony_ci#endif
183662306a36Sopenharmony_ci/* check_forking - simulate the kernel forking sequence with the tree. */
183762306a36Sopenharmony_cistatic noinline void __init check_forking(struct maple_tree *mt)
183862306a36Sopenharmony_ci{
183962306a36Sopenharmony_ci
184062306a36Sopenharmony_ci	struct maple_tree newmt;
184162306a36Sopenharmony_ci	int i, nr_entries = 134;
184262306a36Sopenharmony_ci	void *val;
184362306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
184462306a36Sopenharmony_ci	MA_STATE(newmas, mt, 0, 0);
184562306a36Sopenharmony_ci	struct rw_semaphore newmt_lock;
184662306a36Sopenharmony_ci
184762306a36Sopenharmony_ci	init_rwsem(&newmt_lock);
184862306a36Sopenharmony_ci
184962306a36Sopenharmony_ci	for (i = 0; i <= nr_entries; i++)
185062306a36Sopenharmony_ci		mtree_store_range(mt, i*10, i*10 + 5,
185162306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
185262306a36Sopenharmony_ci
185362306a36Sopenharmony_ci	mt_set_non_kernel(99999);
185462306a36Sopenharmony_ci	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
185562306a36Sopenharmony_ci	mt_set_external_lock(&newmt, &newmt_lock);
185662306a36Sopenharmony_ci	newmas.tree = &newmt;
185762306a36Sopenharmony_ci	mas_reset(&newmas);
185862306a36Sopenharmony_ci	mas_reset(&mas);
185962306a36Sopenharmony_ci	down_write(&newmt_lock);
186062306a36Sopenharmony_ci	mas.index = 0;
186162306a36Sopenharmony_ci	mas.last = 0;
186262306a36Sopenharmony_ci	if (mas_expected_entries(&newmas, nr_entries)) {
186362306a36Sopenharmony_ci		pr_err("OOM!");
186462306a36Sopenharmony_ci		BUG_ON(1);
186562306a36Sopenharmony_ci	}
186662306a36Sopenharmony_ci	rcu_read_lock();
186762306a36Sopenharmony_ci	mas_for_each(&mas, val, ULONG_MAX) {
186862306a36Sopenharmony_ci		newmas.index = mas.index;
186962306a36Sopenharmony_ci		newmas.last = mas.last;
187062306a36Sopenharmony_ci		mas_store(&newmas, val);
187162306a36Sopenharmony_ci	}
187262306a36Sopenharmony_ci	rcu_read_unlock();
187362306a36Sopenharmony_ci	mas_destroy(&newmas);
187462306a36Sopenharmony_ci	mt_validate(&newmt);
187562306a36Sopenharmony_ci	mt_set_non_kernel(0);
187662306a36Sopenharmony_ci	__mt_destroy(&newmt);
187762306a36Sopenharmony_ci	up_write(&newmt_lock);
187862306a36Sopenharmony_ci}
187962306a36Sopenharmony_ci
188062306a36Sopenharmony_cistatic noinline void __init check_iteration(struct maple_tree *mt)
188162306a36Sopenharmony_ci{
188262306a36Sopenharmony_ci	int i, nr_entries = 125;
188362306a36Sopenharmony_ci	void *val;
188462306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci	for (i = 0; i <= nr_entries; i++)
188762306a36Sopenharmony_ci		mtree_store_range(mt, i * 10, i * 10 + 9,
188862306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
188962306a36Sopenharmony_ci
189062306a36Sopenharmony_ci	mt_set_non_kernel(99999);
189162306a36Sopenharmony_ci
189262306a36Sopenharmony_ci	i = 0;
189362306a36Sopenharmony_ci	mas_lock(&mas);
189462306a36Sopenharmony_ci	mas_for_each(&mas, val, 925) {
189562306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.index != i * 10);
189662306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.last != i * 10 + 9);
189762306a36Sopenharmony_ci		/* Overwrite end of entry 92 */
189862306a36Sopenharmony_ci		if (i == 92) {
189962306a36Sopenharmony_ci			mas.index = 925;
190062306a36Sopenharmony_ci			mas.last = 929;
190162306a36Sopenharmony_ci			mas_store(&mas, val);
190262306a36Sopenharmony_ci		}
190362306a36Sopenharmony_ci		i++;
190462306a36Sopenharmony_ci	}
190562306a36Sopenharmony_ci	/* Ensure mas_find() gets the next value */
190662306a36Sopenharmony_ci	val = mas_find(&mas, ULONG_MAX);
190762306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(i));
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_ci	mas_set(&mas, 0);
191062306a36Sopenharmony_ci	i = 0;
191162306a36Sopenharmony_ci	mas_for_each(&mas, val, 785) {
191262306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.index != i * 10);
191362306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.last != i * 10 + 9);
191462306a36Sopenharmony_ci		/* Overwrite start of entry 78 */
191562306a36Sopenharmony_ci		if (i == 78) {
191662306a36Sopenharmony_ci			mas.index = 780;
191762306a36Sopenharmony_ci			mas.last = 785;
191862306a36Sopenharmony_ci			mas_store(&mas, val);
191962306a36Sopenharmony_ci		} else {
192062306a36Sopenharmony_ci			i++;
192162306a36Sopenharmony_ci		}
192262306a36Sopenharmony_ci	}
192362306a36Sopenharmony_ci	val = mas_find(&mas, ULONG_MAX);
192462306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(i));
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_ci	mas_set(&mas, 0);
192762306a36Sopenharmony_ci	i = 0;
192862306a36Sopenharmony_ci	mas_for_each(&mas, val, 765) {
192962306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.index != i * 10);
193062306a36Sopenharmony_ci		MT_BUG_ON(mt, mas.last != i * 10 + 9);
193162306a36Sopenharmony_ci		/* Overwrite end of entry 76 and advance to the end */
193262306a36Sopenharmony_ci		if (i == 76) {
193362306a36Sopenharmony_ci			mas.index = 760;
193462306a36Sopenharmony_ci			mas.last = 765;
193562306a36Sopenharmony_ci			mas_store(&mas, val);
193662306a36Sopenharmony_ci		}
193762306a36Sopenharmony_ci		i++;
193862306a36Sopenharmony_ci	}
193962306a36Sopenharmony_ci	/* Make sure the next find returns the one after 765, 766-769 */
194062306a36Sopenharmony_ci	val = mas_find(&mas, ULONG_MAX);
194162306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(76));
194262306a36Sopenharmony_ci	mas_unlock(&mas);
194362306a36Sopenharmony_ci	mas_destroy(&mas);
194462306a36Sopenharmony_ci	mt_set_non_kernel(0);
194562306a36Sopenharmony_ci}
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_cistatic noinline void __init check_mas_store_gfp(struct maple_tree *mt)
194862306a36Sopenharmony_ci{
194962306a36Sopenharmony_ci
195062306a36Sopenharmony_ci	struct maple_tree newmt;
195162306a36Sopenharmony_ci	int i, nr_entries = 135;
195262306a36Sopenharmony_ci	void *val;
195362306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
195462306a36Sopenharmony_ci	MA_STATE(newmas, mt, 0, 0);
195562306a36Sopenharmony_ci
195662306a36Sopenharmony_ci	for (i = 0; i <= nr_entries; i++)
195762306a36Sopenharmony_ci		mtree_store_range(mt, i*10, i*10 + 5,
195862306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
195962306a36Sopenharmony_ci
196062306a36Sopenharmony_ci	mt_set_non_kernel(99999);
196162306a36Sopenharmony_ci	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE);
196262306a36Sopenharmony_ci	newmas.tree = &newmt;
196362306a36Sopenharmony_ci	rcu_read_lock();
196462306a36Sopenharmony_ci	mas_lock(&newmas);
196562306a36Sopenharmony_ci	mas_reset(&newmas);
196662306a36Sopenharmony_ci	mas_set(&mas, 0);
196762306a36Sopenharmony_ci	mas_for_each(&mas, val, ULONG_MAX) {
196862306a36Sopenharmony_ci		newmas.index = mas.index;
196962306a36Sopenharmony_ci		newmas.last = mas.last;
197062306a36Sopenharmony_ci		mas_store_gfp(&newmas, val, GFP_KERNEL);
197162306a36Sopenharmony_ci	}
197262306a36Sopenharmony_ci	mas_unlock(&newmas);
197362306a36Sopenharmony_ci	rcu_read_unlock();
197462306a36Sopenharmony_ci	mt_validate(&newmt);
197562306a36Sopenharmony_ci	mt_set_non_kernel(0);
197662306a36Sopenharmony_ci	mtree_destroy(&newmt);
197762306a36Sopenharmony_ci}
197862306a36Sopenharmony_ci
197962306a36Sopenharmony_ci#if defined(BENCH_FORK)
198062306a36Sopenharmony_cistatic noinline void __init bench_forking(struct maple_tree *mt)
198162306a36Sopenharmony_ci{
198262306a36Sopenharmony_ci
198362306a36Sopenharmony_ci	struct maple_tree newmt;
198462306a36Sopenharmony_ci	int i, nr_entries = 134, nr_fork = 80000;
198562306a36Sopenharmony_ci	void *val;
198662306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
198762306a36Sopenharmony_ci	MA_STATE(newmas, mt, 0, 0);
198862306a36Sopenharmony_ci	struct rw_semaphore newmt_lock;
198962306a36Sopenharmony_ci
199062306a36Sopenharmony_ci	init_rwsem(&newmt_lock);
199162306a36Sopenharmony_ci	mt_set_external_lock(&newmt, &newmt_lock);
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_ci	for (i = 0; i <= nr_entries; i++)
199462306a36Sopenharmony_ci		mtree_store_range(mt, i*10, i*10 + 5,
199562306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
199662306a36Sopenharmony_ci
199762306a36Sopenharmony_ci	for (i = 0; i < nr_fork; i++) {
199862306a36Sopenharmony_ci		mt_set_non_kernel(99999);
199962306a36Sopenharmony_ci		mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE);
200062306a36Sopenharmony_ci		newmas.tree = &newmt;
200162306a36Sopenharmony_ci		mas_reset(&newmas);
200262306a36Sopenharmony_ci		mas_reset(&mas);
200362306a36Sopenharmony_ci		mas.index = 0;
200462306a36Sopenharmony_ci		mas.last = 0;
200562306a36Sopenharmony_ci		rcu_read_lock();
200662306a36Sopenharmony_ci		down_write(&newmt_lock);
200762306a36Sopenharmony_ci		if (mas_expected_entries(&newmas, nr_entries)) {
200862306a36Sopenharmony_ci			printk("OOM!");
200962306a36Sopenharmony_ci			BUG_ON(1);
201062306a36Sopenharmony_ci		}
201162306a36Sopenharmony_ci		mas_for_each(&mas, val, ULONG_MAX) {
201262306a36Sopenharmony_ci			newmas.index = mas.index;
201362306a36Sopenharmony_ci			newmas.last = mas.last;
201462306a36Sopenharmony_ci			mas_store(&newmas, val);
201562306a36Sopenharmony_ci		}
201662306a36Sopenharmony_ci		mas_destroy(&newmas);
201762306a36Sopenharmony_ci		rcu_read_unlock();
201862306a36Sopenharmony_ci		mt_validate(&newmt);
201962306a36Sopenharmony_ci		mt_set_non_kernel(0);
202062306a36Sopenharmony_ci		__mt_destroy(&newmt);
202162306a36Sopenharmony_ci		up_write(&newmt_lock);
202262306a36Sopenharmony_ci	}
202362306a36Sopenharmony_ci}
202462306a36Sopenharmony_ci#endif
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_cistatic noinline void __init next_prev_test(struct maple_tree *mt)
202762306a36Sopenharmony_ci{
202862306a36Sopenharmony_ci	int i, nr_entries;
202962306a36Sopenharmony_ci	void *val;
203062306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
203162306a36Sopenharmony_ci	struct maple_enode *mn;
203262306a36Sopenharmony_ci	static const unsigned long *level2;
203362306a36Sopenharmony_ci	static const unsigned long level2_64[] = { 707, 1000, 710, 715, 720,
203462306a36Sopenharmony_ci						   725};
203562306a36Sopenharmony_ci	static const unsigned long level2_32[] = { 1747, 2000, 1750, 1755,
203662306a36Sopenharmony_ci						   1760, 1765};
203762306a36Sopenharmony_ci	unsigned long last_index;
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	if (MAPLE_32BIT) {
204062306a36Sopenharmony_ci		nr_entries = 500;
204162306a36Sopenharmony_ci		level2 = level2_32;
204262306a36Sopenharmony_ci		last_index = 0x138e;
204362306a36Sopenharmony_ci	} else {
204462306a36Sopenharmony_ci		nr_entries = 200;
204562306a36Sopenharmony_ci		level2 = level2_64;
204662306a36Sopenharmony_ci		last_index = 0x7d6;
204762306a36Sopenharmony_ci	}
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_ci	for (i = 0; i <= nr_entries; i++)
205062306a36Sopenharmony_ci		mtree_store_range(mt, i*10, i*10 + 5,
205162306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
205262306a36Sopenharmony_ci
205362306a36Sopenharmony_ci	mas_lock(&mas);
205462306a36Sopenharmony_ci	for (i = 0; i <= nr_entries / 2; i++) {
205562306a36Sopenharmony_ci		mas_next(&mas, 1000);
205662306a36Sopenharmony_ci		if (mas_is_none(&mas))
205762306a36Sopenharmony_ci			break;
205862306a36Sopenharmony_ci
205962306a36Sopenharmony_ci	}
206062306a36Sopenharmony_ci	mas_reset(&mas);
206162306a36Sopenharmony_ci	mas_set(&mas, 0);
206262306a36Sopenharmony_ci	i = 0;
206362306a36Sopenharmony_ci	mas_for_each(&mas, val, 1000) {
206462306a36Sopenharmony_ci		i++;
206562306a36Sopenharmony_ci	}
206662306a36Sopenharmony_ci
206762306a36Sopenharmony_ci	mas_reset(&mas);
206862306a36Sopenharmony_ci	mas_set(&mas, 0);
206962306a36Sopenharmony_ci	i = 0;
207062306a36Sopenharmony_ci	mas_for_each(&mas, val, 1000) {
207162306a36Sopenharmony_ci		mas_pause(&mas);
207262306a36Sopenharmony_ci		i++;
207362306a36Sopenharmony_ci	}
207462306a36Sopenharmony_ci
207562306a36Sopenharmony_ci	/*
207662306a36Sopenharmony_ci	 * 680 - 685 = 0x61a00001930c
207762306a36Sopenharmony_ci	 * 686 - 689 = NULL;
207862306a36Sopenharmony_ci	 * 690 - 695 = 0x61a00001930c
207962306a36Sopenharmony_ci	 * Check simple next/prev
208062306a36Sopenharmony_ci	 */
208162306a36Sopenharmony_ci	mas_set(&mas, 686);
208262306a36Sopenharmony_ci	val = mas_walk(&mas);
208362306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
208462306a36Sopenharmony_ci
208562306a36Sopenharmony_ci	val = mas_next(&mas, 1000);
208662306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(690 / 10));
208762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 690);
208862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 695);
208962306a36Sopenharmony_ci
209062306a36Sopenharmony_ci	val = mas_prev(&mas, 0);
209162306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(680 / 10));
209262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 680);
209362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 685);
209462306a36Sopenharmony_ci
209562306a36Sopenharmony_ci	val = mas_next(&mas, 1000);
209662306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(690 / 10));
209762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 690);
209862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 695);
209962306a36Sopenharmony_ci
210062306a36Sopenharmony_ci	val = mas_next(&mas, 1000);
210162306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(700 / 10));
210262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 700);
210362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 705);
210462306a36Sopenharmony_ci
210562306a36Sopenharmony_ci	/* Check across node boundaries of the tree */
210662306a36Sopenharmony_ci	mas_set(&mas, 70);
210762306a36Sopenharmony_ci	val = mas_walk(&mas);
210862306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(70 / 10));
210962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 70);
211062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 75);
211162306a36Sopenharmony_ci
211262306a36Sopenharmony_ci	val = mas_next(&mas, 1000);
211362306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(80 / 10));
211462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 80);
211562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 85);
211662306a36Sopenharmony_ci
211762306a36Sopenharmony_ci	val = mas_prev(&mas, 70);
211862306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(70 / 10));
211962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 70);
212062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 75);
212162306a36Sopenharmony_ci
212262306a36Sopenharmony_ci	/* Check across two levels of the tree */
212362306a36Sopenharmony_ci	mas_reset(&mas);
212462306a36Sopenharmony_ci	mas_set(&mas, level2[0]);
212562306a36Sopenharmony_ci	val = mas_walk(&mas);
212662306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
212762306a36Sopenharmony_ci	val = mas_next(&mas, level2[1]);
212862306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(level2[2] / 10));
212962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != level2[2]);
213062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != level2[3]);
213162306a36Sopenharmony_ci	mn = mas.node;
213262306a36Sopenharmony_ci
213362306a36Sopenharmony_ci	val = mas_next(&mas, level2[1]);
213462306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(level2[4] / 10));
213562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != level2[4]);
213662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != level2[5]);
213762306a36Sopenharmony_ci	MT_BUG_ON(mt, mn == mas.node);
213862306a36Sopenharmony_ci
213962306a36Sopenharmony_ci	val = mas_prev(&mas, 0);
214062306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(level2[2] / 10));
214162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != level2[2]);
214262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != level2[3]);
214362306a36Sopenharmony_ci
214462306a36Sopenharmony_ci	/* Check running off the end and back on */
214562306a36Sopenharmony_ci	mas_set(&mas, nr_entries * 10);
214662306a36Sopenharmony_ci	val = mas_walk(&mas);
214762306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(nr_entries));
214862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != (nr_entries * 10));
214962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != (nr_entries * 10 + 5));
215062306a36Sopenharmony_ci
215162306a36Sopenharmony_ci	val = mas_next(&mas, ULONG_MAX);
215262306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
215362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != last_index);
215462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
215562306a36Sopenharmony_ci
215662306a36Sopenharmony_ci	val = mas_prev(&mas, 0);
215762306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(nr_entries));
215862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != (nr_entries * 10));
215962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != (nr_entries * 10 + 5));
216062306a36Sopenharmony_ci
216162306a36Sopenharmony_ci	/* Check running off the start and back on */
216262306a36Sopenharmony_ci	mas_reset(&mas);
216362306a36Sopenharmony_ci	mas_set(&mas, 10);
216462306a36Sopenharmony_ci	val = mas_walk(&mas);
216562306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(1));
216662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 10);
216762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 15);
216862306a36Sopenharmony_ci
216962306a36Sopenharmony_ci	val = mas_prev(&mas, 0);
217062306a36Sopenharmony_ci	MT_BUG_ON(mt, val != xa_mk_value(0));
217162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
217262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 5);
217362306a36Sopenharmony_ci
217462306a36Sopenharmony_ci	val = mas_prev(&mas, 0);
217562306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
217662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
217762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 5);
217862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
217962306a36Sopenharmony_ci
218062306a36Sopenharmony_ci	mas.index = 0;
218162306a36Sopenharmony_ci	mas.last = 5;
218262306a36Sopenharmony_ci	mas_store(&mas, NULL);
218362306a36Sopenharmony_ci	mas_reset(&mas);
218462306a36Sopenharmony_ci	mas_set(&mas, 10);
218562306a36Sopenharmony_ci	mas_walk(&mas);
218662306a36Sopenharmony_ci
218762306a36Sopenharmony_ci	val = mas_prev(&mas, 0);
218862306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
218962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
219062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 9);
219162306a36Sopenharmony_ci	mas_unlock(&mas);
219262306a36Sopenharmony_ci
219362306a36Sopenharmony_ci	mtree_destroy(mt);
219462306a36Sopenharmony_ci
219562306a36Sopenharmony_ci	mt_init(mt);
219662306a36Sopenharmony_ci	mtree_store_range(mt, 0, 0, xa_mk_value(0), GFP_KERNEL);
219762306a36Sopenharmony_ci	mtree_store_range(mt, 5, 5, xa_mk_value(5), GFP_KERNEL);
219862306a36Sopenharmony_ci	rcu_read_lock();
219962306a36Sopenharmony_ci	mas_set(&mas, 5);
220062306a36Sopenharmony_ci	val = mas_prev(&mas, 4);
220162306a36Sopenharmony_ci	MT_BUG_ON(mt, val != NULL);
220262306a36Sopenharmony_ci	rcu_read_unlock();
220362306a36Sopenharmony_ci}
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci
220662306a36Sopenharmony_ci
220762306a36Sopenharmony_ci/* Test spanning writes that require balancing right sibling or right cousin */
220862306a36Sopenharmony_cistatic noinline void __init check_spanning_relatives(struct maple_tree *mt)
220962306a36Sopenharmony_ci{
221062306a36Sopenharmony_ci
221162306a36Sopenharmony_ci	unsigned long i, nr_entries = 1000;
221262306a36Sopenharmony_ci
221362306a36Sopenharmony_ci	for (i = 0; i <= nr_entries; i++)
221462306a36Sopenharmony_ci		mtree_store_range(mt, i*10, i*10 + 5,
221562306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
221662306a36Sopenharmony_ci
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_ci	mtree_store_range(mt, 9365, 9955, NULL, GFP_KERNEL);
221962306a36Sopenharmony_ci}
222062306a36Sopenharmony_ci
222162306a36Sopenharmony_cistatic noinline void __init check_fuzzer(struct maple_tree *mt)
222262306a36Sopenharmony_ci{
222362306a36Sopenharmony_ci	/*
222462306a36Sopenharmony_ci	 * 1. Causes a spanning rebalance of a single root node.
222562306a36Sopenharmony_ci	 * Fixed by setting the correct limit in mast_cp_to_nodes() when the
222662306a36Sopenharmony_ci	 * entire right side is consumed.
222762306a36Sopenharmony_ci	 */
222862306a36Sopenharmony_ci	mtree_test_insert(mt, 88, (void *)0xb1);
222962306a36Sopenharmony_ci	mtree_test_insert(mt, 84, (void *)0xa9);
223062306a36Sopenharmony_ci	mtree_test_insert(mt, 2,  (void *)0x5);
223162306a36Sopenharmony_ci	mtree_test_insert(mt, 4,  (void *)0x9);
223262306a36Sopenharmony_ci	mtree_test_insert(mt, 14, (void *)0x1d);
223362306a36Sopenharmony_ci	mtree_test_insert(mt, 7,  (void *)0xf);
223462306a36Sopenharmony_ci	mtree_test_insert(mt, 12, (void *)0x19);
223562306a36Sopenharmony_ci	mtree_test_insert(mt, 18, (void *)0x25);
223662306a36Sopenharmony_ci	mtree_test_store_range(mt, 8, 18, (void *)0x11);
223762306a36Sopenharmony_ci	mtree_destroy(mt);
223862306a36Sopenharmony_ci
223962306a36Sopenharmony_ci
224062306a36Sopenharmony_ci	/*
224162306a36Sopenharmony_ci	 * 2. Cause a spanning rebalance of two nodes in root.
224262306a36Sopenharmony_ci	 * Fixed by setting mast->r->max correctly.
224362306a36Sopenharmony_ci	 */
224462306a36Sopenharmony_ci	mt_init_flags(mt, 0);
224562306a36Sopenharmony_ci	mtree_test_store(mt, 87, (void *)0xaf);
224662306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
224762306a36Sopenharmony_ci	mtree_test_load(mt, 4);
224862306a36Sopenharmony_ci	mtree_test_insert(mt, 4, (void *)0x9);
224962306a36Sopenharmony_ci	mtree_test_store(mt, 8, (void *)0x11);
225062306a36Sopenharmony_ci	mtree_test_store(mt, 44, (void *)0x59);
225162306a36Sopenharmony_ci	mtree_test_store(mt, 68, (void *)0x89);
225262306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
225362306a36Sopenharmony_ci	mtree_test_insert(mt, 43, (void *)0x57);
225462306a36Sopenharmony_ci	mtree_test_insert(mt, 24, (void *)0x31);
225562306a36Sopenharmony_ci	mtree_test_insert(mt, 844, (void *)0x699);
225662306a36Sopenharmony_ci	mtree_test_store(mt, 84, (void *)0xa9);
225762306a36Sopenharmony_ci	mtree_test_store(mt, 4, (void *)0x9);
225862306a36Sopenharmony_ci	mtree_test_erase(mt, 4);
225962306a36Sopenharmony_ci	mtree_test_load(mt, 5);
226062306a36Sopenharmony_ci	mtree_test_erase(mt, 0);
226162306a36Sopenharmony_ci	mtree_destroy(mt);
226262306a36Sopenharmony_ci
226362306a36Sopenharmony_ci	/*
226462306a36Sopenharmony_ci	 * 3. Cause a node overflow on copy
226562306a36Sopenharmony_ci	 * Fixed by using the correct check for node size in mas_wr_modify()
226662306a36Sopenharmony_ci	 * Also discovered issue with metadata setting.
226762306a36Sopenharmony_ci	 */
226862306a36Sopenharmony_ci	mt_init_flags(mt, 0);
226962306a36Sopenharmony_ci	mtree_test_store_range(mt, 0, ULONG_MAX, (void *)0x1);
227062306a36Sopenharmony_ci	mtree_test_store(mt, 4, (void *)0x9);
227162306a36Sopenharmony_ci	mtree_test_erase(mt, 5);
227262306a36Sopenharmony_ci	mtree_test_erase(mt, 0);
227362306a36Sopenharmony_ci	mtree_test_erase(mt, 4);
227462306a36Sopenharmony_ci	mtree_test_store(mt, 5, (void *)0xb);
227562306a36Sopenharmony_ci	mtree_test_erase(mt, 5);
227662306a36Sopenharmony_ci	mtree_test_store(mt, 5, (void *)0xb);
227762306a36Sopenharmony_ci	mtree_test_erase(mt, 5);
227862306a36Sopenharmony_ci	mtree_test_erase(mt, 4);
227962306a36Sopenharmony_ci	mtree_test_store(mt, 4, (void *)0x9);
228062306a36Sopenharmony_ci	mtree_test_store(mt, 444, (void *)0x379);
228162306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
228262306a36Sopenharmony_ci	mtree_test_load(mt, 0);
228362306a36Sopenharmony_ci	mtree_test_store(mt, 5, (void *)0xb);
228462306a36Sopenharmony_ci	mtree_test_erase(mt, 0);
228562306a36Sopenharmony_ci	mtree_destroy(mt);
228662306a36Sopenharmony_ci
228762306a36Sopenharmony_ci	/*
228862306a36Sopenharmony_ci	 * 4. spanning store failure due to writing incorrect pivot value at
228962306a36Sopenharmony_ci	 * last slot.
229062306a36Sopenharmony_ci	 * Fixed by setting mast->r->max correctly in mast_cp_to_nodes()
229162306a36Sopenharmony_ci	 *
229262306a36Sopenharmony_ci	 */
229362306a36Sopenharmony_ci	mt_init_flags(mt, 0);
229462306a36Sopenharmony_ci	mtree_test_insert(mt, 261, (void *)0x20b);
229562306a36Sopenharmony_ci	mtree_test_store(mt, 516, (void *)0x409);
229662306a36Sopenharmony_ci	mtree_test_store(mt, 6, (void *)0xd);
229762306a36Sopenharmony_ci	mtree_test_insert(mt, 5, (void *)0xb);
229862306a36Sopenharmony_ci	mtree_test_insert(mt, 1256, (void *)0x9d1);
229962306a36Sopenharmony_ci	mtree_test_store(mt, 4, (void *)0x9);
230062306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
230162306a36Sopenharmony_ci	mtree_test_store(mt, 56, (void *)0x71);
230262306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
230362306a36Sopenharmony_ci	mtree_test_store(mt, 24, (void *)0x31);
230462306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
230562306a36Sopenharmony_ci	mtree_test_insert(mt, 2263, (void *)0x11af);
230662306a36Sopenharmony_ci	mtree_test_insert(mt, 446, (void *)0x37d);
230762306a36Sopenharmony_ci	mtree_test_store_range(mt, 6, 45, (void *)0xd);
230862306a36Sopenharmony_ci	mtree_test_store_range(mt, 3, 446, (void *)0x7);
230962306a36Sopenharmony_ci	mtree_destroy(mt);
231062306a36Sopenharmony_ci
231162306a36Sopenharmony_ci	/*
231262306a36Sopenharmony_ci	 * 5. mas_wr_extend_null() may overflow slots.
231362306a36Sopenharmony_ci	 * Fix by checking against wr_mas->node_end.
231462306a36Sopenharmony_ci	 */
231562306a36Sopenharmony_ci	mt_init_flags(mt, 0);
231662306a36Sopenharmony_ci	mtree_test_store(mt, 48, (void *)0x61);
231762306a36Sopenharmony_ci	mtree_test_store(mt, 3, (void *)0x7);
231862306a36Sopenharmony_ci	mtree_test_load(mt, 0);
231962306a36Sopenharmony_ci	mtree_test_store(mt, 88, (void *)0xb1);
232062306a36Sopenharmony_ci	mtree_test_store(mt, 81, (void *)0xa3);
232162306a36Sopenharmony_ci	mtree_test_insert(mt, 0, (void *)0x1);
232262306a36Sopenharmony_ci	mtree_test_insert(mt, 8, (void *)0x11);
232362306a36Sopenharmony_ci	mtree_test_insert(mt, 4, (void *)0x9);
232462306a36Sopenharmony_ci	mtree_test_insert(mt, 2480, (void *)0x1361);
232562306a36Sopenharmony_ci	mtree_test_insert(mt, ULONG_MAX,
232662306a36Sopenharmony_ci			  (void *)0xffffffffffffffff);
232762306a36Sopenharmony_ci	mtree_test_erase(mt, ULONG_MAX);
232862306a36Sopenharmony_ci	mtree_destroy(mt);
232962306a36Sopenharmony_ci
233062306a36Sopenharmony_ci	/*
233162306a36Sopenharmony_ci	 * 6.  When reusing a node with an implied pivot and the node is
233262306a36Sopenharmony_ci	 * shrinking, old data would be left in the implied slot
233362306a36Sopenharmony_ci	 * Fixed by checking the last pivot for the mas->max and clear
233462306a36Sopenharmony_ci	 * accordingly.  This only affected the left-most node as that node is
233562306a36Sopenharmony_ci	 * the only one allowed to end in NULL.
233662306a36Sopenharmony_ci	 */
233762306a36Sopenharmony_ci	mt_init_flags(mt, 0);
233862306a36Sopenharmony_ci	mtree_test_erase(mt, 3);
233962306a36Sopenharmony_ci	mtree_test_insert(mt, 22, (void *)0x2d);
234062306a36Sopenharmony_ci	mtree_test_insert(mt, 15, (void *)0x1f);
234162306a36Sopenharmony_ci	mtree_test_load(mt, 2);
234262306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
234362306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
234462306a36Sopenharmony_ci	mtree_test_insert(mt, 5, (void *)0xb);
234562306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
234662306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
234762306a36Sopenharmony_ci	mtree_test_insert(mt, 4, (void *)0x9);
234862306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
234962306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
235062306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
235162306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
235262306a36Sopenharmony_ci	mtree_test_erase(mt, 3);
235362306a36Sopenharmony_ci	mtree_test_insert(mt, 22, (void *)0x2d);
235462306a36Sopenharmony_ci	mtree_test_insert(mt, 15, (void *)0x1f);
235562306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
235662306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
235762306a36Sopenharmony_ci	mtree_test_insert(mt, 8, (void *)0x11);
235862306a36Sopenharmony_ci	mtree_test_load(mt, 2);
235962306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
236062306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
236162306a36Sopenharmony_ci	mtree_test_store(mt, 1, (void *)0x3);
236262306a36Sopenharmony_ci	mtree_test_insert(mt, 5, (void *)0xb);
236362306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
236462306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
236562306a36Sopenharmony_ci	mtree_test_insert(mt, 4, (void *)0x9);
236662306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
236762306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
236862306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
236962306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
237062306a36Sopenharmony_ci	mtree_test_erase(mt, 3);
237162306a36Sopenharmony_ci	mtree_test_insert(mt, 22, (void *)0x2d);
237262306a36Sopenharmony_ci	mtree_test_insert(mt, 15, (void *)0x1f);
237362306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
237462306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
237562306a36Sopenharmony_ci	mtree_test_insert(mt, 8, (void *)0x11);
237662306a36Sopenharmony_ci	mtree_test_insert(mt, 12, (void *)0x19);
237762306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
237862306a36Sopenharmony_ci	mtree_test_store_range(mt, 4, 62, (void *)0x9);
237962306a36Sopenharmony_ci	mtree_test_erase(mt, 62);
238062306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 0, (void *)0x3);
238162306a36Sopenharmony_ci	mtree_test_insert(mt, 11, (void *)0x17);
238262306a36Sopenharmony_ci	mtree_test_insert(mt, 3, (void *)0x7);
238362306a36Sopenharmony_ci	mtree_test_insert(mt, 3, (void *)0x7);
238462306a36Sopenharmony_ci	mtree_test_store(mt, 62, (void *)0x7d);
238562306a36Sopenharmony_ci	mtree_test_erase(mt, 62);
238662306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 15, (void *)0x3);
238762306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
238862306a36Sopenharmony_ci	mtree_test_insert(mt, 22, (void *)0x2d);
238962306a36Sopenharmony_ci	mtree_test_insert(mt, 12, (void *)0x19);
239062306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
239162306a36Sopenharmony_ci	mtree_test_insert(mt, 3, (void *)0x7);
239262306a36Sopenharmony_ci	mtree_test_store(mt, 62, (void *)0x7d);
239362306a36Sopenharmony_ci	mtree_test_erase(mt, 62);
239462306a36Sopenharmony_ci	mtree_test_insert(mt, 122, (void *)0xf5);
239562306a36Sopenharmony_ci	mtree_test_store(mt, 3, (void *)0x7);
239662306a36Sopenharmony_ci	mtree_test_insert(mt, 0, (void *)0x1);
239762306a36Sopenharmony_ci	mtree_test_store_range(mt, 0, 1, (void *)0x1);
239862306a36Sopenharmony_ci	mtree_test_insert(mt, 85, (void *)0xab);
239962306a36Sopenharmony_ci	mtree_test_insert(mt, 72, (void *)0x91);
240062306a36Sopenharmony_ci	mtree_test_insert(mt, 81, (void *)0xa3);
240162306a36Sopenharmony_ci	mtree_test_insert(mt, 726, (void *)0x5ad);
240262306a36Sopenharmony_ci	mtree_test_insert(mt, 0, (void *)0x1);
240362306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
240462306a36Sopenharmony_ci	mtree_test_store(mt, 51, (void *)0x67);
240562306a36Sopenharmony_ci	mtree_test_insert(mt, 611, (void *)0x4c7);
240662306a36Sopenharmony_ci	mtree_test_insert(mt, 485, (void *)0x3cb);
240762306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
240862306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
240962306a36Sopenharmony_ci	mtree_test_insert(mt, 0, (void *)0x1);
241062306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
241162306a36Sopenharmony_ci	mtree_test_insert_range(mt, 26, 1, (void *)0x35);
241262306a36Sopenharmony_ci	mtree_test_load(mt, 1);
241362306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 22, (void *)0x3);
241462306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
241562306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
241662306a36Sopenharmony_ci	mtree_test_load(mt, 53);
241762306a36Sopenharmony_ci	mtree_test_load(mt, 1);
241862306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 1, (void *)0x3);
241962306a36Sopenharmony_ci	mtree_test_insert(mt, 222, (void *)0x1bd);
242062306a36Sopenharmony_ci	mtree_test_insert(mt, 485, (void *)0x3cb);
242162306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
242262306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
242362306a36Sopenharmony_ci	mtree_test_load(mt, 0);
242462306a36Sopenharmony_ci	mtree_test_insert(mt, 21, (void *)0x2b);
242562306a36Sopenharmony_ci	mtree_test_insert(mt, 3, (void *)0x7);
242662306a36Sopenharmony_ci	mtree_test_store(mt, 621, (void *)0x4db);
242762306a36Sopenharmony_ci	mtree_test_insert(mt, 0, (void *)0x1);
242862306a36Sopenharmony_ci	mtree_test_erase(mt, 5);
242962306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
243062306a36Sopenharmony_ci	mtree_test_store(mt, 62, (void *)0x7d);
243162306a36Sopenharmony_ci	mtree_test_erase(mt, 62);
243262306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 0, (void *)0x3);
243362306a36Sopenharmony_ci	mtree_test_insert(mt, 22, (void *)0x2d);
243462306a36Sopenharmony_ci	mtree_test_insert(mt, 12, (void *)0x19);
243562306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
243662306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
243762306a36Sopenharmony_ci	mtree_test_store_range(mt, 4, 62, (void *)0x9);
243862306a36Sopenharmony_ci	mtree_test_erase(mt, 62);
243962306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
244062306a36Sopenharmony_ci	mtree_test_load(mt, 1);
244162306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 22, (void *)0x3);
244262306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
244362306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
244462306a36Sopenharmony_ci	mtree_test_load(mt, 53);
244562306a36Sopenharmony_ci	mtree_test_load(mt, 1);
244662306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 1, (void *)0x3);
244762306a36Sopenharmony_ci	mtree_test_insert(mt, 222, (void *)0x1bd);
244862306a36Sopenharmony_ci	mtree_test_insert(mt, 485, (void *)0x3cb);
244962306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
245062306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
245162306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
245262306a36Sopenharmony_ci	mtree_test_load(mt, 0);
245362306a36Sopenharmony_ci	mtree_test_load(mt, 0);
245462306a36Sopenharmony_ci	mtree_destroy(mt);
245562306a36Sopenharmony_ci
245662306a36Sopenharmony_ci	/*
245762306a36Sopenharmony_ci	 * 7. Previous fix was incomplete, fix mas_resuse_node() clearing of old
245862306a36Sopenharmony_ci	 * data by overwriting it first - that way metadata is of no concern.
245962306a36Sopenharmony_ci	 */
246062306a36Sopenharmony_ci	mt_init_flags(mt, 0);
246162306a36Sopenharmony_ci	mtree_test_load(mt, 1);
246262306a36Sopenharmony_ci	mtree_test_insert(mt, 102, (void *)0xcd);
246362306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
246462306a36Sopenharmony_ci	mtree_test_erase(mt, 0);
246562306a36Sopenharmony_ci	mtree_test_load(mt, 0);
246662306a36Sopenharmony_ci	mtree_test_insert(mt, 4, (void *)0x9);
246762306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
246862306a36Sopenharmony_ci	mtree_test_insert(mt, 110, (void *)0xdd);
246962306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
247062306a36Sopenharmony_ci	mtree_test_insert_range(mt, 5, 0, (void *)0xb);
247162306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
247262306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
247362306a36Sopenharmony_ci	mtree_test_store(mt, 112, (void *)0xe1);
247462306a36Sopenharmony_ci	mtree_test_insert(mt, 21, (void *)0x2b);
247562306a36Sopenharmony_ci	mtree_test_store(mt, 1, (void *)0x3);
247662306a36Sopenharmony_ci	mtree_test_insert_range(mt, 110, 2, (void *)0xdd);
247762306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
247862306a36Sopenharmony_ci	mtree_test_load(mt, 22);
247962306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
248062306a36Sopenharmony_ci	mtree_test_store(mt, 210, (void *)0x1a5);
248162306a36Sopenharmony_ci	mtree_test_store_range(mt, 0, 2, (void *)0x1);
248262306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
248362306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
248462306a36Sopenharmony_ci	mtree_test_erase(mt, 22);
248562306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
248662306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
248762306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
248862306a36Sopenharmony_ci	mtree_test_load(mt, 112);
248962306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
249062306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
249162306a36Sopenharmony_ci	mtree_test_store(mt, 1, (void *)0x3);
249262306a36Sopenharmony_ci	mtree_test_insert_range(mt, 1, 2, (void *)0x3);
249362306a36Sopenharmony_ci	mtree_test_erase(mt, 0);
249462306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
249562306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
249662306a36Sopenharmony_ci	mtree_test_erase(mt, 0);
249762306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
249862306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
249962306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
250062306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
250162306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
250262306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
250362306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
250462306a36Sopenharmony_ci	mtree_test_insert_range(mt, 1, 2, (void *)0x3);
250562306a36Sopenharmony_ci	mtree_test_erase(mt, 0);
250662306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
250762306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
250862306a36Sopenharmony_ci	mtree_test_load(mt, 112);
250962306a36Sopenharmony_ci	mtree_test_store_range(mt, 110, 12, (void *)0xdd);
251062306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
251162306a36Sopenharmony_ci	mtree_test_load(mt, 110);
251262306a36Sopenharmony_ci	mtree_test_insert_range(mt, 4, 71, (void *)0x9);
251362306a36Sopenharmony_ci	mtree_test_load(mt, 2);
251462306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
251562306a36Sopenharmony_ci	mtree_test_insert_range(mt, 11, 22, (void *)0x17);
251662306a36Sopenharmony_ci	mtree_test_erase(mt, 12);
251762306a36Sopenharmony_ci	mtree_test_store(mt, 2, (void *)0x5);
251862306a36Sopenharmony_ci	mtree_test_load(mt, 22);
251962306a36Sopenharmony_ci	mtree_destroy(mt);
252062306a36Sopenharmony_ci
252162306a36Sopenharmony_ci
252262306a36Sopenharmony_ci	/*
252362306a36Sopenharmony_ci	 * 8.  When rebalancing or spanning_rebalance(), the max of the new node
252462306a36Sopenharmony_ci	 * may be set incorrectly to the final pivot and not the right max.
252562306a36Sopenharmony_ci	 * Fix by setting the left max to orig right max if the entire node is
252662306a36Sopenharmony_ci	 * consumed.
252762306a36Sopenharmony_ci	 */
252862306a36Sopenharmony_ci	mt_init_flags(mt, 0);
252962306a36Sopenharmony_ci	mtree_test_store(mt, 6, (void *)0xd);
253062306a36Sopenharmony_ci	mtree_test_store(mt, 67, (void *)0x87);
253162306a36Sopenharmony_ci	mtree_test_insert(mt, 15, (void *)0x1f);
253262306a36Sopenharmony_ci	mtree_test_insert(mt, 6716, (void *)0x3479);
253362306a36Sopenharmony_ci	mtree_test_store(mt, 61, (void *)0x7b);
253462306a36Sopenharmony_ci	mtree_test_insert(mt, 13, (void *)0x1b);
253562306a36Sopenharmony_ci	mtree_test_store(mt, 8, (void *)0x11);
253662306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
253762306a36Sopenharmony_ci	mtree_test_load(mt, 0);
253862306a36Sopenharmony_ci	mtree_test_erase(mt, 67167);
253962306a36Sopenharmony_ci	mtree_test_insert_range(mt, 6, 7167, (void *)0xd);
254062306a36Sopenharmony_ci	mtree_test_insert(mt, 6, (void *)0xd);
254162306a36Sopenharmony_ci	mtree_test_erase(mt, 67);
254262306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
254362306a36Sopenharmony_ci	mtree_test_erase(mt, 667167);
254462306a36Sopenharmony_ci	mtree_test_insert(mt, 6, (void *)0xd);
254562306a36Sopenharmony_ci	mtree_test_store(mt, 67, (void *)0x87);
254662306a36Sopenharmony_ci	mtree_test_insert(mt, 5, (void *)0xb);
254762306a36Sopenharmony_ci	mtree_test_erase(mt, 1);
254862306a36Sopenharmony_ci	mtree_test_insert(mt, 6, (void *)0xd);
254962306a36Sopenharmony_ci	mtree_test_erase(mt, 67);
255062306a36Sopenharmony_ci	mtree_test_insert(mt, 15, (void *)0x1f);
255162306a36Sopenharmony_ci	mtree_test_insert(mt, 67167, (void *)0x20cbf);
255262306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
255362306a36Sopenharmony_ci	mtree_test_load(mt, 7);
255462306a36Sopenharmony_ci	mtree_test_insert(mt, 16, (void *)0x21);
255562306a36Sopenharmony_ci	mtree_test_insert(mt, 36, (void *)0x49);
255662306a36Sopenharmony_ci	mtree_test_store(mt, 67, (void *)0x87);
255762306a36Sopenharmony_ci	mtree_test_store(mt, 6, (void *)0xd);
255862306a36Sopenharmony_ci	mtree_test_insert(mt, 367, (void *)0x2df);
255962306a36Sopenharmony_ci	mtree_test_insert(mt, 115, (void *)0xe7);
256062306a36Sopenharmony_ci	mtree_test_store(mt, 0, (void *)0x1);
256162306a36Sopenharmony_ci	mtree_test_store_range(mt, 1, 3, (void *)0x3);
256262306a36Sopenharmony_ci	mtree_test_store(mt, 1, (void *)0x3);
256362306a36Sopenharmony_ci	mtree_test_erase(mt, 67167);
256462306a36Sopenharmony_ci	mtree_test_insert_range(mt, 6, 47, (void *)0xd);
256562306a36Sopenharmony_ci	mtree_test_store(mt, 1, (void *)0x3);
256662306a36Sopenharmony_ci	mtree_test_insert_range(mt, 1, 67, (void *)0x3);
256762306a36Sopenharmony_ci	mtree_test_load(mt, 67);
256862306a36Sopenharmony_ci	mtree_test_insert(mt, 1, (void *)0x3);
256962306a36Sopenharmony_ci	mtree_test_erase(mt, 67167);
257062306a36Sopenharmony_ci	mtree_destroy(mt);
257162306a36Sopenharmony_ci
257262306a36Sopenharmony_ci	/*
257362306a36Sopenharmony_ci	 * 9. spanning store to the end of data caused an invalid metadata
257462306a36Sopenharmony_ci	 * length which resulted in a crash eventually.
257562306a36Sopenharmony_ci	 * Fix by checking if there is a value in pivot before incrementing the
257662306a36Sopenharmony_ci	 * metadata end in mab_mas_cp().  To ensure this doesn't happen again,
257762306a36Sopenharmony_ci	 * abstract the two locations this happens into a function called
257862306a36Sopenharmony_ci	 * mas_leaf_set_meta().
257962306a36Sopenharmony_ci	 */
258062306a36Sopenharmony_ci	mt_init_flags(mt, 0);
258162306a36Sopenharmony_ci	mtree_test_insert(mt, 21, (void *)0x2b);
258262306a36Sopenharmony_ci	mtree_test_insert(mt, 12, (void *)0x19);
258362306a36Sopenharmony_ci	mtree_test_insert(mt, 6, (void *)0xd);
258462306a36Sopenharmony_ci	mtree_test_insert(mt, 8, (void *)0x11);
258562306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
258662306a36Sopenharmony_ci	mtree_test_insert(mt, 91, (void *)0xb7);
258762306a36Sopenharmony_ci	mtree_test_insert(mt, 18, (void *)0x25);
258862306a36Sopenharmony_ci	mtree_test_insert(mt, 81, (void *)0xa3);
258962306a36Sopenharmony_ci	mtree_test_store_range(mt, 0, 128, (void *)0x1);
259062306a36Sopenharmony_ci	mtree_test_store(mt, 1, (void *)0x3);
259162306a36Sopenharmony_ci	mtree_test_erase(mt, 8);
259262306a36Sopenharmony_ci	mtree_test_insert(mt, 11, (void *)0x17);
259362306a36Sopenharmony_ci	mtree_test_insert(mt, 8, (void *)0x11);
259462306a36Sopenharmony_ci	mtree_test_insert(mt, 21, (void *)0x2b);
259562306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
259662306a36Sopenharmony_ci	mtree_test_insert(mt, ULONG_MAX - 10, (void *)0xffffffffffffffeb);
259762306a36Sopenharmony_ci	mtree_test_erase(mt, ULONG_MAX - 10);
259862306a36Sopenharmony_ci	mtree_test_store_range(mt, 0, 281, (void *)0x1);
259962306a36Sopenharmony_ci	mtree_test_erase(mt, 2);
260062306a36Sopenharmony_ci	mtree_test_insert(mt, 1211, (void *)0x977);
260162306a36Sopenharmony_ci	mtree_test_insert(mt, 111, (void *)0xdf);
260262306a36Sopenharmony_ci	mtree_test_insert(mt, 13, (void *)0x1b);
260362306a36Sopenharmony_ci	mtree_test_insert(mt, 211, (void *)0x1a7);
260462306a36Sopenharmony_ci	mtree_test_insert(mt, 11, (void *)0x17);
260562306a36Sopenharmony_ci	mtree_test_insert(mt, 5, (void *)0xb);
260662306a36Sopenharmony_ci	mtree_test_insert(mt, 1218, (void *)0x985);
260762306a36Sopenharmony_ci	mtree_test_insert(mt, 61, (void *)0x7b);
260862306a36Sopenharmony_ci	mtree_test_store(mt, 1, (void *)0x3);
260962306a36Sopenharmony_ci	mtree_test_insert(mt, 121, (void *)0xf3);
261062306a36Sopenharmony_ci	mtree_test_insert(mt, 8, (void *)0x11);
261162306a36Sopenharmony_ci	mtree_test_insert(mt, 21, (void *)0x2b);
261262306a36Sopenharmony_ci	mtree_test_insert(mt, 2, (void *)0x5);
261362306a36Sopenharmony_ci	mtree_test_insert(mt, ULONG_MAX - 10, (void *)0xffffffffffffffeb);
261462306a36Sopenharmony_ci	mtree_test_erase(mt, ULONG_MAX - 10);
261562306a36Sopenharmony_ci}
261662306a36Sopenharmony_ci
261762306a36Sopenharmony_ci/* duplicate the tree with a specific gap */
261862306a36Sopenharmony_cistatic noinline void __init check_dup_gaps(struct maple_tree *mt,
261962306a36Sopenharmony_ci				    unsigned long nr_entries, bool zero_start,
262062306a36Sopenharmony_ci				    unsigned long gap)
262162306a36Sopenharmony_ci{
262262306a36Sopenharmony_ci	unsigned long i = 0;
262362306a36Sopenharmony_ci	struct maple_tree newmt;
262462306a36Sopenharmony_ci	int ret;
262562306a36Sopenharmony_ci	void *tmp;
262662306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
262762306a36Sopenharmony_ci	MA_STATE(newmas, &newmt, 0, 0);
262862306a36Sopenharmony_ci	struct rw_semaphore newmt_lock;
262962306a36Sopenharmony_ci
263062306a36Sopenharmony_ci	init_rwsem(&newmt_lock);
263162306a36Sopenharmony_ci	mt_set_external_lock(&newmt, &newmt_lock);
263262306a36Sopenharmony_ci
263362306a36Sopenharmony_ci	if (!zero_start)
263462306a36Sopenharmony_ci		i = 1;
263562306a36Sopenharmony_ci
263662306a36Sopenharmony_ci	mt_zero_nr_tallocated();
263762306a36Sopenharmony_ci	for (; i <= nr_entries; i++)
263862306a36Sopenharmony_ci		mtree_store_range(mt, i*10, (i+1)*10 - gap,
263962306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
264062306a36Sopenharmony_ci
264162306a36Sopenharmony_ci	mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN);
264262306a36Sopenharmony_ci	mt_set_non_kernel(99999);
264362306a36Sopenharmony_ci	down_write(&newmt_lock);
264462306a36Sopenharmony_ci	ret = mas_expected_entries(&newmas, nr_entries);
264562306a36Sopenharmony_ci	mt_set_non_kernel(0);
264662306a36Sopenharmony_ci	MT_BUG_ON(mt, ret != 0);
264762306a36Sopenharmony_ci
264862306a36Sopenharmony_ci	rcu_read_lock();
264962306a36Sopenharmony_ci	mas_for_each(&mas, tmp, ULONG_MAX) {
265062306a36Sopenharmony_ci		newmas.index = mas.index;
265162306a36Sopenharmony_ci		newmas.last = mas.last;
265262306a36Sopenharmony_ci		mas_store(&newmas, tmp);
265362306a36Sopenharmony_ci	}
265462306a36Sopenharmony_ci	rcu_read_unlock();
265562306a36Sopenharmony_ci	mas_destroy(&newmas);
265662306a36Sopenharmony_ci
265762306a36Sopenharmony_ci	__mt_destroy(&newmt);
265862306a36Sopenharmony_ci	up_write(&newmt_lock);
265962306a36Sopenharmony_ci}
266062306a36Sopenharmony_ci
266162306a36Sopenharmony_ci/* Duplicate many sizes of trees.  Mainly to test expected entry values */
266262306a36Sopenharmony_cistatic noinline void __init check_dup(struct maple_tree *mt)
266362306a36Sopenharmony_ci{
266462306a36Sopenharmony_ci	int i;
266562306a36Sopenharmony_ci	int big_start = 100010;
266662306a36Sopenharmony_ci
266762306a36Sopenharmony_ci	/* Check with a value at zero */
266862306a36Sopenharmony_ci	for (i = 10; i < 1000; i++) {
266962306a36Sopenharmony_ci		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
267062306a36Sopenharmony_ci		check_dup_gaps(mt, i, true, 5);
267162306a36Sopenharmony_ci		mtree_destroy(mt);
267262306a36Sopenharmony_ci		rcu_barrier();
267362306a36Sopenharmony_ci	}
267462306a36Sopenharmony_ci
267562306a36Sopenharmony_ci	cond_resched();
267662306a36Sopenharmony_ci	mt_cache_shrink();
267762306a36Sopenharmony_ci	/* Check with a value at zero, no gap */
267862306a36Sopenharmony_ci	for (i = 1000; i < 2000; i++) {
267962306a36Sopenharmony_ci		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
268062306a36Sopenharmony_ci		check_dup_gaps(mt, i, true, 0);
268162306a36Sopenharmony_ci		mtree_destroy(mt);
268262306a36Sopenharmony_ci		rcu_barrier();
268362306a36Sopenharmony_ci	}
268462306a36Sopenharmony_ci
268562306a36Sopenharmony_ci	cond_resched();
268662306a36Sopenharmony_ci	mt_cache_shrink();
268762306a36Sopenharmony_ci	/* Check with a value at zero and unreasonably large */
268862306a36Sopenharmony_ci	for (i = big_start; i < big_start + 10; i++) {
268962306a36Sopenharmony_ci		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
269062306a36Sopenharmony_ci		check_dup_gaps(mt, i, true, 5);
269162306a36Sopenharmony_ci		mtree_destroy(mt);
269262306a36Sopenharmony_ci		rcu_barrier();
269362306a36Sopenharmony_ci	}
269462306a36Sopenharmony_ci
269562306a36Sopenharmony_ci	cond_resched();
269662306a36Sopenharmony_ci	mt_cache_shrink();
269762306a36Sopenharmony_ci	/* Small to medium size not starting at zero*/
269862306a36Sopenharmony_ci	for (i = 200; i < 1000; i++) {
269962306a36Sopenharmony_ci		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
270062306a36Sopenharmony_ci		check_dup_gaps(mt, i, false, 5);
270162306a36Sopenharmony_ci		mtree_destroy(mt);
270262306a36Sopenharmony_ci		rcu_barrier();
270362306a36Sopenharmony_ci	}
270462306a36Sopenharmony_ci
270562306a36Sopenharmony_ci	cond_resched();
270662306a36Sopenharmony_ci	mt_cache_shrink();
270762306a36Sopenharmony_ci	/* Unreasonably large not starting at zero*/
270862306a36Sopenharmony_ci	for (i = big_start; i < big_start + 10; i++) {
270962306a36Sopenharmony_ci		mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);
271062306a36Sopenharmony_ci		check_dup_gaps(mt, i, false, 5);
271162306a36Sopenharmony_ci		mtree_destroy(mt);
271262306a36Sopenharmony_ci		rcu_barrier();
271362306a36Sopenharmony_ci		cond_resched();
271462306a36Sopenharmony_ci		mt_cache_shrink();
271562306a36Sopenharmony_ci	}
271662306a36Sopenharmony_ci
271762306a36Sopenharmony_ci	/* Check non-allocation tree not starting at zero */
271862306a36Sopenharmony_ci	for (i = 1500; i < 3000; i++) {
271962306a36Sopenharmony_ci		mt_init_flags(mt, 0);
272062306a36Sopenharmony_ci		check_dup_gaps(mt, i, false, 5);
272162306a36Sopenharmony_ci		mtree_destroy(mt);
272262306a36Sopenharmony_ci		rcu_barrier();
272362306a36Sopenharmony_ci		cond_resched();
272462306a36Sopenharmony_ci		if (i % 2 == 0)
272562306a36Sopenharmony_ci			mt_cache_shrink();
272662306a36Sopenharmony_ci	}
272762306a36Sopenharmony_ci
272862306a36Sopenharmony_ci	mt_cache_shrink();
272962306a36Sopenharmony_ci	/* Check non-allocation tree starting at zero */
273062306a36Sopenharmony_ci	for (i = 200; i < 1000; i++) {
273162306a36Sopenharmony_ci		mt_init_flags(mt, 0);
273262306a36Sopenharmony_ci		check_dup_gaps(mt, i, true, 5);
273362306a36Sopenharmony_ci		mtree_destroy(mt);
273462306a36Sopenharmony_ci		rcu_barrier();
273562306a36Sopenharmony_ci		cond_resched();
273662306a36Sopenharmony_ci	}
273762306a36Sopenharmony_ci
273862306a36Sopenharmony_ci	mt_cache_shrink();
273962306a36Sopenharmony_ci	/* Unreasonably large */
274062306a36Sopenharmony_ci	for (i = big_start + 5; i < big_start + 10; i++) {
274162306a36Sopenharmony_ci		mt_init_flags(mt, 0);
274262306a36Sopenharmony_ci		check_dup_gaps(mt, i, true, 5);
274362306a36Sopenharmony_ci		mtree_destroy(mt);
274462306a36Sopenharmony_ci		rcu_barrier();
274562306a36Sopenharmony_ci		mt_cache_shrink();
274662306a36Sopenharmony_ci		cond_resched();
274762306a36Sopenharmony_ci	}
274862306a36Sopenharmony_ci}
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_cistatic noinline void __init check_bnode_min_spanning(struct maple_tree *mt)
275162306a36Sopenharmony_ci{
275262306a36Sopenharmony_ci	int i = 50;
275362306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
275462306a36Sopenharmony_ci
275562306a36Sopenharmony_ci	mt_set_non_kernel(9999);
275662306a36Sopenharmony_ci	mas_lock(&mas);
275762306a36Sopenharmony_ci	do {
275862306a36Sopenharmony_ci		mas_set_range(&mas, i*10, i*10+9);
275962306a36Sopenharmony_ci		mas_store(&mas, check_bnode_min_spanning);
276062306a36Sopenharmony_ci	} while (i--);
276162306a36Sopenharmony_ci
276262306a36Sopenharmony_ci	mas_set_range(&mas, 240, 509);
276362306a36Sopenharmony_ci	mas_store(&mas, NULL);
276462306a36Sopenharmony_ci	mas_unlock(&mas);
276562306a36Sopenharmony_ci	mas_destroy(&mas);
276662306a36Sopenharmony_ci	mt_set_non_kernel(0);
276762306a36Sopenharmony_ci}
276862306a36Sopenharmony_ci
276962306a36Sopenharmony_cistatic noinline void __init check_empty_area_window(struct maple_tree *mt)
277062306a36Sopenharmony_ci{
277162306a36Sopenharmony_ci	unsigned long i, nr_entries = 20;
277262306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
277362306a36Sopenharmony_ci
277462306a36Sopenharmony_ci	for (i = 1; i <= nr_entries; i++)
277562306a36Sopenharmony_ci		mtree_store_range(mt, i*10, i*10 + 9,
277662306a36Sopenharmony_ci				  xa_mk_value(i), GFP_KERNEL);
277762306a36Sopenharmony_ci
277862306a36Sopenharmony_ci	/* Create another hole besides the one at 0 */
277962306a36Sopenharmony_ci	mtree_store_range(mt, 160, 169, NULL, GFP_KERNEL);
278062306a36Sopenharmony_ci
278162306a36Sopenharmony_ci	/* Check lower bounds that don't fit */
278262306a36Sopenharmony_ci	rcu_read_lock();
278362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 10) != -EBUSY);
278462306a36Sopenharmony_ci
278562306a36Sopenharmony_ci	mas_reset(&mas);
278662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 6, 90, 5) != -EBUSY);
278762306a36Sopenharmony_ci
278862306a36Sopenharmony_ci	/* Check lower bound that does fit */
278962306a36Sopenharmony_ci	mas_reset(&mas);
279062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 5) != 0);
279162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 5);
279262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 9);
279362306a36Sopenharmony_ci	rcu_read_unlock();
279462306a36Sopenharmony_ci
279562306a36Sopenharmony_ci	/* Check one gap that doesn't fit and one that does */
279662306a36Sopenharmony_ci	rcu_read_lock();
279762306a36Sopenharmony_ci	mas_reset(&mas);
279862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 217, 9) != 0);
279962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 161);
280062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 169);
280162306a36Sopenharmony_ci
280262306a36Sopenharmony_ci	/* Check one gap that does fit above the min */
280362306a36Sopenharmony_ci	mas_reset(&mas);
280462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 3) != 0);
280562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 216);
280662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 218);
280762306a36Sopenharmony_ci
280862306a36Sopenharmony_ci	/* Check size that doesn't fit any gap */
280962306a36Sopenharmony_ci	mas_reset(&mas);
281062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 16) != -EBUSY);
281162306a36Sopenharmony_ci
281262306a36Sopenharmony_ci	/*
281362306a36Sopenharmony_ci	 * Check size that doesn't fit the lower end of the window but
281462306a36Sopenharmony_ci	 * does fit the gap
281562306a36Sopenharmony_ci	 */
281662306a36Sopenharmony_ci	mas_reset(&mas);
281762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 167, 200, 4) != -EBUSY);
281862306a36Sopenharmony_ci
281962306a36Sopenharmony_ci	/*
282062306a36Sopenharmony_ci	 * Check size that doesn't fit the upper end of the window but
282162306a36Sopenharmony_ci	 * does fit the gap
282262306a36Sopenharmony_ci	 */
282362306a36Sopenharmony_ci	mas_reset(&mas);
282462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 162, 4) != -EBUSY);
282562306a36Sopenharmony_ci
282662306a36Sopenharmony_ci	/* Check mas_empty_area forward */
282762306a36Sopenharmony_ci	mas_reset(&mas);
282862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 9) != 0);
282962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
283062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 8);
283162306a36Sopenharmony_ci
283262306a36Sopenharmony_ci	mas_reset(&mas);
283362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 4) != 0);
283462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
283562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 3);
283662306a36Sopenharmony_ci
283762306a36Sopenharmony_ci	mas_reset(&mas);
283862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 11) != -EBUSY);
283962306a36Sopenharmony_ci
284062306a36Sopenharmony_ci	mas_reset(&mas);
284162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 5, 100, 6) != -EBUSY);
284262306a36Sopenharmony_ci
284362306a36Sopenharmony_ci	mas_reset(&mas);
284462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 0, 8, 10) != -EINVAL);
284562306a36Sopenharmony_ci
284662306a36Sopenharmony_ci	mas_reset(&mas);
284762306a36Sopenharmony_ci	mas_empty_area(&mas, 100, 165, 3);
284862306a36Sopenharmony_ci
284962306a36Sopenharmony_ci	mas_reset(&mas);
285062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 100, 163, 6) != -EBUSY);
285162306a36Sopenharmony_ci	rcu_read_unlock();
285262306a36Sopenharmony_ci}
285362306a36Sopenharmony_ci
285462306a36Sopenharmony_cistatic noinline void __init check_empty_area_fill(struct maple_tree *mt)
285562306a36Sopenharmony_ci{
285662306a36Sopenharmony_ci	const unsigned long max = 0x25D78000;
285762306a36Sopenharmony_ci	unsigned long size;
285862306a36Sopenharmony_ci	int loop, shift;
285962306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
286062306a36Sopenharmony_ci
286162306a36Sopenharmony_ci	mt_set_non_kernel(99999);
286262306a36Sopenharmony_ci	for (shift = 12; shift <= 16; shift++) {
286362306a36Sopenharmony_ci		loop = 5000;
286462306a36Sopenharmony_ci		size = 1 << shift;
286562306a36Sopenharmony_ci		while (loop--) {
286662306a36Sopenharmony_ci			mas_set(&mas, 0);
286762306a36Sopenharmony_ci			mas_lock(&mas);
286862306a36Sopenharmony_ci			MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != 0);
286962306a36Sopenharmony_ci			MT_BUG_ON(mt, mas.last != mas.index + size - 1);
287062306a36Sopenharmony_ci			mas_store_gfp(&mas, (void *)size, GFP_KERNEL);
287162306a36Sopenharmony_ci			mas_unlock(&mas);
287262306a36Sopenharmony_ci			mas_reset(&mas);
287362306a36Sopenharmony_ci		}
287462306a36Sopenharmony_ci	}
287562306a36Sopenharmony_ci
287662306a36Sopenharmony_ci	/* No space left. */
287762306a36Sopenharmony_ci	size = 0x1000;
287862306a36Sopenharmony_ci	rcu_read_lock();
287962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != -EBUSY);
288062306a36Sopenharmony_ci	rcu_read_unlock();
288162306a36Sopenharmony_ci
288262306a36Sopenharmony_ci	/* Fill a depth 3 node to the maximum */
288362306a36Sopenharmony_ci	for (unsigned long i = 629440511; i <= 629440800; i += 6)
288462306a36Sopenharmony_ci		mtree_store_range(mt, i, i + 5, (void *)i, GFP_KERNEL);
288562306a36Sopenharmony_ci	/* Make space in the second-last depth 4 node */
288662306a36Sopenharmony_ci	mtree_erase(mt, 631668735);
288762306a36Sopenharmony_ci	/* Make space in the last depth 4 node */
288862306a36Sopenharmony_ci	mtree_erase(mt, 629506047);
288962306a36Sopenharmony_ci	mas_reset(&mas);
289062306a36Sopenharmony_ci	/* Search from just after the gap in the second-last depth 4 */
289162306a36Sopenharmony_ci	rcu_read_lock();
289262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas_empty_area(&mas, 629506048, 690000000, 0x5000) != 0);
289362306a36Sopenharmony_ci	rcu_read_unlock();
289462306a36Sopenharmony_ci	mt_set_non_kernel(0);
289562306a36Sopenharmony_ci}
289662306a36Sopenharmony_ci
289762306a36Sopenharmony_ci/*
289862306a36Sopenharmony_ci * Check MAS_START, MAS_PAUSE, active (implied), and MAS_NONE transitions.
289962306a36Sopenharmony_ci *
290062306a36Sopenharmony_ci * The table below shows the single entry tree (0-0 pointer) and normal tree
290162306a36Sopenharmony_ci * with nodes.
290262306a36Sopenharmony_ci *
290362306a36Sopenharmony_ci * Function	ENTRY	Start		Result		index & last
290462306a36Sopenharmony_ci *     ┬          ┬       ┬               ┬                ┬
290562306a36Sopenharmony_ci *     │          │       │               │                └─ the final range
290662306a36Sopenharmony_ci *     │          │       │               └─ The node value after execution
290762306a36Sopenharmony_ci *     │          │       └─ The node value before execution
290862306a36Sopenharmony_ci *     │          └─ If the entry exists or does not exists (DNE)
290962306a36Sopenharmony_ci *     └─ The function name
291062306a36Sopenharmony_ci *
291162306a36Sopenharmony_ci * Function	ENTRY	Start		Result		index & last
291262306a36Sopenharmony_ci * mas_next()
291362306a36Sopenharmony_ci *  - after last
291462306a36Sopenharmony_ci *			Single entry tree at 0-0
291562306a36Sopenharmony_ci *			------------------------
291662306a36Sopenharmony_ci *		DNE	MAS_START	MAS_NONE	1 - oo
291762306a36Sopenharmony_ci *		DNE	MAS_PAUSE	MAS_NONE	1 - oo
291862306a36Sopenharmony_ci *		DNE	MAS_ROOT	MAS_NONE	1 - oo
291962306a36Sopenharmony_ci *			when index = 0
292062306a36Sopenharmony_ci *		DNE	MAS_NONE	MAS_ROOT	0
292162306a36Sopenharmony_ci *			when index > 0
292262306a36Sopenharmony_ci *		DNE	MAS_NONE	MAS_NONE	1 - oo
292362306a36Sopenharmony_ci *
292462306a36Sopenharmony_ci *			Normal tree
292562306a36Sopenharmony_ci *			-----------
292662306a36Sopenharmony_ci *		exists	MAS_START	active		range
292762306a36Sopenharmony_ci *		DNE	MAS_START	active		set to last range
292862306a36Sopenharmony_ci *		exists	MAS_PAUSE	active		range
292962306a36Sopenharmony_ci *		DNE	MAS_PAUSE	active		set to last range
293062306a36Sopenharmony_ci *		exists	MAS_NONE	active		range
293162306a36Sopenharmony_ci *		exists	active		active		range
293262306a36Sopenharmony_ci *		DNE	active		active		set to last range
293362306a36Sopenharmony_ci *		ERANGE	active		MAS_OVERFLOW	last range
293462306a36Sopenharmony_ci *
293562306a36Sopenharmony_ci * Function	ENTRY	Start		Result		index & last
293662306a36Sopenharmony_ci * mas_prev()
293762306a36Sopenharmony_ci * - before index
293862306a36Sopenharmony_ci *			Single entry tree at 0-0
293962306a36Sopenharmony_ci *			------------------------
294062306a36Sopenharmony_ci *				if index > 0
294162306a36Sopenharmony_ci *		exists	MAS_START	MAS_ROOT	0
294262306a36Sopenharmony_ci *		exists	MAS_PAUSE	MAS_ROOT	0
294362306a36Sopenharmony_ci *		exists	MAS_NONE	MAS_ROOT	0
294462306a36Sopenharmony_ci *
294562306a36Sopenharmony_ci *				if index == 0
294662306a36Sopenharmony_ci *		DNE	MAS_START	MAS_NONE	0
294762306a36Sopenharmony_ci *		DNE	MAS_PAUSE	MAS_NONE	0
294862306a36Sopenharmony_ci *		DNE	MAS_NONE	MAS_NONE	0
294962306a36Sopenharmony_ci *		DNE	MAS_ROOT	MAS_NONE	0
295062306a36Sopenharmony_ci *
295162306a36Sopenharmony_ci *			Normal tree
295262306a36Sopenharmony_ci *			-----------
295362306a36Sopenharmony_ci *		exists	MAS_START	active		range
295462306a36Sopenharmony_ci *		DNE	MAS_START	active		set to min
295562306a36Sopenharmony_ci *		exists	MAS_PAUSE	active		range
295662306a36Sopenharmony_ci *		DNE	MAS_PAUSE	active		set to min
295762306a36Sopenharmony_ci *		exists	MAS_NONE	active		range
295862306a36Sopenharmony_ci *		DNE	MAS_NONE	MAS_NONE	set to min
295962306a36Sopenharmony_ci *		any	MAS_ROOT	MAS_NONE	0
296062306a36Sopenharmony_ci *		exists	active		active		range
296162306a36Sopenharmony_ci *		DNE	active		active		last range
296262306a36Sopenharmony_ci *		ERANGE	active		MAS_UNDERFLOW	last range
296362306a36Sopenharmony_ci *
296462306a36Sopenharmony_ci * Function	ENTRY	Start		Result		index & last
296562306a36Sopenharmony_ci * mas_find()
296662306a36Sopenharmony_ci *  - at index or next
296762306a36Sopenharmony_ci *			Single entry tree at 0-0
296862306a36Sopenharmony_ci *			------------------------
296962306a36Sopenharmony_ci *				if index >  0
297062306a36Sopenharmony_ci *		DNE	MAS_START	MAS_NONE	0
297162306a36Sopenharmony_ci *		DNE	MAS_PAUSE	MAS_NONE	0
297262306a36Sopenharmony_ci *		DNE	MAS_ROOT	MAS_NONE	0
297362306a36Sopenharmony_ci *		DNE	MAS_NONE	MAS_NONE	1
297462306a36Sopenharmony_ci *				if index ==  0
297562306a36Sopenharmony_ci *		exists	MAS_START	MAS_ROOT	0
297662306a36Sopenharmony_ci *		exists	MAS_PAUSE	MAS_ROOT	0
297762306a36Sopenharmony_ci *		exists	MAS_NONE	MAS_ROOT	0
297862306a36Sopenharmony_ci *
297962306a36Sopenharmony_ci *			Normal tree
298062306a36Sopenharmony_ci *			-----------
298162306a36Sopenharmony_ci *		exists	MAS_START	active		range
298262306a36Sopenharmony_ci *		DNE	MAS_START	active		set to max
298362306a36Sopenharmony_ci *		exists	MAS_PAUSE	active		range
298462306a36Sopenharmony_ci *		DNE	MAS_PAUSE	active		set to max
298562306a36Sopenharmony_ci *		exists	MAS_NONE	active		range (start at last)
298662306a36Sopenharmony_ci *		exists	active		active		range
298762306a36Sopenharmony_ci *		DNE	active		active		last range (max < last)
298862306a36Sopenharmony_ci *
298962306a36Sopenharmony_ci * Function	ENTRY	Start		Result		index & last
299062306a36Sopenharmony_ci * mas_find_rev()
299162306a36Sopenharmony_ci *  - at index or before
299262306a36Sopenharmony_ci *			Single entry tree at 0-0
299362306a36Sopenharmony_ci *			------------------------
299462306a36Sopenharmony_ci *				if index >  0
299562306a36Sopenharmony_ci *		exists	MAS_START	MAS_ROOT	0
299662306a36Sopenharmony_ci *		exists	MAS_PAUSE	MAS_ROOT	0
299762306a36Sopenharmony_ci *		exists	MAS_NONE	MAS_ROOT	0
299862306a36Sopenharmony_ci *				if index ==  0
299962306a36Sopenharmony_ci *		DNE	MAS_START	MAS_NONE	0
300062306a36Sopenharmony_ci *		DNE	MAS_PAUSE	MAS_NONE	0
300162306a36Sopenharmony_ci *		DNE	MAS_NONE	MAS_NONE	0
300262306a36Sopenharmony_ci *		DNE	MAS_ROOT	MAS_NONE	0
300362306a36Sopenharmony_ci *
300462306a36Sopenharmony_ci *			Normal tree
300562306a36Sopenharmony_ci *			-----------
300662306a36Sopenharmony_ci *		exists	MAS_START	active		range
300762306a36Sopenharmony_ci *		DNE	MAS_START	active		set to min
300862306a36Sopenharmony_ci *		exists	MAS_PAUSE	active		range
300962306a36Sopenharmony_ci *		DNE	MAS_PAUSE	active		set to min
301062306a36Sopenharmony_ci *		exists	MAS_NONE	active		range (start at index)
301162306a36Sopenharmony_ci *		exists	active		active		range
301262306a36Sopenharmony_ci *		DNE	active		active		last range (min > index)
301362306a36Sopenharmony_ci *
301462306a36Sopenharmony_ci * Function	ENTRY	Start		Result		index & last
301562306a36Sopenharmony_ci * mas_walk()
301662306a36Sopenharmony_ci * - Look up index
301762306a36Sopenharmony_ci *			Single entry tree at 0-0
301862306a36Sopenharmony_ci *			------------------------
301962306a36Sopenharmony_ci *				if index >  0
302062306a36Sopenharmony_ci *		DNE	MAS_START	MAS_ROOT	1 - oo
302162306a36Sopenharmony_ci *		DNE	MAS_PAUSE	MAS_ROOT	1 - oo
302262306a36Sopenharmony_ci *		DNE	MAS_NONE	MAS_ROOT	1 - oo
302362306a36Sopenharmony_ci *		DNE	MAS_ROOT	MAS_ROOT	1 - oo
302462306a36Sopenharmony_ci *				if index ==  0
302562306a36Sopenharmony_ci *		exists	MAS_START	MAS_ROOT	0
302662306a36Sopenharmony_ci *		exists	MAS_PAUSE	MAS_ROOT	0
302762306a36Sopenharmony_ci *		exists	MAS_NONE	MAS_ROOT	0
302862306a36Sopenharmony_ci *		exists	MAS_ROOT	MAS_ROOT	0
302962306a36Sopenharmony_ci *
303062306a36Sopenharmony_ci *			Normal tree
303162306a36Sopenharmony_ci *			-----------
303262306a36Sopenharmony_ci *		exists	MAS_START	active		range
303362306a36Sopenharmony_ci *		DNE	MAS_START	active		range of NULL
303462306a36Sopenharmony_ci *		exists	MAS_PAUSE	active		range
303562306a36Sopenharmony_ci *		DNE	MAS_PAUSE	active		range of NULL
303662306a36Sopenharmony_ci *		exists	MAS_NONE	active		range
303762306a36Sopenharmony_ci *		DNE	MAS_NONE	active		range of NULL
303862306a36Sopenharmony_ci *		exists	active		active		range
303962306a36Sopenharmony_ci *		DNE	active		active		range of NULL
304062306a36Sopenharmony_ci */
304162306a36Sopenharmony_ci
304262306a36Sopenharmony_ci#define mas_active(x)		(((x).node != MAS_ROOT) && \
304362306a36Sopenharmony_ci				 ((x).node != MAS_START) && \
304462306a36Sopenharmony_ci				 ((x).node != MAS_PAUSE) && \
304562306a36Sopenharmony_ci				 ((x).node != MAS_NONE))
304662306a36Sopenharmony_cistatic noinline void __init check_state_handling(struct maple_tree *mt)
304762306a36Sopenharmony_ci{
304862306a36Sopenharmony_ci	MA_STATE(mas, mt, 0, 0);
304962306a36Sopenharmony_ci	void *entry, *ptr = (void *) 0x1234500;
305062306a36Sopenharmony_ci	void *ptr2 = &ptr;
305162306a36Sopenharmony_ci	void *ptr3 = &ptr2;
305262306a36Sopenharmony_ci
305362306a36Sopenharmony_ci	/* Check MAS_ROOT First */
305462306a36Sopenharmony_ci	mtree_store_range(mt, 0, 0, ptr, GFP_KERNEL);
305562306a36Sopenharmony_ci
305662306a36Sopenharmony_ci	mas_lock(&mas);
305762306a36Sopenharmony_ci	/* prev: Start -> underflow*/
305862306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
305962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
306062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
306162306a36Sopenharmony_ci
306262306a36Sopenharmony_ci	/* prev: Start -> root */
306362306a36Sopenharmony_ci	mas_set(&mas, 10);
306462306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
306562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
306662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
306762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
306862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
306962306a36Sopenharmony_ci
307062306a36Sopenharmony_ci	/* prev: pause -> root */
307162306a36Sopenharmony_ci	mas_set(&mas, 10);
307262306a36Sopenharmony_ci	mas_pause(&mas);
307362306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
307462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
307562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
307662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
307762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
307862306a36Sopenharmony_ci
307962306a36Sopenharmony_ci	/* next: start -> none */
308062306a36Sopenharmony_ci	mas_set(&mas, 0);
308162306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
308262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
308362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
308462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
308562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
308662306a36Sopenharmony_ci
308762306a36Sopenharmony_ci	/* next: start -> none*/
308862306a36Sopenharmony_ci	mas_set(&mas, 10);
308962306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
309062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
309162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
309262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
309362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
309462306a36Sopenharmony_ci
309562306a36Sopenharmony_ci	/* find: start -> root */
309662306a36Sopenharmony_ci	mas_set(&mas, 0);
309762306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
309862306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
309962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
310062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
310162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
310262306a36Sopenharmony_ci
310362306a36Sopenharmony_ci	/* find: root -> none */
310462306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
310562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
310662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
310762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
310862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
310962306a36Sopenharmony_ci
311062306a36Sopenharmony_ci	/* find: none -> none */
311162306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
311262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
311362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
311462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
311562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
311662306a36Sopenharmony_ci
311762306a36Sopenharmony_ci	/* find: start -> none */
311862306a36Sopenharmony_ci	mas_set(&mas, 10);
311962306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
312062306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
312162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
312262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
312362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
312462306a36Sopenharmony_ci
312562306a36Sopenharmony_ci	/* find_rev: none -> root */
312662306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
312762306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
312862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
312962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
313062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
313162306a36Sopenharmony_ci
313262306a36Sopenharmony_ci	/* find_rev: start -> root */
313362306a36Sopenharmony_ci	mas_set(&mas, 0);
313462306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
313562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
313662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
313762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
313862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
313962306a36Sopenharmony_ci
314062306a36Sopenharmony_ci	/* find_rev: root -> none */
314162306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
314262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
314362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
314462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
314562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
314662306a36Sopenharmony_ci
314762306a36Sopenharmony_ci	/* find_rev: none -> none */
314862306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
314962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
315062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
315162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
315262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
315362306a36Sopenharmony_ci
315462306a36Sopenharmony_ci	/* find_rev: start -> root */
315562306a36Sopenharmony_ci	mas_set(&mas, 10);
315662306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
315762306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
315862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
315962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
316062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
316162306a36Sopenharmony_ci
316262306a36Sopenharmony_ci	/* walk: start -> none */
316362306a36Sopenharmony_ci	mas_set(&mas, 10);
316462306a36Sopenharmony_ci	entry = mas_walk(&mas);
316562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
316662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
316762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
316862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
316962306a36Sopenharmony_ci
317062306a36Sopenharmony_ci	/* walk: pause -> none*/
317162306a36Sopenharmony_ci	mas_set(&mas, 10);
317262306a36Sopenharmony_ci	mas_pause(&mas);
317362306a36Sopenharmony_ci	entry = mas_walk(&mas);
317462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
317562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
317662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
317762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
317862306a36Sopenharmony_ci
317962306a36Sopenharmony_ci	/* walk: none -> none */
318062306a36Sopenharmony_ci	mas.index = mas.last = 10;
318162306a36Sopenharmony_ci	entry = mas_walk(&mas);
318262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
318362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
318462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
318562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
318662306a36Sopenharmony_ci
318762306a36Sopenharmony_ci	/* walk: none -> none */
318862306a36Sopenharmony_ci	entry = mas_walk(&mas);
318962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
319062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
319162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
319262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
319362306a36Sopenharmony_ci
319462306a36Sopenharmony_ci	/* walk: start -> root */
319562306a36Sopenharmony_ci	mas_set(&mas, 0);
319662306a36Sopenharmony_ci	entry = mas_walk(&mas);
319762306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
319862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
319962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
320062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
320162306a36Sopenharmony_ci
320262306a36Sopenharmony_ci	/* walk: pause -> root */
320362306a36Sopenharmony_ci	mas_set(&mas, 0);
320462306a36Sopenharmony_ci	mas_pause(&mas);
320562306a36Sopenharmony_ci	entry = mas_walk(&mas);
320662306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
320762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
320862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
320962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
321062306a36Sopenharmony_ci
321162306a36Sopenharmony_ci	/* walk: none -> root */
321262306a36Sopenharmony_ci	mas.node = MAS_NONE;
321362306a36Sopenharmony_ci	entry = mas_walk(&mas);
321462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
321562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
321662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
321762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
321862306a36Sopenharmony_ci
321962306a36Sopenharmony_ci	/* walk: root -> root */
322062306a36Sopenharmony_ci	entry = mas_walk(&mas);
322162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
322262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
322362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
322462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
322562306a36Sopenharmony_ci
322662306a36Sopenharmony_ci	/* walk: root -> none */
322762306a36Sopenharmony_ci	mas_set(&mas, 10);
322862306a36Sopenharmony_ci	entry = mas_walk(&mas);
322962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
323062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 1);
323162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
323262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_NONE);
323362306a36Sopenharmony_ci
323462306a36Sopenharmony_ci	/* walk: none -> root */
323562306a36Sopenharmony_ci	mas.index = mas.last = 0;
323662306a36Sopenharmony_ci	entry = mas_walk(&mas);
323762306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
323862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
323962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0);
324062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_ROOT);
324162306a36Sopenharmony_ci
324262306a36Sopenharmony_ci	mas_unlock(&mas);
324362306a36Sopenharmony_ci
324462306a36Sopenharmony_ci	/* Check when there is an actual node */
324562306a36Sopenharmony_ci	mtree_store_range(mt, 0, 0, NULL, GFP_KERNEL);
324662306a36Sopenharmony_ci	mtree_store_range(mt, 0x1000, 0x1500, ptr, GFP_KERNEL);
324762306a36Sopenharmony_ci	mtree_store_range(mt, 0x2000, 0x2500, ptr2, GFP_KERNEL);
324862306a36Sopenharmony_ci	mtree_store_range(mt, 0x3000, 0x3500, ptr3, GFP_KERNEL);
324962306a36Sopenharmony_ci
325062306a36Sopenharmony_ci	mas_lock(&mas);
325162306a36Sopenharmony_ci
325262306a36Sopenharmony_ci	/* next: start ->active */
325362306a36Sopenharmony_ci	mas_set(&mas, 0);
325462306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
325562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
325662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
325762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
325862306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
325962306a36Sopenharmony_ci
326062306a36Sopenharmony_ci	/* next: pause ->active */
326162306a36Sopenharmony_ci	mas_set(&mas, 0);
326262306a36Sopenharmony_ci	mas_pause(&mas);
326362306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
326462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
326562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
326662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
326762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
326862306a36Sopenharmony_ci
326962306a36Sopenharmony_ci	/* next: none ->active */
327062306a36Sopenharmony_ci	mas.index = mas.last = 0;
327162306a36Sopenharmony_ci	mas.offset = 0;
327262306a36Sopenharmony_ci	mas.node = MAS_NONE;
327362306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
327462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
327562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
327662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
327762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
327862306a36Sopenharmony_ci
327962306a36Sopenharmony_ci	/* next:active ->active */
328062306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
328162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr2);
328262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x2000);
328362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x2500);
328462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
328562306a36Sopenharmony_ci
328662306a36Sopenharmony_ci	/* next:active -> active beyond data */
328762306a36Sopenharmony_ci	entry = mas_next(&mas, 0x2999);
328862306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
328962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x2501);
329062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x2fff);
329162306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
329262306a36Sopenharmony_ci
329362306a36Sopenharmony_ci	/* Continue after last range ends after max */
329462306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
329562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr3);
329662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3000);
329762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x3500);
329862306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
329962306a36Sopenharmony_ci
330062306a36Sopenharmony_ci	/* next:active -> active continued */
330162306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
330262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
330362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3501);
330462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
330562306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
330662306a36Sopenharmony_ci
330762306a36Sopenharmony_ci	/* next:active -> overflow  */
330862306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
330962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
331062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3501);
331162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
331262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_OVERFLOW);
331362306a36Sopenharmony_ci
331462306a36Sopenharmony_ci	/* next:overflow -> overflow  */
331562306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
331662306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
331762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3501);
331862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
331962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_OVERFLOW);
332062306a36Sopenharmony_ci
332162306a36Sopenharmony_ci	/* prev:overflow -> active  */
332262306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
332362306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr3);
332462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3000);
332562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x3500);
332662306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
332762306a36Sopenharmony_ci
332862306a36Sopenharmony_ci	/* next: none -> active, skip value at location */
332962306a36Sopenharmony_ci	mas_set(&mas, 0);
333062306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
333162306a36Sopenharmony_ci	mas.node = MAS_NONE;
333262306a36Sopenharmony_ci	mas.offset = 0;
333362306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
333462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr2);
333562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x2000);
333662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x2500);
333762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
333862306a36Sopenharmony_ci
333962306a36Sopenharmony_ci	/* prev:active ->active */
334062306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
334162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
334262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
334362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
334462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
334562306a36Sopenharmony_ci
334662306a36Sopenharmony_ci	/* prev:active -> active spanning end range */
334762306a36Sopenharmony_ci	entry = mas_prev(&mas, 0x0100);
334862306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
334962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
335062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x0FFF);
335162306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
335262306a36Sopenharmony_ci
335362306a36Sopenharmony_ci	/* prev:active -> underflow */
335462306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
335562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
335662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
335762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x0FFF);
335862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
335962306a36Sopenharmony_ci
336062306a36Sopenharmony_ci	/* prev:underflow -> underflow */
336162306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
336262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
336362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
336462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x0FFF);
336562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
336662306a36Sopenharmony_ci
336762306a36Sopenharmony_ci	/* next:underflow -> active */
336862306a36Sopenharmony_ci	entry = mas_next(&mas, ULONG_MAX);
336962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
337062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
337162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
337262306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
337362306a36Sopenharmony_ci
337462306a36Sopenharmony_ci	/* prev:first value -> underflow */
337562306a36Sopenharmony_ci	entry = mas_prev(&mas, 0x1000);
337662306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
337762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
337862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
337962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
338062306a36Sopenharmony_ci
338162306a36Sopenharmony_ci	/* find:underflow -> first value */
338262306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
338362306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
338462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
338562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
338662306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
338762306a36Sopenharmony_ci
338862306a36Sopenharmony_ci	/* prev: pause ->active */
338962306a36Sopenharmony_ci	mas_set(&mas, 0x3600);
339062306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
339162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr3);
339262306a36Sopenharmony_ci	mas_pause(&mas);
339362306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
339462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr2);
339562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x2000);
339662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x2500);
339762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
339862306a36Sopenharmony_ci
339962306a36Sopenharmony_ci	/* prev:active -> active spanning min */
340062306a36Sopenharmony_ci	entry = mas_prev(&mas, 0x1600);
340162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
340262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1501);
340362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1FFF);
340462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
340562306a36Sopenharmony_ci
340662306a36Sopenharmony_ci	/* prev: active ->active, continue */
340762306a36Sopenharmony_ci	entry = mas_prev(&mas, 0);
340862306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
340962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
341062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
341162306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
341262306a36Sopenharmony_ci
341362306a36Sopenharmony_ci	/* find: start ->active */
341462306a36Sopenharmony_ci	mas_set(&mas, 0);
341562306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
341662306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
341762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
341862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
341962306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
342062306a36Sopenharmony_ci
342162306a36Sopenharmony_ci	/* find: pause ->active */
342262306a36Sopenharmony_ci	mas_set(&mas, 0);
342362306a36Sopenharmony_ci	mas_pause(&mas);
342462306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
342562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
342662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
342762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
342862306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
342962306a36Sopenharmony_ci
343062306a36Sopenharmony_ci	/* find: start ->active on value */;
343162306a36Sopenharmony_ci	mas_set(&mas, 1200);
343262306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
343362306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
343462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
343562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
343662306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
343762306a36Sopenharmony_ci
343862306a36Sopenharmony_ci	/* find:active ->active */
343962306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
344062306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr2);
344162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x2000);
344262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x2500);
344362306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
344462306a36Sopenharmony_ci
344562306a36Sopenharmony_ci
344662306a36Sopenharmony_ci	/* find:active -> active (NULL)*/
344762306a36Sopenharmony_ci	entry = mas_find(&mas, 0x2700);
344862306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
344962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x2501);
345062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x2FFF);
345162306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
345262306a36Sopenharmony_ci
345362306a36Sopenharmony_ci	/* find: overflow ->active */
345462306a36Sopenharmony_ci	entry = mas_find(&mas, 0x5000);
345562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr3);
345662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3000);
345762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x3500);
345862306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
345962306a36Sopenharmony_ci
346062306a36Sopenharmony_ci	/* find:active -> active (NULL) end*/
346162306a36Sopenharmony_ci	entry = mas_find(&mas, ULONG_MAX);
346262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
346362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3501);
346462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != ULONG_MAX);
346562306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
346662306a36Sopenharmony_ci
346762306a36Sopenharmony_ci	/* find_rev: active (END) ->active */
346862306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
346962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr3);
347062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x3000);
347162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x3500);
347262306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
347362306a36Sopenharmony_ci
347462306a36Sopenharmony_ci	/* find_rev:active ->active */
347562306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
347662306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr2);
347762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x2000);
347862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x2500);
347962306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
348062306a36Sopenharmony_ci
348162306a36Sopenharmony_ci	/* find_rev: pause ->active */
348262306a36Sopenharmony_ci	mas_pause(&mas);
348362306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
348462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
348562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
348662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
348762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
348862306a36Sopenharmony_ci
348962306a36Sopenharmony_ci	/* find_rev:active -> active */
349062306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
349162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
349262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0);
349362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x0FFF);
349462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
349562306a36Sopenharmony_ci
349662306a36Sopenharmony_ci	/* find_rev: start ->active */
349762306a36Sopenharmony_ci	mas_set(&mas, 0x1200);
349862306a36Sopenharmony_ci	entry = mas_find_rev(&mas, 0);
349962306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
350062306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
350162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
350262306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
350362306a36Sopenharmony_ci
350462306a36Sopenharmony_ci	/* mas_walk start ->active */
350562306a36Sopenharmony_ci	mas_set(&mas, 0x1200);
350662306a36Sopenharmony_ci	entry = mas_walk(&mas);
350762306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
350862306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
350962306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
351062306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
351162306a36Sopenharmony_ci
351262306a36Sopenharmony_ci	/* mas_walk start ->active */
351362306a36Sopenharmony_ci	mas_set(&mas, 0x1600);
351462306a36Sopenharmony_ci	entry = mas_walk(&mas);
351562306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
351662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1501);
351762306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1fff);
351862306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
351962306a36Sopenharmony_ci
352062306a36Sopenharmony_ci	/* mas_walk pause ->active */
352162306a36Sopenharmony_ci	mas_set(&mas, 0x1200);
352262306a36Sopenharmony_ci	mas_pause(&mas);
352362306a36Sopenharmony_ci	entry = mas_walk(&mas);
352462306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
352562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
352662306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
352762306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
352862306a36Sopenharmony_ci
352962306a36Sopenharmony_ci	/* mas_walk pause -> active */
353062306a36Sopenharmony_ci	mas_set(&mas, 0x1600);
353162306a36Sopenharmony_ci	mas_pause(&mas);
353262306a36Sopenharmony_ci	entry = mas_walk(&mas);
353362306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
353462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1501);
353562306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1fff);
353662306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
353762306a36Sopenharmony_ci
353862306a36Sopenharmony_ci	/* mas_walk none -> active */
353962306a36Sopenharmony_ci	mas_set(&mas, 0x1200);
354062306a36Sopenharmony_ci	mas.node = MAS_NONE;
354162306a36Sopenharmony_ci	entry = mas_walk(&mas);
354262306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
354362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
354462306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
354562306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
354662306a36Sopenharmony_ci
354762306a36Sopenharmony_ci	/* mas_walk none -> active */
354862306a36Sopenharmony_ci	mas_set(&mas, 0x1600);
354962306a36Sopenharmony_ci	mas.node = MAS_NONE;
355062306a36Sopenharmony_ci	entry = mas_walk(&mas);
355162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
355262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1501);
355362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1fff);
355462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
355562306a36Sopenharmony_ci
355662306a36Sopenharmony_ci	/* mas_walk active -> active */
355762306a36Sopenharmony_ci	mas.index = 0x1200;
355862306a36Sopenharmony_ci	mas.last = 0x1200;
355962306a36Sopenharmony_ci	mas.offset = 0;
356062306a36Sopenharmony_ci	entry = mas_walk(&mas);
356162306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != ptr);
356262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1000);
356362306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1500);
356462306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
356562306a36Sopenharmony_ci
356662306a36Sopenharmony_ci	/* mas_walk active -> active */
356762306a36Sopenharmony_ci	mas.index = 0x1600;
356862306a36Sopenharmony_ci	mas.last = 0x1600;
356962306a36Sopenharmony_ci	entry = mas_walk(&mas);
357062306a36Sopenharmony_ci	MT_BUG_ON(mt, entry != NULL);
357162306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.index != 0x1501);
357262306a36Sopenharmony_ci	MT_BUG_ON(mt, mas.last != 0x1fff);
357362306a36Sopenharmony_ci	MT_BUG_ON(mt, !mas_active(mas));
357462306a36Sopenharmony_ci
357562306a36Sopenharmony_ci	mas_unlock(&mas);
357662306a36Sopenharmony_ci}
357762306a36Sopenharmony_ci
357862306a36Sopenharmony_cistatic DEFINE_MTREE(tree);
357962306a36Sopenharmony_cistatic int __init maple_tree_seed(void)
358062306a36Sopenharmony_ci{
358162306a36Sopenharmony_ci	unsigned long set[] = { 5015, 5014, 5017, 25, 1000,
358262306a36Sopenharmony_ci				1001, 1002, 1003, 1005, 0,
358362306a36Sopenharmony_ci				5003, 5002};
358462306a36Sopenharmony_ci	void *ptr = &set;
358562306a36Sopenharmony_ci
358662306a36Sopenharmony_ci	pr_info("\nTEST STARTING\n\n");
358762306a36Sopenharmony_ci
358862306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
358962306a36Sopenharmony_ci	check_root_expand(&tree);
359062306a36Sopenharmony_ci	mtree_destroy(&tree);
359162306a36Sopenharmony_ci
359262306a36Sopenharmony_ci#if defined(BENCH_SLOT_STORE)
359362306a36Sopenharmony_ci#define BENCH
359462306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
359562306a36Sopenharmony_ci	bench_slot_store(&tree);
359662306a36Sopenharmony_ci	mtree_destroy(&tree);
359762306a36Sopenharmony_ci	goto skip;
359862306a36Sopenharmony_ci#endif
359962306a36Sopenharmony_ci#if defined(BENCH_NODE_STORE)
360062306a36Sopenharmony_ci#define BENCH
360162306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
360262306a36Sopenharmony_ci	bench_node_store(&tree);
360362306a36Sopenharmony_ci	mtree_destroy(&tree);
360462306a36Sopenharmony_ci	goto skip;
360562306a36Sopenharmony_ci#endif
360662306a36Sopenharmony_ci#if defined(BENCH_AWALK)
360762306a36Sopenharmony_ci#define BENCH
360862306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
360962306a36Sopenharmony_ci	bench_awalk(&tree);
361062306a36Sopenharmony_ci	mtree_destroy(&tree);
361162306a36Sopenharmony_ci	goto skip;
361262306a36Sopenharmony_ci#endif
361362306a36Sopenharmony_ci#if defined(BENCH_WALK)
361462306a36Sopenharmony_ci#define BENCH
361562306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
361662306a36Sopenharmony_ci	bench_walk(&tree);
361762306a36Sopenharmony_ci	mtree_destroy(&tree);
361862306a36Sopenharmony_ci	goto skip;
361962306a36Sopenharmony_ci#endif
362062306a36Sopenharmony_ci#if defined(BENCH_FORK)
362162306a36Sopenharmony_ci#define BENCH
362262306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
362362306a36Sopenharmony_ci	bench_forking(&tree);
362462306a36Sopenharmony_ci	mtree_destroy(&tree);
362562306a36Sopenharmony_ci	goto skip;
362662306a36Sopenharmony_ci#endif
362762306a36Sopenharmony_ci#if defined(BENCH_MT_FOR_EACH)
362862306a36Sopenharmony_ci#define BENCH
362962306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
363062306a36Sopenharmony_ci	bench_mt_for_each(&tree);
363162306a36Sopenharmony_ci	mtree_destroy(&tree);
363262306a36Sopenharmony_ci	goto skip;
363362306a36Sopenharmony_ci#endif
363462306a36Sopenharmony_ci#if defined(BENCH_MAS_FOR_EACH)
363562306a36Sopenharmony_ci#define BENCH
363662306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
363762306a36Sopenharmony_ci	bench_mas_for_each(&tree);
363862306a36Sopenharmony_ci	mtree_destroy(&tree);
363962306a36Sopenharmony_ci	goto skip;
364062306a36Sopenharmony_ci#endif
364162306a36Sopenharmony_ci#if defined(BENCH_MAS_PREV)
364262306a36Sopenharmony_ci#define BENCH
364362306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
364462306a36Sopenharmony_ci	bench_mas_prev(&tree);
364562306a36Sopenharmony_ci	mtree_destroy(&tree);
364662306a36Sopenharmony_ci	goto skip;
364762306a36Sopenharmony_ci#endif
364862306a36Sopenharmony_ci
364962306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
365062306a36Sopenharmony_ci	check_iteration(&tree);
365162306a36Sopenharmony_ci	mtree_destroy(&tree);
365262306a36Sopenharmony_ci
365362306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
365462306a36Sopenharmony_ci	check_forking(&tree);
365562306a36Sopenharmony_ci	mtree_destroy(&tree);
365662306a36Sopenharmony_ci
365762306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
365862306a36Sopenharmony_ci	check_mas_store_gfp(&tree);
365962306a36Sopenharmony_ci	mtree_destroy(&tree);
366062306a36Sopenharmony_ci
366162306a36Sopenharmony_ci	/* Test ranges (store and insert) */
366262306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
366362306a36Sopenharmony_ci	check_ranges(&tree);
366462306a36Sopenharmony_ci	mtree_destroy(&tree);
366562306a36Sopenharmony_ci
366662306a36Sopenharmony_ci#if defined(CONFIG_64BIT)
366762306a36Sopenharmony_ci	/* These tests have ranges outside of 4GB */
366862306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
366962306a36Sopenharmony_ci	check_alloc_range(&tree);
367062306a36Sopenharmony_ci	mtree_destroy(&tree);
367162306a36Sopenharmony_ci
367262306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
367362306a36Sopenharmony_ci	check_alloc_rev_range(&tree);
367462306a36Sopenharmony_ci	mtree_destroy(&tree);
367562306a36Sopenharmony_ci#endif
367662306a36Sopenharmony_ci
367762306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
367862306a36Sopenharmony_ci
367962306a36Sopenharmony_ci	check_load(&tree, set[0], NULL);       /* See if 5015 -> NULL */
368062306a36Sopenharmony_ci
368162306a36Sopenharmony_ci	check_insert(&tree, set[9], &tree);     /* Insert 0 */
368262306a36Sopenharmony_ci	check_load(&tree, set[9], &tree);       /* See if 0 -> &tree */
368362306a36Sopenharmony_ci	check_load(&tree, set[0], NULL);       /* See if 5015 -> NULL */
368462306a36Sopenharmony_ci
368562306a36Sopenharmony_ci	check_insert(&tree, set[10], ptr);      /* Insert 5003 */
368662306a36Sopenharmony_ci	check_load(&tree, set[9], &tree);       /* See if 0 -> &tree */
368762306a36Sopenharmony_ci	check_load(&tree, set[11], NULL);       /* See if 5002 -> NULL */
368862306a36Sopenharmony_ci	check_load(&tree, set[10], ptr);       /* See if 5003 -> ptr */
368962306a36Sopenharmony_ci
369062306a36Sopenharmony_ci	/* Clear out the tree */
369162306a36Sopenharmony_ci	mtree_destroy(&tree);
369262306a36Sopenharmony_ci
369362306a36Sopenharmony_ci	/* Try to insert, insert a dup, and load back what was inserted. */
369462306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
369562306a36Sopenharmony_ci	check_insert(&tree, set[0], &tree);     /* Insert 5015 */
369662306a36Sopenharmony_ci	check_dup_insert(&tree, set[0], &tree); /* Insert 5015 again */
369762306a36Sopenharmony_ci	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
369862306a36Sopenharmony_ci
369962306a36Sopenharmony_ci	/*
370062306a36Sopenharmony_ci	 * Second set of tests try to load a value that doesn't exist, inserts
370162306a36Sopenharmony_ci	 * a second value, then loads the value again
370262306a36Sopenharmony_ci	 */
370362306a36Sopenharmony_ci	check_load(&tree, set[1], NULL);        /* See if 5014 -> NULL */
370462306a36Sopenharmony_ci	check_insert(&tree, set[1], ptr);       /* insert 5014 -> ptr */
370562306a36Sopenharmony_ci	check_load(&tree, set[1], ptr);         /* See if 5014 -> ptr */
370662306a36Sopenharmony_ci	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
370762306a36Sopenharmony_ci	/*
370862306a36Sopenharmony_ci	 * Tree currently contains:
370962306a36Sopenharmony_ci	 * p[0]: 14 -> (nil) p[1]: 15 -> ptr p[2]: 16 -> &tree p[3]: 0 -> (nil)
371062306a36Sopenharmony_ci	 */
371162306a36Sopenharmony_ci	check_insert(&tree, set[6], ptr);       /* insert 1002 -> ptr */
371262306a36Sopenharmony_ci	check_insert(&tree, set[7], &tree);       /* insert 1003 -> &tree */
371362306a36Sopenharmony_ci
371462306a36Sopenharmony_ci	check_load(&tree, set[0], &tree);       /* See if 5015 -> &tree */
371562306a36Sopenharmony_ci	check_load(&tree, set[1], ptr);         /* See if 5014 -> ptr */
371662306a36Sopenharmony_ci	check_load(&tree, set[6], ptr);         /* See if 1002 -> ptr */
371762306a36Sopenharmony_ci	check_load(&tree, set[7], &tree);       /* 1003 = &tree ? */
371862306a36Sopenharmony_ci
371962306a36Sopenharmony_ci	/* Clear out tree */
372062306a36Sopenharmony_ci	mtree_destroy(&tree);
372162306a36Sopenharmony_ci
372262306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
372362306a36Sopenharmony_ci	/* Test inserting into a NULL hole. */
372462306a36Sopenharmony_ci	check_insert(&tree, set[5], ptr);       /* insert 1001 -> ptr */
372562306a36Sopenharmony_ci	check_insert(&tree, set[7], &tree);       /* insert 1003 -> &tree */
372662306a36Sopenharmony_ci	check_insert(&tree, set[6], ptr);       /* insert 1002 -> ptr */
372762306a36Sopenharmony_ci	check_load(&tree, set[5], ptr);         /* See if 1001 -> ptr */
372862306a36Sopenharmony_ci	check_load(&tree, set[6], ptr);         /* See if 1002 -> ptr */
372962306a36Sopenharmony_ci	check_load(&tree, set[7], &tree);       /* See if 1003 -> &tree */
373062306a36Sopenharmony_ci
373162306a36Sopenharmony_ci	/* Clear out the tree */
373262306a36Sopenharmony_ci	mtree_destroy(&tree);
373362306a36Sopenharmony_ci
373462306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
373562306a36Sopenharmony_ci	/*
373662306a36Sopenharmony_ci	 *       set[] = {5015, 5014, 5017, 25, 1000,
373762306a36Sopenharmony_ci	 *                1001, 1002, 1003, 1005, 0,
373862306a36Sopenharmony_ci	 *                5003, 5002};
373962306a36Sopenharmony_ci	 */
374062306a36Sopenharmony_ci
374162306a36Sopenharmony_ci	check_insert(&tree, set[0], ptr); /* 5015 */
374262306a36Sopenharmony_ci	check_insert(&tree, set[1], &tree); /* 5014 */
374362306a36Sopenharmony_ci	check_insert(&tree, set[2], ptr); /* 5017 */
374462306a36Sopenharmony_ci	check_insert(&tree, set[3], &tree); /* 25 */
374562306a36Sopenharmony_ci	check_load(&tree, set[0], ptr);
374662306a36Sopenharmony_ci	check_load(&tree, set[1], &tree);
374762306a36Sopenharmony_ci	check_load(&tree, set[2], ptr);
374862306a36Sopenharmony_ci	check_load(&tree, set[3], &tree);
374962306a36Sopenharmony_ci	check_insert(&tree, set[4], ptr); /* 1000 < Should split. */
375062306a36Sopenharmony_ci	check_load(&tree, set[0], ptr);
375162306a36Sopenharmony_ci	check_load(&tree, set[1], &tree);
375262306a36Sopenharmony_ci	check_load(&tree, set[2], ptr);
375362306a36Sopenharmony_ci	check_load(&tree, set[3], &tree); /*25 */
375462306a36Sopenharmony_ci	check_load(&tree, set[4], ptr);
375562306a36Sopenharmony_ci	check_insert(&tree, set[5], &tree); /* 1001 */
375662306a36Sopenharmony_ci	check_load(&tree, set[0], ptr);
375762306a36Sopenharmony_ci	check_load(&tree, set[1], &tree);
375862306a36Sopenharmony_ci	check_load(&tree, set[2], ptr);
375962306a36Sopenharmony_ci	check_load(&tree, set[3], &tree);
376062306a36Sopenharmony_ci	check_load(&tree, set[4], ptr);
376162306a36Sopenharmony_ci	check_load(&tree, set[5], &tree);
376262306a36Sopenharmony_ci	check_insert(&tree, set[6], ptr);
376362306a36Sopenharmony_ci	check_load(&tree, set[0], ptr);
376462306a36Sopenharmony_ci	check_load(&tree, set[1], &tree);
376562306a36Sopenharmony_ci	check_load(&tree, set[2], ptr);
376662306a36Sopenharmony_ci	check_load(&tree, set[3], &tree);
376762306a36Sopenharmony_ci	check_load(&tree, set[4], ptr);
376862306a36Sopenharmony_ci	check_load(&tree, set[5], &tree);
376962306a36Sopenharmony_ci	check_load(&tree, set[6], ptr);
377062306a36Sopenharmony_ci	check_insert(&tree, set[7], &tree);
377162306a36Sopenharmony_ci	check_load(&tree, set[0], ptr);
377262306a36Sopenharmony_ci	check_insert(&tree, set[8], ptr);
377362306a36Sopenharmony_ci
377462306a36Sopenharmony_ci	check_insert(&tree, set[9], &tree);
377562306a36Sopenharmony_ci
377662306a36Sopenharmony_ci	check_load(&tree, set[0], ptr);
377762306a36Sopenharmony_ci	check_load(&tree, set[1], &tree);
377862306a36Sopenharmony_ci	check_load(&tree, set[2], ptr);
377962306a36Sopenharmony_ci	check_load(&tree, set[3], &tree);
378062306a36Sopenharmony_ci	check_load(&tree, set[4], ptr);
378162306a36Sopenharmony_ci	check_load(&tree, set[5], &tree);
378262306a36Sopenharmony_ci	check_load(&tree, set[6], ptr);
378362306a36Sopenharmony_ci	check_load(&tree, set[9], &tree);
378462306a36Sopenharmony_ci	mtree_destroy(&tree);
378562306a36Sopenharmony_ci
378662306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
378762306a36Sopenharmony_ci	check_seq(&tree, 16, false);
378862306a36Sopenharmony_ci	mtree_destroy(&tree);
378962306a36Sopenharmony_ci
379062306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
379162306a36Sopenharmony_ci	check_seq(&tree, 1000, true);
379262306a36Sopenharmony_ci	mtree_destroy(&tree);
379362306a36Sopenharmony_ci
379462306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
379562306a36Sopenharmony_ci	check_rev_seq(&tree, 1000, true);
379662306a36Sopenharmony_ci	mtree_destroy(&tree);
379762306a36Sopenharmony_ci
379862306a36Sopenharmony_ci	check_lower_bound_split(&tree);
379962306a36Sopenharmony_ci	check_upper_bound_split(&tree);
380062306a36Sopenharmony_ci	check_mid_split(&tree);
380162306a36Sopenharmony_ci
380262306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
380362306a36Sopenharmony_ci	check_next_entry(&tree);
380462306a36Sopenharmony_ci	check_find(&tree);
380562306a36Sopenharmony_ci	check_find_2(&tree);
380662306a36Sopenharmony_ci	mtree_destroy(&tree);
380762306a36Sopenharmony_ci
380862306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
380962306a36Sopenharmony_ci	check_prev_entry(&tree);
381062306a36Sopenharmony_ci	mtree_destroy(&tree);
381162306a36Sopenharmony_ci
381262306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
381362306a36Sopenharmony_ci	check_gap_combining(&tree);
381462306a36Sopenharmony_ci	mtree_destroy(&tree);
381562306a36Sopenharmony_ci
381662306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
381762306a36Sopenharmony_ci	check_node_overwrite(&tree);
381862306a36Sopenharmony_ci	mtree_destroy(&tree);
381962306a36Sopenharmony_ci
382062306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
382162306a36Sopenharmony_ci	next_prev_test(&tree);
382262306a36Sopenharmony_ci	mtree_destroy(&tree);
382362306a36Sopenharmony_ci
382462306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
382562306a36Sopenharmony_ci	check_spanning_relatives(&tree);
382662306a36Sopenharmony_ci	mtree_destroy(&tree);
382762306a36Sopenharmony_ci
382862306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
382962306a36Sopenharmony_ci	check_rev_find(&tree);
383062306a36Sopenharmony_ci	mtree_destroy(&tree);
383162306a36Sopenharmony_ci
383262306a36Sopenharmony_ci	mt_init_flags(&tree, 0);
383362306a36Sopenharmony_ci	check_fuzzer(&tree);
383462306a36Sopenharmony_ci	mtree_destroy(&tree);
383562306a36Sopenharmony_ci
383662306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
383762306a36Sopenharmony_ci	check_dup(&tree);
383862306a36Sopenharmony_ci	mtree_destroy(&tree);
383962306a36Sopenharmony_ci
384062306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
384162306a36Sopenharmony_ci	check_bnode_min_spanning(&tree);
384262306a36Sopenharmony_ci	mtree_destroy(&tree);
384362306a36Sopenharmony_ci
384462306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
384562306a36Sopenharmony_ci	check_empty_area_window(&tree);
384662306a36Sopenharmony_ci	mtree_destroy(&tree);
384762306a36Sopenharmony_ci
384862306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
384962306a36Sopenharmony_ci	check_empty_area_fill(&tree);
385062306a36Sopenharmony_ci	mtree_destroy(&tree);
385162306a36Sopenharmony_ci
385262306a36Sopenharmony_ci	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
385362306a36Sopenharmony_ci	check_state_handling(&tree);
385462306a36Sopenharmony_ci	mtree_destroy(&tree);
385562306a36Sopenharmony_ci
385662306a36Sopenharmony_ci#if defined(BENCH)
385762306a36Sopenharmony_ciskip:
385862306a36Sopenharmony_ci#endif
385962306a36Sopenharmony_ci	rcu_barrier();
386062306a36Sopenharmony_ci	pr_info("maple_tree: %u of %u tests passed\n",
386162306a36Sopenharmony_ci			atomic_read(&maple_tree_tests_passed),
386262306a36Sopenharmony_ci			atomic_read(&maple_tree_tests_run));
386362306a36Sopenharmony_ci	if (atomic_read(&maple_tree_tests_run) ==
386462306a36Sopenharmony_ci	    atomic_read(&maple_tree_tests_passed))
386562306a36Sopenharmony_ci		return 0;
386662306a36Sopenharmony_ci
386762306a36Sopenharmony_ci	return -EINVAL;
386862306a36Sopenharmony_ci}
386962306a36Sopenharmony_ci
387062306a36Sopenharmony_cistatic void __exit maple_tree_harvest(void)
387162306a36Sopenharmony_ci{
387262306a36Sopenharmony_ci
387362306a36Sopenharmony_ci}
387462306a36Sopenharmony_ci
387562306a36Sopenharmony_cimodule_init(maple_tree_seed);
387662306a36Sopenharmony_cimodule_exit(maple_tree_harvest);
387762306a36Sopenharmony_ciMODULE_AUTHOR("Liam R. Howlett <Liam.Howlett@Oracle.com>");
387862306a36Sopenharmony_ciMODULE_LICENSE("GPL");
3879