aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/idr.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/idr.h')
-rw-r--r--include/linux/idr.h174
1 files changed, 75 insertions, 99 deletions
diff --git a/include/linux/idr.h b/include/linux/idr.h
index fa14f834e4ed..7d6a6313f0ab 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -15,10 +15,10 @@
15#include <linux/radix-tree.h> 15#include <linux/radix-tree.h>
16#include <linux/gfp.h> 16#include <linux/gfp.h>
17#include <linux/percpu.h> 17#include <linux/percpu.h>
18#include <linux/bug.h>
19 18
20struct idr { 19struct idr {
21 struct radix_tree_root idr_rt; 20 struct radix_tree_root idr_rt;
21 unsigned int idr_base;
22 unsigned int idr_next; 22 unsigned int idr_next;
23}; 23};
24 24
@@ -31,10 +31,26 @@ struct idr {
31/* Set the IDR flag and the IDR_FREE tag */ 31/* Set the IDR flag and the IDR_FREE tag */
32#define IDR_RT_MARKER ((__force gfp_t)(3 << __GFP_BITS_SHIFT)) 32#define IDR_RT_MARKER ((__force gfp_t)(3 << __GFP_BITS_SHIFT))
33 33
34#define IDR_INIT \ 34#define IDR_INIT_BASE(base) { \
35{ \ 35 .idr_rt = RADIX_TREE_INIT(IDR_RT_MARKER), \
36 .idr_rt = RADIX_TREE_INIT(IDR_RT_MARKER) \ 36 .idr_base = (base), \
37 .idr_next = 0, \
37} 38}
39
40/**
41 * IDR_INIT() - Initialise an IDR.
42 *
43 * A freshly-initialised IDR contains no IDs.
44 */
45#define IDR_INIT IDR_INIT_BASE(0)
46
47/**
48 * DEFINE_IDR() - Define a statically-allocated IDR
49 * @name: Name of IDR
50 *
51 * An IDR defined using this macro is ready for use with no additional
52 * initialisation required. It contains no IDs.
53 */
38#define DEFINE_IDR(name) struct idr name = IDR_INIT 54#define DEFINE_IDR(name) struct idr name = IDR_INIT
39 55
40/** 56/**
@@ -82,80 +98,52 @@ static inline void idr_set_cursor(struct idr *idr, unsigned int val)
82 98
83void idr_preload(gfp_t gfp_mask); 99void idr_preload(gfp_t gfp_mask);
84 100
85int idr_alloc_cmn(struct idr *idr, void *ptr, unsigned long *index, 101int idr_alloc(struct idr *, void *ptr, int start, int end, gfp_t);
86 unsigned long start, unsigned long end, gfp_t gfp, 102int __must_check idr_alloc_u32(struct idr *, void *ptr, u32 *id,
87 bool ext); 103 unsigned long max, gfp_t);
88 104int idr_alloc_cyclic(struct idr *, void *ptr, int start, int end, gfp_t);
89/** 105void *idr_remove(struct idr *, unsigned long id);
90 * idr_alloc - allocate an id 106void *idr_find(const struct idr *, unsigned long id);
91 * @idr: idr handle
92 * @ptr: pointer to be associated with the new id
93 * @start: the minimum id (inclusive)
94 * @end: the maximum id (exclusive)
95 * @gfp: memory allocation flags
96 *
97 * Allocates an unused ID in the range [start, end). Returns -ENOSPC
98 * if there are no unused IDs in that range.
99 *
100 * Note that @end is treated as max when <= 0. This is to always allow
101 * using @start + N as @end as long as N is inside integer range.
102 *
103 * Simultaneous modifications to the @idr are not allowed and should be
104 * prevented by the user, usually with a lock. idr_alloc() may be called
105 * concurrently with read-only accesses to the @idr, such as idr_find() and
106 * idr_for_each_entry().
107 */
108static inline int idr_alloc(struct idr *idr, void *ptr,
109 int start, int end, gfp_t gfp)
110{
111 unsigned long id;
112 int ret;
113
114 if (WARN_ON_ONCE(start < 0))
115 return -EINVAL;
116
117 ret = idr_alloc_cmn(idr, ptr, &id, start, end, gfp, false);
118
119 if (ret)
120 return ret;
121
122 return id;
123}
124
125static inline int idr_alloc_ext(struct idr *idr, void *ptr,
126 unsigned long *index,
127 unsigned long start,
128 unsigned long end,
129 gfp_t gfp)
130{
131 return idr_alloc_cmn(idr, ptr, index, start, end, gfp, true);
132}
133
134int idr_alloc_cyclic(struct idr *, void *entry, int start, int end, gfp_t);
135int idr_for_each(const struct idr *, 107int idr_for_each(const struct idr *,
136 int (*fn)(int id, void *p, void *data), void *data); 108 int (*fn)(int id, void *p, void *data), void *data);
137void *idr_get_next(struct idr *, int *nextid); 109void *idr_get_next(struct idr *, int *nextid);
138void *idr_get_next_ext(struct idr *idr, unsigned long *nextid); 110void *idr_get_next_ul(struct idr *, unsigned long *nextid);
139void *idr_replace(struct idr *, void *, int id); 111void *idr_replace(struct idr *, void *, unsigned long id);
140void *idr_replace_ext(struct idr *idr, void *ptr, unsigned long id);
141void idr_destroy(struct idr *); 112void idr_destroy(struct idr *);
142 113
143static inline void *idr_remove_ext(struct idr *idr, unsigned long id) 114/**
144{ 115 * idr_init_base() - Initialise an IDR.
145 return radix_tree_delete_item(&idr->idr_rt, id, NULL); 116 * @idr: IDR handle.
146} 117 * @base: The base value for the IDR.
147 118 *
148static inline void *idr_remove(struct idr *idr, int id) 119 * This variation of idr_init() creates an IDR which will allocate IDs
120 * starting at %base.
121 */
122static inline void idr_init_base(struct idr *idr, int base)
149{ 123{
150 return idr_remove_ext(idr, id); 124 INIT_RADIX_TREE(&idr->idr_rt, IDR_RT_MARKER);
125 idr->idr_base = base;
126 idr->idr_next = 0;
151} 127}
152 128
129/**
130 * idr_init() - Initialise an IDR.
131 * @idr: IDR handle.
132 *
133 * Initialise a dynamically allocated IDR. To initialise a
134 * statically allocated IDR, use DEFINE_IDR().
135 */
153static inline void idr_init(struct idr *idr) 136static inline void idr_init(struct idr *idr)
154{ 137{
155 INIT_RADIX_TREE(&idr->idr_rt, IDR_RT_MARKER); 138 idr_init_base(idr, 0);
156 idr->idr_next = 0;
157} 139}
158 140
141/**
142 * idr_is_empty() - Are there any IDs allocated?
143 * @idr: IDR handle.
144 *
145 * Return: %true if any IDs have been allocated from this IDR.
146 */
159static inline bool idr_is_empty(const struct idr *idr) 147static inline bool idr_is_empty(const struct idr *idr)
160{ 148{
161 return radix_tree_empty(&idr->idr_rt) && 149 return radix_tree_empty(&idr->idr_rt) &&
@@ -174,50 +162,38 @@ static inline void idr_preload_end(void)
174} 162}
175 163
176/** 164/**
177 * idr_find - return pointer for given id 165 * idr_for_each_entry() - Iterate over an IDR's elements of a given type.
178 * @idr: idr handle 166 * @idr: IDR handle.
179 * @id: lookup key 167 * @entry: The type * to use as cursor
180 * 168 * @id: Entry ID.
181 * Return the pointer given the id it has been registered with. A %NULL
182 * return indicates that @id is not valid or you passed %NULL in
183 * idr_get_new().
184 * 169 *
185 * This function can be called under rcu_read_lock(), given that the leaf 170 * @entry and @id do not need to be initialized before the loop, and
186 * pointers lifetimes are correctly managed. 171 * after normal termination @entry is left with the value NULL. This
172 * is convenient for a "not found" value.
187 */ 173 */
188static inline void *idr_find_ext(const struct idr *idr, unsigned long id) 174#define idr_for_each_entry(idr, entry, id) \
189{ 175 for (id = 0; ((entry) = idr_get_next(idr, &(id))) != NULL; ++id)
190 return radix_tree_lookup(&idr->idr_rt, id);
191}
192
193static inline void *idr_find(const struct idr *idr, int id)
194{
195 return idr_find_ext(idr, id);
196}
197 176
198/** 177/**
199 * idr_for_each_entry - iterate over an idr's elements of a given type 178 * idr_for_each_entry_ul() - Iterate over an IDR's elements of a given type.
200 * @idr: idr handle 179 * @idr: IDR handle.
201 * @entry: the type * to use as cursor 180 * @entry: The type * to use as cursor.
202 * @id: id entry's key 181 * @id: Entry ID.
203 * 182 *
204 * @entry and @id do not need to be initialized before the loop, and 183 * @entry and @id do not need to be initialized before the loop, and
205 * after normal terminatinon @entry is left with the value NULL. This 184 * after normal termination @entry is left with the value NULL. This
206 * is convenient for a "not found" value. 185 * is convenient for a "not found" value.
207 */ 186 */
208#define idr_for_each_entry(idr, entry, id) \ 187#define idr_for_each_entry_ul(idr, entry, id) \
209 for (id = 0; ((entry) = idr_get_next(idr, &(id))) != NULL; ++id) 188 for (id = 0; ((entry) = idr_get_next_ul(idr, &(id))) != NULL; ++id)
210#define idr_for_each_entry_ext(idr, entry, id) \
211 for (id = 0; ((entry) = idr_get_next_ext(idr, &(id))) != NULL; ++id)
212 189
213/** 190/**
214 * idr_for_each_entry_continue - continue iteration over an idr's elements of a given type 191 * idr_for_each_entry_continue() - Continue iteration over an IDR's elements of a given type
215 * @idr: idr handle 192 * @idr: IDR handle.
216 * @entry: the type * to use as cursor 193 * @entry: The type * to use as a cursor.
217 * @id: id entry's key 194 * @id: Entry ID.
218 * 195 *
219 * Continue to iterate over list of given type, continuing after 196 * Continue to iterate over entries, continuing after the current position.
220 * the current position.
221 */ 197 */
222#define idr_for_each_entry_continue(idr, entry, id) \ 198#define idr_for_each_entry_continue(idr, entry, id) \
223 for ((entry) = idr_get_next((idr), &(id)); \ 199 for ((entry) = idr_get_next((idr), &(id)); \