diff options
Diffstat (limited to 'include/linux/xarray.h')
-rw-r--r-- | include/linux/xarray.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/include/linux/xarray.h b/include/linux/xarray.h index 9e4c86853fa4..5c8acfc4ff55 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h | |||
@@ -5,9 +5,111 @@ | |||
5 | * eXtensible Arrays | 5 | * eXtensible Arrays |
6 | * Copyright (c) 2017 Microsoft Corporation | 6 | * Copyright (c) 2017 Microsoft Corporation |
7 | * Author: Matthew Wilcox <willy@infradead.org> | 7 | * Author: Matthew Wilcox <willy@infradead.org> |
8 | * | ||
9 | * See Documentation/core-api/xarray.rst for how to use the XArray. | ||
8 | */ | 10 | */ |
9 | 11 | ||
12 | #include <linux/bug.h> | ||
10 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | #include <linux/types.h> | ||
15 | |||
16 | /* | ||
17 | * The bottom two bits of the entry determine how the XArray interprets | ||
18 | * the contents: | ||
19 | * | ||
20 | * 00: Pointer entry | ||
21 | * 10: Internal entry | ||
22 | * x1: Value entry or tagged pointer | ||
23 | * | ||
24 | * Attempting to store internal entries in the XArray is a bug. | ||
25 | */ | ||
26 | |||
27 | #define BITS_PER_XA_VALUE (BITS_PER_LONG - 1) | ||
28 | |||
29 | /** | ||
30 | * xa_mk_value() - Create an XArray entry from an integer. | ||
31 | * @v: Value to store in XArray. | ||
32 | * | ||
33 | * Context: Any context. | ||
34 | * Return: An entry suitable for storing in the XArray. | ||
35 | */ | ||
36 | static inline void *xa_mk_value(unsigned long v) | ||
37 | { | ||
38 | WARN_ON((long)v < 0); | ||
39 | return (void *)((v << 1) | 1); | ||
40 | } | ||
41 | |||
42 | /** | ||
43 | * xa_to_value() - Get value stored in an XArray entry. | ||
44 | * @entry: XArray entry. | ||
45 | * | ||
46 | * Context: Any context. | ||
47 | * Return: The value stored in the XArray entry. | ||
48 | */ | ||
49 | static inline unsigned long xa_to_value(const void *entry) | ||
50 | { | ||
51 | return (unsigned long)entry >> 1; | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * xa_is_value() - Determine if an entry is a value. | ||
56 | * @entry: XArray entry. | ||
57 | * | ||
58 | * Context: Any context. | ||
59 | * Return: True if the entry is a value, false if it is a pointer. | ||
60 | */ | ||
61 | static inline bool xa_is_value(const void *entry) | ||
62 | { | ||
63 | return (unsigned long)entry & 1; | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * xa_tag_pointer() - Create an XArray entry for a tagged pointer. | ||
68 | * @p: Plain pointer. | ||
69 | * @tag: Tag value (0, 1 or 3). | ||
70 | * | ||
71 | * If the user of the XArray prefers, they can tag their pointers instead | ||
72 | * of storing value entries. Three tags are available (0, 1 and 3). | ||
73 | * These are distinct from the xa_mark_t as they are not replicated up | ||
74 | * through the array and cannot be searched for. | ||
75 | * | ||
76 | * Context: Any context. | ||
77 | * Return: An XArray entry. | ||
78 | */ | ||
79 | static inline void *xa_tag_pointer(void *p, unsigned long tag) | ||
80 | { | ||
81 | return (void *)((unsigned long)p | tag); | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * xa_untag_pointer() - Turn an XArray entry into a plain pointer. | ||
86 | * @entry: XArray entry. | ||
87 | * | ||
88 | * If you have stored a tagged pointer in the XArray, call this function | ||
89 | * to get the untagged version of the pointer. | ||
90 | * | ||
91 | * Context: Any context. | ||
92 | * Return: A pointer. | ||
93 | */ | ||
94 | static inline void *xa_untag_pointer(void *entry) | ||
95 | { | ||
96 | return (void *)((unsigned long)entry & ~3UL); | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * xa_pointer_tag() - Get the tag stored in an XArray entry. | ||
101 | * @entry: XArray entry. | ||
102 | * | ||
103 | * If you have stored a tagged pointer in the XArray, call this function | ||
104 | * to get the tag of that pointer. | ||
105 | * | ||
106 | * Context: Any context. | ||
107 | * Return: A tag. | ||
108 | */ | ||
109 | static inline unsigned int xa_pointer_tag(void *entry) | ||
110 | { | ||
111 | return (unsigned long)entry & 3UL; | ||
112 | } | ||
11 | 113 | ||
12 | #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) | 114 | #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) |
13 | #define xa_lock(xa) spin_lock(&(xa)->xa_lock) | 115 | #define xa_lock(xa) spin_lock(&(xa)->xa_lock) |