Commit fbb564a5 authored by wuchi's avatar wuchi Committed by Jens Axboe
Browse files

lib/sbitmap: Fix invalid loop in __sbitmap_queue_get_batch()



1. Getting next index before continue branch.
2. Checking free bits when setting the target bits. Otherwise,
it may reuse the busying bits.

Signed-off-by: default avatarwuchi <wuchi.zero@gmail.com>
Reviewed-by: default avatarMartin Wilck <mwilck@suse.com>
Link: https://lore.kernel.org/r/20220605145835.26916-1-wuchi.zero@gmail.com


Fixes: 9672b0d4 ("sbitmap: add __sbitmap_queue_get_batch()")
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent e531485a
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -528,7 +528,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,

		sbitmap_deferred_clear(map);
		if (map->word == (1UL << (map_depth - 1)) - 1)
			continue;
			goto next;

		nr = find_first_zero_bit(&map->word, map_depth);
		if (nr + nr_tags <= map_depth) {
@@ -539,6 +539,8 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,
			get_mask = ((1UL << map_tags) - 1) << nr;
			do {
				val = READ_ONCE(map->word);
				if ((val & ~get_mask) != val)
					goto next;
				ret = atomic_long_cmpxchg(ptr, val, get_mask | val);
			} while (ret != val);
			get_mask = (get_mask & ~ret) >> nr;
@@ -549,6 +551,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,
				return get_mask;
			}
		}
next:
		/* Jump to next index. */
		if (++index >= sb->map_nr)
			index = 0;