mirror of
https://github.com/torvalds/linux.git
synced 2026-01-25 07:47:50 +00:00
Partially revert "rust: drm: gem: Implement AlwaysRefCounted for all gem objects automatically"
Currently in order to implement AlwaysRefCounted for gem objects, we use a
blanket implementation:
unsafe impl<T: IntoGEMObject> AlwaysRefCounted for T { … }
While this technically works, it comes with the rather unfortunate downside
that attempting to create a similar blanket implementation in any other
kernel crate will now fail in a rather confusing way.
Using an example from the (not yet upstream) rust DRM KMS bindings, if we
were to add:
unsafe impl<T: RcModeObject> AlwaysRefCounted for T { … }
Then the moment that both blanket implementations are present in the same
kernel tree, compilation fails with the following:
error[E0119]: conflicting implementations of trait `types::AlwaysRefCounted`
--> rust/kernel/drm/kms.rs:504:1
|
504 | unsafe impl<T: RcModeObject> AlwaysRefCounted for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
::: rust/kernel/drm/gem/mod.rs:97:1
|
97 | unsafe impl<T: IntoGEMObject> AlwaysRefCounted for T {
| ---------------------------------------------------- first implementation here
So, revert these changes for now. The proper fix for this is to introduce a
macro for copy/pasting the same implementation of AlwaysRefCounted around.
This reverts commit 38cb08c3fc.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20251016210955.2813186-2-lyude@redhat.com
This commit is contained in:
@@ -55,26 +55,6 @@ pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted {
|
||||
unsafe fn from_raw<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self;
|
||||
}
|
||||
|
||||
// SAFETY: All gem objects are refcounted.
|
||||
unsafe impl<T: IntoGEMObject> AlwaysRefCounted for T {
|
||||
fn inc_ref(&self) {
|
||||
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
|
||||
unsafe { bindings::drm_gem_object_get(self.as_raw()) };
|
||||
}
|
||||
|
||||
unsafe fn dec_ref(obj: NonNull<Self>) {
|
||||
// SAFETY: We either hold the only refcount on `obj`, or one of many - meaning that no one
|
||||
// else could possibly hold a mutable reference to `obj` and thus this immutable reference
|
||||
// is safe.
|
||||
let obj = unsafe { obj.as_ref() }.as_raw();
|
||||
|
||||
// SAFETY:
|
||||
// - The safety requirements guarantee that the refcount is non-zero.
|
||||
// - We hold no references to `obj` now, making it safe for us to potentially deallocate it.
|
||||
unsafe { bindings::drm_gem_object_put(obj) };
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn open_callback<T: DriverObject>(
|
||||
raw_obj: *mut bindings::drm_gem_object,
|
||||
raw_file: *mut bindings::drm_file,
|
||||
@@ -273,6 +253,22 @@ impl<T: DriverObject> Object<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: Instances of `Object<T>` are always reference-counted.
|
||||
unsafe impl<T: DriverObject> crate::types::AlwaysRefCounted for Object<T> {
|
||||
fn inc_ref(&self) {
|
||||
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
|
||||
unsafe { bindings::drm_gem_object_get(self.as_raw()) };
|
||||
}
|
||||
|
||||
unsafe fn dec_ref(obj: NonNull<Self>) {
|
||||
// SAFETY: `obj` is a valid pointer to an `Object<T>`.
|
||||
let obj = unsafe { obj.as_ref() };
|
||||
|
||||
// SAFETY: The safety requirements guarantee that the refcount is non-zero.
|
||||
unsafe { bindings::drm_gem_object_put(obj.as_raw()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DriverObject> super::private::Sealed for Object<T> {}
|
||||
|
||||
impl<T: DriverObject> Deref for Object<T> {
|
||||
|
||||
Reference in New Issue
Block a user