aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3130-drm-amdgpu-Update-page-diretories-after-page-tables.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3130-drm-amdgpu-Update-page-diretories-after-page-tables.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3130-drm-amdgpu-Update-page-diretories-after-page-tables.patch186
1 files changed, 186 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3130-drm-amdgpu-Update-page-diretories-after-page-tables.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3130-drm-amdgpu-Update-page-diretories-after-page-tables.patch
new file mode 100644
index 00000000..5a67fc7a
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3130-drm-amdgpu-Update-page-diretories-after-page-tables.patch
@@ -0,0 +1,186 @@
+From a54a155b4b30d2154e0c32ef32eb528fc0fc54be Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Thu, 4 Jan 2018 20:14:54 -0500
+Subject: [PATCH 3130/4131] drm/amdgpu: Update page diretories after page
+ tables
+
+With an upcoming amdgpu change, huge page handling during page table
+updates can invalidate page directory entries again. Therefore update
+page directories only after updating page tables.
+
+Change-Id: I3de514abac89ef2864808fc4813c4248ca7bebe0
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 97 +++++++++++++++++-------
+ 1 file changed, 69 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 606677a..e386fb3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -377,9 +377,10 @@ static int amdgpu_amdkfd_validate(void *param, struct amdgpu_bo *bo)
+
+ /* vm_validate_pt_pd_bos - Validate page table and directory BOs
+ *
+- * Also updates page directory entries so we don't need to do this
+- * again later until the page directory is validated again (e.g. after
+- * an eviction or allocating new page tables).
++ * Page directories are not updated here because huge page handling
++ * during page table updates can invalidate page directory entries
++ * again. Page directories are only updated after updating page
++ * tables.
+ */
+ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
+ {
+@@ -411,11 +412,37 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
+ }
+ }
+
++ return 0;
++}
++
++static int sync_vm_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
++ struct dma_fence *f)
++{
++ int ret = amdgpu_sync_fence(adev, sync, f, false);
++
++ /* Sync objects can't handle multiple GPUs (contexts) updating
++ * sync->last_vm_update. Fortunately we don't need it for
++ * KFD's purposes, so we can just drop that fence.
++ */
++ if (sync->last_vm_update) {
++ dma_fence_put(sync->last_vm_update);
++ sync->last_vm_update = NULL;
++ }
++
++ return ret;
++}
++
++static int vm_update_pds(struct amdgpu_vm *vm, struct amdgpu_sync *sync)
++{
++ struct amdgpu_bo *pd = vm->root.base.bo;
++ struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev);
++ int ret;
++
+ ret = amdgpu_vm_update_directories(adev, vm);
+- if (ret != 0)
++ if (ret)
+ return ret;
+
+- return 0;
++ return sync_vm_fence(adev, sync, vm->last_update);
+ }
+
+ /* add_bo_to_vm - Add a BO to a VM
+@@ -428,7 +455,7 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
+ * 2. Add BO to the VM
+ * 3. Determine ASIC-specific PTE flags
+ * 4. Alloc page tables and directories if needed
+- * 4a. Validate new page tables and directories and update directories
++ * 4a. Validate new page tables and directories
+ */
+ static int add_bo_to_vm(struct amdgpu_device *adev, struct kgd_mem *mem,
+ struct amdgpu_vm *avm, bool is_aql,
+@@ -939,16 +966,7 @@ static int unmap_bo_from_gpuvm(struct amdgpu_device *adev,
+ /* Add the eviction fence back */
+ amdgpu_bo_fence(pd, &kvm->process_info->eviction_fence->base, true);
+
+- amdgpu_sync_fence(adev, sync, bo_va->last_pt_update, false);
+-
+- /* Sync objects can't handle multiple GPUs (contexts) updating
+- * sync->last_vm_update. Fortunately we don't need it for
+- * KFD's purposes, so we can just drop that fence.
+- */
+- if (sync->last_vm_update) {
+- dma_fence_put(sync->last_vm_update);
+- sync->last_vm_update = NULL;
+- }
++ sync_vm_fence(adev, sync, bo_va->last_pt_update);
+
+ return 0;
+ }
+@@ -973,18 +991,7 @@ static int update_gpuvm_pte(struct amdgpu_device *adev,
+ return ret;
+ }
+
+- amdgpu_sync_fence(adev, sync, bo_va->last_pt_update, false);
+-
+- /* Sync objects can't handle multiple GPUs (contexts) updating
+- * sync->last_vm_update. Fortunately we don't need it for
+- * KFD's purposes, so we can just drop that fence.
+- */
+- if (sync->last_vm_update) {
+- dma_fence_put(sync->last_vm_update);
+- sync->last_vm_update = NULL;
+- }
+-
+- return 0;
++ return sync_vm_fence(adev, sync, bo_va->last_pt_update);
+ }
+
+ static int map_bo_to_gpuvm(struct amdgpu_device *adev,
+@@ -1316,6 +1323,13 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
+ pr_err("Failed to map radeon bo to gpuvm\n");
+ goto map_bo_to_gpuvm_failed;
+ }
++
++ ret = vm_update_pds(vm, ctx.sync);
++ if (ret) {
++ pr_err("Failed to update page directories\n");
++ goto map_bo_to_gpuvm_failed;
++ }
++
+ entry->is_mapped = true;
+ mem->mapped_to_gpu_memory++;
+ pr_debug("\t INC mapping count %d\n",
+@@ -1914,6 +1928,22 @@ static int process_validate_vms(struct amdkfd_process_info *process_info)
+ return 0;
+ }
+
++static int process_update_pds(struct amdkfd_process_info *process_info,
++ struct amdgpu_sync *sync)
++{
++ struct amdkfd_vm *peer_vm;
++ int ret;
++
++ list_for_each_entry(peer_vm, &process_info->vm_list_head,
++ vm_list_node) {
++ ret = vm_update_pds(&peer_vm->base, sync);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
+ /* Evict a userptr BO by stopping the queues if necessary
+ *
+ * Runs in MMU notifier, may be in RECLAIM_FS context. This means it
+@@ -2165,6 +2195,10 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
+ }
+ }
+ }
++
++ /* Update page directories */
++ ret = process_update_pds(process_info, &sync);
++
+ unreserve_out:
+ list_for_each_entry(peer_vm, &process_info->vm_list_head,
+ vm_list_node)
+@@ -2358,6 +2392,13 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
+ }
+ }
+
++ /* Update page directories */
++ ret = process_update_pds(process_info, ctx.sync);
++ if (ret) {
++ pr_debug("Memory eviction: update PDs failed. Try again\n");
++ goto validate_map_fail;
++ }
++
+ amdgpu_sync_wait(ctx.sync, false);
+
+ /* Release old eviction fence and create new one, because fence only
+--
+2.7.4
+