From 4f0f871730b76730ca58209181d16725b0c40184 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 10 Feb 2010 09:45:13 +0000 Subject: intel: Handle resetting of input params after EINTR during SET_TILING The SET_TILING is pernicious in that it overwrites the input arguments following an error in order to report the current tiling state of the buffer. This caught us by surprise as we then fed those arguments back into to the ioctl unmodified following an EINTR and so the kernel then reported success for the no-op. We interpreted this success as meaning that the tiling on the buffer had changed so updated our state and started using the buffer incorrectly in the new tiled/untiled manner. This lead to all sorts of random corruption and GPU hangs, even though the batch buffers would look sane (when the GPU had not wandered off into forbidden territory). References: Bug 25475 - [i915] Xorg crash / Execbuf while wedged http://bugs.freedesktop.org/show_bug.cgi?id=25475 Bug 25554 - i830_uxa_prepare_access: gtt bo map failed: Input/output error http://bugs.freedesktop.org/show_bug.cgi?id=25554 (And probably every other weird bug in the last few months.) Signed-off-by: Chris Wilson --- intel/intel_bufmgr_gem.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index 66d12bce..4e61cefe 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -1423,18 +1423,15 @@ drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode, memset(&set_tiling, 0, sizeof(set_tiling)); set_tiling.handle = bo_gem->gem_handle; - set_tiling.tiling_mode = *tiling_mode; - set_tiling.stride = stride; do { + set_tiling.tiling_mode = *tiling_mode; + set_tiling.stride = stride; + ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling); } while (ret == -1 && errno == EINTR); - if (ret != 0) { - *tiling_mode = bo_gem->tiling_mode; - return -errno; - } bo_gem->tiling_mode = set_tiling.tiling_mode; bo_gem->swizzle_mode = set_tiling.swizzle_mode; @@ -1445,7 +1442,7 @@ drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode, drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem); *tiling_mode = bo_gem->tiling_mode; - return 0; + return ret == 0 ? 0 : -errno; } static int -- cgit v1.2.3