[PATCH] drm/radeon: fix CP semaphores on CIK
Alex Deucher
alexdeucher at gmail.com
Tue Feb 18 09:55:18 PST 2014
On Tue, Feb 18, 2014 at 5:38 AM, Christian König
<deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at amd.com>
>
> 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 at amd.com>
> Cc: stable at vger.kernel.org
Applied to -fixes. thanks!
Alex
> ---
> drivers/gpu/drm/radeon/radeon.h | 4 +++-
> drivers/gpu/drm/radeon/radeon_ring.c | 2 +-
> drivers/gpu/drm/radeon/radeon_semaphore.c | 19 ++++++++++++++++---
> 3 files changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 4a8ac1c..024db37 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 1b783f0..15e44a7 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 2b42aa1..9006b32 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;
> --
> 1.8.3.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list