summaryrefslogtreecommitdiffstats
path: root/lib/test_rhashtable.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2015-04-30 18:37:44 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-03 23:08:54 -0400
commit246b23a7695bd5a457aa51a36a948cce53d1d477 (patch)
tree16ff143dd196e071343e5d4d5a451fe8ab7faf64 /lib/test_rhashtable.c
parentfcc570207c1e7c485050adbab1e5d7808eab0fd4 (diff)
rhashtable-test: Use walker to test bucket statistics
As resizes may continue to run in the background, use walker to ensure we see all entries. Also print the encountered number of rehashes queued up while traversing. This may lead to warnings due to entries being seen multiple times. We consider them non-fatal. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib/test_rhashtable.c')
-rw-r--r--lib/test_rhashtable.c60
1 files changed, 30 insertions, 30 deletions
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index 935693ed7ae5..3a9a3d9c0cbf 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -89,41 +89,43 @@ static int __init test_rht_lookup(struct rhashtable *ht)
89 return 0; 89 return 0;
90} 90}
91 91
92static void test_bucket_stats(struct rhashtable *ht, bool quiet) 92static void test_bucket_stats(struct rhashtable *ht)
93{ 93{
94 unsigned int cnt, rcu_cnt, i, total = 0; 94 unsigned int err, total = 0, chain_len = 0;
95 struct rhashtable_iter hti;
95 struct rhash_head *pos; 96 struct rhash_head *pos;
96 struct test_obj *obj;
97 struct bucket_table *tbl;
98 97
99 tbl = rht_dereference_rcu(ht->tbl, ht); 98 err = rhashtable_walk_init(ht, &hti);
100 for (i = 0; i < tbl->size; i++) { 99 if (err) {
101 rcu_cnt = cnt = 0; 100 pr_warn("Test failed: allocation error");
101 return;
102 }
102 103
103 if (!quiet) 104 err = rhashtable_walk_start(&hti);
104 pr_info(" [%#4x/%u]", i, tbl->size); 105 if (err && err != -EAGAIN) {
106 pr_warn("Test failed: iterator failed: %d\n", err);
107 return;
108 }
105 109
106 rht_for_each_entry_rcu(obj, pos, tbl, i, node) { 110 while ((pos = rhashtable_walk_next(&hti))) {
107 cnt++; 111 if (PTR_ERR(pos) == -EAGAIN) {
108 total++; 112 pr_info("Info: encountered resize\n");
109 if (!quiet) 113 chain_len++;
110 pr_cont(" [%p],", obj); 114 continue;
115 } else if (IS_ERR(pos)) {
116 pr_warn("Test failed: rhashtable_walk_next() error: %ld\n",
117 PTR_ERR(pos));
118 break;
111 } 119 }
112 120
113 rht_for_each_entry_rcu(obj, pos, tbl, i, node) 121 total++;
114 rcu_cnt++;
115
116 if (rcu_cnt != cnt)
117 pr_warn("Test failed: Chain count mismach %d != %d",
118 cnt, rcu_cnt);
119
120 if (!quiet)
121 pr_cont("\n [%#x] first element: %p, chain length: %u\n",
122 i, tbl->buckets[i], cnt);
123 } 122 }
124 123
125 pr_info(" Traversal complete: counted=%u, nelems=%u, entries=%d\n", 124 rhashtable_walk_stop(&hti);
126 total, atomic_read(&ht->nelems), entries); 125 rhashtable_walk_exit(&hti);
126
127 pr_info(" Traversal complete: counted=%u, nelems=%u, entries=%d, table-jumps=%u\n",
128 total, atomic_read(&ht->nelems), entries, chain_len);
127 129
128 if (total != atomic_read(&ht->nelems) || total != entries) 130 if (total != atomic_read(&ht->nelems) || total != entries)
129 pr_warn("Test failed: Total count mismatch ^^^"); 131 pr_warn("Test failed: Total count mismatch ^^^");
@@ -152,14 +154,12 @@ static s64 __init test_rhashtable(struct rhashtable *ht)
152 return err; 154 return err;
153 } 155 }
154 156
157 test_bucket_stats(ht);
155 rcu_read_lock(); 158 rcu_read_lock();
156 test_bucket_stats(ht, true);
157 test_rht_lookup(ht); 159 test_rht_lookup(ht);
158 rcu_read_unlock(); 160 rcu_read_unlock();
159 161
160 rcu_read_lock(); 162 test_bucket_stats(ht);
161 test_bucket_stats(ht, true);
162 rcu_read_unlock();
163 163
164 pr_info(" Deleting %d keys\n", entries); 164 pr_info(" Deleting %d keys\n", entries);
165 for (i = 0; i < entries; i++) { 165 for (i = 0; i < entries; i++) {