rhashtable: Add selftest for rhashtable_next_key()

Insert n elements, then verify:
  - NULL prev_key walks from the beginning, visiting all n
  - non-existing prev_key returns ERR_PTR(-ENOENT)

Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Link: https://lore.kernel.org/r/20260605-rhash-v7-2-5b8e05f8630d@meta.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Mykyta Yatsenko 2026-06-05 04:41:19 -07:00 committed by Alexei Starovoitov
parent 8f4fa9f89b
commit e673eee0f4

View File

@ -679,6 +679,78 @@ static int threadfunc(void *data)
return err;
}
static int __init test_rhashtable_next_key(void)
{
struct rhashtable_params params = test_rht_params;
struct test_obj_val key_missing = { .id = 99999, .tid = 0 };
struct test_obj_val *prev_key = NULL;
struct rhashtable ht;
struct test_obj *objs, *cur;
int i, count = 0, err;
int visited_keys[8] = { 0 };
const int n = ARRAY_SIZE(visited_keys);
params.nelem_hint = n;
err = rhashtable_init(&ht, &params);
if (err)
return err;
objs = kcalloc(n, sizeof(*objs), GFP_KERNEL);
if (!objs) {
rhashtable_destroy(&ht);
return -ENOMEM;
}
for (i = 0; i < n; i++) {
objs[i].value.id = i;
err = rhashtable_insert_fast(&ht, &objs[i].node, params);
if (err)
goto out;
}
rcu_read_lock();
/* NULL prev_key: walk from the beginning, expect all n elements. */
while ((cur = rhashtable_next_key(&ht, prev_key))) {
if (IS_ERR(cur)) {
err = -EINVAL;
goto unlock;
}
count++;
prev_key = &cur->value;
visited_keys[cur->value.id] = 1;
if (count > n)
break;
}
if (count != n) {
err = -EINVAL;
goto unlock;
}
for (i = 0; i < n; i++) {
if (!visited_keys[i]) {
err = -EINVAL;
goto unlock;
}
}
/* Non-existing prev_key: must return ERR_PTR(-ENOENT). */
cur = rhashtable_next_key(&ht, &key_missing);
if (!IS_ERR(cur) || PTR_ERR(cur) != -ENOENT)
err = -EINVAL;
unlock:
rcu_read_unlock();
out:
for (i = 0; i < n; i++)
rhashtable_remove_fast(&ht, &objs[i].node, params);
kfree(objs);
rhashtable_destroy(&ht);
return err;
}
static int __init test_rht_init(void)
{
unsigned int entries;
@ -738,6 +810,9 @@ static int __init test_rht_init(void)
test_insert_duplicates_run();
pr_info("Testing rhashtable_next_key: %s\n",
test_rhashtable_next_key() == 0 ? "pass" : "FAIL");
if (!tcount)
return 0;