diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-07-10 08:36:24 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-07-10 09:31:12 -0400 |
commit | 46a0b638f35b45fc13d3dc0deb6a7e17988170b2 (patch) | |
tree | b9adaa3d3246579aa8fd4b1d0638145bbddc3afc | |
parent | d18b9619034230b6f945e215276425636ca401fe (diff) |
Revert "drm/i915: Workaround incoherence between fences and LLC across multiple CPUs"
This reverts commit 25ff119 and the follow on for Valleyview commit 2dc8aae.
commit 25ff1195f8a0b3724541ae7bbe331b4296de9c06
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Thu Apr 4 21:31:03 2013 +0100
drm/i915: Workaround incoherence between fences and LLC across multiple CPUs
commit 2dc8aae06d53458dd3624dc0accd4f81100ee631
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Wed May 22 17:08:06 2013 +0100
drm/i915: Workaround incoherence with fence updates on Valleyview
Jon Bloomfield came up with a plausible explanation and cheap fix
(drm/i915: Fix incoherence with fence updates on Sandybridge+) for the
race condition, so lets run with it.
This is a candidate for stable as the old workaround incurs a
significant cost (calling wbinvd on all CPUs before performing the
register write) for some workloads as noted by Carsten Emde.
Link: http://lists.freedesktop.org/archives/intel-gfx/2013-June/028819.html
References: https://www.osadl.org/?id=1543#c7602
References: https://bugs.freedesktop.org/show_bug.cgi?id=63825
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Carsten Emde <C.Emde@osadl.org>
Cc: stable@vger.kernel.org
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 47 |
1 files changed, 4 insertions, 43 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a34e8e2ba98a..06d66e09da17 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2829,56 +2829,17 @@ static inline int fence_number(struct drm_i915_private *dev_priv, | |||
2829 | return fence - dev_priv->fence_regs; | 2829 | return fence - dev_priv->fence_regs; |
2830 | } | 2830 | } |
2831 | 2831 | ||
2832 | struct write_fence { | ||
2833 | struct drm_device *dev; | ||
2834 | struct drm_i915_gem_object *obj; | ||
2835 | int fence; | ||
2836 | }; | ||
2837 | |||
2838 | static void i915_gem_write_fence__ipi(void *data) | ||
2839 | { | ||
2840 | struct write_fence *args = data; | ||
2841 | |||
2842 | /* Required for SNB+ with LLC */ | ||
2843 | wbinvd(); | ||
2844 | |||
2845 | /* Required for VLV */ | ||
2846 | i915_gem_write_fence(args->dev, args->fence, args->obj); | ||
2847 | } | ||
2848 | |||
2849 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | 2832 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, |
2850 | struct drm_i915_fence_reg *fence, | 2833 | struct drm_i915_fence_reg *fence, |
2851 | bool enable) | 2834 | bool enable) |
2852 | { | 2835 | { |
2853 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 2836 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
2854 | struct write_fence args = { | 2837 | int reg = fence_number(dev_priv, fence); |
2855 | .dev = obj->base.dev, | 2838 | |
2856 | .fence = fence_number(dev_priv, fence), | 2839 | i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); |
2857 | .obj = enable ? obj : NULL, | ||
2858 | }; | ||
2859 | |||
2860 | /* In order to fully serialize access to the fenced region and | ||
2861 | * the update to the fence register we need to take extreme | ||
2862 | * measures on SNB+. In theory, the write to the fence register | ||
2863 | * flushes all memory transactions before, and coupled with the | ||
2864 | * mb() placed around the register write we serialise all memory | ||
2865 | * operations with respect to the changes in the tiler. Yet, on | ||
2866 | * SNB+ we need to take a step further and emit an explicit wbinvd() | ||
2867 | * on each processor in order to manually flush all memory | ||
2868 | * transactions before updating the fence register. | ||
2869 | * | ||
2870 | * However, Valleyview complicates matter. There the wbinvd is | ||
2871 | * insufficient and unlike SNB/IVB requires the serialising | ||
2872 | * register write. (Note that that register write by itself is | ||
2873 | * conversely not sufficient for SNB+.) To compromise, we do both. | ||
2874 | */ | ||
2875 | if (INTEL_INFO(args.dev)->gen >= 6) | ||
2876 | on_each_cpu(i915_gem_write_fence__ipi, &args, 1); | ||
2877 | else | ||
2878 | i915_gem_write_fence(args.dev, args.fence, args.obj); | ||
2879 | 2840 | ||
2880 | if (enable) { | 2841 | if (enable) { |
2881 | obj->fence_reg = args.fence; | 2842 | obj->fence_reg = reg; |
2882 | fence->obj = obj; | 2843 | fence->obj = obj; |
2883 | list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); | 2844 | list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); |
2884 | } else { | 2845 | } else { |