public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: daniel.vetter@ffwll.ch
Subject: [PATCH 09/22] drm/i915/lmem: support kernel mapping
Date: Fri, 27 Sep 2019 18:33:56 +0100	[thread overview]
Message-ID: <20190927173409.31175-10-matthew.auld@intel.com> (raw)
In-Reply-To: <20190927173409.31175-1-matthew.auld@intel.com>

From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>

We can create LMEM objects, but we also need to support mapping them
into kernel space for internal use.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Steve Hampson <steven.t.hampson@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c  |  4 +-
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c      | 36 +++++++++
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h      |  8 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.h    |  6 ++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 +-
 drivers/gpu/drm/i915/gem/i915_gem_pages.c     | 20 ++++-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c     |  3 +-
 .../drm/i915/gem/selftests/huge_gem_object.c  |  4 +-
 .../drm/i915/selftests/intel_memory_region.c  | 76 +++++++++++++++++++
 9 files changed, 152 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index 5e72cb1cc2d3..c2e237702e8c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -140,7 +140,9 @@ static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj,
 
 static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
 	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
-		 I915_GEM_OBJECT_IS_SHRINKABLE,
+		 I915_GEM_OBJECT_IS_SHRINKABLE |
+		 I915_GEM_OBJECT_IS_MAPPABLE,
+
 	.get_pages = i915_gem_object_get_pages_internal,
 	.put_pages = i915_gem_object_put_pages_internal,
 };
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 26a23304df32..d7ec74ed5b88 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -9,11 +9,47 @@
 #include "i915_drv.h"
 
 const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
+	.flags = I915_GEM_OBJECT_IS_MAPPABLE,
+
 	.get_pages = i915_gem_object_get_pages_buddy,
 	.put_pages = i915_gem_object_put_pages_buddy,
 	.release = i915_gem_object_release_memory_region,
 };
 
+/* XXX: Time to vfunc your life up? */
+void __iomem *i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object *obj,
+					       unsigned long n)
+{
+	resource_size_t offset;
+
+	offset = i915_gem_object_get_dma_address(obj, n);
+
+	return io_mapping_map_wc(&obj->mm.region->iomap, offset, PAGE_SIZE);
+}
+
+void __iomem *i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
+						      unsigned long n)
+{
+	resource_size_t offset;
+
+	offset = i915_gem_object_get_dma_address(obj, n);
+
+	return io_mapping_map_atomic_wc(&obj->mm.region->iomap, offset);
+}
+
+void __iomem *i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
+					  unsigned long n,
+					  unsigned long size)
+{
+	resource_size_t offset;
+
+	GEM_BUG_ON(!(obj->flags & I915_BO_ALLOC_CONTIGUOUS));
+
+	offset = i915_gem_object_get_dma_address(obj, n);
+
+	return io_mapping_map_wc(&obj->mm.region->iomap, offset, size);
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
 	struct intel_memory_region *region = obj->mm.region;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index ebc15fe24f58..31a6462bdbb6 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -13,6 +13,14 @@ struct drm_i915_gem_object;
 
 extern const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops;
 
+void __iomem *i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
+					  unsigned long n, unsigned long size);
+void __iomem *i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object *obj,
+					       unsigned long n);
+void __iomem *
+i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
+					unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index d5839cbd82c0..e8cc776581d0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -158,6 +158,12 @@ i915_gem_object_is_proxy(const struct drm_i915_gem_object *obj)
 	return obj->ops->flags & I915_GEM_OBJECT_IS_PROXY;
 }
 
