Unverified Commit 50ddb5ec authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!5744 Backport maple_tree: iterator state changes

Merge Pull Request from: @ci-robot 
 
PR sync from: Peng Zhang <zhangpeng362@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/X42OX5L6WME7W5A65E5BJKW3WIZCYEJL/ 
From: ZhangPeng <zhangpeng362@huawei.com>

Backport maple_tree: iterator state changes and 1 bugfix.

With this patch series, we can get a 3% performance improvement
for lmbench Page_Fault from 0.373 -> 0.364.

Andrew Morton (1):
  lib/maple_tree.c: fix build error due to hotfix alteration

Liam R. Howlett (12):
  maple_tree: remove unnecessary default labels from switch statements
  maple_tree: make mas_erase() more robust
  maple_tree: move debug check to __mas_set_range()
  maple_tree: add end of node tracking to the maple state
  maple_tree: use cached node end in mas_next()
  maple_tree: use cached node end in mas_destroy()
  maple_tree: clean up inlines for some functions
  maple_tree: separate ma_state node from status
  maple_tree: remove mas_searchable()
  maple_tree: use maple state end for write operations
  maple_tree: don't find node end in mtree_lookup_walk()
  maple_tree: mtree_range_walk() clean up


-- 
2.25.1
 
https://gitee.com/openeuler/kernel/issues/I9EHBO 
 
Link:https://gitee.com/openeuler/kernel/pulls/5744

 

Reviewed-by: default avatarZucheng Zheng <zhengzucheng@huawei.com>
Reviewed-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: default avatarXu Kuohai <xukuohai@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 091bfd85 d39f5650
Loading
Loading
Loading
Loading
+179 −163
Original line number Diff line number Diff line
@@ -349,6 +349,36 @@ static inline bool mtree_empty(const struct maple_tree *mt)

/* Advanced API */

/*
 * Maple State Status
 * ma_active means the maple state is pointing to a node and offset and can
 * continue operating on the tree.
 * ma_start means we have not searched the tree.
 * ma_root means we have searched the tree and the entry we found lives in
 * the root of the tree (ie it has index 0, length 1 and is the only entry in
 * the tree).
 * ma_none means we have searched the tree and there is no node in the
 * tree for this entry.  For example, we searched for index 1 in an empty
 * tree.  Or we have a tree which points to a full leaf node and we
 * searched for an entry which is larger than can be contained in that
 * leaf node.
 * ma_pause means the data within the maple state may be stale, restart the
 * operation
 * ma_overflow means the search has reached the upper limit of the search
 * ma_underflow means the search has reached the lower limit of the search
 * ma_error means there was an error, check the node for the error number.
 */
enum maple_status {
	ma_active,
	ma_start,
	ma_root,
	ma_none,
	ma_pause,
	ma_overflow,
	ma_underflow,
	ma_error,
};

/*
 * The maple state is defined in the struct ma_state and is used to keep track
 * of information during operations, and even between operations when using the
@@ -381,6 +411,13 @@ static inline bool mtree_empty(const struct maple_tree *mt)
 * When returning a value the maple state index and last respectively contain
 * the start and end of the range for the entry.  Ranges are inclusive in the
 * Maple Tree.
 *
 * The status of the state is used to determine how the next action should treat
 * the state.  For instance, if the status is ma_start then the next action
 * should start at the root of the tree and walk down.  If the status is
 * ma_pause then the node may be stale data and should be discarded.  If the
 * status is ma_overflow, then the last action hit the upper limit.
 *
 */
struct ma_state {
	struct maple_tree *tree;	/* The tree we're operating in */
@@ -390,9 +427,11 @@ struct ma_state {
	unsigned long min;		/* The minimum index of this node - implied pivot min */
	unsigned long max;		/* The maximum index of this node - implied pivot max */
	struct maple_alloc *alloc;	/* Allocated nodes for this operation */
	enum maple_status status;	/* The status of the state (active, start, none, etc) */
	unsigned char depth;		/* depth of tree descent during write */
	unsigned char offset;
	unsigned char mas_flags;
	unsigned char end;		/* The end of the node */
};

struct ma_wr_state {
@@ -402,7 +441,6 @@ struct ma_wr_state {
	unsigned long r_max;		/* range max */
	enum maple_type type;		/* mas->node type */
	unsigned char offset_end;	/* The offset where the write ends */
	unsigned char node_end;		/* mas->node end */
	unsigned long *pivots;		/* mas->node->pivots pointer */
	unsigned long end_piv;		/* The pivot at the offset end */
	void __rcu **slots;		/* mas->node->slots pointer */
@@ -415,28 +453,12 @@ struct ma_wr_state {
		spin_lock_nested(&((mas)->tree->ma_lock), subclass)
#define mas_unlock(mas)         spin_unlock(&((mas)->tree->ma_lock))


/*
 * Special values for ma_state.node.
 * MAS_START means we have not searched the tree.
 * MAS_ROOT means we have searched the tree and the entry we found lives in
 * the root of the tree (ie it has index 0, length 1 and is the only entry in
 * the tree).
 * MAS_NONE means we have searched the tree and there is no node in the
 * tree for this entry.  For example, we searched for index 1 in an empty
 * tree.  Or we have a tree which points to a full leaf node and we
 * searched for an entry which is larger than can be contained in that
 * leaf node.
 * MA_ERROR represents an errno.  After dropping the lock and attempting
 * to resolve the error, the walk would have to be restarted from the
 * top of the tree as the tree may have been modified.
 */
#define MAS_START	((struct maple_enode *)1UL)
#define MAS_ROOT	((struct maple_enode *)5UL)
#define MAS_NONE	((struct maple_enode *)9UL)
#define MAS_PAUSE	((struct maple_enode *)17UL)
#define MAS_OVERFLOW	((struct maple_enode *)33UL)
#define MAS_UNDERFLOW	((struct maple_enode *)65UL)
#define MA_ERROR(err) \
		((struct maple_enode *)(((unsigned long)err << 2) | 2UL))

@@ -445,7 +467,8 @@ struct ma_wr_state {
		.tree = mt,						\
		.index = first,						\
		.last = end,						\
		.node = MAS_START,					\
		.node = NULL,						\
		.status = ma_start,					\
		.min = 0,						\
		.max = ULONG_MAX,					\
		.alloc = NULL,						\
@@ -476,7 +499,6 @@ void *mas_find_range(struct ma_state *mas, unsigned long max);
void *mas_find_rev(struct ma_state *mas, unsigned long min);
void *mas_find_range_rev(struct ma_state *mas, unsigned long max);
int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp);
bool mas_is_err(struct ma_state *mas);

bool mas_nomem(struct ma_state *mas, gfp_t gfp);
void mas_pause(struct ma_state *mas);
@@ -505,28 +527,18 @@ static inline void mas_init(struct ma_state *mas, struct maple_tree *tree,
	mas->tree = tree;
	mas->index = mas->last = addr;
	mas->max = ULONG_MAX;
	mas->node = MAS_START;
	mas->status = ma_start;
	mas->node = NULL;
}

/* Checks if a mas has not found anything */
static inline bool mas_is_none(const struct ma_state *mas)
static inline bool mas_is_active(struct ma_state *mas)
{
	return mas->node == MAS_NONE;
	return mas->status == ma_active;
}

/* Checks if a mas has been paused */
static inline bool mas_is_paused(const struct ma_state *mas)
static inline bool mas_is_err(struct ma_state *mas)
{
	return mas->node == MAS_PAUSE;
}

/* Check if the mas is pointing to a node or not */
static inline bool mas_is_active(struct ma_state *mas)
{
	if ((unsigned long)mas->node >= MAPLE_RESERVED_RANGE)
		return true;

	return false;
	return mas->status == ma_error;
}

/**
@@ -539,9 +551,10 @@ static inline bool mas_is_active(struct ma_state *mas)
 *
 * Context: Any context.
 */
static inline void mas_reset(struct ma_state *mas)
static __always_inline void mas_reset(struct ma_state *mas)
{
	mas->node = MAS_START;
	mas->status = ma_start;
	mas->node = NULL;
}

/**
@@ -557,6 +570,131 @@ static inline void mas_reset(struct ma_state *mas)
 */
#define mas_for_each(__mas, __entry, __max) \
	while (((__entry) = mas_find((__mas), (__max))) != NULL)

#ifdef CONFIG_DEBUG_MAPLE_TREE
enum mt_dump_format {
	mt_dump_dec,
	mt_dump_hex,
};

extern atomic_t maple_tree_tests_run;
extern atomic_t maple_tree_tests_passed;

void mt_dump(const struct maple_tree *mt, enum mt_dump_format format);
void mas_dump(const struct ma_state *mas);
void mas_wr_dump(const struct ma_wr_state *wr_mas);
void mt_validate(struct maple_tree *mt);
void mt_cache_shrink(void);
#define MT_BUG_ON(__tree, __x) do {					\
	atomic_inc(&maple_tree_tests_run);				\
	if (__x) {							\
		pr_info("BUG at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mt_dump(__tree, mt_dump_hex);				\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
} while (0)

#define MAS_BUG_ON(__mas, __x) do {					\
	atomic_inc(&maple_tree_tests_run);				\
	if (__x) {							\
		pr_info("BUG at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_dump(__mas);					\
		mt_dump((__mas)->tree, mt_dump_hex);			\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
} while (0)

#define MAS_WR_BUG_ON(__wrmas, __x) do {				\
	atomic_inc(&maple_tree_tests_run);				\
	if (__x) {							\
		pr_info("BUG at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_wr_dump(__wrmas);					\
		mas_dump((__wrmas)->mas);				\
		mt_dump((__wrmas)->mas->tree, mt_dump_hex);		\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
} while (0)

#define MT_WARN_ON(__tree, __x)  ({					\
	int ret = !!(__x);						\
	atomic_inc(&maple_tree_tests_run);				\
	if (ret) {							\
		pr_info("WARN at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mt_dump(__tree, mt_dump_hex);				\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
	unlikely(ret);							\
})

#define MAS_WARN_ON(__mas, __x) ({					\
	int ret = !!(__x);						\
	atomic_inc(&maple_tree_tests_run);				\
	if (ret) {							\
		pr_info("WARN at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_dump(__mas);					\
		mt_dump((__mas)->tree, mt_dump_hex);			\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
	unlikely(ret);							\
})

#define MAS_WR_WARN_ON(__wrmas, __x) ({					\
	int ret = !!(__x);						\
	atomic_inc(&maple_tree_tests_run);				\
	if (ret) {							\
		pr_info("WARN at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_wr_dump(__wrmas);					\
		mas_dump((__wrmas)->mas);				\
		mt_dump((__wrmas)->mas->tree, mt_dump_hex);		\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
	unlikely(ret);							\
})
#else
#define MT_BUG_ON(__tree, __x)		BUG_ON(__x)
#define MAS_BUG_ON(__mas, __x)		BUG_ON(__x)
#define MAS_WR_BUG_ON(__mas, __x)	BUG_ON(__x)
#define MT_WARN_ON(__tree, __x)		WARN_ON(__x)
#define MAS_WARN_ON(__mas, __x)		WARN_ON(__x)
#define MAS_WR_WARN_ON(__mas, __x)	WARN_ON(__x)
#endif /* CONFIG_DEBUG_MAPLE_TREE */

/**
 * __mas_set_range() - Set up Maple Tree operation state to a sub-range of the
 * current location.
@@ -570,6 +708,9 @@ static inline void mas_reset(struct ma_state *mas)
static inline void __mas_set_range(struct ma_state *mas, unsigned long start,
		unsigned long last)
{
	/* Ensure the range starts within the current slot */
	MAS_WARN_ON(mas, mas_is_active(mas) &&
		   (mas->index > start || mas->last < start));
	mas->index = start;
	mas->last = last;
}
@@ -587,8 +728,8 @@ static inline void __mas_set_range(struct ma_state *mas, unsigned long start,
static inline
void mas_set_range(struct ma_state *mas, unsigned long start, unsigned long last)
{
	mas_reset(mas);
	__mas_set_range(mas, start, last);
	mas->node = MAS_START;
}

/**
@@ -713,129 +854,4 @@ void *mt_next(struct maple_tree *mt, unsigned long index, unsigned long max);
	for (__entry = mt_find(__tree, &(__index), __max); \
		__entry; __entry = mt_find_after(__tree, &(__index), __max))


#ifdef CONFIG_DEBUG_MAPLE_TREE
enum mt_dump_format {
	mt_dump_dec,
	mt_dump_hex,
};

extern atomic_t maple_tree_tests_run;
extern atomic_t maple_tree_tests_passed;

void mt_dump(const struct maple_tree *mt, enum mt_dump_format format);
void mas_dump(const struct ma_state *mas);
void mas_wr_dump(const struct ma_wr_state *wr_mas);
void mt_validate(struct maple_tree *mt);
void mt_cache_shrink(void);
#define MT_BUG_ON(__tree, __x) do {					\
	atomic_inc(&maple_tree_tests_run);				\
	if (__x) {							\
		pr_info("BUG at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mt_dump(__tree, mt_dump_hex);				\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
} while (0)

#define MAS_BUG_ON(__mas, __x) do {					\
	atomic_inc(&maple_tree_tests_run);				\
	if (__x) {							\
		pr_info("BUG at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_dump(__mas);					\
		mt_dump((__mas)->tree, mt_dump_hex);			\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
} while (0)

#define MAS_WR_BUG_ON(__wrmas, __x) do {				\
	atomic_inc(&maple_tree_tests_run);				\
	if (__x) {							\
		pr_info("BUG at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_wr_dump(__wrmas);					\
		mas_dump((__wrmas)->mas);				\
		mt_dump((__wrmas)->mas->tree, mt_dump_hex);		\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
} while (0)

#define MT_WARN_ON(__tree, __x)  ({					\
	int ret = !!(__x);						\
	atomic_inc(&maple_tree_tests_run);				\
	if (ret) {							\
		pr_info("WARN at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mt_dump(__tree, mt_dump_hex);				\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
	unlikely(ret);							\
})

#define MAS_WARN_ON(__mas, __x) ({					\
	int ret = !!(__x);						\
	atomic_inc(&maple_tree_tests_run);				\
	if (ret) {							\
		pr_info("WARN at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_dump(__mas);					\
		mt_dump((__mas)->tree, mt_dump_hex);			\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
	unlikely(ret);							\
})

#define MAS_WR_WARN_ON(__wrmas, __x) ({					\
	int ret = !!(__x);						\
	atomic_inc(&maple_tree_tests_run);				\
	if (ret) {							\
		pr_info("WARN at %s:%d (%u)\n",				\
		__func__, __LINE__, __x);				\
		mas_wr_dump(__wrmas);					\
		mas_dump((__wrmas)->mas);				\
		mt_dump((__wrmas)->mas->tree, mt_dump_hex);		\
		pr_info("Pass: %u Run:%u\n",				\
			atomic_read(&maple_tree_tests_passed),		\
			atomic_read(&maple_tree_tests_run));		\
		dump_stack();						\
	} else {							\
		atomic_inc(&maple_tree_tests_passed);			\
	}								\
	unlikely(ret);							\
})
#else
#define MT_BUG_ON(__tree, __x)		BUG_ON(__x)
#define MAS_BUG_ON(__mas, __x)		BUG_ON(__x)
#define MAS_WR_BUG_ON(__mas, __x)	BUG_ON(__x)
#define MT_WARN_ON(__tree, __x)		WARN_ON(__x)
#define MAS_WARN_ON(__mas, __x)		WARN_ON(__x)
#define MAS_WR_WARN_ON(__mas, __x)	WARN_ON(__x)
#endif /* CONFIG_DEBUG_MAPLE_TREE */

#endif /*_LINUX_MAPLE_TREE_H */
+2 −1
Original line number Diff line number Diff line
@@ -1079,7 +1079,8 @@ struct vma_iterator {
		.mas = {						\
			.tree = &(__mm)->mm_mt,				\
			.index = __addr,				\
			.node = MAS_START,				\
			.node = NULL,					\
			.status = ma_start,				\
		},							\
	}

+386 −330

File changed.

Preview size limit exceeded, changes collapsed.

+119 −91
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ atomic_t maple_tree_tests_passed;
/* #define BENCH_NODE_STORE */
/* #define BENCH_AWALK */
/* #define BENCH_WALK */
/* #define BENCH_LOAD */
/* #define BENCH_MT_FOR_EACH */
/* #define BENCH_FORK */
/* #define BENCH_MAS_FOR_EACH */
@@ -54,6 +55,11 @@ atomic_t maple_tree_tests_passed;
#else
#define cond_resched()			do {} while (0)
#endif

#define mas_is_none(x)		((x)->status == ma_none)
#define mas_is_overflow(x)	((x)->status == ma_overflow)
#define mas_is_underflow(x)	((x)->status == ma_underflow)

static int __init mtree_insert_index(struct maple_tree *mt,
				     unsigned long index, gfp_t gfp)
{
@@ -582,7 +588,7 @@ static noinline void __init check_find(struct maple_tree *mt)
	MT_BUG_ON(mt, last != mas.last);


	mas.node = MAS_NONE;
	mas.status = ma_none;
	mas.index = ULONG_MAX;
	mas.last = ULONG_MAX;
	entry2 = mas_prev(&mas, 0);
@@ -1749,6 +1755,19 @@ static noinline void __init bench_walk(struct maple_tree *mt)
}
#endif

#if defined(BENCH_LOAD)
static noinline void __init bench_load(struct maple_tree *mt)
{
	int i, max = 2500, count = 550000000;

	for (i = 0; i < max; i += 10)
		mtree_store_range(mt, i, i + 5, xa_mk_value(i), GFP_KERNEL);

	for (i = 0; i < count; i++)
		mtree_load(mt, 1470);
}
#endif

#if defined(BENCH_MT_FOR_EACH)
static noinline void __init bench_mt_for_each(struct maple_tree *mt)
{
@@ -2178,7 +2197,7 @@ static noinline void __init next_prev_test(struct maple_tree *mt)
	MT_BUG_ON(mt, val != NULL);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 5);
	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	mas.index = 0;
	mas.last = 5;
@@ -3042,10 +3061,6 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt)
 *		DNE	active		active		range of NULL
 */

#define mas_active(x)		(((x).node != MAS_ROOT) && \
				 ((x).node != MAS_START) && \
				 ((x).node != MAS_PAUSE) && \
				 ((x).node != MAS_NONE))
static noinline void __init check_state_handling(struct maple_tree *mt)
{
	MA_STATE(mas, mt, 0, 0);
@@ -3060,7 +3075,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	/* prev: Start -> underflow*/
	entry = mas_prev(&mas, 0);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
	MT_BUG_ON(mt, mas.status != ma_underflow);

	/* prev: Start -> root */
	mas_set(&mas, 10);
@@ -3068,7 +3083,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* prev: pause -> root */
	mas_set(&mas, 10);
@@ -3077,7 +3092,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* next: start -> none */
	mas_set(&mas, 0);
@@ -3085,7 +3100,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* next: start -> none*/
	mas_set(&mas, 10);
@@ -3093,7 +3108,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* find: start -> root */
	mas_set(&mas, 0);
@@ -3101,21 +3116,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* find: root -> none */
	entry = mas_find(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* find: none -> none */
	entry = mas_find(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* find: start -> none */
	mas_set(&mas, 10);
@@ -3123,14 +3138,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* find_rev: none -> root */
	entry = mas_find_rev(&mas, 0);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* find_rev: start -> root */
	mas_set(&mas, 0);
@@ -3138,21 +3153,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* find_rev: root -> none */
	entry = mas_find_rev(&mas, 0);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* find_rev: none -> none */
	entry = mas_find_rev(&mas, 0);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* find_rev: start -> root */
	mas_set(&mas, 10);
@@ -3160,7 +3175,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* walk: start -> none */
	mas_set(&mas, 10);
@@ -3168,7 +3183,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* walk: pause -> none*/
	mas_set(&mas, 10);
@@ -3177,7 +3192,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* walk: none -> none */
	mas.index = mas.last = 10;
@@ -3185,14 +3200,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* walk: none -> none */
	entry = mas_walk(&mas);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* walk: start -> root */
	mas_set(&mas, 0);
@@ -3200,7 +3215,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* walk: pause -> root */
	mas_set(&mas, 0);
@@ -3209,22 +3224,22 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* walk: none -> root */
	mas.node = MAS_NONE;
	mas.status = ma_none;
	entry = mas_walk(&mas);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* walk: root -> root */
	entry = mas_walk(&mas);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	/* walk: root -> none */
	mas_set(&mas, 10);
@@ -3232,7 +3247,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 1);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_NONE);
	MT_BUG_ON(mt, mas.status != ma_none);

	/* walk: none -> root */
	mas.index = mas.last = 0;
@@ -3240,7 +3255,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0);
	MT_BUG_ON(mt, mas.node != MAS_ROOT);
	MT_BUG_ON(mt, mas.status != ma_root);

	mas_unlock(&mas);

@@ -3258,7 +3273,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* next: pause ->active */
	mas_set(&mas, 0);
@@ -3267,126 +3282,132 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* next: none ->active */
	mas.index = mas.last = 0;
	mas.offset = 0;
	mas.node = MAS_NONE;
	mas.status = ma_none;
	entry = mas_next(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* next:active ->active */
	entry = mas_next(&mas, ULONG_MAX);
	/* next:active ->active (spanning limit) */
	entry = mas_next(&mas, 0x2100);
	MT_BUG_ON(mt, entry != ptr2);
	MT_BUG_ON(mt, mas.index != 0x2000);
	MT_BUG_ON(mt, mas.last != 0x2500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* next:active -> active beyond data */
	/* next:active -> overflow (limit reached) beyond data */
	entry = mas_next(&mas, 0x2999);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x2501);
	MT_BUG_ON(mt, mas.last != 0x2fff);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_overflow(&mas));

	/* Continue after last range ends after max */
	/* next:overflow -> active (limit changed) */
	entry = mas_next(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != ptr3);
	MT_BUG_ON(mt, mas.index != 0x3000);
	MT_BUG_ON(mt, mas.last != 0x3500);
	MT_BUG_ON(mt, !mas_active(mas));

	/* next:active -> active continued */
	entry = mas_next(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x3501);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* next:active -> overflow  */
	/* next:active ->  overflow (limit reached) */
	entry = mas_next(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x3501);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_OVERFLOW);
	MT_BUG_ON(mt, !mas_is_overflow(&mas));

	/* next:overflow -> overflow  */
	entry = mas_next(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x3501);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, mas.node != MAS_OVERFLOW);
	MT_BUG_ON(mt, !mas_is_overflow(&mas));

	/* prev:overflow -> active  */
	entry = mas_prev(&mas, 0);
	MT_BUG_ON(mt, entry != ptr3);
	MT_BUG_ON(mt, mas.index != 0x3000);
	MT_BUG_ON(mt, mas.last != 0x3500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* next: none -> active, skip value at location */
	mas_set(&mas, 0);
	entry = mas_next(&mas, ULONG_MAX);
	mas.node = MAS_NONE;
	mas.status = ma_none;
	mas.offset = 0;
	entry = mas_next(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != ptr2);
	MT_BUG_ON(mt, mas.index != 0x2000);
	MT_BUG_ON(mt, mas.last != 0x2500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* prev:active ->active */
	entry = mas_prev(&mas, 0);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* prev:active -> underflow (span limit) */
	mas_next(&mas, ULONG_MAX);
	entry = mas_prev(&mas, 0x1200);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_is_active(&mas)); /* spanning limit */
	entry = mas_prev(&mas, 0x1200); /* underflow */
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	/* prev:active -> active spanning end range */
	/* prev:underflow -> underflow (lower limit) spanning end range */
	entry = mas_prev(&mas, 0x0100);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0x0FFF);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	/* prev:active -> underflow */
	/* prev:underflow -> underflow */
	entry = mas_prev(&mas, 0);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0x0FFF);
	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	/* prev:underflow -> underflow */
	entry = mas_prev(&mas, 0);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0x0FFF);
	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	/* next:underflow -> active */
	entry = mas_next(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* prev:first value -> underflow */
	entry = mas_prev(&mas, 0x1000);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW);
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	/* find:underflow -> first value */
	entry = mas_find(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* prev: pause ->active */
	mas_set(&mas, 0x3600);
@@ -3397,21 +3418,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr2);
	MT_BUG_ON(mt, mas.index != 0x2000);
	MT_BUG_ON(mt, mas.last != 0x2500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* prev:active -> active spanning min */
	/* prev:active -> underflow spanning min */
	entry = mas_prev(&mas, 0x1600);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x1501);
	MT_BUG_ON(mt, mas.last != 0x1FFF);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	/* prev: active ->active, continue */
	entry = mas_prev(&mas, 0);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find: start ->active */
	mas_set(&mas, 0);
@@ -3419,7 +3440,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find: pause ->active */
	mas_set(&mas, 0);
@@ -3428,7 +3449,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find: start ->active on value */;
	mas_set(&mas, 1200);
@@ -3436,14 +3457,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find:active ->active */
	entry = mas_find(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != ptr2);
	MT_BUG_ON(mt, mas.index != 0x2000);
	MT_BUG_ON(mt, mas.last != 0x2500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));


	/* find:active -> active (NULL)*/
@@ -3451,35 +3472,35 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x2501);
	MT_BUG_ON(mt, mas.last != 0x2FFF);
	MT_BUG_ON(mt, !mas_active(mas));
	MAS_BUG_ON(&mas, !mas_is_active(&mas));

	/* find: overflow ->active */
	entry = mas_find(&mas, 0x5000);
	MT_BUG_ON(mt, entry != ptr3);
	MT_BUG_ON(mt, mas.index != 0x3000);
	MT_BUG_ON(mt, mas.last != 0x3500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find:active -> active (NULL) end*/
	entry = mas_find(&mas, ULONG_MAX);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x3501);
	MT_BUG_ON(mt, mas.last != ULONG_MAX);
	MT_BUG_ON(mt, !mas_active(mas));
	MAS_BUG_ON(&mas, !mas_is_active(&mas));

	/* find_rev: active (END) ->active */
	entry = mas_find_rev(&mas, 0);
	MT_BUG_ON(mt, entry != ptr3);
	MT_BUG_ON(mt, mas.index != 0x3000);
	MT_BUG_ON(mt, mas.last != 0x3500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find_rev:active ->active */
	entry = mas_find_rev(&mas, 0);
	MT_BUG_ON(mt, entry != ptr2);
	MT_BUG_ON(mt, mas.index != 0x2000);
	MT_BUG_ON(mt, mas.last != 0x2500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find_rev: pause ->active */
	mas_pause(&mas);
@@ -3487,14 +3508,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* find_rev:active -> active */
	/* find_rev:active -> underflow */
	entry = mas_find_rev(&mas, 0);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0);
	MT_BUG_ON(mt, mas.last != 0x0FFF);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_underflow(&mas));

	/* find_rev: start ->active */
	mas_set(&mas, 0x1200);
@@ -3502,7 +3523,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk start ->active */
	mas_set(&mas, 0x1200);
@@ -3510,7 +3531,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk start ->active */
	mas_set(&mas, 0x1600);
@@ -3518,7 +3539,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x1501);
	MT_BUG_ON(mt, mas.last != 0x1fff);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk pause ->active */
	mas_set(&mas, 0x1200);
@@ -3527,7 +3548,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk pause -> active */
	mas_set(&mas, 0x1600);
@@ -3536,25 +3557,25 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x1501);
	MT_BUG_ON(mt, mas.last != 0x1fff);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk none -> active */
	mas_set(&mas, 0x1200);
	mas.node = MAS_NONE;
	mas.status = ma_none;
	entry = mas_walk(&mas);
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk none -> active */
	mas_set(&mas, 0x1600);
	mas.node = MAS_NONE;
	mas.status = ma_none;
	entry = mas_walk(&mas);
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x1501);
	MT_BUG_ON(mt, mas.last != 0x1fff);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk active -> active */
	mas.index = 0x1200;
@@ -3564,7 +3585,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != ptr);
	MT_BUG_ON(mt, mas.index != 0x1000);
	MT_BUG_ON(mt, mas.last != 0x1500);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	/* mas_walk active -> active */
	mas.index = 0x1600;
