diff options
Diffstat (limited to 'drivers')
-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; |