From: Liam R. Howlett <Liam.Howlett@oracle.com>
Date: Fri, 23 May 2025 16:28:03 +0000 (-0400)
Subject: force span of null endings and rewind of sd fixed
X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=100646a74d463e0b84a32f0c94a3ddd40f3bba01;p=users%2Fjedix%2Flinux-maple.git

force span of null endings and rewind of sd fixed

Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
---

diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index 2076450e20bb..5c0986d0f52a 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -2620,6 +2620,7 @@ static inline void mas_topiary_replace(struct ma_state *mas,
 		mas_topiary_node(mas, &tmp[i], in_rcu);
 
 	mas_mat_destroy(mas, &subtrees);
+	printk("\n\n");
 }
 
 /*
@@ -3155,11 +3156,19 @@ void mns_node_part_span_leaf_init(struct ma_node_part *part,
 		part->skip++;
 	}
 
-	part->skip = wr_r->offset_end - wr_l->mas->offset + wr_l->mas->end + 1;
+	part->skip = wr_r->offset_end - wr_l->mas->offset + 1;
+	if (wr_r->node != wr_l->node)
+		part->skip += wr_l->mas->end;
 	part->leaf = true;
-	printk("%s skip %u (%u - %u + %u + 1)\n", __func__, part->skip,
-	       wr_r->offset_end, wr_l->mas->offset, wr_l->mas->end);
+
+	printk("%s skip %u (1 + %u - %u",__func__, part->skip,
+	       wr_r->offset_end, wr_l->mas->offset);
+	if (wr_r->node != wr_l->node)
+		printk("+ %u + 1", wr_l->mas->end);
+
+	printk(")\n");
 }
+
 static inline
 void mni_node_part_init(struct ma_node_part *part,
 		struct ma_node_info *left, struct ma_node_info *right)
@@ -3447,8 +3456,10 @@ 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->max != ULONG_MAX) {
+			printk("offset %u is null\n", p->offset - 1);
 			BUG_ON(p->slots[p->offset - 1] == NULL);
+		}
 	} else {
 		unsigned long gap_off = 0;
 		if (p->gaps) {
@@ -4969,6 +4980,7 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
 	struct split_data sd;
 	struct ma_node_part part;
 	unsigned long min;
+	bool force_more = false;
 
 	mas = wr_mas->mas;
 	trace_ma_op(__func__, mas);
@@ -4986,7 +4998,6 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
 		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);
 	if (!wr_mas->entry && r_mas.offset == r_mas.end) {
@@ -5027,6 +5038,11 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
 	printk("wr_mas offset end is %u\n", wr_mas->offset_end);
 	printk("src is %p slots is %p\n", right.node, right.slots);
 	mns_node_part_span_leaf_init(&part, wr_mas, &r_wr_mas, &right);
+	if (wr_mas->node == r_wr_mas.node){
+		printk("FORCE DATA\n");
+		force_more = true;
+	}
+
 	do {
 		height++;
 		d = s = 0;
@@ -5049,8 +5065,9 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
 		 */
 		/* Set up sources (up to 3) + part (always) */
 		sd.new_end = mas->end - part.skip + 1 + part.size;
