On to, 2016-05-12 at 15:28 +0100, Chris Wilson wrote: > When creating the hibernation image, the CPU will read the pages of all > objects and thus conflict with our domain tracking. We need to update > our domain tracking to accurately reflect the state on restoration. > > v2: Perform the domain tracking inside freeze, before the image is > written, rather than upon restoration. > > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Imre Deak <imre.deak@xxxxxxxxx> > Cc: David Weinehall <david.weinehall@xxxxxxxxx> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_drv.c | 12 +++++++++++- > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > drivers/gpu/drm/i915/i915_gem.c | 28 ++++++++++++++++++++++++++++ > 3 files changed, 41 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index 6a2e7f84276b..dba03c026151 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -1123,7 +1123,17 @@ static int i915_pm_freeze(struct device *dev) > > static int i915_pm_freeze_late(struct device *dev) > { > - return i915_pm_suspend_late(dev); > + int ret; > + > + ret = i915_pm_suspend_late(dev); > + if (ret) > + return ret; > + > + ret = i915_gem_freeze_late(dev_to_i915(dev)); > + if (ret) > + return ret; > + > + return 0; > } > > /* thaw: called after creating the hibernation image, but before turning off. */ > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 7a0b51301337..0a4255fa8895 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -2961,6 +2961,8 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data, > void i915_gem_load_init(struct drm_device *dev); > void i915_gem_load_cleanup(struct drm_device *dev); > void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); > +int i915_gem_freeze_late(struct drm_i915_private *dev_priv); > + > void *i915_gem_object_alloc(struct drm_device *dev); > void i915_gem_object_free(struct drm_i915_gem_object *obj); > void i915_gem_object_init(struct drm_i915_gem_object *obj, > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > index be75689455b2..7bd670e34ee5 100644 > --- a/drivers/gpu/drm/i915/i915_gem.c > +++ b/drivers/gpu/drm/i915/i915_gem.c > @@ -5053,6 +5053,34 @@ void i915_gem_load_cleanup(struct drm_device *dev) > kmem_cache_destroy(dev_priv->objects); > } > > +int i915_gem_freeze_late(struct drm_i915_private *dev_priv) > +{ > + struct drm_i915_gem_object *obj; > + > + /* Called just before we write the hibernation image. > + * > + * We need to update the domain tracking to reflect that the CPU > + * will be accessing all the pages to create and restore from the > + * hibernation, and so upon restoration those pages will be in the > + * CPU domain. > + * > + * To make sure the hibernation image contains the latest state, > + * we update that state just before writing out the image. > + */ > + > + list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) { > + obj->base.read_domains = I915_GEM_DOMAIN_CPU; > + obj->base.write_domain = I915_GEM_DOMAIN_CPU; > + } > + > + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { > + obj->base.read_domains = I915_GEM_DOMAIN_CPU; > + obj->base.write_domain = I915_GEM_DOMAIN_CPU; > + } > + > + return 0; > +} > + > void i915_gem_release(struct drm_device *dev, struct drm_file *file) > { > struct drm_i915_file_private *file_priv = file->driver_priv; -- Joonas Lahtinen Open Source Technology Center Intel Corporation _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx