Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/drm2/dist/drm Touch up drm_syncobj.c.
details: https://anonhg.NetBSD.org/src/rev/46ff1a85e779
branches: trunk
changeset: 1028331:46ff1a85e779
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Dec 19 10:39:14 2021 +0000
description:
Touch up drm_syncobj.c.
diffstat:
sys/external/bsd/drm2/dist/drm/drm_syncobj.c | 120 ++++++++++++++++++++------
1 files changed, 91 insertions(+), 29 deletions(-)
diffs (254 lines):
diff -r e455eeb8009d -r 46ff1a85e779 sys/external/bsd/drm2/dist/drm/drm_syncobj.c
--- a/sys/external/bsd/drm2/dist/drm/drm_syncobj.c Sun Dec 19 10:39:06 2021 +0000
+++ b/sys/external/bsd/drm2/dist/drm/drm_syncobj.c Sun Dec 19 10:39:14 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_syncobj.c,v 1.3 2021/12/19 01:16:13 riastradh Exp $ */
+/* $NetBSD: drm_syncobj.c,v 1.4 2021/12/19 10:39:14 riastradh Exp $ */
/*
* Copyright 2017 Red Hat
@@ -125,7 +125,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_syncobj.c,v 1.3 2021/12/19 01:16:13 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_syncobj.c,v 1.4 2021/12/19 10:39:14 riastradh Exp $");
#include <linux/anon_inodes.h>
#include <linux/file.h>
@@ -147,8 +147,20 @@
struct syncobj_wait_entry {
struct list_head node;
#ifdef __NetBSD__
+ /*
+ * Lock order:
+ * syncobj->lock ???? fence lock
+ * syncobj->lock then wait->lock
+ * fence lock then wait->lock
+ *
+ * syncobj->lock serializes wait->node and wait->fence.
+ * wait->lock serializes wait->signalledp, and, by
+ * interlocking with syncobj->lock, coordinates wakeups on
+ * wait->cv for wait->fence.
+ */
kmutex_t *lock;
kcondvar_t *cv;
+ bool *signalledp;
#else
struct task_struct *task;
#endif
@@ -157,6 +169,32 @@
u64 point;
};
+#ifdef __NetBSD__
+static int
+cv_wait_timeout_sig(kcondvar_t *cv, kmutex_t *lock, long *timeoutp)
+{
+ unsigned long ticks = *timeoutp;
+ unsigned starttime, endtime;
+ int error;
+
+ starttime = hardclock_ticks;
+ error = cv_timedwait_sig(cv, lock, MIN(ticks, INT_MAX));
+ endtime = hardclock_ticks;
+
+ if (error == EINTR || error == ERESTART) {
+ return ERESTARTSYS;
+ } else {
+ KASSERTMSG(error == 0 || error == EWOULDBLOCK,
+ "error=%d", error);
+ if (endtime - starttime < ticks)
+ *timeoutp = ticks - (endtime - starttime);
+ else
+ *timeoutp = 0;
+ return 0;
+ }
+}
+#endif
+
static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
struct syncobj_wait_entry *wait);
@@ -352,12 +390,25 @@
return ret;
memset(&wait, 0, sizeof(wait));
+#ifdef __NetBSD__
+ kmutex_t lock;
+ kcondvar_t cv;
+ mutex_init(&lock, MUTEX_DEFAULT, IPL_VM);
+ cv_init(&cv, "drmfnfnc");
+ wait.cv = &cv;
+#else
wait.task = current;
wait.point = point;
+#endif
drm_syncobj_fence_add_wait(syncobj, &wait);
+#ifdef __NetBSD__
+ spin_lock(&syncobj->lock);
+#endif
do {
+#ifndef __NetBSD__
set_current_state(TASK_INTERRUPTIBLE);
+#endif
if (wait.fence) {
ret = 0;
break;
@@ -367,15 +418,32 @@
break;
}
+#ifdef __NetBSD__
+ mutex_enter(&lock);
+ spin_unlock(&syncobj->lock);
+ /* XXX errno NetBSD->Linux */
+ ret = -cv_wait_timeout_sig(&cv, &lock, &timeout);
+ mutex_exit(&lock);
+ spin_lock(&syncobj->lock);
+ if (ret)
+ break;
+#else
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
timeout = schedule_timeout(timeout);
+#endif
} while (1);
+#ifdef __NetBSD__
+ spin_unlock(&syncobj->lock);
+ cv_destroy(&cv);
+ mutex_destroy(&lock);
+#else
__set_current_state(TASK_RUNNING);
+#endif
*fence = wait.fence;
if (wait.node.next)
@@ -611,16 +679,14 @@
return -EINVAL;
#ifdef __NetBSD__
- if (file->f_ops != &drm_syncobj_file_ops) {
- fd_putfile(fd);
- return -EINVAL;
- }
+ if (f.file->f_ops != &drm_syncobj_file_ops)
#else
- if (f.file->f_op != &drm_syncobj_file_fops) {
+ if (f.file->f_op != &drm_syncobj_file_fops)
+#endif
+ {
fdput(f);
return -EINVAL;
}
-#endif
/* take a reference to put in the idr */
#ifdef __NetBSD__
@@ -642,11 +708,7 @@
} else
drm_syncobj_put(syncobj);
-#ifdef __NetBSD__
- fd_putfile(fd);
-#else
fdput(f);
-#endif
return ret;
}
@@ -688,7 +750,7 @@
goto out;
/* Find the fence. */
- ret = drm_syncobj_find_fence(file_private, handle, &fence);
+ ret = drm_syncobj_find_fence(file_private, handle, 0, 0, &fence);
if (ret)
goto out;
@@ -951,6 +1013,7 @@
#ifdef __NetBSD__
mutex_enter(wait->lock);
+ *wait->signalledp = true;
cv_broadcast(wait->cv);
mutex_exit(wait->lock);
#else
@@ -970,7 +1033,9 @@
if (!fence || dma_fence_chain_find_seqno(&fence, wait->point)) {
dma_fence_put(fence);
return;
- } else if (!fence) {
+ }
+
+ if (!fence) {
wait->fence = dma_fence_get_stub();
} else {
wait->fence = fence;
@@ -1001,6 +1066,8 @@
#ifdef __NetBSD__
kmutex_t lock;
kcondvar_t cv;
+ bool signalled = false;
+ int ret;
mutex_init(&lock, MUTEX_DEFAULT, IPL_VM);
cv_init(&cv, "drmsynco");
#endif
@@ -1030,11 +1097,10 @@
*/
signaled_count = 0;
for (i = 0; i < count; ++i) {
- struct dma_fence *fence;
-
#ifdef __NetBSD__
entries[i].lock = &lock;
entries[i].cv = &cv;
+ entries[i].signalledp = &signalled;
#else
entries[i].task = current;
#endif
@@ -1117,21 +1183,15 @@
}
#ifdef __NetBSD__
- unsigned long ticks = ret;
- unsigned starttime = hardclock_ticks;
mutex_enter(&lock);
- ret = -cv_timedwait_sig(&cv, &lock, MIN(ticks, INT_MAX));
+ if (signalled)
+ ret = 0;
+ else
+ ret = -cv_wait_timeout_sig(&cv, &lock, &timeout);
mutex_exit(&lock);
- unsigned endtime = hardclock_ticks;
- if (ret == -EINTR || ret == -ERESTART) {
- ret = -ERESTARTSYS;
- } else if (ret == -EWOULDBLOCK) {
- if (endtime - starttime < ticks)
- ret = ticks - (endtime - starttime);
- else
- ret = 0;
- } else {
- KASSERTMSG(ret == 0, "%ld", ret);
+ if (ret) {
+ timeout = -ERESTARTSYS;
+ goto done_waiting;
}
#else
if (signal_pending(current)) {
@@ -1160,8 +1220,10 @@
err_free_points:
kfree(points);
+#ifdef __NetBSD__
cv_destroy(&cv);
mutex_destroy(&lock);
+#endif
return timeout;
}
Home |
Main Index |
Thread Index |
Old Index