From: Liam R. Howlett Date: Tue, 6 May 2025 14:45:41 +0000 (-0400) Subject: still issues X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a786bbdc1833e94f78d436ce7219e43240e84109;p=users%2Fjedix%2Flinux-maple.git still issues Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 39a35f764e94..de0d21ee651d 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -3129,7 +3129,6 @@ struct ma_node_info { unsigned char end; unsigned char insert_off; unsigned char offset; /* Operating position */ - bool is_alloc; }; struct ma_node_state { @@ -3159,20 +3158,24 @@ void mns_node_part_leaf_init(struct ma_node_part *part, if (wr_mas->r_min < wr_mas->mas->index) { part->pivots[0] = wr_mas->mas->index - 1; part->slots[0] = wr_mas->content; + printk("%s zero piv is %lu\n", __func__,part->pivots[part->size]); part->size++; } part->pivots[part->size] = wr_mas->mas->last; part->slots[part->size] = wr_mas->entry; + printk("%s one piv is %lu\n", __func__,part->pivots[part->size]); part->size++; if (wr_mas->end_piv > wr_mas->mas->last) { part->pivots[part->size] = wr_mas->end_piv; part->slots[part->size] = src->slots[wr_mas->offset_end]; + printk("%s last piv is %lx\n", __func__,part->pivots[part->size]); part->size++; } part->skip = wr_mas->offset_end - wr_mas->mas->offset + 1; + printk("skip %u\n", part->skip); part->leaf = true; } @@ -3208,7 +3211,6 @@ void _mni_node_init(struct ma_node_info *mni, struct maple_node *node, mni->slots = ma_slots(node, type); mni->pivots = ma_pivots(node, type); mni->gaps = ma_gaps(node, type); - mni->is_alloc = false; } static inline @@ -3371,17 +3373,39 @@ void mni_cp(struct ma_node_info *src, struct ma_node_info *dst, src->offset += len; } +struct split_data { + /* + * Used to split the data between two nodes. + * The user of this struct, mt_wr_split_data(), must keep track of the + * offset into the entire data (up to two nodes worth), so that the + * insert can be placed in the correct place while the source data that + * is overwritten is skipped. + */ + unsigned char offset; /* Offset into destination data (entire set) */ + unsigned char space; /* The space left in the current destination node */ + unsigned char split; /* Proposed split of data */ + unsigned char insert; /* Insert location of destination */ + unsigned char insert_end;/* Insert end location of destination */ + unsigned char new_end; /* Total data */ + unsigned char src_ins_end; /* Offset into source data where the write ends */ + unsigned char len; /* Number of ma_node_states in the states array */ + struct ma_node_state states[5]; + bool is_alloc; +}; + /* * * Zero any area that needs to be zeroed and set the metadata. * metadata needs the largest gap for non-leaves. */ static __always_inline -void mni_finalise(struct ma_node_info *p) +void mni_finalise(struct ma_node_info *p, struct split_data *sd) { unsigned long max_gap; unsigned char len; + if (!sd->is_alloc) + printk("\n\n\nNOT ALLOC\n\n\n"); len = mt_slots[p->type] - p->offset; if (len) { memset(p->slots + p->offset, 0, len * sizeof(void *)); @@ -3399,7 +3423,7 @@ void mni_finalise(struct ma_node_info *p) unsigned long *pivs; void **slots; - if (!p->is_alloc) + if (!sd->is_alloc) goto finalise_leaf; i = 0; offset = p->offset - 2; @@ -3445,6 +3469,13 @@ finalise_leaf: if (p->offset <= mt_pivots[p->type]) { ma_set_meta(p->node, p->type, 0, p->offset - 1); } + if (p->max != ULONG_MAX) { + if (p->slots[p->offset - 1] == NULL) { + printk("last slot %u has %lu\n", p->offset - 1, + p->pivots[p->offset - 1]); + } + BUG_ON(p->slots[p->offset - 1] == NULL); + } } else { unsigned long gap_off = 0; if (p->gaps) { @@ -3553,6 +3584,8 @@ void mns_assemble(struct ma_node_state *states, unsigned char len) if (last_dst != ns->dst) { WARN_ON_ONCE(!max); ns->dst->min = max + 1; + printk("%p max set to %lu\n", last_dst->node, last_dst->max); + printk("%p min set to %lu\n", ns->dst->node, ns->dst->min); } last_dst = ns->dst; @@ -3584,7 +3617,9 @@ void mns_assemble(struct ma_node_state *states, unsigned char len) if (ns->start + size > mt_pivots[ns->info->type]) { piv_overflow = 1; max = ns->info->max; + printk("max fro ns->info->max\n"); } else { + printk("max from %lu\n", size - 1 ); max = s_piv[size - 1]; } } @@ -3609,25 +3644,6 @@ void mns_assemble(struct ma_node_state *states, unsigned char len) } } -struct split_data { - /* - * Used to split the data between two nodes. - * The user of this struct, mt_wr_split_data(), must keep track of the - * offset into the entire data (up to two nodes worth), so that the - * insert can be placed in the correct place while the source data that - * is overwritten is skipped. - */ - unsigned char offset; /* Offset into destination data (entire set) */ - unsigned char space; /* The space left in the current destination node */ - unsigned char split; /* Proposed split of data */ - unsigned char insert; /* Insert location of destination */ - unsigned char insert_end;/* Insert end location of destination */ - unsigned char new_end; /* Total data */ - unsigned char src_ins_end; /* Offset into source data where the write ends */ - unsigned char len; /* Number of ma_node_states in the states array */ - struct ma_node_state states[5]; -}; - static inline void mas_wr_converged(struct ma_node_info *src, struct ma_node_info *dst, struct ma_node_part *part, struct ma_state *mas, struct split_data *sd) @@ -3661,7 +3677,7 @@ static inline void mas_wr_converged(struct ma_node_info *src, mns_assemble(sd->states, sd->len); dst->node->parent = src->node->parent; - mni_finalise(dst); + mni_finalise(dst, sd); } /* @@ -3685,10 +3701,12 @@ static void split_state_setup(struct ma_node_info *src, 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]); + printk("Size is %u/%u\n", copied, part->size); mns_mni_init(state, dst, part->pos , copied); state->use_part = true; part->pos += copied; src->offset = sd->src_ins_end + 1; + printk("Set src %p offset to %u\n", src->node, src->offset); } else { state->info = src; if (sd->offset < sd->insert_end) { @@ -3696,11 +3714,14 @@ static void split_state_setup(struct ma_node_info *src, * First part of node, may split across node * boundaries though */ + printk("%d\n", __LINE__); copied = min(sd->space, sd->insert - sd->offset); } else { + printk("%d\n", __LINE__); copied = min(sd->space, (src->end - src->offset + 1)); } BUG_ON(copied == 0); + printk("src offset is %u\n", src->offset); mns_mni_init(state, dst, src->offset, copied); src->offset += copied; } @@ -3912,8 +3933,8 @@ bool mas_wr_try_rebalance(struct ma_state *mas, struct ma_node_info *src, } mns_assemble(sd->states, sd->len); - mni_finalise(left); - mni_finalise(right); + mni_finalise(left, sd); + mni_finalise(right, sd); mni_node_part_init(part, left, right); mas_ascend(mas); mas->end = parent.end; @@ -3939,8 +3960,9 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas, bool left_store) { struct ma_node_info *dst; + struct ma_node_state *state; - printk("\t\t%s\n", __func__); + printk("\t\t%s \n", __func__); sd->insert_end = sd->insert + part->size - 1; if (!left_store) { char len; @@ -3950,25 +3972,33 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas, * the right node */ printk("store is in right\n"); + state = &sd->states[sd->len]; left->min = src2->min; right->max = src->max; sd->offset = src2->end + 1; - sd->split++; - sd->states[sd->len].info = src2; + state->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, sd->split); - mns_mni_init(&sd->states[sd->len], left, 0, sd->split); + printk("cp to left %u+%u\n", 0, sd->split); + mns_mni_init(state, left, 0, sd->split); + if (ma_is_leaf(src->type) && mns_ends_in_null(state)) { + printk("ends in null\n"); + sd->split--; + state->size--; + printk("NEW cp to left %u-%u\n", 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); + printk("cp to right %u-%u (%u + 1 - %u\n", sd->split, len, src2->end, sd->split); sd->len++; sd->space = mt_slots[right->type]; dst = right; + printk("src ins end is %u\n", wr_mas->offset_end); + printk("\n"); } else { printk("store left\n"); sd->space = sd->split; @@ -3990,23 +4020,42 @@ static void mas_wr_rebalance_two(struct ma_wr_state *wr_mas, if (left_store) { char len; + if (sd->offset >= sd->insert && sd->offset <= sd->insert_end) + printk("BING\n"); + + state = &sd->states[sd->len]; sd->split = (sd->new_end + 1) / 2; printk("sd is at offset %u splut %u\n", sd->offset, sd->split); len = sd->split - sd->offset; - sd->states[sd->len].info = src2; + state->info = src2; printk("cp right->%u + %u to left\n", 0, len); - mns_mni_init(&sd->states[sd->len], left, 0, len); - sd->len++; + mns_mni_init(state, left, 0, len); + if (ma_is_leaf(src->type) && mns_ends_in_null(state)) { + printk("ends in null\n"); + sd->split--; + sd->offset--; + sd->space++; + state->size--; + len--; + } + + 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"); printk("cp the right->to right->%u + %u\n", len, src2->end + 1); + sd->len++; /* Stored to the left, copy the last of the right->in src2 */ sd->states[sd->len].info = src2; mns_mni_init(&sd->states[sd->len], right, len, src2->end + 1 - len); + 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++; } mns_assemble(sd->states, sd->len); - mni_finalise(left); - mni_finalise(right); + mni_finalise(left, sd); + mni_finalise(right, sd); mni_node_part_init(part, left, right); part->skip = 2; } @@ -4057,7 +4106,7 @@ static void mas_wr_rebalance_reduce(struct ma_wr_state *wr_mas, } mns_assemble(sd->states, sd->len); - mni_finalise(left); + mni_finalise(left, sd); mni_node_part_init(part, left, NULL); part->skip = 2; } @@ -4084,21 +4133,26 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas) */ mt_dump(mas->tree, mt_dump_dec); printk("Rebalance %p offset %u - %u\n", mas->node, mas->offset, wr_mas->offset_end); - printk("Store %lu - %lu\n", mas->index, mas->last); + printk("Store %p %lu - %lu\n", wr_mas->entry, mas->index, mas->last); height = mas_mt_height(mas); mni_mas_init(&src, mas); src.end = mas->end; + printk("HERE\n"); mns_node_part_leaf_init(&part, wr_mas, &src); sd.new_end = mas->end + part.size - part.skip + 1; sd.src_ins_end = wr_mas->offset_end; sd.len = 0; mni_node_init(&left, mas_pop_node(mas), wr_mas->type); + printk("left is %p\n", left.node); if (mt_is_alloc(mas->tree)) - left.is_alloc = true; + sd.is_alloc = true; + else + sd.is_alloc = false; + do { printk("\tloop\n"); tmp_mas = *mas; @@ -4121,33 +4175,31 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas) printk("rebalance %p %p\n", src.node, src2.node); sd.new_end += src2.end + 1; + printk("new end %u\n", sd.new_end); if (sd.new_end < mt_min_slots[left.type]) { printk("Not enough tdata\n"); exit(0); } - if (sd.split < mt_min_slots[left.type]) { - printk("Too small split\n"); - exit(0); - } + printk("Total data is %u\n", sd.new_end); + printk("sd insert is %u\n", sd.insert); + if (sd.new_end >= mt_slots[left.type]) { if (sd.new_end - sd.split < mt_min_slots[left.type]) { printk("Too big split\n"); exit(0); } - printk("Total data is %u\n", sd.new_end); - printk("sd insert is %u\n", sd.insert); - if (sd.new_end >= mt_slots[left.type]) { mni_node_init(&right, mas_pop_node(mas), mte_node_type(mas->node)); + printk("right is %p\n", right.node); + printk("%s end with %lu - %lu\n", __func__, mas->index, mas->last); mas_wr_rebalance_two(wr_mas, &left, &right, &src, &src2, &part, &sd, left_store); mas_ascend(mas); mas->end = parent.end; mas->offset = parent.insert_off; - printk("Replacing 2 nodes, break\n"); + printk("Replacing 2 nodes (%d), break\n", sd.new_end); printk("mas is %p\n", mas->node); break; } printk("REDUCE %p %p\n", src.node, src2.node); - sd.split = 255; mas_wr_rebalance_reduce(wr_mas, &left, &src, &src2, &part, &sd, left_store); /* Must go again */ @@ -4189,7 +4241,7 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas) mas_wr_converged(&parent, &new_parent, &part, mas, &sd); src.enode = parent.enode; - printk("Replace %p with %p\n", parent.node, new_parent.enode); + printk("Replace %p with %p\n", parent.node, mte_to_node(new_parent.enode)); mas->node = new_parent.enode; new_root: mas_wmb_replace(mas, src.enode); @@ -4220,7 +4272,9 @@ static void mas_wr_split(struct ma_wr_state *wr_mas) mni_node_init(&right, mas_pop_node(mas), wr_mas->type); if (mt_is_alloc(mas->tree)) - right.is_alloc = left.is_alloc = true; + sd.is_alloc = true; + else + sd.is_alloc = false; mns_node_part_leaf_init(&part, wr_mas, &src); sd.new_end = mas->end + part.size; /* - skip + 1 */ @@ -4240,8 +4294,8 @@ static void mas_wr_split(struct ma_wr_state *wr_mas) mt_wr_split_data(&src, &left, &right, &part, &sd); mns_assemble(sd.states, sd.len); - mni_finalise(&left); - mni_finalise(&right); + mni_finalise(&left, &sd); + mni_finalise(&right, &sd); if (height == 1) goto new_root; @@ -4272,8 +4326,8 @@ static void mas_wr_split(struct ma_wr_state *wr_mas) mt_wr_split_data(&src, &left, &right, &part, &sd); mns_assemble(sd.states, sd.len); - mni_finalise(&left); - mni_finalise(&right); + mni_finalise(&left, &sd); + mni_finalise(&right, &sd); } new_root: diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index db6fe093f711..5d0a95b328c9 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -2630,6 +2630,7 @@ static noinline void __init check_fuzzer(struct maple_tree *mt) mtree_test_load(mt, 1); mtree_test_store_range(mt, 1, 22, (void *)0x3); mtree_test_insert(mt, 1, (void *)0x3); + mt_dump(mt, mt_dump_dec); mtree_test_erase(mt, 1); mtree_test_load(mt, 53); mtree_test_load(mt, 1); diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/maple.c index 7b58ca3cd18f..ad89fce34736 100644 --- a/tools/testing/radix-tree/maple.c +++ b/tools/testing/radix-tree/maple.c @@ -27,7 +27,7 @@ #include "../../../lib/test_maple_tree.c" #define RCU_RANGE_COUNT 1000 -#define RCU_MT_BUG_ON(test, y) {if (y) { test->stop = true; } MT_BUG_ON(test->mt, y); } +#define RCU_MT_BUG_ON(_test, _y) {if (_y) { {if (_test->stop != true) MT_BUG_ON(_test->mt, _y);} _test->stop = true; }} struct rcu_test_struct2 { struct maple_tree *mt; @@ -725,8 +725,11 @@ static noinline void __init check_erase_testset(struct maple_tree *mt) /* Shrinking tree test. */ - for (int i = 13; i < ARRAY_SIZE(set); i++) + for (int i = 13; i < ARRAY_SIZE(set); i++) { + mt_dump(mt, mt_dump_dec); + printk("STORE %lu -> %p\n", set[i], entry[i%2]); erase_check_insert(mt, i); + } mt_set_non_kernel(99); for (int i = 18; i < ARRAY_SIZE(set); i++) { @@ -34379,6 +34382,7 @@ static void *rcu_reader_fwd(void *ptr) bool toggled, modified, deleted, added; int i; void *entry, *prev = NULL; + struct maple_node *p_node = NULL; MA_STATE(mas, test->mt, 0, 0); rcu_reader_register(test); @@ -34427,7 +34431,18 @@ static void *rcu_reader_fwd(void *ptr) } } + if (mas.index != r_start) { + alt = xa_mk_value(index + i * 2 + 1 + + RCU_RANGE_COUNT); + printk("Error: mas %p %lu-%lu %p != %lu-%lu %p %p line %d i %d, pnode %p\n", + mte_to_node(mas.node), mas.index, mas.last, entry, + r_start, r_end, expected, alt, + __LINE__, i, p_node); + } RCU_MT_BUG_ON(test, mas.index != r_start); + if (mas.last != r_end) { + printk("last is wrong: %lx vs %lx\n", mas.last, r_end); + } RCU_MT_BUG_ON(test, mas.last != r_end); if (i == reader->flip) { @@ -34472,6 +34487,7 @@ static void *rcu_reader_fwd(void *ptr) } i++; + p_node = mte_to_node(mas.node); } rcu_read_unlock(); usleep(test->pause); @@ -34552,8 +34568,8 @@ static void *rcu_reader_rev(void *ptr) alt = xa_mk_value(index + i * 2 + 1 + RCU_RANGE_COUNT); mt_dump(test->mt, mt_dump_dec); - printk("Error: %lu-%lu %p != %lu-%lu %p %p line %d i %d\n", - mas.index, mas.last, entry, + printk("Error: mas %p %lu-%lu %p != %lu-%lu %p %p line %d i %d\n", + mas.node, mas.index, mas.last, entry, r_start, r_end, expected, alt, line, i); } @@ -36367,7 +36383,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); @@ -36424,8 +36440,8 @@ void farmer_tests(void) check_mtree_dup(&tree); mtree_destroy(&tree); -skip: /* RCU testing */ +skip: mt_init_flags(&tree, 0); check_erase_testset(&tree); mtree_destroy(&tree); @@ -36542,10 +36558,10 @@ static void regression_tests(void) void maple_tree_tests(void) { - maple_tree_seed(); - maple_tree_harvest(); + //maple_tree_seed(); + //maple_tree_harvest(); #if !defined(BENCH) - regression_tests(); + //regression_tests(); farmer_tests(); #endif }