aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/idr.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/lib/idr.c b/lib/idr.c
index 44ab3b2a4eba..21e12af1f231 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -456,7 +456,8 @@ EXPORT_SYMBOL(idr_destroy);
456 * return indicates that @id is not valid or you passed %NULL in 456 * return indicates that @id is not valid or you passed %NULL in
457 * idr_get_new(). 457 * idr_get_new().
458 * 458 *
459 * The caller must serialize idr_find() vs idr_get_new() and idr_remove(). 459 * This function can be called under rcu_read_lock(), given that the leaf
460 * pointers lifetimes are correctly managed.
460 */ 461 */
461void *idr_find(struct idr *idp, int id) 462void *idr_find(struct idr *idp, int id)
462{ 463{
@@ -464,7 +465,7 @@ void *idr_find(struct idr *idp, int id)
464 struct idr_layer *p; 465 struct idr_layer *p;
465 466
466 n = idp->layers * IDR_BITS; 467 n = idp->layers * IDR_BITS;
467 p = idp->top; 468 p = rcu_dereference(idp->top);
468 469
469 /* Mask off upper bits we don't use for the search. */ 470 /* Mask off upper bits we don't use for the search. */
470 id &= MAX_ID_MASK; 471 id &= MAX_ID_MASK;
@@ -474,7 +475,7 @@ void *idr_find(struct idr *idp, int id)
474 475
475 while (n > 0 && p) { 476 while (n > 0 && p) {
476 n -= IDR_BITS; 477 n -= IDR_BITS;
477 p = p->ary[(id >> n) & IDR_MASK]; 478 p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
478 } 479 }
479 return((void *)p); 480 return((void *)p);
480} 481}
@@ -507,7 +508,7 @@ int idr_for_each(struct idr *idp,
507 struct idr_layer **paa = &pa[0]; 508 struct idr_layer **paa = &pa[0];
508 509
509 n = idp->layers * IDR_BITS; 510 n = idp->layers * IDR_BITS;
510 p = idp->top; 511 p = rcu_dereference(idp->top);
511 max = 1 << n; 512 max = 1 << n;
512 513
513 id = 0; 514 id = 0;
@@ -515,7 +516,7 @@ int idr_for_each(struct idr *idp,
515 while (n > 0 && p) { 516 while (n > 0 && p) {
516 n -= IDR_BITS; 517 n -= IDR_BITS;
517 *paa++ = p; 518 *paa++ = p;
518 p = p->ary[(id >> n) & IDR_MASK]; 519 p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
519 } 520 }
520 521
521 if (p) { 522 if (p) {