aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0390-drm-amdgpu-stop-using-the-ring-index-in-the-SA.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0390-drm-amdgpu-stop-using-the-ring-index-in-the-SA.patch')
-rw-r--r--common/recipes-kernel/linux/files/0390-drm-amdgpu-stop-using-the-ring-index-in-the-SA.patch177
1 files changed, 177 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0390-drm-amdgpu-stop-using-the-ring-index-in-the-SA.patch b/common/recipes-kernel/linux/files/0390-drm-amdgpu-stop-using-the-ring-index-in-the-SA.patch
new file mode 100644
index 00000000..2300320a
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0390-drm-amdgpu-stop-using-the-ring-index-in-the-SA.patch
@@ -0,0 +1,177 @@
+From b94cc62076223ff4af68772430e75e0d0ef6e3bc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 11 Mar 2016 14:50:08 +0100
+Subject: [PATCH 0390/1110] drm/amdgpu: stop using the ring index in the SA
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The ring index will always collide as hash into the fence list, so use
+the context number instead. That can still cause collisions, but they
+are less likely than using ring indices.
+
+Signed-off-by: Christian König <christian.koenig@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 | 5 +++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | 53 ++++++++++++----------------------
+ 2 files changed, 22 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 7fc816a..3abc639 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -540,11 +540,14 @@ int amdgpu_gem_debugfs_init(struct amdgpu_device *adev);
+ * Assumption is that there won't be hole (all object on same
+ * alignment).
+ */
++
++#define AMDGPU_SA_NUM_FENCE_LISTS 32
++
+ struct amdgpu_sa_manager {
+ wait_queue_head_t wq;
+ struct amdgpu_bo *bo;
+ struct list_head *hole;
+- struct list_head flist[AMDGPU_MAX_RINGS];
++ struct list_head flist[AMDGPU_SA_NUM_FENCE_LISTS];
+ struct list_head olist;
+ unsigned size;
+ uint64_t gpu_addr;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+index 2faf03b..8bf84ef 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+@@ -60,9 +60,8 @@ int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev,
+ sa_manager->align = align;
+ sa_manager->hole = &sa_manager->olist;
+ INIT_LIST_HEAD(&sa_manager->olist);
+- for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
++ for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i)
+ INIT_LIST_HEAD(&sa_manager->flist[i]);
+- }
+
+ r = amdgpu_bo_create(adev, size, align, true, domain,
+ 0, NULL, NULL, &sa_manager->bo);
+@@ -228,11 +227,9 @@ static bool amdgpu_sa_event(struct amdgpu_sa_manager *sa_manager,
+ unsigned soffset, eoffset, wasted;
+ int i;
+
+- for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
+- if (!list_empty(&sa_manager->flist[i])) {
++ for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i)
++ if (!list_empty(&sa_manager->flist[i]))
+ return true;
+- }
+- }
+
+ soffset = amdgpu_sa_bo_hole_soffset(sa_manager);
+ eoffset = amdgpu_sa_bo_hole_eoffset(sa_manager);
+@@ -265,12 +262,11 @@ static bool amdgpu_sa_bo_next_hole(struct amdgpu_sa_manager *sa_manager,
+ /* go over all fence list and try to find the closest sa_bo
+ * of the current last
+ */
+- for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
++ for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) {
+ struct amdgpu_sa_bo *sa_bo;
+
+- if (list_empty(&sa_manager->flist[i])) {
++ if (list_empty(&sa_manager->flist[i]))
+ continue;
+- }
+
+ sa_bo = list_first_entry(&sa_manager->flist[i],
+ struct amdgpu_sa_bo, flist);
+@@ -299,7 +295,9 @@ static bool amdgpu_sa_bo_next_hole(struct amdgpu_sa_manager *sa_manager,
+ }
+
+ if (best_bo) {
+- uint32_t idx = amdgpu_ring_from_fence(best_bo->fence)->idx;
++ uint32_t idx = best_bo->fence->context;
++
++ idx %= AMDGPU_SA_NUM_FENCE_LISTS;
+ ++tries[idx];
+ sa_manager->hole = best_bo->olist.prev;
+
+@@ -315,8 +313,8 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
+ struct amdgpu_sa_bo **sa_bo,
+ unsigned size, unsigned align)
+ {
+- struct fence *fences[AMDGPU_MAX_RINGS];
+- unsigned tries[AMDGPU_MAX_RINGS];
++ struct fence *fences[AMDGPU_SA_NUM_FENCE_LISTS];
++ unsigned tries[AMDGPU_SA_NUM_FENCE_LISTS];
+ unsigned count;
+ int i, r;
+ signed long t;
+@@ -338,7 +336,7 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
+
+ spin_lock(&sa_manager->wq.lock);
+ do {
+- for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
++ for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) {
+ fences[i] = NULL;
+ tries[i] = 0;
+ }
+@@ -355,7 +353,7 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
+ /* see if we can skip over some allocations */
+ } while (amdgpu_sa_bo_next_hole(sa_manager, fences, tries));
+
+- for (i = 0, count = 0; i < AMDGPU_MAX_RINGS; ++i)
++ for (i = 0, count = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i)
+ if (fences[i])
+ fences[count++] = fence_get(fences[i]);
+
+@@ -397,8 +395,9 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo,
+ spin_lock(&sa_manager->wq.lock);
+ if (fence && !fence_is_signaled(fence)) {
+ uint32_t idx;
++
+ (*sa_bo)->fence = fence_get(fence);
+- idx = amdgpu_ring_from_fence(fence)->idx;
++ idx = fence->context % AMDGPU_SA_NUM_FENCE_LISTS;
+ list_add_tail(&(*sa_bo)->flist, &sa_manager->flist[idx]);
+ } else {
+ amdgpu_sa_bo_remove_locked(*sa_bo);
+@@ -410,25 +409,6 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo,
+
+ #if defined(CONFIG_DEBUG_FS)
+
+-static void amdgpu_sa_bo_dump_fence(struct fence *fence, struct seq_file *m)
+-{
+- struct amdgpu_fence *a_fence = to_amdgpu_fence(fence);
+- struct amd_sched_fence *s_fence = to_amd_sched_fence(fence);
+-
+- if (a_fence)
+- seq_printf(m, " protected by 0x%016llx on ring %d",
+- a_fence->seq, a_fence->ring->idx);
+-
+- if (s_fence) {
+- struct amdgpu_ring *ring;
+-
+-
+- ring = container_of(s_fence->sched, struct amdgpu_ring, sched);
+- seq_printf(m, " protected by 0x%016x on ring %d",
+- s_fence->base.seqno, ring->idx);
+- }
+-}
+-
+ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
+ struct seq_file *m)
+ {
+@@ -445,8 +425,11 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
+ }
+ seq_printf(m, "[0x%010llx 0x%010llx] size %8lld",
+ soffset, eoffset, eoffset - soffset);
++
+ if (i->fence)
+- amdgpu_sa_bo_dump_fence(i->fence, m);
++ seq_printf(m, " protected by 0x%08x on context %d",
++ i->fence->seqno, i->fence->context);
++
+ seq_printf(m, "\n");
+ }
+ spin_unlock(&sa_manager->wq.lock);
+--
+2.7.4
+