Reviewed-by: Adrián Larumbe <[email protected]> On 26.08.2026 16:56, Boris Brezillon wrote: > We will soon need this to fix the unplug logic and make sure panthor_vm > objects are not left behind after an unplug. > > Signed-off-by: Boris Brezillon <[email protected]> > --- > drivers/gpu/drm/panthor/panthor_mmu.c | 31 +++++++++++++++++++++++++++---- > 1 file changed, 27 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c > b/drivers/gpu/drm/panthor/panthor_mmu.c > index 47c57b39bd12..6368bf57b8f5 100644 > --- a/drivers/gpu/drm/panthor/panthor_mmu.c > +++ b/drivers/gpu/drm/panthor/panthor_mmu.c > @@ -117,12 +117,15 @@ struct panthor_mmu { > > /** @vm: VMs management fields */ > struct { > - /** @vm.lock: Lock protecting access to list. */ > + /** @vm.lock: Lock protecting access to list and user_owned. */ > struct mutex lock; > > /** @vm.list: List containing all VMs. */ > struct list_head list; > > + /** @vm.list: List containing VMs with a valid handle. */ > + struct list_head user_owned; > + > /** @vm.reset_in_progress: True if a reset is in progress. */ > bool reset_in_progress; > > @@ -447,6 +450,9 @@ struct panthor_vm { > /** @node: Used to insert the VM in the panthor_mmu::vm::list. */ > struct list_head node; > > + /* @user_node: Used to insert the VM in the panthor_mmu::vm::user_owned > list. */ > + struct list_head user_node; > + > /** @for_mcu: True if this is the MCU VM. */ > bool for_mcu; > > @@ -1681,10 +1687,19 @@ int panthor_vm_pool_create_vm(struct panthor_device > *ptdev, > drm_gem_object_get(&pool->dummy->base); > vm->dummy = pool->dummy; > > + /* Insert in the list before xa_alloc() so we can't race with > + * panthor_vm_pool_destroy_vm() have the VM inserted in the > + * user_owned list after it's been destroyed. > + */ > + scoped_guard(mutex, &ptdev->mmu->vm.lock) > + list_add_tail(&vm->user_node, &ptdev->mmu->vm.user_owned); > + > ret = xa_alloc(&pool->xa, &id, vm, > XA_LIMIT(1, PANTHOR_MAX_VMS_PER_FILE), GFP_KERNEL); > > if (ret) { > + scoped_guard(mutex, &ptdev->mmu->vm.lock) > + list_del_init(&vm->user_node); > panthor_vm_put(vm); > return ret; > } > @@ -1739,13 +1754,19 @@ static void panthor_vm_destroy(struct panthor_vm *vm) > */ > int panthor_vm_pool_destroy_vm(struct panthor_vm_pool *pool, u32 handle) > { > + struct panthor_device *ptdev; > struct panthor_vm *vm; > > vm = xa_erase(&pool->xa, handle); > + if (!vm) > + return -EINVAL; > + > + ptdev = container_of(vm->as->base.drm, struct panthor_device, base); > + scoped_guard(mutex, &ptdev->mmu->vm.lock) > + list_del_init(&vm->user_node); > > panthor_vm_destroy(vm); > - > - return vm ? 0 : -EINVAL; > + return 0; > } > > /** > @@ -1785,7 +1806,7 @@ void panthor_vm_pool_destroy(struct panthor_file *pfile) > return; > > xa_for_each(&pfile->vms->xa, i, vm) > - panthor_vm_destroy(vm); > + panthor_vm_pool_destroy_vm(pfile->vms, i); > > if (pfile->vms->dummy) > drm_gem_object_put(&pfile->vms->dummy->base); > @@ -3182,6 +3203,7 @@ panthor_vm_create(struct panthor_device *ptdev, bool > for_mcu, > goto err_put_as; > } > > + INIT_LIST_HEAD(&vm->user_node); > vm->user_va_range = kernel_va_start; > vm->as = as; > mutex_init(&vm->heaps.lock); > @@ -3707,6 +3729,7 @@ int panthor_mmu_init(struct panthor_device *ptdev) > return ret; > > INIT_LIST_HEAD(&mmu->vm.list); > + INIT_LIST_HEAD(&mmu->vm.user_owned); > ret = drmm_mutex_init(&ptdev->base, &mmu->vm.lock); > if (ret) > return ret; > > -- > 2.55.0
Adrian Larumbe
