diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-01-28 19:17:14 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-01-28 19:22:55 +0000 |
commit | 2425f03432de9bedeeda14ddbc5742cf7ce22874 (patch) | |
tree | b3da2357cc0f108ffc14658cf7d35a7a0c8efeb9 | |
parent | 8b0ebebcab21647348f769c25ca0c1d81d169e75 (diff) |
sna: Check for a hang after a spurious error return from set-domain-ioctl
set-domain-ioctl should only ever fail for invalid user input, beyond
the normal signal handling. As such if we do find a spurious error
return from the kernel, check for a GPU hang.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 2cf2c89a..0c3e0b08 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -5488,11 +5488,13 @@ void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo) set_domain.handle = bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; - if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) { - kgem_bo_retire(kgem, bo); - bo->domain = DOMAIN_GTT; - bo->gtt_dirty = true; + if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { + DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); + kgem_throttle(kgem); } + kgem_bo_retire(kgem, bo); + bo->domain = DOMAIN_GTT; + bo->gtt_dirty = true; } return ptr; @@ -5687,10 +5689,12 @@ void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo) set_domain.read_domains = I915_GEM_DOMAIN_CPU; set_domain.write_domain = I915_GEM_DOMAIN_CPU; - if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) { - kgem_bo_retire(kgem, bo); - bo->domain = DOMAIN_CPU; + if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { + DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); + kgem_throttle(kgem); } + kgem_bo_retire(kgem, bo); + bo->domain = DOMAIN_CPU; } } @@ -5723,14 +5727,16 @@ void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write) set_domain.read_domains = I915_GEM_DOMAIN_CPU; set_domain.write_domain = write ? I915_GEM_DOMAIN_CPU : 0; - if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) { - if (write) { - kgem_bo_retire(kgem, bo); - bo->domain = DOMAIN_CPU; - } else { - kgem_bo_maybe_retire(kgem, bo); - bo->domain = DOMAIN_NONE; - } + if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { + DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); + kgem_throttle(kgem); + } + if (write) { + kgem_bo_retire(kgem, bo); + bo->domain = DOMAIN_CPU; + } else { + kgem_bo_maybe_retire(kgem, bo); + bo->domain = DOMAIN_NONE; } } } @@ -5756,11 +5762,13 @@ void kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo) set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; - if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) { - kgem_bo_retire(kgem, bo); - bo->domain = DOMAIN_GTT; - bo->gtt_dirty = true; + if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { + DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); + kgem_throttle(kgem); } + kgem_bo_retire(kgem, bo); + bo->domain = DOMAIN_GTT; + bo->gtt_dirty = true; } } @@ -6566,9 +6574,10 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo) set_domain.read_domains = bo->mmapped == MMAPPED_CPU ? I915_GEM_DOMAIN_CPU : I915_GEM_DOMAIN_GTT; - if (do_ioctl(kgem->fd, - DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) - return; + if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { + DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); + kgem_throttle(kgem); + } } else { if (gem_read(kgem->fd, bo->base.handle, (char *)bo->mem+offset, |