aboutsummaryrefslogtreecommitdiffstats
path: root/lib/idr.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-11-12 09:09:01 -0500
committerIngo Molnar <mingo@kernel.org>2014-11-12 09:09:01 -0500
commit890ca861f868a10617029ffc87eae7d48ea6876c (patch)
tree713383f4e3bbd94ddb9816a25e6b3911511908f1 /lib/idr.c
parent03452d27c6cd9cebb59a6bb0fb6bd8557916c263 (diff)
parent206c5f60a3d902bc4b56dab2de3e88de5eb06108 (diff)
Merge tag 'v3.18-rc4' into x86/cleanups, to refresh the tree before pulling new changes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib/idr.c')
-rw-r--r--lib/idr.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/lib/idr.c b/lib/idr.c
index 39158abebad1..e654aebd5f80 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -590,26 +590,27 @@ static void __idr_remove_all(struct idr *idp)
590 struct idr_layer **paa = &pa[0]; 590 struct idr_layer **paa = &pa[0];
591 591
592 n = idp->layers * IDR_BITS; 592 n = idp->layers * IDR_BITS;
593 p = idp->top; 593 *paa = idp->top;
594 RCU_INIT_POINTER(idp->top, NULL); 594 RCU_INIT_POINTER(idp->top, NULL);
595 max = idr_max(idp->layers); 595 max = idr_max(idp->layers);
596 596
597 id = 0; 597 id = 0;
598 while (id >= 0 && id <= max) { 598 while (id >= 0 && id <= max) {
599 p = *paa;
599 while (n > IDR_BITS && p) { 600 while (n > IDR_BITS && p) {
600 n -= IDR_BITS; 601 n -= IDR_BITS;
601 *paa++ = p;
602 p = p->ary[(id >> n) & IDR_MASK]; 602 p = p->ary[(id >> n) & IDR_MASK];
603 *++paa = p;
603 } 604 }
604 605
605 bt_mask = id; 606 bt_mask = id;
606 id += 1 << n; 607 id += 1 << n;
607 /* Get the highest bit that the above add changed from 0->1. */ 608 /* Get the highest bit that the above add changed from 0->1. */
608 while (n < fls(id ^ bt_mask)) { 609 while (n < fls(id ^ bt_mask)) {
609 if (p) 610 if (*paa)
610 free_layer(idp, p); 611 free_layer(idp, *paa);
611 n += IDR_BITS; 612 n += IDR_BITS;
612 p = *--paa; 613 --paa;
613 } 614 }
614 } 615 }
615 idp->layers = 0; 616 idp->layers = 0;
@@ -625,7 +626,7 @@ static void __idr_remove_all(struct idr *idp)
625 * idr_destroy(). 626 * idr_destroy().
626 * 627 *
627 * A typical clean-up sequence for objects stored in an idr tree will use 628 * A typical clean-up sequence for objects stored in an idr tree will use
628 * idr_for_each() to free all objects, if necessay, then idr_destroy() to 629 * idr_for_each() to free all objects, if necessary, then idr_destroy() to
629 * free up the id mappings and cached idr_layers. 630 * free up the id mappings and cached idr_layers.
630 */ 631 */
631void idr_destroy(struct idr *idp) 632void idr_destroy(struct idr *idp)
@@ -692,15 +693,16 @@ int idr_for_each(struct idr *idp,
692 struct idr_layer **paa = &pa[0]; 693 struct idr_layer **paa = &pa[0];
693 694
694 n = idp->layers * IDR_BITS; 695 n = idp->layers * IDR_BITS;
695 p = rcu_dereference_raw(idp->top); 696 *paa = rcu_dereference_raw(idp->top);
696 max = idr_max(idp->layers); 697 max = idr_max(idp->layers);
697 698
698 id = 0; 699 id = 0;
699 while (id >= 0 && id <= max) { 700 while (id >= 0 && id <= max) {
701 p = *paa;
700 while (n > 0 && p) { 702 while (n > 0 && p) {
701 n -= IDR_BITS; 703 n -= IDR_BITS;
702 *paa++ = p;
703 p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]); 704 p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]);
705 *++paa = p;
704 } 706 }
705 707
706 if (p) { 708 if (p) {
@@ -712,7 +714,7 @@ int idr_for_each(struct idr *idp,
712 id += 1 << n; 714 id += 1 << n;
713 while (n < fls(id)) { 715 while (n < fls(id)) {
714 n += IDR_BITS; 716 n += IDR_BITS;
715 p = *--paa; 717 --paa;
716 } 718 }
717 } 719 }
718 720
@@ -740,17 +742,18 @@ void *idr_get_next(struct idr *idp, int *nextidp)
740 int n, max; 742 int n, max;
741 743
742 /* find first ent */ 744 /* find first ent */
743 p = rcu_dereference_raw(idp->top); 745 p = *paa = rcu_dereference_raw(idp->top);
744 if (!p) 746 if (!p)
745 return NULL; 747 return NULL;
746 n = (p->layer + 1) * IDR_BITS; 748 n = (p->layer + 1) * IDR_BITS;
747 max = idr_max(p->layer + 1); 749 max = idr_max(p->layer + 1);
748 750
749 while (id >= 0 && id <= max) { 751 while (id >= 0 && id <= max) {
752 p = *paa;
750 while (n > 0 && p) { 753 while (n > 0 && p) {
751 n -= IDR_BITS; 754 n -= IDR_BITS;
752 *paa++ = p;
753 p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]); 755 p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]);
756 *++paa = p;
754 } 757 }
755 758
756 if (p) { 759 if (p) {
@@ -768,7 +771,7 @@ void *idr_get_next(struct idr *idp, int *nextidp)
768 id = round_up(id + 1, 1 << n); 771 id = round_up(id + 1, 1 << n);
769 while (n < fls(id)) { 772 while (n < fls(id)) {
770 n += IDR_BITS; 773 n += IDR_BITS;
771 p = *--paa; 774 --paa;
772 } 775 }
773 } 776 }
774 return NULL; 777 return NULL;