diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rhashtable.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index e5f5e69c7a7b..c7e987ab3361 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
@@ -653,15 +653,15 @@ static int __init test_rht_lookup(struct rhashtable *ht) | |||
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | 655 | ||
656 | static void test_bucket_stats(struct rhashtable *ht, | 656 | static void test_bucket_stats(struct rhashtable *ht, bool quiet) |
657 | struct bucket_table *tbl, | ||
658 | bool quiet) | ||
659 | { | 657 | { |
660 | unsigned int cnt, i, total = 0; | 658 | unsigned int cnt, rcu_cnt, i, total = 0; |
661 | struct test_obj *obj; | 659 | struct test_obj *obj; |
660 | struct bucket_table *tbl; | ||
662 | 661 | ||
662 | tbl = rht_dereference_rcu(ht->tbl, ht); | ||
663 | for (i = 0; i < tbl->size; i++) { | 663 | for (i = 0; i < tbl->size; i++) { |
664 | cnt = 0; | 664 | rcu_cnt = cnt = 0; |
665 | 665 | ||
666 | if (!quiet) | 666 | if (!quiet) |
667 | pr_info(" [%#4x/%zu]", i, tbl->size); | 667 | pr_info(" [%#4x/%zu]", i, tbl->size); |
@@ -673,6 +673,13 @@ static void test_bucket_stats(struct rhashtable *ht, | |||
673 | pr_cont(" [%p],", obj); | 673 | pr_cont(" [%p],", obj); |
674 | } | 674 | } |
675 | 675 | ||
676 | rht_for_each_entry_rcu(obj, tbl->buckets[i], node) | ||
677 | rcu_cnt++; | ||
678 | |||
679 | if (rcu_cnt != cnt) | ||
680 | pr_warn("Test failed: Chain count mismach %d != %d", | ||
681 | cnt, rcu_cnt); | ||
682 | |||
676 | if (!quiet) | 683 | if (!quiet) |
677 | pr_cont("\n [%#x] first element: %p, chain length: %u\n", | 684 | pr_cont("\n [%#x] first element: %p, chain length: %u\n", |
678 | i, tbl->buckets[i], cnt); | 685 | i, tbl->buckets[i], cnt); |
@@ -680,6 +687,9 @@ static void test_bucket_stats(struct rhashtable *ht, | |||
680 | 687 | ||
681 | pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n", | 688 | pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n", |
682 | total, ht->nelems, TEST_ENTRIES); | 689 | total, ht->nelems, TEST_ENTRIES); |
690 | |||
691 | if (total != ht->nelems || total != TEST_ENTRIES) | ||
692 | pr_warn("Test failed: Total count mismatch ^^^"); | ||
683 | } | 693 | } |
684 | 694 | ||
685 | static int __init test_rhashtable(struct rhashtable *ht) | 695 | static int __init test_rhashtable(struct rhashtable *ht) |
@@ -710,8 +720,7 @@ static int __init test_rhashtable(struct rhashtable *ht) | |||
710 | } | 720 | } |
711 | 721 | ||
712 | rcu_read_lock(); | 722 | rcu_read_lock(); |
713 | tbl = rht_dereference_rcu(ht->tbl, ht); | 723 | test_bucket_stats(ht, true); |
714 | test_bucket_stats(ht, tbl, true); | ||
715 | test_rht_lookup(ht); | 724 | test_rht_lookup(ht); |
716 | rcu_read_unlock(); | 725 | rcu_read_unlock(); |
717 | 726 | ||
@@ -735,6 +744,10 @@ static int __init test_rhashtable(struct rhashtable *ht) | |||
735 | rcu_read_unlock(); | 744 | rcu_read_unlock(); |
736 | } | 745 | } |
737 | 746 | ||
747 | rcu_read_lock(); | ||
748 | test_bucket_stats(ht, true); | ||
749 | rcu_read_unlock(); | ||
750 | |||
738 | pr_info(" Deleting %d keys\n", TEST_ENTRIES); | 751 | pr_info(" Deleting %d keys\n", TEST_ENTRIES); |
739 | for (i = 0; i < TEST_ENTRIES; i++) { | 752 | for (i = 0; i < TEST_ENTRIES; i++) { |
740 | u32 key = i * 2; | 753 | u32 key = i * 2; |