Skip to content

Commit

Permalink
Revert "drm/i915: Workaround incoherence between fences and LLC acros…
Browse files Browse the repository at this point in the history
…s multiple CPUs"

This reverts commit 25ff119 and the follow on for Valleyview commit 2dc8aae.

commit 25ff119
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 2dc8aae
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>
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Jul 10, 2013
1 parent d18b961 commit 46a0b63
Showing 1 changed file with 4 additions and 43 deletions.
47 changes: 4 additions & 43 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2829,56 +2829,17 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
return fence - dev_priv->fence_regs;
}

struct write_fence {
struct drm_device *dev;
struct drm_i915_gem_object *obj;
int fence;
};

static void i915_gem_write_fence__ipi(void *data)
{
struct write_fence *args = data;

/* Required for SNB+ with LLC */
wbinvd();

/* Required for VLV */
i915_gem_write_fence(args->dev, args->fence, args->obj);
}

static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
struct drm_i915_fence_reg *fence,
bool enable)
{
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
struct write_fence args = {
.dev = obj->base.dev,
.fence = fence_number(dev_priv, fence),
.obj = enable ? obj : NULL,
};

/* In order to fully serialize access to the fenced region and
* the update to the fence register we need to take extreme
* measures on SNB+. In theory, the write to the fence register
* flushes all memory transactions before, and coupled with the
* mb() placed around the register write we serialise all memory
* operations with respect to the changes in the tiler. Yet, on
* SNB+ we need to take a step further and emit an explicit wbinvd()
* on each processor in order to manually flush all memory
* transactions before updating the fence register.
*
* However, Valleyview complicates matter. There the wbinvd is
* insufficient and unlike SNB/IVB requires the serialising
* register write. (Note that that register write by itself is
* conversely not sufficient for SNB+.) To compromise, we do both.
*/
if (INTEL_INFO(args.dev)->gen >= 6)
on_each_cpu(i915_gem_write_fence__ipi, &args, 1);
else
i915_gem_write_fence(args.dev, args.fence, args.obj);
int reg = fence_number(dev_priv, fence);

i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);

if (enable) {
obj->fence_reg = args.fence;
obj->fence_reg = reg;
fence->obj = obj;
list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
} else {
Expand Down

0 comments on commit 46a0b63

Please sign in to comment.