Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be062fa4 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Initialise i915_gem_object_create_from_data() directly



Use pagecache_write to avoid shmemfs clearing the pages prior to us
immediately overwriting them with our data.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170317194648.12468-2-chris@chris-wilson.co.uk


Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
parent f3ddd2c1
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -4953,9 +4953,9 @@ i915_gem_object_create_from_data(struct drm_i915_private *dev_priv,
			         const void *data, size_t size)
{
	struct drm_i915_gem_object *obj;
	struct sg_table *sg;
	size_t bytes;
	int ret;
	struct file *file;
	size_t offset;
	int err;

	obj = i915_gem_object_create(dev_priv, round_up(size, PAGE_SIZE));
	if (IS_ERR(obj))
@@ -4963,26 +4963,39 @@ i915_gem_object_create_from_data(struct drm_i915_private *dev_priv,

	GEM_BUG_ON(obj->base.write_domain != I915_GEM_DOMAIN_CPU);

	ret = i915_gem_object_pin_pages(obj);
	if (ret)
	file = obj->base.filp;
	offset = 0;
	do {
		unsigned int len = min_t(typeof(size), size, PAGE_SIZE);
		struct page *page;
		void *pgdata, *vaddr;

		err = pagecache_write_begin(file, file->f_mapping,
					    offset, len, 0,
					    &page, &pgdata);
		if (err < 0)
			goto fail;

	sg = obj->mm.pages;
	bytes = sg_copy_from_buffer(sg->sgl, sg->nents, (void *)data, size);
	obj->mm.dirty = true; /* Backing store is now out of date */
	i915_gem_object_unpin_pages(obj);
		vaddr = kmap(page);
		memcpy(vaddr, data, len);
		kunmap(page);

	if (WARN_ON(bytes != size)) {
		DRM_ERROR("Incomplete copy, wrote %zu of %zu", bytes, size);
		ret = -EFAULT;
		err = pagecache_write_end(file, file->f_mapping,
					  offset, len, len,
					  page, pgdata);
		if (err < 0)
			goto fail;
	}

		size -= len;
		data += len;
		offset += len;
	} while (size);

	return obj;

fail:
	i915_gem_object_put(obj);
	return ERR_PTR(ret);
	return ERR_PTR(err);
}

struct scatterlist *