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 /include/linux/xarray.h | |
| 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 'include/linux/xarray.h')
| -rw-r--r-- | include/linux/xarray.h | 34 |
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); | |||
| 277 | void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); | 278 | void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); |
| 278 | void *xa_cmpxchg(struct xarray *, unsigned long index, | 279 | void *xa_cmpxchg(struct xarray *, unsigned long index, |
| 279 | void *old, void *entry, gfp_t); | 280 | void *old, void *entry, gfp_t); |
| 281 | int xa_reserve(struct xarray *, unsigned long index, gfp_t); | ||
| 280 | bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); | 282 | bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); |
| 281 | void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); | 283 | void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); |
| 282 | void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); | 284 | void 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 | */ | ||
| 385 | static 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 | */ | ||
| 686 | static 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 | */ |
| 881 | static inline bool xas_retry(struct xa_state *xas, const void *entry) | 909 | static 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); |