-		if (r_mas.node != mas->node)
+		if (r_mas.node != mas->node) {
 			sd.new_end += r_mas.end;
+		}
 
 		printk("\tAt %p and r_mas %p\n", mas_mn(mas), mas_mn(&r_mas));
 		printk("new end is %u (%u + %u - %u + 1 + %u)\n", sd.new_end,
@@ -5059,27 +5076,29 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
 		mas_wr_ascend_init(mas, &parent);
 		printk("ascend is %u (%u + %u - %u + 1 + %u)\n", sd.new_end,
 		       r_mas.end, mas->end, part.skip, part.size);
-		if (sd.new_end < mt_min_slots[left.type] &&
-		    !ma_is_root(left.node) &&
-		    (left.min || right.max != ULONG_MAX)) {
+		if ((sd.new_end < mt_min_slots[left.type] &&
+		     !ma_is_root(left.node) &&
+		     (left.min || right.max != ULONG_MAX)) ||
+		    unlikely(force_more)) {
+			force_more = false;
 			/* Take in more nodes */
 			printk("!!! %d min slots not met\n", __LINE__);
 			if (r_parent.insert_off < r_parent.end) {
 				src[2] = &other;
-			printk("%d: set src %u\n", __LINE__, 2);
+				printk("%d: set src %u\n", __LINE__, 2);
 				mas_next_node(&r_mas, r_parent.node, ULONG_MAX);
-				other = r_parent;
-				other.insert_off++;
 				r_parent.insert_off++;
+				other = r_parent;
+				printk("r_parent insert off is now %u\n",
+				       r_parent.insert_off);
 				printk("Looks like there is a right sibling\n");
 			} else if (parent.insert_off) {
 				printk("%d: set src %u\n", __LINE__, s);
 				src[0] = &other;
 				s++;
 				mas_prev_node(mas, 0);
-				other = parent;
-				other.insert_off--;
 				parent.insert_off--;
+				other = parent;
 				printk("Looks like there is a left sibling\n");
 			} else if (r_parent.max > ULONG_MAX) {
 			printk("%d: set src %u\n", __LINE__, 2);
@@ -5096,12 +5115,13 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
 				s++;
 				mas_prev_node(mas, 0);
 				mni_mas_init(&other, &r_mas);
-				parent.offset--;
+				parent.insert_off--;
 				printk("Looks like there is a left cousin\n");
 				BUG_ON(1);
 			}
 
 			mni_descend(&other);
+			printk("descended other into %p with end %u\n", other.node, other.end);
 			sd.new_end += other.end + 1;
 			printk("new end is now %u\n", sd.new_end);
 		}
@@ -5170,16 +5190,22 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
 			unsigned char max = limits[d] + 1 - sd.offset;
 
 			printk("limits is %u/%u\n", limits[d], sd.offset);
-			printk("pass dst %p\n", &dst[d]);
+			printk("pass %u dst %p (%p)\n", d, &dst[d], dst[d].node);
 			spanning_append(&sd, src[s], &dst[d], max);
 			/* destination full */
+			printk("offset %u > %u\n", sd.offset, limits[d]);
 			if (sd.offset > limits[d]) {
 				/* Check NULL.. */
 				if (ma_is_leaf(src[s]->type)
 				    && mns_ends_in_null(&sd.states[sd.len - 1])) {
-					sd.states[sd.len - 1].size--;
+					printk("\tnull correction\n");
+					if (sd.states[sd.len - 1].size > 1)
+						sd.states[sd.len - 1].size--;
+					else
+						sd.len--;
 					limits[d]--;
 					sd.offset--;
+					src[s]->offset--;
 				}
 				dst[d].max = src[s]->pivots[src[s]->offset - 1];
 				dst[d].offset = 0;
@@ -8971,14 +8997,15 @@ void mt_validate(struct maple_tree *mt)
 		mas_descend(&mas);
 
 	while (!mas_is_overflow(&mas)) {
+		if (mte_dead_node(mas.node))
+			printk("DEAD NODE! %p\n", mte_to_node(mas.node));
 		MAS_WARN_ON(&mas, mte_dead_node(mas.node));
 		end = mas_data_end(&mas);
-		if (end < mt_min_slot_count(mas.node) &&
-				(mas.max != ULONG_MAX))
+		if (!mte_is_root(mas.node) && (end < mt_min_slot_count(mas.node)))
 		pr_err("Invalid size %u of " PTR_FMT "\n",
 		       end, mas_mn(&mas));
-		if (MAS_WARN_ON(&mas, (end < mt_min_slot_count(mas.node)) &&
-				(!mte_is_root(mas.node)))) {
+		if (!mte_is_root(mas.node) &&
+		     MAS_WARN_ON(&mas, (end < mt_min_slot_count(mas.node)))) {
 			pr_err("Invalid size %u of " PTR_FMT "\n",
 			       end, mas_mn(&mas));
 		}