[FOR_CI_v4 02/16] drm/i915/tdr: Separate reset bit encoding from reset counter

Arun Siluvery arun.siluvery at linux.intel.com
Tue Jul 5 15:34:06 UTC 2016


In preparation for engine reset feature, separate reset bit encoding from
the reset counter. We will need to check whether reset is in progress for
all engines going forward, we can extend current mechanism of encoding
reset_in_progress in reset_counter variable for all engines but this means
we will have to do multiple atomic_reads to determine reset_in_progress
status (N+1 reads). This can be simplified into a single atomic_read by
separting this into a different variable.

Signed-off-by: Arun Siluvery <arun.siluvery at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 14 +++++++-------
 drivers/gpu/drm/i915/i915_drv.h | 39 ++++++++++++++++++++++-----------------
 drivers/gpu/drm/i915/i915_gem.c | 12 ++++++------
 drivers/gpu/drm/i915/i915_irq.c |  2 +-
 4 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 694edac..d5245b8 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1611,7 +1611,7 @@ static int i915_drm_resume(struct drm_device *dev)
 	mutex_lock(&dev->struct_mutex);
 	if (i915_gem_init_hw(dev)) {
 		DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n");
-		atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
+		atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_flags);
 	}
 	mutex_unlock(&dev->struct_mutex);
 
@@ -1771,7 +1771,6 @@ int i915_reset(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = &dev_priv->drm;
 	struct i915_gpu_error *error = &dev_priv->gpu_error;
-	unsigned reset_counter;
 	int ret;
 
 	intel_reset_gt_powersave(dev_priv);
@@ -1779,11 +1778,12 @@ int i915_reset(struct drm_i915_private *dev_priv)
 	mutex_lock(&dev->struct_mutex);
 
 	/* Clear any previous failed attempts at recovery. Time to try again. */
-	atomic_andnot(I915_WEDGED, &error->reset_counter);
+	atomic_andnot(I915_WEDGED, &error->reset_flags);
 
-	/* Clear the reset-in-progress flag and increment the reset epoch. */
-	reset_counter = atomic_inc_return(&error->reset_counter);
-	if (WARN_ON(__i915_reset_in_progress(reset_counter))) {
+	/* Clear the reset-in-progress flag */
+	atomic_andnot(I915_RESET_IN_PROGRESS_FLAG, &error->reset_flags);
+
+	if (WARN_ON(i915_reset_in_progress(error))) {
 		ret = -EIO;
 		goto error;
 	}
@@ -1837,7 +1837,7 @@ int i915_reset(struct drm_i915_private *dev_priv)
 	return 0;
 
 error:
-	atomic_or(I915_WEDGED, &error->reset_counter);
+	atomic_or(I915_WEDGED, &error->reset_flags);
 	mutex_unlock(&dev->struct_mutex);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c269e0a..ef0ecd6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1372,17 +1372,22 @@ struct i915_gpu_error {
 	unsigned long missed_irq_rings;
 
 	/**
-	 * State variable controlling the reset flow and count
+	 * Reset flags indicating reset in progress status
 	 *
-	 * This is a counter which gets incremented when reset is triggered,
-	 * and again when reset has been handled. So odd values (lowest bit set)
-	 * means that reset is in progress and even values that
-	 * (reset_counter >> 1):th reset was successfully completed.
+	 * It is a mask indicating reset pending status of all engines as
+	 * well as full gpu reset. A bit corresponding to engine id is set
+	 * if reset for that particular engine is in progress. Bit0 is
+	 * reserved for full gpu reset.
 	 *
 	 * If reset is not completed succesfully, the I915_WEDGE bit is
 	 * set meaning that hardware is terminally sour and there is no
 	 * recovery. All waiters on the reset_queue will be woken when
 	 * that happens.
+	 */
+	atomic_t reset_flags;
+
+	/**
+	 * This is a counter that keeps track of full gpu resets.
 	 *
 	 * This counter is used by the wait_seqno code to notice that reset
 	 * event happened and it needs to restart the entire ioctl (since most
@@ -1392,7 +1397,7 @@ struct i915_gpu_error {
 	 * naturally enforces the correct ordering between the bail-out of the
 	 * waiter and the gpu reset work code.
 	 */
-	atomic_t reset_counter;
+	atomic_t global_reset_counter;
 
 #define I915_RESET_IN_PROGRESS_FLAG	1
 #define I915_WEDGED			(1 << 31)
@@ -3321,42 +3326,42 @@ void i915_gem_retire_requests_ring(struct intel_engine_cs *engine);
 
 static inline u32 i915_reset_counter(struct i915_gpu_error *error)
 {
-	return atomic_read(&error->reset_counter);
+	return atomic_read(&error->global_reset_counter);
 }
 
-static inline bool __i915_reset_in_progress(u32 reset)
+static inline bool __i915_reset_in_progress(u32 reset_flags)
 {
-	return unlikely(reset & I915_RESET_IN_PROGRESS_FLAG);
+	return unlikely(reset_flags & I915_RESET_IN_PROGRESS_FLAG);
 }
 
-static inline bool __i915_reset_in_progress_or_wedged(u32 reset)
+static inline bool __i915_reset_in_progress_or_wedged(u32 reset_flags)
 {
-	return unlikely(reset & (I915_RESET_IN_PROGRESS_FLAG | I915_WEDGED));
+	return unlikely(reset_flags & (I915_RESET_IN_PROGRESS_FLAG | I915_WEDGED));
 }
 
-static inline bool __i915_terminally_wedged(u32 reset)
+static inline bool __i915_terminally_wedged(u32 reset_flags)
 {
-	return unlikely(reset & I915_WEDGED);
+	return unlikely(reset_flags & I915_WEDGED);
 }
 
 static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
 {
-	return __i915_reset_in_progress(i915_reset_counter(error));
+	return __i915_reset_in_progress(atomic_read(&error->reset_flags));
 }
 
 static inline bool i915_reset_in_progress_or_wedged(struct i915_gpu_error *error)
 {
-	return __i915_reset_in_progress_or_wedged(i915_reset_counter(error));
+	return __i915_reset_in_progress_or_wedged(atomic_read(&error->reset_flags));
 }
 
 static inline bool i915_terminally_wedged(struct i915_gpu_error *error)
 {
-	return __i915_terminally_wedged(i915_reset_counter(error));
+	return __i915_terminally_wedged(atomic_read(&error->reset_flags));
 }
 
 static inline u32 i915_reset_count(struct i915_gpu_error *error)
 {
-	return ((i915_reset_counter(error) & ~I915_WEDGED) + 1) / 2;
+	return i915_reset_counter(error);
 }
 
 void i915_gem_reset(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8f50919..e7a4562 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1326,12 +1326,12 @@ put_rpm:
 }
 
 static int
-i915_gem_check_wedge(unsigned reset_counter, bool interruptible)
+i915_gem_check_wedge(unsigned reset_flags, bool interruptible)
 {
-	if (__i915_terminally_wedged(reset_counter))
+	if (__i915_terminally_wedged(reset_flags))
 		return -EIO;
 
-	if (__i915_reset_in_progress(reset_counter)) {
+	if (__i915_reset_in_progress(reset_flags)) {
 		/* Non-interruptible callers can't handle -EAGAIN, hence return
 		 * -EIO unconditionally for these. */
 		if (!interruptible)
@@ -3000,7 +3000,7 @@ __i915_gem_request_alloc(struct intel_engine_cs *engine,
 			 struct drm_i915_gem_request **req_out)
 {
 	struct drm_i915_private *dev_priv = engine->i915;
-	unsigned reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+	unsigned reset_flags = i915_reset_in_progress(&dev_priv->gpu_error);
 	struct drm_i915_gem_request *req;
 	int ret;
 
@@ -3013,7 +3013,7 @@ __i915_gem_request_alloc(struct intel_engine_cs *engine,
 	 * EIO if the GPU is already wedged, or EAGAIN to drop the struct_mutex
 	 * and restart.
 	 */
-	ret = i915_gem_check_wedge(reset_counter, dev_priv->mm.interruptible);
+	ret = i915_gem_check_wedge(reset_flags, dev_priv->mm.interruptible);
 	if (ret)
 		return ret;
 
@@ -5221,7 +5221,7 @@ int i915_gem_init(struct drm_device *dev)
 		 * for all other failure, such as an allocation failure, bail.
 		 */
 		DRM_ERROR("Failed to initialize GPU, declaring it wedged\n");
-		atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
+		atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_flags);
 		ret = 0;
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b77d808..39002be 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2675,7 +2675,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
 
 	if (engine_mask) {
 		atomic_or(I915_RESET_IN_PROGRESS_FLAG,
-				&dev_priv->gpu_error.reset_counter);
+			  &dev_priv->gpu_error.reset_flags);
 
 		/*
 		 * Wakeup waiting processes so that the reset function
-- 
1.9.1



More information about the Intel-gfx-trybot mailing list