@@ -3573,7 +3594,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
	MT_BUG_ON(mt, entry != NULL);
	MT_BUG_ON(mt, mas.index != 0x1501);
	MT_BUG_ON(mt, mas.last != 0x1fff);
	MT_BUG_ON(mt, !mas_active(mas));
	MT_BUG_ON(mt, !mas_is_active(&mas));

	mas_unlock(&mas);
}
@@ -3616,6 +3637,13 @@ static int __init maple_tree_seed(void)
	mtree_destroy(&tree);
	goto skip;
#endif
#if defined(BENCH_LOAD)
#define BENCH
	mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
	bench_load(&tree);
	mtree_destroy(&tree);
	goto skip;
#endif
#if defined(BENCH_FORK)
#define BENCH
	bench_forking();
+4 −6
Original line number Diff line number Diff line
@@ -1228,8 +1228,6 @@ static inline bool vma_soft_dirty_enabled(struct vm_area_struct *vma)
static inline void vma_iter_config(struct vma_iterator *vmi,
		unsigned long index, unsigned long last)
{
	MAS_BUG_ON(&vmi->mas, vmi->mas.node != MAS_START &&
		   (vmi->mas.index > index || vmi->mas.last < index));
	__mas_set_range(&vmi->mas, index, last - 1);
}

