<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/rust/kernel/devres.rs, branch v7.2.4</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>rust: devres: ensure revocation is complete before device finishes unbinding</title>
<updated>2026-09-07T15:36:31+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-06-28T20:02:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=cdbbcd7c64c9d4dc8d1a47e34cb16db90fbc5a13'/>
<id>cdbbcd7c64c9d4dc8d1a47e34cb16db90fbc5a13</id>
<content type='text'>
commit a10639966fd72fff8f7fbf3c8e733307daabd38f upstream.

Now that the revocation Completion is in place, also address the
symmetric case. When Devres::drop() wins the is_available swap and the
devres callback loses, the callback returns to devres_release_all()
without waiting. This means device unbinding can complete while
Devres::drop() is still executing drop_in_place() on another CPU, which
is a problem if T's destructor accesses device state.

Make the synchronization bidirectional. Whichever side performs
drop_in_place() signals the Completion, and the other side waits.

This does not reintroduce the nested Devres deadlock fixed by commit
ba268514ea14 ("rust: devres: fix race condition due to nesting"),
because that deadlock was caused by drop waiting for the release
callback to return (the old 'devm' Completion). Here, both sides only
wait for drop_in_place() to finish, which completes within the current
call chain. The Arc&lt;Inner&lt;T&gt;&gt; keeps the Inner allocation alive
independently.

Cc: stable@vger.kernel.org
Fixes: ba268514ea14 ("rust: devres: fix race condition due to nesting")
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Link: https://patch.msgid.link/20260628200304.2365598-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit a10639966fd72fff8f7fbf3c8e733307daabd38f upstream.

Now that the revocation Completion is in place, also address the
symmetric case. When Devres::drop() wins the is_available swap and the
devres callback loses, the callback returns to devres_release_all()
without waiting. This means device unbinding can complete while
Devres::drop() is still executing drop_in_place() on another CPU, which
is a problem if T's destructor accesses device state.

Make the synchronization bidirectional. Whichever side performs
drop_in_place() signals the Completion, and the other side waits.

This does not reintroduce the nested Devres deadlock fixed by commit
ba268514ea14 ("rust: devres: fix race condition due to nesting"),
because that deadlock was caused by drop waiting for the release
callback to return (the old 'devm' Completion). Here, both sides only
wait for drop_in_place() to finish, which completes within the current
call chain. The Arc&lt;Inner&lt;T&gt;&gt; keeps the Inner allocation alive
independently.

Cc: stable@vger.kernel.org
Fixes: ba268514ea14 ("rust: devres: fix race condition due to nesting")
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Link: https://patch.msgid.link/20260628200304.2365598-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: devres: fix race between concurrent revokers</title>
<updated>2026-09-07T15:36:31+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-06-28T17:44:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=c7e3d57c705ab1053a6a1bbef96795e792da1540'/>
<id>c7e3d57c705ab1053a6a1bbef96795e792da1540</id>
<content type='text'>
commit acc516dfa1972d31836b50abc0115216cd0fccc5 upstream.

There is a potential race condition when two paths try to revoke a
Devres concurrently.

The driver core's devres_release_all() calls Revocable::revoke() via the
release callback, while Devres::drop() calls revoke_nosync() on another
CPU.

The revoker that does not claim the is_available swap returns
immediately, but the revoker that did may still be executing
drop_in_place() on the inner data. This can cause a use-after-free when
the other revoker's caller proceeds to drop adjacent resources that
drop_in_place() still references (e.g., Devres&lt;DmaMappedSgt&gt; racing with
SGTable freeing the backing sg_table and pages).

Fix this by adding a Completion. The release callback signals the
Completion after revoke() finishes, and Devres::drop() waits for it when
it loses the is_available swap. This ensures the wrapped object is fully
torn down before Devres::drop() returns.

