drm/nouveau: Avoid potential race between nouveau_fence_update() and context takedown.
authorFrancisco Jerez <currojerez@riseup.net>
Wed, 8 Dec 2010 01:35:45 +0000 (02:35 +0100)
committerFrancisco Jerez <currojerez@riseup.net>
Wed, 8 Dec 2010 02:01:02 +0000 (03:01 +0100)
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_fence.c

index 01290d2952ae52c9868a2d73cbc189c716f6993d..374a9793b85f99607bad72d97751b92f381a6711 100644 (file)
@@ -77,14 +77,17 @@ nouveau_fence_update(struct nouveau_channel *chan)
 
        spin_lock(&chan->fence.lock);
 
-       if (USE_REFCNT(dev))
-               sequence = nvchan_rd32(chan, 0x48);
-       else
-               sequence = atomic_read(&chan->fence.last_sequence_irq);
-
-       if (chan->fence.sequence_ack == sequence)
-               goto out;
-       chan->fence.sequence_ack = sequence;
+       /* Fetch the last sequence if the channel is still up and running */
+       if (likely(!list_empty(&chan->fence.pending))) {
+               if (USE_REFCNT(dev))
+                       sequence = nvchan_rd32(chan, 0x48);
+               else
+                       sequence = atomic_read(&chan->fence.last_sequence_irq);
+
+               if (chan->fence.sequence_ack == sequence)
+                       goto out;
+               chan->fence.sequence_ack = sequence;
+       }
 
        list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) {
                sequence = fence->sequence;