summaryrefslogtreecommitdiff
path: root/rust/kernel/devres.rs
AgeCommit message (Collapse)Author
11 hoursMerge tag 'rust-6.17' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux Pull Rust updates from Miguel Ojeda: "Toolchain and infrastructure: - Enable a set of Clippy lints: 'ptr_as_ptr', 'ptr_cast_constness', 'as_ptr_cast_mut', 'as_underscore', 'cast_lossless' and 'ref_as_ptr' These are intended to avoid type casts with the 'as' operator, which are quite powerful, into restricted variants that are less powerful and thus should help to avoid mistakes - Remove the 'author' key now that most instances were moved to the plural one in the previous cycle 'kernel' crate: - New 'bug' module: add 'warn_on!' macro which reuses the existing 'BUG'/'WARN' infrastructure, i.e. it respects the usual sysctls and kernel parameters: warn_on!(value == 42); To avoid duplicating the assembly code, the same strategy is followed as for the static branch code in order to share the assembly between both C and Rust This required a few rearrangements on C arch headers -- the existing C macros should still generate the same outputs, thus no functional change expected there - 'workqueue' module: add delayed work items, including a 'DelayedWork' struct, a 'impl_has_delayed_work!' macro and an 'enqueue_delayed' method, e.g.: /// Enqueue the struct for execution on the system workqueue, /// where its value will be printed 42 jiffies later. fn print_later(value: Arc<MyStruct>) { let _ = workqueue::system().enqueue_delayed(value, 42); } - New 'bits' module: add support for 'bit' and 'genmask' functions, with runtime- and compile-time variants, e.g.: static_assert!(0b00010000 == bit_u8(4)); static_assert!(0b00011110 == genmask_u8(1..=4)); assert!(checked_bit_u32(u32::BITS).is_none()); - 'uaccess' module: add 'UserSliceReader::strcpy_into_buf', which reads NUL-terminated strings from userspace into a '&CStr' Introduce 'UserPtr' newtype, similar in purpose to '__user' in C, to minimize mistakes handling userspace pointers, including mixing them up with integers and leaking them via the 'Debug' trait. Add it to the prelude, too - Start preparations for the replacement of our custom 'CStr' type with the analogous type in the 'core' standard library. This will take place across several cycles to make it easier. For this one, it includes a new 'fmt' module, using upstream method names and some other cleanups Replace 'fmt!' with a re-export, which helps Clippy lint properly, and clean up the found 'uninlined-format-args' instances - 'dma' module: - Clarify wording and be consistent in 'coherent' nomenclature - Convert the 'read!()' and 'write!()' macros to return a 'Result' - Add 'as_slice()', 'write()' methods in 'CoherentAllocation' - Expose 'count()' and 'size()' in 'CoherentAllocation' and add the corresponding type invariants - Implement 'CoherentAllocation::dma_handle_with_offset()' - 'time' module: - Make 'Instant' generic over clock source. This allows the compiler to assert that arithmetic expressions involving the 'Instant' use 'Instants' based on the same clock source - Make 'HrTimer' generic over the timer mode. 'HrTimer' timers take a 'Duration' or an 'Instant' when setting the expiry time, depending on the timer mode. With this change, the compiler can check the type matches the timer mode - Add an abstraction for 'fsleep'. 'fsleep' is a flexible sleep function that will select an appropriate sleep method depending on the requested sleep time - Avoid 64-bit divisions on 32-bit hardware when calculating timestamps - Seal the 'HrTimerMode' trait. This prevents users of the 'HrTimerMode' from implementing the trait on their own types - Pass the correct timer mode ID to 'hrtimer_start_range_ns()' - 'list' module: remove 'OFFSET' constants, allowing to remove pointer arithmetic; now 'impl_list_item!' invokes 'impl_has_list_links!' or 'impl_has_list_links_self_ptr!'. Other simplifications too - 'types' module: remove 'ForeignOwnable::PointedTo' in favor of a constant, which avoids exposing the type of the opaque pointer, and require 'into_foreign' to return non-null Remove the 'Either<L, R>' type as well. It is unused, and we want to encourage the use of custom enums for concrete use cases - 'sync' module: implement 'Borrow' and 'BorrowMut' for 'Arc' types to allow them to be used in generic APIs - 'alloc' module: implement 'Borrow' and 'BorrowMut' for 'Box<T, A>'; and 'Borrow', 'BorrowMut' and 'Default' for 'Vec<T, A>' - 'Opaque' type: add 'cast_from' method to perform a restricted cast that cannot change the inner type and use it in callers of 'container_of!'. Rename 'raw_get' to 'cast_into' to match it - 'rbtree' module: add 'is_empty' method - 'sync' module: new 'aref' submodule to hold 'AlwaysRefCounted' and 'ARef', which are moved from the too general 'types' module which we want to reduce or eventually remove. Also fix a safety comment in 'static_lock_class' 'pin-init' crate: - Add 'impl<T, E> [Pin]Init<T, E> for Result<T, E>', so results are now (pin-)initializers - Add 'Zeroable::init_zeroed()' that delegates to 'init_zeroed()' - New 'zeroed()', a safe version of 'mem::zeroed()' and also provide it via 'Zeroable::zeroed()' - Implement 'Zeroable' for 'Option<&T>', 'Option<&mut T>' and for 'Option<[unsafe] [extern "abi"] fn(...args...) -> ret>' for '"Rust"' and '"C"' ABIs and up to 20 arguments - Changed blanket impls of 'Init' and 'PinInit' from 'impl<T, E> [Pin]Init<T, E> for T' to 'impl<T> [Pin]Init<T> for T' - Renamed 'zeroed()' to 'init_zeroed()' - Upstream dev news: improve CI more to deny warnings, use '--all-targets'. Check the synchronization status of the two '-next' branches in upstream and the kernel MAINTAINERS: - Add Vlastimil Babka, Liam R. Howlett, Uladzislau Rezki and Lorenzo Stoakes as reviewers (thanks everyone) And a few other cleanups and improvements" * tag 'rust-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (76 commits) rust: Add warn_on macro arm64/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust riscv/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust x86/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust rust: kernel: move ARef and AlwaysRefCounted to sync::aref rust: sync: fix safety comment for `static_lock_class` rust: types: remove `Either<L, R>` rust: kernel: use `core::ffi::CStr` method names rust: str: add `CStr` methods matching `core::ffi::CStr` rust: str: remove unnecessary qualification rust: use `kernel::{fmt,prelude::fmt!}` rust: kernel: add `fmt` module rust: kernel: remove `fmt!`, fix clippy::uninlined-format-args scripts: rust: emit path candidates in panic message scripts: rust: replace length checks with match rust: list: remove nonexistent generic parameter in link rust: bits: add support for bits/genmask macros rust: list: remove OFFSET constants rust: list: add `impl_list_item!` examples rust: list: use fully qualified path ...
2025-07-15rust: devres: provide an accessor for the deviceDanilo Krummrich
Provide an accessor for the Device a Devres instance has been created with. For instance, this is useful when registrations want to provide a &Device<Bound> for a scope that is protected by Devres. Suggested-by: Benno Lossin <lossin@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250713182737.64448-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-15rust: devres: initialize Devres::inner::data lastDanilo Krummrich
Users may want to access the Devres object from callbacks registered through the initialization of Devres::inner::data. For those accesses to be valid, Devres::inner::data must be initialized last [1]. Credit to Boqun for spotting this [2]. Link: https://lore.kernel.org/lkml/DBBPHO26CPBS.2OVI1OERCB2J5@kernel.org/ [1] Link: https://lore.kernel.org/lkml/aHSmxWeIy3L-AKIV@Mac.home/ [2] Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250714113712.22158-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-05rust: devres: remove unused importTamir Duberstein
As far as I can tell, `c_str` was never used, hence remove it. Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250704-cstr-include-devres-v1-1-4ee9e56fca09@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28rust: devres: get rid of Devres' inner ArcDanilo Krummrich
So far Devres uses an inner memory allocation and reference count, i.e. an inner Arc, in order to ensure that the devres callback can't run into a use-after-free in case where the Devres object is dropped while the devres callback runs concurrently. Instead, use a completion in order to avoid a potential UAF: In Devres::drop(), if we detect that we can't remove the devres action anymore, we wait for the completion that is completed from the devres callback. If, in turn, we were able to successfully remove the devres action, we can just go ahead. This, again, allows us to get rid of the internal Arc, and instead let Devres consume an `impl PinInit<T, E>` in order to return an `impl PinInit<Devres<T>, E>`, which enables us to get away with less memory allocations. Additionally, having the resulting explicit synchronization in Devres::drop() prevents potential subtle undesired side effects of the devres callback dropping the final Arc reference asynchronously within the devres callback. Reviewed-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Link: https://lore.kernel.org/r/20250626200054.243480-4-dakr@kernel.org [ Move '# Invariants' below '# Examples'. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28rust: devres: replace Devres::new_foreign_owned()Danilo Krummrich
Replace Devres::new_foreign_owned() with devres::register(). The current implementation of Devres::new_foreign_owned() creates a full Devres container instance, including the internal Revocable and completion. However, none of that is necessary for the intended use of giving full ownership of an object to devres and getting it dropped once the given device is unbound. Hence, implement devres::register(), which is limited to consume the given data, wrap it in a KBox and drop the KBox once the given device is unbound, without any other synchronization. Cc: Dave Airlie <airlied@redhat.com> Cc: Simona Vetter <simona.vetter@ffwll.ch> Cc: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250626200054.243480-3-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28rust: revocable: support fallible PinInit typesDanilo Krummrich
Currently, Revocable::new() only supports infallible PinInit implementations, i.e. impl PinInit<T, Infallible>. This has been sufficient so far, since users such as Devres do not support fallibility. Since this is about to change, make Revocable::new() generic over the error type E. Reviewed-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250626200054.243480-2-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28rust: devres: require T: Send for DevresDanilo Krummrich
Due to calling Revocable::revoke() from Devres::devres_callback() T may be dropped from Devres::devres_callback() and hence must be Send. Fix this by adding the corresponding bound to Devres and DevresInner. Reported-by: Boqun Feng <boqun.feng@gmail.com> Closes: https://lore.kernel.org/lkml/aFzI5L__OcB9hqdG@Mac.home/ Fixes: 76c01ded724b ("rust: add devres abstraction") Reviewed-by: Boqun Feng <boqun.fenng@gmail.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250626132544.72866-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-24rust: Use consistent "# Examples" heading style in rustdocViresh Kumar
Use a consistent `# Examples` heading in rustdoc across the codebase. Some modules previously used `## Examples` (even when they should be available as top-level headers), while others used `# Example`, which deviates from the preferred `# Examples` style. Suggested-by: Miguel Ojeda <ojeda@kernel.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/ddd5ce0ac20c99a72a4f1e4322d3de3911056922.1749545815.git.viresh.kumar@linaro.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-06-22rust: enable `clippy::as_underscore` lintTamir Duberstein
In Rust 1.63.0, Clippy introduced the `as_underscore` lint [1]: > The conversion might include lossy conversion or a dangerous cast that > might go undetected due to the type being inferred. > > The lint is allowed by default as using `_` is less wordy than always > specifying the type. Always specifying the type is especially helpful in function call contexts where the inferred type may change at a distance. Specifying the type also allows Clippy to spot more cases of `useless_conversion`. The primary downside is the need to specify the type in trivial getters. There are 4 such functions: 3 have become slightly less ergonomic, 1 was revealed to be a `useless_conversion`. While this doesn't eliminate unchecked `as` conversions, it makes such conversions easier to scrutinize. It also has the slight benefit of removing a degree of freedom on which to bikeshed. Thus apply the changes and enable the lint -- no functional change intended. Link: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore [1] Reviewed-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20250615-ptr-as-ptr-v12-4-f43b024581e8@gmail.com [ Changed `isize` to `c_long`. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-06-22rust: enable `clippy::as_ptr_cast_mut` lintTamir Duberstein
In Rust 1.66.0, Clippy introduced the `as_ptr_cast_mut` lint [1]: > Since `as_ptr` takes a `&self`, the pointer won’t have write > permissions unless interior mutability is used, making it unlikely > that having it as a mutable pointer is correct. There is only one affected callsite, and the change amounts to replacing `as _` with `.cast_mut().cast()`. This doesn't change the semantics, but is more descriptive of what's going on. Apply this change and enable the lint -- no functional change intended. Link: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut [1] Reviewed-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20250615-ptr-as-ptr-v12-3-f43b024581e8@gmail.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-06-22rust: enable `clippy::ptr_as_ptr` lintTamir Duberstein
In Rust 1.51.0, Clippy introduced the `ptr_as_ptr` lint [1]: > Though `as` casts between raw pointers are not terrible, > `pointer::cast` is safer because it cannot accidentally change the > pointer's mutability, nor cast the pointer to other types like `usize`. There are a few classes of changes required: - Modules generated by bindgen are marked `#[allow(clippy::ptr_as_ptr)]`. - Inferred casts (` as _`) are replaced with `.cast()`. - Ascribed casts (` as *... T`) are replaced with `.cast::<T>()`. - Multistep casts from references (` as *const _ as *const T`) are replaced with `core::ptr::from_ref(&x).cast()` with or without `::<T>` according to the previous rules. The `core::ptr::from_ref` call is required because `(x as *const _).cast::<T>()` results in inference failure. - Native literal C strings are replaced with `c_str!().as_char_ptr()`. - `*mut *mut T as _` is replaced with `let *mut *const T = (*mut *mut T)`.cast();` since pointer to pointer can be confusing. Apply these changes and enable the lint -- no functional change intended. Link: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr [1] Reviewed-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Tejun Heo <tj@kernel.org> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20250615-ptr-as-ptr-v12-1-f43b024581e8@gmail.com [ Added `.cast()` for `opp`. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-06-13rust: devres: do not dereference to the internal RevocableDanilo Krummrich
We can't expose direct access to the internal Revocable, since this allows users to directly revoke the internal Revocable without Devres having the chance to synchronize with the devres callback -- we have to guarantee that the internal Revocable has been fully revoked before the device is fully unbound. Hence, remove the corresponding Deref implementation and, instead, provide indirect accessors for the internal Revocable. Note that we can still support Devres::revoke() by implementing the required synchronization (which would be almost identical to the synchronization in Devres::drop()). Fixes: 76c01ded724b ("rust: add devres abstraction") Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250611174827.380555-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-13rust: devres: fix race in Devres::drop()Danilo Krummrich
In Devres::drop() we first remove the devres action and then drop the wrapped device resource. The design goal is to give the owner of a Devres object control over when the device resource is dropped, but limit the overall scope to the corresponding device being bound to a driver. However, there's a race that was introduced with commit 8ff656643d30 ("rust: devres: remove action in `Devres::drop`"), but also has been (partially) present from the initial version on. In Devres::drop(), the devres action is removed successfully and subsequently the destructor of the wrapped device resource runs. However, there is no guarantee that the destructor of the wrapped device resource completes before the driver core is done unbinding the corresponding device. If in Devres::drop(), the devres action can't be removed, it means that the devres callback has been executed already, or is still running concurrently. In case of the latter, either Devres::drop() wins revoking the Revocable or the devres callback wins revoking the Revocable. If Devres::drop() wins, we (again) have no guarantee that the destructor of the wrapped device resource completes before the driver core is done unbinding the corresponding device. CPU0 CPU1 ------------------------------------------------------------------------ Devres::drop() { Devres::devres_callback() { self.data.revoke() { this.data.revoke() { is_available.swap() == true is_available.swap == false } } // [...] // device fully unbound drop_in_place() { // release device resource } } } Depending on the specific device resource, this can potentially lead to user-after-free bugs. In order to fix this, implement the following logic. In the devres callback, we're always good when we get to revoke the device resource ourselves, i.e. Revocable::revoke() returns true. If Revocable::revoke() returns false, it means that Devres::drop(), concurrently, already drops the device resource and we have to wait for Devres::drop() to signal that it finished dropping the device resource. Note that if we hit the case where we need to wait for the completion of Devres::drop() in the devres callback, it means that we're actually racing with a concurrent Devres::drop() call, which already started revoking the device resource for us. This is rather unlikely and means that the concurrent Devres::drop() already started doing our work and we just need to wait for it to complete it for us. Hence, there should not be any additional overhead from that. (Actually, for now it's even better if Devres::drop() does the work for us, since it can bypass the synchronize_rcu() call implied by Revocable::revoke(), but this goes away anyways once I get to implement the split devres callback approach, which allows us to first flip the atomics of all registered Devres objects of a certain device, execute a single synchronize_rcu() and then drop all revocable objects.) In Devres::drop() we try to revoke the device resource. If that is *not* successful, it means that the devres callback already did and we're good. Otherwise, we try to remove the devres action, which, if successful, means that we're good, since the device resource has just been revoked by us *before* we removed the devres action successfully. If the devres action could not be removed, it means that the devres callback must be running concurrently, hence we signal that the device resource has been revoked by us, using the completion. This makes it safe to drop a Devres object from any task and at any point of time, which is one of the design goals. Fixes: 76c01ded724b ("rust: add devres abstraction") Reported-by: Alice Ryhl <aliceryhl@google.com> Closes: https://lore.kernel.org/lkml/aD64YNuqbPPZHAa5@google.com/ Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250612121817.1621-4-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-12rust: devres: fix doctest build under `!CONFIG_PCI`Miguel Ojeda
The doctest requires `CONFIG_PCI`: error[E0432]: unresolved import `kernel::pci` --> rust/doctests_kernel_generated.rs:2689:44 | 2689 | use kernel::{device::Core, devres::Devres, pci}; | ^^^ no `pci` in the root | note: found an item that was configured out --> rust/kernel/lib.rs:96:9 note: the item is gated here --> rust/kernel/lib.rs:95:1 Thus conditionally compile it (which still checks the syntax). Fixes: f301cb978c06 ("rust: devres: implement Devres::access()") Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250511182533.1016163-1-ojeda@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-04rust: devres: implement Devres::access()Danilo Krummrich
Implement a direct accessor for the data stored within the Devres for cases where we can prove that we own a reference to a Device<Bound> (i.e. a bound device) of the same device that was used to create the corresponding Devres container. Usually, when accessing the data stored within a Devres container, it is not clear whether the data has been revoked already due to the device being unbound and, hence, we have to try whether the access is possible and subsequently keep holding the RCU read lock for the duration of the access. However, when we can prove that we hold a reference to Device<Bound> matching the device the Devres container has been created with, we can guarantee that the device is not unbound for the duration of the lifetime of the Device<Bound> reference and, hence, it is not possible for the data within the Devres container to be revoked. Therefore, in this case, we can bypass the atomic check and the RCU read lock, which is a great optimization and simplification for drivers. Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Acked-by: Boqun Feng <boqun.feng@gmail.com> Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com> Link: https://lore.kernel.org/r/20250428140137.468709-3-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-17rust: devres: require a bound deviceDanilo Krummrich
Require the Bound device context to be able to a new Devres container. This ensures that we can't register devres callbacks for unbound devices. Link: https://lore.kernel.org/r/20250413173758.12068-9-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-02-25rust: io: fix devres test with new io accessor functionsFiona Behrens
Fix doctest of `Devres` which still used `writeb` instead of `write8`. Fixes: 354fd6e86fac ("rust: io: rename `io::Io` accessors") Signed-off-by: Fiona Behrens <me@kloenk.dev> Link: https://lore.kernel.org/r/20250224-rust-iowrite-read8-fix-v1-1-c6abee346897@kloenk.dev Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-01-10rust: devres: remove action in `Devres::drop`Danilo Krummrich
So far `DevresInner` is kept alive, even if `Devres` is dropped until the devres callback is executed to avoid a WARN() when the action has been released already. With the introduction of devm_remove_action_nowarn() we can remove the action in `Devres::drop`, handle the case where the action has been released already and hence also free `DevresInner`. Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20250107122609.8135-2-dakr@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2024-12-20rust: add devres abstractionDanilo Krummrich
Add a Rust abstraction for the kernel's devres (device resource management) implementation. The Devres type acts as a container to manage the lifetime and accessibility of device bound resources. Therefore it registers a devres callback and revokes access to the resource on invocation. Users of the Devres abstraction can simply free the corresponding resources in their Drop implementation, which is invoked when either the Devres instance goes out of scope or the devres callback leads to the resource being revoked, which implies a call to drop_in_place(). Signed-off-by: Danilo Krummrich <dakr@kernel.org> Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Link: https://lore.kernel.org/r/20241219170425.12036-9-dakr@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>