Patch "test_rhashtable: add test case for rhltable with duplicate objects" has been added to the 4.15-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
test_rhashtable: add test case for rhltable with duplicate objects
to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
test_rhashtable-add-test-case-for-rhltable-with-duplicate-objects.patch
and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Wed Mar 28 18:37:51 CEST 2018
From: Paul Blakey <[email protected]>
Date: Sun, 4 Mar 2018 17:29:49 +0200
Subject: test_rhashtable: add test case for rhltable with duplicate objects
From: Paul Blakey <[email protected]>
[ Upstream commit 499ac3b60f657dae82055fc81c7b01e6242ac9bc ]
Tries to insert duplicates in the middle of bucket's chain:
bucket 1: [[val 21 (tid=1)]] -> [[ val 1 (tid=2), val 1 (tid=0) ]]
Reuses tid to distinguish the elements insertion order.
--- lib/test_rhashtable.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+)
lib/test_rhashtable.c +134 -0
@@ -79,6 +79,21 @@ struct thread_data {struct test_obj *objs; }; +static u32 my_hashfn (const void *data,u32 len,u32 seed) +{ +const struct test_obj_rhl *obj = data; + +return (obj->value.id %10 ) <<RHT_HASH_RESERVED_SPACE ; +} + +static int my_cmpfn (struct rhashtable_compare_arg *arg,const void *obj) +{ +const struct test_obj_rhl *test_obj = obj; +const struct test_obj_val *val = arg->key; + +return test_obj->value.id - val->id; +} +static struct rhashtable_params test_rht_params = { .head_offset = offsetof(struct test_obj , node), .key_offset = offsetof(struct test_obj , value),
@@ -87,6 +102,17 @@ static struct rhashtable_params test_rht .nulls_base = (3U << RHT_BASE_SHIFT), }; +static struct rhashtable_params test_rht_params_dup = { + .head_offset = offsetof(struct test_obj_rhl , list_node), + .key_offset = offsetof(struct test_obj_rhl , value), + .key_len =sizeof (struct test_obj_val ), + .hashfn = jhash, + .obj_hashfn = my_hashfn, + .obj_cmpfn = my_cmpfn, + .nelem_hint =128 , + .automatic_shrinking = false, +}; +static struct semaphore prestart_sem;static struct semaphore startup_sem =__SEMAPHORE_INITIALIZER (startup_sem,0 );
@@ -469,6 +495,112 @@ static int __init test_rhashtable_max(streturn err; } +static unsigned int __init print_ht (struct rhltable *rhlt) +{ +struct rhashtable *ht; +const struct bucket_table *tbl; +char buff[512 ] ="" ; +unsigned int i, cnt =0 ; + + ht = &rhlt->ht; + tbl =rht_dereference (ht->tbl, ht); +for (i =0 ; i < tbl->size; i++) { +struct rhash_head *pos, *next; +struct test_obj_rhl *p; + + pos =rht_dereference (tbl->buckets[i], ht); + next = !rht_is_a_nulls (pos) ?rht_dereference (pos->next, ht) :NULL ; + +if (!rht_is_a_nulls (pos)) { +sprintf (buff,"%s\nbucket[%d] -> " , buff, i); + } + +while (!rht_is_a_nulls (pos)) { + struct rhlist_head *list = container_of(pos, struct rhlist_head, rhead); +sprintf (buff,"%s[[" , buff); +do { + pos = &list->rhead; + list =rht_dereference (list->next, ht); + p =rht_obj (ht, pos); + +sprintf (buff,"%s val %d (tid=%d)%s" , buff, p->value.id, p->value.tid, + list?", " :" " ); + cnt++; + }while (list); + + pos = next, + next = !rht_is_a_nulls (pos) ? +rht_dereference (pos->next, ht) :NULL ; + +sprintf (buff,"%s]]%s" , buff, !rht_is_a_nulls (pos) ?" -> " :"" ); + } + } +printk (KERN_ERR "\n---- ht: ----%s\n-------------\n" , buff); + +return cnt; +} + +static int __init test_insert_dup (struct test_obj_rhl *rhl_test_objects, +int cnt,bool slow) +{ +struct rhltable rhlt; +unsigned int i, ret; +const char *key; +int err =0 ; + + err =rhltable_init (&rhlt, &test_rht_params_dup); +if (WARN_ON (err)) +return err; + +for (i =0 ; i < cnt; i++) { + rhl_test_objects[i].value.tid = i; + key =rht_obj (&rhlt.ht, &rhl_test_objects[i].list_node.rhead); + key += test_rht_params_dup.key_offset; + +if (slow) { + err =PTR_ERR (rhashtable_insert_slow (&rhlt.ht, key, + &rhl_test_objects[i].list_node.rhead)); +if (err == -EAGAIN ) + err =0 ; + }else + err =rhltable_insert (&rhlt, + &rhl_test_objects[i].list_node, + test_rht_params_dup); +if (WARN (err,"error %d on element %d/%d (%s)\n" , err, i, cnt, slow?"slow" :"fast" )) + goto skip_print; + } + + ret =print_ht (&rhlt); +WARN (ret != cnt,"missing rhltable elements (%d != %d, %s)\n" , ret, cnt, slow?"slow" :"fast" ); + +skip_print: +rhltable_destroy (&rhlt); + +return 0 ; +} + +static int __init test_insert_duplicates_run (void ) +{ +struct test_obj_rhl rhl_test_objects[3 ] = {}; + +pr_info ("test inserting duplicates\n" ); + +/* two different values that map to same bucket */ + rhl_test_objects[0 ].value.id =1 ; + rhl_test_objects[1 ].value.id =21 ; + +/* and another duplicate with same as [0] value +* which will be second on the bucket list */ + rhl_test_objects[2 ].value.id = rhl_test_objects[0 ].value.id; + +test_insert_dup (rhl_test_objects,2 , false); +test_insert_dup (rhl_test_objects,3 , false); +test_insert_dup (rhl_test_objects,2 , true); +test_insert_dup (rhl_test_objects,3 , true); + +return 0 ; +} +static int thread_lookup_test (struct thread_data *tdata) {unsigned int entries = tdata->entries;
@@ -617,6 +749,8 @@ static int __init test_rht_init(void)do_div (total_time, runs);pr_info ("Average test time: %llu\n" , total_time); +test_insert_duplicates_run (); +if (!tcount)return 0 ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.15/rhashtable-fix-rhlist-duplicates-insertion.patch queue-4.15/test_rhashtable-add-test-case-for-rhltable-with-duplicate-objects.patch