diff options
Diffstat (limited to 'lib/test_xarray.c')
-rw-r--r-- | lib/test_xarray.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 85ef1882dd3c..8eba3de1baea 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c | |||
@@ -365,6 +365,73 @@ static noinline void check_multi_store(struct xarray *xa) | |||
365 | #endif | 365 | #endif |
366 | } | 366 | } |
367 | 367 | ||
368 | static noinline void __check_store_iter(struct xarray *xa, unsigned long start, | ||
369 | unsigned int order, unsigned int present) | ||
370 | { | ||
371 | XA_STATE_ORDER(xas, xa, start, order); | ||
372 | void *entry; | ||
373 | unsigned int count = 0; | ||
374 | |||
375 | retry: | ||
376 | xas_lock(&xas); | ||
377 | xas_for_each_conflict(&xas, entry) { | ||
378 | XA_BUG_ON(xa, !xa_is_value(entry)); | ||
379 | XA_BUG_ON(xa, entry < xa_mk_value(start)); | ||
380 | XA_BUG_ON(xa, entry > xa_mk_value(start + (1UL << order) - 1)); | ||
381 | count++; | ||
382 | } | ||
383 | xas_store(&xas, xa_mk_value(start)); | ||
384 | xas_unlock(&xas); | ||
385 | if (xas_nomem(&xas, GFP_KERNEL)) { | ||
386 | count = 0; | ||
387 | goto retry; | ||
388 | } | ||
389 | XA_BUG_ON(xa, xas_error(&xas)); | ||
390 | XA_BUG_ON(xa, count != present); | ||
391 | XA_BUG_ON(xa, xa_load(xa, start) != xa_mk_value(start)); | ||
392 | XA_BUG_ON(xa, xa_load(xa, start + (1UL << order) - 1) != | ||
393 | xa_mk_value(start)); | ||
394 | xa_erase_index(xa, start); | ||
395 | } | ||
396 | |||
397 | static noinline void check_store_iter(struct xarray *xa) | ||
398 | { | ||
399 | unsigned int i, j; | ||
400 | unsigned int max_order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 20 : 1; | ||
401 | |||
402 | for (i = 0; i < max_order; i++) { | ||
403 | unsigned int min = 1 << i; | ||
404 | unsigned int max = (2 << i) - 1; | ||
405 | __check_store_iter(xa, 0, i, 0); | ||
406 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
407 | __check_store_iter(xa, min, i, 0); | ||
408 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
409 | |||
410 | xa_store_index(xa, min, GFP_KERNEL); | ||
411 | __check_store_iter(xa, min, i, 1); | ||
412 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
413 | xa_store_index(xa, max, GFP_KERNEL); | ||
414 | __check_store_iter(xa, min, i, 1); | ||
415 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
416 | |||
417 | for (j = 0; j < min; j++) | ||
418 | xa_store_index(xa, j, GFP_KERNEL); | ||
419 | __check_store_iter(xa, 0, i, min); | ||
420 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
421 | for (j = 0; j < min; j++) | ||
422 | xa_store_index(xa, min + j, GFP_KERNEL); | ||
423 | __check_store_iter(xa, min, i, min); | ||
424 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
425 | } | ||
426 | #ifdef CONFIG_XARRAY_MULTI | ||
427 | xa_store_index(xa, 63, GFP_KERNEL); | ||
428 | xa_store_index(xa, 65, GFP_KERNEL); | ||
429 | __check_store_iter(xa, 64, 2, 1); | ||
430 | xa_erase_index(xa, 63); | ||
431 | #endif | ||
432 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
433 | } | ||
434 | |||
368 | static noinline void check_multi_find(struct xarray *xa) | 435 | static noinline void check_multi_find(struct xarray *xa) |
369 | { | 436 | { |
370 | #ifdef CONFIG_XARRAY_MULTI | 437 | #ifdef CONFIG_XARRAY_MULTI |
@@ -627,6 +694,7 @@ static int xarray_checks(void) | |||
627 | check_find(&array); | 694 | check_find(&array); |
628 | check_destroy(&array); | 695 | check_destroy(&array); |
629 | check_move(&array); | 696 | check_move(&array); |
697 | check_store_iter(&array); | ||
630 | 698 | ||
631 | printk("XArray: %u of %u tests passed\n", tests_passed, tests_run); | 699 | printk("XArray: %u of %u tests passed\n", tests_passed, tests_run); |
632 | return (tests_run == tests_passed) ? 0 : -EINVAL; | 700 | return (tests_run == tests_passed) ? 0 : -EINVAL; |