diff options
author | Francisco Jerez <currojerez@riseup.net> | 2010-12-07 20:35:45 -0500 |
---|---|---|
committer | Francisco Jerez <currojerez@riseup.net> | 2010-12-07 21:01:02 -0500 |
commit | 937c3471cc8b7ef8f9e382d9e4ec232db151ea7b (patch) | |
tree | c23158acf5103cab3306206fdb7839712e6201d9 | |
parent | a8b214f007e299225d3fcf10c46f7fc603c275fa (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.c | 19 |
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; |