On Tue, Dec 02, 2025 at 02:35:37PM +0100, Boris Brezillon wrote:
> When we re-assign a slot to a different VM, we need to make sure the
> old VM caches are flushed before doing the switch. Specialize
> panthor_mmu_as_disable() so we can skip the slot programmation while
> still getting the cache flushing, and call this helper from
> panthor_vm_active() when an idle slot is recycled.
> 
> Fixes: 6e2d3b3e8589 ("drm/panthor: Add support for atomic page table updates")
> Signed-off-by: Boris Brezillon <[email protected]>

Reviewed-by: Liviu Dudau <[email protected]>

Best regards,
Liviu

> ---
>  drivers/gpu/drm/panthor/panthor_mmu.c | 26 ++++++++++++++++++++------
>  1 file changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c 
> b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 8ba5259e3d28..3644af1a8e56 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -585,7 +585,8 @@ static int panthor_mmu_as_enable(struct panthor_device 
> *ptdev, u32 as_nr,
>       return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
>  }
>  
> -static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr)
> +static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr,
> +                               bool recycle_slot)
>  {
>       int ret;
>  
> @@ -595,6 +596,12 @@ static int panthor_mmu_as_disable(struct panthor_device 
> *ptdev, u32 as_nr)
>       if (ret)
>               return ret;
>  
> +     /* If the slot is going to be used immediately, don't bother changing
> +      * the config.
> +      */
> +     if (recycle_slot)
> +             return 0;
> +
>       gpu_write64(ptdev, AS_TRANSTAB(as_nr), 0);
>       gpu_write64(ptdev, AS_MEMATTR(as_nr), 0);
>       gpu_write64(ptdev, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
> @@ -714,6 +721,11 @@ int panthor_vm_active(struct panthor_vm *vm)
>  
>               drm_WARN_ON(&ptdev->base, 
> refcount_read(&lru_vm->as.active_cnt));
>               as = lru_vm->as.id;
> +
> +             ret = panthor_mmu_as_disable(ptdev, as, true);
> +             if (ret)
> +                     goto out_unlock;
> +
>               panthor_vm_release_as_locked(lru_vm);
>       }
>  
> @@ -853,7 +865,7 @@ static void panthor_vm_declare_unusable(struct panthor_vm 
> *vm)
>       vm->unusable = true;
>       mutex_lock(&ptdev->mmu->as.slots_lock);
>       if (vm->as.id >= 0 && drm_dev_enter(&ptdev->base, &cookie)) {
> -             panthor_mmu_as_disable(ptdev, vm->as.id);
> +             panthor_mmu_as_disable(ptdev, vm->as.id, false);
>               drm_dev_exit(cookie);
>       }
>       mutex_unlock(&ptdev->mmu->as.slots_lock);
> @@ -1780,7 +1792,7 @@ static void panthor_mmu_irq_handler(struct 
> panthor_device *ptdev, u32 status)
>                       ptdev->mmu->as.slots[as].vm->unhandled_fault = true;
>  
>               /* Disable the MMU to kill jobs on this AS. */
> -             panthor_mmu_as_disable(ptdev, as);
> +             panthor_mmu_as_disable(ptdev, as, false);
>               mutex_unlock(&ptdev->mmu->as.slots_lock);
>  
>               status &= ~mask;
> @@ -1809,7 +1821,8 @@ void panthor_mmu_suspend(struct panthor_device *ptdev)
>               struct panthor_vm *vm = ptdev->mmu->as.slots[i].vm;
>  
>               if (vm) {
> -                     drm_WARN_ON(&ptdev->base, panthor_mmu_as_disable(ptdev, 
> i));
> +                     drm_WARN_ON(&ptdev->base,
> +                                 panthor_mmu_as_disable(ptdev, i, false));
>                       panthor_vm_release_as_locked(vm);
>               }
>       }
> @@ -1930,7 +1943,7 @@ static void panthor_vm_free(struct drm_gpuvm *gpuvm)
>               int cookie;
>  
>               if (drm_dev_enter(&ptdev->base, &cookie)) {
> -                     panthor_mmu_as_disable(ptdev, vm->as.id);
> +                     panthor_mmu_as_disable(ptdev, vm->as.id, false);
>                       drm_dev_exit(cookie);
>               }
>  
> @@ -2790,7 +2803,8 @@ void panthor_mmu_unplug(struct panthor_device *ptdev)
>               struct panthor_vm *vm = ptdev->mmu->as.slots[i].vm;
>  
>               if (vm) {
> -                     drm_WARN_ON(&ptdev->base, panthor_mmu_as_disable(ptdev, 
> i));
> +                     drm_WARN_ON(&ptdev->base,
> +                                 panthor_mmu_as_disable(ptdev, i, false));
>                       panthor_vm_release_as_locked(vm);
>               }
>       }
> -- 
> 2.51.1
> 

Reply via email to