@@ -280,6 +280,10 @@ void *xa_cmpxchg(struct xarray *, unsigned long index,
280
280
bool xa_get_mark (struct xarray * , unsigned long index , xa_mark_t );
281
281
void xa_set_mark (struct xarray * , unsigned long index , xa_mark_t );
282
282
void xa_clear_mark (struct xarray * , unsigned long index , xa_mark_t );
283
+ void * xa_find (struct xarray * xa , unsigned long * index ,
284
+ unsigned long max , xa_mark_t ) __attribute__((nonnull (2 )));
285
+ void * xa_find_after (struct xarray * xa , unsigned long * index ,
286
+ unsigned long max , xa_mark_t ) __attribute__((nonnull (2 )));
283
287
284
288
/**
285
289
* xa_init() - Initialise an empty XArray.
@@ -364,6 +368,35 @@ static inline int xa_insert(struct xarray *xa, unsigned long index,
364
368
return - EEXIST ;
365
369
}
366
370
371
+ /**
372
+ * xa_for_each() - Iterate over a portion of an XArray.
373
+ * @xa: XArray.
374
+ * @entry: Entry retrieved from array.
375
+ * @index: Index of @entry.
376
+ * @max: Maximum index to retrieve from array.
377
+ * @filter: Selection criterion.
378
+ *
379
+ * Initialise @index to the lowest index you want to retrieve from the
380
+ * array. During the iteration, @entry will have the value of the entry
381
+ * stored in @xa at @index. The iteration will skip all entries in the
382
+ * array which do not match @filter. You may modify @index during the
383
+ * iteration if you want to skip or reprocess indices. It is safe to modify
384
+ * the array during the iteration. At the end of the iteration, @entry will
385
+ * be set to NULL and @index will have a value less than or equal to max.
386
+ *
387
+ * xa_for_each() is O(n.log(n)) while xas_for_each() is O(n). You have
388
+ * to handle your own locking with xas_for_each(), and if you have to unlock
389
+ * after each iteration, it will also end up being O(n.log(n)). xa_for_each()
390
+ * will spin if it hits a retry entry; if you intend to see retry entries,
391
+ * you should use the xas_for_each() iterator instead. The xas_for_each()
392
+ * iterator will expand into more inline code than xa_for_each().
393
+ *
394
+ * Context: Any context. Takes and releases the RCU lock.
395
+ */
396
+ #define xa_for_each (xa , entry , index , max , filter ) \
397
+ for (entry = xa_find(xa, &index, max, filter); entry; \
398
+ entry = xa_find_after(xa, &index, max, filter))
399
+
367
400
#define xa_trylock (xa ) spin_trylock(&(xa)->xa_lock)
368
401
#define xa_lock (xa ) spin_lock(&(xa)->xa_lock)
369
402
#define xa_unlock (xa ) spin_unlock(&(xa)->xa_lock)
@@ -835,13 +868,16 @@ static inline bool xas_retry(struct xa_state *xas, const void *entry)
835
868
836
869
void * xas_load (struct xa_state * );
837
870
void * xas_store (struct xa_state * , void * entry );
871
+ void * xas_find (struct xa_state * , unsigned long max );
838
872
839
873
bool xas_get_mark (const struct xa_state * , xa_mark_t );
840
874
void xas_set_mark (const struct xa_state * , xa_mark_t );
841
875
void xas_clear_mark (const struct xa_state * , xa_mark_t );
876
+ void * xas_find_marked (struct xa_state * , unsigned long max , xa_mark_t );
842
877
void xas_init_marks (const struct xa_state * );
843
878
844
879
bool xas_nomem (struct xa_state * , gfp_t );
880
+ void xas_pause (struct xa_state * );
845
881
846
882
/**
847
883
* xas_reload() - Refetch an entry from the xarray.
@@ -914,4 +950,133 @@ static inline void xas_set_update(struct xa_state *xas, xa_update_node_t update)
914
950
xas -> xa_update = update ;
915
951
}
916
952
953
+ /**
954
+ * xas_next_entry() - Advance iterator to next present entry.
955
+ * @xas: XArray operation state.
956
+ * @max: Highest index to return.
957
+ *
958
+ * xas_next_entry() is an inline function to optimise xarray traversal for
959
+ * speed. It is equivalent to calling xas_find(), and will call xas_find()
960
+ * for all the hard cases.
961
+ *
962
+ * Return: The next present entry after the one currently referred to by @xas.
963
+ */
964
+ static inline void * xas_next_entry (struct xa_state * xas , unsigned long max )
965
+ {
966
+ struct xa_node * node = xas -> xa_node ;
967
+ void * entry ;
968
+
969
+ if (unlikely (xas_not_node (node ) || node -> shift ||
970
+ xas -> xa_offset != (xas -> xa_index & XA_CHUNK_MASK )))
971
+ return xas_find (xas , max );
972
+
973
+ do {
974
+ if (unlikely (xas -> xa_index >= max ))
975
+ return xas_find (xas , max );
976
+ if (unlikely (xas -> xa_offset == XA_CHUNK_MASK ))
977
+ return xas_find (xas , max );
978
+ entry = xa_entry (xas -> xa , node , xas -> xa_offset + 1 );
979
+ if (unlikely (xa_is_internal (entry )))
980
+ return xas_find (xas , max );
981
+ xas -> xa_offset ++ ;
982
+ xas -> xa_index ++ ;
983
+ } while (!entry );
984
+
985
+ return entry ;
986
+ }
987
+
988
+ /* Private */
989
+ static inline unsigned int xas_find_chunk (struct xa_state * xas , bool advance ,
990
+ xa_mark_t mark )
991
+ {
992
+ unsigned long * addr = xas -> xa_node -> marks [(__force unsigned )mark ];
993
+ unsigned int offset = xas -> xa_offset ;
994
+
995
+ if (advance )
996
+ offset ++ ;
997
+ if (XA_CHUNK_SIZE == BITS_PER_LONG ) {
998
+ if (offset < XA_CHUNK_SIZE ) {
999
+ unsigned long data = * addr & (~0UL << offset );
1000
+ if (data )
1001
+ return __ffs (data );
1002
+ }
1003
+ return XA_CHUNK_SIZE ;
1004
+ }
1005
+
1006
+ return find_next_bit (addr , XA_CHUNK_SIZE , offset );
1007
+ }
1008
+
1009
+ /**
1010
+ * xas_next_marked() - Advance iterator to next marked entry.
1011
+ * @xas: XArray operation state.
1012
+ * @max: Highest index to return.
1013
+ * @mark: Mark to search for.
1014
+ *
1015
+ * xas_next_marked() is an inline function to optimise xarray traversal for
1016
+ * speed. It is equivalent to calling xas_find_marked(), and will call
1017
+ * xas_find_marked() for all the hard cases.
1018
+ *
1019
+ * Return: The next marked entry after the one currently referred to by @xas.
1020
+ */
1021
+ static inline void * xas_next_marked (struct xa_state * xas , unsigned long max ,
1022
+ xa_mark_t mark )
1023
+ {
1024
+ struct xa_node * node = xas -> xa_node ;
1025
+ unsigned int offset ;
1026
+
1027
+ if (unlikely (xas_not_node (node ) || node -> shift ))
1028
+ return xas_find_marked (xas , max , mark );
1029
+ offset = xas_find_chunk (xas , true, mark );
1030
+ xas -> xa_offset = offset ;
1031
+ xas -> xa_index = (xas -> xa_index & ~XA_CHUNK_MASK ) + offset ;
1032
+ if (xas -> xa_index > max )
1033
+ return NULL ;
1034
+ if (offset == XA_CHUNK_SIZE )
1035
+ return xas_find_marked (xas , max , mark );
1036
+ return xa_entry (xas -> xa , node , offset );
1037
+ }
1038
+
1039
+ /*
1040
+ * If iterating while holding a lock, drop the lock and reschedule
1041
+ * every %XA_CHECK_SCHED loops.
1042
+ */
1043
+ enum {
1044
+ XA_CHECK_SCHED = 4096 ,
1045
+ };
1046
+
1047
+ /**
1048
+ * xas_for_each() - Iterate over a range of an XArray.
1049
+ * @xas: XArray operation state.
1050
+ * @entry: Entry retrieved from the array.
1051
+ * @max: Maximum index to retrieve from array.
1052
+ *
1053
+ * The loop body will be executed for each entry present in the xarray
1054
+ * between the current xas position and @max. @entry will be set to
1055
+ * the entry retrieved from the xarray. It is safe to delete entries
1056
+ * from the array in the loop body. You should hold either the RCU lock
1057
+ * or the xa_lock while iterating. If you need to drop the lock, call
1058
+ * xas_pause() first.
1059
+ */
1060
+ #define xas_for_each (xas , entry , max ) \
1061
+ for (entry = xas_find(xas, max); entry; \
1062
+ entry = xas_next_entry(xas, max))
1063
+
1064
+ /**
1065
+ * xas_for_each_marked() - Iterate over a range of an XArray.
1066
+ * @xas: XArray operation state.
1067
+ * @entry: Entry retrieved from the array.
1068
+ * @max: Maximum index to retrieve from array.
1069
+ * @mark: Mark to search for.
1070
+ *
1071
+ * The loop body will be executed for each marked entry in the xarray
1072
+ * between the current xas position and @max. @entry will be set to
1073
+ * the entry retrieved from the xarray. It is safe to delete entries
1074
+ * from the array in the loop body. You should hold either the RCU lock
1075
+ * or the xa_lock while iterating. If you need to drop the lock, call
1076
+ * xas_pause() first.
1077
+ */
1078
+ #define xas_for_each_marked (xas , entry , max , mark ) \
1079
+ for (entry = xas_find_marked(xas, max, mark); entry; \
1080
+ entry = xas_next_marked(xas, max, mark))
1081
+
917
1082
#endif /* _LINUX_XARRAY_H */
0 commit comments