drm/amdkfd: support concurrent userptr update for HMM
authorPhilip Yang <Philip.Yang@amd.com>
Mon, 4 Mar 2019 19:10:12 +0000 (14:10 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Mar 2019 20:36:58 +0000 (15:36 -0500)
Userptr restore may have concurrent userptr invalidation after
hmm_vma_fault adds the range to the hmm->ranges list, needs call
hmm_vma_range_done to remove the range from hmm->ranges list first,
then reschedule the restore worker. Otherwise hmm_vma_fault will add
same range to the list, this will cause loop in the list because
range->next point to range itself.

Add function untrack_invalid_user_pages to reduce code duplication.

Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c

index 314c048fcac6b9eb3732355b3f2d8a2630316413..047bba8c62d6eccffbb2a785b1f2d0d77895a66b 100644 (file)
@@ -1731,6 +1731,23 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
        return 0;
 }
 
+/* Remove invalid userptr BOs from hmm track list
+ *
+ * Stop HMM track the userptr update
+ */
+static void untrack_invalid_user_pages(struct amdkfd_process_info *process_info)
+{
+       struct kgd_mem *mem, *tmp_mem;
+       struct amdgpu_bo *bo;
+
+       list_for_each_entry_safe(mem, tmp_mem,
+                                &process_info->userptr_inval_list,
+                                validate_list.head) {
+               bo = mem->bo;
+               amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
+       }
+}
+
 /* Validate invalid userptr BOs
  *
  * Validates BOs on the userptr_inval_list, and moves them back to the
@@ -1848,12 +1865,6 @@ unreserve_out:
 out_free:
        kfree(pd_bo_list_entries);
 out_no_mem:
-       list_for_each_entry_safe(mem, tmp_mem,
-                                &process_info->userptr_inval_list,
-                                validate_list.head) {
-               bo = mem->bo;
-               amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
-       }
 
        return ret;
 }
@@ -1918,7 +1929,9 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work)
                 * hanging. No point trying again.
                 */
        }
+
 unlock_out:
+       untrack_invalid_user_pages(process_info);
        mutex_unlock(&process_info->lock);
        mmput(mm);
        put_task_struct(usertask);