]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
still issues
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Tue, 6 May 2025 14:45:41 +0000 (10:45 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Tue, 6 May 2025 14:45:41 +0000 (10:45 -0400)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
lib/maple_tree.c
lib/test_maple_tree.c
tools/testing/radix-tree/maple.c

index 39a35f764e945546cd6d991aeb24934a6539dc1f..de0d21ee651da4ec20855ab878398cfeaca1df95 100644 (file)
@@ -3129,7 +3129,6 @@ struct ma_node_info {
        unsigned char end;
        unsigned char insert_off;
        unsigned char offset; /* Operating position */
-       bool is_alloc;
 };
 
 struct ma_node_state {
@@ -3159,20 +3158,24 @@ void mns_node_part_leaf_init(struct ma_node_part *part,
        if (wr_mas->r_min < wr_mas->mas->index) {
                part->pivots[0] = wr_mas->mas->index - 1;
                part->slots[0] = wr_mas->content;
+       printk("%s zero piv is %lu\n", __func__,part->pivots[part->size]);
                part->size++;
        }
 
        part->pivots[part->size] = wr_mas->mas->last;
        part->slots[part->size] = wr_mas->entry;
+       printk("%s one piv is %lu\n", __func__,part->pivots[part->size]);
        part->size++;
 
        if (wr_mas->end_piv > wr_mas->mas->last) {
                part->pivots[part->size] = wr_mas->end_piv;
                part->slots[part->size] = src->slots[wr_mas->offset_end];
+               printk("%s last piv is %lx\n", __func__,part->pivots[part->size]);
                part->size++;
        }
 
        part->skip = wr_mas->offset_end - wr_mas->mas->offset + 1;
+       printk("skip %u\n", part->skip);
        part->leaf = true;
 }
 
@@ -3208,7 +3211,6 @@ void _mni_node_init(struct ma_node_info *mni, struct maple_node *node,
        mni->slots = ma_slots(node, type);
        mni->pivots = ma_pivots(node, type);
        mni->gaps = ma_gaps(node, type);
-       mni->is_alloc = false;
 }
 
 static inline
@@ -3371,17 +3373,39 @@ void mni_cp(struct ma_node_info *src, struct ma_node_info *dst,
        src->offset += len;
 }
 
+struct split_data {
+       /*
+        * Used to split the data between two nodes.
+        * The user of this struct, mt_wr_split_data(), must keep track of the
+        * offset into the entire data (up to two nodes worth), so that the
+        * insert can be placed in the correct place while the source data that
+        * is overwritten is skipped.
+        */
+       unsigned char offset;   /* Offset into destination data (entire set) */
+       unsigned char space;    /* The space left in the current destination node */
+       unsigned char split;    /* Proposed split of data */
+       unsigned char insert;   /* Insert location of destination */
+       unsigned char insert_end;/* Insert end location of destination */
+       unsigned char new_end;  /* Total data  */
+       unsigned char src_ins_end; /* Offset into source data where the write ends */
+       unsigned char len;      /* Number of ma_node_states in the states array */
+       struct ma_node_state states[5];
+       bool is_alloc;
+};
+
 /*
  *
  * Zero any area that needs to be zeroed and set the metadata.
  * metadata needs the largest gap for non-leaves.
  */
 static __always_inline
-void mni_finalise(struct ma_node_info *p)
+void mni_finalise(struct ma_node_info *p, struct split_data *sd)
 {
        unsigned long max_gap;
        unsigned char len;
 
+       if (!sd->is_alloc)
+               printk("\n\n\nNOT ALLOC\n\n\n");
        len = mt_slots[p->type] - p->offset;
        if (len) {
                memset(p->slots + p->offset, 0, len * sizeof(void *));
@@ -3399,7 +3423,7 @@ void mni_finalise(struct ma_node_info *p)
                unsigned long *pivs;
                void **slots;
 
-               if (!p->is_alloc)
+               if (!sd->is_alloc)
                        goto finalise_leaf;
                i = 0;
                offset = p->offset - 2;
@@ -3445,6 +3469,13 @@ finalise_leaf:
                if (p->offset <= mt_pivots[p->type]) {
                        ma_set_meta(p->node, p->type, 0, p->offset - 1);
                }
+               if (p->max != ULONG_MAX) {
+                       if (p->slots[p->offset - 1] == NULL) {
+                               printk("last slot %u has %lu\n", p->offset - 1,
+                                      p->pivots[p->offset - 1]);
+                       }
+                       BUG_ON(p->slots[p->offset - 1] == NULL);
+               }
        } else {
                unsigned long gap_off = 0;
                if (p->gaps) {
@@ -3553,6 +3584,8 @@ void mns_assemble(struct ma_node_state *states, unsigned char len)
                if (last_dst != ns->dst) {
                        WARN_ON_ONCE(!max);
                        ns->dst->min = max + 1;
+                       printk("%p max set to %lu\n", last_dst->node, last_dst->max);
+                       printk("%p min set to %lu\n", ns->dst->node, ns->dst->min);
                }
                last_dst = ns->dst;
 
@@ -3584,7 +3617,9 @@ void mns_assemble(struct ma_node_state *states, unsigned char len)
                        if (ns->start + size > mt_pivots[ns->info->type]) {
                                piv_overflow = 1;
                                max = ns->info->max;
+                               printk("max fro ns->info->max\n");
                        } else {
+                               printk("max from %lu\n", size - 1 );
                                max = s_piv[size - 1];
                        }
                }
@@ -3609,25 +3644,6 @@ void mns_assemble(struct ma_node_state *states, unsigned char len)
        }
 }
 
-struct split_data {
-       /*
-        * Used to split the data between two nodes.
-        * The user of this struct, mt_wr_split_data(), must keep track of the
-        * offset into the entire data (up to two nodes worth), so that the
-        * insert can be placed in the correct place while the source data that
-        * is overwritten is skipped.
-        */
-       unsigned char offset;   /* Offset into destination data (entire set) */
-       unsigned char space;    /* The space left in the current destination node */
-       unsigned char split;    /* Proposed split of data */
-       unsigned char insert;   /* Insert location of destination */
-       unsigned char insert_end;/* Insert end location of destination */
-       unsigned char new_end;  /* Total data  */
-       unsigned char src_ins_end; /* Offset into source data where the write ends */
-       unsigned char len;      /* Number of ma_node_states in the states array */
-       struct ma_node_state states[5];
-};
-
 static inline void mas_wr_converged(struct ma_node_info *src,
                struct ma_node_info *dst, struct ma_node_part *part,
                struct ma_state *mas, struct split_data *sd)
@@ -3661,7 +3677,7 @@ static inline void mas_wr_converged(struct ma_node_info *src,
 
        mns_assemble(sd->states, sd->len);
        dst->node->parent = src->node->parent;
-       mni_finalise(dst);
+       mni_finalise(dst, sd);
 }
 
 /*
@@ -3685,10 +3701,12 @@ static void split_state_setup(struct ma_node_info *src,
                copied = min(part->size - part->pos, sd->space);
                state->part = part;
                printk("insert part at %u first entry is %p\n", sd->offset, part->slots[0]);
+               printk("Size is %u/%u\n", copied, part->size);
                mns_mni_init(state, dst, part->pos , copied);
                state->use_part = true;
                part->pos += copied;
                src->offset = sd->src_ins_end + 1;
+               printk("Set src %p offset to %u\n", src->node, src->offset);
        } else {
                state->info = src;
                if (sd->offset < sd->insert_end) {
@@ -3696,11 +3714,14 @@ static void split_state_setup(struct ma_node_info *src,
                         * First part of node, may split across node
                         * boundaries though
                         */
+                       printk("%d\n", __LINE__);
                        copied = min(sd->space, sd->insert - sd->offset);
                } else {
+                       printk("%d\n", __LINE__);
                        copied = min(sd->space, (src->end - src->offset + 1));
                }
                BUG_ON(copied == 0);
+               printk("src offset is %u\n", src->offset);
                mns_mni_init(state, dst, src->offset, copied);
                src->offset += copied;
        }
