diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-01-13 08:32:52 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-01-27 03:51:07 -0500 |
commit | 0f71979ab7fbd0c71c41c2798de3d33937915434 (patch) | |
tree | 18cbac2efa428f0be13e573dd7d987d9220d7f20 | |
parent | a7cbedec8317a5cacecb567674fdbc1c3fb22de8 (diff) |
drm/i915: Performed deferred clflush inside set-cache-level
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@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Tested-by: Jani Nikula <jani.nikula@intel.com>
Testcase: igt/gem_mmap_wc/set-cache-level
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88607
Tested-by: huax.lu@intel.com
[danvet: Split if into nested if as discussion on the m-l.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 31 |
2 files changed, 10 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index de304d78e2bf..0ad8dbf896c0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -2055,6 +2055,7 @@ struct drm_i915_gem_object { | |||
2055 | */ | 2055 | */ |
2056 | unsigned long gt_ro:1; | 2056 | unsigned long gt_ro:1; |
2057 | unsigned int cache_level:3; | 2057 | unsigned int cache_level:3; |
2058 | unsigned int cache_dirty:1; | ||
2058 | 2059 | ||
2059 | unsigned int has_dma_mapping:1; | 2060 | unsigned int has_dma_mapping:1; |
2060 | 2061 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2a4d1f01118d..a0264aa5cf51 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3637,11 +3637,14 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, | |||
3637 | * snooping behaviour occurs naturally as the result of our domain | 3637 | * snooping behaviour occurs naturally as the result of our domain |
3638 | * tracking. | 3638 | * tracking. |
3639 | */ | 3639 | */ |
3640 | if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) | 3640 | if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) { |
3641 | obj->cache_dirty = true; | ||
3641 | return false; | 3642 | return false; |
3643 | } | ||
3642 | 3644 | ||
3643 | trace_i915_gem_object_clflush(obj); | 3645 | trace_i915_gem_object_clflush(obj); |
3644 | drm_clflush_sg(obj->pages); | 3646 | drm_clflush_sg(obj->pages); |
3647 | obj->cache_dirty = false; | ||
3645 | 3648 | ||
3646 | return true; | 3649 | return true; |
3647 | } | 3650 | } |
@@ -3824,27 +3827,11 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
3824 | vma->node.color = cache_level; | 3827 | vma->node.color = cache_level; |
3825 | obj->cache_level = cache_level; | 3828 | obj->cache_level = cache_level; |
3826 | 3829 | ||
3827 | if (cpu_write_needs_clflush(obj)) { | 3830 | if (obj->cache_dirty && |
3828 | u32 old_read_domains, old_write_domain; | 3831 | obj->base.write_domain != I915_GEM_DOMAIN_CPU && |
3829 | 3832 | cpu_write_needs_clflush(obj)) { | |
3830 | /* If we're coming from LLC cached, then we haven't | 3833 | if (i915_gem_clflush_object(obj, true)) |
3831 | * actually been tracking whether the data is in the | 3834 | i915_gem_chipset_flush(obj->base.dev); |
3832 | * CPU cache or not, since we only allow one bit set | ||
3833 | * in obj->write_domain and have been skipping the clflushes. | ||
3834 | * Just set it to the CPU cache for now. | ||
3835 | */ | ||
3836 | i915_gem_object_retire(obj); | ||
3837 | WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU); | ||
3838 | |||
3839 | old_read_domains = obj->base.read_domains; | ||
3840 | old_write_domain = obj->base.write_domain; | ||
3841 | |||
3842 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | ||
3843 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | ||
3844 | |||
3845 | trace_i915_gem_object_change_domain(obj, | ||
3846 | old_read_domains, | ||
3847 | old_write_domain); | ||
3848 | } | 3835 | } |
3849 | 3836 | ||
3850 | return 0; | 3837 | return 0; |