[PATCH 2/6] drm/amdgpu: Enable amdgpu_ttm_tt_get_user_pages in worker threads

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Felix,
The patch looks fine to me and I can ACK it, but I would prefer that
Alex or Christian will review it as well before pushing it.
Thanks,
Oded

On Fri, Mar 23, 2018 at 10:32 PM, Felix Kuehling <Felix.Kuehling at amd.com> wrote:
> This commit allows amdgpu_ttm_tt_get_user_pages to work in a worker
> thread rather than regular process context. This will be used when
> KFD userptr BOs are restored after an MMU-notifier eviction.
>
> v2: Manage task reference with get_task_struct/put_task_struct
>
> Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 38 +++++++++++++++++++++++++--------
>  1 file changed, 29 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index c2fae04..25490fe 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -689,7 +689,7 @@ struct amdgpu_ttm_tt {
>         struct ttm_dma_tt       ttm;
>         u64                     offset;
>         uint64_t                userptr;
> -       struct mm_struct        *usermm;
> +       struct task_struct      *usertask;
>         uint32_t                userflags;
>         spinlock_t              guptasklock;
>         struct list_head        guptasks;
> @@ -700,14 +700,18 @@ struct amdgpu_ttm_tt {
>  int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>  {
>         struct amdgpu_ttm_tt *gtt = (void *)ttm;
> +       struct mm_struct *mm = gtt->usertask->mm;
>         unsigned int flags = 0;
>         unsigned pinned = 0;
>         int r;
>
> +       if (!mm) /* Happens during process shutdown */
> +               return -ESRCH;
> +
>         if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY))
>                 flags |= FOLL_WRITE;
>
> -       down_read(&current->mm->mmap_sem);
> +       down_read(&mm->mmap_sem);
>
>         if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) {
>                 /* check that we only use anonymous memory
> @@ -715,9 +719,9 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>                 unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
>                 struct vm_area_struct *vma;
>
> -               vma = find_vma(gtt->usermm, gtt->userptr);
> +               vma = find_vma(mm, gtt->userptr);
>                 if (!vma || vma->vm_file || vma->vm_end < end) {
> -                       up_read(&current->mm->mmap_sem);
> +                       up_read(&mm->mmap_sem);
>                         return -EPERM;
>                 }
>         }
> @@ -733,7 +737,12 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>                 list_add(&guptask.list, &gtt->guptasks);
>                 spin_unlock(&gtt->guptasklock);
>
> -               r = get_user_pages(userptr, num_pages, flags, p, NULL);
> +               if (mm == current->mm)
> +                       r = get_user_pages(userptr, num_pages, flags, p, NULL);
> +               else
> +                       r = get_user_pages_remote(gtt->usertask,
> +                                       mm, userptr, num_pages,
> +                                       flags, p, NULL, NULL);
>
>                 spin_lock(&gtt->guptasklock);
>                 list_del(&guptask.list);
> @@ -746,12 +755,12 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>
>         } while (pinned < ttm->num_pages);
>
> -       up_read(&current->mm->mmap_sem);
> +       up_read(&mm->mmap_sem);
>         return 0;
>
>  release_pages:
>         release_pages(pages, pinned);
> -       up_read(&current->mm->mmap_sem);
> +       up_read(&mm->mmap_sem);
>         return r;
>  }
>
> @@ -972,6 +981,9 @@ static void amdgpu_ttm_backend_destroy(struct ttm_tt *ttm)
>  {
>         struct amdgpu_ttm_tt *gtt = (void *)ttm;
>
> +       if (gtt->usertask)
> +               put_task_struct(gtt->usertask);
> +
>         ttm_dma_tt_fini(&gtt->ttm);
>         kfree(gtt);
>  }
> @@ -1072,8 +1084,13 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
>                 return -EINVAL;
>
>         gtt->userptr = addr;
> -       gtt->usermm = current->mm;
>         gtt->userflags = flags;
> +
> +       if (gtt->usertask)
> +               put_task_struct(gtt->usertask);
> +       gtt->usertask = current->group_leader;
> +       get_task_struct(gtt->usertask);
> +
>         spin_lock_init(&gtt->guptasklock);
>         INIT_LIST_HEAD(&gtt->guptasks);
>         atomic_set(&gtt->mmu_invalidations, 0);
> @@ -1089,7 +1106,10 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
>         if (gtt == NULL)
>                 return NULL;
>
> -       return gtt->usermm;
> +       if (gtt->usertask == NULL)
> +               return NULL;
> +
> +       return gtt->usertask->mm;
>  }
>
>  bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
> --
> 2.7.4
>


[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux