From: Liam R. Howlett Date: Thu, 1 Sep 2022 01:03:02 +0000 (-0400) Subject: maple_tree: Avoid BUG_ON() when setting a leaf node as a parent X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f9f40ad2a8afaa9fd422c684d6c3fcf740b5823c;p=users%2Fjedix%2Flinux-maple.git maple_tree: Avoid BUG_ON() when setting a leaf node as a parent 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 --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 832d1e8e1eb3..0241c6c14c1d 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -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); }