]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
spanning store starts now
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 7 May 2025 00:09:09 +0000 (20:09 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 7 May 2025 00:09:09 +0000 (20:09 -0400)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
lib/maple_tree.c

index 544c72c983bec2f8450131537dbf0f8b75721b55..64ae95b02c08489e99d3610af56f02b493276add 100644 (file)
@@ -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