forked from Minki/linux
drm/nouveau: Take fence spinlock before reading the last sequence.
It fixes a race between the TTM delayed work queue and the GEM IOCTLs (fdo bug 29583) uncovered by the BKL removal. Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
ab699ec64a
commit
3ba6462355
@ -64,16 +64,17 @@ nouveau_fence_update(struct nouveau_channel *chan)
|
|||||||
struct nouveau_fence *fence;
|
struct nouveau_fence *fence;
|
||||||
uint32_t sequence;
|
uint32_t sequence;
|
||||||
|
|
||||||
|
spin_lock(&chan->fence.lock);
|
||||||
|
|
||||||
if (USE_REFCNT)
|
if (USE_REFCNT)
|
||||||
sequence = nvchan_rd32(chan, 0x48);
|
sequence = nvchan_rd32(chan, 0x48);
|
||||||
else
|
else
|
||||||
sequence = atomic_read(&chan->fence.last_sequence_irq);
|
sequence = atomic_read(&chan->fence.last_sequence_irq);
|
||||||
|
|
||||||
if (chan->fence.sequence_ack == sequence)
|
if (chan->fence.sequence_ack == sequence)
|
||||||
return;
|
goto out;
|
||||||
chan->fence.sequence_ack = sequence;
|
chan->fence.sequence_ack = sequence;
|
||||||
|
|
||||||
spin_lock(&chan->fence.lock);
|
|
||||||
list_for_each_safe(entry, tmp, &chan->fence.pending) {
|
list_for_each_safe(entry, tmp, &chan->fence.pending) {
|
||||||
fence = list_entry(entry, struct nouveau_fence, entry);
|
fence = list_entry(entry, struct nouveau_fence, entry);
|
||||||
|
|
||||||
@ -85,6 +86,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
|
|||||||
if (sequence == chan->fence.sequence_ack)
|
if (sequence == chan->fence.sequence_ack)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
spin_unlock(&chan->fence.lock);
|
spin_unlock(&chan->fence.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user