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))