If we enter i915_handle_error() a second time and a global reset is
already in progress, we can simply wait for completion of the first
reset. Currently we exit earlier prior to the actual reset being
performed -- the worst of both worlds!

Signed-off-by: Chris Wilson <[email protected]>
Cc: Mika Kuoppala <[email protected]>
Cc: Michel Thierry <[email protected]>
---
 drivers/gpu/drm/i915/i915_irq.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4cd9ee1ba332..906128e8c350 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2600,13 +2600,13 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 }
 
 /**
- * i915_reset_and_wakeup - do process context error handling work
+ * i915_global_reset - do process context error handling work
  * @dev_priv: i915 device private
  *
  * Fire an error uevent so userspace can see that a hang or error
  * was detected.
  */
-static void i915_reset_and_wakeup(struct drm_i915_private *dev_priv)
+static void i915_global_reset(struct drm_i915_private *dev_priv)
 {
        struct kobject *kobj = &dev_priv->drm.primary->kdev->kobj;
        char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
@@ -2646,13 +2646,6 @@ static void i915_reset_and_wakeup(struct 
drm_i915_private *dev_priv)
        if (!test_bit(I915_WEDGED, &dev_priv->gpu_error.flags))
                kobject_uevent_env(kobj,
                                   KOBJ_CHANGE, reset_done_event);
-
-       /*
-        * Note: The wake_up also serves as a memory barrier so that
-        * waiters see the updated value of the dev_priv->gpu_error.
-        */
-       clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags);
-       wake_up_all(&dev_priv->gpu_error.reset_queue);
 }
 
 static inline void
@@ -2745,11 +2738,19 @@ void i915_handle_error(struct drm_i915_private 
*dev_priv,
                goto out;
 
        if (test_and_set_bit(I915_RESET_BACKOFF,
-                            &dev_priv->gpu_error.flags))
+                            &dev_priv->gpu_error.flags)) {
+               wait_on_bit(&dev_priv->gpu_error.flags,
+                           I915_RESET_BACKOFF,
+                           TASK_UNINTERRUPTIBLE);
                goto out;
+       }
+
+       i915_global_reset(dev_priv);
 
-       i915_reset_and_wakeup(dev_priv);
+       clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags);
+       wake_up_bit(&dev_priv->gpu_error.flags, I915_RESET_BACKOFF);
 
+       wake_up_all(&dev_priv->gpu_error.reset_queue);
 out:
        intel_runtime_pm_put(dev_priv);
 }
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to