Commit 3e7b2ec4fe8ef4b05b33db3e84d1b1fbccde250e
Committed by
David S. Miller
1 parent
08dcf9fd19
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
rhashtable: Check for count mismatch while iterating in selftest
Verify whether both the lock and RCU protected iterators see all test entries before and after expanding and shrinking has been performed. Also verify whether the number of entries in the hashtable remains stable during expansion and shrinking. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 20 additions and 7 deletions Side-by-side Diff
lib/rhashtable.c
... | ... | @@ -653,15 +653,15 @@ |
653 | 653 | return 0; |
654 | 654 | } |
655 | 655 | |
656 | -static void test_bucket_stats(struct rhashtable *ht, | |
657 | - struct bucket_table *tbl, | |
658 | - bool quiet) | |
656 | +static void test_bucket_stats(struct rhashtable *ht, bool quiet) | |
659 | 657 | { |
660 | - unsigned int cnt, i, total = 0; | |
658 | + unsigned int cnt, rcu_cnt, i, total = 0; | |
661 | 659 | struct test_obj *obj; |
660 | + struct bucket_table *tbl; | |
662 | 661 | |
662 | + tbl = rht_dereference_rcu(ht->tbl, ht); | |
663 | 663 | for (i = 0; i < tbl->size; i++) { |
664 | - cnt = 0; | |
664 | + rcu_cnt = cnt = 0; | |
665 | 665 | |
666 | 666 | if (!quiet) |
667 | 667 | pr_info(" [%#4x/%zu]", i, tbl->size); |
... | ... | @@ -673,6 +673,13 @@ |
673 | 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 | 683 | if (!quiet) |
677 | 684 | pr_cont("\n [%#x] first element: %p, chain length: %u\n", |
678 | 685 | i, tbl->buckets[i], cnt); |
... | ... | @@ -680,6 +687,9 @@ |
680 | 687 | |
681 | 688 | pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n", |
682 | 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 | 695 | static int __init test_rhashtable(struct rhashtable *ht) |
... | ... | @@ -710,8 +720,7 @@ |
710 | 720 | } |
711 | 721 | |
712 | 722 | rcu_read_lock(); |
713 | - tbl = rht_dereference_rcu(ht->tbl, ht); | |
714 | - test_bucket_stats(ht, tbl, true); | |
723 | + test_bucket_stats(ht, true); | |
715 | 724 | test_rht_lookup(ht); |
716 | 725 | rcu_read_unlock(); |
717 | 726 | |
... | ... | @@ -734,6 +743,10 @@ |
734 | 743 | test_rht_lookup(ht); |
735 | 744 | rcu_read_unlock(); |
736 | 745 | } |
746 | + | |
747 | + rcu_read_lock(); | |
748 | + test_bucket_stats(ht, true); | |
749 | + rcu_read_unlock(); | |
737 | 750 | |
738 | 751 | pr_info(" Deleting %d keys\n", TEST_ENTRIES); |
739 | 752 | for (i = 0; i < TEST_ENTRIES; i++) { |