@@ -3912,8 +3933,8 @@ bool mas_wr_try_rebalance(struct ma_state *mas, struct ma_node_info *src,
        }
 
        mns_assemble(sd->states, sd->len);
-       mni_finalise(left);
-       mni_finalise(right);
+       mni_finalise(left, sd);
+       mni_finalise(right, sd);
        mni_node_part_init(part, left, right);
        mas_ascend(mas);
        mas->end = parent.end;
@@ -3939,8 +3960,9 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas,
                bool left_store)
 {
        struct ma_node_info *dst;
+       struct ma_node_state *state;
 
-       printk("\t\t%s\n", __func__);
+       printk("\t\t%s \n", __func__);
        sd->insert_end = sd->insert + part->size - 1;
        if (!left_store) {
                char len;
@@ -3950,25 +3972,33 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas,
                 * the right node
                 */
                printk("store is in right\n");
+               state = &sd->states[sd->len];
                left->min = src2->min;
                right->max = src->max;
                sd->offset = src2->end + 1;
-               sd->split++;
-               sd->states[sd->len].info = src2;
+               state->info = src2;
                printk("cp from %p\n", src2->node);
                /* The first state to copy is the left node */
-               printk("cp to left %u-%u\n", 0, sd->split);
-               mns_mni_init(&sd->states[sd->len], left, 0, sd->split);
+               printk("cp to left %u+%u\n", 0, sd->split);
+               mns_mni_init(state, left, 0, sd->split);
+               if (ma_is_leaf(src->type) && mns_ends_in_null(state)) {
+                       printk("ends in null\n");
+                       sd->split--;
+                       state->size--;
+                       printk("NEW cp to left %u-%u\n", 0, sd->split);
+               }
                sd->len++;
 
                /* Copy the remainder of the left to the start of the right */
                len = src2->end + 1 - sd->split;
                sd->states[sd->len].info = src2;
                mns_mni_init(&sd->states[sd->len], right, sd->split, len);
-               printk("cp to right %u-%u\n", sd->split, len);
+               printk("cp to right %u-%u (%u + 1 - %u\n", sd->split, len, src2->end, sd->split);
                sd->len++;
                sd->space = mt_slots[right->type];
                dst = right;
+               printk("src ins end is %u\n", wr_mas->offset_end);
+               printk("\n");
        } else {
                printk("store left\n");
                sd->space = sd->split;
@@ -3990,23 +4020,42 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas,
        if (left_store) {
                char len;
 
+               if (sd->offset >= sd->insert && sd->offset <= sd->insert_end)
+                       printk("BING\n");
+
+               state = &sd->states[sd->len];
                sd->split = (sd->new_end + 1) / 2;
                printk("sd is at offset %u splut %u\n", sd->offset, sd->split);
                len = sd->split - sd->offset;
-               sd->states[sd->len].info = src2;
+               state->info = src2;
                printk("cp right->%u + %u to left\n", 0, len);
-               mns_mni_init(&sd->states[sd->len], left, 0, len);
-               sd->len++;
+               mns_mni_init(state, left, 0, len);
+               if (ma_is_leaf(src->type) && mns_ends_in_null(state)) {
+                       printk("ends in null\n");
+                       sd->split--;
+                       sd->offset--;
+                       sd->space++;
+                       state->size--;
+                       len--;
+               }
+
+               printk("state %d: cp %p[%u] + %u to %s\n", sd->len, src->node,
+                      sd->states[sd->len].start,
+                      sd->states[sd->len].size, dst == left ? "left" : "right");
                printk("cp the right->to right->%u + %u\n", len, src2->end + 1);
+               sd->len++;
                /* Stored to the left, copy the last of the right->in src2 */
                sd->states[sd->len].info = src2;
                mns_mni_init(&sd->states[sd->len], right, len, src2->end + 1 - len);
+               printk("state %d: cp %p[%u] + %u to %s\n", sd->len, src->node,
+                      sd->states[sd->len].start,
+                      sd->states[sd->len].size, dst == left ? "left" : "right");
                sd->len++;
        }
 
        mns_assemble(sd->states, sd->len);
-       mni_finalise(left);
-       mni_finalise(right);
+       mni_finalise(left, sd);
+       mni_finalise(right, sd);
        mni_node_part_init(part, left, right);
        part->skip = 2;
 }
@@ -4057,7 +4106,7 @@ static void mas_wr_rebalance_reduce(struct ma_wr_state *wr_mas,
        }
 
        mns_assemble(sd->states, sd->len);
-       mni_finalise(left);
+       mni_finalise(left, sd);
        mni_node_part_init(part, left, NULL);
        part->skip = 2;
 }
