From: David Laight <david.laight.linux@gmail.com>
The current checks in GENMASK/BIT (eg reversed high/low) only work
for 'integer constant expressions' not 'compile-time constants'.
This is true for const_true() and -Wshift-count-overflow/negative.
While compile-time constants may be unusual, they can happen through
function inlining.
This isn't too bad with gcc, but if clang detects a negative/over-large
shift it treats it as 'undefined behaviour' and silently discards all
code that would use the result, so:
int f(u32 x) {int n = 32; return x >> n; }
generates a function that just contains a 'return' instruction.
If 'n' was a variable that happened to be 32, most modern cpu mask
the count - so would return 'x', some might return 0.
Add extra checks for arguments that pass __builtin_constant_p()
but are not 'integer constant expressions.
__builtin_choose_expr() isn't strong enough to allow
_Static_assert() or ({ ... }) in the other branch so non-standard
schemes are used to report the errors.
To reduce pre-processor bloat the checks are only enabled for W=c
(implied by W=1) builds (where they are errors).
Update the unit tests to match.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/bits.h | 45 +++++++++++++++++++++++++++++++++----------
lib/tests/test_bits.c | 34 +++++++++++++++++++-------------
2 files changed, 56 insertions(+), 23 deletions(-)
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 43631a334314..0f559038981d 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -23,20 +23,35 @@
#include <linux/compiler.h>
#include <linux/overflow.h>
-#define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(const_true((l) > (h)))
+#ifndef KBUILD_EXTRA_WARNc
+#define GENMASK_INPUT_CHECK(h, l, width) 0
+#else
+int GENMASK_INPUT_CHECK_FAIL(void) __compiletime_error("Invalid bit numbers");
+#define GENMASK_INPUT_CHECK(h, l, width) \
+ (__builtin_choose_expr(__is_constexpr((l) > (h)), \
+ sizeof(struct { char low_bit_greater_than_high[-((l) > (h))];}), \
+ __builtin_constant_p((l) | (h)) && \
+ ((l) < 0 || (l) > (h) || (h) >= width) && \
+ GENMASK_INPUT_CHECK_FAIL()))
+#endif
/*
- * Generate a mask for the specified type @t. Additional checks are made to
- * guarantee the value returned fits in that type, relying on
- * -Wshift-count-overflow compiler check to detect incompatible arguments.
+ * Generate a mask for the specified type @t.
+ * Checks are made to guarantee the value returned fits in that type.
+ * The compiler's -Wshift-count-overflow/negative check detects invalid values
+ * from 'constant integer expressions' but not other compile time constants.
+ * Clang treats out of value constants as 'undefined behaviour' and stops
+ * generating code - so explicit checks are needed.
+ * Neither BUILD_BUG() nor BUILD_BUG_ON_ZERO() can be used.
+ *
* For example, all these create build errors or warnings:
*
* - GENMASK(15, 20): wrong argument order
* - GENMASK(72, 15): doesn't fit unsigned long
* - GENMASK_U32(33, 15): doesn't fit in a u32
*/
-#define GENMASK_TYPE(t, h, l) \
- ((unsigned int)GENMASK_INPUT_CHECK(h, l) + \
+#define GENMASK_TYPE(t, h, l) \
+ ((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h))))
#endif
@@ -52,16 +67,26 @@
#if !defined(__ASSEMBLY__)
/*
* Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE().
- * The following examples generate compiler warnings from BIT_INPUT_CHECK().
+ * The following examples generate compiler errors from BIT_INPUT_CHECK().
*
* - BIT_U8(8)
* - BIT_U32(-1)
* - BIT_U32(40)
*/
-#define BIT_INPUT_CHECK(type, nr) \
- BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type)))
-#define BIT_TYPE(type, nr) ((unsigned int)BIT_INPUT_CHECK(type, nr) + ((type)1 << (nr)))
+#ifndef KBUILD_EXTRA_WARNc
+#define BIT_INPUT_CHECK(nr, width) 0
+#else
+int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
+#define BIT_INPUT_CHECK(nr, width) \
+ (__builtin_choose_expr(__is_constexpr(nr), \
+ sizeof(struct { char bit_number_too_big[-((nr) >= (width))];}), \
+ __builtin_constant_p(nr) && ((nr) < 0 || (nr) >= width) && \
+ BIT_INPUT_CHECK_FAIL()))
+#endif
+
+#define BIT_TYPE(type, nr) \
+ ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
#endif /* defined(__ASSEMBLY__) */
#define BIT_U8(nr) BIT_TYPE(u8, nr)
diff --git a/lib/tests/test_bits.c b/lib/tests/test_bits.c
index 55be8230f9e7..36eb4661e78b 100644
--- a/lib/tests/test_bits.c
+++ b/lib/tests/test_bits.c
@@ -3,6 +3,8 @@
* Test cases for functions and macros in bits.h
*/
+#define KBUILD_EXTRA_WARNc 1
+
#include <kunit/test.h>
#include <linux/bits.h>
#include <linux/types.h>
@@ -118,24 +120,30 @@ static void genmask_u128_test(struct kunit *test)
static void genmask_input_check_test(struct kunit *test)
{
- unsigned int x, y;
- int z, w;
+ unsigned int x = 1, y = 2;
+ int z = 1, w = 2;
+
+ OPTIMIZER_HIDE_VAR(x);
+ OPTIMIZER_HIDE_VAR(y);
+ OPTIMIZER_HIDE_VAR(z);
+ OPTIMIZER_HIDE_VAR(w);
/* Unknown input */
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y, 32));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w, 32));
/* Valid input */
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21, 64));
+
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80, 128));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65, 128));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0, 128));
}
--
2.39.5
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
config: mips-randconfig-r132-20260122 (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/config)
compiler: mips64-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601221237.soiAkwkN-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
kernel/reboot.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
lib/idr.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
include/linux/find.h:388:46: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
lib/xarray.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
lib/xarray.c: note: in included file:
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
lib/xarray.c: note: in included file (through include/linux/bitmap.h):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
lib/find_bit.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:238:46: sparse: sparse: Variable length array is used.
--
lib/bitmap-str.c: note: in included file:
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
lib/bitmap-str.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
lib/genalloc.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
mm/oom_kill.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/vmscan.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/shmem.c: note: in included file (through include/linux/cpumask.h, include/linux/smp.h, arch/mips/include/asm/cpu-type.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
mm/percpu.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:409:45: sparse: sparse: Variable length array is used.
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
mm/percpu.c: note: in included file:
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
mm/vmalloc.c: note: in included file (through arch/mips/include/asm/page.h, include/linux/shm.h, include/linux/sched.h, ...):
include/asm-generic/memory_model.h:30:23: sparse: sparse: unsigned value that used to be signed checked against zero?
mm/vmalloc.c:554:21: sparse: signed value source
mm/vmalloc.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
mm/vmalloc.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
mm/vmalloc.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
--
mm/slub.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/hugetlb.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/huge_memory.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
>> arch/mips/kernel/cmpxchg.c:20:16: sparse: sparse: Variable length array is used.
arch/mips/kernel/cmpxchg.c:61:16: sparse: sparse: Variable length array is used.
--
>> arch/mips/kernel/cpu-probe.c:709:41: sparse: sparse: Variable length array is used.
arch/mips/kernel/cpu-probe.c:712:45: sparse: sparse: Variable length array is used.
arch/mips/kernel/cpu-probe.c:214:9: sparse: sparse: cast truncates bits from constant value (3fffffffffffe000 becomes ffffe000)
arch/mips/kernel/cpu-probe.c:214:9: sparse: sparse: cast truncates bits from constant value (3fffffffffffe000 becomes ffffe000)
--
>> arch/mips/mm/tlb-r4k.c:536:20: sparse: sparse: Variable length array is used.
--
net/ethtool/ioctl.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, include/linux/smp.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
net/ethtool/bitset.c: note: in included file (through include/linux/ethtool.h, include/uapi/linux/ethtool_netlink.h, include/linux/ethtool_netlink.h):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
net/ethtool/linkmodes.c: note: in included file (through include/linux/bitmap.h, include/linux/ethtool.h, include/uapi/linux/ethtool_netlink.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
net/ethtool/fec.c: note: in included file (through include/linux/bitmap.h, include/linux/ethtool.h, include/uapi/linux/ethtool_netlink.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
>> drivers/clk/clk-multiplier.c:48:16: sparse: sparse: Variable length array is used.
drivers/clk/clk-multiplier.c:141:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/clk-fractional-divider.c:89:17: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:90:17: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:146:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:147:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:195:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:196:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:205:17: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:206:17: sparse: sparse: Variable length array is used.
--
>> drivers/clocksource/mmio.c:66:27: sparse: sparse: Variable length array is used.
--
>> drivers/clocksource/timer-cadence-ttc.c:364:26: sparse: sparse: Variable length array is used.
--
>> drivers/clocksource/ingenic-timer.c:298:34: sparse: sparse: Variable length array is used.
drivers/clocksource/ingenic-timer.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
--
>> drivers/base/regmap/regmap.c:1221:26: sparse: sparse: Variable length array is used.
--
drivers/base/regmap/regcache-rbtree.c: note: in included file (through include/linux/cpumask.h, include/linux/smp.h, arch/mips/include/asm/cpu-type.h, ...):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
drivers/base/regmap/regcache-flat.c: note: in included file:
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
>> drivers/clk/actions/owl-mux.c:42:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/actions/owl-divider.c:76:17: sparse: sparse: Variable length array is used.
--
drivers/gpio/gpiolib.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
drivers/gpio/gpiolib.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:388:46: sparse: sparse: Variable length array is used.
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
drivers/gpio/gpiolib.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
--
>> drivers/gpio/gpio-nomadik.c:285:30: sparse: sparse: Variable length array is used.
drivers/gpio/gpio-nomadik.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
kernel/sched/build_utility.c: note: in included file:
kernel/sched/debug.c:624:17: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/debug.c:624:17: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/debug.c:624:17: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/debug.c:952:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *tsk @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/debug.c:952:9: sparse: expected struct task_struct *tsk
kernel/sched/debug.c:952:9: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/debug.c:952:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *tsk @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/debug.c:952:9: sparse: expected struct task_struct *tsk
kernel/sched/debug.c:952:9: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/build_utility.c: note: in included file:
kernel/sched/topology.c:115:56: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:115:56: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:115:56: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:134:60: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:134:60: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:134:60: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:157:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:157:20: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:157:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:468:19: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct perf_domain *pd @@ got struct perf_domain [noderef] __rcu *pd @@
kernel/sched/topology.c:468:19: sparse: expected struct perf_domain *pd
kernel/sched/topology.c:468:19: sparse: got struct perf_domain [noderef] __rcu *pd
kernel/sched/topology.c:638:49: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:638:49: sparse: expected struct sched_domain *parent
kernel/sched/topology.c:638:49: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:723:50: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:723:50: sparse: expected struct sched_domain *parent
kernel/sched/topology.c:723:50: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:731:55: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain [noderef] __rcu *[noderef] __rcu child @@ got struct sched_domain *[assigned] tmp @@
kernel/sched/topology.c:731:55: sparse: expected struct sched_domain [noderef] __rcu *[noderef] __rcu child
kernel/sched/topology.c:731:55: sparse: got struct sched_domain *[assigned] tmp
kernel/sched/topology.c:744:29: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:744:29: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/topology.c:744:29: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:749:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:749:20: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:749:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:770:13: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *sd @@
kernel/sched/topology.c:770:13: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/topology.c:770:13: sparse: got struct sched_domain [noderef] __rcu *sd
kernel/sched/topology.c:932:70: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:932:70: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:932:70: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:961:59: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:961:59: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:961:59: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1007:57: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1007:57: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:1007:57: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1009:25: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sibling @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1009:25: sparse: expected struct sched_domain *sibling
kernel/sched/topology.c:1009:25: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1017:55: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1017:55: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:1017:55: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1019:25: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sibling @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1019:25: sparse: expected struct sched_domain *sibling
kernel/sched/topology.c:1019:25: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1089:62: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1089:62: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:1089:62: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1193:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *child @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1193:40: sparse: expected struct sched_domain *child
kernel/sched/topology.c:1193:40: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1331:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:1331:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:1331:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:1680:43: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain [noderef] __rcu *child @@ got struct sched_domain *child @@
kernel/sched/topology.c:1680:43: sparse: expected struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1680:43: sparse: got struct sched_domain *child
kernel/sched/topology.c:2470:31: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain [noderef] __rcu *parent @@ got struct sched_domain *sd @@
kernel/sched/topology.c:2470:31: sparse: expected struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:2470:31: sparse: got struct sched_domain *sd
kernel/sched/topology.c:2591:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2591:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2591:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:2612:56: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *child @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:2612:56: sparse: expected struct sched_domain *child
kernel/sched/topology.c:2612:56: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:2611:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2611:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2611:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:2666:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2666:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2666:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/build_utility.c: note: in included file:
kernel/sched/build_utility.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, include/linux/smp.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
kernel/sched/build_utility.c: note: in included file:
kernel/sched/sched.h:2360:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2360:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2360:25: sparse: struct task_struct *
--
>> drivers/clk/ingenic/cgu.c:95:42: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:97:42: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:102:27: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:224:18: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:227:18: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:231:26: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:345:26: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:389:24: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:423:31: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:553:24: sparse: sparse: Variable length array is used.
--
kernel/irq/chip.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
kernel/irq/irq_sim.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
drivers/input/rmi4/rmi_driver.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/input/rmi4/rmi_driver.c: note: in included file:
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
drivers/input/rmi4/rmi_driver.c: note: in included file (through include/linux/bitmap.h):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
>> drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c:338:31: sparse: sparse: Variable length array is used.
--
>> drivers/mfd/atmel-smc.c:56:32: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:57:32: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:120:27: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:159:25: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:198:25: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:236:25: sparse: sparse: Variable length array is used.
--
>> kernel/time/sched_clock.c:194:20: sparse: sparse: Variable length array is used.
--
>> drivers/mtd/nand/bbt.c:87:25: sparse: sparse: Variable length array is used.
drivers/mtd/nand/bbt.c:111:38: sparse: sparse: Variable length array is used.
drivers/mtd/nand/bbt.c:116:20: sparse: sparse: Variable length array is used.
drivers/mtd/nand/bbt.c:122:28: sparse: sparse: Variable length array is used.
--
drivers/opp/cpu.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
drivers/pci/pci.c:1157:36: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [usertype] current_state @@ got int @@
drivers/pci/pci.c:1157:36: sparse: expected restricted pci_power_t [usertype] current_state
drivers/pci/pci.c:1157:36: sparse: got int
drivers/pci/pci.c:1336:15: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [assigned] [usertype] state @@ got int @@
drivers/pci/pci.c:1336:15: sparse: expected restricted pci_power_t [assigned] [usertype] state
drivers/pci/pci.c:1336:15: sparse: got int
drivers/pci/pci.c:1338:50: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1338:69: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1391:28: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [usertype] current_state @@ got int @@
drivers/pci/pci.c:1391:28: sparse: expected restricted pci_power_t [usertype] current_state
drivers/pci/pci.c:1391:28: sparse: got int
drivers/pci/pci.c:1481:16: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1481:35: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1481:52: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1481:70: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1506:15: sparse: sparse: invalid assignment: |=
drivers/pci/pci.c:1506:15: sparse: left side has type unsigned short
drivers/pci/pci.c:1506:15: sparse: right side has type restricted pci_power_t
drivers/pci/pci.c:1518:28: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [usertype] current_state @@ got int @@
drivers/pci/pci.c:1518:28: sparse: expected restricted pci_power_t [usertype] current_state
drivers/pci/pci.c:1518:28: sparse: got int
drivers/pci/pci.c:1535:13: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1535:21: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1537:18: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1537:26: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1560:13: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1560:22: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1865:38: sparse: sparse: array of flexible structures
drivers/pci/pci.c:2343:44: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2662:60: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2663:30: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2834:20: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2834:38: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2857:49: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2857:67: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:4486:13: sparse: sparse: invalid assignment: |=
drivers/pci/pci.c:4486:13: sparse: left side has type unsigned short
drivers/pci/pci.c:4486:13: sparse: right side has type restricted pci_power_t
drivers/pci/pci.c:4491:13: sparse: sparse: invalid assignment: |=
drivers/pci/pci.c:4491:13: sparse: left side has type unsigned short
drivers/pci/pci.c:4491:13: sparse: right side has type restricted pci_power_t
>> drivers/pci/pci.c:5983:19: sparse: sparse: Variable length array is used.
drivers/pci/pci.c:1112:24: sparse: sparse: incorrect type in return expression (different base types) @@ expected int @@ got restricted pci_power_t [usertype] @@
drivers/pci/pci.c:1112:24: sparse: expected int
drivers/pci/pci.c:1112:24: sparse: got restricted pci_power_t [usertype]
drivers/pci/pci.c:1112:24: sparse: sparse: incorrect type in return expression (different base types) @@ expected int @@ got restricted pci_power_t [usertype] @@
drivers/pci/pci.c:1112:24: sparse: expected int
drivers/pci/pci.c:1112:24: sparse: got restricted pci_power_t [usertype]
drivers/pci/pci.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
--
drivers/perf/xgene_pmu.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:388:46: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
>> drivers/clk/renesas/rcar-gen3-cpg.c:287:22: sparse: sparse: Variable length array is used.
--
>> drivers/clk/renesas/rcar-gen4-cpg.c:400:22: sparse: sparse: Variable length array is used.
--
drivers/mtd/nand/raw/nand_macronix.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
>> drivers/clk/spacemit/ccu_mix.c:168:16: sparse: sparse: Variable length array is used.
drivers/clk/spacemit/ccu_mix.c:193:16: sparse: sparse: Variable length array is used.
--
>> drivers/clk/sprd/mux.c:56:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/sprd/div.c:60:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/sprd/pll.c:77:24: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:116:13: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:120:34: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:121:31: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:124:14: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:125:32: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:127:24: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:128:21: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:129:32: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:131:24: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:164:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:170:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:181:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:186:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:192:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:198:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:210:16: sparse: sparse: Variable length array is used.
--
>> drivers/pci/pcie/bwctrl.c:94:26: sparse: sparse: Variable length array is used.
--
>> drivers/pinctrl/renesas/core.c:884:26: sparse: sparse: Variable length array is used.
drivers/pinctrl/renesas/core.c:942:34: sparse: sparse: Variable length array is used.
drivers/pinctrl/renesas/core.c:1241:34: sparse: sparse: Variable length array is used.
--
>> drivers/pinctrl/renesas/pinctrl.c:492:51: sparse: sparse: Variable length array is used.
drivers/pinctrl/renesas/pinctrl.c:527:17: sparse: sparse: Variable length array is used.
--
drivers/pci/controller/pcie-xilinx-dma-pl.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/pci/controller/pcie-xilinx-dma-pl.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
drivers/pci/controller/dwc/pcie-designware-host.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, include/linux/smp.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/pci/controller/dwc/pcie-designware-host.c: note: in included file (through include/linux/cpumask.h, include/linux/smp.h, arch/mips/include/asm/cpu-type.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
vim +209 include/linux/find.h
c56f97c5c71f17 include/linux/find.h Yury Norov [NVIDIA] 2025-06-19 48
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 49 #ifndef find_next_bit
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 50 /**
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 51 * find_next_bit - find the next set bit in a memory region
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 52 * @addr: The address to base the search on
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 53 * @size: The bitmap size in bits
6d7131bd52b3e0 include/linux/find.h Anna-Maria Behnsen 2022-04-11 54 * @offset: The bitnumber to start searching at
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 55 *
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 56 * Returns the bit number for the next set bit
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 57 * If no bits are set, returns @size.
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 58 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 59 static __always_inline
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 60 unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 61 unsigned long offset)
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 62 {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 63 if (small_const_nbits(size)) {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 64 unsigned long val;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 65
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 66 if (unlikely(offset >= size))
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 67 return size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 68
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 @69 val = *addr & GENMASK(size - 1, offset);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 70 return val ? __ffs(val) : size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 71 }
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 72
e79864f3164c57 include/linux/find.h Yury Norov 2022-09-14 73 return _find_next_bit(addr, size, offset);
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 74 }
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 75 #endif
c7f612cdf091de include/asm-generic/bitops/find.h Akinobu Mita 2006-03-26 76
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 77 #ifndef find_next_and_bit
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 78 /**
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 79 * find_next_and_bit - find the next set bit in both memory regions
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 80 * @addr1: The first address to base the search on
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 81 * @addr2: The second address to base the search on
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 82 * @size: The bitmap size in bits
6d7131bd52b3e0 include/linux/find.h Anna-Maria Behnsen 2022-04-11 83 * @offset: The bitnumber to start searching at
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 84 *
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 85 * Returns the bit number for the next set bit
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 86 * If no bits are set, returns @size.
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 87 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 88 static __always_inline
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 89 unsigned long find_next_and_bit(const unsigned long *addr1,
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 90 const unsigned long *addr2, unsigned long size,
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 91 unsigned long offset)
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 92 {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 93 if (small_const_nbits(size)) {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 94 unsigned long val;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 95
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 96 if (unlikely(offset >= size))
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 97 return size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 98
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 99 val = *addr1 & *addr2 & GENMASK(size - 1, offset);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 100 return val ? __ffs(val) : size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 101 }
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 102
e79864f3164c57 include/linux/find.h Yury Norov 2022-09-14 103 return _find_next_and_bit(addr1, addr2, size, offset);
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 104 }
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 105 #endif
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 106
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 107 #ifndef find_next_andnot_bit
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 108 /**
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 109 * find_next_andnot_bit - find the next set bit in *addr1 excluding all the bits
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 110 * in *addr2
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 111 * @addr1: The first address to base the search on
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 112 * @addr2: The second address to base the search on
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 113 * @size: The bitmap size in bits
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 114 * @offset: The bitnumber to start searching at
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 115 *
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 116 * Returns the bit number for the next set bit
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 117 * If no bits are set, returns @size.
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 118 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 119 static __always_inline
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 120 unsigned long find_next_andnot_bit(const unsigned long *addr1,
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 121 const unsigned long *addr2, unsigned long size,
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 122 unsigned long offset)
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 123 {
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 124 if (small_const_nbits(size)) {
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 125 unsigned long val;
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 126
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 127 if (unlikely(offset >= size))
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 128 return size;
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 129
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 130 val = *addr1 & ~*addr2 & GENMASK(size - 1, offset);
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 131 return val ? __ffs(val) : size;
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 132 }
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 133
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 134 return _find_next_andnot_bit(addr1, addr2, size, offset);
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 135 }
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 136 #endif
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 137
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 138 #ifndef find_next_or_bit
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 139 /**
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 140 * find_next_or_bit - find the next set bit in either memory regions
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 141 * @addr1: The first address to base the search on
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 142 * @addr2: The second address to base the search on
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 143 * @size: The bitmap size in bits
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 144 * @offset: The bitnumber to start searching at
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 145 *
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 146 * Returns the bit number for the next set bit
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 147 * If no bits are set, returns @size.
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 148 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 149 static __always_inline
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 150 unsigned long find_next_or_bit(const unsigned long *addr1,
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 151 const unsigned long *addr2, unsigned long size,
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 152 unsigned long offset)
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 153 {
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 154 if (small_const_nbits(size)) {
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 155 unsigned long val;
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 156
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 157 if (unlikely(offset >= size))
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 158 return size;
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 159
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 160 val = (*addr1 | *addr2) & GENMASK(size - 1, offset);
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 161 return val ? __ffs(val) : size;
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 162 }
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 163
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 164 return _find_next_or_bit(addr1, addr2, size, offset);
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 165 }
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 166 #endif
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 167
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 168 #ifndef find_next_zero_bit
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 169 /**
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 170 * find_next_zero_bit - find the next cleared bit in a memory region
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 171 * @addr: The address to base the search on
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 172 * @size: The bitmap size in bits
6d7131bd52b3e0 include/linux/find.h Anna-Maria Behnsen 2022-04-11 173 * @offset: The bitnumber to start searching at
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 174 *
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 175 * Returns the bit number of the next zero bit
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 176 * If no bits are zero, returns @size.
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 177 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 178 static __always_inline
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 179 unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 180 unsigned long offset)
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 181 {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 182 if (small_const_nbits(size)) {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 183 unsigned long val;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 184
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 185 if (unlikely(offset >= size))
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 186 return size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 187
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 188 val = *addr | ~GENMASK(size - 1, offset);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 189 return val == ~0UL ? size : ffz(val);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 190 }
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 191
e79864f3164c57 include/linux/find.h Yury Norov 2022-09-14 192 return _find_next_zero_bit(addr, size, offset);
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 193 }
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 194 #endif
c7f612cdf091de include/asm-generic/bitops/find.h Akinobu Mita 2006-03-26 195
b7ec62d7ee0f0b include/asm-generic/bitops/find.h Yury Norov 2021-08-14 196 #ifndef find_first_bit
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 197 /**
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 198 * find_first_bit - find the first set bit in a memory region
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 199 * @addr: The address to start the search at
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 200 * @size: The maximum number of bits to search
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 201 *
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 202 * Returns the bit number of the first set bit.
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 203 * If no bits are set, returns @size.
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 204 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 205 static __always_inline
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 206 unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 207 {
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 208 if (small_const_nbits(size)) {
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 @209 unsigned long val = *addr & GENMASK(size - 1, 0);
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 210
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 211 return val ? __ffs(val) : size;
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 212 }
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 213
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 214 return _find_first_bit(addr, size);
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 215 }
b7ec62d7ee0f0b include/asm-generic/bitops/find.h Yury Norov 2021-08-14 216 #endif
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 217
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Thu, 22 Jan 2026 12:41:22 +0800 kernel test robot <lkp@intel.com> wrote: > Hi, > > kernel test robot noticed the following build warnings: > > [auto build test WARNING on next-20260120] > > url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456 > base: next-20260120 > patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com > patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() > config: mips-randconfig-r132-20260122 (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/config) > compiler: mips64-linux-gcc (GCC) 10.5.0 > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202601221237.soiAkwkN-lkp@intel.com/ > > sparse warnings: (new ones prefixed by >>) > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...): > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used. Can we stop sparse complaining about sizeof(VLA) ? David
On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote: > On Thu, 22 Jan 2026 12:41:22 +0800 > kernel test robot <lkp@intel.com> wrote: > > > Hi, > > > > kernel test robot noticed the following build warnings: > > > > [auto build test WARNING on next-20260120] > > > > url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456 > > base: next-20260120 > > patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com > > patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() > > config: mips-randconfig-r132-20260122 (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/config) > > compiler: mips64-linux-gcc (GCC) 10.5.0 > > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/reproduce) > > > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > > the same patch/commit), kindly add following tags > > | Reported-by: kernel test robot <lkp@intel.com> > > | Closes: https://lore.kernel.org/oe-kbuild-all/202601221237.soiAkwkN-lkp@intel.com/ > > > > sparse warnings: (new ones prefixed by >>) > > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...): > > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used. > > Can we stop sparse complaining about sizeof(VLA) ? Got it, we will avoid the direct report this 'sparse: Variable length array is used' warning. > > David >
On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote: > On Thu, 22 Jan 2026 12:41:22 +0800 > kernel test robot <lkp@intel.com> wrote: > > sparse warnings: (new ones prefixed by >>) > > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...): > > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used. > > Can we stop sparse complaining about sizeof(VLA) ? First of all, the LKP should install the fork of sparse by Al Viro. That will fix tons of warnings that are related to modules and speed up the process itself. -- With Best Regards, Andy Shevchenko
On Thu, Jan 22, 2026 at 04:26:44PM +0200, Andy Shevchenko wrote: > On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote: > > On Thu, 22 Jan 2026 12:41:22 +0800 > > kernel test robot <lkp@intel.com> wrote: > > > > sparse warnings: (new ones prefixed by >>) > > > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...): > > > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used. > > > > Can we stop sparse complaining about sizeof(VLA) ? > > First of all, the LKP should install the fork of sparse by Al Viro. That will > fix tons of warnings that are related to modules and speed up the process > itself. Thanks Andy, i will switch to the repo from Al Viro for sparse. > > -- > With Best Regards, > Andy Shevchenko > >
Adding the relevant parties to the discussion: +To: Al Viro +To: Chris Li On 23/01/2026 at 02:25, Philip Li wrote: > On Thu, Jan 22, 2026 at 04:26:44PM +0200, Andy Shevchenko wrote: >> On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote: >>> On Thu, 22 Jan 2026 12:41:22 +0800 >>> kernel test robot <lkp@intel.com> wrote: >> >>>> sparse warnings: (new ones prefixed by >>) >>>> kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...): >>>>>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used. >>> >>> Can we stop sparse complaining about sizeof(VLA) ? >> >> First of all, the LKP should install the fork of sparse by Al Viro. That will >> fix tons of warnings that are related to modules and speed up the process >> itself. > > Thanks Andy, i will switch to the repo from Al Viro for sparse. Al Viro's fork just adds 8 commit on top of the upstream sparse repo. Wouldn't it be possible to just merge those? That would be much less confusing. Yours sincerely, Vincent Mailhol
On Fri, Jan 23, 2026 at 09:01:04AM +0100, Vincent Mailhol wrote: > Adding the relevant parties to the discussion: > > +To: Al Viro > +To: Chris Li > > On 23/01/2026 at 02:25, Philip Li wrote: > > On Thu, Jan 22, 2026 at 04:26:44PM +0200, Andy Shevchenko wrote: > >> On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote: > >>> On Thu, 22 Jan 2026 12:41:22 +0800 > >>> kernel test robot <lkp@intel.com> wrote: > >> > >>>> sparse warnings: (new ones prefixed by >>) > >>>> kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...): > >>>>>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used. > >>> > >>> Can we stop sparse complaining about sizeof(VLA) ? > >> > >> First of all, the LKP should install the fork of sparse by Al Viro. That will > >> fix tons of warnings that are related to modules and speed up the process > >> itself. > > > > Thanks Andy, i will switch to the repo from Al Viro for sparse. > > Al Viro's fork just adds 8 commit on top of the upstream sparse repo. > Wouldn't it be possible to just merge those? Ideally yes, but you also should kick the distro's asses to update it, and the sparse should bump its version... > That would be much less confusing. Seems Al become a sparse maintainer de facto :-) -- With Best Regards, Andy Shevchenko
On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote: > > Al Viro's fork just adds 8 commit on top of the upstream sparse repo. > > Wouldn't it be possible to just merge those? > > Ideally yes, but you also should kick the distro's asses to update it, and > the sparse should bump its version... > > > That would be much less confusing. > > Seems Al become a sparse maintainer de facto :-) Huh? What happened to Chris? FWIW, I do have some followups to that series sitting locally; need to get that finished (mostly for proper __VA_OPT__ handling; that got stalled on the lovely corner cases where the interplay with side effects of macro expansion is really nasty - gcc and clang do not agree and gcc is arguably buggy) and posted. I've done quite a bit of sparse work over the years, but I would rather prefer somebody else as overall maintainer, TYVM...
On Fri, Jan 23, 2026 at 08:20:27AM +0000, Al Viro wrote:
> On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote:
>
> > > Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
> > > Wouldn't it be possible to just merge those?
> >
> > Ideally yes, but you also should kick the distro's asses to update it, and
> > the sparse should bump its version...
> >
> > > That would be much less confusing.
> >
> > Seems Al become a sparse maintainer de facto :-)
>
> Huh? What happened to Chris?
I don't know, but upstream sparse haven't applied any solution for
MODULE*("FOO") stuff, nor reaction on my ping in that discussion
(I did it like week or so ago).
> FWIW, I do have some followups to that series
> sitting locally; need to get that finished (mostly for proper __VA_OPT__
> handling; that got stalled on the lovely corner cases where the interplay
> with side effects of macro expansion is really nasty - gcc and clang do
> not agree and gcc is arguably buggy) and posted.
Thanks for doing all this!
> I've done quite a bit of sparse work over the years, but I would rather
> prefer somebody else as overall maintainer, TYVM...
--
With Best Regards,
Andy Shevchenko
On 23/01/2026 at 09:24, Andy Shevchenko wrote:
> On Fri, Jan 23, 2026 at 08:20:27AM +0000, Al Viro wrote:
>> On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote:
>>
>>>> Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
>>>> Wouldn't it be possible to just merge those?
>>>
>>> Ideally yes, but you also should kick the distro's asses to update it, and
>>> the sparse should bump its version...
>>>
>>>> That would be much less confusing.
>>>
>>> Seems Al become a sparse maintainer de facto :-)
>>
>> Huh? What happened to Chris?
After the project hiatus, I can imagine that there is some confusion :)
But Chris is back in his role of maintainer since September 2025. See:
- https://lore.kernel.org/linux-sparse/CACePvbXDO1ZybDu3RaFhED9D-9gC6LTMpWrxoh5xD+ZO5SLdzA@mail.gmail.com/
- https://git.kernel.org/pub/scm/devel/sparse/sparse.git/commit/?id=67f0a03cee4637e495151c48a02be642a158cbbb
> I don't know, but upstream sparse haven't applied any solution for
> MODULE*("FOO") stuff, nor reaction on my ping in that discussion
> (I did it like week or so ago).
I am out of context here, but were the correct people CCed?
Yours sincerely,
Vincent Mailhol
On Fri, Jan 23, 2026 at 09:32:39AM +0100, Vincent Mailhol wrote:
> On 23/01/2026 at 09:24, Andy Shevchenko wrote:
> > On Fri, Jan 23, 2026 at 08:20:27AM +0000, Al Viro wrote:
> >> On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote:
...
> >>>> Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
> >>>> Wouldn't it be possible to just merge those?
> >>>
> >>> Ideally yes, but you also should kick the distro's asses to update it, and
> >>> the sparse should bump its version...
> >>>
> >>>> That would be much less confusing.
> >>>
> >>> Seems Al become a sparse maintainer de facto :-)
> >>
> >> Huh? What happened to Chris?
>
> After the project hiatus, I can imagine that there is some confusion :)
>
> But Chris is back in his role of maintainer since September 2025. See:
>
> - https://lore.kernel.org/linux-sparse/CACePvbXDO1ZybDu3RaFhED9D-9gC6LTMpWrxoh5xD+ZO5SLdzA@mail.gmail.com/
> - https://git.kernel.org/pub/scm/devel/sparse/sparse.git/commit/?id=67f0a03cee4637e495151c48a02be642a158cbbb
>
> > I don't know, but upstream sparse haven't applied any solution for
> > MODULE*("FOO") stuff, nor reaction on my ping in that discussion
> > (I did it like week or so ago).
My ping: https://lore.kernel.org/all/aV9vo7_turBr84bs@black.igk.intel.com/
But now I realised that there was another version of the series, and Chris
seems active there.
https://lore.kernel.org/all/CACePvbU5Pqo=bw_j8arOq16o1JBOSwPtuMZBVozy4FV7YsSLGw@mail.gmail.com/
> I am out of context here, but were the correct people CCed?
I dunno.
--
With Best Regards,
Andy Shevchenko
On Thu, 22 Jan 2026 16:26:44 +0200
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote:
> > On Thu, 22 Jan 2026 12:41:22 +0800
> > kernel test robot <lkp@intel.com> wrote:
>
> > > sparse warnings: (new ones prefixed by >>)
> > > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
> > > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
> >
> > Can we stop sparse complaining about sizeof(VLA) ?
>
> First of all, the LKP should install the fork of sparse by Al Viro. That will
> fix tons of warnings that are related to modules and speed up the process
> itself.
>
The problem I have is I want to generate a compile time error inside:
__builtin_choose_expr(__is_constexpr(x), x && error_a(),
statically_true(y) && error_b());
Neither static_assert() nor a negative bitfield can be used in error_a()
because they are errors when x isn't isn't a 'constexpr',
There is less of a problem for error_b() it can contain a function call,
but can't contain {( ...)}.
One of the compiler complained about sizeof (char [-!!(expr)]) as well.
I'm not sure of anything else that can be use to get an error.
I could use 0 >> -1 but that is only a warning, at least the error message
is related to the bug.
Any other ideas?
David
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
config: s390-randconfig-001-20260122 (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601220829.MgTMeqqN-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from arch/s390/include/asm/bug.h:60,
from include/linux/bug.h:5,
from include/linux/mmdebug.h:5,
from arch/s390/include/asm/cmpxchg.h:11,
from arch/s390/include/asm/atomic.h:16,
from include/linux/atomic.h:7,
from include/asm-generic/bitops/atomic.h:5,
from arch/s390/include/asm/bitops.h:75,
from include/linux/bitops.h:67,
from include/linux/kernel.h:23,
from net/core/page_pool.c:10:
In function 'netmem_clear_pp_magic',
inlined from 'page_pool_clear_pp_info' at net/core/page_pool.c:721:2:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/asm-generic/bug.h:120:25: note: in definition of macro 'WARN_ON_ONCE'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:18:52: note: in expansion of macro 'PP_DMA_INDEX_MASK'
WARN_ON_ONCE(netmem_to_nmdesc(netmem)->pp_magic & PP_DMA_INDEX_MASK);
^~~~~~~~~~~~~~~~~
--
In file included from include/linux/bitops.h:6,
from arch/s390/include/asm/machine.h:25,
from arch/s390/include/asm/lowcore.h:13,
from arch/s390/include/asm/current.h:13,
from arch/s390/include/asm/preempt.h:5,
from include/linux/preempt.h:79,
from arch/s390/include/asm/timex.h:13,
from include/linux/timex.h:67,
from include/linux/time32.h:13,
from include/linux/time.h:60,
from include/linux/stat.h:19,
from include/linux/module.h:13,
from net/core/skbuff.c:37:
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
vim +/GENMASK_INPUT_CHECK_FAIL +35 include/linux/bits.h
25
26 #ifndef KBUILD_EXTRA_WARNc
27 #define GENMASK_INPUT_CHECK(h, l, width) 0
28 #else
29 int GENMASK_INPUT_CHECK_FAIL(void) __compiletime_error("Invalid bit numbers");
30 #define GENMASK_INPUT_CHECK(h, l, width) \
31 (__builtin_choose_expr(__is_constexpr((l) > (h)), \
32 sizeof(struct { char low_bit_greater_than_high[-((l) > (h))];}), \
33 __builtin_constant_p((l) | (h)) && \
34 ((l) < 0 || (l) > (h) || (h) >= width) && \
> 35 GENMASK_INPUT_CHECK_FAIL()))
36 #endif
37
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Thu, 22 Jan 2026 09:11:53 +0800 kernel test robot <lkp@intel.com> wrote: > Hi, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on next-20260120] > > url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456 > base: next-20260120 > patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com > patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() > config: s390-randconfig-001-20260122 (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/config) > compiler: s390-linux-gcc (GCC) 8.5.0 > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202601220829.MgTMeqqN-lkp@intel.com/ > > All errors (new ones prefixed by >>): > > In file included from arch/s390/include/asm/bug.h:60, > from include/linux/bug.h:5, > from include/linux/mmdebug.h:5, > from arch/s390/include/asm/cmpxchg.h:11, > from arch/s390/include/asm/atomic.h:16, > from include/linux/atomic.h:7, > from include/asm-generic/bitops/atomic.h:5, > from arch/s390/include/asm/bitops.h:75, > from include/linux/bitops.h:67, > from include/linux/kernel.h:23, > from net/core/page_pool.c:10: > In function 'netmem_clear_pp_magic', > inlined from 'page_pool_clear_pp_info' at net/core/page_pool.c:721:2: > >> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers ... > include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK' > #define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \ This might be a real bug. The bit of mm.h is: #define PP_DMA_INDEX_SHIFT (1 + __fls(PP_SIGNATURE - POISON_POINTER_DELTA)) #if POISON_POINTER_DELTA > 0 /* PP_SIGNATURE includes POISON_POINTER_DELTA, so limit the size of the DMA * index to not overlap with that if set */ #define PP_DMA_INDEX_BITS MIN(32, __ffs(POISON_POINTER_DELTA) - PP_DMA_INDEX_SHIFT) #else /* Use the lowest bit of PAGE_OFFSET if there's at least 8 bits available; see above */ #define PP_DMA_INDEX_MIN_OFFSET (1 << (PP_DMA_INDEX_SHIFT + 8)) #define PP_DMA_INDEX_BITS ((__builtin_constant_p(PAGE_OFFSET) && \ PAGE_OFFSET >= PP_DMA_INDEX_MIN_OFFSET && \ !(PAGE_OFFSET & (PP_DMA_INDEX_MIN_OFFSET - 1))) ? \ MIN(32, __ffs(PAGE_OFFSET) - PP_DMA_INDEX_SHIFT) : 0) #endif #define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \ PP_DMA_INDEX_SHIFT) I've no idea what the values are, but the 'hi' bit number must exceed that of 'long'. The __ffs() probably stop it being an 'integer constant expression' making it just a 'compile time constant' - which I added a test for. David
On Thu, 22 Jan 2026 10:25:54 +0000 David Laight <david.laight.linux@gmail.com> wrote: > On Thu, 22 Jan 2026 09:11:53 +0800 > kernel test robot <lkp@intel.com> wrote: > > > Hi, > > > > kernel test robot noticed the following build errors: > > > > [auto build test ERROR on next-20260120] > > > > url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456 > > base: next-20260120 > > patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com > > patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() > > config: s390-randconfig-001-20260122 (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/config) > > compiler: s390-linux-gcc (GCC) 8.5.0 > > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/reproduce) > > > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > > the same patch/commit), kindly add following tags > > | Reported-by: kernel test robot <lkp@intel.com> > > | Closes: https://lore.kernel.org/oe-kbuild-all/202601220829.MgTMeqqN-lkp@intel.com/ > > > > All errors (new ones prefixed by >>): > > > > In file included from arch/s390/include/asm/bug.h:60, > > from include/linux/bug.h:5, > > from include/linux/mmdebug.h:5, > > from arch/s390/include/asm/cmpxchg.h:11, > > from arch/s390/include/asm/atomic.h:16, > > from include/linux/atomic.h:7, > > from include/asm-generic/bitops/atomic.h:5, > > from arch/s390/include/asm/bitops.h:75, > > from include/linux/bitops.h:67, > > from include/linux/kernel.h:23, > > from net/core/page_pool.c:10: > > In function 'netmem_clear_pp_magic', > > inlined from 'page_pool_clear_pp_info' at net/core/page_pool.c:721:2: > > >> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers > ... > > include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK' > > #define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \ > > This might be a real bug. > > The bit of mm.h is: > > #define PP_DMA_INDEX_SHIFT (1 + __fls(PP_SIGNATURE - POISON_POINTER_DELTA)) > #if POISON_POINTER_DELTA > 0 > /* PP_SIGNATURE includes POISON_POINTER_DELTA, so limit the size of the DMA > * index to not overlap with that if set > */ > #define PP_DMA_INDEX_BITS MIN(32, __ffs(POISON_POINTER_DELTA) - PP_DMA_INDEX_SHIFT) > #else > /* Use the lowest bit of PAGE_OFFSET if there's at least 8 bits available; see above */ > #define PP_DMA_INDEX_MIN_OFFSET (1 << (PP_DMA_INDEX_SHIFT + 8)) > #define PP_DMA_INDEX_BITS ((__builtin_constant_p(PAGE_OFFSET) && \ > PAGE_OFFSET >= PP_DMA_INDEX_MIN_OFFSET && \ > !(PAGE_OFFSET & (PP_DMA_INDEX_MIN_OFFSET - 1))) ? \ > MIN(32, __ffs(PAGE_OFFSET) - PP_DMA_INDEX_SHIFT) : 0) > > #endif > > #define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \ > PP_DMA_INDEX_SHIFT) I've managed to do an s390 cross build. It is all quite obvious really. For s390 PAGE_OFFSET is usually zero (I think kernel and user mappings are separate?). This make PP_DMA_INDEX_BITS 0. PP_SIGNATURE is 64 - so PP_DMA_INDEX_SHIFT is 7. So it is doing GENMASK(6, 7) and, I think, expecting to get zero. But that is taken a mistyped GENMASK(7, 6) and treated as an error. If I rewrite __fls() and __ffs() to return 'integer constant expressions' when the input is one I think it would always have failed. A comment a few lines higher suggests that the code expects the mask to be zero in this case - and handles it properly. David > > I've no idea what the values are, but the 'hi' bit number must exceed that > of 'long'. > The __ffs() probably stop it being an 'integer constant expression' > making it just a 'compile time constant' - which I added a test for. > > David > >
On 21/01/2026 at 15:57, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> The current checks in GENMASK/BIT (eg reversed high/low) only work
> for 'integer constant expressions' not 'compile-time constants'.
> This is true for const_true() and -Wshift-count-overflow/negative.
> While compile-time constants may be unusual, they can happen through
> function inlining.
Did those new checks actually found any real problem in the code? This
adds a lot of complexity so I am not sure whether this is a winning
trade-off.
> This isn't too bad with gcc, but if clang detects a negative/over-large
> shift it treats it as 'undefined behaviour' and silently discards all
> code that would use the result, so:
> int f(u32 x) {int n = 32; return x >> n; }
> generates a function that just contains a 'return' instruction.
> If 'n' was a variable that happened to be 32, most modern cpu mask
> the count - so would return 'x', some might return 0.
But then, you only solve that shift problem for GENMASK() and
BIT(). Any other usage of the left/right shifts are not diagnosed
unless your check get copy pasted all over the place.
I think that such a check belongs to a static analyzer. Speaking of
which:
$ cat test.c
typedef unsigned int u32;
static int f(u32 x) {int n = 32; return x >> n; }
$ sparse test.c
test.c:2:46: warning: shift too big (32) for type unsigned int$ cat test.c
So here, I would rather keep relying on sparse rather that introducing
the W=c logic and all that macro complexity.
Yours sincerely,
Vincent Mailhol
On Wed, 21 Jan 2026 19:43:07 +0100
Vincent Mailhol <mailhol@kernel.org> wrote:
> On 21/01/2026 at 15:57, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > The current checks in GENMASK/BIT (eg reversed high/low) only work
> > for 'integer constant expressions' not 'compile-time constants'.
> > This is true for const_true() and -Wshift-count-overflow/negative.
> > While compile-time constants may be unusual, they can happen through
> > function inlining.
>
> Did those new checks actually found any real problem in the code? This
> adds a lot of complexity so I am not sure whether this is a winning
> trade-off.
Not in an x86-64 allmodconfig build.
They might in a 32bit one where there have definitely been issues.
>
> > This isn't too bad with gcc, but if clang detects a negative/over-large
> > shift it treats it as 'undefined behaviour' and silently discards all
> > code that would use the result, so:
> > int f(u32 x) {int n = 32; return x >> n; }
> > generates a function that just contains a 'return' instruction.
> > If 'n' was a variable that happened to be 32, most modern cpu mask
> > the count - so would return 'x', some might return 0.
>
> But then, you only solve that shift problem for GENMASK() and
> BIT(). Any other usage of the left/right shifts are not diagnosed
> unless your check get copy pasted all over the place.
>
> I think that such a check belongs to a static analyzer. Speaking of
> which:
>
> $ cat test.c
> typedef unsigned int u32;
> static int f(u32 x) {int n = 32; return x >> n; }
>
> $ sparse test.c
> test.c:2:46: warning: shift too big (32) for type unsigned int$ cat test.c
>
> So here, I would rather keep relying on sparse rather that introducing
> the W=c logic and all that macro complexity.
I suspect the compiler test will find more than sparse.
I liked getting that to work, but maybe it is OTT.
But the W=c is more generally useful.
As well as removing all the compile-time tests from GENMASK() and
(in another patch FIELD_PREP()) which really do bloat the .i file,
I'd like to add some new tests to min/max/clamp to try to get rid
of the more dodgy (and likely buggy) cases without breaking
everyone's build - just failing the W=1 builds is better.
Using a separate flag means you can use W=ce to stop the build,
doing a W=1e build is hopeless.
David
>
>
> Yours sincerely,
> Vincent Mailhol
© 2016 - 2026 Red Hat, Inc.