aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0239-drm-amdgpu-use-a-global-LRU-list-for-VMIDs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0239-drm-amdgpu-use-a-global-LRU-list-for-VMIDs.patch')
-rw-r--r--common/recipes-kernel/linux/files/0239-drm-amdgpu-use-a-global-LRU-list-for-VMIDs.patch225
1 files changed, 225 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0239-drm-amdgpu-use-a-global-LRU-list-for-VMIDs.patch b/common/recipes-kernel/linux/files/0239-drm-amdgpu-use-a-global-LRU-list-for-VMIDs.patch
new file mode 100644
index 00000000..4d9e2d63
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0239-drm-amdgpu-use-a-global-LRU-list-for-VMIDs.patch
@@ -0,0 +1,225 @@
+From 733b067a8a1d587ff27072eb2ba55dc5c5e695f0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 21 Jan 2016 10:19:11 +0100
+Subject: [PATCH 0239/1110] drm/amdgpu: use a global LRU list for VMIDs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With the scheduler enabled managing per ring LRUs don't
+make much sense any more.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 19 ++++----
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 88 ++++++++++++++++------------------
+ drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 3 +-
+ drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 3 +-
+ 4 files changed, 55 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 64784e4..5135635 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -886,18 +886,20 @@ struct amdgpu_vm {
+ spinlock_t freed_lock;
+ };
+
++struct amdgpu_vm_manager_id {
++ struct list_head list;
++ struct fence *active;
++ atomic_long_t owner;
++};
++
+ struct amdgpu_vm_manager {
+- /* protecting IDs */
++ /* Handling of VMIDs */
+ struct mutex lock;
+-
+- struct {
+- struct fence *active;
+- atomic_long_t owner;
+- } ids[AMDGPU_NUM_VM];
++ unsigned num_ids;
++ struct list_head ids_lru;
++ struct amdgpu_vm_manager_id ids[AMDGPU_NUM_VM];
+
+ uint32_t max_pfn;
+- /* number of VMIDs */
+- unsigned nvm;
+ /* vram base address for page table entry */
+ u64 vram_base_offset;
+ /* is vm enabled? */
+@@ -907,6 +909,7 @@ struct amdgpu_vm_manager {
+ struct amdgpu_ring *vm_pte_funcs_ring;
+ };
+
++void amdgpu_vm_manager_init(struct amdgpu_device *adev);
+ void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
+ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
+ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 38ab4a5..796fe49 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -168,79 +168,52 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
+ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
+ struct amdgpu_sync *sync, struct fence *fence)
+ {
+- struct fence *best[AMDGPU_MAX_RINGS] = {};
+ struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx];
+ struct amdgpu_device *adev = ring->adev;
+-
+- unsigned choices[2] = {};
+- unsigned i;
++ struct amdgpu_vm_manager_id *id;
++ int r;
+
+ mutex_lock(&adev->vm_manager.lock);
+
+ /* check if the id is still valid */
+ if (vm_id->id) {
+- unsigned id = vm_id->id;
+ long owner;
+
+- owner = atomic_long_read(&adev->vm_manager.ids[id].owner);
++ id = &adev->vm_manager.ids[vm_id->id];
++ owner = atomic_long_read(&id->owner);
+ if (owner == (long)vm) {
++ list_move_tail(&id->list, &adev->vm_manager.ids_lru);
+ trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx);
+- fence_put(adev->vm_manager.ids[id].active);
+- adev->vm_manager.ids[id].active = fence_get(fence);
+- mutex_unlock(&adev->vm_manager.lock);
+- return 0;
+- }
+- }
+
+- /* we definately need to flush */
+- vm_id->pd_gpu_addr = ~0ll;
++ fence_put(id->active);
++ id->active = fence_get(fence);
+
+- /* skip over VMID 0, since it is the system VM */
+- for (i = 1; i < adev->vm_manager.nvm; ++i) {
+- struct fence *fence = adev->vm_manager.ids[i].active;
+- struct amdgpu_ring *fring;
+-
+- if (fence == NULL) {
+- /* found a free one */
+- vm_id->id = i;
+- trace_amdgpu_vm_grab_id(vm, i, ring->idx);
+ mutex_unlock(&adev->vm_manager.lock);
+ return 0;
+ }
+-
+- fring = amdgpu_ring_from_fence(fence);
+- if (best[fring->idx] == NULL ||
+- fence_is_later(best[fring->idx], fence)) {
+- best[fring->idx] = fence;
+- choices[fring == ring ? 0 : 1] = i;
+- }
+ }
+
+- for (i = 0; i < 2; ++i) {
+- struct fence *active;
+- int r;
+-
+- if (!choices[i])
+- continue;
++ /* we definately need to flush */
++ vm_id->pd_gpu_addr = ~0ll;
+
+- vm_id->id = choices[i];
+- active = adev->vm_manager.ids[vm_id->id].active;
+- r = amdgpu_sync_fence(ring->adev, sync, active);
++ id = list_first_entry(&adev->vm_manager.ids_lru,
++ struct amdgpu_vm_manager_id,
++ list);
++ list_move_tail(&id->list, &adev->vm_manager.ids_lru);
++ atomic_long_set(&id->owner, (long)vm);
+
+- trace_amdgpu_vm_grab_id(vm, choices[i], ring->idx);
+- atomic_long_set(&adev->vm_manager.ids[vm_id->id].owner, (long)vm);
++ vm_id->id = id - adev->vm_manager.ids;
++ trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx);
+
+- fence_put(adev->vm_manager.ids[vm_id->id].active);
+- adev->vm_manager.ids[vm_id->id].active = fence_get(fence);
++ r = amdgpu_sync_fence(ring->adev, sync, id->active);
+
+- mutex_unlock(&adev->vm_manager.lock);
+- return r;
++ if (!r) {
++ fence_put(id->active);
++ id->active = fence_get(fence);
+ }
+
+- /* should never happen */
+- BUG();
+ mutex_unlock(&adev->vm_manager.lock);
+- return -EINVAL;
++ return r;
+ }
+
+ /**
+@@ -1366,6 +1339,25 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+ }
+
+ /**
++ * amdgpu_vm_manager_init - init the VM manager
++ *
++ * @adev: amdgpu_device pointer
++ *
++ * Initialize the VM manager structures
++ */
++void amdgpu_vm_manager_init(struct amdgpu_device *adev)
++{
++ unsigned i;
++
++ INIT_LIST_HEAD(&adev->vm_manager.ids_lru);
++
++ /* skip over VMID 0, since it is the system VM */
++ for (i = 1; i < adev->vm_manager.num_ids; ++i)
++ list_add_tail(&adev->vm_manager.ids[i].list,
++ &adev->vm_manager.ids_lru);
++}
++
++/**
+ * amdgpu_vm_manager_fini - cleanup VM manager
+ *
+ * @adev: amdgpu_device pointer
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+index c01b861..7864318 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+@@ -694,7 +694,8 @@ static int gmc_v7_0_vm_init(struct amdgpu_device *adev)
+ * amdgpu graphics/compute will use VMIDs 1-7
+ * amdkfd will use VMIDs 8-15
+ */
+- adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS;
++ adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS;
++ amdgpu_vm_manager_init(adev);
+
+ /* base offset of vram pages */
+ if (adev->flags & AMD_IS_APU) {
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+index e59251f..009fe5f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+@@ -774,7 +774,8 @@ static int gmc_v8_0_vm_init(struct amdgpu_device *adev)
+ * amdgpu graphics/compute will use VMIDs 1-7
+ * amdkfd will use VMIDs 8-15
+ */
+- adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS;
++ adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS;
++ amdgpu_vm_manager_init(adev);
+
+ /* base offset of vram pages */
+ if (adev->flags & AMD_IS_APU) {
+--
+2.7.4
+