aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/core-api/xarray.rst15
-rw-r--r--include/linux/xarray.h227
-rw-r--r--lib/test_xarray.c57
-rw-r--r--lib/xarray.c92
4 files changed, 278 insertions, 113 deletions
diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst
index 6a6d67acaf69..5d54b27c6eba 100644
--- a/Documentation/core-api/xarray.rst
+++ b/Documentation/core-api/xarray.rst
@@ -108,12 +108,13 @@ some, but not all of the other indices changing.
108 108
109Sometimes you need to ensure that a subsequent call to :c:func:`xa_store` 109Sometimes you need to ensure that a subsequent call to :c:func:`xa_store`
110will not need to allocate memory. The :c:func:`xa_reserve` function 110will not need to allocate memory. The :c:func:`xa_reserve` function
111will store a reserved entry at the indicated index. Users of the normal 111will store a reserved entry at the indicated index. Users of the
112API will see this entry as containing ``NULL``. If you do not need to 112normal API will see this entry as containing ``NULL``. If you do
113use the reserved entry, you can call :c:func:`xa_release` to remove the 113not need to use the reserved entry, you can call :c:func:`xa_release`
114unused entry. If another user has stored to the entry in the meantime, 114to remove the unused entry. If another user has stored to the entry
115:c:func:`xa_release` will do nothing; if instead you want the entry to 115in the meantime, :c:func:`xa_release` will do nothing; if instead you
116become ``NULL``, you should use :c:func:`xa_erase`. 116want the entry to become ``NULL``, you should use :c:func:`xa_erase`.
117Using :c:func:`xa_insert` on a reserved entry will fail.
117 118
118If all entries in the array are ``NULL``, the :c:func:`xa_empty` function 119If all entries in the array are ``NULL``, the :c:func:`xa_empty` function
119will return ``true``. 120will return ``true``.
@@ -183,6 +184,8 @@ Takes xa_lock internally:
183 * :c:func:`xa_store_bh` 184 * :c:func:`xa_store_bh`
184 * :c:func:`xa_store_irq` 185 * :c:func:`xa_store_irq`
185 * :c:func:`xa_insert` 186 * :c:func:`xa_insert`
187 * :c:func:`xa_insert_bh`
188 * :c:func:`xa_insert_irq`
186 * :c:func:`xa_erase` 189 * :c:func:`xa_erase`
187 * :c:func:`xa_erase_bh` 190 * :c:func:`xa_erase_bh`
188 * :c:func:`xa_erase_irq` 191 * :c:func:`xa_erase_irq`
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index f492e21c4aa2..5d9d318bcf7a 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -176,7 +176,8 @@ static inline bool xa_is_internal(const void *entry)
176 */ 176 */
177static inline bool xa_is_err(const void *entry) 177static inline bool xa_is_err(const void *entry)
178{ 178{
179 return unlikely(xa_is_internal(entry)); 179 return unlikely(xa_is_internal(entry) &&
180 entry >= xa_mk_internal(-MAX_ERRNO));
180} 181}
181 182
182/** 183/**
@@ -286,7 +287,6 @@ struct xarray {
286 */ 287 */
287#define DEFINE_XARRAY_ALLOC(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC) 288#define DEFINE_XARRAY_ALLOC(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC)
288 289
289void xa_init_flags(struct xarray *, gfp_t flags);
290void *xa_load(struct xarray *, unsigned long index); 290void *xa_load(struct xarray *, unsigned long index);
291void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); 291void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t);
292void *xa_erase(struct xarray *, unsigned long index); 292void *xa_erase(struct xarray *, unsigned long index);
@@ -304,6 +304,24 @@ unsigned int xa_extract(struct xarray *, void **dst, unsigned long start,
304void xa_destroy(struct xarray *); 304void xa_destroy(struct xarray *);
305 305
306/** 306/**
307 * xa_init_flags() - Initialise an empty XArray with flags.
308 * @xa: XArray.
309 * @flags: XA_FLAG values.
310 *
311 * If you need to initialise an XArray with special flags (eg you need
312 * to take the lock from interrupt context), use this function instead
313 * of xa_init().
314 *
315 * Context: Any context.
316 */
317static inline void xa_init_flags(struct xarray *xa, gfp_t flags)
318{
319 spin_lock_init(&xa->xa_lock);
320 xa->xa_flags = flags;
321 xa->xa_head = NULL;
322}
323
324/**
307 * xa_init() - Initialise an empty XArray. 325 * xa_init() - Initialise an empty XArray.
308 * @xa: XArray. 326 * @xa: XArray.
309 * 327 *
@@ -342,20 +360,45 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark)
342} 360}
343 361
344/** 362/**
345 * xa_for_each() - Iterate over a portion of an XArray. 363 * xa_for_each_start() - Iterate over a portion of an XArray.
346 * @xa: XArray. 364 * @xa: XArray.
365 * @index: Index of @entry.
347 * @entry: Entry retrieved from array. 366 * @entry: Entry retrieved from array.
367 * @start: First index to retrieve from array.
368 *
369 * During the iteration, @entry will have the value of the entry stored
370 * in @xa at @index. You may modify @index during the iteration if you
371 * want to skip or reprocess indices. It is safe to modify the array
372 * during the iteration. At the end of the iteration, @entry will be set
373 * to NULL and @index will have a value less than or equal to max.
374 *
375 * xa_for_each_start() is O(n.log(n)) while xas_for_each() is O(n). You have
376 * to handle your own locking with xas_for_each(), and if you have to unlock
377 * after each iteration, it will also end up being O(n.log(n)).
378 * xa_for_each_start() will spin if it hits a retry entry; if you intend to
379 * see retry entries, you should use the xas_for_each() iterator instead.
380 * The xas_for_each() iterator will expand into more inline code than
381 * xa_for_each_start().
382 *
383 * Context: Any context. Takes and releases the RCU lock.
384 */
385#define xa_for_each_start(xa, index, entry, start) \
386 for (index = start, \
387 entry = xa_find(xa, &index, ULONG_MAX, XA_PRESENT); \
388 entry; \
389 entry = xa_find_after(xa, &index, ULONG_MAX, XA_PRESENT))
390
391/**
392 * xa_for_each() - Iterate over present entries in an XArray.
393 * @xa: XArray.
348 * @index: Index of @entry. 394 * @index: Index of @entry.
349 * @max: Maximum index to retrieve from array. 395 * @entry: Entry retrieved from array.
350 * @filter: Selection criterion.
351 * 396 *
352 * Initialise @index to the lowest index you want to retrieve from the 397 * During the iteration, @entry will have the value of the entry stored
353 * array. During the iteration, @entry will have the value of the entry 398 * in @xa at @index. You may modify @index during the iteration if you want
354 * stored in @xa at @index. The iteration will skip all entries in the 399 * to skip or reprocess indices. It is safe to modify the array during the
355 * array which do not match @filter. You may modify @index during the 400 * iteration. At the end of the iteration, @entry will be set to NULL and
356 * iteration if you want to skip or reprocess indices. It is safe to modify 401 * @index will have a value less than or equal to max.
357 * the array during the iteration. At the end of the iteration, @entry will
358 * be set to NULL and @index will have a value less than or equal to max.
359 * 402 *
360 * xa_for_each() is O(n.log(n)) while xas_for_each() is O(n). You have 403 * xa_for_each() is O(n.log(n)) while xas_for_each() is O(n). You have
361 * to handle your own locking with xas_for_each(), and if you have to unlock 404 * to handle your own locking with xas_for_each(), and if you have to unlock
@@ -366,9 +409,36 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark)
366 * 409 *
367 * Context: Any context. Takes and releases the RCU lock. 410 * Context: Any context. Takes and releases the RCU lock.
368 */ 411 */
369#define xa_for_each(xa, entry, index, max, filter) \ 412#define xa_for_each(xa, index, entry) \
370 for (entry = xa_find(xa, &index, max, filter); entry; \ 413 xa_for_each_start(xa, index, entry, 0)
371 entry = xa_find_after(xa, &index, max, filter)) 414
415/**
416 * xa_for_each_marked() - Iterate over marked entries in an XArray.
417 * @xa: XArray.
418 * @index: Index of @entry.
419 * @entry: Entry retrieved from array.
420 * @filter: Selection criterion.
421 *
422 * During the iteration, @entry will have the value of the entry stored
423 * in @xa at @index. The iteration will skip all entries in the array
424 * which do not match @filter. You may modify @index during the iteration
425 * if you want to skip or reprocess indices. It is safe to modify the array
426 * during the iteration. At the end of the iteration, @entry will be set to
427 * NULL and @index will have a value less than or equal to max.
428 *
429 * xa_for_each_marked() is O(n.log(n)) while xas_for_each_marked() is O(n).
430 * You have to handle your own locking with xas_for_each(), and if you have
431 * to unlock after each iteration, it will also end up being O(n.log(n)).
432 * xa_for_each_marked() will spin if it hits a retry entry; if you intend to
433 * see retry entries, you should use the xas_for_each_marked() iterator
434 * instead. The xas_for_each_marked() iterator will expand into more inline
435 * code than xa_for_each_marked().
436 *
437 * Context: Any context. Takes and releases the RCU lock.
438 */
439#define xa_for_each_marked(xa, index, entry, filter) \
440 for (index = 0, entry = xa_find(xa, &index, ULONG_MAX, filter); \
441 entry; entry = xa_find_after(xa, &index, ULONG_MAX, filter))
372 442
373#define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) 443#define xa_trylock(xa) spin_trylock(&(xa)->xa_lock)
374#define xa_lock(xa) spin_lock(&(xa)->xa_lock) 444#define xa_lock(xa) spin_lock(&(xa)->xa_lock)
@@ -393,40 +463,13 @@ void *__xa_erase(struct xarray *, unsigned long index);
393void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); 463void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t);
394void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, 464void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old,
395 void *entry, gfp_t); 465 void *entry, gfp_t);
466int __xa_insert(struct xarray *, unsigned long index, void *entry, gfp_t);
396int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); 467int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t);
397int __xa_reserve(struct xarray *, unsigned long index, gfp_t); 468int __xa_reserve(struct xarray *, unsigned long index, gfp_t);
398void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); 469void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t);
399void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); 470void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t);
400 471
401/** 472/**
402 * __xa_insert() - Store this entry in the XArray unless another entry is
403 * already present.
404 * @xa: XArray.
405 * @index: Index into array.