From: wuchi Date: Sun, 5 Jun 2022 14:58:35 +0000 (+0800) Subject: lib/sbitmap: Fix invalid loop in __sbitmap_queue_get_batch() X-Git-Tag: baikal/mips/sdk6.1~5392^2~1 X-Git-Url: https://git.baikalelectronics.ru/sdk/?a=commitdiff_plain;h=726f7142eca1a8c8760aeb291eb633821320c719;p=kernel.git 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 Reviewed-by: Martin Wilck Link: https://lore.kernel.org/r/20220605145835.26916-1-wuchi.zero@gmail.com Fixes: 1deeb5d73a89 ("sbitmap: add __sbitmap_queue_get_batch()") Signed-off-by: Jens Axboe --- diff --git a/lib/sbitmap.c b/lib/sbitmap.c index ae4fd4de9ebe7..29eb0484215af 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -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;