diff options
Diffstat (limited to 'include/linux/idr.h')
-rw-r--r-- | include/linux/idr.h | 210 |
1 files changed, 143 insertions, 67 deletions
diff --git a/include/linux/idr.h b/include/linux/idr.h index de7e190f1af4..2640c7e99e51 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h | |||
@@ -17,69 +17,40 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
19 | 19 | ||
20 | #if BITS_PER_LONG == 32 | 20 | /* |
21 | # define IDR_BITS 5 | 21 | * We want shallower trees and thus more bits covered at each layer. 8 |
22 | # define IDR_FULL 0xfffffffful | 22 | * bits gives us large enough first layer for most use cases and maximum |
23 | /* We can only use two of the bits in the top level because there is | 23 | * tree depth of 4. Each idr_layer is slightly larger than 2k on 64bit and |
24 | only one possible bit in the top level (5 bits * 7 levels = 35 | 24 | * 1k on 32bit. |
25 | bits, but you only use 31 bits in the id). */ | 25 | */ |
26 | # define TOP_LEVEL_FULL (IDR_FULL >> 30) | 26 | #define IDR_BITS 8 |
27 | #elif BITS_PER_LONG == 64 | ||
28 | # define IDR_BITS 6 | ||
29 | # define IDR_FULL 0xfffffffffffffffful | ||
30 | /* We can only use two of the bits in the top level because there is | ||
31 | only one possible bit in the top level (6 bits * 6 levels = 36 | ||
32 | bits, but you only use 31 bits in the id). */ | ||
33 | # define TOP_LEVEL_FULL (IDR_FULL >> 62) | ||
34 | #else | ||
35 | # error "BITS_PER_LONG is not 32 or 64" | ||
36 | #endif | ||
37 | |||
38 | #define IDR_SIZE (1 << IDR_BITS) | 27 | #define IDR_SIZE (1 << IDR_BITS) |
39 | #define IDR_MASK ((1 << IDR_BITS)-1) | 28 | #define IDR_MASK ((1 << IDR_BITS)-1) |
40 | 29 | ||
41 | #define MAX_IDR_SHIFT (sizeof(int)*8 - 1) | ||
42 | #define MAX_IDR_BIT (1U << MAX_IDR_SHIFT) | ||
43 | #define MAX_IDR_MASK (MAX_IDR_BIT - 1) | ||
44 | |||
45 | /* Leave the possibility of an incomplete final layer */ | ||
46 | #define MAX_IDR_LEVEL ((MAX_IDR_SHIFT + IDR_BITS - 1) / IDR_BITS) | ||
47 | |||
48 | /* Number of id_layer structs to leave in free list */ | ||
49 | #define MAX_IDR_FREE (MAX_IDR_LEVEL * 2) | ||
50 | |||
51 | struct idr_layer { | 30 | struct idr_layer { |
52 | unsigned long bitmap; /* A zero bit means "space here" */ | 31 | int prefix; /* the ID prefix of this idr_layer */ |
32 | DECLARE_BITMAP(bitmap, IDR_SIZE); /* A zero bit means "space here" */ | ||
53 | struct idr_layer __rcu *ary[1<<IDR_BITS]; | 33 | struct idr_layer __rcu *ary[1<<IDR_BITS]; |
54 | int count; /* When zero, we can release it */ | 34 | int count; /* When zero, we can release it */ |
55 | int layer; /* distance from leaf */ | 35 | int layer; /* distance from leaf */ |
56 | struct rcu_head rcu_head; | 36 | struct rcu_head rcu_head; |
57 | }; | 37 | }; |
58 | 38 | ||
59 | struct idr { | 39 | struct idr { |
60 | struct idr_layer __rcu *top; | 40 | struct idr_layer __rcu *hint; /* the last layer allocated from */ |
61 | struct idr_layer *id_free; | 41 | struct idr_layer __rcu *top; |
62 | int layers; /* only valid without concurrent changes */ | 42 | struct idr_layer *id_free; |
63 | int id_free_cnt; | 43 | int layers; /* only valid w/o concurrent changes */ |
64 | spinlock_t lock; | 44 | int id_free_cnt; |
45 | spinlock_t lock; | ||
65 | }; | 46 | }; |
66 | 47 | ||
67 | #define IDR_INIT(name) \ | 48 | #define IDR_INIT(name) \ |
68 | { \ | 49 | { \ |
69 | .top = NULL, \ | 50 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ |
70 | .id_free = NULL, \ | ||
71 | .layers = 0, \ | ||
72 | .id_free_cnt = 0, \ | ||
73 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ | ||
74 | } | 51 | } |
75 | #define DEFINE_IDR(name) struct idr name = IDR_INIT(name) | 52 | #define DEFINE_IDR(name) struct idr name = IDR_INIT(name) |
76 | 53 | ||
77 | /* Actions to be taken after a call to _idr_sub_alloc */ | ||
78 | #define IDR_NEED_TO_GROW -2 | ||
79 | #define IDR_NOMORE_SPACE -3 | ||
80 | |||
81 | #define _idr_rc_to_errno(rc) ((rc) == -1 ? -EAGAIN : -ENOSPC) | ||
82 | |||
83 | /** | 54 | /** |
84 | * DOC: idr sync | 55 | * DOC: idr sync |
85 | * idr synchronization (stolen from radix-tree.h) | 56 | * idr synchronization (stolen from radix-tree.h) |
@@ -101,19 +72,124 @@ struct idr { | |||
101 | * This is what we export. | 72 | * This is what we export. |
102 | */ | 73 | */ |
103 | 74 | ||
104 | void *idr_find(struct idr *idp, int id); | 75 | void *idr_find_slowpath(struct idr *idp, int id); |
105 | int idr_pre_get(struct idr *idp, gfp_t gfp_mask); | 76 | void idr_preload(gfp_t gfp_mask); |
106 | int idr_get_new(struct idr *idp, void *ptr, int *id); | 77 | int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask); |
107 | int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); | ||
108 | int idr_for_each(struct idr *idp, | 78 | int idr_for_each(struct idr *idp, |
109 | int (*fn)(int id, void *p, void *data), void *data); | 79 | int (*fn)(int id, void *p, void *data), void *data); |
110 | void *idr_get_next(struct idr *idp, int *nextid); | 80 | void *idr_get_next(struct idr *idp, int *nextid); |
111 | void *idr_replace(struct idr *idp, void *ptr, int id); | 81 | void *idr_replace(struct idr *idp, void *ptr, int id); |
112 | void idr_remove(struct idr *idp, int id); | 82 | void idr_remove(struct idr *idp, int id); |
113 | void idr_remove_all(struct idr *idp); | 83 | void idr_free(struct idr *idp, int id); |
114 | void idr_destroy(struct idr *idp); | 84 | void idr_destroy(struct idr *idp); |
115 | void idr_init(struct idr *idp); | 85 | void idr_init(struct idr *idp); |
116 | 86 | ||
87 | /** | ||
88 | * idr_preload_end - end preload section started with idr_preload() | ||
89 | * | ||
90 | * Each idr_preload() should be matched with an invocation of this | ||
91 | * function. See idr_preload() for details. | ||
92 | */ | ||
93 | static inline void idr_preload_end(void) | ||
94 | { | ||
95 | preempt_enable(); | ||
96 | } | ||
97 | |||
98 | /** | ||
99 | * idr_find - return pointer for given id | ||
100 | * @idr: idr handle | ||
101 | * @id: lookup key | ||
102 | * | ||
103 | * Return the pointer given the id it has been registered with. A %NULL | ||
104 | * return indicates that @id is not valid or you passed %NULL in | ||
105 | * idr_get_new(). | ||
106 | * | ||
107 | * This function can be called under rcu_read_lock(), given that the leaf | ||
108 | * pointers lifetimes are correctly managed. | ||
109 | */ | ||
110 | static inline void *idr_find(struct idr *idr, int id) | ||
111 | { | ||
112 | struct idr_layer *hint = rcu_dereference_raw(idr->hint); | ||
113 | |||
114 | if (hint && (id & ~IDR_MASK) == hint->prefix) | ||
115 | return rcu_dereference_raw(hint->ary[id & IDR_MASK]); | ||
116 | |||
117 | return idr_find_slowpath(idr, id); | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * idr_for_each_entry - iterate over an idr's elements of a given type | ||
122 | * @idp: idr handle | ||
123 | * @entry: the type * to use as cursor | ||
124 | * @id: id entry's key | ||
125 | */ | ||
126 | #define idr_for_each_entry(idp, entry, id) \ | ||
127 | for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \ | ||
128 | entry != NULL; \ | ||
129 | ++id, entry = (typeof(entry))idr_get_next((idp), &(id))) | ||
130 | |||
131 | /* | ||
132 | * Don't use the following functions. These exist only to suppress | ||
133 | * deprecated warnings on EXPORT_SYMBOL()s. | ||
134 | */ | ||
135 | int __idr_pre_get(struct idr *idp, gfp_t gfp_mask); | ||
136 | int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); | ||
137 | void __idr_remove_all(struct idr *idp); | ||
138 | |||
139 | /** | ||
140 | * idr_pre_get - reserve resources for idr allocation | ||
141 | * @idp: idr handle | ||
142 | * @gfp_mask: memory allocation flags | ||
143 | * | ||
144 | * Part of old alloc interface. This is going away. Use | ||
145 | * idr_preload[_end]() and idr_alloc() instead. | ||
146 | */ | ||
147 | static inline int __deprecated idr_pre_get(struct idr *idp, gfp_t gfp_mask) | ||
148 | { | ||
149 | return __idr_pre_get(idp, gfp_mask); | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * idr_get_new_above - allocate new idr entry above or equal to a start id | ||
154 | * @idp: idr handle | ||
155 | * @ptr: pointer you want associated with the id | ||
156 | * @starting_id: id to start search at | ||
157 | * @id: pointer to the allocated handle | ||
158 | * | ||
159 | * Part of old alloc interface. This is going away. Use | ||
160 | * idr_preload[_end]() and idr_alloc() instead. | ||
161 | */ | ||
162 | static inline int __deprecated idr_get_new_above(struct idr *idp, void *ptr, | ||
163 | int starting_id, int *id) | ||
164 | { | ||
165 | return __idr_get_new_above(idp, ptr, starting_id, id); | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * idr_get_new - allocate new idr entry | ||
170 | * @idp: idr handle | ||
171 | * @ptr: pointer you want associated with the id | ||
172 | * @id: pointer to the allocated handle | ||
173 | * | ||
174 | * Part of old alloc interface. This is going away. Use | ||
175 | * idr_preload[_end]() and idr_alloc() instead. | ||
176 | */ | ||
177 | static inline int __deprecated idr_get_new(struct idr *idp, void *ptr, int *id) | ||
178 | { | ||
179 | return __idr_get_new_above(idp, ptr, 0, id); | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * idr_remove_all - remove all ids from the given idr tree | ||
184 | * @idp: idr handle | ||
185 | * | ||
186 | * If you're trying to destroy @idp, calling idr_destroy() is enough. | ||
187 | * This is going away. Don't use. | ||
188 | */ | ||
189 | static inline void __deprecated idr_remove_all(struct idr *idp) | ||
190 | { | ||
191 | __idr_remove_all(idp); | ||
192 | } | ||
117 | 193 | ||
118 | /* | 194 | /* |
119 | * IDA - IDR based id allocator, use when translation from id to | 195 | * IDA - IDR based id allocator, use when translation from id to |
@@ -136,12 +212,11 @@ struct ida { | |||
136 | struct ida_bitmap *free_bitmap; | 212 | struct ida_bitmap *free_bitmap; |
137 | }; | 213 | }; |
138 | 214 | ||
139 | #define IDA_INIT(name) { .idr = IDR_INIT(name), .free_bitmap = NULL, } | 215 | #define IDA_INIT(name) { .idr = IDR_INIT((name).idr), .free_bitmap = NULL, } |
140 | #define DEFINE_IDA(name) struct ida name = IDA_INIT(name) | 216 | #define DEFINE_IDA(name) struct ida name = IDA_INIT(name) |
141 | 217 | ||
142 | int ida_pre_get(struct ida *ida, gfp_t gfp_mask); | 218 | int ida_pre_get(struct ida *ida, gfp_t gfp_mask); |
143 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id); | 219 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id); |
144 | int ida_get_new(struct ida *ida, int *p_id); | ||
145 | void ida_remove(struct ida *ida, int id); | 220 | void ida_remove(struct ida *ida, int id); |
146 | void ida_destroy(struct ida *ida); | 221 | void ida_destroy(struct ida *ida); |
147 | void ida_init(struct ida *ida); | 222 | void ida_init(struct ida *ida); |
@@ -150,17 +225,18 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, | |||
150 | gfp_t gfp_mask); | 225 | gfp_t gfp_mask); |
151 | void ida_simple_remove(struct ida *ida, unsigned int id); | 226 | void ida_simple_remove(struct ida *ida, unsigned int id); |
152 | 227 | ||
153 | void __init idr_init_cache(void); | ||
154 | |||
155 | /** | 228 | /** |
156 | * idr_for_each_entry - iterate over an idr's elements of a given type | 229 | * ida_get_new - allocate new ID |
157 | * @idp: idr handle | 230 | * @ida: idr handle |
158 | * @entry: the type * to use as cursor | 231 | * @p_id: pointer to the allocated handle |
159 | * @id: id entry's key | 232 | * |
233 | * Simple wrapper around ida_get_new_above() w/ @starting_id of zero. | ||
160 | */ | 234 | */ |
161 | #define idr_for_each_entry(idp, entry, id) \ | 235 | static inline int ida_get_new(struct ida *ida, int *p_id) |
162 | for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \ | 236 | { |
163 | entry != NULL; \ | 237 | return ida_get_new_above(ida, 0, p_id); |
164 | ++id, entry = (typeof(entry))idr_get_next((idp), &(id))) | 238 | } |
239 | |||
240 | void __init idr_init_cache(void); | ||
165 | 241 | ||
166 | #endif /* __IDR_H__ */ | 242 | #endif /* __IDR_H__ */ |