]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Alloc at most 1 page of nodes during fork.
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Tue, 25 Aug 2020 17:56:13 +0000 (13:56 -0400)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 30 Oct 2020 19:09:17 +0000 (15:09 -0400)
Also fix a corner case of root + children being 17 and thus failing out during a fork

Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
include/linux/maple_tree.h
lib/maple_tree.c

index 105731e081e34688848b080ea90a31bb54f82d6f..20cb7c6cf4d7aec15c7ee03da4a80414e2e072ce 100644 (file)
@@ -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
index 0d15a5cc99fa66ede59ffc2a2c1a1b9906f99393..6733ab06e13f9b44325f1c85d97dde96b76ebc07 100644 (file)
@@ -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);
        }
 }