Commit 63256ec5 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Enforce write ordering through the GTT

We need to ensure that writes through the GTT land before any
modification to the MMIO registers and so must impose a mandatory write
barrier when flushing the GTT domain. This was revealed by relaxing the
write ordering by experimentally mapping the registers and the GATT as
write-combining.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 75901072
...@@ -2393,6 +2393,12 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, ...@@ -2393,6 +2393,12 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj,
obj->last_fenced_ring = NULL; obj->last_fenced_ring = NULL;
} }
/* Ensure that all CPU reads are completed before installing a fence
* and all writes before removing the fence.
*/
if (obj->base.read_domains & I915_GEM_DOMAIN_GTT)
mb();
return 0; return 0;
} }
...@@ -2833,10 +2839,16 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) ...@@ -2833,10 +2839,16 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj)
if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) if (obj->base.write_domain != I915_GEM_DOMAIN_GTT)
return; return;
/* No actual flushing is required for the GTT write domain. Writes /* No actual flushing is required for the GTT write domain. Writes
* to it immediately go to main memory as far as we know, so there's * to it immediately go to main memory as far as we know, so there's
* no chipset flush. It also doesn't land in render cache. * no chipset flush. It also doesn't land in render cache.
*
* However, we do have to enforce the order so that all writes through
* the GTT land before any writes to the device, such as updates to
* the GATT itself.
*/ */
wmb();
i915_gem_release_mmap(obj); i915_gem_release_mmap(obj);
old_write_domain = obj->base.write_domain; old_write_domain = obj->base.write_domain;
......
...@@ -725,6 +725,9 @@ i915_gem_execbuffer_flush(struct drm_device *dev, ...@@ -725,6 +725,9 @@ i915_gem_execbuffer_flush(struct drm_device *dev,
if (flush_domains & I915_GEM_DOMAIN_CPU) if (flush_domains & I915_GEM_DOMAIN_CPU)
intel_gtt_chipset_flush(); intel_gtt_chipset_flush();
if (flush_domains & I915_GEM_DOMAIN_GTT)
wmb();
if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) {
for (i = 0; i < I915_NUM_RINGS; i++) for (i = 0; i < I915_NUM_RINGS; i++)
if (flush_rings & (1 << i)) if (flush_rings & (1 << i))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment