-static inline struct idr_layer *alloc_layer(struct idr *idp)
+static struct idr_layer *alloc_layer(struct idr *idp)
{
struct idr_layer *p;
return(p);
}
-static inline void free_layer(struct idr *idp, struct idr_layer *p)
+static void free_layer(struct idr *idp, struct idr_layer *p)
{
/*
* Depends on the return element being zeroed.
int idr_pre_get(struct idr *idp, unsigned gfp_mask)
{
- while (idp->id_free_cnt < idp->layers + 1) {
+ while (idp->id_free_cnt < IDR_FREE_MAX) {
struct idr_layer *new;
new = kmem_cache_alloc(idr_layer_cache, gfp_mask);
if(new == NULL)
}
EXPORT_SYMBOL(idr_pre_get);
-static inline int sub_alloc(struct idr *idp, int shift, void *ptr)
+static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
{
- int n, v = 0;
- struct idr_layer *p;
- struct idr_layer **pa[MAX_LEVEL];
- struct idr_layer ***paa = &pa[0];
-
- *paa = NULL;
- *++paa = &idp->top;
+ int n, m, sh;
+ struct idr_layer *p, *new;
+ struct idr_layer *pa[MAX_LEVEL];
+ int l, id;
+ long bm;
- /*
- * By keeping each pointer in an array we can do the
- * "after" recursion processing. In this case, that means
- * we can update the upper level bit map.
- */
-
- while (1){
- p = **paa;
- n = ffz(p->bitmap);
- if (shift){
- /*
- * We run around this while until we
- * reach the leaf node...
- */
- if (!p->ary[n]){
- /*
- * If no node, allocate one, AFTER
- * we insure that we will not
- * intrude on the reserved bit field.
- */
- if ((n << shift) >= MAX_ID_BIT)
- return -1;
- p->ary[n] = alloc_layer(idp);
- p->count++;
+ id = *starting_id;
+ p = idp->top;
+ l = idp->layers;
+ pa[l--] = NULL;
+ while (1) {
+ /*
+ * We run around this while until we reach the leaf node...
+ */
+ n = (id >> (IDR_BITS*l)) & IDR_MASK;
+ bm = ~p->bitmap;
+ m = find_next_bit(&bm, IDR_SIZE, n);
+ if (m == IDR_SIZE) {
+ /* no space available go back to previous layer. */
+ l++;
+ id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
+ if (!(p = pa[l])) {
+ *starting_id = id;
+ return -2;
}
- *++paa = &p->ary[n];
- v += (n << shift);
- shift -= IDR_BITS;
- } else {
- /*
- * We have reached the leaf node, plant the
- * users pointer and return the raw id.
- */
- p->ary[n] = (struct idr_layer *)ptr;
- __set_bit(n, &p->bitmap);
- v += n;
+ continue;
+ }
+ if (m != n) {
+ sh = IDR_BITS*l;
+ id = ((id >> sh) ^ n ^ m) << sh;
+ }
+ if (id >= MAX_ID_BIT)
+ return -1;
+ if (l == 0)
+ break;
+ /*
+ * Create the layer below if it is missing.
+ */
+ if (!p->ary[m]) {
+ if (!(new = alloc_layer(idp)))
+ return -1;
+ p->ary[m] = new;
p->count++;
- /*
- * This is the post recursion processing. Once
- * we find a bitmap that is not full we are
- * done
- */
- while (*(paa-1) && (**paa)->bitmap == IDR_FULL){
- n = *paa - &(**(paa-1))->ary[0];
- __set_bit(n, &(**--paa)->bitmap);
- }
- return(v);
}
+ pa[l--] = p;
+ p = p->ary[m];
+ }
+ /*
+ * We have reached the leaf node, plant the
+ * users pointer and return the raw id.
+ */
+ p->ary[m] = (struct idr_layer *)ptr;
+ __set_bit(m, &p->bitmap);
+ p->count++;
+ /*
+ * If this layer is full mark the bit in the layer above
+ * to show that this part of the radix tree is full.
+ * This may complete the layer above and require walking
+ * up the radix tree.
+ */
+ n = id;
+ while (p->bitmap == IDR_FULL) {
+ if (!(p = pa[++l]))
+ break;
+ n = n >> IDR_BITS;
+ __set_bit((n & IDR_MASK), &p->bitmap);
}
+ return(id);
}
-int idr_get_new(struct idr *idp, void *ptr)
+int idr_get_new_above(struct idr *idp, void *ptr, int starting_id)
{
- int v;
+ struct idr_layer *p, *new;
+ int layers, v, id;
- if (idp->id_free_cnt < idp->layers + 1)
- return (-1);
+ id = starting_id;
+build_up:
+ p = idp->top;
+ layers = idp->layers;
+ if (unlikely(!p)) {
+ if (!(p = alloc_layer(idp)))
+ return -1;
+ layers = 1;
+ }
/*
- * Add a new layer if the array is full
+ * Add a new layer to the top of the tree if the requested
+ * id is larger than the currently allocated space.
*/
- if (unlikely(!idp->top || idp->top->bitmap == IDR_FULL)){
- /*
- * This is a bit different than the lower layers because
- * we have one branch already allocated and full.
- */
- struct idr_layer *new = alloc_layer(idp);
- new->ary[0] = idp->top;
- if ( idp->top)
- ++new->count;
- idp->top = new;
- if ( idp->layers++ )
+ while (id >= (1 << (layers*IDR_BITS))) {
+ layers++;
+ if (!p->count)
+ continue;
+ if (!(new = alloc_layer(idp))) {
+ /*
+ * The allocation failed. If we built part of
+ * the structure tear it down.
+ */
+ for (new = p; p && p != idp->top; new = p) {
+ p = p->ary[0];
+ new->ary[0] = 0;
+ new->bitmap = new->count = 0;
+ free_layer(idp, new);
+ }
+ return -1;
+ }
+ new->ary[0] = p;
+ new->count = 1;
+ if (p->bitmap == IDR_FULL)
__set_bit(0, &new->bitmap);
+ p = new;
}
- v = sub_alloc(idp, (idp->layers - 1) * IDR_BITS, ptr);
- if ( likely(v >= 0 )){
+ idp->top = p;
+ idp->layers = layers;
+ v = sub_alloc(idp, ptr, &id);
+ if (v == -2)
+ goto build_up;
+ if ( likely(v >= 0 )) {
idp->count++;
v += (idp->count << MAX_ID_SHIFT);
if ( unlikely( v == -1 ))
}
return(v);
}
+EXPORT_SYMBOL(idr_get_new_above);
+
+int idr_get_new(struct idr *idp, void *ptr)
+{
+ return idr_get_new_above(idp, ptr, 0);
+}
EXPORT_SYMBOL(idr_get_new);
-static inline void sub_remove(struct idr *idp, int shift, int id)
+static void sub_remove(struct idr *idp, int shift, int id)
{
struct idr_layer *p = idp->top;
struct idr_layer **pa[MAX_LEVEL];