diff options
Diffstat (limited to 'include/linux/radix-tree.h')
-rw-r--r-- | include/linux/radix-tree.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index cbfa11537421..0deb842541ac 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Momchil Velikov | 2 | * Copyright (C) 2001 Momchil Velikov |
3 | * Portions Copyright (C) 2001 Christoph Hellwig | 3 | * Portions Copyright (C) 2001 Christoph Hellwig |
4 | * Copyright (C) 2006 Nick Piggin | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 7 | * modify it under the terms of the GNU General Public License as |
@@ -21,6 +22,35 @@ | |||
21 | 22 | ||
22 | #include <linux/preempt.h> | 23 | #include <linux/preempt.h> |
23 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/kernel.h> | ||
26 | #include <linux/rcupdate.h> | ||
27 | |||
28 | /* | ||
29 | * A direct pointer (root->rnode pointing directly to a data item, | ||
30 | * rather than another radix_tree_node) is signalled by the low bit | ||
31 | * set in the root->rnode pointer. | ||
32 | * | ||
33 | * In this case root->height is also NULL, but the direct pointer tests are | ||
34 | * needed for RCU lookups when root->height is unreliable. | ||
35 | */ | ||
36 | #define RADIX_TREE_DIRECT_PTR 1 | ||
37 | |||
38 | static inline void *radix_tree_ptr_to_direct(void *ptr) | ||
39 | { | ||
40 | return (void *)((unsigned long)ptr | RADIX_TREE_DIRECT_PTR); | ||
41 | } | ||
42 | |||
43 | static inline void *radix_tree_direct_to_ptr(void *ptr) | ||
44 | { | ||
45 | return (void *)((unsigned long)ptr & ~RADIX_TREE_DIRECT_PTR); | ||
46 | } | ||
47 | |||
48 | static inline int radix_tree_is_direct_ptr(void *ptr) | ||
49 | { | ||
50 | return (int)((unsigned long)ptr & RADIX_TREE_DIRECT_PTR); | ||
51 | } | ||
52 | |||
53 | /*** radix-tree API starts here ***/ | ||
24 | 54 | ||
25 | #define RADIX_TREE_MAX_TAGS 2 | 55 | #define RADIX_TREE_MAX_TAGS 2 |
26 | 56 | ||
@@ -47,6 +77,77 @@ do { \ | |||
47 | (root)->rnode = NULL; \ | 77 | (root)->rnode = NULL; \ |
48 | } while (0) | 78 | } while (0) |
49 | 79 | ||
80 | /** | ||
81 | * Radix-tree synchronization | ||
82 | * | ||
83 | * The radix-tree API requires that users provide all synchronisation (with | ||
84 | * specific exceptions, noted below). | ||
85 | * | ||
86 | * Synchronization of access to the data items being stored in the tree, and | ||
87 | * management of their lifetimes must be completely managed by API users. | ||
88 | * | ||
89 | * For API usage, in general, | ||
90 | * - any function _modifying_ the the tree or tags (inserting or deleting | ||
91 | * items, setting or clearing tags must exclude other modifications, and | ||
92 | * exclude any functions reading the tree. | ||
93 | * - any function _reading_ the the tree or tags (looking up items or tags, | ||
94 | * gang lookups) must exclude modifications to the tree, but may occur | ||
95 | * concurrently with other readers. | ||
96 | * | ||
97 | * The notable exceptions to this rule are the following functions: | ||
98 | * radix_tree_lookup | ||
99 | * radix_tree_tag_get | ||
100 | * radix_tree_gang_lookup | ||
101 | * radix_tree_gang_lookup_tag | ||
102 | * radix_tree_tagged | ||
103 | * | ||
104 | * The first 4 functions are able to be called locklessly, using RCU. The | ||
105 | * caller must ensure calls to these functions are made within rcu_read_lock() | ||
106 | * regions. Other readers (lock-free or otherwise) and modifications may be | ||
107 | * running concurrently. | ||
108 | * | ||
109 | * It is still required that the caller manage the synchronization and lifetimes | ||
110 | * of the items. So if RCU lock-free lookups are used, typically this would mean | ||
111 | * that the items have their own locks, or are amenable to lock-free access; and | ||
112 | * that the items are freed by RCU (or only freed after having been deleted from | ||
113 | * the radix tree *and* a synchronize_rcu() grace period). | ||
114 | * | ||
115 | * (Note, rcu_assign_pointer and rcu_dereference are not needed to control | ||
116 | * access to data items when inserting into or looking up from the radix tree) | ||
117 | * | ||
118 | * radix_tree_tagged is able to be called without locking or RCU. | ||
119 | */ | ||
120 | |||
121 | /** | ||
122 | * radix_tree_deref_slot - dereference a slot | ||
123 | * @pslot: pointer to slot, returned by radix_tree_lookup_slot | ||
124 | * Returns: item that was stored in that slot with any direct pointer flag | ||
125 | * removed. | ||
126 | * | ||
127 | * For use with radix_tree_lookup_slot(). Caller must hold tree at least read | ||
128 | * locked across slot lookup and dereference. More likely, will be used with | ||
129 | * radix_tree_replace_slot(), as well, so caller will hold tree write locked. | ||
130 | */ | ||
131 | static inline void *radix_tree_deref_slot(void **pslot) | ||
132 | { | ||
133 | return radix_tree_direct_to_ptr(*pslot); | ||
134 | } | ||
135 | /** | ||
136 | * radix_tree_replace_slot - replace item in a slot | ||
137 | * @pslot: pointer to slot, returned by radix_tree_lookup_slot | ||
138 | * @item: new item to store in the slot. | ||
139 | * | ||
140 | * For use with radix_tree_lookup_slot(). Caller must hold tree write locked | ||
141 | * across slot lookup and replacement. | ||
142 | */ | ||
143 | static inline void radix_tree_replace_slot(void **pslot, void *item) | ||
144 | { | ||
145 | BUG_ON(radix_tree_is_direct_ptr(item)); | ||
146 | rcu_assign_pointer(*pslot, | ||
147 | (void *)((unsigned long)item | | ||
148 | ((unsigned long)*pslot & RADIX_TREE_DIRECT_PTR))); | ||
149 | } | ||
150 | |||
50 | int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); | 151 | int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); |
51 | void *radix_tree_lookup(struct radix_tree_root *, unsigned long); | 152 | void *radix_tree_lookup(struct radix_tree_root *, unsigned long); |
52 | void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); | 153 | void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); |