Module Name: src
Committed By: riastradh
Date: Sun May 19 13:28:28 UTC 2024
Modified Files:
src/sys/external/bsd/drm2/ttm: ttm_bo_vm.c
Log Message:
ttm: Sync ttm_bo_uvm_fault_idle better with Linux.
PR xsrc/58133
To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/sys/external/bsd/drm2/ttm/ttm_bo_vm.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/ttm/ttm_bo_vm.c
diff -u src/sys/external/bsd/drm2/ttm/ttm_bo_vm.c:1.22 src/sys/external/bsd/drm2/ttm/ttm_bo_vm.c:1.23
--- src/sys/external/bsd/drm2/ttm/ttm_bo_vm.c:1.22 Thu Jul 21 08:07:56 2022
+++ src/sys/external/bsd/drm2/ttm/ttm_bo_vm.c Sun May 19 13:28:28 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ttm_bo_vm.c,v 1.22 2022/07/21 08:07:56 riastradh Exp $ */
+/* $NetBSD: ttm_bo_vm.c,v 1.23 2024/05/19 13:28:28 riastradh Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ttm_bo_vm.c,v 1.22 2022/07/21 08:07:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ttm_bo_vm.c,v 1.23 2024/05/19 13:28:28 riastradh Exp $");
#include <sys/types.h>
@@ -44,8 +44,6 @@ __KERNEL_RCSID(0, "$NetBSD: ttm_bo_vm.c,
#include <ttm/ttm_bo_driver.h>
-static int ttm_bo_uvm_fault_idle(struct ttm_buffer_object *,
- struct uvm_faultinfo *);
static int ttm_bo_uvm_lookup(struct ttm_bo_device *, unsigned long,
unsigned long, struct ttm_buffer_object **);
@@ -134,10 +132,7 @@ ttm_bo_uvm_fault(struct uvm_faultinfo *u
ret = ttm_bo_uvm_fault_idle(bo, ufi);
if (ret) {
KASSERT(ret == -ERESTART || ret == -EFAULT);
- /* ttm_bo_uvm_fault_idle calls uvmfault_unlockall for us. */
- ttm_bo_unreserve(bo);
- /* XXX errno Linux->NetBSD */
- return -ret;
+ goto out1;
}
ret = ttm_mem_io_lock(man, true);
@@ -221,24 +216,49 @@ out0: uvmfault_unlockall(ufi, ufi->entry
static int
ttm_bo_uvm_fault_idle(struct ttm_buffer_object *bo, struct uvm_faultinfo *ufi)
{
- int ret = 0;
+ int err, ret = 0;
if (__predict_true(!bo->moving))
- goto out0;
+ goto out_unlock;
+ /*
+ * Quick non-stalling check for idle.
+ */
if (dma_fence_is_signaled(bo->moving))
- goto out1;
+ goto out_clear;
- if (dma_fence_wait(bo->moving, true) != 0) {
- ret = -EFAULT;
- goto out2;
+ /*
+ * If possible, avoid waiting for GPU with mmap_sem
+ * held.
+ * XXX Need to integrate this properly into caller's
+ * error branches so it doesn't uvmfault_unlockall twice.
+ */
+ if (0) {
+ ret = -ERESTART;
+
+ ttm_bo_get(bo);
+ uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, NULL);
+ (void) dma_fence_wait(bo->moving, true);
+ dma_resv_unlock(bo->base.resv);
+ ttm_bo_put(bo);
+ goto out_unlock;
+ }
+
+ /*
+ * Ordinary wait.
+ */
+ err = dma_fence_wait(bo->moving, true);
+ if (__predict_false(ret != 0)) {
+ ret = (err != -ERESTARTSYS) ? -EFAULT : -ERESTART;
+ goto out_unlock;
}
- ret = -ERESTART;
-out2: uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, NULL);
-out1: dma_fence_put(bo->moving);
+out_clear:
+ dma_fence_put(bo->moving);
bo->moving = NULL;
-out0: return ret;
+
+out_unlock:
+ return ret;
}
int