Skip to content

Commit 00ed452

Browse files
author
Matthew Wilcox (Oracle)
committed
XArray: Add xa_for_each_range
This function supports iterating over a range of an array. Also add documentation links for xa_for_each_start(). Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
1 parent c44aa5e commit 00ed452

2 files changed

Lines changed: 38 additions & 9 deletions

File tree

Documentation/core-api/xarray.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ at that index is ``NULL``, you can use xa_insert() which
8282
returns ``-EBUSY`` if the entry is not empty.
8383

8484
You can copy entries out of the XArray into a plain array by calling
85-
xa_extract(). Or you can iterate over the present entries in
86-
the XArray by calling xa_for_each(). You may prefer to use
87-
xa_find() or xa_find_after() to move to the next present
88-
entry in the XArray.
85+
xa_extract(). Or you can iterate over the present entries in the XArray
86+
by calling xa_for_each(), xa_for_each_start() or xa_for_each_range().
87+
You may prefer to use xa_find() or xa_find_after() to move to the next
88+
present entry in the XArray.
8989

9090
Calling xa_store_range() stores the same entry in a range
9191
of indices. If you do this, some of the other operations will behave
@@ -193,6 +193,8 @@ No lock needed:
193193
Takes RCU read lock:
194194
* xa_load()
195195
* xa_for_each()
196+
* xa_for_each_start()
197+
* xa_for_each_range()
196198
* xa_find()
197199
* xa_find_after()
198200
* xa_extract()

include/linux/xarray.h

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,36 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark)
416416
return xa->xa_flags & XA_FLAGS_MARK(mark);
417417
}
418418

419+
/**
420+
* xa_for_each_range() - Iterate over a portion of an XArray.
421+
* @xa: XArray.
422+
* @index: Index of @entry.
423+
* @entry: Entry retrieved from array.
424+
* @start: First index to retrieve from array.
425+
* @last: Last index to retrieve from array.
426+
*
427+
* During the iteration, @entry will have the value of the entry stored
428+
* in @xa at @index. You may modify @index during the iteration if you
429+
* want to skip or reprocess indices. It is safe to modify the array
430+
* during the iteration. At the end of the iteration, @entry will be set
431+
* to NULL and @index will have a value less than or equal to max.
432+
*
433+
* xa_for_each_range() is O(n.log(n)) while xas_for_each() is O(n). You have
434+
* to handle your own locking with xas_for_each(), and if you have to unlock
435+
* after each iteration, it will also end up being O(n.log(n)).
436+
* xa_for_each_range() will spin if it hits a retry entry; if you intend to
437+
* see retry entries, you should use the xas_for_each() iterator instead.
438+
* The xas_for_each() iterator will expand into more inline code than
439+
* xa_for_each_range().
440+
*
441+
* Context: Any context. Takes and releases the RCU lock.
442+
*/
443+
#define xa_for_each_range(xa, index, entry, start, last) \
444+
for (index = start, \
445+
entry = xa_find(xa, &index, last, XA_PRESENT); \
446+
entry; \
447+
entry = xa_find_after(xa, &index, last, XA_PRESENT))
448+
419449
/**
420450
* xa_for_each_start() - Iterate over a portion of an XArray.
421451
* @xa: XArray.
@@ -439,11 +469,8 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark)
439469
*
440470
* Context: Any context. Takes and releases the RCU lock.
441471
*/
442-
#define xa_for_each_start(xa, index, entry, start) \
443-
for (index = start, \
444-
entry = xa_find(xa, &index, ULONG_MAX, XA_PRESENT); \
445-
entry; \
446-
entry = xa_find_after(xa, &index, ULONG_MAX, XA_PRESENT))
472+
#define xa_for_each_start(xa, index, entry, start) \
473+
xa_for_each_range(xa, index, entry, start, ULONG_MAX)
447474

448475
/**
449476
* xa_for_each() - Iterate over present entries in an XArray.

0 commit comments

Comments
 (0)