diff options
Diffstat (limited to 'lib/test_xarray.c')
-rw-r--r-- | lib/test_xarray.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/lib/test_xarray.c b/lib/test_xarray.c index aa47754150ce..0598e86af8fc 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c | |||
@@ -208,15 +208,19 @@ static noinline void check_xa_mark_1(struct xarray *xa, unsigned long index) | |||
208 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_2)); | 208 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_2)); |
209 | 209 | ||
210 | /* We should see two elements in the array */ | 210 | /* We should see two elements in the array */ |
211 | rcu_read_lock(); | ||
211 | xas_for_each(&xas, entry, ULONG_MAX) | 212 | xas_for_each(&xas, entry, ULONG_MAX) |
212 | seen++; | 213 | seen++; |
214 | rcu_read_unlock(); | ||
213 | XA_BUG_ON(xa, seen != 2); | 215 | XA_BUG_ON(xa, seen != 2); |
214 | 216 | ||
215 | /* One of which is marked */ | 217 | /* One of which is marked */ |
216 | xas_set(&xas, 0); | 218 | xas_set(&xas, 0); |
217 | seen = 0; | 219 | seen = 0; |
220 | rcu_read_lock(); | ||
218 | xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0) | 221 | xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0) |
219 | seen++; | 222 | seen++; |
223 | rcu_read_unlock(); | ||
220 | XA_BUG_ON(xa, seen != 1); | 224 | XA_BUG_ON(xa, seen != 1); |
221 | } | 225 | } |
222 | XA_BUG_ON(xa, xa_get_mark(xa, next, XA_MARK_0)); | 226 | XA_BUG_ON(xa, xa_get_mark(xa, next, XA_MARK_0)); |
@@ -373,6 +377,12 @@ static noinline void check_reserve(struct xarray *xa) | |||
373 | xa_erase_index(xa, 12345678); | 377 | xa_erase_index(xa, 12345678); |
374 | XA_BUG_ON(xa, !xa_empty(xa)); | 378 | XA_BUG_ON(xa, !xa_empty(xa)); |
375 | 379 | ||
380 | /* And so does xa_insert */ | ||
381 | xa_reserve(xa, 12345678, GFP_KERNEL); | ||
382 | XA_BUG_ON(xa, xa_insert(xa, 12345678, xa_mk_value(12345678), 0) != 0); | ||
383 | xa_erase_index(xa, 12345678); | ||
384 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
385 | |||
376 | /* Can iterate through a reserved entry */ | 386 | /* Can iterate through a reserved entry */ |
377 | xa_store_index(xa, 5, GFP_KERNEL); | 387 | xa_store_index(xa, 5, GFP_KERNEL); |
378 | xa_reserve(xa, 6, GFP_KERNEL); | 388 | xa_reserve(xa, 6, GFP_KERNEL); |
@@ -436,7 +446,9 @@ static noinline void check_multi_store_1(struct xarray *xa, unsigned long index, | |||
436 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); | 446 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); |
437 | XA_BUG_ON(xa, xa_load(xa, min - 1) != NULL); | 447 | XA_BUG_ON(xa, xa_load(xa, min - 1) != NULL); |
438 | 448 | ||
449 | xas_lock(&xas); | ||
439 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(min)) != xa_mk_value(index)); | 450 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(min)) != xa_mk_value(index)); |
451 | xas_unlock(&xas); | ||
440 | XA_BUG_ON(xa, xa_load(xa, min) != xa_mk_value(min)); | 452 | XA_BUG_ON(xa, xa_load(xa, min) != xa_mk_value(min)); |
441 | XA_BUG_ON(xa, xa_load(xa, max - 1) != xa_mk_value(min)); | 453 | XA_BUG_ON(xa, xa_load(xa, max - 1) != xa_mk_value(min)); |
442 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); | 454 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); |
@@ -452,9 +464,11 @@ static noinline void check_multi_store_2(struct xarray *xa, unsigned long index, | |||
452 | XA_STATE(xas, xa, index); | 464 | XA_STATE(xas, xa, index); |
453 | xa_store_order(xa, index, order, xa_mk_value(0), GFP_KERNEL); | 465 | xa_store_order(xa, index, order, xa_mk_value(0), GFP_KERNEL); |
454 | 466 | ||
467 | xas_lock(&xas); | ||
455 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(1)) != xa_mk_value(0)); | 468 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(1)) != xa_mk_value(0)); |
456 | XA_BUG_ON(xa, xas.xa_index != index); | 469 | XA_BUG_ON(xa, xas.xa_index != index); |
457 | XA_BUG_ON(xa, xas_store(&xas, NULL) != xa_mk_value(1)); | 470 | XA_BUG_ON(xa, xas_store(&xas, NULL) != xa_mk_value(1)); |
471 | xas_unlock(&xas); | ||
458 | XA_BUG_ON(xa, !xa_empty(xa)); | 472 | XA_BUG_ON(xa, !xa_empty(xa)); |
459 | } | 473 | } |
460 | #endif | 474 | #endif |
@@ -498,7 +512,7 @@ static noinline void check_multi_store(struct xarray *xa) | |||
498 | rcu_read_unlock(); | 512 | rcu_read_unlock(); |
499 | 513 | ||
500 | /* We can erase multiple values with a single store */ | 514 | /* We can erase multiple values with a single store */ |
501 | xa_store_order(xa, 0, 63, NULL, GFP_KERNEL); | 515 | xa_store_order(xa, 0, BITS_PER_LONG - 1, NULL, GFP_KERNEL); |
502 | XA_BUG_ON(xa, !xa_empty(xa)); | 516 | XA_BUG_ON(xa, !xa_empty(xa)); |
503 | 517 | ||
504 | /* Even when the first slot is empty but the others aren't */ | 518 | /* Even when the first slot is empty but the others aren't */ |
@@ -702,7 +716,7 @@ static noinline void check_multi_find_2(struct xarray *xa) | |||
702 | } | 716 | } |
703 | } | 717 | } |
704 | 718 | ||
705 | static noinline void check_find(struct xarray *xa) | 719 | static noinline void check_find_1(struct xarray *xa) |
706 | { | 720 | { |
707 | unsigned long i, j, k; | 721 | unsigned long i, j, k; |
708 | 722 | ||
@@ -748,6 +762,34 @@ static noinline void check_find(struct xarray *xa) | |||
748 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_0)); | 762 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_0)); |
749 | } | 763 | } |
750 | XA_BUG_ON(xa, !xa_empty(xa)); | 764 | XA_BUG_ON(xa, !xa_empty(xa)); |
765 | } | ||
766 | |||
767 | static noinline void check_find_2(struct xarray *xa) | ||
768 | { | ||
769 | void *entry; | ||
770 | unsigned long i, j, index = 0; | ||
771 | |||
772 | xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { | ||
773 | XA_BUG_ON(xa, true); | ||
774 | } | ||
775 | |||
776 | for (i = 0; i < 1024; i++) { | ||
777 | xa_store_index(xa, index, GFP_KERNEL); | ||
778 | j = 0; | ||
779 | index = 0; | ||
780 | xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { | ||
781 | XA_BUG_ON(xa, xa_mk_value(index) != entry); | ||
782 | XA_BUG_ON(xa, index != j++); | ||
783 | } | ||
784 | } | ||
785 | |||
786 | xa_destroy(xa); | ||
787 | } | ||
788 | |||
789 | static noinline void check_find(struct xarray *xa) | ||
790 | { | ||
791 | check_find_1(xa); | ||
792 | check_find_2(xa); | ||
751 | check_multi_find(xa); | 793 | check_multi_find(xa); |
752 | check_multi_find_2(xa); | 794 | check_multi_find_2(xa); |
753 | } | 795 | } |
@@ -1067,7 +1109,7 @@ static noinline void check_store_range(struct xarray *xa) | |||
1067 | __check_store_range(xa, 4095 + i, 4095 + j); | 1109 | __check_store_range(xa, 4095 + i, 4095 + j); |
1068 | __check_store_range(xa, 4096 + i, 4096 + j); | 1110 | __check_store_range(xa, 4096 + i, 4096 + j); |
1069 | __check_store_range(xa, 123456 + i, 123456 + j); | 1111 | __check_store_range(xa, 123456 + i, 123456 + j); |
1070 | __check_store_range(xa, UINT_MAX + i, UINT_MAX + j); | 1112 | __check_store_range(xa, (1 << 24) + i, (1 << 24) + j); |
1071 | } | 1113 | } |
1072 | } | 1114 | } |
1073 | } | 1115 | } |
@@ -1146,10 +1188,12 @@ static noinline void check_account(struct xarray *xa) | |||
1146 | XA_STATE(xas, xa, 1 << order); | 1188 | XA_STATE(xas, xa, 1 << order); |
1147 | 1189 | ||
1148 | xa_store_order(xa, 0, order, xa, GFP_KERNEL); | 1190 | xa_store_order(xa, 0, order, xa, GFP_KERNEL); |
1191 | rcu_read_lock(); | ||
1149 | xas_load(&xas); | 1192 | xas_load(&xas); |
1150 | XA_BUG_ON(xa, xas.xa_node->count == 0); | 1193 | XA_BUG_ON(xa, xas.xa_node->count == 0); |
1151 | XA_BUG_ON(xa, xas.xa_node->count > (1 << order)); | 1194 | XA_BUG_ON(xa, xas.xa_node->count > (1 << order)); |
1152 | XA_BUG_ON(xa, xas.xa_node->nr_values != 0); | 1195 | XA_BUG_ON(xa, xas.xa_node->nr_values != 0); |
1196 | rcu_read_unlock(); | ||
1153 | 1197 | ||
1154 | xa_store_order(xa, 1 << order, order, xa_mk_value(1 << order), | 1198 | xa_store_order(xa, 1 << order, order, xa_mk_value(1 << order), |
1155 | GFP_KERNEL); | 1199 | GFP_KERNEL); |