diff options
author | Matthew Wilcox <willy@infradead.org> | 2017-11-22 08:36:00 -0500 |
---|---|---|
committer | Matthew Wilcox <willy@infradead.org> | 2018-10-21 10:46:39 -0400 |
commit | e21a29552fa3f44ea41c53488875015ae70fd7f8 (patch) | |
tree | 615c10e662faa49f3910fb269d4be6d029513632 /lib | |
parent | a12831bf4293d38518e41b80dd897af0122bb268 (diff) |
shmem: Convert find_swap_entry to XArray
This is a 1:1 conversion. The major part of this patch is converting
the test framework from userspace to kernel space and mirroring the
algorithm now used in find_swap_entry().
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/test_xarray.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 128c6489082f..815daffdd8c9 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c | |||
@@ -631,6 +631,61 @@ static noinline void check_find(struct xarray *xa) | |||
631 | check_multi_find_2(xa); | 631 | check_multi_find_2(xa); |
632 | } | 632 | } |
633 | 633 | ||
634 | /* See find_swap_entry() in mm/shmem.c */ | ||
635 | static noinline unsigned long xa_find_entry(struct xarray *xa, void *item) | ||
636 | { | ||
637 | XA_STATE(xas, xa, 0); | ||
638 | unsigned int checked = 0; | ||
639 | void *entry; | ||
640 | |||
641 | rcu_read_lock(); | ||
642 | xas_for_each(&xas, entry, ULONG_MAX) { | ||
643 | if (xas_retry(&xas, entry)) | ||
644 | continue; | ||
645 | if (entry == item) | ||
646 | break; | ||
647 | checked++; | ||
648 | if ((checked % 4) != 0) | ||
649 | continue; | ||
650 | xas_pause(&xas); | ||
651 | } | ||
652 | rcu_read_unlock(); | ||
653 | |||
654 | return entry ? xas.xa_index : -1; | ||
655 | } | ||
656 | |||
657 | static noinline void check_find_entry(struct xarray *xa) | ||
658 | { | ||
659 | #ifdef CONFIG_XARRAY_MULTI | ||
660 | unsigned int order; | ||
661 | unsigned long offset, index; | ||
662 | |||
663 | for (order = 0; order < 20; order++) { | ||
664 | for (offset = 0; offset < (1UL << (order + 3)); | ||
665 | offset += (1UL << order)) { | ||
666 | for (index = 0; index < (1UL << (order + 5)); | ||
667 | index += (1UL << order)) { | ||
668 | xa_store_order(xa, index, order, | ||
669 | xa_mk_value(index), GFP_KERNEL); | ||
670 | XA_BUG_ON(xa, xa_load(xa, index) != | ||
671 | xa_mk_value(index)); | ||
672 | XA_BUG_ON(xa, xa_find_entry(xa, | ||
673 | xa_mk_value(index)) != index); | ||
674 | } | ||
675 | XA_BUG_ON(xa, xa_find_entry(xa, xa) != -1); | ||
676 | xa_destroy(xa); | ||
677 | } | ||
678 | } | ||
679 | #endif | ||
680 | |||
681 | XA_BUG_ON(xa, xa_find_entry(xa, xa) != -1); | ||
682 | xa_store_index(xa, ULONG_MAX, GFP_KERNEL); | ||
683 | XA_BUG_ON(xa, xa_find_entry(xa, xa) != -1); | ||
684 | XA_BUG_ON(xa, xa_find_entry(xa, xa_mk_value(LONG_MAX)) != -1); | ||
685 | xa_erase_index(xa, ULONG_MAX); | ||
686 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
687 | } | ||
688 | |||
634 | static noinline void check_move_small(struct xarray *xa, unsigned long idx) | 689 | static noinline void check_move_small(struct xarray *xa, unsigned long idx) |
635 | { | 690 | { |
636 | XA_STATE(xas, xa, 0); | 691 | XA_STATE(xas, xa, 0); |
@@ -972,6 +1027,7 @@ static int xarray_checks(void) | |||
972 | check_multi_store(&array); | 1027 | check_multi_store(&array); |
973 | check_xa_alloc(); | 1028 | check_xa_alloc(); |
974 | check_find(&array); | 1029 | check_find(&array); |
1030 | check_find_entry(&array); | ||
975 | check_destroy(&array); | 1031 | check_destroy(&array); |
976 | check_move(&array); | 1032 | check_move(&array); |
977 | check_create_range(&array); | 1033 | check_create_range(&array); |