From: Greg KH <gregkh@linuxfoundation.org>
To: Alice Ryhl <aliceryhl@google.com>
Cc: Danilo Krummrich <dakr@kernel.org>,
rafael@kernel.org, ojeda@kernel.org, boqun.feng@gmail.com,
gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org,
a.hindborg@kernel.org, tmgross@umich.edu,
driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/5] devres: export devres_node_init() and devres_node_add()
Date: Fri, 6 Feb 2026 14:55:50 +0100 [thread overview]
Message-ID: <2026020633-foe-etching-e464@gregkh> (raw)
In-Reply-To: <aYXtwXYAELSIoxXE@google.com>
On Fri, Feb 06, 2026 at 01:33:53PM +0000, Alice Ryhl wrote:
> On Fri, Feb 06, 2026 at 02:22:42PM +0100, Greg KH wrote:
> > On Fri, Feb 06, 2026 at 02:16:05PM +0100, Danilo Krummrich wrote:
> > > On Fri Feb 6, 2026 at 1:34 PM CET, Greg KH wrote:
> > > > That's fine, because the rust driver core code should also be built into
> > > > the kernel, not as a module, right?
> > >
> > > Yes, but the Rust compiler may still choose to put some of the core code into
> > > the module.
> >
> > What exactly do you mean by "the module"?
> >
> > > Especially with generic types and functions the Rust compiler may move some the
> > > generated code for a certain type instance into the module that instanciates the
> > > type.
> >
> > Ah, that's a mess. why? The code lives in the .rs file in the kernel
> > core, right?
>
> It might still be inlined into downstream compilation units. Rust has no
> equivalent to 'static inline' function in a header file, after all.
>
> > > For instance, even though rust/kernel/devres.rs is *always* built-in, we get the
> > > following error when devres_node_init() is not exported when the users of this
> > > built-in code are built as module.
> > >
> > > ERROR: modpost: "devres_node_init" [drivers/pwm/pwm_th1520.ko] undefined!
> > > ERROR: modpost: "devres_node_init" [drivers/gpu/drm/tyr/tyr.ko] undefined!
> > > ERROR: modpost: "devres_node_init" [drivers/gpu/nova-core/nova_core.ko] undefined!
> > > ERROR: modpost: "devres_node_init" [samples/rust/rust_dma.ko] undefined!
> > > ERROR: modpost: "devres_node_init" [samples/rust/rust_driver_pci.ko] undefined!
> > > ERROR: modpost: "devres_node_init" [samples/rust/rust_driver_auxiliary.ko] undefined!
> > > make[2]: *** [scripts/Makefile.modpost:147: Module.symvers] Error 1
> >
> > This feels like a compiler bug, how is the compiler reaching into
> > devres.rs and sucking out code to put into the module? Doesn't the
> > build/link boundry stay at the .rs boundry?
>
> It's quite intentional.
>
> It used to be the case that only functions marked #[inline] could be
> inlined like this, but it was changed so that small functions without
> any marker are also eligible for inlining. Now you need #[inline(never)]
> to ensure it does not happen.
>
> Note that this analysis only applies to non-generic code. If you call
> devres_node_init() from within this function:
>
> impl Devres<T> {
> fn new() -> Self {
> ... devres_node_init() ...
> }
> }
>
> then since `new()` is generic over T, it is duplicated for each type T
> it is used with (via monomorphisation, like C++ templates). So the
> actual `new` function might be instantiated in the crate that uses
> Devres<MyDriverType>, and in this case it ends up in the module even
> with #[inline(never)].
>
> So you'd need a non-generic Rust function with #[inline(never)] in this
> case, and have Devres::<T>::new() call that function.
>
> > > However, sprinkling "raw" EXPORT_SYMBOL_GPL() due to that is not great at all.
> > > Hence, we could do something like in [1] instead. I don't know if there are
> > > other options that may be better though.
> > >
> > > [1] https://lore.kernel.org/all/DG7UR3WWZB4V.2MYMJJH1VDHH@kernel.org/
> >
> > That's a start, but still messy. There's no compiler options to prevent
> > this "lifting" of the code out of devres.rs? If not, this is not going
> > to be the only problem that drivers run into like this in the future.
>
> Because of how monomorphisation, as-is the code actually lives in the
> module to begin with.
Ok, but again, that is going to cause all sorts of "the symbol is
undefined" type of problems going forward as a developers just "assumes"
that the place where the symbol is exported will actually have the
symbol exported from it, not that this place will be copied inline into
somewhere else.
Think about the interaction between module symbol namespaces here. This
isn't going to scale, and will trip people up and cause us to be forced
to export way more than we really want to (like this patch series shows,
I don't want to export any of these...)
thanks,
greg k-h
next prev parent reply other threads:[~2026-02-06 13:55 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-05 22:31 [PATCH 0/5] Use struct devres_node in Devres<T> Danilo Krummrich
2026-02-05 22:31 ` [PATCH 1/5] devres: move struct devres_node into base.h Danilo Krummrich
2026-02-05 22:31 ` [PATCH 2/5] devres: export devres_node_init() and devres_node_add() Danilo Krummrich
2026-02-06 10:43 ` Danilo Krummrich
2026-02-06 11:04 ` Greg KH
2026-02-06 11:32 ` Danilo Krummrich
2026-02-06 11:34 ` Alice Ryhl
2026-02-06 11:46 ` Danilo Krummrich
2026-02-06 12:34 ` Greg KH
2026-02-06 13:16 ` Danilo Krummrich
2026-02-06 13:20 ` Alice Ryhl
2026-02-06 13:25 ` Greg KH
2026-02-06 13:33 ` Danilo Krummrich
2026-02-06 13:35 ` Alice Ryhl
2026-02-06 13:22 ` Greg KH
2026-02-06 13:33 ` Alice Ryhl
2026-02-06 13:55 ` Greg KH [this message]
2026-02-06 14:23 ` Gary Guo
2026-02-06 14:31 ` Greg KH
2026-02-06 15:09 ` Alice Ryhl
2026-02-06 16:31 ` Alice Ryhl
2026-02-06 14:08 ` Danilo Krummrich
2026-02-05 22:31 ` [PATCH 3/5] devres: add devres_node_remove() Danilo Krummrich
2026-02-05 22:31 ` [PATCH 4/5] devres: rename and export set_node_dbginfo() Danilo Krummrich
2026-02-05 22:31 ` [PATCH 5/5] rust: devres: embed struct devres_node directly Danilo Krummrich
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=2026020633-foe-etching-e464@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=a.hindborg@kernel.org \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=driver-core@lists.linux.dev \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox