[PATCH v2 09/12] rust: drm: gem: Introduce OwnedSGTable
Lyude Paul
lyude at redhat.com
Wed May 21 20:29:16 UTC 2025
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 OwnedSGTable - 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 OwnedSGTable. The
type can be used identically to a normal SGTable.
Signed-off-by: Lyude Paul <lyude at redhat.com>
---
rust/kernel/drm/gem/shmem.rs | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs
index c38fca715429e..bff038df93334 100644
--- a/rust/kernel/drm/gem/shmem.rs
+++ b/rust/kernel/drm/gem/shmem.rs
@@ -20,7 +20,7 @@
prelude::*,
types::{ARef, Opaque},
container_of,
- scatterlist,
+ scatterlist::SGTable,
};
use core::{
mem::MaybeUninit,
@@ -172,23 +172,36 @@ extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) {
let _ = unsafe { KBox::from_raw(this) };
}
- /// Creates (if necessary) and returns a scatter-gather table of DMA pages for this object.
+ /// Creates (if necessary) and returns an immutable reference to a scatter-gather table of DMA
+ /// pages for this object.
///
/// This will pin the object in memory.
- pub fn sg_table(&self) -> Result<SGTable<T>> {
+ #[inline]
+ pub fn sg_table(&self) -> Result<&SGTable> {
// SAFETY:
// - drm_gem_shmem_get_pages_sgt is thread-safe.
// - drm_gem_shmem_get_pages_sgt returns either a valid pointer to a scatterlist, or an
// error pointer.
let sgt = from_err_ptr(unsafe { bindings::drm_gem_shmem_get_pages_sgt(self.as_shmem()) })?;
- Ok(SGTable {
- // SAFETY: We checked that `sgt` is not an error pointer, so it must be a valid pointer
- // to a scatterlist.
- sgt: NonNull::from(unsafe { scatterlist::SGTable::as_ref(sgt) }),
+ // SAFETY: We checked above that `sgt` is not an error pointer, so it must be a valid
+ // pointer to a scatterlist
+ Ok(unsafe { SGTable::as_ref(sgt) })
+ }
+
+ /// Creates (if necessary) and returns an owned 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<OwnedSGTable<T>> {
+ Ok(OwnedSGTable {
+ 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()
+ _owner: self.into(),
})
}
--
2.49.0
More information about the dri-devel
mailing list