rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Lyude Paul <lyude@redhat.com>
To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org,
	linux-kernel@vger.kernel.org
Cc: "David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"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" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Daniel Almeida" <daniel.almeida@collabora.com>,
	"Asahi Lina" <lina+kernel@asahilina.net>
Subject: [PATCH v3 11/14] rust: drm: gem: Introduce SGTableRef
Date: Fri, 29 Aug 2025 18:35:26 -0400	[thread overview]
Message-ID: <20250829224116.477990-12-lyude@redhat.com> (raw)
In-Reply-To: <20250829224116.477990-1-lyude@redhat.com>

Currently we expose the ability to retrieve an SGTable for an shmem gem
object using gem::shmem::Object::<T>::sg_table(). However, this only gives us a
borrowed reference. This being said - retrieving an SGTable is a fallible
operation, and as such it's reasonable that a driver may want to hold
onto an SGTable for longer then a reference would allow in order to avoid
having to deal with fallibility every time they want to access the SGTable.
One such driver with this usecase is the Asahi driver.

So to support this, let's introduce SGTableRef - which both holds a
pointer to the SGTable and a reference to its respective GEM object in
order to keep the GEM object alive for as long as the SGTableRef. The
type can be used identically to a normal SGTable.

Signed-off-by: Lyude Paul <lyude@redhat.com>

---
V3:
* Rename OwnedSGTable to SGTableRef. Since the current version of the
  SGTable abstractions now has a `Owned` and `Borrowed` variant, I think
  renaming this to SGTableRef makes things less confusing.
  We do however, keep the name of owned_sg_table() as-is.

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 rust/kernel/drm/gem/shmem.rs | 50 ++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs
index 6a8a392c3691b..1437cda27a22c 100644
--- a/rust/kernel/drm/gem/shmem.rs
+++ b/rust/kernel/drm/gem/shmem.rs
@@ -178,6 +178,22 @@ pub fn sg_table(&self) -> Result<&scatterlist::SGTable> {
         Ok(unsafe { scatterlist::SGTable::from_raw(sgt) })
     }
 
+    /// Creates (if necessary) and returns an owned reference to a scatter-gather table of DMA pages
+    /// for this object.
+    ///
+    /// This is the same as [`sg_table`](Self::sg_table), except that it instead returns a
+    /// [`OwnedSGTable`] which holds a reference to the associated gem object.
+    ///
+    /// This will pin the object in memory.
+    pub fn owned_sg_table(&self) -> Result<SGTableRef<T>> {
+        Ok(SGTableRef {
+            sgt: self.sg_table()?.into(),
+            // INVARIANT: We take an owned refcount to `self` here, ensuring that `sgt` remains
+            // valid for as long as this `OwnedSGTable`.
+            _owner: self.into(),
+        })
+    }
+
     /// Creates and returns a virtual kernel memory mapping for this object.
     pub fn vmap(&self) -> Result<VMap<T>> {
         let mut map: MaybeUninit<bindings::iosys_map> = MaybeUninit::uninit();
@@ -309,3 +325,37 @@ fn drop(&mut self) {
 unsafe impl<T: DriverObject> Send for VMap<T> {}
 /// SAFETY: `iosys_map` objects are safe to send across threads.
 unsafe impl<T: DriverObject> Sync for VMap<T> {}
+
+/// An owned reference to a scatter-gather table of DMA address spans for a GEM shmem object.
+///
+/// This object holds an owned reference to the underlying GEM shmem object, ensuring that the
+/// [`SGTable`] referenced by `SGTableRef` remains valid for the lifetime of this object.
+///
+/// # Invariants
+///
+/// - `sgt` is kept alive by `_owner`, ensuring it remains valid for as long as `Self`.
+/// - `sgt` corresponds to the owned object in `_owner`.
+/// - This object is only exposed in situations where we know the underlying `SGTable` will not be
+///   modified for the lifetime of this object.
+///
+/// [`SGTable`]: scatterlist::SGTable
+pub struct SGTableRef<T: DriverObject> {
+    sgt: NonNull<scatterlist::SGTable>,
+    _owner: ARef<Object<T>>,
+}
+
+// SAFETY: This object is only exposed in situations where we know the underlying `SGTable` will not
+// be modified for the lifetime of this object.
+unsafe impl<T: DriverObject> Send for SGTableRef<T> {}
+// SAFETY: This object is only exposed in situations where we know the underlying `SGTable` will not
+// be modified for the lifetime of this object.
+unsafe impl<T: DriverObject> Sync for SGTableRef<T> {}
+
+impl<T: DriverObject> Deref for SGTableRef<T> {
+    type Target = scatterlist::SGTable;
+
+    fn deref(&self) -> &Self::Target {
+        // SAFETY: Creating an immutable reference to this is safe via our type invariants.
+        unsafe { self.sgt.as_ref() }
+    }
+}
-- 
2.50.0


  parent reply	other threads:[~2025-08-29 22:43 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-29 22:35 [PATCH v3 00/14] Rust abstractions for shmem-backed GEM objects Lyude Paul
2025-08-29 22:35 ` [PATCH v3 01/14] rust: drm: gem: Simplify use of generics Lyude Paul
2025-09-01 15:37   ` Daniel Almeida
2025-09-02 18:50     ` Lyude Paul
2025-09-04 12:11   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 02/14] rust: drm: gem: Add DriverFile type alias Lyude Paul
2025-09-04 12:16   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 03/14] rust: drm: gem: Drop Object::SIZE Lyude Paul
2025-09-04 12:17   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 04/14] rust: drm: gem: Support driver-private GEM object types Lyude Paul
2025-09-04 12:51   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 05/14] rust: helpers: Add bindings/wrappers for dma_resv_lock Lyude Paul
2025-08-29 22:35 ` [PATCH v3 06/14] rust: drm: gem: Add raw_dma_resv() function Lyude Paul
2025-09-04 12:55   ` Daniel Almeida
2025-09-04 13:09   ` Alice Ryhl
2025-08-29 22:35 ` [PATCH v3 07/14] drm/gem/shmem: Extract drm_gem_shmem_init() from drm_gem_shmem_create() Lyude Paul
2025-09-04 13:29   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 08/14] drm/gem/shmem: Extract drm_gem_shmem_release() from drm_gem_shmem_free() Lyude Paul
2025-09-04 13:35   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 09/14] rust: gem: Introduce DriverObject::Args Lyude Paul
2025-09-04 13:42   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 10/14] rust: drm: gem: shmem: Add DRM shmem helper abstraction Lyude Paul
2025-09-05 17:04   ` Daniel Almeida
2025-08-29 22:35 ` Lyude Paul [this message]
2025-09-04 16:03   ` [PATCH v3 11/14] rust: drm: gem: Introduce SGTableRef Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 12/14] rust: Add dma_buf stub bindings Lyude Paul
2025-09-04 16:16   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 13/14] rust: drm: gem: Add export() callback Lyude Paul
2025-09-05 15:09   ` Daniel Almeida
2025-08-29 22:35 ` [PATCH v3 14/14] rust: drm: gem: Add BaseObject::prime_export() Lyude Paul
2025-09-05 15:18   ` Daniel Almeida

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=20250829224116.477990-12-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=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gary@garyguo.net \
    --cc=lina+kernel@asahilina.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lossin@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).