summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c6
-rw-r--r--drivers/gpu/drm/i915/i915_params.c4
-rw-r--r--drivers/gpu/drm/i915/i915_params.h1
-rw-r--r--drivers/gpu/drm/i915/i915_scheduler.c38
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;