From: Deborah Brouwer <deborah.brouwer@collabora.com>
To: Ke Sun <sunke@kylinos.cn>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>, "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>,
"Tamir Duberstein" <tamird@kernel.org>,
"Alexandre Courbot" <acourbot@nvidia.com>,
"Onur Özkan" <work@onurozkan.dev>,
"Lyude Paul" <lyude@redhat.com>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Johan Hovold" <johan@kernel.org>,
"Sami Tolvanen" <samitolvanen@google.com>,
rust-for-linux@vger.kernel.org, dri-devel@lists.freedesktop.org,
driver-core@lists.linux.dev, "Alvin Sun" <alvin.sun@linux.dev>
Subject: Re: [PATCH v6 04/10] drm/tyr: add per-file VM pool
Date: Fri, 13 Nov 2026 17:24:40 -0700 [thread overview]
Message-ID: <aveqSHOLD8J0CjsO@um790> (raw)
In-Reply-To: <20261109-tyr-ioctls-v6-4-b2896bf2b3c9@kylinos.cn>
On Mon, Nov 09, 2026 at 08:36:47AM +0800, Ke Sun wrote:
> From: Alvin Sun <alvin.sun@linux.dev>
>
> Userspace needs multiple independent GPU address spaces per file,
> addressed by ID through the VM ioctls as in panthor. Store them in an
> IdPool (capped at 32 for panthor parity) plus an XArray. On failure
> the caller receives the VM for teardown through the returned error,
> whether the un-stored clone or the original on an ID conflict, so an
> aborted creation never leaks a VM. The pool kills every VM still
> stored when the file closes.
>
> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
> ---
> drivers/gpu/drm/tyr/vm.rs | 140 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 139 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/tyr/vm.rs b/drivers/gpu/drm/tyr/vm.rs
> index 1dd11b2b12532..6f5518652a03f 100644
> --- a/drivers/gpu/drm/tyr/vm.rs
> +++ b/drivers/gpu/drm/tyr/vm.rs
> @@ -33,6 +33,7 @@
> }, //
> },
> fmt,
> + id_pool::IdPool,
> impl_flags,
> io::PhysAddr,
> iommu::pgtable::{
> @@ -41,6 +42,7 @@
> ARM64LPAES1, //
> },
> new_mutex,
> + num::casts::FromSafeCast,
> prelude::*,
> sizes::{
> SZ_1G,
> @@ -53,7 +55,11 @@
> ArcBorrow,
> Mutex, //
> },
> - uapi, //
> + uapi,
> + xarray::{
> + AllocKind,
> + XArray, //
> + }, //
> };
>
> use crate::{
> @@ -947,3 +953,135 @@ fn pt_unmap(dev: &Device, pt: &IoPageTable<'_, ARM64LPAES1>, range: Range<u64>)
>
> Ok(())
> }
> +
> +/// Maximum number of VMs a single file may hold, matching panthor's
> +/// `PANTHOR_MAX_VMS_PER_FILE`.
> +const MAX_VMS_PER_FILE: usize = 32;
> +
> +/// Per-open-file pool of VMs.
> +#[pin_data(PinnedDrop)]
> +pub(crate) struct VmPool<'drm> {
> + /// Parent device, for error reporting.
> + dev: &'drm Device<Bound>,
> + #[pin]
> + ids: Mutex<IdPool>,
> + #[pin]
> + vms: XArray<Arc<Vm<'drm>>>,
> +}
> +
> +/// Error returned when a VM cannot be added to the pool. The caller
> +/// owns the teardown of the VM in [`AddError::vm`].
> +pub(crate) struct AddError<'drm> {
> + #[expect(dead_code)]
> + pub(crate) error: Error,
> + #[expect(dead_code)]
> + pub(crate) vm: Arc<Vm<'drm>>,
> +}
> +
> +impl<'drm> VmPool<'drm> {
> + /// Creates a new [`VmPool`].
> + #[expect(dead_code)]
> + pub(crate) fn new(dev: &'drm Device<Bound>) -> impl PinInit<Self> {
> + let ids = IdPool::new();
I sent a reply to sashiko-review lists but i meant it to go to the whole
thread. Basically, just wanted to suggest using IdPool::with_capacity()
to make sure we can create 32 vms on 32 bit builds.
https://lore.kernel.org/dri-devel/avZlPvHqlxmu2hNO@um790/
> + pin_init!(Self {
> + dev,
> + ids <- new_mutex!(ids),
> + vms <- XArray::new(AllocKind::Alloc),
> + })
> + }
> +
> + /// Stores the VM and returns the allocated ID.
> + ///
> + /// On failure - ID space exhausted or a store failure - the VM is
> + /// returned in an [`AddError`] so the caller owns the teardown.
> + // TODO: allocate IDs with the XArray directly (once it grows range
> + // allocation, the equivalent of C's `XA_LIMIT`) and drop the IdPool.
> + #[expect(dead_code)]
> + pub(crate) fn add(&self, vm: Arc<Vm<'drm>>) -> Result<u32, AddError<'drm>> {
> + let id = (|| {
> + let mut ids = self.ids.lock();
> + let unused = ids.find_unused_id(1).ok_or(ENOSPC)?;
> + if unused.as_usize() > MAX_VMS_PER_FILE {
> + return Err(ENOSPC);
Turns out since panthor uses xa_alloc() it will return
" * -EBUSY if there are no free entries in @limit." so we better do
the same here.
> + }
> + Ok(unused.acquire())
> + })();
> + let id = match id {
> + Ok(id) => id,
> + Err(error) => return Err(AddError { error, vm }),
> + };
> +
> + let mut vms = self.vms.lock();
> + match vms.store(id, vm.clone(), GFP_KERNEL) {
> + Ok(prev_vm) => {
> + if let Some(prev_vm) = prev_vm {
> + // An existing VM at the freshly allocated slot means the
> + // IdPool and the XArray are out of sync: the stored VM is
> + // a pool entry, so the pool kills it and the caller's VM
> + // is returned for teardown.
> + drop(vms.remove(id));
> + drop(vms);
> + prev_vm.kill();
> + self.ids.lock().release_id(id);
> + dev_err!(
> + self.dev,
> + "IdPool/XArray out of sync at VM pool id {id} (stored VM conflict)"
> + );
> + return Err(AddError { error: EBUSY, vm });
> + }
> + Ok(id as u32)
> + }
> + Err(err) => {
> + // Drop the XArray spinlock before acquiring the `ids` mutex.
> + drop(vms);
> + // Release the pooled id; the VM never entered the pool, so it
> + // is returned to the caller for teardown.
> + self.ids.lock().release_id(id);
> + Err(AddError {
> + error: err.error,
> + vm: err.value,
> + })
> + }
> + }
> + }
> +
> + /// Removes and kills the VM with the given ID.
> + #[expect(dead_code)]
> + pub(crate) fn remove(&self, id: u32) -> Result<()> {
> + let mut vms = self.vms.lock();
> + let vm = match vms.remove(usize::from_safe_cast(id)) {
> + Some(vm) => vm,
> + None => return Err(EINVAL),
> + };
> + // Drop the XArray spinlock before killing, since `kill()` may sleep.
> + drop(vms);
> + // Kill the VM before handing the id back to the pool, so a VM is
> + // never reusable while still alive.
> + vm.kill();
> + self.ids.lock().release_id(usize::from_safe_cast(id));
> + Ok(())
> + }
> +
> + /// Gets a shared reference to the VM with the given ID.
> + #[expect(dead_code)]
> + pub(crate) fn get(&self, id: u32) -> Option<Arc<Vm<'drm>>> {
> + let vms = self.vms.lock();
> + let borrow = vms.get(usize::from_safe_cast(id))?;
> + Some(Arc::from(borrow))
> + }
> +}
> +
> +#[pinned_drop]
> +impl PinnedDrop for VmPool<'_> {
> + fn drop(self: Pin<&mut Self>) {
> + // Kill every VM left in the pool. The ID range is bounded by
> + // `MAX_VMS_PER_FILE`, so this loop is cheap and runs at file close.
> + for id in 1..=MAX_VMS_PER_FILE {
> + // Release the XArray lock guard before killing: `kill()` may sleep.
> + let vm = self.vms.lock().remove(id);
> + if let Some(vm) = vm {
> + vm.kill();
> + }
> + }
> + }
> +}
>
> --
> 2.43.0
>
next prev parent reply other threads:[~2026-11-14 0:25 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 0:36 [PATCH v6 00/10] drm/tyr: add VM and BO ioctl support Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:36 ` [PATCH v6 01/10] rust: sizes: add SZ_4G constant Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:36 ` [PATCH v6 02/10] rust: task: add task_size() Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:36 ` [PATCH v6 03/10] rust: sync: arc: relax `ForeignOwnable` for `Arc<T>` Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:36 ` [PATCH v6 04/10] drm/tyr: add per-file VM pool Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:48 ` sashiko-bot
2026-11-13 1:17 ` Deborah Brouwer
2026-11-14 0:24 ` Deborah Brouwer [this message]
2026-11-09 0:36 ` [PATCH v6 05/10] drm/tyr: add user and MCU VM specifications Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:36 ` [PATCH v6 06/10] drm/tyr: add BO creation and lookup helpers Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:36 ` [PATCH v6 07/10] drm/tyr: add VM-related ioctls Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 1:01 ` sashiko-bot
2026-11-09 0:36 ` [PATCH v6 08/10] rust: device: expose the device DMA attribute Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 0:36 ` [PATCH v6 09/10] drm/tyr: support write-combine BO mappings Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 1:10 ` sashiko-bot
2026-11-09 0:36 ` [PATCH v6 10/10] drm/tyr: add BO-related ioctls Ke Sun via B4 Relay
2026-11-09 0:36 ` Ke Sun
2026-11-09 1:05 ` sashiko-bot
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=aveqSHOLD8J0CjsO@um790 \
--to=deborah.brouwer@collabora.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=alvin.sun@linux.dev \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=driver-core@lists.linux.dev \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=johan@kernel.org \
--cc=lossin@kernel.org \
--cc=lyude@redhat.com \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=samitolvanen@google.com \
--cc=simona@ffwll.ch \
--cc=sunke@kylinos.cn \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
/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.