On Wed, Feb 11, 2026 at 09:03:39AM +0100, Boris Brezillon wrote: > While drm_gem_shmem_object does most of the job we need it to do, the > way sub-resources (pages, sgt, vmap) are handled and their lifetimes > gets in the way of BO reclaim. There has been attempts to address > that [1], but in the meantime, new gem_shmem users were introduced > (accel drivers), and some of them manually free some of these resources. > This makes things harder to control/sanitize/validate. > > Thomas Zimmerman is not a huge fan of enforcing lifetimes of sub-resources > and forcing gem_shmem users to go through new gem_shmem helpers when they > need manual control of some sort, and I believe this is a dead end if > we don't force users to follow some stricter rules through carefully > designed helpers, because there will always be one user doing crazy things > with gem_shmem_object internals, which ends up tripping out the common > helpers when they are called. > > The consensus we reached was that we would be better off forking > gem_shmem in panthor. So here we are, parting ways with gem_shmem. The > current transition tries to minimize the changes, but there are still > some aspects that are different, the main one being that we no longer > have a pages_use_count, and pages stays around until the GEM object is > destroyed (or when evicted once we've added a shrinker). The sgt also > no longer retains pages. This is losely based on how msm does things by > the way. > > If there's any interest in sharing code (probably with msm, since the > panthor shrinker is going to be losely based on the msm implementation), > we can always change gears and do that once we have everything > working/merged. > > [1]https://patchwork.kernel.org/project/dri-devel/patch/[email protected]/ > > v2: > - Fix refcounting > - Add a _locked suffix to a bunch of functions expecting the resv lock > to be held > - Take the lock before releasing resources in panthor_gem_free_object() > > v3: > - Use ERR_CAST() to fix an ERR-ptr deref > - Add missing resv_[un]lock() around a panthor_gem_backing_unpin_locked() > call > > Signed-off-by: Boris Brezillon <[email protected]>
With the issue Steven has pointed out fixed: Reviewed-by: Liviu Dudau <[email protected]> Best regards, Liviu > --- > drivers/gpu/drm/panthor/Kconfig | 1 - > drivers/gpu/drm/panthor/panthor_drv.c | 7 +- > drivers/gpu/drm/panthor/panthor_fw.c | 16 +- > drivers/gpu/drm/panthor/panthor_gem.c | 700 ++++++++++++++++++++---- > drivers/gpu/drm/panthor/panthor_gem.h | 62 ++- > drivers/gpu/drm/panthor/panthor_mmu.c | 48 +- > drivers/gpu/drm/panthor/panthor_sched.c | 9 +- > 7 files changed, 669 insertions(+), 174 deletions(-) > > diff --git a/drivers/gpu/drm/panthor/Kconfig b/drivers/gpu/drm/panthor/Kconfig > index 55b40ad07f3b..911e7f4810c3 100644 > --- a/drivers/gpu/drm/panthor/Kconfig > +++ b/drivers/gpu/drm/panthor/Kconfig > @@ -8,7 +8,6 @@ config DRM_PANTHOR > depends on MMU > select DEVFREQ_GOV_SIMPLE_ONDEMAND > select DRM_EXEC > - select DRM_GEM_SHMEM_HELPER > select DRM_GPUVM > select DRM_SCHED > select IOMMU_IO_PGTABLE_LPAE > diff --git a/drivers/gpu/drm/panthor/panthor_drv.c > b/drivers/gpu/drm/panthor/panthor_drv.c > index 52c27a60c84a..90e9abc22d9e 100644 > --- a/drivers/gpu/drm/panthor/panthor_drv.c > +++ b/drivers/gpu/drm/panthor/panthor_drv.c > @@ -19,6 +19,7 @@ > #include <drm/drm_debugfs.h> > #include <drm/drm_drv.h> > #include <drm/drm_exec.h> > +#include <drm/drm_file.h> > #include <drm/drm_ioctl.h> > #include <drm/drm_print.h> > #include <drm/drm_syncobj.h> > @@ -1457,7 +1458,7 @@ static int panthor_ioctl_bo_query_info(struct > drm_device *ddev, void *data, > args->create_flags = bo->flags; > > args->extra_flags = 0; > - if (drm_gem_is_imported(&bo->base.base)) > + if (drm_gem_is_imported(&bo->base)) > args->extra_flags |= DRM_PANTHOR_BO_IS_IMPORTED; > > drm_gem_object_put(obj); > @@ -1671,8 +1672,7 @@ static const struct drm_driver panthor_drm_driver = { > .major = 1, > .minor = 7, > > - .gem_create_object = panthor_gem_create_object, > - .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, > + .gem_prime_import_sg_table = panthor_gem_prime_import_sg_table, > .gem_prime_import = panthor_gem_prime_import, > #ifdef CONFIG_DEBUG_FS > .debugfs_init = panthor_debugfs_init, > @@ -1822,3 +1822,4 @@ module_exit(panthor_exit); > MODULE_AUTHOR("Panthor Project Developers"); > MODULE_DESCRIPTION("Panthor DRM Driver"); > MODULE_LICENSE("Dual MIT/GPL"); > +MODULE_IMPORT_NS("DMA_BUF"); > diff --git a/drivers/gpu/drm/panthor/panthor_fw.c > b/drivers/gpu/drm/panthor/panthor_fw.c > index 5a904ca64525..9e61d26c3a15 100644 > --- a/drivers/gpu/drm/panthor/panthor_fw.c > +++ b/drivers/gpu/drm/panthor/panthor_fw.c > @@ -628,7 +628,6 @@ static int panthor_fw_load_section_entry(struct > panthor_device *ptdev, > u32 cache_mode = hdr.flags & > CSF_FW_BINARY_IFACE_ENTRY_CACHE_MODE_MASK; > struct panthor_gem_object *bo; > u32 vm_map_flags = 0; > - struct sg_table *sgt; > u64 va = hdr.va.start; > > if (!(hdr.flags & CSF_FW_BINARY_IFACE_ENTRY_WR)) > @@ -666,11 +665,12 @@ static int panthor_fw_load_section_entry(struct > panthor_device *ptdev, > panthor_fw_init_section_mem(ptdev, section); > > bo = to_panthor_bo(section->mem->obj); > - sgt = drm_gem_shmem_get_pages_sgt(&bo->base); > - if (IS_ERR(sgt)) > - return PTR_ERR(sgt); > > - dma_sync_sgtable_for_device(ptdev->base.dev, sgt, > DMA_TO_DEVICE); > + /* An sgt should have been requested when the kernel BO was > GPU-mapped. */ > + if (drm_WARN_ON_ONCE(&ptdev->base, !bo->dmap.sgt)) > + return -EINVAL; > + > + dma_sync_sgtable_for_device(ptdev->base.dev, bo->dmap.sgt, > DMA_TO_DEVICE); > } > > if (hdr.va.start == CSF_MCU_SHARED_REGION_START) > @@ -730,8 +730,10 @@ panthor_reload_fw_sections(struct panthor_device *ptdev, > bool full_reload) > continue; > > panthor_fw_init_section_mem(ptdev, section); > - sgt = > drm_gem_shmem_get_pages_sgt(&to_panthor_bo(section->mem->obj)->base); > - if (!drm_WARN_ON(&ptdev->base, IS_ERR_OR_NULL(sgt))) > + > + /* An sgt should have been requested when the kernel BO was > GPU-mapped. */ > + sgt = to_panthor_bo(section->mem->obj)->dmap.sgt; > + if (!drm_WARN_ON_ONCE(&ptdev->base, !sgt)) > dma_sync_sgtable_for_device(ptdev->base.dev, sgt, > DMA_TO_DEVICE); > } > } > diff --git a/drivers/gpu/drm/panthor/panthor_gem.c > b/drivers/gpu/drm/panthor/panthor_gem.c > index 4b3d82f001d8..c07ae062c98f 100644 > --- a/drivers/gpu/drm/panthor/panthor_gem.c > +++ b/drivers/gpu/drm/panthor/panthor_gem.c > @@ -8,9 +8,11 @@ > #include <linux/dma-mapping.h> > #include <linux/err.h> > #include <linux/slab.h> > +#include <linux/vmalloc.h> > > #include <drm/drm_debugfs.h> > #include <drm/drm_file.h> > +#include <drm/drm_prime.h> > #include <drm/drm_print.h> > #include <drm/panthor_drm.h> > > @@ -44,7 +46,7 @@ static void panthor_gem_debugfs_bo_init(struct > panthor_gem_object *bo) > > static void panthor_gem_debugfs_bo_add(struct panthor_gem_object *bo) > { > - struct panthor_device *ptdev = container_of(bo->base.base.dev, > + struct panthor_device *ptdev = container_of(bo->base.dev, > struct panthor_device, > base); > > bo->debugfs.creator.tgid = current->group_leader->pid; > @@ -57,7 +59,7 @@ static void panthor_gem_debugfs_bo_add(struct > panthor_gem_object *bo) > > static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) > { > - struct panthor_device *ptdev = container_of(bo->base.base.dev, > + struct panthor_device *ptdev = container_of(bo->base.dev, > struct panthor_device, > base); > > if (list_empty(&bo->debugfs.node)) > @@ -80,9 +82,9 @@ static void panthor_gem_debugfs_bo_init(struct > panthor_gem_object *bo) {} > #endif > > static bool > -should_map_wc(struct panthor_gem_object *bo, struct panthor_vm *exclusive_vm) > +should_map_wc(struct panthor_gem_object *bo) > { > - struct panthor_device *ptdev = container_of(bo->base.base.dev, struct > panthor_device, base); > + struct panthor_device *ptdev = container_of(bo->base.dev, struct > panthor_device, base); > > /* We can't do uncached mappings if the device is coherent, > * because the zeroing done by the shmem layer at page allocation > @@ -112,6 +114,211 @@ should_map_wc(struct panthor_gem_object *bo, struct > panthor_vm *exclusive_vm) > return true; > } > > +static void > +panthor_gem_backing_cleanup_locked(struct panthor_gem_object *bo) > +{ > + dma_resv_assert_held(bo->base.resv); > + > + if (!bo->backing.pages) > + return; > + > + drm_gem_put_pages(&bo->base, bo->backing.pages, true, false); > + bo->backing.pages = NULL; > +} > + > +static int > +panthor_gem_backing_get_pages_locked(struct panthor_gem_object *bo) > +{ > + dma_resv_assert_held(bo->base.resv); > + > + if (bo->backing.pages) > + return 0; > + > + bo->backing.pages = drm_gem_get_pages(&bo->base); > + if (IS_ERR(bo->backing.pages)) { > + drm_dbg_kms(bo->base.dev, "Failed to get pages (%pe)\n", > + bo->backing.pages); > + return PTR_ERR(bo->backing.pages); > + } > + > + return 0; > +} > + > +static int panthor_gem_backing_pin_locked(struct panthor_gem_object *bo) > +{ > + int ret; > + > + dma_resv_assert_held(bo->base.resv); > + drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base)); > + > + if (refcount_inc_not_zero(&bo->backing.pin_count)) > + return 0; > + > + ret = panthor_gem_backing_get_pages_locked(bo); > + if (!ret) > + refcount_set(&bo->backing.pin_count, 1); > + > + return ret; > +} > + > +static void panthor_gem_backing_unpin_locked(struct panthor_gem_object *bo) > +{ > + dma_resv_assert_held(bo->base.resv); > + drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base)); > + > + if (refcount_dec_and_test(&bo->backing.pin_count)) { > + /* We don't release anything when pin_count drops to zero. > + * Pages stay there until an explicit cleanup is requested. > + */ > + } > +} > + > +static void > +panthor_gem_dev_map_cleanup_locked(struct panthor_gem_object *bo) > +{ > + dma_resv_assert_held(bo->base.resv); > + > + if (!bo->dmap.sgt) > + return; > + > + dma_unmap_sgtable(drm_dev_dma_dev(bo->base.dev), bo->dmap.sgt, > DMA_BIDIRECTIONAL, 0); > + sg_free_table(bo->dmap.sgt); > + kfree(bo->dmap.sgt); > + bo->dmap.sgt = NULL; > +} > + > +static struct sg_table * > +panthor_gem_dev_map_get_sgt_locked(struct panthor_gem_object *bo) > +{ > + struct sg_table *sgt; > + int ret; > + > + dma_resv_assert_held(bo->base.resv); > + > + if (bo->dmap.sgt) > + return bo->dmap.sgt; > + > + if (drm_WARN_ON_ONCE(bo->base.dev, !bo->backing.pages)) > + return ERR_PTR(-EINVAL); > + > + /* Pages stay around after they've been allocated. At least that stands > + * until we add a shrinker. > + */ > + ret = panthor_gem_backing_get_pages_locked(bo); > + if (ret) > + return ERR_PTR(ret); > + > + sgt = drm_prime_pages_to_sg(bo->base.dev, bo->backing.pages, > + bo->base.size >> PAGE_SHIFT); > + if (IS_ERR(sgt)) > + return sgt; > + > + /* Map the pages for use by the h/w. */ > + ret = dma_map_sgtable(drm_dev_dma_dev(bo->base.dev), sgt, > DMA_BIDIRECTIONAL, 0); > + if (ret) > + goto err_free_sgt; > + > + bo->dmap.sgt = sgt; > + return sgt; > + > +err_free_sgt: > + sg_free_table(sgt); > + kfree(sgt); > + return ERR_PTR(ret); > +} > + > +struct sg_table * > +panthor_gem_get_dev_sgt(struct panthor_gem_object *bo) > +{ > + struct sg_table *sgt; > + > + dma_resv_lock(bo->base.resv, NULL); > + sgt = panthor_gem_dev_map_get_sgt_locked(bo); > + dma_resv_unlock(bo->base.resv); > + > + return sgt; > +} > + > +static void > +panthor_gem_vmap_cleanup_locked(struct panthor_gem_object *bo) > +{ > + if (!bo->cmap.vaddr) > + return; > + > + vunmap(bo->cmap.vaddr); > + bo->cmap.vaddr = NULL; > + panthor_gem_backing_unpin_locked(bo); > +} > + > +static int > +panthor_gem_prep_for_cpu_map_locked(struct panthor_gem_object *bo) > +{ > + if (should_map_wc(bo)) { > + struct sg_table *sgt; > + > + sgt = panthor_gem_dev_map_get_sgt_locked(bo); > + if (IS_ERR(sgt)) > + return PTR_ERR(sgt); > + } > + > + return 0; > +} > + > +static void * > +panthor_gem_vmap_get_locked(struct panthor_gem_object *bo) > +{ > + pgprot_t prot = PAGE_KERNEL; > + void *vaddr; > + int ret; > + > + dma_resv_assert_held(bo->base.resv); > + > + if (drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base))) > + return ERR_PTR(-EINVAL); > + > + if (refcount_inc_not_zero(&bo->cmap.vaddr_use_count)) { > + drm_WARN_ON_ONCE(bo->base.dev, !bo->cmap.vaddr); > + return bo->cmap.vaddr; > + } > + > + ret = panthor_gem_backing_pin_locked(bo); > + if (ret) > + return ERR_PTR(ret); > + > + ret = panthor_gem_prep_for_cpu_map_locked(bo); > + if (ret) > + return ERR_PTR(ret); > + > + if (should_map_wc(bo)) > + prot = pgprot_writecombine(prot); > + > + vaddr = vmap(bo->backing.pages, bo->base.size >> PAGE_SHIFT, VM_MAP, > prot); > + if (!vaddr) { > + ret = -ENOMEM; > + goto err_unpin; > + } > + > + bo->cmap.vaddr = vaddr; > + refcount_set(&bo->cmap.vaddr_use_count, 1); > + return vaddr; > + > +err_unpin: > + panthor_gem_backing_unpin_locked(bo); > + return ERR_PTR(ret); > +} > + > +static void > +panthor_gem_vmap_put_locked(struct panthor_gem_object *bo) > +{ > + dma_resv_assert_held(bo->base.resv); > + > + if (drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base))) > + return; > + > + if (refcount_dec_and_test(&bo->cmap.vaddr_use_count)) > + panthor_gem_vmap_cleanup_locked(bo); > +} > + > static void panthor_gem_free_object(struct drm_gem_object *obj) > { > struct panthor_gem_object *bo = to_panthor_bo(obj); > @@ -127,8 +334,19 @@ static void panthor_gem_free_object(struct > drm_gem_object *obj) > > mutex_destroy(&bo->label.lock); > > - drm_gem_free_mmap_offset(&bo->base.base); > - drm_gem_shmem_free(&bo->base); > + if (drm_gem_is_imported(obj)) { > + drm_prime_gem_destroy(obj, bo->dmap.sgt); > + } else { > + dma_resv_lock(obj->resv, NULL); > + panthor_gem_vmap_cleanup_locked(bo); > + panthor_gem_dev_map_cleanup_locked(bo); > + panthor_gem_backing_cleanup_locked(bo); > + dma_resv_unlock(obj->resv); > + } > + > + drm_gem_object_release(obj); > + > + kfree(bo); > drm_gem_object_put(vm_root_gem); > } > > @@ -159,15 +377,15 @@ panthor_gem_prime_begin_cpu_access(struct dma_buf > *dma_buf, > { > struct drm_gem_object *obj = dma_buf->priv; > struct drm_device *dev = obj->dev; > - struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); > + struct panthor_gem_object *bo = to_panthor_bo(obj); > struct dma_buf_attachment *attach; > > dma_resv_lock(obj->resv, NULL); > - if (shmem->sgt) > - dma_sync_sgtable_for_cpu(dev->dev, shmem->sgt, dir); > + if (bo->dmap.sgt) > + dma_sync_sgtable_for_cpu(drm_dev_dma_dev(dev), bo->dmap.sgt, > dir); > > - if (shmem->vaddr) > - invalidate_kernel_vmap_range(shmem->vaddr, shmem->base.size); > + if (bo->cmap.vaddr) > + invalidate_kernel_vmap_range(bo->cmap.vaddr, bo->base.size); > > list_for_each_entry(attach, &dma_buf->attachments, node) { > struct sg_table *sgt = attach->priv; > @@ -186,7 +404,7 @@ panthor_gem_prime_end_cpu_access(struct dma_buf *dma_buf, > { > struct drm_gem_object *obj = dma_buf->priv; > struct drm_device *dev = obj->dev; > - struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); > + struct panthor_gem_object *bo = to_panthor_bo(obj); > struct dma_buf_attachment *attach; > > dma_resv_lock(obj->resv, NULL); > @@ -197,11 +415,11 @@ panthor_gem_prime_end_cpu_access(struct dma_buf > *dma_buf, > dma_sync_sgtable_for_device(attach->dev, sgt, dir); > } > > - if (shmem->vaddr) > - flush_kernel_vmap_range(shmem->vaddr, shmem->base.size); > + if (bo->cmap.vaddr) > + flush_kernel_vmap_range(bo->cmap.vaddr, bo->base.size); > > - if (shmem->sgt) > - dma_sync_sgtable_for_device(dev->dev, shmem->sgt, dir); > + if (bo->dmap.sgt) > + dma_sync_sgtable_for_device(drm_dev_dma_dev(dev), bo->dmap.sgt, > dir); > > dma_resv_unlock(obj->resv); > return 0; > @@ -258,53 +476,338 @@ panthor_gem_prime_import(struct drm_device *dev, > return drm_gem_prime_import(dev, dma_buf); > } > > +static void panthor_gem_print_info(struct drm_printer *p, unsigned int > indent, > + const struct drm_gem_object *obj) > +{ > + const struct panthor_gem_object *bo = to_panthor_bo(obj); > + > + if (drm_gem_is_imported(&bo->base)) > + return; > + > + drm_printf_indent(p, indent, "resident=%s\n", > str_true_false(bo->backing.pages)); > + drm_printf_indent(p, indent, "pages_pin_count=%u\n", > refcount_read(&bo->backing.pin_count)); > + drm_printf_indent(p, indent, "vmap_use_count=%u\n", > + refcount_read(&bo->cmap.vaddr_use_count)); > + drm_printf_indent(p, indent, "vaddr=%p\n", bo->cmap.vaddr); > +} > + > +static int panthor_gem_pin_locked(struct drm_gem_object *obj) > +{ > + if (drm_gem_is_imported(obj)) > + return 0; > + > + return panthor_gem_backing_pin_locked(to_panthor_bo(obj)); > +} > + > +static void panthor_gem_unpin_locked(struct drm_gem_object *obj) > +{ > + if (!drm_gem_is_imported(obj)) > + panthor_gem_backing_unpin_locked(to_panthor_bo(obj)); > +} > + > +int panthor_gem_pin(struct panthor_gem_object *bo) > +{ > + int ret = 0; > + > + if (drm_gem_is_imported(&bo->base)) > + return 0; > + > + if (refcount_inc_not_zero(&bo->backing.pin_count)) > + return 0; > + > + dma_resv_lock(bo->base.resv, NULL); > + ret = panthor_gem_backing_pin_locked(bo); > + dma_resv_unlock(bo->base.resv); > + > + return ret; > +} > + > +void panthor_gem_unpin(struct panthor_gem_object *bo) > +{ > + if (drm_gem_is_imported(&bo->base)) > + return; > + > + if (!refcount_dec_not_one(&bo->backing.pin_count)) { > + dma_resv_lock(bo->base.resv, NULL); > + panthor_gem_backing_unpin_locked(bo); > + dma_resv_unlock(bo->base.resv); > + } > +} > + > +static struct sg_table *panthor_gem_get_sg_table(struct drm_gem_object *obj) > +{ > + struct panthor_gem_object *bo = to_panthor_bo(obj); > + > + drm_WARN_ON_ONCE(obj->dev, drm_gem_is_imported(obj)); > + drm_WARN_ON_ONCE(obj->dev, !bo->backing.pages); > + drm_WARN_ON_ONCE(obj->dev, !refcount_read(&bo->backing.pin_count)); > + > + return drm_prime_pages_to_sg(obj->dev, bo->backing.pages, obj->size >> > PAGE_SHIFT); > +} > + > +static int panthor_gem_vmap_locked(struct drm_gem_object *obj, > + struct iosys_map *map) > +{ > + struct panthor_gem_object *bo = to_panthor_bo(obj); > + void *vaddr; > + > + dma_resv_assert_held(obj->resv); > + > + if (drm_gem_is_imported(obj)) > + return dma_buf_vmap(obj->import_attach->dmabuf, map); > + > + vaddr = panthor_gem_vmap_get_locked(bo); > + if (IS_ERR(vaddr)) > + return PTR_ERR(vaddr); > + > + iosys_map_set_vaddr(map, vaddr); > + return 0; > +} > + > +static void panthor_gem_vunmap_locked(struct drm_gem_object *obj, > + struct iosys_map *map) > +{ > + struct panthor_gem_object *bo = to_panthor_bo(obj); > + > + dma_resv_assert_held(obj->resv); > + > + if (drm_gem_is_imported(obj)) { > + dma_buf_vunmap(obj->import_attach->dmabuf, map); > + } else { > + drm_WARN_ON_ONCE(obj->dev, bo->cmap.vaddr != map->vaddr); > + panthor_gem_vmap_put_locked(bo); > + } > +} > + > +static int panthor_gem_mmap(struct drm_gem_object *obj, struct > vm_area_struct *vma) > +{ > + struct panthor_gem_object *bo = to_panthor_bo(obj); > + int ret; > + > + if (drm_gem_is_imported(obj)) { > + /* Reset both vm_ops and vm_private_data, so we don't end up > with > + * vm_ops pointing to our implementation if the dma-buf backend > + * doesn't set those fields. > + */ > + vma->vm_private_data = NULL; > + vma->vm_ops = NULL; > + > + ret = dma_buf_mmap(obj->dma_buf, vma, 0); > + > + /* Drop the reference drm_gem_mmap_obj() acquired.*/ > + if (!ret) > + drm_gem_object_put(obj); > + > + return ret; > + } > + > + if (is_cow_mapping(vma->vm_flags)) > + return -EINVAL; > + > + dma_resv_lock(obj->resv, NULL); > + ret = panthor_gem_backing_get_pages_locked(bo); > + if (!ret) > + ret = panthor_gem_prep_for_cpu_map_locked(bo); > + dma_resv_unlock(obj->resv); > + > + if (ret) > + return ret; > + > + vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); > + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); > + if (should_map_wc(bo)) > + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); > + > + return 0; > +} > + > static enum drm_gem_object_status panthor_gem_status(struct drm_gem_object > *obj) > { > struct panthor_gem_object *bo = to_panthor_bo(obj); > enum drm_gem_object_status res = 0; > > - if (drm_gem_is_imported(&bo->base.base) || bo->base.pages) > + if (drm_gem_is_imported(&bo->base) || bo->backing.pages) > res |= DRM_GEM_OBJECT_RESIDENT; > > return res; > } > > -static const struct drm_gem_object_funcs panthor_gem_funcs = { > - .free = panthor_gem_free_object, > - .print_info = drm_gem_shmem_object_print_info, > - .pin = drm_gem_shmem_object_pin, > - .unpin = drm_gem_shmem_object_unpin, > - .get_sg_table = drm_gem_shmem_object_get_sg_table, > - .vmap = drm_gem_shmem_object_vmap, > - .vunmap = drm_gem_shmem_object_vunmap, > - .mmap = drm_gem_shmem_object_mmap, > - .status = panthor_gem_status, > - .export = panthor_gem_prime_export, > - .vm_ops = &drm_gem_shmem_vm_ops, > +static bool try_map_pmd(struct vm_fault *vmf, unsigned long addr, struct > page *page) > +{ > +#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP > + unsigned long pfn = page_to_pfn(page); > + unsigned long paddr = pfn << PAGE_SHIFT; > + bool aligned = (addr & ~PMD_MASK) == (paddr & ~PMD_MASK); > + > + if (aligned && > + pmd_none(*vmf->pmd) && > + folio_test_pmd_mappable(page_folio(page))) { > + pfn &= PMD_MASK >> PAGE_SHIFT; > + if (vmf_insert_pfn_pmd(vmf, pfn, false) == VM_FAULT_NOPAGE) > + return true; > + } > +#endif > + > + return false; > +} > + > +static vm_fault_t panthor_gem_fault(struct vm_fault *vmf) > +{ > + struct vm_area_struct *vma = vmf->vma; > + struct drm_gem_object *obj = vma->vm_private_data; > + struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); > + loff_t num_pages = obj->size >> PAGE_SHIFT; > + vm_fault_t ret; > + pgoff_t page_offset; > + unsigned long pfn; > + > + /* Offset to faulty address in the VMA. */ > + page_offset = vmf->pgoff - vma->vm_pgoff; > + > + dma_resv_lock(bo->base.resv, NULL); > + > + if (page_offset >= num_pages || > + drm_WARN_ON_ONCE(obj->dev, !bo->backing.pages)) { > + ret = VM_FAULT_SIGBUS; > + goto out; > + } > + > + if (try_map_pmd(vmf, vmf->address, bo->backing.pages[page_offset])) { > + ret = VM_FAULT_NOPAGE; > + goto out; > + } > + > + pfn = page_to_pfn(bo->backing.pages[page_offset]); > + ret = vmf_insert_pfn(vma, vmf->address, pfn); > + > + out: > + dma_resv_unlock(bo->base.resv); > + > + return ret; > +} > + > +static void panthor_gem_vm_open(struct vm_area_struct *vma) > +{ > + struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); > + > + drm_WARN_ON(bo->base.dev, drm_gem_is_imported(&bo->base)); > + > + dma_resv_lock(bo->base.resv, NULL); > + > + /* We should have already pinned the pages when the buffer was first > + * mmap'd, vm_open() just grabs an additional reference for the new > + * mm the vma is getting copied into (ie. on fork()). > + */ > + drm_WARN_ON_ONCE(bo->base.dev, !bo->backing.pages); > + > + dma_resv_unlock(bo->base.resv); > + > + drm_gem_vm_open(vma); > +} > + > +const struct vm_operations_struct panthor_gem_vm_ops = { > + .fault = panthor_gem_fault, > + .open = panthor_gem_vm_open, > + .close = drm_gem_vm_close, > }; > > -/** > - * panthor_gem_create_object - Implementation of driver->gem_create_object. > - * @ddev: DRM device > - * @size: Size in bytes of the memory the object will reference > - * > - * This lets the GEM helpers allocate object structs for us, and keep > - * our BO stats correct. > - */ > -struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, > size_t size) > -{ > - struct panthor_gem_object *obj; > +static const struct drm_gem_object_funcs panthor_gem_funcs = { > + .free = panthor_gem_free_object, > + .print_info = panthor_gem_print_info, > + .pin = panthor_gem_pin_locked, > + .unpin = panthor_gem_unpin_locked, > + .get_sg_table = panthor_gem_get_sg_table, > + .vmap = panthor_gem_vmap_locked, > + .vunmap = panthor_gem_vunmap_locked, > + .mmap = panthor_gem_mmap, > + .status = panthor_gem_status, > + .export = panthor_gem_prime_export, > + .vm_ops = &panthor_gem_vm_ops, > +}; > > - obj = kzalloc(sizeof(*obj), GFP_KERNEL); > - if (!obj) > +static struct panthor_gem_object * > +panthor_gem_alloc_object(uint32_t flags) > +{ > + struct panthor_gem_object *bo; > + > + bo = kzalloc(sizeof(*bo), GFP_KERNEL); > + if (!bo) > return ERR_PTR(-ENOMEM); > > - obj->base.base.funcs = &panthor_gem_funcs; > - mutex_init(&obj->label.lock); > + bo->base.funcs = &panthor_gem_funcs; > + bo->flags = flags; > + mutex_init(&bo->label.lock); > + panthor_gem_debugfs_bo_init(bo); > + return bo; > +} > > - panthor_gem_debugfs_bo_init(obj); > +static struct panthor_gem_object * > +panthor_gem_create(struct drm_device *dev, size_t size, uint32_t flags, > + struct panthor_vm *exclusive_vm, u32 usage_flags) > +{ > + struct panthor_gem_object *bo; > + int ret; > > - return &obj->base.base; > + bo = panthor_gem_alloc_object(flags); > + if (IS_ERR(bo)) > + return bo; > + > + size = PAGE_ALIGN(size); > + ret = drm_gem_object_init(dev, &bo->base, size); > + if (ret) > + goto err_put; > + > + /* Our buffers are kept pinned, so allocating them > + * from the MOVABLE zone is a really bad idea, and > + * conflicts with CMA. See comments above new_inode() > + * why this is required _and_ expected if you're > + * going to pin these pages. > + */ > + mapping_set_gfp_mask(bo->base.filp->f_mapping, > + GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); > + > + ret = drm_gem_create_mmap_offset(&bo->base); > + if (ret) > + goto err_put; > + > + if (exclusive_vm) { > + bo->exclusive_vm_root_gem = panthor_vm_root_gem(exclusive_vm); > + drm_gem_object_get(bo->exclusive_vm_root_gem); > + bo->base.resv = bo->exclusive_vm_root_gem->resv; > + } > + > + panthor_gem_debugfs_set_usage_flags(bo, usage_flags); > + return bo; > + > +err_put: > + drm_gem_object_put(&bo->base); > + return ERR_PTR(ret); > +} > + > +struct drm_gem_object * > +panthor_gem_prime_import_sg_table(struct drm_device *dev, > + struct dma_buf_attachment *attach, > + struct sg_table *sgt) > +{ > + struct panthor_gem_object *bo; > + int ret; > + > + bo = panthor_gem_alloc_object(0); > + if (IS_ERR(bo)) > + return ERR_CAST(bo); > + > + drm_gem_private_object_init(dev, &bo->base, attach->dmabuf->size); > + > + ret = drm_gem_create_mmap_offset(&bo->base); > + if (ret) > + goto err_put; > + > + bo->dmap.sgt = sgt; > + return &bo->base; > + > +err_put: > + drm_gem_object_put(&bo->base); > + return ERR_PTR(ret); > } > > /** > @@ -325,54 +828,22 @@ panthor_gem_create_with_handle(struct drm_file *file, > u64 *size, u32 flags, u32 *handle) > { > int ret; > - struct drm_gem_shmem_object *shmem; > struct panthor_gem_object *bo; > > - shmem = drm_gem_shmem_create(ddev, *size); > - if (IS_ERR(shmem)) > - return PTR_ERR(shmem); > - > - bo = to_panthor_bo(&shmem->base); > - bo->flags = flags; > - bo->base.map_wc = should_map_wc(bo, exclusive_vm); > - > - if (exclusive_vm) { > - bo->exclusive_vm_root_gem = panthor_vm_root_gem(exclusive_vm); > - drm_gem_object_get(bo->exclusive_vm_root_gem); > - bo->base.base.resv = bo->exclusive_vm_root_gem->resv; > - } > - > - panthor_gem_debugfs_set_usage_flags(bo, 0); > - > - /* If this is a write-combine mapping, we query the sgt to force a CPU > - * cache flush (dma_map_sgtable() is called when the sgt is created). > - * This ensures the zero-ing is visible to any uncached mapping created > - * by vmap/mmap. > - * FIXME: Ideally this should be done when pages are allocated, not at > - * BO creation time. > - */ > - if (shmem->map_wc) { > - struct sg_table *sgt; > - > - sgt = drm_gem_shmem_get_pages_sgt(shmem); > - if (IS_ERR(sgt)) { > - ret = PTR_ERR(sgt); > - goto out_put_gem; > - } > - } > + bo = panthor_gem_create(ddev, *size, flags, exclusive_vm, 0); > + if (IS_ERR(bo)) > + return PTR_ERR(bo); > > /* > * Allocate an id of idr table where the obj is registered > * and handle has the id what user can see. > */ > - ret = drm_gem_handle_create(file, &shmem->base, handle); > + ret = drm_gem_handle_create(file, &bo->base, handle); > if (!ret) > - *size = bo->base.base.size; > + *size = bo->base.size; > > -out_put_gem: > /* drop reference from allocate - handle holds it now. */ > - drm_gem_object_put(&shmem->base); > - > + drm_gem_object_put(&bo->base); > return ret; > } > > @@ -417,18 +888,17 @@ panthor_gem_sync(struct drm_gem_object *obj, u32 type, > u64 offset, u64 size) > { > struct panthor_gem_object *bo = to_panthor_bo(obj); > - struct drm_gem_shmem_object *shmem = &bo->base; > - const struct drm_device *dev = shmem->base.dev; > + struct device *dma_dev = drm_dev_dma_dev(bo->base.dev); > struct sg_table *sgt; > struct scatterlist *sgl; > unsigned int count; > > /* Make sure the range is in bounds. */ > - if (offset + size < offset || offset + size > shmem->base.size) > + if (offset + size < offset || offset + size > bo->base.size) > return -EINVAL; > > /* Disallow CPU-cache maintenance on imported buffers. */ > - if (drm_gem_is_imported(&shmem->base)) > + if (drm_gem_is_imported(&bo->base)) > return -EINVAL; > > switch (type) { > @@ -441,14 +911,14 @@ panthor_gem_sync(struct drm_gem_object *obj, u32 type, > } > > /* Don't bother if it's WC-mapped */ > - if (shmem->map_wc) > + if (should_map_wc(bo)) > return 0; > > /* Nothing to do if the size is zero. */ > if (size == 0) > return 0; > > - sgt = drm_gem_shmem_get_pages_sgt(shmem); > + sgt = panthor_gem_get_dev_sgt(bo); > if (IS_ERR(sgt)) > return PTR_ERR(sgt); > > @@ -489,9 +959,9 @@ panthor_gem_sync(struct drm_gem_object *obj, u32 type, > * > * for the flush+invalidate case. > */ > - dma_sync_single_for_device(dev->dev, paddr, len, DMA_TO_DEVICE); > + dma_sync_single_for_device(dma_dev, paddr, len, DMA_TO_DEVICE); > if (type == DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE) > - dma_sync_single_for_cpu(dev->dev, paddr, len, > DMA_FROM_DEVICE); > + dma_sync_single_for_cpu(dma_dev, paddr, len, > DMA_FROM_DEVICE); > } > > return 0; > @@ -541,7 +1011,6 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, > struct panthor_vm *vm, > size_t size, u32 bo_flags, u32 vm_map_flags, > u64 gpu_va, const char *name) > { > - struct drm_gem_shmem_object *obj; > struct panthor_kernel_bo *kbo; > struct panthor_gem_object *bo; > u32 debug_flags = PANTHOR_DEBUGFS_GEM_USAGE_FLAG_KERNEL; > @@ -554,25 +1023,18 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, > struct panthor_vm *vm, > if (!kbo) > return ERR_PTR(-ENOMEM); > > - obj = drm_gem_shmem_create(&ptdev->base, size); > - if (IS_ERR(obj)) { > - ret = PTR_ERR(obj); > - goto err_free_bo; > - } > - > - bo = to_panthor_bo(&obj->base); > - kbo->obj = &obj->base; > - bo->flags = bo_flags; > - bo->base.map_wc = should_map_wc(bo, vm); > - bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); > - drm_gem_object_get(bo->exclusive_vm_root_gem); > - bo->base.base.resv = bo->exclusive_vm_root_gem->resv; > - > if (vm == panthor_fw_vm(ptdev)) > debug_flags |= PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED; > > + bo = panthor_gem_create(&ptdev->base, size, bo_flags, vm, debug_flags); > + if (IS_ERR(bo)) { > + ret = PTR_ERR(bo); > + goto err_free_kbo; > + } > + > + kbo->obj = &bo->base; > + > panthor_gem_kernel_bo_set_label(kbo, name); > - panthor_gem_debugfs_set_usage_flags(to_panthor_bo(kbo->obj), > debug_flags); > > /* The system and GPU MMU page size might differ, which becomes a > * problem for FW sections that need to be mapped at explicit address > @@ -596,9 +1058,9 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, > struct panthor_vm *vm, > panthor_vm_free_va(vm, &kbo->va_node); > > err_put_obj: > - drm_gem_object_put(&obj->base); > + drm_gem_object_put(&bo->base); > > -err_free_bo: > +err_free_kbo: > kfree(kbo); > return ERR_PTR(ret); > } > @@ -646,7 +1108,7 @@ static void panthor_gem_debugfs_bo_print(struct > panthor_gem_object *bo, > struct seq_file *m, > struct gem_size_totals *totals) > { > - unsigned int refcount = kref_read(&bo->base.base.refcount); > + unsigned int refcount = kref_read(&bo->base.refcount); > char creator_info[32] = {}; > size_t resident_size; > u32 gem_usage_flags = bo->debugfs.flags; > @@ -656,21 +1118,21 @@ static void panthor_gem_debugfs_bo_print(struct > panthor_gem_object *bo, > if (!refcount) > return; > > - resident_size = bo->base.pages ? bo->base.base.size : 0; > + resident_size = bo->backing.pages ? bo->base.size : 0; > > snprintf(creator_info, sizeof(creator_info), > "%s/%d", bo->debugfs.creator.process_name, > bo->debugfs.creator.tgid); > seq_printf(m, "%-32s%-16d%-16d%-16zd%-16zd0x%-16lx", > creator_info, > - bo->base.base.name, > + bo->base.name, > refcount, > - bo->base.base.size, > + bo->base.size, > resident_size, > - drm_vma_node_start(&bo->base.base.vma_node)); > + drm_vma_node_start(&bo->base.vma_node)); > > - if (bo->base.base.import_attach) > + if (bo->base.import_attach) > gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED; > - if (bo->base.base.dma_buf) > + if (bo->base.dma_buf) > gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED; > > seq_printf(m, "0x%-8x 0x%-10x", gem_state_flags, gem_usage_flags); > @@ -679,10 +1141,8 @@ static void panthor_gem_debugfs_bo_print(struct > panthor_gem_object *bo, > seq_printf(m, "%s\n", bo->label.str ? : ""); > } > > - totals->size += bo->base.base.size; > + totals->size += bo->base.size; > totals->resident += resident_size; > - if (bo->base.madv > 0) > - totals->reclaimable += resident_size; > } > > static void panthor_gem_debugfs_print_bos(struct panthor_device *ptdev, > diff --git a/drivers/gpu/drm/panthor/panthor_gem.h > b/drivers/gpu/drm/panthor/panthor_gem.h > index 94b2d17cf032..b66478c9590c 100644 > --- a/drivers/gpu/drm/panthor/panthor_gem.h > +++ b/drivers/gpu/drm/panthor/panthor_gem.h > @@ -5,7 +5,7 @@ > #ifndef __PANTHOR_GEM_H__ > #define __PANTHOR_GEM_H__ > > -#include <drm/drm_gem_shmem_helper.h> > +#include <drm/drm_gem.h> > #include <drm/drm_mm.h> > > #include <linux/iosys-map.h> > @@ -60,12 +60,51 @@ struct panthor_gem_debugfs { > u32 flags; > }; > > +/** > + * struct panthor_gem_backing - GEM memory backing related data > + */ > +struct panthor_gem_backing { > + /** @pages: Pages requested with drm_gem_get_pages() */ > + struct page **pages; > + > + /** @pin_count: Number of active pin requests on this GEM */ > + refcount_t pin_count; > +}; > + > +/** > + * struct panthor_gem_cpu_map - GEM CPU mapping related data > + */ > +struct panthor_gem_cpu_map { > + /** @vaddr: Address returned by vmap() */ > + void *vaddr; > + > + /** @vaddr_use_count: Number of active vmap() requests on this GEM */ > + refcount_t vaddr_use_count; > +}; > + > +/** > + * struct panthor_gem_dev_map - GEM device mapping related data > + */ > +struct panthor_gem_dev_map { > + /** @sgt: Device mapped sg_table for this GEM */ > + struct sg_table *sgt; > +}; > + > /** > * struct panthor_gem_object - Driver specific GEM object. > */ > struct panthor_gem_object { > - /** @base: Inherit from drm_gem_shmem_object. */ > - struct drm_gem_shmem_object base; > + /** @base: Inherit from drm_gem_object. */ > + struct drm_gem_object base; > + > + /** @backing: Memory backing state */ > + struct panthor_gem_backing backing; > + > + /** @cmap: CPU mapping state */ > + struct panthor_gem_cpu_map cmap; > + > + /** @dmap: Device mapping state */ > + struct panthor_gem_dev_map dmap; > > /** > * @exclusive_vm_root_gem: Root GEM of the exclusive VM this GEM object > @@ -130,22 +169,25 @@ struct panthor_kernel_bo { > void *kmap; > }; > > -static inline > -struct panthor_gem_object *to_panthor_bo(struct drm_gem_object *obj) > -{ > - return container_of(to_drm_gem_shmem_obj(obj), struct > panthor_gem_object, base); > -} > +#define to_panthor_bo(obj) container_of_const(obj, struct > panthor_gem_object, base) > > void panthor_gem_init(struct panthor_device *ptdev); > > -struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, > size_t size); > - > +struct drm_gem_object * > +panthor_gem_prime_import_sg_table(struct drm_device *dev, > + struct dma_buf_attachment *attach, > + struct sg_table *sgt); > int > panthor_gem_create_with_handle(struct drm_file *file, > struct drm_device *ddev, > struct panthor_vm *exclusive_vm, > u64 *size, u32 flags, uint32_t *handle); > > +struct sg_table * > +panthor_gem_get_dev_sgt(struct panthor_gem_object *bo); > +int panthor_gem_pin(struct panthor_gem_object *bo); > +void panthor_gem_unpin(struct panthor_gem_object *bo); > + > void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label); > void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const > char *label); > int panthor_gem_sync(struct drm_gem_object *obj, > diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c > b/drivers/gpu/drm/panthor/panthor_mmu.c > index 99c794c429ca..dc2d653edf12 100644 > --- a/drivers/gpu/drm/panthor/panthor_mmu.c > +++ b/drivers/gpu/drm/panthor/panthor_mmu.c > @@ -5,6 +5,7 @@ > #include <drm/drm_debugfs.h> > #include <drm/drm_drv.h> > #include <drm/drm_exec.h> > +#include <drm/drm_file.h> > #include <drm/drm_gpuvm.h> > #include <drm/drm_managed.h> > #include <drm/drm_print.h> > @@ -1083,8 +1084,7 @@ static void panthor_vm_bo_free(struct drm_gpuvm_bo > *vm_bo) > { > struct panthor_gem_object *bo = to_panthor_bo(vm_bo->obj); > > - if (!drm_gem_is_imported(&bo->base.base)) > - drm_gem_shmem_unpin(&bo->base); > + panthor_gem_unpin(bo); > kfree(vm_bo); > } > > @@ -1206,7 +1206,7 @@ static int panthor_vm_prepare_map_op_ctx(struct > panthor_vm_op_ctx *op_ctx, > return -EINVAL; > > /* Make sure the VA and size are in-bounds. */ > - if (size > bo->base.base.size || offset > bo->base.base.size - size) > + if (size > bo->base.size || offset > bo->base.size - size) > return -EINVAL; > > /* If the BO has an exclusive VM attached, it can't be mapped to other > VMs. */ > @@ -1223,39 +1223,30 @@ static int panthor_vm_prepare_map_op_ctx(struct > panthor_vm_op_ctx *op_ctx, > if (ret) > goto err_cleanup; > > - if (!drm_gem_is_imported(&bo->base.base)) { > - /* Pre-reserve the BO pages, so the map operation doesn't have > to > - * allocate. This pin is dropped in panthor_vm_bo_free(), so > - * once we have successfully called drm_gpuvm_bo_create(), > - * GPUVM will take care of dropping the pin for us. > - */ > - ret = drm_gem_shmem_pin(&bo->base); > - if (ret) > - goto err_cleanup; > - } > + /* Pre-reserve the BO pages, so the map operation doesn't have to > + * allocate. > + */ > + ret = panthor_gem_pin(bo); > + if (ret) > + goto err_cleanup; > > - sgt = drm_gem_shmem_get_pages_sgt(&bo->base); > + sgt = panthor_gem_get_dev_sgt(bo); > if (IS_ERR(sgt)) { > - if (!drm_gem_is_imported(&bo->base.base)) > - drm_gem_shmem_unpin(&bo->base); > - > + panthor_gem_unpin(bo); > ret = PTR_ERR(sgt); > goto err_cleanup; > } > > op_ctx->map.sgt = sgt; > > - preallocated_vm_bo = drm_gpuvm_bo_create(&vm->base, &bo->base.base); > + preallocated_vm_bo = drm_gpuvm_bo_create(&vm->base, &bo->base); > if (!preallocated_vm_bo) { > - if (!drm_gem_is_imported(&bo->base.base)) > - drm_gem_shmem_unpin(&bo->base); > - > + panthor_gem_unpin(bo); > ret = -ENOMEM; > goto err_cleanup; > } > > op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo); > - > op_ctx->map.bo_offset = offset; > > /* L1, L2 and L3 page tables. > @@ -1284,7 +1275,7 @@ static int panthor_vm_prepare_map_op_ctx(struct > panthor_vm_op_ctx *op_ctx, > } > > /* Insert BO into the extobj list last, when we know nothing can fail. > */ > - if (bo->base.base.resv != panthor_vm_resv(vm)) { > + if (bo->base.resv != panthor_vm_resv(vm)) { > dma_resv_lock(panthor_vm_resv(vm), NULL); > drm_gpuvm_bo_extobj_add(op_ctx->map.vm_bo); > dma_resv_unlock(panthor_vm_resv(vm)); > @@ -2056,9 +2047,9 @@ static void panthor_vma_link(struct panthor_vm *vm, > { > struct panthor_gem_object *bo = to_panthor_bo(vma->base.gem.obj); > > - mutex_lock(&bo->base.base.gpuva.lock); > + mutex_lock(&bo->base.gpuva.lock); > drm_gpuva_link(&vma->base, vm_bo); > - mutex_unlock(&bo->base.base.gpuva.lock); > + mutex_unlock(&bo->base.gpuva.lock); > } > > static void panthor_vma_unlink(struct panthor_vma *vma) > @@ -2110,11 +2101,12 @@ static int panthor_gpuva_sm_step_map(struct > drm_gpuva_op *op, void *priv) > static bool > iova_mapped_as_huge_page(struct drm_gpuva_op_map *op, u64 addr) > { > + struct panthor_gem_object *bo = to_panthor_bo(op->gem.obj); > const struct page *pg; > pgoff_t bo_offset; > > bo_offset = addr - op->va.addr + op->gem.offset; > - pg = to_panthor_bo(op->gem.obj)->base.pages[bo_offset >> PAGE_SHIFT]; > + pg = bo->backing.pages[bo_offset >> PAGE_SHIFT]; > > return folio_size(page_folio(pg)) >= SZ_2M; > } > @@ -2183,7 +2175,7 @@ static int panthor_gpuva_sm_step_remap(struct > drm_gpuva_op *op, > u64 size = op->remap.prev->va.addr + op->remap.prev->va.range - > unmap_start; > > ret = panthor_vm_map_pages(vm, unmap_start, > flags_to_prot(unmap_vma->flags), > - bo->base.sgt, offset, size); > + bo->dmap.sgt, offset, size); > if (ret) > return ret; > > @@ -2197,7 +2189,7 @@ static int panthor_gpuva_sm_step_remap(struct > drm_gpuva_op *op, > u64 size = unmap_start + unmap_range - op->remap.next->va.addr; > > ret = panthor_vm_map_pages(vm, addr, > flags_to_prot(unmap_vma->flags), > - bo->base.sgt, > op->remap.next->gem.offset, size); > + bo->dmap.sgt, > op->remap.next->gem.offset, size); > if (ret) > return ret; > > diff --git a/drivers/gpu/drm/panthor/panthor_sched.c > b/drivers/gpu/drm/panthor/panthor_sched.c > index ca272dbae14d..2ddf64870d85 100644 > --- a/drivers/gpu/drm/panthor/panthor_sched.c > +++ b/drivers/gpu/drm/panthor/panthor_sched.c > @@ -3,7 +3,7 @@ > > #include <drm/drm_drv.h> > #include <drm/drm_exec.h> > -#include <drm/drm_gem_shmem_helper.h> > +#include <drm/drm_file.h> > #include <drm/drm_managed.h> > #include <drm/drm_print.h> > #include <drm/gpu_scheduler.h> > @@ -871,8 +871,7 @@ panthor_queue_get_syncwait_obj(struct panthor_group > *group, struct panthor_queue > int ret; > > if (queue->syncwait.kmap) { > - bo = container_of(queue->syncwait.obj, > - struct panthor_gem_object, base.base); > + bo = to_panthor_bo(queue->syncwait.obj); > goto out_sync; > } > > @@ -882,7 +881,7 @@ panthor_queue_get_syncwait_obj(struct panthor_group > *group, struct panthor_queue > if (drm_WARN_ON(&ptdev->base, IS_ERR_OR_NULL(bo))) > goto err_put_syncwait_obj; > > - queue->syncwait.obj = &bo->base.base; > + queue->syncwait.obj = &bo->base; > ret = drm_gem_vmap(queue->syncwait.obj, &map); > if (drm_WARN_ON(&ptdev->base, ret)) > goto err_put_syncwait_obj; > @@ -896,7 +895,7 @@ panthor_queue_get_syncwait_obj(struct panthor_group > *group, struct panthor_queue > * drm_gem_shmem_sync() is a NOP if map_wc=true, so no need to check > * it here. > */ > - panthor_gem_sync(&bo->base.base, queue->syncwait.offset, > + panthor_gem_sync(&bo->base, queue->syncwait.offset, > queue->syncwait.sync64 ? > sizeof(struct panthor_syncobj_64b) : > sizeof(struct panthor_syncobj_32b), > -- > 2.52.0 > -- ==================== | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --------------- ¯\_(ツ)_/¯
