]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: WIP, error in delete path when allocations fail.
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Mon, 6 Jan 2020 18:39:36 +0000 (13:39 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 30 Oct 2020 18:56:55 +0000 (14:56 -0400)
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c
lib/test_maple_tree.c

index e322eb707405be1a55afcedda1661f66f584ae44..5640c8b3309c1086ce6a9c6035d6a038712a2ee3 100644 (file)
@@ -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;
index e59f7d6ea9d8b40a583b4631841a80eb3ee9c91c..ade52143846ace3637ae465c19e490c271068054 100644 (file)
@@ -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);