aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/5408-drm-amdgpu-use-leaf-iterator-for-allocating-PD-PT.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5408-drm-amdgpu-use-leaf-iterator-for-allocating-PD-PT.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/5408-drm-amdgpu-use-leaf-iterator-for-allocating-PD-PT.patch212
1 files changed, 212 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5408-drm-amdgpu-use-leaf-iterator-for-allocating-PD-PT.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5408-drm-amdgpu-use-leaf-iterator-for-allocating-PD-PT.patch
new file mode 100644
index 00000000..c80708a8
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5408-drm-amdgpu-use-leaf-iterator-for-allocating-PD-PT.patch
@@ -0,0 +1,212 @@
+From 4df7af9cc5ca7dd6876f2a8a7532c89145874e51 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Sat, 1 Sep 2018 12:03:37 +0200
+Subject: [PATCH 5408/5725] drm/amdgpu: use leaf iterator for allocating PD/PT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Less code and allows for easier error handling.
+
+Change-Id: Iecf14e422b289d440b6d77547f9c3a1025635d55
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
+Reviewed-by: Huang Rui <ray.huang@amd.com>
+Signed-off-by: Raveendra Talabattula <raveendra.talabattula@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 156 ++++++++++++---------------------
+ 1 file changed, 55 insertions(+), 101 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index dd6d1c5..7499956 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -774,103 +774,6 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ }
+
+ /**
+- * amdgpu_vm_alloc_levels - allocate the PD/PT levels
+- *
+- * @adev: amdgpu_device pointer
+- * @vm: requested vm
+- * @parent: parent PT
+- * @saddr: start of the address range
+- * @eaddr: end of the address range
+- * @level: VMPT level
+- * @ats: indicate ATS support from PTE
+- *
+- * Make sure the page directories and page tables are allocated
+- *
+- * Returns:
+- * 0 on success, errno otherwise.
+- */
+-static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
+- struct amdgpu_vm *vm,
+- struct amdgpu_vm_pt *parent,
+- uint64_t saddr, uint64_t eaddr,
+- unsigned level, bool ats)
+-{
+- unsigned shift = amdgpu_vm_level_shift(adev, level);
+- struct amdgpu_bo_param bp;
+- unsigned pt_idx, from, to;
+- int r;
+-
+- if (!parent->entries) {
+- unsigned num_entries = amdgpu_vm_num_entries(adev, level);
+-
+- parent->entries = kvmalloc_array(num_entries,
+- sizeof(struct amdgpu_vm_pt),
+- GFP_KERNEL | __GFP_ZERO);
+- if (!parent->entries)
+- return -ENOMEM;
+- }
+-
+- from = saddr >> shift;
+- to = eaddr >> shift;
+- if (from >= amdgpu_vm_num_entries(adev, level) ||
+- to >= amdgpu_vm_num_entries(adev, level))
+- return -EINVAL;
+-
+- ++level;
+- saddr = saddr & ((1 << shift) - 1);
+- eaddr = eaddr & ((1 << shift) - 1);
+-
+- amdgpu_vm_bo_param(adev, vm, level, &bp);
+-
+- /* walk over the address space and allocate the page tables */
+- for (pt_idx = from; pt_idx <= to; ++pt_idx) {
+- struct amdgpu_vm_pt *entry = &parent->entries[pt_idx];
+- struct amdgpu_bo *pt;
+-
+- if (!entry->base.bo) {
+- r = amdgpu_bo_create(adev, &bp, &pt);
+- if (r)
+- return r;
+-
+- r = amdgpu_vm_clear_bo(adev, vm, pt, level, ats);
+- if (r) {
+- amdgpu_bo_unref(&pt->shadow);
+- amdgpu_bo_unref(&pt);
+- return r;
+- }
+-
+- if (vm->use_cpu_for_update) {
+- r = amdgpu_bo_kmap(pt, NULL);
+- if (r) {
+- amdgpu_bo_unref(&pt->shadow);
+- amdgpu_bo_unref(&pt);
+- return r;
+- }
+- }
+-
+- /* Keep a reference to the root directory to avoid
+- * freeing them up in the wrong order.
+- */
+- pt->parent = amdgpu_bo_ref(parent->base.bo);
+-
+- amdgpu_vm_bo_base_init(&entry->base, vm, pt);
+- }
+-
+- if (level < AMDGPU_VM_PTB) {
+- uint64_t sub_saddr = (pt_idx == from) ? saddr : 0;
+- uint64_t sub_eaddr = (pt_idx == to) ? eaddr :
+- ((1 << shift) - 1);
+- r = amdgpu_vm_alloc_levels(adev, vm, entry, sub_saddr,
+- sub_eaddr, level, ats);
+- if (r)
+- return r;
+- }
+- }
+-
+- return 0;
+-}
+-
+-/**
+ * amdgpu_vm_alloc_pts - Allocate page tables.
+ *
+ * @adev: amdgpu_device pointer
+@@ -878,7 +781,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
+ * @saddr: Start address which needs to be allocated
+ * @size: Size from start address we need.
+ *
+- * Make sure the page tables are allocated.
++ * Make sure the page directories and page tables are allocated
+ *
+ * Returns:
+ * 0 on success, errno otherwise.
+@@ -887,8 +790,11 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
+ struct amdgpu_vm *vm,
+ uint64_t saddr, uint64_t size)
+ {
+- uint64_t eaddr;
++ struct amdgpu_vm_pt_cursor cursor;
++ struct amdgpu_bo *pt;
+ bool ats = false;
++ uint64_t eaddr;
++ int r;
+
+ /* validate the parameters */
+ if (saddr & AMDGPU_GPU_PAGE_MASK || size & AMDGPU_GPU_PAGE_MASK)
+@@ -908,8 +814,56 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
+ return -EINVAL;
+ }
+
+- return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr,
+- adev->vm_manager.root_level, ats);
++ for_each_amdgpu_vm_pt_leaf(adev, vm, saddr, eaddr, cursor) {
++ struct amdgpu_vm_pt *entry = cursor.entry;
++ struct amdgpu_bo_param bp;
++
++ if (cursor.level < AMDGPU_VM_PTB) {
++ unsigned num_entries;
++
++ num_entries = amdgpu_vm_num_entries(adev, cursor.level);
++ entry->entries = kvmalloc_array(num_entries,
++ sizeof(*entry->entries),
++ GFP_KERNEL |
++ __GFP_ZERO);
++ if (!entry->entries)
++ return -ENOMEM;
++ }
++
++
++ if (entry->base.bo)
++ continue;
++
++ amdgpu_vm_bo_param(adev, vm, cursor.level, &bp);
++
++ r = amdgpu_bo_create(adev, &bp, &pt);
++ if (r)
++ return r;
++
++ r = amdgpu_vm_clear_bo(adev, vm, pt, cursor.level, ats);
++ if (r)
++ goto error_free_pt;
++
++ if (vm->use_cpu_for_update) {
++ r = amdgpu_bo_kmap(pt, NULL);
++ if (r)
++ goto error_free_pt;
++ }
++
++ /* Keep a reference to the root directory to avoid
++ * freeing them up in the wrong order.
++ */
++ pt->parent = amdgpu_bo_ref(cursor.parent->base.bo);
++
++ amdgpu_vm_bo_base_init(&entry->base, vm, pt);
++ }
++
++ return 0;
++
++error_free_pt:
++ amdgpu_bo_unref(&pt->shadow);
++ amdgpu_bo_unref(&pt);
++ return r;
+ }
+
+ /**
+--
+2.7.4
+