168cf618cSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * include/linux/idr.h
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * 2002-10-18 written by Jim Houston [email protected]
61da177e4SLinus Torvalds * Copyright (C) 2002 by Concurrent Computer Corporation
71da177e4SLinus Torvalds *
81da177e4SLinus Torvalds * Small id to pointer translation service avoiding fixed sized
91da177e4SLinus Torvalds * tables.
101da177e4SLinus Torvalds */
11f668ab1aSLuben Tuikov
12f668ab1aSLuben Tuikov #ifndef __IDR_H__
13f668ab1aSLuben Tuikov #define __IDR_H__
14f668ab1aSLuben Tuikov
150a835c4fSMatthew Wilcox #include <linux/radix-tree.h>
160a835c4fSMatthew Wilcox #include <linux/gfp.h>
177ad3d4d8SMatthew Wilcox #include <linux/percpu.h>
181da177e4SLinus Torvalds #include <linux/cleanup.h>
191da177e4SLinus Torvalds
200a835c4fSMatthew Wilcox struct idr {
216ce711f2SMatthew Wilcox struct radix_tree_root idr_rt;
220a835c4fSMatthew Wilcox unsigned int idr_base;
231da177e4SLinus Torvalds unsigned int idr_next;
241da177e4SLinus Torvalds };
250a835c4fSMatthew Wilcox
260a835c4fSMatthew Wilcox /*
270a835c4fSMatthew Wilcox * The IDR API does not expose the tagging functionality of the radix tree
280a835c4fSMatthew Wilcox * to users. Use tag 0 to track whether a node has free space below it.
290a835c4fSMatthew Wilcox */
300a835c4fSMatthew Wilcox #define IDR_FREE 0
310a835c4fSMatthew Wilcox
32fa290cdaSMatthew Wilcox /* Set the IDR flag and the IDR_FREE tag */
33fa290cdaSMatthew Wilcox #define IDR_RT_MARKER (ROOT_IS_IDR | (__force gfp_t) \
340a835c4fSMatthew Wilcox (1 << (ROOT_TAG_SHIFT + IDR_FREE)))
35f6bb2a2cSMatthew Wilcox
36f6bb2a2cSMatthew Wilcox #define IDR_INIT_BASE(name, base) { \
376ce711f2SMatthew Wilcox .idr_rt = RADIX_TREE_INIT(name, IDR_RT_MARKER), \
386ce711f2SMatthew Wilcox .idr_base = (base), \
391da177e4SLinus Torvalds .idr_next = 0, \
401da177e4SLinus Torvalds }
41f9c46d6eSNadia Derbey
426ce711f2SMatthew Wilcox /**
43f6bb2a2cSMatthew Wilcox * IDR_INIT() - Initialise an IDR.
446ce711f2SMatthew Wilcox * @name: Name of IDR.
456ce711f2SMatthew Wilcox *
466ce711f2SMatthew Wilcox * A freshly-initialised IDR contains no IDs.
47f6bb2a2cSMatthew Wilcox */
486ce711f2SMatthew Wilcox #define IDR_INIT(name) IDR_INIT_BASE(name, 0)
496ce711f2SMatthew Wilcox
50f6bb2a2cSMatthew Wilcox /**
51f6bb2a2cSMatthew Wilcox * DEFINE_IDR() - Define a statically-allocated IDR.
52ac665d94SMatthew Wilcox * @name: Name of IDR.
53ac665d94SMatthew Wilcox *
54ac665d94SMatthew Wilcox * An IDR defined using this macro is ready for use with no additional
55ac665d94SMatthew Wilcox * initialisation required. It contains no IDs.
56f6bb2a2cSMatthew Wilcox */
57ac665d94SMatthew Wilcox #define DEFINE_IDR(name) struct idr name = IDR_INIT(name)
58ac665d94SMatthew Wilcox
5944430612SMatthew Wilcox /**
6044430612SMatthew Wilcox * idr_get_cursor - Return the current position of the cyclic allocator
6144430612SMatthew Wilcox * @idr: idr handle
6244430612SMatthew Wilcox *
6344430612SMatthew Wilcox * The value returned is the value that will be next returned from
6444430612SMatthew Wilcox * idr_alloc_cyclic() if it is free (otherwise the search will start from
6544430612SMatthew Wilcox * this position).
660a835c4fSMatthew Wilcox */
idr_get_cursor(const struct idr * idr)6744430612SMatthew Wilcox static inline unsigned int idr_get_cursor(const struct idr *idr)
680a835c4fSMatthew Wilcox {
6944430612SMatthew Wilcox return READ_ONCE(idr->idr_next);
7044430612SMatthew Wilcox }
7144430612SMatthew Wilcox
7244430612SMatthew Wilcox /**
7344430612SMatthew Wilcox * idr_set_cursor - Set the current position of the cyclic allocator
7444430612SMatthew Wilcox * @idr: idr handle
7544430612SMatthew Wilcox * @val: new position
7644430612SMatthew Wilcox *
7744430612SMatthew Wilcox * The next call to idr_alloc_cyclic() will return @val if it is free
7844430612SMatthew Wilcox * (otherwise the search will start from this position).
7944430612SMatthew Wilcox */
idr_set_cursor(struct idr * idr,unsigned int val)8044430612SMatthew Wilcox static inline void idr_set_cursor(struct idr *idr, unsigned int val)
810a835c4fSMatthew Wilcox {
8244430612SMatthew Wilcox WRITE_ONCE(idr->idr_next, val);
8344430612SMatthew Wilcox }
8444430612SMatthew Wilcox
8556083ab1SRandy Dunlap /**
86f9c46d6eSNadia Derbey * DOC: idr sync
87f9c46d6eSNadia Derbey * idr synchronization (stolen from radix-tree.h)
88f9c46d6eSNadia Derbey *
89f9c46d6eSNadia Derbey * idr_find() is able to be called locklessly, using RCU. The caller must
90f9c46d6eSNadia Derbey * ensure calls to this function are made within rcu_read_lock() regions.
91f9c46d6eSNadia Derbey * Other readers (lock-free or otherwise) and modifications may be running
92f9c46d6eSNadia Derbey * concurrently.
93f9c46d6eSNadia Derbey *
94f9c46d6eSNadia Derbey * It is still required that the caller manage the synchronization and
95f9c46d6eSNadia Derbey * lifetimes of the items. So if RCU lock-free lookups are used, typically
96f9c46d6eSNadia Derbey * this would mean that the items have their own locks, or are amenable to
97f9c46d6eSNadia Derbey * lock-free access; and that the items are freed by RCU (or only freed after
98f9c46d6eSNadia Derbey * having been deleted from the idr tree *and* a synchronize_rcu() grace
99f9c46d6eSNadia Derbey * period).
100f9c46d6eSNadia Derbey */
1013c60e868S[email protected]
1023c60e868S[email protected] #define idr_lock(idr) xa_lock(&(idr)->idr_rt)
1033c60e868S[email protected] #define idr_unlock(idr) xa_unlock(&(idr)->idr_rt)
1043c60e868S[email protected] #define idr_lock_bh(idr) xa_lock_bh(&(idr)->idr_rt)
1053c60e868S[email protected] #define idr_unlock_bh(idr) xa_unlock_bh(&(idr)->idr_rt)
1063c60e868S[email protected] #define idr_lock_irq(idr) xa_lock_irq(&(idr)->idr_rt)
1073c60e868S[email protected] #define idr_unlock_irq(idr) xa_unlock_irq(&(idr)->idr_rt)
1083c60e868S[email protected] #define idr_lock_irqsave(idr, flags) \
1093c60e868S[email protected] xa_lock_irqsave(&(idr)->idr_rt, flags)
1103c60e868S[email protected] #define idr_unlock_irqrestore(idr, flags) \
1113c60e868S[email protected] xa_unlock_irqrestore(&(idr)->idr_rt, flags)
112d5c7409fSTejun Heo
113388f79fdSChris Mi void idr_preload(gfp_t gfp_mask);
1146ce711f2SMatthew Wilcox
1156ce711f2SMatthew Wilcox int idr_alloc(struct idr *, void *ptr, int start, int end, gfp_t);
116e096f6a7SMatthew Wilcox int __must_check idr_alloc_u32(struct idr *, void *ptr, u32 *id,
1176ce711f2SMatthew Wilcox unsigned long max, gfp_t);
1186ce711f2SMatthew Wilcox int idr_alloc_cyclic(struct idr *, void *ptr, int start, int end, gfp_t);
1196ce711f2SMatthew Wilcox void *idr_remove(struct idr *, unsigned long id);
1200a835c4fSMatthew Wilcox void *idr_find(const struct idr *, unsigned long id);
12196d7fa42SKristian Hoegsberg int idr_for_each(const struct idr *,
1220a835c4fSMatthew Wilcox int (*fn)(int id, void *p, void *data), void *data);
1237a457577SMatthew Wilcox void *idr_get_next(struct idr *, int *nextid);
124234a4624SMatthew Wilcox void *idr_get_next_ul(struct idr *, unsigned long *nextid);
1250a835c4fSMatthew Wilcox void *idr_replace(struct idr *, void *, unsigned long id);
1260a835c4fSMatthew Wilcox void idr_destroy(struct idr *);
1276ce711f2SMatthew Wilcox
1286ce711f2SMatthew Wilcox struct __class_idr {
1296ce711f2SMatthew Wilcox struct idr *idr;
1306ce711f2SMatthew Wilcox int id;
1316ce711f2SMatthew Wilcox };
1326ce711f2SMatthew Wilcox
1336ce711f2SMatthew Wilcox #define idr_null ((struct __class_idr){ NULL, -1 })
1346ce711f2SMatthew Wilcox #define take_idr_id(id) __get_and_null(id, idr_null)
1356ce711f2SMatthew Wilcox
1360a835c4fSMatthew Wilcox DEFINE_CLASS(idr_alloc, struct __class_idr,
1370a835c4fSMatthew Wilcox if (_T.id >= 0) idr_remove(_T.idr, _T.id),
1386ce711f2SMatthew Wilcox ((struct __class_idr){
1390a835c4fSMatthew Wilcox .idr = idr,
1400a835c4fSMatthew Wilcox .id = idr_alloc(idr, ptr, start, end, gfp),
1410a835c4fSMatthew Wilcox }),
1426ce711f2SMatthew Wilcox struct idr *idr, void *ptr, int start, int end, gfp_t gfp);
1436ce711f2SMatthew Wilcox
1446ce711f2SMatthew Wilcox /**
1456ce711f2SMatthew Wilcox * idr_init_base() - Initialise an IDR.
1466ce711f2SMatthew Wilcox * @idr: IDR handle.
1476ce711f2SMatthew Wilcox * @base: The base value for the IDR.
1486ce711f2SMatthew Wilcox *
1496ce711f2SMatthew Wilcox * This variation of idr_init() creates an IDR which will allocate IDs
1506ce711f2SMatthew Wilcox * starting at %base.
1516ce711f2SMatthew Wilcox */
idr_init_base(struct idr * idr,int base)1526ce711f2SMatthew Wilcox static inline void idr_init_base(struct idr *idr, int base)
1536ce711f2SMatthew Wilcox {
154ac665d94SMatthew Wilcox INIT_RADIX_TREE(&idr->idr_rt, IDR_RT_MARKER);
155ac665d94SMatthew Wilcox idr->idr_base = base;
156ac665d94SMatthew Wilcox idr->idr_next = 0;
157ac665d94SMatthew Wilcox }
158ac665d94SMatthew Wilcox
159ac665d94SMatthew Wilcox /**
1600a835c4fSMatthew Wilcox * idr_init() - Initialise an IDR.
1610a835c4fSMatthew Wilcox * @idr: IDR handle.
1620a835c4fSMatthew Wilcox *
1630a835c4fSMatthew Wilcox * Initialise a dynamically allocated IDR. To initialise a
1640a835c4fSMatthew Wilcox * statically allocated IDR, use DEFINE_IDR().
165f668ab1aSLuben Tuikov */
idr_init(struct idr * idr)16649038ef4STejun Heo static inline void idr_init(struct idr *idr)
167d5c7409fSTejun Heo {
168d5c7409fSTejun Heo idr_init_base(idr, 0);
169d5c7409fSTejun Heo }
170d5c7409fSTejun Heo
171d5c7409fSTejun Heo /**
172d5c7409fSTejun Heo * idr_is_empty() - Are there any IDs allocated?
173d5c7409fSTejun Heo * @idr: IDR handle.
174cfa6705dSSebastian Andrzej Siewior *
175d5c7409fSTejun Heo * Return: %true if any IDs have been allocated from this IDR.
176d5c7409fSTejun Heo */
idr_is_empty(const struct idr * idr)177d5c7409fSTejun Heo static inline bool idr_is_empty(const struct idr *idr)
1787a457577SMatthew Wilcox {
1797a457577SMatthew Wilcox return radix_tree_empty(&idr->idr_rt) &&
1807a457577SMatthew Wilcox radix_tree_tagged(&idr->idr_rt, IDR_FREE);
1817a457577SMatthew Wilcox }
182b949be58SGeorge Spelvin
183b949be58SGeorge Spelvin /**
1847a457577SMatthew Wilcox * idr_preload_end - end preload section started with idr_preload()
185b949be58SGeorge Spelvin *
18649038ef4STejun Heo * Each idr_preload() should be matched with an invocation of this
1870a835c4fSMatthew Wilcox * function. See idr_preload() for details.
188f6341c5aSMatthew Wilcox (Oracle) */
idr_preload_end(void)18949038ef4STejun Heo static inline void idr_preload_end(void)
190a55bbd37SAndreas Gruenbacher {
1917a457577SMatthew Wilcox local_unlock(&radix_tree_preloads.lock);
1927a457577SMatthew Wilcox }
1937a457577SMatthew Wilcox
194e33d2b74SCong Wang /**
1957a457577SMatthew Wilcox * idr_for_each_entry() - Iterate over an IDR's elements of a given type.
196a55bbd37SAndreas Gruenbacher * @idr: IDR handle.
1977a457577SMatthew Wilcox * @entry: The type * to use as cursor
1987a457577SMatthew Wilcox * @id: Entry ID.
1997a457577SMatthew Wilcox *
2007a457577SMatthew Wilcox * @entry and @id do not need to be initialized before the loop, and
201e33d2b74SCong Wang * after normal termination @entry is left with the value NULL. This
202e33d2b74SCong Wang * is convenient for a "not found" value.
203e8ae8ad4SNeilBrown */
204e33d2b74SCong Wang #define idr_for_each_entry(idr, entry, id) \
2057a457577SMatthew Wilcox for (id = 0; ((entry) = idr_get_next(idr, &(id))) != NULL; id += 1U)
2067a457577SMatthew Wilcox
2077a457577SMatthew Wilcox /**
2087a457577SMatthew Wilcox * idr_for_each_entry_ul() - Iterate over an IDR's elements of a given type.
2097a457577SMatthew Wilcox * @idr: IDR handle.
2107a457577SMatthew Wilcox * @entry: The type * to use as cursor.
2117a457577SMatthew Wilcox * @tmp: A temporary placeholder for ID.
2127a457577SMatthew Wilcox * @id: Entry ID.
213a55bbd37SAndreas Gruenbacher *
2140a835c4fSMatthew Wilcox * @entry and @id do not need to be initialized before the loop, and
2150a835c4fSMatthew Wilcox * after normal termination @entry is left with the value NULL. This
216a55bbd37SAndreas Gruenbacher * is convenient for a "not found" value.
2170a835c4fSMatthew Wilcox */
218a55bbd37SAndreas Gruenbacher #define idr_for_each_entry_ul(idr, entry, tmp, id) \
219d39d7149SCong Wang for (tmp = 0, id = 0; \
220d39d7149SCong Wang ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \
221d39d7149SCong Wang tmp = id, ++id)
222d39d7149SCong Wang
223d39d7149SCong Wang /**
224d39d7149SCong Wang * idr_for_each_entry_continue() - Continue iteration over an IDR's elements of a given type
225d39d7149SCong Wang * @idr: IDR handle.
226d39d7149SCong Wang * @entry: The type * to use as a cursor.
227e8ae8ad4SNeilBrown * @id: Entry ID.
228e8ae8ad4SNeilBrown *
229d39d7149SCong Wang * Continue to iterate over entries, continuing after the current position.
230d39d7149SCong Wang */
231d39d7149SCong Wang #define idr_for_each_entry_continue(idr, entry, id) \
232e8ae8ad4SNeilBrown for ((entry) = idr_get_next((idr), &(id)); \
233d39d7149SCong Wang entry; \
234d39d7149SCong Wang ++id, (entry) = idr_get_next((idr), &(id)))
235c8615d37STejun Heo
236f32f004cSMatthew Wilcox /**
23772dba584STejun Heo * idr_for_each_entry_continue_ul() - Continue iteration over an IDR's elements of a given type
23872dba584STejun Heo * @idr: IDR handle.
2390a835c4fSMatthew Wilcox * @entry: The type * to use as a cursor.
24072dba584STejun Heo * @tmp: A temporary placeholder for ID.
24172dba584STejun Heo * @id: Entry ID.
24272dba584STejun Heo *
24372dba584STejun Heo * Continue to iterate over entries, continuing after the current position.
24472dba584STejun Heo * After normal termination @entry is left with the value NULL. This
24572dba584STejun Heo * is convenient for a "not found" value.
24672dba584STejun Heo */
247f32f004cSMatthew Wilcox #define idr_for_each_entry_continue_ul(idr, entry, tmp, id) \
24872dba584STejun Heo for (tmp = id; \
24972dba584STejun Heo ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \
250f32f004cSMatthew Wilcox tmp = id, ++id)
251f32f004cSMatthew Wilcox
252f6bb2a2cSMatthew Wilcox /*
253f32f004cSMatthew Wilcox * IDA - ID Allocator, use when translation from id to pointer isn't necessary.
2540a835c4fSMatthew Wilcox */
255f6bb2a2cSMatthew Wilcox #define IDA_CHUNK_SIZE 128 /* 128 bytes per chunk */
25672dba584STejun Heo #define IDA_BITMAP_LONGS (IDA_CHUNK_SIZE / sizeof(long))
2575ade60ddSMatthew Wilcox #define IDA_BITMAP_BITS (IDA_BITMAP_LONGS * sizeof(long) * 8)
2585ade60ddSMatthew Wilcox
25972dba584STejun Heo struct ida_bitmap {
260*7fe6b987SYi Liu unsigned long bitmap[IDA_BITMAP_LONGS];
26172dba584STejun Heo };
2625ade60ddSMatthew Wilcox
2635ade60ddSMatthew Wilcox struct ida {
2645ade60ddSMatthew Wilcox struct xarray xa;
2655ade60ddSMatthew Wilcox };
2665ade60ddSMatthew Wilcox
2675ade60ddSMatthew Wilcox #define IDA_INIT_FLAGS (XA_FLAGS_LOCK_IRQ | XA_FLAGS_ALLOC)
2685ade60ddSMatthew Wilcox
2693b674261SStephen Boyd #define IDA_INIT(name) { \
2703b674261SStephen Boyd .xa = XARRAY_INIT(name, IDA_INIT_FLAGS) \
2715ade60ddSMatthew Wilcox }
2725ade60ddSMatthew Wilcox #define DEFINE_IDA(name) struct ida name = IDA_INIT(name)
2735ade60ddSMatthew Wilcox
2745ade60ddSMatthew Wilcox int ida_alloc_range(struct ida *, unsigned int min, unsigned int max, gfp_t);
2755ade60ddSMatthew Wilcox void ida_free(struct ida *, unsigned int id);
2765ade60ddSMatthew Wilcox void ida_destroy(struct ida *ida);
2775ade60ddSMatthew Wilcox int ida_find_first_range(struct ida *ida, unsigned int min, unsigned int max);
2785ade60ddSMatthew Wilcox
2795ade60ddSMatthew Wilcox /**
2805ade60ddSMatthew Wilcox * ida_alloc() - Allocate an unused ID.
2815ade60ddSMatthew Wilcox * @ida: IDA handle.
2825ade60ddSMatthew Wilcox * @gfp: Memory allocation flags.
2835ade60ddSMatthew Wilcox *
2845ade60ddSMatthew Wilcox * Allocate an ID between 0 and %INT_MAX, inclusive.
2855ade60ddSMatthew Wilcox *
2865ade60ddSMatthew Wilcox * Context: Any context. It is safe to call this function without
2873b674261SStephen Boyd * locking in your code.
2883b674261SStephen Boyd * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
2895ade60ddSMatthew Wilcox * or %-ENOSPC if there are no free IDs.
2905ade60ddSMatthew Wilcox */
ida_alloc(struct ida * ida,gfp_t gfp)2915ade60ddSMatthew Wilcox static inline int ida_alloc(struct ida *ida, gfp_t gfp)
2925ade60ddSMatthew Wilcox {
2935ade60ddSMatthew Wilcox return ida_alloc_range(ida, 0, ~0, gfp);
2945ade60ddSMatthew Wilcox }
2955ade60ddSMatthew Wilcox
2965ade60ddSMatthew Wilcox /**
2975ade60ddSMatthew Wilcox * ida_alloc_min() - Allocate an unused ID.
2985ade60ddSMatthew Wilcox * @ida: IDA handle.
2995ade60ddSMatthew Wilcox * @min: Lowest ID to allocate.
3005ade60ddSMatthew Wilcox * @gfp: Memory allocation flags.
3015ade60ddSMatthew Wilcox *
3025ade60ddSMatthew Wilcox * Allocate an ID between @min and %INT_MAX, inclusive.
3035ade60ddSMatthew Wilcox *
3045ade60ddSMatthew Wilcox * Context: Any context. It is safe to call this function without
3053b674261SStephen Boyd * locking in your code.
3063b674261SStephen Boyd * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
3075ade60ddSMatthew Wilcox * or %-ENOSPC if there are no free IDs.
3085ade60ddSMatthew Wilcox */
ida_alloc_min(struct ida * ida,unsigned int min,gfp_t gfp)3095ade60ddSMatthew Wilcox static inline int ida_alloc_min(struct ida *ida, unsigned int min, gfp_t gfp)
3105ade60ddSMatthew Wilcox {
3115ade60ddSMatthew Wilcox return ida_alloc_range(ida, min, ~0, gfp);
3125ade60ddSMatthew Wilcox }
3135ade60ddSMatthew Wilcox
31488eca020SRusty Russell /**
3150a835c4fSMatthew Wilcox * ida_alloc_max() - Allocate an unused ID.
3160a835c4fSMatthew Wilcox * @ida: IDA handle.
317f32f004cSMatthew Wilcox * @max: Highest ID to allocate.
3180a835c4fSMatthew Wilcox * @gfp: Memory allocation flags.
3190a835c4fSMatthew Wilcox *
3203264ceecSStephen Boyd * Allocate an ID between 0 and @max, inclusive.
3213264ceecSStephen Boyd *
3223264ceecSStephen Boyd * Context: Any context. It is safe to call this function without
3233264ceecSStephen Boyd * locking in your code.
3245ade60ddSMatthew Wilcox * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
3255ade60ddSMatthew Wilcox * or %-ENOSPC if there are no free IDs.
3265ade60ddSMatthew Wilcox */
ida_alloc_max(struct ida * ida,unsigned int max,gfp_t gfp)32749038ef4STejun Heo static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp)
3280a835c4fSMatthew Wilcox {
32999c49407SMatthew Wilcox return ida_alloc_range(ida, 0, max, gfp);
330f32f004cSMatthew Wilcox }
33199c49407SMatthew Wilcox
ida_init(struct ida * ida)332*7fe6b987SYi Liu static inline void ida_init(struct ida *ida)
333*7fe6b987SYi Liu {
334*7fe6b987SYi Liu xa_init_flags(&ida->xa, IDA_INIT_FLAGS);
335*7fe6b987SYi Liu }
336*7fe6b987SYi Liu
337*7fe6b987SYi Liu /*
338*7fe6b987SYi Liu * ida_simple_get() and ida_simple_remove() are deprecated. Use
339*7fe6b987SYi Liu * ida_alloc() and ida_free() instead respectively.
340*7fe6b987SYi Liu */
341*7fe6b987SYi Liu #define ida_simple_get(ida, start, end, gfp) \
342f668ab1aSLuben Tuikov ida_alloc_range(ida, start, (end) - 1, gfp)
343 #define ida_simple_remove(ida, id) ida_free(ida, id)
344
ida_is_empty(const struct ida * ida)345 static inline bool ida_is_empty(const struct ida *ida)
346 {
347 return xa_empty(&ida->xa);
348 }
349
ida_exists(struct ida * ida,unsigned int id)350 static inline bool ida_exists(struct ida *ida, unsigned int id)
351 {
352 return ida_find_first_range(ida, id, id) == id;
353 }
354
ida_find_first(struct ida * ida)355 static inline int ida_find_first(struct ida *ida)
356 {
357 return ida_find_first_range(ida, 0, ~0);
358 }
359 #endif /* __IDR_H__ */
360