Skip to content

Commit

Permalink
drm/i915: Serialise updates to GGTT with access through GGTT on Braswell
Browse files Browse the repository at this point in the history
When accessing through the GTT from one CPU whilst concurrently updating
the GGTT PTEs in another thread, the hardware likes to return random
data. As we have strong serialisation prevent us from modifying the PTE
of an active GTT mmapping, we have to conclude that it whilst modifying
other PTE's that error occurs. (I have not looked for any pattern such
as modifying PTE within the same page or cacheline as active PTE -
though checking whether revoking neighbouring objects should be enough
to test that theory.) The corruption also seems restricted to Braswell
and disappears with maxcpus=0. This patch stops all access through the
GTT by other CPUs when we update any PTE by stopping the machine around
the GGTT update.

Note that splitting up the 64 bit write into two 32 bit writes was
tried and found to fail too.

Testcase: igt/gem_concurrent_blit
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89079
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
[danvet: Add note about 2x 32bits failing too.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Nov 17, 2015
1 parent 14631e9 commit 5bab6f6
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config DRM_I915
# the shmem_readpage() which depends upon tmpfs
select SHMEM
select TMPFS
select STOP_MACHINE
select DRM_KMS_HELPER
select DRM_PANEL
select DRM_MIPI_DSI
Expand Down
24 changes: 24 additions & 0 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/

#include <linux/seq_file.h>
#include <linux/stop_machine.h>
#include <drm/drmP.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
Expand Down Expand Up @@ -2533,6 +2534,26 @@ static int ggtt_bind_vma(struct i915_vma *vma,
return 0;
}

struct ggtt_bind_vma__cb {
struct i915_vma *vma;
enum i915_cache_level cache_level;
u32 flags;
};

static int ggtt_bind_vma__cb(void *_arg)
{
struct ggtt_bind_vma__cb *arg = _arg;
return ggtt_bind_vma(arg->vma, arg->cache_level, arg->flags);
}

static int ggtt_bind_vma__BKL(struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags)
{
struct ggtt_bind_vma__cb arg = { vma, cache_level, flags };
return stop_machine(ggtt_bind_vma__cb, &arg, NULL);
}

static int aliasing_gtt_bind_vma(struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags)
Expand Down Expand Up @@ -3000,6 +3021,9 @@ static int gen8_gmch_probe(struct drm_device *dev,
dev_priv->gtt.base.bind_vma = ggtt_bind_vma;
dev_priv->gtt.base.unbind_vma = ggtt_unbind_vma;

if (IS_CHERRYVIEW(dev))
dev_priv->gtt.base.bind_vma = ggtt_bind_vma__BKL;

return ret;
}

Expand Down

0 comments on commit 5bab6f6

Please sign in to comment.