aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/xarray.h
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2018-10-01 14:54:59 -0400
committerMatthew Wilcox <willy@infradead.org>2018-10-21 10:46:00 -0400
commit9f14d4f1f1045f161fd4db8a8e194b7825c2874a (patch)
treefcc3e832d34116dec5dfe2e36525cbdb81cc47c8 /include/linux/xarray.h
parent2264f5132fe45571139727ebdeb78696b35d1506 (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 'include/linux/xarray.h')
-rw-r--r--include/linux/xarray.h34
1 files changed, 32 insertions, 2 deletions
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index deae17aa0ed7..bed63d3cfea8 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -32,7 +32,8 @@
32 * The following internal entries have a special meaning: 32 * The following internal entries have a special meaning:
33 * 33 *
34 * 0-62: Sibling entries 34 * 0-62: Sibling entries
35 * 256: Retry entry 35 * 256: Zero entry
36 * 257: Retry entry
36 * 37 *
37 * Errors are also represented as internal entries, but use the negative 38 * Errors are also represented as internal entries, but use the negative
38 * space (-4094 to -2). They're never stored in the slots array; only 39 * space (-4094 to -2). They're never stored in the slots array; only
@@ -277,6 +278,7 @@ void *xa_load(struct xarray *, unsigned long index);
277void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); 278void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t);
278void *xa_cmpxchg(struct xarray *, unsigned long index, 279void *xa_cmpxchg(struct xarray *, unsigned long index,
279 void *old, void *entry, gfp_t); 280 void *old, void *entry, gfp_t);
281int xa_reserve(struct xarray *, unsigned long index, gfp_t);
280bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); 282bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t);
281void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); 283void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t);
282void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); 284void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t);
@@ -372,6 +374,20 @@ static inline int xa_insert(struct xarray *xa, unsigned long index,
372} 374}
373 375
374/** 376/**
377 * xa_release() - Release a reserved entry.
378 * @xa: XArray.
379 * @index: Index of entry.
380 *
381 * After calling xa_reserve(), you can call this function to release the
382 * reservation. If the entry at @index has been stored to, this function
383 * will do nothing.
384 */
385static inline void xa_release(struct xarray *xa, unsigned long index)
386{
387 xa_cmpxchg(xa, index, NULL, NULL, 0);
388}
389
390/**
375 * xa_for_each() - Iterate over a portion of an XArray. 391 * xa_for_each() - Iterate over a portion of an XArray.
376 * @xa: XArray. 392 * @xa: XArray.
377 * @entry: Entry retrieved from array. 393 * @entry: Entry retrieved from array.
@@ -658,7 +674,19 @@ static inline bool xa_is_sibling(const void *entry)
658 (entry < xa_mk_sibling(XA_CHUNK_SIZE - 1)); 674 (entry < xa_mk_sibling(XA_CHUNK_SIZE - 1));
659} 675}
660 676
661#define XA_RETRY_ENTRY xa_mk_internal(256) 677#define XA_ZERO_ENTRY xa_mk_internal(256)
678#define XA_RETRY_ENTRY xa_mk_internal(257)
679
680/**
681 * xa_is_zero() - Is the entry a zero entry?
682 * @entry: Entry retrieved from the XArray
683 *
684 * Return: %true if the entry is a zero entry.
685 */
686static inline bool xa_is_zero(const void *entry)
687{
688 return unlikely(entry == XA_ZERO_ENTRY);
689}
662 690
663/** 691/**
664 * xa_is_retry() - Is the entry a retry entry? 692 * xa_is_retry() - Is the entry a retry entry?
@@ -880,6 +908,8 @@ static inline void xas_reset(struct xa_state *xas)
880 */ 908 */
881static inline bool xas_retry(struct xa_state *xas, const void *entry) 909static inline bool xas_retry(struct xa_state *xas, const void *entry)
882{ 910{
911 if (xa_is_zero(entry))
912 return true;
883 if (!xa_is_retry(entry)) 913 if (!xa_is_retry(entry))
884 return false; 914 return false;
885 xas_reset(xas); 915 xas_reset(xas);