aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/xarray.h
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2018-12-31 10:41:01 -0500
committerMatthew Wilcox <willy@infradead.org>2019-02-06 13:32:23 -0500
commita3e4d3f97ec844de005a679585c04c5c03dfbdb6 (patch)
treec4cda3a98cba2d9923e7356e587f6a958b2971d7 /include/linux/xarray.h
parent3ccaf57a6a63ad171a951dcaddffc453b2414c7b (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 'include/linux/xarray.h')
-rw-r--r--include/linux/xarray.h80
1 files changed, 51 insertions, 29 deletions
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 99dd0838b4ba..883bb958e462 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -200,6 +200,27 @@ static inline int xa_err(void *entry)
200 return 0; 200 return 0;
201} 201}
202 202
203/**
204 * struct xa_limit - Represents a range of IDs.
205 * @min: The lowest ID to allocate (inclusive).
206 * @max: The maximum ID to allocate (inclusive).
207 *
208 * This structure is used either directly or via the XA_LIMIT() macro
209 * to communicate the range of IDs that are valid for allocation.
210 * Two common ranges are predefined for you:
211 * * xa_limit_32b - [0 - UINT_MAX]
212 * * xa_limit_31b - [0 - INT_MAX]
213 */
214struct xa_limit {
215 u32 max;
216 u32 min;
217};
218
219#define XA_LIMIT(_min, _max) (struct xa_limit) { .min = _min, .max = _max }
220
221#define xa_limit_32b XA_LIMIT(0, UINT_MAX)
222#define xa_limit_31b XA_LIMIT(0, INT_MAX)
223
203typedef unsigned __bitwise xa_mark_t; 224typedef unsigned __bitwise xa_mark_t;
204#define XA_MARK_0 ((__force xa_mark_t)0U) 225#define XA_MARK_0 ((__force xa_mark_t)0U)
205#define XA_MARK_1 ((__force xa_mark_t)1U) 226#define XA_MARK_1 ((__force xa_mark_t)1U)
@@ -476,7 +497,8 @@ void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t);
476void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, 497void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old,
477 void *entry, gfp_t); 498 void *entry, gfp_t);
478int __xa_insert(struct xarray *, unsigned long index, void *entry, gfp_t); 499int __xa_insert(struct xarray *, unsigned long index, void *entry, gfp_t);
479int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); 500int __must_check __xa_alloc(struct xarray *, u32 *id, void *entry,
501 struct xa_limit, gfp_t);
480int __xa_reserve(struct xarray *, unsigned long index, gfp_t); 502int __xa_reserve(struct xarray *, unsigned long index, gfp_t);
481void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); 503void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t);
482void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); 504void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t);
@@ -753,26 +775,26 @@ static inline int xa_insert_irq(struct xarray *xa, unsigned long index,
753 * xa_alloc() - Find somewhere to store this entry in the XArray. 775 * xa_alloc() - Find somewhere to store this entry in the XArray.
754 * @xa: XArray. 776 * @xa: XArray.
755 * @id: Pointer to ID. 777 * @id: Pointer to ID.
756 * @max: Maximum ID to allocate (inclusive).
757 * @entry: New entry. 778 * @entry: New entry.
779 * @limit: Range of ID to allocate.
758 * @gfp: Memory allocation flags. 780 * @gfp: Memory allocation flags.
759 * 781 *
760 * Allocates an unused ID in the range specified by @id and @max. 782 * Finds an empty entry in @xa between @limit.min and @limit.max,
761 * Updates the @id pointer with the index, then stores the entry at that 783 * stores the index into the @id pointer, then stores the entry at
762 * index. A concurrent lookup will not see an uninitialised @id. 784 * that index. A concurrent lookup will not see an uninitialised @id.
763 * 785 *
764 * Context: Process context. Takes and releases the xa_lock. May sleep if 786 * Context: Any context. Takes and releases the xa_lock. May sleep if
765 * the @gfp flags permit. 787 * the @gfp flags permit.
766 * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if 788 * Return: 0 on success, -ENOMEM if memory could not be allocated or
767 * there is no more space in the XArray. 789 * -EBUSY if there are no free entries in @limit.
768 */ 790 */
769static inline int xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry, 791static inline __must_check int xa_alloc(struct xarray *xa, u32 *id,
770 gfp_t gfp) 792 void *entry, struct xa_limit limit, gfp_t gfp)
771{ 793{
772 int err; 794 int err;
773 795
774 xa_lock(xa); 796 xa_lock(xa);
775 err = __xa_alloc(xa, id, max, entry, gfp); 797 err = __xa_alloc(xa, id, entry, limit, gfp);
776 xa_unlock(xa); 798 xa_unlock(xa);
777 799
778 return err; 800 return err;
@@ -782,26 +804,26 @@ static inline int xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry,
782 * xa_alloc_bh() - Find somewhere to store this entry in the XArray. 804 * xa_alloc_bh() - Find somewhere to store this entry in the XArray.
783 * @xa: XArray. 805 * @xa: XArray.
784 * @id: Pointer to ID. 806 * @id: Pointer to ID.
785 * @max: Maximum ID to allocate (inclusive).
786 * @entry: New entry. 807 * @entry: New entry.
808 * @limit: Range of ID to allocate.
787 * @gfp: Memory allocation flags. 809 * @gfp: Memory allocation flags.
788 * 810 *
789 * Allocates an unused ID in the range specified by @id and @max. 811 * Finds an empty entry in @xa between @limit.min and @limit.max,
790 * Updates the @id pointer with the index, then stores the entry at that 812 * stores the index into the @id pointer, then stores the entry at
791 * index. A concurrent lookup will not see an uninitialised @id. 813 * that index. A concurrent lookup will not see an uninitialised @id.
792 * 814 *
793 * Context: Any context. Takes and releases the xa_lock while 815 * Context: Any context. Takes and releases the xa_lock while
794 * disabling softirqs. May sleep if the @gfp flags permit. 816 * disabling softirqs. May sleep if the @gfp flags permit.
795 * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if 817 * Return: 0 on success, -ENOMEM if memory could not be allocated or
796 * there is no more space in the XArray. 818 * -EBUSY if there are no free entries in @limit.
797 */ 819 */
798static inline int xa_alloc_bh(struct xarray *xa, u32 *id, u32 max, void *entry, 820static inline int __must_check xa_alloc_bh(struct xarray *xa, u32 *id,
799 gfp_t gfp) 821 void *entry, struct xa_limit limit, gfp_t gfp)
800{ 822{
801 int err; 823 int err;
802 824
803 xa_lock_bh(xa); 825 xa_lock_bh(xa);
804 err = __xa_alloc(xa, id, max, entry, gfp); 826 err = __xa_alloc(xa, id, entry, limit, gfp);
805 xa_unlock_bh(xa); 827 xa_unlock_bh(xa);
806 828
807 return err; 829 return err;
@@ -811,26 +833,26 @@ static inline int xa_alloc_bh(struct xarray *xa, u32 *id, u32 max, void *entry,
811 * xa_alloc_irq() - Find somewhere to store this entry in the XArray. 833 * xa_alloc_irq() - Find somewhere to store this entry in the XArray.
812 * @xa: XArray. 834 * @xa: XArray.
813 * @id: Pointer to ID. 835 * @id: Pointer to ID.
814 * @max: Maximum ID to allocate (inclusive).
815 * @entry: New entry. 836 * @entry: New entry.
837 * @limit: Range of ID to allocate.
816 * @gfp: Memory allocation flags. 838 * @gfp: Memory allocation flags.
817 * 839 *
818 * Allocates an unused ID in the range specified by @id and @max. 840 * Finds an empty entry in @xa between @limit.min and @limit.max,
819 * Updates the @id pointer with the index, then stores the entry at that 841 * stores the index into the @id pointer, then stores the entry at
820 * index. A concurrent lookup will not see an uninitialised @id. 842 * that index. A concurrent lookup will not see an uninitialised @id.
821 * 843 *
822 * Context: Process context. Takes and releases the xa_lock while 844 * Context: Process context. Takes and releases the xa_lock while
823 * disabling interrupts. May sleep if the @gfp flags permit. 845 * disabling interrupts. May sleep if the @gfp flags permit.
824 * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if 846 * Return: 0 on success, -ENOMEM if memory could not be allocated or
825 * there is no more space in the XArray. 847 * -EBUSY if there are no free entries in @limit.
826 */ 848 */
827static inline int xa_alloc_irq(struct xarray *xa, u32 *id, u32 max, void *entry, 849static inline int __must_check xa_alloc_irq(struct xarray *xa, u32 *id,
828 gfp_t gfp) 850 void *entry, struct xa_limit limit, gfp_t gfp)
829{ 851{
830 int err; 852 int err;
831 853
832 xa_lock_irq(xa); 854 xa_lock_irq(xa);
833 err = __xa_alloc(xa, id, max, entry, gfp); 855 err = __xa_alloc(xa, id, entry, limit, gfp);
834 xa_unlock_irq(xa); 856 xa_unlock_irq(xa);
835 857
836 return err; 858 return err;