+static inline bool
+i915_gem_object_is_mappable(const struct drm_i915_gem_object *obj)
+{
+	return obj->ops->flags & I915_GEM_OBJECT_IS_MAPPABLE;
+}
+
 static inline bool
 i915_gem_object_needs_async_cancel(const struct drm_i915_gem_object *obj)
 {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 0d934b67e547..743898944760 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -32,7 +32,8 @@ struct drm_i915_gem_object_ops {
 #define I915_GEM_OBJECT_HAS_STRUCT_PAGE	BIT(0)
 #define I915_GEM_OBJECT_IS_SHRINKABLE	BIT(1)
 #define I915_GEM_OBJECT_IS_PROXY	BIT(2)
-#define I915_GEM_OBJECT_ASYNC_CANCEL	BIT(3)
+#define I915_GEM_OBJECT_IS_MAPPABLE	BIT(3)
+#define I915_GEM_OBJECT_ASYNC_CANCEL	BIT(4)
 
 	/* Interface between the GEM object and its backing storage.
 	 * get_pages() is called once prior to the use of the associated set
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index b0ec0959c13f..fc4ad29ce881 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -7,6 +7,7 @@
 #include "i915_drv.h"
 #include "i915_gem_object.h"
 #include "i915_scatterlist.h"
+#include "i915_gem_lmem.h"
 
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 				 struct sg_table *pages,
@@ -172,7 +173,9 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
 		void *ptr;
 
 		ptr = page_mask_bits(obj->mm.mapping);
-		if (is_vmalloc_addr(ptr))
+		if (i915_gem_object_is_lmem(obj))
+			io_mapping_unmap(ptr);
+		else if (is_vmalloc_addr(ptr))
 			vunmap(ptr);
 		else
 			kunmap(kmap_to_page(ptr));
@@ -231,7 +234,7 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
 }
 
 /* The 'mapping' part of i915_gem_object_pin_map() below */
-static void *i915_gem_object_map(const struct drm_i915_gem_object *obj,
+static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
 				 enum i915_map_type type)
 {
 	unsigned long n_pages = obj->base.size >> PAGE_SHIFT;
@@ -244,6 +247,13 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj,
 	pgprot_t pgprot;
 	void *addr;
 
+	if (i915_gem_object_is_lmem(obj)) {
+		if (type != I915_MAP_WC)
+			return NULL;
+
+		return i915_gem_object_lmem_io_map(obj, 0, obj->base.size);
+	}
+
 	/* A single page can always be kmapped */
 	if (n_pages == 1 && type == I915_MAP_WB)
 		return kmap(sg_page(sgt->sgl));
@@ -289,7 +299,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 	void *ptr;
 	int err;
 
-	if (unlikely(!i915_gem_object_has_struct_page(obj)))
+	if (unlikely(!i915_gem_object_is_mappable(obj)))
 		return ERR_PTR(-ENXIO);
 
 	err = mutex_lock_interruptible(&obj->mm.lock);
@@ -321,7 +331,9 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 			goto err_unpin;
 		}
 
-		if (is_vmalloc_addr(ptr))
+		if (i915_gem_object_is_lmem(obj))
+			io_mapping_unmap(ptr);
+		else if (is_vmalloc_addr(ptr))
 			vunmap(ptr);
 		else
 			kunmap(kmap_to_page(ptr));
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 4c4954e8ce0a..9f5d903f7793 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -422,7 +422,8 @@ static void shmem_release(struct drm_i915_gem_object *obj)
 
 const struct drm_i915_gem_object_ops i915_gem_shmem_ops = {
 	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
-		 I915_GEM_OBJECT_IS_SHRINKABLE,
+		 I915_GEM_OBJECT_IS_SHRINKABLE |
+		 I915_GEM_OBJECT_IS_MAPPABLE,
 
 	.get_pages = shmem_get_pages,
 	.put_pages = shmem_put_pages,
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
index 3c5d17b2b670..686e0e909280 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
@@ -86,7 +86,9 @@ static void huge_put_pages(struct drm_i915_gem_object *obj,
 
 static const struct drm_i915_gem_object_ops huge_ops = {
 	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
-		 I915_GEM_OBJECT_IS_SHRINKABLE,
+		 I915_GEM_OBJECT_IS_SHRINKABLE |
+		 I915_GEM_OBJECT_IS_MAPPABLE,
+
 	.get_pages = huge_get_pages,
 	.put_pages = huge_put_pages,
 };
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 1e9a0eef17fc..ba98e8254b80 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -13,8 +13,10 @@
 
 #include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
+#include "gem/i915_gem_object_blt.h"
 #include "gem/selftests/mock_context.h"
 #include "gt/intel_gt.h"
+#include "selftests/igt_flush_test.h"
 #include "selftests/i915_random.h"
 
 static void close_objects(struct list_head *objects)
@@ -274,6 +276,79 @@ static int igt_lmem_create(void *arg)
 	return err;
 }
 
+static int igt_lmem_write_cpu(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	struct intel_context *ce = i915->engine[BCS0]->kernel_context;
+	struct drm_i915_gem_object *obj;
+	struct rnd_state prng;
+	u32 *vaddr;
+	u32 dword;
+	u32 val;
+	u32 sz;
+	int err;
+
+	if (!HAS_ENGINE(i915, BCS0))
+		return 0;
+
+	sz = round_up(prandom_u32_state(&prng) % SZ_32M, PAGE_SIZE);
+
+	obj = i915_gem_object_create_lmem(i915, sz, I915_BO_ALLOC_CONTIGUOUS);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);
+	if (IS_ERR(vaddr)) {
+		pr_err("Failed to iomap lmembar; err=%d\n", (int)PTR_ERR(vaddr));
+		err = PTR_ERR(vaddr);
+		goto out_put;
+	}
+
+	val = prandom_u32_state(&prng);
+
+	/* Write from gpu and then read from cpu */
+	err = i915_gem_object_fill_blt(obj, ce, val);
+	if (err)
+		goto out_unpin;
+
+	i915_gem_object_lock(obj);
+	err = i915_gem_object_set_to_wc_domain(obj, true);
+	i915_gem_object_unlock(obj);
+	if (err)
+		goto out_unpin;
+
+	for (dword = 0; dword < sz / sizeof(u32); ++dword) {
+		if (vaddr[dword] != val) {
+			pr_err("vaddr[%u]=%u, val=%u\n", dword, vaddr[dword],
+			        val);
+			err = -EINVAL;
+			break;
+		}
+	}
+
+	/* Write from the cpu and read again from the cpu */
+	memset32(vaddr, val ^ 0xdeadbeaf, sz / sizeof(u32));
+
+	for (dword = 0; dword < sz / sizeof(u32); ++dword) {
+		if (vaddr[dword] != (val ^ 0xdeadbeaf)) {
+			pr_err("vaddr[%u]=%u, val=%u\n", dword, vaddr[dword],
+			        val ^ 0xdeadbeaf);
+			err = -EINVAL;
+			break;
+		}
+	}
+
+out_unpin:
+	i915_gem_object_unpin_map(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	if (igt_flush_test(i915, I915_WAIT_LOCKED))
+		err = -EIO;
+
+	return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
@@ -313,6 +388,7 @@ int intel_memory_region_live_selftests(struct drm_i915_private *i915)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_lmem_create),
+		SUBTEST(igt_lmem_write_cpu),
 	};
 	int err;
 
-- 
2.20.1

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

  parent reply	other threads:[~2019-09-27 17:34 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-27 17:33 [PATCH 00/22] LMEM basics Matthew Auld
2019-09-27 17:33 ` [PATCH 01/22] drm/i915: check for kernel_context Matthew Auld
2019-09-27 17:37   ` Chris Wilson
2019-09-27 17:33 ` [PATCH 02/22] drm/i915: simplify i915_gem_init_early Matthew Auld
2019-09-27 17:39   ` Chris Wilson
2019-09-27 17:33 ` [PATCH 03/22] drm/i915: introduce intel_memory_region Matthew Auld
2019-09-27 18:08   ` Chris Wilson
2019-09-27 18:21   ` Chris Wilson
2019-09-27 18:24   ` Chris Wilson
2019-09-27 18:25     ` Chris Wilson
2019-09-27 20:27   ` Chris Wilson
2019-09-27 20:30   ` Chris Wilson
2019-09-27 17:33 ` [PATCH 04/22] drm/i915/region: support continuous allocations Matthew Auld
2019-09-27 18:35   ` Chris Wilson
2019-09-27 18:46   ` Ruhl, Michael J
2019-09-27 17:33 ` [PATCH 05/22] drm/i915/region: support volatile objects Matthew Auld
2019-09-27 17:33 ` [PATCH 06/22] drm/i915: Add memory region information to device_info Matthew Auld
2019-09-27 17:33 ` [PATCH 07/22] drm/i915: support creating LMEM objects Matthew Auld
2019-09-27 18:45   ` Chris Wilson
2019-09-27 17:33 ` [PATCH 08/22] drm/i915: setup io-mapping for LMEM Matthew Auld
2019-09-27 17:33 ` Matthew Auld [this message]
2019-09-27 19:24   ` [PATCH 09/22] drm/i915/lmem: support kernel mapping Chris Wilson
2019-09-27 20:39   ` Chris Wilson
2019-09-27 17:33 ` [PATCH 10/22] drm/i915/selftests: add write-dword test for LMEM Matthew Auld
2019-09-27 19:27   ` Chris Wilson
2019-09-27 20:42   ` Chris Wilson
2019-09-30  9:58     ` Matthew Auld
2019-09-30 10:46       ` Chris Wilson
2019-09-27 17:33 ` [PATCH 11/22] drm/i915/selftest: extend coverage to include LMEM huge-pages Matthew Auld
2019-09-27 17:33 ` [PATCH 12/22] drm/i915: enumerate and init each supported region Matthew Auld
2019-09-27 20:44   ` Chris Wilson
2019-09-27 17:34 ` [PATCH 13/22] drm/i915: treat shmem as a region Matthew Auld
2019-09-27 17:34 ` [PATCH 14/22] drm/i915: treat stolen " Matthew Auld
2019-09-27 19:30   ` Chris Wilson
2019-09-27 17:34 ` [PATCH 15/22] drm/i915: define HAS_MAPPABLE_APERTURE Matthew Auld
2019-09-27 17:34 ` [PATCH 16/22] drm/i915: do not map aperture if it is not available Matthew Auld
2019-09-27 17:34 ` [PATCH 17/22] drm/i915: set num_fence_regs to 0 if there is no aperture Matthew Auld
2019-09-27 20:49   ` Chris Wilson
2019-09-27 17:34 ` [PATCH 18/22] drm/i915/selftests: check for missing aperture Matthew Auld
2019-09-27 20:51   ` Chris Wilson
2019-09-27 17:34 ` [PATCH 19/22] drm/i915: error capture with no ggtt slot Matthew Auld
2019-09-27 17:52   ` Chris Wilson
2019-09-27 17:34 ` [PATCH 20/22] drm/i915: Don't try to place HWS in non-existing mappable region Matthew Auld
2019-09-27 17:34 ` [PATCH 21/22] drm/i915: check for missing aperture in GTT pread/pwrite paths Matthew Auld
2019-09-27 17:57   ` Chris Wilson
2019-09-27 17:34 ` [PATCH 22/22] HAX drm/i915: add the fake lmem region Matthew Auld
2019-09-27 18:29 ` ✗ Fi.CI.CHECKPATCH: warning for LMEM basics Patchwork
2019-09-27 18:39 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-09-27 18:51 ` ✓ Fi.CI.BAT: success " Patchwork
2019-09-28  9:47 ` ✗ Fi.CI.IGT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190927173409.31175-10-matthew.auld@intel.com \
    --to=matthew.auld@intel.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox