svn commit: r214037 - projects/ofed/head/sys/ofed/include/linux
Jeff Roberson
jeff at FreeBSD.org
Mon Oct 18 22:21:57 UTC 2010
Author: jeff
Date: Mon Oct 18 22:21:57 2010
New Revision: 214037
URL: http://svn.freebsd.org/changeset/base/214037
Log:
- Fill the bitmap for layers that are brought in directly from the
allocator in idr_get(). Otherwise they will present as empty.
- Don't forget to set il when traversing the tree in get_new_*
even when we don't have to allocate a new layer. This was causing
large idrs to fail on remove.
Sponsored by: Isilon Systems, iX Systems, and Panasas.
Modified:
projects/ofed/head/sys/ofed/include/linux/linux_idr.c
Modified: projects/ofed/head/sys/ofed/include/linux/linux_idr.c
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/linux_idr.c Mon Oct 18 22:19:47 2010 (r214036)
+++ projects/ofed/head/sys/ofed/include/linux/linux_idr.c Mon Oct 18 22:21:57 2010 (r214037)
@@ -255,6 +255,7 @@ idr_get(struct idr *idr)
return (il);
}
il = malloc(sizeof(*il), M_IDR, M_ZERO | M_NOWAIT);
+ bitmap_fill(&il->bitmap, IDR_SIZE);
return (il);
}
@@ -307,10 +308,11 @@ idr_get_new(struct idr *idr, void *ptr,
if (layer == 0)
break;
if (il->ary[idx] == NULL) {
- il = il->ary[idx] = idr_get(idr);
- if (il == NULL)
+ il->ary[idx] = idr_get(idr);
+ if (il->ary[idx] == NULL)
goto out;
}
+ il = il->ary[idx];
}
/*
* Allocate the leaf to the consumer.
@@ -328,10 +330,12 @@ idr_get_new(struct idr *idr, void *ptr,
error = 0;
out:
mtx_unlock(&idr->lock);
+#ifdef INVARIANTS
if (error == 0 && idr_find(idr, id) != ptr) {
panic("idr_get_new: Failed for idr %p, id %d, ptr %p\n",
idr, id, ptr);
}
+#endif
return (error);
}
@@ -358,6 +362,10 @@ restart:
layer++;
idx >>= IDR_BITS;
}
+ if (layer == MAX_LEVEL + 1) {
+ error = -ENOSPC;
+ goto out;
+ }
/*
* Expand the tree until there is free space at or beyond starting_id.
*/
@@ -407,10 +415,11 @@ restart:
if (layer == 0)
break;
if (il->ary[idx] == NULL) {
- il = il->ary[idx] = idr_get(idr);
- if (il == NULL)
+ il->ary[idx] = idr_get(idr);
+ if (il->ary[idx] == NULL)
goto out;
}
+ il = il->ary[idx];
}
/*
* Allocate the leaf to the consumer.
@@ -428,5 +437,11 @@ restart:
error = 0;
out:
mtx_unlock(&idr->lock);
+#ifdef INVARIANTS
+ if (error == 0 && idr_find(idr, id) != ptr) {
+ panic("idr_get_new_above: Failed for idr %p, id %d, ptr %p\n",
+ idr, id, ptr);
+ }
+#endif
return (error);
}
More information about the svn-src-projects
mailing list