@@ -100,12 +100,31 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv,
spin_unlock(&dev_priv->mm.object_stat_lock);
}
+static bool i915_engine_reset_pending(struct i915_gpu_error *error,
+ struct intel_engine_cs *engine)
+{
+ int i;
+
+ if (engine)
+ return i915_engine_reset_in_progress(error, engine->id);
+
+ for (i = 0; i < I915_NUM_ENGINES; ++i) {
+ if (i915_engine_reset_in_progress(error, i))
+ return true;
+ }
+
+ return false;
+}
+
static int
i915_gem_wait_for_error(struct i915_gpu_error *error)
{
int ret;
- if (!i915_reset_in_progress(error))
+#define EXIT_COND (!i915_reset_in_progress(error) || \
+ !i915_engine_reset_pending(error, NULL))
+
+ if (EXIT_COND)
return 0;
/*
@@ -114,7 +133,7 @@ i915_gem_wait_for_error(struct i915_gpu_error *error)
* we should simply try to bail out and fail as gracefully as possible.
*/
ret = wait_event_interruptible_timeout(error->reset_queue,
- !i915_reset_in_progress(error),
+ EXIT_COND,
10*HZ);
if (ret == 0) {
DRM_ERROR("Timed out waiting for the gpu reset to complete\n");
@@ -1325,12 +1344,18 @@ put_rpm:
}
static int
-i915_gem_check_wedge(unsigned reset_counter, bool interruptible)
+i915_gem_check_wedge(struct drm_i915_private *dev_priv,
+ struct intel_engine_cs *engine,
+ bool interruptible)
{
+ struct i915_gpu_error *error = &dev_priv->gpu_error;
+ unsigned reset_counter = i915_reset_counter(error);
+
if (__i915_terminally_wedged(reset_counter))
return -EIO;
- if (__i915_reset_in_progress(reset_counter)) {
+ if (__i915_reset_in_progress(reset_counter) ||
+ i915_engine_reset_pending(error, engine)) {
/* Non-interruptible callers can't handle -EAGAIN, hence return
* -EIO unconditionally for these. */
if (!interruptible)
@@ -1500,6 +1525,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
for (;;) {
struct timer_list timer;
+ int reset_pending;
prepare_to_wait(&engine->irq_queue, &wait, state);
@@ -1515,6 +1541,13 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
break;
}
+ reset_pending = i915_engine_reset_pending(&dev_priv->gpu_error,
+ NULL);
+ if (reset_pending) {
+ ret = -EAGAIN;
+ break;
+ }
+
if (i915_gem_request_completed(req, false)) {
ret = 0;
break;
@@ -2997,7 +3030,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(dev_priv, NULL, dev_priv->mm.interruptible);
if (ret)
return ret;