Commit 3e7b2ec4 authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

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: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 08dcf9fd
...@@ -653,15 +653,15 @@ static int __init test_rht_lookup(struct rhashtable *ht) ...@@ -653,15 +653,15 @@ static int __init test_rht_lookup(struct rhashtable *ht)
return 0; return 0;
} }
static void test_bucket_stats(struct rhashtable *ht, static void test_bucket_stats(struct rhashtable *ht, bool quiet)
struct bucket_table *tbl,
bool quiet)
{ {
unsigned int cnt, i, total = 0; unsigned int cnt, rcu_cnt, i, total = 0;
struct test_obj *obj; struct test_obj *obj;
struct bucket_table *tbl;
tbl = rht_dereference_rcu(ht->tbl, ht);
for (i = 0; i < tbl->size; i++) { for (i = 0; i < tbl->size; i++) {
cnt = 0; rcu_cnt = cnt = 0;
if (!quiet) if (!quiet)
pr_info(" [%#4x/%zu]", i, tbl->size); pr_info(" [%#4x/%zu]", i, tbl->size);
...@@ -673,6 +673,13 @@ static void test_bucket_stats(struct rhashtable *ht, ...@@ -673,6 +673,13 @@ static void test_bucket_stats(struct rhashtable *ht,
pr_cont(" [%p],", obj); pr_cont(" [%p],", obj);
} }
rht_for_each_entry_rcu(obj, tbl->buckets[i], node)
rcu_cnt++;
if (rcu_cnt != cnt)
pr_warn("Test failed: Chain count mismach %d != %d",
cnt, rcu_cnt);
if (!quiet) if (!quiet)
pr_cont("\n [%#x] first element: %p, chain length: %u\n", pr_cont("\n [%#x] first element: %p, chain length: %u\n",
i, tbl->buckets[i], cnt); i, tbl->buckets[i], cnt);
...@@ -680,6 +687,9 @@ static void test_bucket_stats(struct rhashtable *ht, ...@@ -680,6 +687,9 @@ static void test_bucket_stats(struct rhashtable *ht,
pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n", pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n",
total, ht->nelems, TEST_ENTRIES); total, ht->nelems, TEST_ENTRIES);
if (total != ht->nelems || total != TEST_ENTRIES)
pr_warn("Test failed: Total count mismatch ^^^");
} }
static int __init test_rhashtable(struct rhashtable *ht) static int __init test_rhashtable(struct rhashtable *ht)
...@@ -710,8 +720,7 @@ static int __init test_rhashtable(struct rhashtable *ht) ...@@ -710,8 +720,7 @@ static int __init test_rhashtable(struct rhashtable *ht)
} }
rcu_read_lock(); rcu_read_lock();
tbl = rht_dereference_rcu(ht->tbl, ht); test_bucket_stats(ht, true);
test_bucket_stats(ht, tbl, true);
test_rht_lookup(ht); test_rht_lookup(ht);
rcu_read_unlock(); rcu_read_unlock();
...@@ -735,6 +744,10 @@ static int __init test_rhashtable(struct rhashtable *ht) ...@@ -735,6 +744,10 @@ static int __init test_rhashtable(struct rhashtable *ht)
rcu_read_unlock(); rcu_read_unlock();
} }
rcu_read_lock();
test_bucket_stats(ht, true);
rcu_read_unlock();
pr_info(" Deleting %d keys\n", TEST_ENTRIES); pr_info(" Deleting %d keys\n", TEST_ENTRIES);
for (i = 0; i < TEST_ENTRIES; i++) { for (i = 0; i < TEST_ENTRIES; i++) {
u32 key = i * 2; u32 key = i * 2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment