Insert a wait parameter in the code so we can possibly timeout on a seqno wait if need be. The code should be functionally the same as before because all the callers will continue to retry if an arbitrary timeout elapses. Signed-off-by: Ben Widawsky <benjamin.widawsky at intel.com> --- drivers/gpu/drm/i915/i915_gem.c | 41 ++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 920dbc1..7bfad04 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1847,25 +1847,36 @@ i915_gem_retire_work_handler(struct work_struct *work) mutex_unlock(&dev->struct_mutex); } +#define SEQNO_WAIT_DEFAULT (3000000UL) static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, - bool interruptible) + bool interruptible, long *usecs) { drm_i915_private_t *dev_priv = ring->dev->dev_private; - int ret = 0; + const long timeout = usecs_to_jiffies(*usecs); + long end; #define EXIT_COND \ (i915_seqno_passed(ring->get_seqno(ring), seqno) || \ atomic_read(&dev_priv->mm.wedged)) if (interruptible) - ret = wait_event_interruptible(ring->irq_queue, - EXIT_COND); + end = wait_event_interruptible_timeout(ring->irq_queue, + EXIT_COND, + timeout); else - wait_event(ring->irq_queue, EXIT_COND); - + end = wait_event_timeout(ring->irq_queue, EXIT_COND, timeout); #undef EXIT_COND - return ret; + switch (end) { + case 0: /* Tiemout */ + return -ETIME; + case -ERESTARTSYS: /* Signal */ + return -ERESTARTSYS; + default: /* Completed */ + BUG_ON(end < 0); /* We're not aware of other errors */ + *usecs = jiffies_to_usecs(timeout - end); + return 0; + } } /** @@ -1916,7 +1927,12 @@ i915_wait_request(struct intel_ring_buffer *ring, if (WARN_ON(!ring->irq_get(ring))) return -EBUSY; - ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible); + do { + long time = SEQNO_WAIT_DEFAULT; + ret = __wait_seqno(ring, seqno, + dev_priv->mm.interruptible, + &time); + } while (ret == -ETIME); ring->irq_put(ring); trace_i915_gem_request_wait_end(ring, seqno); @@ -3012,13 +3028,16 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) * lockless. */ if (ring->irq_get(ring)) { - ret = __wait_seqno(ring, seqno, true); + do { + long time = SEQNO_WAIT_DEFAULT; + ret = __wait_seqno(ring, seqno, true, &time); + } while (ret == -ETIME); ring->irq_put(ring); - if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) ret = -EIO; - } else + } else { ret = -EBUSY; + } } if (ret == 0) -- 1.7.10