summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_sw_fence_work.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-12-16 19:17:16 +0300
committerChris Wilson <chris@chris-wilson.co.uk>2019-12-18 13:13:03 +0300
commit54d7195f8c64c83a13bd343e349b1bbf158c8aad (patch)
tree8f75bb41b6d0d2a5066b9a925d290d8e772c22f8 /drivers/gpu/drm/i915/i915_sw_fence_work.c
parentf20c6b278d1a0cedc691c3b0ebcf9154ad9d8a1a (diff)
downloadlinux-54d7195f8c64c83a13bd343e349b1bbf158c8aad.tar.xz
drm/i915: Unpin vma->obj on early error
If we inherit an error along the fence chain, we skip the main work callback and go straight to the error. In the case of the vma bind worker, we only dropped the pinned pages from the worker. In the process, make sure we call the release earlier rather than wait until the final reference to the fence is dropped (as a reference is kept while being listened upon). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191216161717.2688274-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_sw_fence_work.c')
-rw-r--r--drivers/gpu/drm/i915/i915_sw_fence_work.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_sw_fence_work.c b/drivers/gpu/drm/i915/i915_sw_fence_work.c
index 8538ee7a521d..997b2998f1f2 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence_work.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence_work.c
@@ -6,6 +6,13 @@
#include "i915_sw_fence_work.h"
+static void fence_complete(struct dma_fence_work *f)
+{
+ if (f->ops->release)
+ f->ops->release(f);
+ dma_fence_signal(&f->dma);
+}
+
static void fence_work(struct work_struct *work)
{
struct dma_fence_work *f = container_of(work, typeof(*f), work);
@@ -14,7 +21,8 @@ static void fence_work(struct work_struct *work)
err = f->ops->work(f);
if (err)
dma_fence_set_error(&f->dma, err);
- dma_fence_signal(&f->dma);
+
+ fence_complete(f);
dma_fence_put(&f->dma);
}
@@ -32,7 +40,7 @@ fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
dma_fence_get(&f->dma);
queue_work(system_unbound_wq, &f->work);
} else {
- dma_fence_signal(&f->dma);
+ fence_complete(f);
}
break;
@@ -60,9 +68,6 @@ static void fence_release(struct dma_fence *fence)
{
struct dma_fence_work *f = container_of(fence, typeof(*f), dma);
- if (f->ops->release)
- f->ops->release(f);
-
i915_sw_fence_fini(&f->chain);
BUILD_BUG_ON(offsetof(typeof(*f), dma));