diff options
Diffstat (limited to 'lib/test_rhashtable.c')
-rw-r--r-- | lib/test_rhashtable.c | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index 64e899b63337..0ffca990a833 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c | |||
@@ -56,8 +56,13 @@ static bool enomem_retry = false; | |||
56 | module_param(enomem_retry, bool, 0); | 56 | module_param(enomem_retry, bool, 0); |
57 | MODULE_PARM_DESC(enomem_retry, "Retry insert even if -ENOMEM was returned (default: off)"); | 57 | MODULE_PARM_DESC(enomem_retry, "Retry insert even if -ENOMEM was returned (default: off)"); |
58 | 58 | ||
59 | struct test_obj_val { | ||
60 | int id; | ||
61 | int tid; | ||
62 | }; | ||
63 | |||
59 | struct test_obj { | 64 | struct test_obj { |
60 | int value; | 65 | struct test_obj_val value; |
61 | struct rhash_head node; | 66 | struct rhash_head node; |
62 | }; | 67 | }; |
63 | 68 | ||
@@ -72,7 +77,7 @@ static struct test_obj array[MAX_ENTRIES]; | |||
72 | static struct rhashtable_params test_rht_params = { | 77 | static struct rhashtable_params test_rht_params = { |
73 | .head_offset = offsetof(struct test_obj, node), | 78 | .head_offset = offsetof(struct test_obj, node), |
74 | .key_offset = offsetof(struct test_obj, value), | 79 | .key_offset = offsetof(struct test_obj, value), |
75 | .key_len = sizeof(int), | 80 | .key_len = sizeof(struct test_obj_val), |
76 | .hashfn = jhash, | 81 | .hashfn = jhash, |
77 | .nulls_base = (3U << RHT_BASE_SHIFT), | 82 | .nulls_base = (3U << RHT_BASE_SHIFT), |
78 | }; | 83 | }; |
@@ -109,24 +114,26 @@ static int __init test_rht_lookup(struct rhashtable *ht) | |||
109 | for (i = 0; i < entries * 2; i++) { | 114 | for (i = 0; i < entries * 2; i++) { |
110 | struct test_obj *obj; | 115 | struct test_obj *obj; |
111 | bool expected = !(i % 2); | 116 | bool expected = !(i % 2); |
112 | u32 key = i; | 117 | struct test_obj_val key = { |
118 | .id = i, | ||
119 | }; | ||
113 | 120 | ||
114 | if (array[i / 2].value == TEST_INSERT_FAIL) | 121 | if (array[i / 2].value.id == TEST_INSERT_FAIL) |
115 | expected = false; | 122 | expected = false; |
116 | 123 | ||
117 | obj = rhashtable_lookup_fast(ht, &key, test_rht_params); | 124 | obj = rhashtable_lookup_fast(ht, &key, test_rht_params); |
118 | 125 | ||
119 | if (expected && !obj) { | 126 | if (expected && !obj) { |
120 | pr_warn("Test failed: Could not find key %u\n", key); | 127 | pr_warn("Test failed: Could not find key %u\n", key.id); |
121 | return -ENOENT; | 128 | return -ENOENT; |
122 | } else if (!expected && obj) { | 129 | } else if (!expected && obj) { |
123 | pr_warn("Test failed: Unexpected entry found for key %u\n", | 130 | pr_warn("Test failed: Unexpected entry found for key %u\n", |
124 | key); | 131 | key.id); |
125 | return -EEXIST; | 132 | return -EEXIST; |
126 | } else if (expected && obj) { | 133 | } else if (expected && obj) { |
127 | if (obj->value != i) { | 134 | if (obj->value.id != i) { |
128 | pr_warn("Test failed: Lookup value mismatch %u!=%u\n", | 135 | pr_warn("Test failed: Lookup value mismatch %u!=%u\n", |
129 | obj->value, i); | 136 | obj->value.id, i); |
130 | return -EINVAL; | 137 | return -EINVAL; |
131 | } | 138 | } |
132 | } | 139 | } |
@@ -195,7 +202,7 @@ static s64 __init test_rhashtable(struct rhashtable *ht) | |||
195 | for (i = 0; i < entries; i++) { | 202 | for (i = 0; i < entries; i++) { |
196 | struct test_obj *obj = &array[i]; | 203 | struct test_obj *obj = &array[i]; |
197 | 204 | ||
198 | obj->value = i * 2; | 205 | obj->value.id = i * 2; |
199 | err = insert_retry(ht, &obj->node, test_rht_params); | 206 | err = insert_retry(ht, &obj->node, test_rht_params); |
200 | if (err > 0) | 207 | if (err > 0) |
201 | insert_retries += err; | 208 | insert_retries += err; |
@@ -216,9 +223,11 @@ static s64 __init test_rhashtable(struct rhashtable *ht) | |||
216 | 223 | ||
217 | pr_info(" Deleting %d keys\n", entries); | 224 | pr_info(" Deleting %d keys\n", entries); |
218 | for (i = 0; i < entries; i++) { | 225 | for (i = 0; i < entries; i++) { |
219 | u32 key = i * 2; | 226 | struct test_obj_val key = { |
227 | .id = i * 2, | ||
228 | }; | ||
220 | 229 | ||
221 | if (array[i].value != TEST_INSERT_FAIL) { | 230 | if (array[i].value.id != TEST_INSERT_FAIL) { |
222 | obj = rhashtable_lookup_fast(ht, &key, test_rht_params); | 231 | obj = rhashtable_lookup_fast(ht, &key, test_rht_params); |
223 | BUG_ON(!obj); | 232 | BUG_ON(!obj); |
224 | 233 | ||
@@ -242,18 +251,21 @@ static int thread_lookup_test(struct thread_data *tdata) | |||
242 | 251 | ||
243 | for (i = 0; i < entries; i++) { | 252 | for (i = 0; i < entries; i++) { |
244 | struct test_obj *obj; | 253 | struct test_obj *obj; |
245 | int key = (tdata->id << 16) | i; | 254 | struct test_obj_val key = { |
255 | .id = i, | ||
256 | .tid = tdata->id, | ||
257 | }; | ||
246 | 258 | ||
247 | obj = rhashtable_lookup_fast(&ht, &key, test_rht_params); | 259 | obj = rhashtable_lookup_fast(&ht, &key, test_rht_params); |
248 | if (obj && (tdata->objs[i].value == TEST_INSERT_FAIL)) { | 260 | if (obj && (tdata->objs[i].value.id == TEST_INSERT_FAIL)) { |
249 | pr_err(" found unexpected object %d\n", key); | 261 | pr_err(" found unexpected object %d-%d\n", key.tid, key.id); |
250 | err++; | 262 | err++; |
251 | } else if (!obj && (tdata->objs[i].value != TEST_INSERT_FAIL)) { | 263 | } else if (!obj && (tdata->objs[i].value.id != TEST_INSERT_FAIL)) { |
252 | pr_err(" object %d not found!\n", key); | 264 | pr_err(" object %d-%d not found!\n", key.tid, key.id); |
253 | err++; | 265 | err++; |
254 | } else if (obj && (obj->value != key)) { | 266 | } else if (obj && memcmp(&obj->value, &key, sizeof(key))) { |
255 | pr_err(" wrong object returned (got %d, expected %d)\n", | 267 | pr_err(" wrong object returned (got %d-%d, expected %d-%d)\n", |
256 | obj->value, key); | 268 | obj->value.tid, obj->value.id, key.tid, key.id); |
257 | err++; | 269 | err++; |
258 | } | 270 | } |
259 | 271 | ||
@@ -272,7 +284,8 @@ static int threadfunc(void *data) | |||
272 | pr_err(" thread[%d]: down_interruptible failed\n", tdata->id); | 284 | pr_err(" thread[%d]: down_interruptible failed\n", tdata->id); |
273 | 285 | ||
274 | for (i = 0; i < entries; i++) { | 286 | for (i = 0; i < entries; i++) { |
275 | tdata->objs[i].value = (tdata->id << 16) | i; | 287 | tdata->objs[i].value.id = i; |
288 | tdata->objs[i].value.tid = tdata->id; | ||
276 | err = insert_retry(&ht, &tdata->objs[i].node, test_rht_params); | 289 | err = insert_retry(&ht, &tdata->objs[i].node, test_rht_params); |
277 | if (err > 0) { | 290 | if (err > 0) { |
278 | insert_retries += err; | 291 | insert_retries += err; |
@@ -295,7 +308,7 @@ static int threadfunc(void *data) | |||
295 | 308 | ||
296 | for (step = 10; step > 0; step--) { | 309 | for (step = 10; step > 0; step--) { |
297 | for (i = 0; i < entries; i += step) { | 310 | for (i = 0; i < entries; i += step) { |
298 | if (tdata->objs[i].value == TEST_INSERT_FAIL) | 311 | if (tdata->objs[i].value.id == TEST_INSERT_FAIL) |
299 | continue; | 312 | continue; |
300 | err = rhashtable_remove_fast(&ht, &tdata->objs[i].node, | 313 | err = rhashtable_remove_fast(&ht, &tdata->objs[i].node, |
301 | test_rht_params); | 314 | test_rht_params); |
@@ -304,7 +317,7 @@ static int threadfunc(void *data) | |||
304 | tdata->id); | 317 | tdata->id); |
305 | goto out; | 318 | goto out; |
306 | } | 319 | } |
307 | tdata->objs[i].value = TEST_INSERT_FAIL; | 320 | tdata->objs[i].value.id = TEST_INSERT_FAIL; |
308 | 321 | ||
309 | cond_resched(); | 322 | cond_resched(); |
310 | } | 323 | } |