@@ -1258,13 +1256,13 @@ static inline void vma_iter_store(struct vma_iterator *vmi,
{

#if defined(CONFIG_DEBUG_VM_MAPLE_TREE)
	if (MAS_WARN_ON(&vmi->mas, vmi->mas.node != MAS_START &&
	if (MAS_WARN_ON(&vmi->mas, vmi->mas.status != ma_start &&
			vmi->mas.index > vma->vm_start)) {
		pr_warn("%lx > %lx\n store vma %lx-%lx\n into slot %lx-%lx\n",
			vmi->mas.index, vma->vm_start, vma->vm_start,
			vma->vm_end, vmi->mas.index, vmi->mas.last);
	}
	if (MAS_WARN_ON(&vmi->mas, vmi->mas.node != MAS_START &&
	if (MAS_WARN_ON(&vmi->mas, vmi->mas.status != ma_start &&
			vmi->mas.last <  vma->vm_start)) {
		pr_warn("%lx < %lx\nstore vma %lx-%lx\ninto slot %lx-%lx\n",
		       vmi->mas.last, vma->vm_start, vma->vm_start, vma->vm_end,
@@ -1272,7 +1270,7 @@ static inline void vma_iter_store(struct vma_iterator *vmi,
	}
#endif

	if (vmi->mas.node != MAS_START &&
	if (vmi->mas.status != ma_start &&
	    ((vmi->mas.index > vma->vm_start) || (vmi->mas.last < vma->vm_start)))
		vma_iter_invalidate(vmi);

@@ -1283,7 +1281,7 @@ static inline void vma_iter_store(struct vma_iterator *vmi,
static inline int vma_iter_store_gfp(struct vma_iterator *vmi,
			struct vm_area_struct *vma, gfp_t gfp)
{
	if (vmi->mas.node != MAS_START &&
	if (vmi->mas.status != ma_start &&
	    ((vmi->mas.index > vma->vm_start) || (vmi->mas.last < vma->vm_start)))
		vma_iter_invalidate(vmi);

Loading