From: Alistair Popple <apopple@nvidia.com>
To: Gary Guo <gary@garyguo.net>
Cc: rust-for-linux@vger.kernel.org, "Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Tamir Duberstein" <tamird@kernel.org>,
"Alexandre Courbot" <acourbot@nvidia.com>,
"Onur Özkan" <work@onurozkan.dev>,
"Asahi Lina" <lina+kernel@asahilina.net>,
"Martin Rodriguez Reboredo" <yakoyoku@gmail.com>
Subject: Re: [PATCH] rust: kbuild: export symbols from the `uapi` crate
Date: Thu, 10 Sep 2026 12:21:59 +1000 [thread overview]
Message-ID: <aqIQNhGdRTsv4v52@nvdebian.thelocal> (raw)
In-Reply-To: <DLAUS65AAH2A.39ZT3OE05AR1K@garyguo.net>
On 2026-09-10 at 00:25 +1000, Gary Guo <gary@garyguo.net> wrote...
> On Wed Sep 9, 2026 at 7:06 AM BST, Alistair Popple wrote:
> > Symbols from the `bindings` crate and the C helpers are exported so
> > that loadable modules can link against code the compiler chose not to
> > instantiate in the module itself. The `uapi` crate has the same problem
> > but nothing from it is exported.
> >
> > In practice this goes unnoticed because the only functions in `uapi`
> > are the trivial `Default` implementations generated by `bindgen`,
> > which rustc inlines across crates. With CONFIG_RUST_DEBUG_ASSERTIONS=y
> > however, the `Default` implementation for structs can grow past the
> > automatic cross-crate inlining threshold. The module then references the
> > copy in `uapi.o`, which is not exported, and the build fails:
> >
> > ERROR: modpost: drivers/gpu/nova-drm.ko: symbol '_RNvXsH_Csk9v2ZIpWbWt_4uapiNtB5_17drm_nova_info_gpuNtNtCsfr3MPOfBGpN_4core7default7Default7default' undefined!
>
> Hmm, uapi' ideally should just be type exports and produce no code.
>
> Default implementation should carry `#[inline]` annotation so they're
> only codegenned in actual user crate. Rust's `#[derive(Default)]` would always
> add that. Can you check if that's bindgen-produced manual Default impl that
> somehow misses the attribute?
Right, bindgen-produced Default impl do not have that attribute. For example
here is the bindgen generated implementation I see:
impl Default for drm_nova_info_gpu {
fn default() -> Self {
let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
unsafe {
::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
Manually adding #[inline] fixes the problem of course. I guess we could add some
sed Makefile hackery to manually add it. For example something like the below,
not sure if that would be preferred?
---
diff --cc rust/Makefile
index da1a7409d984,da1a7409d984..535a3bf181bb
--- a/rust/Makefile
+++ b/rust/Makefile
@@@ -525,13 -525,13 +525,16 @@@ quiet_cmd_bindgen = BINDGEN $
$(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \
$(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters)
$(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \
-- sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@
++ sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g; \
++ s/^([[:space:]]*)fn default\(\) -> Self \{/\1#[inline]\n\1fn default() -> Self {/' $@
$(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \
$(src)/bindgen_parameters FORCE
$(call if_changed_dep,bindgen)
$(obj)/uapi/uapi_generated.rs: private bindgen_target_flags = \
$(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters)
++$(obj)/uapi/uapi_generated.rs: private bindgen_target_extra = ; \
++ sed -Ei 's/^([[:space:]]*)fn default\(\) -> Self \{/\1#[inline]\n\1fn default() -> Self {/' $@
$(obj)/uapi/uapi_generated.rs: $(src)/uapi/uapi_helper.h \
$(src)/bindgen_parameters FORCE
$(call if_changed_dep,bindgen)
> Best,
> Gary
>
> >
> > Fix this by exporting the `uapi` symbols in the same way as `bindings`.
> >
> > Fixes: 4e1746656839 ("rust: uapi: Add UAPI crate")
> > Signed-off-by: Alistair Popple <apopple@nvidia.com>
> > Assisted-by: LLM
> > ---
> > rust/Makefile | 7 ++++++-
> > rust/exports.c | 1 +
> > 2 files changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/rust/Makefile b/rust/Makefile
> > index da1a7409d984..083992a5c1c9 100644
> > --- a/rust/Makefile
> > +++ b/rust/Makefile
> > @@ -27,6 +27,7 @@ always-$(CONFIG_RUST) += exports_bindings_generated.h exports_kernel_generated.h
> >
> > always-$(CONFIG_RUST) += uapi/uapi_generated.rs
> > obj-$(CONFIG_RUST) += uapi.o
> > +always-$(CONFIG_RUST) += exports_uapi_generated.h
> >
> > ifdef CONFIG_RUST_BUILD_ASSERT_ALLOW
> > obj-$(CONFIG_RUST) += build_error.o
> > @@ -575,7 +576,8 @@ $(obj)/exports_core_generated.h: $(obj)/core.o FORCE
> > # in the crate where they are defined. Other helpers, called from non-inline
> > # functions, may not be exported, in principle. However, in general, the Rust
> > # compiler does not guarantee codegen will be performed for a non-inline
> > -# function either. Therefore, we export all symbols from helpers and bindings.
> > +# function either. Therefore, we export all symbols from helpers, bindings and
> > +# uapi.
> > # In the future, this may be revisited to reduce the number of exports after
> > # the compiler is informed about the places codegen is required.
> > $(obj)/exports_helpers_generated.h: $(obj)/helpers/helpers.o FORCE
> > @@ -587,6 +589,9 @@ $(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE
> > $(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE
> > $(call if_changed,exports)
> >
> > +$(obj)/exports_uapi_generated.h: $(obj)/uapi.o FORCE
> > + $(call if_changed,exports)
> > +
> > quiet_cmd_rustc_procmacrolibrary = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) PL $@
> > cmd_rustc_procmacrolibrary = \
> > $(rustc_target_envs) \
> > diff --git a/rust/exports.c b/rust/exports.c
> > index 1b52460b0f4e..434f0b73151f 100644
> > --- a/rust/exports.c
> > +++ b/rust/exports.c
> > @@ -17,6 +17,7 @@
> >
> > #include "exports_core_generated.h"
> > #include "exports_bindings_generated.h"
> > +#include "exports_uapi_generated.h"
> > #include "exports_kernel_generated.h"
> >
> > #ifndef CONFIG_RUST_INLINE_HELPERS
> >
> > base-commit: b705c185105762676aa6ec16cf976101df87cc35
>
>
next prev parent reply other threads:[~2026-09-10 2:22 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 6:06 [PATCH] rust: kbuild: export symbols from the `uapi` crate Alistair Popple
2026-09-09 14:25 ` Gary Guo
2026-09-10 2:21 ` Alistair Popple [this message]
2026-09-10 9:20 ` Alice Ryhl
2026-09-10 11:36 ` Gary Guo
2026-09-16 1:25 ` Alistair Popple
2026-09-16 7:39 ` Gary Guo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aqIQNhGdRTsv4v52@nvdebian.thelocal \
--to=apopple@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=lina+kernel@asahilina.net \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
--cc=yakoyoku@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.