blob: 9122cf8bf52a756536c48d50af680c90db24cdf1 [file] [log] [blame]
Matthew Wilcoxf6bb2a22018-04-10 16:36:52 -07001/* SPDX-License-Identifier: GPL-2.0+ */
2#ifndef _LINUX_XARRAY_H
3#define _LINUX_XARRAY_H
4/*
5 * eXtensible Arrays
6 * Copyright (c) 2017 Microsoft Corporation
Matthew Wilcox3d0186b2018-06-16 17:32:07 -04007 * Author: Matthew Wilcox <willy@infradead.org>
Matthew Wilcox3159f942017-11-03 13:30:42 -04008 *
9 * See Documentation/core-api/xarray.rst for how to use the XArray.
Matthew Wilcoxf6bb2a22018-04-10 16:36:52 -070010 */
11
Matthew Wilcox3159f942017-11-03 13:30:42 -040012#include <linux/bug.h>
Matthew Wilcoxf8d5d0c2017-11-07 16:30:10 -050013#include <linux/compiler.h>
14#include <linux/kconfig.h>
Matthew Wilcoxf6bb2a22018-04-10 16:36:52 -070015#include <linux/spinlock.h>
Matthew Wilcox3159f942017-11-03 13:30:42 -040016#include <linux/types.h>
17
18/*
19 * The bottom two bits of the entry determine how the XArray interprets
20 * the contents:
21 *
22 * 00: Pointer entry
23 * 10: Internal entry
24 * x1: Value entry or tagged pointer
25 *
26 * Attempting to store internal entries in the XArray is a bug.
Matthew Wilcox02c02bf2017-11-03 23:09:45 -040027 *
28 * Most internal entries are pointers to the next node in the tree.
29 * The following internal entries have a special meaning:
30 *
31 * 0-62: Sibling entries
32 * 256: Retry entry
Matthew Wilcox3159f942017-11-03 13:30:42 -040033 */
34
35#define BITS_PER_XA_VALUE (BITS_PER_LONG - 1)
36
37/**
38 * xa_mk_value() - Create an XArray entry from an integer.
39 * @v: Value to store in XArray.
40 *
41 * Context: Any context.
42 * Return: An entry suitable for storing in the XArray.
43 */
44static inline void *xa_mk_value(unsigned long v)
45{
46 WARN_ON((long)v < 0);
47 return (void *)((v << 1) | 1);
48}
49
50/**
51 * xa_to_value() - Get value stored in an XArray entry.
52 * @entry: XArray entry.
53 *
54 * Context: Any context.
55 * Return: The value stored in the XArray entry.
56 */
57static inline unsigned long xa_to_value(const void *entry)
58{
59 return (unsigned long)entry >> 1;
60}
61
62/**
63 * xa_is_value() - Determine if an entry is a value.
64 * @entry: XArray entry.
65 *
66 * Context: Any context.
67 * Return: True if the entry is a value, false if it is a pointer.
68 */
69static inline bool xa_is_value(const void *entry)
70{
71 return (unsigned long)entry & 1;
72}
73
74/**
75 * xa_tag_pointer() - Create an XArray entry for a tagged pointer.
76 * @p: Plain pointer.
77 * @tag: Tag value (0, 1 or 3).
78 *
79 * If the user of the XArray prefers, they can tag their pointers instead
80 * of storing value entries. Three tags are available (0, 1 and 3).
81 * These are distinct from the xa_mark_t as they are not replicated up
82 * through the array and cannot be searched for.
83 *
84 * Context: Any context.
85 * Return: An XArray entry.
86 */
87static inline void *xa_tag_pointer(void *p, unsigned long tag)
88{
89 return (void *)((unsigned long)p | tag);
90}
91
92/**
93 * xa_untag_pointer() - Turn an XArray entry into a plain pointer.
94 * @entry: XArray entry.
95 *
96 * If you have stored a tagged pointer in the XArray, call this function
97 * to get the untagged version of the pointer.
98 *
99 * Context: Any context.
100 * Return: A pointer.
101 */
102static inline void *xa_untag_pointer(void *entry)
103{
104 return (void *)((unsigned long)entry & ~3UL);
105}
106
107/**
108 * xa_pointer_tag() - Get the tag stored in an XArray entry.
109 * @entry: XArray entry.
110 *
111 * If you have stored a tagged pointer in the XArray, call this function
112 * to get the tag of that pointer.
113 *
114 * Context: Any context.
115 * Return: A tag.
116 */
117static inline unsigned int xa_pointer_tag(void *entry)
118{
119 return (unsigned long)entry & 3UL;
120}
Matthew Wilcoxf6bb2a22018-04-10 16:36:52 -0700121
Matthew Wilcox02c02bf2017-11-03 23:09:45 -0400122/*
123 * xa_mk_internal() - Create an internal entry.
124 * @v: Value to turn into an internal entry.
125 *
126 * Context: Any context.
127 * Return: An XArray internal entry corresponding to this value.
128 */
129static inline void *xa_mk_internal(unsigned long v)
130{
131 return (void *)((v << 2) | 2);
132}
133
134/*
135 * xa_to_internal() - Extract the value from an internal entry.
136 * @entry: XArray entry.
137 *
138 * Context: Any context.
139 * Return: The value which was stored in the internal entry.
140 */
141static inline unsigned long xa_to_internal(const void *entry)
142{
143 return (unsigned long)entry >> 2;
144}
145
146/*
147 * xa_is_internal() - Is the entry an internal entry?
148 * @entry: XArray entry.
149 *
150 * Context: Any context.
151 * Return: %true if the entry is an internal entry.
152 */
153static inline bool xa_is_internal(const void *entry)
154{
155 return ((unsigned long)entry & 3) == 2;
156}
157
Matthew Wilcoxf8d5d0c2017-11-07 16:30:10 -0500158/**
159 * struct xarray - The anchor of the XArray.
160 * @xa_lock: Lock that protects the contents of the XArray.
161 *
162 * To use the xarray, define it statically or embed it in your data structure.
163 * It is a very small data structure, so it does not usually make sense to
164 * allocate it separately and keep a pointer to it in your data structure.
165 *
166 * You may use the xa_lock to protect your own data structures as well.
167 */
168/*
169 * If all of the entries in the array are NULL, @xa_head is a NULL pointer.
170 * If the only non-NULL entry in the array is at index 0, @xa_head is that
171 * entry. If any other entry in the array is non-NULL, @xa_head points
172 * to an @xa_node.
173 */
174struct xarray {
175 spinlock_t xa_lock;
176/* private: The rest of the data structure is not to be used directly. */
177 gfp_t xa_flags;
178 void __rcu * xa_head;
179};
180
181#define XARRAY_INIT(name, flags) { \
182 .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \
183 .xa_flags = flags, \
184 .xa_head = NULL, \
185}
186
187/**
188 * DEFINE_XARRAY_FLAGS() - Define an XArray with custom flags.
189 * @name: A string that names your XArray.
190 * @flags: XA_FLAG values.
191 *
192 * This is intended for file scope definitions of XArrays. It declares
193 * and initialises an empty XArray with the chosen name and flags. It is
194 * equivalent to calling xa_init_flags() on the array, but it does the
195 * initialisation at compiletime instead of runtime.
196 */
197#define DEFINE_XARRAY_FLAGS(name, flags) \
198 struct xarray name = XARRAY_INIT(name, flags)
199
200/**
201 * DEFINE_XARRAY() - Define an XArray.
202 * @name: A string that names your XArray.
203 *
204 * This is intended for file scope definitions of XArrays. It declares
205 * and initialises an empty XArray with the chosen name. It is equivalent
206 * to calling xa_init() on the array, but it does the initialisation at
207 * compiletime instead of runtime.
208 */
209#define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0)
210
211void xa_init_flags(struct xarray *, gfp_t flags);
212
213/**
214 * xa_init() - Initialise an empty XArray.
215 * @xa: XArray.
216 *
217 * An empty XArray is full of NULL entries.
218 *
219 * Context: Any context.
220 */
221static inline void xa_init(struct xarray *xa)
222{
223 xa_init_flags(xa, 0);
224}
225
Matthew Wilcoxf6bb2a22018-04-10 16:36:52 -0700226#define xa_trylock(xa) spin_trylock(&(xa)->xa_lock)
227#define xa_lock(xa) spin_lock(&(xa)->xa_lock)
228#define xa_unlock(xa) spin_unlock(&(xa)->xa_lock)
229#define xa_lock_bh(xa) spin_lock_bh(&(xa)->xa_lock)
230#define xa_unlock_bh(xa) spin_unlock_bh(&(xa)->xa_lock)
231#define xa_lock_irq(xa) spin_lock_irq(&(xa)->xa_lock)
232#define xa_unlock_irq(xa) spin_unlock_irq(&(xa)->xa_lock)
233#define xa_lock_irqsave(xa, flags) \
234 spin_lock_irqsave(&(xa)->xa_lock, flags)
235#define xa_unlock_irqrestore(xa, flags) \
236 spin_unlock_irqrestore(&(xa)->xa_lock, flags)
237
Matthew Wilcox02c02bf2017-11-03 23:09:45 -0400238/* Everything below here is the Advanced API. Proceed with caution. */
239
240/*
241 * The xarray is constructed out of a set of 'chunks' of pointers. Choosing
242 * the best chunk size requires some tradeoffs. A power of two recommends
243 * itself so that we can walk the tree based purely on shifts and masks.
244 * Generally, the larger the better; as the number of slots per level of the
245 * tree increases, the less tall the tree needs to be. But that needs to be
246 * balanced against the memory consumption of each node. On a 64-bit system,
247 * xa_node is currently 576 bytes, and we get 7 of them per 4kB page. If we
248 * doubled the number of slots per node, we'd get only 3 nodes per 4kB page.
249 */
250#ifndef XA_CHUNK_SHIFT
251#define XA_CHUNK_SHIFT (CONFIG_BASE_SMALL ? 4 : 6)
252#endif
253#define XA_CHUNK_SIZE (1UL << XA_CHUNK_SHIFT)
254#define XA_CHUNK_MASK (XA_CHUNK_SIZE - 1)
255
256/* Private */
257static inline bool xa_is_node(const void *entry)
258{
259 return xa_is_internal(entry) && (unsigned long)entry > 4096;
260}
261
262/* Private */
263static inline void *xa_mk_sibling(unsigned int offset)
264{
265 return xa_mk_internal(offset);
266}
267
268/* Private */
269static inline unsigned long xa_to_sibling(const void *entry)
270{
271 return xa_to_internal(entry);
272}
273
274/**
275 * xa_is_sibling() - Is the entry a sibling entry?
276 * @entry: Entry retrieved from the XArray
277 *
278 * Return: %true if the entry is a sibling entry.
279 */
280static inline bool xa_is_sibling(const void *entry)
281{
282 return IS_ENABLED(CONFIG_XARRAY_MULTI) && xa_is_internal(entry) &&
283 (entry < xa_mk_sibling(XA_CHUNK_SIZE - 1));
284}
285
286#define XA_RETRY_ENTRY xa_mk_internal(256)
287
Matthew Wilcoxf6bb2a22018-04-10 16:36:52 -0700288#endif /* _LINUX_XARRAY_H */