diff options
author | Matthew Wilcox <willy@infradead.org> | 2018-12-31 10:41:01 -0500 |
---|---|---|
committer | Matthew Wilcox <willy@infradead.org> | 2019-02-06 13:32:23 -0500 |
commit | a3e4d3f97ec844de005a679585c04c5c03dfbdb6 (patch) | |
tree | c4cda3a98cba2d9923e7356e587f6a958b2971d7 /lib/test_xarray.c | |
parent | 3ccaf57a6a63ad171a951dcaddffc453b2414c7b (diff) |
XArray: Redesign xa_alloc API
It was too easy to forget to initialise the start index. Add an
xa_limit data structure which can be used to pass min & max, and
define a couple of special values for common cases. Also add some
more tests cribbed from the IDR test suite. Change the return value
from -ENOSPC to -EBUSY to match xa_insert().
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'lib/test_xarray.c')
-rw-r--r-- | lib/test_xarray.c | 86 |
1 files changed, 70 insertions, 16 deletions
diff --git a/lib/test_xarray.c b/lib/test_xarray.c index cd74f8f32abe..b5a6b981454d 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c | |||
@@ -40,9 +40,9 @@ static void *xa_store_index(struct xarray *xa, unsigned long index, gfp_t gfp) | |||
40 | 40 | ||
41 | static void xa_alloc_index(struct xarray *xa, unsigned long index, gfp_t gfp) | 41 | static void xa_alloc_index(struct xarray *xa, unsigned long index, gfp_t gfp) |
42 | { | 42 | { |
43 | u32 id = 0; | 43 | u32 id; |
44 | 44 | ||
45 | XA_BUG_ON(xa, xa_alloc(xa, &id, UINT_MAX, xa_mk_index(index), | 45 | XA_BUG_ON(xa, xa_alloc(xa, &id, xa_mk_index(index), xa_limit_32b, |
46 | gfp) != 0); | 46 | gfp) != 0); |
47 | XA_BUG_ON(xa, id != index); | 47 | XA_BUG_ON(xa, id != index); |
48 | } | 48 | } |
@@ -640,28 +640,81 @@ static noinline void check_xa_alloc_1(struct xarray *xa, unsigned int base) | |||
640 | xa_destroy(xa); | 640 | xa_destroy(xa); |
641 | 641 | ||
642 | /* Check that we fail properly at the limit of allocation */ | 642 | /* Check that we fail properly at the limit of allocation */ |
643 | id = 0xfffffffeU; | 643 | XA_BUG_ON(xa, xa_alloc(xa, &id, xa_mk_index(UINT_MAX - 1), |
644 | XA_BUG_ON(xa, xa_alloc(xa, &id, UINT_MAX, xa_mk_index(id), | 644 | XA_LIMIT(UINT_MAX - 1, UINT_MAX), |
645 | GFP_KERNEL) != 0); | 645 | GFP_KERNEL) != 0); |
646 | XA_BUG_ON(xa, id != 0xfffffffeU); | 646 | XA_BUG_ON(xa, id != 0xfffffffeU); |
647 | XA_BUG_ON(xa, xa_alloc(xa, &id, UINT_MAX, xa_mk_index(id), | 647 | XA_BUG_ON(xa, xa_alloc(xa, &id, xa_mk_index(UINT_MAX), |
648 | XA_LIMIT(UINT_MAX - 1, UINT_MAX), | ||
648 | GFP_KERNEL) != 0); | 649 | GFP_KERNEL) != 0); |
649 | XA_BUG_ON(xa, id != 0xffffffffU); | 650 | XA_BUG_ON(xa, id != 0xffffffffU); |
650 | XA_BUG_ON(xa, xa_alloc(xa, &id, UINT_MAX, xa_mk_index(id), | 651 | id = 3; |
651 | GFP_KERNEL) != -ENOSPC); | 652 | XA_BUG_ON(xa, xa_alloc(xa, &id, xa_mk_index(0), |
652 | XA_BUG_ON(xa, id != 0xffffffffU); | 653 | XA_LIMIT(UINT_MAX - 1, UINT_MAX), |
654 | GFP_KERNEL) != -EBUSY); | ||
655 | XA_BUG_ON(xa, id != 3); | ||
653 | xa_destroy(xa); | 656 | xa_destroy(xa); |
654 | 657 | ||
655 | id = 10; | 658 | XA_BUG_ON(xa, xa_alloc(xa, &id, xa_mk_index(10), XA_LIMIT(10, 5), |
656 | XA_BUG_ON(xa, xa_alloc(xa, &id, 5, xa_mk_index(id), | 659 | GFP_KERNEL) != -EBUSY); |
657 | GFP_KERNEL) != -ENOSPC); | ||
658 | XA_BUG_ON(xa, xa_store_index(xa, 3, GFP_KERNEL) != 0); | 660 | XA_BUG_ON(xa, xa_store_index(xa, 3, GFP_KERNEL) != 0); |
659 | XA_BUG_ON(xa, xa_alloc(xa, &id, 5, xa_mk_index(id), | 661 | XA_BUG_ON(xa, xa_alloc(xa, &id, xa_mk_index(10), XA_LIMIT(10, 5), |
660 | GFP_KERNEL) != -ENOSPC); | 662 | GFP_KERNEL) != -EBUSY); |
661 | xa_erase_index(xa, 3); | 663 | xa_erase_index(xa, 3); |
662 | XA_BUG_ON(xa, !xa_empty(xa)); | 664 | XA_BUG_ON(xa, !xa_empty(xa)); |
663 | } | 665 | } |
664 | 666 | ||
667 | static noinline void check_xa_alloc_2(struct xarray *xa, unsigned int base) | ||
668 | { | ||
669 | unsigned int i, id; | ||
670 | unsigned long index; | ||
671 | void *entry; | ||
672 | |||
673 | /* Allocate and free a NULL and check xa_empty() behaves */ | ||
674 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
675 | XA_BUG_ON(xa, xa_alloc(xa, &id, NULL, xa_limit_32b, GFP_KERNEL) != 0); | ||
676 | XA_BUG_ON(xa, id != base); | ||
677 | XA_BUG_ON(xa, xa_empty(xa)); | ||
678 | XA_BUG_ON(xa, xa_erase(xa, id) != NULL); | ||
679 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
680 | |||
681 | /* Ditto, but check destroy instead of erase */ | ||
682 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
683 | XA_BUG_ON(xa, xa_alloc(xa, &id, NULL, xa_limit_32b, GFP_KERNEL) != 0); | ||
684 | XA_BUG_ON(xa, id != base); | ||
685 | XA_BUG_ON(xa, xa_empty(xa)); | ||
686 | xa_destroy(xa); | ||
687 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
688 | |||
689 | for (i = base; i < base + 10; i++) { | ||
690 | XA_BUG_ON(xa, xa_alloc(xa, &id, NULL, xa_limit_32b, | ||
691 | GFP_KERNEL) != 0); | ||
692 | XA_BUG_ON(xa, id != i); | ||
693 | } | ||
694 | |||
695 | XA_BUG_ON(xa, xa_store(xa, 3, xa_mk_index(3), GFP_KERNEL) != NULL); | ||
696 | XA_BUG_ON(xa, xa_store(xa, 4, xa_mk_index(4), GFP_KERNEL) != NULL); | ||
697 | XA_BUG_ON(xa, xa_store(xa, 4, NULL, GFP_KERNEL) != xa_mk_index(4)); | ||
698 | XA_BUG_ON(xa, xa_erase(xa, 5) != NULL); | ||
699 | XA_BUG_ON(xa, xa_alloc(xa, &id, NULL, xa_limit_32b, GFP_KERNEL) != 0); | ||
700 | XA_BUG_ON(xa, id != 5); | ||
701 | |||
702 | xa_for_each(xa, index, entry) { | ||
703 | xa_erase_index(xa, index); | ||
704 | } | ||
705 | |||
706 | for (i = base; i < base + 9; i++) { | ||
707 | XA_BUG_ON(xa, xa_erase(xa, i) != NULL); | ||
708 | XA_BUG_ON(xa, xa_empty(xa)); | ||
709 | } | ||
710 | XA_BUG_ON(xa, xa_erase(xa, 8) != NULL); | ||
711 | XA_BUG_ON(xa, xa_empty(xa)); | ||
712 | XA_BUG_ON(xa, xa_erase(xa, base + 9) != NULL); | ||
713 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
714 | |||
715 | xa_destroy(xa); | ||
716 | } | ||
717 | |||
665 | static DEFINE_XARRAY_ALLOC(xa0); | 718 | static DEFINE_XARRAY_ALLOC(xa0); |
666 | static DEFINE_XARRAY_ALLOC1(xa1); | 719 | static DEFINE_XARRAY_ALLOC1(xa1); |
667 | 720 | ||
@@ -669,6 +722,8 @@ static noinline void check_xa_alloc(void) | |||
669 | { | 722 | { |
670 | check_xa_alloc_1(&xa0, 0); | 723 | check_xa_alloc_1(&xa0, 0); |
671 | check_xa_alloc_1(&xa1, 1); | 724 | check_xa_alloc_1(&xa1, 1); |
725 | check_xa_alloc_2(&xa0, 0); | ||
726 | check_xa_alloc_2(&xa1, 1); | ||
672 | } | 727 | } |
673 | 728 | ||
674 | static noinline void __check_store_iter(struct xarray *xa, unsigned long start, | 729 | static noinline void __check_store_iter(struct xarray *xa, unsigned long start, |
@@ -1219,9 +1274,8 @@ static void check_align_1(struct xarray *xa, char *name) | |||
1219 | void *entry; | 1274 | void *entry; |
1220 | 1275 | ||
1221 | for (i = 0; i < 8; i++) { | 1276 | for (i = 0; i < 8; i++) { |
1222 | id = 0; | 1277 | XA_BUG_ON(xa, xa_alloc(xa, &id, name + i, xa_limit_32b, |
1223 | XA_BUG_ON(xa, xa_alloc(xa, &id, UINT_MAX, name + i, GFP_KERNEL) | 1278 | GFP_KERNEL) != 0); |
1224 | != 0); | ||
1225 | XA_BUG_ON(xa, id != i); | 1279 | XA_BUG_ON(xa, id != i); |
1226 | } | 1280 | } |
1227 | xa_for_each(xa, index, entry) | 1281 | xa_for_each(xa, index, entry) |