diff options
author | Tejun Heo <tj@kernel.org> | 2013-02-28 05:05:07 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-28 07:10:20 +0400 |
commit | 54616283c2948812a44240858ced610e7cacbde1 (patch) | |
tree | 268bbe9049d9370d5b644dfde51fc4a8942bae3b | |
parent | 050a6b47d98e2bcea909c1129111e721668aaa2c (diff) | |
download | linux-54616283c2948812a44240858ced610e7cacbde1.tar.xz |
idr: add idr_layer->prefix
Add a field which carries the prefix of ID the idr_layer covers. This
will be used to implement lookup hint.
This patch doesn't make use of the new field and doesn't introduce any
behavior difference.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/idr.h | 1 | ||||
-rw-r--r-- | lib/idr.c | 13 |
2 files changed, 14 insertions, 0 deletions
diff --git a/include/linux/idr.h b/include/linux/idr.h index 43b87b1c77a3..7b1c5c6f9a06 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -28,6 +28,7 @@ #define IDR_MASK ((1 << IDR_BITS)-1) struct idr_layer { + int prefix; /* the ID prefix of this idr_layer */ DECLARE_BITMAP(bitmap, IDR_SIZE); /* A zero bit means "space here" */ struct idr_layer __rcu *ary[1<<IDR_BITS]; int count; /* When zero, we can release it */ diff --git a/lib/idr.c b/lib/idr.c index d66e75bfc1a0..5cd602936645 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -60,6 +60,16 @@ static int idr_max(int layers) return (1 << bits) - 1; } +/* + * Prefix mask for an idr_layer at @layer. For layer 0, the prefix mask is + * all bits except for the lower IDR_BITS. For layer 1, 2 * IDR_BITS, and + * so on. + */ +static int idr_layer_prefix_mask(int layer) +{ + return ~idr_max(layer + 1); +} + static struct idr_layer *get_from_free_list(struct idr *idp) { struct idr_layer *p; @@ -272,6 +282,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa, if (!new) return -ENOMEM; new->layer = l-1; + new->prefix = id & idr_layer_prefix_mask(new->layer); rcu_assign_pointer(p->ary[m], new); p->count++; } @@ -313,6 +324,7 @@ build_up: * upwards. */ p->layer++; + WARN_ON_ONCE(p->prefix); continue; } if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) { @@ -334,6 +346,7 @@ build_up: new->ary[0] = p; new->count = 1; new->layer = layers-1; + new->prefix = id & idr_layer_prefix_mask(new->layer); if (bitmap_full(p->bitmap, IDR_SIZE)) __set_bit(0, new->bitmap); p = new; |