15
15
#include <linux/radix-tree.h>
16
16
#include <linux/gfp.h>
17
17
#include <linux/percpu.h>
18
- #include <linux/bug.h>
19
18
20
19
struct idr {
21
20
struct radix_tree_root idr_rt ;
21
+ unsigned int idr_base ;
22
22
unsigned int idr_next ;
23
23
};
24
24
@@ -31,10 +31,26 @@ struct idr {
31
31
/* Set the IDR flag and the IDR_FREE tag */
32
32
#define IDR_RT_MARKER ((__force gfp_t)(3 << __GFP_BITS_SHIFT))
33
33
34
- #define IDR_INIT \
35
- { \
36
- .idr_rt = RADIX_TREE_INIT(IDR_RT_MARKER) \
34
+ #define IDR_INIT_BASE (base ) { \
35
+ .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
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
83
99
void idr_preload (gfp_t gfp_mask );
84
100
85
- int idr_alloc_cmn (struct idr * idr , void * ptr , unsigned long * index ,
86
- unsigned long start , unsigned long end , gfp_t gfp ,
87
- bool ext );
88
-
89
- /**
90
- * idr_alloc - allocate an 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
- */
108
- static 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
-
125
- static 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
-
134
- int idr_alloc_cyclic (struct idr * , void * entry , int start , int end , gfp_t );
101
+ int idr_alloc (struct idr * , void * ptr , int start , int end , gfp_t );
102
+ int __must_check idr_alloc_u32 (struct idr * , void * ptr , u32 * id ,
103
+ unsigned long max , gfp_t );
104
+ int idr_alloc_cyclic (struct idr * , void * ptr , int start , int end , gfp_t );
105
+ void * idr_remove (struct idr * , unsigned long id );
106
+ void * idr_find (const struct idr * , unsigned long id );
135
107
int idr_for_each (const struct idr * ,
136
108
int (* fn )(int id , void * p , void * data ), void * data );
137
109
void * idr_get_next (struct idr * , int * nextid );
138
- void * idr_get_next_ext (struct idr * idr , unsigned long * nextid );
139
- void * idr_replace (struct idr * , void * , int id );
140
- void * idr_replace_ext (struct idr * idr , void * ptr , unsigned long id );
110
+ void * idr_get_next_ul (struct idr * , unsigned long * nextid );
111
+ void * idr_replace (struct idr * , void * , unsigned long id );
141
112
void idr_destroy (struct idr * );
142
113
143
- static inline void * idr_remove_ext (struct idr * idr , unsigned long id )
144
- {
145
- return radix_tree_delete_item (& idr -> idr_rt , id , NULL );
146
- }
147
-
148
- static inline void * idr_remove (struct idr * idr , int id )
114
+ /**
115
+ * idr_init_base() - Initialise an IDR.
116
+ * @idr: IDR handle.
117
+ * @base: The base value for the IDR.
118
+ *
119
+ * This variation of idr_init() creates an IDR which will allocate IDs
120
+ * starting at %base.
121
+ */
122
+ static 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
+ */
153
136
static inline void idr_init (struct idr * idr )
154
137
{
155
- INIT_RADIX_TREE (& idr -> idr_rt , IDR_RT_MARKER );
156
- idr -> idr_next = 0 ;
138
+ idr_init_base (idr , 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
+ */
159
147
static inline bool idr_is_empty (const struct idr * idr )
160
148
{
161
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
178
- * @idr: idr handle
179
- * @id: lookup key
180
- *
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().
165
+ * idr_for_each_entry() - Iterate over an IDR's elements of a given type.
166
+ * @idr: IDR handle.
167
+ * @entry: The type * to use as cursor
168
+ * @id: Entry ID.
184
169
*
185
- * This function can be called under rcu_read_lock(), given that the leaf
186
- * pointers lifetimes are correctly managed.
170
+ * @entry and @id do not need to be initialized before the loop, and
171
+ * after normal termination @entry is left with the value NULL. This
172
+ * is convenient for a "not found" value.
187
173
*/
188
- static inline void * idr_find_ext (const struct idr * idr , unsigned long id )
189
- {
190
- return radix_tree_lookup (& idr -> idr_rt , id );
191
- }
192
-
193
- static inline void * idr_find (const struct idr * idr , int id )
194
- {
195
- return idr_find_ext (idr , id );
196
- }
174
+ #define idr_for_each_entry (idr , entry , id ) \
175
+ for (id = 0; ((entry) = idr_get_next(idr, &(id))) != NULL; ++id)
197
176
198
177
/**
199
- * idr_for_each_entry - iterate over an idr 's elements of a given type
200
- * @idr: idr handle
201
- * @entry: the type * to use as cursor
202
- * @id: id entry's key
178
+ * idr_for_each_entry_ul() - Iterate over an IDR 's elements of a given type.
179
+ * @idr: IDR handle.
180
+ * @entry: The type * to use as cursor.
181
+ * @id: Entry ID.
203
182
*
204
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
185
* is convenient for a "not found" value.
207
186
*/
208
- #define idr_for_each_entry (idr , entry , id ) \
209
- for (id = 0; ((entry) = idr_get_next(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)
187
+ #define idr_for_each_entry_ul (idr , entry , id ) \
188
+ for (id = 0; ((entry) = idr_get_next_ul(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
215
- * @idr: idr handle
216
- * @entry: the type * to use as cursor
217
- * @id: id entry's key
191
+ * idr_for_each_entry_continue() - Continue iteration over an IDR 's elements of a given type
192
+ * @idr: IDR handle.
193
+ * @entry: The type * to use as a cursor.
194
+ * @id: Entry ID.
218
195
*
219
- * Continue to iterate over list of given type, continuing after
220
- * the current position.
196
+ * Continue to iterate over entries, continuing after the current position.
221
197
*/
222
198
#define idr_for_each_entry_continue (idr , entry , id ) \
223
199
for ((entry) = idr_get_next((idr), &(id)); \
0 commit comments