diff options
Diffstat (limited to 'lib/test_maple_tree.c')
| -rw-r--r-- | lib/test_maple_tree.c | 141 | 
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index 8d4c92cbdd0c..0674aebd4423 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -44,6 +44,8 @@ atomic_t maple_tree_tests_passed;  /* #define BENCH_WALK */  /* #define BENCH_MT_FOR_EACH */  /* #define BENCH_FORK */ +/* #define BENCH_MAS_FOR_EACH */ +/* #define BENCH_MAS_PREV */  #ifdef __KERNEL__  #define mt_set_non_kernel(x)		do {} while (0) @@ -1157,6 +1159,71 @@ static noinline void __init check_ranges(struct maple_tree *mt)  	MT_BUG_ON(mt, !mt_height(mt));  	mtree_destroy(mt); +	/* Check in-place modifications */ +	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE); +	/* Append to the start of last range */ +	mt_set_non_kernel(50); +	for (i = 0; i <= 500; i++) { +		val = i * 5 + 1; +		val2 = val + 4; +		check_store_range(mt, val, val2, xa_mk_value(val), 0); +	} + +	/* Append to the last range without touching any boundaries */ +	for (i = 0; i < 10; i++) { +		val = val2 + 5; +		val2 = val + 4; +		check_store_range(mt, val, val2, xa_mk_value(val), 0); +	} + +	/* Append to the end of last range */ +	val = val2; +	for (i = 0; i < 10; i++) { +		val += 5; +		MT_BUG_ON(mt, mtree_test_store_range(mt, val, ULONG_MAX, +						     xa_mk_value(val)) != 0); +	} + +	/* Overwriting the range and over a part of the next range */ +	for (i = 10; i < 30; i += 2) { +		val = i * 5 + 1; +		val2 = val + 5; +		check_store_range(mt, val, val2, xa_mk_value(val), 0); +	} + +	/* Overwriting a part of the range and over the next range */ +	for (i = 50; i < 70; i += 2) { +		val2 = i * 5; +		val = val2 - 5; +		check_store_range(mt, val, val2, xa_mk_value(val), 0); +	} + +	/* +	 * Expand the range, only partially overwriting the previous and +	 * next ranges +	 */ +	for (i = 100; i < 130; i += 3) { +		val = i * 5 - 5; +		val2 = i * 5 + 1; +		check_store_range(mt, val, val2, xa_mk_value(val), 0); +	} + +	/* +	 * Expand the range, only partially overwriting the previous and +	 * next ranges, in RCU mode +	 */ +	mt_set_in_rcu(mt); +	for (i = 150; i < 180; i += 3) { +		val = i * 5 - 5; +		val2 = i * 5 + 1; +		check_store_range(mt, val, val2, xa_mk_value(val), 0); +	} + +	MT_BUG_ON(mt, !mt_height(mt)); +	mt_validate(mt); +	mt_set_non_kernel(0); +	mtree_destroy(mt); +  	/* Test rebalance gaps */  	mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE);  	mt_set_non_kernel(50); @@ -1705,6 +1772,66 @@ static noinline void __init bench_mt_for_each(struct maple_tree *mt)  }  #endif +#if defined(BENCH_MAS_FOR_EACH) +static noinline void __init bench_mas_for_each(struct maple_tree *mt) +{ +	int i, count = 1000000; +	unsigned long max = 2500; +	void *entry; +	MA_STATE(mas, mt, 0, 0); + +	for (i = 0; i < max; i += 5) { +		int gap = 4; + +		if (i % 30 == 0) +			gap = 3; +		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL); +	} + +	rcu_read_lock(); +	for (i = 0; i < count; i++) { +		unsigned long j = 0; + +		mas_for_each(&mas, entry, max) { +			MT_BUG_ON(mt, entry != xa_mk_value(j)); +			j += 5; +		} +		mas_set(&mas, 0); +	} +	rcu_read_unlock(); + +} +#endif +#if defined(BENCH_MAS_PREV) +static noinline void __init bench_mas_prev(struct maple_tree *mt) +{ +	int i, count = 1000000; +	unsigned long max = 2500; +	void *entry; +	MA_STATE(mas, mt, 0, 0); + +	for (i = 0; i < max; i += 5) { +		int gap = 4; + +		if (i % 30 == 0) +			gap = 3; +		mtree_store_range(mt, i, i + gap, xa_mk_value(i), GFP_KERNEL); +	} + +	rcu_read_lock(); +	for (i = 0; i < count; i++) { +		unsigned long j = 2495; + +		mas_set(&mas, ULONG_MAX); +		while ((entry = mas_prev(&mas, 0)) != NULL) { +			MT_BUG_ON(mt, entry != xa_mk_value(j)); +			j -= 5; +		} +	} +	rcu_read_unlock(); + +} +#endif  /* check_forking - simulate the kernel forking sequence with the tree. */  static noinline void __init check_forking(struct maple_tree *mt)  { @@ -3433,6 +3560,20 @@ static int __init maple_tree_seed(void)  	mtree_destroy(&tree);  	goto skip;  #endif +#if defined(BENCH_MAS_FOR_EACH) +#define BENCH +	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); +	bench_mas_for_each(&tree); +	mtree_destroy(&tree); +	goto skip; +#endif +#if defined(BENCH_MAS_PREV) +#define BENCH +	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); +	bench_mas_prev(&tree); +	mtree_destroy(&tree); +	goto skip; +#endif  	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);  	check_iteration(&tree);  | 
