diff options
author | Dave Gordon <david.s.gordon@intel.com> | 2015-10-26 18:37:36 +0000 |
---|---|---|
committer | John Harrison <John.C.Harrison@Intel.com> | 2016-06-28 17:19:21 +0100 |
commit | af833ea2683b093966f966c30bc025cde36f89d2 (patch) | |
tree | 8f92a9bc9ceef9eed61362811335e49c09062c64 | |
parent | a3a5aa5a3eff2eab70e4deaf85d2f978c64a38c0 (diff) |
drm/i915/preempt: scheduler logic for queueing preemptive requests
This is the very first stage of the scheduler's preemption logic, where
it determines whether a request should be marked as potentially
preemptive, at the point where it is added to the scheduler's queue.
Subsequent logic will determine how to handle the request on the basis
of the flags set here.
Actually-preemptive requests are disabled via a module parameter at this
early stage, as the rest of the logic to process them isn't in place
yet.
For: VIZ-2021
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_params.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_params.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_scheduler.c | 38 |
4 files changed, 46 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c55b5ec8c16b..0ed102d87d5a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3666,6 +3666,12 @@ const char *i915_scheduler_queue_status_str( case I915_SQS_FLYING: return "Flying"; + case I915_SQS_OVERTAKING: + return "Overtaking"; + + case I915_SQS_PREEMPTED: + return "Preempted"; + case I915_SQS_COMPLETE: return "Complete"; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index f10482d06864..7d93b5b9d12c 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -59,6 +59,7 @@ struct i915_params i915 __read_mostly = { .enable_dp_mst = true, .inject_load_failure = 0, .enable_scheduler = 1, + .enable_preemption = 0, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -214,3 +215,6 @@ MODULE_PARM_DESC(inject_load_failure, module_param_named_unsafe(enable_scheduler, i915.enable_scheduler, int, 0600); MODULE_PARM_DESC(enable_scheduler, "Enable scheduler (0 = disable, 1 = enable [default])"); + +module_param_named_unsafe(enable_preemption, i915.enable_preemption, int, 0600); +MODULE_PARM_DESC(enable_preemption, "Enable pre-emption within scheduler (0 = disable [default], 1 = enable)"); diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 44b08b3d5b90..6031b69493ad 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -51,6 +51,7 @@ struct i915_params { int edp_vswing; unsigned int inject_load_failure; int enable_scheduler; + int enable_preemption; /* leave bools at the end to not create holes */ bool enable_hangcheck; bool fastboot; diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index c74606520ebc..b2e1c386fb12 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -51,10 +51,13 @@ bool i915_scheduler_is_enabled(struct drm_device *dev) const char *i915_qe_state_str(struct i915_scheduler_queue_entry *node) { + uint32_t sched_flags = node->params.request->scheduler_flags; static char str[50]; char *ptr = str; *(ptr++) = node->bumped ? 'B' : '-', + *(ptr++) = (sched_flags & I915_REQ_SF_PREEMPT) ? 'P' : '-'; + *(ptr++) = (sched_flags & I915_REQ_SF_WAS_PREEMPT) ? 'p' : '-'; *(ptr++) = i915_gem_request_completed(node->params.request) ? 'C' : '-'; *ptr = 0; @@ -77,6 +80,12 @@ char i915_scheduler_queue_status_chr(enum i915_scheduler_queue_status status) case I915_SQS_FLYING: return 'F'; + case I915_SQS_OVERTAKING: + return 'O'; + + case I915_SQS_PREEMPTED: + return 'P'; + case I915_SQS_COMPLETE: return 'C'; @@ -241,6 +250,7 @@ static void i915_scheduler_node_fly(struct i915_scheduler_queue_entry *node) struct drm_i915_private *dev_priv = to_i915(node->params.dev); struct i915_scheduler *scheduler = dev_priv->scheduler; struct intel_engine_cs *engine = node->params.engine; + struct drm_i915_gem_request *req = node->params.request; assert_scheduler_lock_held(scheduler); @@ -253,7 +263,10 @@ static void i915_scheduler_node_fly(struct i915_scheduler_queue_entry *node) */ list_add(&node->link, &scheduler->node_queue[engine->id]); - node->status = I915_SQS_FLYING; + if (req->scheduler_flags & I915_REQ_SF_PREEMPT) + node->status = I915_SQS_OVERTAKING; + else + node->status = I915_SQS_FLYING; scheduler->counts[engine->id].flying++; trace_i915_scheduler_fly(engine, node); @@ -858,7 +871,7 @@ int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe) struct i915_scheduler *scheduler = dev_priv->scheduler; struct intel_engine_cs *engine = qe->params.engine; struct i915_scheduler_queue_entry *node; - bool not_flying; + bool not_flying, want_preempt; int i, e; int incomplete; @@ -939,6 +952,25 @@ int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe) not_flying = i915_scheduler_count_flying(scheduler, engine) < scheduler->min_flying; + want_preempt = node->priority >= scheduler->priority_level_preempt; + + if (!i915.enable_preemption) + want_preempt = false; + + /* Pre-emption is not yet implemented in non-execlist mode */ + if (!i915.enable_execlists) + want_preempt = false; + + /* Pre-emption is not yet implemented in non-GUC mode */ + if (!i915.enable_guc_submission) + want_preempt = false; + + if (want_preempt) { + node->params.request->scheduler_flags |= + I915_REQ_SF_WAS_PREEMPT | I915_REQ_SF_PREEMPT; + scheduler->stats[engine->id].preempts_queued++; + } + scheduler->counts[engine->id].queued++; scheduler->stats[engine->id].queued++; @@ -947,7 +979,7 @@ int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe) spin_unlock_irq(&scheduler->lock); - if (not_flying) + if (not_flying || want_preempt) i915_scheduler_submit(engine); return 0; |