summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-01-28 19:17:14 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2014-01-28 19:22:55 +0000
commit2425f03432de9bedeeda14ddbc5742cf7ce22874 (patch)
treeb3da2357cc0f108ffc14658cf7d35a7a0c8efeb9
parent8b0ebebcab21647348f769c25ca0c1d81d169e75 (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.c53
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,