162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci======
462306a36Sopenharmony_ciXArray
562306a36Sopenharmony_ci======
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci:Author: Matthew Wilcox
862306a36Sopenharmony_ci
962306a36Sopenharmony_ciOverview
1062306a36Sopenharmony_ci========
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ciThe XArray is an abstract data type which behaves like a very large array
1362306a36Sopenharmony_ciof pointers.  It meets many of the same needs as a hash or a conventional
1462306a36Sopenharmony_ciresizable array.  Unlike a hash, it allows you to sensibly go to the
1562306a36Sopenharmony_cinext or previous entry in a cache-efficient manner.  In contrast to a
1662306a36Sopenharmony_ciresizable array, there is no need to copy data or change MMU mappings in
1762306a36Sopenharmony_ciorder to grow the array.  It is more memory-efficient, parallelisable
1862306a36Sopenharmony_ciand cache friendly than a doubly-linked list.  It takes advantage of
1962306a36Sopenharmony_ciRCU to perform lookups without locking.
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ciThe XArray implementation is efficient when the indices used are densely
2262306a36Sopenharmony_ciclustered; hashing the object and using the hash as the index will not
2362306a36Sopenharmony_ciperform well.  The XArray is optimised for small indices, but still has
2462306a36Sopenharmony_cigood performance with large indices.  If your index can be larger than
2562306a36Sopenharmony_ci``ULONG_MAX`` then the XArray is not the data type for you.  The most
2662306a36Sopenharmony_ciimportant user of the XArray is the page cache.
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciNormal pointers may be stored in the XArray directly.  They must be 4-byte
2962306a36Sopenharmony_cialigned, which is true for any pointer returned from kmalloc() and
3062306a36Sopenharmony_cialloc_page().  It isn't true for arbitrary user-space pointers,
3162306a36Sopenharmony_cinor for function pointers.  You can store pointers to statically allocated
3262306a36Sopenharmony_ciobjects, as long as those objects have an alignment of at least 4.
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciYou can also store integers between 0 and ``LONG_MAX`` in the XArray.
3562306a36Sopenharmony_ciYou must first convert it into an entry using xa_mk_value().
3662306a36Sopenharmony_ciWhen you retrieve an entry from the XArray, you can check whether it is
3762306a36Sopenharmony_cia value entry by calling xa_is_value(), and convert it back to
3862306a36Sopenharmony_cian integer by calling xa_to_value().
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciSome users want to tag the pointers they store in the XArray.  You can
4162306a36Sopenharmony_cicall xa_tag_pointer() to create an entry with a tag, xa_untag_pointer()
4262306a36Sopenharmony_cito turn a tagged entry back into an untagged pointer and xa_pointer_tag()
4362306a36Sopenharmony_cito retrieve the tag of an entry.  Tagged pointers use the same bits that
4462306a36Sopenharmony_ciare used to distinguish value entries from normal pointers, so you must
4562306a36Sopenharmony_cidecide whether they want to store value entries or tagged pointers in
4662306a36Sopenharmony_ciany particular XArray.
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ciThe XArray does not support storing IS_ERR() pointers as some
4962306a36Sopenharmony_ciconflict with value entries or internal entries.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciAn unusual feature of the XArray is the ability to create entries which
5262306a36Sopenharmony_cioccupy a range of indices.  Once stored to, looking up any index in
5362306a36Sopenharmony_cithe range will return the same entry as looking up any other index in
5462306a36Sopenharmony_cithe range.  Storing to any index will store to all of them.  Multi-index
5562306a36Sopenharmony_cientries can be explicitly split into smaller entries, or storing ``NULL``
5662306a36Sopenharmony_ciinto any entry will cause the XArray to forget about the range.
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ciNormal API
5962306a36Sopenharmony_ci==========
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciStart by initialising an XArray, either with DEFINE_XARRAY()
6262306a36Sopenharmony_cifor statically allocated XArrays or xa_init() for dynamically
6362306a36Sopenharmony_ciallocated ones.  A freshly-initialised XArray contains a ``NULL``
6462306a36Sopenharmony_cipointer at every index.
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciYou can then set entries using xa_store() and get entries
6762306a36Sopenharmony_ciusing xa_load().  xa_store will overwrite any entry with the
6862306a36Sopenharmony_cinew entry and return the previous entry stored at that index.  You can
6962306a36Sopenharmony_ciuse xa_erase() instead of calling xa_store() with a
7062306a36Sopenharmony_ci``NULL`` entry.  There is no difference between an entry that has never
7162306a36Sopenharmony_cibeen stored to, one that has been erased and one that has most recently
7262306a36Sopenharmony_cihad ``NULL`` stored to it.
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ciYou can conditionally replace an entry at an index by using
7562306a36Sopenharmony_cixa_cmpxchg().  Like cmpxchg(), it will only succeed if
7662306a36Sopenharmony_cithe entry at that index has the 'old' value.  It also returns the entry
7762306a36Sopenharmony_ciwhich was at that index; if it returns the same entry which was passed as
7862306a36Sopenharmony_ci'old', then xa_cmpxchg() succeeded.
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciIf you want to only store a new entry to an index if the current entry
8162306a36Sopenharmony_ciat that index is ``NULL``, you can use xa_insert() which
8262306a36Sopenharmony_cireturns ``-EBUSY`` if the entry is not empty.
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ciYou can copy entries out of the XArray into a plain array by calling
8562306a36Sopenharmony_cixa_extract().  Or you can iterate over the present entries in the XArray
8662306a36Sopenharmony_ciby calling xa_for_each(), xa_for_each_start() or xa_for_each_range().
8762306a36Sopenharmony_ciYou may prefer to use xa_find() or xa_find_after() to move to the next
8862306a36Sopenharmony_cipresent entry in the XArray.
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ciCalling xa_store_range() stores the same entry in a range
9162306a36Sopenharmony_ciof indices.  If you do this, some of the other operations will behave
9262306a36Sopenharmony_ciin a slightly odd way.  For example, marking the entry at one index
9362306a36Sopenharmony_cimay result in the entry being marked at some, but not all of the other
9462306a36Sopenharmony_ciindices.  Storing into one index may result in the entry retrieved by
9562306a36Sopenharmony_cisome, but not all of the other indices changing.
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ciSometimes you need to ensure that a subsequent call to xa_store()
9862306a36Sopenharmony_ciwill not need to allocate memory.  The xa_reserve() function
9962306a36Sopenharmony_ciwill store a reserved entry at the indicated index.  Users of the
10062306a36Sopenharmony_cinormal API will see this entry as containing ``NULL``.  If you do
10162306a36Sopenharmony_cinot need to use the reserved entry, you can call xa_release()
10262306a36Sopenharmony_cito remove the unused entry.  If another user has stored to the entry
10362306a36Sopenharmony_ciin the meantime, xa_release() will do nothing; if instead you
10462306a36Sopenharmony_ciwant the entry to become ``NULL``, you should use xa_erase().
10562306a36Sopenharmony_ciUsing xa_insert() on a reserved entry will fail.
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciIf all entries in the array are ``NULL``, the xa_empty() function
10862306a36Sopenharmony_ciwill return ``true``.
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ciFinally, you can remove all entries from an XArray by calling
11162306a36Sopenharmony_cixa_destroy().  If the XArray entries are pointers, you may wish
11262306a36Sopenharmony_cito free the entries first.  You can do this by iterating over all present
11362306a36Sopenharmony_cientries in the XArray using the xa_for_each() iterator.
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciSearch Marks
11662306a36Sopenharmony_ci------------
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ciEach entry in the array has three bits associated with it called marks.
11962306a36Sopenharmony_ciEach mark may be set or cleared independently of the others.  You can
12062306a36Sopenharmony_ciiterate over marked entries by using the xa_for_each_marked() iterator.
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ciYou can enquire whether a mark is set on an entry by using
12362306a36Sopenharmony_cixa_get_mark().  If the entry is not ``NULL``, you can set a mark on it
12462306a36Sopenharmony_ciby using xa_set_mark() and remove the mark from an entry by calling
12562306a36Sopenharmony_cixa_clear_mark().  You can ask whether any entry in the XArray has a
12662306a36Sopenharmony_ciparticular mark set by calling xa_marked().  Erasing an entry from the
12762306a36Sopenharmony_ciXArray causes all marks associated with that entry to be cleared.
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ciSetting or clearing a mark on any index of a multi-index entry will
13062306a36Sopenharmony_ciaffect all indices covered by that entry.  Querying the mark on any
13162306a36Sopenharmony_ciindex will return the same result.
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ciThere is no way to iterate over entries which are not marked; the data
13462306a36Sopenharmony_cistructure does not allow this to be implemented efficiently.  There are
13562306a36Sopenharmony_cinot currently iterators to search for logical combinations of bits (eg
13662306a36Sopenharmony_ciiterate over all entries which have both ``XA_MARK_1`` and ``XA_MARK_2``
13762306a36Sopenharmony_ciset, or iterate over all entries which have ``XA_MARK_0`` or ``XA_MARK_2``
13862306a36Sopenharmony_ciset).  It would be possible to add these if a user arises.
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ciAllocating XArrays
14162306a36Sopenharmony_ci------------------
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ciIf you use DEFINE_XARRAY_ALLOC() to define the XArray, or
14462306a36Sopenharmony_ciinitialise it by passing ``XA_FLAGS_ALLOC`` to xa_init_flags(),
14562306a36Sopenharmony_cithe XArray changes to track whether entries are in use or not.
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ciYou can call xa_alloc() to store the entry at an unused index
14862306a36Sopenharmony_ciin the XArray.  If you need to modify the array from interrupt context,
14962306a36Sopenharmony_ciyou can use xa_alloc_bh() or xa_alloc_irq() to disable
15062306a36Sopenharmony_ciinterrupts while allocating the ID.
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciUsing xa_store(), xa_cmpxchg() or xa_insert() will
15362306a36Sopenharmony_cialso mark the entry as being allocated.  Unlike a normal XArray, storing
15462306a36Sopenharmony_ci``NULL`` will mark the entry as being in use, like xa_reserve().
15562306a36Sopenharmony_ciTo free an entry, use xa_erase() (or xa_release() if
15662306a36Sopenharmony_ciyou only want to free the entry if it's ``NULL``).
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ciBy default, the lowest free entry is allocated starting from 0.  If you
15962306a36Sopenharmony_ciwant to allocate entries starting at 1, it is more efficient to use
16062306a36Sopenharmony_ciDEFINE_XARRAY_ALLOC1() or ``XA_FLAGS_ALLOC1``.  If you want to
16162306a36Sopenharmony_ciallocate IDs up to a maximum, then wrap back around to the lowest free
16262306a36Sopenharmony_ciID, you can use xa_alloc_cyclic().
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciYou cannot use ``XA_MARK_0`` with an allocating XArray as this mark
16562306a36Sopenharmony_ciis used to track whether an entry is free or not.  The other marks are
16662306a36Sopenharmony_ciavailable for your use.
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ciMemory allocation
16962306a36Sopenharmony_ci-----------------
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ciThe xa_store(), xa_cmpxchg(), xa_alloc(),
17262306a36Sopenharmony_cixa_reserve() and xa_insert() functions take a gfp_t
17362306a36Sopenharmony_ciparameter in case the XArray needs to allocate memory to store this entry.
17462306a36Sopenharmony_ciIf the entry is being deleted, no memory allocation needs to be performed,
17562306a36Sopenharmony_ciand the GFP flags specified will be ignored.
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ciIt is possible for no memory to be allocatable, particularly if you pass
17862306a36Sopenharmony_cia restrictive set of GFP flags.  In that case, the functions return a
17962306a36Sopenharmony_cispecial value which can be turned into an errno using xa_err().
18062306a36Sopenharmony_ciIf you don't need to know exactly which error occurred, using
18162306a36Sopenharmony_cixa_is_err() is slightly more efficient.
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ciLocking
18462306a36Sopenharmony_ci-------
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciWhen using the Normal API, you do not have to worry about locking.
18762306a36Sopenharmony_ciThe XArray uses RCU and an internal spinlock to synchronise access:
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ciNo lock needed:
19062306a36Sopenharmony_ci * xa_empty()
19162306a36Sopenharmony_ci * xa_marked()
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ciTakes RCU read lock:
19462306a36Sopenharmony_ci * xa_load()
19562306a36Sopenharmony_ci * xa_for_each()
19662306a36Sopenharmony_ci * xa_for_each_start()
19762306a36Sopenharmony_ci * xa_for_each_range()
19862306a36Sopenharmony_ci * xa_find()
19962306a36Sopenharmony_ci * xa_find_after()
20062306a36Sopenharmony_ci * xa_extract()
20162306a36Sopenharmony_ci * xa_get_mark()
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ciTakes xa_lock internally:
20462306a36Sopenharmony_ci * xa_store()
20562306a36Sopenharmony_ci * xa_store_bh()
20662306a36Sopenharmony_ci * xa_store_irq()
20762306a36Sopenharmony_ci * xa_insert()
20862306a36Sopenharmony_ci * xa_insert_bh()
20962306a36Sopenharmony_ci * xa_insert_irq()
21062306a36Sopenharmony_ci * xa_erase()
21162306a36Sopenharmony_ci * xa_erase_bh()
21262306a36Sopenharmony_ci * xa_erase_irq()
21362306a36Sopenharmony_ci * xa_cmpxchg()
21462306a36Sopenharmony_ci * xa_cmpxchg_bh()
21562306a36Sopenharmony_ci * xa_cmpxchg_irq()
21662306a36Sopenharmony_ci * xa_store_range()
21762306a36Sopenharmony_ci * xa_alloc()
21862306a36Sopenharmony_ci * xa_alloc_bh()
21962306a36Sopenharmony_ci * xa_alloc_irq()
22062306a36Sopenharmony_ci * xa_reserve()
22162306a36Sopenharmony_ci * xa_reserve_bh()
22262306a36Sopenharmony_ci * xa_reserve_irq()
22362306a36Sopenharmony_ci * xa_destroy()
22462306a36Sopenharmony_ci * xa_set_mark()
22562306a36Sopenharmony_ci * xa_clear_mark()
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ciAssumes xa_lock held on entry:
22862306a36Sopenharmony_ci * __xa_store()
22962306a36Sopenharmony_ci * __xa_insert()
23062306a36Sopenharmony_ci * __xa_erase()
23162306a36Sopenharmony_ci * __xa_cmpxchg()
23262306a36Sopenharmony_ci * __xa_alloc()
23362306a36Sopenharmony_ci * __xa_set_mark()
23462306a36Sopenharmony_ci * __xa_clear_mark()
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ciIf you want to take advantage of the lock to protect the data structures
23762306a36Sopenharmony_cithat you are storing in the XArray, you can call xa_lock()
23862306a36Sopenharmony_cibefore calling xa_load(), then take a reference count on the
23962306a36Sopenharmony_ciobject you have found before calling xa_unlock().  This will
24062306a36Sopenharmony_ciprevent stores from removing the object from the array between looking
24162306a36Sopenharmony_ciup the object and incrementing the refcount.  You can also use RCU to
24262306a36Sopenharmony_ciavoid dereferencing freed memory, but an explanation of that is beyond
24362306a36Sopenharmony_cithe scope of this document.
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ciThe XArray does not disable interrupts or softirqs while modifying
24662306a36Sopenharmony_cithe array.  It is safe to read the XArray from interrupt or softirq
24762306a36Sopenharmony_cicontext as the RCU lock provides enough protection.
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ciIf, for example, you want to store entries in the XArray in process
25062306a36Sopenharmony_cicontext and then erase them in softirq context, you can do that this way::
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci    void foo_init(struct foo *foo)
25362306a36Sopenharmony_ci    {
25462306a36Sopenharmony_ci        xa_init_flags(&foo->array, XA_FLAGS_LOCK_BH);
25562306a36Sopenharmony_ci    }
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci    int foo_store(struct foo *foo, unsigned long index, void *entry)
25862306a36Sopenharmony_ci    {
25962306a36Sopenharmony_ci        int err;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci        xa_lock_bh(&foo->array);
26262306a36Sopenharmony_ci        err = xa_err(__xa_store(&foo->array, index, entry, GFP_KERNEL));
26362306a36Sopenharmony_ci        if (!err)
26462306a36Sopenharmony_ci            foo->count++;
26562306a36Sopenharmony_ci        xa_unlock_bh(&foo->array);
26662306a36Sopenharmony_ci        return err;
26762306a36Sopenharmony_ci    }
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci    /* foo_erase() is only called from softirq context */
27062306a36Sopenharmony_ci    void foo_erase(struct foo *foo, unsigned long index)
27162306a36Sopenharmony_ci    {
27262306a36Sopenharmony_ci        xa_lock(&foo->array);
27362306a36Sopenharmony_ci        __xa_erase(&foo->array, index);
27462306a36Sopenharmony_ci        foo->count--;
27562306a36Sopenharmony_ci        xa_unlock(&foo->array);
27662306a36Sopenharmony_ci    }
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ciIf you are going to modify the XArray from interrupt or softirq context,
27962306a36Sopenharmony_ciyou need to initialise the array using xa_init_flags(), passing
28062306a36Sopenharmony_ci``XA_FLAGS_LOCK_IRQ`` or ``XA_FLAGS_LOCK_BH``.
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ciThe above example also shows a common pattern of wanting to extend the
28362306a36Sopenharmony_cicoverage of the xa_lock on the store side to protect some statistics
28462306a36Sopenharmony_ciassociated with the array.
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ciSharing the XArray with interrupt context is also possible, either
28762306a36Sopenharmony_ciusing xa_lock_irqsave() in both the interrupt handler and process
28862306a36Sopenharmony_cicontext, or xa_lock_irq() in process context and xa_lock()
28962306a36Sopenharmony_ciin the interrupt handler.  Some of the more common patterns have helper
29062306a36Sopenharmony_cifunctions such as xa_store_bh(), xa_store_irq(),
29162306a36Sopenharmony_cixa_erase_bh(), xa_erase_irq(), xa_cmpxchg_bh()
29262306a36Sopenharmony_ciand xa_cmpxchg_irq().
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ciSometimes you need to protect access to the XArray with a mutex because
29562306a36Sopenharmony_cithat lock sits above another mutex in the locking hierarchy.  That does
29662306a36Sopenharmony_cinot entitle you to use functions like __xa_erase() without taking
29762306a36Sopenharmony_cithe xa_lock; the xa_lock is used for lockdep validation and will be used
29862306a36Sopenharmony_cifor other purposes in the future.
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ciThe __xa_set_mark() and __xa_clear_mark() functions are also
30162306a36Sopenharmony_ciavailable for situations where you look up an entry and want to atomically
30262306a36Sopenharmony_ciset or clear a mark.  It may be more efficient to use the advanced API
30362306a36Sopenharmony_ciin this case, as it will save you from walking the tree twice.
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ciAdvanced API
30662306a36Sopenharmony_ci============
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ciThe advanced API offers more flexibility and better performance at the
30962306a36Sopenharmony_cicost of an interface which can be harder to use and has fewer safeguards.
31062306a36Sopenharmony_ciNo locking is done for you by the advanced API, and you are required
31162306a36Sopenharmony_cito use the xa_lock while modifying the array.  You can choose whether
31262306a36Sopenharmony_cito use the xa_lock or the RCU lock while doing read-only operations on
31362306a36Sopenharmony_cithe array.  You can mix advanced and normal operations on the same array;
31462306a36Sopenharmony_ciindeed the normal API is implemented in terms of the advanced API.  The
31562306a36Sopenharmony_ciadvanced API is only available to modules with a GPL-compatible license.
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ciThe advanced API is based around the xa_state.  This is an opaque data
31862306a36Sopenharmony_cistructure which you declare on the stack using the XA_STATE() macro.
31962306a36Sopenharmony_ciThis macro initialises the xa_state ready to start walking around the
32062306a36Sopenharmony_ciXArray.  It is used as a cursor to maintain the position in the XArray
32162306a36Sopenharmony_ciand let you compose various operations together without having to restart
32262306a36Sopenharmony_cifrom the top every time.  The contents of the xa_state are protected by
32362306a36Sopenharmony_cithe rcu_read_lock() or the xas_lock().  If you need to drop whichever of
32462306a36Sopenharmony_cithose locks is protecting your state and tree, you must call xas_pause()
32562306a36Sopenharmony_ciso that future calls do not rely on the parts of the state which were
32662306a36Sopenharmony_cileft unprotected.
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ciThe xa_state is also used to store errors.  You can call
32962306a36Sopenharmony_cixas_error() to retrieve the error.  All operations check whether
33062306a36Sopenharmony_cithe xa_state is in an error state before proceeding, so there's no need
33162306a36Sopenharmony_cifor you to check for an error after each call; you can make multiple
33262306a36Sopenharmony_cicalls in succession and only check at a convenient point.  The only
33362306a36Sopenharmony_cierrors currently generated by the XArray code itself are ``ENOMEM`` and
33462306a36Sopenharmony_ci``EINVAL``, but it supports arbitrary errors in case you want to call
33562306a36Sopenharmony_cixas_set_err() yourself.
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ciIf the xa_state is holding an ``ENOMEM`` error, calling xas_nomem()
33862306a36Sopenharmony_ciwill attempt to allocate more memory using the specified gfp flags and
33962306a36Sopenharmony_cicache it in the xa_state for the next attempt.  The idea is that you take
34062306a36Sopenharmony_cithe xa_lock, attempt the operation and drop the lock.  The operation
34162306a36Sopenharmony_ciattempts to allocate memory while holding the lock, but it is more
34262306a36Sopenharmony_cilikely to fail.  Once you have dropped the lock, xas_nomem()
34362306a36Sopenharmony_cican try harder to allocate more memory.  It will return ``true`` if it
34462306a36Sopenharmony_ciis worth retrying the operation (i.e. that there was a memory error *and*
34562306a36Sopenharmony_cimore memory was allocated).  If it has previously allocated memory, and
34662306a36Sopenharmony_cithat memory wasn't used, and there is no error (or some error that isn't
34762306a36Sopenharmony_ci``ENOMEM``), then it will free the memory previously allocated.
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ciInternal Entries
35062306a36Sopenharmony_ci----------------
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ciThe XArray reserves some entries for its own purposes.  These are never
35362306a36Sopenharmony_ciexposed through the normal API, but when using the advanced API, it's
35462306a36Sopenharmony_cipossible to see them.  Usually the best way to handle them is to pass them
35562306a36Sopenharmony_cito xas_retry(), and retry the operation if it returns ``true``.
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci.. flat-table::
35862306a36Sopenharmony_ci   :widths: 1 1 6
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci   * - Name
36162306a36Sopenharmony_ci     - Test
36262306a36Sopenharmony_ci     - Usage
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci   * - Node
36562306a36Sopenharmony_ci     - xa_is_node()
36662306a36Sopenharmony_ci     - An XArray node.  May be visible when using a multi-index xa_state.
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci   * - Sibling
36962306a36Sopenharmony_ci     - xa_is_sibling()
37062306a36Sopenharmony_ci     - A non-canonical entry for a multi-index entry.  The value indicates
37162306a36Sopenharmony_ci       which slot in this node has the canonical entry.
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci   * - Retry
37462306a36Sopenharmony_ci     - xa_is_retry()
37562306a36Sopenharmony_ci     - This entry is currently being modified by a thread which has the
37662306a36Sopenharmony_ci       xa_lock.  The node containing this entry may be freed at the end
37762306a36Sopenharmony_ci       of this RCU period.  You should restart the lookup from the head
37862306a36Sopenharmony_ci       of the array.
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci   * - Zero
38162306a36Sopenharmony_ci     - xa_is_zero()
38262306a36Sopenharmony_ci     - Zero entries appear as ``NULL`` through the Normal API, but occupy
38362306a36Sopenharmony_ci       an entry in the XArray which can be used to reserve the index for
38462306a36Sopenharmony_ci       future use.  This is used by allocating XArrays for allocated entries
38562306a36Sopenharmony_ci       which are ``NULL``.
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ciOther internal entries may be added in the future.  As far as possible, they
38862306a36Sopenharmony_ciwill be handled by xas_retry().
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ciAdditional functionality
39162306a36Sopenharmony_ci------------------------
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ciThe xas_create_range() function allocates all the necessary memory
39462306a36Sopenharmony_cito store every entry in a range.  It will set ENOMEM in the xa_state if
39562306a36Sopenharmony_ciit cannot allocate memory.
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ciYou can use xas_init_marks() to reset the marks on an entry
39862306a36Sopenharmony_cito their default state.  This is usually all marks clear, unless the
39962306a36Sopenharmony_ciXArray is marked with ``XA_FLAGS_TRACK_FREE``, in which case mark 0 is set
40062306a36Sopenharmony_ciand all other marks are clear.  Replacing one entry with another using
40162306a36Sopenharmony_cixas_store() will not reset the marks on that entry; if you want
40262306a36Sopenharmony_cithe marks reset, you should do that explicitly.
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ciThe xas_load() will walk the xa_state as close to the entry
40562306a36Sopenharmony_cias it can.  If you know the xa_state has already been walked to the
40662306a36Sopenharmony_cientry and need to check that the entry hasn't changed, you can use
40762306a36Sopenharmony_cixas_reload() to save a function call.
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ciIf you need to move to a different index in the XArray, call
41062306a36Sopenharmony_cixas_set().  This resets the cursor to the top of the tree, which
41162306a36Sopenharmony_ciwill generally make the next operation walk the cursor to the desired
41262306a36Sopenharmony_cispot in the tree.  If you want to move to the next or previous index,
41362306a36Sopenharmony_cicall xas_next() or xas_prev().  Setting the index does
41462306a36Sopenharmony_cinot walk the cursor around the array so does not require a lock to be
41562306a36Sopenharmony_ciheld, while moving to the next or previous index does.
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ciYou can search for the next present entry using xas_find().  This
41862306a36Sopenharmony_ciis the equivalent of both xa_find() and xa_find_after();
41962306a36Sopenharmony_ciif the cursor has been walked to an entry, then it will find the next
42062306a36Sopenharmony_cientry after the one currently referenced.  If not, it will return the
42162306a36Sopenharmony_cientry at the index of the xa_state.  Using xas_next_entry() to
42262306a36Sopenharmony_cimove to the next present entry instead of xas_find() will save
42362306a36Sopenharmony_cia function call in the majority of cases at the expense of emitting more
42462306a36Sopenharmony_ciinline code.
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ciThe xas_find_marked() function is similar.  If the xa_state has
42762306a36Sopenharmony_cinot been walked, it will return the entry at the index of the xa_state,
42862306a36Sopenharmony_ciif it is marked.  Otherwise, it will return the first marked entry after
42962306a36Sopenharmony_cithe entry referenced by the xa_state.  The xas_next_marked()
43062306a36Sopenharmony_cifunction is the equivalent of xas_next_entry().
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ciWhen iterating over a range of the XArray using xas_for_each()
43362306a36Sopenharmony_cior xas_for_each_marked(), it may be necessary to temporarily stop
43462306a36Sopenharmony_cithe iteration.  The xas_pause() function exists for this purpose.
43562306a36Sopenharmony_ciAfter you have done the necessary work and wish to resume, the xa_state
43662306a36Sopenharmony_ciis in an appropriate state to continue the iteration after the entry
43762306a36Sopenharmony_ciyou last processed.  If you have interrupts disabled while iterating,
43862306a36Sopenharmony_cithen it is good manners to pause the iteration and reenable interrupts
43962306a36Sopenharmony_cievery ``XA_CHECK_SCHED`` entries.
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ciThe xas_get_mark(), xas_set_mark() and xas_clear_mark() functions require
44262306a36Sopenharmony_cithe xa_state cursor to have been moved to the appropriate location in the
44362306a36Sopenharmony_ciXArray; they will do nothing if you have called xas_pause() or xas_set()
44462306a36Sopenharmony_ciimmediately before.
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ciYou can call xas_set_update() to have a callback function
44762306a36Sopenharmony_cicalled each time the XArray updates a node.  This is used by the page
44862306a36Sopenharmony_cicache workingset code to maintain its list of nodes which contain only
44962306a36Sopenharmony_cishadow entries.
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ciMulti-Index Entries
45262306a36Sopenharmony_ci-------------------
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ciThe XArray has the ability to tie multiple indices together so that
45562306a36Sopenharmony_cioperations on one index affect all indices.  For example, storing into
45662306a36Sopenharmony_ciany index will change the value of the entry retrieved from any index.
45762306a36Sopenharmony_ciSetting or clearing a mark on any index will set or clear the mark
45862306a36Sopenharmony_cion every index that is tied together.  The current implementation
45962306a36Sopenharmony_cionly allows tying ranges which are aligned powers of two together;
46062306a36Sopenharmony_cieg indices 64-127 may be tied together, but 2-6 may not be.  This may
46162306a36Sopenharmony_cisave substantial quantities of memory; for example tying 512 entries
46262306a36Sopenharmony_citogether will save over 4kB.
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ciYou can create a multi-index entry by using XA_STATE_ORDER()
46562306a36Sopenharmony_cior xas_set_order() followed by a call to xas_store().
46662306a36Sopenharmony_ciCalling xas_load() with a multi-index xa_state will walk the
46762306a36Sopenharmony_cixa_state to the right location in the tree, but the return value is not
46862306a36Sopenharmony_cimeaningful, potentially being an internal entry or ``NULL`` even when there
46962306a36Sopenharmony_ciis an entry stored within the range.  Calling xas_find_conflict()
47062306a36Sopenharmony_ciwill return the first entry within the range or ``NULL`` if there are no
47162306a36Sopenharmony_cientries in the range.  The xas_for_each_conflict() iterator will
47262306a36Sopenharmony_ciiterate over every entry which overlaps the specified range.
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ciIf xas_load() encounters a multi-index entry, the xa_index
47562306a36Sopenharmony_ciin the xa_state will not be changed.  When iterating over an XArray
47662306a36Sopenharmony_cior calling xas_find(), if the initial index is in the middle
47762306a36Sopenharmony_ciof a multi-index entry, it will not be altered.  Subsequent calls
47862306a36Sopenharmony_cior iterations will move the index to the first index in the range.
47962306a36Sopenharmony_ciEach entry will only be returned once, no matter how many indices it
48062306a36Sopenharmony_cioccupies.
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ciUsing xas_next() or xas_prev() with a multi-index xa_state is not
48362306a36Sopenharmony_cisupported.  Using either of these functions on a multi-index entry will
48462306a36Sopenharmony_cireveal sibling entries; these should be skipped over by the caller.
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ciStoring ``NULL`` into any index of a multi-index entry will set the
48762306a36Sopenharmony_cientry at every index to ``NULL`` and dissolve the tie.  A multi-index
48862306a36Sopenharmony_cientry can be split into entries occupying smaller ranges by calling
48962306a36Sopenharmony_cixas_split_alloc() without the xa_lock held, followed by taking the lock
49062306a36Sopenharmony_ciand calling xas_split().
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ciFunctions and structures
49362306a36Sopenharmony_ci========================
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci.. kernel-doc:: include/linux/xarray.h
49662306a36Sopenharmony_ci.. kernel-doc:: lib/xarray.c
497