Cc: stable@vger.kernel.org
Reported-by: Sashiko &lt;sashiko-bot@kernel.org&gt;
Closes: https://lore.kernel.org/dri-devel/20260612202841.2577C1F000E9@smtp.kernel.org/
Fixes: 05aa6fb1c21d ("rust: scatterlist: Add abstraction for sg_table")
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Link: https://patch.msgid.link/20260628174451.2275679-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit acc516dfa1972d31836b50abc0115216cd0fccc5 upstream.

There is a potential race condition when two paths try to revoke a
Devres concurrently.

The driver core's devres_release_all() calls Revocable::revoke() via the
release callback, while Devres::drop() calls revoke_nosync() on another
CPU.

The revoker that does not claim the is_available swap returns
immediately, but the revoker that did may still be executing
drop_in_place() on the inner data. This can cause a use-after-free when
the other revoker's caller proceeds to drop adjacent resources that
drop_in_place() still references (e.g., Devres&lt;DmaMappedSgt&gt; racing with
SGTable freeing the backing sg_table and pages).

Fix this by adding a Completion. The release callback signals the
Completion after revoke() finishes, and Devres::drop() waits for it when
it loses the is_available swap. This ensures the wrapped object is fully
torn down before Devres::drop() returns.

Cc: stable@vger.kernel.org
Reported-by: Sashiko &lt;sashiko-bot@kernel.org&gt;
Closes: https://lore.kernel.org/dri-devel/20260612202841.2577C1F000E9@smtp.kernel.org/
Fixes: 05aa6fb1c21d ("rust: scatterlist: Add abstraction for sg_table")
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Link: https://patch.msgid.link/20260628174451.2275679-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: io: gate ioremap doctests on CONFIG_HAS_IOMEM</title>
<updated>2026-08-06T14:05:50+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-08-05T21:28:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=f88db65aece9f9d26287b6377b7c7730ecf9f11a'/>
<id>f88db65aece9f9d26287b6377b7c7730ecf9f11a</id>
<content type='text'>
The doc examples in io.rs and devres.rs directly call
bindings::ioremap() and bindings::iounmap(), which do not exist when
CONFIG_HAS_IOMEM is not set. This causes build failures with
CONFIG_RUST_KERNEL_DOCTESTS=y on such configurations (e.g. s390
allnoconfig).

Gate the affected doctests with `#![cfg(CONFIG_HAS_IOMEM)]` so they are
skipped when IOMEM is unavailable.

Fixes: 3f70ebe63858 ("s390: Enable Rust support")
Reviewed-by: Arnd Bergmann &lt;arnd@arndb.de&gt;
Link: https://patch.msgid.link/20260805212920.1996937-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The doc examples in io.rs and devres.rs directly call
bindings::ioremap() and bindings::iounmap(), which do not exist when
CONFIG_HAS_IOMEM is not set. This causes build failures with
CONFIG_RUST_KERNEL_DOCTESTS=y on such configurations (e.g. s390
allnoconfig).

Gate the affected doctests with `#![cfg(CONFIG_HAS_IOMEM)]` so they are
skipped when IOMEM is unavailable.

Fixes: 3f70ebe63858 ("s390: Enable Rust support")
Reviewed-by: Arnd Bergmann &lt;arnd@arndb.de&gt;
Link: https://patch.msgid.link/20260805212920.1996937-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: devres: add 'static bound to Devres&lt;T&gt;</title>
<updated>2026-05-28T23:06:10+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-05-26T00:04:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=016267b521b18529c977c9eca9597a1669c3d73c'/>
<id>016267b521b18529c977c9eca9597a1669c3d73c</id>
<content type='text'>
Devres::new() registers a callback with the C devres subsystem via
devres_node_add(). If the Devres is leaked (e.g. via
core::mem::forget(), which is safe), its Drop impl never runs, and the
devres release callback will revoke the inner Revocable on device
unbind, which drops T in place. If T contains non-'static references,
those may be dangling by that point.

Add a 'static bound to prevent storing types with borrowed data in
Devres.

Fixes: 76c01ded724b ("rust: add devres abstraction")
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Eliot Courtney &lt;ecourtney@nvidia.com&gt;
Link: https://patch.msgid.link/20260526000447.350558-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Devres::new() registers a callback with the C devres subsystem via
devres_node_add(). If the Devres is leaked (e.g. via
core::mem::forget(), which is safe), its Drop impl never runs, and the
devres release callback will revoke the inner Revocable on device
unbind, which drops T in place. If T contains non-'static references,
those may be dangling by that point.

Add a 'static bound to prevent storing types with borrowed data in
Devres.

Fixes: 76c01ded724b ("rust: add devres abstraction")
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Eliot Courtney &lt;ecourtney@nvidia.com&gt;
Link: https://patch.msgid.link/20260526000447.350558-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: pci: make Bar lifetime-parameterized</title>
<updated>2026-05-27T14:24:23+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-05-25T20:21:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=8ea0b6d5bef5e4f4637964c3b2cf732d9bf4f408'/>
<id>8ea0b6d5bef5e4f4637964c3b2cf732d9bf4f408</id>
<content type='text'>
Convert pci::Bar&lt;SIZE&gt; to pci::Bar&lt;'a, SIZE&gt;, storing &amp;'a Device&lt;Bound&gt;
to tie the BAR mapping lifetime to the device.

iomap_region_sized() now returns Result&lt;Bar&lt;'a, SIZE&gt;&gt; directly instead
of impl PinInit&lt;Devres&lt;Bar&lt;SIZE&gt;&gt;, Error&gt;.

Since the lifetime ties the mapping to the device's bound state, callers
no longer need Devres for the common case where the Bar lives in the
driver's private data.

Add Bar::into_devres() to consume the bar and register it as a
device-managed resource, returning Devres&lt;Bar&lt;'static, SIZE&gt;&gt;. The
lifetime is erased to 'static because Devres guarantees the bar does not
actually outlive the device -- access is revoked on unbind.

Reviewed-by: Eliot Courtney &lt;ecourtney@nvidia.com&gt;
Reviewed-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Link: https://patch.msgid.link/20260525202921.124698-19-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Convert pci::Bar&lt;SIZE&gt; to pci::Bar&lt;'a, SIZE&gt;, storing &amp;'a Device&lt;Bound&gt;
to tie the BAR mapping lifetime to the device.

iomap_region_sized() now returns Result&lt;Bar&lt;'a, SIZE&gt;&gt; directly instead
of impl PinInit&lt;Devres&lt;Bar&lt;SIZE&gt;&gt;, Error&gt;.

Since the lifetime ties the mapping to the device's bound state, callers
no longer need Devres for the common case where the Bar lives in the
driver's private data.

Add Bar::into_devres() to consume the bar and register it as a
device-managed resource, returning Devres&lt;Bar&lt;'static, SIZE&gt;&gt;. The
lifetime is erased to 'static because Devres guarantees the bar does not
actually outlive the device -- access is revoked on unbind.

Reviewed-by: Eliot Courtney &lt;ecourtney@nvidia.com&gt;
Reviewed-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Link: https://patch.msgid.link/20260525202921.124698-19-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: device: make Core and CoreInternal lifetime-parameterized</title>
<updated>2026-05-27T14:22:42+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-05-25T20:20:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=24799831d631239ff21ea1bf7feee832df48b81f'/>
<id>24799831d631239ff21ea1bf7feee832df48b81f</id>
<content type='text'>
Device&lt;Core&gt; references in probe callbacks are scoped to the callback,
not the full binding duration. Add a lifetime parameter to Core and
CoreInternal to accurately represent this in the type system.

Suggested-by: Gary Guo &lt;gary@garyguo.net&gt;
Reviewed-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Eliot Courtney &lt;ecourtney@nvidia.com&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Link: https://patch.msgid.link/20260525202921.124698-12-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Device&lt;Core&gt; references in probe callbacks are scoped to the callback,
not the full binding duration. Add a lifetime parameter to Core and
CoreInternal to accurately represent this in the type system.

Suggested-by: Gary Guo &lt;gary@garyguo.net&gt;
Reviewed-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Eliot Courtney &lt;ecourtney@nvidia.com&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Link: https://patch.msgid.link/20260525202921.124698-12-dakr@kernel.org
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: devres: embed struct devres_node directly</title>
<updated>2026-03-17T23:47:14+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-02-13T22:07:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=9aa64d2503c6f5a803ff2990608312e5bdc6b0de'/>
<id>9aa64d2503c6f5a803ff2990608312e5bdc6b0de</id>
<content type='text'>
Currently, the Devres&lt;T&gt; container uses devm_add_action() to register a
devres callback.

devm_add_action() allocates a struct action_devres, which on top of
struct devres_node, just keeps a data pointer and release function
pointer.

This is an unnecessary indirection, given that analogous to struct
devres, the Devres&lt;T&gt; container can just embed a struct devres_node
directly without an additional allocation.

In contrast to struct devres, we don't need to force an alignment of
ARCH_DMA_MINALIGN (as struct devres does to account for the worst case)
since we have generics in Rust. I.e. the compiler already ensures
correct alignment of the embedded T in Devres&lt;T&gt;.

Thus, get rid of devm_add_action() and instead embed a struct
devres_node directly.

Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Acked-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Link: https://patch.msgid.link/20260213220718.82835-6-dakr@kernel.org
[ * Improve comment about core::any::type_name(),
  * add #[must_use] to devres_node_remove(),
  * use container_of!() in devres_node_free_node().

    - Danilo ]
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently, the Devres&lt;T&gt; container uses devm_add_action() to register a
devres callback.

devm_add_action() allocates a struct action_devres, which on top of
struct devres_node, just keeps a data pointer and release function
pointer.

This is an unnecessary indirection, given that analogous to struct
devres, the Devres&lt;T&gt; container can just embed a struct devres_node
directly without an additional allocation.

In contrast to struct devres, we don't need to force an alignment of
ARCH_DMA_MINALIGN (as struct devres does to account for the worst case)
since we have generics in Rust. I.e. the compiler already ensures
correct alignment of the embedded T in Devres&lt;T&gt;.

Thus, get rid of devm_add_action() and instead embed a struct
devres_node directly.

Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Acked-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Link: https://patch.msgid.link/20260213220718.82835-6-dakr@kernel.org
[ * Improve comment about core::any::type_name(),
  * add #[must_use] to devres_node_remove(),
  * use container_of!() in devres_node_free_node().

    - Danilo ]
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: devres: fix race condition due to nesting</title>
<updated>2026-02-07T00:03:49+00:00</updated>
<author>
<name>Danilo Krummrich</name>
<email>dakr@kernel.org</email>
</author>
<published>2026-02-05T22:25:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=ba268514ea14b44570030e8ed2aef92a38679e85'/>
<id>ba268514ea14b44570030e8ed2aef92a38679e85</id>
<content type='text'>
Commit f5d3ef25d238 ("rust: devres: get rid of Devres' inner Arc") did
attempt to optimize away the internal reference count of Devres.

However, without an internal reference count, we can't support cases
where Devres is indirectly nested, resulting into a deadlock.

Such indirect nesting easily happens in the following way:

A registration object (which is guarded by devres) hold a reference
count of an object that holds a device resource guarded by devres
itself.

For instance a drm::Registration holds a reference of a drm::Device. The
drm::Device itself holds a device resource in its private data.

When the drm::Registration is dropped by devres, and it happens that it
did hold the last reference count of the drm::Device, it also drops the
device resource, which is guarded by devres itself.

