Re: [PATCH v7 5/7] drm/tyr: add a kernel buffer object

Daniel Almeida <[email protected]>
Newsgroups org.kernel.vger.rust-for-linux,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>

> On 14 Jul 2026, at 00:18, Deborah Brouwer <[email protected]> wrote:
> 
> Introduce a buffer object type (KernelBo) for internal driver allocations
> that are managed by the kernel rather than userspace.
> 
> KernelBo wraps a GEM shmem object and automatically handles GPU virtual
> address space mapping during creation and unmapping on drop. This provides
> a safe and convenient way for the driver to both allocate and clean up
> internal buffers for kernel-managed resources.
> 
> Co-developed-by: Boris Brezillon <[email protected]>
> Signed-off-by: Boris Brezillon <[email protected]>
> Signed-off-by: Deborah Brouwer <[email protected]>
> ---
> drivers/gpu/drm/tyr/gem.rs | 101 +++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 97 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tyr/gem.rs b/drivers/gpu/drm/tyr/gem.rs
> index c28be61a01bb..47a05a33388e 100644
> --- a/drivers/gpu/drm/tyr/gem.rs
> +++ b/drivers/gpu/drm/tyr/gem.rs
> @@ -4,18 +4,29 @@
> //! This module provides buffer object (BO) management functionality using
> //! DRM's GEM subsystem with shmem backing.
> 
> +use core::ops::Range;
> +
> use kernel::{
>     drm::gem::{
>         self,
>         shmem, //
>     },
>     prelude::*,
> -    sync::aref::ARef, //
> +    sync::{
> +        aref::ARef,
> +        Arc, //
> +    }, //
> };
> 
> -use crate::driver::{
> -    TyrDrmDevice,
> -    TyrDrmDriver, //
> +use crate::{
> +    driver::{
> +        TyrDrmDevice,
> +        TyrDrmDriver, //
> +    },
> +    vm::{
> +        Vm,
> +        VmMapFlags, //
> +    },
> };
> 
> /// Tyr's DriverObject type for GEM objects.
> @@ -56,3 +67,85 @@ pub(crate) fn new_dummy_object(ddev: &TyrDrmDevice) -> Result<ARef<Bo>> {
> 
>     Ok(bo)
> }
> +
> +/// Specifies how to choose a GPU virtual address for a [`KernelBo`].
> +/// An automatic VA allocation strategy will be added in the future.
> +pub(crate) enum KernelBoVaAlloc {
> +    /// Explicit VA address specified by the caller.
> +    #[expect(dead_code)]
> +    Explicit(u64),
> +}
> +
> +/// A kernel-owned buffer object with automatic GPU virtual address mapping.
> +///
> +/// This structure represents a buffer object that is created and managed entirely
> +/// by the kernel driver, as opposed to userspace-created GEM objects. It combines
> +/// a GEM object with automatic GPU virtual address (VA) space mapping and cleanup.
> +///
> +/// When dropped, the buffer is automatically unmapped from the GPU VA space.
> +pub(crate) struct KernelBo<'bound> {
> +    /// The underlying GEM buffer object.
> +    #[expect(dead_code)]
> +    pub(crate) bo: ARef<Bo>,

Can we make this private?

> +    /// The GPU VM this buffer is mapped into.
> +    vm: Arc<Vm<'bound>>,
> +    /// The GPU VA range occupied by this buffer.
> +    va_range: Range<u64>,
> +}
> +
> +impl<'bound> KernelBo<'bound> {
> +    /// Creates a new kernel-owned buffer object and maps it into GPU VA space.
> +    ///
> +    /// This function allocates a new shmem-backed GEM object and immediately maps
> +    /// it into the specified GPU virtual memory space. The mapping is automatically
> +    /// cleaned up when the [`KernelBo`] is dropped.
> +    #[expect(dead_code)]
> +    pub(crate) fn new(
> +        ddev: &TyrDrmDevice,
> +        vm: Arc<Vm<'bound>>,
> +        size: u64,
> +        va_alloc: KernelBoVaAlloc,
> +        flags: VmMapFlags,
> +    ) -> Result<Self> {
> +        if size == 0 {
> +            pr_err!("Cannot create KernelBo with size 0\n");
> +            return Err(EINVAL);
> +        }
> +
> +        let KernelBoVaAlloc::Explicit(va) = va_alloc;
> +
> +        let bo = Bo::new(
> +            ddev,
> +            size as usize,

As a general rule, let’s try our best to reduce the number of `as` casts. Let’s go with
usize::try_from

> +            shmem::ObjectConfig {
> +                map_wc: true,
> +                parent_resv_obj: None,
> +            },
> +            BoCreateArgs { flags: 0 },
> +        )?;
> +
> +        vm.map_bo_range(&bo, 0, size, va, flags)?;
> +
> +        Ok(KernelBo {
> +            bo,
> +            vm,
> +            va_range: va..(va + size),
> +        })
> +    }
> +}
> +
> +impl Drop for KernelBo<'_> {
> +    fn drop(&mut self) {
> +        let va = self.va_range.start;
> +        let size = self.va_range.end - self.va_range.start;
> +
> +        if let Err(e) = self.vm.unmap_range(va, size) {
> +            pr_err!(
> +                "Failed to unmap KernelBo range {:#x}..{:#x}: {:?}\n",
> +                self.va_range.start,
> +                self.va_range.end,
> +                e
> +            );
> +        }
> +    }
> +}
> 
> -- 
> 2.54.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.