mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
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: 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: 9672b0d437
("sbitmap: add __sbitmap_queue_get_batch()")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
e531485a0a
commit
fbb564a557
1 changed files with 4 additions and 1 deletions
|
@ -528,7 +528,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,
|
||||||
|
|
||||||
sbitmap_deferred_clear(map);
|
sbitmap_deferred_clear(map);
|
||||||
if (map->word == (1UL << (map_depth - 1)) - 1)
|
if (map->word == (1UL << (map_depth - 1)) - 1)
|
||||||
continue;
|
goto next;
|
||||||
|
|
||||||
nr = find_first_zero_bit(&map->word, map_depth);
|
nr = find_first_zero_bit(&map->word, map_depth);
|
||||||
if (nr + nr_tags <= 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;
|
get_mask = ((1UL << map_tags) - 1) << nr;
|
||||||
do {
|
do {
|
||||||
val = READ_ONCE(map->word);
|
val = READ_ONCE(map->word);
|
||||||
|
if ((val & ~get_mask) != val)
|
||||||
|
goto next;
|
||||||
ret = atomic_long_cmpxchg(ptr, val, get_mask | val);
|
ret = atomic_long_cmpxchg(ptr, val, get_mask | val);
|
||||||
} while (ret != val);
|
} while (ret != val);
|
||||||
get_mask = (get_mask & ~ret) >> nr;
|
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;
|
return get_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next:
|
||||||
/* Jump to next index. */
|
/* Jump to next index. */
|
||||||
if (++index >= sb->map_nr)
|
if (++index >= sb->map_nr)
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue