From: Liam R. Howlett Date: Fri, 2 May 2025 20:01:06 +0000 (-0400) Subject: split_state_setup() working better X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=4285b571bcaaf1e038a7b197929df6b2432835da;p=users%2Fjedix%2Flinux-maple.git split_state_setup() working better Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 2eba5b01992d..374d0d9fbd27 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -3664,41 +3664,50 @@ static inline void mas_wr_converged(struct ma_node_info *src, mni_finalise(dst); } -static void state_setup(struct ma_node_state *state, struct ma_node_info *src, +/* + * split_state_setup() - Set up the ma_node_state at sd->state[sd->len] + * + * Depending on the sd->offset, set up the next state. + * Does not check for NULLs at the end. + */ +static void split_state_setup(struct ma_node_info *src, struct ma_node_info *dst, struct ma_node_part *part, struct split_data *sd) { - unsigned char copied; - - /* Configure one state */ - state = &sd->states[sd->len]; - if (sd->offset >= sd->insert && sd->offset <= sd->insert_end) { - copied = min(part->size - part->pos, sd->space); - state->part = part; - printk("insert part at %u first entry is %p\n", sd->offset, part->slots[0]); - mns_mni_init(state, dst, part->pos , copied); - state->use_part = true; - part->pos += copied; - src->offset = sd->src_ins_end + 1; + struct ma_node_state *state; + unsigned char copied; + + /* Configure one state */ + printk("\t set up state %u\n", sd->len); + printk("\t insert from %u - %u\n", sd->insert, sd->insert_end); + state = &sd->states[sd->len]; + if (sd->offset >= sd->insert && sd->offset <= sd->insert_end) { + copied = min(part->size - part->pos, sd->space); + state->part = part; + printk("insert part at %u first entry is %p\n", sd->offset, part->slots[0]); + mns_mni_init(state, dst, part->pos , copied); + state->use_part = true; + part->pos += copied; + src->offset = sd->src_ins_end + 1; + } else { + state->info = src; + if (sd->offset < sd->insert_end) { + /* + * First part of node, may split across node + * boundaries though + */ + copied = min(sd->space, sd->insert - sd->offset); } else { - state->info = src; - if (sd->offset < sd->insert_end) { - /* - * First part of node, may split across node - * boundaries though - */ - copied = min(sd->space, sd->insert - sd->offset); - } else { - copied = min(sd->space, (src->end - src->offset + 1)); - } - BUG_ON(copied == 0); - mns_mni_init(state, dst, src->offset, copied); - src->offset += copied; + copied = min(sd->space, (src->end - src->offset + 1)); } + BUG_ON(copied == 0); + mns_mni_init(state, dst, src->offset, copied); + src->offset += copied; + } - sd->offset += copied; - sd->space -= copied; - printk("offset %u split %u\n", sd->offset, sd->split); + sd->offset += copied; + sd->space -= copied; + printk("offset %u split %u\n", sd->offset, sd->split); } /* @@ -3745,7 +3754,7 @@ static void mt_wr_split_data(struct ma_node_info *src, do { /* Configure one state */ state = &sd->states[sd->len]; - state_setup(state, src, to, part, sd); + split_state_setup(src, to, part, sd); /* * Potentially remove one entry from the state if it's NULL and @@ -3929,6 +3938,10 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas, struct split_data *sd, bool left_store) { + struct ma_node_info *dst; + + printk("\t\t%s\n", __func__); + sd->insert_end = sd->insert + part->size - 1; if (!left_store) { char len; @@ -3936,31 +3949,44 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas, * Store to the right implies left is going to donate data to * the right node */ - printk("store right\n"); + printk("store is in right\n"); left->min = src2->min; right->max = src->max; sd->offset = src2->end + 1; sd->split++; sd->states[sd->len].info = src2; + printk("cp from %p\n", src2->node); /* The first state to copy is the left node */ - printk("cp to left %u-%u\n", 0, src2->end + 1); + printk("cp to left %u-%u\n", 0, sd->split); mns_mni_init(&sd->states[sd->len], left, 0, sd->split); sd->len++; + /* Copy the remainder of the left to the start of the right */ len = src2->end + 1 - sd->split; sd->states[sd->len].info = src2; mns_mni_init(&sd->states[sd->len], right, sd->split, len); + printk("cp to right %u-%u\n", sd->split, len); + sd->len++; sd->space = mt_slots[right->type]; - sd->split = 255; + dst = right; } else { printk("store left\n"); sd->space = sd->split; sd->offset = 0; left->min = src->min; right->max = src2->max; + dst = left; } - mt_wr_split_data(src, left, right, part, sd); + do { + printk("cp from %p starting at %u\n", src->node, src->offset); + split_state_setup(src, dst, part, sd); + printk("state %d: cp %p[%u] + %u to %s\n", sd->len, src->node, + sd->states[sd->len].start, + sd->states[sd->len].size, dst == left ? "left" : "right"); + sd->len++; + } while (src->offset <= src->end); + if (left_store) { char len; diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/maple.c index ed88f7da937e..6884548f4c3c 100644 --- a/tools/testing/radix-tree/maple.c +++ b/tools/testing/radix-tree/maple.c @@ -36367,7 +36367,7 @@ void farmer_tests(void) struct maple_node *node; DEFINE_MTREE(tree); - goto skip; + //goto skip; mt_dump(&tree, mt_dump_dec); mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | MT_FLAGS_USE_RCU);