From: Liam R. Howlett Date: Wed, 7 May 2025 00:09:09 +0000 (-0400) Subject: spanning store starts now X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=33ff3448a85af8c69eb498e72420a9067b7f717f;p=users%2Fjedix%2Flinux-maple.git spanning store starts now Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 544c72c983be..64ae95b02c08 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -2191,6 +2191,7 @@ static inline void mas_wr_node_walk(struct ma_wr_state *wr_mas) index = mas->index; + printk("%s: index %lu\n", __func__, index); if (unlikely(ma_is_dense(wr_mas->type))) { wr_mas->r_max = wr_mas->r_min = index; mas->offset = mas->index = mas->min; @@ -2198,11 +2199,13 @@ static inline void mas_wr_node_walk(struct ma_wr_state *wr_mas) } wr_mas->node = mas_mn(mas); + printk("at node %p\n", wr_mas->node); pivs = wr_mas->pivots = ma_pivots(wr_mas->node, wr_mas->type); count = mas->end = ma_data_end(wr_mas->node, wr_mas->type, pivs, mas->max); offset = mas->offset; + printk("start offset is %u\n", offset); if (index > pivs[count - 1]) { wr_mas->r_max = mas->max; wr_mas->offset_end = mas->offset = count; @@ -2213,6 +2216,7 @@ static inline void mas_wr_node_walk(struct ma_wr_state *wr_mas) while (index > pivs[offset]) offset++; + printk("end offset is %u\n", offset); wr_mas->r_max = pivs[offset]; wr_mas->r_min = mas_safe_min(mas, pivs, offset); wr_mas->offset_end = mas->offset = offset; @@ -3121,6 +3125,7 @@ void mns_node_part_leaf_init(struct ma_node_part *part, part->skip = wr_mas->offset_end - wr_mas->mas->offset + 1; part->leaf = true; + printk("%s skip %u\n", __func__, part->skip); } static inline @@ -3552,6 +3557,7 @@ static void split_state_setup(struct ma_node_info *src, unsigned char size; unsigned char max_copy; + printk("src %p dst %p\n", src->node, dst->node); /* Configure one state */ state = &sd->states[sd->len]; size = sd->space; @@ -3560,11 +3566,13 @@ static void split_state_setup(struct ma_node_info *src, if (max_copy < size) size = max_copy; + printk("\tstore part: %u %u %u\n", sd->len, part->pos, size); state->part = part; mns_mni_init(state, dst, part->pos, size); state->use_part = true; part->pos += size; src->offset = sd->src_ins_end + 1; + printk("src offset is now %u\n", src->offset); } else { state->info = src; @@ -3577,6 +3585,7 @@ static void split_state_setup(struct ma_node_info *src, if (max_copy < size) size = max_copy; + printk("\tstore info: %u %u %u\n", sd->len, src->offset, size); BUG_ON(size == 0); mns_mni_init(state, dst, src->offset, size); src->offset += size; @@ -3913,6 +3922,7 @@ static void rebalance_reduce(struct ma_node_info *left, struct ma_node_info *src, struct ma_node_info *src2, struct ma_node_part *part, struct split_data *sd) { + printk("sd len is %u\n", sd->len); sd->insert_end = sd->insert + part->size - 1; if (!sd->left_store) { left->min = src2->min; @@ -3921,6 +3931,7 @@ static void rebalance_reduce(struct ma_node_info *left, sd->space = sd->new_end + 1; sd->states[sd->len].info = src2; /* The first state to copy is the left node */ + printk("%d sd len is %u\n", __LINE__, sd->len); mns_mni_init(&sd->states[sd->len], left, 0, src2->end + 1); sd->len++; } else { @@ -3937,8 +3948,11 @@ static void rebalance_reduce(struct ma_node_info *left, } while (src->offset <= src->end); if (sd->left_store) { + unsigned char len = src2->end + 1 - src2->offset; + sd->states[sd->len].info = src2; - mns_mni_init(&sd->states[sd->len], left, 0, src2->end + 1); + printk("cp %u node %p offset %u-%u to left too\n", sd->len, src2->node, src2->offset, len); + mns_mni_init(&sd->states[sd->len], left, src2->offset, len); sd->len++; } @@ -4452,6 +4466,7 @@ done: return; } + /* * mas_wr_spanning_store() - Create a subtree with the store operation completed * and new nodes where necessary, then place the sub-tree in the actual tree. @@ -4459,7 +4474,7 @@ done: * span. * @wr_mas: The maple write state */ -static noinline void mas_wr_spanning_store(struct ma_wr_state *wr_mas) +static noinline void __mas_wr_spanning_store(struct ma_wr_state *wr_mas) { struct maple_subtree_state mast; struct maple_big_node b_node; @@ -4719,6 +4734,7 @@ static __always_inline void mas_wr_end_piv(struct ma_wr_state *wr_mas) unsigned long last = wr_mas->mas->last; unsigned long *pivs = wr_mas->pivots; + printk("last is %u\n", last); if (last > pivs[wr_mas->mas->end - 1]) { wr_mas->offset_end = wr_mas->mas->end; wr_mas->end_piv = wr_mas->mas->max; @@ -4726,6 +4742,8 @@ static __always_inline void mas_wr_end_piv(struct ma_wr_state *wr_mas) } offset_end = wr_mas->offset_end; + printk("end offset is %u\n", offset_end); + printk("pivs at offset is %u\n", pivs[offset_end]); while (last > pivs[offset_end]) offset_end++; @@ -4784,6 +4802,123 @@ static inline void mas_wr_append(struct ma_wr_state *wr_mas, return; } +static void mas_wr_spanning_store(struct ma_wr_state *wr_mas) +{ + struct ma_state *mas; + MA_STATE(r_mas, NULL, 0, 0); + MA_WR_STATE(r_wr_mas, &r_mas, wr_mas->entry); + struct ma_node_info src, r_src, left, right, middle; + struct ma_node_info parent, r_parent, new_parent; + struct ma_node_part part; + struct split_data sd; + unsigned char height; + + mas = wr_mas->mas; + utrace_ma_op(__func__, mas); + + mt_dump(mas->tree, mt_dump_dec); + printk("Storing %lu - %lu -> %p\n", mas->index, mas->last, wr_mas->entry); + + if (unlikely(!mas->index && mas->last == ULONG_MAX)) + 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); + r_mas.index = r_mas.min; + r_mas.offset = 0; + mas_wr_end_piv(&r_wr_mas); + + /* Set up left side. */ + printk("\nwr_mas\n"); + mas_wr_walk_index(wr_mas); + + + printk("At %p and %p\n", mas_mn(mas), mas_mn(&r_mas)); + printk("r_mas: end piv is %lu\n", r_wr_mas.end_piv); + + wr_mas->end_piv = r_wr_mas.end_piv; + mni_mas_init(&src, mas); + mni_mas_init(&r_src, &r_mas); + printk("offset end is %u\n", r_wr_mas.offset_end); + sd.len = 0; + sd.offset = 0; + sd.left_store = true; + sd.insert = mas->offset; + sd.src_ins_end = wr_mas->offset_end + mas->end + 1; + wr_mas->offset_end += mas->end + part.skip + 1; + mns_node_part_leaf_init(&part, wr_mas, &right); + do { + struct ma_node_state *state; + + for (int i = 0; i < part.size; i++) + printk("slot %u is %lu -> %p\n", i, part.pivots[i], part.slots[i]); + printk("skip %u\n", part.skip); + + sd.new_end = r_mas.end + mas->end - part.skip; + sd.len = 0; + r_src.offset = r_wr_mas.offset_end + 1; + printk("new end is %u\n", sd.new_end); + + mni_node_init(&left, mas_pop_node(mas), src.type); + left.min = src.min; + mas_wr_ascend_init(mas, &parent); + mas->end = parent.end; + mas_wr_ascend_init(&r_mas, &r_parent); + r_mas.end = r_parent.end; + if (sd.new_end < mt_slots[src.type]) { + /* Single node at this level */ + printk("%d\n", __LINE__); + left.max = r_src.max; + right.node = NULL; + middle.node = NULL; + sd.split = mt_slots[src.type]; + rebalance_reduce(&left, &src, &r_src, &part, &sd); + if (ma_is_root(parent.node)) { + /* This is wrong... + * We have parent.end != 1, but we have + * replaced all the data.. + * */ + if (parent.end != 1) + break; + + src.enode = mas->node; + left.node->parent = mas_mn(mas)->parent; + mas->node = left.enode; + mas->depth = mas_mt_height(mas) - 1; + mas_set_height(mas); + goto new_root; + } + } else if (sd.new_end < 2 * mt_slots[src.type]) { + printk("%d\n", __LINE__); + mni_node_init(&right, mas_pop_node(mas), r_src.type); + middle.node = NULL; + right.max = r_src.max; + } else { + printk("%d\n", __LINE__); + mni_node_init(&right, mas_pop_node(mas), r_src.type); + mni_node_init(&middle, mas_pop_node(mas), src.type); + right.max = r_src.max; + } + + sd.len = 0; + sd.offset = 0; + } while ((parent.node != r_parent.node) && + sd.new_end >= mt_slots[parent.type]); + + mas_wr_converged(&parent, &new_parent, &part, mas, &sd); + src.enode = parent.enode; + mas->node = new_parent.enode; + printk("replace %p with %p\n", src.enode, mas->node); + +new_root: + mas_wmb_replace(mas, src.enode); + mtree_range_walk(mas); + mt_dump(mas->tree, mt_dump_dec); + mt_validate(mas->tree); +} + /* * mas_wr_store_entry() - Internal call to store a value * @wr_mas: The maple write state