aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index de45b60516e6..3b9d18b9e92e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2662,17 +2662,35 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
2662 return fence - dev_priv->fence_regs; 2662 return fence - dev_priv->fence_regs;
2663} 2663}
2664 2664
2665static void i915_gem_write_fence__ipi(void *data)
2666{
2667 wbinvd();
2668}
2669
2665static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, 2670static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
2666 struct drm_i915_fence_reg *fence, 2671 struct drm_i915_fence_reg *fence,
2667 bool enable) 2672 bool enable)
2668{ 2673{
2669 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 2674 struct drm_device *dev = obj->base.dev;
2670 int reg = fence_number(dev_priv, fence); 2675 struct drm_i915_private *dev_priv = dev->dev_private;
2671 2676 int fence_reg = fence_number(dev_priv, fence);
2672 i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); 2677
2678 /* In order to fully serialize access to the fenced region and
2679 * the update to the fence register we need to take extreme
2680 * measures on SNB+. In theory, the write to the fence register
2681 * flushes all memory transactions before, and coupled with the
2682 * mb() placed around the register write we serialise all memory
2683 * operations with respect to the changes in the tiler. Yet, on
2684 * SNB+ we need to take a step further and emit an explicit wbinvd()
2685 * on each processor in order to manually flush all memory
2686 * transactions before updating the fence register.
2687 */
2688 if (HAS_LLC(obj->base.dev))
2689 on_each_cpu(i915_gem_write_fence__ipi, NULL, 1);
2690 i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL);
2673 2691
2674 if (enable) { 2692 if (enable) {
2675 obj->fence_reg = reg; 2693 obj->fence_reg = fence_reg;
2676 fence->obj = obj; 2694 fence->obj = obj;
2677 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); 2695 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
2678 } else { 2696 } else {