[intel-gem] Use polling in i915_gem_idle instead of interrupts.
While waiting for the hardware to idle on leavevt or lastclose, poll for the sync sequence number instead of waiting for an interrupt. This allows the code to bail if the hardware hangs for some reason. Also, this avoids issues with signals as the exisiting wait function is interruptible.main
parent
71b1623e22
commit
54817317e9
|
@ -2139,8 +2139,9 @@ static int
|
||||||
i915_gem_idle(struct drm_device *dev)
|
i915_gem_idle(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
uint32_t seqno;
|
uint32_t seqno, cur_seqno, last_seqno;
|
||||||
int ret;
|
int ret;
|
||||||
|
int stuck;
|
||||||
|
|
||||||
if (dev_priv->mm.suspended)
|
if (dev_priv->mm.suspended)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2161,11 +2162,26 @@ i915_gem_idle(struct drm_device *dev)
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
ret = i915_wait_request(dev, seqno);
|
|
||||||
if (ret) {
|
dev_priv->mm.waiting_gem_seqno = seqno;
|
||||||
mutex_unlock(&dev->struct_mutex);
|
last_seqno = 0;
|
||||||
return ret;
|
stuck = 0;
|
||||||
|
for (;;) {
|
||||||
|
cur_seqno = i915_get_gem_seqno(dev);
|
||||||
|
if (i915_seqno_passed(cur_seqno, seqno))
|
||||||
|
break;
|
||||||
|
if (last_seqno == cur_seqno) {
|
||||||
|
if (stuck++ > 100) {
|
||||||
|
DRM_ERROR("hardware wedged\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msleep(10);
|
||||||
|
last_seqno = cur_seqno;
|
||||||
}
|
}
|
||||||
|
dev_priv->mm.waiting_gem_seqno = 0;
|
||||||
|
|
||||||
|
i915_gem_retire_requests(dev);
|
||||||
|
|
||||||
/* Active and flushing should now be empty as we've
|
/* Active and flushing should now be empty as we've
|
||||||
* waited for a sequence higher than any pending execbuffer
|
* waited for a sequence higher than any pending execbuffer
|
||||||
|
@ -2521,14 +2537,17 @@ void
|
||||||
i915_gem_lastclose(struct drm_device *dev)
|
i915_gem_lastclose(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
|
|
||||||
ret = i915_gem_idle(dev);
|
if (dev_priv->ring.ring_obj != NULL) {
|
||||||
if (ret)
|
ret = i915_gem_idle(dev);
|
||||||
DRM_ERROR("failed to idle hardware: %d\n", ret);
|
if (ret)
|
||||||
|
DRM_ERROR("failed to idle hardware: %d\n", ret);
|
||||||
i915_gem_cleanup_ringbuffer(dev);
|
|
||||||
|
i915_gem_cleanup_ringbuffer(dev);
|
||||||
|
}
|
||||||
|
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue