drm/i915: Tighten reset_counter for reset status
In the reset_counter, we use two bits to track a GPU hang and reset. The low bit is a "reset-in-progress" flag that we set to signal when we need to break waiters in order for the recovery task to grab the mutex. As soon as the recovery task has the mutex, we can clear that flag (which we do by incrementing the reset_counter thereby incrementing the gobal reset epoch). By clearing that flag when the recovery task holds the struct_mutex, we can forgo a second flag that simply tells GEM to ignore the "reset-in-progress" flag. The second flag we store in the reset_counter is whether the reset failed and we consider the GPU terminally wedged. Whilst this flag is set, all access to the GPU (at least through GEM rather than direct mmio access) is verboten. PS: Fun is in store, as in the future we want to move from a global reset epoch to a per-engine reset engine with request recovery. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-6-git-send-email-chris@chris-wilson.co.uk
This commit is contained in:
@@ -83,9 +83,7 @@ i915_gem_wait_for_error(struct i915_gpu_error *error)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#define EXIT_COND (!i915_reset_in_progress_or_wedged(error) || \
|
||||
i915_terminally_wedged(error))
|
||||
if (EXIT_COND)
|
||||
if (!i915_reset_in_progress(error))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -94,17 +92,16 @@ 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,
|
||||
EXIT_COND,
|
||||
!i915_reset_in_progress(error),
|
||||
10*HZ);
|
||||
if (ret == 0) {
|
||||
DRM_ERROR("Timed out waiting for the gpu reset to complete\n");
|
||||
return -EIO;
|
||||
} else if (ret < 0) {
|
||||
return ret;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#undef EXIT_COND
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i915_mutex_lock_interruptible(struct drm_device *dev)
|
||||
@@ -1113,22 +1110,16 @@ i915_gem_check_wedge(struct i915_gpu_error *error,
|
||||
bool interruptible)
|
||||
{
|
||||
if (i915_reset_in_progress_or_wedged(error)) {
|
||||
/* Recovery complete, but the reset failed ... */
|
||||
if (i915_terminally_wedged(error))
|
||||
return -EIO;
|
||||
|
||||
/* Non-interruptible callers can't handle -EAGAIN, hence return
|
||||
* -EIO unconditionally for these. */
|
||||
if (!interruptible)
|
||||
return -EIO;
|
||||
|
||||
/* Recovery complete, but the reset failed ... */
|
||||
if (i915_terminally_wedged(error))
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
* Check if GPU Reset is in progress - we need intel_ring_begin
|
||||
* to work properly to reinit the hw state while the gpu is
|
||||
* still marked as reset-in-progress. Handle this with a flag.
|
||||
*/
|
||||
if (!error->reload_in_reset)
|
||||
return -EAGAIN;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user