raxix-tree: introduce CONFIG_RADIX_TREE_MULTIORDER
authorMatthew Wilcox <willy@linux.intel.com>
Sat, 21 May 2016 00:01:54 +0000 (17:01 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 21 May 2016 00:58:30 +0000 (17:58 -0700)
I've been receiving increasingly concerned notes from 0day about how
much my recent changes have been bloating the radix tree.  Make it
happier by only including multiorder support if
CONFIG_TRANSPARENT_HUGEPAGES is set.

This is an independent Kconfig option, so other radix tree users can
also set it if they have a need.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Kirill Shutemov <kirill.shutemov@linux.intel.com>
Cc: Jan Kara <jack@suse.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
lib/Kconfig
lib/radix-tree.c
mm/Kconfig
tools/testing/radix-tree/linux/kernel.h

index 61d55bd..d79909d 100644 (file)
@@ -362,6 +362,9 @@ config INTERVAL_TREE
 
          for more information.
 
+config RADIX_TREE_MULTIORDER
+       bool
+
 config ASSOCIATIVE_ARRAY
        bool
        help
index 1624c41..799f341 100644 (file)
@@ -484,6 +484,7 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
                slot = node->slots[offset];
        }
 
+#ifdef CONFIG_RADIX_TREE_MULTIORDER
        /* Insert pointers to the canonical entry */
        if ((shift - order) > 0) {
                int i, n = 1 << (shift - order);
@@ -499,6 +500,7 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
                        node->count++;
                }
        }
+#endif
 
        if (nodep)
                *nodep = node;
@@ -1469,6 +1471,20 @@ bool __radix_tree_delete_node(struct radix_tree_root *root,
        return deleted;
 }
 
+static inline void delete_sibling_entries(struct radix_tree_node *node,
+                                       void *ptr, unsigned offset)
+{
+#ifdef CONFIG_RADIX_TREE_MULTIORDER
+       int i;
+       for (i = 1; offset + i < RADIX_TREE_MAP_SIZE; i++) {
+               if (node->slots[offset + i] != ptr)
+                       break;
+               node->slots[offset + i] = NULL;
+               node->count--;
+       }
+#endif
+}
+
 /**
  *     radix_tree_delete_item    -    delete an item from a radix tree
  *     @root:          radix tree root
@@ -1484,7 +1500,7 @@ void *radix_tree_delete_item(struct radix_tree_root *root,
                             unsigned long index, void *item)
 {
        struct radix_tree_node *node;
-       unsigned int offset, i;
+       unsigned int offset;
        void **slot;
        void *entry;
        int tag;
@@ -1513,13 +1529,7 @@ void *radix_tree_delete_item(struct radix_tree_root *root,
                        radix_tree_tag_clear(root, index, tag);
        }
 
-       /* Delete any sibling slots pointing to this slot */
-       for (i = 1; offset + i < RADIX_TREE_MAP_SIZE; i++) {
-               if (node->slots[offset + i] != ptr_to_indirect(slot))
-                       break;
-               node->slots[offset + i] = NULL;
-               node->count--;
-       }
+       delete_sibling_entries(node, ptr_to_indirect(slot), offset);
        node->slots[offset] = NULL;
        node->count--;
 
index 1a6a28e..2664c11 100644 (file)
@@ -404,6 +404,7 @@ config TRANSPARENT_HUGEPAGE
        bool "Transparent Hugepage Support"
        depends on HAVE_ARCH_TRANSPARENT_HUGEPAGE
        select COMPACTION
+       select RADIX_TREE_MULTIORDER
        help
          Transparent Hugepages allows the kernel to use huge pages and
          huge tlb transparently to the applications whenever possible.
index 31fe2c7..8ea0ed4 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "../../include/linux/compiler.h"
 
+#define CONFIG_RADIX_TREE_MULTIORDER
 #define CONFIG_SHMEM
 #define CONFIG_SWAP