Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | |
| 3 | ====== |
| 4 | XArray |
| 5 | ====== |
| 6 | |
| 7 | :Author: Matthew Wilcox |
| 8 | |
| 9 | Overview |
| 10 | ======== |
| 11 | |
| 12 | The XArray is an abstract data type which behaves like a very large array |
| 13 | of pointers. It meets many of the same needs as a hash or a conventional |
| 14 | resizable array. Unlike a hash, it allows you to sensibly go to the |
| 15 | next or previous entry in a cache-efficient manner. In contrast to a |
| 16 | resizable array, there is no need to copy data or change MMU mappings in |
| 17 | order to grow the array. It is more memory-efficient, parallelisable |
| 18 | and cache friendly than a doubly-linked list. It takes advantage of |
| 19 | RCU to perform lookups without locking. |
| 20 | |
| 21 | The XArray implementation is efficient when the indices used are densely |
| 22 | clustered; hashing the object and using the hash as the index will not |
| 23 | perform well. The XArray is optimised for small indices, but still has |
| 24 | good performance with large indices. If your index can be larger than |
| 25 | ``ULONG_MAX`` then the XArray is not the data type for you. The most |
| 26 | important user of the XArray is the page cache. |
| 27 | |
| 28 | Each non-``NULL`` entry in the array has three bits associated with |
| 29 | it called marks. Each mark may be set or cleared independently of |
| 30 | the others. You can iterate over entries which are marked. |
| 31 | |
| 32 | Normal pointers may be stored in the XArray directly. They must be 4-byte |
| 33 | aligned, which is true for any pointer returned from :c:func:`kmalloc` and |
| 34 | :c:func:`alloc_page`. It isn't true for arbitrary user-space pointers, |
| 35 | nor for function pointers. You can store pointers to statically allocated |
| 36 | objects, as long as those objects have an alignment of at least 4. |
| 37 | |
| 38 | You can also store integers between 0 and ``LONG_MAX`` in the XArray. |
| 39 | You must first convert it into an entry using :c:func:`xa_mk_value`. |
| 40 | When you retrieve an entry from the XArray, you can check whether it is |
| 41 | a value entry by calling :c:func:`xa_is_value`, and convert it back to |
| 42 | an integer by calling :c:func:`xa_to_value`. |
| 43 | |
| 44 | Some users want to store tagged pointers instead of using the marks |
| 45 | described above. They can call :c:func:`xa_tag_pointer` to create an |
| 46 | entry with a tag, :c:func:`xa_untag_pointer` to turn a tagged entry |
| 47 | back into an untagged pointer and :c:func:`xa_pointer_tag` to retrieve |
| 48 | the tag of an entry. Tagged pointers use the same bits that are used |
| 49 | to distinguish value entries from normal pointers, so each user must |
| 50 | decide whether they want to store value entries or tagged pointers in |
| 51 | any particular XArray. |
| 52 | |
| 53 | The XArray does not support storing :c:func:`IS_ERR` pointers as some |
| 54 | conflict with value entries or internal entries. |
| 55 | |
| 56 | An unusual feature of the XArray is the ability to create entries which |
| 57 | occupy a range of indices. Once stored to, looking up any index in |
| 58 | the range will return the same entry as looking up any other index in |
| 59 | the range. Setting a mark on one index will set it on all of them. |
| 60 | Storing to any index will store to all of them. Multi-index entries can |
| 61 | be explicitly split into smaller entries, or storing ``NULL`` into any |
| 62 | entry will cause the XArray to forget about the range. |
| 63 | |
| 64 | Normal API |
| 65 | ========== |
| 66 | |
| 67 | Start by initialising an XArray, either with :c:func:`DEFINE_XARRAY` |
| 68 | for statically allocated XArrays or :c:func:`xa_init` for dynamically |
| 69 | allocated ones. A freshly-initialised XArray contains a ``NULL`` |
| 70 | pointer at every index. |
| 71 | |
| 72 | You can then set entries using :c:func:`xa_store` and get entries |
| 73 | using :c:func:`xa_load`. xa_store will overwrite any entry with the |
| 74 | new entry and return the previous entry stored at that index. You can |
| 75 | use :c:func:`xa_erase` instead of calling :c:func:`xa_store` with a |
| 76 | ``NULL`` entry. There is no difference between an entry that has never |
Matthew Wilcox | 804dfaf | 2018-11-05 16:37:15 -0500 | [diff] [blame] | 77 | been stored to, one that has been erased and one that has most recently |
| 78 | had ``NULL`` stored to it. |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 79 | |
| 80 | You can conditionally replace an entry at an index by using |
| 81 | :c:func:`xa_cmpxchg`. Like :c:func:`cmpxchg`, it will only succeed if |
| 82 | the entry at that index has the 'old' value. It also returns the entry |
| 83 | which was at that index; if it returns the same entry which was passed as |
| 84 | 'old', then :c:func:`xa_cmpxchg` succeeded. |
| 85 | |
| 86 | If you want to only store a new entry to an index if the current entry |
| 87 | at that index is ``NULL``, you can use :c:func:`xa_insert` which |
| 88 | returns ``-EEXIST`` if the entry is not empty. |
| 89 | |
| 90 | You can enquire whether a mark is set on an entry by using |
| 91 | :c:func:`xa_get_mark`. If the entry is not ``NULL``, you can set a mark |
| 92 | on it by using :c:func:`xa_set_mark` and remove the mark from an entry by |
| 93 | calling :c:func:`xa_clear_mark`. You can ask whether any entry in the |
| 94 | XArray has a particular mark set by calling :c:func:`xa_marked`. |
| 95 | |
| 96 | You can copy entries out of the XArray into a plain array by calling |
| 97 | :c:func:`xa_extract`. Or you can iterate over the present entries in |
| 98 | the XArray by calling :c:func:`xa_for_each`. You may prefer to use |
| 99 | :c:func:`xa_find` or :c:func:`xa_find_after` to move to the next present |
| 100 | entry in the XArray. |
| 101 | |
Matthew Wilcox | 0e9446c | 2018-08-15 14:13:29 -0400 | [diff] [blame] | 102 | Calling :c:func:`xa_store_range` stores the same entry in a range |
| 103 | of indices. If you do this, some of the other operations will behave |
| 104 | in a slightly odd way. For example, marking the entry at one index |
| 105 | may result in the entry being marked at some, but not all of the other |
| 106 | indices. Storing into one index may result in the entry retrieved by |
| 107 | some, but not all of the other indices changing. |
| 108 | |
Matthew Wilcox | 4c0608f | 2018-10-30 09:45:55 -0400 | [diff] [blame] | 109 | Sometimes you need to ensure that a subsequent call to :c:func:`xa_store` |
| 110 | will not need to allocate memory. The :c:func:`xa_reserve` function |
| 111 | will store a reserved entry at the indicated index. Users of the normal |
| 112 | API will see this entry as containing ``NULL``. If you do not need to |
| 113 | use the reserved entry, you can call :c:func:`xa_release` to remove the |
| 114 | unused entry. If another user has stored to the entry in the meantime, |
| 115 | :c:func:`xa_release` will do nothing; if instead you want the entry to |
| 116 | become ``NULL``, you should use :c:func:`xa_erase`. |
| 117 | |
Matthew Wilcox | 804dfaf | 2018-11-05 16:37:15 -0500 | [diff] [blame] | 118 | If all entries in the array are ``NULL``, the :c:func:`xa_empty` function |
| 119 | will return ``true``. |
| 120 | |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 121 | Finally, you can remove all entries from an XArray by calling |
| 122 | :c:func:`xa_destroy`. If the XArray entries are pointers, you may wish |
| 123 | to free the entries first. You can do this by iterating over all present |
| 124 | entries in the XArray using the :c:func:`xa_for_each` iterator. |
| 125 | |
Matthew Wilcox | d9c4804 | 2018-11-05 16:15:56 -0500 | [diff] [blame] | 126 | Allocating XArrays |
| 127 | ------------------ |
| 128 | |
| 129 | If you use :c:func:`DEFINE_XARRAY_ALLOC` to define the XArray, or |
| 130 | initialise it by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`, |
| 131 | the XArray changes to track whether entries are in use or not. |
Matthew Wilcox | 371c752 | 2018-07-04 10:50:12 -0400 | [diff] [blame] | 132 | |
| 133 | You can call :c:func:`xa_alloc` to store the entry at any unused index |
| 134 | in the XArray. If you need to modify the array from interrupt context, |
| 135 | you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable |
Matthew Wilcox | d9c4804 | 2018-11-05 16:15:56 -0500 | [diff] [blame] | 136 | interrupts while allocating the ID. |
| 137 | |
| 138 | Using :c:func:`xa_store`, :c:func:`xa_cmpxchg` or :c:func:`xa_insert` |
| 139 | will mark the entry as being allocated. Unlike a normal XArray, storing |
| 140 | ``NULL`` will mark the entry as being in use, like :c:func:`xa_reserve`. |
| 141 | To free an entry, use :c:func:`xa_erase` (or :c:func:`xa_release` if |
| 142 | you only want to free the entry if it's ``NULL``). |
| 143 | |
| 144 | You cannot use ``XA_MARK_0`` with an allocating XArray as this mark |
| 145 | is used to track whether an entry is free or not. The other marks are |
| 146 | available for your use. |
Matthew Wilcox | 371c752 | 2018-07-04 10:50:12 -0400 | [diff] [blame] | 147 | |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 148 | Memory allocation |
| 149 | ----------------- |
| 150 | |
Matthew Wilcox | 371c752 | 2018-07-04 10:50:12 -0400 | [diff] [blame] | 151 | The :c:func:`xa_store`, :c:func:`xa_cmpxchg`, :c:func:`xa_alloc`, |
| 152 | :c:func:`xa_reserve` and :c:func:`xa_insert` functions take a gfp_t |
| 153 | parameter in case the XArray needs to allocate memory to store this entry. |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 154 | If the entry is being deleted, no memory allocation needs to be performed, |
| 155 | and the GFP flags specified will be ignored. |
| 156 | |
| 157 | It is possible for no memory to be allocatable, particularly if you pass |
| 158 | a restrictive set of GFP flags. In that case, the functions return a |
| 159 | special value which can be turned into an errno using :c:func:`xa_err`. |
| 160 | If you don't need to know exactly which error occurred, using |
| 161 | :c:func:`xa_is_err` is slightly more efficient. |
| 162 | |
| 163 | Locking |
| 164 | ------- |
| 165 | |
| 166 | When using the Normal API, you do not have to worry about locking. |
| 167 | The XArray uses RCU and an internal spinlock to synchronise access: |
| 168 | |
| 169 | No lock needed: |
| 170 | * :c:func:`xa_empty` |
| 171 | * :c:func:`xa_marked` |
| 172 | |
| 173 | Takes RCU read lock: |
| 174 | * :c:func:`xa_load` |
| 175 | * :c:func:`xa_for_each` |
| 176 | * :c:func:`xa_find` |
| 177 | * :c:func:`xa_find_after` |
| 178 | * :c:func:`xa_extract` |
| 179 | * :c:func:`xa_get_mark` |
| 180 | |
| 181 | Takes xa_lock internally: |
| 182 | * :c:func:`xa_store` |
Matthew Wilcox | 84e5acb | 2018-10-26 14:41:29 -0400 | [diff] [blame] | 183 | * :c:func:`xa_store_bh` |
| 184 | * :c:func:`xa_store_irq` |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 185 | * :c:func:`xa_insert` |
| 186 | * :c:func:`xa_erase` |
| 187 | * :c:func:`xa_erase_bh` |
| 188 | * :c:func:`xa_erase_irq` |
| 189 | * :c:func:`xa_cmpxchg` |
Matthew Wilcox | 0e9446c | 2018-08-15 14:13:29 -0400 | [diff] [blame] | 190 | * :c:func:`xa_store_range` |
Matthew Wilcox | 371c752 | 2018-07-04 10:50:12 -0400 | [diff] [blame] | 191 | * :c:func:`xa_alloc` |
| 192 | * :c:func:`xa_alloc_bh` |
| 193 | * :c:func:`xa_alloc_irq` |
Matthew Wilcox | 4c0608f | 2018-10-30 09:45:55 -0400 | [diff] [blame] | 194 | * :c:func:`xa_reserve` |
| 195 | * :c:func:`xa_reserve_bh` |
| 196 | * :c:func:`xa_reserve_irq` |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 197 | * :c:func:`xa_destroy` |
| 198 | * :c:func:`xa_set_mark` |
| 199 | * :c:func:`xa_clear_mark` |
| 200 | |
| 201 | Assumes xa_lock held on entry: |
| 202 | * :c:func:`__xa_store` |
| 203 | * :c:func:`__xa_insert` |
| 204 | * :c:func:`__xa_erase` |
| 205 | * :c:func:`__xa_cmpxchg` |
Matthew Wilcox | 371c752 | 2018-07-04 10:50:12 -0400 | [diff] [blame] | 206 | * :c:func:`__xa_alloc` |
Matthew Wilcox | 4c0608f | 2018-10-30 09:45:55 -0400 | [diff] [blame] | 207 | * :c:func:`__xa_reserve` |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 208 | * :c:func:`__xa_set_mark` |
| 209 | * :c:func:`__xa_clear_mark` |
| 210 | |
| 211 | If you want to take advantage of the lock to protect the data structures |
| 212 | that you are storing in the XArray, you can call :c:func:`xa_lock` |
| 213 | before calling :c:func:`xa_load`, then take a reference count on the |
| 214 | object you have found before calling :c:func:`xa_unlock`. This will |
| 215 | prevent stores from removing the object from the array between looking |
| 216 | up the object and incrementing the refcount. You can also use RCU to |
| 217 | avoid dereferencing freed memory, but an explanation of that is beyond |
| 218 | the scope of this document. |
| 219 | |
| 220 | The XArray does not disable interrupts or softirqs while modifying |
| 221 | the array. It is safe to read the XArray from interrupt or softirq |
| 222 | context as the RCU lock provides enough protection. |
| 223 | |
| 224 | If, for example, you want to store entries in the XArray in process |
| 225 | context and then erase them in softirq context, you can do that this way:: |
| 226 | |
| 227 | void foo_init(struct foo *foo) |
| 228 | { |
| 229 | xa_init_flags(&foo->array, XA_FLAGS_LOCK_BH); |
| 230 | } |
| 231 | |
| 232 | int foo_store(struct foo *foo, unsigned long index, void *entry) |
| 233 | { |
| 234 | int err; |
| 235 | |
| 236 | xa_lock_bh(&foo->array); |
| 237 | err = xa_err(__xa_store(&foo->array, index, entry, GFP_KERNEL)); |
| 238 | if (!err) |
| 239 | foo->count++; |
| 240 | xa_unlock_bh(&foo->array); |
| 241 | return err; |
| 242 | } |
| 243 | |
| 244 | /* foo_erase() is only called from softirq context */ |
| 245 | void foo_erase(struct foo *foo, unsigned long index) |
| 246 | { |
| 247 | xa_lock(&foo->array); |
| 248 | __xa_erase(&foo->array, index); |
| 249 | foo->count--; |
| 250 | xa_unlock(&foo->array); |
| 251 | } |
| 252 | |
| 253 | If you are going to modify the XArray from interrupt or softirq context, |
| 254 | you need to initialise the array using :c:func:`xa_init_flags`, passing |
| 255 | ``XA_FLAGS_LOCK_IRQ`` or ``XA_FLAGS_LOCK_BH``. |
| 256 | |
| 257 | The above example also shows a common pattern of wanting to extend the |
| 258 | coverage of the xa_lock on the store side to protect some statistics |
| 259 | associated with the array. |
| 260 | |
| 261 | Sharing the XArray with interrupt context is also possible, either |
| 262 | using :c:func:`xa_lock_irqsave` in both the interrupt handler and process |
| 263 | context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock` |
| 264 | in the interrupt handler. Some of the more common patterns have helper |
Matthew Wilcox | 84e5acb | 2018-10-26 14:41:29 -0400 | [diff] [blame] | 265 | functions such as :c:func:`xa_store_bh`, :c:func:`xa_store_irq`, |
| 266 | :c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`. |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 267 | |
| 268 | Sometimes you need to protect access to the XArray with a mutex because |
| 269 | that lock sits above another mutex in the locking hierarchy. That does |
| 270 | not entitle you to use functions like :c:func:`__xa_erase` without taking |
| 271 | the xa_lock; the xa_lock is used for lockdep validation and will be used |
| 272 | for other purposes in the future. |
| 273 | |
| 274 | The :c:func:`__xa_set_mark` and :c:func:`__xa_clear_mark` functions are also |
| 275 | available for situations where you look up an entry and want to atomically |
| 276 | set or clear a mark. It may be more efficient to use the advanced API |
| 277 | in this case, as it will save you from walking the tree twice. |
| 278 | |
| 279 | Advanced API |
| 280 | ============ |
| 281 | |
| 282 | The advanced API offers more flexibility and better performance at the |
| 283 | cost of an interface which can be harder to use and has fewer safeguards. |
| 284 | No locking is done for you by the advanced API, and you are required |
| 285 | to use the xa_lock while modifying the array. You can choose whether |
| 286 | to use the xa_lock or the RCU lock while doing read-only operations on |
| 287 | the array. You can mix advanced and normal operations on the same array; |
| 288 | indeed the normal API is implemented in terms of the advanced API. The |
| 289 | advanced API is only available to modules with a GPL-compatible license. |
| 290 | |
| 291 | The advanced API is based around the xa_state. This is an opaque data |
| 292 | structure which you declare on the stack using the :c:func:`XA_STATE` |
| 293 | macro. This macro initialises the xa_state ready to start walking |
| 294 | around the XArray. It is used as a cursor to maintain the position |
| 295 | in the XArray and let you compose various operations together without |
| 296 | having to restart from the top every time. |
| 297 | |
| 298 | The xa_state is also used to store errors. You can call |
| 299 | :c:func:`xas_error` to retrieve the error. All operations check whether |
| 300 | the xa_state is in an error state before proceeding, so there's no need |
| 301 | for you to check for an error after each call; you can make multiple |
| 302 | calls in succession and only check at a convenient point. The only |
| 303 | errors currently generated by the XArray code itself are ``ENOMEM`` and |
| 304 | ``EINVAL``, but it supports arbitrary errors in case you want to call |
| 305 | :c:func:`xas_set_err` yourself. |
| 306 | |
| 307 | If the xa_state is holding an ``ENOMEM`` error, calling :c:func:`xas_nomem` |
| 308 | will attempt to allocate more memory using the specified gfp flags and |
| 309 | cache it in the xa_state for the next attempt. The idea is that you take |
| 310 | the xa_lock, attempt the operation and drop the lock. The operation |
| 311 | attempts to allocate memory while holding the lock, but it is more |
| 312 | likely to fail. Once you have dropped the lock, :c:func:`xas_nomem` |
| 313 | can try harder to allocate more memory. It will return ``true`` if it |
| 314 | is worth retrying the operation (i.e. that there was a memory error *and* |
| 315 | more memory was allocated). If it has previously allocated memory, and |
| 316 | that memory wasn't used, and there is no error (or some error that isn't |
| 317 | ``ENOMEM``), then it will free the memory previously allocated. |
| 318 | |
| 319 | Internal Entries |
| 320 | ---------------- |
| 321 | |
| 322 | The XArray reserves some entries for its own purposes. These are never |
| 323 | exposed through the normal API, but when using the advanced API, it's |
| 324 | possible to see them. Usually the best way to handle them is to pass them |
| 325 | to :c:func:`xas_retry`, and retry the operation if it returns ``true``. |
| 326 | |
| 327 | .. flat-table:: |
| 328 | :widths: 1 1 6 |
| 329 | |
| 330 | * - Name |
| 331 | - Test |
| 332 | - Usage |
| 333 | |
| 334 | * - Node |
| 335 | - :c:func:`xa_is_node` |
| 336 | - An XArray node. May be visible when using a multi-index xa_state. |
| 337 | |
| 338 | * - Sibling |
| 339 | - :c:func:`xa_is_sibling` |
| 340 | - A non-canonical entry for a multi-index entry. The value indicates |
| 341 | which slot in this node has the canonical entry. |
| 342 | |
| 343 | * - Retry |
| 344 | - :c:func:`xa_is_retry` |
| 345 | - This entry is currently being modified by a thread which has the |
| 346 | xa_lock. The node containing this entry may be freed at the end |
| 347 | of this RCU period. You should restart the lookup from the head |
| 348 | of the array. |
| 349 | |
Matthew Wilcox | 9f14d4f | 2018-10-01 14:54:59 -0400 | [diff] [blame] | 350 | * - Zero |
| 351 | - :c:func:`xa_is_zero` |
| 352 | - Zero entries appear as ``NULL`` through the Normal API, but occupy |
| 353 | an entry in the XArray which can be used to reserve the index for |
Matthew Wilcox | d9c4804 | 2018-11-05 16:15:56 -0500 | [diff] [blame] | 354 | future use. This is used by allocating XArrays for allocated entries |
| 355 | which are ``NULL``. |
Matthew Wilcox | 9f14d4f | 2018-10-01 14:54:59 -0400 | [diff] [blame] | 356 | |
Matthew Wilcox | 992a8e6 | 2017-11-23 22:57:20 -0500 | [diff] [blame] | 357 | Other internal entries may be added in the future. As far as possible, they |
| 358 | will be handled by :c:func:`xas_retry`. |
| 359 | |
| 360 | Additional functionality |
| 361 | ------------------------ |
| 362 | |
| 363 | The :c:func:`xas_create_range` function allocates all the necessary memory |
| 364 | to store every entry in a range. It will set ENOMEM in the xa_state if |
| 365 | it cannot allocate memory. |
| 366 | |
| 367 | You can use :c:func:`xas_init_marks` to reset the marks on an entry |
| 368 | to their default state. This is usually all marks clear, unless the |
| 369 | XArray is marked with ``XA_FLAGS_TRACK_FREE``, in which case mark 0 is set |
| 370 | and all other marks are clear. Replacing one entry with another using |
| 371 | :c:func:`xas_store` will not reset the marks on that entry; if you want |
| 372 | the marks reset, you should do that explicitly. |
| 373 | |
| 374 | The :c:func:`xas_load` will walk the xa_state as close to the entry |
| 375 | as it can. If you know the xa_state has already been walked to the |
| 376 | entry and need to check that the entry hasn't changed, you can use |
| 377 | :c:func:`xas_reload` to save a function call. |
| 378 | |
| 379 | If you need to move to a different index in the XArray, call |
| 380 | :c:func:`xas_set`. This resets the cursor to the top of the tree, which |
| 381 | will generally make the next operation walk the cursor to the desired |
| 382 | spot in the tree. If you want to move to the next or previous index, |
| 383 | call :c:func:`xas_next` or :c:func:`xas_prev`. Setting the index does |
| 384 | not walk the cursor around the array so does not require a lock to be |
| 385 | held, while moving to the next or previous index does. |
| 386 | |
| 387 | You can search for the next present entry using :c:func:`xas_find`. This |
| 388 | is the equivalent of both :c:func:`xa_find` and :c:func:`xa_find_after`; |
| 389 | if the cursor has been walked to an entry, then it will find the next |
| 390 | entry after the one currently referenced. If not, it will return the |
| 391 | entry at the index of the xa_state. Using :c:func:`xas_next_entry` to |
| 392 | move to the next present entry instead of :c:func:`xas_find` will save |
| 393 | a function call in the majority of cases at the expense of emitting more |
| 394 | inline code. |
| 395 | |
| 396 | The :c:func:`xas_find_marked` function is similar. If the xa_state has |
| 397 | not been walked, it will return the entry at the index of the xa_state, |
| 398 | if it is marked. Otherwise, it will return the first marked entry after |
| 399 | the entry referenced by the xa_state. The :c:func:`xas_next_marked` |
| 400 | function is the equivalent of :c:func:`xas_next_entry`. |
| 401 | |
| 402 | When iterating over a range of the XArray using :c:func:`xas_for_each` |
| 403 | or :c:func:`xas_for_each_marked`, it may be necessary to temporarily stop |
| 404 | the iteration. The :c:func:`xas_pause` function exists for this purpose. |
| 405 | After you have done the necessary work and wish to resume, the xa_state |
| 406 | is in an appropriate state to continue the iteration after the entry |
| 407 | you last processed. If you have interrupts disabled while iterating, |
| 408 | then it is good manners to pause the iteration and reenable interrupts |
| 409 | every ``XA_CHECK_SCHED`` entries. |
| 410 | |
| 411 | The :c:func:`xas_get_mark`, :c:func:`xas_set_mark` and |
| 412 | :c:func:`xas_clear_mark` functions require the xa_state cursor to have |
| 413 | been moved to the appropriate location in the xarray; they will do |
| 414 | nothing if you have called :c:func:`xas_pause` or :c:func:`xas_set` |
| 415 | immediately before. |
| 416 | |
| 417 | You can call :c:func:`xas_set_update` to have a callback function |
| 418 | called each time the XArray updates a node. This is used by the page |
| 419 | cache workingset code to maintain its list of nodes which contain only |
| 420 | shadow entries. |
| 421 | |
| 422 | Multi-Index Entries |
| 423 | ------------------- |
| 424 | |
| 425 | The XArray has the ability to tie multiple indices together so that |
| 426 | operations on one index affect all indices. For example, storing into |
| 427 | any index will change the value of the entry retrieved from any index. |
| 428 | Setting or clearing a mark on any index will set or clear the mark |
| 429 | on every index that is tied together. The current implementation |
| 430 | only allows tying ranges which are aligned powers of two together; |
| 431 | eg indices 64-127 may be tied together, but 2-6 may not be. This may |
| 432 | save substantial quantities of memory; for example tying 512 entries |
| 433 | together will save over 4kB. |
| 434 | |
| 435 | You can create a multi-index entry by using :c:func:`XA_STATE_ORDER` |
| 436 | or :c:func:`xas_set_order` followed by a call to :c:func:`xas_store`. |
| 437 | Calling :c:func:`xas_load` with a multi-index xa_state will walk the |
| 438 | xa_state to the right location in the tree, but the return value is not |
| 439 | meaningful, potentially being an internal entry or ``NULL`` even when there |
| 440 | is an entry stored within the range. Calling :c:func:`xas_find_conflict` |
| 441 | will return the first entry within the range or ``NULL`` if there are no |
| 442 | entries in the range. The :c:func:`xas_for_each_conflict` iterator will |
| 443 | iterate over every entry which overlaps the specified range. |
| 444 | |
| 445 | If :c:func:`xas_load` encounters a multi-index entry, the xa_index |
| 446 | in the xa_state will not be changed. When iterating over an XArray |
| 447 | or calling :c:func:`xas_find`, if the initial index is in the middle |
| 448 | of a multi-index entry, it will not be altered. Subsequent calls |
| 449 | or iterations will move the index to the first index in the range. |
| 450 | Each entry will only be returned once, no matter how many indices it |
| 451 | occupies. |
| 452 | |
| 453 | Using :c:func:`xas_next` or :c:func:`xas_prev` with a multi-index xa_state |
| 454 | is not supported. Using either of these functions on a multi-index entry |
| 455 | will reveal sibling entries; these should be skipped over by the caller. |
| 456 | |
| 457 | Storing ``NULL`` into any index of a multi-index entry will set the entry |
| 458 | at every index to ``NULL`` and dissolve the tie. Splitting a multi-index |
| 459 | entry into entries occupying smaller ranges is not yet supported. |
| 460 | |
| 461 | Functions and structures |
| 462 | ======================== |
| 463 | |
| 464 | .. kernel-doc:: include/linux/xarray.h |
| 465 | .. kernel-doc:: lib/xarray.c |