[Intel-gfx] [PATCH 8/8] drm/i915: Migrate stolen objects before hibernation
Chris Wilson
chris at chris-wilson.co.uk
Tue Dec 15 03:46:12 PST 2015
On Tue, Dec 15, 2015 at 04:26:08PM +0530, ankitprasad.r.sharma at intel.com wrote:
> From: Chris Wilson <chris at chris-wilson.co.uk>
> +static int
> +copy_content(struct drm_i915_gem_object *obj,
> + struct drm_i915_private *i915,
> + struct address_space *mapping)
> +{
> + struct drm_mm_node node;
> + int ret, i;
> +
> + ret = i915_gem_object_set_to_gtt_domain(obj, false);
> + if (ret)
> + return ret;
> +
> + /* stolen objects are already pinned to prevent shrinkage */
> + memset(&node, 0, sizeof(node));
> + ret = insert_mappable_node(i915, &node);
> + if (ret)
> + return ret;
> +
> + for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
> + struct page *page;
> + void *__iomem src;
> + void *dst;
> +
> + i915->gtt.base.insert_page(&i915->gtt.base,
> + i915_gem_object_get_dma_address(obj, i),
> + node.start,
> + I915_CACHE_NONE,
> + 0);
> +
> + page = shmem_read_mapping_page(mapping, i);
> + if (IS_ERR(page)) {
> + ret = PTR_ERR(page);
> + break;
> + }
> +
> + src = io_mapping_map_atomic_wc(i915->gtt.mappable, node.start);
> + dst = kmap_atomic(page);
> + wmb();
> + memcpy_fromio(dst, src, PAGE_SIZE);
> + wmb();
> + kunmap_atomic(dst);
> + io_mapping_unmap_atomic(src);
> +
> + page_cache_release(page);
> + }
> +
> + wmb();
After moving the barriers, this one is redundant.
> + i915->gtt.base.clear_range(&i915->gtt.base,
> + node.start, node.size,
> + true);
> + drm_mm_remove_node(&node);
> + obj->base.read_domains = I915_GEM_DOMAIN_CPU;
> + obj->base.write_domain = I915_GEM_DOMAIN_CPU;
On the error path, we shouldn't be marking new domains as the object
reverts back to the previous set of pages.
If you do a bit of rearranging of the goto err, you could just put
return i915_gem_object_set_to_cpu_domain(obj, true);
It will be mostly a no-op over the current set read/write domains (but
should help in case it ever is not).
> +int
> +i915_gem_freeze(struct drm_device *dev)
> +{
> + /* Called before i915_gem_suspend() when hibernating */
> + struct drm_i915_private *i915 = to_i915(dev);
> + struct drm_i915_gem_object *obj, *tmp;
> + struct list_head *phase[] = {
> + &i915->mm.unbound_list, &i915->mm.bound_list, NULL
> + }, **p;
> + int ret;
> +
> + ret = i915_mutex_lock_interruptible(dev);
> + if (ret)
> + return ret;
> +
> + /* Across hibernation, the stolen area is not preserved.
> + * Anything inside stolen must copied back to normal
> + * memory if we wish to preserve it.
> + */
> + for (p = phase; *p; p++) {
Since we are making changes, might as well push this loop to
i915_gem_stolen_freeze() and i915_gem_stolen.c. Probably best to push
the i915_gem_object_stolen_migrate_to_shemfs() there as well.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list