summaryrefslogtreecommitdiffstats
path: root/include/linux/xarray.h
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2017-11-07 14:57:46 -0500
committerMatthew Wilcox <willy@infradead.org>2018-10-21 10:45:57 -0400
commitad3d6c7263e368abdc151e1cc13dc78aa39cc7a7 (patch)
tree54279b42ac6fbede3abc75ea44fbe1554b633228 /include/linux/xarray.h
parent992a8e60e3fea77c55589fc1c5af2304e78a5baa (diff)
xarray: Add XArray load operation
The xa_load function brings with it a lot of infrastructure; xa_empty(), xa_is_err(), and large chunks of the XArray advanced API that are used to implement xa_load. As the test-suite demonstrates, it is possible to use the XArray functions on a radix tree. The radix tree functions depend on the GFP flags being stored in the root of the tree, so it's not possible to use the radix tree functions on an XArray. Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'include/linux/xarray.h')
-rw-r--r--include/linux/xarray.h336
1 files changed, 336 insertions, 0 deletions
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 52141dfc5a90..a0df8217068c 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -12,6 +12,8 @@
12#include <linux/bug.h> 12#include <linux/bug.h>
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/kconfig.h> 14#include <linux/kconfig.h>
15#include <linux/kernel.h>
16#include <linux/rcupdate.h>
15#include <linux/spinlock.h> 17#include <linux/spinlock.h>
16#include <linux/types.h> 18#include <linux/types.h>
17 19
@@ -30,6 +32,10 @@
30 * 32 *
31 * 0-62: Sibling entries 33 * 0-62: Sibling entries
32 * 256: Retry entry 34 * 256: Retry entry
35 *
36 * Errors are also represented as internal entries, but use the negative
37 * space (-4094 to -2). They're never stored in the slots array; only
38 * returned by the normal API.
33 */ 39 */
34 40
35#define BITS_PER_XA_VALUE (BITS_PER_LONG - 1) 41#define BITS_PER_XA_VALUE (BITS_PER_LONG - 1)
@@ -156,6 +162,42 @@ static inline bool xa_is_internal(const void *entry)
156} 162}
157 163
158/** 164/**
165 * xa_is_err() - Report whether an XArray operation returned an error
166 * @entry: Result from calling an XArray function
167 *
168 * If an XArray operation cannot complete an operation, it will return
169 * a special value indicating an error. This function tells you
170 * whether an error occurred; xa_err() tells you which error occurred.
171 *
172 * Context: Any context.
173 * Return: %true if the entry indicates an error.
174 */
175static inline bool xa_is_err(const void *entry)
176{
177 return unlikely(xa_is_internal(entry));
178}
179
180/**
181 * xa_err() - Turn an XArray result into an errno.
182 * @entry: Result from calling an XArray function.
183 *
184 * If an XArray operation cannot complete an operation, it will return
185 * a special pointer value which encodes an errno. This function extracts
186 * the errno from the pointer value, or returns 0 if the pointer does not
187 * represent an errno.
188 *
189 * Context: Any context.
190 * Return: A negative errno or 0.
191 */
192static inline int xa_err(void *entry)
193{
194 /* xa_to_internal() would not do sign extension. */
195 if (xa_is_err(entry))
196 return (long)entry >> 2;
197 return 0;
198}
199
200/**
159 * struct xarray - The anchor of the XArray. 201 * struct xarray - The anchor of the XArray.
160 * @xa_lock: Lock that protects the contents of the XArray. 202 * @xa_lock: Lock that protects the contents of the XArray.
161 * 203 *
@@ -209,6 +251,7 @@ struct xarray {
209#define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0) 251#define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0)
210 252
211void xa_init_flags(struct xarray *, gfp_t flags); 253void xa_init_flags(struct xarray *, gfp_t flags);
254void *xa_load(struct xarray *, unsigned long index);
212 255
213/** 256/**
214 * xa_init() - Initialise an empty XArray. 257 * xa_init() - Initialise an empty XArray.
@@ -223,6 +266,18 @@ static inline void xa_init(struct xarray *xa)
223 xa_init_flags(xa, 0); 266 xa_init_flags(xa, 0);
224} 267}
225 268
269/**
270 * xa_empty() - Determine if an array has any present entries.
271 * @xa: XArray.
272 *
273 * Context: Any context.
274 * Return: %true if the array contains only NULL pointers.
275 */
276static inline bool xa_empty(const struct xarray *xa)
277{
278 return xa->xa_head == NULL;
279}
280
226#define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) 281#define xa_trylock(xa) spin_trylock(&(xa)->xa_lock)
227#define xa_lock(xa) spin_lock(&(xa)->xa_lock) 282#define xa_lock(xa) spin_lock(&(xa)->xa_lock)
228#define xa_unlock(xa) spin_unlock(&(xa)->xa_lock) 283#define xa_unlock(xa) spin_unlock(&(xa)->xa_lock)
@@ -280,6 +335,65 @@ struct xa_node {
280 }; 335 };
281}; 336};
282 337
338void xa_dump(const struct xarray *);
339void xa_dump_node(const struct xa_node *);
340
341#ifdef XA_DEBUG
342#define XA_BUG_ON(xa, x) do { \
343 if (x) { \
344 xa_dump(xa); \
345 BUG(); \
346 } \
347 } while (0)
348#define XA_NODE_BUG_ON(node, x) do { \
349 if (x) { \
350 if (node) xa_dump_node(node); \
351 BUG(); \
352 } \
353 } while (0)
354#else
355#define XA_BUG_ON(xa, x) do { } while (0)
356#define XA_NODE_BUG_ON(node, x) do { } while (0)
357#endif
358
359/* Private */
360static inline void *xa_head(const struct xarray *xa)
361{
362 return rcu_dereference_check(xa->xa_head,
363 lockdep_is_held(&xa->xa_lock));
364}
365
366/* Private */
367static inline void *xa_head_locked(const struct xarray *xa)
368{
369 return rcu_dereference_protected(xa->xa_head,
370 lockdep_is_held(&xa->xa_lock));
371}
372
373/* Private */
374static inline void *xa_entry(const struct xarray *xa,
375 const struct xa_node *node, unsigned int offset)
376{
377 XA_NODE_BUG_ON(node, offset >= XA_CHUNK_SIZE);
378 return rcu_dereference_check(node->slots[offset],
379 lockdep_is_held(&xa->xa_lock));
380}
381
382/* Private */
383static inline void *xa_entry_locked(const struct xarray *xa,
384 const struct xa_node *node, unsigned int offset)
385{
386 XA_NODE_BUG_ON(node, offset >= XA_CHUNK_SIZE);
387 return rcu_dereference_protected(node->slots[offset],
388 lockdep_is_held(&xa->xa_lock));
389}
390
391/* Private */
392static inline struct xa_node *xa_to_node(const void *entry)
393{
394 return (struct xa_node *)((unsigned long)entry - 2);
395}
396
283/* Private */ 397/* Private */
284static inline bool xa_is_node(const void *entry) 398static inline bool xa_is_node(const void *entry)
285{ 399{
@@ -312,4 +426,226 @@ static inline bool xa_is_sibling(const void *entry)
312 426
313#define XA_RETRY_ENTRY xa_mk_internal(256) 427#define XA_RETRY_ENTRY xa_mk_internal(256)
314 428
429/**
430 * xa_is_retry() - Is the entry a retry entry?
431 * @entry: Entry retrieved from the XArray
432 *
433 * Return: %true if the entry is a retry entry.
434 */
435static inline bool xa_is_retry(const void *entry)
436{
437 return unlikely(entry == XA_RETRY_ENTRY);
438}
439
440/**
441 * typedef xa_update_node_t - A callback function from the XArray.
442 * @node: The node which is being processed
443 *
444 * This function is called every time the XArray updates the count of
445 * present and value entries in a node. It allows advanced users to
446 * maintain the private_list in the node.
447 *
448 * Context: The xa_lock is held and interrupts may be disabled.
449 * Implementations should not drop the xa_lock, nor re-enable
450 * interrupts.
451 */
452typedef void (*xa_update_node_t)(struct xa_node *node);
453
454/*
455 * The xa_state is opaque to its users. It contains various different pieces
456 * of state involved in the current operation on the XArray. It should be
457 * declared on the stack and passed between the various internal routines.
458 * The various elements in it should not be accessed directly, but only
459 * through the provided accessor functions. The below documentation is for
460 * the benefit of those working on the code, not for users of the XArray.
461 *
462 * @xa_node usually points to the xa_node containing the slot we're operating
463 * on (and @xa_offset is the offset in the slots array). If there is a
464 * single entry in the array at index 0, there are no allocated xa_nodes to
465 * point to, and so we store %NULL in @xa_node. @xa_node is set to
466 * the value %XAS_RESTART if the xa_state is not walked to the correct
467 * position in the tree of nodes for this operation. If an error occurs
468 * during an operation, it is set to an %XAS_ERROR value. If we run off the
469 * end of the allocated nodes, it is set to %XAS_BOUNDS.
470 */
471struct xa_state {
472 struct xarray *xa;
473 unsigned long xa_index;
474 unsigned char xa_shift;
475 unsigned char xa_sibs;
476 unsigned char xa_offset;
477 unsigned char xa_pad; /* Helps gcc generate better code */
478 struct xa_node *xa_node;
479 struct xa_node *xa_alloc;
480 xa_update_node_t xa_update;
481};
482
483/*
484 * We encode errnos in the xas->xa_node. If an error has happened, we need to
485 * drop the lock to fix it, and once we've done so the xa_state is invalid.
486 */
487#define XA_ERROR(errno) ((struct xa_node *)(((unsigned long)errno << 2) | 2UL))
488#define XAS_BOUNDS ((struct xa_node *)1UL)
489#define XAS_RESTART ((struct xa_node *)3UL)
490
491#define __XA_STATE(array, index, shift, sibs) { \
492 .xa = array, \
493 .xa_index = index, \
494 .xa_shift = shift, \
495 .xa_sibs = sibs, \
496 .xa_offset = 0, \
497 .xa_pad = 0, \
498 .xa_node = XAS_RESTART, \
499 .xa_alloc = NULL, \
500 .xa_update = NULL \
501}
502
503/**
504 * XA_STATE() - Declare an XArray operation state.
505 * @name: Name of this operation state (usually xas).
506 * @array: Array to operate on.
507 * @index: Initial index of interest.
508 *
509 * Declare and initialise an xa_state on the stack.
510 */
511#define XA_STATE(name, array, index) \
512 struct xa_state name = __XA_STATE(array, index, 0, 0)
513
514/**
515 * XA_STATE_ORDER() - Declare an XArray operation state.
516 * @name: Name of this operation state (usually xas).
517 * @array: Array to operate on.
518 * @index: Initial index of interest.
519 * @order: Order of entry.
520 *
521 * Declare and initialise an xa_state on the stack. This variant of
522 * XA_STATE() allows you to specify the 'order' of the element you
523 * want to operate on.`
524 */
525#define XA_STATE_ORDER(name, array, index, order) \
526 struct xa_state name = __XA_STATE(array, \
527 (index >> order) << order, \
528 order - (order % XA_CHUNK_SHIFT), \
529 (1U << (order % XA_CHUNK_SHIFT)) - 1)
530
531#define xas_marked(xas, mark) xa_marked((xas)->xa, (mark))
532#define xas_trylock(xas) xa_trylock((xas)->xa)
533#define xas_lock(xas) xa_lock((xas)->xa)
534#define xas_unlock(xas) xa_unlock((xas)->xa)
535#define xas_lock_bh(xas) xa_lock_bh((xas)->xa)
536#define xas_unlock_bh(xas) xa_unlock_bh((xas)->xa)
537#define xas_lock_irq(xas) xa_lock_irq((xas)->xa)
538#define xas_unlock_irq(xas) xa_unlock_irq((xas)->xa)
539#define xas_lock_irqsave(xas, flags) \
540 xa_lock_irqsave((xas)->xa, flags)
541#define xas_unlock_irqrestore(xas, flags) \
542 xa_unlock_irqrestore((xas)->xa, flags)
543
544/**
545 * xas_error() - Return an errno stored in the xa_state.
546 * @xas: XArray operation state.
547 *
548 * Return: 0 if no error has been noted. A negative errno if one has.
549 */
550static inline int xas_error(const struct xa_state *xas)
551{
552 return xa_err(xas->xa_node);
553}
554
555/**
556 * xas_set_err() - Note an error in the xa_state.
557 * @xas: XArray operation state.
558 * @err: Negative error number.
559 *
560 * Only call this function with a negative @err; zero or positive errors
561 * will probably not behave the way you think they should. If you want
562 * to clear the error from an xa_state, use xas_reset().
563 */
564static inline void xas_set_err(struct xa_state *xas, long err)
565{
566 xas->xa_node = XA_ERROR(err);
567}
568
569/**
570 * xas_invalid() - Is the xas in a retry or error state?
571 * @xas: XArray operation state.
572 *
573 * Return: %true if the xas cannot be used for operations.
574 */
575static inline bool xas_invalid(const struct xa_state *xas)
576{
577 return (unsigned long)xas->xa_node & 3;
578}
579
580/**
581 * xas_valid() - Is the xas a valid cursor into the array?
582 * @xas: XArray operation state.
583 *
584 * Return: %true if the xas can be used for operations.
585 */
586static inline bool xas_valid(const struct xa_state *xas)
587{
588 return !xas_invalid(xas);
589}
590
591/**
592 * xas_reset() - Reset an XArray operation state.
593 * @xas: XArray operation state.
594 *
595 * Resets the error or walk state of the @xas so future walks of the
596 * array will start from the root. Use this if you have dropped the
597 * xarray lock and want to reuse the xa_state.
598 *
599 * Context: Any context.
600 */
601static inline void xas_reset(struct xa_state *xas)
602{
603 xas->xa_node = XAS_RESTART;
604}
605
606/**
607 * xas_retry() - Retry the operation if appropriate.
608 * @xas: XArray operation state.
609 * @entry: Entry from xarray.
610 *
611 * The advanced functions may sometimes return an internal entry, such as
612 * a retry entry or a zero entry. This function sets up the @xas to restart
613 * the walk from the head of the array if needed.
614 *
615 * Context: Any context.
616 * Return: true if the operation needs to be retried.
617 */
618static inline bool xas_retry(struct xa_state *xas, const void *entry)
619{
620 if (!xa_is_retry(entry))
621 return false;
622 xas_reset(xas);
623 return true;
624}
625
626void *xas_load(struct xa_state *);
627
628/**
629 * xas_reload() - Refetch an entry from the xarray.
630 * @xas: XArray operation state.
631 *
632 * Use this function to check that a previously loaded entry still has
633 * the same value. This is useful for the lockless pagecache lookup where
634 * we walk the array with only the RCU lock to protect us, lock the page,
635 * then check that the page hasn't moved since we looked it up.
636 *
637 * The caller guarantees that @xas is still valid. If it may be in an
638 * error or restart state, call xas_load() instead.
639 *
640 * Return: The entry at this location in the xarray.
641 */
642static inline void *xas_reload(struct xa_state *xas)
643{
644 struct xa_node *node = xas->xa_node;
645
646 if (node)
647 return xa_entry(xas->xa, node, xas->xa_offset);
648 return xa_head(xas->xa);
649}
650
315#endif /* _LINUX_XARRAY_H */ 651#endif /* _LINUX_XARRAY_H */