Commit 14dba717 authored by Thomas Hellstrom's avatar Thomas Hellstrom

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: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarBrian Paul <brianp@vmware.com>
Reviewed-by: default avatarDeepak Rawat <drawat@vmware.com>
parent 3fbeccf8
......@@ -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);
ret = schedule_timeout(ret);
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags)) {
if (ret == 0 && timeout > 0)
ret = 1;
break;
}
spin_lock_irqsave(f->lock, irq_flags);
if (ret > 0 && intr && signal_pending(current))
if (intr && signal_pending(current)) {
ret = -ERESTARTSYS;
}
break;
}
if (ret == 0)
break;
spin_unlock(f->lock);
ret = schedule_timeout(ret);
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment