Commit 461fb99c authored by Chris Wilson's avatar Chris Wilson

drm/i915: Update domain tracking for GEM objects on hibernation

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Imre Deak <imre.deak@intel.com>
Cc: David Weinehall <david.weinehall@intel.com>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1463207195-22076-2-git-send-email-chris@chris-wilson.co.uk
parent 1f19ac2a
...@@ -1123,7 +1123,17 @@ static int i915_pm_freeze(struct device *dev) ...@@ -1123,7 +1123,17 @@ static int i915_pm_freeze(struct device *dev)
static int i915_pm_freeze_late(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. */ /* thaw: called after creating the hibernation image, but before turning off. */
......
...@@ -2976,6 +2976,8 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data, ...@@ -2976,6 +2976,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_init(struct drm_device *dev);
void i915_gem_load_cleanup(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); 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_alloc(struct drm_device *dev);
void i915_gem_object_free(struct drm_i915_gem_object *obj); void i915_gem_object_free(struct drm_i915_gem_object *obj);
void i915_gem_object_init(struct drm_i915_gem_object *obj, void i915_gem_object_init(struct drm_i915_gem_object *obj,
......
...@@ -5054,6 +5054,34 @@ void i915_gem_load_cleanup(struct drm_device *dev) ...@@ -5054,6 +5054,34 @@ void i915_gem_load_cleanup(struct drm_device *dev)
kmem_cache_destroy(dev_priv->objects); 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) void i915_gem_release(struct drm_device *dev, struct drm_file *file)
{ {
struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_file_private *file_priv = file->driver_priv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment