|
@@ -456,7 +456,8 @@ EXPORT_SYMBOL(idr_destroy);
|
|
|
* return indicates that @id is not valid or you passed %NULL in
|
|
|
* idr_get_new().
|
|
|
*
|
|
|
- * The caller must serialize idr_find() vs idr_get_new() and idr_remove().
|
|
|
+ * This function can be called under rcu_read_lock(), given that the leaf
|
|
|
+ * pointers lifetimes are correctly managed.
|
|
|
*/
|
|
|
void *idr_find(struct idr *idp, int id)
|
|
|
{
|
|
@@ -464,7 +465,7 @@ void *idr_find(struct idr *idp, int id)
|
|
|
struct idr_layer *p;
|
|
|
|
|
|
n = idp->layers * IDR_BITS;
|
|
|
- p = idp->top;
|
|
|
+ p = rcu_dereference(idp->top);
|
|
|
|
|
|
/* Mask off upper bits we don't use for the search. */
|
|
|
id &= MAX_ID_MASK;
|
|
@@ -474,7 +475,7 @@ void *idr_find(struct idr *idp, int id)
|
|
|
|
|
|
while (n > 0 && p) {
|
|
|
n -= IDR_BITS;
|
|
|
- p = p->ary[(id >> n) & IDR_MASK];
|
|
|
+ p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
|
|
|
}
|
|
|
return((void *)p);
|
|
|
}
|
|
@@ -507,7 +508,7 @@ int idr_for_each(struct idr *idp,
|
|
|
struct idr_layer **paa = &pa[0];
|
|
|
|
|
|
n = idp->layers * IDR_BITS;
|
|
|
- p = idp->top;
|
|
|
+ p = rcu_dereference(idp->top);
|
|
|
max = 1 << n;
|
|
|
|
|
|
id = 0;
|
|
@@ -515,7 +516,7 @@ int idr_for_each(struct idr *idp,
|
|
|
while (n > 0 && p) {
|
|
|
n -= IDR_BITS;
|
|
|
*paa++ = p;
|
|
|
- p = p->ary[(id >> n) & IDR_MASK];
|
|
|
+ p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
|
|
|
}
|
|
|
|
|
|
if (p) {
|