summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2020-12-31 06:31:56 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2020-12-31 06:31:56 +0000
commitff5cd0529ace405899f12fcf895255845f11f5c8 (patch)
tree60de405d7c96616eb1047f4993fd563eecdbec71 /sys/dev
parent1d9f56388b1edf3101b0dbbe427ac33f003f7466 (diff)
don't oversleep when waiting on fences
original diff from and ok cheloha@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/drm/drm_linux.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c
index 32f6db5ff4d..d01db47d517 100644
--- a/sys/dev/pci/drm/drm_linux.c
+++ b/sys/dev/pci/drm/drm_linux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_linux.c,v 1.73 2020/12/13 04:00:38 jsg Exp $ */
+/* $OpenBSD: drm_linux.c,v 1.74 2020/12/31 06:31:55 jsg Exp $ */
/*
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
* Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
@@ -1325,10 +1325,13 @@ long
dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
{
long ret = timeout ? timeout : 1;
+ unsigned long end;
int err;
struct default_wait_cb cb;
bool was_set;
+ KASSERT(timeout <= INT_MAX);
+
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return ret;
@@ -1356,15 +1359,15 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
cb.proc = curproc;
list_add(&cb.base.node, &fence->cb_list);
- while (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
- err = msleep(curproc, fence->lock, intr ? PCATCH : 0, "dmafence",
- timeout);
+ end = jiffies + timeout;
+ for (ret = timeout; ret > 0; ret = MAX(0, end - jiffies)) {
+ if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
+ break;
+ err = msleep(curproc, fence->lock, intr ? PCATCH : 0,
+ "dmafence", ret);
if (err == EINTR || err == ERESTART) {
ret = -ERESTARTSYS;
break;
- } else if (err == EWOULDBLOCK) {
- ret = 0;
- break;
}
}
@@ -1398,8 +1401,11 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
bool intr, long timeout, uint32_t *idx)
{
struct default_wait_cb *cb;
+ long ret = timeout;
+ unsigned long end;
int i, err;
- int ret = timeout;
+
+ KASSERT(timeout <= INT_MAX);
if (timeout == 0) {
for (i = 0; i < count; i++) {
@@ -1427,18 +1433,14 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
}
}
- while (ret > 0) {
+ end = jiffies + timeout;
+ for (ret = timeout; ret > 0; ret = MAX(0, end - jiffies)) {
if (dma_fence_test_signaled_any(fences, count, idx))
break;
-
- err = tsleep(curproc, intr ? PCATCH : 0,
- "dfwat", timeout);
+ err = tsleep(curproc, intr ? PCATCH : 0, "dfwat", ret);
if (err == EINTR || err == ERESTART) {
ret = -ERESTARTSYS;
break;
- } else if (err == EWOULDBLOCK) {
- ret = 0;
- break;
}
}