[PATCH v3 0/7] rust: build_assert: document and fix use with function arguments

Alexandre Courbot posted 7 patches 1 week, 4 days ago
rust/kernel/bits.rs          | 6 ++++--
rust/kernel/build_assert.rs  | 7 ++++++-
rust/kernel/cpufreq.rs       | 2 ++
rust/kernel/io.rs            | 9 ++++++---
rust/kernel/io/resource.rs   | 2 ++
rust/kernel/irq/flags.rs     | 2 ++
rust/kernel/num/bounded.rs   | 1 +
rust/kernel/sync/refcount.rs | 3 ++-
8 files changed, 25 insertions(+), 7 deletions(-)
[PATCH v3 0/7] rust: build_assert: document and fix use with function arguments
Posted by Alexandre Courbot 1 week, 4 days ago
`build_assert` relies on the compiler to optimize out its error path,
lest build fails with the dreaded error:

    ERROR: modpost: "rust_build_error" [path/to/module.ko] undefined!

It has been observed that very trivial code performing I/O accesses
(sometimes even using an immediate value) would seemingly randomly fail
with this error whenever `CLIPPY=1` was set. The same behavior was also
observed until different, very similar conditions [1][2].

The cause, as pointed out by Gary Guo [3], appears to be that the
failing function is eventually using `build_assert` with its argument,
but is only annotated with `#[inline]`. This gives the compiler freedom
to not inline the function, which it notably did when Clippy was active,
triggering the error.

The fix is to annotate functions passing their argument to
`build_assert` with `#[inline(always)]`, telling the compiler to be as
aggressive as possible with their inlining. This is also the correct
behavior as inlining is mandatory for correct behavior in these cases.

This series fixes all possible points of failure in the kernel crate,
and adds documentation to `build_assert` explaining how to properly
inline functions for which this behavior may arise.

[1] https://lore.kernel.org/all/DEEUYUOAEZU3.1J1HM2YQ10EX1@nvidia.com/
[2] https://lore.kernel.org/all/A1A280D4-836E-4D75-863E-30B1C276C80C@collabora.com/
[3] https://lore.kernel.org/all/20251121143008.2f5acc33.gary@garyguo.net/

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
Changes in v3:
- Add "Fixes:" tags.
- CC stable on fixup patches.
- Link to v2: https://patch.msgid.link/20251128-io-build-assert-v2-0-a9ea9ce7d45d@nvidia.com

Changes in v2:
- Turn into a series and address other similar cases in the kernel crate.
- Link to v1: https://patch.msgid.link/20251127-io-build-assert-v1-1-04237f2e5850@nvidia.com

---
Alexandre Courbot (7):
      rust: build_assert: add instructions for use with function arguments
      rust: io: always inline functions using build_assert with arguments
      rust: cpufreq: always inline functions using build_assert with arguments
      rust: bits: always inline functions using build_assert with arguments
      rust: sync: refcount: always inline functions using build_assert with arguments
      rust: irq: always inline functions using build_assert with arguments
      rust: num: bounded: add missing comment for always inlined function

 rust/kernel/bits.rs          | 6 ++++--
 rust/kernel/build_assert.rs  | 7 ++++++-
 rust/kernel/cpufreq.rs       | 2 ++
 rust/kernel/io.rs            | 9 ++++++---
 rust/kernel/io/resource.rs   | 2 ++
 rust/kernel/irq/flags.rs     | 2 ++
 rust/kernel/num/bounded.rs   | 1 +
 rust/kernel/sync/refcount.rs | 3 ++-
 8 files changed, 25 insertions(+), 7 deletions(-)
---
base-commit: ba65a4e7120a616d9c592750d9147f6dcafedffa
change-id: 20251127-io-build-assert-3579a5bfb81c

Best regards,
-- 
Alexandre Courbot <acourbot@nvidia.com>
Re: [PATCH v3 0/7] rust: build_assert: document and fix use with function arguments
Posted by Gary Guo 1 week, 3 days ago
On Mon, 08 Dec 2025 11:46:58 +0900
Alexandre Courbot <acourbot@nvidia.com> wrote:

> `build_assert` relies on the compiler to optimize out its error path,
> lest build fails with the dreaded error:
> 
>     ERROR: modpost: "rust_build_error" [path/to/module.ko] undefined!
> 
> It has been observed that very trivial code performing I/O accesses
> (sometimes even using an immediate value) would seemingly randomly fail
> with this error whenever `CLIPPY=1` was set. The same behavior was also
> observed until different, very similar conditions [1][2].
> 
> The cause, as pointed out by Gary Guo [3], appears to be that the
> failing function is eventually using `build_assert` with its argument,
> but is only annotated with `#[inline]`. This gives the compiler freedom
> to not inline the function, which it notably did when Clippy was active,
> triggering the error.

That's an interesting observation, so `#[inline]` is fine without
clippy but `#[inline(always)]` is needed when Clippy is used?

I know Clippy would affect codegen but this might be a first concrete
example that it actually creates (non-perf) issues that I've countered
in practice.

> 
> The fix is to annotate functions passing their argument to
> `build_assert` with `#[inline(always)]`, telling the compiler to be as
> aggressive as possible with their inlining. This is also the correct
> behavior as inlining is mandatory for correct behavior in these cases.

Yeah, I suppose when you draw parallelism with C `BUILD_BUG` macro,
there are a few users of that in other macros, which are kinda
force-inlined.

> 
> This series fixes all possible points of failure in the kernel crate,
> and adds documentation to `build_assert` explaining how to properly
> inline functions for which this behavior may arise.
> 
> [1] https://lore.kernel.org/all/DEEUYUOAEZU3.1J1HM2YQ10EX1@nvidia.com/
> [2] https://lore.kernel.org/all/A1A280D4-836E-4D75-863E-30B1C276C80C@collabora.com/
> [3] https://lore.kernel.org/all/20251121143008.2f5acc33.gary@garyguo.net/
> 
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> Changes in v3:
> - Add "Fixes:" tags.
> - CC stable on fixup patches.
> - Link to v2: https://patch.msgid.link/20251128-io-build-assert-v2-0-a9ea9ce7d45d@nvidia.com
> 
> Changes in v2:
> - Turn into a series and address other similar cases in the kernel crate.
> - Link to v1: https://patch.msgid.link/20251127-io-build-assert-v1-1-04237f2e5850@nvidia.com
> 
> ---
> Alexandre Courbot (7):
>       rust: build_assert: add instructions for use with function arguments
>       rust: io: always inline functions using build_assert with arguments
>       rust: cpufreq: always inline functions using build_assert with arguments
>       rust: bits: always inline functions using build_assert with arguments
>       rust: sync: refcount: always inline functions using build_assert with arguments
>       rust: irq: always inline functions using build_assert with arguments
>       rust: num: bounded: add missing comment for always inlined function
> 
>  rust/kernel/bits.rs          | 6 ++++--
>  rust/kernel/build_assert.rs  | 7 ++++++-
>  rust/kernel/cpufreq.rs       | 2 ++
>  rust/kernel/io.rs            | 9 ++++++---
>  rust/kernel/io/resource.rs   | 2 ++
>  rust/kernel/irq/flags.rs     | 2 ++
>  rust/kernel/num/bounded.rs   | 1 +
>  rust/kernel/sync/refcount.rs | 3 ++-
>  8 files changed, 25 insertions(+), 7 deletions(-)
> ---
> base-commit: ba65a4e7120a616d9c592750d9147f6dcafedffa
> change-id: 20251127-io-build-assert-3579a5bfb81c
> 
> Best regards,
Re: [PATCH v3 0/7] rust: build_assert: document and fix use with function arguments
Posted by Alexandre Courbot 1 week, 3 days ago
On Mon Dec 8, 2025 at 10:49 PM JST, Gary Guo wrote:
> On Mon, 08 Dec 2025 11:46:58 +0900
> Alexandre Courbot <acourbot@nvidia.com> wrote:
>
>> `build_assert` relies on the compiler to optimize out its error path,
>> lest build fails with the dreaded error:
>> 
>>     ERROR: modpost: "rust_build_error" [path/to/module.ko] undefined!
>> 
>> It has been observed that very trivial code performing I/O accesses
>> (sometimes even using an immediate value) would seemingly randomly fail
>> with this error whenever `CLIPPY=1` was set. The same behavior was also
>> observed until different, very similar conditions [1][2].
>> 
>> The cause, as pointed out by Gary Guo [3], appears to be that the
>> failing function is eventually using `build_assert` with its argument,
>> but is only annotated with `#[inline]`. This gives the compiler freedom
>> to not inline the function, which it notably did when Clippy was active,
>> triggering the error.
>
> That's an interesting observation, so `#[inline]` is fine without
> clippy but `#[inline(always)]` is needed when Clippy is used?

Precisely. And sometimes just moving the code invoking the
not-always-inlined function that invokes build_assert is enough to fix
it, so I don't know of an accurately reproducible pattern. It also
occurs pretty rarely.