Re: FAILED: patch "[PATCH] drm/radeon: fix CP semaphores on CIK" failed to apply to 3.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Greg,

something went wrong here. The patch doesn't apply to your 3.14-stable tree because it's already part of 3.14 since rc4.

Maybe you wanted to apply it to some different tree or something else?

Regards,
Christian.

Am 21.05.2014 08:52, schrieb gregkh@xxxxxxxxxxxxxxxxxxx:
The patch below does not apply to the 3.14-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@xxxxxxxxxxxxxxx>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

 From 1c61eae469e0d1d2fb9d7b77f51ca50c1f8f3ce9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@xxxxxxx>
Date: Tue, 18 Feb 2014 01:50:22 -0700
Subject: [PATCH] drm/radeon: fix CP semaphores on CIK
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The CP semaphore queue on CIK has a bug that triggers if uncompleted
waits use the same address while a signal is still pending. Work around
this by using different addresses for each sync.

Signed-off-by: Christian König <christian.koenig@xxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4a8ac1cd6b4c..024db37b1832 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -135,6 +135,9 @@ extern int radeon_hard_reset;
  /* R600+ */
  #define R600_RING_TYPE_UVD_INDEX	5
+/* number of hw syncs before falling back on blocking */
+#define RADEON_NUM_SYNCS			4
+
  /* hardcode those limit for now */
  #define RADEON_VA_IB_OFFSET			(1 << 20)
  #define RADEON_VA_RESERVED_SIZE			(8 << 20)
@@ -554,7 +557,6 @@ int radeon_mode_dumb_mmap(struct drm_file *filp,
  /*
   * Semaphores.
   */
-/* everything here is constant */
  struct radeon_semaphore {
  	struct radeon_sa_bo		*sa_bo;
  	signed				waiters;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 1b783f0e6d3a..15e44a7281ab 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -139,7 +139,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
  	}
/* 64 dwords should be enough for fence too */
-	r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_RINGS * 8);
+	r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8);
  	if (r) {
  		dev_err(rdev->dev, "scheduling IB failed (%d).\n", r);
  		return r;
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 2b42aa1914f2..9006b32d5eed 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -34,14 +34,15 @@
  int radeon_semaphore_create(struct radeon_device *rdev,
  			    struct radeon_semaphore **semaphore)
  {
+	uint32_t *cpu_addr;
  	int i, r;
*semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL);
  	if (*semaphore == NULL) {
  		return -ENOMEM;
  	}
-	r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo,
-			     &(*semaphore)->sa_bo, 8, 8, true);
+	r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo,
+			     8 * RADEON_NUM_SYNCS, 8, true);
  	if (r) {
  		kfree(*semaphore);
  		*semaphore = NULL;
@@ -49,7 +50,10 @@ int radeon_semaphore_create(struct radeon_device *rdev,
  	}
  	(*semaphore)->waiters = 0;
  	(*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo);
-	*((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0;
+
+	cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo);
+	for (i = 0; i < RADEON_NUM_SYNCS; ++i)
+		cpu_addr[i] = 0;
for (i = 0; i < RADEON_NUM_RINGS; ++i)
  		(*semaphore)->sync_to[i] = NULL;
@@ -125,6 +129,7 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
  				struct radeon_semaphore *semaphore,
  				int ring)
  {
+	unsigned count = 0;
  	int i, r;
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
@@ -140,6 +145,12 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
  			return -EINVAL;
  		}
+ if (++count > RADEON_NUM_SYNCS) {
+			/* not enough room, wait manually */
+			radeon_fence_wait_locked(fence);
+			continue;
+		}
+
  		/* allocate enough space for sync command */
  		r = radeon_ring_alloc(rdev, &rdev->ring[i], 16);
  		if (r) {
@@ -164,6 +175,8 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
radeon_ring_commit(rdev, &rdev->ring[i]);
  		radeon_fence_note_sync(fence, ring);
+
+		semaphore->gpu_addr += 8;
  	}
return 0;


--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]