aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/1618-drm-amdgpu-Use-separate-resv.-list-in-restore.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/1618-drm-amdgpu-Use-separate-resv.-list-in-restore.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/1618-drm-amdgpu-Use-separate-resv.-list-in-restore.patch177
1 files changed, 177 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/1618-drm-amdgpu-Use-separate-resv.-list-in-restore.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/1618-drm-amdgpu-Use-separate-resv.-list-in-restore.patch
new file mode 100644
index 00000000..b45fbbf4
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/1618-drm-amdgpu-Use-separate-resv.-list-in-restore.patch
@@ -0,0 +1,177 @@
+From a6863fb8d017749b01ec2ed3bf783e6bf9b8caf7 Mon Sep 17 00:00:00 2001
+From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+Date: Fri, 10 Mar 2017 18:07:01 -0500
+Subject: [PATCH 1618/4131] drm/amdgpu: Use separate resv. list in restore
+
+ttm_eu_reserve_buffers() can reorder the items in the resv. list. This
+could corrupt the kfd_bo_list, instead create a separate list for
+reserve and unreserve.
+
+Change-Id: I2690e2c0f5264d28c3b63d85ec94783e1ccae810
+Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 1 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 73 +++++++++++-------------
+ 2 files changed, 34 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+index 1fdade9..262a4fe 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+@@ -50,6 +50,7 @@ struct kgd_mem {
+ struct list_head bo_va_list;
+ /* protected by amdkfd_process_info.lock */
+ struct ttm_validate_buffer validate_list;
++ struct ttm_validate_buffer resv_list;
+ uint32_t domain;
+ unsigned int mapped_to_gpu_memory;
+ void *kptr;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 358bb72..a8482ce 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -2097,18 +2097,19 @@ int amdgpu_amdkfd_gpuvm_restore_mem(struct kgd_mem *mem, struct mm_struct *mm)
+ * should be called when the Process is still valid. BO restore involves -
+ *
+ * 1. Release old eviction fence and create new one
+- * 2. Get PD BO list and PT BO list from all the VMs.
+- * 3. Merge PD BO list into KFD BO list. Reserve all BOs.
+- * 4. Split the list into PD BO list and KFD BO list
+- * 5. Validate of PD and PT BOs and add new fence to the BOs
+- * 6. Validate all KFD BOs and Map them and add new fence
+- * 7. Merge PD BO list into KFD BO list. Unreserve all BOs
+- * 8. Restore back KFD BO list by removing PD BO entries
++ * 2. Get two copies of PD BO list from all the VMs. Keep one copy as pd_list.
++ * 3 Use the second PD list and kfd_bo_list to create a list (ctx.list) of
++ * BOs that need to be reserved.
++ * 4. Reserve all the BOs
++ * 5. Validate of PD and PT BOs.
++ * 6. Validate all KFD BOs using kfd_bo_list and Map them and add new fence
++ * 7. Add fence to all PD and PT BOs.
++ * 8. Unreserve all BOs
+ */
+
+ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info)
+ {
+- struct amdgpu_bo_list_entry *pd_bo_list, *last_pd_bo_entry, *entry;
++ struct amdgpu_bo_list_entry *pd_bo_list, *entry;
+ struct amdkfd_process_info *process_info = info;
+ struct amdkfd_vm *peer_vm;
+ struct kgd_mem *mem;
+@@ -2117,17 +2118,17 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info)
+ struct amdgpu_device *adev;
+ struct amdgpu_vm_parser param;
+ int ret = 0, i;
+- struct list_head duplicate_save;
++ struct list_head duplicate_save, pd_list;
+
+ if (WARN_ON(!process_info))
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&duplicate_save);
+-
++ INIT_LIST_HEAD(&pd_list);
+ INIT_LIST_HEAD(&ctx.list);
+ INIT_LIST_HEAD(&ctx.duplicates);
+
+- pd_bo_list = kcalloc(process_info->n_vms,
++ pd_bo_list = kcalloc(process_info->n_vms * 2,
+ sizeof(struct amdgpu_bo_list_entry),
+ GFP_KERNEL);
+ if (pd_bo_list == NULL)
+@@ -2151,39 +2152,36 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info)
+ list_for_each_entry(peer_vm, &process_info->vm_list_head,
+ vm_list_node) {
+ amdgpu_vm_get_pd_bo(&peer_vm->base, &ctx.list,
+- &pd_bo_list[i]);
+- i++;
++ &pd_bo_list[i++]);
++ amdgpu_vm_get_pd_bo(&peer_vm->base, &pd_list,
++ &pd_bo_list[i++]);
+ }
+
+- /* Needed to splicing and cutting the lists */
+- last_pd_bo_entry = list_last_entry(&ctx.list,
+- struct amdgpu_bo_list_entry,
+- tv.head);
++ /* Reserve all BOs and page tables/directory. Add all BOs from
++ * kfd_bo_list to ctx.list
++ */
++ list_for_each_entry(mem, &process_info->kfd_bo_list,
++ validate_list.head) {
+
+- /* Reserve all BOs and page tables/directory. */
+- list_splice_init(&ctx.list, &process_info->kfd_bo_list);
+- ret = ttm_eu_reserve_buffers(&ctx.ticket, &process_info->kfd_bo_list,
++ list_add_tail(&mem->resv_list.head, &ctx.list);
++ mem->resv_list.bo = mem->validate_list.bo;
++ mem->resv_list.shared = mem->validate_list.shared;
++ }
++
++ ret = ttm_eu_reserve_buffers(&ctx.ticket, &ctx.list,
+ false, &duplicate_save);
+ if (ret) {
+ pr_debug("Memory eviction: TTM Reserve Failed. Try again\n");
+ goto ttm_reserve_fail;
+ }
+
+- /* Ensure kfd_bo_list does not change after ttm_eu_reserve_buffers(),
+- * so that the following list operation such as list_cut_position()
+- * can work as expected.
+- */
+ if (!list_empty(&duplicate_save))
+ pr_err("BUG: list of BOs to reserve has duplicates!\n");
+
+- /* Restore kfd_bo_list. ctx.list contains only PDs */
+- list_cut_position(&ctx.list, &process_info->kfd_bo_list,
+- &last_pd_bo_entry->tv.head);
+-
+ amdgpu_sync_create(&ctx.sync);
+
+ /* Validate PDs*/
+- list_for_each_entry(entry, &ctx.list, tv.head) {
++ list_for_each_entry(entry, &pd_list, tv.head) {
+ struct amdgpu_bo *bo = entry->robj;
+
+ ret = amdgpu_amdkfd_bo_validate(bo, bo->prefered_domains,
+@@ -2211,10 +2209,8 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info)
+ atomic64_read(&adev->num_evictions);
+ }
+
+- /* Wait for PD/PTs validate to finish and attach eviction fence.
+- * PD/PT share the same reservation object
+- */
+- list_for_each_entry(entry, &ctx.list, tv.head) {
++ /* Wait for PD/PTs validate to finish */
++ list_for_each_entry(entry, &pd_list, tv.head) {
+ struct amdgpu_bo *bo = entry->robj;
+
+ ttm_bo_wait(&bo->tbo, false, false);
+@@ -2258,20 +2254,17 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info)
+ ttm_bo_wait(&bo->tbo, false, false);
+ amdgpu_bo_fence(bo, &process_info->eviction_fence->base, true);
+ }
+- list_for_each_entry(entry, &ctx.list, tv.head) {
++
++ /* Attach eviction fence to PD / PT BOs */
++ list_for_each_entry(entry, &pd_list, tv.head) {
+ struct amdgpu_bo *bo = entry->robj;
+
+ amdgpu_bo_fence(bo, &process_info->eviction_fence->base, true);
+ }
+ validate_map_fail:
+- /* Add PDs to kfd_bo_list for unreserve */
+- list_splice_init(&ctx.list, &process_info->kfd_bo_list);
+- ttm_eu_backoff_reservation(&ctx.ticket, &process_info->kfd_bo_list);
++ ttm_eu_backoff_reservation(&ctx.ticket, &ctx.list);
+ amdgpu_sync_free(&ctx.sync);
+ ttm_reserve_fail:
+- /* Restore kfd_bo_list */
+- list_cut_position(&ctx.list, &process_info->kfd_bo_list,
+- &last_pd_bo_entry->tv.head);
+ mutex_unlock(&process_info->lock);
+ evict_fence_fail:
+ kfree(pd_bo_list);
+--
+2.7.4
+