diff options
author | Matthew Wilcox <willy@infradead.org> | 2018-10-01 14:54:59 -0400 |
---|---|---|
committer | Matthew Wilcox <willy@infradead.org> | 2018-10-21 10:46:00 -0400 |
commit | 9f14d4f1f1045f161fd4db8a8e194b7825c2874a (patch) | |
tree | fcc3e832d34116dec5dfe2e36525cbdb81cc47c8 /lib/test_xarray.c | |
parent | 2264f5132fe45571139727ebdeb78696b35d1506 (diff) |
xarray: Add xa_reserve and xa_release
This function reserves a slot in the XArray for users which need
to acquire multiple locks before storing their entry in the tree and
so cannot use a plain xa_store().
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'lib/test_xarray.c')
-rw-r--r-- | lib/test_xarray.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 703370015d10..6aafd411a5c3 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c | |||
@@ -259,6 +259,45 @@ static noinline void check_cmpxchg(struct xarray *xa) | |||
259 | XA_BUG_ON(xa, !xa_empty(xa)); | 259 | XA_BUG_ON(xa, !xa_empty(xa)); |
260 | } | 260 | } |
261 | 261 | ||
262 | static noinline void check_reserve(struct xarray *xa) | ||
263 | { | ||
264 | void *entry; | ||
265 | unsigned long index = 0; | ||
266 | |||
267 | /* An array with a reserved entry is not empty */ | ||
268 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
269 | xa_reserve(xa, 12345678, GFP_KERNEL); | ||
270 | XA_BUG_ON(xa, xa_empty(xa)); | ||
271 | XA_BUG_ON(xa, xa_load(xa, 12345678)); | ||
272 | xa_release(xa, 12345678); | ||
273 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
274 | |||
275 | /* Releasing a used entry does nothing */ | ||
276 | xa_reserve(xa, 12345678, GFP_KERNEL); | ||
277 | XA_BUG_ON(xa, xa_store_index(xa, 12345678, GFP_NOWAIT) != NULL); | ||
278 | xa_release(xa, 12345678); | ||
279 | xa_erase_index(xa, 12345678); | ||
280 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
281 | |||
282 | /* cmpxchg sees a reserved entry as NULL */ | ||
283 | xa_reserve(xa, 12345678, GFP_KERNEL); | ||
284 | XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, NULL, xa_mk_value(12345678), | ||
285 | GFP_NOWAIT) != NULL); | ||
286 | xa_release(xa, 12345678); | ||
287 | xa_erase_index(xa, 12345678); | ||
288 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
289 | |||
290 | /* Can iterate through a reserved entry */ | ||
291 | xa_store_index(xa, 5, GFP_KERNEL); | ||
292 | xa_reserve(xa, 6, GFP_KERNEL); | ||
293 | xa_store_index(xa, 7, GFP_KERNEL); | ||
294 | |||
295 | xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { | ||
296 | XA_BUG_ON(xa, index != 5 && index != 7); | ||
297 | } | ||
298 | xa_destroy(xa); | ||
299 | } | ||
300 | |||
262 | static noinline void check_xas_erase(struct xarray *xa) | 301 | static noinline void check_xas_erase(struct xarray *xa) |
263 | { | 302 | { |
264 | XA_STATE(xas, xa, 0); | 303 | XA_STATE(xas, xa, 0); |
@@ -808,6 +847,7 @@ static int xarray_checks(void) | |||
808 | check_xa_shrink(&array); | 847 | check_xa_shrink(&array); |
809 | check_xas_erase(&array); | 848 | check_xas_erase(&array); |
810 | check_cmpxchg(&array); | 849 | check_cmpxchg(&array); |
850 | check_reserve(&array); | ||
811 | check_multi_store(&array); | 851 | check_multi_store(&array); |
812 | check_find(&array); | 852 | check_find(&array); |
813 | check_destroy(&array); | 853 | check_destroy(&array); |