[PATCH 68/74] drm/i915: Add asynchronous waits on a value to change from non-zero
Chris Wilson
chris at chris-wilson.co.uk
Sun Jul 16 19:01:09 UTC 2017
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_sw_fence.c | 58 ++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_sw_fence.h | 4 +++
2 files changed, 62 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
index 742ea4c5d2c9..27fdb3c5283a 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -533,6 +533,64 @@ int i915_sw_fence_await_completion(struct i915_sw_fence *fence,
return pending;
}
+struct wait_value {
+ wait_queue_t base;
+ unsigned int *value;
+};
+
+static int i915_sw_fence_wake_value(wait_queue_t *wq,
+ unsigned mode, int flags, void *key)
+{
+ struct wait_value *wv = container_of(wq, typeof(*wv), base);
+
+ if (!READ_ONCE(*wv->value))
+ return 0;
+
+ return i915_sw_fence_wake(wq, mode, flags, key);
+}
+
+int i915_sw_fence_await_value(struct i915_sw_fence *fence,
+ wait_queue_head_t *wait,
+ unsigned int *value,
+ gfp_t gfp)
+{
+ struct wait_value *wv;
+ unsigned long flags;
+ int pending;
+
+ if (READ_ONCE(*value))
+ return 0;
+
+ wv = kmalloc(sizeof(*wv), gfp);
+ if (unlikely(!wv)) {
+ if (!gfpflags_allow_blocking(gfp))
+ return -ENOMEM;
+
+ wait_event(*wait, READ_ONCE(*value));
+ return 0;
+ }
+
+ INIT_LIST_HEAD(&wv->base.task_list);
+ wv->base.flags = I915_SW_FENCE_FLAG_ALLOC;
+ wv->base.func = i915_sw_fence_wake_value;
+ wv->base.private = fence;
+ wv->value = value;
+
+ i915_sw_fence_await(fence);
+
+ spin_lock_irqsave(&wait->lock, flags);
+ if (!READ_ONCE(*value)) {
+ __add_wait_queue_tail(wait, &wv->base);
+ pending = 1;
+ } else {
+ i915_sw_fence_wake(&wv->base, 0, 0, NULL);
+ pending = 0;
+ }
+ spin_unlock_irqrestore(&wait->lock, flags);
+
+ return pending;
+}
+
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftests/i915_sw_fence.c"
#endif
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h b/drivers/gpu/drm/i915/i915_sw_fence.h
index 92832a07b8ee..2d2ac872ec86 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.h
+++ b/drivers/gpu/drm/i915/i915_sw_fence.h
@@ -69,6 +69,10 @@ int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
struct i915_sw_fence *after,
gfp_t gfp);
+int i915_sw_fence_await_value(struct i915_sw_fence *fence,
+ wait_queue_head_t *wait,
+ unsigned int *value,
+ gfp_t gfp);
int i915_sw_fence_await_completion(struct i915_sw_fence *fence,
struct completion *x,
gfp_t gfp);
--
2.13.2
More information about the Intel-gfx-trybot
mailing list