From 0a2c6664e56f0dff7535c3d3d9a6174279e18acc Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Thu, 2 May 2024 17:24:42 +0800 Subject: lib/test_bitops: Add benchmark test for fns() Introduce a benchmark test for the fns(). It measures the total time taken by fns() to process 10,000 test data generated using get_random_bytes() for each n in the range [0, BITS_PER_LONG). example: test_bitops: fns: 7637268 ns CC: Andrew Morton CC: Rasmus Villemoes CC: David Laight Signed-off-by: Kuan-Wei Chiu Suggested-by: Yury Norov Signed-off-by: Yury Norov --- lib/test_bitops.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'lib') diff --git a/lib/test_bitops.c b/lib/test_bitops.c index 3b7bcbee84db..55669624bb28 100644 --- a/lib/test_bitops.c +++ b/lib/test_bitops.c @@ -5,9 +5,11 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include +#include /* a tiny module only meant to test * @@ -50,6 +52,30 @@ static unsigned long order_comb_long[][2] = { }; #endif +static int __init test_fns(void) +{ + static volatile __always_used unsigned long tmp __initdata; + unsigned long *buf __free(kfree) = NULL; + unsigned int i, n; + ktime_t time; + + buf = kmalloc_array(10000, sizeof(unsigned long), GFP_KERNEL); + if (!buf) + return -ENOMEM; + + get_random_bytes(buf, 10000 * sizeof(unsigned long)); + time = ktime_get(); + + for (n = 0; n < BITS_PER_LONG; n++) + for (i = 0; i < 10000; i++) + tmp = fns(buf[i], n); + + time = ktime_get() - time; + pr_err("fns: %18llu ns\n", time); + + return 0; +} + static int __init test_bitops_startup(void) { int i, bit_set; @@ -94,6 +120,8 @@ static int __init test_bitops_startup(void) if (bit_set != BITOPS_LAST) pr_err("ERROR: FOUND SET BIT %d\n", bit_set); + test_fns(); + pr_info("Completed bitops test\n"); return 0; -- cgit v1.2.3 From 77db1920a88103e8ef9ee58130df7c970aea3d17 Mon Sep 17 00:00:00 2001 From: Yury Norov Date: Thu, 2 May 2024 09:56:33 -0700 Subject: lib: make test_bitops compilable into the kernel image The test now is limited to be compiled as a module. There's no technical reason for it. Now that the test bears some performance benchmarks, it would be reasonable to run it at kernel load time, before userspace starts, to reduce possible jitter. Reviewed-by: Kuan-Wei Chiu Signed-off-by: Yury Norov --- lib/Kconfig.debug | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c63a5fbf1f1c..fc8fe1ea5b49 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2436,7 +2436,6 @@ config TEST_LKM config TEST_BITOPS tristate "Test module for compilation of bitops operations" - depends on m help This builds the "test_bitops" module that is much like the TEST_LKM module except that it does a basic exercise of the -- cgit v1.2.3 From 0b2811ba11b04353033237359c9d042eb0cdc1c1 Mon Sep 17 00:00:00 2001 From: Yury Norov Date: Thu, 2 May 2024 10:12:56 -0700 Subject: 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 Closes: https://lore.kernel.org/all/Zi50cAgR8nZvgLa3@yury-ThinkPad/T/#m6da806a0525e74dcc91f35e5f20766ed4e853e8a Signed-off-by: Yury Norov --- lib/find_bit.c | 2 +- lib/test_bitmap.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/find_bit.c b/lib/find_bit.c index 32f99e9a670e..0bddfc3ff248 100644 --- a/lib/find_bit.c +++ b/lib/find_bit.c @@ -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; \ }) diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index 6b2b33579f56..088838f829c9 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c @@ -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++); -- cgit v1.2.3 From 9f2c2d6ba13da08643c65b948ce5e3d616864c47 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 May 2024 23:01:31 +0300 Subject: bitops: Move aligned_byte_mask() to wordpart.h The bitops.h is for bit related operations. The aligned_byte_mask() is about byte (or part of the machine word) operations, for which we have a separate header, move the mentioned macro to wordpart.h to consolidate similar operations. Signed-off-by: Andy Shevchenko Signed-off-by: Yury Norov --- lib/usercopy.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/usercopy.c b/lib/usercopy.c index d29fe29c6849..4b62e6299cc8 100644 --- a/lib/usercopy.c +++ b/lib/usercopy.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /* out-of-line parts */ -- cgit v1.2.3 From 5671dca241b9a2f4ecf88d8e992041cfb580e0a5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 May 2024 23:01:32 +0300 Subject: usercopy: Don't use "proxy" headers Update header inclusions to follow IWYU (Include What You Use) principle. Signed-off-by: Andy Shevchenko Signed-off-by: Yury Norov --- lib/usercopy.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/usercopy.c b/lib/usercopy.c index 4b62e6299cc8..499a7a7d54db 100644 --- a/lib/usercopy.c +++ b/lib/usercopy.c @@ -1,10 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 -#include +#include +#include +#include #include #include +#include +#include +#include #include #include -#include /* out-of-line parts */ -- cgit v1.2.3