summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-02-05 10:41:33 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-02-05 10:41:33 +0000
commitab39ffdd2c61271440ef8c0505b939d3fd220106 (patch)
tree3e3379da4a703f77b1d5a7239d6734e3bf50aa7d /sys
parent46352f6ed370520f74931ff1a9a5bbf0044d2568 (diff)
Do proper error handling in the fault handler. Fixes spurious SIGSEGVs as
seen with the new xf86-video-intel 2.99.909 on some hardware. The problem was probably masked bu the holding logic that was removed in rev 1.67. tested by tedu@, matthieu@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/drm/i915/i915_gem.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/sys/dev/pci/drm/i915/i915_gem.c b/sys/dev/pci/drm/i915/i915_gem.c
index 5610817caca..6ec39493257 100644
--- a/sys/dev/pci/drm/i915/i915_gem.c
+++ b/sys/dev/pci/drm/i915/i915_gem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_gem.c,v 1.68 2014/02/02 10:54:10 kettenis Exp $ */
+/* $OpenBSD: i915_gem.c,v 1.69 2014/02/05 10:41:32 kettenis Exp $ */
/*
* Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org>
*
@@ -1522,6 +1522,7 @@ i915_gem_fault(struct drm_gem_object *gem_obj, struct uvm_faultinfo *ufi,
NULL, NULL);
DRM_UNLOCK();
dev_priv->entries--;
+ pmap_update(ufi->orig_map->pmap);
uvm_wait("intelflt");
return (VM_PAGER_REFAULT);
}
@@ -1533,18 +1534,42 @@ unlock:
DRM_UNLOCK();
dev_priv->entries--;
pmap_update(ufi->orig_map->pmap);
- if (ret == -EIO) {
+
+ switch (ret) {
+ case -EIO:
+ /* If this -EIO is due to a gpu hang, give the reset code a
+ * chance to clean up the mess. Otherwise return the proper
+ * SIGBUS. */
+ if (!atomic_read(&dev_priv->mm.wedged))
+ return VM_PAGER_ERROR;
+ case -EAGAIN:
+ /* Give the error handler a chance to run and move the
+ * objects off the GPU active list. Next time we service the
+ * fault, we should be able to transition the page into the
+ * GTT without touching the GPU (and so avoid further
+ * EIO/EGAIN). If the GPU is wedged, then there is no issue
+ * with coherency, just lost writes.
+ */
+#if 0
+ set_need_resched();
+#endif
+ case 0:
+ case -ERESTART:
+ case -EINTR:
+ case -EBUSY:
/*
- * EIO means we're wedged, so upon resetting the gpu we'll
- * be alright and can refault. XXX only on resettable chips.
+ * EBUSY is ok: this just means that another thread
+ * already did the job.
*/
- ret = VM_PAGER_REFAULT;
- } else if (ret) {
- ret = VM_PAGER_ERROR;
- } else {
- ret = VM_PAGER_OK;
+ return VM_PAGER_OK;
+ case -ENOMEM:
+ return VM_PAGER_ERROR;
+ case -ENOSPC:
+ return VM_PAGER_ERROR;
+ default:
+ WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret);
+ return VM_PAGER_ERROR;
}
- return ret;
}
/**