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