Skip to content

Commit 0b2811b

Browse files
committed
bitmap: relax find_nth_bit() limitation on return value
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>
1 parent 77db192 commit 0b2811b

File tree

3 files changed

+4
-4
lines changed

3 files changed

+4
-4
lines changed

include/linux/find.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
220220
* idx = find_first_bit(addr, size);
221221
*
222222
* Returns the bit number of the N'th set bit.
223-
* If no such, returns @size.
223+
* If no such, returns >= @size.
224224
*/
225225
static inline
226226
unsigned long find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n)

lib/find_bit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ out: \
8787
if (sz % BITS_PER_LONG) \
8888
tmp = (FETCH) & BITMAP_LAST_WORD_MASK(sz); \
8989
found: \
90-
sz = min(idx * BITS_PER_LONG + fns(tmp, nr), sz); \
90+
sz = idx * BITS_PER_LONG + fns(tmp, nr); \
9191
out: \
9292
sz; \
9393
})

lib/test_bitmap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ static void __init test_find_nth_bit(void)
244244
expect_eq_uint(60, find_nth_bit(bmap, 64 * 3, 5));
245245
expect_eq_uint(80, find_nth_bit(bmap, 64 * 3, 6));
246246
expect_eq_uint(123, find_nth_bit(bmap, 64 * 3, 7));
247-
expect_eq_uint(64 * 3, find_nth_bit(bmap, 64 * 3, 8));
247+
expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3, 8) < 64 * 3));
248248

249249
expect_eq_uint(10, find_nth_bit(bmap, 64 * 3 - 1, 0));
250250
expect_eq_uint(20, find_nth_bit(bmap, 64 * 3 - 1, 1));
@@ -254,7 +254,7 @@ static void __init test_find_nth_bit(void)
254254
expect_eq_uint(60, find_nth_bit(bmap, 64 * 3 - 1, 5));
255255
expect_eq_uint(80, find_nth_bit(bmap, 64 * 3 - 1, 6));
256256
expect_eq_uint(123, find_nth_bit(bmap, 64 * 3 - 1, 7));
257-
expect_eq_uint(64 * 3 - 1, find_nth_bit(bmap, 64 * 3 - 1, 8));
257+
expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3 - 1, 8) < 64 * 3 - 1));
258258

259259
for_each_set_bit(bit, exp1, EXP1_IN_BITS) {
260260
b = find_nth_bit(exp1, EXP1_IN_BITS, cnt++);

0 commit comments

Comments
 (0)