mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 07:23:14 +00:00
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>
This commit is contained in:
parent
050a6b47d9
commit
54616283c2
@ -28,6 +28,7 @@
|
|||||||
#define IDR_MASK ((1 << IDR_BITS)-1)
|
#define IDR_MASK ((1 << IDR_BITS)-1)
|
||||||
|
|
||||||
struct idr_layer {
|
struct idr_layer {
|
||||||
|
int prefix; /* the ID prefix of this idr_layer */
|
||||||
DECLARE_BITMAP(bitmap, IDR_SIZE); /* A zero bit means "space here" */
|
DECLARE_BITMAP(bitmap, IDR_SIZE); /* A zero bit means "space here" */
|
||||||
struct idr_layer __rcu *ary[1<<IDR_BITS];
|
struct idr_layer __rcu *ary[1<<IDR_BITS];
|
||||||
int count; /* When zero, we can release it */
|
int count; /* When zero, we can release it */
|
||||||
|
13
lib/idr.c
13
lib/idr.c
@ -60,6 +60,16 @@ static int idr_max(int layers)
|
|||||||
return (1 << bits) - 1;
|
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)
|
static struct idr_layer *get_from_free_list(struct idr *idp)
|
||||||
{
|
{
|
||||||
struct idr_layer *p;
|
struct idr_layer *p;
|
||||||
@ -272,6 +282,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa,
|
|||||||
if (!new)
|
if (!new)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
new->layer = l-1;
|
new->layer = l-1;
|
||||||
|
new->prefix = id & idr_layer_prefix_mask(new->layer);
|
||||||
rcu_assign_pointer(p->ary[m], new);
|
rcu_assign_pointer(p->ary[m], new);
|
||||||
p->count++;
|
p->count++;
|
||||||
}
|
}
|
||||||
@ -313,6 +324,7 @@ static int idr_get_empty_slot(struct idr *idp, int starting_id,
|
|||||||
* upwards.
|
* upwards.
|
||||||
*/
|
*/
|
||||||
p->layer++;
|
p->layer++;
|
||||||
|
WARN_ON_ONCE(p->prefix);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) {
|
if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) {
|
||||||
@ -334,6 +346,7 @@ static int idr_get_empty_slot(struct idr *idp, int starting_id,
|
|||||||
new->ary[0] = p;
|
new->ary[0] = p;
|
||||||
new->count = 1;
|
new->count = 1;
|
||||||
new->layer = layers-1;
|
new->layer = layers-1;
|
||||||
|
new->prefix = id & idr_layer_prefix_mask(new->layer);
|
||||||
if (bitmap_full(p->bitmap, IDR_SIZE))
|
if (bitmap_full(p->bitmap, IDR_SIZE))
|
||||||
__set_bit(0, new->bitmap);
|
__set_bit(0, new->bitmap);
|
||||||
p = new;
|
p = new;
|
||||||
|
Loading…
Reference in New Issue
Block a user