rust/kernel/irq/request.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
These callback functions take a generic `T` that is used in the body as
the generic argument in `Registration` and `ThreadedRegistration`. Those
types require `T: 'static`, but due to a compiler bug this requirement
isn't propagated to the function. Thus add the bound. This was caught in
the upstream Rust CI [1].
Signed-off-by: Benno Lossin <lossin@kernel.org>
Link: https://github.com/rust-lang/rust/pull/149389 [1]
---
rust/kernel/irq/request.rs | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/rust/kernel/irq/request.rs b/rust/kernel/irq/request.rs
index b150563fdef8..2ceeaeb0543a 100644
--- a/rust/kernel/irq/request.rs
+++ b/rust/kernel/irq/request.rs
@@ -261,7 +261,10 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
/// # Safety
///
/// This function should be only used as the callback in `request_irq`.
-unsafe extern "C" fn handle_irq_callback<T: Handler>(_irq: i32, ptr: *mut c_void) -> c_uint {
+unsafe extern "C" fn handle_irq_callback<T: Handler + 'static>(
+ _irq: i32,
+ ptr: *mut c_void,
+) -> c_uint {
// SAFETY: `ptr` is a pointer to `Registration<T>` set in `Registration::new`
let registration = unsafe { &*(ptr as *const Registration<T>) };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
@@ -480,7 +483,7 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
/// # Safety
///
/// This function should be only used as the callback in `request_threaded_irq`.
-unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler>(
+unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler + 'static>(
_irq: i32,
ptr: *mut c_void,
) -> c_uint {
@@ -496,7 +499,10 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
/// # Safety
///
/// This function should be only used as the callback in `request_threaded_irq`.
-unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler>(_irq: i32, ptr: *mut c_void) -> c_uint {
+unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler + 'static>(
+ _irq: i32,
+ ptr: *mut c_void,
+) -> c_uint {
// SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new`
let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
base-commit: 63804fed149a6750ffd28610c5c1c98cce6bd377
--
2.52.0
On Sat, Feb 14, 2026 at 10:27 AM Benno Lossin <lossin@kernel.org> wrote:
>
> These callback functions take a generic `T` that is used in the body as
> the generic argument in `Registration` and `ThreadedRegistration`. Those
> types require `T: 'static`, but due to a compiler bug this requirement
> isn't propagated to the function. Thus add the bound. This was caught in
> the upstream Rust CI [1].
>
> Signed-off-by: Benno Lossin <lossin@kernel.org>
> Link: https://github.com/rust-lang/rust/pull/149389 [1]
Applied to `rust-fixes` -- thanks everyone!
Daniel: I added your Reviewed-by from the other patch (and linked to
that patch separately too) -- I hope that is OK.
[ The three errors looked similar and will start appearing with Rust
1.95.0 (expected 2026-04-16). The first one was:
error[E0310]: the parameter type `T` may not live long enough
Error: --> rust/kernel/irq/request.rs:266:43
|
266 | let registration = unsafe { &*(ptr as *const
Registration<T>) };
| ^^^^^^^^^^^^^^^^^^^^^^
| |
| the
parameter type `T` must be valid for the static lifetime...
| ...so that
the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
264 | unsafe extern "C" fn handle_irq_callback<T: Handler +
'static>(_irq: i32, ptr: *mut c_void) -> c_uint {
| +++++++++
- Miguel ]
Cheers,
Miguel
On Sat Feb 14, 2026 at 10:27 AM CET, Benno Lossin wrote: > These callback functions take a generic `T` that is used in the body as > the generic argument in `Registration` and `ThreadedRegistration`. Those > types require `T: 'static`, but due to a compiler bug this requirement > isn't propagated to the function. Thus add the bound. This was caught in > the upstream Rust CI [1]. > > Signed-off-by: Benno Lossin <lossin@kernel.org> > Link: https://github.com/rust-lang/rust/pull/149389 [1] As discussed, this will go through the Rust tree -- thanks Miguel! Acked-by: Danilo Krummrich <dakr@kernel.org>
On Sat, Feb 14, 2026 at 10:27 AM Benno Lossin <lossin@kernel.org> wrote:
>
> These callback functions take a generic `T` that is used in the body as
> the generic argument in `Registration` and `ThreadedRegistration`. Those
> types require `T: 'static`, but due to a compiler bug this requirement
> isn't propagated to the function. Thus add the bound. This was caught in
> the upstream Rust CI [1].
>
> Signed-off-by: Benno Lossin <lossin@kernel.org>
> Link: https://github.com/rust-lang/rust/pull/149389 [1]
Would it not be a cleaner fix to just add 'static as a super-trait to
the traits directly?
trait Handler: Send + Sync + 'static {}
Alice
On Sat Feb 14, 2026 at 10:27 AM CET, Benno Lossin wrote: > These callback functions take a generic `T` that is used in the body as > the generic argument in `Registration` and `ThreadedRegistration`. Those > types require `T: 'static`, but due to a compiler bug this requirement > isn't propagated to the function. Thus add the bound. This was caught in > the upstream Rust CI [1]. > > Signed-off-by: Benno Lossin <lossin@kernel.org> > Link: https://github.com/rust-lang/rust/pull/149389 [1] IIUC, the current code will not compile with a fixed compiler, right? If this is correct, this needs to be backported; I can add the Fixes: tag and Cc: stable when I apply the patch. - Danilo
On Sat Feb 14, 2026 at 11:23 AM CET, Danilo Krummrich wrote:
> On Sat Feb 14, 2026 at 10:27 AM CET, Benno Lossin wrote:
>> These callback functions take a generic `T` that is used in the body as
>> the generic argument in `Registration` and `ThreadedRegistration`. Those
>> types require `T: 'static`, but due to a compiler bug this requirement
>> isn't propagated to the function. Thus add the bound. This was caught in
>> the upstream Rust CI [1].
>>
>> Signed-off-by: Benno Lossin <lossin@kernel.org>
>> Link: https://github.com/rust-lang/rust/pull/149389 [1]
>
> IIUC, the current code will not compile with a fixed compiler, right?
Correct.
> If this is correct, this needs to be backported; I can add the Fixes: tag and
> Cc: stable when I apply the patch.
Oh yeah I forgot about that, good catch. I think it should be
Fixes: 29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks")
Since that introduces the usage of the `[Threaded]Registration` types
in the function bodies.
It can also be backported further, but then it needs to be split into
threaded and non-threaded variants:
- 135d40523244 ("rust: irq: add support for threaded IRQs and handlers")
- 0851d34a8cc3 ("rust: irq: add support for non-threaded IRQs and handlers")
Cheers,
Benno
On Sat Feb 14, 2026 at 12:56 PM CET, Benno Lossin wrote:
> Oh yeah I forgot about that, good catch. I think it should be
>
> Fixes: 29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks")
>
> Since that introduces the usage of the `[Threaded]Registration` types
> in the function bodies.
>
> It can also be backported further, but then it needs to be split into
> threaded and non-threaded variants:
All commits were introduced in v6.18, so technically there is no "backported
further".
But IIUC, with a fixed compiler, it also would not compile without commit
29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks"),
correct? I.e. the two commits below are the correct Fixes: tags.
> - 135d40523244 ("rust: irq: add support for threaded IRQs and handlers")
> - 0851d34a8cc3 ("rust: irq: add support for non-threaded IRQs and handlers")
On Sat Feb 14, 2026 at 1:18 PM CET, Danilo Krummrich wrote:
> On Sat Feb 14, 2026 at 12:56 PM CET, Benno Lossin wrote:
>> Oh yeah I forgot about that, good catch. I think it should be
>>
>> Fixes: 29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks")
>>
>> Since that introduces the usage of the `[Threaded]Registration` types
>> in the function bodies.
>>
>> It can also be backported further, but then it needs to be split into
>> threaded and non-threaded variants:
>
> All commits were introduced in v6.18, so technically there is no "backported
> further".
>
> But IIUC, with a fixed compiler, it also would not compile without commit
> 29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks"),
> correct? I.e. the two commits below are the correct Fixes: tags.
>
>> - 135d40523244 ("rust: irq: add support for threaded IRQs and handlers")
>> - 0851d34a8cc3 ("rust: irq: add support for non-threaded IRQs and handlers")
With a fixed compiler these two would also still compile. It's just that
the callbacks will only ever be called with `T: 'static`, since that is
a bound on `[Threaded]Registration`, which stores these functions in the
C side. So from a purely no-compile-error perspective, 29e16fcd67ee is
the correct fixes. But from a "good API design" perspective, we could
choose the two other commits.
But since all commits are in v6.18, it doesn't matter all that much.
Cheers,
Benno
On Sat Feb 14, 2026 at 1:49 PM CET, Benno Lossin wrote:
> With a fixed compiler these two would also still compile. It's just that
> the callbacks will only ever be called with `T: 'static`, since that is
> a bound on `[Threaded]Registration`, which stores these functions in the
> C side. So from a purely no-compile-error perspective, 29e16fcd67ee is
> the correct fixes. But from a "good API design" perspective, we could
> choose the two other commits.
Makes sense, I will add
Fixes: 29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks")
then.
Thanks,
Danilo
On 2026-02-14 09:27, Benno Lossin wrote:
> These callback functions take a generic `T` that is used in the body as
> the generic argument in `Registration` and `ThreadedRegistration`. Those
> types require `T: 'static`, but due to a compiler bug this requirement
> isn't propagated to the function. Thus add the bound. This was caught in
> the upstream Rust CI [1].
>
> Signed-off-by: Benno Lossin <lossin@kernel.org>
> Link: https://github.com/rust-lang/rust/pull/149389 [1]
Reviewed-by: Gary Guo <gary@garyguo.net>
> ---
> rust/kernel/irq/request.rs | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/rust/kernel/irq/request.rs b/rust/kernel/irq/request.rs
> index b150563fdef8..2ceeaeb0543a 100644
> --- a/rust/kernel/irq/request.rs
> +++ b/rust/kernel/irq/request.rs
> @@ -261,7 +261,10 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
> /// # Safety
> ///
> /// This function should be only used as the callback in `request_irq`.
> -unsafe extern "C" fn handle_irq_callback<T: Handler>(_irq: i32, ptr: *mut c_void) -> c_uint {
> +unsafe extern "C" fn handle_irq_callback<T: Handler + 'static>(
> + _irq: i32,
> + ptr: *mut c_void,
> +) -> c_uint {
> // SAFETY: `ptr` is a pointer to `Registration<T>` set in `Registration::new`
> let registration = unsafe { &*(ptr as *const Registration<T>) };
> // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
> @@ -480,7 +483,7 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
> /// # Safety
> ///
> /// This function should be only used as the callback in `request_threaded_irq`.
> -unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler>(
> +unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler + 'static>(
> _irq: i32,
> ptr: *mut c_void,
> ) -> c_uint {
> @@ -496,7 +499,10 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
> /// # Safety
> ///
> /// This function should be only used as the callback in `request_threaded_irq`.
> -unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler>(_irq: i32, ptr: *mut c_void) -> c_uint {
> +unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler + 'static>(
> + _irq: i32,
> + ptr: *mut c_void,
> +) -> c_uint {
> // SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new`
> let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) };
> // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
>
> base-commit: 63804fed149a6750ffd28610c5c1c98cce6bd377
© 2016 - 2026 Red Hat, Inc.