We don't want to busywait on the GPU if we have other work to do. If we
give non-busywaiting workloads higher (initial) priority than workloads
that require a busywait, we will prioritise work that is ready to run
immediately.

Testcase: igt/gem_exec_schedule/semaphore
Signed-off-by: Chris Wilson <[email protected]>
---
 drivers/gpu/drm/i915/i915_request.c   |  8 +++++++-
 drivers/gpu/drm/i915/i915_scheduler.c |  2 +-
 drivers/gpu/drm/i915/i915_scheduler.h | 11 +++++++----
 drivers/gpu/drm/i915/intel_lrc.c      |  5 +++--
 4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index 6d825cd28ae6..30cd8724d39f 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -844,7 +844,7 @@ emit_semaphore_wait(struct i915_request *to,
                intel_ring_advance(to, cs);
        }
 
-       to->sched.semaphore = true;
+       to->sched.semaphore |= I915_SCHED_HAS_SEMAPHORE;
        return 0;
 }
 
@@ -867,6 +867,9 @@ i915_request_await_request(struct i915_request *to, struct 
i915_request *from)
                        return ret;
        }
 
+       if (from->sched.semaphore && !i915_request_started(from))
+               to->sched.semaphore |= I915_SCHED_CHAIN_SEMAPHORE;
+
        if (to->engine == from->engine) {
                ret = i915_sw_fence_await_sw_fence_gfp(&to->submit,
                                                       &from->submit,
@@ -1117,6 +1120,9 @@ void i915_request_add(struct i915_request *request)
        if (engine->schedule) {
                struct i915_sched_attr attr = request->gem_context->sched;
 
+               if (!request->sched.semaphore)
+                       attr.priority |= I915_PRIORITY_NOSEMAPHORE;
+
                /*
                 * Boost priorities to new clients (new request flows).
                 *
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index aa6c663dca09..4394763d10d8 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -29,7 +29,7 @@ void i915_sched_node_init(struct i915_sched_node *node)
        INIT_LIST_HEAD(&node->waiters_list);
        INIT_LIST_HEAD(&node->link);
        node->attr.priority = I915_PRIORITY_INVALID;
-       node->semaphore = false;
+       node->semaphore = 0;
 }
 
 static struct i915_dependency *
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h 
b/drivers/gpu/drm/i915/i915_scheduler.h
index d764cf10536f..d84f09e8c248 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -24,14 +24,15 @@ enum {
        I915_PRIORITY_INVALID = INT_MIN
 };
 
-#define I915_USER_PRIORITY_SHIFT 2
+#define I915_USER_PRIORITY_SHIFT 3
 #define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT)
 
 #define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT)
 #define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1)
 
-#define I915_PRIORITY_WAIT     ((u8)BIT(0))
-#define I915_PRIORITY_NEWCLIENT        ((u8)BIT(1))
+#define I915_PRIORITY_WAIT             ((u8)BIT(0))
+#define I915_PRIORITY_NEWCLIENT                ((u8)BIT(1))
+#define I915_PRIORITY_NOSEMAPHORE      ((u8)BIT(2))
 
 struct i915_sched_attr {
        /**
@@ -72,7 +73,9 @@ struct i915_sched_node {
        struct list_head waiters_list; /* those after us, they depend upon us */
        struct list_head link;
        struct i915_sched_attr attr;
-       bool semaphore;
+       unsigned long semaphore;
+#define I915_SCHED_HAS_SEMAPHORE       BIT(0)
+#define I915_SCHED_CHAIN_SEMAPHORE     BIT(1)
 };
 
 struct i915_dependency {
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 80d17b75b2e6..5bb3964bb202 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -164,7 +164,7 @@
 #define WA_TAIL_DWORDS 2
 #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS)
 
-#define ACTIVE_PRIORITY (I915_PRIORITY_NEWCLIENT)
+#define ACTIVE_PRIORITY (I915_PRIORITY_NEWCLIENT | I915_PRIORITY_NOSEMAPHORE)
 
 static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
                                            struct intel_engine_cs *engine,
@@ -614,7 +614,8 @@ static bool can_merge_rq(const struct i915_request *prev,
         * rules should mean that if this semaphore is preempted, its
         * dependency chain is preserved and suitably promoted via PI.
         */
-       if (prev->sched.semaphore && !i915_request_started(prev))
+       if (prev->sched.semaphore & I915_SCHED_HAS_SEMAPHORE &&
+           !i915_request_started(prev))
                return false;
 
        if (!can_merge_ctx(prev->hw_context, next->hw_context))
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to