Commit 8c2def89 authored by Omar Sandoval's avatar Omar Sandoval Committed by Jens Axboe

sbitmap: fix sbitmap_for_each_set()

We need to ignore bits in the cleared mask when iterating over all set
bits.

Fixes: ea86ea2c ("sbitmap: ammortize cost of clearing bits")
Reported-by: Jens Axboe@kernel.dk>
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent fe1f4526
...@@ -265,12 +265,14 @@ static inline void __sbitmap_for_each_set(struct sbitmap *sb, ...@@ -265,12 +265,14 @@ static inline void __sbitmap_for_each_set(struct sbitmap *sb,
nr = SB_NR_TO_BIT(sb, start); nr = SB_NR_TO_BIT(sb, start);
while (scanned < sb->depth) { while (scanned < sb->depth) {
struct sbitmap_word *word = &sb->map[index]; unsigned long word;
unsigned int depth = min_t(unsigned int, word->depth - nr, unsigned int depth = min_t(unsigned int,
sb->map[index].depth - nr,
sb->depth - scanned); sb->depth - scanned);
scanned += depth; scanned += depth;
if (!word->word) word = sb->map[index].word & ~sb->map[index].cleared;
if (!word)
goto next; goto next;
/* /*
...@@ -280,7 +282,7 @@ static inline void __sbitmap_for_each_set(struct sbitmap *sb, ...@@ -280,7 +282,7 @@ static inline void __sbitmap_for_each_set(struct sbitmap *sb,
*/ */
depth += nr; depth += nr;
while (1) { while (1) {
nr = find_next_bit(&word->word, depth, nr); nr = find_next_bit(&word, depth, nr);
if (nr >= depth) if (nr >= depth)
break; break;
if (!fn(sb, (index << sb->shift) + nr, data)) if (!fn(sb, (index << sb->shift) + nr, data))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment