[PATCH] HAX: Faster resume

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Wed Oct 4 09:45:53 UTC 2017


---
 drivers/gpu/drm/drm_atomic_helper.c  | 28 +++++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_display.c | 16 ++++++++++------
 include/drm/drm_atomic.h             |  2 ++
 include/drm/drm_atomic_helper.h      |  3 ++-
 4 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 01c34bc5b5b0..f103e2b2f489 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1670,6 +1670,9 @@ crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc)
 			return NULL;
 
 		init_commit(state->fake_commit, NULL);
+
+		if (state->legacy_cursor_update)
+			complete_all(&state->fake_commit->hw_done);
 	}
 
 	return state->fake_commit;
@@ -1976,6 +1979,9 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
 		complete_all(&commit->cleanup_done);
 		WARN_ON(!try_wait_for_completion(&commit->hw_done));
 
+		if (old_state->kernel_flip)
+			continue;
+
 		spin_lock(&crtc->commit_lock);
 		list_del(&commit->commit_entry);
 		spin_unlock(&crtc->commit_lock);
@@ -2425,10 +2431,12 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 		crtc->state = new_crtc_state;
 
 		if (new_crtc_state->commit) {
-			spin_lock(&crtc->commit_lock);
-			list_add(&new_crtc_state->commit->commit_entry,
-				 &crtc->commit_list);
-			spin_unlock(&crtc->commit_lock);
+			if (!state->kernel_flip) {
+				spin_lock(&crtc->commit_lock);
+				list_add(&new_crtc_state->commit->commit_entry,
+					&crtc->commit_list);
+				spin_unlock(&crtc->commit_lock);
+			}
 
 			new_crtc_state->commit->event = NULL;
 		}
@@ -2968,6 +2976,7 @@ EXPORT_SYMBOL(drm_atomic_helper_suspend);
  * drm_atomic_helper_commit_duplicated_state - commit duplicated state
  * @state: duplicated atomic state to commit
  * @ctx: pointer to acquire_ctx to use for commit.
+ * @nonblock: Whether to use nonblocking commit.
  *
  * The state returned by drm_atomic_helper_duplicate_state() and
  * drm_atomic_helper_suspend() is partially invalid, and needs to
@@ -2980,7 +2989,8 @@ EXPORT_SYMBOL(drm_atomic_helper_suspend);
  * drm_atomic_helper_suspend()
  */
 int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
-					      struct drm_modeset_acquire_ctx *ctx)
+					      struct drm_modeset_acquire_ctx *ctx,
+					      bool nonblock)
 {
 	int i;
 	struct drm_plane *plane;
@@ -3006,7 +3016,11 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
 	for_each_new_connector_in_state(state, connector, new_conn_state, i)
 		state->connectors[i].old_state = connector->state;
 
-	ret = drm_atomic_commit(state);
+	if (nonblock)
+		ret = drm_atomic_nonblocking_commit(state);
+	else
+		ret = drm_atomic_commit(state);
+
 	if (plane_mask)
 		drm_atomic_clean_old_fb(dev, plane_mask, ret);
 
@@ -3044,7 +3058,7 @@ int drm_atomic_helper_resume(struct drm_device *dev,
 		if (err)
 			goto out;
 
-		err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
+		err = drm_atomic_helper_commit_duplicated_state(state, &ctx, false);
 out:
 		if (err != -EDEADLK)
 			break;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cdb2e25a577c..74a86500378e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3650,7 +3650,8 @@ static void skylake_disable_primary_plane(struct intel_plane *primary,
 static int
 __intel_display_resume(struct drm_device *dev,
 		       struct drm_atomic_state *state,
-		       struct drm_modeset_acquire_ctx *ctx)
+		       struct drm_modeset_acquire_ctx *ctx,
+		       bool nonblock)
 {
 	struct drm_crtc_state *crtc_state;
 	struct drm_crtc *crtc;
@@ -3680,7 +3681,10 @@ __intel_display_resume(struct drm_device *dev,
 	if (!HAS_GMCH_DISPLAY(to_i915(dev)))
 		to_intel_atomic_state(state)->skip_intermediate_wm = true;
 
-	ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
+	if (nonblock)
+		state->kernel_flip = 1;
+
+	ret = drm_atomic_helper_commit_duplicated_state(state, ctx, nonblock);
 
 	WARN_ON(ret == -EDEADLK);
 	return ret;
@@ -3769,7 +3773,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
 	/* reset doesn't touch the display */
 	if (!gpu_reset_clobbers_display(dev_priv)) {
 		/* for testing only restore the display */
-		ret = __intel_display_resume(dev, state, ctx);
+		ret = __intel_display_resume(dev, state, ctx, false);
 		if (ret)
 			DRM_ERROR("Restoring old state failed with %i\n", ret);
 	} else {
@@ -3788,7 +3792,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
 			dev_priv->display.hpd_irq_setup(dev_priv);
 		spin_unlock_irq(&dev_priv->irq_lock);
 
-		ret = __intel_display_resume(dev, state, ctx);
+		ret = __intel_display_resume(dev, state, ctx, false);
 		if (ret)
 			DRM_ERROR("Restoring old state failed with %i\n", ret);
 
@@ -10122,7 +10126,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 	if (!state)
 		return;
 
-	ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
+	ret = drm_atomic_helper_commit_duplicated_state(state, ctx, false);
 	if (ret)
 		DRM_DEBUG_KMS("Couldn't release load detect pipe: %i\n", ret);
 	drm_atomic_state_put(state);
@@ -15222,7 +15226,7 @@ void intel_display_resume(struct drm_device *dev)
 	}
 
 	if (!ret)
-		ret = __intel_display_resume(dev, state, &ctx);
+		ret = __intel_display_resume(dev, state, &ctx, true);
 
 	intel_enable_ipc(dev_priv);
 	drm_modeset_drop_locks(&ctx);
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 5834580d75bc..d49427bce64f 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -210,6 +210,7 @@ struct __drm_private_objs_state {
  * @dev: parent DRM device
  * @allow_modeset: allow full modeset
  * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
+ * @kernel_flip: This is a kernel flip, userspace should stall rather than return -EBUSY.
  * @async_update: hint for asynchronous plane update
  * @planes: pointer to array of structures with per-plane data
  * @crtcs: pointer to array of CRTC pointers
@@ -225,6 +226,7 @@ struct drm_atomic_state {
 	struct drm_device *dev;
 	bool allow_modeset : 1;
 	bool legacy_cursor_update : 1;
+	bool kernel_flip : 1;
 	bool async_update : 1;
 	struct __drm_planes_state *planes;
 	struct __drm_crtcs_state *crtcs;
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index d2b56cc657e9..3236b2a3e816 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -120,7 +120,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 void drm_atomic_helper_shutdown(struct drm_device *dev);
 struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev);
 int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
-					      struct drm_modeset_acquire_ctx *ctx);
+					      struct drm_modeset_acquire_ctx *ctx,
+					      bool nonblock);
 int drm_atomic_helper_resume(struct drm_device *dev,
 			     struct drm_atomic_state *state);
 
-- 
2.14.1



More information about the Intel-gfx-trybot mailing list