summaryrefslogtreecommitdiffstats
path: root/include/linux/xarray.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/xarray.h')
-rw-r--r--include/linux/xarray.h102
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 */
36static 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 */
49static 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 */
61static 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 */
79static 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 */
94static 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 */
109static 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)