Skip to content

Commit

Permalink
lib/sbitmap: Fix invalid loop in __sbitmap_queue_get_batch()
Browse files Browse the repository at this point in the history
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: wuchi <wuchi.zero@gmail.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
Link: https://lore.kernel.org/r/20220605145835.26916-1-wuchi.zero@gmail.com
Fixes: 9672b0d ("sbitmap: add __sbitmap_queue_get_batch()")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
wuchi authored and Jens Axboe committed Jun 25, 2022
1 parent e531485 commit fbb564a
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/sbitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit fbb564a

Please sign in to comment.