Thus, resulting into a deadlock in the Devres destructor of the device
resource, as in the following backtrace.

	sysrq: Show Blocked State
	task:rmmod           state:D stack:0     pid:1331  tgid:1331  ppid:1330   task_flags:0x400100 flags:0x00000010
	Call trace:
	 __switch_to+0x190/0x294 (T)
	 __schedule+0x878/0xf10
	 schedule+0x4c/0xcc
	 schedule_timeout+0x44/0x118
	 wait_for_common+0xc0/0x18c
	 wait_for_completion+0x18/0x24
	 _RINvNtCs4gKlGRWyJ5S_4core3ptr13drop_in_placeINtNtNtCsgzhNYVB7wSz_6kernel4sync3arc3ArcINtNtBN_6devres6DevresmEEECsRdyc7Hyps3_15rust_driver_pci+0x68/0xe8 [rust_driver_pci]
	 _RINvNvNtCsgzhNYVB7wSz_6kernel6devres16register_foreign8callbackINtNtCs4gKlGRWyJ5S_4core3pin3PinINtNtNtB6_5alloc4kbox3BoxINtNtNtB6_4sync3arc3ArcINtB4_6DevresmEENtNtB1A_9allocator7KmallocEEECsRdyc7Hyps3_15rust_driver_pci+0x34/0xc8 [rust_driver_pci]
	 devm_action_release+0x14/0x20
	 devres_release_all+0xb8/0x118
	 device_release_driver_internal+0x1c4/0x28c
	 driver_detach+0x94/0xd4
	 bus_remove_driver+0xdc/0x11c
	 driver_unregister+0x34/0x58
	 pci_unregister_driver+0x20/0x80
	 __arm64_sys_delete_module+0x1d8/0x254
	 invoke_syscall+0x40/0xcc
	 el0_svc_common+0x8c/0xd8
	 do_el0_svc+0x1c/0x28
	 el0_svc+0x54/0x1d4
	 el0t_64_sync_handler+0x84/0x12c
	 el0t_64_sync+0x198/0x19c

In order to fix this, re-introduce the internal reference count.

Reported-by: Boris Brezillon &lt;boris.brezillon@collabora.com&gt;
Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/.E2.9C.94.20Deadlock.20caused.20by.20nested.20Devres/with/571242651
Reported-by: Markus Probst &lt;markus.probst@posteo.de&gt;
Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/.E2.9C.94.20Devres.20inside.20Devres.20stuck.20on.20cleanup/with/571239721
Reported-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Closes: https://gitlab.freedesktop.org/panfrost/linux/-/merge_requests/56#note_3282757
Fixes: f5d3ef25d238 ("rust: devres: get rid of Devres' inner Arc")
Reviewed-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Tested-by: Boris Brezillon &lt;boris.brezillon@collabora.com&gt;
Link: https://patch.msgid.link/20260205222529.91465-1-dakr@kernel.org
[ Call clone() prior to devm_add_action(). - Danilo ]
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Commit f5d3ef25d238 ("rust: devres: get rid of Devres' inner Arc") did
attempt to optimize away the internal reference count of Devres.

However, without an internal reference count, we can't support cases
where Devres is indirectly nested, resulting into a deadlock.

Such indirect nesting easily happens in the following way:

A registration object (which is guarded by devres) hold a reference
count of an object that holds a device resource guarded by devres
itself.

For instance a drm::Registration holds a reference of a drm::Device. The
drm::Device itself holds a device resource in its private data.

When the drm::Registration is dropped by devres, and it happens that it
did hold the last reference count of the drm::Device, it also drops the
device resource, which is guarded by devres itself.

Thus, resulting into a deadlock in the Devres destructor of the device
resource, as in the following backtrace.

	sysrq: Show Blocked State
	task:rmmod           state:D stack:0     pid:1331  tgid:1331  ppid:1330   task_flags:0x400100 flags:0x00000010
	Call trace:
	 __switch_to+0x190/0x294 (T)
	 __schedule+0x878/0xf10
	 schedule+0x4c/0xcc
	 schedule_timeout+0x44/0x118
	 wait_for_common+0xc0/0x18c
	 wait_for_completion+0x18/0x24
	 _RINvNtCs4gKlGRWyJ5S_4core3ptr13drop_in_placeINtNtNtCsgzhNYVB7wSz_6kernel4sync3arc3ArcINtNtBN_6devres6DevresmEEECsRdyc7Hyps3_15rust_driver_pci+0x68/0xe8 [rust_driver_pci]
	 _RINvNvNtCsgzhNYVB7wSz_6kernel6devres16register_foreign8callbackINtNtCs4gKlGRWyJ5S_4core3pin3PinINtNtNtB6_5alloc4kbox3BoxINtNtNtB6_4sync3arc3ArcINtB4_6DevresmEENtNtB1A_9allocator7KmallocEEECsRdyc7Hyps3_15rust_driver_pci+0x34/0xc8 [rust_driver_pci]
	 devm_action_release+0x14/0x20
	 devres_release_all+0xb8/0x118
	 device_release_driver_internal+0x1c4/0x28c
	 driver_detach+0x94/0xd4
	 bus_remove_driver+0xdc/0x11c
	 driver_unregister+0x34/0x58
	 pci_unregister_driver+0x20/0x80
	 __arm64_sys_delete_module+0x1d8/0x254
	 invoke_syscall+0x40/0xcc
	 el0_svc_common+0x8c/0xd8
	 do_el0_svc+0x1c/0x28
	 el0_svc+0x54/0x1d4
	 el0t_64_sync_handler+0x84/0x12c
	 el0t_64_sync+0x198/0x19c

In order to fix this, re-introduce the internal reference count.

Reported-by: Boris Brezillon &lt;boris.brezillon@collabora.com&gt;
Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/.E2.9C.94.20Deadlock.20caused.20by.20nested.20Devres/with/571242651
Reported-by: Markus Probst &lt;markus.probst@posteo.de&gt;
Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/.E2.9C.94.20Devres.20inside.20Devres.20stuck.20on.20cleanup/with/571239721
Reported-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Closes: https://gitlab.freedesktop.org/panfrost/linux/-/merge_requests/56#note_3282757
Fixes: f5d3ef25d238 ("rust: devres: get rid of Devres' inner Arc")
Reviewed-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Tested-by: Boris Brezillon &lt;boris.brezillon@collabora.com&gt;
Link: https://patch.msgid.link/20260205222529.91465-1-dakr@kernel.org
[ Call clone() prior to devm_add_action(). - Danilo ]
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: io: separate generic I/O helpers from MMIO implementation</title>
<updated>2026-01-23T20:20:11+00:00</updated>
<author>
<name>Zhi Wang</name>
<email>zhiw@nvidia.com</email>
</author>
<published>2026-01-21T20:22:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=121d87b28e1d9061d3aaa156c43a627d3cb5e620'/>
<id>121d87b28e1d9061d3aaa156c43a627d3cb5e620</id>
<content type='text'>
The previous Io&lt;SIZE&gt; type combined both the generic I/O access helpers
and MMIO implementation details in a single struct. This coupling prevented
reusing the I/O helpers for other backends, such as PCI configuration
space.

Establish a clean separation between the I/O interface and concrete
backends by separating generic I/O helpers from MMIO implementation.

Introduce a new trait hierarchy to handle different access capabilities:

- IoCapable&lt;T&gt;: A marker trait indicating that a backend supports I/O
  operations of a certain type (u8, u16, u32, or u64).

- Io trait: Defines fallible (try_read8, try_write8, etc.) and infallibile
  (read8, write8, etc.) I/O methods with runtime bounds checking and
  compile-time bounds checking.

- IoKnownSize trait: The marker trait for types support infallible I/O
  methods.

Move the MMIO-specific logic into a dedicated Mmio&lt;SIZE&gt; type that
implements the Io traits. Rename IoRaw to MmioRaw and update consumers to
use the new types.

