From: Liam R. Howlett Date: Tue, 25 Aug 2020 17:56:13 +0000 (-0400) Subject: maple_tree: Alloc at most 1 page of nodes during fork. X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=1020374d187ba2f0dfb5e7f2f5de09c2f464c5a7;p=users%2Fjedix%2Flinux-maple.git maple_tree: Alloc at most 1 page of nodes during fork. Also fix a corner case of root + children being 17 and thus failing out during a fork Signed-off-by: Liam R. Howlett --- diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h index 105731e081e34..20cb7c6cf4d7a 100644 --- a/include/linux/maple_tree.h +++ b/include/linux/maple_tree.h @@ -37,6 +37,7 @@ #define MAPLE_SPARSE16_SLOTS 24 /* 248 bytes */ #define MAPLE_SPARSE9_SLOTS 27 /* 256 bytes */ #define MAPLE_SPARSE6_SLOTS 30 /* 256 bytes */ +#define MA_NODE_PER_PAGE 16 #else #define MAPLE_NODE_SLOTS 15 /* 128 bytes including ->parent */ #define MAPLE_RANGE64_SLOTS 8 /* 128 bytes */ @@ -49,6 +50,7 @@ #define MAPLE_SPARSE16_SLOTS 12 /* 128 bytes */ #define MAPLE_SPARSE9_SLOTS 13 /* 127 bytes */ #define MAPLE_SPARSE6_SLOTS 14 /* 128 bytes */ +#define MA_NODE_PER_PAGE 32 #endif // End NODE256 #else diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 0d15a5cc99fa6..6733ab06e13f9 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -22,9 +22,6 @@ #define ma_parent_ptr(x) ((struct maple_pnode *)(x)) #define ma_mnode_ptr(x) ((struct maple_node *)(x)) #define ma_enode_ptr(x) ((struct maple_enode *)(x)) -#undef XA_RETRY_ENTRY -#undef XA_SKIP_ENTRY -#undef XA_DELETED_ENTRY static struct kmem_cache *maple_node_cache; @@ -572,6 +569,7 @@ static inline struct maple_enode *ma_get_rcu_slot( const struct maple_node *mn, unsigned char slot, enum maple_type type, struct maple_tree *mtree) { + switch (type) { case maple_range_64: case maple_leaf_64: @@ -4357,7 +4355,7 @@ static inline struct maple_enode *mas_dup_node(struct ma_state *oldmas, static inline void mas_dup_alloc(struct ma_state *mas, int *node_cnt) { - int alloc_cnt = min(*node_cnt, 127); + int alloc_cnt = min(*node_cnt, MA_NODE_PER_PAGE); /* Allocate nodes for new tree. Maximum will be 16 ** height */ *node_cnt -= alloc_cnt; mas_node_cnt(mas, alloc_cnt); @@ -4411,6 +4409,9 @@ static inline void mas_dup_tree_start(struct ma_state *oldmas, struct ma_state *mas, int *node_cnt) { + if (xa_is_node(mas->tree->ma_root)) + goto dup_children; + if (mas->alloc) goto allocated; @@ -4435,8 +4436,12 @@ allocated: mte_to_node(mas->node)->parent = ma_parent_ptr( ((unsigned long)mas->tree | MA_ROOT_PARENT)); rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node)); + +dup_children: if (!mte_is_leaf(oldmas->node)) { mas_dup_children(mas, node_cnt); + if (mas_is_err(mas)) + return; mas_adopt_children(mas, mas->node); } }