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>
This commit is contained in:
parent
77db1920a8
commit
0b2811ba11
@ -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)
|
||||
|
@ -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; \
|
||||
})
|
||||
|
@ -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));
|
||||
@ -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++);
|
||||
|
Loading…
Reference in New Issue
Block a user