On Tue, Jan 13, 2015 at 01:32:52PM +0000, Chris Wilson wrote: > Currently we are hitting the WARN inside > i915_gem_object_set_cache_level() as we can now have an unbound object > in the GTT write domain (due to 43566dedde54f9 "drm/i915: Broaden > application of set-domain(GTT)"). To avoid the warning, we need to track > when we elided the clflush on a cacheable object and then evict the > cache for the object when we move the object out of a cacheable domain. > > Reported-by: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx> > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx> > Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_drv.h | 1 + > drivers/gpu/drm/i915/i915_gem.c | 32 +++++++++----------------------- > 2 files changed, 10 insertions(+), 23 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index bf18a5238887..7070482000cd 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1998,6 +1998,7 @@ struct drm_i915_gem_object { > */ > unsigned long gt_ro:1; > unsigned int cache_level:3; > + unsigned int cache_dirty:1; > > unsigned int has_dma_mapping:1; > > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > index 9bafe50d3df7..aa089e7c31bf 100644 > --- a/drivers/gpu/drm/i915/i915_gem.c > +++ b/drivers/gpu/drm/i915/i915_gem.c > @@ -3639,11 +3639,14 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, > * snooping behaviour occurs naturally as the result of our domain > * tracking. > */ > - if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) > + if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) { > + obj->cache_dirty = true; Hmm. This would mark the cache dirty even when just moving to the CPU read domain. A subsequent set_cache_level might then flush a bit needlessly. But maybe that's rare enoguh to ignore? I suppose we could follow this up with another patch to fix kms_pwrite_crc using cache_dirty as well. But actually that would require doing the clflush even when the cache_level didn't change, which might aggravate the needless flushing issue somewhat. Or perhaps we should just add another cache_dirty dependent flush to i915_gem_object_pin_to_display_plane() to deal with that particular problem? > return false; > + } > > trace_i915_gem_object_clflush(obj); > drm_clflush_sg(obj->pages); > + obj->cache_dirty = false; > > return true; > } > @@ -3826,28 +3829,11 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, > vma->node.color = cache_level; > obj->cache_level = cache_level; > > - if (cpu_write_needs_clflush(obj)) { > - u32 old_read_domains, old_write_domain; > - > - /* If we're coming from LLC cached, then we haven't > - * actually been tracking whether the data is in the > - * CPU cache or not, since we only allow one bit set > - * in obj->write_domain and have been skipping the clflushes. > - * Just set it to the CPU cache for now. > - */ > - i915_gem_object_retire(obj); > - WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU); > - > - old_read_domains = obj->base.read_domains; > - old_write_domain = obj->base.write_domain; > - > - obj->base.read_domains = I915_GEM_DOMAIN_CPU; > - obj->base.write_domain = I915_GEM_DOMAIN_CPU; > - > - trace_i915_gem_object_change_domain(obj, > - old_read_domains, > - old_write_domain); > - } > + if (obj->cache_dirty && > + obj->base.write_domain != I915_GEM_DOMAIN_CPU && > + cpu_write_needs_clflush(obj) && > + i915_gem_clflush_object(obj, true)) > + i915_gem_chipset_flush(obj->base.dev); > > return 0; > } > -- > 2.1.4 -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx