diff options
author | Dave Airlie <airlied@redhat.com> | 2018-07-10 04:05:46 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-07-10 04:10:34 +0300 |
commit | 8038d2a9e6cde825be46359ad98a084da92294fe (patch) | |
tree | beb2c8b3a6bce8193f395ff50b221fad6ae2cd7b /drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | |
parent | ba7ca97d73b437eec883eba785495b8c9759b5f2 (diff) | |
parent | 812a954b787ab5a91d62e597a36351628b08d079 (diff) | |
download | linux-8038d2a9e6cde825be46359ad98a084da92294fe.tar.xz |
Merge tag 'vmwgfx-next-4.19-2' of git://people.freedesktop.org/~thomash/linux into drm-next
A series of cleanups / reorganizations and modesetting changes that
mostly target atomic state validation.
[airlied: conflicts with SPDX stuff in amdgpu tree]
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1a88485e-e509-b00e-8485-19194f074115@vmware.com
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_fence.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index c2eeb677cdfc..3d546d409334 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -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); |