From: Lyude Paul <lyude@redhat.com>
To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
rust-for-linux@vger.kernel.org
Cc: "Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Alyssa Rosenzweig" <alyssa@rosenzweig.io>,
"Asahi Lina" <lina@asahilina.net>
Subject: [PATCH 4/4] rust: drm: gem: Implement AlwaysRefCounted for all gem objects automatically
Date: Thu, 1 May 2025 14:33:19 -0400 [thread overview]
Message-ID: <20250501183717.2058109-5-lyude@redhat.com> (raw)
In-Reply-To: <20250501183717.2058109-1-lyude@redhat.com>
Currently we are requiring AlwaysRefCounted in most trait bounds for gem
objects, and implementing it by hand for our only current type of gem
object. However, all gem objects use the same functions for reference
counting - and all gem objects support reference counting.
We're planning on adding support for shmem gem objects, let's move this
around a bit by instead making IntoGEMObject require AlwaysRefCounted as a
trait bound, and then provide a blanket AlwaysRefCounted implementation for
any object that implements IntoGEMObject so all gem object types can use
the same AlwaysRefCounted implementation. This also makes things less
verbose by making the AlwaysRefCounted trait bound implicit for any
IntoGEMObject bound.
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
rust/kernel/drm/gem/mod.rs | 47 +++++++++++++++++++-------------------
1 file changed, 24 insertions(+), 23 deletions(-)
diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
index 55b2f1d056c39..929f6c9718362 100644
--- a/rust/kernel/drm/gem/mod.rs
+++ b/rust/kernel/drm/gem/mod.rs
@@ -10,7 +10,7 @@
drm::driver::{AllocImpl, AllocOps},
error::{to_result, Result},
prelude::*,
- types::{ARef, Opaque},
+ types::{ARef, AlwaysRefCounted, Opaque},
};
use core::{mem, ops::Deref, ptr, ptr::NonNull};
@@ -36,7 +36,7 @@ fn close(
}
/// Trait that represents a GEM object subtype
-pub trait IntoGEMObject: Sized + super::private::Sealed {
+pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted {
/// Owning driver for this type
type Driver: drm::Driver;
@@ -52,6 +52,26 @@ pub trait IntoGEMObject: Sized + super::private::Sealed {
unsafe fn as_ref<'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_gem_obj()) };
+ }
+
+ 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_gem_obj();
+
+ // 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) };
+ }
+}
+
/// Trait which must be implemented by drivers using base GEM objects.
pub trait DriverObject: BaseDriverObject<Object<Self>> {
/// Parent `Driver` for this object.
@@ -110,10 +130,7 @@ unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self {
}
/// Base operations shared by all GEM object classes
-pub trait BaseObject
-where
- Self: crate::types::AlwaysRefCounted + IntoGEMObject,
-{
+pub trait BaseObject: IntoGEMObject {
/// Returns the size of the object in bytes.
fn size(&self) -> usize {
// SAFETY: `self.into_gem_obj()` is guaranteed to be a pointer to a valid `struct
@@ -175,7 +192,7 @@ fn create_mmap_offset(&self) -> Result<u64> {
}
}
-impl<T> BaseObject for T where Self: crate::types::AlwaysRefCounted + IntoGEMObject {}
+impl<T: IntoGEMObject> BaseObject for T {}
/// A base GEM object.
///
@@ -269,22 +286,6 @@ extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) {
}
}
-// 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> {
--
2.48.1
next prev parent reply other threads:[~2025-05-01 18:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-01 18:33 [PATCH 0/4] drm: Rust GEM bindings cleanup Lyude Paul
2025-05-01 18:33 ` [PATCH 1/4] rust: drm: gem: Use NonNull for Object::dev Lyude Paul
2025-05-09 20:59 ` Daniel Almeida
2025-05-12 12:11 ` Danilo Krummrich
2025-05-01 18:33 ` [PATCH 2/4] rust: drm: gem: Refactor IntoGEMObject::from_gem_obj() to as_ref() Lyude Paul
2025-05-09 21:37 ` Daniel Almeida
2025-05-13 19:25 ` Lyude Paul
2025-05-13 21:22 ` Lyude Paul
2025-05-12 12:21 ` Danilo Krummrich
2025-05-01 18:33 ` [PATCH 3/4] rust: drm: gem: s/into_gem_obj()/as_gem_obj()/ Lyude Paul
2025-05-09 21:42 ` Daniel Almeida
2025-05-12 12:22 ` Danilo Krummrich
2025-05-01 18:33 ` Lyude Paul [this message]
2025-05-09 21:47 ` [PATCH 4/4] rust: drm: gem: Implement AlwaysRefCounted for all gem objects automatically Daniel Almeida
2025-05-12 12:24 ` Danilo Krummrich
2025-05-15 18:58 ` [PATCH 0/4] drm: Rust GEM bindings cleanup Danilo Krummrich
2025-05-15 19:05 ` Danilo Krummrich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250501183717.2058109-5-lyude@redhat.com \
--to=lyude@redhat.com \
--cc=a.hindborg@kernel.org \
--cc=airlied@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=alyssa@rosenzweig.io \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=lina@asahilina.net \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).