diff mbox

[1/3] drm/i915: Flush the context object from the CPU caches upon switching

Message ID 1342352064-6749-1-git-send-email-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson July 15, 2012, 11:34 a.m. UTC
The issue is that we stale data in the CPU caches, when we come to
swap-out the object, the CPU may short-circuit the reads from those
cacheline and so corrupt the context object.

Secondary, leaving the context object as being marked in the CPU write
domain whilst on the GPU active list is a bad idea and will throw
warnings later.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_gem_context.c |    7 +++++++
 1 file changed, 7 insertions(+)

Comments

Daniel Vetter July 15, 2012, 3:16 p.m. UTC | #1
On Sun, Jul 15, 2012 at 12:34:22PM +0100, Chris Wilson wrote:
> The issue is that we stale data in the CPU caches, when we come to
> swap-out the object, the CPU may short-circuit the reads from those
> cacheline and so corrupt the context object.
> 
> Secondary, leaving the context object as being marked in the CPU write
> domain whilst on the GPU active list is a bad idea and will throw
> warnings later.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
> ---
>  drivers/gpu/drm/i915/i915_gem_context.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 9ae3f2c..fd978bb 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -374,6 +374,13 @@ static int do_switch(struct drm_i915_gem_object *from_obj,
>  	if (ret)
>  		return ret;
>  
> +	/* Clear this page out of any CPU caches for coherent swap-in/out */
> +	ret = i915_gem_object_set_to_gtt_domain(to->obj, false);
> +	if (ret) {
> +		i915_gem_object_unpin(to->obj);
> +		return ret;
> +	}
> +

Do I understand things correctly that thanks to clever use of
set_to_gtt_domain with write = false and not setting a write_domain when
moving the old context object to the active list we won't block? If so,
I'll add a short note to that effect to the commit message when merging.

And given that we have similar clever interface abuse in the pwrite/pread
code, some code rework is in order I guess. We could replace all that
domain tracking with bool gpu_coherent would be simpler (after the
flushing_list's permanent demise, of course).
-Daniel

>  	if (!to->obj->has_global_gtt_mapping)
>  		i915_gem_gtt_bind_object(to->obj, to->obj->cache_level);
>  
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Chris Wilson July 15, 2012, 7:09 p.m. UTC | #2
On Sun, 15 Jul 2012 17:16:34 +0200, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Sun, Jul 15, 2012 at 12:34:22PM +0100, Chris Wilson wrote:
> > The issue is that we stale data in the CPU caches, when we come to
> > swap-out the object, the CPU may short-circuit the reads from those
> > cacheline and so corrupt the context object.
> > 
> > Secondary, leaving the context object as being marked in the CPU write
> > domain whilst on the GPU active list is a bad idea and will throw
> > warnings later.
> > 
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
> > ---
> >  drivers/gpu/drm/i915/i915_gem_context.c |    7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> > index 9ae3f2c..fd978bb 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_context.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> > @@ -374,6 +374,13 @@ static int do_switch(struct drm_i915_gem_object *from_obj,
> >  	if (ret)
> >  		return ret;
> >  
> > +	/* Clear this page out of any CPU caches for coherent swap-in/out */
> > +	ret = i915_gem_object_set_to_gtt_domain(to->obj, false);
> > +	if (ret) {
> > +		i915_gem_object_unpin(to->obj);
> > +		return ret;
> > +	}
> > +
> 
> Do I understand things correctly that thanks to clever use of
> set_to_gtt_domain with write = false and not setting a write_domain when
> moving the old context object to the active list we won't block? If so,
> I'll add a short note to that effect to the commit message when merging.

Worse, it was accidentally very clever. :(

Definitely needs a comment and in the future a new function to dtrt
intentionally!
-Chris
Daniel Vetter July 16, 2012, 8:43 a.m. UTC | #3
On Sun, Jul 15, 2012 at 08:09:36PM +0100, Chris Wilson wrote:
> On Sun, 15 Jul 2012 17:16:34 +0200, Daniel Vetter <daniel@ffwll.ch> wrote:
> > On Sun, Jul 15, 2012 at 12:34:22PM +0100, Chris Wilson wrote:
> > > The issue is that we stale data in the CPU caches, when we come to
> > > swap-out the object, the CPU may short-circuit the reads from those
> > > cacheline and so corrupt the context object.
> > > 
> > > Secondary, leaving the context object as being marked in the CPU write
> > > domain whilst on the GPU active list is a bad idea and will throw
> > > warnings later.
> > > 
> > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > > Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
> > > ---
> > >  drivers/gpu/drm/i915/i915_gem_context.c |    7 +++++++
> > >  1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> > > index 9ae3f2c..fd978bb 100644
> > > --- a/drivers/gpu/drm/i915/i915_gem_context.c
> > > +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> > > @@ -374,6 +374,13 @@ static int do_switch(struct drm_i915_gem_object *from_obj,
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > +	/* Clear this page out of any CPU caches for coherent swap-in/out */
> > > +	ret = i915_gem_object_set_to_gtt_domain(to->obj, false);
> > > +	if (ret) {
> > > +		i915_gem_object_unpin(to->obj);
> > > +		return ret;
> > > +	}
> > > +
> > 
> > Do I understand things correctly that thanks to clever use of
> > set_to_gtt_domain with write = false and not setting a write_domain when
> > moving the old context object to the active list we won't block? If so,
> > I'll add a short note to that effect to the commit message when merging.
> 
> Worse, it was accidentally very clever. :(
> 
> Definitely needs a comment and in the future a new function to dtrt
> intentionally!
Queued for -next (with comments to explain this trickery added as
discussed on irc), thanks for the patch. I'll pick up the other two
patches once Ben has smashed an r-b onto them.
-Daniel
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 9ae3f2c..fd978bb 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -374,6 +374,13 @@  static int do_switch(struct drm_i915_gem_object *from_obj,
 	if (ret)
 		return ret;
 
+	/* Clear this page out of any CPU caches for coherent swap-in/out */
+	ret = i915_gem_object_set_to_gtt_domain(to->obj, false);
+	if (ret) {
+		i915_gem_object_unpin(to->obj);
+		return ret;
+	}
+
 	if (!to->obj->has_global_gtt_mapping)
 		i915_gem_gtt_bind_object(to->obj, to->obj->cache_level);