Adding Alex, Christian On Fri, May 11, 2018 at 10:36 AM, Oded Gabbay <oded.gabbay at gmail.com> wrote: > 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(¤t->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(¤t->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, >t->guptasks); >> spin_unlock(>t->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(>t->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(¤t->mm->mmap_sem); >> + up_read(&mm->mmap_sem); >> return 0; >> >> release_pages: >> release_pages(pages, pinned); >> - up_read(¤t->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(>t->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(>t->guptasklock); >> INIT_LIST_HEAD(>t->guptasks); >> atomic_set(>t->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 >>