Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 359381
b: refs/heads/master
c: 326cf0f
h: refs/heads/master
i:
  359379: bc5acb4
v: v3
  • Loading branch information
Tejun Heo authored and Linus Torvalds committed Feb 28, 2013
1 parent 9858468 commit 4f688b7
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d6870312659d8c6e80419ddb09d366bdd0f17ab6
refs/heads/master: 326cf0f0f308933c10236280a322031f0097205d
38 changes: 23 additions & 15 deletions trunk/lib/idr.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ static DEFINE_PER_CPU(struct idr_layer *, idr_preload_head);
static DEFINE_PER_CPU(int, idr_preload_cnt);
static DEFINE_SPINLOCK(simple_ida_lock);

/* the maximum ID which can be allocated given idr->layers */
static int idr_max(int layers)
{
int bits = min_t(int, layers * IDR_BITS, MAX_IDR_SHIFT);

return (1 << bits) - 1;
}

static struct idr_layer *get_from_free_list(struct idr *idp)
{
struct idr_layer *p;
Expand Down Expand Up @@ -290,7 +298,7 @@ static int idr_get_empty_slot(struct idr *idp, int starting_id,
* Add a new layer to the top of the tree if the requested
* id is larger than the currently allocated space.
*/
while ((layers < (MAX_IDR_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
while (id > idr_max(layers)) {
layers++;
if (!p->count) {
/* special case: if the tree is currently empty,
Expand Down Expand Up @@ -361,7 +369,7 @@ static void idr_fill_slot(void *ptr, int id, struct idr_layer **pa)
*/
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
{
struct idr_layer *pa[MAX_IDR_LEVEL];
struct idr_layer *pa[MAX_IDR_LEVEL + 1];
int rv;

rv = idr_get_empty_slot(idp, starting_id, pa, 0, idp);
Expand Down Expand Up @@ -457,7 +465,7 @@ EXPORT_SYMBOL(idr_preload);
int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
{
int max = end > 0 ? end - 1 : INT_MAX; /* inclusive upper limit */
struct idr_layer *pa[MAX_IDR_LEVEL];
struct idr_layer *pa[MAX_IDR_LEVEL + 1];
int id;

might_sleep_if(gfp_mask & __GFP_WAIT);
Expand Down Expand Up @@ -490,7 +498,7 @@ static void idr_remove_warning(int id)
static void sub_remove(struct idr *idp, int shift, int id)
{
struct idr_layer *p = idp->top;
struct idr_layer **pa[MAX_IDR_LEVEL];
struct idr_layer **pa[MAX_IDR_LEVEL + 1];
struct idr_layer ***paa = &pa[0];
struct idr_layer *to_free;
int n;
Expand Down Expand Up @@ -571,16 +579,16 @@ void __idr_remove_all(struct idr *idp)
int n, id, max;
int bt_mask;
struct idr_layer *p;
struct idr_layer *pa[MAX_IDR_LEVEL];
struct idr_layer *pa[MAX_IDR_LEVEL + 1];
struct idr_layer **paa = &pa[0];

n = idp->layers * IDR_BITS;
p = idp->top;
rcu_assign_pointer(idp->top, NULL);
max = 1 << n;
max = idr_max(idp->layers);

id = 0;
while (id < max) {
while (id >= 0 && id <= max) {
while (n > IDR_BITS && p) {
n -= IDR_BITS;
*paa++ = p;
Expand Down Expand Up @@ -650,7 +658,7 @@ void *idr_find(struct idr *idp, int id)
/* Mask off upper bits we don't use for the search. */
id &= MAX_IDR_MASK;

if (id >= (1 << n))
if (id > idr_max(p->layer + 1))
return NULL;
BUG_ON(n == 0);

Expand Down Expand Up @@ -686,15 +694,15 @@ int idr_for_each(struct idr *idp,
{
int n, id, max, error = 0;
struct idr_layer *p;
struct idr_layer *pa[MAX_IDR_LEVEL];
struct idr_layer *pa[MAX_IDR_LEVEL + 1];
struct idr_layer **paa = &pa[0];

n = idp->layers * IDR_BITS;
p = rcu_dereference_raw(idp->top);
max = 1 << n;
max = idr_max(idp->layers);

id = 0;
while (id < max) {
while (id >= 0 && id <= max) {
while (n > 0 && p) {
n -= IDR_BITS;
*paa++ = p;
Expand Down Expand Up @@ -732,7 +740,7 @@ EXPORT_SYMBOL(idr_for_each);
*/
void *idr_get_next(struct idr *idp, int *nextidp)
{
struct idr_layer *p, *pa[MAX_IDR_LEVEL];
struct idr_layer *p, *pa[MAX_IDR_LEVEL + 1];
struct idr_layer **paa = &pa[0];
int id = *nextidp;
int n, max;
Expand All @@ -742,9 +750,9 @@ void *idr_get_next(struct idr *idp, int *nextidp)
if (!p)
return NULL;
n = (p->layer + 1) * IDR_BITS;
max = 1 << n;
max = idr_max(p->layer + 1);

while (id < max) {
while (id >= 0 && id <= max) {
while (n > 0 && p) {
n -= IDR_BITS;
*paa++ = p;
Expand Down Expand Up @@ -918,7 +926,7 @@ EXPORT_SYMBOL(ida_pre_get);
*/
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
{
struct idr_layer *pa[MAX_IDR_LEVEL];
struct idr_layer *pa[MAX_IDR_LEVEL + 1];
struct ida_bitmap *bitmap;
unsigned long flags;
int idr_id = starting_id / IDA_BITMAP_BITS;
Expand Down

0 comments on commit 4f688b7

Please sign in to comment.