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.h172
1 files changed, 107 insertions, 65 deletions
diff --git a/include/linux/idr.h b/include/linux/idr.h
index de7e190f1af4..a6f38b5c34e4 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
51struct idr_layer { 30struct 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
59struct idr { 39struct 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,90 @@ struct idr {
101 * This is what we export. 72 * This is what we export.
102 */ 73 */
103 74
104void *idr_find(struct idr *idp, int id); 75void *idr_find_slowpath(struct idr *idp, int id);
105int idr_pre_get(struct idr *idp, gfp_t gfp_mask); 76int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
106int idr_get_new(struct idr *idp, void *ptr, int *id);
107int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); 77int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
78void idr_preload(gfp_t gfp_mask);
79int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
108int idr_for_each(struct idr *idp, 80int idr_for_each(struct idr *idp,
109 int (*fn)(int id, void *p, void *data), void *data); 81 int (*fn)(int id, void *p, void *data), void *data);
110void *idr_get_next(struct idr *idp, int *nextid); 82void *idr_get_next(struct idr *idp, int *nextid);
111void *idr_replace(struct idr *idp, void *ptr, int id); 83void *idr_replace(struct idr *idp, void *ptr, int id);
112void idr_remove(struct idr *idp, int id); 84void idr_remove(struct idr *idp, int id);
113void idr_remove_all(struct idr *idp); 85void idr_free(struct idr *idp, int id);
114void idr_destroy(struct idr *idp); 86void idr_destroy(struct idr *idp);
115void idr_init(struct idr *idp); 87void idr_init(struct idr *idp);
116 88
89/**
90 * idr_preload_end - end preload section started with idr_preload()
91 *
92 * Each idr_preload() should be matched with an invocation of this
93 * function. See idr_preload() for details.
94 */
95static inline void idr_preload_end(void)
96{
97 preempt_enable();
98}
99
100/**
101 * idr_find - return pointer for given id
102 * @idp: idr handle
103 * @id: lookup key
104 *
105 * Return the pointer given the id it has been registered with. A %NULL
106 * return indicates that @id is not valid or you passed %NULL in
107 * idr_get_new().
108 *
109 * This function can be called under rcu_read_lock(), given that the leaf
110 * pointers lifetimes are correctly managed.
111 */
112static inline void *idr_find(struct idr *idr, int id)
113{
114 struct idr_layer *hint = rcu_dereference_raw(idr->hint);
115
116 if (hint && (id & ~IDR_MASK) == hint->prefix)
117 return rcu_dereference_raw(hint->ary[id & IDR_MASK]);
118
119 return idr_find_slowpath(idr, id);
120}
121
122/**
123 * idr_get_new - allocate new idr entry
124 * @idp: idr handle
125 * @ptr: pointer you want associated with the id
126 * @id: pointer to the allocated handle
127 *
128 * Simple wrapper around idr_get_new_above() w/ @starting_id of zero.
129 */
130static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
131{
132 return idr_get_new_above(idp, ptr, 0, id);
133}
134
135/**
136 * idr_for_each_entry - iterate over an idr's elements of a given type
137 * @idp: idr handle
138 * @entry: the type * to use as cursor
139 * @id: id entry's key
140 */
141#define idr_for_each_entry(idp, entry, id) \
142 for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \
143 entry != NULL; \
144 ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
145
146void __idr_remove_all(struct idr *idp); /* don't use */
147
148/**
149 * idr_remove_all - remove all ids from the given idr tree
150 * @idp: idr handle
151 *
152 * If you're trying to destroy @idp, calling idr_destroy() is enough.
153 * This is going away. Don't use.
154 */
155static inline void __deprecated idr_remove_all(struct idr *idp)
156{
157 __idr_remove_all(idp);
158}
117 159
118/* 160/*
119 * IDA - IDR based id allocator, use when translation from id to 161 * IDA - IDR based id allocator, use when translation from id to
@@ -136,12 +178,11 @@ struct ida {
136 struct ida_bitmap *free_bitmap; 178 struct ida_bitmap *free_bitmap;
137}; 179};
138 180
139#define IDA_INIT(name) { .idr = IDR_INIT(name), .free_bitmap = NULL, } 181#define IDA_INIT(name) { .idr = IDR_INIT((name).idr), .free_bitmap = NULL, }
140#define DEFINE_IDA(name) struct ida name = IDA_INIT(name) 182#define DEFINE_IDA(name) struct ida name = IDA_INIT(name)
141 183
142int ida_pre_get(struct ida *ida, gfp_t gfp_mask); 184int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
143int ida_get_new_above(struct ida *ida, int starting_id, int *p_id); 185int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
144int ida_get_new(struct ida *ida, int *p_id);
145void ida_remove(struct ida *ida, int id); 186void ida_remove(struct ida *ida, int id);
146void ida_destroy(struct ida *ida); 187void ida_destroy(struct ida *ida);
147void ida_init(struct ida *ida); 188void ida_init(struct ida *ida);
@@ -150,17 +191,18 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end,
150 gfp_t gfp_mask); 191 gfp_t gfp_mask);
151void ida_simple_remove(struct ida *ida, unsigned int id); 192void ida_simple_remove(struct ida *ida, unsigned int id);
152 193
153void __init idr_init_cache(void);
154
155/** 194/**
156 * idr_for_each_entry - iterate over an idr's elements of a given type 195 * ida_get_new - allocate new ID
157 * @idp: idr handle 196 * @ida: idr handle
158 * @entry: the type * to use as cursor 197 * @p_id: pointer to the allocated handle
159 * @id: id entry's key 198 *
199 * Simple wrapper around ida_get_new_above() w/ @starting_id of zero.
160 */ 200 */
161#define idr_for_each_entry(idp, entry, id) \ 201static inline int ida_get_new(struct ida *ida, int *p_id)
162 for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \ 202{
163 entry != NULL; \ 203 return ida_get_new_above(ida, 0, p_id);
164 ++id, entry = (typeof(entry))idr_get_next((idp), &(id))) 204}
205
206void __init idr_init_cache(void);
165 207
166#endif /* __IDR_H__ */ 208#endif /* __IDR_H__ */