diff options
Diffstat (limited to 'lib/test_xarray.c')
-rw-r--r-- | lib/test_xarray.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/lib/test_xarray.c b/lib/test_xarray.c index a96f67caa1c2..85ef1882dd3c 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c | |||
@@ -465,6 +465,120 @@ static noinline void check_find(struct xarray *xa) | |||
465 | check_multi_find_2(xa); | 465 | check_multi_find_2(xa); |
466 | } | 466 | } |
467 | 467 | ||
468 | static noinline void check_move_small(struct xarray *xa, unsigned long idx) | ||
469 | { | ||
470 | XA_STATE(xas, xa, 0); | ||
471 | unsigned long i; | ||
472 | |||
473 | xa_store_index(xa, 0, GFP_KERNEL); | ||
474 | xa_store_index(xa, idx, GFP_KERNEL); | ||
475 | |||
476 | rcu_read_lock(); | ||
477 | for (i = 0; i < idx * 4; i++) { | ||
478 | void *entry = xas_next(&xas); | ||
479 | if (i <= idx) | ||
480 | XA_BUG_ON(xa, xas.xa_node == XAS_RESTART); | ||
481 | XA_BUG_ON(xa, xas.xa_index != i); | ||
482 | if (i == 0 || i == idx) | ||
483 | XA_BUG_ON(xa, entry != xa_mk_value(i)); | ||
484 | else | ||
485 | XA_BUG_ON(xa, entry != NULL); | ||
486 | } | ||
487 | xas_next(&xas); | ||
488 | XA_BUG_ON(xa, xas.xa_index != i); | ||
489 | |||
490 | do { | ||
491 | void *entry = xas_prev(&xas); | ||
492 | i--; | ||
493 | if (i <= idx) | ||
494 | XA_BUG_ON(xa, xas.xa_node == XAS_RESTART); | ||
495 | XA_BUG_ON(xa, xas.xa_index != i); | ||
496 | if (i == 0 || i == idx) | ||
497 | XA_BUG_ON(xa, entry != xa_mk_value(i)); | ||
498 | else | ||
499 | XA_BUG_ON(xa, entry != NULL); | ||
500 | } while (i > 0); | ||
501 | |||
502 | xas_set(&xas, ULONG_MAX); | ||
503 | XA_BUG_ON(xa, xas_next(&xas) != NULL); | ||
504 | XA_BUG_ON(xa, xas.xa_index != ULONG_MAX); | ||
505 | XA_BUG_ON(xa, xas_next(&xas) != xa_mk_value(0)); | ||
506 | XA_BUG_ON(xa, xas.xa_index != 0); | ||
507 | XA_BUG_ON(xa, xas_prev(&xas) != NULL); | ||
508 | XA_BUG_ON(xa, xas.xa_index != ULONG_MAX); | ||
509 | rcu_read_unlock(); | ||
510 | |||
511 | xa_erase_index(xa, 0); | ||
512 | xa_erase_index(xa, idx); | ||
513 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
514 | } | ||
515 | |||
516 | static noinline void check_move(struct xarray *xa) | ||
517 | { | ||
518 | XA_STATE(xas, xa, (1 << 16) - 1); | ||
519 | unsigned long i; | ||
520 | |||
521 | for (i = 0; i < (1 << 16); i++) | ||
522 | XA_BUG_ON(xa, xa_store_index(xa, i, GFP_KERNEL) != NULL); | ||
523 | |||
524 | rcu_read_lock(); | ||
525 | do { | ||
526 | void *entry = xas_prev(&xas); | ||
527 | i--; | ||
528 | XA_BUG_ON(xa, entry != xa_mk_value(i)); | ||
529 | XA_BUG_ON(xa, i != xas.xa_index); | ||
530 | } while (i != 0); | ||
531 | |||
532 | XA_BUG_ON(xa, xas_prev(&xas) != NULL); | ||
533 | XA_BUG_ON(xa, xas.xa_index != ULONG_MAX); | ||
534 | |||
535 | do { | ||
536 | void *entry = xas_next(&xas); | ||
537 | XA_BUG_ON(xa, entry != xa_mk_value(i)); | ||
538 | XA_BUG_ON(xa, i != xas.xa_index); | ||
539 | i++; | ||
540 | } while (i < (1 << 16)); | ||
541 | rcu_read_unlock(); | ||
542 | |||
543 | for (i = (1 << 8); i < (1 << 15); i++) | ||
544 | xa_erase_index(xa, i); | ||
545 | |||
546 | i = xas.xa_index; | ||
547 | |||
548 | rcu_read_lock(); | ||
549 | do { | ||
550 | void *entry = xas_prev(&xas); | ||
551 | i--; | ||
552 | if ((i < (1 << 8)) || (i >= (1 << 15))) | ||
553 | XA_BUG_ON(xa, entry != xa_mk_value(i)); | ||
554 | else | ||
555 | XA_BUG_ON(xa, entry != NULL); | ||
556 | XA_BUG_ON(xa, i != xas.xa_index); | ||
557 | } while (i != 0); | ||
558 | |||
559 | XA_BUG_ON(xa, xas_prev(&xas) != NULL); | ||
560 | XA_BUG_ON(xa, xas.xa_index != ULONG_MAX); | ||
561 | |||
562 | do { | ||
563 | void *entry = xas_next(&xas); | ||
564 | if ((i < (1 << 8)) || (i >= (1 << 15))) | ||
565 | XA_BUG_ON(xa, entry != xa_mk_value(i)); | ||
566 | else | ||
567 | XA_BUG_ON(xa, entry != NULL); | ||
568 | XA_BUG_ON(xa, i != xas.xa_index); | ||
569 | i++; | ||
570 | } while (i < (1 << 16)); | ||
571 | rcu_read_unlock(); | ||
572 | |||
573 | xa_destroy(xa); | ||
574 | |||
575 | for (i = 0; i < 16; i++) | ||
576 | check_move_small(xa, 1UL << i); | ||
577 | |||
578 | for (i = 2; i < 16; i++) | ||
579 | check_move_small(xa, (1UL << i) - 1); | ||
580 | } | ||
581 | |||
468 | static noinline void check_destroy(struct xarray *xa) | 582 | static noinline void check_destroy(struct xarray *xa) |
469 | { | 583 | { |
470 | unsigned long index; | 584 | unsigned long index; |
@@ -512,6 +626,7 @@ static int xarray_checks(void) | |||
512 | check_multi_store(&array); | 626 | check_multi_store(&array); |
513 | check_find(&array); | 627 | check_find(&array); |
514 | check_destroy(&array); | 628 | check_destroy(&array); |
629 | check_move(&array); | ||
515 | 630 | ||
516 | printk("XArray: %u of %u tests passed\n", tests_passed, tests_run); | 631 | printk("XArray: %u of %u tests passed\n", tests_passed, tests_run); |
517 | return (tests_run == tests_passed) ? 0 : -EINVAL; | 632 | return (tests_run == tests_passed) ? 0 : -EINVAL; |