From: Liam R. Howlett Date: Tue, 4 Feb 2025 18:05:35 +0000 (-0500) Subject: rebalance wip X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f6d5891874d74ffe395b5963c29ec3ed048ea28b;p=users%2Fjedix%2Flinux-maple.git rebalance wip Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 23f56d15a4a3..5f76c8bce6e2 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -3225,8 +3225,8 @@ static __always_inline void mns_insert_part(struct ma_node_part *part, struct ma_node_state *dst) { - //printk("insert pos %u/%u %u/%u\n", part->pos, part->size, - // dst->offset, part->dst_max_off); + printk("insert pos %u/%u %u/%u\n", part->pos, part->size, + dst->offset, part->dst_max_off); while (dst->offset < mt_slots[dst->type]) { //printk("Store part %u into %u %p\n", part->pos, dst->offset, part->slots[part->pos]); @@ -3240,30 +3240,30 @@ void mns_insert_part(struct ma_node_part *part, if (dst->offset < mt_pivots[dst->type]) dst->pivots[dst->offset] = part->pivots[part->pos]; - //printk ("offset %lx\n", part->pivots[part->pos]); + printk ("offset %lx\n", part->pivots[part->pos]); dst->offset++; dst->max = part->pivots[part->pos]; - //printk("Offset is %u, use max for pivot\n", dst->offset); + printk("Offset is %u, use max for pivot\n", dst->offset); part->pos++; - //printk("dst offset is %u\n", dst->offset); + printk("dst offset is %u\n", dst->offset); if (part->pos >= part->size) { - //printk("pos >= size\n"); + printk("pos >= size\n"); part->unfinished = false; return; /* Nothing to do */ } if (dst->offset > part->dst_max_off) { - //printk("push part to next node\n"); + printk("push part to next node\n"); /* push to next node */ part->unfinished = true; return; } - //printk("dst offset is %u max is %u\n", dst->offset, part->dst_max_off); + printk("dst offset is %u max is %u\n", dst->offset, part->dst_max_off); } - //printk("OUT OF ROOM??\n"); + printk("OUT OF ROOM??\n"); /* Out of room.. */ //WARN_ON_ONCE(1); part->unfinished = true; @@ -3309,6 +3309,17 @@ static inline void mns_pmns_init(struct ma_node_state *mns, struct ma_node_state *pmns, unsigned char p_off, struct maple_tree *mt) { + if (p_off == pmns->end) { + mns->max = pmns->max; + mns->min = pmns->pivots[p_off - 1]; + } else { + mns->max = pmns->pivots[p_off]; + if (p_off) + mns->min = pmns->pivots[p_off - 1]; + else + mns->min = pmns->min; + } + mns->enode = mt_slot_locked(mt, pmns->slots, p_off); mns->insert = p_off; _mns_node_init(mns, mte_to_node(mns->enode), @@ -3328,10 +3339,10 @@ void mns_cp(struct ma_node_state *src, struct ma_node_state *dst, unsigned long max; size_t size; - //printk("Cp %p %u-%u\n", dst->node, dst->offset, dst->offset + len - 1); - //printk("src %p %u-%u\n", src->node, src->offset, src->offset + len - 1); + printk("Cp %p %u-%u\n", dst->node, dst->offset, dst->offset + len - 1); + printk("src %p %u-%u\n", src->node, src->offset, src->offset + len - 1); size = len * sizeof(void *); - //printk("Copy %lu (%lu)\n", size, len); + printk("Copy %lu (%u)\n", size, len); memcpy(dst->slots + dst->offset, src->slots + src->offset, size); size = len * sizeof(unsigned long); @@ -3341,18 +3352,18 @@ void mns_cp(struct ma_node_state *src, struct ma_node_state *dst, if (src->offset + len > mt_pivots[src->type]) { size = mt_pivots[src->type] - src->offset; max = src->max; - //printk("Avoid overflow, use max %lx\n", max); + printk("Avoid overflow, use max %lx\n", max); } else { size = len; max = src->pivots[src->offset + len - 1]; - //printk("use max %lx\n", max); + printk("use max %lx from %p[%u]\n", max, src->node, src->offset + len - 1); } if (dst->offset + len > mt_pivots[dst->type]) { size = mt_pivots[dst->type] - dst->offset; - //printk("Avoid overflow, SET max %lx\n", max); + printk("Avoid overflow, SET max %lx\n", max); } else { - //printk("Set piv %u to %lx\n", dst->offset + len - 1, max); + printk("Set piv %u to %lx\n", dst->offset + len - 1, max); dst->pivots[dst->offset + len - 1] = max; } @@ -3502,6 +3513,7 @@ static inline void mas_wr_converged(struct ma_node_state *src, struct ma_state *mas) { mns_node_init(dst, mas_pop_node(mas), src->type); + printk("%s: %p -> %p\n", __func__, src->node, dst->node); if (mas->offset) mns_cp(src, dst, mas->offset); @@ -3674,21 +3686,26 @@ static void mas_wr_rebalance_nodes( l_end = l_src->end; r_end = r_src->end; if (left_store) { /* Store is targeting l_src */ + printk("%s %d\n", __func__, __LINE__); if (mas_off <= split) { /* Store will end up in left */ + printk("%s %d\n", __func__, __LINE__); if (mas_off) mns_cp(l_src, left, mas_off); ma_part->dst_max_off = split; mns_insert_part(ma_part, left); l_src->offset+= ma_part->skip; - //printk("%d\n", __LINE__); + printk("%d\n", __LINE__); + printk("\tright min %lu left max %lu\n", right->min, left->max); if (left->offset <= split) mns_cp(l_src, left, split - left->offset + 1); + printk("\tright min %lu left max %lu\n", right->min, left->max); mas_wr_split_no_null(l_src, left, right, r_end + new_end + 1, ma_part); right->min = left->max + 1; + printk("\tright min %lu left max %lu\n", right->min, left->max); if (ma_part->unfinished) mns_insert_part(ma_part, right); @@ -3696,6 +3713,7 @@ static void mas_wr_rebalance_nodes( mns_cp(l_src, right, l_end - l_src->offset + 1); } else { /* Store will end up in right */ + printk("%s %d\n", __func__, __LINE__); mns_cp(l_src, left, split + 1); mas_wr_split_no_null(l_src, left, right, r_end + new_end + 1, ma_part); @@ -3710,7 +3728,9 @@ static void mas_wr_rebalance_nodes( mns_cp(r_src, right, r_end + 1); } else { /* Store is targeting r_src */ + printk("%s %d\n", __func__, __LINE__); if (split <= l_end) { /* Store will end up in right */ + printk("%s %d\n", __func__, __LINE__); mns_cp(l_src, left, split + 1); mas_wr_split_no_null(l_src, left, right, l_end + new_end + 1, ma_part); @@ -3727,6 +3747,7 @@ static void mas_wr_rebalance_nodes( } else { /* Store will end up in left */ unsigned char r_split; + printk("%s %d\n", __func__, __LINE__); r_split = split - l_end - 1; mns_cp(l_src, left, l_end + 1); if (mas_off <= r_split) { @@ -3884,44 +3905,62 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas) struct ma_node_state left, right; struct ma_node_part ma_part; unsigned char total, split, height; + unsigned char insert; trace_ma_op(__func__, mas); + mt_dump(mas->tree, mt_dump_dec); height = mas_mt_height(mas); mns_mas_init(&src, mas); + src.min = mas->min; + src.max = mas->max; + src.end = mas->end; mns_node_part_leaf_init(&ma_part, wr_mas, &src); /* Total will lack sibling data until the sibling is known */ + printk("end %p %u\n", mas->node, mas->end); total = mas->end + ma_part.size - ma_part.skip - 1; + printk("%p will have %u in the end\n", mas->node, total); + printk("Skip %u\n", ma_part.skip); + // Skipping is causing a copy beyond the end of the src. + + printk("Rebalance %p %lu-%lu", mas->node, mas->index, mas->last); + insert = mas->offset; + printk("Write to node at %u\n", insert); while (mas->depth) { - bool consume = false; - unsigned char data_size; bool l_store; mas_wr_ascend_init(mas, &parent); + printk("Ascend to parent %p\n", parent.node); + printk("offset of child is %u\n", mas->offset); mas->depth--; mns_set_end(&parent); parent.insert = mas->offset; + printk("parent insert is %u\n", parent.insert); - if (!parent.insert) { - /* Pull data from l_src */ - mns_pmns_init(&l_src, &parent, mas->offset + 1, mas->tree); - r_src = src; - r_src.end = mas->end; - r_src.insert = mas->offset; - mns_set_end(&l_src); - total += l_src.end; - l_store = false; - } else { + if (parent.insert < parent.end) { /* Pull data from r_src */ - mns_pmns_init(&r_src, &parent, mas->offset - 1, mas->tree); + printk("Pull from right\n"); + mns_pmns_init(&r_src, &parent, mas->offset + 1, mas->tree); mns_set_end(&r_src); + printk("right is %p %lu-%lu\n", r_src.node, r_src.min, r_src.max); l_src = src; - l_src.end = mas->end; - l_src.insert = mas->offset; + l_src.insert = insert; total += r_src.end; l_store = true; + } else { + /* Pull data from l_src */ + printk("Pull from left\n"); + mns_pmns_init(&l_src, &parent, mas->offset - 1, mas->tree); + printk("left is %p\n", l_src.node); + r_src = src; + r_src.insert = insert; + mns_set_end(&l_src); + total += l_src.end; + l_store = false; + parent.insert--; } + printk("\tNew total will be %u\n", total); mns_node_init(&left, mas_pop_node(mas), l_src.type); /* * Two possibilities: @@ -3932,33 +3971,35 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas) ma_is_root(parent.node)) { struct ma_node_state new_parent; + printk("Rebalance\n"); /* * Rebalance between nodes is possible, so the * operation stops early. */ mns_node_init(&right, mas_pop_node(mas), r_src.type); + printk("new right will be %p\n", right.node); split = mas_wr_rebalance_calc(total, l_src.type); + printk("split is %u\n", split); left.min = l_src.min; mas_wr_rebalance_nodes(&l_src, &r_src, &left, &right, l_store, split, &ma_part, - mas->offset, total); + insert, total); mns_finalise(&left); mns_finalise(&right); - mas_ascend(mas); - mas->end = parent.end; - mas->offset = parent.insert; mns_node_part_init(&ma_part, &left, &right); ma_part.skip = 2; mas_wr_converged(&parent, &new_parent, &ma_part, mas); src.enode = parent.enode; mas->node = new_parent.enode; mas->depth = height; + printk("Height is %u\n", mas->depth); break; } + printk("consume\n"); /* Reduce two nodes into one */ if (l_store) { if (l_src.insert) @@ -3997,6 +4038,7 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas) mas_wmb_replace(mas, parent.enode); mtree_range_walk(mas); + mt_dump(mas->tree, mt_dump_dec); } /* @@ -4792,7 +4834,7 @@ static inline void mas_wr_store_entry(struct ma_wr_state *wr_mas) mas_wr_split(wr_mas); break; case wr_rebalance: - mas_wr_bnode(wr_mas); + mas_wr_rebalance(wr_mas); break; case wr_exact_fit: rcu_assign_pointer(wr_mas->slots[mas->offset], wr_mas->entry);