]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
try to honor min height calc
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 3 Sep 2025 01:16:48 +0000 (21:16 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 3 Sep 2025 01:16:48 +0000 (21:16 -0400)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
include/linux/maple_tree.h
lib/maple_tree.c
lib/test_maple_tree.c

index eb8f55d139b8f9de4d62f5f4dd1c7a81e3a6a3eb..5e225e40b653afc0aabbd1828c3e103fac75e53f 100644 (file)
@@ -666,6 +666,7 @@ void mt_cache_shrink(void);
                pr_info("BUG at %s:%d (%u)\n",                          \
                __func__, __LINE__, __x);                               \
                mt_dump(__tree, mt_dump_hex);                           \
+               fflush(stdout);\
                pr_info("Pass: %u Run:%u\n",                            \
                        atomic_read(&maple_tree_tests_passed),          \
                        atomic_read(&maple_tree_tests_run));            \
@@ -682,6 +683,7 @@ void mt_cache_shrink(void);
                __func__, __LINE__, __x);                               \
                mas_dump(__mas);                                        \
                mt_dump((__mas)->tree, mt_dump_hex);                    \
+               fflush(stdout);\
                pr_info("Pass: %u Run:%u\n",                            \
                        atomic_read(&maple_tree_tests_passed),          \
                        atomic_read(&maple_tree_tests_run));            \
@@ -699,6 +701,7 @@ void mt_cache_shrink(void);
                mas_wr_dump(__wrmas);                                   \
                mas_dump((__wrmas)->mas);                               \
                mt_dump((__wrmas)->mas->tree, mt_dump_hex);             \
+               fflush(stdout);\
                pr_info("Pass: %u Run:%u\n",                            \
                        atomic_read(&maple_tree_tests_passed),          \
                        atomic_read(&maple_tree_tests_run));            \
index ed546a9236c2ce2dfe6ce1f1aff589ec90fd9d91..dd8f6596b3532bd06f24773a85c58aa538d95bfe 100644 (file)
@@ -1170,6 +1170,10 @@ static inline struct maple_node *mas_pop_node(struct ma_state *mas)
        unsigned int req = mas_alloc_req(mas);
 
        /* nothing or a request pending. */
+       if (!total) {
+               printk("Ran out of nodes\n");
+               mt_dump(mas->tree, mt_dump_hex);
+       }
        if (WARN_ON(!total))
                return NULL;
 
