[Intel-gfx] [RFC 30/37] drm/i915/preempt: don't allow nonbatch ctx init when the scheduler is busy

John.C.Harrison at Intel.com John.C.Harrison at Intel.com
Mon Nov 23 03:42:05 PST 2015


From: Dave Gordon <david.s.gordon at intel.com>

If the scheduler is busy (e.g. processing a preemption) it will need to
be able to acquire the struct_mutex, so we can't allow untracked
requests to bypass the scheduler and go directly to the hardware (much
confusion will result). Since untracked requests are used only for
initialisation of logical contexts, we can avoid the problem by forcing
any thread trying to initialise a context at an unfortunate time to drop
the mutex and retry later.

For: VIZ-2021
Signed-off-by: Dave Gordon <david.s.gordon at intel.com>
---
 drivers/gpu/drm/i915/i915_scheduler.c | 6 ++++++
 drivers/gpu/drm/i915/i915_scheduler.h | 1 +
 drivers/gpu/drm/i915/intel_lrc.c      | 8 ++++++++
 3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index 81ac88b..a037ba2 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -1778,6 +1778,12 @@ bool i915_scheduler_is_ring_preempting(struct intel_engine_cs *ring)
 	return false;
 }
 
+bool i915_scheduler_is_ring_busy(struct intel_engine_cs *ring)
+{
+	/* Currently only pre-emption ties up the scheduler. */
+	return i915_scheduler_is_ring_preempting(ring);
+}
+
 /*
  * Used by TDR to distinguish hung rings (not moving but with work to do)
  * from idle rings (not moving because there is nothing to do).
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
index 569215a..d5f4af3 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -195,6 +195,7 @@ bool        i915_scheduler_notify_request(struct drm_i915_gem_request *req);
 void        i915_scheduler_wakeup(struct drm_device *dev);
 bool        i915_scheduler_is_ring_flying(struct intel_engine_cs *ring);
 bool        i915_scheduler_is_ring_preempting(struct intel_engine_cs *ring);
+bool        i915_scheduler_is_ring_busy(struct intel_engine_cs *ring);
 void        i915_gem_scheduler_work_handler(struct work_struct *work);
 int         i915_scheduler_flush(struct intel_engine_cs *ring, bool is_locked);
 int         i915_scheduler_flush_stamp(struct intel_engine_cs *ring,
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index b7d9fbd..1ccb50d 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2582,6 +2582,14 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 	WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL);
 	WARN_ON(ctx->engine[ring->id].state);
 
+	/* Don't submit non-scheduler requests while the scheduler is busy */
+	if (i915_scheduler_is_ring_busy(ring)) {
+		mutex_unlock(&dev->struct_mutex);
+		msleep(1);
+		mutex_lock(&dev->struct_mutex);
+		return -EAGAIN;
+	}
+
 	intel_runtime_pm_get(dev->dev_private);
 
 	context_size = round_up(intel_lr_context_size(ring), 4096);
-- 
1.9.1



More information about the Intel-gfx mailing list