Commit 067311d3 authored by Liam R. Howlett's avatar Liam R. Howlett Committed by Andrew Morton

maple_tree: separate ma_state node from status

The maple tree node is overloaded to keep status as well as the active
node.  This, unfortunately, results in a re-walk on underflow or overflow.
Since the maple state has room, the status can be placed in its own enum
in the structure.  Once an underflow/overflow is detected, certain modes
can restore the status to active and others may need to re-walk just that
one node to see the entry.

The status being an enum has the benefit of detecting unhandled status in
switch statements.

[Liam.Howlett@oracle.com: fix comments about MAS_*]
  Link: https://lkml.kernel.org/r/20231106154124.614247-1-Liam.Howlett@oracle.com
[Liam.Howlett@oracle.com: update forking to separate maple state and node]
  Link: https://lkml.kernel.org/r/20231106154551.615042-1-Liam.Howlett@oracle.com
[Liam.Howlett@oracle.com: fix mas_prev() state separation code]
  Link: https://lkml.kernel.org/r/20231207193319.4025462-1-Liam.Howlett@oracle.com
Link: https://lkml.kernel.org/r/20231101171629.3612299-9-Liam.Howlett@oracle.comSigned-off-by: default avatarLiam R. Howlett <Liam.Howlett@oracle.com>
Cc: Peng Zhang <zhangpeng.00@bytedance.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 271f61a8
...@@ -349,6 +349,36 @@ static inline bool mtree_empty(const struct maple_tree *mt) ...@@ -349,6 +349,36 @@ static inline bool mtree_empty(const struct maple_tree *mt)
/* Advanced API */ /* 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 * 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 * 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) ...@@ -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 * 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 * the start and end of the range for the entry. Ranges are inclusive in the
* Maple Tree. * 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 ma_state {
struct maple_tree *tree; /* The tree we're operating in */ struct maple_tree *tree; /* The tree we're operating in */
...@@ -390,6 +427,7 @@ struct ma_state { ...@@ -390,6 +427,7 @@ struct ma_state {
unsigned long min; /* The minimum index of this node - implied pivot min */ unsigned long min; /* The minimum index of this node - implied pivot min */
unsigned long max; /* The maximum index of this node - implied pivot max */ unsigned long max; /* The maximum index of this node - implied pivot max */
struct maple_alloc *alloc; /* Allocated nodes for this operation */ 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 depth; /* depth of tree descent during write */
unsigned char offset; unsigned char offset;
unsigned char mas_flags; unsigned char mas_flags;
...@@ -416,28 +454,12 @@ struct ma_wr_state { ...@@ -416,28 +454,12 @@ struct ma_wr_state {
spin_lock_nested(&((mas)->tree->ma_lock), subclass) spin_lock_nested(&((mas)->tree->ma_lock), subclass)
#define mas_unlock(mas) spin_unlock(&((mas)->tree->ma_lock)) #define mas_unlock(mas) spin_unlock(&((mas)->tree->ma_lock))
/* /*
* Special values for ma_state.node. * 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 * MA_ERROR represents an errno. After dropping the lock and attempting
* to resolve the error, the walk would have to be restarted from the * to resolve the error, the walk would have to be restarted from the
* top of the tree as the tree may have been modified. * 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) \ #define MA_ERROR(err) \
((struct maple_enode *)(((unsigned long)err << 2) | 2UL)) ((struct maple_enode *)(((unsigned long)err << 2) | 2UL))
...@@ -446,7 +468,8 @@ struct ma_wr_state { ...@@ -446,7 +468,8 @@ struct ma_wr_state {
.tree = mt, \ .tree = mt, \
.index = first, \ .index = first, \
.last = end, \ .last = end, \
.node = MAS_START, \ .node = NULL, \
.status = ma_start, \
.min = 0, \ .min = 0, \
.max = ULONG_MAX, \ .max = ULONG_MAX, \
.alloc = NULL, \ .alloc = NULL, \
...@@ -477,7 +500,6 @@ void *mas_find_range(struct ma_state *mas, unsigned long max); ...@@ -477,7 +500,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_rev(struct ma_state *mas, unsigned long min);
void *mas_find_range_rev(struct ma_state *mas, unsigned long max); void *mas_find_range_rev(struct ma_state *mas, unsigned long max);
int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp); 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); bool mas_nomem(struct ma_state *mas, gfp_t gfp);
void mas_pause(struct ma_state *mas); void mas_pause(struct ma_state *mas);
...@@ -506,28 +528,18 @@ static inline void mas_init(struct ma_state *mas, struct maple_tree *tree, ...@@ -506,28 +528,18 @@ static inline void mas_init(struct ma_state *mas, struct maple_tree *tree,
mas->tree = tree; mas->tree = tree;
mas->index = mas->last = addr; mas->index = mas->last = addr;
mas->max = ULONG_MAX; 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_active(struct ma_state *mas)
static inline bool mas_is_none(const struct ma_state *mas)
{
return mas->node == MAS_NONE;
}
/* Checks if a mas has been paused */
static inline bool mas_is_paused(const struct ma_state *mas)
{ {
return mas->node == MAS_PAUSE; return mas->status == ma_active;
} }
/* Check if the mas is pointing to a node or not */ static inline bool mas_is_err(struct ma_state *mas)
static inline bool mas_is_active(struct ma_state *mas)
{ {
if ((unsigned long)mas->node >= MAPLE_RESERVED_RANGE) return mas->status == ma_error;
return true;
return false;
} }
/** /**
...@@ -540,9 +552,10 @@ static inline bool mas_is_active(struct ma_state *mas) ...@@ -540,9 +552,10 @@ static inline bool mas_is_active(struct ma_state *mas)
* *
* Context: Any context. * 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;
} }
/** /**
...@@ -716,7 +729,7 @@ static inline void __mas_set_range(struct ma_state *mas, unsigned long start, ...@@ -716,7 +729,7 @@ static inline void __mas_set_range(struct ma_state *mas, unsigned long start,
static inline static inline
void mas_set_range(struct ma_state *mas, unsigned long start, unsigned long last) void mas_set_range(struct ma_state *mas, unsigned long start, unsigned long last)
{ {
mas->node = MAS_START; mas_reset(mas);
__mas_set_range(mas, start, last); __mas_set_range(mas, start, last);
} }
......
...@@ -1071,7 +1071,8 @@ struct vma_iterator { ...@@ -1071,7 +1071,8 @@ struct vma_iterator {
.mas = { \ .mas = { \
.tree = &(__mm)->mm_mt, \ .tree = &(__mm)->mm_mt, \
.index = __addr, \ .index = __addr, \
.node = MAS_START, \ .node = NULL, \
.status = ma_start, \
}, \ }, \
} }
......
...@@ -249,40 +249,40 @@ static __always_inline bool mt_is_reserved(const void *entry) ...@@ -249,40 +249,40 @@ static __always_inline bool mt_is_reserved(const void *entry)
xa_is_internal(entry); xa_is_internal(entry);
} }
static inline void mas_set_err(struct ma_state *mas, long err) static __always_inline void mas_set_err(struct ma_state *mas, long err)
{ {
mas->node = MA_ERROR(err); mas->node = MA_ERROR(err);
mas->status = ma_error;
} }
static inline bool mas_is_ptr(const struct ma_state *mas) static __always_inline bool mas_is_ptr(const struct ma_state *mas)
{ {
return mas->node == MAS_ROOT; return mas->status == ma_root;
} }
static inline bool mas_is_start(const struct ma_state *mas) static __always_inline bool mas_is_start(const struct ma_state *mas)
{ {
return mas->node == MAS_START; return mas->status == ma_start;
} }
bool mas_is_err(struct ma_state *mas) static __always_inline bool mas_is_none(const struct ma_state *mas)
{ {
return xa_is_err(mas->node); return mas->status == ma_none;
} }
static __always_inline bool mas_is_overflow(struct ma_state *mas) static __always_inline bool mas_is_paused(const struct ma_state *mas)
{ {
if (unlikely(mas->node == MAS_OVERFLOW)) return mas->status == ma_pause;
return true;
return false;
} }
static __always_inline bool mas_is_underflow(struct ma_state *mas) static __always_inline bool mas_is_overflow(struct ma_state *mas)
{ {
if (unlikely(mas->node == MAS_UNDERFLOW)) return mas->status == ma_overflow;
return true; }
return false; static inline bool mas_is_underflow(struct ma_state *mas)
{
return mas->status == ma_underflow;
} }
static inline bool mas_searchable(struct ma_state *mas) static inline bool mas_searchable(struct ma_state *mas)
...@@ -1274,6 +1274,7 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) ...@@ -1274,6 +1274,7 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
if (mas->mas_flags & MA_STATE_PREALLOC) { if (mas->mas_flags & MA_STATE_PREALLOC) {
if (allocated) if (allocated)
return; return;
BUG_ON(!allocated);
WARN_ON(!allocated); WARN_ON(!allocated);
} }
...@@ -1379,14 +1380,14 @@ static void mas_node_count(struct ma_state *mas, int count) ...@@ -1379,14 +1380,14 @@ static void mas_node_count(struct ma_state *mas, int count)
* mas_start() - Sets up maple state for operations. * mas_start() - Sets up maple state for operations.
* @mas: The maple state. * @mas: The maple state.
* *
* If mas->node == MAS_START, then set the min, max and depth to * If mas->status == mas_start, then set the min, max and depth to
* defaults. * defaults.
* *
* Return: * Return:
* - If mas->node is an error or not MAS_START, return NULL. * - If mas->node is an error or not mas_start, return NULL.
* - If it's an empty tree: NULL & mas->node == MAS_NONE * - If it's an empty tree: NULL & mas->status == ma_none
* - If it's a single entry: The entry & mas->node == MAS_ROOT * - If it's a single entry: The entry & mas->status == mas_root
* - If it's a tree: NULL & mas->node == safe root node. * - If it's a tree: NULL & mas->status == safe root node.
*/ */
static inline struct maple_enode *mas_start(struct ma_state *mas) static inline struct maple_enode *mas_start(struct ma_state *mas)
{ {
...@@ -1402,6 +1403,7 @@ static inline struct maple_enode *mas_start(struct ma_state *mas) ...@@ -1402,6 +1403,7 @@ static inline struct maple_enode *mas_start(struct ma_state *mas)
/* Tree with nodes */ /* Tree with nodes */
if (likely(xa_is_node(root))) { if (likely(xa_is_node(root))) {
mas->depth = 1; mas->depth = 1;
mas->status = ma_active;
mas->node = mte_safe_root(root); mas->node = mte_safe_root(root);
mas->offset = 0; mas->offset = 0;
if (mte_dead_node(mas->node)) if (mte_dead_node(mas->node))
...@@ -1412,13 +1414,14 @@ static inline struct maple_enode *mas_start(struct ma_state *mas) ...@@ -1412,13 +1414,14 @@ static inline struct maple_enode *mas_start(struct ma_state *mas)
/* empty tree */ /* empty tree */
if (unlikely(!root)) { if (unlikely(!root)) {
mas->node = MAS_NONE; mas->node = NULL;
mas->status = ma_none;
mas->offset = MAPLE_NODE_SLOTS; mas->offset = MAPLE_NODE_SLOTS;
return NULL; return NULL;
} }
/* Single entry tree */ /* Single entry tree */
mas->node = MAS_ROOT; mas->status = ma_root;
mas->offset = MAPLE_NODE_SLOTS; mas->offset = MAPLE_NODE_SLOTS;
/* Single entry tree. */ /* Single entry tree. */
...@@ -2225,19 +2228,21 @@ static inline bool mas_next_sibling(struct ma_state *mas) ...@@ -2225,19 +2228,21 @@ static inline bool mas_next_sibling(struct ma_state *mas)
} }
/* /*
* mte_node_or_node() - Return the encoded node or MAS_NONE. * mte_node_or_none() - Set the enode and state.
* @enode: The encoded maple node. * @enode: The encoded maple node.
* *
* Shorthand to avoid setting %NULLs in the tree or maple_subtree_state. * Set the node to the enode and the status.
*
* Return: @enode or MAS_NONE
*/ */
static inline struct maple_enode *mte_node_or_none(struct maple_enode *enode) static inline void mas_node_or_none(struct ma_state *mas,
struct maple_enode *enode)
{ {
if (enode) if (enode) {
return enode; mas->node = enode;
mas->status = ma_active;
return ma_enode_ptr(MAS_NONE); } else {
mas->node = NULL;
mas->status = ma_none;
}
} }
/* /*
...@@ -2557,13 +2562,15 @@ static inline void mast_set_split_parents(struct maple_subtree_state *mast, ...@@ -2557,13 +2562,15 @@ static inline void mast_set_split_parents(struct maple_subtree_state *mast,
* The node will either be RCU freed or pushed back on the maple state. * The node will either be RCU freed or pushed back on the maple state.
*/ */
static inline void mas_topiary_node(struct ma_state *mas, static inline void mas_topiary_node(struct ma_state *mas,
struct maple_enode *enode, bool in_rcu) struct ma_state *tmp_mas, bool in_rcu)
{ {
struct maple_node *tmp; struct maple_node *tmp;
struct maple_enode *enode;
if (enode == MAS_NONE) if (mas_is_none(tmp_mas))
return; return;
enode = tmp_mas->node;
tmp = mte_to_node(enode); tmp = mte_to_node(enode);
mte_set_node_dead(enode); mte_set_node_dead(enode);
if (in_rcu) if (in_rcu)
...@@ -2603,8 +2610,8 @@ static inline void mas_topiary_replace(struct ma_state *mas, ...@@ -2603,8 +2610,8 @@ static inline void mas_topiary_replace(struct ma_state *mas,
/* Update the parent pointers in the tree */ /* Update the parent pointers in the tree */
tmp[0] = *mas; tmp[0] = *mas;
tmp[0].offset = 0; tmp[0].offset = 0;
tmp[1].node = MAS_NONE; tmp[1].status = ma_none;
tmp[2].node = MAS_NONE; tmp[2].status = ma_none;
while (!mte_is_leaf(tmp[0].node)) { while (!mte_is_leaf(tmp[0].node)) {
n = 0; n = 0;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
...@@ -2624,7 +2631,7 @@ static inline void mas_topiary_replace(struct ma_state *mas, ...@@ -2624,7 +2631,7 @@ static inline void mas_topiary_replace(struct ma_state *mas,
break; break;
while (n < 3) while (n < 3)
tmp_next[n++].node = MAS_NONE; tmp_next[n++].status = ma_none;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
tmp[i] = tmp_next[i]; tmp[i] = tmp_next[i];
...@@ -2637,8 +2644,8 @@ static inline void mas_topiary_replace(struct ma_state *mas, ...@@ -2637,8 +2644,8 @@ static inline void mas_topiary_replace(struct ma_state *mas,
tmp[0] = *mas; tmp[0] = *mas;
tmp[0].offset = 0; tmp[0].offset = 0;
tmp[0].node = old_enode; tmp[0].node = old_enode;
tmp[1].node = MAS_NONE; tmp[1].status = ma_none;
tmp[2].node = MAS_NONE; tmp[2].status = ma_none;
in_rcu = mt_in_rcu(mas->tree); in_rcu = mt_in_rcu(mas->tree);
do { do {
n = 0; n = 0;
...@@ -2653,7 +2660,7 @@ static inline void mas_topiary_replace(struct ma_state *mas, ...@@ -2653,7 +2660,7 @@ static inline void mas_topiary_replace(struct ma_state *mas,
if ((tmp_next[n].min >= tmp_next->index) && if ((tmp_next[n].min >= tmp_next->index) &&
(tmp_next[n].max <= tmp_next->last)) { (tmp_next[n].max <= tmp_next->last)) {
mat_add(&subtrees, tmp_next[n].node); mat_add(&subtrees, tmp_next[n].node);
tmp_next[n].node = MAS_NONE; tmp_next[n].status = ma_none;
} else { } else {
n++; n++;
} }
...@@ -2664,16 +2671,16 @@ static inline void mas_topiary_replace(struct ma_state *mas, ...@@ -2664,16 +2671,16 @@ static inline void mas_topiary_replace(struct ma_state *mas,
break; break;
while (n < 3) while (n < 3)
tmp_next[n++].node = MAS_NONE; tmp_next[n++].status = ma_none;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
mas_topiary_node(mas, tmp[i].node, in_rcu); mas_topiary_node(mas, &tmp[i], in_rcu);
tmp[i] = tmp_next[i]; tmp[i] = tmp_next[i];
} }
} while (!mte_is_leaf(tmp[0].node)); } while (!mte_is_leaf(tmp[0].node));
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
mas_topiary_node(mas, tmp[i].node, in_rcu); mas_topiary_node(mas, &tmp[i], in_rcu);
mas_mat_destroy(mas, &subtrees); mas_mat_destroy(mas, &subtrees);
} }
...@@ -2712,9 +2719,9 @@ static inline void mast_cp_to_nodes(struct maple_subtree_state *mast, ...@@ -2712,9 +2719,9 @@ static inline void mast_cp_to_nodes(struct maple_subtree_state *mast,
{ {
bool new_lmax = true; bool new_lmax = true;
mast->l->node = mte_node_or_none(left); mas_node_or_none(mast->l, left);
mast->m->node = mte_node_or_none(middle); mas_node_or_none(mast->m, middle);
mast->r->node = mte_node_or_none(right); mas_node_or_none(mast->r, right);
mast->l->min = mast->orig_l->min; mast->l->min = mast->orig_l->min;
if (split == mast->bn->b_end) { if (split == mast->bn->b_end) {
...@@ -2894,7 +2901,7 @@ static int mas_spanning_rebalance(struct ma_state *mas, ...@@ -2894,7 +2901,7 @@ static int mas_spanning_rebalance(struct ma_state *mas,
mast->l = &l_mas; mast->l = &l_mas;
mast->m = &m_mas; mast->m = &m_mas;
mast->r = &r_mas; mast->r = &r_mas;
l_mas.node = r_mas.node = m_mas.node = MAS_NONE; l_mas.status = r_mas.status = m_mas.status = ma_none;
/* Check if this is not root and has sufficient data. */ /* Check if this is not root and has sufficient data. */
if (((mast->orig_l->min != 0) || (mast->orig_r->max != ULONG_MAX)) && if (((mast->orig_l->min != 0) || (mast->orig_r->max != ULONG_MAX)) &&
...@@ -3421,7 +3428,6 @@ static int mas_split(struct ma_state *mas, struct maple_big_node *b_node) ...@@ -3421,7 +3428,6 @@ static int mas_split(struct ma_state *mas, struct maple_big_node *b_node)
/* Try to push left. */ /* Try to push left. */
if (mas_push_data(mas, height, &mast, true)) if (mas_push_data(mas, height, &mast, true))
break; break;
/* Try to push right. */ /* Try to push right. */
if (mas_push_data(mas, height, &mast, false)) if (mas_push_data(mas, height, &mast, false))
break; break;
...@@ -3537,6 +3543,7 @@ static inline int mas_root_expand(struct ma_state *mas, void *entry) ...@@ -3537,6 +3543,7 @@ static inline int mas_root_expand(struct ma_state *mas, void *entry)
slots = ma_slots(node, type); slots = ma_slots(node, type);
node->parent = ma_parent_ptr(mas_tree_parent(mas)); node->parent = ma_parent_ptr(mas_tree_parent(mas));
mas->node = mt_mk_node(node, type); mas->node = mt_mk_node(node, type);
mas->status = ma_active;
if (mas->index) { if (mas->index) {
if (contents) { if (contents) {
...@@ -3569,7 +3576,7 @@ static inline void mas_store_root(struct ma_state *mas, void *entry) ...@@ -3569,7 +3576,7 @@ static inline void mas_store_root(struct ma_state *mas, void *entry)
mas_root_expand(mas, entry); mas_root_expand(mas, entry);
else { else {
rcu_assign_pointer(mas->tree->ma_root, entry); rcu_assign_pointer(mas->tree->ma_root, entry);
mas->node = MAS_START; mas->status = ma_start;
} }
} }
...@@ -3801,7 +3808,7 @@ static inline int mas_new_root(struct ma_state *mas, void *entry) ...@@ -3801,7 +3808,7 @@ static inline int mas_new_root(struct ma_state *mas, void *entry)
mas->depth = 0; mas->depth = 0;
mas_set_height(mas); mas_set_height(mas);
rcu_assign_pointer(mas->tree->ma_root, entry); rcu_assign_pointer(mas->tree->ma_root, entry);
mas->node = MAS_START; mas->status = ma_start;
goto done; goto done;
} }
...@@ -3814,6 +3821,7 @@ static inline int mas_new_root(struct ma_state *mas, void *entry) ...@@ -3814,6 +3821,7 @@ static inline int mas_new_root(struct ma_state *mas, void *entry)
slots = ma_slots(node, type); slots = ma_slots(node, type);
node->parent = ma_parent_ptr(mas_tree_parent(mas)); node->parent = ma_parent_ptr(mas_tree_parent(mas));
mas->node = mt_mk_node(node, type); mas->node = mt_mk_node(node, type);
mas->status = ma_active;
rcu_assign_pointer(slots[0], entry); rcu_assign_pointer(slots[0], entry);
pivots[0] = mas->last; pivots[0] = mas->last;
mas->depth = 1; mas->depth = 1;
...@@ -4367,11 +4375,13 @@ static __always_inline bool mas_rewalk_if_dead(struct ma_state *mas, ...@@ -4367,11 +4375,13 @@ static __always_inline bool mas_rewalk_if_dead(struct ma_state *mas,
/* /*
* mas_prev_node() - Find the prev non-null entry at the same level in the * mas_prev_node() - Find the prev non-null entry at the same level in the
* tree. The prev value will be mas->node[mas->offset] or MAS_NONE. * tree. The prev value will be mas->node[mas->offset] or the status will be
* ma_none.
* @mas: The maple state * @mas: The maple state
* @min: The lower limit to search * @min: The lower limit to search
* *
* The prev node value will be mas->node[mas->offset] or MAS_NONE. * The prev node value will be mas->node[mas->offset] or the status will be
* ma_none.
* Return: 1 if the node is dead, 0 otherwise. * Return: 1 if the node is dead, 0 otherwise.
*/ */
static int mas_prev_node(struct ma_state *mas, unsigned long min) static int mas_prev_node(struct ma_state *mas, unsigned long min)
...@@ -4441,7 +4451,7 @@ static int mas_prev_node(struct ma_state *mas, unsigned long min) ...@@ -4441,7 +4451,7 @@ static int mas_prev_node(struct ma_state *mas, unsigned long min)
if (unlikely(ma_dead_node(node))) if (unlikely(ma_dead_node(node)))
return 1; return 1;
mas->node = MAS_NONE; mas->status = ma_underflow;
return 0; return 0;
} }
...@@ -4455,8 +4465,7 @@ static int mas_prev_node(struct ma_state *mas, unsigned long min) ...@@ -4455,8 +4465,7 @@ static int mas_prev_node(struct ma_state *mas, unsigned long min)
* *
* Return: The entry in the previous slot which is possibly NULL * Return: The entry in the previous slot which is possibly NULL
*/ */
static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty, static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty)
bool set_underflow)
{ {
void *entry; void *entry;
void __rcu **slots; void __rcu **slots;
...@@ -4489,13 +4498,16 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty, ...@@ -4489,13 +4498,16 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty,
mas->last = mas->index - 1; mas->last = mas->index - 1;
mas->index = mas_safe_min(mas, pivots, mas->offset); mas->index = mas_safe_min(mas, pivots, mas->offset);
} else { } else {
if (mas->index <= min)
goto underflow;
if (mas_prev_node(mas, min)) { if (mas_prev_node(mas, min)) {
mas_rewalk(mas, save_point); mas_rewalk(mas, save_point);
goto retry; goto retry;
} }
if (mas_is_none(mas)) if (WARN_ON_ONCE(mas_is_underflow(mas)))
goto underflow; return NULL;
mas->last = mas->max; mas->last = mas->max;
node = mas_mn(mas); node = mas_mn(mas);
...@@ -4509,12 +4521,15 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty, ...@@ -4509,12 +4521,15 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty,
if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) if (unlikely(mas_rewalk_if_dead(mas, node, save_point)))
goto retry; goto retry;
if (likely(entry)) if (likely(entry))
return entry; return entry;
if (!empty) { if (!empty) {
if (mas->index <= min) if (mas->index <= min) {
goto underflow; mas->status = ma_underflow;
return NULL;
}
goto again; goto again;
} }
...@@ -4522,8 +4537,7 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty, ...@@ -4522,8 +4537,7 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty,
return entry; return entry;
underflow: underflow:
if (set_underflow) mas->status = ma_underflow;
mas->node = MAS_UNDERFLOW;
return NULL; return NULL;
} }
...@@ -4532,7 +4546,8 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty, ...@@ -4532,7 +4546,8 @@ static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty,
* @mas: The maple state * @mas: The maple state
* @max: The maximum pivot value to check. * @max: The maximum pivot value to check.
* *
* The next value will be mas->node[mas->offset] or MAS_NONE. * The next value will be mas->node[mas->offset] or the status will have
* overflowed.
* Return: 1 on dead node, 0 otherwise. * Return: 1 on dead node, 0 otherwise.
*/ */
static int mas_next_node(struct ma_state *mas, struct maple_node *node, static int mas_next_node(struct ma_state *mas, struct maple_node *node,
...@@ -4548,13 +4563,13 @@ static int mas_next_node(struct ma_state *mas, struct maple_node *node, ...@@ -4548,13 +4563,13 @@ static int mas_next_node(struct ma_state *mas, struct maple_node *node,
void __rcu **slots; void __rcu **slots;
if (mas->max >= max) if (mas->max >= max)
goto no_entry; goto overflow;
min = mas->max + 1; min = mas->max + 1;
level = 0; level = 0;
do { do {
if (ma_is_root(node)) if (ma_is_root(node))
goto no_entry; goto overflow;
/* Walk up. */ /* Walk up. */
if (unlikely(mas_ascend(mas))) if (unlikely(mas_ascend(mas)))
...@@ -4605,11 +4620,11 @@ static int mas_next_node(struct ma_state *mas, struct maple_node *node, ...@@ -4605,11 +4620,11 @@ static int mas_next_node(struct ma_state *mas, struct maple_node *node,
mas->min = min; mas->min = min;
return 0; return 0;
no_entry: overflow:
if (unlikely(ma_dead_node(node))) if (unlikely(ma_dead_node(node)))
return 1; return 1;
mas->node = MAS_NONE; mas->status = ma_overflow;
return 0; return 0;
} }
...@@ -4624,8 +4639,7 @@ static int mas_next_node(struct ma_state *mas, struct maple_node *node, ...@@ -4624,8 +4639,7 @@ static int mas_next_node(struct ma_state *mas, struct maple_node *node,
* *
* Return: The entry in the next slot which is possibly NULL * Return: The entry in the next slot which is possibly NULL
*/ */
static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty, static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty)
bool set_overflow)
{ {
void __rcu **slots; void __rcu **slots;
unsigned long *pivots; unsigned long *pivots;
...@@ -4646,13 +4660,15 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty, ...@@ -4646,13 +4660,15 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty,
if (likely(mas->offset < mas->end)) if (likely(mas->offset < mas->end))
pivot = pivots[mas->offset]; pivot = pivots[mas->offset];
else else
goto overflow; pivot = mas->max;
if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) if (unlikely(mas_rewalk_if_dead(mas, node, save_point)))
goto retry; goto retry;
if (pivot >= max) if (pivot >= max) { /* Was at the limit, next will extend beyond */
goto overflow; mas->status = ma_overflow;
return NULL;
}
} }
if (likely(mas->offset < mas->end)) { if (likely(mas->offset < mas->end)) {
...@@ -4664,16 +4680,18 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty, ...@@ -4664,16 +4680,18 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty,
else else
mas->last = mas->max; mas->last = mas->max;
} else { } else {
if (mas->last >= max) {
mas->status = ma_overflow;
return NULL;
}
if (mas_next_node(mas, node, max)) { if (mas_next_node(mas, node, max)) {
mas_rewalk(mas, save_point); mas_rewalk(mas, save_point);
goto retry; goto retry;
} }
if (WARN_ON_ONCE(mas_is_none(mas))) { if (WARN_ON_ONCE(mas_is_overflow(mas)))
mas->node = MAS_OVERFLOW;
return NULL; return NULL;
goto overflow;
}
mas->offset = 0; mas->offset = 0;
mas->index = mas->min; mas->index = mas->min;
...@@ -4691,20 +4709,18 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty, ...@@ -4691,20 +4709,18 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty,
if (entry) if (entry)
return entry; return entry;
if (!empty) { if (!empty) {
if (mas->last >= max) if (mas->last >= max) {
goto overflow; mas->status = ma_overflow;
return NULL;
}
mas->index = mas->last + 1; mas->index = mas->last + 1;
goto again; goto again;
} }
return entry; return entry;
overflow:
if (set_overflow)
mas->node = MAS_OVERFLOW;
return NULL;
} }
/* /*
...@@ -4723,11 +4739,11 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty, ...@@ -4723,11 +4739,11 @@ static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty,
static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit) static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit)
{ {
if (mas->last >= limit) { if (mas->last >= limit) {
mas->node = MAS_OVERFLOW; mas->status = ma_overflow;
return NULL; return NULL;
} }
return mas_next_slot(mas, limit, false, true); return mas_next_slot(mas, limit, false);
} }
/* /*
...@@ -4895,7 +4911,7 @@ static inline bool mas_anode_descend(struct ma_state *mas, unsigned long size) ...@@ -4895,7 +4911,7 @@ static inline bool mas_anode_descend(struct ma_state *mas, unsigned long size)
* @mas: The maple state. * @mas: The maple state.
* *
* mas->index and mas->last will be set to the range if there is a value. If * mas->index and mas->last will be set to the range if there is a value. If
* mas->node is MAS_NONE, reset to MAS_START. * mas->status is ma_none, reset to ma_start
* *
* Return: the entry at the location or %NULL. * Return: the entry at the location or %NULL.
*/ */
...@@ -4904,7 +4920,7 @@ void *mas_walk(struct ma_state *mas) ...@@ -4904,7 +4920,7 @@ void *mas_walk(struct ma_state *mas)
void *entry; void *entry;
if (!mas_is_active(mas) || !mas_is_start(mas)) if (!mas_is_active(mas) || !mas_is_start(mas))
mas->node = MAS_START; mas->status = ma_start;
retry: retry:
entry = mas_state_walk(mas); entry = mas_state_walk(mas);
if (mas_is_start(mas)) { if (mas_is_start(mas)) {
...@@ -4920,7 +4936,7 @@ void *mas_walk(struct ma_state *mas) ...@@ -4920,7 +4936,7 @@ void *mas_walk(struct ma_state *mas)
mas->index = 1; mas->index = 1;
mas->last = ULONG_MAX; mas->last = ULONG_MAX;
mas->node = MAS_NONE; mas->status = ma_none;
return NULL; return NULL;
} }
...@@ -5672,27 +5688,40 @@ static bool mas_next_setup(struct ma_state *mas, unsigned long max, ...@@ -5672,27 +5688,40 @@ static bool mas_next_setup(struct ma_state *mas, unsigned long max,
bool was_none = mas_is_none(mas); bool was_none = mas_is_none(mas);
if (unlikely(mas->last >= max)) { if (unlikely(mas->last >= max)) {
mas->node = MAS_OVERFLOW; mas->status = ma_overflow;
return true; return true;
} }
if (mas_is_active(mas)) switch (mas->status) {
case ma_active:
return false; return false;
case ma_none:
if (mas_is_none(mas) || mas_is_paused(mas)) { fallthrough;
mas->node = MAS_START; case ma_pause:
} else if (mas_is_overflow(mas)) { mas->status = ma_start;
fallthrough;
case ma_start:
mas_walk(mas); /* Retries on dead nodes handled by mas_walk */
break;
case ma_overflow:
/* Overflowed before, but the max changed */ /* Overflowed before, but the max changed */
mas->node = MAS_START; mas->status = ma_active;
} else if (mas_is_underflow(mas)) { break;
mas->node = MAS_START; case ma_underflow:
/* The user expects the mas to be one before where it is */
mas->status = ma_active;
*entry = mas_walk(mas); *entry = mas_walk(mas);
if (*entry) if (*entry)
return true; return true;
break;
case ma_root:
break;
case ma_error:
return true;
} }
if (mas_is_start(mas)) if (likely(mas_is_active(mas))) /* Fast path */
*entry = mas_walk(mas); /* Retries on dead nodes handled by mas_walk */ return false;
if (mas_is_ptr(mas)) { if (mas_is_ptr(mas)) {
*entry = NULL; *entry = NULL;
...@@ -5702,7 +5731,7 @@ static bool mas_next_setup(struct ma_state *mas, unsigned long max, ...@@ -5702,7 +5731,7 @@ static bool mas_next_setup(struct ma_state *mas, unsigned long max,
} }
mas->index = 1; mas->index = 1;
mas->last = ULONG_MAX; mas->last = ULONG_MAX;
mas->node = MAS_NONE; mas->status = ma_none;
return true; return true;
} }
...@@ -5731,7 +5760,7 @@ void *mas_next(struct ma_state *mas, unsigned long max) ...@@ -5731,7 +5760,7 @@ void *mas_next(struct ma_state *mas, unsigned long max)
return entry; return entry;
/* Retries on dead nodes handled by mas_next_slot */ /* Retries on dead nodes handled by mas_next_slot */
return mas_next_slot(mas, max, false, true); return mas_next_slot(mas, max, false);
} }
EXPORT_SYMBOL_GPL(mas_next); EXPORT_SYMBOL_GPL(mas_next);
...@@ -5754,7 +5783,7 @@ void *mas_next_range(struct ma_state *mas, unsigned long max) ...@@ -5754,7 +5783,7 @@ void *mas_next_range(struct ma_state *mas, unsigned long max)
return entry; return entry;
/* Retries on dead nodes handled by mas_next_slot */ /* Retries on dead nodes handled by mas_next_slot */
return mas_next_slot(mas, max, true, true); return mas_next_slot(mas, max, true);
} }
EXPORT_SYMBOL_GPL(mas_next_range); EXPORT_SYMBOL_GPL(mas_next_range);
...@@ -5785,33 +5814,45 @@ EXPORT_SYMBOL_GPL(mt_next); ...@@ -5785,33 +5814,45 @@ EXPORT_SYMBOL_GPL(mt_next);
static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry) static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry)
{ {
if (unlikely(mas->index <= min)) { if (unlikely(mas->index <= min)) {
mas->node = MAS_UNDERFLOW; mas->status = ma_underflow;
return true; return true;
} }
if (mas_is_active(mas)) switch (mas->status) {
case ma_active:
return false; return false;
case ma_start:
if (mas_is_overflow(mas)) { break;
mas->node = MAS_START; case ma_none:
fallthrough;
case ma_pause:
mas->status = ma_start;
break;
case ma_underflow:
/* underflowed before but the min changed */
mas->status = ma_active;
break;
case ma_overflow:
/* User expects mas to be one after where it is */
mas->status = ma_active;
*entry = mas_walk(mas); *entry = mas_walk(mas);
if (*entry) if (*entry)
return true; return true;
} break;
case ma_root:
if (mas_is_none(mas) || mas_is_paused(mas)) { break;
mas->node = MAS_START; case ma_error:
} else if (mas_is_underflow(mas)) { return true;
/* underflowed before but the min changed */
mas->node = MAS_START;
} }
if (mas_is_start(mas)) if (mas_is_start(mas))
mas_walk(mas); mas_walk(mas);
if (unlikely(mas_is_ptr(mas))) { if (unlikely(mas_is_ptr(mas))) {
if (!mas->index) if (!mas->index) {
goto none; mas->status = ma_none;
return true;
}
mas->index = mas->last = 0; mas->index = mas->last = 0;
*entry = mas_root(mas); *entry = mas_root(mas);
return true; return true;
...@@ -5821,7 +5862,7 @@ static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry ...@@ -5821,7 +5862,7 @@ static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry
if (mas->index) { if (mas->index) {
/* Walked to out-of-range pointer? */ /* Walked to out-of-range pointer? */
mas->index = mas->last = 0; mas->index = mas->last = 0;
mas->node = MAS_ROOT; mas->status = ma_root;
*entry = mas_root(mas); *entry = mas_root(mas);
return true; return true;
} }
...@@ -5829,10 +5870,6 @@ static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry ...@@ -5829,10 +5870,6 @@ static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry
} }
return false; return false;
none:
mas->node = MAS_NONE;
return true;
} }
/** /**
...@@ -5841,7 +5878,7 @@ static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry ...@@ -5841,7 +5878,7 @@ static bool mas_prev_setup(struct ma_state *mas, unsigned long min, void **entry
* @min: The minimum value to check. * @min: The minimum value to check.
* *
* Must hold rcu_read_lock or the write lock. * Must hold rcu_read_lock or the write lock.
* Will reset mas to MAS_START if the node is MAS_NONE. Will stop on not * Will reset mas to ma_start if the status is ma_none. Will stop on not
* searchable nodes. * searchable nodes.
* *
* Return: the previous value or %NULL. * Return: the previous value or %NULL.
...@@ -5853,7 +5890,7 @@ void *mas_prev(struct ma_state *mas, unsigned long min) ...@@ -5853,7 +5890,7 @@ void *mas_prev(struct ma_state *mas, unsigned long min)
if (mas_prev_setup(mas, min, &entry)) if (mas_prev_setup(mas, min, &entry))
return entry; return entry;
return mas_prev_slot(mas, min, false, true); return mas_prev_slot(mas, min, false);
} }
EXPORT_SYMBOL_GPL(mas_prev); EXPORT_SYMBOL_GPL(mas_prev);
...@@ -5864,7 +5901,7 @@ EXPORT_SYMBOL_GPL(mas_prev); ...@@ -5864,7 +5901,7 @@ EXPORT_SYMBOL_GPL(mas_prev);
* *
* Sets @mas->index and @mas->last to the range. * Sets @mas->index and @mas->last to the range.
* Must hold rcu_read_lock or the write lock. * Must hold rcu_read_lock or the write lock.
* Will reset mas to MAS_START if the node is MAS_NONE. Will stop on not * Will reset mas to ma_start if the node is ma_none. Will stop on not
* searchable nodes. * searchable nodes.
* *
* Return: the previous value or %NULL. * Return: the previous value or %NULL.
...@@ -5876,7 +5913,7 @@ void *mas_prev_range(struct ma_state *mas, unsigned long min) ...@@ -5876,7 +5913,7 @@ void *mas_prev_range(struct ma_state *mas, unsigned long min)
if (mas_prev_setup(mas, min, &entry)) if (mas_prev_setup(mas, min, &entry))
return entry; return entry;
return mas_prev_slot(mas, min, true, true); return mas_prev_slot(mas, min, true);
} }
EXPORT_SYMBOL_GPL(mas_prev_range); EXPORT_SYMBOL_GPL(mas_prev_range);
...@@ -5919,7 +5956,8 @@ EXPORT_SYMBOL_GPL(mt_prev); ...@@ -5919,7 +5956,8 @@ EXPORT_SYMBOL_GPL(mt_prev);
*/ */
void mas_pause(struct ma_state *mas) void mas_pause(struct ma_state *mas)
{ {
mas->node = MAS_PAUSE; mas->status = ma_pause;
mas->node = NULL;
} }
EXPORT_SYMBOL_GPL(mas_pause); EXPORT_SYMBOL_GPL(mas_pause);
...@@ -5933,32 +5971,52 @@ EXPORT_SYMBOL_GPL(mas_pause); ...@@ -5933,32 +5971,52 @@ EXPORT_SYMBOL_GPL(mas_pause);
*/ */
static __always_inline bool mas_find_setup(struct ma_state *mas, unsigned long max, void **entry) static __always_inline bool mas_find_setup(struct ma_state *mas, unsigned long max, void **entry)
{ {
if (mas_is_active(mas)) { switch (mas->status) {
case ma_active:
if (mas->last < max) if (mas->last < max)
return false; return false;
return true; return true;
} case ma_start:
break;
if (mas_is_paused(mas)) { case ma_pause:
if (unlikely(mas->last >= max)) if (unlikely(mas->last >= max))
return true; return true;
mas->index = ++mas->last; mas->index = ++mas->last;
mas->node = MAS_START; mas->status = ma_start;
} else if (mas_is_none(mas)) { break;
case ma_none:
if (unlikely(mas->last >= max)) if (unlikely(mas->last >= max))
return true; return true;
mas->index = mas->last; mas->index = mas->last;
mas->node = MAS_START; mas->status = ma_start;
} else if (mas_is_overflow(mas) || mas_is_underflow(mas)) { break;
if (mas->index > max) { case ma_underflow:
mas->node = MAS_OVERFLOW; /* mas is pointing at entry before unable to go lower */
if (unlikely(mas->index >= max)) {
mas->status = ma_overflow;
return true; return true;
} }
mas->node = MAS_START; mas->status = ma_active;
*entry = mas_walk(mas);
if (*entry)
return true;
break;
case ma_overflow:
if (unlikely(mas->last >= max))
return true;
mas->status = ma_active;
*entry = mas_walk(mas);
if (*entry)
return true;
break;
case ma_root:
break;
case ma_error:
return true;
} }
if (mas_is_start(mas)) { if (mas_is_start(mas)) {
...@@ -5985,7 +6043,7 @@ static __always_inline bool mas_find_setup(struct ma_state *mas, unsigned long m ...@@ -5985,7 +6043,7 @@ static __always_inline bool mas_find_setup(struct ma_state *mas, unsigned long m
return false; return false;
ptr_out_of_range: ptr_out_of_range:
mas->node = MAS_NONE; mas->status = ma_none;
mas->index = 1; mas->index = 1;
mas->last = ULONG_MAX; mas->last = ULONG_MAX;
return true; return true;
...@@ -5999,7 +6057,7 @@ static __always_inline bool mas_find_setup(struct ma_state *mas, unsigned long m ...@@ -5999,7 +6057,7 @@ static __always_inline bool mas_find_setup(struct ma_state *mas, unsigned long m
* *
* Must hold rcu_read_lock or the write lock. * Must hold rcu_read_lock or the write lock.
* If an entry exists, last and index are updated accordingly. * If an entry exists, last and index are updated accordingly.
* May set @mas->node to MAS_NONE. * May set @mas->status to ma_overflow.
* *
* Return: The entry or %NULL. * Return: The entry or %NULL.
*/ */
...@@ -6011,7 +6069,10 @@ void *mas_find(struct ma_state *mas, unsigned long max) ...@@ -6011,7 +6069,10 @@ void *mas_find(struct ma_state *mas, unsigned long max)
return entry; return entry;
/* Retries on dead nodes handled by mas_next_slot */ /* Retries on dead nodes handled by mas_next_slot */
return mas_next_slot(mas, max, false, false); entry = mas_next_slot(mas, max, false);
/* Ignore overflow */
mas->status = ma_active;
return entry;
} }
EXPORT_SYMBOL_GPL(mas_find); EXPORT_SYMBOL_GPL(mas_find);
...@@ -6023,7 +6084,7 @@ EXPORT_SYMBOL_GPL(mas_find); ...@@ -6023,7 +6084,7 @@ EXPORT_SYMBOL_GPL(mas_find);
* *
* Must hold rcu_read_lock or the write lock. * Must hold rcu_read_lock or the write lock.
* If an entry exists, last and index are updated accordingly. * If an entry exists, last and index are updated accordingly.
* May set @mas->node to MAS_NONE. * May set @mas->status to ma_overflow.
* *
* Return: The entry or %NULL. * Return: The entry or %NULL.
*/ */
...@@ -6035,7 +6096,7 @@ void *mas_find_range(struct ma_state *mas, unsigned long max) ...@@ -6035,7 +6096,7 @@ void *mas_find_range(struct ma_state *mas, unsigned long max)
return entry; return entry;
/* Retries on dead nodes handled by mas_next_slot */ /* Retries on dead nodes handled by mas_next_slot */
return mas_next_slot(mas, max, true, false); return mas_next_slot(mas, max, true);
} }
EXPORT_SYMBOL_GPL(mas_find_range); EXPORT_SYMBOL_GPL(mas_find_range);
...@@ -6050,33 +6111,45 @@ EXPORT_SYMBOL_GPL(mas_find_range); ...@@ -6050,33 +6111,45 @@ EXPORT_SYMBOL_GPL(mas_find_range);
static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min, static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min,
void **entry) void **entry)
{ {
if (mas_is_active(mas)) {
if (mas->index > min)
return false;
return true;
}
if (mas_is_paused(mas)) { switch (mas->status) {
case ma_active:
goto active;
case ma_start:
break;
case ma_pause:
if (unlikely(mas->index <= min)) { if (unlikely(mas->index <= min)) {
mas->node = MAS_NONE; mas->status = ma_underflow;
return true; return true;
} }
mas->node = MAS_START;
mas->last = --mas->index; mas->last = --mas->index;
} else if (mas_is_none(mas)) { mas->status = ma_start;
break;
case ma_none:
if (mas->index <= min) if (mas->index <= min)
goto none; goto none;
mas->last = mas->index; mas->last = mas->index;
mas->node = MAS_START; mas->status = ma_start;
} else if (mas_is_underflow(mas) || mas_is_overflow(mas)) { break;
if (mas->last <= min) { case ma_overflow: /* user expects the mas to be one after where it is */
mas->node = MAS_UNDERFLOW; if (unlikely(mas->index <= min)) {
mas->status = ma_underflow;
return true; return true;
} }
mas->node = MAS_START; mas->status = ma_active;
break;
case ma_underflow: /* user expects the mas to be one before where it is */
if (unlikely(mas->index <= min))
return true;
mas->status = ma_active;
break;
case ma_root:
break;
case ma_error:
return true;
} }
if (mas_is_start(mas)) { if (mas_is_start(mas)) {
...@@ -6099,19 +6172,20 @@ static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min, ...@@ -6099,19 +6172,20 @@ static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min,
* previous location is 0. * previous location is 0.
*/ */
mas->last = mas->index = 0; mas->last = mas->index = 0;
mas->node = MAS_ROOT; mas->status = ma_root;
*entry = mas_root(mas); *entry = mas_root(mas);
return true; return true;
} }
} }
active:
if (mas->index < min) if (mas->index < min)
return true; return true;
return false; return false;
none: none:
mas->node = MAS_NONE; mas->status = ma_none;
return true; return true;
} }
...@@ -6124,7 +6198,7 @@ static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min, ...@@ -6124,7 +6198,7 @@ static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min,
* *
* Must hold rcu_read_lock or the write lock. * Must hold rcu_read_lock or the write lock.
* If an entry exists, last and index are updated accordingly. * If an entry exists, last and index are updated accordingly.
* May set @mas->node to MAS_NONE. * May set @mas->status to ma_underflow.
* *
* Return: The entry or %NULL. * Return: The entry or %NULL.
*/ */
...@@ -6136,7 +6210,7 @@ void *mas_find_rev(struct ma_state *mas, unsigned long min) ...@@ -6136,7 +6210,7 @@ void *mas_find_rev(struct ma_state *mas, unsigned long min)
return entry; return entry;
/* Retries on dead nodes handled by mas_prev_slot */ /* Retries on dead nodes handled by mas_prev_slot */
return mas_prev_slot(mas, min, false, false); return mas_prev_slot(mas, min, false);
} }
EXPORT_SYMBOL_GPL(mas_find_rev); EXPORT_SYMBOL_GPL(mas_find_rev);
...@@ -6150,7 +6224,7 @@ EXPORT_SYMBOL_GPL(mas_find_rev); ...@@ -6150,7 +6224,7 @@ EXPORT_SYMBOL_GPL(mas_find_rev);
* *
* Must hold rcu_read_lock or the write lock. * Must hold rcu_read_lock or the write lock.
* If an entry exists, last and index are updated accordingly. * If an entry exists, last and index are updated accordingly.
* May set @mas->node to MAS_NONE. * May set @mas->status to ma_underflow.
* *
* Return: The entry or %NULL. * Return: The entry or %NULL.
*/ */
...@@ -6162,7 +6236,7 @@ void *mas_find_range_rev(struct ma_state *mas, unsigned long min) ...@@ -6162,7 +6236,7 @@ void *mas_find_range_rev(struct ma_state *mas, unsigned long min)
return entry; return entry;
/* Retries on dead nodes handled by mas_prev_slot */ /* Retries on dead nodes handled by mas_prev_slot */
return mas_prev_slot(mas, min, true, false); return mas_prev_slot(mas, min, true);
} }
EXPORT_SYMBOL_GPL(mas_find_range_rev); EXPORT_SYMBOL_GPL(mas_find_range_rev);
...@@ -6183,7 +6257,7 @@ void *mas_erase(struct ma_state *mas) ...@@ -6183,7 +6257,7 @@ void *mas_erase(struct ma_state *mas)
MA_WR_STATE(wr_mas, mas, NULL); MA_WR_STATE(wr_mas, mas, NULL);
if (!mas_is_active(mas) || !mas_is_start(mas)) if (!mas_is_active(mas) || !mas_is_start(mas))
mas->node = MAS_START; mas->status = ma_start;
/* Retry unnecessary when holding the write lock. */ /* Retry unnecessary when holding the write lock. */
entry = mas_state_walk(mas); entry = mas_state_walk(mas);
...@@ -6228,7 +6302,7 @@ bool mas_nomem(struct ma_state *mas, gfp_t gfp) ...@@ -6228,7 +6302,7 @@ bool mas_nomem(struct ma_state *mas, gfp_t gfp)
if (!mas_allocated(mas)) if (!mas_allocated(mas))
return false; return false;
mas->node = MAS_START; mas->status = ma_start;
return true; return true;
} }
...@@ -6627,7 +6701,7 @@ static inline void mas_dup_build(struct ma_state *mas, struct ma_state *new_mas, ...@@ -6627,7 +6701,7 @@ static inline void mas_dup_build(struct ma_state *mas, struct ma_state *new_mas,
node = mt_alloc_one(gfp); node = mt_alloc_one(gfp);
if (!node) { if (!node) {
new_mas->node = MAS_NONE; new_mas->status = ma_none;
mas_set_err(mas, -ENOMEM); mas_set_err(mas, -ENOMEM);
return; return;
} }
...@@ -6971,11 +7045,11 @@ static inline struct maple_enode *mas_get_slot(struct ma_state *mas, ...@@ -6971,11 +7045,11 @@ static inline struct maple_enode *mas_get_slot(struct ma_state *mas,
static void mas_dfs_postorder(struct ma_state *mas, unsigned long max) static void mas_dfs_postorder(struct ma_state *mas, unsigned long max)
{ {
struct maple_enode *p = MAS_NONE, *mn = mas->node; struct maple_enode *p, *mn = mas->node;
unsigned long p_min, p_max; unsigned long p_min, p_max;
mas_next_node(mas, mas_mn(mas), max); mas_next_node(mas, mas_mn(mas), max);
if (!mas_is_none(mas)) if (!mas_is_overflow(mas))
return; return;
if (mte_is_root(mn)) if (mte_is_root(mn))
...@@ -6988,7 +7062,7 @@ static void mas_dfs_postorder(struct ma_state *mas, unsigned long max) ...@@ -6988,7 +7062,7 @@ static void mas_dfs_postorder(struct ma_state *mas, unsigned long max)
p_min = mas->min; p_min = mas->min;
p_max = mas->max; p_max = mas->max;
mas_prev_node(mas, 0); mas_prev_node(mas, 0);
} while (!mas_is_none(mas)); } while (!mas_is_underflow(mas));
mas->node = p; mas->node = p;
mas->max = p_max; mas->max = p_max;
...@@ -7443,7 +7517,7 @@ static void mt_validate_nulls(struct maple_tree *mt) ...@@ -7443,7 +7517,7 @@ static void mt_validate_nulls(struct maple_tree *mt)
MA_STATE(mas, mt, 0, 0); MA_STATE(mas, mt, 0, 0);
mas_start(&mas); mas_start(&mas);
if (mas_is_none(&mas) || (mas.node == MAS_ROOT)) if (mas_is_none(&mas) || (mas_is_ptr(&mas)))
return; return;
while (!mte_is_leaf(mas.node)) while (!mte_is_leaf(mas.node))
...@@ -7460,7 +7534,7 @@ static void mt_validate_nulls(struct maple_tree *mt) ...@@ -7460,7 +7534,7 @@ static void mt_validate_nulls(struct maple_tree *mt)
last = entry; last = entry;
if (offset == mas_data_end(&mas)) { if (offset == mas_data_end(&mas)) {
mas_next_node(&mas, mas_mn(&mas), ULONG_MAX); mas_next_node(&mas, mas_mn(&mas), ULONG_MAX);
if (mas_is_none(&mas)) if (mas_is_overflow(&mas))
return; return;
offset = 0; offset = 0;
slots = ma_slots(mte_to_node(mas.node), slots = ma_slots(mte_to_node(mas.node),
...@@ -7469,7 +7543,7 @@ static void mt_validate_nulls(struct maple_tree *mt) ...@@ -7469,7 +7543,7 @@ static void mt_validate_nulls(struct maple_tree *mt)
offset++; offset++;
} }
} while (!mas_is_none(&mas)); } while (!mas_is_overflow(&mas));
} }
/* /*
...@@ -7490,7 +7564,7 @@ void mt_validate(struct maple_tree *mt) ...@@ -7490,7 +7564,7 @@ void mt_validate(struct maple_tree *mt)
while (!mte_is_leaf(mas.node)) while (!mte_is_leaf(mas.node))
mas_descend(&mas); mas_descend(&mas);
while (!mas_is_none(&mas)) { while (!mas_is_overflow(&mas)) {
MAS_WARN_ON(&mas, mte_dead_node(mas.node)); MAS_WARN_ON(&mas, mte_dead_node(mas.node));
end = mas_data_end(&mas); end = mas_data_end(&mas);
if (MAS_WARN_ON(&mas, (end < mt_min_slot_count(mas.node)) && if (MAS_WARN_ON(&mas, (end < mt_min_slot_count(mas.node)) &&
...@@ -7515,16 +7589,35 @@ EXPORT_SYMBOL_GPL(mt_validate); ...@@ -7515,16 +7589,35 @@ EXPORT_SYMBOL_GPL(mt_validate);
void mas_dump(const struct ma_state *mas) void mas_dump(const struct ma_state *mas)
{ {
pr_err("MAS: tree=%p enode=%p ", mas->tree, mas->node); pr_err("MAS: tree=%p enode=%p ", mas->tree, mas->node);
if (mas_is_none(mas)) switch (mas->status) {
pr_err("(MAS_NONE) "); case ma_active:
else if (mas_is_ptr(mas)) pr_err("(ma_active)");
pr_err("(MAS_ROOT) "); break;
else if (mas_is_start(mas)) case ma_none:
pr_err("(MAS_START) "); pr_err("(ma_none)");
else if (mas_is_paused(mas)) break;
pr_err("(MAS_PAUSED) "); case ma_root:
pr_err("(ma_root)");
pr_err("[%u] index=%lx last=%lx\n", mas->offset, mas->index, mas->last); break;
case ma_start:
pr_err("(ma_start) ");
break;
case ma_pause:
pr_err("(ma_pause) ");
break;
case ma_overflow:
pr_err("(ma_overflow) ");
break;
case ma_underflow:
pr_err("(ma_underflow) ");
break;
case ma_error:
pr_err("(ma_error) ");
break;
}
pr_err("[%u/%u] index=%lx last=%lx\n", mas->offset, mas->end,
mas->index, mas->last);
pr_err(" min=%lx max=%lx alloc=%p, depth=%u, flags=%x\n", pr_err(" min=%lx max=%lx alloc=%p, depth=%u, flags=%x\n",
mas->min, mas->max, mas->alloc, mas->depth, mas->mas_flags); mas->min, mas->max, mas->alloc, mas->depth, mas->mas_flags);
if (mas->index > mas->last) if (mas->index > mas->last)
......
...@@ -54,6 +54,11 @@ atomic_t maple_tree_tests_passed; ...@@ -54,6 +54,11 @@ atomic_t maple_tree_tests_passed;
#else #else
#define cond_resched() do {} while (0) #define cond_resched() do {} while (0)
#endif #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, static int __init mtree_insert_index(struct maple_tree *mt,
unsigned long index, gfp_t gfp) unsigned long index, gfp_t gfp)
{ {
...@@ -582,7 +587,7 @@ static noinline void __init check_find(struct maple_tree *mt) ...@@ -582,7 +587,7 @@ static noinline void __init check_find(struct maple_tree *mt)
MT_BUG_ON(mt, last != mas.last); MT_BUG_ON(mt, last != mas.last);
mas.node = MAS_NONE; mas.status = ma_none;
mas.index = ULONG_MAX; mas.index = ULONG_MAX;
mas.last = ULONG_MAX; mas.last = ULONG_MAX;
entry2 = mas_prev(&mas, 0); entry2 = mas_prev(&mas, 0);
...@@ -2178,7 +2183,7 @@ static noinline void __init next_prev_test(struct maple_tree *mt) ...@@ -2178,7 +2183,7 @@ static noinline void __init next_prev_test(struct maple_tree *mt)
MT_BUG_ON(mt, val != NULL); MT_BUG_ON(mt, val != NULL);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 5); 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.index = 0;
mas.last = 5; mas.last = 5;
...@@ -3042,10 +3047,6 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt) ...@@ -3042,10 +3047,6 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt)
* DNE active active range of NULL * 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) static noinline void __init check_state_handling(struct maple_tree *mt)
{ {
MA_STATE(mas, mt, 0, 0); MA_STATE(mas, mt, 0, 0);
...@@ -3060,7 +3061,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3060,7 +3061,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
/* prev: Start -> underflow*/ /* prev: Start -> underflow*/
entry = mas_prev(&mas, 0); entry = mas_prev(&mas, 0);
MT_BUG_ON(mt, entry != NULL); 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 */ /* prev: Start -> root */
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3068,7 +3069,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3068,7 +3069,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* prev: pause -> root */
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3077,7 +3078,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3077,7 +3078,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* next: start -> none */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3085,7 +3086,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3085,7 +3086,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); MT_BUG_ON(mt, mas.last != ULONG_MAX);
MT_BUG_ON(mt, entry != NULL); 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*/ /* next: start -> none*/
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3093,7 +3094,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3093,7 +3094,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); MT_BUG_ON(mt, mas.last != ULONG_MAX);
MT_BUG_ON(mt, entry != NULL); 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 */ /* find: start -> root */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3101,21 +3102,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3101,21 +3102,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* find: root -> none */
entry = mas_find(&mas, ULONG_MAX); entry = mas_find(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* find: none -> none */
entry = mas_find(&mas, ULONG_MAX); entry = mas_find(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* find: start -> none */
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3123,14 +3124,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3123,14 +3124,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* find_rev: none -> root */
entry = mas_find_rev(&mas, 0); entry = mas_find_rev(&mas, 0);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* find_rev: start -> root */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3138,21 +3139,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3138,21 +3139,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* find_rev: root -> none */
entry = mas_find_rev(&mas, 0); entry = mas_find_rev(&mas, 0);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* find_rev: none -> none */
entry = mas_find_rev(&mas, 0); entry = mas_find_rev(&mas, 0);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* find_rev: start -> root */
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3160,7 +3161,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3160,7 +3161,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* walk: start -> none */
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3168,7 +3169,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3168,7 +3169,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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*/ /* walk: pause -> none*/
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3177,7 +3178,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3177,7 +3178,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* walk: none -> none */
mas.index = mas.last = 10; mas.index = mas.last = 10;
...@@ -3185,14 +3186,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3185,14 +3186,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* walk: none -> none */
entry = mas_walk(&mas); entry = mas_walk(&mas);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* walk: start -> root */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3200,7 +3201,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3200,7 +3201,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* walk: pause -> root */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3209,22 +3210,22 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3209,22 +3210,22 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* walk: none -> root */
mas.node = MAS_NONE; mas.status = ma_none;
entry = mas_walk(&mas); entry = mas_walk(&mas);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* walk: root -> root */
entry = mas_walk(&mas); entry = mas_walk(&mas);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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 */ /* walk: root -> none */
mas_set(&mas, 10); mas_set(&mas, 10);
...@@ -3232,7 +3233,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3232,7 +3233,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 1); MT_BUG_ON(mt, mas.index != 1);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* walk: none -> root */
mas.index = mas.last = 0; mas.index = mas.last = 0;
...@@ -3240,7 +3241,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3240,7 +3241,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 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); mas_unlock(&mas);
...@@ -3258,7 +3259,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3258,7 +3259,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* next: pause ->active */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3267,126 +3268,132 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3267,126 +3268,132 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* next: none ->active */
mas.index = mas.last = 0; mas.index = mas.last = 0;
mas.offset = 0; mas.offset = 0;
mas.node = MAS_NONE; mas.status = ma_none;
entry = mas_next(&mas, ULONG_MAX); entry = mas_next(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* next:active ->active (spanning limit) */
entry = mas_next(&mas, ULONG_MAX); entry = mas_next(&mas, 0x2100);
MT_BUG_ON(mt, entry != ptr2); MT_BUG_ON(mt, entry != ptr2);
MT_BUG_ON(mt, mas.index != 0x2000); MT_BUG_ON(mt, mas.index != 0x2000);
MT_BUG_ON(mt, mas.last != 0x2500); 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); entry = mas_next(&mas, 0x2999);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x2501); MT_BUG_ON(mt, mas.index != 0x2501);
MT_BUG_ON(mt, mas.last != 0x2fff); 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); entry = mas_next(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != ptr3); MT_BUG_ON(mt, entry != ptr3);
MT_BUG_ON(mt, mas.index != 0x3000); MT_BUG_ON(mt, mas.index != 0x3000);
MT_BUG_ON(mt, mas.last != 0x3500); MT_BUG_ON(mt, mas.last != 0x3500);
MT_BUG_ON(mt, !mas_active(mas)); MT_BUG_ON(mt, !mas_is_active(&mas));
/* next:active -> active continued */ /* next:active -> overflow (limit reached) */
entry = mas_next(&mas, ULONG_MAX); entry = mas_next(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x3501); MT_BUG_ON(mt, mas.index != 0x3501);
MT_BUG_ON(mt, mas.last != ULONG_MAX); MT_BUG_ON(mt, mas.last != ULONG_MAX);
MT_BUG_ON(mt, !mas_active(mas)); MT_BUG_ON(mt, !mas_is_overflow(&mas));
/* next:active -> 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);
/* next:overflow -> overflow */ /* next:overflow -> overflow */
entry = mas_next(&mas, ULONG_MAX); entry = mas_next(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x3501); MT_BUG_ON(mt, mas.index != 0x3501);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* prev:overflow -> active */
entry = mas_prev(&mas, 0); entry = mas_prev(&mas, 0);
MT_BUG_ON(mt, entry != ptr3); MT_BUG_ON(mt, entry != ptr3);
MT_BUG_ON(mt, mas.index != 0x3000); MT_BUG_ON(mt, mas.index != 0x3000);
MT_BUG_ON(mt, mas.last != 0x3500); 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 */ /* next: none -> active, skip value at location */
mas_set(&mas, 0); mas_set(&mas, 0);
entry = mas_next(&mas, ULONG_MAX); entry = mas_next(&mas, ULONG_MAX);
mas.node = MAS_NONE; mas.status = ma_none;
mas.offset = 0; mas.offset = 0;
entry = mas_next(&mas, ULONG_MAX); entry = mas_next(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != ptr2); MT_BUG_ON(mt, entry != ptr2);
MT_BUG_ON(mt, mas.index != 0x2000); MT_BUG_ON(mt, mas.index != 0x2000);
MT_BUG_ON(mt, mas.last != 0x2500); 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 */ /* prev:active ->active */
entry = mas_prev(&mas, 0); entry = mas_prev(&mas, 0);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); MT_BUG_ON(mt, mas.last != 0x1500);
MT_BUG_ON(mt, !mas_active(mas)); MT_BUG_ON(mt, !mas_is_active(&mas));
/* prev:active -> active spanning end range */ /* 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:underflow -> underflow (lower limit) spanning end range */
entry = mas_prev(&mas, 0x0100); entry = mas_prev(&mas, 0x0100);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 0x0FFF); 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); entry = mas_prev(&mas, 0);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 0x0FFF); 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 */ /* prev:underflow -> underflow */
entry = mas_prev(&mas, 0); entry = mas_prev(&mas, 0);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 0x0FFF); 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 */ /* next:underflow -> active */
entry = mas_next(&mas, ULONG_MAX); entry = mas_next(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* prev:first value -> underflow */
entry = mas_prev(&mas, 0x1000); entry = mas_prev(&mas, 0x1000);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* find:underflow -> first value */
entry = mas_find(&mas, ULONG_MAX); entry = mas_find(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* prev: pause ->active */
mas_set(&mas, 0x3600); mas_set(&mas, 0x3600);
...@@ -3397,21 +3404,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3397,21 +3404,21 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr2); MT_BUG_ON(mt, entry != ptr2);
MT_BUG_ON(mt, mas.index != 0x2000); MT_BUG_ON(mt, mas.index != 0x2000);
MT_BUG_ON(mt, mas.last != 0x2500); 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); entry = mas_prev(&mas, 0x1600);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x1501); MT_BUG_ON(mt, mas.index != 0x1501);
MT_BUG_ON(mt, mas.last != 0x1FFF); 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 */ /* prev: active ->active, continue */
entry = mas_prev(&mas, 0); entry = mas_prev(&mas, 0);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* find: start ->active */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3419,7 +3426,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3419,7 +3426,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* find: pause ->active */
mas_set(&mas, 0); mas_set(&mas, 0);
...@@ -3428,7 +3435,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3428,7 +3435,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */; /* find: start ->active on value */;
mas_set(&mas, 1200); mas_set(&mas, 1200);
...@@ -3436,14 +3443,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3436,14 +3443,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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 */ /* find:active ->active */
entry = mas_find(&mas, ULONG_MAX); entry = mas_find(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != ptr2); MT_BUG_ON(mt, entry != ptr2);
MT_BUG_ON(mt, mas.index != 0x2000); MT_BUG_ON(mt, mas.index != 0x2000);
MT_BUG_ON(mt, mas.last != 0x2500); 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)*/ /* find:active -> active (NULL)*/
...@@ -3451,35 +3458,35 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3451,35 +3458,35 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x2501); MT_BUG_ON(mt, mas.index != 0x2501);
MT_BUG_ON(mt, mas.last != 0x2FFF); 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 */ /* find: overflow ->active */
entry = mas_find(&mas, 0x5000); entry = mas_find(&mas, 0x5000);
MT_BUG_ON(mt, entry != ptr3); MT_BUG_ON(mt, entry != ptr3);
MT_BUG_ON(mt, mas.index != 0x3000); MT_BUG_ON(mt, mas.index != 0x3000);
MT_BUG_ON(mt, mas.last != 0x3500); 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*/ /* find:active -> active (NULL) end*/
entry = mas_find(&mas, ULONG_MAX); entry = mas_find(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x3501); MT_BUG_ON(mt, mas.index != 0x3501);
MT_BUG_ON(mt, mas.last != ULONG_MAX); 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 */ /* find_rev: active (END) ->active */
entry = mas_find_rev(&mas, 0); entry = mas_find_rev(&mas, 0);
MT_BUG_ON(mt, entry != ptr3); MT_BUG_ON(mt, entry != ptr3);
MT_BUG_ON(mt, mas.index != 0x3000); MT_BUG_ON(mt, mas.index != 0x3000);
MT_BUG_ON(mt, mas.last != 0x3500); 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 */ /* find_rev:active ->active */
entry = mas_find_rev(&mas, 0); entry = mas_find_rev(&mas, 0);
MT_BUG_ON(mt, entry != ptr2); MT_BUG_ON(mt, entry != ptr2);
MT_BUG_ON(mt, mas.index != 0x2000); MT_BUG_ON(mt, mas.index != 0x2000);
MT_BUG_ON(mt, mas.last != 0x2500); 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 */ /* find_rev: pause ->active */
mas_pause(&mas); mas_pause(&mas);
...@@ -3487,14 +3494,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3487,14 +3494,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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); entry = mas_find_rev(&mas, 0);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0); MT_BUG_ON(mt, mas.index != 0);
MT_BUG_ON(mt, mas.last != 0x0FFF); 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 */ /* find_rev: start ->active */
mas_set(&mas, 0x1200); mas_set(&mas, 0x1200);
...@@ -3502,7 +3509,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3502,7 +3509,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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_walk start ->active */
mas_set(&mas, 0x1200); mas_set(&mas, 0x1200);
...@@ -3510,7 +3517,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3510,7 +3517,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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_walk start ->active */
mas_set(&mas, 0x1600); mas_set(&mas, 0x1600);
...@@ -3518,7 +3525,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3518,7 +3525,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x1501); MT_BUG_ON(mt, mas.index != 0x1501);
MT_BUG_ON(mt, mas.last != 0x1fff); 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_walk pause ->active */
mas_set(&mas, 0x1200); mas_set(&mas, 0x1200);
...@@ -3527,7 +3534,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3527,7 +3534,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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_walk pause -> active */
mas_set(&mas, 0x1600); mas_set(&mas, 0x1600);
...@@ -3536,25 +3543,25 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3536,25 +3543,25 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x1501); MT_BUG_ON(mt, mas.index != 0x1501);
MT_BUG_ON(mt, mas.last != 0x1fff); 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_walk none -> active */
mas_set(&mas, 0x1200); mas_set(&mas, 0x1200);
mas.node = MAS_NONE; mas.status = ma_none;
entry = mas_walk(&mas); entry = mas_walk(&mas);
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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_walk none -> active */
mas_set(&mas, 0x1600); mas_set(&mas, 0x1600);
mas.node = MAS_NONE; mas.status = ma_none;
entry = mas_walk(&mas); entry = mas_walk(&mas);
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x1501); MT_BUG_ON(mt, mas.index != 0x1501);
MT_BUG_ON(mt, mas.last != 0x1fff); 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_walk active -> active */
mas.index = 0x1200; mas.index = 0x1200;
...@@ -3564,7 +3571,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3564,7 +3571,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != ptr); MT_BUG_ON(mt, entry != ptr);
MT_BUG_ON(mt, mas.index != 0x1000); MT_BUG_ON(mt, mas.index != 0x1000);
MT_BUG_ON(mt, mas.last != 0x1500); 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_walk active -> active */
mas.index = 0x1600; mas.index = 0x1600;
...@@ -3573,7 +3580,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) ...@@ -3573,7 +3580,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt)
MT_BUG_ON(mt, entry != NULL); MT_BUG_ON(mt, entry != NULL);
MT_BUG_ON(mt, mas.index != 0x1501); MT_BUG_ON(mt, mas.index != 0x1501);
MT_BUG_ON(mt, mas.last != 0x1fff); 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); mas_unlock(&mas);
} }
......
...@@ -1163,13 +1163,13 @@ static inline void vma_iter_store(struct vma_iterator *vmi, ...@@ -1163,13 +1163,13 @@ static inline void vma_iter_store(struct vma_iterator *vmi,
{ {
#if defined(CONFIG_DEBUG_VM_MAPLE_TREE) #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)) { vmi->mas.index > vma->vm_start)) {
pr_warn("%lx > %lx\n store vma %lx-%lx\n into slot %lx-%lx\n", pr_warn("%lx > %lx\n store vma %lx-%lx\n into slot %lx-%lx\n",
vmi->mas.index, vma->vm_start, vma->vm_start, vmi->mas.index, vma->vm_start, vma->vm_start,
vma->vm_end, vmi->mas.index, vmi->mas.last); 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)) { vmi->mas.last < vma->vm_start)) {
pr_warn("%lx < %lx\nstore vma %lx-%lx\ninto slot %lx-%lx\n", 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, vmi->mas.last, vma->vm_start, vma->vm_start, vma->vm_end,
...@@ -1177,7 +1177,7 @@ static inline void vma_iter_store(struct vma_iterator *vmi, ...@@ -1177,7 +1177,7 @@ static inline void vma_iter_store(struct vma_iterator *vmi,
} }
#endif #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))) ((vmi->mas.index > vma->vm_start) || (vmi->mas.last < vma->vm_start)))
vma_iter_invalidate(vmi); vma_iter_invalidate(vmi);
...@@ -1188,7 +1188,7 @@ static inline void vma_iter_store(struct vma_iterator *vmi, ...@@ -1188,7 +1188,7 @@ static inline void vma_iter_store(struct vma_iterator *vmi,
static inline int vma_iter_store_gfp(struct vma_iterator *vmi, static inline int vma_iter_store_gfp(struct vma_iterator *vmi,
struct vm_area_struct *vma, gfp_t gfp) 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))) ((vmi->mas.index > vma->vm_start) || (vmi->mas.last < vma->vm_start)))
vma_iter_invalidate(vmi); vma_iter_invalidate(vmi);
......
...@@ -118,6 +118,7 @@ static noinline void __init check_new_node(struct maple_tree *mt) ...@@ -118,6 +118,7 @@ static noinline void __init check_new_node(struct maple_tree *mt)
MT_BUG_ON(mt, mas.alloc == NULL); MT_BUG_ON(mt, mas.alloc == NULL);
MT_BUG_ON(mt, mas.alloc->slot[0] == NULL); MT_BUG_ON(mt, mas.alloc->slot[0] == NULL);
mas_push_node(&mas, mn); mas_push_node(&mas, mn);
mas_reset(&mas);
mas_nomem(&mas, GFP_KERNEL); /* free */ mas_nomem(&mas, GFP_KERNEL); /* free */
mtree_unlock(mt); mtree_unlock(mt);
...@@ -141,7 +142,7 @@ static noinline void __init check_new_node(struct maple_tree *mt) ...@@ -141,7 +142,7 @@ static noinline void __init check_new_node(struct maple_tree *mt)
mn->parent = ma_parent_ptr(mn); mn->parent = ma_parent_ptr(mn);
ma_free_rcu(mn); ma_free_rcu(mn);
mas.node = MAS_START; mas.status = ma_start;
mas_nomem(&mas, GFP_KERNEL); mas_nomem(&mas, GFP_KERNEL);
/* Allocate 3 nodes, will fail. */ /* Allocate 3 nodes, will fail. */
mas_node_count(&mas, 3); mas_node_count(&mas, 3);
...@@ -158,6 +159,7 @@ static noinline void __init check_new_node(struct maple_tree *mt) ...@@ -158,6 +159,7 @@ static noinline void __init check_new_node(struct maple_tree *mt)
/* Ensure we counted 3. */ /* Ensure we counted 3. */
MT_BUG_ON(mt, mas_allocated(&mas) != 3); MT_BUG_ON(mt, mas_allocated(&mas) != 3);
/* Free. */ /* Free. */
mas_reset(&mas);
mas_nomem(&mas, GFP_KERNEL); mas_nomem(&mas, GFP_KERNEL);
/* Set allocation request to 1. */ /* Set allocation request to 1. */
...@@ -272,6 +274,7 @@ static noinline void __init check_new_node(struct maple_tree *mt) ...@@ -272,6 +274,7 @@ static noinline void __init check_new_node(struct maple_tree *mt)
ma_free_rcu(mn); ma_free_rcu(mn);
MT_BUG_ON(mt, mas_allocated(&mas) != i - j - 1); MT_BUG_ON(mt, mas_allocated(&mas) != i - j - 1);
} }
mas_reset(&mas);
MT_BUG_ON(mt, mas_nomem(&mas, GFP_KERNEL)); MT_BUG_ON(mt, mas_nomem(&mas, GFP_KERNEL));
} }
...@@ -294,6 +297,7 @@ static noinline void __init check_new_node(struct maple_tree *mt) ...@@ -294,6 +297,7 @@ static noinline void __init check_new_node(struct maple_tree *mt)
smn = smn->slot[0]; /* next. */ smn = smn->slot[0]; /* next. */
} }
MT_BUG_ON(mt, mas_allocated(&mas) != total); MT_BUG_ON(mt, mas_allocated(&mas) != total);
mas_reset(&mas);
mas_nomem(&mas, GFP_KERNEL); /* Free. */ mas_nomem(&mas, GFP_KERNEL); /* Free. */
MT_BUG_ON(mt, mas_allocated(&mas) != 0); MT_BUG_ON(mt, mas_allocated(&mas) != 0);
...@@ -441,7 +445,7 @@ static noinline void __init check_new_node(struct maple_tree *mt) ...@@ -441,7 +445,7 @@ static noinline void __init check_new_node(struct maple_tree *mt)
mas.node = MA_ERROR(-ENOMEM); mas.node = MA_ERROR(-ENOMEM);
mas_node_count(&mas, 10); /* Request */ mas_node_count(&mas, 10); /* Request */
mas_nomem(&mas, GFP_KERNEL); /* Fill request */ mas_nomem(&mas, GFP_KERNEL); /* Fill request */
mas.node = MAS_START; mas.status = ma_start;
MT_BUG_ON(mt, mas_allocated(&mas) != 10); MT_BUG_ON(mt, mas_allocated(&mas) != 10);
mas_destroy(&mas); mas_destroy(&mas);
...@@ -452,7 +456,7 @@ static noinline void __init check_new_node(struct maple_tree *mt) ...@@ -452,7 +456,7 @@ static noinline void __init check_new_node(struct maple_tree *mt)
mas.node = MA_ERROR(-ENOMEM); mas.node = MA_ERROR(-ENOMEM);
mas_node_count(&mas, 10 + MAPLE_ALLOC_SLOTS - 1); /* Request */ mas_node_count(&mas, 10 + MAPLE_ALLOC_SLOTS - 1); /* Request */
mas_nomem(&mas, GFP_KERNEL); /* Fill request */ mas_nomem(&mas, GFP_KERNEL); /* Fill request */
mas.node = MAS_START; mas.status = ma_start;
MT_BUG_ON(mt, mas_allocated(&mas) != 10 + MAPLE_ALLOC_SLOTS - 1); MT_BUG_ON(mt, mas_allocated(&mas) != 10 + MAPLE_ALLOC_SLOTS - 1);
mas_destroy(&mas); mas_destroy(&mas);
...@@ -941,7 +945,7 @@ static inline bool mas_tree_walk(struct ma_state *mas, unsigned long *range_min, ...@@ -941,7 +945,7 @@ static inline bool mas_tree_walk(struct ma_state *mas, unsigned long *range_min,
ret = mas_descend_walk(mas, range_min, range_max); ret = mas_descend_walk(mas, range_min, range_max);
if (unlikely(mte_dead_node(mas->node))) { if (unlikely(mte_dead_node(mas->node))) {
mas->node = MAS_START; mas->status = ma_start;
goto retry; goto retry;
} }
...@@ -961,10 +965,10 @@ static inline void *mas_range_load(struct ma_state *mas, ...@@ -961,10 +965,10 @@ static inline void *mas_range_load(struct ma_state *mas,
unsigned long index = mas->index; unsigned long index = mas->index;
if (mas_is_none(mas) || mas_is_paused(mas)) if (mas_is_none(mas) || mas_is_paused(mas))
mas->node = MAS_START; mas->status = ma_start;
retry: retry:
if (mas_tree_walk(mas, range_min, range_max)) if (mas_tree_walk(mas, range_min, range_max))
if (unlikely(mas->node == MAS_ROOT)) if (unlikely(mas->status == ma_root))
return mas_root(mas); return mas_root(mas);
if (likely(mas->offset != MAPLE_NODE_SLOTS)) if (likely(mas->offset != MAPLE_NODE_SLOTS))
...@@ -35337,7 +35341,7 @@ static void mas_dfs_preorder(struct ma_state *mas) ...@@ -35337,7 +35341,7 @@ static void mas_dfs_preorder(struct ma_state *mas)
unsigned char end, slot = 0; unsigned char end, slot = 0;
unsigned long *pivots; unsigned long *pivots;
if (mas->node == MAS_START) { if (mas->status == ma_start) {
mas_start(mas); mas_start(mas);
return; return;
} }
...@@ -35374,7 +35378,7 @@ static void mas_dfs_preorder(struct ma_state *mas) ...@@ -35374,7 +35378,7 @@ static void mas_dfs_preorder(struct ma_state *mas)
return; return;
done: done:
mas->node = MAS_NONE; mas->status = ma_none;
} }
...@@ -35833,7 +35837,7 @@ static noinline void __init check_nomem(struct maple_tree *mt) ...@@ -35833,7 +35837,7 @@ static noinline void __init check_nomem(struct maple_tree *mt)
mas_store(&ms, &ms); /* insert 1 -> &ms, fails. */ mas_store(&ms, &ms); /* insert 1 -> &ms, fails. */
MT_BUG_ON(mt, ms.node != MA_ERROR(-ENOMEM)); MT_BUG_ON(mt, ms.node != MA_ERROR(-ENOMEM));
mas_nomem(&ms, GFP_KERNEL); /* Node allocated in here. */ mas_nomem(&ms, GFP_KERNEL); /* Node allocated in here. */
MT_BUG_ON(mt, ms.node != MAS_START); MT_BUG_ON(mt, ms.status != ma_start);
mtree_unlock(mt); mtree_unlock(mt);
MT_BUG_ON(mt, mtree_insert(mt, 2, mt, GFP_KERNEL) != 0); MT_BUG_ON(mt, mtree_insert(mt, 2, mt, GFP_KERNEL) != 0);
mtree_lock(mt); mtree_lock(mt);
...@@ -35952,7 +35956,7 @@ static int __init compare_tree(struct maple_tree *mt_a, struct maple_tree *mt_b) ...@@ -35952,7 +35956,7 @@ static int __init compare_tree(struct maple_tree *mt_a, struct maple_tree *mt_b)
if (mas_is_ptr(&mas_a) || mas_is_ptr(&mas_b)) { if (mas_is_ptr(&mas_a) || mas_is_ptr(&mas_b)) {
if (!(mas_is_ptr(&mas_a) && mas_is_ptr(&mas_b))) { if (!(mas_is_ptr(&mas_a) && mas_is_ptr(&mas_b))) {
pr_err("One is MAS_ROOT and the other is not.\n"); pr_err("One is ma_root and the other is not.\n");
return -1; return -1;
} }
return 0; return 0;
...@@ -35961,7 +35965,7 @@ static int __init compare_tree(struct maple_tree *mt_a, struct maple_tree *mt_b) ...@@ -35961,7 +35965,7 @@ static int __init compare_tree(struct maple_tree *mt_a, struct maple_tree *mt_b)
while (!mas_is_none(&mas_a) || !mas_is_none(&mas_b)) { while (!mas_is_none(&mas_a) || !mas_is_none(&mas_b)) {
if (mas_is_none(&mas_a) || mas_is_none(&mas_b)) { if (mas_is_none(&mas_a) || mas_is_none(&mas_b)) {
pr_err("One is MAS_NONE and the other is not.\n"); pr_err("One is ma_none and the other is not.\n");
return -1; return -1;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment