diff options
Diffstat (limited to 'Documentation/core-api')
-rw-r--r-- | Documentation/core-api/xarray.rst | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst index a4e705108f42..dbe96cb5558e 100644 --- a/Documentation/core-api/xarray.rst +++ b/Documentation/core-api/xarray.rst | |||
@@ -74,7 +74,8 @@ 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 | 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 | 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 | 76 | ``NULL`` entry. There is no difference between an entry that has never |
77 | been stored to and one that has most recently had ``NULL`` stored to it. | 77 | been stored to, one that has been erased and one that has most recently |
78 | had ``NULL`` stored to it. | ||
78 | 79 | ||
79 | You can conditionally replace an entry at an index by using | 80 | You can conditionally replace an entry at an index by using |
80 | :c:func:`xa_cmpxchg`. Like :c:func:`cmpxchg`, it will only succeed if | 81 | :c:func:`xa_cmpxchg`. Like :c:func:`cmpxchg`, it will only succeed if |
@@ -105,23 +106,44 @@ may result in the entry being marked at some, but not all of the other | |||
105 | indices. Storing into one index may result in the entry retrieved by | 106 | indices. Storing into one index may result in the entry retrieved by |
106 | some, but not all of the other indices changing. | 107 | some, but not all of the other indices changing. |
107 | 108 | ||
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 | |||
118 | If all entries in the array are ``NULL``, the :c:func:`xa_empty` function | ||
119 | will return ``true``. | ||
120 | |||
108 | Finally, you can remove all entries from an XArray by calling | 121 | Finally, you can remove all entries from an XArray by calling |
109 | :c:func:`xa_destroy`. If the XArray entries are pointers, you may wish | 122 | :c:func:`xa_destroy`. If the XArray entries are pointers, you may wish |
110 | to free the entries first. You can do this by iterating over all present | 123 | to free the entries first. You can do this by iterating over all present |
111 | entries in the XArray using the :c:func:`xa_for_each` iterator. | 124 | entries in the XArray using the :c:func:`xa_for_each` iterator. |
112 | 125 | ||
113 | ID assignment | 126 | Allocating XArrays |
114 | ------------- | 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. | ||
115 | 132 | ||
116 | You can call :c:func:`xa_alloc` to store the entry at any unused index | 133 | You can call :c:func:`xa_alloc` to store the entry at any unused index |
117 | in the XArray. If you need to modify the array from interrupt context, | 134 | in the XArray. If you need to modify the array from interrupt context, |
118 | you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable | 135 | you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable |
119 | interrupts while allocating the ID. Unlike :c:func:`xa_store`, allocating | 136 | interrupts while allocating the ID. |
120 | a ``NULL`` pointer does not delete an entry. Instead it reserves an | 137 | |
121 | entry like :c:func:`xa_reserve` and you can release it using either | 138 | Using :c:func:`xa_store`, :c:func:`xa_cmpxchg` or :c:func:`xa_insert` |
122 | :c:func:`xa_erase` or :c:func:`xa_release`. To use ID assignment, the | 139 | will mark the entry as being allocated. Unlike a normal XArray, storing |
123 | XArray must be defined with :c:func:`DEFINE_XARRAY_ALLOC`, or initialised | 140 | ``NULL`` will mark the entry as being in use, like :c:func:`xa_reserve`. |
124 | by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`, | 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. | ||
125 | 147 | ||
126 | Memory allocation | 148 | Memory allocation |
127 | ----------------- | 149 | ----------------- |
@@ -158,6 +180,8 @@ Takes RCU read lock: | |||
158 | 180 | ||
159 | Takes xa_lock internally: | 181 | Takes xa_lock internally: |
160 | * :c:func:`xa_store` | 182 | * :c:func:`xa_store` |
183 | * :c:func:`xa_store_bh` | ||
184 | * :c:func:`xa_store_irq` | ||
161 | * :c:func:`xa_insert` | 185 | * :c:func:`xa_insert` |
162 | * :c:func:`xa_erase` | 186 | * :c:func:`xa_erase` |
163 | * :c:func:`xa_erase_bh` | 187 | * :c:func:`xa_erase_bh` |
@@ -167,6 +191,9 @@ Takes xa_lock internally: | |||
167 | * :c:func:`xa_alloc` | 191 | * :c:func:`xa_alloc` |
168 | * :c:func:`xa_alloc_bh` | 192 | * :c:func:`xa_alloc_bh` |
169 | * :c:func:`xa_alloc_irq` | 193 | * :c:func:`xa_alloc_irq` |
194 | * :c:func:`xa_reserve` | ||
195 | * :c:func:`xa_reserve_bh` | ||
196 | * :c:func:`xa_reserve_irq` | ||
170 | * :c:func:`xa_destroy` | 197 | * :c:func:`xa_destroy` |
171 | * :c:func:`xa_set_mark` | 198 | * :c:func:`xa_set_mark` |
172 | * :c:func:`xa_clear_mark` | 199 | * :c:func:`xa_clear_mark` |
@@ -177,6 +204,7 @@ Assumes xa_lock held on entry: | |||
177 | * :c:func:`__xa_erase` | 204 | * :c:func:`__xa_erase` |
178 | * :c:func:`__xa_cmpxchg` | 205 | * :c:func:`__xa_cmpxchg` |
179 | * :c:func:`__xa_alloc` | 206 | * :c:func:`__xa_alloc` |
207 | * :c:func:`__xa_reserve` | ||
180 | * :c:func:`__xa_set_mark` | 208 | * :c:func:`__xa_set_mark` |
181 | * :c:func:`__xa_clear_mark` | 209 | * :c:func:`__xa_clear_mark` |
182 | 210 | ||
@@ -234,7 +262,8 @@ Sharing the XArray with interrupt context is also possible, either | |||
234 | using :c:func:`xa_lock_irqsave` in both the interrupt handler and process | 262 | using :c:func:`xa_lock_irqsave` in both the interrupt handler and process |
235 | context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock` | 263 | context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock` |
236 | in the interrupt handler. Some of the more common patterns have helper | 264 | in the interrupt handler. Some of the more common patterns have helper |
237 | functions such as :c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`. | 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`. | ||
238 | 267 | ||
239 | Sometimes you need to protect access to the XArray with a mutex because | 268 | Sometimes you need to protect access to the XArray with a mutex because |
240 | that lock sits above another mutex in the locking hierarchy. That does | 269 | that lock sits above another mutex in the locking hierarchy. That does |
@@ -322,7 +351,8 @@ to :c:func:`xas_retry`, and retry the operation if it returns ``true``. | |||
322 | - :c:func:`xa_is_zero` | 351 | - :c:func:`xa_is_zero` |
323 | - Zero entries appear as ``NULL`` through the Normal API, but occupy | 352 | - Zero entries appear as ``NULL`` through the Normal API, but occupy |
324 | an entry in the XArray which can be used to reserve the index for | 353 | an entry in the XArray which can be used to reserve the index for |
325 | future use. | 354 | future use. This is used by allocating XArrays for allocated entries |
355 | which are ``NULL``. | ||
326 | 356 | ||
327 | Other internal entries may be added in the future. As far as possible, they | 357 | Other internal entries may be added in the future. As far as possible, they |
328 | will be handled by :c:func:`xas_retry`. | 358 | will be handled by :c:func:`xas_retry`. |