@@ -4084,21 +4133,26 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas)
         */
        mt_dump(mas->tree, mt_dump_dec);
        printk("Rebalance %p offset %u - %u\n", mas->node, mas->offset, wr_mas->offset_end);
-       printk("Store %lu - %lu\n", mas->index, mas->last);
+       printk("Store %p %lu - %lu\n", wr_mas->entry, mas->index, mas->last);
 
        height = mas_mt_height(mas);
 
        mni_mas_init(&src, mas);
        src.end = mas->end;
 
+       printk("HERE\n");
        mns_node_part_leaf_init(&part, wr_mas, &src);
        sd.new_end = mas->end + part.size - part.skip + 1;
        sd.src_ins_end = wr_mas->offset_end;
        sd.len = 0;
 
        mni_node_init(&left, mas_pop_node(mas), wr_mas->type);
+       printk("left is %p\n", left.node);
        if (mt_is_alloc(mas->tree))
-               left.is_alloc = true;
+               sd.is_alloc = true;
+       else
+               sd.is_alloc = false;
+
        do {
                printk("\tloop\n");
                tmp_mas = *mas;
@@ -4121,33 +4175,31 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas)
 
                printk("rebalance %p %p\n", src.node, src2.node);
                sd.new_end += src2.end + 1;
+               printk("new end %u\n", sd.new_end);
                if (sd.new_end < mt_min_slots[left.type]) {
                        printk("Not enough tdata\n");
                        exit(0);
                }
