[PATCH] drm/i915: Support to create uncached user mapping for a Gem object

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Akash Goel <akash.goel@xxxxxxxxx>

This patch provides support to create uncached virtual mappings for a Gem
object. It intends to provide the same funtionality of 'mmap_gtt' interface
without the constraints of a limited aperture space, but provided clients
handles the linear to tile conversion on their own.
This is for improving the CPU write operation performance, as with such
mapping, writes are almost 50% faster than with mmap_gtt. Also it avoids the
Cache flush after update from CPU side, when object is passed onto GPU, which
will be the case if regular mmap ioctl interface is used.
This type of mapping is specially useful in case of sub-region update,
i.e. when only a portion of the object is to be updated.
To ensure the cache coherency, before using this mapping, the GTT domain has
been reused here. This provides the required Cache flush if the object is in
CPU domain or synchronization against the concurrent rendering. Although the
access through an uncached mmap shall automatically invalidate the cache lines,
but this may not be true for non temporal write instructions and also not all
pages of the object be updated at any given point of time through this mapping.
Having a call to get_pages in set_to_gtt_domain function, as added by Chris in
the earlier patch, would guarantee the clflush and so there will be no cache-
lines holding the data for the object before it is accessed through this map.
A new field 'flags' has been added to 'drm_i915_gem_mmap' structure, used in
gem_mmap ioctl, which allows to convey the required mapping type as uncached.
User can query the driver for the support of this mapping through the
get_params. For that a new define I915_PARAM_HAS_UC_MMAP has been added.

Change-Id: Ie883942f9e689525f72fe9a8d3780c3a9faa769a
Signed-off-by: Akash Goel <akash.goel@xxxxxxxxx>
---
 drivers/gpu/drm/i915/i915_dma.c |  3 +++
 drivers/gpu/drm/i915/i915_gem.c | 17 +++++++++++++++++
 include/uapi/drm/i915_drm.h     |  4 ++++
 3 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 1b39807..2d8191a 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1027,6 +1027,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_CMD_PARSER_VERSION:
 		value = i915_cmd_parser_get_version();
 		break;
+	case I915_PARAM_HAS_UC_MMAP:
+		value = 1;
+		break;
 	default:
 		DRM_DEBUG("Unknown parameter %d\n", param->param);
 		return -EINVAL;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1b192d4..16b267b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1492,6 +1492,23 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
 	addr = vm_mmap(obj->filp, 0, args->size,
 		       PROT_READ | PROT_WRITE, MAP_SHARED,
 		       args->offset);
+
+	if (args->flags & I915_GEM_USE_UNCACHED_MMAP) {
+		struct mm_struct *mm = current->mm;
+		struct vm_area_struct *vma;
+		down_write(&mm->mmap_sem);
+		vma = find_vma(mm, addr);
+		if (!vma) {
+			drm_gem_object_unreference_unlocked(obj);
+			return -EINVAL;
+		}
+		/* Change the page attribute to uncached (along with
+		 * write-combinning to get better performance) */
+		vma->vm_page_prot =
+			pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+		up_write(&mm->mmap_sem);
+	}
+
 	drm_gem_object_unreference_unlocked(obj);
 	if (IS_ERR((void *)addr))
 		return addr;
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index ff57f07..3d0b1c0 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -340,6 +340,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXEC_HANDLE_LUT   26
 #define I915_PARAM_HAS_WT     	 	 27
 #define I915_PARAM_CMD_PARSER_VERSION	 28
+#define I915_PARAM_HAS_UC_MMAP  	 29
 
 typedef struct drm_i915_getparam {
 	int param;
@@ -487,6 +488,9 @@ struct drm_i915_gem_mmap {
 	 * This is a fixed-size type for 32/64 compatibility.
 	 */
 	__u64 addr_ptr;
+
+#define I915_GEM_USE_UNCACHED_MMAP (1<<0)
+	__u64 flags;
 };
 
 struct drm_i915_gem_mmap_gtt {
-- 
1.9.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux