aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-10-01 10:47:53 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2018-10-01 15:34:19 -0400
commitb16c765122f987056e1dc9ef6c214571bb5bd694 (patch)
tree4d40534af04067fbe590fbc25e0d6d221e3f7aa3 /drivers/gpu
parent790ea70c5eb5e0893da0224cd093718b133f4461 (diff)
drm/i915: Priority boost for new clients
Taken from an idea used for FQ_CODEL, we give the first request of a new request flows a small priority boost. These flows are likely to correspond with short, interactive tasks and so be more latency sensitive than the longer free running queues. As soon as the client has more than one request in the queue, further requests are not boosted and it settles down into ordinary steady state behaviour. Such small kicks dramatically help combat the starvation issue, by allowing each client the opportunity to run even when the system is under heavy throughput load (within the constraints of the user selected priority). v2: Mark the preempted request as the start of a new flow, to prevent a single client being continually gazumped by its peers. Testcase: igt/benchmarks/rrul Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181001144755.7978-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_request.c16
-rw-r--r--drivers/gpu/drm/i915/i915_scheduler.h4
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c25
3 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index a492385b2089..56140ca054e8 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -1127,8 +1127,20 @@ void i915_request_add(struct i915_request *request)
1127 */ 1127 */
1128 local_bh_disable(); 1128 local_bh_disable();
1129 rcu_read_lock(); /* RCU serialisation for set-wedged protection */ 1129 rcu_read_lock(); /* RCU serialisation for set-wedged protection */
1130 if (engine->schedule) 1130 if (engine->schedule) {
1131 engine->schedule(request, &request->gem_context->sched); 1131 struct i915_sched_attr attr = request->gem_context->sched;
1132
1133 /*
1134 * Boost priorities to new clients (new request flows).
1135 *
1136 * Allow interactive/synchronous clients to jump ahead of
1137 * the bulk clients. (FQ_CODEL)
1138 */
1139 if (!prev || i915_request_completed(prev))
1140 attr.priority |= I915_PRIORITY_NEWCLIENT;
1141
1142 engine->schedule(request, &attr);
1143 }
1132 rcu_read_unlock(); 1144 rcu_read_unlock();
1133 i915_sw_fence_commit(&request->submit); 1145 i915_sw_fence_commit(&request->submit);
1134 local_bh_enable(); /* Kick the execlists tasklet if just scheduled */ 1146 local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
index 89d456312557..53dc7dbf88b9 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -19,12 +19,14 @@ enum {
19 I915_PRIORITY_INVALID = INT_MIN 19 I915_PRIORITY_INVALID = INT_MIN
20}; 20};
21 21
22#define I915_USER_PRIORITY_SHIFT 0 22#define I915_USER_PRIORITY_SHIFT 1
23#define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT) 23#define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT)
24 24
25#define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT) 25#define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT)
26#define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1) 26#define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1)
27 27
28#define I915_PRIORITY_NEWCLIENT ((u8)BIT(0))
29
28struct i915_sched_attr { 30struct i915_sched_attr {
29 /** 31 /**
30 * @priority: execution and service priority 32 * @priority: execution and service priority
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 4ee00f531153..5f324d6b44d5 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -363,9 +363,9 @@ static void unwind_wa_tail(struct i915_request *rq)
363 363
364static void __unwind_incomplete_requests(struct intel_engine_cs *engine) 364static void __unwind_incomplete_requests(struct intel_engine_cs *engine)
365{ 365{
366 struct i915_request *rq, *rn; 366 struct i915_request *rq, *rn, *active = NULL;
367 struct list_head *uninitialized_var(pl); 367 struct list_head *uninitialized_var(pl);
368 int last_prio = I915_PRIORITY_INVALID; 368 int prio = I915_PRIORITY_INVALID | I915_PRIORITY_NEWCLIENT;
369 369
370 lockdep_assert_held(&engine->timeline.lock); 370 lockdep_assert_held(&engine->timeline.lock);
371 371
@@ -373,19 +373,32 @@ static void __unwind_incomplete_requests(struct intel_engine_cs *engine)
373 &engine->timeline.requests, 373 &engine->timeline.requests,
374 link) { 374 link) {
375 if (i915_request_completed(rq)) 375 if (i915_request_completed(rq))
376 return; 376 break;
377 377
378 __i915_request_unsubmit(rq); 378 __i915_request_unsubmit(rq);
379 unwind_wa_tail(rq); 379 unwind_wa_tail(rq);
380 380
381 GEM_BUG_ON(rq_prio(rq) == I915_PRIORITY_INVALID); 381 GEM_BUG_ON(rq_prio(rq) == I915_PRIORITY_INVALID);
382 if (rq_prio(rq) != last_prio) { 382 if (rq_prio(rq) != prio) {
383 last_prio = rq_prio(rq); 383 prio = rq_prio(rq);
384 pl = lookup_priolist(engine, last_prio); 384 pl = lookup_priolist(engine, prio);
385 } 385 }
386 GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root)); 386 GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root));
387 387
388 list_add(&rq->sched.link, pl); 388 list_add(&rq->sched.link, pl);
389
390 active = rq;
391 }
392
393 /*
394 * The active request is now effectively the start of a new client
395 * stream, so give it the equivalent small priority bump to prevent
396 * it being gazumped a second time by another peer.
397 */
398 if (!(prio & I915_PRIORITY_NEWCLIENT)) {
399 prio |= I915_PRIORITY_NEWCLIENT;
400 list_move_tail(&active->sched.link,
401 lookup_priolist(engine, prio));
389 } 402 }
390} 403}
391 404