Module Name: src Committed By: riastradh Date: Tue Oct 25 23:34:06 UTC 2022
Modified Files: src/sys/external/bsd/drm2/dist/drm/vmwgfx: vmwgfx_drv.c vmwgfx_drv.h vmwgfx_execbuf.c vmwgfx_fence.c vmwgfx_fifo.c vmwgfx_irq.c Log Message: vmwgfx(4): Convert fence_queue and fifo_queue to drm_waitqueue_t. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c cvs rdiff -u -r1.6 -r1.7 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h cvs rdiff -u -r1.3 -r1.4 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_execbuf.c \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fence.c \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fifo.c \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c:1.5 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c:1.6 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c:1.5 Thu Feb 17 01:21:02 2022 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c Tue Oct 25 23:34:05 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_drv.c,v 1.5 2022/02/17 01:21:02 riastradh Exp $ */ +/* $NetBSD: vmwgfx_drv.c,v 1.6 2022/10/25 23:34:05 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,7 +28,7 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_drv.c,v 1.5 2022/02/17 01:21:02 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_drv.c,v 1.6 2022/10/25 23:34:05 riastradh Exp $"); #include <linux/console.h> #include <linux/dma-mapping.h> @@ -655,8 +655,10 @@ static int vmw_driver_load(struct drm_de INIT_LIST_HEAD(&dev_priv->res_lru[i]); } - init_waitqueue_head(&dev_priv->fence_queue); - init_waitqueue_head(&dev_priv->fifo_queue); + DRM_INIT_WAITQUEUE(&dev_priv->fence_queue, "vmwgfence"); + spin_lock_init(&dev_priv->fence_lock); + DRM_INIT_WAITQUEUE(&dev_priv->fifo_queue, "vmwgfifo"); + spin_lock_init(&dev_priv->fifo_lock); dev_priv->fence_queue_waiters = 0; dev_priv->fifo_queue_waiters = 0; @@ -963,6 +965,11 @@ out_no_device: out_err4: memunmap(dev_priv->mmio_virt); out_err0: + spin_lock_destroy(&dev_priv->fifo_lock); + DRM_DESTROY_WAITQUEUE(&dev_priv->fifo_queue); + spin_lock_destroy(&dev_priv->fence_lock); + DRM_DESTROY_WAITQUEUE(&dev_priv->fence_queue); + for (i = vmw_res_context; i < vmw_res_max; ++i) idr_destroy(&dev_priv->res_idr[i]); @@ -1015,6 +1022,11 @@ static void vmw_driver_unload(struct drm if (dev_priv->ctx.staged_bindings) vmw_binding_state_free(dev_priv->ctx.staged_bindings); + spin_lock_destroy(&dev_priv->fifo_lock); + DRM_DESTROY_WAITQUEUE(&dev_priv->fifo_queue); + spin_lock_destroy(&dev_priv->fence_lock); + DRM_DESTROY_WAITQUEUE(&dev_priv->fence_queue); + for (i = vmw_res_context; i < vmw_res_max; ++i) idr_destroy(&dev_priv->res_idr[i]); Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.6 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.7 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.6 Thu Feb 17 01:21:02 2022 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h Tue Oct 25 23:34:05 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_drv.h,v 1.6 2022/02/17 01:21:02 riastradh Exp $ */ +/* $NetBSD: vmwgfx_drv.h,v 1.7 2022/10/25 23:34:05 riastradh Exp $ */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /************************************************************************** @@ -538,7 +538,9 @@ struct vmw_private { atomic_t marker_seq; drm_waitqueue_t fence_queue; + spinlock_t fence_lock; drm_waitqueue_t fifo_queue; + spinlock_t fifo_lock; spinlock_t waiter_lock; int fence_queue_waiters; /* Protected by waiter_lock */ int goal_queue_waiters; /* Protected by waiter_lock */ Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_execbuf.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_execbuf.c:1.3 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_execbuf.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_execbuf.c:1.3 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_execbuf.c Tue Oct 25 23:34:05 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_execbuf.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_execbuf.c,v 1.4 2022/10/25 23:34:05 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -27,7 +27,7 @@ * **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_execbuf.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_execbuf.c,v 1.4 2022/10/25 23:34:05 riastradh Exp $"); #include <linux/sync_file.h> @@ -3447,8 +3447,10 @@ vmw_execbuf_copy_fence_user(struct vmw_p fence_rep.handle = fence_handle; fence_rep.seqno = fence->base.seqno; + spin_lock(&dev_priv->fence_lock); vmw_update_seqno(dev_priv, &dev_priv->fifo); fence_rep.passed_seqno = dev_priv->last_read_seqno; + spin_unlock(&dev_priv->fence_lock); } /* Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fence.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fence.c:1.3 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fence.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fence.c:1.3 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fence.c Tue Oct 25 23:34:05 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_fence.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_fence.c,v 1.4 2022/10/25 23:34:05 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,12 +28,14 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_fence.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_fence.c,v 1.4 2022/10/25 23:34:05 riastradh Exp $"); #include <linux/sched/signal.h> #include "vmwgfx_drv.h" +#include <linux/nbsd-namespace.h> + #define VMW_FENCE_WRAP (1 << 31) struct vmw_fence_manager { @@ -158,7 +160,11 @@ static bool vmw_fence_enable_signaling(s struct vmwgfx_wait_cb { struct dma_fence_cb base; +#ifdef __NetBSD__ + drm_waitqueue_t wq; +#else struct task_struct *task; +#endif }; static void @@ -167,7 +173,11 @@ vmwgfx_wait_cb(struct dma_fence *fence, struct vmwgfx_wait_cb *wait = container_of(cb, struct vmwgfx_wait_cb, base); +#ifdef __NetBSD__ + DRM_SPIN_WAKEUP_ALL(&wait->wq, fence->lock); +#else wake_up_process(wait->task); +#endif } static void __vmw_fences_update(struct vmw_fence_manager *fman); @@ -198,10 +208,26 @@ static long vmw_fence_wait(struct dma_fe goto out; } - cb.base.func = vmwgfx_wait_cb; +#ifdef __NetBSD__ + DRM_INIT_WAITQUEUE(&cb.wq, "vmwgfxwf"); +#else cb.task = current; - list_add(&cb.base.node, &f->cb_list); +#endif + spin_unlock(f->lock); + ret = dma_fence_add_callback(f, &cb.base, vmwgfx_wait_cb); + spin_lock(f->lock); + if (ret) + goto out; +#ifdef __NetBSD__ +#define C (__vmw_fences_update(fman), dma_fence_is_signaled_locked(f)) + if (intr) { + DRM_SPIN_TIMED_WAIT_UNTIL(ret, &cb.wq, f->lock, timeout, C); + } else { + DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, &cb.wq, f->lock, timeout, + C); + } +#else for (;;) { __vmw_fences_update(fman); @@ -238,9 +264,16 @@ static long vmw_fence_wait(struct dma_fe __set_current_state(TASK_RUNNING); if (!list_empty(&cb.base.node)) list_del(&cb.base.node); +#endif + spin_unlock(f->lock); + dma_fence_remove_callback(f, &cb.base); + spin_lock(f->lock); out: spin_unlock(f->lock); +#ifdef __NetBSD__ + DRM_DESTROY_WAITQUEUE(&cb.wq); +#endif vmw_seqno_waiter_remove(dev_priv); @@ -878,8 +911,11 @@ int vmw_fence_obj_signaled_ioctl(struct arg->signaled = vmw_fence_obj_signaled(fence); arg->signaled_flags = arg->flags; + spin_lock(&dev_priv->fence_lock); + const u32 seqno = dev_priv->last_read_seqno; + spin_unlock(&dev_priv->fence_lock); spin_lock(&fman->lock); - arg->passed_seqno = dev_priv->last_read_seqno; + arg->passed_seqno = seqno; spin_unlock(&fman->lock); ttm_base_object_unref(&base); Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fifo.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fifo.c:1.3 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fifo.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fifo.c:1.3 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fifo.c Tue Oct 25 23:34:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_fifo.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_fifo.c,v 1.4 2022/10/25 23:34:06 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,7 +28,7 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_fifo.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_fifo.c,v 1.4 2022/10/25 23:34:06 riastradh Exp $"); #include <linux/sched/signal.h> @@ -36,6 +36,8 @@ __KERNEL_RCSID(0, "$NetBSD: vmwgfx_fifo. #include "vmwgfx_drv.h" +#include <linux/nbsd-namespace.h> + struct vmw_temp_set_context { SVGA3dCmdHeader header; SVGA3dCmdDXTempSetContext body; @@ -227,14 +229,20 @@ static int vmw_fifo_wait_noirq(struct vm { int ret = 0; unsigned long end_jiffies = jiffies + timeout; +#ifdef __NetBSD__ + assert_spin_locked(&dev_priv->fifo_lock); +#else DEFINE_WAIT(__wait); +#endif DRM_INFO("Fifo wait noirq.\n"); for (;;) { +#ifndef __NetBSD__ prepare_to_wait(&dev_priv->fifo_queue, &__wait, (interruptible) ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); +#endif if (!vmw_fifo_is_full(dev_priv, bytes)) break; if (time_after_eq(jiffies, end_jiffies)) { @@ -242,14 +250,40 @@ static int vmw_fifo_wait_noirq(struct vm DRM_ERROR("SVGA device lockup.\n"); break; } +#ifdef __NetBSD__ + if (interruptible) { + DRM_SPIN_TIMED_WAIT_UNTIL(ret, &dev_priv->fifo_queue, + &dev_priv->fifo_lock, 1, + !vmw_fifo_is_full(dev_priv, bytes)); + } else { + DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, + &dev_priv->fifo_queue, + &dev_priv->fifo_lock, 1, + !vmw_fifo_is_full(dev_priv, bytes)); + } + if (ret) { + if (ret > 0) /* success */ + ret = 0; + break; + } + /* + * ret=0 means the wait timed out after one tick, so + * try again + */ +#else schedule_timeout(1); if (interruptible && signal_pending(current)) { ret = -ERESTARTSYS; break; } +#endif } +#ifdef __NetBSD__ + DRM_SPIN_WAKEUP_ALL(&dev_priv->fifo_queue, &dev_priv->fifo_lock); +#else finish_wait(&dev_priv->fifo_queue, &__wait); wake_up_all(&dev_priv->fifo_queue); +#endif DRM_INFO("Fifo noirq exit.\n"); return ret; } @@ -260,25 +294,32 @@ static int vmw_fifo_wait(struct vmw_priv { long ret = 1L; - if (likely(!vmw_fifo_is_full(dev_priv, bytes))) + spin_lock(&dev_priv->fifo_lock); + + if (likely(!vmw_fifo_is_full(dev_priv, bytes))) { + spin_unlock(&dev_priv->fifo_lock); return 0; + } vmw_fifo_ping_host(dev_priv, SVGA_SYNC_FIFOFULL); - if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) - return vmw_fifo_wait_noirq(dev_priv, bytes, + if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) { + ret = vmw_fifo_wait_noirq(dev_priv, bytes, interruptible, timeout); + spin_unlock(&dev_priv->fifo_lock); + return ret; + } vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_FIFO_PROGRESS, &dev_priv->fifo_queue_waiters); if (interruptible) - ret = wait_event_interruptible_timeout - (dev_priv->fifo_queue, - !vmw_fifo_is_full(dev_priv, bytes), timeout); + DRM_SPIN_TIMED_WAIT_UNTIL(ret, &dev_priv->fifo_queue, + &dev_priv->fifo_lock, timeout, + !vmw_fifo_is_full(dev_priv, bytes)); else - ret = wait_event_timeout - (dev_priv->fifo_queue, - !vmw_fifo_is_full(dev_priv, bytes), timeout); + DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, &dev_priv->fifo_queue, + &dev_priv->fifo_lock, timeout, + !vmw_fifo_is_full(dev_priv, bytes)); if (unlikely(ret == 0)) ret = -EBUSY; @@ -288,6 +329,8 @@ static int vmw_fifo_wait(struct vmw_priv vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_FIFO_PROGRESS, &dev_priv->fifo_queue_waiters); + spin_unlock(&dev_priv->fifo_lock); + return ret; } @@ -576,7 +619,9 @@ int vmw_fifo_send_fence(struct vmw_priva cmd_fence->fence = *seqno; vmw_fifo_commit_flush(dev_priv, bytes); (void) vmw_marker_push(&fifo_state->marker_queue, *seqno); + spin_lock(&dev_priv->fence_lock); vmw_update_seqno(dev_priv, fifo_state); + spin_unlock(&dev_priv->fence_lock); out_err: return ret; Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c:1.3 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c:1.3 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c Tue Oct 25 23:34:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_irq.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_irq.c,v 1.4 2022/10/25 23:34:06 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,7 +28,7 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_irq.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_irq.c,v 1.4 2022/10/25 23:34:06 riastradh Exp $"); #include <linux/sched/signal.h> @@ -55,8 +55,11 @@ static irqreturn_t vmw_thread_fn(int irq if (test_and_clear_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending)) { + spin_lock(&dev_priv->fence_lock); vmw_fences_update(dev_priv->fman); - wake_up_all(&dev_priv->fence_queue); + DRM_SPIN_WAKEUP_ALL(&dev_priv->fence_queue, + &dev_priv->fence_lock); + spin_unlock(&dev_priv->fence_lock); ret = IRQ_HANDLED; } @@ -96,8 +99,12 @@ static irqreturn_t vmw_irq_handler(int i if (!status) return IRQ_NONE; - if (masked_status & SVGA_IRQFLAG_FIFO_PROGRESS) - wake_up_all(&dev_priv->fifo_queue); + if (masked_status & SVGA_IRQFLAG_FIFO_PROGRESS) { + spin_lock(&dev_priv->fifo_lock); + DRM_SPIN_WAKEUP_ALL(&dev_priv->fifo_queue, + &dev_priv->fifo_lock); + spin_unlock(&dev_priv->fifo_lock); + } if ((masked_status & (SVGA_IRQFLAG_ANY_FENCE | SVGA_IRQFLAG_FENCE_GOAL)) && @@ -125,6 +132,8 @@ void vmw_update_seqno(struct vmw_private u32 *fifo_mem = dev_priv->mmio_virt; uint32_t seqno = vmw_mmio_read(fifo_mem + SVGA_FIFO_FENCE); + assert_spin_locked(&dev_priv->fence_lock); + if (dev_priv->last_read_seqno != seqno) { dev_priv->last_read_seqno = seqno; vmw_marker_pull(&fifo_state->marker_queue, seqno); @@ -138,6 +147,8 @@ bool vmw_seqno_passed(struct vmw_private struct vmw_fifo_state *fifo_state; bool ret; + assert_spin_locked(&dev_priv->fence_lock); + if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP)) return true; @@ -175,7 +186,9 @@ int vmw_fallback_wait(struct vmw_private int ret; unsigned long end_jiffies = jiffies + timeout; bool (*wait_condition)(struct vmw_private *, uint32_t); +#ifndef __NetBSD__ DEFINE_WAIT(__wait); +#endif wait_condition = (fifo_idle) ? &vmw_fifo_idle : &vmw_seqno_passed; @@ -194,10 +207,40 @@ int vmw_fallback_wait(struct vmw_private } } + spin_lock(&dev_priv->fence_lock); + signal_seq = atomic_read(&dev_priv->marker_seq); ret = 0; for (;;) { +#ifdef __NetBSD__ + if (!lazy) { + if (wait_condition(dev_priv, seqno)) + break; + spin_unlock(&dev_priv->fence_lock); + if ((++count & 0xf) == 0) + yield(); + spin_lock(&dev_priv->fence_lock); + } else if (interruptible) { + DRM_SPIN_TIMED_WAIT_UNTIL(ret, &dev_priv->fence_queue, + &dev_priv->fence_lock, /*timeout*/1, + wait_condition(dev_priv, seqno)); + } else { + DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, + &dev_priv->fence_queue, + &dev_priv->fence_lock, /*timeout*/1, + wait_condition(dev_priv, seqno)); + } + if (ret) { /* success or error but not timeout */ + if (ret > 0) /* success */ + ret = 0; + break; + } + if (time_after_eq(jiffies, end_jiffies)) { + DRM_ERROR("SVGA device lockup.\n"); + break; + } +#else prepare_to_wait(&dev_priv->fence_queue, &__wait, (interruptible) ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); @@ -225,14 +268,22 @@ int vmw_fallback_wait(struct vmw_private ret = -ERESTARTSYS; break; } +#endif } +#ifndef __NetBSD__ finish_wait(&dev_priv->fence_queue, &__wait); +#endif if (ret == 0 && fifo_idle) { u32 *fifo_mem = dev_priv->mmio_virt; vmw_mmio_write(signal_seq, fifo_mem + SVGA_FIFO_FENCE); } +#ifdef __NetBSD__ + DRM_SPIN_WAKEUP_ALL(&dev_priv->fence_queue, &dev_priv->fence_lock); + spin_unlock(&dev_priv->fence_lock); +#else wake_up_all(&dev_priv->fence_queue); +#endif out_err: if (fifo_idle) up_read(&fifo_state->rwsem); @@ -294,37 +345,46 @@ int vmw_wait_seqno(struct vmw_private *d long ret; struct vmw_fifo_state *fifo = &dev_priv->fifo; - if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP)) + spin_lock(&dev_priv->fence_lock); + if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP)) { + spin_unlock(&dev_priv->fence_lock); return 0; + } - if (likely(vmw_seqno_passed(dev_priv, seqno))) + if (likely(vmw_seqno_passed(dev_priv, seqno))) { + spin_unlock(&dev_priv->fence_lock); return 0; + } vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); - if (!(fifo->capabilities & SVGA_FIFO_CAP_FENCE)) + if (!(fifo->capabilities & SVGA_FIFO_CAP_FENCE)) { + spin_unlock(&dev_priv->fence_lock); return vmw_fallback_wait(dev_priv, lazy, true, seqno, interruptible, timeout); + } - if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) + if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) { + spin_unlock(&dev_priv->fence_lock); return vmw_fallback_wait(dev_priv, lazy, false, seqno, interruptible, timeout); + } vmw_seqno_waiter_add(dev_priv); if (interruptible) - ret = wait_event_interruptible_timeout - (dev_priv->fence_queue, - vmw_seqno_passed(dev_priv, seqno), - timeout); + DRM_SPIN_TIMED_WAIT_UNTIL(ret, &dev_priv->fence_queue, + &dev_priv->fence_lock, timeout, + vmw_seqno_passed(dev_priv, seqno)); else - ret = wait_event_timeout - (dev_priv->fence_queue, - vmw_seqno_passed(dev_priv, seqno), - timeout); + DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, &dev_priv->fence_queue, + &dev_priv->fence_lock, timeout, + vmw_seqno_passed(dev_priv, seqno)); vmw_seqno_waiter_remove(dev_priv); + spin_unlock(&dev_priv->fence_lock); + if (unlikely(ret == 0)) ret = -EBUSY; else if (likely(ret > 0))