-               if (sd.split < mt_min_slots[left.type]) {
-                       printk("Too small split\n");
-                       exit(0);
-               }
+               printk("Total data is %u\n", sd.new_end);
+               printk("sd insert is %u\n", sd.insert);
+               if (sd.new_end >= mt_slots[left.type]) {
                if (sd.new_end - sd.split < mt_min_slots[left.type]) {
                        printk("Too big split\n");
                        exit(0);
                }
-               printk("Total data is %u\n", sd.new_end);
-               printk("sd insert is %u\n", sd.insert);
-               if (sd.new_end >= mt_slots[left.type]) {
                        mni_node_init(&right, mas_pop_node(mas), mte_node_type(mas->node));
+                       printk("right is %p\n", right.node);
+       printk("%s end with %lu - %lu\n", __func__, mas->index, mas->last);
                        mas_wr_rebalance_two(wr_mas, &left, &right, &src, &src2, &part, &sd, left_store);
                        mas_ascend(mas);
                        mas->end = parent.end;
                        mas->offset = parent.insert_off;
-                       printk("Replacing 2 nodes, break\n");
+                       printk("Replacing 2 nodes (%d), break\n", sd.new_end);
                        printk("mas is %p\n", mas->node);
                        break;
                }
 
                printk("REDUCE %p %p\n", src.node, src2.node);
-               sd.split = 255;
                mas_wr_rebalance_reduce(wr_mas, &left, &src, &src2, &part, &sd, left_store);
 
                /* Must go again */
@@ -4189,7 +4241,7 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas)
 
        mas_wr_converged(&parent, &new_parent, &part, mas, &sd);
        src.enode = parent.enode;
-       printk("Replace %p with %p\n", parent.node, new_parent.enode);
+       printk("Replace %p with %p\n", parent.node, mte_to_node(new_parent.enode));
        mas->node = new_parent.enode;
 new_root:
        mas_wmb_replace(mas, src.enode);
@@ -4220,7 +4272,9 @@ static void mas_wr_split(struct ma_wr_state *wr_mas)
        mni_node_init(&right, mas_pop_node(mas), wr_mas->type);
 
        if (mt_is_alloc(mas->tree))
-               right.is_alloc = left.is_alloc = true;
+               sd.is_alloc = true;
+       else
+               sd.is_alloc = false;
 
        mns_node_part_leaf_init(&part, wr_mas, &src);
        sd.new_end = mas->end + part.size; /* - skip + 1 */
@@ -4240,8 +4294,8 @@ static void mas_wr_split(struct ma_wr_state *wr_mas)
 
        mt_wr_split_data(&src, &left, &right, &part, &sd);
        mns_assemble(sd.states, sd.len);
-       mni_finalise(&left);
-       mni_finalise(&right);
+       mni_finalise(&left, &sd);
+       mni_finalise(&right, &sd);
 
        if (height == 1)
                goto new_root;
@@ -4272,8 +4326,8 @@ static void mas_wr_split(struct ma_wr_state *wr_mas)
 
                mt_wr_split_data(&src, &left, &right, &part, &sd);
                mns_assemble(sd.states, sd.len);
-               mni_finalise(&left);
-               mni_finalise(&right);
+               mni_finalise(&left, &sd);
+               mni_finalise(&right, &sd);
        }
 
 new_root:
index db6fe093f711c285b10a209b61d6ce44ac044fec..5d0a95b328c98d164036272055befc74263d371f 100644 (file)
@@ -2630,6 +2630,7 @@ static noinline void __init check_fuzzer(struct maple_tree *mt)
        mtree_test_load(mt, 1);
        mtree_test_store_range(mt, 1, 22, (void *)0x3);
        mtree_test_insert(mt, 1, (void *)0x3);
+       mt_dump(mt, mt_dump_dec);
        mtree_test_erase(mt, 1);
        mtree_test_load(mt, 53);
        mtree_test_load(mt, 1);
