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