mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-20 07:18:35 +07:00
drm/vmwgfx: Reorganize the fence wait loop
Reorganize the fence wait loop somewhat to make it look more like the examples in set_current_state() kerneldoc, and add some code comments. Also if we're about to time out, make sure we check again whether the fence is actually signaled. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Deepak Rawat <drawat@vmware.com>
This commit is contained in:
parent
3fbeccf8ce
commit
14dba71784
@ -175,7 +175,6 @@ static long vmw_fence_wait(struct dma_fence *f, bool intr, signed long timeout)
|
||||
struct vmw_private *dev_priv = fman->dev_priv;
|
||||
struct vmwgfx_wait_cb cb;
|
||||
long ret = timeout;
|
||||
unsigned long irq_flags;
|
||||
|
||||
if (likely(vmw_fence_obj_signaled(fence)))
|
||||
return timeout;
|
||||
@ -183,7 +182,7 @@ static long vmw_fence_wait(struct dma_fence *f, bool intr, signed long timeout)
|
||||
vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
|
||||
vmw_seqno_waiter_add(dev_priv);
|
||||
|
||||
spin_lock_irqsave(f->lock, irq_flags);
|
||||
spin_lock(f->lock);
|
||||
|
||||
if (intr && signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
@ -194,30 +193,45 @@ static long vmw_fence_wait(struct dma_fence *f, bool intr, signed long timeout)
|
||||
cb.task = current;
|
||||
list_add(&cb.base.node, &f->cb_list);
|
||||
|
||||
while (ret > 0) {
|
||||
for (;;) {
|
||||
__vmw_fences_update(fman);
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags))
|
||||
break;
|
||||
|
||||
/*
|
||||
* We can use the barrier free __set_current_state() since
|
||||
* DMA_FENCE_FLAG_SIGNALED_BIT + wakeup is protected by the
|
||||
* fence spinlock.
|
||||
*/
|
||||
if (intr)
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
else
|
||||
__set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
spin_unlock_irqrestore(f->lock, irq_flags);
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags)) {
|
||||
if (ret == 0 && timeout > 0)
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (intr && signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
break;
|
||||
|
||||
spin_unlock(f->lock);
|
||||
|
||||
ret = schedule_timeout(ret);
|
||||
|
||||
spin_lock_irqsave(f->lock, irq_flags);
|
||||
if (ret > 0 && intr && signal_pending(current))
|
||||
ret = -ERESTARTSYS;
|
||||
spin_lock(f->lock);
|
||||
}
|
||||
|
||||
__set_current_state(TASK_RUNNING);
|
||||
if (!list_empty(&cb.base.node))
|
||||
list_del(&cb.base.node);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(f->lock, irq_flags);
|
||||
spin_unlock(f->lock);
|
||||
|
||||
vmw_seqno_waiter_remove(dev_priv);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user