[Intel-gfx] [PATCH] drm/i915: Fix __wait_seqno to use true infinite timeouts

Rodrigo Vivi rodrigo.vivi at gmail.com
Tue Aug 13 15:36:04 CEST 2013


applied to experimental drm-intel-collector.

drivers/gpu/drm/i915/i915_gem.c: In function ‘__wait_seqno’:
drivers/gpu/drm/i915/i915_gem.c:1033:20: warning: ‘timeout_jiffies’ may be used
+uninitialized in this function



On Tue, Aug 6, 2013 at 10:03 PM, Chris Wilson <chris at chris-wilson.co.uk> wrote:
> Rather than continue to fix up the timeouts to work around the interface
> impedence in wait_event_*(), open code the combination of
> wait_event[_interruptible][_timeout]. And note the code size reduction,
> and dare say readability?, in doing so..
>
> Food for thought.
> ---
>  drivers/gpu/drm/i915/i915_gem.c | 82 ++++++++++++++++++++---------------------
>  1 file changed, 39 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 99ba622..8adbce9 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1088,23 +1088,18 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
>                         bool interruptible, struct timespec *timeout)
>  {
>         drm_i915_private_t *dev_priv = ring->dev->dev_private;
> -       struct timespec before, now, wait_time={1,0};
> -       unsigned long timeout_jiffies;
> -       long end;
> -       bool wait_forever = true;
> +       struct timespec before, now;
> +       DEFINE_WAIT(__wait);
> +       long timeout_jiffies;
>         int ret;
>
>         if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
>                 return 0;
>
> -       trace_i915_gem_request_wait_begin(ring, seqno);
> -
> -       if (timeout != NULL) {
> -               wait_time = *timeout;
> -               wait_forever = false;
> -       }
> +       if (timeout)
> +               timeout_jiffies = timespec_to_jiffies_timeout(timeout);
>
> -       timeout_jiffies = timespec_to_jiffies_timeout(&wait_time);
> +       trace_i915_gem_request_wait_begin(ring, seqno);
>
>         if (WARN_ON(!ring->irq_get(ring)))
>                 return -ENODEV;
> @@ -1112,36 +1107,47 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
>         /* Record current time in case interrupted by signal, or wedged * */
>         getrawmonotonic(&before);
>
> -#define EXIT_COND \
> -       (i915_seqno_passed(ring->get_seqno(ring, false), seqno) || \
> -        i915_reset_in_progress(&dev_priv->gpu_error) || \
> -        reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
> -       do {
> -               if (interruptible)
> -                       end = wait_event_interruptible_timeout(ring->irq_queue,
> -                                                              EXIT_COND,
> -                                                              timeout_jiffies);
> -               else
> -                       end = wait_event_timeout(ring->irq_queue, EXIT_COND,
> -                                                timeout_jiffies);
> +       for (;;) {
> +               prepare_to_wait(&ring->irq_queue, &__wait,
> +                               interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
>
>                 /* We need to check whether any gpu reset happened in between
>                  * the caller grabbing the seqno and now ... */
> -               if (reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
> -                       end = -EAGAIN;
> +               if (reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) {
> +                       /* ... but upgrade the -EGAIN to an -EIO if the gpu
> +                        * is truely gone. */
> +                       ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
> +                       if (ret == 0)
> +                               ret = -EAGAIN;
> +                       break;
> +               }
>
> -               /* ... but upgrade the -EGAIN to an -EIO if the gpu is truely
> -                * gone. */
> -               ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
> -               if (ret)
> -                       end = ret;
> -       } while (end == 0 && wait_forever);
> +               if (i915_seqno_passed(ring->get_seqno(ring, false), seqno)) {
> +                       ret = 0;
> +                       break;
> +               }
> +
> +               if (interruptible && signal_pending(current)) {
> +                       ret = -ERESTARTSYS;
> +                       break;
> +               }
> +
> +               if (timeout) {
> +                       if (timeout_jiffies == 0) {
> +                               ret = -ETIME;
> +                               break;
> +                       }
> +
> +                       timeout_jiffies = schedule_timeout(timeout_jiffies);
> +               } else
> +                       schedule();
> +       }
> +       finish_wait(&ring->irq_queue, &__wait);
>
>         getrawmonotonic(&now);
>
>         ring->irq_put(ring);
>         trace_i915_gem_request_wait_end(ring, seqno);
> -#undef EXIT_COND
>
>         if (timeout) {
>                 struct timespec sleep_time = timespec_sub(now, before);
> @@ -1150,17 +1156,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
>                         set_normalized_timespec(timeout, 0, 0);
>         }
>
> -       switch (end) {
> -       case -EIO:
> -       case -EAGAIN: /* Wedged */
> -       case -ERESTARTSYS: /* Signal */
> -               return (int)end;
> -       case 0: /* Timeout */
> -               return -ETIME;
> -       default: /* Completed */
> -               WARN_ON(end < 0); /* We're not aware of other errors */
> -               return 0;
> -       }
> +       return ret;
>  }
>
>  /**
> --
> 1.8.4.rc1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br



More information about the Intel-gfx mailing list