]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
spanning_ascend fixes
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Mon, 1 Sep 2025 06:07:05 +0000 (02:07 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Mon, 1 Sep 2025 06:07:05 +0000 (02:07 -0400)
fix gaps by moving sibling check earlier
fix node_finalise by making cp->end +1, was skipping last node
Continue if left and right meet (l_wr_mas->mas->noded == r_wr_mas..

Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
lib/maple_tree.c

index f4566e5d4ef9f7a095bd2d2af840f5ad521ca50b..90c080bb318b386346ba9ae0af8782fd758d8321 100644 (file)
@@ -3334,8 +3334,22 @@ static bool spanning_ascend(struct maple_copy *cp, struct ma_state *mas,
                struct ma_state *sib)
 {
        unsigned char d;
-       unsigned long min = l_wr_mas->mas->min;
+       unsigned long min;
+
+       printk("%s: %d\n", __func__, cp->d_count);
+
+       if (sib->end) {
+               printk("sib is at %p\n", sib->node);
+               if (sib->max < l_wr_mas->mas->min) {
+                       *l_wr_mas->mas = *sib;
+                       printk("Shift left\n");
+               } else {
+                       *r_wr_mas->mas = *sib;
+                       printk("Shift Right: %p\n", r_wr_mas->mas->node);
+               }
+       }
 
+       min = l_wr_mas->mas->min;
        for (d = 0; d < cp->d_count; d++) {
                struct maple_node *mn = cp->dst[d].node;
                enum maple_type mt = cp->dst[d].mt;
@@ -3345,34 +3359,26 @@ static bool spanning_ascend(struct maple_copy *cp, struct ma_state *mas,
                cp->slot[d] = mt_mk_node(mn, mt);
                cp->pivot[d] = max;
                printk("%p %lx - %lx\n", cp->slot[d], min, max);
-               if (ma_is_leaf(mt)) {
-                       cp->gap[d] = ma_leaf_max_gap(mn, mt, min, max,
-                                       ma_pivots(mn, mt), ma_slots(mn,mt));
-                       printk("New gap for %p = %lx\n", mn, cp->gap[d]);
-               } else {
-                       unsigned long *gaps = ma_gaps(mn, mt);
+               if (mt_is_alloc(mas->tree)) {
+                       if (ma_is_leaf(mt)) {
+                               cp->gap[d] = ma_leaf_max_gap(mn, mt, min, max,
+                                                    ma_pivots(mn, mt),
+                                                    ma_slots(mn,mt));
+                       } else {
+                               unsigned long *gaps = ma_gaps(mn, mt);
 
-                       if (gaps) {
-                               unsigned char gap_slot;
+                               if (gaps) {
+                                       unsigned char gap_slot;
 
-                               gap_slot = ma_meta_gap(mn);
-                               cp->gap[d] = gaps[gap_slot];
+                                       gap_slot = ma_meta_gap(mn);
+                                       cp->gap[d] = gaps[gap_slot];
+                               }
                        }
+                       printk("gap %lx\n", cp->gap[d]);
                }
                min = max + 1;
        }
 
-       if (sib->end) {
-               printk("sib is at %p\n", sib->node);
-               if (sib->max < l_wr_mas->mas->min) {
-                       *l_wr_mas->mas = *sib;
-                       printk("Shift left\n");
-               } else {
-                       *r_wr_mas->mas = *sib;
-                       printk("Shift Right: %p\n", r_wr_mas->mas->node);
-               }
-       }
-
        cp->end = cp->d_count - 1;
        cp->min = l_wr_mas->mas->min;
        cp->max = r_wr_mas->mas->max;
@@ -3391,12 +3397,12 @@ static bool spanning_ascend(struct maple_copy *cp, struct ma_state *mas,
                        spanning_init_cp_src(cp);
                        node_copy(mas, cp->src[0].node, 0, cp->data, cp->max, maple_copy,
                                  cp->dst[0].node, 0, mt);
-                       node_finalise(cp->dst[0].node, mt, cp->end);
+                       node_finalise(cp->dst[0].node, mt, cp->end + 1);
                        cp->slot[0] = mt_mk_node(cp->dst[0].node, mt);
                        cp->height++;
                }
 
-               printk("CONVERGED\n");
+               printk("CONVERGED d_count is %u\n", cp->d_count);
                WARN_ON_ONCE(cp->dst[0].node != mte_to_node(cp->slot[0]));
                cp->dst[0].node->parent = ma_parent_ptr(mas_tree_parent(mas));
                while (!mte_is_root(mas->node))
@@ -3404,10 +3410,12 @@ static bool spanning_ascend(struct maple_copy *cp, struct ma_state *mas,
                printk("parent %p vs %p\n", cp->dst[0].node->parent, mas_mn(mas)->parent);
                printk("cp->dst %p cp->slot %p\n", cp->dst[0].node, mte_to_node(cp->slot[0]));
                return false;
-       } else if (l_wr_mas->mas->node == r_wr_mas->mas->node){
+       } else if (l_wr_mas->mas->node == r_wr_mas->mas->node) {
+               /* Converged, but caused a cascading split. */
                WARN_ON_ONCE(cp->d_count != 1);
-               cp->dst[0].node->parent = mas_mn(mas)->parent;
-               return false;
+               printk("WARNING! CONVERGED d_count is %u\n", cp->d_count);
+               //cp->dst[0].node->parent = mas_mn(mas)->parent;
+               //return false;
        }
 
        printk("more nodes.. %u\n", cp->end);