]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
force span of null endings and rewind of sd fixed
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Fri, 23 May 2025 16:28:03 +0000 (12:28 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Fri, 23 May 2025 16:28:03 +0000 (12:28 -0400)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
lib/maple_tree.c

index 2076450e20bbdce8ceb07c88eae437b9cdee71e0..5c0986d0f52a1de1cdf0b332e8ac88568d8816da 100644 (file)
@@ -2620,6 +2620,7 @@ static inline void mas_topiary_replace(struct ma_state *mas,
                mas_topiary_node(mas, &tmp[i], in_rcu);
 
        mas_mat_destroy(mas, &subtrees);
+       printk("\n\n");
 }
 
 /*
@@ -3155,11 +3156,19 @@ void mns_node_part_span_leaf_init(struct ma_node_part *part,
                part->skip++;
        }
 
-       part->skip = wr_r->offset_end - wr_l->mas->offset + wr_l->mas->end + 1;
+       part->skip = wr_r->offset_end - wr_l->mas->offset + 1;
+       if (wr_r->node != wr_l->node)
+               part->skip += wr_l->mas->end;
        part->leaf = true;
-       printk("%s skip %u (%u - %u + %u + 1)\n", __func__, part->skip,
-              wr_r->offset_end, wr_l->mas->offset, wr_l->mas->end);
+
+       printk("%s skip %u (1 + %u - %u",__func__, part->skip,
+              wr_r->offset_end, wr_l->mas->offset);
+       if (wr_r->node != wr_l->node)
+               printk("+ %u + 1", wr_l->mas->end);
+
+       printk(")\n");
 }
+
 static inline
 void mni_node_part_init(struct ma_node_part *part,
                struct ma_node_info *left, struct ma_node_info *right)
@@ -3447,8 +3456,10 @@ 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->max != ULONG_MAX) {
+                       printk("offset %u is null\n", p->offset - 1);
                        BUG_ON(p->slots[p->offset - 1] == NULL);
+               }
        } else {
                unsigned long gap_off = 0;
                if (p->gaps) {
@@ -4969,6 +4980,7 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
        struct split_data sd;
        struct ma_node_part part;
        unsigned long min;
+       bool force_more = false;
 
        mas = wr_mas->mas;
        trace_ma_op(__func__, mas);
@@ -4986,7 +4998,6 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
                return mas_new_root(mas, wr_mas->entry);
 
        r_mas = *mas;
-       printk("r_wr_mas\n");
        r_mas.index = r_mas.last;
        mas_wr_walk_index(&r_wr_mas);
        if (!wr_mas->entry && r_mas.offset == r_mas.end) {
@@ -5027,6 +5038,11 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
        printk("wr_mas offset end is %u\n", wr_mas->offset_end);
        printk("src is %p slots is %p\n", right.node, right.slots);
        mns_node_part_span_leaf_init(&part, wr_mas, &r_wr_mas, &right);
+       if (wr_mas->node == r_wr_mas.node){
+               printk("FORCE DATA\n");
+               force_more = true;
+       }
+
        do {
                height++;
                d = s = 0;
@@ -5049,8 +5065,9 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
                 */
                /* Set up sources (up to 3) + part (always) */
                sd.new_end = mas->end - part.skip + 1 + part.size;
-               if (r_mas.node != mas->node)
+               if (r_mas.node != mas->node) {
                        sd.new_end += r_mas.end;
+               }
 
                printk("\tAt %p and r_mas %p\n", mas_mn(mas), mas_mn(&r_mas));
                printk("new end is %u (%u + %u - %u + 1 + %u)\n", sd.new_end,
@@ -5059,27 +5076,29 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
                mas_wr_ascend_init(mas, &parent);
                printk("ascend is %u (%u + %u - %u + 1 + %u)\n", sd.new_end,
                       r_mas.end, mas->end, part.skip, part.size);
-               if (sd.new_end < mt_min_slots[left.type] &&
-                   !ma_is_root(left.node) &&
-                   (left.min || right.max != ULONG_MAX)) {
+               if ((sd.new_end < mt_min_slots[left.type] &&
+                    !ma_is_root(left.node) &&
+                    (left.min || right.max != ULONG_MAX)) ||
+                   unlikely(force_more)) {
+                       force_more = false;
                        /* Take in more nodes */
                        printk("!!! %d min slots not met\n", __LINE__);
                        if (r_parent.insert_off < r_parent.end) {
                                src[2] = &other;
-                       printk("%d: set src %u\n", __LINE__, 2);
+                               printk("%d: set src %u\n", __LINE__, 2);
                                mas_next_node(&r_mas, r_parent.node, ULONG_MAX);
-                               other = r_parent;
-                               other.insert_off++;
                                r_parent.insert_off++;
+                               other = r_parent;
+                               printk("r_parent insert off is now %u\n",
+                                      r_parent.insert_off);
                                printk("Looks like there is a right sibling\n");
                        } else if (parent.insert_off) {
                                printk("%d: set src %u\n", __LINE__, s);
                                src[0] = &other;
                                s++;
                                mas_prev_node(mas, 0);
-                               other = parent;
-                               other.insert_off--;
                                parent.insert_off--;
+                               other = parent;
                                printk("Looks like there is a left sibling\n");
                        } else if (r_parent.max > ULONG_MAX) {
                        printk("%d: set src %u\n", __LINE__, 2);
@@ -5096,12 +5115,13 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
                                s++;
                                mas_prev_node(mas, 0);
                                mni_mas_init(&other, &r_mas);
-                               parent.offset--;
+                               parent.insert_off--;
                                printk("Looks like there is a left cousin\n");
                                BUG_ON(1);
                        }
 
                        mni_descend(&other);
+                       printk("descended other into %p with end %u\n", other.node, other.end);
                        sd.new_end += other.end + 1;
                        printk("new end is now %u\n", sd.new_end);
                }
@@ -5170,16 +5190,22 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
                        unsigned char max = limits[d] + 1 - sd.offset;
 
                        printk("limits is %u/%u\n", limits[d], sd.offset);
-                       printk("pass dst %p\n", &dst[d]);
+                       printk("pass %u dst %p (%p)\n", d, &dst[d], dst[d].node);
                        spanning_append(&sd, src[s], &dst[d], max);
                        /* destination full */
+                       printk("offset %u > %u\n", sd.offset, limits[d]);
                        if (sd.offset > limits[d]) {
                                /* Check NULL.. */
                                if (ma_is_leaf(src[s]->type)
                                    && mns_ends_in_null(&sd.states[sd.len - 1])) {
-                                       sd.states[sd.len - 1].size--;
+                                       printk("\tnull correction\n");
+                                       if (sd.states[sd.len - 1].size > 1)
+                                               sd.states[sd.len - 1].size--;
+                                       else
+                                               sd.len--;
                                        limits[d]--;
                                        sd.offset--;
+                                       src[s]->offset--;
                                }
                                dst[d].max = src[s]->pivots[src[s]->offset - 1];
                                dst[d].offset = 0;
@@ -8971,14 +8997,15 @@ void mt_validate(struct maple_tree *mt)
                mas_descend(&mas);
 
        while (!mas_is_overflow(&mas)) {
+               if (mte_dead_node(mas.node))
+                       printk("DEAD NODE! %p\n", mte_to_node(mas.node));
                MAS_WARN_ON(&mas, mte_dead_node(mas.node));
                end = mas_data_end(&mas);
-               if (end < mt_min_slot_count(mas.node) &&
-                               (mas.max != ULONG_MAX))
+               if (!mte_is_root(mas.node) && (end < mt_min_slot_count(mas.node)))
                pr_err("Invalid size %u of " PTR_FMT "\n",
                       end, mas_mn(&mas));
-               if (MAS_WARN_ON(&mas, (end < mt_min_slot_count(mas.node)) &&
-                               (!mte_is_root(mas.node)))) {
+               if (!mte_is_root(mas.node) &&
+                    MAS_WARN_ON(&mas, (end < mt_min_slot_count(mas.node)))) {
                        pr_err("Invalid size %u of " PTR_FMT "\n",
                               end, mas_mn(&mas));
                }