From: Liam R. Howlett Date: Tue, 26 Aug 2025 01:39:05 +0000 (-0400) Subject: new root broken X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=4ed2e12f7577cc634ed923df3084bf84b9fb6b3a;p=users%2Fjedix%2Flinux-maple.git new root broken Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index a6be76a6fea7..743009ff6cae 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -1498,7 +1498,6 @@ void wr_mas_ascend(struct ma_wr_state *wr_mas) mas->end = ma_data_end(wr_mas->node, wr_mas->type, wr_mas->pivots, mas->max); wr_mas->slots = ma_slots(wr_mas->node, wr_mas->type); - wr_mas->r_min = mas->min; wr_mas->r_min = mas_safe_min(mas, wr_mas->pivots, mas->offset); wr_mas->r_max = mas_safe_pivot(mas, wr_mas->pivots, mas->offset, wr_mas->type); @@ -2297,7 +2296,7 @@ static inline void mast_rebalance_prev(struct maple_subtree_state *mast) } static inline -bool mas_spanning_move(struct ma_wr_state *l_wr_mas, +void mas_spanning_move(struct ma_wr_state *l_wr_mas, struct ma_wr_state *r_wr_mas, struct ma_state *nneighbour) { struct ma_state l_tmp = *l_wr_mas->mas; @@ -2317,7 +2316,7 @@ bool mas_spanning_move(struct ma_wr_state *l_wr_mas, r_tmp.end = mas_data_end(&r_tmp); *nneighbour = r_tmp; - return true; + return; } else if (l_tmp.offset) { l_tmp.offset--; do { @@ -2327,12 +2326,11 @@ bool mas_spanning_move(struct ma_wr_state *l_wr_mas, l_tmp.end = l_tmp.offset; *nneighbour = l_tmp; - return false; + return; } } while (!mte_is_root(r_tmp.node)); WARN_ON_ONCE(1); - return false; } /* @@ -2902,6 +2900,9 @@ unsigned long node_copy(struct ma_state *mas, struct maple_node *src, + printk("cp src %p[%u-%u] => %p[%u]\n", src, start, start + size - 1, + dst, d_start); + printk("size is %u\n", size); 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; @@ -2923,7 +2924,7 @@ unsigned long node_copy(struct ma_state *mas, struct maple_node *src, d_max = s_max; if (start + size < mt_pivots[s_mt]) - d_max = s_pivots[size]; + d_max = s_pivots[size - 1]; size--; if (d_start + size < mt_pivots[d_mt]) @@ -3036,6 +3037,7 @@ static inline void spanning_data_calc(struct maple_copy *cp, if (((l_wr_mas->mas->min != 0) || (r_wr_mas->mas->max != ULONG_MAX)) && (cp->data < mt_min_slots[l_wr_mas->type])) { + printk("MOVING!\n"); mas_spanning_move(l_wr_mas, r_wr_mas, sib); cp->data += sib->end + 1; printk("%p data = %u\n", sib->node, cp->data); @@ -3070,6 +3072,16 @@ void spanning_split_dest_setup(struct maple_copy *cp, struct ma_state *mas, } +void spanning_init_cp_src(struct maple_copy *cp) +{ + cp->src[cp->s_count].node = ma_mnode_ptr(cp); + cp->src[cp->s_count].mt = maple_copy; + cp->src[cp->s_count].max = cp->max; + cp->src[cp->s_count].start = 0; + cp->src[cp->s_count].end = cp->end; + cp->s_count++; +} + /* * src->start and end are 0 indexed */ @@ -3084,16 +3096,15 @@ void spanning_split_src_setup(struct maple_copy *cp, struct ma_state *mas, /* Copy left 0 - offset */ if (l_wr_mas->mas->offset) { - append_node_cp(cp, l_wr_mas->mas, 0, l_wr_mas->mas->offset - 1); - cp->src[cp->s_count - 1].max = l_wr_mas->r_min - 1; + unsigned char off = l_wr_mas->mas->offset - 1; + + append_node_cp(cp, l_wr_mas->mas, 0, off); + cp->src[cp->s_count - 1].max = cp->min - 1; + printk("Use pivot %p [%u]\n", l_wr_mas->node, off); } - cp->src[cp->s_count].node = ma_mnode_ptr(cp); - cp->src[cp->s_count].mt = maple_copy; - cp->src[cp->s_count].max = cp->max; - cp->src[cp->s_count].start = 0; - cp->src[cp->s_count].end = cp->end; - cp->s_count++; + printk("cp min is %lx\n", cp->min); + spanning_init_cp_src(cp); /* Copy right either from offset or offset + 1 pending on r_max */ if (r_wr_mas->mas->end != r_wr_mas->mas->offset) @@ -3261,41 +3272,57 @@ static bool spanning_ascend(struct maple_copy *cp, struct ma_state *mas, cp->pivot[d] = cp->dst[d].max; printk("cp slot %u => %p piv %lx\n", d, cp->slot[d], cp->pivot[d]); } - //cp->slot[d] = mt_mk_node(cp->dst[d].node, cp->dst[d].mt); - cp->max = cp->dst[cp->d_count - 1].max; - printk("cp max is %lx\n", cp->max); - - if (cp->d_count == 1) { - /* Converged to one node */ - printk("CONVERGED\n"); - if (!cp->min && cp->max == ULONG_MAX) { - cp->dst[0].node->parent = ma_parent_ptr(mas_tree_parent(mas)); - while (!mte_is_root(mas->node)) - mas_ascend(mas); - } - else { - cp->dst[0].node->parent = mas_mn(mas)->parent; - } - return false; - } else { - printk("\t\t\t\td_count %u\n", 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\n"); + printk("Shift Right: %p\n", r_wr_mas->mas->node); } } + cp->end = cp->d_count - 1; - printk("more nodes.. %u\n", cp->end); + cp->min = l_wr_mas->mas->min; + cp->max = r_wr_mas->mas->max; + + if (!cp->min && cp->max == ULONG_MAX) { + if (cp->d_count != 1) { + enum maple_type mt = maple_arange_64; + + if (!mt_is_alloc(mas->tree)) + mt = maple_range_64; + + spanning_split_dest_setup(cp, mas, mt); + spanning_init_cp_src(cp); + node_copy(mas, cp->src[0].node, 0, cp->d_count, cp->max, maple_copy, + cp->dst[0].node, 0, mt); + printk("New root\n"); + BUG_ON(1); + } + printk("CONVERGED\n"); + cp->dst[0].node->parent = ma_parent_ptr(mas_tree_parent(mas)); + while (!mte_is_root(mas->node)) + mas_ascend(mas); + return false; + } else if (l_wr_mas->mas->node == r_wr_mas->mas->node){ + if (cp->d_count == 1) { + cp->dst[0].node->parent = mas_mn(mas)->parent; + return false; + } + BUG_ON(1); + } else { + printk("\t\t\t\td_count %u\n", cp->d_count); + } + + printk("more nodes.. %u\n", cp->end); wr_mas_ascend(l_wr_mas); wr_mas_ascend(r_wr_mas); - printk("At %p and %p\n", l_wr_mas->node, r_wr_mas->node); + printk("At %p[%u] and %p[%u]\n", l_wr_mas->node, l_wr_mas->mas->offset, + r_wr_mas->node, r_wr_mas->mas->offset); /* * cp->slot[0] should go in l_wr_mas->offset * cp->slot[end] should go in r_wr_mas->offset @@ -3481,7 +3508,7 @@ static void mas_spanning_rebalance(struct ma_state *mas, } -static inline void mas_wr_spanning_rebalance(struct ma_state *mas, +static void mas_wr_spanning_rebalance(struct ma_state *mas, unsigned char height, struct ma_wr_state *l_wr_mas, struct ma_wr_state *r_wr_mas) { @@ -3499,6 +3526,7 @@ static inline void mas_wr_spanning_rebalance(struct ma_state *mas, mt_dump(mas->tree, mt_dump_hex); + printk("\n\nSTARTING WRITE OF %lx - %lx => %p\n", mas->index, mas->last, l_wr_mas->entry); spanning_leaf_init(&cp, mas, l_wr_mas, r_wr_mas); do { printk("\nlmas %p rmas %p\n", l_wr_mas->node, r_wr_mas->node); @@ -3510,7 +3538,7 @@ static inline void mas_wr_spanning_rebalance(struct ma_state *mas, #if 1 if (debug < 2) { - unsigned long min = cp.min; + unsigned long min = l_wr_mas->mas->min; printk("\n\nCount is %u\n", cp.d_count); for (int i = 0; i < cp.d_count; i++) { printk("dump %p %lx - %lx\n", cp.dst[i].node, min, cp.dst[i].max); diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/maple.c index ac44c32b3c0e..132352c72722 100644 --- a/tools/testing/radix-tree/maple.c +++ b/tools/testing/radix-tree/maple.c @@ -35697,6 +35697,7 @@ static noinline void __init check_spanning_write(struct maple_tree *mt) mtree_lock(mt); mas_store_gfp(&mas, NULL, GFP_KERNEL); mas_set(&mas, 1205); + printk("Check %lx\n", mas.index); MT_BUG_ON(mt, mas_walk(&mas) != NULL); mtree_unlock(mt); mtree_destroy(mt);