drm/nouveau: base fence timeout on time of emission
authorMarcin Slusarz <marcin.slusarz@gmail.com>
Wed, 25 Apr 2012 21:20:33 +0000 (23:20 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 24 May 2012 06:31:59 +0000 (16:31 +1000)
Wait loop can be interrupted by signal, so if signals are raised
periodically (e.g. SIGALRM) this loop may never finish. Use
emission time as a base for fence timeout.

Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_fence.c

index cb19bf447952f26a6b6f357bd2c8d8c5ccc2bda5..ff5969d057ea0cc825368a1a0f3871a5127cd808 100644 (file)
@@ -44,6 +44,7 @@ struct nouveau_fence {
 
        uint32_t sequence;
        bool signalled;
+       unsigned long timeout;
 
        void (*work)(void *priv, bool signalled);
        void *priv;
@@ -172,6 +173,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
        }
        OUT_RING (chan, fence->sequence);
        FIRE_RING(chan);
+       fence->timeout = jiffies + 3 * DRM_HZ;
 
        return 0;
 }
@@ -230,7 +232,8 @@ __nouveau_fence_signalled(void *sync_obj, void *sync_arg)
 int
 __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
 {
-       unsigned long timeout = jiffies + (3 * DRM_HZ);
+       struct nouveau_fence *fence = nouveau_fence(sync_obj);
+       unsigned long timeout = fence->timeout;
        unsigned long sleep_time = NSEC_PER_MSEC / 1000;
        ktime_t t;
        int ret = 0;