linux/rust/kernel
Danilo Krummrich ba268514ea rust: devres: fix race condition due to nesting
Commit f5d3ef25d2 ("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 <boris.brezillon@collabora.com>
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 <markus.probst@posteo.de>
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 <aliceryhl@google.com>
Closes: https://gitlab.freedesktop.org/panfrost/linux/-/merge_requests/56#note_3282757
Fixes: f5d3ef25d2 ("rust: devres: get rid of Devres' inner Arc")
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Tested-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://patch.msgid.link/20260205222529.91465-1-dakr@kernel.org
[ Call clone() prior to devm_add_action(). - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-02-07 01:03:49 +01:00
..
alloc rust: alloc: use kernel::fmt 2025-10-20 04:04:23 +02:00
block rust: block: update ARef and AlwaysRefCounted imports from sync::aref 2025-11-05 18:24:10 -07:00
debugfs rust: debugfs: use pin_init::zeroed() for file_operations 2026-01-25 20:53:30 +01:00
device rust: device: replace kernel::c_str! with C-Strings 2025-12-22 17:30:24 +01:00
drm drm-next for 6.19-rc1: 2025-12-04 08:53:30 -08:00
fs rust: fs: add file::Offset type alias 2025-11-05 00:05:38 +01:00
io Linux 6.19-rc7 2026-01-26 13:23:52 +01:00
irq Linux 6.19-rc7 2026-01-26 13:23:52 +01:00
list rust: list: remove nonexistent generic parameter in link 2025-07-20 19:29:19 +02:00
mm mm: introduce VMA flags bitmap type 2025-11-29 10:41:09 -08:00
net Networking changes for 6.18. 2025-10-02 15:17:01 -07:00
num rust: num: bounded: rename try_into_bitint to try_into_bounded 2025-11-24 16:38:23 +01:00
pci rust: io: move MIN_SIZE and io_addr_assert to IoKnownSize 2026-02-01 22:23:59 +01:00
str rust: str: add radix prefixed integer parsing functions 2025-11-03 14:40:45 +01:00
sync rust: sync: atomic: separate import "blocks" 2025-12-06 08:44:10 -08:00
time rust: add udelay() function 2025-11-04 13:25:29 +01:00
.gitignore rust: Add warn_on macro 2025-07-23 02:05:58 +02:00
acpi.rs rust: acpi: replace core::mem::zeroed with pin_init::zeroed 2025-10-27 20:27:05 +01:00
alloc.rs Summary of significant series in this pull request: 2025-10-02 18:18:33 -07:00
auxiliary.rs Linux 6.19-rc7 2026-01-26 13:23:52 +01:00
bitmap.rs rust: bitmap: add BitmapVec::new_inline() 2025-11-26 11:25:35 -05:00
bits.rs rust: bits: add support for bits/genmask macros 2025-07-19 23:18:18 +02:00
block.rs rust: block: add block related constants 2025-09-02 05:23:56 -06:00
bug.rs rust: Add warn_on macro 2025-07-23 02:05:58 +02:00
build_assert.rs rust: add build_error! to the prelude 2025-01-10 00:19:09 +01:00
clk.rs rust: clk: use CStr::as_char_ptr 2025-10-22 07:15:19 +02:00
configfs.rs rust: configfs: use CStr::as_char_ptr 2025-10-22 07:14:57 +02:00
cpu.rs rust: kernel: cpu: mark CpuId::current() inline 2025-09-14 23:58:45 +02:00
cpufreq.rs Merge 6.18-rc3 into driver-core-next 2025-10-27 08:02:50 +01:00
cpumask.rs rust: cpumask: Mark CpumaskVar as transparent 2025-08-14 09:55:47 +05:30
cred.rs Char/Misc/IIO/Binder changes for 6.18-rc1 2025-10-04 16:26:32 -07:00
debugfs.rs rust: debugfs: Use kernel Atomic type in docs example 2026-01-19 15:02:46 +01:00
device.rs Linux 6.19-rc7 2026-01-26 13:23:52 +01:00
device_id.rs rust: device_id: replace incorrect word in safety documentation 2025-12-29 14:09:18 +01:00
devres.rs rust: devres: fix race condition due to nesting 2026-02-07 01:03:49 +01:00
dma.rs rust: dma: allow drivers to tune max segment size 2026-01-28 16:53:24 +01:00
driver.rs Linux 6.19-rc7 2026-01-26 13:23:52 +01:00
error.rs rust: replace CStr with core::ffi::CStr 2025-10-22 07:47:27 +02:00
faux.rs rust: faux: use "kernel vertical" style for imports 2026-01-07 19:56:00 +01:00
firmware.rs rust: firmware: replace kernel::c_str! with C-Strings 2025-11-17 00:53:47 +01:00
fmt.rs rust: support formatting of foreign types 2025-10-22 07:15:31 +02:00
fs.rs rust: fs: add Kiocb struct 2025-09-06 13:27:20 +02:00
generated_arch_reachable_asm.rs.S rust: Add warn_on macro 2025-07-23 02:05:58 +02:00
generated_arch_static_branch_asm.rs.S rust: jump_label: skip formatting generated file 2024-11-20 13:32:42 -05:00
generated_arch_warn_asm.rs.S rust: Add warn_on macro 2025-07-23 02:05:58 +02:00
i2c.rs rust: driver: drop device private data post unbind 2026-01-16 01:17:29 +01:00
id_pool.rs rust: id_pool: do not immediately acquire new ids 2025-12-02 14:17:09 -05:00
init.rs rust: allow clippy::disallowed_names for doctests 2025-11-17 22:53:27 +01:00
io.rs rust: io: move MIN_SIZE and io_addr_assert to IoKnownSize 2026-02-01 22:23:59 +01:00
ioctl.rs rust: start using the #[expect(...)] attribute 2024-10-07 21:39:57 +02:00
iov.rs rust: iov: add iov_iter abstractions for ITER_DEST 2025-09-06 13:27:20 +02:00
irq.rs rust: irq: add support for threaded IRQs and handlers 2025-08-12 20:22:09 +02:00
jump_label.rs rust: jump_label: skip formatting generated file 2024-11-20 13:32:42 -05:00
kunit.rs linux_kselftest-kunit-6.18-rc1 2025-10-01 19:15:11 -07:00
lib.rs rust: Add soc_device support 2025-12-28 12:43:56 +01:00
list.rs rust: list: add warning to List::remove docs about mem::take 2025-11-26 13:26:59 +01:00
maple_tree.rs rust: maple_tree: rcu_read_lock() in destructor to silence lockdep 2025-12-23 11:23:15 -08:00
miscdevice.rs Char/Misc/IIO/Binder changes for 6.18-rc1 2025-10-04 16:26:32 -07:00
mm.rs rust: mm: update ARef and AlwaysRefCounted imports from sync::aref 2025-09-13 16:55:15 -07:00
module_param.rs Modules changes for v6.19-rc1 2025-12-06 08:27:07 -08:00
net.rs rust: core abstractions for network PHY drivers 2023-12-15 09:35:50 +00:00
num.rs rust: num: add Bounded integer wrapping type 2025-11-19 00:22:24 +01:00
of.rs rust: of: use core::ffi::CStr method names 2025-09-16 09:26:59 +02:00
opp.rs Rust changes for v6.19 2025-12-03 14:16:49 -08:00
page.rs Char/Misc/IIO/Binder changes for 6.18-rc1 2025-10-04 16:26:32 -07:00
pci.rs rust: pci: re-export ConfigSpace 2026-02-01 22:18:24 +01:00
pid_namespace.rs rust: pid_namespace: update AlwaysRefCounted imports from sync::aref 2025-08-19 13:08:41 +02:00
platform.rs Linux 6.19-rc7 2026-01-26 13:23:52 +01:00
prelude.rs drm-next for 6.19-rc1: 2025-12-04 08:53:30 -08:00
print.rs rust: use kernel::{fmt,prelude::fmt!} 2025-07-21 01:16:35 +02:00
processor.rs rust: Add cpu_relax() helper 2025-08-21 16:58:07 +02:00
ptr.rs rust: remove spurious use core::fmt::Debug 2025-10-20 04:04:24 +02:00
pwm.rs pwm: Fix Rust formatting 2025-11-13 10:21:01 +01:00
rbtree.rs rust: rbtree: add immutable cursor 2025-11-16 21:56:57 +01:00
regulator.rs rust: regulator: use CStr::as_char_ptr 2025-10-22 07:14:57 +02:00
revocable.rs Rust changes for v6.17 2025-08-03 13:49:10 -07:00
scatterlist.rs rust: scatterlist: Update ARef imports to use sync::aref 2025-12-18 17:25:45 +01:00
security.rs rust_binder: add Rust Binder driver 2025-09-19 09:40:46 +02:00
seq_file.rs rust: replace CStr with core::ffi::CStr 2025-10-22 07:47:27 +02:00
sizes.rs rust: sizes: add constants up to SZ_2G 2025-06-23 18:12:30 +02:00
slice.rs rust: slice: fix broken intra-doc links 2025-11-20 10:13:35 +00:00
soc.rs rust: Add soc_device support 2025-12-28 12:43:56 +01:00
static_assert.rs rust: use absolute paths in macros referencing core and kernel 2025-05-23 00:12:14 +02:00
std_vendor.rs rust: convert raw URLs to Markdown autolinks in comments 2025-05-12 00:20:25 +02:00
str.rs Modules changes for v6.19-rc1 2025-12-06 08:27:07 -08:00
sync.rs Modules changes for v6.19-rc1 2025-12-06 08:27:07 -08:00
task.rs rust: task: update ARef and AlwaysRefCounted imports from sync::aref 2025-09-08 00:11:19 +02:00
time.rs rust: time: Implement basic arithmetic operations for Delta 2025-09-04 16:56:48 +02:00
tracepoint.rs rust: add tracepoint support 2024-11-04 16:21:44 -05:00
transmute.rs rust: transmute: add from_bytes_prefix family of methods 2025-11-05 20:29:34 +09:00
types.rs rust: allow clippy::disallowed_names for doctests 2025-11-17 22:53:27 +01:00
uaccess.rs rust: uaccess: add UserSliceWriter::write_slice_file() 2025-11-05 00:35:37 +01:00
usb.rs rust: driver: drop device private data post unbind 2026-01-16 01:17:29 +01:00
workqueue.rs rust: pin-init: add pin projections to #[pin_data] 2025-09-11 23:26:20 +02:00
xarray.rs rust: types: add FOREIGN_ALIGN to ForeignOwnable 2025-07-14 23:55:24 +02:00