From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "Lyude Paul" <lyude@redhat.com>
Cc: <nouveau@lists.freedesktop.org>, "Gary Guo" <gary@garyguo.net>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
<rust-for-linux@vger.kernel.org>,
"Danilo Krummrich" <dakr@kernel.org>,
<dri-devel@lists.freedesktop.org>,
"Matthew Maurer" <mmaurer@google.com>,
"FUJITA Tomonori" <fujita.tomonori@gmail.com>,
"Lorenzo Stoakes" <lorenzo.stoakes@oracle.com>,
<christian.koenig@amd.com>, "Asahi Lina" <lina@asahilina.net>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Simona Vetter" <simona@ffwll.ch>,
"Alice Ryhl" <aliceryhl@google.com>,
"Boqun Feng" <boqun@kernel.org>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Krishna Ketan Rai" <prafulrai522@gmail.com>,
<linux-media@vger.kernel.org>,
"Shankari Anand" <shankari.ak0208@gmail.com>,
"David Airlie" <airlied@gmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Viresh Kumar" <viresh.kumar@linaro.org>,
<linaro-mm-sig@lists.linaro.org>,
"Asahi Lina" <lina+kernel@asahilina.net>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
<kernel@vger.kernel.org>
Subject: Re: [PATCH v10 4/5] rust: drm: gem: Introduce shmem::SGTable
Date: Fri, 10 Apr 2026 16:55:27 +0900 [thread overview]
Message-ID: <DHPBAVQHIM11.XVBHOWYFRITF@nvidia.com> (raw)
In-Reply-To: <20260409001559.622026-5-lyude@redhat.com>
On Thu Apr 9, 2026 at 9:12 AM JST, Lyude Paul wrote:
> In order to do this, we need to be careful to ensure that any interface we
> expose for scatterlists ensures that any mappings created from one are
> destroyed on driver-unbind. To do this, we introduce a Devres resource into
> shmem::Object that we use in order to ensure that we release any SGTable
> mappings on driver-unbind. We store this in an UnsafeCell and protect
> access to it using the dma_resv lock that we already have from the shmem
> gem object, which is the same lock that currently protects
> drm_gem_object_shmem->sgt.
>
> We also provide two different methods for acquiring an sg table:
> self.sg_table(), and self.owned_sg_table(). The first function is for
> short-term uses of mapped SGTables, the second is for callers that need to
> hold onto the mapped SGTable for an extended period of time. The second
> variant uses Devres of course, whereas the first simply relies on rust's
> borrow checker to prevent driver-unbind when using the mapped SGTable.
>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
>
> ---
> V3:
> * Rename OwnedSGTable to shmem::SGTable. Since the current version of the
> SGTable abstractions now has a `Owned` and `Borrowed` variant, I think
> renaming this to shmem::SGTable makes things less confusing.
> We do however, keep the name of owned_sg_table() as-is.
> V4:
> * Clarify safety comments for SGTable to explain why the object is
> thread-safe.
> * Rename from SGTableRef to SGTable
> V10:
> * Use Devres in order to ensure that SGTables are revocable, and are
> unmapped on driver-unbind.
>
> rust/kernel/drm/gem/shmem.rs | 191 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 189 insertions(+), 2 deletions(-)
>
> diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs
> index c643f18b20838..111be446213df 100644
> --- a/rust/kernel/drm/gem/shmem.rs
> +++ b/rust/kernel/drm/gem/shmem.rs
> @@ -11,25 +11,38 @@
>
> use crate::{
> container_of,
> + device::{
> + self,
> + Bound, //
> + },
> + devres::*,
> drm::{
> driver,
> gem,
> private::Sealed, //
> Device,
> },
> - error::to_result,
> + error::{
> + from_err_ptr, //
> + to_result,
nit: `//` guard should be on last item.
> + },
> prelude::*,
> + scatterlist,
> types::{
> ARef,
> Opaque, //
> }, //
> };
> use core::{
> + cell::UnsafeCell,
> ops::{
> Deref,
> DerefMut, //
> },
> - ptr::NonNull,
> + ptr::{
> + self,
> + NonNull, //
> + },
> };
> use gem::{
> BaseObjectPrivate,
> @@ -65,6 +78,10 @@ pub struct Object<T: DriverObject> {
> obj: Opaque<bindings::drm_gem_shmem_object>,
> /// Parent object that owns this object's DMA reservation object.
> parent_resv_obj: Option<ARef<Object<T>>>,
> + /// Devres object for unmapping any SGTable on driver-unbind.
> + ///
> + /// This is protected by the object's dma_resv lock.
> + sgt_res: UnsafeCell<Option<Devres<SGTableMap<T>>>>,
> #[pin]
> inner: T,
> }
> @@ -117,6 +134,7 @@ pub fn new(
> try_pin_init!(Self {
> obj <- Opaque::init_zeroed(),
> parent_resv_obj: config.parent_resv_obj.map(|p| p.into()),
> + sgt_res: UnsafeCell::new(None),
> inner <- T::new(dev, size, args),
> }),
> GFP_KERNEL,
> @@ -176,6 +194,100 @@ extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) {
> // SAFETY: We're recovering the Kbox<> we created in gem_create_object()
> let _ = unsafe { KBox::from_raw(this) };
> }
> +
> + // If necessary, create an SGTable for the gem object and register a Devres for it to ensure
> + // that it is unmapped on driver unbind.
> + fn create_sg_table<'a>(
This method looks like it is misnamed - it won't create the SG table if
it already exists, just return a reference to it. Maybe `get_sg_table`
is a more fitting name.
I would have suggesting splitting the creation part into a dedicated
method, but it would require the resv lock to be acquired as a
precondition so not sure that's worth it.
> + &'a self,
> + dev: &'a device::Device<Bound>,
> + ) -> Result<&'a Devres<SGTableMap<T>>> {
> + let ret;
> + let sgt_res_ptr = self.sgt_res.get();
> +
> + // SAFETY: This lock is initialized throughout the lifetime of the gem object
> + unsafe { bindings::dma_resv_lock(self.raw_dma_resv(), ptr::null_mut()) };
> +
> + // SAFETY: We just grabbed the lock required for reading this data above.
> + let sgt_res = unsafe { (*sgt_res_ptr).as_ref() };
> + if let Some(sgt_res) = sgt_res {
> + // We already have a Devres object for this sg table, return it
> + ret = Ok(sgt_res);
nit: let's use `let ret = if let Some(sgt_res) ...` to avoid the
multiple `ret = `statements?
Or maybe even better, you might be able to use
`Option::get_or_insert_with`.
WARNING: multiple messages have this Message-ID (diff)
From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "Lyude Paul" <lyude@redhat.com>
Cc: nouveau@lists.freedesktop.org, Gary Guo <gary@garyguo.net>,
Daniel Almeida <daniel.almeida@collabora.com>,
rust-for-linux@vger.kernel.org,
Danilo Krummrich <dakr@kernel.org>,
dri-devel@lists.freedesktop.org,
Matthew Maurer <mmaurer@google.com>,
FUJITA Tomonori <fujita.tomonori@gmail.com>,
Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
christian.koenig@amd.com, Asahi Lina <lina@asahilina.net>,
Miguel Ojeda <ojeda@kernel.org>,
Andreas Hindborg <a.hindborg@kernel.org>,
Simona Vetter <simona@ffwll.ch>,
Alice Ryhl <aliceryhl@google.com>, Boqun Feng <boqun@kernel.org>,
Sumit Semwal <sumit.semwal@linaro.org>,
Krishna Ketan Rai <prafulrai522@gmail.com>,
linux-media@vger.kernel.org,
Shankari Anand <shankari.ak0208@gmail.com>,
Benno Lossin <lossin@kernel.org>,
Viresh Kumar <viresh.kumar@linaro.org>,
linaro-mm-sig@lists.linaro.org,
Asahi Lina <lina+kernel@asahilina.net>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
kernel@vger.kernel.org
Subject: Re: [PATCH v10 4/5] rust: drm: gem: Introduce shmem::SGTable
Date: Fri, 10 Apr 2026 16:55:27 +0900 [thread overview]
Message-ID: <DHPBAVQHIM11.XVBHOWYFRITF@nvidia.com> (raw)
In-Reply-To: <20260409001559.622026-5-lyude@redhat.com>
On Thu Apr 9, 2026 at 9:12 AM JST, Lyude Paul wrote:
> In order to do this, we need to be careful to ensure that any interface we
> expose for scatterlists ensures that any mappings created from one are
> destroyed on driver-unbind. To do this, we introduce a Devres resource into
> shmem::Object that we use in order to ensure that we release any SGTable
> mappings on driver-unbind. We store this in an UnsafeCell and protect
> access to it using the dma_resv lock that we already have from the shmem
> gem object, which is the same lock that currently protects
> drm_gem_object_shmem->sgt.
>
> We also provide two different methods for acquiring an sg table:
> self.sg_table(), and self.owned_sg_table(). The first function is for
> short-term uses of mapped SGTables, the second is for callers that need to
> hold onto the mapped SGTable for an extended period of time. The second
> variant uses Devres of course, whereas the first simply relies on rust's
> borrow checker to prevent driver-unbind when using the mapped SGTable.
>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
>
> ---
> V3:
> * Rename OwnedSGTable to shmem::SGTable. Since the current version of the
> SGTable abstractions now has a `Owned` and `Borrowed` variant, I think
> renaming this to shmem::SGTable makes things less confusing.
> We do however, keep the name of owned_sg_table() as-is.
> V4:
> * Clarify safety comments for SGTable to explain why the object is
> thread-safe.
> * Rename from SGTableRef to SGTable
> V10:
> * Use Devres in order to ensure that SGTables are revocable, and are
> unmapped on driver-unbind.
>
> rust/kernel/drm/gem/shmem.rs | 191 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 189 insertions(+), 2 deletions(-)
>
> diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs
> index c643f18b20838..111be446213df 100644
> --- a/rust/kernel/drm/gem/shmem.rs
> +++ b/rust/kernel/drm/gem/shmem.rs
> @@ -11,25 +11,38 @@
>
> use crate::{
> container_of,
> + device::{
> + self,
> + Bound, //
> + },
> + devres::*,
> drm::{
> driver,
> gem,
> private::Sealed, //
> Device,
> },
> - error::to_result,
> + error::{
> + from_err_ptr, //
> + to_result,
nit: `//` guard should be on last item.
> + },
> prelude::*,
> + scatterlist,
> types::{
> ARef,
> Opaque, //
> }, //
> };
> use core::{
> + cell::UnsafeCell,
> ops::{
> Deref,
> DerefMut, //
> },
> - ptr::NonNull,
> + ptr::{
> + self,
> + NonNull, //
> + },
> };
> use gem::{
> BaseObjectPrivate,
> @@ -65,6 +78,10 @@ pub struct Object<T: DriverObject> {
> obj: Opaque<bindings::drm_gem_shmem_object>,
> /// Parent object that owns this object's DMA reservation object.
> parent_resv_obj: Option<ARef<Object<T>>>,
> + /// Devres object for unmapping any SGTable on driver-unbind.
> + ///
> + /// This is protected by the object's dma_resv lock.
> + sgt_res: UnsafeCell<Option<Devres<SGTableMap<T>>>>,
> #[pin]
> inner: T,
> }
> @@ -117,6 +134,7 @@ pub fn new(
> try_pin_init!(Self {
> obj <- Opaque::init_zeroed(),
> parent_resv_obj: config.parent_resv_obj.map(|p| p.into()),
> + sgt_res: UnsafeCell::new(None),
> inner <- T::new(dev, size, args),
> }),
> GFP_KERNEL,
> @@ -176,6 +194,100 @@ extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) {
> // SAFETY: We're recovering the Kbox<> we created in gem_create_object()
> let _ = unsafe { KBox::from_raw(this) };
> }
> +
> + // If necessary, create an SGTable for the gem object and register a Devres for it to ensure
> + // that it is unmapped on driver unbind.
> + fn create_sg_table<'a>(
This method looks like it is misnamed - it won't create the SG table if
it already exists, just return a reference to it. Maybe `get_sg_table`
is a more fitting name.
I would have suggesting splitting the creation part into a dedicated
method, but it would require the resv lock to be acquired as a
precondition so not sure that's worth it.
> + &'a self,
> + dev: &'a device::Device<Bound>,
> + ) -> Result<&'a Devres<SGTableMap<T>>> {
> + let ret;
> + let sgt_res_ptr = self.sgt_res.get();
> +
> + // SAFETY: This lock is initialized throughout the lifetime of the gem object
> + unsafe { bindings::dma_resv_lock(self.raw_dma_resv(), ptr::null_mut()) };
> +
> + // SAFETY: We just grabbed the lock required for reading this data above.
> + let sgt_res = unsafe { (*sgt_res_ptr).as_ref() };
> + if let Some(sgt_res) = sgt_res {
> + // We already have a Devres object for this sg table, return it
> + ret = Ok(sgt_res);
nit: let's use `let ret = if let Some(sgt_res) ...` to avoid the
multiple `ret = `statements?
Or maybe even better, you might be able to use
`Option::get_or_insert_with`.
next prev parent reply other threads:[~2026-04-10 7:55 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-09 0:12 [PATCH v10 0/5] Rust bindings for gem shmem Lyude Paul
2026-04-09 0:12 ` Lyude Paul
2026-04-09 0:12 ` [PATCH v10 1/5] rust: drm: gem: s/device::Device/Device/ for shmem.rs Lyude Paul
2026-04-09 0:12 ` Lyude Paul
2026-04-10 7:54 ` Alexandre Courbot
2026-04-10 7:54 ` Alexandre Courbot
2026-04-09 0:12 ` [PATCH v10 2/5] drm/gem/shmem: Introduce __drm_gem_shmem_free_sgt_locked() Lyude Paul
2026-04-09 0:12 ` Lyude Paul
2026-04-10 7:54 ` Alexandre Courbot
2026-04-10 7:54 ` Alexandre Courbot
2026-04-09 0:12 ` [PATCH v10 3/5] drm/gem/shmem: Export drm_gem_shmem_get_pages_sgt_locked() Lyude Paul
2026-04-09 0:12 ` Lyude Paul
2026-04-10 7:55 ` Alexandre Courbot
2026-04-10 7:55 ` Alexandre Courbot
2026-04-09 0:12 ` [PATCH v10 4/5] rust: drm: gem: Introduce shmem::SGTable Lyude Paul
2026-04-09 0:12 ` Lyude Paul
2026-04-09 22:57 ` Deborah Brouwer
2026-04-09 22:57 ` Deborah Brouwer
2026-04-21 23:04 ` Lyude Paul
2026-04-21 23:04 ` Lyude Paul
2026-04-10 7:55 ` Alexandre Courbot [this message]
2026-04-10 7:55 ` Alexandre Courbot
2026-04-17 19:44 ` lyude
2026-04-17 19:44 ` lyude
2026-04-17 19:45 ` lyude
2026-04-17 19:45 ` lyude
2026-04-09 0:12 ` [PATCH v10 5/5] rust: drm: gem: Add vmap functions to shmem bindings Lyude Paul
2026-04-09 0:12 ` Lyude Paul
2026-04-11 13:32 ` Alexandre Courbot
2026-04-11 13:32 ` Alexandre Courbot
2026-04-21 21:15 ` Lyude Paul
2026-04-21 21:15 ` Lyude Paul
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=DHPBAVQHIM11.XVBHOWYFRITF@nvidia.com \
--to=acourbot@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=boqun@kernel.org \
--cc=christian.koenig@amd.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=fujita.tomonori@gmail.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=kernel@vger.kernel.org \
--cc=lina+kernel@asahilina.net \
--cc=lina@asahilina.net \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-media@vger.kernel.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=lossin@kernel.org \
--cc=lyude@redhat.com \
--cc=mmaurer@google.com \
--cc=nouveau@lists.freedesktop.org \
--cc=ojeda@kernel.org \
--cc=prafulrai522@gmail.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=shankari.ak0208@gmail.com \
--cc=simona@ffwll.ch \
--cc=sumit.semwal@linaro.org \
--cc=viresh.kumar@linaro.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.