summaryrefslogtreecommitdiffstats
path: root/include/linux/radix-tree.h
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2014-04-03 17:47:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-03 19:21:01 -0400
commit139e561660fe11e0fc35e142a800df3dd7d03e9d (patch)
treeb46c699ad4840fb76e71fe17b340f890587e2f6a /include/linux/radix-tree.h
parenta528910e12ec7ee203095eb1711468a66b9b60b0 (diff)
lib: radix_tree: tree node interface
Make struct radix_tree_node part of the public interface and provide API functions to create, look up, and delete whole nodes. Refactor the existing insert, look up, delete functions on top of these new node primitives. This will allow the VM to track and garbage collect page cache radix tree nodes. [sasha.levin@oracle.com: return correct error code on insertion failure] Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Rik van Riel <riel@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Bob Liu <bob.liu@oracle.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Dave Chinner <david@fromorbit.com> Cc: Greg Thelen <gthelen@google.com> Cc: Hugh Dickins <hughd@google.com> Cc: Jan Kara <jack@suse.cz> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Luigi Semenzato <semenzato@google.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Metin Doslu <metin@citusdata.com> Cc: Michel Lespinasse <walken@google.com> Cc: Ozgun Erdogan <ozgun@citusdata.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Roman Gushchin <klamm@yandex-team.ru> Cc: Ryan Mallon <rmallon@gmail.com> Cc: Tejun Heo <tj@kernel.org> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Sasha Levin <sasha.levin@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/radix-tree.h')
-rw-r--r--include/linux/radix-tree.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index e8be53ecfc45..13636c40bc42 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -60,6 +60,33 @@ static inline int radix_tree_is_indirect_ptr(void *ptr)
60 60
61#define RADIX_TREE_MAX_TAGS 3 61#define RADIX_TREE_MAX_TAGS 3
62 62
63#ifdef __KERNEL__
64#define RADIX_TREE_MAP_SHIFT (CONFIG_BASE_SMALL ? 4 : 6)
65#else
66#define RADIX_TREE_MAP_SHIFT 3 /* For more stressful testing */
67#endif
68
69#define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT)
70#define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1)
71
72#define RADIX_TREE_TAG_LONGS \
73 ((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG)
74
75struct radix_tree_node {
76 unsigned int height; /* Height from the bottom */
77 unsigned int count;
78 union {
79 struct radix_tree_node *parent; /* Used when ascending tree */
80 struct rcu_head rcu_head; /* Used when freeing node */
81 };
82 void __rcu *slots[RADIX_TREE_MAP_SIZE];
83 unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS];
84};
85
86#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
87#define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \
88 RADIX_TREE_MAP_SHIFT))
89
63/* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */ 90/* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */
64struct radix_tree_root { 91struct radix_tree_root {
65 unsigned int height; 92 unsigned int height;
@@ -101,6 +128,7 @@ do { \
101 * concurrently with other readers. 128 * concurrently with other readers.
102 * 129 *
103 * The notable exceptions to this rule are the following functions: 130 * The notable exceptions to this rule are the following functions:
131 * __radix_tree_lookup
104 * radix_tree_lookup 132 * radix_tree_lookup
105 * radix_tree_lookup_slot 133 * radix_tree_lookup_slot
106 * radix_tree_tag_get 134 * radix_tree_tag_get
@@ -216,9 +244,15 @@ static inline void radix_tree_replace_slot(void **pslot, void *item)
216 rcu_assign_pointer(*pslot, item); 244 rcu_assign_pointer(*pslot, item);
217} 245}
218 246
247int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
248 struct radix_tree_node **nodep, void ***slotp);
219int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); 249int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
250void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index,
251 struct radix_tree_node **nodep, void ***slotp);
220void *radix_tree_lookup(struct radix_tree_root *, unsigned long); 252void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
221void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); 253void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
254bool __radix_tree_delete_node(struct radix_tree_root *root, unsigned long index,
255 struct radix_tree_node *node);
222void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *); 256void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *);
223void *radix_tree_delete(struct radix_tree_root *, unsigned long); 257void *radix_tree_delete(struct radix_tree_root *, unsigned long);
224unsigned int 258unsigned int