aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0292-drm-amdgpu-recreate-fence-from-user-seq.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0292-drm-amdgpu-recreate-fence-from-user-seq.patch')
-rw-r--r--common/recipes-kernel/linux/files/0292-drm-amdgpu-recreate-fence-from-user-seq.patch131
1 files changed, 131 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0292-drm-amdgpu-recreate-fence-from-user-seq.patch b/common/recipes-kernel/linux/files/0292-drm-amdgpu-recreate-fence-from-user-seq.patch
new file mode 100644
index 00000000..da2703e4
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0292-drm-amdgpu-recreate-fence-from-user-seq.patch
@@ -0,0 +1,131 @@
+From 03507c4f2f63d8d98c2455cf4d192589fac553c7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 19 Jun 2015 17:00:19 +0200
+Subject: [PATCH 0292/1050] drm/amdgpu: recreate fence from user seq
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+And use common fence infrastructure for the wait.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 ++---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 11 +++++----
+ drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 37 +++++++++++++++++++++++++++++--
+ 3 files changed, 44 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 963c4ba..0165783 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -425,6 +425,8 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
+ unsigned irq_type);
+ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
+ struct amdgpu_fence **fence);
++int amdgpu_fence_recreate(struct amdgpu_ring *ring, void *owner,
++ uint64_t seq, struct amdgpu_fence **fence);
+ void amdgpu_fence_process(struct amdgpu_ring *ring);
+ int amdgpu_fence_wait_next(struct amdgpu_ring *ring);
+ int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
+@@ -435,9 +437,6 @@ int amdgpu_fence_wait(struct amdgpu_fence *fence, bool interruptible);
+ int amdgpu_fence_wait_any(struct amdgpu_device *adev,
+ struct amdgpu_fence **fences,
+ bool intr);
+-long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev,
+- u64 *target_seq, bool intr,
+- long timeout);
+ struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence);
+ void amdgpu_fence_unref(struct amdgpu_fence **fence);
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index 86b78c7..84ba1d1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -739,9 +739,9 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
+ {
+ union drm_amdgpu_wait_cs *wait = data;
+ struct amdgpu_device *adev = dev->dev_private;
+- uint64_t seq[AMDGPU_MAX_RINGS] = {0};
+- struct amdgpu_ring *ring = NULL;
+ unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout);
++ struct amdgpu_fence *fence = NULL;
++ struct amdgpu_ring *ring = NULL;
+ struct amdgpu_ctx *ctx;
+ long r;
+
+@@ -754,9 +754,12 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
+ if (r)
+ return r;
+
+- seq[ring->idx] = wait->in.handle;
++ r = amdgpu_fence_recreate(ring, filp, wait->in.handle, &fence);
++ if (r)
++ return r;
+
+- r = amdgpu_fence_wait_seq_timeout(adev, seq, true, timeout);
++ r = fence_wait_timeout(&fence->base, true, timeout);
++ amdgpu_fence_unref(&fence);
+ amdgpu_ctx_put(ctx);
+ if (r < 0)
+ return r;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+index f2d885c..a7189a1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+@@ -136,6 +136,38 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
+ }
+
+ /**
++ * amdgpu_fence_recreate - recreate a fence from an user fence
++ *
++ * @ring: ring the fence is associated with
++ * @owner: creator of the fence
++ * @seq: user fence sequence number
++ * @fence: resulting amdgpu fence object
++ *
++ * Recreates a fence command from the user fence sequence number (all asics).
++ * Returns 0 on success, -ENOMEM on failure.
++ */
++int amdgpu_fence_recreate(struct amdgpu_ring *ring, void *owner,
++ uint64_t seq, struct amdgpu_fence **fence)
++{
++ struct amdgpu_device *adev = ring->adev;
++
++ if (seq > ring->fence_drv.sync_seq[ring->idx])
++ return -EINVAL;
++
++ *fence = kmalloc(sizeof(struct amdgpu_fence), GFP_KERNEL);
++ if ((*fence) == NULL)
++ return -ENOMEM;
++
++ (*fence)->seq = seq;
++ (*fence)->ring = ring;
++ (*fence)->owner = owner;
++ fence_init(&(*fence)->base, &amdgpu_fence_ops,
++ &adev->fence_queue.lock, adev->fence_context + ring->idx,
++ (*fence)->seq);
++ return 0;
++}
++
++/**
+ * amdgpu_fence_check_signaled - callback from fence_queue
+ *
+ * this function is called with fence_queue lock held, which is also used
+@@ -517,8 +549,9 @@ static bool amdgpu_fence_any_seq_signaled(struct amdgpu_device *adev, u64 *seq)
+ * the wait timeout, or an error for all other cases.
+ * -EDEADLK is returned when a GPU lockup has been detected.
+ */
+-long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev, u64 *target_seq,
+- bool intr, long timeout)
++static long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev,
++ u64 *target_seq, bool intr,
++ long timeout)
+ {
+ uint64_t last_seq[AMDGPU_MAX_RINGS];
+ bool signaled;
+--
+1.9.1
+