@@ -1822,6 +1826,7 @@ static inline bool mas_find_child(struct ma_state *mas, struct ma_state *child)
        end = ma_data_end(node, mt, pivots, mas->max);
        for (offset = mas->offset; offset <= end; offset++) {
                entry = mas_slot_locked(mas, slots, offset);
+               printk("entry %p at offset %u\n", entry, offset);
                if (mte_parent(entry) == node) {
                        *child = *mas;
                        mas->offset = offset + 1;
@@ -2907,10 +2912,12 @@ unsigned long node_copy(struct ma_state *mas, struct maple_node *src,
 
 
 
+       printk("d_start = %u on %u\n", d_start, d_mt);
        d_slots = ma_slots(dst, d_mt) + d_start;
        d_pivots = ma_pivots(dst, d_mt) + d_start;
        s_slots = ma_slots(src, s_mt) + start;
        s_pivots = ma_pivots(src, s_mt) + start;
+       fflush(stdout);
        memcpy(d_slots, s_slots, size * sizeof(void __rcu*));
        if (!ma_is_leaf(d_mt) && s_mt == maple_copy) {
                struct maple_enode *edst = mt_mk_node(dst, d_mt);
@@ -2999,6 +3006,9 @@ static inline void spanning_leaf_init(struct maple_copy *cp,
 {
        unsigned char end = 0;
 
+       printk("write %lx - %lx => %p\n", mas->index, mas->last, l_wr_mas->entry);
+       printk("l %p[%u] r %p[%u]\n", l_wr_mas->node, l_wr_mas->mas->offset - 1,
+              r_wr_mas->node, r_wr_mas->mas->offset + 1);
        /* Create entries to insert including split entries to left and right */
        if (l_wr_mas->r_min < mas->index) {
                cp->slot[0] = l_wr_mas->content;
@@ -3041,16 +3051,20 @@ static inline void spanning_data_calc(struct maple_copy *cp,
 
        /* Add 1 every time for the 0th element */
        cp->data = l_wr_mas->mas->offset;
+       printk("%d %d\n", __LINE__, cp->data);
 
        cp->data += cp->end + 1;
+       printk("%d %d\n", __LINE__, cp->data);
 
        /* Data from right (offset + 1 to end), +1 for zero */
        cp->data += r_wr_mas->mas->end - r_wr_mas->mas->offset;
+       printk("%d %d\n", __LINE__, cp->data);
 
        if (((l_wr_mas->mas->min != 0) || (r_wr_mas->mas->max != ULONG_MAX)) &&
            (cp->data <= mt_min_slots[l_wr_mas->type])) {
                mas_spanning_move(l_wr_mas, r_wr_mas, sib);
                cp->data += sib->end + 1;
+       printk("%d %d\n", __LINE__, cp->data);
        } else {
                sib->end = 0;
        }
@@ -3061,22 +3075,72 @@ static inline
 void spanning_split_dest_setup(struct maple_copy *cp, struct ma_state *mas,
                enum maple_type mt)
 {
-       cp->d_count = 0;
-       /* Calc split here; cp->data is not 0 indexed */
-       if (cp->data < mt_slots[mt]) {
+       /* Data is 1 indexed, every src has +1 added.  */
+
+       if (cp->data <= mt_slots[mt]) {
                cp->split = cp->data;
                cp->d_count = 1;
-       } else if (cp->data < mt_slots[mt] * 2 - 1) {
-               cp->split = (cp->data + 1) / 2;
-               cp->d_count = 2;
-       }  else {
-               cp->split = (cp->data + 2) / 3;
-               cp->d_count = 3;
+               goto node_setup;
        }
 
+       cp->split = cp->data / 2;
+       cp->d_count = 2;
+       if (cp->data < mt_slots[mt] * 2) {
+               unsigned char off;
+               unsigned char s;
+
+               if (!ma_is_leaf(mt))
+                       goto node_setup;
+
+#if 1
+
+               /*
+                * Leaf nodes are a bit tricky because we cannot assume the data
+                * can fit due to the NULL limitation on node ends.
+                */
+               off = cp->split;;
+               printk("start %u\n", off);
+               for (s = 0; s < cp->s_count; s++) {
+                       unsigned char s_off;
+
+                       s_off = cp->src[s].end - cp->src[s].start;
+                       printk("%u size %u\n", s, s_off);
+                       if (s)
+                               off--;
+                       if (s_off >= off) {
+                               printk("s_off fits\n");
+                               break;
+                       }
+                       off -= s_off;
+                       printk("offset %u\n", off);
+               }
+               off += cp->src[s].start;
+               printk("CHECK %p[%u]\n", cp->src[s].node, off);
+               mt_dump(mas->tree, mt_dump_hex);
+               fflush(stdout);
+               if (ma_slots(cp->src[s].node, cp->src[s].mt)[off]) {
+                       printk("src %u slot %u is not NULL\n", s, off);
+                       goto node_setup;
+               } else
+                       printk("src %u slot %u IS NULL\n", s, off);
+
+               cp->split++;
+               printk("set split to %u\n", cp->split);
+               if (cp->split < mt_slots[mt])
+                       goto node_setup;
+
+       }
+#endif
+       /* No other choice but to 3-way split the data */
+       cp->split = (cp->data + 2) / 3;
+       cp->d_count = 3;
+
+node_setup:
+       printk("data %u split %u d_count %u type %u\n", cp->data, cp->split, cp->d_count, mt);
        for (int i = 0; i < cp->d_count; i++) {
                cp->dst[i].mt = mt;
                cp->dst[i].node = ma_mnode_ptr(mas_pop_node(mas));
+               printk("%d type %u ptr %p\n", i, mt, cp->dst[i].node);
        }
 }
 
@@ -3122,7 +3186,7 @@ void spanning_split_src_setup(struct maple_copy *cp, struct ma_state *mas,
                append_node_cp(cp, sib, 0, sib->end);
 }
 
-static inline
+//static inline
 void spanning_data_write(struct maple_copy *cp, struct ma_state *mas)
 {
        struct maple_node *dst, *src;
@@ -3133,8 +3197,8 @@ void spanning_data_write(struct maple_copy *cp, struct ma_state *mas)
        unsigned char split, next_node, size;
        unsigned long s_max;
        enum maple_type s_mt, d_mt;
-       int debug = 0;
 
+       printk("\n\n%s\n", __func__);
        s = d = 0;
        /* Readability help */
        src = cp->src[s].node;
@@ -3154,18 +3218,27 @@ void spanning_data_write(struct maple_copy *cp, struct ma_state *mas)
         * size (and split, and next_node will be 1 indexed while
         * src start/end dst start/end are 0 indexed
         */
+       printk("MAX src %u dst %u\n", cp->s_count, cp->d_count);
        do {
                do {
-                       debug++;
-                       BUG_ON(debug > 8);
-                       size = next_node - data_offset;
+                       printk("%u - %u + 1\n", next_node, data_offset);
+                       size = next_node - data_offset + 1;
                        /* Fill the destination */
-                       if (src_end - s_offset + 1 < size)
+                       printk("src end %u s_off %u size %u\n", src_end, s_offset, size);
+                       if (src_end - s_offset + 1 < size) {
                                size = src_end - s_offset + 1;
+                               printk("%d: %u %u %u\n", __LINE__, size, split, dst_offset);
+                       }
 
-                       if (split - dst_offset + 1 < size)
+                       printk("splut %u d_off %u size %u\n", split , dst_offset, size);
+                       if (split - dst_offset + 1 < size) {
                                size = split - dst_offset + 1;
+                               printk("%d: %u %u %u\n", __LINE__, size, split, dst_offset);
+                       }
 
+                       printk("Size is %u\n", size);
+                       printk("src %u dst %u\n", s, d);
+                       printk("src node %p to %p\n", src, dst);
                        node_copy(mas, src, s_offset, size, s_max, s_mt, dst,
                                  dst_offset, d_mt);
                        data_offset += size;
@@ -3187,22 +3260,26 @@ void spanning_data_write(struct maple_copy *cp, struct ma_state *mas)
                                s_max = cp->src[s].max;
                                s_mt = cp->src[s].mt;
                        }
-               } while (data_offset < next_node);
+               } while (data_offset <= next_node);
 
                next_node *= 2;
                if (next_node > data + 1)
                        next_node = data + 1;
 
                split = cp->split;
-               /* Handle null entries */
                if (dst_offset <= mt_pivots[d_mt]) {
                        cp->dst[d].max = ma_pivots(dst, d_mt)[dst_offset - 1];
                } else {
-                       cp->dst[d].max = s_max;
+                       cp->dst[d].max = ma_pivots(src, s_mt)[s_offset - 1];
                }
 
+               /* Handle null entries */
                if (cp->dst[d].max != ULONG_MAX &&
                    !ma_slots(dst, d_mt)[dst_offset - 1]) {
+                       printk("%p slot %u is nul!!\n", dst, dst_offset - 1);
+                       printk("src is %p[%u]\n", src, s_offset - 1);
+                       fflush(stdout);
+                       BUG_ON(cp->d_count == 2);
                        if (s_offset == cp->src[s].start) {
                                s--;
                                src = cp->src[s].node;
@@ -3226,11 +3303,13 @@ void spanning_data_write(struct maple_copy *cp, struct ma_state *mas)
                        return;
                }
                /* Reset local dst */
+               printk("Switch dst at %d\n", cp->d_count);
                ++d;
                dst = cp->dst[d].node;
                d_mt = cp->dst[d].mt;
                dst_offset = 0;
        } while (data_offset <= data);
+       BUG_ON(1);
 }
 
 
@@ -3297,7 +3376,6 @@ static bool spanning_ascend(struct maple_copy *cp, struct ma_state *mas,
                        cp->slot[0] = mt_mk_node(cp->dst[0].node, mt);
                        cp->height++;
                }
-
                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))
@@ -3306,15 +3384,16 @@ static bool spanning_ascend(struct maple_copy *cp, struct ma_state *mas,
        } else if (l_wr_mas->mas->node == r_wr_mas->mas->node) {
                /* Converged, but caused a cascading split. */
                if (cp->d_count != 1) {
-                       mt_dump(mas->tree, mt_dump_hex);
-                       printk("At %p\n", l_wr_mas->mas->node);
-                       printk("Writing %lx -%lx => %p\n", mas->index, mas->last, l_wr_mas->entry);
+                       //mt_dump(mas->tree, mt_dump_hex);
+                       //printk("At %p\n", l_wr_mas->mas->node);
+                       //printk("Writing %lx -%lx => %p\n", mas->index, mas->last, l_wr_mas->entry);
                }
-               WARN_ON_ONCE(cp->d_count != 1);
+               //WARN_ON_ONCE(cp->d_count != 1);
                //cp->dst[0].node->parent = mas_mn(mas)->parent;
                //return false;
        }
 
+       cp->height++;
        wr_mas_ascend(l_wr_mas);
        wr_mas_ascend(r_wr_mas);
        /*
@@ -3493,12 +3572,12 @@ static void mas_wr_spanning_rebalance(struct ma_state *mas,
         * being stored to the last slot of the left node.
         */
 
+       cp.height = 1;
        spanning_leaf_init(&cp, mas, l_wr_mas, r_wr_mas);
        do {
-               cp.height++;
                spanning_data_calc(&cp, mas, l_wr_mas, r_wr_mas, &sib);
-               spanning_split_dest_setup(&cp, mas, l_wr_mas->type);
                spanning_split_src_setup(&cp, mas, l_wr_mas, r_wr_mas, &sib);
+               spanning_split_dest_setup(&cp, mas, l_wr_mas->type);
                spanning_data_write(&cp, mas);
        } while (spanning_ascend(&cp, mas, l_wr_mas, r_wr_mas, &sib));
 
@@ -3506,6 +3585,7 @@ static void mas_wr_spanning_rebalance(struct ma_state *mas,
        mas->node = cp.slot[0];
        mas_wmb_replace(mas, old_enode, cp.height);
        mtree_range_walk(mas);
+       printk("\n\n");
 }
 
 /*
@@ -4294,6 +4374,8 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
         */
        mas = wr_mas->mas;
        trace_ma_op(__func__, mas);
+       //mt_dump(mas->tree, mt_dump_hex);
+       //printk ("%p %s %lx - %lx => %p\n", mas->tree, __func__, mas->index, mas->last, wr_mas->entry);
 
        if (unlikely(!mas->index && mas->last == ULONG_MAX))
                return mas_new_root(mas, wr_mas->entry);
index e3bb034436fae4d9cf4adaa746c47cf20648fa55..1e2c41cb24af9fb4cf2ab6c055f526f79c3de4a1 100644 (file)
@@ -1024,6 +1024,7 @@ static noinline void __init check_ranges(struct maple_tree *mt)
        mt_set_non_kernel(10);
        check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
        MT_BUG_ON(mt, !mt_height(mt));
+       mt_validate(mt);
        mtree_destroy(mt);
 
        /* Create tree of 1-200 */
@@ -1031,11 +1032,13 @@ static noinline void __init check_ranges(struct maple_tree *mt)
        /* Store 45-168 */
        check_store_range(mt, r[10], r[11], xa_mk_value(r[10]), 0);
        MT_BUG_ON(mt, !mt_height(mt));
+       mt_validate(mt);
        mtree_destroy(mt);
 
        check_seq(mt, 30, false);
        check_store_range(mt, 6, 18, xa_mk_value(6), 0);
        MT_BUG_ON(mt, !mt_height(mt));
+       mt_validate(mt);
        mtree_destroy(mt);
 
        /* Overwrite across multiple levels. */
@@ -1061,6 +1064,9 @@ static noinline void __init check_ranges(struct maple_tree *mt)
        check_load(mt, r[13] + 1, xa_mk_value(r[13] + 1));
        check_load(mt, 135, NULL);
        check_load(mt, 140, NULL);
+       mt_validate(mt);
+       mt_dump(mt, mt_dump_hex);
+       //exit(0);
        mt_set_non_kernel(0);
        MT_BUG_ON(mt, !mt_height(mt));
        mtree_destroy(mt);