[PATCH 7/7] reset-modeset-to-srcu

Chris Wilson chris at chris-wilson.co.uk
Thu Feb 21 12:05:48 UTC 2019


---
 drivers/gpu/drm/i915/i915_gem.c               |  1 -
 drivers/gpu/drm/i915/i915_gpu_error.h         |  9 +---
 drivers/gpu/drm/i915/i915_reset.c             |  1 -
 drivers/gpu/drm/i915/intel_display.c          | 46 ++++---------------
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  1 -
 5 files changed, 10 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 62e4df1cbf87..bd292563c3af 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5261,7 +5261,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 			  i915_gem_retire_work_handler);
 	INIT_DELAYED_WORK(&dev_priv->gt.idle_work,
 			  i915_gem_idle_work_handler);
-	init_waitqueue_head(&dev_priv->gpu_error.wait_queue);
 	init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
 	mutex_init(&dev_priv->gpu_error.wedge_mutex);
 	init_srcu_struct(&dev_priv->gpu_error.reset_backoff_srcu);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
index 8c1569c1830d..3b0b2f90472d 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -217,8 +217,7 @@ struct i915_gpu_error {
 	 */
 	unsigned long flags;
 #define I915_RESET_BACKOFF	0
-#define I915_RESET_MODESET	1
-#define I915_RESET_ENGINE	2
+#define I915_RESET_ENGINE	1
 #define I915_WEDGED		(BITS_PER_LONG - 1)
 
 	/** Number of times the device has been reset (global) */
@@ -229,12 +228,6 @@ struct i915_gpu_error {
 
 	struct mutex wedge_mutex; /* serialises wedging/unwedging */
 
-	/**
-	 * Waitqueue to signal when a hang is detected. Used to for waiters
-	 * to release the struct_mutex for the reset to procede.
-	 */
-	wait_queue_head_t wait_queue;
-
 	/**
 	 * Waitqueue to signal when the reset has completed. Used by clients
 	 * that wait for dev_priv->mm.wedged to settle.
diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c
index 55d6123dbba4..d0bf4a8e4268 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -1254,7 +1254,6 @@ void i915_handle_error(struct drm_i915_private *i915,
 	 */
 	if (intel_has_reset_engine(i915) && !__i915_wedged(error)) {
 		for_each_engine_masked(engine, i915, engine_mask, tmp) {
-			BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE);
 			if (test_and_set_bit(I915_RESET_ENGINE + engine->id,
 					     &error->flags))
 				continue;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0ca09d1341f3..59578d78ee54 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3861,10 +3861,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
 	    !gpu_reset_clobbers_display(dev_priv))
 		return;
 
-	/* We have a modeset vs reset deadlock, defensively unbreak it. */
-	set_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
-	wake_up_all(&dev_priv->gpu_error.wait_queue);
-
 	if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) {
 		DRM_DEBUG_KMS("Modeset potentially stuck, unbreaking through wedging\n");
 		i915_gem_set_wedged(dev_priv);
@@ -3891,6 +3887,7 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
 	if (IS_ERR(state)) {
 		ret = PTR_ERR(state);
 		DRM_ERROR("Duplicating state failed with %i\n", ret);
+		mutex_unlock(&dev->mode_config.mutex);
 		return;
 	}
 
@@ -3898,6 +3895,7 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
 	if (ret) {
 		DRM_ERROR("Suspending crtc's failed with %i\n", ret);
 		drm_atomic_state_put(state);
+		mutex_unlock(&dev->mode_config.mutex);
 		return;
 	}
 
@@ -3912,13 +3910,10 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
 	struct drm_atomic_state *state;
 	int ret;
 
-	/* reset doesn't touch the display */
-	if (!test_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags))
-		return;
-
+	/* reset doesn't touch the display? */
 	state = fetch_and_zero(&dev_priv->modeset_restore_state);
 	if (!state)
-		goto unlock;
+		return;
 
 	/* reset doesn't touch the display */
 	if (!gpu_reset_clobbers_display(dev_priv)) {
@@ -3948,12 +3943,9 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
 	}
 
 	drm_atomic_state_put(state);
-unlock:
 	drm_modeset_drop_locks(ctx);
 	drm_modeset_acquire_fini(ctx);
 	mutex_unlock(&dev->mode_config.mutex);
-
-	clear_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
 }
 
 static void icl_set_pipe_chicken(struct intel_crtc *crtc)
@@ -13182,30 +13174,6 @@ static void intel_atomic_helper_free_state_worker(struct work_struct *work)
 	intel_atomic_helper_free_state(dev_priv);
 }
 
-static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state)
-{
-	struct wait_queue_entry wait_fence, wait_reset;
-	struct drm_i915_private *dev_priv = to_i915(intel_state->base.dev);
-
-	init_wait_entry(&wait_fence, 0);
-	init_wait_entry(&wait_reset, 0);
-	for (;;) {
-		prepare_to_wait(&intel_state->commit_ready.wait,
-				&wait_fence, TASK_UNINTERRUPTIBLE);
-		prepare_to_wait(&dev_priv->gpu_error.wait_queue,
-				&wait_reset, TASK_UNINTERRUPTIBLE);
-
-
-		if (i915_sw_fence_done(&intel_state->commit_ready)
-		    || test_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags))
-			break;
-
-		schedule();
-	}
-	finish_wait(&intel_state->commit_ready.wait, &wait_fence);
-	finish_wait(&dev_priv->gpu_error.wait_queue, &wait_reset);
-}
-
 static void intel_atomic_cleanup_work(struct work_struct *work)
 {
 	struct drm_atomic_state *state =
@@ -13230,9 +13198,11 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 	struct intel_crtc *intel_crtc;
 	u64 put_domains[I915_MAX_PIPES] = {};
 	intel_wakeref_t wakeref = 0;
+	int srcu;
 	int i;
 
-	intel_atomic_commit_fence_wait(intel_state);
+	srcu = i915_reset_trylock(dev_priv);
+	i915_sw_fence_wait(&intel_state->commit_ready);
 
 	drm_atomic_helper_wait_for_dependencies(state);
 
@@ -13397,6 +13367,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 	 */
 	INIT_WORK(&state->commit_work, intel_atomic_cleanup_work);
 	queue_work(system_highpri_wq, &state->commit_work);
+
+	i915_reset_unlock(dev_priv, srcu);
 }
 
 static void intel_atomic_commit_work(struct work_struct *work)
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index fc516a2970f4..397b3fe77e27 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -187,7 +187,6 @@ struct drm_i915_private *mock_gem_device(void)
 	mock_uncore_init(i915);
 	i915_gem_init__mm(i915);
 
-	init_waitqueue_head(&i915->gpu_error.wait_queue);
 	init_waitqueue_head(&i915->gpu_error.reset_queue);
 	init_srcu_struct(&i915->gpu_error.reset_backoff_srcu);
 	mutex_init(&i915->gpu_error.wedge_mutex);
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list