index 7b58ca3cd18f53c9c79e5c0a7dec8ae99c28e2bb..ad89fce347360a67e4c8cb654b1d759c6572a96c 100644 (file)
@@ -27,7 +27,7 @@
 #include "../../../lib/test_maple_tree.c"
 
 #define RCU_RANGE_COUNT 1000
-#define RCU_MT_BUG_ON(test, y) {if (y) { test->stop = true; } MT_BUG_ON(test->mt, y); }
+#define RCU_MT_BUG_ON(_test, _y) {if (_y) { {if (_test->stop != true) MT_BUG_ON(_test->mt, _y);} _test->stop = true; }}
 
 struct rcu_test_struct2 {
        struct maple_tree *mt;
@@ -725,8 +725,11 @@ static noinline void __init check_erase_testset(struct maple_tree *mt)
 
        /* Shrinking tree test. */
 
-       for (int i = 13; i < ARRAY_SIZE(set); i++)
+       for (int i = 13; i < ARRAY_SIZE(set); i++) {
+               mt_dump(mt, mt_dump_dec);
+               printk("STORE %lu -> %p\n", set[i], entry[i%2]);
                erase_check_insert(mt, i);
+       }
 
        mt_set_non_kernel(99);
        for (int i = 18; i < ARRAY_SIZE(set); i++) {
@@ -34379,6 +34382,7 @@ static void *rcu_reader_fwd(void *ptr)
        bool toggled, modified, deleted, added;
        int i;
        void *entry, *prev = NULL;
+       struct maple_node *p_node = NULL;
        MA_STATE(mas, test->mt, 0, 0);
 
        rcu_reader_register(test);
@@ -34427,7 +34431,18 @@ static void *rcu_reader_fwd(void *ptr)
                                }
                        }
 
+                       if (mas.index != r_start) {
+                               alt = xa_mk_value(index + i * 2 + 1 +
+                                                 RCU_RANGE_COUNT);
+                               printk("Error: mas %p %lu-%lu %p != %lu-%lu %p %p line %d i %d, pnode %p\n",
+                                      mte_to_node(mas.node), mas.index, mas.last, entry,
+                                      r_start, r_end, expected, alt,
+                                      __LINE__, i, p_node);
+                       }
                        RCU_MT_BUG_ON(test, mas.index != r_start);
+                       if (mas.last != r_end) {
+                               printk("last is wrong: %lx vs %lx\n", mas.last, r_end);
+                       }
                        RCU_MT_BUG_ON(test, mas.last != r_end);
 
                        if (i == reader->flip) {
@@ -34472,6 +34487,7 @@ static void *rcu_reader_fwd(void *ptr)
                        }
 
                        i++;
+                       p_node = mte_to_node(mas.node);
                }
                rcu_read_unlock();
                usleep(test->pause);
@@ -34552,8 +34568,8 @@ static void *rcu_reader_rev(void *ptr)
                                alt = xa_mk_value(index + i * 2 + 1 +
                                                  RCU_RANGE_COUNT);
                                mt_dump(test->mt, mt_dump_dec);
-                               printk("Error: %lu-%lu %p != %lu-%lu %p %p line %d i %d\n",
-                                      mas.index, mas.last, entry,
+                               printk("Error: mas %p %lu-%lu %p != %lu-%lu %p %p line %d i %d\n",
+                                      mas.node, mas.index, mas.last, entry,
                                       r_start, r_end, expected, alt,
                                       line, i);
                        }
@@ -36367,7 +36383,7 @@ void farmer_tests(void)
        struct maple_node *node;
        DEFINE_MTREE(tree);
 
-       //goto skip;
+       goto skip;
        mt_dump(&tree, mt_dump_dec);
 
        mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | MT_FLAGS_USE_RCU);
@@ -36424,8 +36440,8 @@ void farmer_tests(void)
        check_mtree_dup(&tree);
        mtree_destroy(&tree);
 
-skip:
        /* RCU testing */
+skip:
        mt_init_flags(&tree, 0);
        check_erase_testset(&tree);
        mtree_destroy(&tree);
@@ -36542,10 +36558,10 @@ static void regression_tests(void)
 
 void maple_tree_tests(void)
 {
-       maple_tree_seed();
-       maple_tree_harvest();
+       //maple_tree_seed();
+       //maple_tree_harvest();
 #if !defined(BENCH)
-       regression_tests();
+       //regression_tests();
        farmer_tests();
 #endif
 }