diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-02-05 10:41:33 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-02-05 10:41:33 +0000 |
commit | ab39ffdd2c61271440ef8c0505b939d3fd220106 (patch) | |
tree | 3e3379da4a703f77b1d5a7239d6734e3bf50aa7d /sys | |
parent | 46352f6ed370520f74931ff1a9a5bbf0044d2568 (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.c | 45 |
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; } /** |