aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/0357-drm-amdgpu-add-some-VM-PD-PT-iterators-v2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0357-drm-amdgpu-add-some-VM-PD-PT-iterators-v2.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/0357-drm-amdgpu-add-some-VM-PD-PT-iterators-v2.patch258
1 files changed, 258 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0357-drm-amdgpu-add-some-VM-PD-PT-iterators-v2.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0357-drm-amdgpu-add-some-VM-PD-PT-iterators-v2.patch
new file mode 100644
index 00000000..59c4cc8a
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0357-drm-amdgpu-add-some-VM-PD-PT-iterators-v2.patch
@@ -0,0 +1,258 @@
+From f81b0807cbcec5d1276663934f4eea6f2b7a4155 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Sat, 1 Sep 2018 10:36:48 +0200
+Subject: [PATCH 0357/2940] drm/amdgpu: add some VM PD/PT iterators v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Both a leaf as well as dfs iterator to walk over all the PDs/PTs.
+
+v2: update comments and fix for_each_amdgpu_vm_pt_dfs_safe
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Huang Rui <ray.huang@amd.com>
+Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 224 +++++++++++++++++++++++++
+ 1 file changed, 224 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index c57c9405a4ce..aa107f7fe581 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -355,6 +355,230 @@ static struct amdgpu_vm_pt *amdgpu_vm_pt_parent(struct amdgpu_vm_pt *pt)
+ return list_first_entry(&parent->va, struct amdgpu_vm_pt, base.bo_list);
+ }
+
++/**
++ * amdgpu_vm_pt_cursor - state for for_each_amdgpu_vm_pt
++ */
++struct amdgpu_vm_pt_cursor {
++ uint64_t pfn;
++ struct amdgpu_vm_pt *parent;
++ struct amdgpu_vm_pt *entry;
++ unsigned level;
++};
++
++/**
++ * amdgpu_vm_pt_start - start PD/PT walk
++ *
++ * @adev: amdgpu_device pointer
++ * @vm: amdgpu_vm structure
++ * @start: start address of the walk
++ * @cursor: state to initialize
++ *
++ * Initialize a amdgpu_vm_pt_cursor to start a walk.
++ */
++static void amdgpu_vm_pt_start(struct amdgpu_device *adev,
++ struct amdgpu_vm *vm, uint64_t start,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ cursor->pfn = start;
++ cursor->parent = NULL;
++ cursor->entry = &vm->root;
++ cursor->level = adev->vm_manager.root_level;
++}
++
++/**
++ * amdgpu_vm_pt_descendant - go to child node
++ *
++ * @adev: amdgpu_device pointer
++ * @cursor: current state
++ *
++ * Walk to the child node of the current node.
++ * Returns:
++ * True if the walk was possible, false otherwise.
++ */
++static bool amdgpu_vm_pt_descendant(struct amdgpu_device *adev,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ unsigned num_entries, shift, idx;
++
++ if (!cursor->entry->entries)
++ return false;
++
++ BUG_ON(!cursor->entry->base.bo);
++ num_entries = amdgpu_vm_num_entries(adev, cursor->level);
++ shift = amdgpu_vm_level_shift(adev, cursor->level);
++
++ ++cursor->level;
++ idx = (cursor->pfn >> shift) % num_entries;
++ cursor->parent = cursor->entry;
++ cursor->entry = &cursor->entry->entries[idx];
++ return true;
++}
++
++/**
++ * amdgpu_vm_pt_sibling - go to sibling node
++ *
++ * @adev: amdgpu_device pointer
++ * @cursor: current state
++ *
++ * Walk to the sibling node of the current node.
++ * Returns:
++ * True if the walk was possible, false otherwise.
++ */
++static bool amdgpu_vm_pt_sibling(struct amdgpu_device *adev,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ unsigned shift, num_entries;
++
++ /* Root doesn't have a sibling */
++ if (!cursor->parent)
++ return false;
++
++ /* Go to our parents and see if we got a sibling */
++ shift = amdgpu_vm_level_shift(adev, cursor->level - 1);
++ num_entries = amdgpu_vm_num_entries(adev, cursor->level - 1);
++
++ if (cursor->entry == &cursor->parent->entries[num_entries - 1])
++ return false;
++
++ cursor->pfn += 1ULL << shift;
++ cursor->pfn &= ~((1ULL << shift) - 1);
++ ++cursor->entry;
++ return true;
++}
++
++/**
++ * amdgpu_vm_pt_ancestor - go to parent node
++ *
++ * @cursor: current state
++ *
++ * Walk to the parent node of the current node.
++ * Returns:
++ * True if the walk was possible, false otherwise.
++ */
++static bool amdgpu_vm_pt_ancestor(struct amdgpu_vm_pt_cursor *cursor)
++{
++ if (!cursor->parent)
++ return false;
++
++ --cursor->level;
++ cursor->entry = cursor->parent;
++ cursor->parent = amdgpu_vm_pt_parent(cursor->parent);
++ return true;
++}
++
++/**
++ * amdgpu_vm_pt_next - get next PD/PT in hieratchy
++ *
++ * @adev: amdgpu_device pointer
++ * @cursor: current state
++ *
++ * Walk the PD/PT tree to the next node.
++ */
++static void amdgpu_vm_pt_next(struct amdgpu_device *adev,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ /* First try a newborn child */
++ if (amdgpu_vm_pt_descendant(adev, cursor))
++ return;
++
++ /* If that didn't worked try to find a sibling */
++ while (!amdgpu_vm_pt_sibling(adev, cursor)) {
++ /* No sibling, go to our parents and grandparents */
++ if (!amdgpu_vm_pt_ancestor(cursor)) {
++ cursor->pfn = ~0ll;
++ return;
++ }
++ }
++}
++
++/**
++ * amdgpu_vm_pt_first_leaf - get first leaf PD/PT
++ *
++ * @adev: amdgpu_device pointer
++ * @vm: amdgpu_vm structure
++ * @start: start addr of the walk
++ * @cursor: state to initialize
++ *
++ * Start a walk and go directly to the leaf node.
++ */
++static void amdgpu_vm_pt_first_leaf(struct amdgpu_device *adev,
++ struct amdgpu_vm *vm, uint64_t start,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ amdgpu_vm_pt_start(adev, vm, start, cursor);
++ while (amdgpu_vm_pt_descendant(adev, cursor));
++}
++
++/**
++ * amdgpu_vm_pt_next_leaf - get next leaf PD/PT
++ *
++ * @adev: amdgpu_device pointer
++ * @cursor: current state
++ *
++ * Walk the PD/PT tree to the next leaf node.
++ */
++static void amdgpu_vm_pt_next_leaf(struct amdgpu_device *adev,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ amdgpu_vm_pt_next(adev, cursor);
++ while (amdgpu_vm_pt_descendant(adev, cursor));
++}
++
++/**
++ * for_each_amdgpu_vm_pt_leaf - walk over all leaf PDs/PTs in the hierarchy
++ */
++#define for_each_amdgpu_vm_pt_leaf(adev, vm, start, end, cursor) \
++ for (amdgpu_vm_pt_first_leaf((adev), (vm), (start), &(cursor)); \
++ (cursor).pfn <= end; amdgpu_vm_pt_next_leaf((adev), &(cursor)))
++
++/**
++ * amdgpu_vm_pt_first_dfs - start a deep first search
++ *
++ * @adev: amdgpu_device structure
++ * @vm: amdgpu_vm structure
++ * @cursor: state to initialize
++ *
++ * Starts a deep first traversal of the PD/PT tree.
++ */
++static void amdgpu_vm_pt_first_dfs(struct amdgpu_device *adev,
++ struct amdgpu_vm *vm,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ amdgpu_vm_pt_start(adev, vm, 0, cursor);
++ while (amdgpu_vm_pt_descendant(adev, cursor));
++}
++
++/**
++ * amdgpu_vm_pt_next_dfs - get the next node for a deep first search
++ *
++ * @adev: amdgpu_device structure
++ * @cursor: current state
++ *
++ * Move the cursor to the next node in a deep first search.
++ */
++static void amdgpu_vm_pt_next_dfs(struct amdgpu_device *adev,
++ struct amdgpu_vm_pt_cursor *cursor)
++{
++ if (!cursor->entry)
++ return;
++
++ if (!cursor->parent)
++ cursor->entry = NULL;
++ else if (amdgpu_vm_pt_sibling(adev, cursor))
++ while (amdgpu_vm_pt_descendant(adev, cursor));
++ else
++ amdgpu_vm_pt_ancestor(cursor);
++}
++
++/**
++ * for_each_amdgpu_vm_pt_dfs_safe - safe deep first search of all PDs/PTs
++ */
++#define for_each_amdgpu_vm_pt_dfs_safe(adev, vm, cursor, entry) \
++ for (amdgpu_vm_pt_first_dfs((adev), (vm), &(cursor)), \
++ (entry) = (cursor).entry, amdgpu_vm_pt_next_dfs((adev), &(cursor));\
++ (entry); (entry) = (cursor).entry, \
++ amdgpu_vm_pt_next_dfs((adev), &(cursor)))
++
+ /**
+ * amdgpu_vm_get_pd_bo - add the VM PD to a validation list
+ *
+--
+2.17.1
+