aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-09-09 16:19:57 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2016-09-09 16:31:43 -0400
commitfbb30a5c463ff882980ce62d2ac27a0672efafb8 (patch)
tree163127dd199b46cce3ff35ac8adb2615c1be1bb3 /drivers/gpu/drm
parent7aab2d534e35177cb08aed4075aa200b368ad496 (diff)
drm/i915: Flush to GTT domain all GGTT bound objects after hibernation
Recently I have been applying an optimisation to avoid stalling and clflushing GGTT objects based on their current binding. That is we only set-to-gtt-domain upon first bind. However, on hibernation the objects remain bound, but they are in the CPU domain. Currently (since commit 975f7ff42edf ("drm/i915: Lazily migrate the objects after hibernation")) we only flush scanout objects as all other objects are expected to be flushed prior to use. That breaks down in the face of the runtime optimisation above - and we need to flush all GGTT pinned objects (essentially ringbuffers). To reduce the burden of extra clflushes, we only flush those objects we cannot discard from the GGTT. Everything pinned to the scanout, or current contexts or ringbuffers will be flushed and rebound. Other objects, such as inactive contexts, will be left unbound and in the CPU domain until first use after resuming. Fixes: 7abc98fadfdd ("drm/i915: Only change the context object's domain...") Fixes: 57e885318119 ("drm/i915: Use VMA for ringbuffer tracking") References: https://bugs.freedesktop.org/show_bug.cgi?id=94722 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Cc: David Weinehall <david.weinehall@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20160909201957.2499-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f3c6876da521..61ab65b01cc4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3237,8 +3237,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
3237{ 3237{
3238 struct drm_i915_private *dev_priv = to_i915(dev); 3238 struct drm_i915_private *dev_priv = to_i915(dev);
3239 struct i915_ggtt *ggtt = &dev_priv->ggtt; 3239 struct i915_ggtt *ggtt = &dev_priv->ggtt;
3240 struct drm_i915_gem_object *obj; 3240 struct drm_i915_gem_object *obj, *on;
3241 struct i915_vma *vma;
3242 3241
3243 i915_check_and_clear_faults(dev_priv); 3242 i915_check_and_clear_faults(dev_priv);
3244 3243
@@ -3246,20 +3245,32 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
3246 ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total, 3245 ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total,
3247 true); 3246 true);
3248 3247
3249 /* Cache flush objects bound into GGTT and rebind them. */ 3248 ggtt->base.closed = true; /* skip rewriting PTE on VMA unbind */
3250 list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { 3249
3250 /* clflush objects bound into the GGTT and rebind them. */
3251 list_for_each_entry_safe(obj, on,
3252 &dev_priv->mm.bound_list, global_list) {
3253 bool ggtt_bound = false;
3254 struct i915_vma *vma;
3255
3251 list_for_each_entry(vma, &obj->vma_list, obj_link) { 3256 list_for_each_entry(vma, &obj->vma_list, obj_link) {
3252 if (vma->vm != &ggtt->base) 3257 if (vma->vm != &ggtt->base)
3253 continue; 3258 continue;
3254 3259
3260 if (!i915_vma_unbind(vma))
3261 continue;
3262
3255 WARN_ON(i915_vma_bind(vma, obj->cache_level, 3263 WARN_ON(i915_vma_bind(vma, obj->cache_level,
3256 PIN_UPDATE)); 3264 PIN_UPDATE));
3265 ggtt_bound = true;
3257 } 3266 }
3258 3267
3259 if (obj->pin_display) 3268 if (ggtt_bound)
3260 WARN_ON(i915_gem_object_set_to_gtt_domain(obj, false)); 3269 WARN_ON(i915_gem_object_set_to_gtt_domain(obj, false));
3261 } 3270 }
3262 3271
3272 ggtt->base.closed = false;
3273
3263 if (INTEL_INFO(dev)->gen >= 8) { 3274 if (INTEL_INFO(dev)->gen >= 8) {
3264 if (IS_CHERRYVIEW(dev) || IS_BROXTON(dev)) 3275 if (IS_CHERRYVIEW(dev) || IS_BROXTON(dev))
3265 chv_setup_private_ppat(dev_priv); 3276 chv_setup_private_ppat(dev_priv);