Cc: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Cc: Alice Ryhl &lt;aliceryhl@google.com&gt;
Cc: Bjorn Helgaas &lt;helgaas@kernel.org&gt;
Cc: Gary Guo &lt;gary@garyguo.net&gt;
Cc: Danilo Krummrich &lt;dakr@kernel.org&gt;
Cc: John Hubbard &lt;jhubbard@nvidia.com&gt;
Signed-off-by: Zhi Wang &lt;zhiw@nvidia.com&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Link: https://patch.msgid.link/20260121202212.4438-3-zhiw@nvidia.com
[ Add #[expect(unused)] to define_{read,write}!(). - Danilo ]
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The previous Io&lt;SIZE&gt; type combined both the generic I/O access helpers
and MMIO implementation details in a single struct. This coupling prevented
reusing the I/O helpers for other backends, such as PCI configuration
space.

Establish a clean separation between the I/O interface and concrete
backends by separating generic I/O helpers from MMIO implementation.

Introduce a new trait hierarchy to handle different access capabilities:

- IoCapable&lt;T&gt;: A marker trait indicating that a backend supports I/O
  operations of a certain type (u8, u16, u32, or u64).

- Io trait: Defines fallible (try_read8, try_write8, etc.) and infallibile
  (read8, write8, etc.) I/O methods with runtime bounds checking and
  compile-time bounds checking.

- IoKnownSize trait: The marker trait for types support infallible I/O
  methods.

Move the MMIO-specific logic into a dedicated Mmio&lt;SIZE&gt; type that
implements the Io traits. Rename IoRaw to MmioRaw and update consumers to
use the new types.

Cc: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Cc: Alice Ryhl &lt;aliceryhl@google.com&gt;
Cc: Bjorn Helgaas &lt;helgaas@kernel.org&gt;
Cc: Gary Guo &lt;gary@garyguo.net&gt;
Cc: Danilo Krummrich &lt;dakr@kernel.org&gt;
Cc: John Hubbard &lt;jhubbard@nvidia.com&gt;
Signed-off-by: Zhi Wang &lt;zhiw@nvidia.com&gt;
Reviewed-by: Alice Ryhl &lt;aliceryhl@google.com&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Link: https://patch.msgid.link/20260121202212.4438-3-zhiw@nvidia.com
[ Add #[expect(unused)] to define_{read,write}!(). - Danilo ]
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>rust: devres: style for imports</title>
<updated>2026-01-23T18:16:11+00:00</updated>
<author>
<name>Zhi Wang</name>
<email>zhiw@nvidia.com</email>
</author>
<published>2026-01-21T20:22:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=7043698aee6b6f61415ebb49b7e95fdfb9373a77'/>
<id>7043698aee6b6f61415ebb49b7e95fdfb9373a77</id>
<content type='text'>
Convert all imports in the devres to use "kernel vertical" style.

Cc: Gary Guo &lt;gary@garyguo.net&gt;
Cc: Miguel Ojeda &lt;ojeda@kernel.org&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Signed-off-by: Zhi Wang &lt;zhiw@nvidia.com&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Link: https://patch.msgid.link/20260121202212.4438-2-zhiw@nvidia.com
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Convert all imports in the devres to use "kernel vertical" style.

Cc: Gary Guo &lt;gary@garyguo.net&gt;
Cc: Miguel Ojeda &lt;ojeda@kernel.org&gt;
Reviewed-by: Gary Guo &lt;gary@garyguo.net&gt;
Signed-off-by: Zhi Wang &lt;zhiw@nvidia.com&gt;
Reviewed-by: Alexandre Courbot &lt;acourbot@nvidia.com&gt;
Link: https://patch.msgid.link/20260121202212.4438-2-zhiw@nvidia.com
Signed-off-by: Danilo Krummrich &lt;dakr@kernel.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
