]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Avoid BUG_ON() when setting a leaf node as a parent maple_v6.1-rc5_upstream
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Thu, 1 Sep 2022 01:03:02 +0000 (21:03 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Mon, 28 Nov 2022 20:18:34 +0000 (15:18 -0500)
Don't crash the kernel in the very unlikely case that the node passed as
the parent is actually a leaf.  Instead, use MT_WARN_ON() to increase
the probability of the debug information being recorded.

Pass through the maple state so the maple tree can be retrieved.

Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
lib/maple_tree.c

index 832d1e8e1eb3d9a75d8b5b554fe73c10d10d1dbb..0241c6c14c1d0c1d2df821addf38b93ea4326000 100644 (file)
@@ -455,7 +455,7 @@ enum maple_type mas_parent_enum(struct ma_state *mas, struct maple_enode *enode)
 }
 
 /*
- * mte_set_parent() - Set the parent node and encode the slot
+ * mas_set_parent() - Set the parent node and encode the slot
  * @enode: The encoded maple node.
  * @parent: The encoded maple node that is the parent of @enode.
  * @slot: The slot that @enode resides in @parent.
@@ -464,16 +464,19 @@ enum maple_type mas_parent_enum(struct ma_state *mas, struct maple_enode *enode)
  * parent type.
  */
 static inline
-void mte_set_parent(struct maple_enode *enode, const struct maple_enode *parent,
-                   unsigned char slot)
+void mas_set_parent(struct ma_state *mas, struct maple_enode *enode,
+                   const struct maple_enode *parent, unsigned char slot)
 {
        unsigned long val = (unsigned long) parent;
        unsigned long shift;
        unsigned long type;
        enum maple_type p_type = mte_node_type(parent);
 
-       BUG_ON(p_type == maple_dense);
-       BUG_ON(p_type == maple_leaf_64);
+       if (MT_WARN_ON(mas->tree, p_type == maple_dense))
+               pr_err("Dense node %p cannot be parent\n", parent);
+
+       if (MT_WARN_ON(mas->tree, p_type == maple_leaf_64))
+               pr_err("Leaf node %p cannot be parent\n", parent);
 
        switch (p_type) {
        case maple_range_64:
@@ -1741,7 +1744,7 @@ static inline void mas_adopt_children(struct ma_state *mas,
        offset = ma_data_end(node, type, pivots, mas->max);
        do {
                child = mas_slot_locked(mas, slots, offset);
-               mte_set_parent(child, parent, offset);
+               mas_set_parent(mas, child, parent, offset);
        } while (offset--);
 }
 
@@ -2710,7 +2713,7 @@ static inline void mab_set_b_end(struct maple_big_node *b_node,
 }
 
 /*
- * mte_set_split_parent() - combine_then_separate helper function.  Sets the parent
+ * mas_set_split_parent() - combine_then_separate helper function.  Sets the parent
  * of @mas->node to either @left or @right, depending on @slot and @split
  *
  * @mas - the maple state with the node that needs a parent
@@ -2719,18 +2722,17 @@ static inline void mab_set_b_end(struct maple_big_node *b_node,
  * @slot - the slot the mas->node was placed
  * @split - the split location between @left and @right
  */
-static inline void mte_set_split_parent(struct maple_enode *enode,
-                                       struct maple_enode *left,
-                                       struct maple_enode *right,
-                                       unsigned char *slot, unsigned char split)
+static inline void mas_set_split_parent(struct ma_state *mas,
+       struct maple_enode *enode, struct maple_enode *left,
+       struct maple_enode *right, unsigned char *slot, unsigned char split)
 {
        if (enode == MAS_NONE)
                return;
 
        if ((*slot) <= split)
-               mte_set_parent(enode, left, *slot);
+               mas_set_parent(mas, enode, left, *slot);
        else if (right)
-               mte_set_parent(enode, right, (*slot) - split - 1);
+               mas_set_parent(mas, enode, right, (*slot) - split - 1);
 
        (*slot)++;
 }
@@ -2790,13 +2792,13 @@ static inline void mast_set_split_parents(struct maple_subtree_state *mast,
        slot = mast->l->offset;
 
        mte_mid_split_check(&l, &r, right, slot, &split, mid_split);
-       mte_set_split_parent(mast->l->node, l, r, &slot, split);
+       mas_set_split_parent(mast->l, mast->l->node, l, r, &slot, split);
 
        mte_mid_split_check(&l, &r, right, slot, &split, mid_split);
-       mte_set_split_parent(mast->m->node, l, r, &slot, split);
+       mas_set_split_parent(mast->m, mast->m->node, l, r, &slot, split);
 
        mte_mid_split_check(&l, &r, right, slot, &split, mid_split);
-       mte_set_split_parent(mast->r->node, l, r, &slot, split);
+       mas_set_split_parent(mast->r, mast->r->node, l, r, &slot, split);
 }
 
 /*
@@ -3125,12 +3127,12 @@ static int mas_spanning_rebalance(struct ma_state *mas,
                                mte_node_type(mast->orig_l->node));
        mast->orig_l->depth++;
        mab_mas_cp(mast->bn, 0, mt_slots[mast->bn->type] - 1, &l_mas, true);
-       mte_set_parent(left, l_mas.node, slot);
+       mas_set_parent(mas, left, l_mas.node, slot);
        if (middle)
-               mte_set_parent(middle, l_mas.node, ++slot);
+               mas_set_parent(mas, middle, l_mas.node, ++slot);
 
        if (right)
-               mte_set_parent(right, l_mas.node, ++slot);
+               mas_set_parent(mas, right, l_mas.node, ++slot);
 
        if (mas_is_root_limits(mast->l)) {
 new_root:
@@ -3357,8 +3359,8 @@ static inline bool mas_split_final_node(struct maple_split_state *mss,
         * The Big_node data should just fit in a single node.
         */
        ancestor = mas_new_ma_node(mas, mss->bn);
-       mte_set_parent(mss->l->node, ancestor, mss->l->offset);
-       mte_set_parent(mss->r->node, ancestor, mss->r->offset);
+       mas_set_parent(mas, mss->l->node, ancestor, mss->l->offset);
+       mas_set_parent(mas, mss->r->node, ancestor, mss->r->offset);
        mte_to_node(ancestor)->parent = mas_mn(mas)->parent;
 
        mss->l->node = ancestor;
@@ -3424,9 +3426,9 @@ static inline void mss_split_data(struct maple_split_state *mss,
                return;
 
        p_slot = mss->offset;
-       mte_set_split_parent(mss->l_node, mss->l->node, mss->r->node,
+       mas_set_split_parent(mas, mss->l_node, mss->l->node, mss->r->node,
                             &p_slot, split);
-       mte_set_split_parent(mss->r_node, mss->l->node, mss->r->node,
+       mas_set_split_parent(mas, mss->r_node, mss->l->node, mss->r->node,
                             &p_slot, split);
 }