aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-12-07 20:35:45 -0500
committerFrancisco Jerez <currojerez@riseup.net>2010-12-07 21:01:02 -0500
commit937c3471cc8b7ef8f9e382d9e4ec232db151ea7b (patch)
treec23158acf5103cab3306206fdb7839712e6201d9
parenta8b214f007e299225d3fcf10c46f7fc603c275fa (diff)
drm/nouveau: Avoid potential race between nouveau_fence_update() and context takedown.
Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 01290d2952a..374a9793b85 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -77,14 +77,17 @@ nouveau_fence_update(struct nouveau_channel *chan)
77 77
78 spin_lock(&chan->fence.lock); 78 spin_lock(&chan->fence.lock);
79 79
80 if (USE_REFCNT(dev)) 80 /* Fetch the last sequence if the channel is still up and running */
81 sequence = nvchan_rd32(chan, 0x48); 81 if (likely(!list_empty(&chan->fence.pending))) {
82 else 82 if (USE_REFCNT(dev))
83 sequence = atomic_read(&chan->fence.last_sequence_irq); 83 sequence = nvchan_rd32(chan, 0x48);
84 84 else
85 if (chan->fence.sequence_ack == sequence) 85 sequence = atomic_read(&chan->fence.last_sequence_irq);
86 goto out; 86
87 chan->fence.sequence_ack = sequence; 87 if (chan->fence.sequence_ack == sequence)
88 goto out;
89 chan->fence.sequence_ack = sequence;
90 }
88 91
89 list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) { 92 list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) {
90 sequence = fence->sequence; 93 sequence = fence->sequence;