drm/i915: Fix tiling corruption from pipelined fencing

... even though it was disabled. A mistake in the handling of fence reuse
caused us to skip the vital delay of waiting for the object to finish
rendering before changing the register. This resulted in us changing the
fence register whilst the bo was active and so causing the blits to
complete using the wrong stride or even the wrong tiling. (Visually the
effect is that small blocks of the screen look like they have been
interlaced). The fix is to wait for the GPU to finish using the memory
region pointed to by the fence before changing it.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34584
Cc: Andy Whitcroft <apw@canonical.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
[Note for 2.6.38-stable, we need to reintroduce the interruptible passing]
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Tested-by: Dave Airlie <airlied@linux.ie>

+17 -27
+17 -27
drivers/gpu/drm/i915/i915_gem.c
··· 2581 2581 reg = &dev_priv->fence_regs[obj->fence_reg]; 2582 2582 list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list); 2583 2583 2584 - if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) 2585 - pipelined = NULL; 2584 + if (obj->tiling_changed) { 2585 + ret = i915_gem_object_flush_fence(obj, pipelined); 2586 + if (ret) 2587 + return ret; 2588 + 2589 + if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) 2590 + pipelined = NULL; 2591 + 2592 + if (pipelined) { 2593 + reg->setup_seqno = 2594 + i915_gem_next_request_seqno(pipelined); 2595 + obj->last_fenced_seqno = reg->setup_seqno; 2596 + obj->last_fenced_ring = pipelined; 2597 + } 2598 + 2599 + goto update; 2600 + } 2586 2601 2587 2602 if (!pipelined) { 2588 2603 if (reg->setup_seqno) { ··· 2616 2601 ret = i915_gem_object_flush_fence(obj, pipelined); 2617 2602 if (ret) 2618 2603 return ret; 2619 - } else if (obj->tiling_changed) { 2620 - if (obj->fenced_gpu_access) { 2621 - if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { 2622 - ret = i915_gem_flush_ring(obj->ring, 2623 - 0, obj->base.write_domain); 2624 - if (ret) 2625 - return ret; 2626 - } 2627 - 2628 - obj->fenced_gpu_access = false; 2629 - } 2630 - } 2631 - 2632 - if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) 2633 - pipelined = NULL; 2634 - BUG_ON(!pipelined && reg->setup_seqno); 2635 - 2636 - if (obj->tiling_changed) { 2637 - if (pipelined) { 2638 - reg->setup_seqno = 2639 - i915_gem_next_request_seqno(pipelined); 2640 - obj->last_fenced_seqno = reg->setup_seqno; 2641 - obj->last_fenced_ring = pipelined; 2642 - } 2643 - goto update; 2644 2604 } 2645 2605 2646 2606 return 0;