From: Liam R. Howlett Date: Mon, 6 Jan 2020 18:39:36 +0000 (-0500) Subject: maple_tree: WIP, error in delete path when allocations fail. X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=6ea15e4e674839891f78f5a847bd463d6339a1cd;p=users%2Fjedix%2Flinux-maple.git maple_tree: WIP, error in delete path when allocations fail. Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index e322eb707405b..5640c8b3309c1 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -811,30 +811,36 @@ bool mas_retry(struct ma_state *mas, const void *entry) return true; } -static inline void mas_encoded_parent(struct ma_state *mas) +static inline void mas_ascend(struct ma_state *mas) { - struct maple_enode *p_enode, *gp_enode; - enum maple_type ptype, gptype; - unsigned char slot; + struct maple_enode *p_enode; + struct maple_node *p_node; + unsigned char p_slot; + enum maple_type p_type; - ptype = mas_parent_enum(mas, mas->node); - p_enode = mt_mk_node(mte_parent(mas->node), ptype); - if (_ma_is_root(mte_parent(mas->node))) { - mas->node = p_enode; - mas_set_slot(mas, 0); // No slot. + p_type = mas_parent_enum(mas, mas->node); + p_node = mte_parent(mas->node); + p_slot = mte_parent_slot(mas->node); + p_enode = mt_mk_node(p_node, p_type); + if (_ma_is_root(p_node)) { mas->min = 0; - mas->max = mt_max[ptype]; - return; + mas->max = mt_max[p_type]; + } else if (!p_slot || p_slot >= mt_pivots[p_type]) { + mas->node = p_enode; + mas_ascend(mas); + mas_set_slot(mas, p_slot); + mas_descend(mas); + } else { + struct maple_enode *gp_enode = mt_mk_node(mte_parent(p_enode), + mas_parent_enum(mas, p_enode)); + unsigned char gp_slot = mte_parent_slot(p_enode); + mas->node = gp_enode; + mas_set_slot(mas, gp_slot); + mas_update_limits(mas, gp_slot, mas_parent_enum(mas, p_enode)); } - - gptype = mas_parent_enum(mas, p_enode); - gp_enode = mt_mk_node(mte_parent(p_enode), gptype); - slot = mte_parent_slot(p_enode); - mas->node = gp_enode; - mas_set_slot(mas, slot); - mas_update_limits(mas, slot, gptype); mas->node = p_enode; } + /* mas_get_prev_pivot() - Return the previous pivot. * * Mainly for extracting the previous pivot in the case of slot = 0. @@ -860,7 +866,7 @@ static inline unsigned long mas_get_prev_pivot(const struct ma_state *mas, while (prev_piv.min == mas->min) { p_slot = mte_parent_slot(prev_piv.node); - mas_encoded_parent(&prev_piv); + mas_ascend(&prev_piv); if (p_slot) break; } @@ -1093,6 +1099,7 @@ static inline unsigned char mas_data_end(const struct ma_state *mas, void *entry; piv = _mas_get_safe_pivot(mas, slot, type); + printk("%p[%u] piv %lu\n", mas_mn(mas), slot, piv); if (!piv && slot) { // Past the end of data. slot--; piv = prev_piv; @@ -1127,12 +1134,15 @@ static inline unsigned char mas_data_end(const struct ma_state *mas, counted_null = 0; } - if (piv == mas->max) + if (piv == mas->max) { + printk("max hit %lu\n", mas->max); break; + } prev_piv = piv; } + printk("last piv %lu slot %u coalesce %u\n", piv, slot, *coalesce); *last_piv = piv; return slot; } @@ -1168,7 +1178,7 @@ static inline void mas_ma_cp_store(struct maple_node *mn, enum maple_type type, unsigned char slot, unsigned long piv, void *entry, bool flush) { - printk("set %p[%u] -> %p\n", mn, slot, entry); + //printk("set %p[%u] -> %p\n", mn, slot, entry); ma_set_rcu_slot(mn, slot, type, entry); if (flush) wmb(); // data needs to exist before pivot for readers @@ -1287,7 +1297,7 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, if (right) { split = mas_cp_calc_split(mas, mas_type, append); - printk("Using split of %d\n", split); + // printk("Using split of %d\n", split); } if (left) { @@ -1300,14 +1310,14 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, p_slot = mte_parent_slot(left->node); parent = mte_parent(left->node); mas_type = mas_parent_enum(mas, left->node); - printk("parent is %p\n", parent); + // printk("parent is %p\n", parent); } if (!entry_cnt) piv[2] = mas->max; if (append) { // start at a given slot, so append there. - printk("append\n"); + // printk("append\n"); //mt_dump(mas->tree); mas_dup_state(&cp, mas); src_slot = entry_cnt; @@ -1316,12 +1326,12 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, if (!written_piv) // empty node. written_piv = mas->min; - printk("src_slot %u written %lu\n", src_slot, written_piv); + // printk("src_slot %u written %lu\n", src_slot, written_piv); slot = entry_cnt; if (existing) { slot++; src_slot++; - printk("there is an existing\n"); + // printk("there is an existing\n"); } entry_cnt = 0; @@ -1335,10 +1345,10 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, do { int i = 2; // Default to just writing the pivot. int j = 3; // Loop limit. - printk("src slot %u entry_cnt %d slot %u\n", src_slot, entry_cnt, slot); + // printk("src slot %u entry_cnt %d slot %u\n", src_slot, entry_cnt, slot); if (entry_cnt < 0) { - printk("Setting to appending mode\n"); + // printk("Setting to appending mode\n"); appending = true; existing = NULL; piv[2] = mas->max; @@ -1347,8 +1357,8 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, if (!piv[2] && src_slot) piv[2] = mas->max; existing = mte_get_rcu_slot(mas->node, src_slot); - printk("getting %u (%lu->%p)\n", src_slot, piv[2], - existing); + // printk("getting %u (%lu->%p)\n", src_slot, piv[2], + // existing); } @@ -1356,7 +1366,7 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, if (!appending) { if (mt_will_coalesce(existing)) { - printk("coalesce\n"); + // printk("coalesce\n"); goto skip_src_slot; } @@ -1370,18 +1380,18 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, if (append || (attempt_insert && (cp.index <= piv[2]))) { i = 0; - printk("Written piv %lu\n", written_piv); + // printk("Written piv %lu\n", written_piv); if (written_piv == cp.index - 1) i = 1; // previous pivot matches exactly. else if (!src_slot && written_piv == cp.index) i = 1; // mas->min matches exactly. - printk("piv2 %lu <= last %lu\n", piv[2], cp.last); + // printk("piv2 %lu <= last %lu\n", piv[2], cp.last); if (appending) j--; else if (!appending && (piv[2] <= cp.last)) j--; // skip last pivot. - printk("piv array %u-%u\n", i, j); + // printk("piv array %u-%u\n", i, j); attempt_insert = false; } @@ -1392,9 +1402,9 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, if (!loop_entry && !ma_is_leaf(mn_type)) { - printk("BUG Here\n"); + // printk("BUG Here\n"); } - printk("write array %d %lu to %u entry_cnt %d\n", i, piv[i], slot, entry_cnt); + // printk("write array %d %lu to %u entry_cnt %d\n", i, piv[i], slot, entry_cnt); if (i == 1) loop_entry = entry; @@ -1427,7 +1437,7 @@ static inline unsigned char mas_ma_cp(struct ma_state *mas, (slot > split)) { ret = slot - 1; if (update_gaps) { - printk("Write gap %p[%u] -> %lu\n", parent, p_slot, max_gap); + // printk("Write gap %p[%u] -> %lu\n", parent, p_slot, max_gap); parent->ma64.gap[p_slot] = max_gap; } @@ -1449,7 +1459,7 @@ skip_src_slot: else ret = src_slot - 1; - printk("Done\n"); + // printk("Done\n"); return ret; } @@ -1634,7 +1644,7 @@ static inline void mas_parent_gap(struct ma_state *mas, unsigned char slot, unsigned long max_gap = 0; unsigned char max_slot = 0; - mas_encoded_parent(mas); + mas_ascend(mas); mte_set_gap(mas->node, slot, new); if (mte_is_root(mas->node)) @@ -2067,7 +2077,7 @@ static inline int mas_split(struct ma_state *mas, unsigned char slot, p_slot = mte_parent_slot(mas->node); mas_dup_state(&parent, mas); - mas_encoded_parent(&parent); + mas_ascend(&parent); old_parent = parent.node; ptype = mte_node_type(parent.node); @@ -2324,7 +2334,10 @@ static inline int _mas_add_slot_cnt(struct ma_state *mas, printk("req slots %d\n", req_slots); // Check if it's safe to use the slot without a pivot. - if (max == mas->max) // max of the slot == max of the node. + // max of the slot == max of the node. + // max of the tree is being set. + if ((max == mas->max && mas->max != ULONG_MAX) || + (mas->max == ULONG_MAX && mas->last == ULONG_MAX)) return req_slots; if (!last_entry) // nothing at the last slot. @@ -2449,7 +2462,6 @@ static inline int _mas_add(struct ma_state *mas, void *entry, bool overwrite, printk("Adding %lu-%lu\n", mas->index, mas->last); new_end = _mas_add_slot_cnt(mas, slot, min, max) - coalesce; - mt_dump(mas->tree); printk("%s: %p new_end %u slot_cnt %u\n", __func__, mas_mn(mas), new_end, slot_cnt); if (new_end > slot_cnt) { @@ -2578,7 +2590,7 @@ walk_again: if (mte_is_root(mas->node)) goto no_entry; - mas_encoded_parent(mas); + mas_ascend(mas); if (mas->max > max) goto no_entry; @@ -2650,7 +2662,7 @@ static inline void mas_prev_slot(struct ma_state *mas, unsigned long min) // Walk up. while (1) { slot = mte_parent_slot(mas->node); - mas_encoded_parent(mas); + mas_ascend(mas); if (mas->min < min) goto no_entry; @@ -2707,7 +2719,7 @@ restart_prev_node: while (1) { unsigned long min; - mas_encoded_parent(mas); + mas_ascend(mas); level++; if (!mas_safe_slot(mas, &slot, -1)) @@ -2794,7 +2806,7 @@ restart_next_node: slot = mas_get_slot(mas); start_piv = mas_get_safe_pivot(mas, slot); level++; - mas_encoded_parent(mas); + mas_ascend(mas); if (!mas_safe_slot(mas, &slot, 1)) { if (mte_is_root(mas->node)) @@ -2955,7 +2967,7 @@ static inline void* mas_last_entry(struct ma_state *mas, if (!mas_next_nentry(mas, limit, &range_start)) { void *entry = mte_get_rcu_slot(mas->node, slot - 1); if (mte_is_leaf(mas->node)) { - mas->index = range_start; + mas->index = range_start - 1; return entry; } mas->max = prev_max; @@ -3097,6 +3109,7 @@ static inline void* _mas_prev(struct ma_state *mas, unsigned long limit) mas->last = max; slot = mas_get_slot(mas); + printk("%s: slot %u\n", __func__, slot); if (slot) mas->index = mas_get_safe_pivot(mas, slot - 1) + 1; else @@ -3124,7 +3137,10 @@ void *mas_prev(struct ma_state *mas, unsigned long min) return mas_last_entry(mas, ULONG_MAX); } - entry = _mas_prev(mas, min); + do { + entry = _mas_prev(mas, min); + } while (!entry || mt_will_coalesce(entry)); + return entry; } EXPORT_SYMBOL_GPL(mas_prev); @@ -3181,9 +3197,9 @@ static inline void mas_coalesce_empty(struct ma_state *mas, struct maple_enode *eparent, unsigned char p_slot, enum maple_type p_type) { - mte_set_rcu_slot(eparent, p_slot, XA_SKIP_ENTRY); + mte_set_rcu_slot(eparent, p_slot, XA_DELETED_ENTRY); mas_set_slot(mas, p_slot); - mas_coalesce_pivots(mas, p_slot, p_type, true); + mas_coalesce_pivots(mas, p_slot, p_type, false); } /** Private @@ -3239,7 +3255,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, this_p_slot = mte_parent_slot(this_enode); mas_dup_state(&p_state, mas); // set the parent node, etc. - mas_encoded_parent(&p_state); // Actually make it the parent. + mas_ascend(&p_state); // Actually make it the parent. // Get the next entry. mas_set_slot(&p_state, this_p_slot + 1); @@ -3247,7 +3263,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, // this_enode is the right-most node of the parent. // Reset parent info. mas_dup_state(&p_state, mas); - mas_encoded_parent(&p_state); + mas_ascend(&p_state); mas_set_slot(&p_state, this_p_slot); if (mas_prev_nentry(&p_state, 0, &r_piv)) { // If there is a node to the left, rebalance the left @@ -3310,7 +3326,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, printk("ends in null at %p[%u] => %ld\n", this_enode, l_slot_cnt, r_state.max); mte_set_pivot(this_enode, l_slot_cnt, r_state.max); do { // FIXME: What about non-end nodes? - mas_encoded_parent(mas); + mas_ascend(mas); mte_set_pivot(mas->node, this_p_slot, r_state.max); this_p_slot = mte_parent_slot(mas->node); } while (!mte_is_root(mas->node)); @@ -3359,8 +3375,6 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, cp_state.max = cp_state.last; // update cp state max. cp.src_start = i; } - // if right isn't fully consumed - // mas_copy to new right. // mte_to_node(cp_state.node)->parent = mte_to_node(this_enode)->parent; @@ -3448,7 +3462,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, this_p_slot = mte_parent_slot(this_enode); mas_dup_state(&p_state, mas); // set the parent node, etc. - mas_encoded_parent(&p_state); // Actually make it the parent. + mas_ascend(&p_state); // Actually make it the parent. // Get the next entry. mas_set_slot(&p_state, this_p_slot + 1); @@ -3456,7 +3470,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, // this_enode is the right-most node of the parent. // Reset parent info. mas_dup_state(&p_state, mas); - mas_encoded_parent(&p_state); + mas_ascend(&p_state); mas_set_slot(&p_state, this_p_slot); if (mas_prev_nentry(&p_state, 0, &r_piv)) { // If there is a node to the left, rebalance the left @@ -3468,7 +3482,9 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, // No left or right, rebalance the parent. // But first, remove this entry if it's empty. if (end < coalesce) { - printk("%d empty\n", __LINE__); + printk("%d empty %d %d\n", __LINE__, end, coalesce); + // FIXME: deleted? + // deleted.. AND FREE! mas_coalesce_empty(&p_state, p_state.node, this_p_slot, mte_node_type(p_state.node)); } @@ -3480,6 +3496,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, return 1; } + printk("left and right\n"); // If we reached here, then the node to the right exists. // set the ma_state information and save a copy for this slot. mas_dup_state(&r_state, &p_state); @@ -3491,7 +3508,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, printk("r_slot_cnt %u\n", r_slot_cnt); if (r_end < r_coalesce && r_state.max != ULONG_MAX) { printk("skip entry?\n"); - // This node needs to be a skip entry. + // This node needs to be a deleted entry. all_slots = l_slot_cnt; new_type = mte_node_type(this_enode); l_piv = r_state.max; @@ -3504,7 +3521,7 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, if (all_slots > mt_slot_count(this_enode) - 1) node_cnt++; - printk("%d l_slot_cnt %d\n", __LINE__, l_slot_cnt); + printk("%d l_slot_cnt %d %u %u\n", __LINE__, l_slot_cnt, end, coalesce); // check if left ends in NULL if (l_slot_cnt && !mte_get_rcu_slot(this_enode, l_slot_cnt)) l_null_end = true; @@ -3514,15 +3531,40 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end, printk("ends in null at %p[%u] => %ld\n", this_enode, l_slot_cnt, r_state.max); mte_set_pivot(this_enode, l_slot_cnt, r_state.max); do { - mas_encoded_parent(mas); + unsigned old_piv, old_mas_max = mas->max; + mas_ascend(mas); + old_piv = mte_get_pivot(mas->node, this_p_slot); + if (old_piv != old_mas_max) + break; mte_set_pivot(mas->node, this_p_slot, r_state.max); this_p_slot = mte_parent_slot(mas->node); } while (!mte_is_root(mas->node)); - return 0; + return 1; } mas_node_cnt(mas, node_cnt); - if (mas_is_err(mas)) + if (mas_is_err(mas)) { + // Special case. If we are failing to allocate but the tree + // should be collapsed back, then do the right thing (tm). + if ((r_end == r_coalesce) && + (r_state.max == ULONG_MAX) && + (end >= coalesce)) { + mte_set_pivot(this_enode, l_slot_cnt, r_state.max); + do { + unsigned old_piv, old_mas_max = mas->max; + mas_ascend(mas); + old_piv = mte_get_pivot(mas->node, this_p_slot); + if (old_piv != old_mas_max) + break; + mte_set_pivot(mas->node, this_p_slot, r_state.max); + this_p_slot = mte_parent_slot(mas->node); + } while (!mte_is_root(mas->node)); + r_p_slot = mte_parent_slot(r_enode); + mas_coalesce_empty(&r_state, p_state.node, r_p_slot, + mte_node_type(p_state.node)); + mt_dump(mas->tree); + } return 0; + } printk("here %d\n", __LINE__); // Coalesce this_enode into a new node. @@ -3718,11 +3760,13 @@ static inline void mas_coalesce(struct ma_state *mas) void *entry; start: + mt_dump(mas->tree); if (mte_is_root(mas->node)) return mas_coalesce_root(mas); this_enode = mas->node; this_type = mte_node_type(this_enode); end = mas_data_end(mas, this_type, &this_piv, &coalesce); + printk("data end of %p = %u\n", mas_mn(mas), end); p_type = mas_parent_enum(mas, this_enode); p_slot = mte_parent_slot(this_enode); eparent = mt_mk_node(mte_parent(this_enode), p_type); @@ -3732,23 +3776,20 @@ start: h_data = ma_hard_data(end, coalesce); if (h_data < mt_min_slots[this_type] - 1) { printk("rebalance?\n"); - if (mas_rebalance(mas, end, coalesce)) { - mt_dump(mas->tree); + if (mas_rebalance(mas, end, coalesce)) goto done; - } if (mas_is_err(mas)) { - if (h_data >= 1) + if (end >= coalesce) return; if (mas->max == ULONG_MAX) return; // Single entry and allocation failed, free this_enode - printk("failure path?\n"); + printk("failure path? %u %u\n", end, coalesce); + // FIXME: Deleted? mas->node = this_enode; - mas_encoded_parent(mas); mas_coalesce_empty(mas, eparent, p_slot, p_type); check_parent = true; - mas->node = this_enode; goto done; } } @@ -3761,11 +3802,6 @@ start: if (!mt_is_empty(entry)) goto check_start; - if (end <= coalesce) { - printk("%d empty %p\n", __LINE__, mas_mn(mas)); - mas_coalesce_empty(mas, eparent, p_slot, p_type); - check_parent = true; - } // Check if next node starts with null. mas_next_slot(mas, ULONG_MAX); @@ -3790,6 +3826,7 @@ start: if (!slot) { // Empty node... + // deleted.. AND FREE! mas_coalesce_empty(mas, eparent, p_slot, p_type); check_parent = true; piv = mas->min; @@ -3838,8 +3875,10 @@ done: mas->node = this_enode; if (check_parent) { check_parent = false; - mas_encoded_parent(mas); + mas_ascend(mas); + printk(" -> max is %lu\n", mas->max); mte_free(this_enode); + printk("going to start with %p\n", mas_mn(mas)); goto start; } @@ -4285,9 +4324,11 @@ void *mas_find(struct ma_state *mas, unsigned long max) while (mas_search_cont(mas, index, max, entry)) { entry = _mas_next(mas, max, &index); + printk("%s: %ld -> %p\n", __func__, mas->index, entry); if (mt_is_empty(entry)) entry = NULL; } + printk("%s: %ld -> %p\n", __func__, mas->index, entry); if (entry) mas->index = index; @@ -4385,7 +4426,6 @@ static inline int mas_replace_tree(struct ma_state *mas, void *new_entry) MA_STATE(r_mas, mas->tree, mas->last + 1, mas->last + 1); MA_STATE(l_mas, mas->tree, 0, 0); - mt_dump(mas->tree); // Count the slots that will be used in the node we landed. slot_cnt = 3 + mas_get_slot(mas); // 3 is the max a new entry can create. @@ -4642,7 +4682,7 @@ static int mas_fill_gap(struct ma_state *mas, void *entry, unsigned char slot, * calculate the index and last will cause an issue in the gap * calculation, so fix the ma_state here */ - mas_encoded_parent(mas); + mas_ascend(mas); mas->max = mas_get_safe_pivot(mas, pslot); if (pslot) mas->min = mas_get_safe_pivot(mas, pslot - 1) + 1; @@ -4898,7 +4938,7 @@ static inline bool mas_rewind_node(struct ma_state *mas) } } else { slot = mte_parent_slot(mas->node); - mas_encoded_parent(mas); + mas_ascend(mas); } } while (!slot); @@ -4920,7 +4960,7 @@ static inline bool mas_skip_node(struct ma_state *mas) } } else { slot = mte_parent_slot(mas->node); - mas_encoded_parent(mas); + mas_ascend(mas); } } while (slot > mt_slot_count(mas->node) - 1); @@ -5450,7 +5490,7 @@ static inline void mas_dfs_postorder(struct ma_state *mas, unsigned long max) return; mas->node = mn; - mas_encoded_parent(mas); + mas_ascend(mas); while (mas->node != MAS_NONE) { p = mas->node; p_min = mas->min; diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index e59f7d6ea9d8b..ade52143846ac 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -17,7 +17,9 @@ int mtree_insert_index(struct maple_tree *mt, unsigned long index, gfp_t gfp) static void mtree_erase_index(struct maple_tree *mt, unsigned long index) { + printk("erase %lu\n", index); MT_BUG_ON(mt, mtree_erase(mt, index) != xa_mk_value(index & LONG_MAX)); + printk("load %lu\n", index); MT_BUG_ON(mt, mtree_load(mt, index) != NULL); } @@ -556,6 +558,7 @@ static noinline void check_find(struct maple_tree *mt) entry = mas_prev(&mas, 0); index = mas.index; last = mas.last; + mt_dump(mt); // Erase the last entry. mas_reset(&mas); @@ -565,10 +568,16 @@ static noinline void check_find(struct maple_tree *mt) // Get the previous value from MAS_START mas_reset(&mas); + printk("non mas index set to %lu\n", index); + printk("index set to %lu\n", mas.index); entry2 = mas_prev(&mas, 0); + printk("index set to %lu\n", mas.index); // Check results. + printk("entry %p %p\n" ,entry, entry2); MT_BUG_ON(mt, entry != entry2); + printk("index %lu != %lu\n", index, mas.index); + printk("last %lu != %lu\n", last, mas.last); MT_BUG_ON(mt, index != mas.index); MT_BUG_ON(mt, last != mas.last); mas_unlock(&mas); @@ -603,6 +612,8 @@ static noinline void check_find_2(struct maple_tree *mt) } for (i = 0; i < 256; i++) { + mt_dump(mt); + printk("\t\tErase %lu\n", i); mtree_erase_index(mt, i); j = i + 1; mas_set(&mas, 0); @@ -610,14 +621,16 @@ static noinline void check_find_2(struct maple_tree *mt) mas_for_each(&mas, entry, ULONG_MAX) { if (mas_retry(&mas, entry)) continue; + printk("Checking %lu\n", j); MT_BUG_ON(mt, entry != xa_mk_value(j)); j++; } rcu_read_unlock(); + printk("Checking %lu = 256\n", j); MT_BUG_ON(mt, j != 256); } - MT_BUG_ON(mt, !mtree_empty(mt)); + //MT_BUG_ON(mt, !mtree_empty(mt)); } #define erase_ptr(i) entry[i%2] @@ -2196,11 +2209,13 @@ static int maple_tree_seed(void) check_next_entry(&tree); check_find(&tree); check_find_2(&tree); + goto done; mtree_init(&tree, 0); check_prev_entry(&tree); +done: rcu_barrier(); pr_info("maple_tree: %u of %u tests passed\n", tests_passed, tests_run);