[PATCH] drm/ttm: Allow vm fault retries

Jakob Bornecrantz wallbraker at gmail.com
Tue Oct 29 14:52:46 CET 2013


On Thu, Oct 10, 2013 at 8:22 PM, Thomas Hellstrom <thellstrom at vmware.com> wrote:
> Make use of the FAULT_FLAG_ALLOW_RETRY flag to allow dropping the
> mmap_sem while waiting for bo idle.
>
> FAULT_FLAG_ALLOW_RETRY appears to be primarily designed for disk waits
> but should work just as fine for GPU waits..
>
> Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>

Reviewed-by: Jakob Bornecrantz <jakob at vmware.com>

Tho somebody else should also take a look at this.


> ---
>  drivers/gpu/drm/ttm/ttm_bo_vm.c |   62 +++++++++++++++++++++++++++++++--------
>  1 file changed, 50 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> index 1006c15..c03514b 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> @@ -41,6 +41,51 @@
>
>  #define TTM_BO_VM_NUM_PREFAULT 16
>
> +static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
> +                               struct vm_area_struct *vma,
> +                               struct vm_fault *vmf)
> +{
> +       struct ttm_bo_device *bdev = bo->bdev;
> +       int ret = 0;
> +
> +       spin_lock(&bdev->fence_lock);
> +       if (likely(!test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)))
> +               goto out_unlock;
> +
> +       /*
> +        * Quick non-stalling check for idle.
> +        */
> +       ret = ttm_bo_wait(bo, false, false, true);
> +       if (likely(ret == 0))
> +               goto out_unlock;
> +
> +       /*
> +        * If possible, avoid waiting for GPU with mmap_sem
> +        * held.
> +        */
> +       if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
> +               ret = VM_FAULT_RETRY;
> +               if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
> +                       goto out_unlock;
> +
> +               up_read(&vma->vm_mm->mmap_sem);
> +               (void) ttm_bo_wait(bo, false, true, false);
> +               goto out_unlock;
> +       }
> +
> +       /*
> +        * Ordinary wait.
> +        */
> +       ret = ttm_bo_wait(bo, false, true, false);
> +       if (unlikely(ret != 0))
> +               ret = (ret != -ERESTARTSYS) ? VM_FAULT_SIGBUS :
> +                       VM_FAULT_NOPAGE;
> +
> +out_unlock:
> +       spin_unlock(&bdev->fence_lock);
> +       return ret;
> +}
> +
>  static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
>  {
>         struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
> @@ -91,18 +136,11 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
>          * Wait for buffer data in transit, due to a pipelined
>          * move.
>          */
> -
> -       spin_lock(&bdev->fence_lock);
> -       if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) {
> -               ret = ttm_bo_wait(bo, false, true, false);
> -               spin_unlock(&bdev->fence_lock);
> -               if (unlikely(ret != 0)) {
> -                       retval = (ret != -ERESTARTSYS) ?
> -                           VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
> -                       goto out_unlock;
> -               }
> -       } else
> -               spin_unlock(&bdev->fence_lock);
> +       ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
> +       if (unlikely(ret != 0)) {
> +               retval = ret;
> +               goto out_unlock;
> +       }
>
>         ret = ttm_mem_io_lock(man, true);
>         if (unlikely(ret != 0)) {
> --
> 1.7.10.4
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list