Skip to content

Commit

Permalink
bitmap: relax find_nth_bit() limitation on return value
Browse files Browse the repository at this point in the history
The function claims to return the bitmap size, if Nth bit doesn't exist.
This rule is violated in inline case because the fns() that is used
there doesn't know anything about size of the bitmap.

So, relax this requirement to '>= size', and make the outline
implementation a bit cheaper.

All in-tree kernel users of find_nth_bit() are safe against that.

Reported-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Closes: https://lore.kernel.org/all/Zi50cAgR8nZvgLa3@yury-ThinkPad/T/#m6da806a0525e74dcc91f35e5f20766ed4e853e8a
Signed-off-by: Yury Norov <yury.norov@gmail.com>
  • Loading branch information
Yury Norov committed May 9, 2024
1 parent 77db192 commit 0b2811b
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 4 deletions.
2 changes: 1 addition & 1 deletion include/linux/find.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
* idx = find_first_bit(addr, size);
*
* Returns the bit number of the N'th set bit.
* If no such, returns @size.
* If no such, returns >= @size.
*/
static inline
unsigned long find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n)
Expand Down
2 changes: 1 addition & 1 deletion lib/find_bit.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ out: \
if (sz % BITS_PER_LONG) \
tmp = (FETCH) & BITMAP_LAST_WORD_MASK(sz); \
found: \
sz = min(idx * BITS_PER_LONG + fns(tmp, nr), sz); \
sz = idx * BITS_PER_LONG + fns(tmp, nr); \
out: \
sz; \
})
Expand Down
4 changes: 2 additions & 2 deletions lib/test_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ static void __init test_find_nth_bit(void)
expect_eq_uint(60, find_nth_bit(bmap, 64 * 3, 5));
expect_eq_uint(80, find_nth_bit(bmap, 64 * 3, 6));
expect_eq_uint(123, find_nth_bit(bmap, 64 * 3, 7));
expect_eq_uint(64 * 3, find_nth_bit(bmap, 64 * 3, 8));
expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3, 8) < 64 * 3));

expect_eq_uint(10, find_nth_bit(bmap, 64 * 3 - 1, 0));
expect_eq_uint(20, find_nth_bit(bmap, 64 * 3 - 1, 1));
Expand All @@ -254,7 +254,7 @@ static void __init test_find_nth_bit(void)
expect_eq_uint(60, find_nth_bit(bmap, 64 * 3 - 1, 5));
expect_eq_uint(80, find_nth_bit(bmap, 64 * 3 - 1, 6));
expect_eq_uint(123, find_nth_bit(bmap, 64 * 3 - 1, 7));
expect_eq_uint(64 * 3 - 1, find_nth_bit(bmap, 64 * 3 - 1, 8));
expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3 - 1, 8) < 64 * 3 - 1));

for_each_set_bit(bit, exp1, EXP1_IN_BITS) {
b = find_nth_bit(exp1, EXP1_IN_BITS, cnt++);
Expand Down

0 comments on commit 0b2811b

Please sign in to comment.