All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
@ 2019-02-14 14:56 Matthew Auld
  2019-02-14 14:56 ` [RFC PATCH 01/42] drm/i915: support 1G pages for the 48b PPGTT Matthew Auld
                   ` (44 more replies)
  0 siblings, 45 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:56 UTC (permalink / raw)
  To: intel-gfx

In preparation for upcoming devices with device local memory, introduce the
concept of different memory regions, and a simple buddy allocator to manage
them.

At the end of the series are a couple of HAX patches which introduce a fake
local memory region for testing purposes. Currently smoke tested on a Skull
Canyon device.

Abdiel Janulgue (13):
  drm/i915: Add memory region information to device_info
  drm/i915/lmem: add helper to get CPU visible pfn
  drm/i915/lmem: support kernel mapping
  drm/i915: Split out GTT fault handler to make it generic
  drm/i915: Set correct vmf source pages for gem objects
  drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET
  drm/i915: cpu-map based dumb buffers
  drm/i915: Add fill_pages handler for dma_buf imported objects
  UPSTREAM: drm/i915/query: Split out query item checks
  drm/i915/query: Expose memory regions through the query uAPI
  drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION
  drm/i915: enumerate and init each supported region
  drm/i915: setup io-mapping for LMEM

Daniele Ceraolo Spurio (5):
  drm/i915: define HAS_MAPPABLE_APERTURE
  drm/i915: do not map aperture if it is not available.
  drm/i915: expose missing map_gtt support to users
  drm/i915: set num_fence_regs to 0 if there is no aperture
  drm/i915: error capture with no ggtt slot

Matthew Auld (23):
  drm/i915: support 1G pages for the 48b PPGTT
  drm/i915: enable platform support for 1G pages
  drm/i915: buddy allocator
  drm/i915: introduce intel_memory_region
  drm/i915/region: support basic eviction
  drm/i915/region: support continuous allocations
  drm/i915/region: support volatile objects
  drm/i915: support creating LMEM objects
  drm/i915/selftests: exercise writes to LMEM
  drm/i915/selftests: exercise huge-pages for LMEM
  drm/i915: support object clearing via blitter engine
  drm/i915: introduce kernel blitter_context
  drm/i915: support copying objects via blitter engine
  drm/i915: support basic object migration
  drm/i915/lmem: support CPU relocations
  drm/i915: add vfunc for pread
  drm/i915/lmem: support pread
  drm/i915/lmem: support pwrite
  drm/i915/lmem: include debugfs metrics
  drm/i915: treat shmem as a region
  drm/i915: treat stolen as a region
  HAX drm/i915: add the fake lmem region
  HAX drm/i915/lmem: default userspace allocations to LMEM

Michal Wajdeczko (1):
  drm/i915: Don't try to place HWS in non-existing mappable region

 arch/x86/kernel/early-quirks.c                |   26 +
 drivers/gpu/drm/i915/Makefile                 |    3 +
 drivers/gpu/drm/i915/i915_debugfs.c           |   31 +
 drivers/gpu/drm/i915/i915_drv.c               |   19 +-
 drivers/gpu/drm/i915/i915_drv.h               |   37 +-
 drivers/gpu/drm/i915/i915_gem.c               | 1005 +++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_buddy.c         |  206 ++++
 drivers/gpu/drm/i915/i915_gem_buddy.h         |  118 ++
 drivers/gpu/drm/i915/i915_gem_context.c       |   13 +
 drivers/gpu/drm/i915/i915_gem_dmabuf.c        |   14 +
 drivers/gpu/drm/i915/i915_gem_execbuffer.c    |   67 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c           |  136 ++-
 drivers/gpu/drm/i915/i915_gem_gtt.h           |    4 +-
 drivers/gpu/drm/i915/i915_gem_object.c        |    1 +
 drivers/gpu/drm/i915/i915_gem_object.h        |   43 +-
 drivers/gpu/drm/i915/i915_gem_shrinker.c      |   59 +
 drivers/gpu/drm/i915/i915_gem_stolen.c        |   66 +-
 drivers/gpu/drm/i915/i915_gpu_error.c         |   63 +-
 drivers/gpu/drm/i915/i915_pci.c               |   18 +-
 drivers/gpu/drm/i915/i915_query.c             |   97 +-
 drivers/gpu/drm/i915/intel_device_info.h      |    1 +
 drivers/gpu/drm/i915/intel_engine_cs.c        |    2 +-
 drivers/gpu/drm/i915/intel_gpu_commands.h     |    3 +
 drivers/gpu/drm/i915/intel_memory_region.c    |  286 +++++
 drivers/gpu/drm/i915/intel_memory_region.h    |  140 +++
 drivers/gpu/drm/i915/intel_region_lmem.c      |  388 +++++++
 drivers/gpu/drm/i915/intel_region_lmem.h      |   46 +
 drivers/gpu/drm/i915/selftests/huge_pages.c   |  204 +++-
 .../gpu/drm/i915/selftests/i915_gem_buddy.c   |  209 ++++
 .../gpu/drm/i915/selftests/i915_gem_object.c  |  150 +++
 .../drm/i915/selftests/i915_live_selftests.h  |    1 +
 .../drm/i915/selftests/i915_mock_selftests.h  |    2 +
 .../drm/i915/selftests/intel_memory_region.c  |  911 +++++++++++++++
 .../gpu/drm/i915/selftests/mock_gem_device.c  |    8 +-
 drivers/gpu/drm/i915/selftests/mock_region.c  |   75 ++
 drivers/gpu/drm/i915/selftests/mock_region.h  |   35 +
 include/drm/i915_drm.h                        |    3 +
 include/uapi/drm/i915_drm.h                   |   94 +-
 38 files changed, 4396 insertions(+), 188 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_buddy.c
 create mode 100644 drivers/gpu/drm/i915/i915_gem_buddy.h
 create mode 100644 drivers/gpu/drm/i915/intel_memory_region.c
 create mode 100644 drivers/gpu/drm/i915/intel_memory_region.h
 create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.c
 create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.h
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_buddy.c
 create mode 100644 drivers/gpu/drm/i915/selftests/intel_memory_region.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.h

-- 
2.20.1

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* [RFC PATCH 01/42] drm/i915: support 1G pages for the 48b PPGTT
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
@ 2019-02-14 14:56 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 02/42] drm/i915: enable platform support for 1G pages Matthew Auld
                   ` (43 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:56 UTC (permalink / raw)
  To: intel-gfx

Support inserting 1G gtt pages into the 48b PPGTT.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c         |  4 ++++
 drivers/gpu/drm/i915/i915_gem_gtt.c         | 16 +++++++++++++---
 drivers/gpu/drm/i915/i915_gem_gtt.h         |  4 +++-
 drivers/gpu/drm/i915/selftests/huge_pages.c |  3 ++-
 4 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 2aeea977283f..fed46fe19c03 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -118,10 +118,14 @@ stringify_page_sizes(unsigned int page_sizes, char *buf, size_t len)
 		return "64K";
 	case I915_GTT_PAGE_SIZE_2M:
 		return "2M";
+	case I915_GTT_PAGE_SIZE_1G:
+		return "1G";
 	default:
 		if (!buf)
 			return "M";
 
+		if (page_sizes & I915_GTT_PAGE_SIZE_1G)
+			x += snprintf(buf + x, len - x, "1G, ");
 		if (page_sizes & I915_GTT_PAGE_SIZE_2M)
 			x += snprintf(buf + x, len - x, "2M, ");
 		if (page_sizes & I915_GTT_PAGE_SIZE_64K)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d646d37eec2f..de67a2f1ccfe 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1069,9 +1069,19 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 		gen8_pte_t *vaddr;
 		u16 index, max;
 
-		if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M &&
-		    IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) &&
-		    rem >= I915_GTT_PAGE_SIZE_2M && !idx.pte) {
+		if (unlikely(vma->page_sizes.sg & I915_GTT_PAGE_SIZE_1G) &&
+		    IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_1G) &&
+		    rem >= I915_GTT_PAGE_SIZE_1G && !(idx.pte | idx.pde)) {
+			index = idx.pdpe;
+			max = GEN8_PML4ES_PER_PML4;
+			page_size = I915_GTT_PAGE_SIZE_1G;
+
+			encode |= GEN8_PDPE_PS_1G;
+
+			vaddr = kmap_atomic_px(pdp);
+		} else if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M &&
+			   IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) &&
+			   rem >= I915_GTT_PAGE_SIZE_2M && !idx.pte) {
 			index = idx.pde;
 			max = I915_PDES;
 			page_size = I915_GTT_PAGE_SIZE_2M;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 03ade71b8d9a..9a8066779f47 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -46,9 +46,10 @@
 #define I915_GTT_PAGE_SIZE_4K	BIT_ULL(12)
 #define I915_GTT_PAGE_SIZE_64K	BIT_ULL(16)
 #define I915_GTT_PAGE_SIZE_2M	BIT_ULL(21)
+#define I915_GTT_PAGE_SIZE_1G	BIT_ULL(30)
 
 #define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K
-#define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M
+#define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_1G
 
 #define I915_GTT_PAGE_MASK -I915_GTT_PAGE_SIZE
 
@@ -160,6 +161,7 @@ typedef u64 gen8_ppgtt_pml4e_t;
 
 #define GEN8_PDE_IPS_64K BIT(11)
 #define GEN8_PDE_PS_2M   BIT(7)
+#define GEN8_PDPE_PS_1G  BIT(7)
 
 struct sg_table;
 
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index a9a2fa35876f..b6d84939592b 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -30,6 +30,7 @@
 #include "i915_random.h"
 
 static const unsigned int page_sizes[] = {
+	I915_GTT_PAGE_SIZE_1G,
 	I915_GTT_PAGE_SIZE_2M,
 	I915_GTT_PAGE_SIZE_64K,
 	I915_GTT_PAGE_SIZE_4K,
@@ -1220,7 +1221,7 @@ static int igt_ppgtt_exhaust_huge(void *arg)
 	 */
 
 	n = 0;
-	for_each_set_bit(i, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1)
+	for_each_set_bit(i, &supported, ilog2(I915_GTT_PAGE_SIZE_2M) + 1)
 		pages[n++] = BIT(i);
 
 	for (size_mask = 2; size_mask < BIT(n); size_mask++) {
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 02/42] drm/i915: enable platform support for 1G pages
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
  2019-02-14 14:56 ` [RFC PATCH 01/42] drm/i915: support 1G pages for the 48b PPGTT Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 03/42] drm/i915: buddy allocator Matthew Auld
                   ` (42 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

For gen8+ platforms which support the 48b PPGTT, enable support for 1G
pages. Also enable for mock testing.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c                  | 6 ++++--
 drivers/gpu/drm/i915/selftests/mock_gem_device.c | 3 ++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index c4d6b8da9b03..4a7b587e9a92 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -431,7 +431,8 @@ static const struct intel_device_info intel_haswell_gt3_info = {
 	GEN(8), \
 	BDW_COLORS, \
 	.page_sizes = I915_GTT_PAGE_SIZE_4K | \
-		      I915_GTT_PAGE_SIZE_2M, \
+		      I915_GTT_PAGE_SIZE_2M | \
+		      I915_GTT_PAGE_SIZE_1G, \
 	.has_logical_ring_contexts = 1, \
 	.ppgtt = INTEL_PPGTT_FULL_4LVL, \
 	.has_64bit_reloc = 1, \
@@ -491,7 +492,8 @@ static const struct intel_device_info intel_cherryview_info = {
 #define GEN9_DEFAULT_PAGE_SIZES \
 	.page_sizes = I915_GTT_PAGE_SIZE_4K | \
 		      I915_GTT_PAGE_SIZE_64K | \
-		      I915_GTT_PAGE_SIZE_2M
+		      I915_GTT_PAGE_SIZE_2M | \
+		      I915_GTT_PAGE_SIZE_1G
 
 #define GEN9_FEATURES \
 	GEN8_FEATURES, \
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index fc516a2970f4..876f4e6dadac 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -182,7 +182,8 @@ struct drm_i915_private *mock_gem_device(void)
 	mkwrite_device_info(i915)->page_sizes =
 		I915_GTT_PAGE_SIZE_4K |
 		I915_GTT_PAGE_SIZE_64K |
-		I915_GTT_PAGE_SIZE_2M;
+		I915_GTT_PAGE_SIZE_2M |
+		I915_GTT_PAGE_SIZE_1G;
 
 	mock_uncore_init(i915);
 	i915_gem_init__mm(i915);
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 03/42] drm/i915: buddy allocator
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
  2019-02-14 14:56 ` [RFC PATCH 01/42] drm/i915: support 1G pages for the 48b PPGTT Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 02/42] drm/i915: enable platform support for 1G pages Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-15 12:34   ` Jani Nikula
  2019-02-14 14:57 ` [RFC PATCH 04/42] drm/i915: introduce intel_memory_region Matthew Auld
                   ` (41 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Really simply buddy allocator.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/i915_gem_buddy.c         | 206 +++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_buddy.h         | 118 ++++++++++
 .../gpu/drm/i915/selftests/i915_gem_buddy.c   | 209 ++++++++++++++++++
 .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
 5 files changed, 535 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_buddy.c
 create mode 100644 drivers/gpu/drm/i915/i915_gem_buddy.h
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_buddy.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1787e1299b1b..e5ce813d1936 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -61,6 +61,7 @@ i915-y += \
 	  i915_active.o \
 	  i915_cmd_parser.o \
 	  i915_gem_batch_pool.o \
+	  i915_gem_buddy.o \
 	  i915_gem_clflush.o \
 	  i915_gem_context.o \
 	  i915_gem_dmabuf.o \
diff --git a/drivers/gpu/drm/i915/i915_gem_buddy.c b/drivers/gpu/drm/i915/i915_gem_buddy.c
new file mode 100644
index 000000000000..4dc688c091a2
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_buddy.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/list.h>
+
+#include "i915_gem_buddy.h"
+#include "i915_gem.h"
+
+int i915_gem_buddy_init(struct i915_gem_buddy_mm *mm, u64 size, u64 min_size)
+{
+	unsigned int i;
+
+	/*
+	 * XXX: if not a power of 2, maybe split into power of 2 blocks,
+	 * effectively having multiple roots, similar to if we had a global
+	 * MAX_ORDER.
+	 */
+	size = rounddown_pow_of_two(size);
+	min_size = roundup_pow_of_two(min_size);
+
+	if (size < min_size)
+		return -EINVAL;
+
+	if (min_size < PAGE_SIZE)
+		return -EINVAL;
+
+	mm->max_order = ilog2(size) - ilog2(min_size);
+	mm->min_size = min_size;
+
+	mm->free_list = kmalloc_array(mm->max_order + 1,
+				      sizeof(struct list_head),
+				      GFP_KERNEL);
+	if (!mm->free_list)
+		return -ENOMEM;
+
+	for (i = 0; i <= mm->max_order; ++i)
+		INIT_LIST_HEAD(&mm->free_list[i]);
+
+	mm->blocks = KMEM_CACHE(i915_gem_buddy_block, SLAB_HWCACHE_ALIGN);
+	if (!mm->blocks)
+		goto out_free_list;
+
+	mm->root = kmem_cache_zalloc(mm->blocks, GFP_KERNEL);
+	if (!mm->root)
+		goto out_free_blocks;
+
+	mm->root->header = mm->max_order;
+
+	list_add(&mm->root->link, &mm->free_list[mm->max_order]);
+
+	return 0;
+
+out_free_blocks:
+	kmem_cache_destroy(mm->blocks);
+out_free_list:
+	kfree(mm->free_list);
+
+	return -ENOMEM;
+}
+
+void i915_gem_buddy_fini(struct i915_gem_buddy_mm *mm)
+{
+	if (WARN_ON(i915_gem_buddy_block_allocated(mm->root)))
+		return;
+
+	kfree(mm->free_list);
+	kmem_cache_free(mm->blocks, mm->root);
+	kmem_cache_destroy(mm->blocks);
+}
+
+/*
+ * The 'order' here means:
+ *
+ * 0 = 2^0 * mm->min_size
+ * 1 = 2^1 * mm->min_size
+ * 2 = 2^2 * mm->min_size
+ * ...
+ */
+struct i915_gem_buddy_block *
+i915_gem_buddy_alloc(struct i915_gem_buddy_mm *mm, unsigned int order)
+{
+	struct i915_gem_buddy_block *block = NULL;
+	struct i915_gem_buddy_block *root;
+	unsigned int i;
+
+	for (i = order; i <= mm->max_order; ++i) {
+		block = list_first_entry_or_null(&mm->free_list[i],
+						 struct i915_gem_buddy_block,
+						 link);
+		if (block)
+			break;
+	}
+
+	if (!block)
+		return ERR_PTR(-ENOSPC);
+
+	GEM_BUG_ON(i915_gem_buddy_block_allocated(block));
+
+	root = block;
+
+	while (i != order) {
+		u64 offset = i915_gem_buddy_block_offset(block);
+
+		block->left = kmem_cache_zalloc(mm->blocks, GFP_KERNEL);
+		if (!block->left)
+			goto out_free_blocks;
+
+		block->left->header = offset;
+		block->left->header |= I915_GEM_BUDDY_HEADER_ALLOCATED;
+		block->left->header |= i - 1;
+		block->left->parent = block;
+
+		INIT_LIST_HEAD(&block->left->link);
+
+		block->right = kmem_cache_zalloc(mm->blocks, GFP_KERNEL);
+		if (!block->right) {
+			kmem_cache_free(mm->blocks, block->left);
+			goto out_free_blocks;
+		}
+
+		block->right->header = offset + (BIT(i - 1) * mm->min_size);
+		block->right->header |= i - 1;
+		block->right->parent = block;
+
+		list_add(&block->right->link, &mm->free_list[i - 1]);
+
+		block = block->left;
+		i--;
+	}
+
+	root->header |= I915_GEM_BUDDY_HEADER_ALLOCATED;
+	list_del(&root->link);
+
+	return block;
+
+out_free_blocks:
+	while (block != root) {
+		if (block->right)
+			list_del(&block->right->link);
+
+		kmem_cache_free(mm->blocks, block->left);
+		kmem_cache_free(mm->blocks, block->right);
+
+		block = block->parent;
+	}
+
+	return ERR_PTR(-ENOMEM);
+}
+
+void i915_gem_buddy_free(struct i915_gem_buddy_mm *mm,
+			 struct i915_gem_buddy_block *block)
+{
+	GEM_BUG_ON(!i915_gem_buddy_block_allocated(block));
+
+	while (block->parent) {
+		struct i915_gem_buddy_block *buddy;
+		struct i915_gem_buddy_block *parent;
+
+		parent = block->parent;
+
+		if (parent->left == block)
+			buddy = parent->right;
+		else
+			buddy = parent->left;
+
+		if (i915_gem_buddy_block_allocated(buddy))
+			break;
+
+		list_del(&buddy->link);
+
+		kmem_cache_free(mm->blocks, block);
+		kmem_cache_free(mm->blocks, buddy);
+
+		block = parent;
+	}
+
+	block->header &= ~I915_GEM_BUDDY_HEADER_ALLOCATED;
+	list_add(&block->link,
+		 &mm->free_list[i915_gem_buddy_block_order(block)]);
+}
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/i915_gem_buddy.c"
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_buddy.h b/drivers/gpu/drm/i915/i915_gem_buddy.h
new file mode 100644
index 000000000000..b3f06e9086b3
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_buddy.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __I915_GEM_BUDDY_H__
+#define __I915_GEM_BUDDY_H__
+
+#include <linux/bitops.h>
+
+struct list_head;
+
+struct i915_gem_buddy_block {
+#define I915_GEM_BUDDY_HEADER_OFFSET (~(BIT(12) - 1))
+#define I915_GEM_BUDDY_HEADER_ALLOCATED BIT(11)
+#define I915_GEM_BUDDY_HEADER_ORDER (BIT(11) - 1)
+	u64 header;
+
+	struct i915_gem_buddy_block *left;
+	struct i915_gem_buddy_block *right;
+	struct i915_gem_buddy_block *parent;
+
+	/* Always safe to reuse once the block is allocated */
+	struct list_head link;
+};
+
+/*
+ * Binary Buddy System
+ *
+ * XXX: Idealy we would just use the intrusive version of the buddy system i.e
+ * the classical version, where we store the block info in the free blocks, but
+ * if we are dealing with something like stolen memory, this would very quickly
+ * turn into a dumbster fire with having to memremap/ioremap parts of stolen in
+ * the allocator.
+ */
+struct i915_gem_buddy_mm {
+	unsigned int max_order;
+	/* Must be at least PAGE_SIZE */
+	u64 min_size;
+
+	struct kmem_cache *blocks;
+
+	/* Maintain a free list for each order. */
+	struct list_head *free_list;
+
+	/*
+	 * Maintain an explicit binary tree to track the allocation of the
+	 * address space. This gives us a simple way of finding a buddy block
+	 * and performing the potentially recursive merge step when freeing a
+	 * block.  Nodes are either allocated or free, in which case they will
+	 * also exist on the respective free list.
+	 */
+	struct i915_gem_buddy_block *root;
+};
+
+static inline u64
+i915_gem_buddy_block_offset(struct i915_gem_buddy_block *block)
+{
+	return block->header & I915_GEM_BUDDY_HEADER_OFFSET;
+}
+
+static inline unsigned int
+i915_gem_buddy_block_order(struct i915_gem_buddy_block *block)
+{
+	return block->header & I915_GEM_BUDDY_HEADER_ORDER;
+}
+
+static inline bool
+i915_gem_buddy_block_allocated(struct i915_gem_buddy_block *block)
+{
+	return block->header & I915_GEM_BUDDY_HEADER_ALLOCATED;
+}
+
+static inline u64
+i915_gem_buddy_block_size(struct i915_gem_buddy_mm *mm,
+		          struct i915_gem_buddy_block *block)
+{
+	return BIT(i915_gem_buddy_block_order(block)) * mm->min_size;
+}
+
+static inline u64 i915_gem_buddy_size(struct i915_gem_buddy_mm *mm)
+{
+	return i915_gem_buddy_block_size(mm, mm->root);
+}
+
+int i915_gem_buddy_init(struct i915_gem_buddy_mm *mm,
+			u64 size,
+			u64 min_size);
+
+void i915_gem_buddy_fini(struct i915_gem_buddy_mm *mm);
+
+struct i915_gem_buddy_block *
+i915_gem_buddy_alloc(struct i915_gem_buddy_mm *mm,
+		     unsigned int order);
+
+void i915_gem_buddy_free(struct i915_gem_buddy_mm *mm,
+			 struct i915_gem_buddy_block *block);
+
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_buddy.c b/drivers/gpu/drm/i915/selftests/i915_gem_buddy.c
new file mode 100644
index 000000000000..c6782a39a1e9
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_buddy.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#define SZ_64G (1ULL << 36)
+
+static int igt_buddy_init(void *arg)
+{
+	struct i915_gem_buddy_mm mm;
+	u64 size;
+	int err = 0;
+
+	for (size = PAGE_SIZE; size <= SZ_64G; size <<= 1) {
+		struct i915_gem_buddy_block *block;
+
+		err = i915_gem_buddy_init(&mm, size, PAGE_SIZE);
+		if (err) {
+			pr_err("buddy_init with size=%llx\n failed(%d)\n",
+			       size, err);
+			return err;
+		}
+
+		block = i915_gem_buddy_alloc(&mm, mm.max_order);
+		if (IS_ERR(block)) {
+			err = PTR_ERR(block);
+			pr_err("buddy_alloc with size=%llx\n failed(%d)\n",
+			       size, err);
+			goto out_buddy_fini;
+		}
+
+		if (i915_gem_buddy_block_order(block) != mm.max_order) {
+			pr_err("buddy_alloc size mismatch\n");
+			err = -EINVAL;
+		}
+
+		if (i915_gem_buddy_block_offset(block) != 0) {
+			pr_err("buddy_alloc offset mismatch\n");
+			err = -EINVAL;
+		}
+
+		if (!list_empty(&mm.free_list[mm.max_order])) {
+			pr_err("buddy_alloc state mismatch, block is on free list\n");
+			err = -EINVAL;
+		}
+
+		if (block != mm.root) {
+			pr_err("buddy_alloc state mismatch, block != root\n");
+			err = -EINVAL;
+		}
+
+		if (block->left || block->right) {
+			pr_err("buddy_alloc state mismatch, block is not leaf\n");
+			err = -EINVAL;
+		}
+
+		i915_gem_buddy_free(&mm, block);
+
+		if (list_empty(&mm.free_list[mm.max_order])) {
+			pr_err("buddy_free state mismatch, block not on free list\n");
+			err = -EINVAL;
+		}
+
+		i915_gem_buddy_fini(&mm);
+
+		if (err)
+			return err;
+	}
+
+	return 0;
+
+out_buddy_fini:
+	i915_gem_buddy_fini(&mm);
+
+	return err;
+}
+
+static int igt_buddy_alloc(void *arg)
+{
+	struct i915_gem_buddy_mm mm;
+	u64 size;
+	int order;
+	int err;
+
+	err = i915_gem_buddy_init(&mm, SZ_64G, PAGE_SIZE);
+	if (err) {
+		pr_err("buddy_init with size=%llx\n failed(%d)\n", SZ_64G, err);
+		return err;
+	}
+
+	for (order = mm.max_order; order >= 0; order--) {
+		struct i915_gem_buddy_block *block, *on;
+		struct list_head blocks;
+		u64 block_size;
+		u64 offset;
+		u64 prev_offset;
+		u64 n_blocks;
+
+		size = i915_gem_buddy_size(&mm);
+		if (size != SZ_64G) {
+			pr_err("buddy_size mismatch\n");
+			err = -EINVAL;
+			break;
+		}
+
+		if (list_empty(&mm.free_list[mm.max_order])) {
+			pr_err("root not on the free list\n");
+			err = -EINVAL;
+			break;
+		}
+
+		pr_info("filling address space(%llx) with order=%d\n",
+			i915_gem_buddy_size(&mm), order);
+
+		prev_offset = 0;
+		n_blocks = div64_u64(size, BIT(order) * mm.min_size);
+		INIT_LIST_HEAD(&blocks);
+
+		while (n_blocks--) {
+			block = i915_gem_buddy_alloc(&mm, order);
+			if (IS_ERR(block)) {
+				err = PTR_ERR(block);
+				if (err == -ENOMEM) {
+					pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
+					        order);
+				} else {
+					pr_err("buddy_alloc with order=%d failed(%d)\n",
+					       order, err);
+				}
+
+				break;
+			}
+
+			list_add(&block->link, &blocks);
+
+			if (i915_gem_buddy_block_order(block) != order) {
+				pr_err("buddy_alloc order mismatch\n");
+				err = -EINVAL;
+				break;
+			}
+
+			block_size = i915_gem_buddy_block_size(&mm, block);
+			offset = i915_gem_buddy_block_offset(block);
+
+			if (!IS_ALIGNED(offset, block_size)) {
+				pr_err("buddy_alloc offset misaligned, offset=%llx, block_size=%llu\n",
+					offset, block_size);
+				err = -EINVAL;
+				break;
+			}
+
+			if (offset && offset != (prev_offset + block_size)) {
+				pr_err("buddy_alloc offset mismatch, prev_offset=%llx, offset=%llx\n",
+				       prev_offset, offset);
+				err = -EINVAL;
+				break;
+			}
+
+			prev_offset = offset;
+		}
+
+		list_for_each_entry_safe(block, on, &blocks, link) {
+			list_del(&block->link);
+			i915_gem_buddy_free(&mm, block);
+		}
+
+		if (err)
+			break;
+	}
+
+	i915_gem_buddy_fini(&mm);
+
+	if (err == -ENOMEM)
+		err = 0;
+
+	return err;
+}
+
+int i915_gem_buddy_mock_selftests(void)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_buddy_init),
+		SUBTEST(igt_buddy_alloc),
+	};
+
+	return i915_subtests(tests, NULL);
+}
+
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 88e5ab586337..984e07ed65e5 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -24,3 +24,4 @@ selftest(evict, i915_gem_evict_mock_selftests)
 selftest(gtt, i915_gem_gtt_mock_selftests)
 selftest(hugepages, i915_gem_huge_page_mock_selftests)
 selftest(contexts, i915_gem_context_mock_selftests)
+selftest(buddy, i915_gem_buddy_mock_selftests)
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (2 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 03/42] drm/i915: buddy allocator Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:16   ` Chris Wilson
  2019-02-26 13:00   ` Tvrtko Ursulin
  2019-02-14 14:57 ` [RFC PATCH 05/42] drm/i915/region: support basic eviction Matthew Auld
                   ` (40 subsequent siblings)
  44 siblings, 2 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Support memory regions, as defined by a given (start, end), and allow
creating GEM objects which are backed by said region.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/i915_drv.h               |   1 +
 drivers/gpu/drm/i915/i915_gem.c               |   1 +
 drivers/gpu/drm/i915/i915_gem_object.h        |   9 +
 drivers/gpu/drm/i915/intel_memory_region.c    | 232 ++++++++++++++++++
 drivers/gpu/drm/i915/intel_memory_region.h    | 126 ++++++++++
 drivers/gpu/drm/i915/selftests/huge_pages.c   |  81 ++++++
 .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
 .../drm/i915/selftests/intel_memory_region.c  | 128 ++++++++++
 .../gpu/drm/i915/selftests/mock_gem_device.c  |   1 +
 drivers/gpu/drm/i915/selftests/mock_region.c  |  71 ++++++
 drivers/gpu/drm/i915/selftests/mock_region.h  |  35 +++
 12 files changed, 687 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/intel_memory_region.c
 create mode 100644 drivers/gpu/drm/i915/intel_memory_region.h
 create mode 100644 drivers/gpu/drm/i915/selftests/intel_memory_region.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index e5ce813d1936..96be264fa382 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -88,6 +88,7 @@ i915-y += \
 	  intel_engine_cs.o \
 	  intel_hangcheck.o \
 	  intel_lrc.o \
+	  intel_memory_region.o \
 	  intel_mocs.o \
 	  intel_ringbuffer.o \
 	  intel_uncore.o \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 17fe942eaafa..0bea7d889284 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -72,6 +72,7 @@
 #include "intel_wopcm.h"
 #include "intel_workarounds.h"
 #include "intel_uc.h"
+#include "intel_memory_region.h"
 
 #include "i915_gem.h"
 #include "i915_gem_context.h"
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b421bc7a2e26..92768ab294a4 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5706,4 +5706,5 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
 #include "selftests/i915_gem_object.c"
 #include "selftests/i915_gem_coherency.c"
 #include "selftests/i915_gem.c"
+#include "selftests/intel_memory_region.c"
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index fab040331cdb..ac52f61e8ad1 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -87,6 +87,15 @@ struct drm_i915_gem_object {
 
 	const struct drm_i915_gem_object_ops *ops;
 
+	/**
+	 * Memory region for this object.
+	 */
+	struct intel_memory_region *memory_region;
+	/**
+	 * List of memory region blocks allocated for this object.
+	 */
+	struct list_head blocks;
+
 	struct {
 		/**
 		 * @vma.lock: protect the list/tree of vmas
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
new file mode 100644
index 000000000000..405d6d51194f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "intel_memory_region.h"
+#include "i915_drv.h"
+
+static void
+memory_region_free_pages(struct drm_i915_gem_object *obj,
+			 struct sg_table *pages)
+{
+
+	struct i915_gem_buddy_block *block, *on;
+
+	lockdep_assert_held(&obj->memory_region->mm_lock);
+
+	list_for_each_entry_safe(block, on, &obj->blocks, link) {
+		list_del_init(&block->link);
+		i915_gem_buddy_free(&obj->memory_region->mm, block);
+	}
+
+	sg_free_table(pages);
+	kfree(pages);
+}
+
+void
+i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
+				   struct sg_table *pages)
+{
+	mutex_lock(&obj->memory_region->mm_lock);
+	memory_region_free_pages(obj, pages);
+	mutex_unlock(&obj->memory_region->mm_lock);
+
+	obj->mm.dirty = false;
+}
+
+int
+i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
+{
+	struct intel_memory_region *mem = obj->memory_region;
+	resource_size_t size = obj->base.size;
+	struct sg_table *st;
+	struct scatterlist *sg;
+	unsigned int sg_page_sizes;
+	unsigned long n_pages;
+
+	GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.min_size));
+	GEM_BUG_ON(!list_empty(&obj->blocks));
+
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		return -ENOMEM;
+
+	n_pages = div64_u64(size, mem->mm.min_size);
+
+	if (sg_alloc_table(st, n_pages, GFP_KERNEL)) {
+		kfree(st);
+		return -ENOMEM;
+	}
+
+	sg = st->sgl;
+	st->nents = 0;
+	sg_page_sizes = 0;
+
+	mutex_lock(&mem->mm_lock);
+
+	do {
+		struct i915_gem_buddy_block *block;
+		unsigned int order;
+		u64 block_size;
+		u64 offset;
+
+		order = fls(n_pages) - 1;
+		GEM_BUG_ON(order > mem->mm.max_order);
+
+		do {
+			block = i915_gem_buddy_alloc(&mem->mm, order);
+			if (!IS_ERR(block))
+				break;
+
+			/* XXX: some kind of eviction pass, local to the device */
+			if (!order--)
+				goto err_free_blocks;
+		} while (1);
+
+		n_pages -= 1 << order;
+
+		INIT_LIST_HEAD(&block->link);
+		list_add(&block->link, &obj->blocks);
+
+		block_size = i915_gem_buddy_block_size(&mem->mm, block);
+		offset = i915_gem_buddy_block_offset(block);
+
+		sg_dma_address(sg) = mem->region.start + offset;
+		sg_dma_len(sg) = block_size;
+
+		sg->length = block_size;
+		sg_page_sizes |= block_size;
+		st->nents++;
+
+		if (!n_pages) {
+			sg_mark_end(sg);
+			break;
+		}
+
+		sg = __sg_next(sg);
+	} while (1);
+
+	mutex_unlock(&mem->mm_lock);
+
+	i915_sg_trim(st);
+
+	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
+
+	return 0;
+
+err_free_blocks:
+	memory_region_free_pages(obj, st);
+	mutex_unlock(&mem->mm_lock);
+	return -ENOSPC;
+}
+
+int i915_memory_region_init_buddy(struct intel_memory_region *mem)
+{
+	return i915_gem_buddy_init(&mem->mm, resource_size(&mem->region),
+				   mem->min_page_size);
+}
+
+void i915_memory_region_release_buddy(struct intel_memory_region *mem)
+{
+	i915_gem_buddy_fini(&mem->mm);
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_region(struct intel_memory_region *mem,
+			      resource_size_t size,
+			      unsigned int flags)
+{
+	struct drm_i915_gem_object *obj;
+
+	if (!mem)
+		return ERR_PTR(-ENODEV);
+
+	size = round_up(size, mem->min_page_size);
+
+	GEM_BUG_ON(!size);
+	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
+
+	if (size >> PAGE_SHIFT > INT_MAX)
+		return ERR_PTR(-E2BIG);
+
+	if (overflows_type(size, obj->base.size))
+		return ERR_PTR(-E2BIG);
+
+	obj = mem->ops->object_create(mem, size, flags);
+	if (IS_ERR(obj))
+		return obj;
+
+	INIT_LIST_HEAD(&obj->blocks);
+	obj->memory_region = mem;
+
+	i915_gem_object_set_cache_coherency(obj, obj->cache_level);
+
+	return obj;
+}
+
+struct intel_memory_region *
+intel_memory_region_create(struct drm_i915_private *i915,
+			   resource_size_t start,
+			   resource_size_t size,
+			   resource_size_t min_page_size,
+			   resource_size_t io_start,
+			   const struct intel_memory_region_ops *ops)
+{
+	struct intel_memory_region *mem;
+	int err;
+
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem)
+		return ERR_PTR(-ENOMEM);
+
+	mem->i915 = i915;
+	mem->region = (struct resource)DEFINE_RES_MEM(start, size);
+	mem->io_start = io_start;
+	mem->min_page_size = min_page_size;
+	mem->ops = ops;
+
+	mutex_init(&mem->mm_lock);
+
+	if (ops->init) {
+		err = ops->init(mem);
+		if (err) {
+			kfree(mem);
+			mem = ERR_PTR(err);
+		}
+	}
+
+	return mem;
+}
+
+void
+intel_memory_region_destroy(struct intel_memory_region *mem)
+{
+	if (mem->ops->release)
+		mem->ops->release(mem);
+
+	kfree(mem);
+}
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_region.c"
+#endif
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
new file mode 100644
index 000000000000..6d8a954ca75e
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __INTEL_MEMORY_REGION_H__
+#define __INTEL_MEMORY_REGION_H__
+
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/io-mapping.h>
+
+#include "i915_gem_buddy.h"
+
+struct drm_i915_private;
+struct drm_i915_gem_object;
+struct intel_memory_region;
+struct sg_table;
+
+/**
+ *  Base memory type
+ */
+enum intel_memory_type {
+	INTEL_SMEM = 0,
+	INTEL_LMEM,
+	INTEL_STOLEN,
+};
+
+enum intel_region_id {
+	INTEL_MEMORY_SMEM = 0,
+	INTEL_MEMORY_LMEM,
+	INTEL_MEMORY_STOLEN,
+	INTEL_MEMORY_UKNOWN, /* Should be last */
+};
+
+#define REGION_SMEM     BIT(INTEL_MEMORY_SMEM)
+#define REGION_LMEM     BIT(INTEL_MEMORY_LMEM)
+#define REGION_STOLEN   BIT(INTEL_MEMORY_STOLEN)
+
+#define INTEL_MEMORY_TYPE_SHIFT 16
+
+#define MEMORY_TYPE_FROM_REGION(r) (ilog2(r >> INTEL_MEMORY_TYPE_SHIFT))
+#define MEMORY_INSTANCE_FROM_REGION(r) (ilog2(r & 0xffff))
+
+/**
+ * Memory regions encoded as type | instance
+ */
+static const u32 intel_region_map[] = {
+	[INTEL_MEMORY_SMEM] = BIT(INTEL_SMEM + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
+	[INTEL_MEMORY_LMEM] = BIT(INTEL_LMEM + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
+	[INTEL_MEMORY_STOLEN] = BIT(INTEL_STOLEN + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
+};
+
+struct intel_memory_region_ops {
+	unsigned int flags;
+
+	int (*init)(struct intel_memory_region *);
+	void (*release)(struct intel_memory_region *);
+
+	struct drm_i915_gem_object *
+	(*object_create)(struct intel_memory_region *,
+			 resource_size_t,
+			 unsigned int);
+};
+
+struct intel_memory_region {
+	struct drm_i915_private *i915;
+
+	const struct intel_memory_region_ops *ops;
+
+	struct io_mapping iomap;
+	struct resource region;
+
+	struct i915_gem_buddy_mm mm;
+	struct mutex mm_lock;
+
+	resource_size_t io_start;
+	resource_size_t min_page_size;
+
+	unsigned int type;
+	unsigned int instance;
+	unsigned int id;
+};
+
+int i915_memory_region_init_buddy(struct intel_memory_region *mem);
+void i915_memory_region_release_buddy(struct intel_memory_region *mem);
+
+int i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj);
+void i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
+					struct sg_table *pages);
+
+struct intel_memory_region *
+intel_memory_region_create(struct drm_i915_private *i915,
+			   resource_size_t start,
+			   resource_size_t size,
+			   resource_size_t min_page_size,
+			   resource_size_t io_start,
+			   const struct intel_memory_region_ops *ops);
+void
+intel_memory_region_destroy(struct intel_memory_region *mem);
+
+struct drm_i915_gem_object *
+i915_gem_object_create_region(struct intel_memory_region *mem,
+			      resource_size_t size,
+			      unsigned int flags);
+
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index b6d84939592b..b0c8b4955f14 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -458,6 +458,86 @@ static int igt_mock_exhaust_device_supported_pages(void *arg)
 	return err;
 }
 
+
+static int igt_mock_memory_region_huge_pages(void *arg)
+{
+	struct i915_hw_ppgtt *ppgtt = arg;
+	struct drm_i915_private *i915 = ppgtt->vm.i915;
+	unsigned long supported = INTEL_INFO(i915)->page_sizes;
+	struct intel_memory_region *mem;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	int bit;
+	int err = 0;
+
+	mem = mock_region_create(i915, 0, SZ_2G,
+				 I915_GTT_PAGE_SIZE_4K, 0);
+	if (IS_ERR(mem)) {
+		pr_err("failed to create memory region\n");
+		return PTR_ERR(mem);
+	}
+
+	for_each_set_bit(bit, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) {
+		unsigned int page_size = BIT(bit);
+		resource_size_t phys;
+
+		obj = i915_gem_object_create_region(mem, page_size, 0);
+		if (IS_ERR(obj)) {
+			err = PTR_ERR(obj);
+			goto out_destroy_device;
+		}
+
+		pr_info("memory region start(%pa)\n",
+		        &obj->memory_region->region.start);
+		pr_info("creating object, size=%x\n", page_size);
+
+		vma = i915_vma_instance(obj, &ppgtt->vm, NULL);
+		if (IS_ERR(vma)) {
+			err = PTR_ERR(vma);
+			goto out_put;
+		}
+
+		err = i915_vma_pin(vma, 0, 0, PIN_USER);
+		if (err)
+			goto out_close;
+
+		phys = i915_gem_object_get_dma_address(obj, 0);
+		if (!IS_ALIGNED(phys, page_size)) {
+			pr_err("memory region misaligned(%pa)\n", &phys);
+			err = -EINVAL;
+			goto out_close;
+		}
+
+		if (vma->page_sizes.gtt != page_size) {
+			pr_err("page_sizes.gtt=%u, expected=%u\n",
+			       vma->page_sizes.gtt, page_size);
+			err = -EINVAL;
+			goto out_unpin;
+		}
+
+		i915_vma_unpin(vma);
+		i915_vma_close(vma);
+
+		i915_gem_object_put(obj);
+	}
+
+	goto out_destroy_device;
+
+out_unpin:
+	i915_vma_unpin(vma);
+out_close:
+	i915_vma_close(vma);
+out_put:
+	i915_gem_object_put(obj);
+out_destroy_device:
+	mutex_unlock(&i915->drm.struct_mutex);
+	i915_gem_drain_freed_objects(i915);
+	mutex_lock(&i915->drm.struct_mutex);
+	intel_memory_region_destroy(mem);
+
+	return err;
+}
+
 static int igt_mock_ppgtt_misaligned_dma(void *arg)
 {
 	struct i915_hw_ppgtt *ppgtt = arg;
@@ -1697,6 +1777,7 @@ int i915_gem_huge_page_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_mock_exhaust_device_supported_pages),
+		SUBTEST(igt_mock_memory_region_huge_pages),
 		SUBTEST(igt_mock_ppgtt_misaligned_dma),
 		SUBTEST(igt_mock_ppgtt_huge_fill),
 		SUBTEST(igt_mock_ppgtt_64K),
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 984e07ed65e5..3e34ee2255db 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -25,3 +25,4 @@ selftest(gtt, i915_gem_gtt_mock_selftests)
 selftest(hugepages, i915_gem_huge_page_mock_selftests)
 selftest(contexts, i915_gem_context_mock_selftests)
 selftest(buddy, i915_gem_buddy_mock_selftests)
+selftest(memory_region, intel_memory_region_mock_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
new file mode 100644
index 000000000000..2b8d28216d87
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#include "mock_gem_device.h"
+#include "mock_context.h"
+#include "mock_drm.h"
+
+static void close_objects(struct list_head *objects)
+{
+	struct drm_i915_gem_object *obj, *on;
+
+	list_for_each_entry_safe(obj, on, objects, st_link) {
+		if (i915_gem_object_has_pinned_pages(obj))
+			i915_gem_object_unpin_pages(obj);
+		/* No polluting the memory region between tests */
+		__i915_gem_object_put_pages(obj, I915_MM_NORMAL);
+		i915_gem_object_put(obj);
+		list_del(&obj->st_link);
+	}
+}
+
+static int igt_mock_fill(void *arg)
+{
+	struct intel_memory_region *mem = arg;
+	resource_size_t total = resource_size(&mem->region);
+	resource_size_t page_size;
+	resource_size_t rem;
+	unsigned long max_pages;
+	unsigned long page_num;
+	LIST_HEAD(objects);
+	int err = 0;
+
+	page_size = mem->mm.min_size;
+	max_pages = total / page_size;
+	rem = total;
+
+	for_each_prime_number_from(page_num, 1, max_pages) {
+		resource_size_t size = page_num * page_size;
+		struct drm_i915_gem_object *obj;
+
+		obj = i915_gem_object_create_region(mem, size, 0);
+		if (IS_ERR(obj)) {
+			err = PTR_ERR(obj);
+			break;
+		}
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err) {
+			i915_gem_object_put(obj);
+			break;
+		}
+
+		list_add(&obj->st_link, &objects);
+		rem -= size;
+	}
+
+	if (err == -ENOMEM)
+		err = 0;
+	if (err == -ENOSPC) {
+		if (page_num * page_size <= rem) {
+			pr_err("igt_mock_fill failed, space still left in region\n");
+			err = -EINVAL;
+		} else {
+			err = 0;
+		}
+	}
+
+	close_objects(&objects);
+
+	return err;
+}
+
+int intel_memory_region_mock_selftests(void)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_mock_fill),
+	};
+	struct intel_memory_region *mem;
+	struct drm_i915_private *i915;
+	int err;
+
+	i915 = mock_gem_device();
+	if (!i915)
+		return -ENOMEM;
+
+	mem = mock_region_create(i915, 0, SZ_2G,
+				 I915_GTT_PAGE_SIZE_4K, 0);
+	if (IS_ERR(mem)) {
+		pr_err("failed to create memory region\n");
+		err = PTR_ERR(mem);
+		goto out_unref;
+	}
+
+	mutex_lock(&i915->drm.struct_mutex);
+	err = i915_subtests(tests, mem);
+	mutex_unlock(&i915->drm.struct_mutex);
+
+	i915_gem_drain_freed_objects(i915);
+	intel_memory_region_destroy(mem);
+
+out_unref:
+	drm_dev_put(&i915->drm);
+
+	return err;
+}
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 876f4e6dadac..f8901cd12180 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -32,6 +32,7 @@
 #include "mock_gem_object.h"
 #include "mock_gtt.h"
 #include "mock_uncore.h"
+#include "mock_region.h"
 
 void mock_device_flush(struct drm_i915_private *i915)
 {
diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c
new file mode 100644
index 000000000000..2c83711f780d
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/mock_region.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "mock_region.h"
+
+static const struct drm_i915_gem_object_ops mock_region_obj_ops = {
+	.get_pages = i915_memory_region_get_pages_buddy,
+	.put_pages = i915_memory_region_put_pages_buddy,
+};
+
+static struct drm_i915_gem_object *
+mock_object_create(struct intel_memory_region *mem,
+		   resource_size_t size,
+		   unsigned int flags)
+{
+	struct drm_i915_private *i915 = mem->i915;
+	struct drm_i915_gem_object *obj;
+
+	if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
+		return ERR_PTR(-E2BIG);
+
+	obj = i915_gem_object_alloc(i915);
+	if (!obj)
+		return ERR_PTR(-ENOMEM);
+
+	drm_gem_private_object_init(&i915->drm, &obj->base, size);
+	i915_gem_object_init(obj, &mock_region_obj_ops);
+
+	obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
+	obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+
+	return obj;
+}
+
+static const struct intel_memory_region_ops mock_region_ops = {
+	.init = i915_memory_region_init_buddy,
+	.release = i915_memory_region_release_buddy,
+	.object_create = mock_object_create,
+};
+
+struct intel_memory_region *
+mock_region_create(struct drm_i915_private *i915,
+		   resource_size_t start,
+		   resource_size_t size,
+		   resource_size_t min_page_size,
+		   resource_size_t io_start)
+{
+	return intel_memory_region_create(i915, start, size, min_page_size,
+					  io_start, &mock_region_ops);
+}
diff --git a/drivers/gpu/drm/i915/selftests/mock_region.h b/drivers/gpu/drm/i915/selftests/mock_region.h
new file mode 100644
index 000000000000..47718313fa58
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/mock_region.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __MOCK_REGION_H
+#define __MOCK_REGION_H
+
+struct intel_memory_region *
+mock_region_create(struct drm_i915_private *i915,
+		   resource_size_t start,
+		   resource_size_t size,
+		   resource_size_t min_page_size,
+		   resource_size_t io_start);
+
+#endif /* !__MOCK_REGION_H */
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 05/42] drm/i915/region: support basic eviction
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (3 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 04/42] drm/i915: introduce intel_memory_region Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:25   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 06/42] drm/i915/region: support continuous allocations Matthew Auld
                   ` (39 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Support basic eviction for regions.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h               |  2 +
 drivers/gpu/drm/i915/i915_gem.c               | 16 ++++
 drivers/gpu/drm/i915/i915_gem_object.h        |  7 ++
 drivers/gpu/drm/i915/i915_gem_shrinker.c      | 59 ++++++++++++++
 drivers/gpu/drm/i915/intel_memory_region.c    | 40 +++++++++-
 drivers/gpu/drm/i915/intel_memory_region.h    |  7 ++
 .../drm/i915/selftests/intel_memory_region.c  | 76 +++++++++++++++++++
 drivers/gpu/drm/i915/selftests/mock_region.c  |  1 +
 8 files changed, 204 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0bea7d889284..3df27769b978 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3196,6 +3196,8 @@ void i915_gem_shrinker_register(struct drm_i915_private *i915);
 void i915_gem_shrinker_unregister(struct drm_i915_private *i915);
 void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915,
 				    struct mutex *mutex);
+int i915_gem_shrink_memory_region(struct intel_memory_region *mem,
+				  resource_size_t target);
 
 /* i915_gem_tiling.c */
 static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 92768ab294a4..7f044b643a75 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4095,6 +4095,22 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
 	    !i915_gem_object_has_pages(obj))
 		i915_gem_object_truncate(obj);
 
+	if (obj->memory_region) {
+		mutex_lock(&obj->memory_region->obj_lock);
+
+		switch (obj->mm.madv) {
+		case I915_MADV_WILLNEED:
+			list_move(&obj->region_link, &obj->memory_region->objects);
+			break;
+		default:
+			list_move(&obj->region_link,
+				  &obj->memory_region->purgeable);
+			break;
+		}
+
+		mutex_unlock(&obj->memory_region->obj_lock);
+	}
+
 	args->retained = obj->mm.madv != __I915_MADV_PURGED;
 	mutex_unlock(&obj->mm.lock);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index ac52f61e8ad1..76947a6f49f1 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -95,6 +95,13 @@ struct drm_i915_gem_object {
 	 * List of memory region blocks allocated for this object.
 	 */
 	struct list_head blocks;
+	/**
+	 * Element within memory_region->objects or memory_region->purgeable if
+	 * the object is marked as DONTNEED. Access is protected by
+	 * memory_region->obj_lock.
+	 */
+	struct list_head region_link;
+	struct list_head tmp_link;
 
 	struct {
 		/**
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
index 6da795c7e62e..713c6c93cf30 100644
--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -308,6 +308,65 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915)
 	return freed;
 }
 
+int i915_gem_shrink_memory_region(struct intel_memory_region *mem,
+				  resource_size_t target)
+{
+	struct drm_i915_private *i915 = mem->i915;
+	struct drm_i915_gem_object *obj, *on;
+	resource_size_t found;
+	LIST_HEAD(purgeable);
+	bool unlock;
+	int err;
+
+	if (!shrinker_lock(i915, 0, &unlock))
+		return 0;
+
+	i915_retire_requests(i915);
+
+	err = 0;
+	found = 0;
+
+	mutex_lock(&mem->obj_lock);
+
+	list_for_each_entry(obj, &mem->purgeable, region_link) {
+		if (!i915_gem_object_has_pages(obj))
+			continue;
+
+		if (READ_ONCE(obj->pin_global))
+			continue;
+
+		if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count)
+			continue;
+
+		list_add(&obj->tmp_link, &purgeable);
+
+		found += obj->base.size;
+		if (found >= target)
+			goto found;
+	}
+
+	err = -ENOSPC;
+found:
+	mutex_unlock(&mem->obj_lock);
+
+	list_for_each_entry_safe(obj, on, &purgeable, tmp_link) {
+		if (!err)
+			err = i915_gem_object_unbind(obj);
+		if (!err) {
+			__i915_gem_object_put_pages(obj,
+						    I915_MM_SHRINKER);
+			if (!i915_gem_object_has_pages(obj))
+				obj->mm.madv = __I915_MADV_PURGED;
+		}
+
+		list_del(&obj->tmp_link);
+	}
+
+	shrinker_unlock(i915, unlock);
+
+	return err;
+}
+
 static unsigned long
 i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
 {
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 405d6d51194f..f7fdc3e942e6 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -89,7 +89,8 @@ i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
 		unsigned int order;
 		u64 block_size;
 		u64 offset;
-
+		bool retry = false;
+retry:
 		order = fls(n_pages) - 1;
 		GEM_BUG_ON(order > mem->mm.max_order);
 
@@ -98,9 +99,25 @@ i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
 			if (!IS_ERR(block))
 				break;
 
-			/* XXX: some kind of eviction pass, local to the device */
-			if (!order--)
-				goto err_free_blocks;
+			if (!order--) {
+				resource_size_t target;
+				int err;
+
+				if (retry)
+					goto err_free_blocks;
+
+				target = n_pages * mem->mm.min_size;
+
+				mutex_unlock(&mem->mm_lock);
+				err = i915_gem_shrink_memory_region(mem,
+								    target);
+				mutex_lock(&mem->mm_lock);
+				if (err)
+					goto err_free_blocks;
+
+				retry = true;
+				goto retry;
+			}
 		} while (1);
 
 		n_pages -= 1 << order;
@@ -151,6 +168,13 @@ void i915_memory_region_release_buddy(struct intel_memory_region *mem)
 	i915_gem_buddy_fini(&mem->mm);
 }
 
+void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj)
+{
+	mutex_lock(&obj->memory_region->obj_lock);
+	list_del(&obj->region_link);
+	mutex_unlock(&obj->memory_region->obj_lock);
+}
+
 struct drm_i915_gem_object *
 i915_gem_object_create_region(struct intel_memory_region *mem,
 			      resource_size_t size,
@@ -179,6 +203,10 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
 	INIT_LIST_HEAD(&obj->blocks);
 	obj->memory_region = mem;
 
+	mutex_lock(&mem->obj_lock);
+	list_add(&obj->region_link, &mem->objects);
+	mutex_unlock(&mem->obj_lock);
+
 	i915_gem_object_set_cache_coherency(obj, obj->cache_level);
 
 	return obj;
@@ -205,6 +233,10 @@ intel_memory_region_create(struct drm_i915_private *i915,
 	mem->min_page_size = min_page_size;
 	mem->ops = ops;
 
+	mutex_init(&mem->obj_lock);
+	INIT_LIST_HEAD(&mem->objects);
+	INIT_LIST_HEAD(&mem->purgeable);
+
 	mutex_init(&mem->mm_lock);
 
 	if (ops->init) {
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index 6d8a954ca75e..b1546afb0b6e 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -99,6 +99,11 @@ struct intel_memory_region {
 	unsigned int type;
 	unsigned int instance;
 	unsigned int id;
+
+	/* Protects access to objects and purgeable */
+	struct mutex obj_lock;
+	struct list_head objects;
+	struct list_head purgeable;
 };
 
 int i915_memory_region_init_buddy(struct intel_memory_region *mem);
@@ -108,6 +113,8 @@ int i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj);
 void i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
 					struct sg_table *pages);
 
+void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj);
+
 struct intel_memory_region *
 intel_memory_region_create(struct drm_i915_private *i915,
 			   resource_size_t start,
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 2b8d28216d87..1cea381d2d5e 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -93,10 +93,86 @@ static int igt_mock_fill(void *arg)
 	return err;
 }
 
+static void igt_mark_evictable(struct drm_i915_gem_object *obj)
+{
+	i915_gem_object_unpin_pages(obj);
+	obj->mm.madv = I915_MADV_DONTNEED;
+	list_move(&obj->region_link, &obj->memory_region->purgeable);
+}
+
+static int igt_mock_shrink(void *arg)
+{
+	struct intel_memory_region *mem = arg;
+	struct drm_i915_gem_object *obj;
+	unsigned long n_objects;
+	LIST_HEAD(objects);
+	resource_size_t target;
+	resource_size_t total;
+	int err = 0;
+
+	target = mem->mm.min_size;
+	total = resource_size(&mem->region);
+	n_objects = total / target;
+
+	while (n_objects--) {
+		obj = i915_gem_object_create_region(mem,
+						    target,
+						    0);
+		if (IS_ERR(obj)) {
+			err = PTR_ERR(obj);
+			goto err_close_objects;
+		}
+
+		list_add(&obj->st_link, &objects);
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err)
+			goto err_close_objects;
+
+		/*
+		 * Make half of the region evictable, though do so in a
+		 * horribly fragmented fashion.
+		 */
+		if (n_objects % 2)
+			igt_mark_evictable(obj);
+	}
+
+	while (target <= total / 2) {
+		obj = i915_gem_object_create_region(mem, target, 0);
+		if (IS_ERR(obj)) {
+			err = PTR_ERR(obj);
+			goto err_close_objects;
+		}
+
+		list_add(&obj->st_link, &objects);
+
+		/* Provoke the shrinker to start violently swinging its axe! */
+		err = i915_gem_object_pin_pages(obj);
+		if (err) {
+			pr_err("failed to shrink for target=%pa", &target);
+			goto err_close_objects;
+		}
+
+		/* Again, half of the region should remain evictable */
+		igt_mark_evictable(obj);
+
+		target <<= 1;
+	}
+
+err_close_objects:
+	close_objects(&objects);
+
+	if (err == -ENOMEM)
+		err = 0;
+
+	return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_mock_fill),
+		SUBTEST(igt_mock_shrink),
 	};
 	struct intel_memory_region *mem;
 	struct drm_i915_private *i915;
diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c
index 2c83711f780d..11e9f379aaca 100644
--- a/drivers/gpu/drm/i915/selftests/mock_region.c
+++ b/drivers/gpu/drm/i915/selftests/mock_region.c
@@ -27,6 +27,7 @@
 static const struct drm_i915_gem_object_ops mock_region_obj_ops = {
 	.get_pages = i915_memory_region_get_pages_buddy,
 	.put_pages = i915_memory_region_put_pages_buddy,
+	.release = i915_gem_object_release_memory_region,
 };
 
 static struct drm_i915_gem_object *
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 06/42] drm/i915/region: support continuous allocations
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (4 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 05/42] drm/i915/region: support basic eviction Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 07/42] drm/i915/region: support volatile objects Matthew Auld
                   ` (38 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Some objects may need to be allocated as a continuous block, thinking
ahead the various kernel io_mapping interfaces seem to expect it.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_object.h        |   2 +
 drivers/gpu/drm/i915/intel_memory_region.c    |   7 +-
 .../drm/i915/selftests/intel_memory_region.c  | 152 +++++++++++++++++-
 drivers/gpu/drm/i915/selftests/mock_region.c  |   3 +
 4 files changed, 158 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 76947a6f49f1..efc23fc2b1df 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -163,6 +163,8 @@ struct drm_i915_gem_object {
 	 * activity?
 	 */
 #define I915_BO_ACTIVE_REF 0
+#define I915_BO_ALLOC_CONTIGUOUS (1<<1)
+#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS)
 
 	/*
 	 * Is the object to be mapped as read-only to the GPU
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index f7fdc3e942e6..ed37599c7784 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -59,6 +59,7 @@ i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
 {
 	struct intel_memory_region *mem = obj->memory_region;
 	resource_size_t size = obj->base.size;
+	unsigned int flags = obj->flags;
 	struct sg_table *st;
 	struct scatterlist *sg;
 	unsigned int sg_page_sizes;
@@ -99,7 +100,7 @@ i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
 			if (!IS_ERR(block))
 				break;
 
-			if (!order--) {
+			if (flags & I915_BO_ALLOC_CONTIGUOUS || !order--) {
 				resource_size_t target;
 				int err;
 
@@ -185,6 +186,9 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
 	if (!mem)
 		return ERR_PTR(-ENODEV);
 
+	if (flags & ~I915_BO_ALLOC_FLAGS)
+		return ERR_PTR(-EINVAL);
+
 	size = round_up(size, mem->min_page_size);
 
 	GEM_BUG_ON(!size);
@@ -202,6 +206,7 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
 
 	INIT_LIST_HEAD(&obj->blocks);
 	obj->memory_region = mem;
+	obj->flags = flags;
 
 	mutex_lock(&mem->obj_lock);
 	list_add(&obj->region_link, &mem->objects);
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 1cea381d2d5e..fbb1497d0f82 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -95,17 +95,17 @@ static int igt_mock_fill(void *arg)
 
 static void igt_mark_evictable(struct drm_i915_gem_object *obj)
 {
-	i915_gem_object_unpin_pages(obj);
+	if (i915_gem_object_has_pinned_pages(obj))
+		i915_gem_object_unpin_pages(obj);
 	obj->mm.madv = I915_MADV_DONTNEED;
 	list_move(&obj->region_link, &obj->memory_region->purgeable);
 }
 
-static int igt_mock_shrink(void *arg)
+static int igt_frag_region(struct intel_memory_region *mem,
+			   struct list_head *objects)
 {
-	struct intel_memory_region *mem = arg;
 	struct drm_i915_gem_object *obj;
 	unsigned long n_objects;
-	LIST_HEAD(objects);
 	resource_size_t target;
 	resource_size_t total;
 	int err = 0;
@@ -123,7 +123,7 @@ static int igt_mock_shrink(void *arg)
 			goto err_close_objects;
 		}
 
-		list_add(&obj->st_link, &objects);
+		list_add(&obj->st_link, objects);
 
 		err = i915_gem_object_pin_pages(obj);
 		if (err)
@@ -137,6 +137,39 @@ static int igt_mock_shrink(void *arg)
 			igt_mark_evictable(obj);
 	}
 
+	return 0;
+
+err_close_objects:
+	close_objects(objects);
+	return err;
+}
+
+static void igt_defrag_region(struct list_head *objects)
+{
+	struct drm_i915_gem_object *obj;
+
+	list_for_each_entry(obj, objects, st_link) {
+		if (obj->mm.madv == I915_MADV_WILLNEED)
+			igt_mark_evictable(obj);
+	}
+}
+
+static int igt_mock_shrink(void *arg)
+{
+	struct intel_memory_region *mem = arg;
+	struct drm_i915_gem_object *obj;
+	LIST_HEAD(objects);
+	resource_size_t target;
+	resource_size_t total;
+	int err;
+
+	err = igt_frag_region(mem, &objects);
+	if (err)
+		return err;
+
+	total = resource_size(&mem->region);
+	target = mem->mm.min_size;
+
 	while (target <= total / 2) {
 		obj = i915_gem_object_create_region(mem, target, 0);
 		if (IS_ERR(obj)) {
@@ -168,11 +201,120 @@ static int igt_mock_shrink(void *arg)
 	return err;
 }
 
+static int igt_mock_continuous(void *arg)
+{
+	struct intel_memory_region *mem = arg;
+	struct drm_i915_gem_object *obj;
+	LIST_HEAD(objects);
+	resource_size_t target;
+	resource_size_t total;
+	int err;
+
+	err = igt_frag_region(mem, &objects);
+	if (err)
+		return err;
+
+	total = resource_size(&mem->region);
+	target = total / 2;
+
+	/*
+	 * Sanity check that we can allocate all of the available fragmented
+	 * space.
+	 */
+	obj = i915_gem_object_create_region(mem, target, 0);
+	if (IS_ERR(obj)) {
+		err = PTR_ERR(obj);
+		goto err_close_objects;
+	}
+
+	list_add(&obj->st_link, &objects);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err) {
+		pr_err("failed to allocate available space\n");
+		goto err_close_objects;
+	}
+
+	igt_mark_evictable(obj);
+
+	/* Try the smallest possible size -- should succeed */
+	obj = i915_gem_object_create_region(mem, mem->mm.min_size,
+					    I915_BO_ALLOC_CONTIGUOUS);
+	if (IS_ERR(obj)) {
+		err = PTR_ERR(obj);
+		goto err_close_objects;
+	}
+
+	list_add(&obj->st_link, &objects);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err) {
+		pr_err("failed to allocate smallest possible size\n");
+		goto err_close_objects;
+	}
+
+	igt_mark_evictable(obj);
+
+	if (obj->mm.pages->nents != 1) {
+		pr_err("[1]object spans multiple sg entries\n");
+		err = -EINVAL;
+		goto err_close_objects;
+	}
+
+	/*
+	 * Even though there is enough free space for the allocation, we
+	 * shouldn't be able to allocate it, given that it is fragmented, and
+	 * non-continuous.
+	 */
+	obj = i915_gem_object_create_region(mem, target, I915_BO_ALLOC_CONTIGUOUS);
+	if (IS_ERR(obj)) {
+		err = PTR_ERR(obj);
+		goto err_close_objects;
+	}
+
+	list_add(&obj->st_link, &objects);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (!err) {
+		pr_err("expected allocation to fail\n");
+		err = -EINVAL;
+		goto err_close_objects;
+	}
+
+	igt_defrag_region(&objects);
+
+	/* Should now succeed */
+	obj = i915_gem_object_create_region(mem, target, I915_BO_ALLOC_CONTIGUOUS);
+	if (IS_ERR(obj)) {
+		err = PTR_ERR(obj);
+		goto err_close_objects;
+	}
+
+	list_add(&obj->st_link, &objects);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err) {
+		pr_err("failed to allocate from defraged area\n");
+		goto err_close_objects;
+	}
+
+	if (obj->mm.pages->nents != 1) {
+		pr_err("object spans multiple sg entries\n");
+		err = -EINVAL;
+	}
+
+err_close_objects:
+	close_objects(&objects);
+
+	return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_mock_fill),
 		SUBTEST(igt_mock_shrink),
+		SUBTEST(igt_mock_continuous),
 	};
 	struct intel_memory_region *mem;
 	struct drm_i915_private *i915;
diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c
index 11e9f379aaca..c1c09d0e4722 100644
--- a/drivers/gpu/drm/i915/selftests/mock_region.c
+++ b/drivers/gpu/drm/i915/selftests/mock_region.c
@@ -38,6 +38,9 @@ mock_object_create(struct intel_memory_region *mem,
 	struct drm_i915_private *i915 = mem->i915;
 	struct drm_i915_gem_object *obj;
 
+	if (flags & I915_BO_ALLOC_CONTIGUOUS)
+		size = roundup_pow_of_two(size);
+
 	if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
 		return ERR_PTR(-E2BIG);
 
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 07/42] drm/i915/region: support volatile objects
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (5 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 06/42] drm/i915/region: support continuous allocations Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 08/42] drm/i915: Add memory region information to device_info Matthew Auld
                   ` (37 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Volatile objects are marked as DONTNEED while pinned, therefore once
unpinned the backing store can be discarded.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_object.h        |  3 +-
 drivers/gpu/drm/i915/intel_memory_region.c    | 10 +++-
 .../drm/i915/selftests/intel_memory_region.c  | 54 +++++++++++++++++++
 3 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index efc23fc2b1df..0dfe9603e3cc 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -164,7 +164,8 @@ struct drm_i915_gem_object {
 	 */
 #define I915_BO_ACTIVE_REF 0
 #define I915_BO_ALLOC_CONTIGUOUS (1<<1)
-#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS)
+#define I915_BO_ALLOC_VOLATILE   (1<<2)
+#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | I915_BO_ALLOC_VOLATILE)
 
 	/*
 	 * Is the object to be mapped as read-only to the GPU
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index ed37599c7784..5531ed94bdab 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -148,6 +148,9 @@ i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
 
 	i915_sg_trim(st);
 
+	if (flags & I915_BO_ALLOC_VOLATILE)
+		obj->mm.madv = I915_MADV_DONTNEED;
+
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
 	return 0;
@@ -209,7 +212,12 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
 	obj->flags = flags;
 
 	mutex_lock(&mem->obj_lock);
-	list_add(&obj->region_link, &mem->objects);
+
+	if (flags & I915_BO_ALLOC_VOLATILE)
+		list_add(&obj->region_link, &mem->purgeable);
+	else
+		list_add(&obj->region_link, &mem->objects);
+
 	mutex_unlock(&mem->obj_lock);
 
 	i915_gem_object_set_cache_coherency(obj, obj->cache_level);
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index fbb1497d0f82..0f6432a2a4c4 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -309,12 +309,66 @@ static int igt_mock_continuous(void *arg)
 	return err;
 }
 
+static int igt_mock_volatile(void *arg)
+{
+	struct intel_memory_region *mem = arg;
+	struct drm_i915_gem_object *obj;
+	int err;
+
+	obj = i915_gem_object_create_region(mem, PAGE_SIZE, 0);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		goto err_put;
+
+	i915_gem_object_unpin_pages(obj);
+
+	err = i915_gem_shrink_memory_region(mem, PAGE_SIZE);
+	if (err != -ENOSPC) {
+		pr_err("shrink memory region\n");
+		goto err_put;
+	}
+
+	obj = i915_gem_object_create_region(mem, PAGE_SIZE, I915_BO_ALLOC_VOLATILE);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	if (!(obj->flags & I915_BO_ALLOC_VOLATILE)) {
+		pr_err("missing flags\n");
+		goto err_put;
+	}
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		goto err_put;
+
+	i915_gem_object_unpin_pages(obj);
+
+	err = i915_gem_shrink_memory_region(mem, PAGE_SIZE);
+	if (err) {
+		pr_err("failed to shrink memory\n");
+		goto err_put;
+	}
+
+	if (i915_gem_object_has_pages(obj)) {
+		pr_err("object pages not discarded\n");
+		err = -EINVAL;
+	}
+
+err_put:
+	i915_gem_object_put(obj);
+	return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_mock_fill),
 		SUBTEST(igt_mock_shrink),
 		SUBTEST(igt_mock_continuous),
+		SUBTEST(igt_mock_volatile),
 	};
 	struct intel_memory_region *mem;
 	struct drm_i915_private *i915;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 08/42] drm/i915: Add memory region information to device_info
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (6 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 07/42] drm/i915/region: support volatile objects Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 09/42] drm/i915: support creating LMEM objects Matthew Auld
                   ` (36 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

Exposes available regions for the platform. Shared memory will
always be available.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h          |  2 ++
 drivers/gpu/drm/i915/i915_pci.c          | 12 ++++++++++++
 drivers/gpu/drm/i915/intel_device_info.h |  1 +
 3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3df27769b978..3093a8814f8e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2520,6 +2520,8 @@ static inline unsigned int i915_sg_segment_size(void)
 
 #define HAS_IPC(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_ipc)
 
+#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
+
 /*
  * For now, anything with a GuC requires uCode loading, and then supports
  * command submission once loaded. But these are logically independent
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 4a7b587e9a92..19c98215791e 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -85,6 +85,9 @@
 #define GEN_DEFAULT_PAGE_SIZES \
 	.page_sizes = I915_GTT_PAGE_SIZE_4K
 
+#define GEN_DEFAULT_REGIONS \
+	.memory_regions = REGION_SMEM | REGION_STOLEN
+
 #define GEN2_FEATURES \
 	GEN(2), \
 	.num_pipes = 1, \
@@ -97,6 +100,7 @@
 	.ring_mask = RENDER_RING, \
 	.has_snoop = true, \
 	.has_coherent_ggtt = false, \
+	GEN_DEFAULT_REGIONS, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
@@ -136,6 +140,7 @@ static const struct intel_device_info intel_i865g_info = {
 	.ring_mask = RENDER_RING, \
 	.has_snoop = true, \
 	.has_coherent_ggtt = true, \
+	GEN_DEFAULT_REGIONS, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
@@ -213,6 +218,7 @@ static const struct intel_device_info intel_pineview_info = {
 	.ring_mask = RENDER_RING, \
 	.has_snoop = true, \
 	.has_coherent_ggtt = true, \
+	GEN_DEFAULT_REGIONS, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
@@ -262,6 +268,7 @@ static const struct intel_device_info intel_gm45_info = {
 	.has_coherent_ggtt = true, \
 	/* ilk does support rc6, but we do not implement [power] contexts */ \
 	.has_rc6 = 0, \
+	GEN_DEFAULT_REGIONS, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
@@ -289,6 +296,7 @@ static const struct intel_device_info intel_ironlake_m_info = {
 	.has_rc6 = 1, \
 	.has_rc6p = 1, \
 	.ppgtt = INTEL_PPGTT_ALIASING, \
+	GEN_DEFAULT_REGIONS, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
@@ -334,6 +342,7 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info = {
 	.has_rc6 = 1, \
 	.has_rc6p = 1, \
 	.ppgtt = INTEL_PPGTT_FULL, \
+	GEN_DEFAULT_REGIONS, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	GEN_DEFAULT_PAGE_SIZES, \
 	IVB_CURSOR_OFFSETS
@@ -391,6 +400,7 @@ static const struct intel_device_info intel_valleyview_info = {
 	.has_coherent_ggtt = false,
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING,
 	.display_mmio_offset = VLV_DISPLAY_BASE,
+	GEN_DEFAULT_REGIONS,
 	GEN_DEFAULT_PAGE_SIZES,
 	GEN_DEFAULT_PIPEOFFSETS,
 	CURSOR_OFFSETS
@@ -483,6 +493,7 @@ static const struct intel_device_info intel_cherryview_info = {
 	.has_snoop = true,
 	.has_coherent_ggtt = false,
 	.display_mmio_offset = VLV_DISPLAY_BASE,
+	GEN_DEFAULT_REGIONS,
 	GEN_DEFAULT_PAGE_SIZES,
 	GEN_CHV_PIPEOFFSETS,
 	CURSOR_OFFSETS,
@@ -559,6 +570,7 @@ static const struct intel_device_info intel_skylake_gt4_info = {
 	.has_snoop = true, \
 	.has_coherent_ggtt = false, \
 	.display.has_ipc = 1, \
+	GEN_DEFAULT_REGIONS, \
 	GEN9_DEFAULT_PAGE_SIZES, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	IVB_CURSOR_OFFSETS, \
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index e8b8661df746..4179f6a66443 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -180,6 +180,7 @@ struct intel_device_info {
 	} display;
 
 	u16 ddb_size; /* in blocks */
+	u32 memory_regions;
 
 	/* Register offsets for the various display pipes and transcoders */
 	int pipe_offsets[I915_MAX_TRANSCODERS];
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 09/42] drm/i915: support creating LMEM objects
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (7 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 08/42] drm/i915: Add memory region information to device_info Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:30   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 10/42] drm/i915/lmem: add helper to get CPU visible pfn Matthew Auld
                   ` (35 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We currently define LMEM, or local memory, as just another memory
region, like system memory or stolen, which we can expose to userspace
and can be mapped to the CPU via some BAR.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |  1 +
 drivers/gpu/drm/i915/i915_drv.h               |  5 ++
 drivers/gpu/drm/i915/i915_gem_object.c        |  1 +
 drivers/gpu/drm/i915/intel_region_lmem.c      | 82 +++++++++++++++++++
 drivers/gpu/drm/i915/intel_region_lmem.h      | 35 ++++++++
 .../drm/i915/selftests/i915_live_selftests.h  |  1 +
 .../drm/i915/selftests/intel_memory_region.c  | 64 +++++++++++++++
 7 files changed, 189 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.c
 create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 96be264fa382..66a35ae891d8 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -90,6 +90,7 @@ i915-y += \
 	  intel_lrc.o \
 	  intel_memory_region.o \
 	  intel_mocs.o \
+	  intel_region_lmem.o \
 	  intel_ringbuffer.o \
 	  intel_uncore.o \
 	  intel_wopcm.o
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3093a8814f8e..a0ed000d52aa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -85,6 +85,8 @@
 #include "i915_timeline.h"
 #include "i915_vma.h"
 
+#include "intel_region_lmem.h"
+
 #include "intel_gvt.h"
 
 /* General customization:
@@ -1502,6 +1504,8 @@ struct drm_i915_private {
 
 	void __iomem *regs;
 
+	struct intel_memory_region *regions[ARRAY_SIZE(intel_region_map)];
+
 	struct intel_uncore uncore;
 
 	struct i915_virtual_gpu vgpu;
@@ -2521,6 +2525,7 @@ static inline unsigned int i915_sg_segment_size(void)
 #define HAS_IPC(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_ipc)
 
 #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
+#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
 
 /*
  * For now, anything with a GuC requires uCode loading, and then supports
diff --git a/drivers/gpu/drm/i915/i915_gem_object.c b/drivers/gpu/drm/i915/i915_gem_object.c
index aab8cdd80e6d..860482a3f028 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/i915_gem_object.c
@@ -46,3 +46,4 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
 	obj->cache_dirty =
 		!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE);
 }
+
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
new file mode 100644
index 000000000000..4a205639cbb6
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "i915_drv.h"
+#include "intel_memory_region.h"
+#include "intel_region_lmem.h"
+
+static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
+	.get_pages = i915_memory_region_get_pages_buddy,
+	.put_pages = i915_memory_region_put_pages_buddy,
+	.release = i915_gem_object_release_memory_region,
+};
+
+static struct drm_i915_gem_object *
+region_lmem_object_create(struct intel_memory_region *mem,
+			  resource_size_t size,
+			  unsigned int flags)
+{
+	struct drm_i915_private *i915 = mem->i915;
+	struct drm_i915_gem_object *obj;
+
+	if (flags & I915_BO_ALLOC_CONTIGUOUS)
+		size = roundup_pow_of_two(size);
+
+	if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
+		return ERR_PTR(-E2BIG);
+
+	obj = i915_gem_object_alloc(i915);
+	if (!obj)
+		return ERR_PTR(-ENOMEM);
+
+	drm_gem_private_object_init(&i915->drm, &obj->base, size);
+	i915_gem_object_init(obj, &region_lmem_obj_ops);
+
+	obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
+	obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+
+	return obj;
+}
+
+static const struct intel_memory_region_ops region_lmem_ops = {
+	.init = i915_memory_region_init_buddy,
+	.release = i915_memory_region_release_buddy,
+	.object_create = region_lmem_object_create,
+};
+
+bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
+{
+	struct intel_memory_region *region = obj->memory_region;
+
+	return region && region->type == INTEL_LMEM;
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_lmem(struct drm_i915_private *i915,
+			    resource_size_t size,
+			    unsigned int flags)
+{
+	return i915_gem_object_create_region(i915->regions[INTEL_MEMORY_LMEM],
+					     size, flags);
+}
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h b/drivers/gpu/drm/i915/intel_region_lmem.h
new file mode 100644
index 000000000000..7204f61aab44
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_region_lmem.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __INTEL_REGION_LMEM_H
+#define __INTEL_REGION_LMEM_H
+
+bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
+
+struct drm_i915_gem_object *
+i915_gem_object_create_lmem(struct drm_i915_private *i915,
+			    resource_size_t size,
+			    unsigned int flags);
+
+#endif /* !__INTEL_REGION_LMEM_H */
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 6d766925ad04..5c38ea7c5ffe 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -23,6 +23,7 @@ selftest(gem, i915_gem_live_selftests)
 selftest(evict, i915_gem_evict_live_selftests)
 selftest(hugepages, i915_gem_huge_page_live_selftests)
 selftest(contexts, i915_gem_context_live_selftests)
+selftest(memory_region, intel_memory_region_live_selftests)
 selftest(hangcheck, intel_hangcheck_live_selftests)
 selftest(execlists, intel_execlists_live_selftests)
 selftest(guc, intel_guc_live_selftest)
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 0f6432a2a4c4..08fe6e064361 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -362,6 +362,28 @@ static int igt_mock_volatile(void *arg)
 	return err;
 }
 
+static int igt_lmem_create(void *arg)
+{
+	struct i915_gem_context *ctx = arg;
+	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_gem_object *obj;
+	int err = 0;
+
+	obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		goto out_put;
+
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
@@ -398,3 +420,45 @@ int intel_memory_region_mock_selftests(void)
 
 	return err;
 }
+
+int intel_memory_region_live_selftests(struct drm_i915_private *i915)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_lmem_create),
+	};
+	struct i915_gem_context *ctx;
+	struct drm_file *file;
+	intel_wakeref_t wakeref;
+	int err;
+
+	if (!HAS_LMEM(i915)) {
+		pr_info("device lacks LMEM support, skipping\n");
+		return 0;
+	}
+
+	if (i915_terminally_wedged(&i915->gpu_error))
+		return 0;
+
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	mutex_lock(&i915->drm.struct_mutex);
+	wakeref = intel_runtime_pm_get(i915);
+
+	ctx = live_context(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto out_unlock;
+	}
+
+	err = i915_subtests(tests, ctx);
+
+out_unlock:
+	intel_runtime_pm_put(i915, wakeref);
+	mutex_unlock(&i915->drm.struct_mutex);
+
+	mock_file_free(i915, file);
+
+	return err;
+}
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 10/42] drm/i915/lmem: add helper to get CPU visible pfn
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (8 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 09/42] drm/i915: support creating LMEM objects Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:33   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 11/42] drm/i915/selftests: exercise writes to LMEM Matthew Auld
                   ` (34 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_region_lmem.c | 11 +++++++++++
 drivers/gpu/drm/i915/intel_region_lmem.h |  3 +++
 2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
index 4a205639cbb6..b398becb2733 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -65,6 +65,17 @@ static const struct intel_memory_region_ops region_lmem_ops = {
 	.object_create = region_lmem_object_create,
 };
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+					  unsigned long n)
+{
+	struct intel_memory_region *mem = obj->memory_region;
+	resource_size_t offset;
+
+	offset = i915_gem_object_get_dma_address(obj, n);
+
+	return (mem->io_start + offset) >> PAGE_SHIFT;
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
 	struct intel_memory_region *region = obj->memory_region;
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h b/drivers/gpu/drm/i915/intel_region_lmem.h
index 7204f61aab44..1aa24bd28690 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.h
+++ b/drivers/gpu/drm/i915/intel_region_lmem.h
@@ -25,6 +25,9 @@
 #ifndef __INTEL_REGION_LMEM_H
 #define __INTEL_REGION_LMEM_H
 
+unsigned long i915_gem_object_lmem_io_pfn(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 *
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 11/42] drm/i915/selftests: exercise writes to LMEM
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (9 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 10/42] drm/i915/lmem: add helper to get CPU visible pfn Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 12/42] drm/i915/selftests: exercise huge-pages for LMEM Matthew Auld
                   ` (33 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Quick and dirty test to exercise writing through LMEM from the GPU/CPU.
We currently don't have an LMEM region so these tests should just skip
for now.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 .../drm/i915/selftests/intel_memory_region.c  | 225 ++++++++++++++++++
 1 file changed, 225 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 08fe6e064361..210ec6fec19a 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -362,6 +362,201 @@ static int igt_mock_volatile(void *arg)
 	return err;
 }
 
+static struct i915_vma *
+igt_gpu_write_dw(struct i915_vma *vma, u64 offset, u32 val)
+{
+	struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
+	const int gen = INTEL_GEN(vma->vm->i915);
+	unsigned int count = vma->size >> PAGE_SHIFT;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *batch;
+	unsigned int size;
+	u32 *cmd;
+	int n;
+	int err;
+
+	size = (1 + 4 * count) * sizeof(u32);
+	size = round_up(size, PAGE_SIZE);
+	obj = i915_gem_object_create_internal(i915, size);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
+	if (IS_ERR(cmd)) {
+		err = PTR_ERR(cmd);
+		goto err;
+	}
+
+	offset += vma->node.start;
+
+	for (n = 0; n < count; n++) {
+		if (gen >= 8) {
+			*cmd++ = MI_STORE_DWORD_IMM_GEN4;
+			*cmd++ = lower_32_bits(offset);
+			*cmd++ = upper_32_bits(offset);
+			*cmd++ = val;
+		} else if (gen >= 4) {
+			*cmd++ = MI_STORE_DWORD_IMM_GEN4 |
+				(gen < 6 ? 1 << 22 : 0);
+			*cmd++ = 0;
+			*cmd++ = offset;
+			*cmd++ = val;
+		} else {
+			*cmd++ = MI_STORE_DWORD_IMM | 1 << 22;
+			*cmd++ = offset;
+			*cmd++ = val;
+		}
+
+		offset += PAGE_SIZE;
+	}
+
+	*cmd = MI_BATCH_BUFFER_END;
+
+	i915_gem_object_unpin_map(obj);
+
+	err = i915_gem_object_set_to_gtt_domain(obj, false);
+	if (err)
+		goto err;
+
+	batch = i915_vma_instance(obj, vma->vm, NULL);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err;
+	}
+
+	err = i915_vma_pin(batch, 0, 0, PIN_USER);
+	if (err)
+		goto err;
+
+	return batch;
+
+err:
+	i915_gem_object_put(obj);
+
+	return ERR_PTR(err);
+}
+
+static int igt_gpu_write(struct i915_vma *vma,
+			 struct i915_gem_context *ctx,
+			 struct intel_engine_cs *engine,
+			 u32 dword,
+			 u32 value)
+{
+	struct i915_request *rq;
+	struct i915_vma *batch;
+	int flags = 0;
+	int err;
+
+	GEM_BUG_ON(!intel_engine_can_store_dword(engine));
+
+	err = i915_gem_object_set_to_gtt_domain(vma->obj, true);
+	if (err)
+		return err;
+
+	rq = i915_request_alloc(engine, ctx);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	batch = igt_gpu_write_dw(vma, dword * sizeof(u32), value);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err_request;
+	}
+
+	err = i915_vma_move_to_active(batch, rq, 0);
+	i915_vma_unpin(batch);
+	i915_vma_close(batch);
+	if (err)
+		goto err_request;
+
+	i915_gem_object_set_active_reference(batch->obj);
+
+	err = engine->emit_bb_start(rq,
+				    batch->node.start, batch->node.size,
+				    flags);
+	if (err)
+		goto err_request;
+
+	err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
+	if (err)
+		i915_request_skip(rq, err);
+
+err_request:
+	i915_request_add(rq);
+
+	return err;
+}
+
+static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+{
+	unsigned long n;
+	int err;
+
+	err = i915_gem_object_set_to_wc_domain(obj, false);
+	if (err)
+		return err;
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		return err;
+
+	for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) {
+		u32 __iomem *base;
+		u32 read_val;
+
+		base = (void __force *) io_mapping_map_atomic_wc(&obj->memory_region->iomap,
+								 i915_gem_object_get_dma_address(obj, n));
+
+		read_val = ioread32(base + dword);
+		io_mapping_unmap_atomic(base);
+		if (read_val != val) {
+			pr_err("n=%lu base[%u]=%u, val=%u\n",
+			       n, dword, read_val, val);
+			err = -EINVAL;
+			break;
+		}
+	}
+
+	i915_gem_object_unpin_pages(obj);
+	return err;
+}
+
+static int igt_gpu_fill(struct i915_gem_context *ctx,
+			struct drm_i915_gem_object *obj,
+			u32 val)
+{
+	struct drm_i915_private *i915 = ctx->i915;
+	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->vm : &i915->ggtt.vm;
+	struct i915_vma *vma;
+	u32 dword;
+	int err;
+
+	vma = i915_vma_instance(obj, vm, NULL);
+	if (IS_ERR(vma))
+		return PTR_ERR(vma);
+
+	err = i915_vma_pin(vma, 0, 0, PIN_USER);
+	if (err) {
+		i915_vma_close(vma);
+		return err;
+	}
+
+	for (dword = 0; dword < PAGE_SIZE / sizeof(u32); ++dword) {
+		err = igt_gpu_write(vma, ctx, i915->engine[RCS], dword, val);
+		if (err)
+			break;
+
+		err = igt_cpu_check(obj, dword, val);
+		if (err)
+			break;
+	}
+
+	i915_vma_unpin(vma);
+	i915_vma_close(vma);
+
+	return err;
+}
+
 static int igt_lmem_create(void *arg)
 {
 	struct i915_gem_context *ctx = arg;
@@ -384,6 +579,35 @@ static int igt_lmem_create(void *arg)
 	return err;
 }
 
+static int igt_lmem_write_gpu(void *arg)
+{
+	struct i915_gem_context *ctx = arg;
+	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_gem_object *obj;
+	int err = 0;
+
+	obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		goto out_put;
+
+	err = igt_gpu_fill(ctx, obj, 0xdeadbeaf);
+	if (err) {
+		pr_err("igt_gpu_fill failed(%d)\n", err);
+		goto out_unpin;
+	}
+
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
@@ -425,6 +649,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_gpu),
 	};
 	struct i915_gem_context *ctx;
 	struct drm_file *file;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 12/42] drm/i915/selftests: exercise huge-pages for LMEM
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (10 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 11/42] drm/i915/selftests: exercise writes to LMEM Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine Matthew Auld
                   ` (32 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We already exercise huge-pages for our other object types, so add LMEM
objects to the list. Also try our luck with 1G pages.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/huge_pages.c | 121 +++++++++++++++++++-
 1 file changed, 120 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index b0c8b4955f14..f4283d41c13f 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -1095,7 +1095,7 @@ static int gpu_write(struct i915_vma *vma,
 	return err;
 }
 
-static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+static int __cpu_check_shmem(struct drm_i915_gem_object *obj, u32 dword, u32 val)
 {
 	unsigned int needs_flush;
 	unsigned long n;
@@ -1127,6 +1127,52 @@ static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
 	return err;
 }
 
+static int __cpu_check_lmem(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+{
+	unsigned long n;
+	int err;
+
+	err = i915_gem_object_set_to_wc_domain(obj, false);
+	if (err)
+		return err;
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		return err;
+
+	for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) {
+		u32 __iomem *base;
+		u32 read_val;
+
+		base = (void __force *)io_mapping_map_atomic_wc(&obj->memory_region->iomap,
+								i915_gem_object_get_dma_address(obj, n));
+
+		read_val = ioread32(base + dword);
+		io_mapping_unmap_atomic(base);
+		if (read_val != val) {
+			pr_err("n=%lu base[%u]=%u, val=%u\n",
+			       n, dword, read_val, val);
+			err = -EINVAL;
+			break;
+		}
+	}
+
+	i915_gem_object_unpin_pages(obj);
+	return err;
+}
+
+static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+	if (i915_gem_object_has_struct_page(obj))
+		return __cpu_check_shmem(obj, dword, val);
+	else if (HAS_LMEM(i915) && obj->memory_region)
+		return __cpu_check_lmem(obj, dword, val);
+
+	return -ENODEV;
+}
+
 static int __igt_write_huge(struct i915_gem_context *ctx,
 			    struct intel_engine_cs *engine,
 			    struct drm_i915_gem_object *obj,
@@ -1510,6 +1556,78 @@ static int igt_ppgtt_gemfs_huge(void *arg)
 	return err;
 }
 
+static int igt_ppgtt_lmem_huge(void *arg)
+{
+	struct i915_gem_context *ctx = arg;
+	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_gem_object *obj;
+	static const unsigned int sizes[] = {
+		SZ_64K,
+		SZ_512K,
+		SZ_1M,
+		SZ_2M,
+		SZ_1G, /* Try our luck! */
+	};
+	int i;
+	int err;
+
+	if (!HAS_LMEM(i915)) {
+		pr_info("device lacks LMEM support, skipping\n");
+		return 0;
+	}
+
+	/*
+	 * Sanity check that the HW uses huge pages correctly through LMEM
+	 * -- ensure that our writes land in the right place.
+	 */
+
+	for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
+		unsigned int size = sizes[i];
+
+		obj = i915_gem_object_create_lmem(i915, size, 0);
+		if (IS_ERR(obj)) {
+			err = PTR_ERR(obj);
+			if (err == -E2BIG) {
+				pr_info("object too big for region!\n");
+				return 0;
+			}
+
+			return err;
+		}
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err)
+			goto out_put;
+
+		if (obj->mm.page_sizes.phys == I915_GTT_PAGE_SIZE_1G) {
+			pr_info("long live 1G pages!\n");
+		} else if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_64K) {
+			pr_info("LMEM unable to allocate huge-page(s) with size=%u\n",
+				size);
+			goto out_unpin;
+		}
+
+		err = igt_write_huge(ctx, obj);
+		if (err) {
+			pr_err("LMEM write-huge failed with size=%u\n", size);
+			goto out_unpin;
+		}
+
+		i915_gem_object_unpin_pages(obj);
+		__i915_gem_object_put_pages(obj, I915_MM_NORMAL);
+		i915_gem_object_put(obj);
+	}
+
+	return 0;
+
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
 static int igt_ppgtt_pin_update(void *arg)
 {
 	struct i915_gem_context *ctx = arg;
@@ -1835,6 +1953,7 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv)
 		SUBTEST(igt_ppgtt_exhaust_huge),
 		SUBTEST(igt_ppgtt_gemfs_huge),
 		SUBTEST(igt_ppgtt_internal_huge),
+		SUBTEST(igt_ppgtt_lmem_huge),
 	};
 	struct drm_file *file;
 	struct i915_gem_context *ctx;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (11 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 12/42] drm/i915/selftests: exercise huge-pages for LMEM Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:37   ` Chris Wilson
                     ` (2 more replies)
  2019-02-14 14:57 ` [RFC PATCH 14/42] drm/i915: introduce kernel blitter_context Matthew Auld
                   ` (31 subsequent siblings)
  44 siblings, 3 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Support clearing objects via the blitter engine. This is needed for LMEM
where we need to clear the backing store before handing the object to
userspace.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h               |   2 +
 drivers/gpu/drm/i915/i915_gem.c               | 151 ++++++++++++++++++
 drivers/gpu/drm/i915/intel_gpu_commands.h     |   1 +
 .../gpu/drm/i915/selftests/i915_gem_object.c  |  70 ++++++++
 4 files changed, 224 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a0ed000d52aa..feec3bab0f5f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2807,6 +2807,8 @@ void *i915_gem_object_alloc(struct drm_i915_private *dev_priv);
 void i915_gem_object_free(struct drm_i915_gem_object *obj);
 void i915_gem_object_init(struct drm_i915_gem_object *obj,
 			 const struct drm_i915_gem_object_ops *ops);
+int i915_gem_object_clear_blt(struct i915_gem_context *ctx,
+			      struct drm_i915_gem_object *obj);
 struct drm_i915_gem_object *
 i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size);
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7f044b643a75..032d4334c0f1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4288,6 +4288,157 @@ static bool discard_backing_storage(struct drm_i915_gem_object *obj)
 	return atomic_long_read(&obj->base.filp->f_count) == 1;
 }
 
+static struct i915_vma *
+__i915_gem_fill_blt(struct i915_vma *vma, u32 value)
+{
+	struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
+	const int gen = INTEL_GEN(i915);
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *batch;
+	u32 *cmd;
+	int err;
+
+	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
+	if (IS_ERR(cmd)) {
+		err = PTR_ERR(cmd);
+		goto err;
+	}
+
+	if (gen >= 8) {
+		*cmd++ = XY_COLOR_BLT_CMD | BLT_WRITE_RGBA;
+		*cmd++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE;
+		*cmd++ = 0;
+		*cmd++ = vma->obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+		*cmd++ = lower_32_bits(vma->node.start);
+		*cmd++ = upper_32_bits(vma->node.start);
+		*cmd++ = value;
+		*cmd++ = MI_NOOP;
+	} else {
+		*cmd++ = COLOR_BLT_CMD | BLT_WRITE_RGBA;
+		*cmd++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE;
+		*cmd++ = vma->obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE;
+		*cmd++ = vma->node.start;
+		*cmd++ = value;
+		*cmd++ = MI_NOOP;
+	}
+
+	*cmd = MI_BATCH_BUFFER_END;
+
+	i915_gem_object_unpin_map(obj);
+
+	err = i915_gem_object_set_to_gtt_domain(obj, false);
+	if (err)
+		goto err;
+
+	batch = i915_vma_instance(obj, vma->vm, NULL);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err;
+	}
+
+	err = i915_vma_pin(batch, 0, 0, PIN_USER);
+	if (err)
+		goto err;
+
+	return batch;
+
+err:
+	i915_gem_object_put(obj);
+	return ERR_PTR(err);
+}
+
+static int i915_gem_fill_blt(struct i915_gem_context *ctx,
+			     struct i915_vma *vma,
+			     u32 value)
+{
+	struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
+	struct intel_engine_cs *engine = i915->engine[BCS];
+	struct i915_request *rq;
+	struct i915_vma *batch;
+	int flags = 0;
+	int err;
+
+	err = i915_gem_object_set_to_gtt_domain(vma->obj, true);
+	if (err)
+		return err;
+
+	rq = i915_request_alloc(engine, ctx);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	batch = __i915_gem_fill_blt(vma, value);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err_request;
+	}
+
+	err = i915_vma_move_to_active(batch, rq, 0);
+	i915_vma_unpin(batch);
+	i915_vma_close(batch);
+	if (err) {
+		i915_gem_object_put(batch->obj);
+		goto err_request;
+	}
+
+	i915_gem_object_set_active_reference(batch->obj);
+
+	err = engine->emit_bb_start(rq,
+				    batch->node.start, batch->node.size,
+				    flags);
+	if (err)
+		goto err_request;
+
+	err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
+	if (err)
+		i915_request_skip(rq, err);
+
+err_request:
+	i915_request_add(rq);
+	return err;
+}
+
+static int i915_gem_object_fill_blt(struct i915_gem_context *ctx,
+				    struct drm_i915_gem_object *obj,
+				    u32 value)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->vm : &i915->ggtt.vm;
+	struct i915_vma *vma;
+	int err;
+
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	vma = i915_vma_instance(obj, vm, NULL);
+	if (IS_ERR(vma))
+		return PTR_ERR(vma);
+
+	err = i915_vma_pin(vma, 0, 0, PIN_USER);
+	if (err) {
+		i915_vma_close(vma);
+		return err;
+	}
+
+	err = i915_gem_fill_blt(ctx, vma, value);
+	i915_vma_unpin(vma);
+	if (err)
+		return err;
+
+	return i915_gem_object_wait(obj,
+				    I915_WAIT_LOCKED |
+				    I915_WAIT_ALL,
+				    MAX_SCHEDULE_TIMEOUT);
+}
+
+int i915_gem_object_clear_blt(struct i915_gem_context *ctx,
+			      struct drm_i915_gem_object *obj)
+{
+	return i915_gem_object_fill_blt(ctx, obj, 0);
+}
+
 static void __i915_gem_free_objects(struct drm_i915_private *i915,
 				    struct llist_node *freed)
 {
diff --git a/drivers/gpu/drm/i915/intel_gpu_commands.h b/drivers/gpu/drm/i915/intel_gpu_commands.h
index b96a31bc1080..f74ff1d095c2 100644
--- a/drivers/gpu/drm/i915/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/intel_gpu_commands.h
@@ -175,6 +175,7 @@
 #define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2)
 
 #define COLOR_BLT_CMD			(2<<29 | 0x40<<22 | (5-2))
+#define XY_COLOR_BLT_CMD              	(2<<29 | 0x50<<22 | (7-2))
 #define SRC_COPY_BLT_CMD		((2<<29)|(0x43<<22)|4)
 #define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6)
 #define XY_MONO_SRC_COPY_IMM_BLT	((2<<29)|(0x71<<22)|5)
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index 395ae878e0f7..c83dc5e2f219 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -628,6 +628,75 @@ static int igt_mmap_offset_exhaustion(void *arg)
 	goto out;
 }
 
+static int igt_fill_blt(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	struct drm_i915_gem_object *obj;
+	struct i915_gem_context *ctx;
+	struct drm_file *file;
+	struct rnd_state prng;
+	IGT_TIMEOUT(end);
+	u32 *vaddr;
+	int err;
+
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = live_context(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto err_file;
+	}
+
+	obj = i915_gem_object_create_internal(i915, SZ_2M);
+	if (IS_ERR(obj)) {
+		err = PTR_ERR(obj);
+		goto err_file;
+	}
+
+	vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
+	if (IS_ERR(vaddr)) {
+		err = PTR_ERR(vaddr);
+		goto err_put;
+	}
+
+	prandom_seed_state(&prng, i915_selftest.random_seed);
+
+	mutex_lock(&i915->drm.struct_mutex);
+
+	do {
+		u32 val = prandom_u32_state(&prng);
+		u32 i;
+
+		err = i915_gem_object_fill_blt(ctx, obj, val);
+		if (err)
+			break;
+
+		err = i915_gem_object_set_to_cpu_domain(obj, false);
+		if (err)
+			break;
+
+		for (i = 0; i < obj->base.size / sizeof(u32); ++i) {
+			if (vaddr[i] != val) {
+				pr_err("vaddr[%d]=%u, expected=%u\n", i,
+				       val, vaddr[i]);
+				err = -EINVAL;
+				break;
+			}
+		}
+	} while (!time_after(jiffies, end));
+
+	mutex_unlock(&i915->drm.struct_mutex);
+
+	i915_gem_object_unpin_map(obj);
+err_put:
+	i915_gem_object_put(obj);
+err_file:
+	mock_file_free(i915, file);
+	return err;
+}
+
 int i915_gem_object_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
@@ -653,6 +722,7 @@ int i915_gem_object_live_selftests(struct drm_i915_private *i915)
 		SUBTEST(igt_gem_huge),
 		SUBTEST(igt_partial_tiling),
 		SUBTEST(igt_mmap_offset_exhaustion),
+		SUBTEST(igt_fill_blt),
 	};
 
 	return i915_subtests(tests, i915);
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 14/42] drm/i915: introduce kernel blitter_context
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (12 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:42   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 15/42] drm/i915: support copying objects via blitter engine Matthew Auld
                   ` (30 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We may be without a context to perform various internal blitter
operations, for example when performing object migration. Piggybacking
off the kernel_context is probably a bad idea, since it has other uses.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h                  |  2 ++
 drivers/gpu/drm/i915/i915_gem_context.c          | 13 +++++++++++++
 drivers/gpu/drm/i915/selftests/mock_gem_device.c |  4 ++++
 3 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index feec3bab0f5f..5b39af57c36c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1544,6 +1544,8 @@ struct drm_i915_private {
 	struct intel_engine_cs *engine[I915_NUM_ENGINES];
 	/* Context used internally to idle the GPU and setup initial state */
 	struct i915_gem_context *kernel_context;
+	/* Context used internally for various blitting operations */
+	struct i915_gem_context *blitter_context;
 	/* Context only to be used for injecting preemption commands */
 	struct i915_gem_context *preempt_context;
 	struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 280813a4bf82..e814030dd89a 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -583,6 +583,18 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
 	GEM_BUG_ON(!atomic_read(&ctx->hw_id_pin_count));
 	dev_priv->kernel_context = ctx;
 
+	ctx = i915_gem_context_create_kernel(dev_priv, I915_PRIORITY_NORMAL);
+	if (IS_ERR(ctx)) {
+		DRM_ERROR("Failed to create blitter global context\n");
+		return PTR_ERR(ctx);
+	}
+
+	/*
+	 * XXX: one idea here is do s/kernel_context/idle_context/, then use the
+	 * kernel_context for doing things like blitting...
+	 */
+	dev_priv->blitter_context = ctx;
+
 	/* highest priority; preempting task */
 	if (needs_preempt_context(dev_priv)) {
 		ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX);
@@ -615,6 +627,7 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915)
 
 	if (i915->preempt_context)
 		destroy_kernel_context(&i915->preempt_context);
+	destroy_kernel_context(&i915->blitter_context);
 	destroy_kernel_context(&i915->kernel_context);
 
 	/* Must free all deferred contexts (via flush_workqueue) first */
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index f8901cd12180..0b59246c99c8 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -248,6 +248,10 @@ struct drm_i915_private *mock_gem_device(void)
 	if (!i915->engine[RCS])
 		goto err_context;
 
+	i915->blitter_context = mock_context(i915, NULL);
+	if (!i915->blitter_context)
+		goto err_context;
+
 	mutex_unlock(&i915->drm.struct_mutex);
 
 	WARN_ON(i915_gemfs_init(i915));
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 15/42] drm/i915: support copying objects via blitter engine
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (13 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 14/42] drm/i915: introduce kernel blitter_context Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 16/42] drm/i915: support basic object migration Matthew Auld
                   ` (29 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We need to support copying from one object backing store to another for
object migration.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h               |   3 +
 drivers/gpu/drm/i915/i915_gem.c               | 187 ++++++++++++++++++
 drivers/gpu/drm/i915/intel_gpu_commands.h     |   2 +
 .../gpu/drm/i915/selftests/i915_gem_object.c  |  80 ++++++++
 4 files changed, 272 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5b39af57c36c..b9d01caa3430 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2811,6 +2811,9 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 			 const struct drm_i915_gem_object_ops *ops);
 int i915_gem_object_clear_blt(struct i915_gem_context *ctx,
 			      struct drm_i915_gem_object *obj);
+int i915_gem_object_copy_blt(struct i915_gem_context *ctx,
+			     struct drm_i915_gem_object *src,
+			     struct drm_i915_gem_object *dst);
 struct drm_i915_gem_object *
 i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size);
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 032d4334c0f1..501714fbf92f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4288,6 +4288,193 @@ static bool discard_backing_storage(struct drm_i915_gem_object *obj)
 	return atomic_long_read(&obj->base.filp->f_count) == 1;
 }
 
+static struct i915_vma *
+__i915_gem_copy_blt(struct i915_vma *src, struct i915_vma *dst)
+{
+	struct drm_i915_private *i915 = to_i915(src->obj->base.dev);
+	const int gen = INTEL_GEN(i915);
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *batch;
+	u32 *cmd;
+	int err;
+
+	GEM_BUG_ON(src->vm != dst->vm);
+	GEM_BUG_ON(src->obj->base.size != dst->obj->base.size);
+
+	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
+	if (IS_ERR(cmd)) {
+		err = PTR_ERR(cmd);
+		goto err;
+	}
+
+	if (gen >= 9) {
+		*cmd++ = GEN9_XY_FAST_COPY_BLT_CMD;
+		*cmd++ = BLT_DEPTH_32 | PAGE_SIZE;
+		*cmd++ = 0;
+		*cmd++ = src->obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+		*cmd++ = lower_32_bits(dst->node.start);
+		*cmd++ = upper_32_bits(dst->node.start);
+		*cmd++ = 0;
+		*cmd++ = PAGE_SIZE;
+		*cmd++ = lower_32_bits(src->node.start);
+		*cmd++ = upper_32_bits(src->node.start);
+	} else if (gen >= 8) {
+		*cmd++ = GEN8_XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGBA;
+		*cmd++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE;
+		*cmd++ = 0;
+		*cmd++ = src->obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+		*cmd++ = lower_32_bits(dst->node.start);
+		*cmd++ = upper_32_bits(dst->node.start);
+		*cmd++ = 0;
+		*cmd++ = PAGE_SIZE;
+		*cmd++ = lower_32_bits(src->node.start);
+		*cmd++ = upper_32_bits(src->node.start);
+	} else {
+		*cmd++ = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGBA;
+		*cmd++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE;
+		*cmd++ = 0;
+		*cmd++ = src->obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+		*cmd++ = dst->node.start;
+		*cmd++ = 0;
+		*cmd++ = PAGE_SIZE;
+		*cmd++ = src->node.start;
+	}
+
+	*cmd = MI_BATCH_BUFFER_END;
+
+	i915_gem_object_unpin_map(obj);
+
+	err = i915_gem_object_set_to_gtt_domain(obj, false);
+	if (err)
+		goto err;
+
+	batch = i915_vma_instance(obj, src->vm, NULL);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err;
+	}
+
+	err = i915_vma_pin(batch, 0, 0, PIN_USER);
+	if (err)
+		goto err;
+
+	return batch;
+
+err:
+	i915_gem_object_put(obj);
+	return ERR_PTR(err);
+}
+
+static int i915_gem_copy_blt(struct i915_gem_context *ctx,
+			     struct i915_vma *src,
+			     struct i915_vma *dst)
+{
+	struct drm_i915_private *i915 = to_i915(src->obj->base.dev);
+	struct intel_engine_cs *engine = i915->engine[BCS];
+	struct i915_request *rq;
+	struct i915_vma *batch;
+	int flags = 0;
+	int err;
+
+	err = i915_gem_object_set_to_gtt_domain(src->obj, false);
+	if (err)
+		return err;
+
+	err = i915_gem_object_set_to_gtt_domain(dst->obj, true);
+	if (err)
+		return err;
+
+	rq = i915_request_alloc(engine, ctx);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	batch = __i915_gem_copy_blt(src, dst);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err_request;
+	}
+
+	err = i915_vma_move_to_active(batch, rq, 0);
+	i915_vma_unpin(batch);
+	i915_vma_close(batch);
+	if (err) {
+		i915_gem_object_put(batch->obj);
+		goto err_request;
+	}
+
+	i915_gem_object_set_active_reference(batch->obj);
+
+	err = engine->emit_bb_start(rq,
+				    batch->node.start, batch->node.size,
+				    flags);
+	if (err)
+		goto err_request;
+
+	err = i915_vma_move_to_active(src, rq, 0);
+	if (err) {
+		i915_request_skip(rq, err);
+		goto err_request;
+	}
+
+	err = i915_vma_move_to_active(dst, rq, EXEC_OBJECT_WRITE);
+	if (err)
+		i915_request_skip(rq, err);
+
+err_request:
+	i915_request_add(rq);
+	return err;
+}
+
+int i915_gem_object_copy_blt(struct i915_gem_context *ctx,
+			     struct drm_i915_gem_object *src,
+			     struct drm_i915_gem_object *dst)
+{
+	struct drm_i915_private *i915 = to_i915(src->base.dev);
+	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->vm: &i915->ggtt.vm;
+	struct i915_vma *src_vma;
+	struct i915_vma *dst_vma;
+	int err;
+
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	src_vma = i915_vma_instance(src, vm, NULL);
+	if (IS_ERR(src_vma))
+		return PTR_ERR(src_vma);
+
+	err = i915_vma_pin(src_vma, 0, 0, PIN_USER);
+	if (err)
+		return err;
+
+	dst_vma = i915_vma_instance(dst, vm, NULL);
+	if (IS_ERR(dst_vma)) {
+		err = PTR_ERR(dst_vma);
+		goto out_unpin_src;
+	}
+
+	err = i915_vma_pin(dst_vma, 0, 0, PIN_USER);
+	if (err)
+		goto out_unpin_src;
+
+	err = i915_gem_copy_blt(ctx, src_vma, dst_vma);
+	i915_vma_unpin(src_vma);
+	i915_vma_unpin(dst_vma);
+	if (err)
+		return err;
+
+	return i915_gem_object_wait(dst,
+				    I915_WAIT_LOCKED |
+				    I915_WAIT_ALL,
+				    MAX_SCHEDULE_TIMEOUT);
+
+out_unpin_src:
+	i915_vma_unpin(src_vma);
+	return err;
+}
+
 static struct i915_vma *
 __i915_gem_fill_blt(struct i915_vma *vma, u32 value)
 {
diff --git a/drivers/gpu/drm/i915/intel_gpu_commands.h b/drivers/gpu/drm/i915/intel_gpu_commands.h
index f74ff1d095c2..e97e9066676c 100644
--- a/drivers/gpu/drm/i915/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/intel_gpu_commands.h
@@ -178,6 +178,8 @@
 #define XY_COLOR_BLT_CMD              	(2<<29 | 0x50<<22 | (7-2))
 #define SRC_COPY_BLT_CMD		((2<<29)|(0x43<<22)|4)
 #define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6)
+#define GEN8_XY_SRC_COPY_BLT_CMD	((2<<29)|(0x53<<22)|8)
+#define GEN9_XY_FAST_COPY_BLT_CMD	((2<<29)|(0x42<<22)|8)
 #define XY_MONO_SRC_COPY_IMM_BLT	((2<<29)|(0x71<<22)|5)
 #define   BLT_WRITE_A			(2<<20)
 #define   BLT_WRITE_RGB			(1<<20)
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index c83dc5e2f219..dabb03885899 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -697,6 +697,85 @@ static int igt_fill_blt(void *arg)
 	return err;
 }
 
+static int igt_copy_blt(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	struct drm_i915_gem_object *src, *dst;
+	struct i915_gem_context *ctx;
+	struct drm_file *file;
+	u32 *vaddr;
+	int err;
+	u32 i;
+
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = live_context(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto err_file;
+	}
+
+	src = i915_gem_object_create_internal(i915, SZ_2M);
+	if (IS_ERR(src)) {
+		err = PTR_ERR(src);
+		goto err_file;
+	}
+
+	vaddr = i915_gem_object_pin_map(src, I915_MAP_WB);
+	if (IS_ERR(vaddr)) {
+		err = PTR_ERR(vaddr);
+		goto err_put_src;
+	}
+
+	for (i = 0; i < src->base.size / sizeof(u32); ++i)
+		vaddr[i] = i;
+
+	i915_gem_object_unpin_map(src);
+
+	dst = i915_gem_object_create_internal(i915, SZ_2M);
+	if (IS_ERR(dst)) {
+		err = PTR_ERR(dst);
+		goto err_put_src;
+	}
+
+	mutex_lock(&i915->drm.struct_mutex);
+
+	err = i915_gem_object_copy_blt(ctx, src, dst);
+	if (err)
+		goto err_put_dst;
+
+	err = i915_gem_object_set_to_cpu_domain(dst, false);
+	if (err)
+		goto err_put_dst;
+
+	mutex_unlock(&i915->drm.struct_mutex);
+
+	vaddr = i915_gem_object_pin_map(dst, I915_MAP_WB);
+	if (IS_ERR(vaddr)) {
+		err = PTR_ERR(vaddr);
+		goto err_put_dst;
+	}
+
+	for (i = 0; i < dst->base.size / sizeof(u32); ++i) {
+		if (vaddr[i] != i) {
+			pr_err("vaddr[%d]=%u, expected=%u\n", i, vaddr[i], i);
+			err = -EINVAL;
+			break;
+		}
+	}
+
+	i915_gem_object_unpin_map(dst);
+err_put_dst:
+	i915_gem_object_put(dst);
+err_put_src:
+	i915_gem_object_put(src);
+err_file:
+	mock_file_free(i915, file);
+	return err;
+}
+
 int i915_gem_object_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
@@ -723,6 +802,7 @@ int i915_gem_object_live_selftests(struct drm_i915_private *i915)
 		SUBTEST(igt_partial_tiling),
 		SUBTEST(igt_mmap_offset_exhaustion),
 		SUBTEST(igt_fill_blt),
+		SUBTEST(igt_copy_blt),
 	};
 
 	return i915_subtests(tests, i915);
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 16/42] drm/i915: support basic object migration
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (14 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 15/42] drm/i915: support copying objects via blitter engine Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 17/42] drm/i915/lmem: support kernel mapping Matthew Auld
                   ` (28 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We are going want to able to move objects between different regions
like system memory and local memory. In the future everything should
be just another region.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h               |   5 +
 drivers/gpu/drm/i915/i915_gem.c               | 121 +++++++++++++++++
 .../drm/i915/selftests/intel_memory_region.c  | 127 ++++++++++++++++++
 3 files changed, 253 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b9d01caa3430..bdf85e901268 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2822,6 +2822,11 @@ i915_gem_object_create_from_data(struct drm_i915_private *dev_priv,
 void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
 void i915_gem_free_object(struct drm_gem_object *obj);
 
+int i915_gem_object_prepare_move(struct drm_i915_gem_object *obj);
+int i915_gem_object_migrate(struct i915_gem_context *ctx,
+			    struct drm_i915_gem_object *obj,
+			    enum intel_region_id id);
+
 static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
 {
 	if (!atomic_read(&i915->mm.free_count))
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 501714fbf92f..33699b3dc395 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4626,6 +4626,127 @@ int i915_gem_object_clear_blt(struct i915_gem_context *ctx,
 	return i915_gem_object_fill_blt(ctx, obj, 0);
 }
 
+int i915_gem_object_prepare_move(struct drm_i915_gem_object *obj)
+{
+	int err;
+
+	lockdep_assert_held(&obj->base.dev->struct_mutex);
+
+	if (obj->mm.madv != I915_MADV_WILLNEED)
+		return -EINVAL;
+
+	if (i915_gem_object_needs_bit17_swizzle(obj))
+		return -EINVAL;
+
+	if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count)
+		return -EBUSY;
+
+	if (obj->pin_global)
+		return -EBUSY;
+
+	i915_gem_release_mmap(obj);
+
+	GEM_BUG_ON(obj->mm.mapping);
+	GEM_BUG_ON(obj->base.filp && mapping_mapped(obj->base.filp->f_mapping));
+
+	err = i915_gem_object_wait(obj,
+				   I915_WAIT_INTERRUPTIBLE |
+				   I915_WAIT_LOCKED |
+				   I915_WAIT_ALL,
+				   MAX_SCHEDULE_TIMEOUT);
+	if (err)
+		return err;
+
+	return i915_gem_object_unbind(obj);
+}
+
+int i915_gem_object_migrate(struct i915_gem_context *ctx,
+			    struct drm_i915_gem_object *obj,
+			    enum intel_region_id id)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct drm_i915_gem_object *donor;
+	struct intel_memory_region *mem;
+	int err = 0;
+
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	GEM_BUG_ON(id >= INTEL_MEMORY_UKNOWN);
+	GEM_BUG_ON(obj->memory_region->id == id);
+	GEM_BUG_ON(obj->mm.madv != I915_MADV_WILLNEED);
+
+	mem = i915->regions[id];
+
+	donor = i915_gem_object_create_region(mem, obj->base.size, 0);
+	if (IS_ERR(donor))
+		return PTR_ERR(donor);
+
+	/* Copy backing-pages if we have to */
+	if (i915_gem_object_has_pages(obj)) {
+		struct sg_table *pages;
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err)
+			goto err_put_donor;
+
+		err = i915_gem_object_copy_blt(ctx, obj, donor);
+		if (err)
+			goto err_put_donor;
+
+		i915_retire_requests(i915);
+
+		i915_gem_object_unbind(donor);
+		err = i915_gem_object_unbind(obj);
+		if (err)
+			goto err_put_donor;
+
+		mutex_lock(&obj->mm.lock);
+
+		pages = fetch_and_zero(&obj->mm.pages);
+		obj->ops->put_pages(obj, pages);
+
+		obj->mm.pages = __i915_gem_object_unset_pages(donor);
+		memcpy(&obj->mm.page_sizes, &donor->mm.page_sizes,
+		       sizeof(struct i915_page_sizes));
+
+		obj->mm.get_page.sg_pos = obj->mm.pages->sgl;
+		obj->mm.get_page.sg_idx = 0;
+		__i915_gem_object_reset_page_iter(obj);
+
+		mutex_unlock(&obj->mm.lock);
+	}
+
+	if (obj->ops->release)
+		obj->ops->release(obj);
+
+	/* We need still need a little special casing for shmem */
+	if (obj->base.filp)
+		fput(fetch_and_zero(&obj->base.filp));
+	else
+		obj->base.filp = fetch_and_zero(&donor->base.filp);
+
+	obj->base.size = donor->base.size;
+	obj->memory_region = mem;
+	obj->flags = donor->flags;
+	obj->ops = donor->ops;
+
+	list_replace_init(&donor->blocks, &obj->blocks);
+
+	mutex_lock(&mem->obj_lock);
+	list_add(&obj->region_link, &mem->objects);
+	mutex_unlock(&mem->obj_lock);
+
+	GEM_BUG_ON(i915_gem_object_has_pages(donor));
+	GEM_BUG_ON(i915_gem_object_has_pinned_pages(donor));
+
+err_put_donor:
+	i915_gem_object_put(donor);
+	if (i915_gem_object_has_pinned_pages(obj))
+		i915_gem_object_unpin_pages(obj);
+
+	return err;
+}
+
 static void __i915_gem_free_objects(struct drm_i915_private *i915,
 				    struct llist_node *freed)
 {
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 210ec6fec19a..2c07d8d219e5 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -579,6 +579,57 @@ static int igt_lmem_create(void *arg)
 	return err;
 }
 
+static int igt_smem_create_migrate(void *arg)
+{
+	struct i915_gem_context *ctx = arg;
+	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_gem_object *obj;
+	int err = 0;
+
+	/* Switch object backing-store on create */
+	obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+	err = i915_gem_object_migrate(ctx, obj, INTEL_MEMORY_SMEM);
+	if (err)
+		goto out_put;
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		goto out_put;
+
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
+static int igt_lmem_create_migrate(void *arg)
+{
+	struct i915_gem_context *ctx = arg;
+	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_gem_object *obj;
+	int err = 0;
+
+	/* Switch object backing-store on create */
+	obj = i915_gem_object_create(i915, PAGE_SIZE);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+	err = i915_gem_object_migrate(ctx, obj, INTEL_MEMORY_LMEM);
+	if (err)
+		goto out_put;
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		goto out_put;
+
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
 static int igt_lmem_write_gpu(void *arg)
 {
 	struct i915_gem_context *ctx = arg;
@@ -608,6 +659,79 @@ static int igt_lmem_write_gpu(void *arg)
 	return err;
 }
 
+static int igt_lmem_pages_migrate(void *arg)
+{
+	struct i915_gem_context *ctx = arg;
+	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_gem_object *obj;
+	int err;
+	int i;
+
+	/* From LMEM to shmem and back again */
+
+	obj = i915_gem_object_create_lmem(i915, SZ_2M, 0);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	err = i915_gem_object_clear_blt(ctx, obj);
+	if (err)
+		goto out_put;
+
+	for (i = 1; i <= 4; ++i) {
+		err = i915_gem_object_prepare_move(obj);
+		if (err)
+			goto out_put;
+
+		if (i915_gem_object_is_lmem(obj)) {
+			err = i915_gem_object_migrate(ctx, obj, INTEL_MEMORY_SMEM);
+			if (err)
+				goto out_put;
+
+			if (i915_gem_object_is_lmem(obj)) {
+				pr_err("object still backed by lmem\n");
+				err = -EINVAL;
+			}
+
+			if (!list_empty(&obj->blocks)) {
+				pr_err("object leaking memory region\n");
+				err = -EINVAL;
+			}
+
+			if (!i915_gem_object_has_struct_page(obj)) {
+				pr_err("object not backed by struct page\n");
+				err = -EINVAL;
+			}
+
+		} else {
+			err = i915_gem_object_migrate(ctx, obj, INTEL_MEMORY_LMEM);
+			if (err)
+				goto out_put;
+
+			if (i915_gem_object_has_struct_page(obj)) {
+				pr_err("object still backed by struct page\n");
+				err = -EINVAL;
+			}
+
+			if (!i915_gem_object_is_lmem(obj)) {
+				pr_err("object not backed by lmem\n");
+				err = -EINVAL;
+			}
+		}
+
+		if (err)
+			break;
+
+		err = i915_gem_object_fill_blt(ctx, obj, 0xdeadbeaf);
+		if (err)
+			break;
+	}
+
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
 	static const struct i915_subtest tests[] = {
@@ -649,7 +773,10 @@ int intel_memory_region_live_selftests(struct drm_i915_private *i915)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_lmem_create),
+		SUBTEST(igt_smem_create_migrate),
+		SUBTEST(igt_lmem_create_migrate),
 		SUBTEST(igt_lmem_write_gpu),
+		SUBTEST(igt_lmem_pages_migrate),
 	};
 	struct i915_gem_context *ctx;
 	struct drm_file *file;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 17/42] drm/i915/lmem: support kernel mapping
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (15 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 16/42] drm/i915: support basic object migration Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations Matthew Auld
                   ` (27 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c               |  18 ++-
 drivers/gpu/drm/i915/intel_memory_region.h    |   3 +
 drivers/gpu/drm/i915/intel_region_lmem.c      |  24 ++++
 drivers/gpu/drm/i915/intel_region_lmem.h      |   5 +
 drivers/gpu/drm/i915/selftests/huge_pages.c   |   3 +-
 .../drm/i915/selftests/intel_memory_region.c  | 107 +++++++++++++++++-
 6 files changed, 148 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 33699b3dc395..3f319524beed 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2257,7 +2257,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));
@@ -2625,7 +2627,7 @@ int __i915_gem_object_get_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;
@@ -2638,6 +2640,11 @@ 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)) {
+		/* XXX: we are ignoring the type here -- this is simply wc */
+		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));
@@ -2683,7 +2690,8 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 	void *ptr;
 	int ret;
 
-	if (unlikely(!i915_gem_object_has_struct_page(obj)))
+	if (unlikely(!i915_gem_object_has_struct_page(obj) &&
+		     !i915_gem_object_is_lmem(obj)))
 		return ERR_PTR(-ENXIO);
 
 	ret = mutex_lock_interruptible(&obj->mm.lock);
@@ -2715,7 +2723,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/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index b1546afb0b6e..7754989ad165 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -115,6 +115,9 @@ void i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
 
 void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj);
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+					  unsigned long n);
+
 struct intel_memory_region *
 intel_memory_region_create(struct drm_i915_private *i915,
 			   resource_size_t start,
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
index b398becb2733..c8bee0c18c88 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -65,6 +65,30 @@ static const struct intel_memory_region_ops region_lmem_ops = {
 	.object_create = region_lmem_object_create,
 };
 
+/* 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_atomic_wc(&obj->memory_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->memory_region->iomap, offset, size);
+}
+
 unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
 					  unsigned long n)
 {
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h b/drivers/gpu/drm/i915/intel_region_lmem.h
index 1aa24bd28690..a76b77b69e71 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.h
+++ b/drivers/gpu/drm/i915/intel_region_lmem.h
@@ -28,6 +28,11 @@
 unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
 					  unsigned long n);
 
+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);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index f4283d41c13f..103362f8c553 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -1144,8 +1144,7 @@ static int __cpu_check_lmem(struct drm_i915_gem_object *obj, u32 dword, u32 val)
 		u32 __iomem *base;
 		u32 read_val;
 
-		base = (void __force *)io_mapping_map_atomic_wc(&obj->memory_region->iomap,
-								i915_gem_object_get_dma_address(obj, n));
+		base = i915_gem_object_lmem_io_map_page(obj, n);
 
 		read_val = ioread32(base + dword);
 		io_mapping_unmap_atomic(base);
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 2c07d8d219e5..ad8d2eeacf53 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -28,6 +28,9 @@
 #include "mock_context.h"
 #include "mock_drm.h"
 
+typedef int (*cpu_check_fn_t)(struct drm_i915_gem_object *obj,
+			      u32 __iomem *base, u32 dword, u32 val);
+
 static void close_objects(struct list_head *objects)
 {
 	struct drm_i915_gem_object *obj, *on;
@@ -487,7 +490,9 @@ static int igt_gpu_write(struct i915_vma *vma,
 	return err;
 }
 
-static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+static int igt_cpu_check(struct drm_i915_gem_object *obj,
+			 u32 __iomem *base,
+			 u32 dword, u32 val)
 {
 	unsigned long n;
 	int err;
@@ -504,8 +509,7 @@ static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
 		u32 __iomem *base;
 		u32 read_val;
 
-		base = (void __force *) io_mapping_map_atomic_wc(&obj->memory_region->iomap,
-								 i915_gem_object_get_dma_address(obj, n));
+		base = i915_gem_object_lmem_io_map_page(obj, n);
 
 		read_val = ioread32(base + dword);
 		io_mapping_unmap_atomic(base);
@@ -523,11 +527,13 @@ static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
 
 static int igt_gpu_fill(struct i915_gem_context *ctx,
 			struct drm_i915_gem_object *obj,
-			u32 val)
+			cpu_check_fn_t cpu_check,
+			u32 __iomem *base)
 {
 	struct drm_i915_private *i915 = ctx->i915;
 	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->vm : &i915->ggtt.vm;
 	struct i915_vma *vma;
+	struct rnd_state prng;
 	u32 dword;
 	int err;
 
@@ -541,12 +547,14 @@ static int igt_gpu_fill(struct i915_gem_context *ctx,
 		return err;
 	}
 
+	prandom_seed_state(&prng, i915_selftest.random_seed);
 	for (dword = 0; dword < PAGE_SIZE / sizeof(u32); ++dword) {
+		u32 val = prandom_u32_state(&prng);
 		err = igt_gpu_write(vma, ctx, i915->engine[RCS], dword, val);
 		if (err)
 			break;
 
-		err = igt_cpu_check(obj, dword, val);
+		err = cpu_check(obj, base, dword, val);
 		if (err)
 			break;
 	}
@@ -645,7 +653,7 @@ static int igt_lmem_write_gpu(void *arg)
 	if (err)
 		goto out_put;
 
-	err = igt_gpu_fill(ctx, obj, 0xdeadbeaf);
+	err = igt_gpu_fill(ctx, obj, igt_cpu_check, NULL);
 	if (err) {
 		pr_err("igt_gpu_fill failed(%d)\n", err);
 		goto out_unpin;
@@ -659,6 +667,92 @@ static int igt_lmem_write_gpu(void *arg)
 	return err;
 }
 
+static int igt_lmem_cpu_check(struct drm_i915_gem_object *obj,
+			      u32 __iomem *base, u32 dword, u32 val)
+{
+	u32 read_val;
+	int err;
+
+	err = i915_gem_object_wait(obj,
+				   I915_WAIT_INTERRUPTIBLE |
+				   I915_WAIT_LOCKED,
+				   MAX_SCHEDULE_TIMEOUT);
+	if (err)
+		return err;
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		return err;
+
+	read_val = ioread32(base + dword);
+        if (read_val != val) {
+		pr_err("base[%u]=0x%x, val=0x%x\n",
+		       dword, read_val, val);
+		return -EINVAL;
+	}
+
+	i915_gem_object_unpin_pages(obj);
+	return 0;
+}
+
+static int igt_lmem_write_cpu(void *arg)
+{
+	struct i915_gem_context *ctx = arg;
+	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_gem_object *obj;
+	struct rnd_state prng;
+	u32 __iomem *vaddr;
+	u32 dword;
+	int ret = 0;
+
+	obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, I915_BO_ALLOC_CONTIGUOUS);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	ret = i915_gem_object_pin_pages(obj);
+	if (ret)
+		goto out_put;
+
+	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));
+		ret = PTR_ERR(vaddr);
+		goto out_unpin;
+	}
+
+	/* gpu write/cpu read */
+	ret = igt_gpu_fill(ctx, obj, igt_lmem_cpu_check, vaddr);
+	if (ret) {
+		pr_err("igt_gpu_fill failed(%d)\n", ret);
+		goto out_unpin;
+	}
+
+	/* cpu write/cpu read */
+	prandom_seed_state(&prng, i915_selftest.random_seed);
+	for (dword = 0; dword < PAGE_SIZE / sizeof(u32); ++dword) {
+		u32 read_val;
+		u32 val = prandom_u32_state(&prng);
+
+		iowrite32(val, vaddr + dword);
+		wmb();
+
+		read_val = ioread32(vaddr + dword);
+		if (read_val != val) {
+			pr_err("base[%u]=%u, val=%u\n", dword, read_val, val);
+			ret = -EINVAL;
+			break;
+		}
+	}
+
+	i915_gem_object_unpin_map(obj);
+
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+	return ret;
+}
+
 static int igt_lmem_pages_migrate(void *arg)
 {
 	struct i915_gem_context *ctx = arg;
@@ -776,6 +870,7 @@ int intel_memory_region_live_selftests(struct drm_i915_private *i915)
 		SUBTEST(igt_smem_create_migrate),
 		SUBTEST(igt_lmem_create_migrate),
 		SUBTEST(igt_lmem_write_gpu),
+		SUBTEST(igt_lmem_write_cpu),
 		SUBTEST(igt_lmem_pages_migrate),
 	};
 	struct i915_gem_context *ctx;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (16 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 17/42] drm/i915/lmem: support kernel mapping Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:48   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 19/42] drm/i915: add vfunc for pread Matthew Auld
                   ` (26 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We need to support doing relocations from the CPU when dealing with LMEM
objects.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 67 ++++++++++++++++++----
 1 file changed, 56 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 02adcaf6ebea..390691128c1d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -265,6 +265,7 @@ struct i915_execbuffer {
 		bool has_llc : 1;
 		bool has_fence : 1;
 		bool needs_unfenced : 1;
+		bool is_lmem : 1;
 
 		struct i915_request *rq;
 		u32 *rq_cmd;
@@ -973,6 +974,7 @@ static void reloc_cache_init(struct reloc_cache *cache,
 	cache->use_64bit_reloc = HAS_64BIT_RELOC(i915);
 	cache->has_fence = cache->gen < 4;
 	cache->needs_unfenced = INTEL_INFO(i915)->unfenced_needs_alignment;
+	cache->is_lmem = false;
 	cache->node.allocated = false;
 	cache->rq = NULL;
 	cache->rq_size = 0;
@@ -1027,16 +1029,23 @@ static void reloc_cache_reset(struct reloc_cache *cache)
 		i915_gem_obj_finish_shmem_access((struct drm_i915_gem_object *)cache->node.mm);
 	} else {
 		wmb();
-		io_mapping_unmap_atomic((void __iomem *)vaddr);
-		if (cache->node.allocated) {
-			struct i915_ggtt *ggtt = cache_to_ggtt(cache);
-
-			ggtt->vm.clear_range(&ggtt->vm,
-					     cache->node.start,
-					     cache->node.size);
-			drm_mm_remove_node(&cache->node);
+
+		if (cache->is_lmem) {
+			io_mapping_unmap_atomic((void __iomem *)vaddr);
+			i915_gem_object_unpin_pages((struct drm_i915_gem_object *)cache->node.mm);
+			cache->is_lmem = false;
 		} else {
-			i915_vma_unpin((struct i915_vma *)cache->node.mm);
+			io_mapping_unmap_atomic((void __iomem *)vaddr);
+			if (cache->node.allocated) {
+				struct i915_ggtt *ggtt = cache_to_ggtt(cache);
+
+				ggtt->vm.clear_range(&ggtt->vm,
+						     cache->node.start,
+						     cache->node.size);
+				drm_mm_remove_node(&cache->node);
+			} else {
+				i915_vma_unpin((struct i915_vma *)cache->node.mm);
+			}
 		}
 	}
 
@@ -1076,6 +1085,38 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
 	return vaddr;
 }
 
+static void *reloc_lmem(struct drm_i915_gem_object *obj,
+			struct reloc_cache *cache,
+			unsigned long page)
+{
+	void *vaddr;
+	int err;
+
+	GEM_BUG_ON(use_cpu_reloc(cache, obj));
+
+	if (cache->vaddr) {
+		io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
+	} else {
+		err = i915_gem_object_set_to_wc_domain(obj, true);
+		if (err)
+			return ERR_PTR(err);
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err)
+			return ERR_PTR(err);
+
+		cache->node.mm = (void *)obj;
+		cache->is_lmem = true;
+	}
+
+	vaddr = i915_gem_object_lmem_io_map_page(obj, page);
+
+	cache->vaddr = (unsigned long)vaddr;
+	cache->page = page;
+
+	return vaddr;
+}
+
 static void *reloc_iomap(struct drm_i915_gem_object *obj,
 			 struct reloc_cache *cache,
 			 unsigned long page)
@@ -1150,8 +1191,12 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
 		vaddr = unmask_page(cache->vaddr);
 	} else {
 		vaddr = NULL;
-		if ((cache->vaddr & KMAP) == 0)
-			vaddr = reloc_iomap(obj, cache, page);
+		if ((cache->vaddr & KMAP) == 0) {
+			if (i915_gem_object_is_lmem(obj))
+				vaddr = reloc_lmem(obj, cache, page);
+			else
+				vaddr = reloc_iomap(obj, cache, page);
+		}
 		if (!vaddr)
 			vaddr = reloc_kmap(obj, cache, page);
 	}
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 19/42] drm/i915: add vfunc for pread
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (17 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 20/42] drm/i915/lmem: support pread Matthew Auld
                   ` (25 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c        | 6 ++++++
 drivers/gpu/drm/i915/i915_gem_object.h | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3f319524beed..43e813d0e647 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1116,6 +1116,12 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 
 	trace_i915_gem_object_pread(obj, args->offset, args->size);
 
+	ret = -ENODEV;
+	if (obj->ops->pread)
+		ret = obj->ops->pread(obj, args);
+	if (ret != -ENODEV)
+		goto out;
+
 	ret = i915_gem_object_wait(obj,
 				   I915_WAIT_INTERRUPTIBLE,
 				   MAX_SCHEDULE_TIMEOUT);
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 0dfe9603e3cc..f5b8bca33fe3 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -75,6 +75,8 @@ struct drm_i915_gem_object_ops {
 	int (*get_pages)(struct drm_i915_gem_object *);
 	void (*put_pages)(struct drm_i915_gem_object *, struct sg_table *);
 
+	int (*pread)(struct drm_i915_gem_object *,
+		     const struct drm_i915_gem_pread *);
 	int (*pwrite)(struct drm_i915_gem_object *,
 		      const struct drm_i915_gem_pwrite *);
 
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 20/42] drm/i915/lmem: support pread
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (18 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 19/42] drm/i915: add vfunc for pread Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:50   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 21/42] drm/i915/lmem: support pwrite Matthew Auld
                   ` (24 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We need to add support for pread'ing an LMEM object.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_region_lmem.c | 73 ++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
index c8bee0c18c88..67dc50be2e6b 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -26,10 +26,83 @@
 #include "intel_memory_region.h"
 #include "intel_region_lmem.h"
 
+static int region_lmem_pread(struct drm_i915_gem_object *obj,
+			     const struct drm_i915_gem_pread *args)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	intel_wakeref_t wakeref;
+	char __user *user_data;
+	unsigned int offset;
+	unsigned long idx;
+	u64 remain;
+	int ret;
+
+	ret = i915_gem_object_wait(obj,
+				   I915_WAIT_INTERRUPTIBLE,
+				   MAX_SCHEDULE_TIMEOUT);
+	if (ret)
+		return ret;
+
+	ret = i915_gem_object_pin_pages(obj);
+	if (ret)
+		return ret;
+
+	ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
+	if (ret)
+		goto out_unpin;
+
+	wakeref = intel_runtime_pm_get(i915);
+
+	ret = i915_gem_object_set_to_wc_domain(obj, false);
+	mutex_unlock(&i915->drm.struct_mutex);
+	if (ret)
+		goto out_put;
+
+	remain = args->size;
+	user_data = u64_to_user_ptr(args->data_ptr);
+	offset = offset_in_page(args->offset);
+	for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
+		unsigned long unwritten;
+		void __iomem *vaddr;
+		int length;
+
+		length = remain;
+		if (offset + length > PAGE_SIZE)
+			length = PAGE_SIZE - offset;
+
+		vaddr = i915_gem_object_lmem_io_map_page(obj, idx);
+		if (!vaddr) {
+			ret = -ENOMEM;
+			goto out_put;
+		}
+
+		unwritten = copy_to_user(user_data,
+					 (void __force *)vaddr + offset,
+					 length);
+		io_mapping_unmap_atomic(vaddr);
+		if (unwritten) {
+			ret = -EFAULT;
+			goto out_put;
+		}
+
+		remain -= length;
+		user_data += length;
+		offset = 0;
+	}
+
+out_put:
+	intel_runtime_pm_put(i915, wakeref);
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+
+	return ret;
+}
+
 static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
 	.get_pages = i915_memory_region_get_pages_buddy,
 	.put_pages = i915_memory_region_put_pages_buddy,
 	.release = i915_gem_object_release_memory_region,
+	.pread = region_lmem_pread,
 };
 
 static struct drm_i915_gem_object *
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 21/42] drm/i915/lmem: support pwrite
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (19 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 20/42] drm/i915/lmem: support pread Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 22/42] drm/i915: define HAS_MAPPABLE_APERTURE Matthew Auld
                   ` (23 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

We need to add support for pwrite'ing an LMEM object.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_region_lmem.c | 73 ++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
index 67dc50be2e6b..d549242a3578 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -98,11 +98,84 @@ static int region_lmem_pread(struct drm_i915_gem_object *obj,
 	return ret;
 }
 
+static int region_lmem_pwrite(struct drm_i915_gem_object *obj,
+			      const struct drm_i915_gem_pwrite *args)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	intel_wakeref_t wakeref;
+	char __user *user_data;
+	unsigned int offset;
+	unsigned long idx;
+	u64 remain;
+	int ret;
+
+	ret = i915_gem_object_wait(obj,
+				   I915_WAIT_INTERRUPTIBLE,
+				   MAX_SCHEDULE_TIMEOUT);
+	if (ret)
+		return ret;
+
+	ret = i915_gem_object_pin_pages(obj);
+	if (ret)
+		return ret;
+
+	ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
+	if (ret)
+		goto out_unpin;
+
+	wakeref = intel_runtime_pm_get(i915);
+
+	ret = i915_gem_object_set_to_wc_domain(obj, true);
+	mutex_unlock(&i915->drm.struct_mutex);
+	if (ret)
+		goto out_put;
+
+	remain = args->size;
+	user_data = u64_to_user_ptr(args->data_ptr);
+	offset = offset_in_page(args->offset);
+	for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
+		unsigned long unwritten;
+		void __iomem *vaddr;
+		int length;
+
+		length = remain;
+		if (offset + length > PAGE_SIZE)
+			length = PAGE_SIZE - offset;
+
+		vaddr = i915_gem_object_lmem_io_map_page(obj, idx);
+		if (!vaddr) {
+			ret = -ENOMEM;
+			goto out_put;
+		}
+
+		unwritten = copy_from_user((void __force*)vaddr + offset,
+					   user_data,
+					   length);
+		io_mapping_unmap_atomic(vaddr);
+		if (unwritten) {
+			ret = -EFAULT;
+			goto out_put;
+		}
+
+		remain -= length;
+		user_data += length;
+		offset = 0;
+	}
+
+out_put:
+	intel_runtime_pm_put(i915, wakeref);
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+
+	return ret;
+}
+
 static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
 	.get_pages = i915_memory_region_get_pages_buddy,
 	.put_pages = i915_memory_region_put_pages_buddy,
 	.release = i915_gem_object_release_memory_region,
 	.pread = region_lmem_pread,
+	.pwrite = region_lmem_pwrite,
 };
 
 static struct drm_i915_gem_object *
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 22/42] drm/i915: define HAS_MAPPABLE_APERTURE
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (20 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 21/42] drm/i915/lmem: support pwrite Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 23/42] drm/i915: do not map aperture if it is not available Matthew Auld
                   ` (22 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

The following patches in the series will use it to avoid certain
operations when aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bdf85e901268..772fffa87545 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2481,6 +2481,8 @@ static inline unsigned int i915_sg_segment_size(void)
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
 		(INTEL_INFO(dev_priv)->display.overlay_needs_physical)
 
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)
+
 /* Early gen2 have a totally busted CS tlb and require pinned batches. */
 #define HAS_BROKEN_CS_TLB(dev_priv)	(IS_I830(dev_priv) || IS_I845G(dev_priv))
 
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 23/42] drm/i915: do not map aperture if it is not available.
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (21 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 22/42] drm/i915: define HAS_MAPPABLE_APERTURE Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 24/42] drm/i915: expose missing map_gtt support to users Matthew Auld
                   ` (21 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

Skip both setup and cleanup of the aperture mapping if the HW doesn't
have an aperture bar.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 34 ++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index de67a2f1ccfe..3732f21148d3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2831,8 +2831,10 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
 
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
-	arch_phys_wc_del(ggtt->mtrr);
-	io_mapping_fini(&ggtt->iomap);
+	if (HAS_MAPPABLE_APERTURE(dev_priv)) {
+		arch_phys_wc_del(ggtt->mtrr);
+		io_mapping_fini(&ggtt->iomap);
+	}
 
 	i915_gem_cleanup_stolen(dev_priv);
 }
@@ -3214,10 +3216,13 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 	int err;
 
 	/* TODO: We're not aware of mappable constraints on gen8 yet */
-	ggtt->gmadr =
-		(struct resource) DEFINE_RES_MEM(pci_resource_start(pdev, 2),
-						 pci_resource_len(pdev, 2));
-	ggtt->mappable_end = resource_size(&ggtt->gmadr);
+	/* FIXME: We probably need to add do device_info or runtime_info */
+	if (!HAS_LMEM(dev_priv)) {
+		ggtt->gmadr =
+			(struct resource) DEFINE_RES_MEM(pci_resource_start(pdev, 2),
+							 pci_resource_len(pdev, 2));
+		ggtt->mappable_end = resource_size(&ggtt->gmadr);
+	}
 
 	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(39));
 	if (!err)
@@ -3454,14 +3459,17 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
 		ggtt->vm.mm.color_adjust = i915_gtt_color_adjust;
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
-	if (!io_mapping_init_wc(&dev_priv->ggtt.iomap,
-				dev_priv->ggtt.gmadr.start,
-				dev_priv->ggtt.mappable_end)) {
-		ret = -EIO;
-		goto out_gtt_cleanup;
-	}
+	if (HAS_MAPPABLE_APERTURE(dev_priv)) {
+		if (!io_mapping_init_wc(&dev_priv->ggtt.iomap,
+					dev_priv->ggtt.gmadr.start,
+					dev_priv->ggtt.mappable_end)) {
+			ret = -EIO;
+			goto out_gtt_cleanup;
+		}
 
-	ggtt->mtrr = arch_phys_wc_add(ggtt->gmadr.start, ggtt->mappable_end);
+		ggtt->mtrr = arch_phys_wc_add(ggtt->gmadr.start,
+					      ggtt->mappable_end);
+	}
 
 	/*
 	 * Initialise stolen early so that we may reserve preallocated
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 24/42] drm/i915: expose missing map_gtt support to users
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (22 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 23/42] drm/i915: do not map aperture if it is not available Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 25/42] drm/i915: set num_fence_regs to 0 if there is no aperture Matthew Auld
                   ` (20 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

Done by returning -ENODEV from the map_gtt version ioctl.

Cc: Antonio Argenziano <antonio.argenziano@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6630212f2faf..dc446430a340 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -390,6 +390,8 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
 			return value;
 		break;
 	case I915_PARAM_MMAP_GTT_VERSION:
+		if (!HAS_MAPPABLE_APERTURE(dev_priv))
+			return -ENODEV;
 		/* Though we've started our numbering from 1, and so class all
 		 * earlier versions as 0, in effect their value is undefined as
 		 * the ioctl will report EINVAL for the unknown param!
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 25/42] drm/i915: set num_fence_regs to 0 if there is no aperture
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (23 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 24/42] drm/i915: expose missing map_gtt support to users Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 26/42] drm/i915: error capture with no ggtt slot Matthew Auld
                   ` (19 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

We can't fence anything without aperture.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 43e813d0e647..e59f38e00f0d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5666,8 +5666,10 @@ i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
 {
 	int i;
 
-	if (INTEL_GEN(dev_priv) >= 7 && !IS_VALLEYVIEW(dev_priv) &&
-	    !IS_CHERRYVIEW(dev_priv))
+	if (!HAS_MAPPABLE_APERTURE(dev_priv))
+		dev_priv->num_fence_regs = 0;
+	else if (INTEL_GEN(dev_priv) >= 7 && !IS_VALLEYVIEW(dev_priv) &&
+		 !IS_CHERRYVIEW(dev_priv))
 		dev_priv->num_fence_regs = 32;
 	else if (INTEL_GEN(dev_priv) >= 4 ||
 		 IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 26/42] drm/i915: error capture with no ggtt slot
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (24 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 25/42] drm/i915: set num_fence_regs to 0 if there is no aperture Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 15:56   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 27/42] drm/i915: Don't try to place HWS in non-existing mappable region Matthew Auld
                   ` (18 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

If the aperture is not available in HW we can't use a ggtt slot and wc
copy, so fal back to regular kmap.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 19 ++++----
 drivers/gpu/drm/i915/i915_gpu_error.c | 63 ++++++++++++++++++++-------
 2 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 3732f21148d3..045c6715d5a6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2763,13 +2763,15 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
 	if (ret)
 		return ret;
 
-	/* Reserve a mappable slot for our lockless error capture */
-	ret = drm_mm_insert_node_in_range(&ggtt->vm.mm, &ggtt->error_capture,
-					  PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
-					  0, ggtt->mappable_end,
-					  DRM_MM_INSERT_LOW);
-	if (ret)
-		return ret;
+	if (HAS_MAPPABLE_APERTURE(dev_priv)) {
+		/* Reserve a mappable slot for our lockless error capture */
+		ret = drm_mm_insert_node_in_range(&ggtt->vm.mm, &ggtt->error_capture,
+						  PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
+						  0, ggtt->mappable_end,
+						  DRM_MM_INSERT_LOW);
+		if (ret)
+			return ret;
+	}
 
 	/* Clear any non-preallocated blocks */
 	drm_mm_for_each_hole(entry, &ggtt->vm.mm, hole_start, hole_end) {
@@ -2791,7 +2793,8 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
 	return 0;
 
 err:
-	drm_mm_remove_node(&ggtt->error_capture);
+	if (drm_mm_node_allocated(&ggtt->error_capture))
+		drm_mm_remove_node(&ggtt->error_capture);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 9a65341fec09..9ccd6cfa6c25 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -211,7 +211,7 @@ struct compress {
 	void *tmp;
 };
 
-static bool compress_init(struct compress *c)
+static bool compress_init(struct compress *c, bool wc)
 {
 	struct z_stream_s *zstream = memset(&c->zstream, 0, sizeof(c->zstream));
 
@@ -227,7 +227,7 @@ static bool compress_init(struct compress *c)
 	}
 
 	c->tmp = NULL;
-	if (i915_has_memcpy_from_wc())
+	if (wc && i915_has_memcpy_from_wc())
 		c->tmp = (void *)__get_free_page(GFP_ATOMIC | __GFP_NOWARN);
 
 	return true;
@@ -328,10 +328,12 @@ static void err_compression_marker(struct drm_i915_error_state_buf *m)
 #else
 
 struct compress {
+	bool wc;
 };
 
-static bool compress_init(struct compress *c)
+static bool compress_init(struct compress *c, bool wc)
 {
+	c->wc = wc;
 	return true;
 }
 
@@ -347,7 +349,7 @@ static int compress_page(struct compress *c,
 		return -ENOMEM;
 
 	ptr = (void *)page;
-	if (!i915_memcpy_from_wc(ptr, src, PAGE_SIZE))
+	if (!(c->wc && i915_memcpy_from_wc(ptr, src, PAGE_SIZE)))
 		memcpy(ptr, src, PAGE_SIZE);
 	dst->pages[dst->page_count++] = ptr;
 
@@ -1013,7 +1015,6 @@ i915_error_object_create(struct drm_i915_private *i915,
 	struct compress compress;
 	unsigned long num_pages;
 	struct sgt_iter iter;
-	dma_addr_t dma;
 	int ret;
 
 	if (!vma || !vma->pages)
@@ -1032,22 +1033,52 @@ i915_error_object_create(struct drm_i915_private *i915,
 	dst->page_count = 0;
 	dst->unused = 0;
 
-	if (!compress_init(&compress)) {
+	if (!compress_init(&compress, drm_mm_node_allocated(&ggtt->error_capture))) {
 		kfree(dst);
 		return NULL;
 	}
 
 	ret = -EINVAL;
-	for_each_sgt_dma(dma, iter, vma->pages) {
+	if (drm_mm_node_allocated(&ggtt->error_capture)) {
 		void __iomem *s;
+		dma_addr_t dma;
 
-		ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
+		for_each_sgt_dma(dma, iter, vma->pages) {
+			ggtt->vm.insert_page(&ggtt->vm, dma, slot,
+					     I915_CACHE_NONE, 0);
 
-		s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
-		ret = compress_page(&compress, (void  __force *)s, dst);
-		io_mapping_unmap_atomic(s);
-		if (ret)
-			break;
+			s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
+			ret = compress_page(&compress, (void  __force *)s, dst);
+			io_mapping_unmap_atomic(s);
+
+			if (ret)
+				break;
+		}
+	} else if (i915_gem_object_is_lmem(vma->obj)) {
+		void *s;
+		dma_addr_t dma;
+		struct intel_memory_region *mem = vma->obj->memory_region;
+
+		for_each_sgt_dma(dma, iter, vma->pages) {
+			s = io_mapping_map_atomic_wc(&mem->iomap, dma);
+			ret = compress_page(&compress, s, dst);
+			io_mapping_unmap_atomic(s);
+
+			if (ret)
+				break;
+		}
+	} else {
+		void *s;
+		struct page *page;
+
+		for_each_sgt_page(page, iter, vma->pages) {
+			s = kmap_atomic(page);
+			ret = compress_page(&compress, s, dst);
+			kunmap_atomic(s);
+
+			if (ret)
+				break;
+		}
 	}
 
 	if (ret || compress_flush(&compress, dst)) {
@@ -1784,9 +1815,11 @@ static unsigned long capture_find_epoch(const struct i915_gpu_state *error)
 static void capture_finish(struct i915_gpu_state *error)
 {
 	struct i915_ggtt *ggtt = &error->i915->ggtt;
-	const u64 slot = ggtt->error_capture.start;
 
-	ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
+	if (drm_mm_node_allocated(&ggtt->error_capture)) {
+		const u64 slot = ggtt->error_capture.start;
+		ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
+	}
 }
 
 static int capture(void *data)
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 27/42] drm/i915: Don't try to place HWS in non-existing mappable region
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (25 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 26/42] drm/i915: error capture with no ggtt slot Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 28/42] drm/i915: Split out GTT fault handler to make it generic Matthew Auld
                   ` (17 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

From: Michal Wajdeczko <michal.wajdeczko@intel.com>

HWS placement restrictions can't just rely on HAS_LLC flag.

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
---
 drivers/gpu/drm/i915/intel_engine_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 2547e2e51db8..3384cdf7edab 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -502,7 +502,7 @@ static int pin_ggtt_status_page(struct intel_engine_cs *engine,
 	unsigned int flags;
 
 	flags = PIN_GLOBAL;
-	if (!HAS_LLC(engine->i915))
+	if (!HAS_LLC(engine->i915) && HAS_MAPPABLE_APERTURE(engine->i915))
 		/*
 		 * On g33, we cannot place HWS above 256MiB, so
 		 * restrict its pinning to the low mappable arena.
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 28/42] drm/i915: Split out GTT fault handler to make it generic
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (26 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 27/42] drm/i915: Don't try to place HWS in non-existing mappable region Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 16:00   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 29/42] drm/i915: Set correct vmf source pages for gem objects Matthew Auld
                   ` (16 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

In preparation for using multiple page-fault handlers depending
on the object's backing storage.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 112 +++++++++++++++++++-------------
 1 file changed, 66 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e59f38e00f0d..95e31529a738 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1782,11 +1782,7 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
 }
 
 /**
- * i915_gem_fault - fault a page into the GTT
- * @vmf: fault info
- *
- * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped
- * from userspace.  The fault handler takes care of binding the object to
+ * The GTT fill pages handler takes care of binding the object to
  * the GTT (if needed), allocating and programming a fence register (again,
  * only if needed based on whether the old reg is still valid or the object
  * is tiled) and inserting a new PTE into the faulting process.
@@ -1799,57 +1795,20 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
  * The current feature set supported by i915_gem_fault() and thus GTT mmaps
  * is exposed via I915_PARAM_MMAP_GTT_VERSION (see i915_gem_mmap_gtt_version).
  */
-vm_fault_t i915_gem_fault(struct vm_fault *vmf)
+static int __vmf_fill_pages_gtt(struct drm_i915_gem_object *obj,
+				struct vm_fault *vmf,
+				pgoff_t page_offset)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
 	struct vm_area_struct *area = vmf->vma;
-	struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
 	struct drm_device *dev = obj->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct i915_ggtt *ggtt = &dev_priv->ggtt;
 	bool write = area->vm_flags & VM_WRITE;
-	intel_wakeref_t wakeref;
 	struct i915_vma *vma;
-	pgoff_t page_offset;
 	int srcu;
 	int ret;
 
-	/* Sanity check that we allow writing into this object */
-	if (i915_gem_object_is_readonly(obj) && write)
-		return VM_FAULT_SIGBUS;
-
-	/* We don't use vmf->pgoff since that has the fake offset */
-	page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
-
-	trace_i915_gem_object_fault(obj, page_offset, true, write);
-
-	/* Try to flush the object off the GPU first without holding the lock.
-	 * Upon acquiring the lock, we will perform our sanity checks and then
-	 * repeat the flush holding the lock in the normal manner to catch cases
-	 * where we are gazumped.
-	 */
-	ret = i915_gem_object_wait(obj,
-				   I915_WAIT_INTERRUPTIBLE,
-				   MAX_SCHEDULE_TIMEOUT);
-	if (ret)
-		goto err;
-
-	ret = i915_gem_object_pin_pages(obj);
-	if (ret)
-		goto err;
-
-	wakeref = intel_runtime_pm_get(dev_priv);
-
-	ret = i915_mutex_lock_interruptible(dev);
-	if (ret)
-		goto err_rpm;
-
-	/* Access to snoopable pages through the GTT is incoherent. */
-	if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev_priv)) {
-		ret = -EFAULT;
-		goto err_unlock;
-	}
-
 	/* Now pin it into the GTT as needed */
 	vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
 				       PIN_MAPPABLE |
@@ -1880,7 +1839,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 	}
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
-		goto err_unlock;
+		return ret;
 	}
 
 	ret = i915_gem_object_set_to_gtt_domain(obj, write);
@@ -1920,6 +1879,67 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 	i915_vma_unpin_fence(vma);
 err_unpin:
 	__i915_vma_unpin(vma);
+
+	return ret;
+}
+
+/**
+ * i915_gem_fault - fault a page into the memory
+ * @vmf: fault info
+ *
+ * The fault handler is set up by drm_gem_mmap() when mmap_offset is called on
+ * an object from userspace. The missing pages are setup by an object's
+ * vmf_fill_pages pages handler, depending on it's backing storage.
+ */
+vm_fault_t i915_gem_fault(struct vm_fault *vmf)
+{
+	struct vm_area_struct *area = vmf->vma;
+	struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	intel_wakeref_t wakeref;
+	bool write = !!(vmf->flags & FAULT_FLAG_WRITE);
+	pgoff_t page_offset;
+	int ret;
+
+	/* Sanity check that we allow writing into this object */
+	if (i915_gem_object_is_readonly(obj) && write)
+		return VM_FAULT_SIGBUS;
+
+	/* We don't use vmf->pgoff since that has the fake offset */
+	page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
+
+	trace_i915_gem_object_fault(obj, page_offset, true, write);
+
+	/* Try to flush the object off the GPU first without holding the lock.
+	 * Upon acquiring the lock, we will perform our sanity checks and then
+	 * repeat the flush holding the lock in the normal manner to catch cases
+	 * where we are gazumped.
+	 */
+	ret = i915_gem_object_wait(obj,
+				   I915_WAIT_INTERRUPTIBLE,
+				   MAX_SCHEDULE_TIMEOUT);
+	if (ret)
+		goto err;
+
+	ret = i915_gem_object_pin_pages(obj);
+	if (ret)
+		goto err;
+
+	wakeref = intel_runtime_pm_get(dev_priv);
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		goto err_rpm;
+
+	/* Access to snoopable pages through the GTT is incoherent. */
+	if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev_priv)) {
+		ret = -EFAULT;
+		goto err_unlock;
+	}
+
+	ret = __vmf_fill_pages_gtt(obj, vmf, page_offset);
+
 err_unlock:
 	mutex_unlock(&dev->struct_mutex);
 err_rpm:
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 29/42] drm/i915: Set correct vmf source pages for gem objects
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (27 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 28/42] drm/i915: Split out GTT fault handler to make it generic Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 16:02   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET Matthew Auld
                   ` (15 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

This allows page-faults from objects with different backing stores
from a single interface.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c          |  2 +-
 drivers/gpu/drm/i915/i915_drv.h          |  1 +
 drivers/gpu/drm/i915/i915_gem.c          | 58 +++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_gem_object.h   |  6 ++-
 drivers/gpu/drm/i915/intel_region_lmem.c | 28 ++++++++++++
 5 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index dc446430a340..b1200d7ebd13 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2944,7 +2944,7 @@ static const struct file_operations i915_driver_fops = {
 	.open = drm_open,
 	.release = drm_release,
 	.unlocked_ioctl = drm_ioctl,
-	.mmap = drm_gem_mmap,
+	.mmap = i915_gem_mmap,
 	.poll = drm_poll,
 	.read = drm_read,
 	.compat_ioctl = i915_compat_ioctl,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 772fffa87545..065953a9264f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3071,6 +3071,7 @@ int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv,
 int __must_check i915_gem_suspend(struct drm_i915_private *dev_priv);
 void i915_gem_suspend_late(struct drm_i915_private *dev_priv);
 void i915_gem_resume(struct drm_i915_private *dev_priv);
+int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 vm_fault_t i915_gem_fault(struct vm_fault *vmf);
 int i915_gem_object_wait(struct drm_i915_gem_object *obj,
 			 unsigned int flags,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 95e31529a738..48dbb57fbc6d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -38,6 +38,7 @@
 #include <linux/pci.h>
 #include <linux/dma-buf.h>
 #include <linux/mman.h>
+#include <linux/pfn_t.h>
 
 #include "i915_drv.h"
 #include "i915_gem_clflush.h"
@@ -377,6 +378,7 @@ static const struct drm_i915_gem_object_ops i915_gem_phys_ops = {
 	.get_pages = i915_gem_object_get_pages_phys,
 	.put_pages = i915_gem_object_put_pages_phys,
 	.release = i915_gem_object_release_phys,
+	.vmf_fill_pages = i915_gem_vmf_fill_pages_cpu,
 };
 
 static const struct drm_i915_gem_object_ops i915_gem_object_ops;
@@ -1938,7 +1940,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 		goto err_unlock;
 	}
 
-	ret = __vmf_fill_pages_gtt(obj, vmf, page_offset);
+	ret = obj->ops->vmf_fill_pages(obj, vmf, page_offset);
 
 err_unlock:
 	mutex_unlock(&dev->struct_mutex);
@@ -2166,6 +2168,26 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 	return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
 }
 
+int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	int ret;
+	struct drm_i915_gem_object *obj;
+
+	ret = drm_gem_mmap(filp, vma);
+	if (ret < 0)
+		return ret;
+
+	obj = to_intel_bo(vma->vm_private_data);
+	if (obj->memory_region) {
+		if (obj->mmap_origin == I915_MMAP_ORIGIN_OFFSET) {
+			vma->vm_flags &= ~VM_PFNMAP;
+			vma->vm_flags |= VM_MIXEDMAP;
+		}
+	}
+
+	return ret;
+}
+
 /* Immediately discard the backing storage */
 static void
 i915_gem_object_truncate(struct drm_i915_gem_object *obj)
@@ -4194,6 +4216,37 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	i915_gem_info_add_obj(to_i915(obj->base.dev), obj->base.size);
 }
 
+int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
+					 struct vm_fault *vmf,
+					 pgoff_t page_offset)
+{
+	struct vm_area_struct *area = vmf->vma;
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct page *page;
+	unsigned long pfn;
+	vm_fault_t vmf_ret;
+	pgoff_t pg_off = (vmf->address - area->vm_start) >> PAGE_SHIFT;
+
+	if (HAS_MAPPABLE_APERTURE(dev_priv))
+		return __vmf_fill_pages_gtt(obj, vmf, page_offset);
+
+	page = i915_gem_object_get_page(obj, pg_off);
+	pfn = page_to_pfn(page);
+
+	vmf_ret = vmf_insert_mixed(area, vmf->address,
+                                  __pfn_to_pfn_t(pfn, PFN_DEV));
+	if (vmf_ret & VM_FAULT_ERROR)
+		return vm_fault_to_errno(vmf_ret, 0);
+
+	if (!obj->userfault_count++)
+		list_add(&obj->userfault_link, &dev_priv->mm.userfault_list);
+
+	GEM_BUG_ON(!obj->userfault_count);
+
+	return 0;
+}
+
 static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
 	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
 		 I915_GEM_OBJECT_IS_SHRINKABLE,
@@ -4202,6 +4255,7 @@ static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
 	.put_pages = i915_gem_object_put_pages_gtt,
 
 	.pwrite = i915_gem_object_pwrite_gtt,
+	.vmf_fill_pages = i915_gem_vmf_fill_pages_cpu,
 };
 
 static int i915_gem_object_create_shmem(struct drm_device *dev,
@@ -4818,6 +4872,8 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 			spin_unlock(&i915->mm.obj_lock);
 		}
 
+
+		i915_gem_release_mmap(obj);
 		mutex_unlock(&i915->drm.struct_mutex);
 
 		GEM_BUG_ON(obj->bind_count);
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index f5b8bca33fe3..5c6bbe6f5e84 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -82,6 +82,8 @@ struct drm_i915_gem_object_ops {
 
 	int (*dmabuf_export)(struct drm_i915_gem_object *);
 	void (*release)(struct drm_i915_gem_object *);
+	int (*vmf_fill_pages)(struct drm_i915_gem_object *, struct vm_fault *,
+			      pgoff_t);
 };
 
 struct drm_i915_gem_object {
@@ -520,5 +522,7 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
 					 unsigned int cache_level);
 void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
 
+int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
+				struct vm_fault *vmf,
+				pgoff_t page_offset);
 #endif
-
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
index d549242a3578..b8b6b8248737 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -170,12 +170,40 @@ static int region_lmem_pwrite(struct drm_i915_gem_object *obj,
 	return ret;
 }
 
+static int region_lmem_vmf_fill_pages(struct drm_i915_gem_object *obj,
+				      struct vm_fault *vmf,
+				      pgoff_t page_offset)
+{
+	struct vm_area_struct *area = vmf->vma;
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *i915 = to_i915(dev);
+	unsigned long size = area->vm_end - area->vm_start;
+	int i;
+	vm_fault_t vmf_ret;
+
+	for (i = 0; i < size >> PAGE_SHIFT; i++) {
+		vmf_ret = vmf_insert_pfn(area,
+					 (unsigned long)area->vm_start + i * PAGE_SIZE,
+					 i915_gem_object_lmem_io_pfn(obj, i));
+		if (vmf_ret & VM_FAULT_ERROR)
+			return vm_fault_to_errno(vmf_ret, 0);
+	}
+
+	if (!obj->userfault_count++)
+		list_add(&obj->userfault_link, &i915->mm.userfault_list);
+
+	GEM_BUG_ON(!obj->userfault_count);
+
+	return 0;
+}
+
 static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
 	.get_pages = i915_memory_region_get_pages_buddy,
 	.put_pages = i915_memory_region_put_pages_buddy,
 	.release = i915_gem_object_release_memory_region,
 	.pread = region_lmem_pread,
 	.pwrite = region_lmem_pwrite,
+	.vmf_fill_pages = region_lmem_vmf_fill_pages,
 };
 
 static struct drm_i915_gem_object *
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (28 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 29/42] drm/i915: Set correct vmf source pages for gem objects Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 16:05   ` Chris Wilson
  2019-02-26 13:34   ` Tvrtko Ursulin
  2019-02-14 14:57 ` [RFC PATCH 31/42] drm/i915: cpu-map based dumb buffers Matthew Auld
                   ` (14 subsequent siblings)
  44 siblings, 2 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

CPU mmap implementation depending on the object's backing pages.
At the moment we introduce shmem and local-memory BAR fault handlers
Note that the mmap type is done one at a time to circumvent the DRM
offset manager limitation. Note that we multiplex mmap_gtt and
mmap_offset through the same ioctl, and use the zero extending behaviour
of drm to differentiate between them, when we inspect the flags.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c        |  5 +-
 drivers/gpu/drm/i915/i915_drv.h        |  3 +
 drivers/gpu/drm/i915/i915_gem.c        | 94 ++++++++++++++++++++++----
 drivers/gpu/drm/i915/i915_gem_object.h | 10 +++
 include/uapi/drm/i915_drm.h            | 30 ++++++++
 5 files changed, 126 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b1200d7ebd13..90785030a0dd 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -423,6 +423,7 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_EXEC_CAPTURE:
 	case I915_PARAM_HAS_EXEC_BATCH_FIRST:
 	case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
+	case I915_PARAM_MMAP_OFFSET_VERSION:
 		/* For the time being all of these are always true;
 		 * if some supported hardware does not have one of these
 		 * features this value needs to be provided from
@@ -2936,7 +2937,7 @@ const struct dev_pm_ops i915_pm_ops = {
 static const struct vm_operations_struct i915_gem_vm_ops = {
 	.fault = i915_gem_fault,
 	.open = drm_gem_vm_open,
-	.close = drm_gem_vm_close,
+	.close = i915_gem_close,
 };
 
 static const struct file_operations i915_driver_fops = {
@@ -2991,7 +2992,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
-	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_OFFSET, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 065953a9264f..c6ae157d0ede 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2770,6 +2770,8 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
 int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
+int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
 int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
 			      struct drm_file *file_priv);
 int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
@@ -3073,6 +3075,7 @@ void i915_gem_suspend_late(struct drm_i915_private *dev_priv);
 void i915_gem_resume(struct drm_i915_private *dev_priv);
 int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 vm_fault_t i915_gem_fault(struct vm_fault *vmf);
+void i915_gem_close(struct vm_area_struct *vma);
 int i915_gem_object_wait(struct drm_i915_gem_object *obj,
 			 unsigned int flags,
 			 long timeout);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 48dbb57fbc6d..cc6c88ec749d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2123,11 +2123,12 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
 	drm_gem_free_mmap_offset(&obj->base);
 }
 
-int
-i915_gem_mmap_gtt(struct drm_file *file,
-		  struct drm_device *dev,
-		  u32 handle,
-		  u64 *offset)
+static int
+__assign_gem_object_mmap_data(struct drm_file *file,
+			      u32 handle,
+			      enum i915_cpu_mmap_origin_type mmap_type,
+			      u64 mmap_flags,
+			      u64 *offset)
 {
 	struct drm_i915_gem_object *obj;
 	int ret;
@@ -2136,14 +2137,35 @@ i915_gem_mmap_gtt(struct drm_file *file,
 	if (!obj)
 		return -ENOENT;
 
+	if (atomic_read(&obj->mmap_count) &&
+	    obj->mmap_origin != mmap_type) {
+	        /* Re-map object with existing different map-type */
+		ret = -EINVAL;
+		goto err;
+	}
+
 	ret = i915_gem_object_create_mmap_offset(obj);
-	if (ret == 0)
+	if (ret == 0) {
+		obj->mmap_origin = mmap_type;
+		obj->mmap_flags = mmap_flags;
 		*offset = drm_vma_node_offset_addr(&obj->base.vma_node);
+	}
 
+ err:
 	i915_gem_object_put(obj);
 	return ret;
 }
 
+int
+i915_gem_mmap_gtt(struct drm_file *file,
+		  struct drm_device *dev,
+		  u32 handle,
+		  u64 *offset)
+{
+	return __assign_gem_object_mmap_data(file, handle, I915_MMAP_ORIGIN_GTT,
+					     0, offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -2163,9 +2185,45 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file)
 {
-	struct drm_i915_gem_mmap_gtt *args = data;
+	struct drm_i915_gem_mmap_offset *args = data;
+	struct drm_i915_private *i915 = to_i915(dev);
+
+	if (args->flags & I915_MMAP_OFFSET_FLAGS)
+		return i915_gem_mmap_offset_ioctl(dev, data, file);
+
+	if (!HAS_MAPPABLE_APERTURE(i915)) {
+		DRM_ERROR("No aperture, cannot mmap via legacy GTT\n");
+		return -ENODEV;
+	}
+
+	return __assign_gem_object_mmap_data(file, args->handle,
+					     I915_MMAP_ORIGIN_GTT,
+					     0, &args->offset);
+}
+
+int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file)
+{
+	struct drm_i915_gem_mmap_offset *args = data;
 
-	return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
+	if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB)) &&
+	    !boot_cpu_has(X86_FEATURE_PAT))
+		return -ENODEV;
+
+        return __assign_gem_object_mmap_data(file, args->handle,
+					     I915_MMAP_ORIGIN_OFFSET,
+					     args->flags,
+					     &args->offset);
+}
+
+void i915_gem_close(struct vm_area_struct *vma)
+{
+	struct drm_gem_object *gem = vma->vm_private_data;
+	struct drm_i915_gem_object *obj = to_intel_bo(gem);
+
+	atomic_dec(&obj->mmap_count);
+
+	drm_gem_vm_close(vma);
 }
 
 int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -2178,12 +2236,19 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 		return ret;
 
 	obj = to_intel_bo(vma->vm_private_data);
-	if (obj->memory_region) {
-		if (obj->mmap_origin == I915_MMAP_ORIGIN_OFFSET) {
-			vma->vm_flags &= ~VM_PFNMAP;
-			vma->vm_flags |= VM_MIXEDMAP;
-		}
+	if (obj->mmap_origin == I915_MMAP_ORIGIN_OFFSET) {
+		vma->vm_flags &= ~VM_PFNMAP;
+		vma->vm_flags |= VM_MIXEDMAP;
+		if (obj->mmap_flags & I915_MMAP_OFFSET_WC)
+			vma->vm_page_prot =
+				pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+		else if (obj->mmap_flags & I915_MMAP_OFFSET_WB)
+			vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+		else if (obj->mmap_flags & I915_MMAP_OFFSET_UC)
+			vma->vm_page_prot =
+				pgprot_noncached(vm_get_page_prot(vma->vm_flags));
 	}
+	atomic_inc(&obj->mmap_count);
 
 	return ret;
 }
@@ -4228,7 +4293,8 @@ int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
 	vm_fault_t vmf_ret;
 	pgoff_t pg_off = (vmf->address - area->vm_start) >> PAGE_SHIFT;
 
-	if (HAS_MAPPABLE_APERTURE(dev_priv))
+	if (HAS_MAPPABLE_APERTURE(dev_priv) &&
+	    obj->mmap_origin == I915_MMAP_ORIGIN_GTT)
 		return __vmf_fill_pages_gtt(obj, vmf, page_offset);
 
 	page = i915_gem_object_get_page(obj, pg_off);
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 5c6bbe6f5e84..b37ffe2e17b6 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -86,6 +86,12 @@ struct drm_i915_gem_object_ops {
 			      pgoff_t);
 };
 
+enum i915_cpu_mmap_origin_type {
+	I915_MMAP_ORIGIN_NONE = 0,
+	I915_MMAP_ORIGIN_GTT,
+	I915_MMAP_ORIGIN_OFFSET,
+};
+
 struct drm_i915_gem_object {
 	struct drm_gem_object base;
 
@@ -157,6 +163,10 @@ struct drm_i915_gem_object {
 	unsigned int userfault_count;
 	struct list_head userfault_link;
 
+	enum i915_cpu_mmap_origin_type mmap_origin;
+	atomic_t mmap_count;
+	u64 mmap_flags;
+
 	struct list_head batch_pool_link;
 	I915_SELFTEST_DECLARE(struct list_head st_link);
 
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 397810fa2d33..26d2274b5d2b 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -319,6 +319,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_PERF_ADD_CONFIG	0x37
 #define DRM_I915_PERF_REMOVE_CONFIG	0x38
 #define DRM_I915_QUERY			0x39
+#define DRM_I915_GEM_MMAP_OFFSET   	DRM_I915_GEM_MMAP_GTT
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -377,6 +378,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_PERF_ADD_CONFIG	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
 #define DRM_IOCTL_I915_PERF_REMOVE_CONFIG	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
 #define DRM_IOCTL_I915_QUERY			DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
+#define DRM_IOCTL_I915_GEM_MMAP_OFFSET		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_OFFSET, struct drm_i915_gem_mmap_offset)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -559,6 +561,9 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_MMAP_GTT_COHERENT	52
 
+/* Mmap offset ioctl */
+#define I915_PARAM_MMAP_OFFSET_VERSION	55
+
 typedef struct drm_i915_getparam {
 	__s32 param;
 	/*
@@ -731,6 +736,31 @@ struct drm_i915_gem_mmap_gtt {
 	__u64 offset;
 };
 
+struct drm_i915_gem_mmap_offset {
+	/** Handle for the object being mapped. */
+	__u32 handle;
+	__u32 pad;
+	/**
+	 * Fake offset to use for subsequent mmap call
+	 *
+	 * This is a fixed-size type for 32/64 compatibility.
+	 */
+	__u64 offset;
+
+	/**
+	 * Flags for extended behaviour.
+	 *
+	 * It is mandatory that either one of the _WC/_WB flags
+	 * should be passed here.
+	 */
+	__u64 flags;
+#define I915_MMAP_OFFSET_WC (1 << 0)
+#define I915_MMAP_OFFSET_WB (1 << 1)
+#define I915_MMAP_OFFSET_UC (1 << 2)
+#define I915_MMAP_OFFSET_FLAGS \
+	(I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB | I915_MMAP_OFFSET_UC)
+};
+
 struct drm_i915_gem_set_domain {
 	/** Handle for the object */
 	__u32 handle;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 31/42] drm/i915: cpu-map based dumb buffers
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (29 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 16:06   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 32/42] drm/i915: Add fill_pages handler for dma_buf imported objects Matthew Auld
                   ` (13 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

If there is no aperture we can't use map_gtt to map dumb buffers, so we
need a cpu-map based path to do it. We prefer map_gtt on platforms that
do have aperture.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c        | 2 +-
 drivers/gpu/drm/i915/i915_drv.h        | 2 +-
 drivers/gpu/drm/i915/i915_gem.c        | 8 ++++++--
 drivers/gpu/drm/i915/i915_gem_object.h | 1 +
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 90785030a0dd..90ce9973ce46 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -3040,7 +3040,7 @@ static struct drm_driver driver = {
 	.gem_prime_import = i915_gem_prime_import,
 
 	.dumb_create = i915_gem_dumb_create,
-	.dumb_map_offset = i915_gem_mmap_gtt,
+	.dumb_map_offset = i915_gem_mmap_dumb,
 	.ioctls = i915_ioctls,
 	.num_ioctls = ARRAY_SIZE(i915_ioctls),
 	.fops = &i915_driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c6ae157d0ede..f0e8567f18f5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3030,7 +3030,7 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 			 struct drm_device *dev,
 			 struct drm_mode_create_dumb *args);
-int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
 		      u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index cc6c88ec749d..b426a1ee8d0f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2157,12 +2157,16 @@ __assign_gem_object_mmap_data(struct drm_file *file,
 }
 
 int
-i915_gem_mmap_gtt(struct drm_file *file,
+i915_gem_mmap_dumb(struct drm_file *file,
 		  struct drm_device *dev,
 		  u32 handle,
 		  u64 *offset)
 {
-	return __assign_gem_object_mmap_data(file, handle, I915_MMAP_ORIGIN_GTT,
+	struct drm_i915_private *i915 = dev->dev_private;
+	enum i915_cpu_mmap_origin_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
+		I915_MMAP_ORIGIN_GTT : I915_MMAP_ORIGIN_DUMB;
+
+	return __assign_gem_object_mmap_data(file, handle, mmap_type,
 					     0, offset);
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index b37ffe2e17b6..82f9068f8aed 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -90,6 +90,7 @@ enum i915_cpu_mmap_origin_type {
 	I915_MMAP_ORIGIN_NONE = 0,
 	I915_MMAP_ORIGIN_GTT,
 	I915_MMAP_ORIGIN_OFFSET,
+	I915_MMAP_ORIGIN_DUMB,
 };
 
 struct drm_i915_gem_object {
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 32/42] drm/i915: Add fill_pages handler for dma_buf imported objects
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (30 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 31/42] drm/i915: cpu-map based dumb buffers Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 33/42] UPSTREAM: drm/i915/query: Split out query item checks Matthew Auld
                   ` (12 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

Use the plumbing from the new mmap_offset infrastructure to
implement gtt-mmaps.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c        |  8 ++++----
 drivers/gpu/drm/i915/i915_gem_dmabuf.c | 14 ++++++++++++++
 drivers/gpu/drm/i915/i915_gem_object.h |  5 +++++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b426a1ee8d0f..a9e119d8d1f1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1797,9 +1797,9 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
  * The current feature set supported by i915_gem_fault() and thus GTT mmaps
  * is exposed via I915_PARAM_MMAP_GTT_VERSION (see i915_gem_mmap_gtt_version).
  */
-static int __vmf_fill_pages_gtt(struct drm_i915_gem_object *obj,
-				struct vm_fault *vmf,
-				pgoff_t page_offset)
+int i915_vmf_fill_pages_gtt(struct drm_i915_gem_object *obj,
+			    struct vm_fault *vmf,
+			    pgoff_t page_offset)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
 	struct vm_area_struct *area = vmf->vma;
@@ -4299,7 +4299,7 @@ int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
 
 	if (HAS_MAPPABLE_APERTURE(dev_priv) &&
 	    obj->mmap_origin == I915_MMAP_ORIGIN_GTT)
-		return __vmf_fill_pages_gtt(obj, vmf, page_offset);
+		return i915_vmf_fill_pages_gtt(obj, vmf, page_offset);
 
 	page = i915_gem_object_get_page(obj, pg_off);
 	pfn = page_to_pfn(page);
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 02f7298bfe57..b5a8d01e41cc 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -268,9 +268,23 @@ static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj,
 				 DMA_BIDIRECTIONAL);
 }
 
+static int i915_gem_vmf_fill_pages_dmabuf(struct drm_i915_gem_object *obj,
+					  struct vm_fault *vmf,
+					  pgoff_t page_offset)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	if (!HAS_MAPPABLE_APERTURE(dev_priv))
+		return -EFAULT;
+
+	return i915_vmf_fill_pages_gtt(obj, vmf, page_offset);
+}
+
 static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
 	.get_pages = i915_gem_object_get_pages_dmabuf,
 	.put_pages = i915_gem_object_put_pages_dmabuf,
+	.vmf_fill_pages = i915_gem_vmf_fill_pages_dmabuf,
 };
 
 struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 82f9068f8aed..078d5550a1c8 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -536,4 +536,9 @@ void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
 int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
 				struct vm_fault *vmf,
 				pgoff_t page_offset);
+
+int i915_vmf_fill_pages_gtt(struct drm_i915_gem_object *obj,
+			    struct vm_fault *vmf,
+			    pgoff_t page_offset);
+
 #endif
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 33/42] UPSTREAM: drm/i915/query: Split out query item checks
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (31 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 32/42] drm/i915: Add fill_pages handler for dma_buf imported objects Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI Matthew Auld
                   ` (11 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

This simplifies adding new query item objects.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_query.c | 40 ++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index cbcb957b7141..b4f26605f617 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -10,12 +10,33 @@
 #include "i915_query.h"
 #include <uapi/drm/i915_drm.h>
 
+static int init_query_item_check(void* data_ptr, size_t data_sz,
+				 u32 total_length,
+				 struct drm_i915_query_item *query_item)
+{
+	if (query_item->length == 0)
+		return total_length;
+
+	if (query_item->length < total_length)
+		return -EINVAL;
+
+	if (copy_from_user(data_ptr, u64_to_user_ptr(query_item->data_ptr),
+			   data_sz))
+		return -EFAULT;
+
+	if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
+		       total_length))
+		return -EFAULT;
+
+	return 0;
+}
+
 static int query_topology_info(struct drm_i915_private *dev_priv,
 			       struct drm_i915_query_item *query_item)
 {
 	const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
 	struct drm_i915_query_topology_info topo;
-	u32 slice_length, subslice_length, eu_length, total_length;
+	u32 ret, slice_length, subslice_length, eu_length, total_length;
 
 	if (query_item->flags != 0)
 		return -EINVAL;
@@ -33,23 +54,14 @@ static int query_topology_info(struct drm_i915_private *dev_priv,
 
 	total_length = sizeof(topo) + slice_length + subslice_length + eu_length;
 
-	if (query_item->length == 0)
-		return total_length;
-
-	if (query_item->length < total_length)
-		return -EINVAL;
-
-	if (copy_from_user(&topo, u64_to_user_ptr(query_item->data_ptr),
-			   sizeof(topo)))
-		return -EFAULT;
+	ret = init_query_item_check(&topo, sizeof(topo), total_length,
+				    query_item);
+	if (ret != 0)
+		return ret;
 
 	if (topo.flags != 0)
 		return -EINVAL;
 
-	if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
-		       total_length))
-		return -EFAULT;
-
 	memset(&topo, 0, sizeof(topo));
 	topo.max_slices = sseu->max_slices;
 	topo.max_subslices = sseu->max_subslices;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (32 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 33/42] UPSTREAM: drm/i915/query: Split out query item checks Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 16:31   ` Chris Wilson
  2019-02-14 21:15   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 35/42] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION Matthew Auld
                   ` (10 subsequent siblings)
  44 siblings, 2 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

Returns the available memory region areas supported by the HW.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_query.c | 57 +++++++++++++++++++++++++++++++
 include/uapi/drm/i915_drm.h       | 40 +++++++++++++++++++++-
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index b4f26605f617..e03958c7a384 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -95,9 +95,66 @@ static int query_topology_info(struct drm_i915_private *dev_priv,
 	return total_length;
 }
 
+static int query_memregion_info(struct drm_i915_private *dev_priv,
+				struct drm_i915_query_item *query_item)
+{
+	struct drm_i915_query_memory_region_info __user *query_ptr =
+		u64_to_user_ptr(query_item->data_ptr);
+	struct drm_i915_memory_region_info __user *info_ptr =
+		&query_ptr->regions[0];
+	struct drm_i915_memory_region_info info = { };
+	struct drm_i915_query_memory_region_info query;
+	u32 total_length;
+	int ret, i;
+
+	if (query_item->flags != 0)
+		return -EINVAL;
+
+	total_length = sizeof(struct drm_i915_query_memory_region_info);
+	for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) {
+		struct intel_memory_region *region = dev_priv->regions[i];
+
+		if (!region)
+			continue;
+
+		total_length += sizeof(struct drm_i915_memory_region_info);
+	}
+
+	ret = init_query_item_check(&query, sizeof(query), total_length,
+				    query_item);
+	if (ret != 0)
+		return ret;
+
+	if (query.num_regions || query.rsvd[0] || query.rsvd[1] ||
+	    query.rsvd[2])
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) {
+		struct intel_memory_region *region = dev_priv->regions[i];
+
+		if (!region)
+			continue;
+
+		info.id = region->id;
+		info.size = resource_size(&region->region);
+
+		if (__copy_to_user(info_ptr, &info, sizeof(info)))
+			return -EFAULT;
+
+		query.num_regions++;
+		info_ptr++;
+	}
+
+	if (__copy_to_user(query_ptr, &query, sizeof(query)))
+		return -EFAULT;
+
+	return total_length;
+}
+
 static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
 					struct drm_i915_query_item *query_item) = {
 	query_topology_info,
+	query_memregion_info,
 };
 
 int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 26d2274b5d2b..5a102a5cb415 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1744,6 +1744,7 @@ struct drm_i915_perf_oa_config {
 struct drm_i915_query_item {
 	__u64 query_id;
 #define DRM_I915_QUERY_TOPOLOGY_INFO    1
+#define DRM_I915_QUERY_MEMREGION_INFO   3
 
 	/*
 	 * When set to zero by userspace, this is filled with the size of the
@@ -1832,7 +1833,6 @@ struct drm_i915_query_topology_info {
 	 * Offset in data[] at which the EU masks are stored.
 	 */
 	__u16 eu_offset;
-
 	/*
 	 * Stride at which each of the EU masks for each subslice are stored.
 	 */
@@ -1841,6 +1841,44 @@ struct drm_i915_query_topology_info {
 	__u8 data[];
 };
 
+struct drm_i915_memory_region_info {
+
+	/** Base type of a region
+	 */
+#define I915_SYSTEM_MEMORY         0
+#define I915_DEVICE_MEMORY         1
+
+	/** The region id is encoded in a layout which makes it possible to
+	 *  retrieve the following information:
+	 *
+	 *  Base type: log2(ID >> 16)
+	 *  Instance:  log2(ID & 0xffff)
+	 */
+	__u32 id;
+
+	/** Reserved field. MBZ */
+	__u32 rsvd0;
+
+	/** Unused for now. MBZ */
+	__u64 flags;
+
+	__u64 size;
+
+	/** Reserved fields must be cleared to zero. */
+	__u64 rsvd1[4];
+};
+
+struct drm_i915_query_memory_region_info {
+
+	/** Number of struct drm_i915_memory_region_info structs */
+	__u32 num_regions;
+
+	/** MBZ */
+	__u32 rsvd[3];
+
+	struct drm_i915_memory_region_info regions[];
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 35/42] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (33 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 16:20   ` Chris Wilson
  2019-02-14 14:57 ` [RFC PATCH 36/42] drm/i915/lmem: include debugfs metrics Matthew Auld
                   ` (9 subsequent siblings)
  44 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

This call will specify which memory region an object should be placed.

Note that changing the object's backing storage should be immediately
done after an object is created or if it's not yet in use, otherwise
this will fail on a busy object.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c |   1 +
 drivers/gpu/drm/i915/i915_drv.h |   2 +
 drivers/gpu/drm/i915/i915_gem.c | 111 ++++++++++++++++++++++++++++++++
 include/uapi/drm/i915_drm.h     |  24 +++++++
 4 files changed, 138 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 90ce9973ce46..08a4286b70c6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -3016,6 +3016,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_PERF_ADD_CONFIG, i915_perf_add_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_PERF_REMOVE_CONFIG, i915_perf_remove_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_QUERY, i915_query_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_OBJECT_SETPARAM, i915_gem_object_setparam_ioctl, DRM_RENDER_ALLOW),
 };
 
 static struct drm_driver driver = {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f0e8567f18f5..8185ea126752 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2762,6 +2762,8 @@ ibx_disable_display_interrupt(struct drm_i915_private *dev_priv, u32 bits)
 /* i915_gem.c */
 int i915_gem_create_ioctl(struct drm_device *dev, void *data,
 			  struct drm_file *file_priv);
+int i915_gem_object_setparam_ioctl(struct drm_device *dev, void *data,
+				   struct drm_file *file_priv);
 int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv);
 int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a9e119d8d1f1..387eae998fbf 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2257,6 +2257,117 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 	return ret;
 }
 
+static enum intel_region_id
+__region_id(u32 region)
+{
+	enum intel_region_id id;
+
+	for (id = 0; id < ARRAY_SIZE(intel_region_map); ++id) {
+		if (intel_region_map[id] == region)
+			return id;
+	}
+
+	return INTEL_MEMORY_UKNOWN;
+}
+
+static int i915_gem_object_region_select(struct drm_i915_private *dev_priv,
+					 struct drm_i915_gem_object_param *args,
+					 struct drm_file *file,
+					 struct drm_i915_gem_object *obj)
+{
+	struct i915_gem_context *ctx = 0;
+	intel_wakeref_t wakeref;
+	u32 __user *uregions = u64_to_user_ptr(args->data);
+	int i, ret;
+
+	ctx = i915_gem_context_lookup(file->driver_priv,
+				      DEFAULT_CONTEXT_HANDLE);
+	if (!ctx)
+	        return -ENOENT;
+
+	mutex_lock(&dev_priv->drm.struct_mutex);
+	ret = i915_gem_object_prepare_move(obj);
+	if (ret) {
+		DRM_ERROR("Cannot set memory region, object in use\n");
+	        goto err;
+	}
+
+	if (args->size > ARRAY_SIZE(intel_region_map))
+		return -EINVAL;
+
+	for (i = 0; i < args->size; i++) {
+		u32 region;
+		enum intel_region_id id;
+
+		ret = get_user(region, uregions);
+		if (ret)
+			goto err;
+
+		id = __region_id(region);
+		if (id == INTEL_MEMORY_UKNOWN) {
+			ret = -EINVAL;
+			goto err;
+		}
+
+		ret = i915_gem_object_migrate(ctx, obj, id);
+		if (!ret) {
+			if (MEMORY_TYPE_FROM_REGION(region) ==
+			    INTEL_LMEM) {
+				/*
+				 * TODO: this should be part of get_pages(),
+				 * when async get_pages arrives
+				 */
+				with_intel_runtime_pm(dev_priv, wakeref)
+					ret = i915_gem_object_clear_blt(ctx, obj);
+
+				if (ret) {
+					__i915_gem_object_release_unless_active(obj);
+					DRM_ERROR("Failed clearing the object\n");
+					goto err;
+				}
+			}
+			break;
+		}
+		++uregions;
+	}
+err:
+	mutex_unlock(&dev_priv->drm.struct_mutex);
+	i915_gem_context_put(ctx);
+	return ret;
+}
+
+int i915_gem_object_setparam_ioctl(struct drm_device *dev, void *data,
+				   struct drm_file *file)
+{
+
+	struct drm_i915_gem_object_param *args = data;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	obj = i915_gem_object_lookup(file, args->handle);
+	if (!obj)
+		return -ENOENT;
+
+	switch (args->param) {
+	case I915_PARAM_MEMORY_REGION:
+		ret = i915_gem_object_region_select(dev_priv, args, file, obj);
+		if (ret) {
+			DRM_ERROR("Cannot set memory region, migration failed\n");
+			goto err;
+		}
+
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+err:
+	i915_gem_object_put(obj);
+	return ret;
+}
+
 /* Immediately discard the backing storage */
 static void
 i915_gem_object_truncate(struct drm_i915_gem_object *obj)
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 5a102a5cb415..4f789d43d10b 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -320,6 +320,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_PERF_REMOVE_CONFIG	0x38
 #define DRM_I915_QUERY			0x39
 #define DRM_I915_GEM_MMAP_OFFSET   	DRM_I915_GEM_MMAP_GTT
+#define DRM_I915_GEM_OBJECT_SETPARAM	0x3c
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -379,6 +380,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_PERF_REMOVE_CONFIG	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
 #define DRM_IOCTL_I915_QUERY			DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
 #define DRM_IOCTL_I915_GEM_MMAP_OFFSET		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_OFFSET, struct drm_i915_gem_mmap_offset)
+#define DRM_IOCTL_I915_GEM_OBJECT_SETPARAM	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_OBJECT_SETPARAM, struct drm_i915_gem_object_param)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -664,6 +666,28 @@ struct drm_i915_gem_create {
 	__u32 pad;
 };
 
+struct drm_i915_gem_object_param {
+	/** Handle for the object */
+	__u32 handle;
+
+	/** Set the memory region for the object listed in preference order
+	 *  as an array of region ids within data. To force an object
+	 *  to a particular memory region, set the region as the sole entry.
+	 *
+	 *  Valid region ids are derived from the id field of
+	 *  struct drm_i915_memory_region_info.
+	 *  See struct drm_i915_query_memory_region_info.
+	 */
+#define I915_PARAM_MEMORY_REGION 0x1
+	__u32 param;
+
+	__u32 size;
+	/* Unused at the moment */
+	__u32 flags;
+
+	__u64 data;
+};
+
 struct drm_i915_gem_pread {
 	/** Handle for the object being read. */
 	__u32 handle;
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 36/42] drm/i915/lmem: include debugfs metrics
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (34 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 35/42] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 37/42] drm/i915: enumerate and init each supported region Matthew Auld
                   ` (8 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Useful for debugging.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index fed46fe19c03..2178c13213ef 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -435,6 +435,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 	struct i915_ggtt *ggtt = &dev_priv->ggtt;
 	u32 count, mapped_count, purgeable_count, dpy_count, huge_count;
 	u64 size, mapped_size, purgeable_size, dpy_size, huge_size;
+	u32 lmem_count, lmem_dpy_count;
+	u64 lmem_size, lmem_dpy_size;
 	struct drm_i915_gem_object *obj;
 	unsigned int page_sizes = 0;
 	char buf[80];
@@ -448,6 +450,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 	mapped_size = mapped_count = 0;
 	purgeable_size = purgeable_count = 0;
 	huge_size = huge_count = 0;
+	lmem_size = lmem_count = lmem_dpy_size = lmem_dpy_count = 0;
 
 	spin_lock(&dev_priv->mm.obj_lock);
 	list_for_each_entry(obj, &dev_priv->mm.unbound_list, mm.link) {
@@ -469,6 +472,15 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 			huge_size += obj->base.size;
 			page_sizes |= obj->mm.page_sizes.sg;
 		}
+
+		if (i915_gem_object_is_lmem(obj)) {
+			if (obj->pin_global) {
+				lmem_dpy_count++;
+				lmem_dpy_size += obj->base.size;
+			}
+			lmem_count++;
+			lmem_size += obj->base.size;
+		}
 	}
 	seq_printf(m, "%u unbound objects, %llu bytes\n", count, size);
 
@@ -497,6 +509,15 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 			huge_size += obj->base.size;
 			page_sizes |= obj->mm.page_sizes.sg;
 		}
+
+		if (i915_gem_object_is_lmem(obj)) {
+			if (obj->pin_global) {
+				lmem_dpy_count++;
+				lmem_dpy_size += obj->base.size;
+			}
+			lmem_count++;
+			lmem_size += obj->base.size;
+		}
 	}
 	spin_unlock(&dev_priv->mm.obj_lock);
 
@@ -513,6 +534,12 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 	seq_printf(m, "%u display objects (globally pinned), %llu bytes\n",
 		   dpy_count, dpy_size);
 
+	if (HAS_LMEM(dev_priv)) {
+		seq_printf(m, "%u LMEM objects, %llu bytes\n", lmem_count, lmem_size);
+		seq_printf(m, "%u LMEM display objects (globally pinned), %llu bytes\n",
+			   lmem_dpy_count, lmem_dpy_size);
+	}
+
 	seq_printf(m, "%llu [%pa] gtt total\n",
 		   ggtt->vm.total, &ggtt->mappable_end);
 	seq_printf(m, "Supported page sizes: %s\n",
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 37/42] drm/i915: enumerate and init each supported region
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (35 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 36/42] drm/i915/lmem: include debugfs metrics Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 38/42] drm/i915: treat shmem as a region Matthew Auld
                   ` (7 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

Nothing to enumerate yet...

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 73 ++++++++++++++++++++++++++---
 1 file changed, 67 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 045c6715d5a6..e0a8e90b1480 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2798,6 +2798,71 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
 	return ret;
 }
 
+static void i915_gem_cleanup_memory_regions(struct drm_i915_private *i915)
+{
+	int i;
+
+	i915_gem_cleanup_stolen(i915);
+
+	for (i = 0; i < ARRAY_SIZE(i915->regions); ++i)	{
+		struct intel_memory_region *region = i915->regions[i];
+
+		if (region)
+			intel_memory_region_destroy(region);
+	}
+}
+
+static int i915_gem_init_memory_regions(struct drm_i915_private *i915)
+{
+	int err, i;
+
+	/* All platforms currently have system memory */
+	GEM_BUG_ON(!HAS_REGION(i915, REGION_SMEM));
+
+	/*
+	 * Initialise stolen early so that we may reserve preallocated
+	 * objects for the BIOS to KMS transition.
+	 */
+	/* XXX: stolen will become a region at some point */
+	err = i915_gem_init_stolen(i915);
+	if (err)
+		return err;
+
+	for (i = 0; i < ARRAY_SIZE(intel_region_map); i++) {
+		struct intel_memory_region *mem = NULL;
+		u32 type;
+
+		if (!HAS_REGION(i915, BIT(i)))
+			continue;
+
+		type = MEMORY_TYPE_FROM_REGION(intel_region_map[i]);
+		switch (type) {
+		default:
+			break;
+		}
+
+		if (IS_ERR(mem)) {
+			err = PTR_ERR(mem);
+			DRM_ERROR("Failed to setup region(%d) type=%d\n", err, type);
+			goto out_cleanup;
+		}
+
+		if (mem) {
+			mem->id = intel_region_map[i];
+			mem->type = type;
+			mem->instance = MEMORY_INSTANCE_FROM_REGION(intel_region_map[i]);
+		}
+
+		i915->regions[i] = mem;
+	}
+
+	return 0;
+
+out_cleanup:
+	i915_gem_cleanup_memory_regions(i915);
+	return err;
+}
+
 /**
  * i915_ggtt_cleanup_hw - Clean up GGTT hardware initialization
  * @dev_priv: i915 device
@@ -2839,7 +2904,7 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
 		io_mapping_fini(&ggtt->iomap);
 	}
 
-	i915_gem_cleanup_stolen(dev_priv);
+	i915_gem_cleanup_memory_regions(dev_priv);
 }
 
 static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
@@ -3474,11 +3539,7 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
 					      ggtt->mappable_end);
 	}
 
-	/*
-	 * Initialise stolen early so that we may reserve preallocated
-	 * objects for the BIOS to KMS transition.
-	 */
-	ret = i915_gem_init_stolen(dev_priv);
+	ret = i915_gem_init_memory_regions(dev_priv);
 	if (ret)
 		goto out_gtt_cleanup;
 
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 38/42] drm/i915: treat shmem as a region
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (36 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 37/42] drm/i915: enumerate and init each supported region Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 39/42] drm/i915: treat stolen " Matthew Auld
                   ` (6 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            |  2 +
 drivers/gpu/drm/i915/i915_gem.c            | 89 ++++++++++++++--------
 drivers/gpu/drm/i915/i915_gem_gtt.c        | 11 ++-
 drivers/gpu/drm/i915/intel_memory_region.c |  9 +++
 4 files changed, 74 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8185ea126752..23f04e5a4b76 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2833,6 +2833,8 @@ int i915_gem_object_migrate(struct i915_gem_context *ctx,
 			    struct drm_i915_gem_object *obj,
 			    enum intel_region_id id);
 
+struct intel_memory_region *i915_gem_setup_smem(struct drm_i915_private *i915);
+
 static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
 {
 	if (!atomic_read(&i915->mm.free_count))
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 387eae998fbf..3c86909d55b9 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2576,6 +2576,7 @@ bool i915_sg_trim(struct sg_table *orig_st)
 static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+	struct intel_memory_region *mem = obj->memory_region;
 	const unsigned long page_count = obj->base.size / PAGE_SIZE;
 	unsigned long i;
 	struct address_space *mapping;
@@ -2602,7 +2603,7 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	 * If there's no chance of allocating enough pages for the whole
 	 * object, bail early.
 	 */
-	if (page_count > totalram_pages())
+	if (obj->base.size > resource_size(&mem->region))
 		return -ENOMEM;
 
 	st = kmalloc(sizeof(*st), GFP_KERNEL);
@@ -4437,11 +4438,13 @@ static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
 
 	.pwrite = i915_gem_object_pwrite_gtt,
 	.vmf_fill_pages = i915_gem_vmf_fill_pages_cpu,
+
+	.release = i915_gem_object_release_memory_region,
 };
 
-static int i915_gem_object_create_shmem(struct drm_device *dev,
-					struct drm_gem_object *obj,
-					size_t size)
+static int __i915_gem_object_create_shmem(struct drm_device *dev,
+					  struct drm_gem_object *obj,
+					  resource_size_t size)
 {
 	struct drm_i915_private *i915 = to_i915(dev);
 	unsigned long flags = VM_NORESERVE;
@@ -4463,31 +4466,22 @@ static int i915_gem_object_create_shmem(struct drm_device *dev,
 	return 0;
 }
 
-struct drm_i915_gem_object *
-i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
+static struct drm_i915_gem_object *
+i915_gem_object_create_shmem(struct intel_memory_region *mem,
+			     resource_size_t size,
+			     unsigned flags)
 {
+	struct drm_i915_private *dev_priv = mem->i915;
 	struct drm_i915_gem_object *obj;
 	struct address_space *mapping;
-	unsigned int cache_level;
 	gfp_t mask;
 	int ret;
 
-	/* There is a prevalence of the assumption that we fit the object's
-	 * page count inside a 32bit _signed_ variable. Let's document this and
-	 * catch if we ever need to fix it. In the meantime, if you do spot
-	 * such a local variable, please consider fixing!
-	 */
-	if (size >> PAGE_SHIFT > INT_MAX)
-		return ERR_PTR(-E2BIG);
-
-	if (overflows_type(size, obj->base.size))
-		return ERR_PTR(-E2BIG);
-
 	obj = i915_gem_object_alloc(dev_priv);
 	if (obj == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	ret = i915_gem_object_create_shmem(&dev_priv->drm, &obj->base, size);
+	ret = __i915_gem_object_create_shmem(&dev_priv->drm, &obj->base, size);
 	if (ret)
 		goto fail;
 
@@ -4520,13 +4514,9 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 		 * However, we maintain the display planes as UC, and so
 		 * need to rebind when first used as such.
 		 */
-		cache_level = I915_CACHE_LLC;
+		obj->cache_level = I915_CACHE_LLC;
 	else
-		cache_level = I915_CACHE_NONE;
-
-	i915_gem_object_set_cache_coherency(obj, cache_level);
-
-	trace_i915_gem_object_create(obj);
+		obj->cache_level = I915_CACHE_NONE;
 
 	return obj;
 
@@ -4535,6 +4525,49 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 	return ERR_PTR(ret);
 }
 
+struct drm_i915_gem_object *
+i915_gem_object_create(struct drm_i915_private *i915, u64 size)
+{
+	return i915_gem_object_create_region(i915->regions[INTEL_MEMORY_SMEM],
+					     size, 0);
+}
+
+static int i915_region_smem_init(struct intel_memory_region *mem)
+{
+	int err;
+
+	err = i915_gemfs_init(mem->i915);
+	if (err)
+		DRM_NOTE("Unable to create a private tmpfs mount, hugepage support will be disabled(%d).\n", err);
+
+	return 0; /* Don't error, we can simply fallback to the kernel mnt */
+}
+
+static void i915_region_smem_release(struct intel_memory_region *mem)
+{
+	i915_gemfs_fini(mem->i915);
+}
+
+/*
+ * XXX: all of this looks much cleaner when we move all the shmem stuff to
+ * i915_gemfs.[ch] or similar, and also tidy up the pread/pwrite stuff with
+ * proper vfuncs, but we want to avoid doing that on internal, since the
+ * conflicts will be huge later...
+ */
+static const struct intel_memory_region_ops i915_region_smem_ops = {
+	.init = i915_region_smem_init,
+	.release = i915_region_smem_release,
+	.object_create = i915_gem_object_create_shmem,
+};
+
+struct intel_memory_region *i915_gem_setup_smem(struct drm_i915_private *i915)
+{
+	return intel_memory_region_create(i915, 0,
+					  totalram_pages() << PAGE_SHIFT,
+					  I915_GTT_PAGE_SIZE_4K, 0,
+					  &i915_region_smem_ops);
+}
+
 static bool discard_backing_storage(struct drm_i915_gem_object *obj)
 {
 	/* If we are the last user of the backing storage (be it shmemfs
@@ -6019,10 +6052,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 
 	spin_lock_init(&dev_priv->fb_tracking.lock);
 
-	err = i915_gemfs_init(dev_priv);
-	if (err)
-		DRM_NOTE("Unable to create a private tmpfs mount, hugepage support will be disabled(%d).\n", err);
-
 	return 0;
 
 err_dependencies:
@@ -6057,8 +6086,6 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
 
 	/* And ensure that our DESTROY_BY_RCU slabs are truly destroyed */
 	rcu_barrier();
-
-	i915_gemfs_fini(dev_priv);
 }
 
 int i915_gem_freeze(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e0a8e90b1480..84b2fa5608fb 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2837,7 +2837,8 @@ static int i915_gem_init_memory_regions(struct drm_i915_private *i915)
 
 		type = MEMORY_TYPE_FROM_REGION(intel_region_map[i]);
 		switch (type) {
-		default:
+		case INTEL_SMEM:
+			mem = i915_gem_setup_smem(i915);
 			break;
 		}
 
@@ -2847,11 +2848,9 @@ static int i915_gem_init_memory_regions(struct drm_i915_private *i915)
 			goto out_cleanup;
 		}
 
-		if (mem) {
-			mem->id = intel_region_map[i];
-			mem->type = type;
-			mem->instance = MEMORY_INSTANCE_FROM_REGION(intel_region_map[i]);
-		}
+		mem->id = intel_region_map[i];
+		mem->type = type;
+		mem->instance = MEMORY_INSTANCE_FROM_REGION(intel_region_map[i]);
 
 		i915->regions[i] = mem;
 	}
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 5531ed94bdab..17af5b4f0a1a 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -197,6 +197,13 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
 	GEM_BUG_ON(!size);
 	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
 
+	/*
+	 * There is a prevalence of the assumption that we fit the object's
+	 * page count inside a 32bit _signed_ variable. Let's document this and
+	 * catch if we ever need to fix it. In the meantime, if you do spot
+	 * such a local variable, please consider fixing!
+	 */
+
 	if (size >> PAGE_SHIFT > INT_MAX)
 		return ERR_PTR(-E2BIG);
 
@@ -222,6 +229,8 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
 
 	i915_gem_object_set_cache_coherency(obj, obj->cache_level);
 
+	trace_i915_gem_object_create(obj);
+
 	return obj;
 }
 
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 39/42] drm/i915: treat stolen as a region
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (37 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 38/42] drm/i915: treat shmem as a region Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 40/42] drm/i915: setup io-mapping for LMEM Matthew Auld
                   ` (5 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Convert stolen memory over to a region object. Still leaves open the
question with what to do with pre-allocated objects...

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            |  3 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c        | 14 +----
 drivers/gpu/drm/i915/i915_gem_stolen.c     | 66 +++++++++++++++++++---
 drivers/gpu/drm/i915/intel_memory_region.c |  2 +-
 4 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 23f04e5a4b76..46fd5fd64231 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3194,8 +3194,7 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
 					 u64 end);
 void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
 				 struct drm_mm_node *node);
-int i915_gem_init_stolen(struct drm_i915_private *dev_priv);
-void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv);
+struct intel_memory_region *i915_gem_setup_stolen(struct drm_i915_private *i915);
 struct drm_i915_gem_object *
 i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
 			      resource_size_t size);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 84b2fa5608fb..f5d595c700f4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2802,8 +2802,6 @@ static void i915_gem_cleanup_memory_regions(struct drm_i915_private *i915)
 {
 	int i;
 
-	i915_gem_cleanup_stolen(i915);
-
 	for (i = 0; i < ARRAY_SIZE(i915->regions); ++i)	{
 		struct intel_memory_region *region = i915->regions[i];
 
@@ -2819,15 +2817,6 @@ static int i915_gem_init_memory_regions(struct drm_i915_private *i915)
 	/* All platforms currently have system memory */
 	GEM_BUG_ON(!HAS_REGION(i915, REGION_SMEM));
 
-	/*
-	 * Initialise stolen early so that we may reserve preallocated
-	 * objects for the BIOS to KMS transition.
-	 */
-	/* XXX: stolen will become a region at some point */
-	err = i915_gem_init_stolen(i915);
-	if (err)
-		return err;
-
 	for (i = 0; i < ARRAY_SIZE(intel_region_map); i++) {
 		struct intel_memory_region *mem = NULL;
 		u32 type;
@@ -2840,6 +2829,9 @@ static int i915_gem_init_memory_regions(struct drm_i915_private *i915)
 		case INTEL_SMEM:
 			mem = i915_gem_setup_smem(i915);
 			break;
+		case INTEL_STOLEN:
+			mem = i915_gem_setup_stolen(i915);
+			break;
 		}
 
 		if (IS_ERR(mem)) {
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 74a9661479ca..6ef94a32edf9 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -166,7 +166,7 @@ static int i915_adjust_stolen(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
-void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv)
+static void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv)
 {
 	if (!drm_mm_initialized(&dev_priv->mm.stolen))
 		return;
@@ -371,7 +371,7 @@ static void icl_get_stolen_reserved(struct drm_i915_private *dev_priv,
 	}
 }
 
-int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
+static int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
 {
 	resource_size_t reserved_base, stolen_top;
 	resource_size_t reserved_total, reserved_size;
@@ -550,6 +550,9 @@ i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
 
 	i915_gem_stolen_remove_node(dev_priv, stolen);
 	kfree(stolen);
+
+	if (obj->memory_region)
+		i915_gem_object_release_memory_region(obj);
 }
 
 static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
@@ -559,8 +562,8 @@ static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
 };
 
 static struct drm_i915_gem_object *
-_i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
-			       struct drm_mm_node *stolen)
+__i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
+				struct drm_mm_node *stolen)
 {
 	struct drm_i915_gem_object *obj;
 	unsigned int cache_level;
@@ -587,10 +590,12 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
 	return NULL;
 }
 
-struct drm_i915_gem_object *
-i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
-			      resource_size_t size)
+static struct drm_i915_gem_object *
+_i915_gem_object_create_stolen(struct intel_memory_region *mem,
+			       resource_size_t size,
+			       unsigned int flags)
 {
+	struct drm_i915_private *dev_priv = mem->i915;
 	struct drm_i915_gem_object *obj;
 	struct drm_mm_node *stolen;
 	int ret;
@@ -611,7 +616,7 @@ i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
 		return NULL;
 	}
 
-	obj = _i915_gem_object_create_stolen(dev_priv, stolen);
+	obj = __i915_gem_object_create_stolen(dev_priv, stolen);
 	if (obj)
 		return obj;
 
@@ -620,6 +625,49 @@ i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
 	return NULL;
 }
 
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
+			      resource_size_t size)
+{
+	struct drm_i915_gem_object *obj;
+
+	obj = i915_gem_object_create_region(dev_priv->regions[INTEL_MEMORY_STOLEN],
+					    size, I915_BO_ALLOC_CONTIGUOUS);
+	if (IS_ERR(obj))
+		return NULL;
+
+	return obj;
+}
+
+static int i915_memory_region_init_stolen(struct intel_memory_region *mem)
+{
+	/*
+	 * Initialise stolen early so that we may reserve preallocated
+	 * objects for the BIOS to KMS transition.
+	 */
+	return i915_gem_init_stolen(mem->i915);
+}
+
+static void i915_memory_region_release_stolen(struct intel_memory_region *mem)
+{
+	i915_gem_cleanup_stolen(mem->i915);
+}
+
+static const struct intel_memory_region_ops i915_region_stolen_ops = {
+	.init = i915_memory_region_init_stolen,
+	.release = i915_memory_region_release_stolen,
+	.object_create = _i915_gem_object_create_stolen,
+};
+
+struct intel_memory_region *i915_gem_setup_stolen(struct drm_i915_private *i915)
+{
+	return intel_memory_region_create(i915,
+					  intel_graphics_stolen_res.start,
+					  resource_size(&intel_graphics_stolen_res),
+					  I915_GTT_PAGE_SIZE_4K, 0,
+					  &i915_region_stolen_ops);
+}
+
 struct drm_i915_gem_object *
 i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv,
 					       resource_size_t stolen_offset,
@@ -661,7 +709,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
 		return NULL;
 	}
 
-	obj = _i915_gem_object_create_stolen(dev_priv, stolen);
+	obj = __i915_gem_object_create_stolen(dev_priv, stolen);
 	if (obj == NULL) {
 		DRM_DEBUG_DRIVER("failed to allocate stolen object\n");
 		i915_gem_stolen_remove_node(dev_priv, stolen);
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 17af5b4f0a1a..cbdf66fdae4e 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -211,7 +211,7 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
 		return ERR_PTR(-E2BIG);
 
 	obj = mem->ops->object_create(mem, size, flags);
-	if (IS_ERR(obj))
+	if (IS_ERR_OR_NULL(obj))
 		return obj;
 
 	INIT_LIST_HEAD(&obj->blocks);
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 40/42] drm/i915: setup io-mapping for LMEM
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (38 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 39/42] drm/i915: treat stolen " Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 41/42] HAX drm/i915: add the fake lmem region Matthew Auld
                   ` (4 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

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

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/intel_region_lmem.c | 28 ++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
index b8b6b8248737..10dfcf961c4b 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -233,9 +233,33 @@ region_lmem_object_create(struct intel_memory_region *mem,
 	return obj;
 }
 
+static void
+region_lmem_release(struct intel_memory_region *mem)
+{
+	io_mapping_fini(&mem->iomap);
+	i915_memory_region_release_buddy(mem);
+}
+
+static int
+region_lmem_init(struct intel_memory_region *mem)
+{
+	int ret;
+
+	if (!io_mapping_init_wc(&mem->iomap,
+				mem->io_start,
+				resource_size(&mem->region)))
+		return -EIO;
+
+	ret = i915_memory_region_init_buddy(mem);
+	if (ret)
+		io_mapping_fini(&mem->iomap);
+
+	return ret;
+}
+
 static const struct intel_memory_region_ops region_lmem_ops = {
-	.init = i915_memory_region_init_buddy,
-	.release = i915_memory_region_release_buddy,
+	.init = region_lmem_init,
+	.release = region_lmem_release,
 	.object_create = region_lmem_object_create,
 };
 
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 41/42] HAX drm/i915: add the fake lmem region
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (39 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 40/42] drm/i915: setup io-mapping for LMEM Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 14:57 ` [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM Matthew Auld
                   ` (3 subsequent siblings)
  44 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Intended for upstream testing so that we can still exercise the LMEM
plumbing and !HAS_MAPPABLE_APERTURE paths. Smoke tested on Skull Canyon
device. This works by allocating an intel_memory_region for a reserved
portion of system memory, which we treat like LMEM. For the LMEMBAR we
steal the aperture and 1:1 it map to the stolen region.

To enable simply set i915_fake_lmem_start= on the kernel cmdline with the
start of reserved region(see memmap=). The size of the region we can
use is determined by the size of the mappable aperture, so the size of
reserved region should be >= mappable_end.

eg. memmap=2G$16G i915_fake_lmem_start=0x400000000

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 arch/x86/kernel/early-quirks.c             | 26 ++++++++
 drivers/gpu/drm/i915/i915_drv.c            |  7 +++
 drivers/gpu/drm/i915/i915_gem_gtt.c        |  3 +
 drivers/gpu/drm/i915/intel_memory_region.h |  4 ++
 drivers/gpu/drm/i915/intel_region_lmem.c   | 73 ++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_region_lmem.h   |  3 +
 include/drm/i915_drm.h                     |  3 +
 7 files changed, 119 insertions(+)

diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 50d5848bf22e..bdc99d6bfa26 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -600,6 +600,32 @@ static void __init intel_graphics_quirks(int num, int slot, int func)
 	}
 }
 
+struct resource intel_graphics_fake_lmem_res __ro_after_init = DEFINE_RES_MEM(0, 0);
+EXPORT_SYMBOL(intel_graphics_fake_lmem_res);
+
+static int __init early_i915_fake_lmem_init(char *s)
+{
+	u64 start;
+	int ret;
+
+	if (*s == '=')
+		s++;
+
+	ret = kstrtoull(s, 16, &start);
+	if (ret)
+		return ret;
+
+	intel_graphics_fake_lmem_res.start = start;
+	intel_graphics_fake_lmem_res.end = SZ_2G; /* Placeholder; depends on aperture size */
+
+	printk(KERN_INFO "Intel graphics fake LMEM starts at %pa\n",
+	       &intel_graphics_fake_lmem_res.start);
+
+	return 0;
+}
+
+early_param("i915_fake_lmem_start", early_i915_fake_lmem_init);
+
 static void __init force_disable_hpet(int num, int slot, int func)
 {
 #ifdef CONFIG_HPET_TIMER
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 08a4286b70c6..54e24fa075c9 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1732,6 +1732,13 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (!i915_modparams.nuclear_pageflip && match_info->gen < 5)
 		dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
 
+	/* Check if we need fake LMEM */
+	if (INTEL_GEN(dev_priv) >= 9 && intel_graphics_fake_lmem_res.start) {
+		mkwrite_device_info(dev_priv)->memory_regions =
+			REGION_SMEM | REGION_LMEM;
+		GEM_BUG_ON(!HAS_LMEM(dev_priv));
+	}
+
 	ret = pci_enable_device(pdev);
 	if (ret)
 		goto out_fini;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f5d595c700f4..4101992b65f3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2832,6 +2832,9 @@ static int i915_gem_init_memory_regions(struct drm_i915_private *i915)
 		case INTEL_STOLEN:
 			mem = i915_gem_setup_stolen(i915);
 			break;
+		case INTEL_LMEM:
+			mem = i915_gem_setup_fake_lmem(i915);
+			break;
 		}
 
 		if (IS_ERR(mem)) {
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index 7754989ad165..ebc46024a376 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -28,6 +28,7 @@
 #include <linux/ioport.h>
 #include <linux/mutex.h>
 #include <linux/io-mapping.h>
+#include <drm/drm_mm.h>
 
 #include "i915_gem_buddy.h"
 
@@ -90,6 +91,9 @@ struct intel_memory_region {
 	struct io_mapping iomap;
 	struct resource region;
 
+	/* For faking for lmem */
+	struct drm_mm_node fake_mappable;
+
 	struct i915_gem_buddy_mm mm;
 	struct mutex mm_lock;
 
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
index 10dfcf961c4b..a5a7386ff255 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -233,9 +233,41 @@ region_lmem_object_create(struct intel_memory_region *mem,
 	return obj;
 }
 
+static int i915_gem_init_fake_lmem_bar(struct intel_memory_region *mem)
+{
+	struct drm_i915_private *i915 = mem->i915;
+	struct i915_ggtt *ggtt = &i915->ggtt;
+	unsigned long n;
+	int ret;
+
+	mem->fake_mappable.start = 0;
+	mem->fake_mappable.size = resource_size(&mem->region);
+	mem->fake_mappable.color = I915_COLOR_UNEVICTABLE;
+
+	ret = drm_mm_reserve_node(&ggtt->vm.mm, &mem->fake_mappable);
+	if (ret)
+		return ret;
+
+	/* 1:1 map the mappable aperture to our reserved region */
+	for (n = 0; n < mem->fake_mappable.size >> PAGE_SHIFT; ++n) {
+		ggtt->vm.insert_page(&ggtt->vm,
+				     mem->region.start + (n << PAGE_SHIFT),
+				     n << PAGE_SHIFT, I915_CACHE_NONE, 0);
+	}
+
+	return 0;
+}
+
+static void i915_gem_relase_fake_lmem_bar(struct intel_memory_region *mem)
+{
+	if (drm_mm_node_allocated(&mem->fake_mappable))
+		drm_mm_remove_node(&mem->fake_mappable);
+}
+
 static void
 region_lmem_release(struct intel_memory_region *mem)
 {
+	i915_gem_relase_fake_lmem_bar(mem);
 	io_mapping_fini(&mem->iomap);
 	i915_memory_region_release_buddy(mem);
 }
@@ -245,6 +277,11 @@ region_lmem_init(struct intel_memory_region *mem)
 {
 	int ret;
 
+	if (intel_graphics_fake_lmem_res.start) {
+		ret = i915_gem_init_fake_lmem_bar(mem);
+		GEM_BUG_ON(ret);
+	}
+
 	if (!io_mapping_init_wc(&mem->iomap,
 				mem->io_start,
 				resource_size(&mem->region)))
@@ -270,6 +307,7 @@ void __iomem *i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object *obj,
 	resource_size_t offset;
 
 	offset = i915_gem_object_get_dma_address(obj, n);
+	offset -= intel_graphics_fake_lmem_res.start;
 
 	return io_mapping_map_atomic_wc(&obj->memory_region->iomap, offset);
 }
@@ -283,6 +321,7 @@ void __iomem *i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
 	GEM_BUG_ON(!(obj->flags & I915_BO_ALLOC_CONTIGUOUS));
 
 	offset = i915_gem_object_get_dma_address(obj, n);
+	offset -= intel_graphics_fake_lmem_res.start;
 
 	return io_mapping_map_wc(&obj->memory_region->iomap, offset, size);
 }
@@ -294,6 +333,7 @@ unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
 	resource_size_t offset;
 
 	offset = i915_gem_object_get_dma_address(obj, n);
+	offset -= intel_graphics_fake_lmem_res.start;
 
 	return (mem->io_start + offset) >> PAGE_SHIFT;
 }
@@ -313,3 +353,36 @@ i915_gem_object_create_lmem(struct drm_i915_private *i915,
 	return i915_gem_object_create_region(i915->regions[INTEL_MEMORY_LMEM],
 					     size, flags);
 }
+
+struct intel_memory_region *
+i915_gem_setup_fake_lmem(struct drm_i915_private *i915)
+{
+	struct pci_dev *pdev = i915->drm.pdev;
+	struct intel_memory_region *mem;
+	resource_size_t mappable_end;
+	resource_size_t io_start;
+	resource_size_t start;
+
+	GEM_BUG_ON(HAS_MAPPABLE_APERTURE(i915));
+	GEM_BUG_ON(!intel_graphics_fake_lmem_res.start);
+
+	/* Your mappable aperture belongs to me now! */
+	mappable_end = pci_resource_len(pdev, 2);
+	io_start = pci_resource_start(pdev, 2),
+	start = intel_graphics_fake_lmem_res.start;
+
+	mem = intel_memory_region_create(i915,
+					 start,
+					 mappable_end,
+					 I915_GTT_PAGE_SIZE_4K,
+					 io_start,
+					 &region_lmem_ops);
+	if (!IS_ERR(mem)) {
+		DRM_INFO("Intel graphics fake LMEM: %pR\n", &mem->region);
+		DRM_INFO("Intel graphics fake LMEM IO start: %llx\n",
+			 (u64)mem->io_start);
+	}
+
+	return mem;
+}
+
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h b/drivers/gpu/drm/i915/intel_region_lmem.h
index a76b77b69e71..33aadbaba4e0 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.h
+++ b/drivers/gpu/drm/i915/intel_region_lmem.h
@@ -40,4 +40,7 @@ i915_gem_object_create_lmem(struct drm_i915_private *i915,
 			    resource_size_t size,
 			    unsigned int flags);
 
+struct intel_memory_region *
+i915_gem_setup_fake_lmem(struct drm_i915_private *i915);
+
 #endif /* !__INTEL_REGION_LMEM_H */
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index c44703f471b3..59865a2d4305 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -39,6 +39,9 @@ extern bool i915_gpu_turbo_disable(void);
 /* Exported from arch/x86/kernel/early-quirks.c */
 extern struct resource intel_graphics_stolen_res;
 
+/* Exported from arch/x86/kernel/early-printk.c */
+extern struct resource intel_graphics_fake_lmem_res;
+
 /*
  * The Bridge device's PCI config space has information about the
  * fb aperture size and the amount of pre-reserved memory.
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (40 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 41/42] HAX drm/i915: add the fake lmem region Matthew Auld
@ 2019-02-14 14:57 ` Matthew Auld
  2019-02-14 16:13   ` Chris Wilson
  2019-02-14 16:22   ` Chris Wilson
  2019-02-14 17:58 ` ✗ Fi.CI.CHECKPATCH: warning for Introduce memory region concept (including device local memory) Patchwork
                   ` (2 subsequent siblings)
  44 siblings, 2 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-14 14:57 UTC (permalink / raw)
  To: intel-gfx

Hack patch to default all userspace allocations to LMEM. Useful for
testing purposes.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 45 +++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3c86909d55b9..bd857f477ef9 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -641,7 +641,8 @@ i915_gem_create(struct drm_file *file,
 		u32 *handle_p)
 {
 	struct drm_i915_gem_object *obj;
-	int ret;
+	intel_wakeref_t wakeref;
+	int ret = 0;
 	u32 handle;
 
 	size = roundup(size, PAGE_SIZE);
@@ -649,10 +650,50 @@ i915_gem_create(struct drm_file *file,
 		return -EINVAL;
 
 	/* Allocate the new object */
-	obj = i915_gem_object_create(dev_priv, size);
+	if (HAS_LMEM(dev_priv))
+		obj = i915_gem_object_create_lmem(dev_priv, size, 0);
+	else
+		obj = i915_gem_object_create(dev_priv, size);
 	if (IS_ERR(obj))
 		return PTR_ERR(obj);
 
+	if (i915_gem_object_is_lmem(obj)) {
+		struct i915_gem_context *ctx;
+
+		/* XXX: we should prob use the blitter context for this? */
+		ctx = i915_gem_context_lookup(file->driver_priv,
+					      DEFAULT_CONTEXT_HANDLE);
+		if (!ctx) {
+			i915_gem_object_put(obj);
+			return -ENOENT;
+		}
+
+		/*
+		 * XXX: We really want to move this to get_pages(), but we
+		 * require grabbing the BKL for the blitting operation which is
+		 * annoying. In the pipeline is support for async get_pages()
+		 * which should fit nicely for this. Also note that the actual
+		 * clear should be done async(we currently do an object_wait
+		 * in clear_blt which is pure garbage), we just need to take
+		 * care if userspace opts of implicit sync for the execbuf, to
+		 * avoid any potential info leak.
+		 */
+
+		mutex_lock(&dev_priv->drm.struct_mutex);
+
+		with_intel_runtime_pm(dev_priv, wakeref)
+			ret = i915_gem_object_clear_blt(ctx, obj);
+
+		i915_gem_context_put(ctx);
+		if (ret) {
+			__i915_gem_object_release_unless_active(obj);
+			mutex_unlock(&dev_priv->drm.struct_mutex);
+			return ret;
+		}
+
+		mutex_unlock(&dev_priv->drm.struct_mutex);
+	}
+
 	ret = drm_gem_handle_create(file, &obj->base, &handle);
 	/* drop reference from allocate - handle holds it now */
 	i915_gem_object_put(obj);
-- 
2.20.1

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

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
  2019-02-14 14:57 ` [RFC PATCH 04/42] drm/i915: introduce intel_memory_region Matthew Auld
@ 2019-02-14 15:16   ` Chris Wilson
  2019-02-26 14:03     ` Matthew Auld
  2019-02-26 13:00   ` Tvrtko Ursulin
  1 sibling, 1 reply; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:16 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:02)
> +int
> +i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
> +{
> +       struct intel_memory_region *mem = obj->memory_region;
> +       resource_size_t size = obj->base.size;
> +       struct sg_table *st;
> +       struct scatterlist *sg;
> +       unsigned int sg_page_sizes;
> +       unsigned long n_pages;
> +
> +       GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.min_size));
> +       GEM_BUG_ON(!list_empty(&obj->blocks));
> +
> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> +       if (!st)
> +               return -ENOMEM;
> +
> +       n_pages = div64_u64(size, mem->mm.min_size);

min_size is a power of two.

n_pages = size >> ilog2(min_size);

would suffice. Keeping min_order would come in handy later.

> +
> +       if (sg_alloc_table(st, n_pages, GFP_KERNEL)) {
> +               kfree(st);
> +               return -ENOMEM;
> +       }
> +
> +       sg = st->sgl;
> +       st->nents = 0;
> +       sg_page_sizes = 0;
> +
> +       mutex_lock(&mem->mm_lock);
> +
> +       do {
> +               struct i915_gem_buddy_block *block;
> +               unsigned int order;
> +               u64 block_size;
> +               u64 offset;
> +
> +               order = fls(n_pages) - 1;
> +               GEM_BUG_ON(order > mem->mm.max_order);
> +
> +               do {
> +                       block = i915_gem_buddy_alloc(&mem->mm, order);
> +                       if (!IS_ERR(block))
> +                               break;
> +
> +                       /* XXX: some kind of eviction pass, local to the device */
> +                       if (!order--)
> +                               goto err_free_blocks;
> +               } while (1);
> +
> +               n_pages -= 1 << order;

BIT(order) so you don't have sign extension fun. Need to fix
i915_gem_internal.c!

> +struct intel_memory_region_ops {
> +       unsigned int flags;
> +
> +       int (*init)(struct intel_memory_region *);
> +       void (*release)(struct intel_memory_region *);
> +
> +       struct drm_i915_gem_object *
> +       (*object_create)(struct intel_memory_region *,
> +                        resource_size_t,
> +                        unsigned int);

create_object()

ops is acting as a factory here; and we are not operating on the object
itself.

> +static int igt_mock_fill(void *arg)
> +{
> +       struct intel_memory_region *mem = arg;
> +       resource_size_t total = resource_size(&mem->region);
> +       resource_size_t page_size;
> +       resource_size_t rem;
> +       unsigned long max_pages;
> +       unsigned long page_num;
> +       LIST_HEAD(objects);
> +       int err = 0;
> +
> +       page_size = mem->mm.min_size;
> +       max_pages = total / page_size;

Hmm, 32b? Can resource_size_t be 64b on a 32b system?

It must be to accommodate PAE.

> +static struct drm_i915_gem_object *
> +mock_object_create(struct intel_memory_region *mem,
> +                  resource_size_t size,
> +                  unsigned int flags)
> +{
> +       struct drm_i915_private *i915 = mem->i915;
> +       struct drm_i915_gem_object *obj;
> +
> +       if (size > BIT(mem->mm.max_order) * mem->mm.min_size)

A mix of 64b and 32b types.

if (size >> mem->mm.max_order + mem->mm.min_order)

> +               return ERR_PTR(-E2BIG);

GEM_BUG_ON(overflows_type(size, obj->base.size);

> +       obj = i915_gem_object_alloc(i915);
> +       if (!obj)
> +               return ERR_PTR(-ENOMEM);
> +
> +       drm_gem_private_object_init(&i915->drm, &obj->base, size);
> +       i915_gem_object_init(obj, &mock_region_obj_ops);
> +
> +       obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
> +       obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;

i915_gem_object_set_cache_coherency() ?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 05/42] drm/i915/region: support basic eviction
  2019-02-14 14:57 ` [RFC PATCH 05/42] drm/i915/region: support basic eviction Matthew Auld
@ 2019-02-14 15:25   ` Chris Wilson
  2019-02-26 14:58     ` Matthew Auld
  0 siblings, 1 reply; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:25 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:03)
> Support basic eviction for regions.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h               |  2 +
>  drivers/gpu/drm/i915/i915_gem.c               | 16 ++++
>  drivers/gpu/drm/i915/i915_gem_object.h        |  7 ++
>  drivers/gpu/drm/i915/i915_gem_shrinker.c      | 59 ++++++++++++++
>  drivers/gpu/drm/i915/intel_memory_region.c    | 40 +++++++++-
>  drivers/gpu/drm/i915/intel_memory_region.h    |  7 ++
>  .../drm/i915/selftests/intel_memory_region.c  | 76 +++++++++++++++++++
>  drivers/gpu/drm/i915/selftests/mock_region.c  |  1 +
>  8 files changed, 204 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 0bea7d889284..3df27769b978 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3196,6 +3196,8 @@ void i915_gem_shrinker_register(struct drm_i915_private *i915);
>  void i915_gem_shrinker_unregister(struct drm_i915_private *i915);
>  void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915,
>                                     struct mutex *mutex);
> +int i915_gem_shrink_memory_region(struct intel_memory_region *mem,
> +                                 resource_size_t target);
>  
>  /* i915_gem_tiling.c */
>  static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 92768ab294a4..7f044b643a75 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -4095,6 +4095,22 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
>             !i915_gem_object_has_pages(obj))
>                 i915_gem_object_truncate(obj);
>  
> +       if (obj->memory_region) {
> +               mutex_lock(&obj->memory_region->obj_lock);
> +
> +               switch (obj->mm.madv) {
> +               case I915_MADV_WILLNEED:
> +                       list_move(&obj->region_link, &obj->memory_region->objects);
> +                       break;
> +               default:
> +                       list_move(&obj->region_link,
> +                                 &obj->memory_region->purgeable);
> +                       break;
> +               }
> +
> +               mutex_unlock(&obj->memory_region->obj_lock);
> +       }
> +
>         args->retained = obj->mm.madv != __I915_MADV_PURGED;
>         mutex_unlock(&obj->mm.lock);
>  
> diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
> index ac52f61e8ad1..76947a6f49f1 100644
> --- a/drivers/gpu/drm/i915/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/i915_gem_object.h
> @@ -95,6 +95,13 @@ struct drm_i915_gem_object {
>          * List of memory region blocks allocated for this object.
>          */
>         struct list_head blocks;
> +       /**
> +        * Element within memory_region->objects or memory_region->purgeable if
> +        * the object is marked as DONTNEED. Access is protected by
> +        * memory_region->obj_lock.

Lies. ;-p

> +        */
> +       struct list_head region_link;
> +       struct list_head tmp_link;
>  
>         struct {
>                 /**
> diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> index 6da795c7e62e..713c6c93cf30 100644
> --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
> +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> @@ -308,6 +308,65 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915)
>         return freed;
>  }
>  
> +int i915_gem_shrink_memory_region(struct intel_memory_region *mem,
> +                                 resource_size_t target)

If it's not going to be coupled into the mm.shrinker callback, do not put
it here! And there's no reason why we would ever couple local memory to
the generic mm shrinker!

> +{
> +       struct drm_i915_private *i915 = mem->i915;
> +       struct drm_i915_gem_object *obj, *on;
> +       resource_size_t found;
> +       LIST_HEAD(purgeable);
> +       bool unlock;
> +       int err;
> +
> +       if (!shrinker_lock(i915, 0, &unlock))
> +               return 0;

Don't...

> +
> +       i915_retire_requests(i915);

And this, don't do this.

> +       err = 0;
> +       found = 0;
> +
> +       mutex_lock(&mem->obj_lock);

That's all the top-level locking we should ever need.

> +       list_for_each_entry(obj, &mem->purgeable, region_link) {
> +               if (!i915_gem_object_has_pages(obj))
> +                       continue;
> +
> +               if (READ_ONCE(obj->pin_global))
> +                       continue;
> +
> +               if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count)
> +                       continue;
> +
> +               list_add(&obj->tmp_link, &purgeable);

Oh crikey.

> +
> +               found += obj->base.size;
> +               if (found >= target)
> +                       goto found;
> +       }
> +
> +       err = -ENOSPC;
> +found:
> +       mutex_unlock(&mem->obj_lock);
> +
> +       list_for_each_entry_safe(obj, on, &purgeable, tmp_link) {
> +               if (!err)
> +                       err = i915_gem_object_unbind(obj);

I would advise not to worry about unbinding until you have it decoupled
from struct_mutex. Or at least defer struct_mutex until you truly need
it to access the vma, so that it doesn't get abused for anything else.

> +               if (!err) {
> +                       __i915_gem_object_put_pages(obj,
> +                                                   I915_MM_SHRINKER);
> +                       if (!i915_gem_object_has_pages(obj))
> +                               obj->mm.madv = __I915_MADV_PURGED;

But this is racy.

> +               }
> +
> +               list_del(&obj->tmp_link);

I'm still going crikey. That's no excuse to invoke struct_mutex.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 09/42] drm/i915: support creating LMEM objects
  2019-02-14 14:57 ` [RFC PATCH 09/42] drm/i915: support creating LMEM objects Matthew Auld
@ 2019-02-14 15:30   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:30 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:07)
> +int intel_memory_region_live_selftests(struct drm_i915_private *i915)
> +{
> +       static const struct i915_subtest tests[] = {
> +               SUBTEST(igt_lmem_create),
> +       };
> +       struct i915_gem_context *ctx;
> +       struct drm_file *file;
> +       intel_wakeref_t wakeref;
> +       int err;
> +
> +       if (!HAS_LMEM(i915)) {
> +               pr_info("device lacks LMEM support, skipping\n");
> +               return 0;
> +       }
> +
> +       if (i915_terminally_wedged(&i915->gpu_error))
> +               return 0;
> +
> +       file = mock_file(i915);
> +       if (IS_ERR(file))
> +               return PTR_ERR(file);
> +
> +       mutex_lock(&i915->drm.struct_mutex);
> +       wakeref = intel_runtime_pm_get(i915);

Is taking a global mutex and wakeref wise? Unless I see otherwise, it
means I assume you haven't tested without struct_mutex or rpm very well.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 10/42] drm/i915/lmem: add helper to get CPU visible pfn
  2019-02-14 14:57 ` [RFC PATCH 10/42] drm/i915/lmem: add helper to get CPU visible pfn Matthew Auld
@ 2019-02-14 15:33   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:33 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:08)
> From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>

Why?

So can something without a CPU visible struct page even have a pfn?

> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_region_lmem.c | 11 +++++++++++
>  drivers/gpu/drm/i915/intel_region_lmem.h |  3 +++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c
> index 4a205639cbb6..b398becb2733 100644
> --- a/drivers/gpu/drm/i915/intel_region_lmem.c
> +++ b/drivers/gpu/drm/i915/intel_region_lmem.c
> @@ -65,6 +65,17 @@ static const struct intel_memory_region_ops region_lmem_ops = {
>         .object_create = region_lmem_object_create,
>  };
>  
> +unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
> +                                         unsigned long n)
> +{
> +       struct intel_memory_region *mem = obj->memory_region;
> +       resource_size_t offset;
> +
> +       offset = i915_gem_object_get_dma_address(obj, n);

Magic of type convenience?

We definitely do not want to be returning a dma_address as a CPU
address. The semantics here needs to be cleaned up.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine
  2019-02-14 14:57 ` [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine Matthew Auld
@ 2019-02-14 15:37   ` Chris Wilson
  2019-02-14 15:38   ` Chris Wilson
  2019-02-14 15:40   ` Chris Wilson
  2 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:37 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:11)
> diff --git a/drivers/gpu/drm/i915/intel_gpu_commands.h b/drivers/gpu/drm/i915/intel_gpu_commands.h
> index b96a31bc1080..f74ff1d095c2 100644
> --- a/drivers/gpu/drm/i915/intel_gpu_commands.h
> +++ b/drivers/gpu/drm/i915/intel_gpu_commands.h
> @@ -175,6 +175,7 @@
>  #define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2)
>  
>  #define COLOR_BLT_CMD                  (2<<29 | 0x40<<22 | (5-2))
> +#define XY_COLOR_BLT_CMD               (2<<29 | 0x50<<22 | (7-2))

Remove the dword lengths here. The XY commands are not gen8 specific,
and construction is much neater if we just add the pktlen on writing the
cmd.

>  #define SRC_COPY_BLT_CMD               ((2<<29)|(0x43<<22)|4)
>  #define XY_SRC_COPY_BLT_CMD            ((2<<29)|(0x53<<22)|6)
>  #define XY_MONO_SRC_COPY_IMM_BLT       ((2<<29)|(0x71<<22)|5)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine
  2019-02-14 14:57 ` [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine Matthew Auld
  2019-02-14 15:37   ` Chris Wilson
@ 2019-02-14 15:38   ` Chris Wilson
  2019-02-14 15:40   ` Chris Wilson
  2 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:38 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:11)
> +static struct i915_vma *
> +__i915_gem_fill_blt(struct i915_vma *vma, u32 value)
> +{
> +       struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
> +       const int gen = INTEL_GEN(i915);
> +       struct drm_i915_gem_object *obj;
> +       struct i915_vma *batch;
> +       u32 *cmd;
> +       int err;
> +
> +       obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
> +       if (IS_ERR(obj))
> +               return ERR_CAST(obj);
> +
> +       cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
> +       if (IS_ERR(cmd)) {
> +               err = PTR_ERR(cmd);
> +               goto err;
> +       }
> +
> +       if (gen >= 8) {
> +               *cmd++ = XY_COLOR_BLT_CMD | BLT_WRITE_RGBA;
> +               *cmd++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE;
> +               *cmd++ = 0;
> +               *cmd++ = vma->obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
> +               *cmd++ = lower_32_bits(vma->node.start);
> +               *cmd++ = upper_32_bits(vma->node.start);
> +               *cmd++ = value;
> +               *cmd++ = MI_NOOP;
> +       } else {
> +               *cmd++ = COLOR_BLT_CMD | BLT_WRITE_RGBA;
> +               *cmd++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE;
> +               *cmd++ = vma->obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE;
> +               *cmd++ = vma->node.start;
> +               *cmd++ = value;
> +               *cmd++ = MI_NOOP;
> +       }
> +
> +       *cmd = MI_BATCH_BUFFER_END;

Why did you create a batch? Just issue the command from inside the
request.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine
  2019-02-14 14:57 ` [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine Matthew Auld
  2019-02-14 15:37   ` Chris Wilson
  2019-02-14 15:38   ` Chris Wilson
@ 2019-02-14 15:40   ` Chris Wilson
  2 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:40 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:11)
> +static int i915_gem_object_fill_blt(struct i915_gem_context *ctx,
> +                                   struct drm_i915_gem_object *obj,
> +                                   u32 value)
> +{
> +       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> +       struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->vm : &i915->ggtt.vm;
> +       struct i915_vma *vma;
> +       int err;
> +
> +       lockdep_assert_held(&i915->drm.struct_mutex);
> +
> +       vma = i915_vma_instance(obj, vm, NULL);
> +       if (IS_ERR(vma))
> +               return PTR_ERR(vma);
> +
> +       err = i915_vma_pin(vma, 0, 0, PIN_USER);
> +       if (err) {
> +               i915_vma_close(vma);
> +               return err;
> +       }
> +
> +       err = i915_gem_fill_blt(ctx, vma, value);
> +       i915_vma_unpin(vma);
> +       if (err)
> +               return err;
> +
> +       return i915_gem_object_wait(obj,
> +                                   I915_WAIT_LOCKED |
> +                                   I915_WAIT_ALL,
> +                                   MAX_SCHEDULE_TIMEOUT);

Oh no, don't even start by making this synchronous.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 14/42] drm/i915: introduce kernel blitter_context
  2019-02-14 14:57 ` [RFC PATCH 14/42] drm/i915: introduce kernel blitter_context Matthew Auld
@ 2019-02-14 15:42   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:42 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:12)
> We may be without a context to perform various internal blitter
> operations, for example when performing object migration. Piggybacking
> off the kernel_context is probably a bad idea, since it has other uses.

Explain why it is a worse idea than creating yet another kernel context
to manage. The fact that we may use it for blitting makes the kernel
context even more viable for its other jobs (such as knowing we've
flushed off user contexts). Convince me that we really need more than
one internal context; and that blitting especially needs its own.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations
  2019-02-14 14:57 ` [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations Matthew Auld
@ 2019-02-14 15:48   ` Chris Wilson
  2019-02-26 18:53     ` Matthew Auld
  0 siblings, 1 reply; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:48 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:16)
> We need to support doing relocations from the CPU when dealing with LMEM
> objects.

Why not just use the GPU reloc? Please do explain the relative merits.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 20/42] drm/i915/lmem: support pread
  2019-02-14 14:57 ` [RFC PATCH 20/42] drm/i915/lmem: support pread Matthew Auld
@ 2019-02-14 15:50   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:50 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:18)
> +       ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
> +       if (ret)
> +               goto out_unpin;
> +
> +       wakeref = intel_runtime_pm_get(i915);

But why wakeref in the middle?
> +
> +       ret = i915_gem_object_set_to_wc_domain(obj, false);
> +       mutex_unlock(&i915->drm.struct_mutex);

Anyway, this is a disaster that needs fixing before we make it worse.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 26/42] drm/i915: error capture with no ggtt slot
  2019-02-14 14:57 ` [RFC PATCH 26/42] drm/i915: error capture with no ggtt slot Matthew Auld
@ 2019-02-14 15:56   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 15:56 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:24)
> +               void *s;
> +               struct page *page;
> +
> +               for_each_sgt_page(page, iter, vma->pages) {
> +                       s = kmap_atomic(page);

These pages are not coherent, so missing the point of using UC/WC access
to get what the GPU saw and not what the CPU last speculated.

Typically, and historically, we would use clflush before after.

Just be careful not to use drm_clflush as that invokes wbinvd via
on_each_cpu and is therefore illegal.

Alternatively would be to kmap them as WC.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 28/42] drm/i915: Split out GTT fault handler to make it generic
  2019-02-14 14:57 ` [RFC PATCH 28/42] drm/i915: Split out GTT fault handler to make it generic Matthew Auld
@ 2019-02-14 16:00   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:00 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:26)
> From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> 
> In preparation for using multiple page-fault handlers depending
> on the object's backing storage.
> 
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem.c | 112 +++++++++++++++++++-------------
>  1 file changed, 66 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index e59f38e00f0d..95e31529a738 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1782,11 +1782,7 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
>  }
>  
>  /**
> - * i915_gem_fault - fault a page into the GTT
> - * @vmf: fault info
> - *
> - * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped
> - * from userspace.  The fault handler takes care of binding the object to
> + * The GTT fill pages handler takes care of binding the object to
>   * the GTT (if needed), allocating and programming a fence register (again,
>   * only if needed based on whether the old reg is still valid or the object
>   * is tiled) and inserting a new PTE into the faulting process.
> @@ -1799,57 +1795,20 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
>   * The current feature set supported by i915_gem_fault() and thus GTT mmaps
>   * is exposed via I915_PARAM_MMAP_GTT_VERSION (see i915_gem_mmap_gtt_version).
>   */
> -vm_fault_t i915_gem_fault(struct vm_fault *vmf)
> +static int __vmf_fill_pages_gtt(struct drm_i915_gem_object *obj,
> +                               struct vm_fault *vmf,
> +                               pgoff_t page_offset)
>  {
>  #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
>         struct vm_area_struct *area = vmf->vma;
> -       struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
>         struct drm_device *dev = obj->base.dev;
>         struct drm_i915_private *dev_priv = to_i915(dev);
>         struct i915_ggtt *ggtt = &dev_priv->ggtt;
>         bool write = area->vm_flags & VM_WRITE;
> -       intel_wakeref_t wakeref;
>         struct i915_vma *vma;
> -       pgoff_t page_offset;
>         int srcu;
>         int ret;
>  
> -       /* Sanity check that we allow writing into this object */
> -       if (i915_gem_object_is_readonly(obj) && write)
> -               return VM_FAULT_SIGBUS;
> -
> -       /* We don't use vmf->pgoff since that has the fake offset */
> -       page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
> -
> -       trace_i915_gem_object_fault(obj, page_offset, true, write);
> -
> -       /* Try to flush the object off the GPU first without holding the lock.
> -        * Upon acquiring the lock, we will perform our sanity checks and then
> -        * repeat the flush holding the lock in the normal manner to catch cases
> -        * where we are gazumped.
> -        */
> -       ret = i915_gem_object_wait(obj,
> -                                  I915_WAIT_INTERRUPTIBLE,
> -                                  MAX_SCHEDULE_TIMEOUT);
> -       if (ret)
> -               goto err;
> -
> -       ret = i915_gem_object_pin_pages(obj);
> -       if (ret)
> -               goto err;
> -
> -       wakeref = intel_runtime_pm_get(dev_priv);
> -
> -       ret = i915_mutex_lock_interruptible(dev);
> -       if (ret)
> -               goto err_rpm;
> -
> -       /* Access to snoopable pages through the GTT is incoherent. */
> -       if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev_priv)) {
> -               ret = -EFAULT;
> -               goto err_unlock;
> -       }
> -
>         /* Now pin it into the GTT as needed */
>         vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
>                                        PIN_MAPPABLE |
> @@ -1880,7 +1839,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
>         }
>         if (IS_ERR(vma)) {
>                 ret = PTR_ERR(vma);
> -               goto err_unlock;
> +               return ret;
>         }
>  
>         ret = i915_gem_object_set_to_gtt_domain(obj, write);
> @@ -1920,6 +1879,67 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
>         i915_vma_unpin_fence(vma);
>  err_unpin:
>         __i915_vma_unpin(vma);
> +
> +       return ret;
> +}
> +
> +/**
> + * i915_gem_fault - fault a page into the memory
> + * @vmf: fault info
> + *
> + * The fault handler is set up by drm_gem_mmap() when mmap_offset is called on
> + * an object from userspace. The missing pages are setup by an object's
> + * vmf_fill_pages pages handler, depending on it's backing storage.
> + */
> +vm_fault_t i915_gem_fault(struct vm_fault *vmf)
> +{
> +       struct vm_area_struct *area = vmf->vma;
> +       struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
> +       struct drm_device *dev = obj->base.dev;
> +       struct drm_i915_private *dev_priv = to_i915(dev);
> +       intel_wakeref_t wakeref;
> +       bool write = !!(vmf->flags & FAULT_FLAG_WRITE);
> +       pgoff_t page_offset;
> +       int ret;
> +
> +       /* Sanity check that we allow writing into this object */
> +       if (i915_gem_object_is_readonly(obj) && write)
> +               return VM_FAULT_SIGBUS;
> +
> +       /* We don't use vmf->pgoff since that has the fake offset */
> +       page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
> +
> +       trace_i915_gem_object_fault(obj, page_offset, true, write);
> +
> +       /* Try to flush the object off the GPU first without holding the lock.
> +        * Upon acquiring the lock, we will perform our sanity checks and then
> +        * repeat the flush holding the lock in the normal manner to catch cases
> +        * where we are gazumped.
> +        */
> +       ret = i915_gem_object_wait(obj,
> +                                  I915_WAIT_INTERRUPTIBLE,
> +                                  MAX_SCHEDULE_TIMEOUT);
> +       if (ret)
> +               goto err;
> +
> +       ret = i915_gem_object_pin_pages(obj);
> +       if (ret)
> +               goto err;
> +
> +       wakeref = intel_runtime_pm_get(dev_priv);
> +
> +       ret = i915_mutex_lock_interruptible(dev);
> +       if (ret)
> +               goto err_rpm;
> +
> +       /* Access to snoopable pages through the GTT is incoherent. */
> +       if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev_priv)) {
> +               ret = -EFAULT;
> +               goto err_unlock;
> +       }

That's a GGTT limitation, you'll probably have different variants for
other hw.

> +
> +       ret = __vmf_fill_pages_gtt(obj, vmf, page_offset);

Not yet seeing much point here instead of using different vm_ops for
different HW. 

> +
>  err_unlock:
>         mutex_unlock(&dev->struct_mutex);

Especially as any new HW is surely not falling for this trap.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 29/42] drm/i915: Set correct vmf source pages for gem objects
  2019-02-14 14:57 ` [RFC PATCH 29/42] drm/i915: Set correct vmf source pages for gem objects Matthew Auld
@ 2019-02-14 16:02   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:02 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:27)
> +int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
> +                                        struct vm_fault *vmf,
> +                                        pgoff_t page_offset)
> +{
> +       struct vm_area_struct *area = vmf->vma;
> +       struct drm_device *dev = obj->base.dev;
> +       struct drm_i915_private *dev_priv = to_i915(dev);
> +       struct page *page;
> +       unsigned long pfn;
> +       vm_fault_t vmf_ret;
> +       pgoff_t pg_off = (vmf->address - area->vm_start) >> PAGE_SHIFT;
> +
> +       if (HAS_MAPPABLE_APERTURE(dev_priv))
> +               return __vmf_fill_pages_gtt(obj, vmf, page_offset);
> +
> +       page = i915_gem_object_get_page(obj, pg_off);
> +       pfn = page_to_pfn(page);
> +
> +       vmf_ret = vmf_insert_mixed(area, vmf->address,
> +                                  __pfn_to_pfn_t(pfn, PFN_DEV));
> +       if (vmf_ret & VM_FAULT_ERROR)
> +               return vm_fault_to_errno(vmf_ret, 0);
> +
> +       if (!obj->userfault_count++)
> +               list_add(&obj->userfault_link, &dev_priv->mm.userfault_list);
> +
> +       GEM_BUG_ON(!obj->userfault_count);

What are you using the GGTT fence tracking for?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET
  2019-02-14 14:57 ` [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET Matthew Auld
@ 2019-02-14 16:05   ` Chris Wilson
  2019-02-26 13:34   ` Tvrtko Ursulin
  1 sibling, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:05 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:28)
> @@ -157,6 +163,10 @@ struct drm_i915_gem_object {
>         unsigned int userfault_count;
>         struct list_head userfault_link;
>  
> +       enum i915_cpu_mmap_origin_type mmap_origin;
> +       atomic_t mmap_count;
> +       u64 mmap_flags;

These flags must be per-mmap instance, userspace does try to keep
several different types of mmaps active.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 31/42] drm/i915: cpu-map based dumb buffers
  2019-02-14 14:57 ` [RFC PATCH 31/42] drm/i915: cpu-map based dumb buffers Matthew Auld
@ 2019-02-14 16:06   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:06 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:29)
> From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> 
> If there is no aperture we can't use map_gtt to map dumb buffers, so we
> need a cpu-map based path to do it. We prefer map_gtt on platforms that
> do have aperture.

This is very hard as a standalone patch to see if you the semantics for
dumb buffers correct. Is is coherent for starters?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM
  2019-02-14 14:57 ` [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM Matthew Auld
@ 2019-02-14 16:13   ` Chris Wilson
  2019-02-18 12:44     ` Chris Wilson
  2019-02-19 17:44     ` Chris Wilson
  2019-02-14 16:22   ` Chris Wilson
  1 sibling, 2 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:13 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:40)
> Hack patch to default all userspace allocations to LMEM. Useful for
> testing purposes.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem.c | 45 +++++++++++++++++++++++++++++++--
>  1 file changed, 43 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 3c86909d55b9..bd857f477ef9 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -641,7 +641,8 @@ i915_gem_create(struct drm_file *file,
>                 u32 *handle_p)
>  {
>         struct drm_i915_gem_object *obj;
> -       int ret;
> +       intel_wakeref_t wakeref;
> +       int ret = 0;
>         u32 handle;
>  
>         size = roundup(size, PAGE_SIZE);
> @@ -649,10 +650,50 @@ i915_gem_create(struct drm_file *file,
>                 return -EINVAL;
>  
>         /* Allocate the new object */
> -       obj = i915_gem_object_create(dev_priv, size);
> +       if (HAS_LMEM(dev_priv))
> +               obj = i915_gem_object_create_lmem(dev_priv, size, 0);
> +       else
> +               obj = i915_gem_object_create(dev_priv, size);
>         if (IS_ERR(obj))
>                 return PTR_ERR(obj);
>  
> +       if (i915_gem_object_is_lmem(obj)) {
> +               struct i915_gem_context *ctx;
> +
> +               /* XXX: we should prob use the blitter context for this? */

Or the kernel_context which is setup for emitting without taking
struct_mutex...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 35/42] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION
  2019-02-14 14:57 ` [RFC PATCH 35/42] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION Matthew Auld
@ 2019-02-14 16:20   ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:20 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:33)
> From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> 
> This call will specify which memory region an object should be placed.
> 
> Note that changing the object's backing storage should be immediately
> done after an object is created or if it's not yet in use, otherwise
> this will fail on a busy object.

We already have a generic object SETPARAM, GETPARAM. The idea was to
extend CONTEXT_SETPARAM/GETPARAM into OBJECT_SETPARAM/GETPARAM by
splitting u64 parameter into (u32 object_class, u32 parameter).
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM
  2019-02-14 14:57 ` [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM Matthew Auld
  2019-02-14 16:13   ` Chris Wilson
@ 2019-02-14 16:22   ` Chris Wilson
  1 sibling, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:22 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:40)
> Hack patch to default all userspace allocations to LMEM. Useful for
> testing purposes.

One caveat to note is that userspace assumes objects start idle in
.write=CPU. That assumption may very well be put to the test, and go
unnoticed for quite a while...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI
  2019-02-14 14:57 ` [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI Matthew Auld
@ 2019-02-14 16:31   ` Chris Wilson
  2019-02-14 16:33     ` Chris Wilson
  2019-02-14 21:15   ` Chris Wilson
  1 sibling, 1 reply; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:31 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:32)
>  int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 26d2274b5d2b..5a102a5cb415 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1744,6 +1744,7 @@ struct drm_i915_perf_oa_config {
>  struct drm_i915_query_item {
>         __u64 query_id;
>  #define DRM_I915_QUERY_TOPOLOGY_INFO    1
> +#define DRM_I915_QUERY_MEMREGION_INFO   3

Ahem.

>         /*
>          * When set to zero by userspace, this is filled with the size of the
> @@ -1832,7 +1833,6 @@ struct drm_i915_query_topology_info {
>          * Offset in data[] at which the EU masks are stored.
>          */
>         __u16 eu_offset;
> -
>         /*
>          * Stride at which each of the EU masks for each subslice are stored.
>          */
> @@ -1841,6 +1841,44 @@ struct drm_i915_query_topology_info {
>         __u8 data[];
>  };
>  
> +struct drm_i915_memory_region_info {
> +
> +       /** Base type of a region
> +        */
> +#define I915_SYSTEM_MEMORY         0
> +#define I915_DEVICE_MEMORY         1
> +
> +       /** The region id is encoded in a layout which makes it possible to
> +        *  retrieve the following information:
> +        *
> +        *  Base type: log2(ID >> 16)
> +        *  Instance:  log2(ID & 0xffff)
> +        */
> +       __u32 id;
> +
> +       /** Reserved field. MBZ */
> +       __u32 rsvd0;
> +
> +       /** Unused for now. MBZ */
> +       __u64 flags;
> +
> +       __u64 size;
> +
> +       /** Reserved fields must be cleared to zero. */
> +       __u64 rsvd1[4];
> +};

If you were to apply this to stolen memory as an example, can you spot
how much information is missing?

Userspace would need to know total size, largest allocation chunk (i.e
largest object), rough estimate of availability, and most importantly a
list of API that is not allowed (such as CPU mmap, fencing). There's
without a doubt more that would be needed to actually wire it up to Vk.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI
  2019-02-14 16:31   ` Chris Wilson
@ 2019-02-14 16:33     ` Chris Wilson
  2019-02-14 21:12       ` Chris Wilson
  0 siblings, 1 reply; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 16:33 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Chris Wilson (2019-02-14 16:31:13)
> Quoting Matthew Auld (2019-02-14 14:57:32)
> >  int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
> > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > index 26d2274b5d2b..5a102a5cb415 100644
> > --- a/include/uapi/drm/i915_drm.h
> > +++ b/include/uapi/drm/i915_drm.h
> > @@ -1744,6 +1744,7 @@ struct drm_i915_perf_oa_config {
> >  struct drm_i915_query_item {
> >         __u64 query_id;
> >  #define DRM_I915_QUERY_TOPOLOGY_INFO    1
> > +#define DRM_I915_QUERY_MEMREGION_INFO   3
> 
> Ahem.
> 
> >         /*
> >          * When set to zero by userspace, this is filled with the size of the
> > @@ -1832,7 +1833,6 @@ struct drm_i915_query_topology_info {
> >          * Offset in data[] at which the EU masks are stored.
> >          */
> >         __u16 eu_offset;
> > -
> >         /*
> >          * Stride at which each of the EU masks for each subslice are stored.
> >          */
> > @@ -1841,6 +1841,44 @@ struct drm_i915_query_topology_info {
> >         __u8 data[];
> >  };
> >  
> > +struct drm_i915_memory_region_info {
> > +
> > +       /** Base type of a region
> > +        */
> > +#define I915_SYSTEM_MEMORY         0
> > +#define I915_DEVICE_MEMORY         1
> > +
> > +       /** The region id is encoded in a layout which makes it possible to
> > +        *  retrieve the following information:
> > +        *
> > +        *  Base type: log2(ID >> 16)
> > +        *  Instance:  log2(ID & 0xffff)
> > +        */
> > +       __u32 id;
> > +
> > +       /** Reserved field. MBZ */
> > +       __u32 rsvd0;
> > +
> > +       /** Unused for now. MBZ */
> > +       __u64 flags;
> > +
> > +       __u64 size;
> > +
> > +       /** Reserved fields must be cleared to zero. */
> > +       __u64 rsvd1[4];
> > +};
> 
> If you were to apply this to stolen memory as an example, can you spot
> how much information is missing?
> 
> Userspace would need to know total size, largest allocation chunk (i.e
> largest object), rough estimate of availability, and most importantly a
> list of API that is not allowed (such as CPU mmap, fencing). There's
> without a doubt more that would be needed to actually wire it up to Vk.

Cross-process/ppgtt and cross-device sharing for example...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for Introduce memory region concept (including device local memory)
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (41 preceding siblings ...)
  2019-02-14 14:57 ` [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM Matthew Auld
@ 2019-02-14 17:58 ` Patchwork
  2019-02-14 18:15 ` ✗ Fi.CI.SPARSE: " Patchwork
  2019-02-15  0:47 ` [RFC PATCH 00/42] " Dave Airlie
  44 siblings, 0 replies; 97+ messages in thread
From: Patchwork @ 2019-02-14 17:58 UTC (permalink / raw)
  To: intel-gfx

== Series Details ==

Series: Introduce memory region concept (including device local memory)
URL   : https://patchwork.freedesktop.org/series/56683/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
3a398101dfda drm/i915: support 1G pages for the 48b PPGTT
e99e4b7bc632 drm/i915: enable platform support for 1G pages
ee6706cbf465 drm/i915: buddy allocator
-:25: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#25: 
new file mode 100644

-:30: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#30: FILE: drivers/gpu/drm/i915/i915_gem_buddy.c:1:
+/*

-:242: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#242: FILE: drivers/gpu/drm/i915/i915_gem_buddy.h:1:
+/*

-:336: ERROR:CODE_INDENT: code indent should use tabs where possible
#336: FILE: drivers/gpu/drm/i915/i915_gem_buddy.h:95:
+^I^I          struct i915_gem_buddy_block *block)$

-:336: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#336: FILE: drivers/gpu/drm/i915/i915_gem_buddy.h:95:
+i915_gem_buddy_block_size(struct i915_gem_buddy_mm *mm,
+		          struct i915_gem_buddy_block *block)

-:366: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#366: FILE: drivers/gpu/drm/i915/selftests/i915_gem_buddy.c:1:
+/*

-:511: ERROR:CODE_INDENT: code indent should use tabs where possible
#511: FILE: drivers/gpu/drm/i915/selftests/i915_gem_buddy.c:146:
+^I^I^I^I^I        order);$

-:533: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#533: FILE: drivers/gpu/drm/i915/selftests/i915_gem_buddy.c:168:
+				pr_err("buddy_alloc offset misaligned, offset=%llx, block_size=%llu\n",
+					offset, block_size);

total: 2 errors, 4 warnings, 2 checks, 544 lines checked
f88fcf2002da drm/i915: introduce intel_memory_region
-:68: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#68: 
new file mode 100644

-:73: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#73: FILE: drivers/gpu/drm/i915/intel_memory_region.c:1:
+/*

-:104: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#104: FILE: drivers/gpu/drm/i915/intel_memory_region.c:32:
+{
+

-:311: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#311: FILE: drivers/gpu/drm/i915/intel_memory_region.h:1:
+/*

-:362: WARNING:TYPO_SPELLING: 'UKNOWN' may be misspelled - perhaps 'UNKNOWN'?
#362: FILE: drivers/gpu/drm/i915/intel_memory_region.h:52:
+	INTEL_MEMORY_UKNOWN, /* Should be last */

-:371: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'r' may be better as '(r)' to avoid precedence issues
#371: FILE: drivers/gpu/drm/i915/intel_memory_region.h:61:
+#define MEMORY_TYPE_FROM_REGION(r) (ilog2(r >> INTEL_MEMORY_TYPE_SHIFT))

-:372: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'r' may be better as '(r)' to avoid precedence issues
#372: FILE: drivers/gpu/drm/i915/intel_memory_region.h:62:
+#define MEMORY_INSTANCE_FROM_REGION(r) (ilog2(r & 0xffff))

-:386: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct intel_memory_region *' should also have an identifier name
#386: FILE: drivers/gpu/drm/i915/intel_memory_region.h:76:
+	int (*init)(struct intel_memory_region *);

-:387: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct intel_memory_region *' should also have an identifier name
#387: FILE: drivers/gpu/drm/i915/intel_memory_region.h:77:
+	void (*release)(struct intel_memory_region *);

-:389: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct intel_memory_region *' should also have an identifier name
#389: FILE: drivers/gpu/drm/i915/intel_memory_region.h:79:
+	struct drm_i915_gem_object *

-:389: WARNING:FUNCTION_ARGUMENTS: function definition argument 'resource_size_t' should also have an identifier name
#389: FILE: drivers/gpu/drm/i915/intel_memory_region.h:79:
+	struct drm_i915_gem_object *

-:389: WARNING:FUNCTION_ARGUMENTS: function definition argument 'unsigned int' should also have an identifier name
#389: FILE: drivers/gpu/drm/i915/intel_memory_region.h:79:
+	struct drm_i915_gem_object *

-:404: CHECK:UNCOMMENTED_DEFINITION: struct mutex definition without comment
#404: FILE: drivers/gpu/drm/i915/intel_memory_region.h:94:
+	struct mutex mm_lock;

-:445: CHECK:LINE_SPACING: Please don't use multiple blank lines
#445: FILE: drivers/gpu/drm/i915/selftests/huge_pages.c:461:
 
+

-:475: ERROR:CODE_INDENT: code indent should use tabs where possible
#475: FILE: drivers/gpu/drm/i915/selftests/huge_pages.c:491:
+^I^I        &obj->memory_region->region.start);$

-:551: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#551: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:1:
+/*

-:634: WARNING:EMBEDDED_FUNCTION_NAME: Prefer using '"%s...", __func__' to using 'igt_mock_fill', this function's name, in a string
#634: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:84:
+			pr_err("igt_mock_fill failed, space still left in region\n");

-:697: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#697: FILE: drivers/gpu/drm/i915/selftests/mock_region.c:1:
+/*

-:774: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#774: FILE: drivers/gpu/drm/i915/selftests/mock_region.h:1:
+/*

total: 1 errors, 13 warnings, 5 checks, 730 lines checked
16282e810aa7 drm/i915/region: support basic eviction
eeac2ad5efed drm/i915/region: support continuous allocations
-:21: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#21: FILE: drivers/gpu/drm/i915/i915_gem_object.h:166:
+#define I915_BO_ALLOC_CONTIGUOUS (1<<1)
                                    ^

total: 0 errors, 0 warnings, 1 checks, 236 lines checked
c67d248a5ac8 drm/i915/region: support volatile objects
-:22: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#22: FILE: drivers/gpu/drm/i915/i915_gem_object.h:167:
+#define I915_BO_ALLOC_VOLATILE   (1<<2)
                                    ^

total: 0 errors, 0 warnings, 1 checks, 97 lines checked
161412751175 drm/i915: Add memory region information to device_info
534b79d42ca1 drm/i915: support creating LMEM objects
-:66: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#66: 
new file mode 100644

-:71: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#71: FILE: drivers/gpu/drm/i915/intel_region_lmem.c:1:
+/*

-:159: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#159: FILE: drivers/gpu/drm/i915/intel_region_lmem.h:1:
+/*

total: 0 errors, 3 warnings, 0 checks, 231 lines checked
e743041ee4d0 drm/i915/lmem: add helper to get CPU visible pfn
-:7: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

total: 0 errors, 1 warnings, 0 checks, 26 lines checked
10c8ccf90cfa drm/i915/selftests: exercise writes to LMEM
-:164: CHECK:SPACING: No space is necessary after a cast
#164: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:507:
+		base = (void __force *) io_mapping_map_atomic_wc(&obj->memory_region->iomap,

-:165: WARNING:LONG_LINE: line over 100 characters
#165: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:508:
+								 i915_gem_object_get_dma_address(obj, n));

total: 0 errors, 1 warnings, 1 checks, 243 lines checked
8be573b5def8 drm/i915/selftests: exercise huge-pages for LMEM
-:48: WARNING:LONG_LINE: line over 100 characters
#48: FILE: drivers/gpu/drm/i915/selftests/huge_pages.c:1148:
+								i915_gem_object_get_dma_address(obj, n));

total: 0 errors, 1 warnings, 0 checks, 145 lines checked
9cde284aeb6b drm/i915: support object clearing via blitter engine
-:197: WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#197: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:178:
+#define XY_COLOR_BLT_CMD              ^I(2<<29 | 0x50<<22 | (7-2))$

-:197: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#197: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:178:
+#define XY_COLOR_BLT_CMD              	(2<<29 | 0x50<<22 | (7-2))
                                       	  ^

-:197: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#197: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:178:
+#define XY_COLOR_BLT_CMD              	(2<<29 | 0x50<<22 | (7-2))
                                       	             ^

-:197: CHECK:SPACING: spaces preferred around that '-' (ctx:VxV)
#197: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:178:
+#define XY_COLOR_BLT_CMD              	(2<<29 | 0x50<<22 | (7-2))
                                       	                      ^

-:216: WARNING:LINE_SPACING: Missing a blank line after declarations
#216: FILE: drivers/gpu/drm/i915/selftests/i915_gem_object.c:638:
+	struct rnd_state prng;
+	IGT_TIMEOUT(end);

total: 0 errors, 2 warnings, 3 checks, 254 lines checked
1228281fd8b2 drm/i915: introduce kernel blitter_context
9e466d7c9453 drm/i915: support copying objects via blitter engine
-:181: ERROR:SPACING: spaces required around that ':' (ctx:VxW)
#181: FILE: drivers/gpu/drm/i915/i915_gem.c:4437:
+	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->vm: &i915->ggtt.vm;
 	                                                            ^

-:233: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#233: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:181:
+#define GEN8_XY_SRC_COPY_BLT_CMD	((2<<29)|(0x53<<22)|8)
                                 	   ^

-:233: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#233: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:181:
+#define GEN8_XY_SRC_COPY_BLT_CMD	((2<<29)|(0x53<<22)|8)
                                 	        ^

-:233: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#233: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:181:
+#define GEN8_XY_SRC_COPY_BLT_CMD	((2<<29)|(0x53<<22)|8)
                                 	              ^

-:233: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#233: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:181:
+#define GEN8_XY_SRC_COPY_BLT_CMD	((2<<29)|(0x53<<22)|8)
                                 	                   ^

-:234: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#234: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:182:
+#define GEN9_XY_FAST_COPY_BLT_CMD	((2<<29)|(0x42<<22)|8)
                                  	   ^

-:234: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#234: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:182:
+#define GEN9_XY_FAST_COPY_BLT_CMD	((2<<29)|(0x42<<22)|8)
                                  	        ^

-:234: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#234: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:182:
+#define GEN9_XY_FAST_COPY_BLT_CMD	((2<<29)|(0x42<<22)|8)
                                  	              ^

-:234: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#234: FILE: drivers/gpu/drm/i915/intel_gpu_commands.h:182:
+#define GEN9_XY_FAST_COPY_BLT_CMD	((2<<29)|(0x42<<22)|8)
                                  	                   ^

total: 1 errors, 0 warnings, 8 checks, 302 lines checked
86d8e7614411 drm/i915: support basic object migration
-:84: WARNING:TYPO_SPELLING: 'UKNOWN' may be misspelled - perhaps 'UNKNOWN'?
#84: FILE: drivers/gpu/drm/i915/i915_gem.c:4674:
+	GEM_BUG_ON(id >= INTEL_MEMORY_UKNOWN);

total: 0 errors, 1 warnings, 0 checks, 284 lines checked
30dae501f5a2 drm/i915/lmem: support kernel mapping
-:246: ERROR:CODE_INDENT: code indent should use tabs where possible
#246: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:688:
+        if (read_val != val) {$

-:246: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#246: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:688:
+        if (read_val != val) {$

-:295: WARNING:MEMORY_BARRIER: memory barrier without comment
#295: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:737:
+		wmb();

total: 1 errors, 2 warnings, 0 checks, 271 lines checked
f68e82eb67b5 drm/i915/lmem: support CPU relocations
-:22: WARNING:BOOL_BITFIELD: Avoid using bool as bitfield.  Prefer bool bitfields as unsigned int or u<8|16|32>
#22: FILE: drivers/gpu/drm/i915/i915_gem_execbuffer.c:268:
+		bool is_lmem : 1;

-:81: CHECK:SPACING: No space is necessary after a cast
#81: FILE: drivers/gpu/drm/i915/i915_gem_execbuffer.c:1098:
+		io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));

total: 0 errors, 1 warnings, 1 checks, 98 lines checked
c3e5e28bbbb0 drm/i915: add vfunc for pread
-:7: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

-:35: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct drm_i915_gem_object *' should also have an identifier name
#35: FILE: drivers/gpu/drm/i915/i915_gem_object.h:78:
+	int (*pread)(struct drm_i915_gem_object *,

-:35: WARNING:FUNCTION_ARGUMENTS: function definition argument 'const struct drm_i915_gem_pread *' should also have an identifier name
#35: FILE: drivers/gpu/drm/i915/i915_gem_object.h:78:
+	int (*pread)(struct drm_i915_gem_object *,

total: 0 errors, 3 warnings, 0 checks, 20 lines checked
2960c64a642d drm/i915/lmem: support pread
ed1b910c70d0 drm/i915/lmem: support pwrite
-:70: ERROR:POINTER_LOCATION: "(foo*)" should be "(foo *)"
#70: FILE: drivers/gpu/drm/i915/intel_region_lmem.c:151:
+		unwritten = copy_from_user((void __force*)vaddr + offset,

total: 1 errors, 0 warnings, 0 checks, 84 lines checked
ef4e64371f33 drm/i915: define HAS_MAPPABLE_APERTURE
-:20: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'dev_priv' may be better as '(dev_priv)' to avoid precedence issues
#20: FILE: drivers/gpu/drm/i915/i915_drv.h:2484:
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)

total: 0 errors, 0 warnings, 1 checks, 8 lines checked
229c95e955dc drm/i915: do not map aperture if it is not available.
-:40: CHECK:SPACING: No space is necessary after a cast
#40: FILE: drivers/gpu/drm/i915/i915_gem_gtt.c:3222:
+			(struct resource) DEFINE_RES_MEM(pci_resource_start(pdev, 2),

total: 0 errors, 0 warnings, 1 checks, 53 lines checked
09acc5004c77 drm/i915: expose missing map_gtt support to users
1b4f93df4ea9 drm/i915: set num_fence_regs to 0 if there is no aperture
d5778ede25c7 drm/i915: error capture with no ggtt slot
-:172: WARNING:LINE_SPACING: Missing a blank line after declarations
#172: FILE: drivers/gpu/drm/i915/i915_gpu_error.c:1821:
+		const u64 slot = ggtt->error_capture.start;
+		ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);

total: 0 errors, 1 warnings, 0 checks, 148 lines checked
3fce44863dc2 drm/i915: Don't try to place HWS in non-existing mappable region
ef85f5c27c7e drm/i915: Split out GTT fault handler to make it generic
74497cf26f72 drm/i915: Set correct vmf source pages for gem objects
-:99: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#99: FILE: drivers/gpu/drm/i915/i915_gem.c:4220:
+int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
+					 struct vm_fault *vmf,

-:117: ERROR:CODE_INDENT: code indent should use tabs where possible
#117: FILE: drivers/gpu/drm/i915/i915_gem.c:4238:
+                                  __pfn_to_pfn_t(pfn, PFN_DEV));$

-:117: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#117: FILE: drivers/gpu/drm/i915/i915_gem.c:4238:
+	vmf_ret = vmf_insert_mixed(area, vmf->address,
+                                  __pfn_to_pfn_t(pfn, PFN_DEV));

-:117: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#117: FILE: drivers/gpu/drm/i915/i915_gem.c:4238:
+                                  __pfn_to_pfn_t(pfn, PFN_DEV));$

-:144: CHECK:LINE_SPACING: Please don't use multiple blank lines
#144: FILE: drivers/gpu/drm/i915/i915_gem.c:4875:
 
+

-:157: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct drm_i915_gem_object *' should also have an identifier name
#157: FILE: drivers/gpu/drm/i915/i915_gem_object.h:85:
+	int (*vmf_fill_pages)(struct drm_i915_gem_object *, struct vm_fault *,

-:157: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct vm_fault *' should also have an identifier name
#157: FILE: drivers/gpu/drm/i915/i915_gem_object.h:85:
+	int (*vmf_fill_pages)(struct drm_i915_gem_object *, struct vm_fault *,

-:157: WARNING:FUNCTION_ARGUMENTS: function definition argument 'pgoff_t' should also have an identifier name
#157: FILE: drivers/gpu/drm/i915/i915_gem_object.h:85:
+	int (*vmf_fill_pages)(struct drm_i915_gem_object *, struct vm_fault *,

total: 1 errors, 4 warnings, 3 checks, 170 lines checked
740855ce4e91 drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET
-:96: ERROR:CODE_INDENT: code indent should use tabs where possible
#96: FILE: drivers/gpu/drm/i915/i915_gem.c:2142:
+^I        /* Re-map object with existing different map-type */$

-:158: ERROR:CODE_INDENT: code indent should use tabs where possible
#158: FILE: drivers/gpu/drm/i915/i915_gem.c:2213:
+        return __assign_gem_object_mmap_data(file, args->handle,$

-:158: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#158: FILE: drivers/gpu/drm/i915/i915_gem.c:2213:
+        return __assign_gem_object_mmap_data(file, args->handle,$

-:246: WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#246: FILE: include/uapi/drm/i915_drm.h:322:
+#define DRM_I915_GEM_MMAP_OFFSET   ^IDRM_I915_GEM_MMAP_GTT$

-:254: WARNING:LONG_LINE: line over 100 characters
#254: FILE: include/uapi/drm/i915_drm.h:381:
+#define DRM_IOCTL_I915_GEM_MMAP_OFFSET		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_OFFSET, struct drm_i915_gem_mmap_offset)

total: 2 errors, 3 warnings, 0 checks, 247 lines checked
11a7f845d866 drm/i915: cpu-map based dumb buffers
-:38: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#38: FILE: drivers/gpu/drm/i915/i915_drv.h:3034:
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
 		      u32 handle, u64 *offset);

-:51: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#51: FILE: drivers/gpu/drm/i915/i915_gem.c:2161:
+i915_gem_mmap_dumb(struct drm_file *file,
 		  struct drm_device *dev,

total: 0 errors, 0 warnings, 2 checks, 41 lines checked
ab19cda1cb91 drm/i915: Add fill_pages handler for dma_buf imported objects
469de78b2f36 UPSTREAM: drm/i915/query: Split out query item checks
-:19: ERROR:POINTER_LOCATION: "foo* bar" should be "foo *bar"
#19: FILE: drivers/gpu/drm/i915/i915_query.c:13:
+static int init_query_item_check(void* data_ptr, size_t data_sz,

total: 1 errors, 0 warnings, 0 checks, 61 lines checked
98f3c6f1237a drm/i915/query: Expose memory regions through the query uAPI
-:108: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#108: FILE: include/uapi/drm/i915_drm.h:1845:
+struct drm_i915_memory_region_info {
+

-:135: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#135: FILE: include/uapi/drm/i915_drm.h:1872:
+struct drm_i915_query_memory_region_info {
+

total: 0 errors, 0 warnings, 2 checks, 124 lines checked
0a4924fd6d3c drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION
-:24: WARNING:LONG_LINE: line over 100 characters
#24: FILE: drivers/gpu/drm/i915/i915_drv.c:3019:
+	DRM_IOCTL_DEF_DRV(I915_GEM_OBJECT_SETPARAM, i915_gem_object_setparam_ioctl, DRM_RENDER_ALLOW),

-:59: WARNING:TYPO_SPELLING: 'UKNOWN' may be misspelled - perhaps 'UNKNOWN'?
#59: FILE: drivers/gpu/drm/i915/i915_gem.c:2270:
+	return INTEL_MEMORY_UKNOWN;

-:75: ERROR:CODE_INDENT: code indent should use tabs where possible
#75: FILE: drivers/gpu/drm/i915/i915_gem.c:2286:
+^I        return -ENOENT;$

-:81: ERROR:CODE_INDENT: code indent should use tabs where possible
#81: FILE: drivers/gpu/drm/i915/i915_gem.c:2292:
+^I        goto err;$

-:96: WARNING:TYPO_SPELLING: 'UKNOWN' may be misspelled - perhaps 'UNKNOWN'?
#96: FILE: drivers/gpu/drm/i915/i915_gem.c:2307:
+		if (id == INTEL_MEMORY_UKNOWN) {

-:131: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#131: FILE: drivers/gpu/drm/i915/i915_gem.c:2342:
+{
+

-:1

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* ✗ Fi.CI.SPARSE: warning for Introduce memory region concept (including device local memory)
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (42 preceding siblings ...)
  2019-02-14 17:58 ` ✗ Fi.CI.CHECKPATCH: warning for Introduce memory region concept (including device local memory) Patchwork
@ 2019-02-14 18:15 ` Patchwork
  2019-02-15  0:47 ` [RFC PATCH 00/42] " Dave Airlie
  44 siblings, 0 replies; 97+ messages in thread
From: Patchwork @ 2019-02-14 18:15 UTC (permalink / raw)
  To: intel-gfx

== Series Details ==

Series: Introduce memory region concept (including device local memory)
URL   : https://patchwork.freedesktop.org/series/56683/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: support 1G pages for the 48b PPGTT
Okay!

Commit: drm/i915: enable platform support for 1G pages
Okay!

Commit: drm/i915: buddy allocator
+./include/linux/slab.h:664:13: error: undefined identifier '__builtin_mul_overflow'
+./include/linux/slab.h:664:13: warning: call with no type!

Commit: drm/i915: introduce intel_memory_region
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3566:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3567:16: warning: expression using sizeof(void)
+./include/uapi/linux/perf_event.h:147:56: warning: cast truncates bits from constant value (8000000000000000 becomes 0)

Commit: drm/i915/region: support basic eviction
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3567:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3569:16: warning: expression using sizeof(void)

Commit: drm/i915/region: support continuous allocations
Okay!

Commit: drm/i915/region: support volatile objects
Okay!

Commit: drm/i915: Add memory region information to device_info
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3569:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3571:16: warning: expression using sizeof(void)

Commit: drm/i915: support creating LMEM objects
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3571:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3576:16: warning: expression using sizeof(void)
+./include/uapi/linux/perf_event.h:147:56: warning: cast truncates bits from constant value (8000000000000000 becomes 0)

Commit: drm/i915/lmem: add helper to get CPU visible pfn
Okay!

Commit: drm/i915/selftests: exercise writes to LMEM
+drivers/gpu/drm/i915/selftests/intel_memory_region.c:507:22:    expected unsigned int [noderef] [usertype] <asn:2>*base
+drivers/gpu/drm/i915/selftests/intel_memory_region.c:507:22:    got void *<noident>
+drivers/gpu/drm/i915/selftests/intel_memory_region.c:507:22: warning: incorrect type in assignment (different address spaces)

Commit: drm/i915/selftests: exercise huge-pages for LMEM
+drivers/gpu/drm/i915/selftests/huge_pages.c:1147:22:    expected unsigned int [noderef] [usertype] <asn:2>*base
+drivers/gpu/drm/i915/selftests/huge_pages.c:1147:22:    got void *<noident>
+drivers/gpu/drm/i915/selftests/huge_pages.c:1147:22: warning: incorrect type in assignment (different address spaces)

Commit: drm/i915: support object clearing via blitter engine
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3576:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3578:16: warning: expression using sizeof(void)

Commit: drm/i915: introduce kernel blitter_context
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3578:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3580:16: warning: expression using sizeof(void)

Commit: drm/i915: support copying objects via blitter engine
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3580:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3583:16: warning: expression using sizeof(void)

Commit: drm/i915: support basic object migration
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3583:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3588:16: warning: expression using sizeof(void)

Commit: drm/i915/lmem: support kernel mapping
+drivers/gpu/drm/i915/i915_gem.c:2261:42:    expected void [noderef] <asn:2>*vaddr
+drivers/gpu/drm/i915/i915_gem.c:2261:42:    got void *[assigned] ptr
+drivers/gpu/drm/i915/i915_gem.c:2261:42: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/i915/i915_gem.c:2645:51:    expected void *
+drivers/gpu/drm/i915/i915_gem.c:2645:51:    got void [noderef] <asn:2>*
+drivers/gpu/drm/i915/i915_gem.c:2645:51: warning: incorrect type in return expression (different address spaces)
+drivers/gpu/drm/i915/i915_gem.c:2727:42:    expected void [noderef] <asn:2>*vaddr
+drivers/gpu/drm/i915/i915_gem.c:2727:42:    got void *[assigned] ptr
+drivers/gpu/drm/i915/i915_gem.c:2727:42: warning: incorrect type in argument 1 (different address spaces)
-O:drivers/gpu/drm/i915/selftests/huge_pages.c:1147:22:    expected unsigned int [noderef] [usertype] <asn:2>*base
-O:drivers/gpu/drm/i915/selftests/huge_pages.c:1147:22:    got void *<noident>
-O:drivers/gpu/drm/i915/selftests/huge_pages.c:1147:22: warning: incorrect type in assignment (different address spaces)
-O:drivers/gpu/drm/i915/selftests/intel_memory_region.c:507:22:    expected unsigned int [noderef] [usertype] <asn:2>*base
-O:drivers/gpu/drm/i915/selftests/intel_memory_region.c:507:22:    got void *<noident>
-O:drivers/gpu/drm/i915/selftests/intel_memory_region.c:507:22: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/selftests/intel_memory_region.c:716:15:    expected unsigned int [noderef] [usertype] <asn:2>*vaddr
+drivers/gpu/drm/i915/selftests/intel_memory_region.c:716:15:    got void *
+drivers/gpu/drm/i915/selftests/intel_memory_region.c:716:15: warning: incorrect type in assignment (different address spaces)

Commit: drm/i915/lmem: support CPU relocations
+drivers/gpu/drm/i915/i915_gem_execbuffer.c:1112:15:    expected void *vaddr
+drivers/gpu/drm/i915/i915_gem_execbuffer.c:1112:15:    got void [noderef] <asn:2>*
+drivers/gpu/drm/i915/i915_gem_execbuffer.c:1112:15: warning: incorrect type in assignment (different address spaces)

Commit: drm/i915: add vfunc for pread
Okay!

Commit: drm/i915/lmem: support pread
Okay!

Commit: drm/i915/lmem: support pwrite
Okay!

Commit: drm/i915: define HAS_MAPPABLE_APERTURE
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3588:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3590:16: warning: expression using sizeof(void)

Commit: drm/i915: do not map aperture if it is not available.
Okay!

Commit: drm/i915: expose missing map_gtt support to users
Okay!

Commit: drm/i915: set num_fence_regs to 0 if there is no aperture
Okay!

Commit: drm/i915: error capture with no ggtt slot
+drivers/gpu/drm/i915/i915_gpu_error.c:1063:27:    expected void *s
+drivers/gpu/drm/i915/i915_gpu_error.c:1063:27:    got void [noderef] <asn:2>*
+drivers/gpu/drm/i915/i915_gpu_error.c:1063:27: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/i915_gpu_error.c:1065:49:    expected void [noderef] <asn:2>*vaddr
+drivers/gpu/drm/i915/i915_gpu_error.c:1065:49:    got void *s
+drivers/gpu/drm/i915/i915_gpu_error.c:1065:49: warning: incorrect type in argument 1 (different address spaces)

Commit: drm/i915: Don't try to place HWS in non-existing mappable region
Okay!

Commit: drm/i915: Split out GTT fault handler to make it generic
Okay!

Commit: drm/i915: Set correct vmf source pages for gem objects
+          ^~
+                           ^~~~~~~~~~~~~~~~~~~~~~~
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:757:9:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:758:45:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:758:45:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:758:45: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/mmio.c:282:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/mmio.c:283:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:196:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_drv.h:3591:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_drv.h:3591:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_drv.h:3591:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_drv.h:3591:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_drv.h:3591:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_drv.h:3591:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/i915_gem.c:2182:10: error: ‘struct drm_i915_gem_object’ has no member named ‘mmap_origin’
+drivers/gpu/drm/i915/i915_gem.c:2182:24: error: no member 'mmap_origin' in struct drm_i915_gem_object
+drivers/gpu/drm/i915/i915_gem.c:2182:24: warning: unknown expression (8 46)
+drivers/gpu/drm/i915/i915_gem.c:2182:27: error: ‘I915_MMAP_ORIGIN_OFFSET’ undeclared (first use in this function); did you mean ‘DUMP_PREFIX_OFFSET’?
+drivers/gpu/drm/i915/i915_gem.c:2182:27: note: each undeclared identifier is reported only once for each function it appears in
+drivers/gpu/drm/i915/i915_gem.c: In function ‘i915_gem_mmap’:
-drivers/gpu/drm/i915/i915_gpu_error.c:1023:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_gpu_error.c:1023:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_gpu_error.c:1063:27:    expected void *s
-drivers/gpu/drm/i915/i915_gpu_error.c:1063:27:    got void [noderef] <asn:2>*
-drivers/gpu/drm/i915/i915_gpu_error.c:1063:27: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/i915_gpu_error.c:1065:49:    expected void [noderef] <asn:2>*vaddr
-drivers/gpu/drm/i915/i915_gpu_error.c:1065:49:    got void *s
-drivers/gpu/drm/i915/i915_gpu_error.c:1065:49: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/i915_gpu_error.c:924:23: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_gpu_error.c:924:23: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_perf.c:1422:15: warning: memset with byte count of 16777216
-drivers/gpu/drm/i915/i915_perf.c:1480:15: warning: memset with byte count of 16777216
-drivers/gpu/drm/i915/icl_dsi.c:129:33: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_ddi.c:652:24: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_ddi.c:654:24: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp_aux_backlight.c:157:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp_aux_backlight.c:157:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp_aux_backlight.c:157:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp_aux_backlight.c:157:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp_aux_backlight.c:157:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp_aux_backlight.c:157:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp_aux_backlight.c:157:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1405:39: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1775:23: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1775:23: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1928:23: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1948:25: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1948:25: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1970:58: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:1970:58: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:230:16: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:275:30: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:275:30: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:368:28: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:368:28: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:4317:26: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:4317:26: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:4360:27: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:4360:27: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:5778:30: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6163:31: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6192:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6192:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6192:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6192:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6193:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6193:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6193:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6193:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6194:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6194:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6194:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6194:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6195:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6195:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6195:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6195:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6196:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6196:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6196:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dp.c:6196:9: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:574:25: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:574:25: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:575:26: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:575:26: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:710:26: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:710:26: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:752:25: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:752:25: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:784:37: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_dsi_vbt.c:784:37: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_fbdev.c:342:30: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_hdmi.c:1503:34: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_hdmi.c:1503:34: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_hdmi.c:1520:42: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_hdmi.c:1520:42: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_hdmi.c:1524:42: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_hdmi.c:1524:42: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_hdmi.c:1527:42: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_i2c.c:442:31: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_i2c.c:444:31: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_i2c.c:444:31: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_i2c.c:506:23: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_i2c.c:506:23: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1485:15: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1485:15: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1485:15: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1485:15: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1485:15: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1485:15: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1485:15: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1534:34: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/intel_panel.c:1534:34: warning: expression using sizeof(void)
-dri

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI
  2019-02-14 16:33     ` Chris Wilson
@ 2019-02-14 21:12       ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 21:12 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Chris Wilson (2019-02-14 16:33:55)
> Quoting Chris Wilson (2019-02-14 16:31:13)
> > Quoting Matthew Auld (2019-02-14 14:57:32)
> > >  int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
> > > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > > index 26d2274b5d2b..5a102a5cb415 100644
> > > --- a/include/uapi/drm/i915_drm.h
> > > +++ b/include/uapi/drm/i915_drm.h
> > > @@ -1744,6 +1744,7 @@ struct drm_i915_perf_oa_config {
> > >  struct drm_i915_query_item {
> > >         __u64 query_id;
> > >  #define DRM_I915_QUERY_TOPOLOGY_INFO    1
> > > +#define DRM_I915_QUERY_MEMREGION_INFO   3
> > 
> > Ahem.
> > 
> > >         /*
> > >          * When set to zero by userspace, this is filled with the size of the
> > > @@ -1832,7 +1833,6 @@ struct drm_i915_query_topology_info {
> > >          * Offset in data[] at which the EU masks are stored.
> > >          */
> > >         __u16 eu_offset;
> > > -
> > >         /*
> > >          * Stride at which each of the EU masks for each subslice are stored.
> > >          */
> > > @@ -1841,6 +1841,44 @@ struct drm_i915_query_topology_info {
> > >         __u8 data[];
> > >  };
> > >  
> > > +struct drm_i915_memory_region_info {
> > > +
> > > +       /** Base type of a region
> > > +        */
> > > +#define I915_SYSTEM_MEMORY         0
> > > +#define I915_DEVICE_MEMORY         1
> > > +
> > > +       /** The region id is encoded in a layout which makes it possible to
> > > +        *  retrieve the following information:
> > > +        *
> > > +        *  Base type: log2(ID >> 16)
> > > +        *  Instance:  log2(ID & 0xffff)
> > > +        */
> > > +       __u32 id;
> > > +
> > > +       /** Reserved field. MBZ */
> > > +       __u32 rsvd0;
> > > +
> > > +       /** Unused for now. MBZ */
> > > +       __u64 flags;
> > > +
> > > +       __u64 size;
> > > +
> > > +       /** Reserved fields must be cleared to zero. */
> > > +       __u64 rsvd1[4];
> > > +};
> > 
> > If you were to apply this to stolen memory as an example, can you spot
> > how much information is missing?
> > 
> > Userspace would need to know total size, largest allocation chunk (i.e
> > largest object), rough estimate of availability, and most importantly a
> > list of API that is not allowed (such as CPU mmap, fencing). There's
> > without a doubt more that would be needed to actually wire it up to Vk.
> 
> Cross-process/ppgtt and cross-device sharing for example...

Another concept along the lines of MAP_PRIVATE above, is pure scratch. A
WO memory region that is not guaranteed to retain its state between
execution and is never swapped out but zapped under pressure. The use
being for things like kernel scratch allocations (for register spilling
and whatnot). Though small in the grand scheme of things, a context may
need 10+MiB of scratch (since even a small amount required per-thread
becomes a large amount) per stage.

I'm just looking to see what possibilities we may explore :)
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI
  2019-02-14 14:57 ` [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI Matthew Auld
  2019-02-14 16:31   ` Chris Wilson
@ 2019-02-14 21:15   ` Chris Wilson
  2019-02-14 21:21     ` Chris Wilson
  2019-02-20 18:56     ` Jason Ekstrand
  1 sibling, 2 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 21:15 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2019-02-14 14:57:32)
> From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> 
> Returns the available memory region areas supported by the HW.

This should include references to the Vulkan spec to show how it can be
used to convey the information required by anv (and what must be
inferred by userspace). That reference should be dotted around the
commitmg, the uapi.h and the code.

https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#memory
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI
  2019-02-14 21:15   ` Chris Wilson
@ 2019-02-14 21:21     ` Chris Wilson
  2019-02-20 18:56     ` Jason Ekstrand
  1 sibling, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-14 21:21 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Chris Wilson (2019-02-14 21:15:17)
> Quoting Matthew Auld (2019-02-14 14:57:32)
> > From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> > 
> > Returns the available memory region areas supported by the HW.
> 
> This should include references to the Vulkan spec to show how it can be
> used to convey the information required by anv (and what must be
> inferred by userspace). That reference should be dotted around the
> commitmg, the uapi.h and the code.
> 
> https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#memory

And also
https://www.khronos.org/registry/OpenCL/specs/opencl-2.0.pdf
3.3 Memory Model

It is not as explicit for probing as Vk, but I expect will useful to
keep a crossreference or two.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
                   ` (43 preceding siblings ...)
  2019-02-14 18:15 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-02-15  0:47 ` Dave Airlie
  2019-02-19 13:32   ` Joonas Lahtinen
  44 siblings, 1 reply; 97+ messages in thread
From: Dave Airlie @ 2019-02-15  0:47 UTC (permalink / raw)
  To: Matthew Auld; +Cc: intel-gfx

On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
>
> In preparation for upcoming devices with device local memory, introduce the
> concept of different memory regions, and a simple buddy allocator to manage
> them.

This is missing the information on why it's not TTM.

Nothing against extending i915 gem off into doing stuff we already
have examples off in tree, but before you do that it would be good to
have a why we can't use TTM discussion in public.

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 03/42] drm/i915: buddy allocator
  2019-02-14 14:57 ` [RFC PATCH 03/42] drm/i915: buddy allocator Matthew Auld
@ 2019-02-15 12:34   ` Jani Nikula
  2019-02-15 15:03     ` Chris Wilson
  0 siblings, 1 reply; 97+ messages in thread
From: Jani Nikula @ 2019-02-15 12:34 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

On Thu, 14 Feb 2019, Matthew Auld <matthew.auld@intel.com> wrote:
> Really simply buddy allocator.
>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile                 |   1 +
>  drivers/gpu/drm/i915/i915_gem_buddy.c         | 206 +++++++++++++++++
>  drivers/gpu/drm/i915/i915_gem_buddy.h         | 118 ++++++++++
>  .../gpu/drm/i915/selftests/i915_gem_buddy.c   | 209 ++++++++++++++++++
>  .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
>  5 files changed, 535 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/i915_gem_buddy.c
>  create mode 100644 drivers/gpu/drm/i915/i915_gem_buddy.h
>  create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_buddy.c
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 1787e1299b1b..e5ce813d1936 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -61,6 +61,7 @@ i915-y += \
>  	  i915_active.o \
>  	  i915_cmd_parser.o \
>  	  i915_gem_batch_pool.o \
> +	  i915_gem_buddy.o \
>  	  i915_gem_clflush.o \
>  	  i915_gem_context.o \
>  	  i915_gem_dmabuf.o \
> diff --git a/drivers/gpu/drm/i915/i915_gem_buddy.c b/drivers/gpu/drm/i915/i915_gem_buddy.c
> new file mode 100644
> index 000000000000..4dc688c091a2
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_gem_buddy.c
> @@ -0,0 +1,206 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */

Please replace the above with

// SPDX-License-Identifier: MIT
/*
 * Copyright © 2019 Intel Corporation
 */

Ditto for all new files being added. (Except .h which will need to have
old style /* ... */ comments around the first line.)

BR,
Jani.


> +
> +#include <linux/slab.h>
> +#include <linux/list.h>
> +
> +#include "i915_gem_buddy.h"
> +#include "i915_gem.h"
> +
> +int i915_gem_buddy_init(struct i915_gem_buddy_mm *mm, u64 size, u64 min_size)
> +{
> +	unsigned int i;
> +
> +	/*
> +	 * XXX: if not a power of 2, maybe split into power of 2 blocks,
> +	 * effectively having multiple roots, similar to if we had a global
> +	 * MAX_ORDER.
> +	 */
> +	size = rounddown_pow_of_two(size);
> +	min_size = roundup_pow_of_two(min_size);
> +
> +	if (size < min_size)
> +		return -EINVAL;
> +
> +	if (min_size < PAGE_SIZE)
> +		return -EINVAL;
> +
> +	mm->max_order = ilog2(size) - ilog2(min_size);
> +	mm->min_size = min_size;
> +
> +	mm->free_list = kmalloc_array(mm->max_order + 1,
> +				      sizeof(struct list_head),
> +				      GFP_KERNEL);
> +	if (!mm->free_list)
> +		return -ENOMEM;
> +
> +	for (i = 0; i <= mm->max_order; ++i)
> +		INIT_LIST_HEAD(&mm->free_list[i]);
> +
> +	mm->blocks = KMEM_CACHE(i915_gem_buddy_block, SLAB_HWCACHE_ALIGN);
> +	if (!mm->blocks)
> +		goto out_free_list;
> +
> +	mm->root = kmem_cache_zalloc(mm->blocks, GFP_KERNEL);
> +	if (!mm->root)
> +		goto out_free_blocks;
> +
> +	mm->root->header = mm->max_order;
> +
> +	list_add(&mm->root->link, &mm->free_list[mm->max_order]);
> +
> +	return 0;
> +
> +out_free_blocks:
> +	kmem_cache_destroy(mm->blocks);
> +out_free_list:
> +	kfree(mm->free_list);
> +
> +	return -ENOMEM;
> +}
> +
> +void i915_gem_buddy_fini(struct i915_gem_buddy_mm *mm)
> +{
> +	if (WARN_ON(i915_gem_buddy_block_allocated(mm->root)))
> +		return;
> +
> +	kfree(mm->free_list);
> +	kmem_cache_free(mm->blocks, mm->root);
> +	kmem_cache_destroy(mm->blocks);
> +}
> +
> +/*
> + * The 'order' here means:
> + *
> + * 0 = 2^0 * mm->min_size
> + * 1 = 2^1 * mm->min_size
> + * 2 = 2^2 * mm->min_size
> + * ...
> + */
> +struct i915_gem_buddy_block *
> +i915_gem_buddy_alloc(struct i915_gem_buddy_mm *mm, unsigned int order)
> +{
> +	struct i915_gem_buddy_block *block = NULL;
> +	struct i915_gem_buddy_block *root;
> +	unsigned int i;
> +
> +	for (i = order; i <= mm->max_order; ++i) {
> +		block = list_first_entry_or_null(&mm->free_list[i],
> +						 struct i915_gem_buddy_block,
> +						 link);
> +		if (block)
> +			break;
> +	}
> +
> +	if (!block)
> +		return ERR_PTR(-ENOSPC);
> +
> +	GEM_BUG_ON(i915_gem_buddy_block_allocated(block));
> +
> +	root = block;
> +
> +	while (i != order) {
> +		u64 offset = i915_gem_buddy_block_offset(block);
> +
> +		block->left = kmem_cache_zalloc(mm->blocks, GFP_KERNEL);
> +		if (!block->left)
> +			goto out_free_blocks;
> +
> +		block->left->header = offset;
> +		block->left->header |= I915_GEM_BUDDY_HEADER_ALLOCATED;
> +		block->left->header |= i - 1;
> +		block->left->parent = block;
> +
> +		INIT_LIST_HEAD(&block->left->link);
> +
> +		block->right = kmem_cache_zalloc(mm->blocks, GFP_KERNEL);
> +		if (!block->right) {
> +			kmem_cache_free(mm->blocks, block->left);
> +			goto out_free_blocks;
> +		}
> +
> +		block->right->header = offset + (BIT(i - 1) * mm->min_size);
> +		block->right->header |= i - 1;
> +		block->right->parent = block;
> +
> +		list_add(&block->right->link, &mm->free_list[i - 1]);
> +
> +		block = block->left;
> +		i--;
> +	}
> +
> +	root->header |= I915_GEM_BUDDY_HEADER_ALLOCATED;
> +	list_del(&root->link);
> +
> +	return block;
> +
> +out_free_blocks:
> +	while (block != root) {
> +		if (block->right)
> +			list_del(&block->right->link);
> +
> +		kmem_cache_free(mm->blocks, block->left);
> +		kmem_cache_free(mm->blocks, block->right);
> +
> +		block = block->parent;
> +	}
> +
> +	return ERR_PTR(-ENOMEM);
> +}
> +
> +void i915_gem_buddy_free(struct i915_gem_buddy_mm *mm,
> +			 struct i915_gem_buddy_block *block)
> +{
> +	GEM_BUG_ON(!i915_gem_buddy_block_allocated(block));
> +
> +	while (block->parent) {
> +		struct i915_gem_buddy_block *buddy;
> +		struct i915_gem_buddy_block *parent;
> +
> +		parent = block->parent;
> +
> +		if (parent->left == block)
> +			buddy = parent->right;
> +		else
> +			buddy = parent->left;
> +
> +		if (i915_gem_buddy_block_allocated(buddy))
> +			break;
> +
> +		list_del(&buddy->link);
> +
> +		kmem_cache_free(mm->blocks, block);
> +		kmem_cache_free(mm->blocks, buddy);
> +
> +		block = parent;
> +	}
> +
> +	block->header &= ~I915_GEM_BUDDY_HEADER_ALLOCATED;
> +	list_add(&block->link,
> +		 &mm->free_list[i915_gem_buddy_block_order(block)]);
> +}
> +
> +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> +#include "selftests/i915_gem_buddy.c"
> +#endif
> diff --git a/drivers/gpu/drm/i915/i915_gem_buddy.h b/drivers/gpu/drm/i915/i915_gem_buddy.h
> new file mode 100644
> index 000000000000..b3f06e9086b3
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_gem_buddy.h
> @@ -0,0 +1,118 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#ifndef __I915_GEM_BUDDY_H__
> +#define __I915_GEM_BUDDY_H__
> +
> +#include <linux/bitops.h>
> +
> +struct list_head;
> +
> +struct i915_gem_buddy_block {
> +#define I915_GEM_BUDDY_HEADER_OFFSET (~(BIT(12) - 1))
> +#define I915_GEM_BUDDY_HEADER_ALLOCATED BIT(11)
> +#define I915_GEM_BUDDY_HEADER_ORDER (BIT(11) - 1)
> +	u64 header;
> +
> +	struct i915_gem_buddy_block *left;
> +	struct i915_gem_buddy_block *right;
> +	struct i915_gem_buddy_block *parent;
> +
> +	/* Always safe to reuse once the block is allocated */
> +	struct list_head link;
> +};
> +
> +/*
> + * Binary Buddy System
> + *
> + * XXX: Idealy we would just use the intrusive version of the buddy system i.e
> + * the classical version, where we store the block info in the free blocks, but
> + * if we are dealing with something like stolen memory, this would very quickly
> + * turn into a dumbster fire with having to memremap/ioremap parts of stolen in
> + * the allocator.
> + */
> +struct i915_gem_buddy_mm {
> +	unsigned int max_order;
> +	/* Must be at least PAGE_SIZE */
> +	u64 min_size;
> +
> +	struct kmem_cache *blocks;
> +
> +	/* Maintain a free list for each order. */
> +	struct list_head *free_list;
> +
> +	/*
> +	 * Maintain an explicit binary tree to track the allocation of the
> +	 * address space. This gives us a simple way of finding a buddy block
> +	 * and performing the potentially recursive merge step when freeing a
> +	 * block.  Nodes are either allocated or free, in which case they will
> +	 * also exist on the respective free list.
> +	 */
> +	struct i915_gem_buddy_block *root;
> +};
> +
> +static inline u64
> +i915_gem_buddy_block_offset(struct i915_gem_buddy_block *block)
> +{
> +	return block->header & I915_GEM_BUDDY_HEADER_OFFSET;
> +}
> +
> +static inline unsigned int
> +i915_gem_buddy_block_order(struct i915_gem_buddy_block *block)
> +{
> +	return block->header & I915_GEM_BUDDY_HEADER_ORDER;
> +}
> +
> +static inline bool
> +i915_gem_buddy_block_allocated(struct i915_gem_buddy_block *block)
> +{
> +	return block->header & I915_GEM_BUDDY_HEADER_ALLOCATED;
> +}
> +
> +static inline u64
> +i915_gem_buddy_block_size(struct i915_gem_buddy_mm *mm,
> +		          struct i915_gem_buddy_block *block)
> +{
> +	return BIT(i915_gem_buddy_block_order(block)) * mm->min_size;
> +}
> +
> +static inline u64 i915_gem_buddy_size(struct i915_gem_buddy_mm *mm)
> +{
> +	return i915_gem_buddy_block_size(mm, mm->root);
> +}
> +
> +int i915_gem_buddy_init(struct i915_gem_buddy_mm *mm,
> +			u64 size,
> +			u64 min_size);
> +
> +void i915_gem_buddy_fini(struct i915_gem_buddy_mm *mm);
> +
> +struct i915_gem_buddy_block *
> +i915_gem_buddy_alloc(struct i915_gem_buddy_mm *mm,
> +		     unsigned int order);
> +
> +void i915_gem_buddy_free(struct i915_gem_buddy_mm *mm,
> +			 struct i915_gem_buddy_block *block);
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_buddy.c b/drivers/gpu/drm/i915/selftests/i915_gem_buddy.c
> new file mode 100644
> index 000000000000..c6782a39a1e9
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/selftests/i915_gem_buddy.c
> @@ -0,0 +1,209 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include "../i915_selftest.h"
> +
> +#define SZ_64G (1ULL << 36)
> +
> +static int igt_buddy_init(void *arg)
> +{
> +	struct i915_gem_buddy_mm mm;
> +	u64 size;
> +	int err = 0;
> +
> +	for (size = PAGE_SIZE; size <= SZ_64G; size <<= 1) {
> +		struct i915_gem_buddy_block *block;
> +
> +		err = i915_gem_buddy_init(&mm, size, PAGE_SIZE);
> +		if (err) {
> +			pr_err("buddy_init with size=%llx\n failed(%d)\n",
> +			       size, err);
> +			return err;
> +		}
> +
> +		block = i915_gem_buddy_alloc(&mm, mm.max_order);
> +		if (IS_ERR(block)) {
> +			err = PTR_ERR(block);
> +			pr_err("buddy_alloc with size=%llx\n failed(%d)\n",
> +			       size, err);
> +			goto out_buddy_fini;
> +		}
> +
> +		if (i915_gem_buddy_block_order(block) != mm.max_order) {
> +			pr_err("buddy_alloc size mismatch\n");
> +			err = -EINVAL;
> +		}
> +
> +		if (i915_gem_buddy_block_offset(block) != 0) {
> +			pr_err("buddy_alloc offset mismatch\n");
> +			err = -EINVAL;
> +		}
> +
> +		if (!list_empty(&mm.free_list[mm.max_order])) {
> +			pr_err("buddy_alloc state mismatch, block is on free list\n");
> +			err = -EINVAL;
> +		}
> +
> +		if (block != mm.root) {
> +			pr_err("buddy_alloc state mismatch, block != root\n");
> +			err = -EINVAL;
> +		}
> +
> +		if (block->left || block->right) {
> +			pr_err("buddy_alloc state mismatch, block is not leaf\n");
> +			err = -EINVAL;
> +		}
> +
> +		i915_gem_buddy_free(&mm, block);
> +
> +		if (list_empty(&mm.free_list[mm.max_order])) {
> +			pr_err("buddy_free state mismatch, block not on free list\n");
> +			err = -EINVAL;
> +		}
> +
> +		i915_gem_buddy_fini(&mm);
> +
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +
> +out_buddy_fini:
> +	i915_gem_buddy_fini(&mm);
> +
> +	return err;
> +}
> +
> +static int igt_buddy_alloc(void *arg)
> +{
> +	struct i915_gem_buddy_mm mm;
> +	u64 size;
> +	int order;
> +	int err;
> +
> +	err = i915_gem_buddy_init(&mm, SZ_64G, PAGE_SIZE);
> +	if (err) {
> +		pr_err("buddy_init with size=%llx\n failed(%d)\n", SZ_64G, err);
> +		return err;
> +	}
> +
> +	for (order = mm.max_order; order >= 0; order--) {
> +		struct i915_gem_buddy_block *block, *on;
> +		struct list_head blocks;
> +		u64 block_size;
> +		u64 offset;
> +		u64 prev_offset;
> +		u64 n_blocks;
> +
> +		size = i915_gem_buddy_size(&mm);
> +		if (size != SZ_64G) {
> +			pr_err("buddy_size mismatch\n");
> +			err = -EINVAL;
> +			break;
> +		}
> +
> +		if (list_empty(&mm.free_list[mm.max_order])) {
> +			pr_err("root not on the free list\n");
> +			err = -EINVAL;
> +			break;
> +		}
> +
> +		pr_info("filling address space(%llx) with order=%d\n",
> +			i915_gem_buddy_size(&mm), order);
> +
> +		prev_offset = 0;
> +		n_blocks = div64_u64(size, BIT(order) * mm.min_size);
> +		INIT_LIST_HEAD(&blocks);
> +
> +		while (n_blocks--) {
> +			block = i915_gem_buddy_alloc(&mm, order);
> +			if (IS_ERR(block)) {
> +				err = PTR_ERR(block);
> +				if (err == -ENOMEM) {
> +					pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
> +					        order);
> +				} else {
> +					pr_err("buddy_alloc with order=%d failed(%d)\n",
> +					       order, err);
> +				}
> +
> +				break;
> +			}
> +
> +			list_add(&block->link, &blocks);
> +
> +			if (i915_gem_buddy_block_order(block) != order) {
> +				pr_err("buddy_alloc order mismatch\n");
> +				err = -EINVAL;
> +				break;
> +			}
> +
> +			block_size = i915_gem_buddy_block_size(&mm, block);
> +			offset = i915_gem_buddy_block_offset(block);
> +
> +			if (!IS_ALIGNED(offset, block_size)) {
> +				pr_err("buddy_alloc offset misaligned, offset=%llx, block_size=%llu\n",
> +					offset, block_size);
> +				err = -EINVAL;
> +				break;
> +			}
> +
> +			if (offset && offset != (prev_offset + block_size)) {
> +				pr_err("buddy_alloc offset mismatch, prev_offset=%llx, offset=%llx\n",
> +				       prev_offset, offset);
> +				err = -EINVAL;
> +				break;
> +			}
> +
> +			prev_offset = offset;
> +		}
> +
> +		list_for_each_entry_safe(block, on, &blocks, link) {
> +			list_del(&block->link);
> +			i915_gem_buddy_free(&mm, block);
> +		}
> +
> +		if (err)
> +			break;
> +	}
> +
> +	i915_gem_buddy_fini(&mm);
> +
> +	if (err == -ENOMEM)
> +		err = 0;
> +
> +	return err;
> +}
> +
> +int i915_gem_buddy_mock_selftests(void)
> +{
> +	static const struct i915_subtest tests[] = {
> +		SUBTEST(igt_buddy_init),
> +		SUBTEST(igt_buddy_alloc),
> +	};
> +
> +	return i915_subtests(tests, NULL);
> +}
> +
> diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> index 88e5ab586337..984e07ed65e5 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> @@ -24,3 +24,4 @@ selftest(evict, i915_gem_evict_mock_selftests)
>  selftest(gtt, i915_gem_gtt_mock_selftests)
>  selftest(hugepages, i915_gem_huge_page_mock_selftests)
>  selftest(contexts, i915_gem_context_mock_selftests)
> +selftest(buddy, i915_gem_buddy_mock_selftests)

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 03/42] drm/i915: buddy allocator
  2019-02-15 12:34   ` Jani Nikula
@ 2019-02-15 15:03     ` Chris Wilson
  2019-02-18 11:35       ` Jani Nikula
  0 siblings, 1 reply; 97+ messages in thread
From: Chris Wilson @ 2019-02-15 15:03 UTC (permalink / raw)
  To: Jani Nikula, Matthew Auld, intel-gfx

Quoting Jani Nikula (2019-02-15 12:34:02)
> Please replace the above with
> 
> // SPDX-License-Identifier: MIT
> /*
>  * Copyright © 2019 Intel Corporation
>  */
> 
> Ditto for all new files being added. (Except .h which will need to have
> old style /* ... */ comments around the first line.)

Rebel against the overlords imposing C++ comments upon us; we will
remain clean! I really do not see the point in using C++ for this one
instance, the perl regex is not any harder to write...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 03/42] drm/i915: buddy allocator
  2019-02-15 15:03     ` Chris Wilson
@ 2019-02-18 11:35       ` Jani Nikula
  0 siblings, 0 replies; 97+ messages in thread
From: Jani Nikula @ 2019-02-18 11:35 UTC (permalink / raw)
  To: Chris Wilson, Matthew Auld, intel-gfx

On Fri, 15 Feb 2019, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> Quoting Jani Nikula (2019-02-15 12:34:02)
>> Please replace the above with
>> 
>> // SPDX-License-Identifier: MIT
>> /*
>>  * Copyright © 2019 Intel Corporation
>>  */
>> 
>> Ditto for all new files being added. (Except .h which will need to have
>> old style /* ... */ comments around the first line.)
>
> Rebel against the overlords imposing C++ comments upon us; we will
> remain clean! I really do not see the point in using C++ for this one
> instance, the perl regex is not any harder to write...

In this case, I'd rather not leave people any wiggle room. Accept any
deviation, and it'll get copy-pasted and deviated more. I want the
message to be clear, put this in verbatim and don't come up with clever
ideas. (Yeah, I see there's deviation already, and I've already
contemplated patches to fix them.)

Perhaps my sentiments are amplified by my annoyance at the combinatorial
explosion of subtly different MIT license texts we already have, making
what's supposed to be a trivial switch to SPDX rather more complicated.

BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM
  2019-02-14 16:13   ` Chris Wilson
@ 2019-02-18 12:44     ` Chris Wilson
  2019-02-19 17:44     ` Chris Wilson
  1 sibling, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-18 12:44 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Chris Wilson (2019-02-14 16:13:18)
> Quoting Matthew Auld (2019-02-14 14:57:40)
> > Hack patch to default all userspace allocations to LMEM. Useful for
> > testing purposes.
> > 
> > Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_gem.c | 45 +++++++++++++++++++++++++++++++--
> >  1 file changed, 43 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index 3c86909d55b9..bd857f477ef9 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -641,7 +641,8 @@ i915_gem_create(struct drm_file *file,
> >                 u32 *handle_p)
> >  {
> >         struct drm_i915_gem_object *obj;
> > -       int ret;
> > +       intel_wakeref_t wakeref;
> > +       int ret = 0;
> >         u32 handle;
> >  
> >         size = roundup(size, PAGE_SIZE);
> > @@ -649,10 +650,50 @@ i915_gem_create(struct drm_file *file,
> >                 return -EINVAL;
> >  
> >         /* Allocate the new object */
> > -       obj = i915_gem_object_create(dev_priv, size);
> > +       if (HAS_LMEM(dev_priv))
> > +               obj = i915_gem_object_create_lmem(dev_priv, size, 0);
> > +       else
> > +               obj = i915_gem_object_create(dev_priv, size);
> >         if (IS_ERR(obj))
> >                 return PTR_ERR(obj);
> >  
> > +       if (i915_gem_object_is_lmem(obj)) {
> > +               struct i915_gem_context *ctx;
> > +
> > +               /* XXX: we should prob use the blitter context for this? */
> 
> Or the kernel_context which is setup for emitting without taking
> struct_mutex...

Actually doing this async (i.e. not blocking object creation due to
clear) requires us to be sure that the cpu access via mmap has a sync
point. pread, mmap_ggtt does, but mmap_(wb|wc) does not currently, and
we would be reliant on userspace doing a set-domain first in order for
them not to see stale buffer content.

Also I have this penciled in to enable buffer pools (e.g. !llc would
dearly love to keep WC pages around before giving them back to the
system).

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-15  0:47 ` [RFC PATCH 00/42] " Dave Airlie
@ 2019-02-19 13:32   ` Joonas Lahtinen
  2019-02-25 20:24     ` Dave Airlie
  0 siblings, 1 reply; 97+ messages in thread
From: Joonas Lahtinen @ 2019-02-19 13:32 UTC (permalink / raw)
  To: Dave Airlie, Matthew Auld; +Cc: intel-gfx, dri-devel

+ dri-devel mailing list, especially for the buddy allocator part

Quoting Dave Airlie (2019-02-15 02:47:07)
> On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
> >
> > In preparation for upcoming devices with device local memory, introduce the
> > concept of different memory regions, and a simple buddy allocator to manage
> > them.
> 
> This is missing the information on why it's not TTM.
> 
> Nothing against extending i915 gem off into doing stuff we already
> have examples off in tree, but before you do that it would be good to
> have a why we can't use TTM discussion in public.

Glad that you asked. It's my fault that it was not included in
the cover letter. I anticipated the question, but was travelling
for a couple of days at the time this was sent. I didn't want
to write a hasty explanation and then disappear, leaving others to
take the heat.

So here goes the less-hasty version:

We did an analysis on the effort needed vs benefit gained of using
TTM when this was started initially. The conclusion was that we
already share the interesting bits of code through core DRM, really.

Re-writing the memory handling to TTM would buy us more fine-grained
locking. But it's more a trait of rewriting the memory handling with
the information we have learned, than rewriting it to use TTM :)

And further, we've been getting rid of struct_mutex at a steady phase
in the past years, so we have a clear path to the fine-grained locking
already in the not-so-distant future. With all this we did not see
much gained from converting over, as the code sharing is already
substantial.

We also wanted to have the buddy allocator instead of a for loop making
drm_mm allocations to make sure we can keep the memory fragmentation
at bay. The intent is to move the buddy allocator to core DRM, to the
benefit of all the drivers, if there is interest from community. It has
been written as a strictly separate component with that in mind.

And if you take the buddy allocator out of the patch set, the rest is
mostly just vfuncing things up to be able to have different backing
storages for objects. We took the opportunity to move over to the more
valgrind friendly mmap while touching things, but it's something we
have been contemplating anyway. And yeah, loads of selftests.

That's really all that needed adding, and most of it is internal to
i915 and not to do with uAPI. This means porting over an userspace
driver doesn't require a substantial rewrite, but adding new a few
new IOCTLs to set the preferred backing storage placements.

All the previous GEM abstractions keep applying, so we did not see
a justification to rewrite the kernel driver and userspace drivers.
It would have just to made things look like TTM, when we already
have the important parts of the code shared with TTM drivers
behind the GEM interfaces which all our drivers sit on top of.

I hope this answered the question to some extent, and feel free to
ask more details or provide suggestion to what we could have done
differently.

Regards, Joonas

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM
  2019-02-14 16:13   ` Chris Wilson
  2019-02-18 12:44     ` Chris Wilson
@ 2019-02-19 17:44     ` Chris Wilson
  1 sibling, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-19 17:44 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Chris Wilson (2019-02-14 16:13:18)
> Quoting Matthew Auld (2019-02-14 14:57:40)
> > Hack patch to default all userspace allocations to LMEM. Useful for
> > testing purposes.
> > 
> > Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_gem.c | 45 +++++++++++++++++++++++++++++++--
> >  1 file changed, 43 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index 3c86909d55b9..bd857f477ef9 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -641,7 +641,8 @@ i915_gem_create(struct drm_file *file,
> >                 u32 *handle_p)
> >  {
> >         struct drm_i915_gem_object *obj;
> > -       int ret;
> > +       intel_wakeref_t wakeref;
> > +       int ret = 0;
> >         u32 handle;
> >  
> >         size = roundup(size, PAGE_SIZE);
> > @@ -649,10 +650,50 @@ i915_gem_create(struct drm_file *file,
> >                 return -EINVAL;
> >  
> >         /* Allocate the new object */
> > -       obj = i915_gem_object_create(dev_priv, size);
> > +       if (HAS_LMEM(dev_priv))
> > +               obj = i915_gem_object_create_lmem(dev_priv, size, 0);
> > +       else
> > +               obj = i915_gem_object_create(dev_priv, size);
> >         if (IS_ERR(obj))
> >                 return PTR_ERR(obj);
> >  
> > +       if (i915_gem_object_is_lmem(obj)) {
> > +               struct i915_gem_context *ctx;
> > +
> > +               /* XXX: we should prob use the blitter context for this? */
> 
> Or the kernel_context which is setup for emitting without taking
> struct_mutex...

Using a single context should only be a last resort; be it kernel or
blitter context. We need to defer this until an owning HW context is
known so that we can properly queue it in their name, or else we end up
with a global barrier being the kernel context and priority inversions
abound.

This does suggest to me that async pages needs to be in better shape...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI
  2019-02-14 21:15   ` Chris Wilson
  2019-02-14 21:21     ` Chris Wilson
@ 2019-02-20 18:56     ` Jason Ekstrand
  1 sibling, 0 replies; 97+ messages in thread
From: Jason Ekstrand @ 2019-02-20 18:56 UTC (permalink / raw)
  To: Chris Wilson; +Cc: Intel GFX, Matthew Auld


[-- Attachment #1.1: Type: text/plain, Size: 653 bytes --]

On Thu, Feb 14, 2019 at 3:15 PM Chris Wilson <chris@chris-wilson.co.uk>
wrote:

> Quoting Matthew Auld (2019-02-14 14:57:32)
> > From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> >
> > Returns the available memory region areas supported by the HW.
>
> This should include references to the Vulkan spec to show how it can be
> used to convey the information required by anv (and what must be
> inferred by userspace). That reference should be dotted around the
> commitmg, the uapi.h and the code.


More to the point, what open-source userspace is there that exercises
this?  No, IGT doesn't count.  The correct answer is "Vulkan". :-)

--Jason

[-- Attachment #1.2: Type: text/html, Size: 1109 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-19 13:32   ` Joonas Lahtinen
@ 2019-02-25 20:24     ` Dave Airlie
  2019-02-26  2:35       ` [Intel-gfx] " Joonas Lahtinen
  0 siblings, 1 reply; 97+ messages in thread
From: Dave Airlie @ 2019-02-25 20:24 UTC (permalink / raw)
  To: Joonas Lahtinen; +Cc: intel-gfx, Matthew Auld, dri-devel

On Tue, 19 Feb 2019 at 23:32, Joonas Lahtinen
<joonas.lahtinen@linux.intel.com> wrote:
>
> + dri-devel mailing list, especially for the buddy allocator part
>
> Quoting Dave Airlie (2019-02-15 02:47:07)
> > On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
> > >
> > > In preparation for upcoming devices with device local memory, introduce the
> > > concept of different memory regions, and a simple buddy allocator to manage
> > > them.
> >
> > This is missing the information on why it's not TTM.
> >
> > Nothing against extending i915 gem off into doing stuff we already
> > have examples off in tree, but before you do that it would be good to
> > have a why we can't use TTM discussion in public.
>
> Glad that you asked. It's my fault that it was not included in
> the cover letter. I anticipated the question, but was travelling
> for a couple of days at the time this was sent. I didn't want
> to write a hasty explanation and then disappear, leaving others to
> take the heat.
>
> So here goes the less-hasty version:
>
> We did an analysis on the effort needed vs benefit gained of using
> TTM when this was started initially. The conclusion was that we
> already share the interesting bits of code through core DRM, really.
>
> Re-writing the memory handling to TTM would buy us more fine-grained
> locking. But it's more a trait of rewriting the memory handling with
> the information we have learned, than rewriting it to use TTM :)
>
> And further, we've been getting rid of struct_mutex at a steady phase
> in the past years, so we have a clear path to the fine-grained locking
> already in the not-so-distant future. With all this we did not see
> much gained from converting over, as the code sharing is already
> substantial.
>
> We also wanted to have the buddy allocator instead of a for loop making
> drm_mm allocations to make sure we can keep the memory fragmentation
> at bay. The intent is to move the buddy allocator to core DRM, to the
> benefit of all the drivers, if there is interest from community. It has
> been written as a strictly separate component with that in mind.
>
> And if you take the buddy allocator out of the patch set, the rest is
> mostly just vfuncing things up to be able to have different backing
> storages for objects. We took the opportunity to move over to the more
> valgrind friendly mmap while touching things, but it's something we
> have been contemplating anyway. And yeah, loads of selftests.
>
> That's really all that needed adding, and most of it is internal to
> i915 and not to do with uAPI. This means porting over an userspace
> driver doesn't require a substantial rewrite, but adding new a few
> new IOCTLs to set the preferred backing storage placements.
>
> All the previous GEM abstractions keep applying, so we did not see
> a justification to rewrite the kernel driver and userspace drivers.
> It would have just to made things look like TTM, when we already
> have the important parts of the code shared with TTM drivers
> behind the GEM interfaces which all our drivers sit on top of.

a) you guys should be the community as well, if the buddy allocator is
useful in the core DRM get out there and try and see if anyone else
has a use case for it, like the GPU scheduler we have now (can i915
use that yet? :-)

b) however this last two paragraphs fill me with no confidence that
you've looked at TTM at all. It sounds like you took comments about
TTM made 10 years ago, and didn't update them. There should be no
major reason for a uapi change just because you adopt TTM. TTM hasn't
ever had a common uapi across drivers upstream, one was proposed
initially > 10 years ago. All the current TTM using drivers except
vmware use a GEM based API as well. TTM is an internal driver helper
for managing pools of RAM.

I'm just not sure what rebuilding a chunk of shared code inside the
i915 driver is buying you, except a transition path into divergence
from all the other discrete RAM drivers. Like the gallium aversion in
userspace, having a TTM aversion in kernel space is going to be the
wrong path, and I'd rather not have to clean it up in 5 years when you
guys eventually realise it.

The i915 GEM code get rewritten and refactored quite often and has a
bus factor of ickle, if he decided to go elsewhere, you will have a
pile of code that nobody gets, I think having a TTM backend would have
a better long term effect on your driver maintainability.

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Intel-gfx] [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-25 20:24     ` Dave Airlie
@ 2019-02-26  2:35       ` Joonas Lahtinen
  2019-02-26  5:31         ` Alex Deucher
  0 siblings, 1 reply; 97+ messages in thread
From: Joonas Lahtinen @ 2019-02-26  2:35 UTC (permalink / raw)
  To: Dave Airlie; +Cc: intel-gfx, Matthew Auld, dri-devel

Quoting Dave Airlie (2019-02-25 12:24:48)
> On Tue, 19 Feb 2019 at 23:32, Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com> wrote:
> >
> > + dri-devel mailing list, especially for the buddy allocator part
> >
> > Quoting Dave Airlie (2019-02-15 02:47:07)
> > > On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
> > > >
> > > > In preparation for upcoming devices with device local memory, introduce the
> > > > concept of different memory regions, and a simple buddy allocator to manage
> > > > them.
> > >
> > > This is missing the information on why it's not TTM.
> > >
> > > Nothing against extending i915 gem off into doing stuff we already
> > > have examples off in tree, but before you do that it would be good to
> > > have a why we can't use TTM discussion in public.
> >
> > Glad that you asked. It's my fault that it was not included in
> > the cover letter. I anticipated the question, but was travelling
> > for a couple of days at the time this was sent. I didn't want
> > to write a hasty explanation and then disappear, leaving others to
> > take the heat.
> >
> > So here goes the less-hasty version:
> >
> > We did an analysis on the effort needed vs benefit gained of using
> > TTM when this was started initially. The conclusion was that we
> > already share the interesting bits of code through core DRM, really.
> >
> > Re-writing the memory handling to TTM would buy us more fine-grained
> > locking. But it's more a trait of rewriting the memory handling with
> > the information we have learned, than rewriting it to use TTM :)
> >
> > And further, we've been getting rid of struct_mutex at a steady phase
> > in the past years, so we have a clear path to the fine-grained locking
> > already in the not-so-distant future. With all this we did not see
> > much gained from converting over, as the code sharing is already
> > substantial.
> >
> > We also wanted to have the buddy allocator instead of a for loop making
> > drm_mm allocations to make sure we can keep the memory fragmentation
> > at bay. The intent is to move the buddy allocator to core DRM, to the
> > benefit of all the drivers, if there is interest from community. It has
> > been written as a strictly separate component with that in mind.
> >
> > And if you take the buddy allocator out of the patch set, the rest is
> > mostly just vfuncing things up to be able to have different backing
> > storages for objects. We took the opportunity to move over to the more
> > valgrind friendly mmap while touching things, but it's something we
> > have been contemplating anyway. And yeah, loads of selftests.
> >
> > That's really all that needed adding, and most of it is internal to
> > i915 and not to do with uAPI. This means porting over an userspace
> > driver doesn't require a substantial rewrite, but adding new a few
> > new IOCTLs to set the preferred backing storage placements.
> >
> > All the previous GEM abstractions keep applying, so we did not see
> > a justification to rewrite the kernel driver and userspace drivers.
> > It would have just to made things look like TTM, when we already
> > have the important parts of the code shared with TTM drivers
> > behind the GEM interfaces which all our drivers sit on top of.
> 
> a) you guys should be the community as well, if the buddy allocator is
> useful in the core DRM get out there and try and see if anyone else
> has a use case for it, like the GPU scheduler we have now (can i915
> use that yet? :-)

Well, the buddy allocator should be useful for anybody wishing to have
as continuous physical allocations as possible. I have naively assumed
that would be almost everyone. So it would be only a question if others
see the amount of work required to convert over is justified for them.

For the common DRM scheduler, I think a solid move from the beginning
would have been to factor out the i915 scheduler as it was most advanced
in features :) Now there is a way more trivial common scheduler core with
no easy path to transition without a feature regression.

We'd have to rewrite many of the more advanced features for that codebase
before we could transition over. It's hard to justify such work, for
that it would buy us very little compared to amount of work.

Situation would be different if there was something gained from
switching over. This would be the situation if the more advanced
scheduler was picked as the shared codebase.

> b) however this last two paragraphs fill me with no confidence that
> you've looked at TTM at all. It sounds like you took comments about
> TTM made 10 years ago, and didn't update them. There should be no
> major reason for a uapi change just because you adopt TTM. TTM hasn't
> ever had a common uapi across drivers upstream, one was proposed
> initially > 10 years ago.

This is one part my confusion on what the question was for and other
part bad wording on my behalf.

So an attempt to re-answer: When this effort was started it was obvious
that the amount of new code required was low (as you can see). Feedback
about what converting to TTM would require vs. give us was gathered from
folks including Daniel and Chris and the unanimous decision was that it
would not be justifiable.

> All the current TTM using drivers except
> vmware use a GEM based API as well. TTM is an internal driver helper
> for managing pools of RAM.
> 
> I'm just not sure what rebuilding a chunk of shared code inside the
> i915 driver is buying you, except a transition path into divergence
> from all the other discrete RAM drivers.

I guess what I'm trying to say, there isn't that much code being added
that wouldn't be there anyway. The i915 GEM code has already grown to
what it is before this.

Adding the suggested smaller amount of code vs. doing a much bigger
rewrite is something of a straightforward choice with the amount of
platforms and features in flight, especially when the end result is
the same.

> Like the gallium aversion in
> userspace, having a TTM aversion in kernel space is going to be the
> wrong path, and I'd rather not have to clean it up in 5 years when you
> guys eventually realise it.
> 
> The i915 GEM code get rewritten and refactored quite often

Well, we continually try to improve things and accommodate upcoming
product requirements and hardware feature. The thing is that we do it
upstream first, so hard to avoid the churn.

When moving rapidly, it's hard to project what the shared portion of
the code might be or exactly look. I'm myself much more believer in
extracting the generic portions out when the code is there and working.

The churn would be even bigger if there is a strict requirement to
refactor the common parts out straight from the beginning, before
anything is even proven in practice.

That'd just mean it gets much harder to sell doing things upstream
first to the management.

When the code is in place and working, and we still agree that more
code reuse could be beneficial, it will be more viable thing to do
when there are less moving parts.

> and has a
> bus factor of ickle, if he decided to go elsewhere, you will have a
> pile of code that nobody gets, I think having a TTM backend would have
> a better long term effect on your driver maintainability.

Well, as you might notice, the patches are not from ickle.

I'm not saying we couldn't improve code sharing. I currently have a
priority in making sure we can enable the upcoming platforms, which has
a much more direct effect on our short and long term driver
maintainability through resourcing :)

If the platform support is not there, it's hard to have the headcount
to work on refactoring the reusable parts of code out.

So I'm hoping we can have an incremental approach to the code
refactorings suggested, that doesn't stall the delivery of the features.

Regards, Joonas

> Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Intel-gfx] [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26  2:35       ` [Intel-gfx] " Joonas Lahtinen
@ 2019-02-26  5:31         ` Alex Deucher
  2019-02-26 10:41           ` Jani Nikula
  2019-02-26 12:17           ` Joonas Lahtinen
  0 siblings, 2 replies; 97+ messages in thread
From: Alex Deucher @ 2019-02-26  5:31 UTC (permalink / raw)
  To: Joonas Lahtinen; +Cc: Intel Graphics Development, Matthew Auld, dri-devel

On Mon, Feb 25, 2019 at 9:35 PM Joonas Lahtinen
<joonas.lahtinen@linux.intel.com> wrote:
>
> Quoting Dave Airlie (2019-02-25 12:24:48)
> > On Tue, 19 Feb 2019 at 23:32, Joonas Lahtinen
> > <joonas.lahtinen@linux.intel.com> wrote:
> > >
> > > + dri-devel mailing list, especially for the buddy allocator part
> > >
> > > Quoting Dave Airlie (2019-02-15 02:47:07)
> > > > On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
> > > > >
> > > > > In preparation for upcoming devices with device local memory, introduce the
> > > > > concept of different memory regions, and a simple buddy allocator to manage
> > > > > them.
> > > >
> > > > This is missing the information on why it's not TTM.
> > > >
> > > > Nothing against extending i915 gem off into doing stuff we already
> > > > have examples off in tree, but before you do that it would be good to
> > > > have a why we can't use TTM discussion in public.
> > >
> > > Glad that you asked. It's my fault that it was not included in
> > > the cover letter. I anticipated the question, but was travelling
> > > for a couple of days at the time this was sent. I didn't want
> > > to write a hasty explanation and then disappear, leaving others to
> > > take the heat.
> > >
> > > So here goes the less-hasty version:
> > >
> > > We did an analysis on the effort needed vs benefit gained of using
> > > TTM when this was started initially. The conclusion was that we
> > > already share the interesting bits of code through core DRM, really.
> > >
> > > Re-writing the memory handling to TTM would buy us more fine-grained
> > > locking. But it's more a trait of rewriting the memory handling with
> > > the information we have learned, than rewriting it to use TTM :)
> > >
> > > And further, we've been getting rid of struct_mutex at a steady phase
> > > in the past years, so we have a clear path to the fine-grained locking
> > > already in the not-so-distant future. With all this we did not see
> > > much gained from converting over, as the code sharing is already
> > > substantial.
> > >
> > > We also wanted to have the buddy allocator instead of a for loop making
> > > drm_mm allocations to make sure we can keep the memory fragmentation
> > > at bay. The intent is to move the buddy allocator to core DRM, to the
> > > benefit of all the drivers, if there is interest from community. It has
> > > been written as a strictly separate component with that in mind.
> > >
> > > And if you take the buddy allocator out of the patch set, the rest is
> > > mostly just vfuncing things up to be able to have different backing
> > > storages for objects. We took the opportunity to move over to the more
> > > valgrind friendly mmap while touching things, but it's something we
> > > have been contemplating anyway. And yeah, loads of selftests.
> > >
> > > That's really all that needed adding, and most of it is internal to
> > > i915 and not to do with uAPI. This means porting over an userspace
> > > driver doesn't require a substantial rewrite, but adding new a few
> > > new IOCTLs to set the preferred backing storage placements.
> > >
> > > All the previous GEM abstractions keep applying, so we did not see
> > > a justification to rewrite the kernel driver and userspace drivers.
> > > It would have just to made things look like TTM, when we already
> > > have the important parts of the code shared with TTM drivers
> > > behind the GEM interfaces which all our drivers sit on top of.
> >
> > a) you guys should be the community as well, if the buddy allocator is
> > useful in the core DRM get out there and try and see if anyone else
> > has a use case for it, like the GPU scheduler we have now (can i915
> > use that yet? :-)
>
> Well, the buddy allocator should be useful for anybody wishing to have
> as continuous physical allocations as possible. I have naively assumed
> that would be almost everyone. So it would be only a question if others
> see the amount of work required to convert over is justified for them.
>
> For the common DRM scheduler, I think a solid move from the beginning
> would have been to factor out the i915 scheduler as it was most advanced
> in features :) Now there is a way more trivial common scheduler core with
> no easy path to transition without a feature regression.

Can you elaborate?  What features are missing from the drm gpu scheduler?

>
> We'd have to rewrite many of the more advanced features for that codebase
> before we could transition over. It's hard to justify such work, for
> that it would buy us very little compared to amount of work.
>
> Situation would be different if there was something gained from
> switching over. This would be the situation if the more advanced
> scheduler was picked as the shared codebase.
>
> > b) however this last two paragraphs fill me with no confidence that
> > you've looked at TTM at all. It sounds like you took comments about
> > TTM made 10 years ago, and didn't update them. There should be no
> > major reason for a uapi change just because you adopt TTM. TTM hasn't
> > ever had a common uapi across drivers upstream, one was proposed
> > initially > 10 years ago.
>
> This is one part my confusion on what the question was for and other
> part bad wording on my behalf.
>
> So an attempt to re-answer: When this effort was started it was obvious
> that the amount of new code required was low (as you can see). Feedback
> about what converting to TTM would require vs. give us was gathered from
> folks including Daniel and Chris and the unanimous decision was that it
> would not be justifiable.
>
> > All the current TTM using drivers except
> > vmware use a GEM based API as well. TTM is an internal driver helper
> > for managing pools of RAM.
> >
> > I'm just not sure what rebuilding a chunk of shared code inside the
> > i915 driver is buying you, except a transition path into divergence
> > from all the other discrete RAM drivers.
>
> I guess what I'm trying to say, there isn't that much code being added
> that wouldn't be there anyway. The i915 GEM code has already grown to
> what it is before this.
>
> Adding the suggested smaller amount of code vs. doing a much bigger
> rewrite is something of a straightforward choice with the amount of
> platforms and features in flight, especially when the end result is
> the same.

Because you will probably never do it.  It's almost always easier to
just incrementally add on to existing code.  One could argue that GEM
evolved into more or less the exact same thing as TTM anyway so why
not bite the bullet and switch at some point?  TTM works fine even for
UMA hardware.

>
> > Like the gallium aversion in
> > userspace, having a TTM aversion in kernel space is going to be the
> > wrong path, and I'd rather not have to clean it up in 5 years when you
> > guys eventually realise it.
> >
> > The i915 GEM code get rewritten and refactored quite often
>
> Well, we continually try to improve things and accommodate upcoming
> product requirements and hardware feature. The thing is that we do it
> upstream first, so hard to avoid the churn.
>
> When moving rapidly, it's hard to project what the shared portion of
> the code might be or exactly look. I'm myself much more believer in
> extracting the generic portions out when the code is there and working.
>
> The churn would be even bigger if there is a strict requirement to
> refactor the common parts out straight from the beginning, before
> anything is even proven in practice.
>
> That'd just mean it gets much harder to sell doing things upstream
> first to the management.

What does upstream first have to do with contributing to shared code?
There is a common misconception in big companies that if you utilize
shared infrastructure it will slow you down or you'll lose control of
your code which is I think what you are referring to.  Ultimately, it
does sometimes raise the bar, but in the long term it benefits
everyone and usually it doesn't really add that much overhead. It
sounds like you are just feeding that misconception; you can't
contribute to or take advantage of any shared infrastructure because
that might slow you down.  If that is the case, then why does upstream
first even matter?  It seems like the only common code you want to
support is common code that you wrote in the first place.

Alex

>
> When the code is in place and working, and we still agree that more
> code reuse could be beneficial, it will be more viable thing to do
> when there are less moving parts.
>
> > and has a
> > bus factor of ickle, if he decided to go elsewhere, you will have a
> > pile of code that nobody gets, I think having a TTM backend would have
> > a better long term effect on your driver maintainability.
>
> Well, as you might notice, the patches are not from ickle.
>
> I'm not saying we couldn't improve code sharing. I currently have a
> priority in making sure we can enable the upcoming platforms, which has
> a much more direct effect on our short and long term driver
> maintainability through resourcing :)
>
> If the platform support is not there, it's hard to have the headcount
> to work on refactoring the reusable parts of code out.
>
> So I'm hoping we can have an incremental approach to the code
> refactorings suggested, that doesn't stall the delivery of the features.
>
> Regards, Joonas
>
> > Dave.
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Intel-gfx] [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26  5:31         ` Alex Deucher
@ 2019-02-26 10:41           ` Jani Nikula
  2019-02-26 12:17           ` Joonas Lahtinen
  1 sibling, 0 replies; 97+ messages in thread
From: Jani Nikula @ 2019-02-26 10:41 UTC (permalink / raw)
  To: Alex Deucher, Joonas Lahtinen
  Cc: Intel Graphics Development, Matthew Auld, dri-devel


So I'm not going to go into technical detail here, which I'll happily
leave to Joonas et al, but I think a couple of general points deserve to
be addressed.

On Tue, 26 Feb 2019, Alex Deucher <alexdeucher@gmail.com> wrote:
> On Mon, Feb 25, 2019 at 9:35 PM Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com> wrote:
>> Adding the suggested smaller amount of code vs. doing a much bigger
>> rewrite is something of a straightforward choice with the amount of
>> platforms and features in flight, especially when the end result is
>> the same.
>
> Because you will probably never do it.  It's almost always easier to
> just incrementally add on to existing code.  One could argue that GEM
> evolved into more or less the exact same thing as TTM anyway so why
> not bite the bullet and switch at some point?  TTM works fine even for
> UMA hardware.

Surely we have lots of faults, but being averse to refactoring,
reworking, and continuously rewriting parts of the driver is not among
them by any stretch. Sometimes it's just for the general
maintainability, sometimes to remodel stuff to neatly plug in support
for that new piece of hardware, and everything in between.

> There is a common misconception in big companies that if you utilize
> shared infrastructure it will slow you down or you'll lose control of
> your code which is I think what you are referring to.  Ultimately, it
> does sometimes raise the bar, but in the long term it benefits
> everyone and usually it doesn't really add that much overhead. It
> sounds like you are just feeding that misconception; you can't
> contribute to or take advantage of any shared infrastructure because
> that might slow you down.  If that is the case, then why does upstream
> first even matter?  It seems like the only common code you want to
> support is common code that you wrote in the first place.

Again, on a general note, without actually checking the stats, I like to
think we're pretty good citizens wrt actively using and contributing to
shared infrastructure, and shared uapi. Especially so for KMS, and even
when it really has slowed us down.

So while you may have fair points about a specific case, and again I'll
let Joonas address the specific case, I'll have to ask you to please not
generalize that to the whole driver.


BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26  5:31         ` Alex Deucher
  2019-02-26 10:41           ` Jani Nikula
@ 2019-02-26 12:17           ` Joonas Lahtinen
  2019-02-26 17:20             ` Alex Deucher
  1 sibling, 1 reply; 97+ messages in thread
From: Joonas Lahtinen @ 2019-02-26 12:17 UTC (permalink / raw)
  To: Alex Deucher; +Cc: Intel Graphics Development, Matthew Auld, dri-devel

Quoting Alex Deucher (2019-02-25 21:31:43)
> On Mon, Feb 25, 2019 at 9:35 PM Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com> wrote:
> >
> > Quoting Dave Airlie (2019-02-25 12:24:48)
> > > On Tue, 19 Feb 2019 at 23:32, Joonas Lahtinen
> > > <joonas.lahtinen@linux.intel.com> wrote:
> > > >
> > > > + dri-devel mailing list, especially for the buddy allocator part
> > > >
> > > > Quoting Dave Airlie (2019-02-15 02:47:07)
> > > > > On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
> > > > > >
> > > > > > In preparation for upcoming devices with device local memory, introduce the
> > > > > > concept of different memory regions, and a simple buddy allocator to manage
> > > > > > them.
> > > > >
> > > > > This is missing the information on why it's not TTM.
> > > > >
> > > > > Nothing against extending i915 gem off into doing stuff we already
> > > > > have examples off in tree, but before you do that it would be good to
> > > > > have a why we can't use TTM discussion in public.
> > > >
> > > > Glad that you asked. It's my fault that it was not included in
> > > > the cover letter. I anticipated the question, but was travelling
> > > > for a couple of days at the time this was sent. I didn't want
> > > > to write a hasty explanation and then disappear, leaving others to
> > > > take the heat.
> > > >
> > > > So here goes the less-hasty version:
> > > >
> > > > We did an analysis on the effort needed vs benefit gained of using
> > > > TTM when this was started initially. The conclusion was that we
> > > > already share the interesting bits of code through core DRM, really.
> > > >
> > > > Re-writing the memory handling to TTM would buy us more fine-grained
> > > > locking. But it's more a trait of rewriting the memory handling with
> > > > the information we have learned, than rewriting it to use TTM :)
> > > >
> > > > And further, we've been getting rid of struct_mutex at a steady phase
> > > > in the past years, so we have a clear path to the fine-grained locking
> > > > already in the not-so-distant future. With all this we did not see
> > > > much gained from converting over, as the code sharing is already
> > > > substantial.
> > > >
> > > > We also wanted to have the buddy allocator instead of a for loop making
> > > > drm_mm allocations to make sure we can keep the memory fragmentation
> > > > at bay. The intent is to move the buddy allocator to core DRM, to the
> > > > benefit of all the drivers, if there is interest from community. It has
> > > > been written as a strictly separate component with that in mind.
> > > >
> > > > And if you take the buddy allocator out of the patch set, the rest is
> > > > mostly just vfuncing things up to be able to have different backing
> > > > storages for objects. We took the opportunity to move over to the more
> > > > valgrind friendly mmap while touching things, but it's something we
> > > > have been contemplating anyway. And yeah, loads of selftests.
> > > >
> > > > That's really all that needed adding, and most of it is internal to
> > > > i915 and not to do with uAPI. This means porting over an userspace
> > > > driver doesn't require a substantial rewrite, but adding new a few
> > > > new IOCTLs to set the preferred backing storage placements.
> > > >
> > > > All the previous GEM abstractions keep applying, so we did not see
> > > > a justification to rewrite the kernel driver and userspace drivers.
> > > > It would have just to made things look like TTM, when we already
> > > > have the important parts of the code shared with TTM drivers
> > > > behind the GEM interfaces which all our drivers sit on top of.
> > >
> > > a) you guys should be the community as well, if the buddy allocator is
> > > useful in the core DRM get out there and try and see if anyone else
> > > has a use case for it, like the GPU scheduler we have now (can i915
> > > use that yet? :-)
> >
> > Well, the buddy allocator should be useful for anybody wishing to have
> > as continuous physical allocations as possible. I have naively assumed
> > that would be almost everyone. So it would be only a question if others
> > see the amount of work required to convert over is justified for them.
> >
> > For the common DRM scheduler, I think a solid move from the beginning
> > would have been to factor out the i915 scheduler as it was most advanced
> > in features :) Now there is a way more trivial common scheduler core with
> > no easy path to transition without a feature regression.
> 
> Can you elaborate?  What features are missing from the drm gpu scheduler?

Priority based pre-emption is the big thing coming to mind. But maybe we
should not derail the discussion in this thread. The discussion should
be in the archives, or we can start a new thread.

> > We'd have to rewrite many of the more advanced features for that codebase
> > before we could transition over. It's hard to justify such work, for
> > that it would buy us very little compared to amount of work.
> >
> > Situation would be different if there was something gained from
> > switching over. This would be the situation if the more advanced
> > scheduler was picked as the shared codebase.
> >
> > > b) however this last two paragraphs fill me with no confidence that
> > > you've looked at TTM at all. It sounds like you took comments about
> > > TTM made 10 years ago, and didn't update them. There should be no
> > > major reason for a uapi change just because you adopt TTM. TTM hasn't
> > > ever had a common uapi across drivers upstream, one was proposed
> > > initially > 10 years ago.
> >
> > This is one part my confusion on what the question was for and other
> > part bad wording on my behalf.
> >
> > So an attempt to re-answer: When this effort was started it was obvious
> > that the amount of new code required was low (as you can see). Feedback
> > about what converting to TTM would require vs. give us was gathered from
> > folks including Daniel and Chris and the unanimous decision was that it
> > would not be justifiable.
> >
> > > All the current TTM using drivers except
> > > vmware use a GEM based API as well. TTM is an internal driver helper
> > > for managing pools of RAM.
> > >
> > > I'm just not sure what rebuilding a chunk of shared code inside the
> > > i915 driver is buying you, except a transition path into divergence
> > > from all the other discrete RAM drivers.
> >
> > I guess what I'm trying to say, there isn't that much code being added
> > that wouldn't be there anyway. The i915 GEM code has already grown to
> > what it is before this.
> >
> > Adding the suggested smaller amount of code vs. doing a much bigger
> > rewrite is something of a straightforward choice with the amount of
> > platforms and features in flight, especially when the end result is
> > the same.
> 
> Because you will probably never do it.  It's almost always easier to
> just incrementally add on to existing code.  One could argue that GEM
> evolved into more or less the exact same thing as TTM anyway so why
> not bite the bullet and switch at some point?  TTM works fine even for
> UMA hardware.

By my understanding there are quite a few differences in low on memory
handling and other more subtle aspects between the two.
Converting over to TTM would be a pretty big rewrite of i915, and the
code sharing is already happening for important parts.

> > > Like the gallium aversion in
> > > userspace, having a TTM aversion in kernel space is going to be the
> > > wrong path, and I'd rather not have to clean it up in 5 years when you
> > > guys eventually realise it.
> > >
> > > The i915 GEM code get rewritten and refactored quite often
> >
> > Well, we continually try to improve things and accommodate upcoming
> > product requirements and hardware feature. The thing is that we do it
> > upstream first, so hard to avoid the churn.
> >
> > When moving rapidly, it's hard to project what the shared portion of
> > the code might be or exactly look. I'm myself much more believer in
> > extracting the generic portions out when the code is there and working.
> >
> > The churn would be even bigger if there is a strict requirement to
> > refactor the common parts out straight from the beginning, before
> > anything is even proven in practice.
> >
> > That'd just mean it gets much harder to sell doing things upstream
> > first to the management.
> 
> What does upstream first have to do with contributing to shared code?
> There is a common misconception in big companies that if you utilize
> shared infrastructure it will slow you down or you'll lose control of
> your code which is I think what you are referring to.

That'd be the wrong impression. Quite the contrary, the biggest chunk
of code here, buddy allocator, was written specifically with the fact
in mind that we can easily move it to DRM core.

And I think we have a solid track history of contributing to the DRM
core, so I'm not sure why you'd think that.

> Ultimately, it
> does sometimes raise the bar, but in the long term it benefits
> everyone and usually it doesn't really add that much overhead.

That we both agree on. But in the case of this specific patch series
it is about rewriting the driver to TTM, which is quite an overhead.

And if most of the important code is shared anyway through DRM core,
doing the rewrite + covering all the subtle differences, does not
sound too compelling.

> It
> sounds like you are just feeding that misconception; you can't
> contribute to or take advantage of any shared infrastructure because
> that might slow you down. If that is the case, then why does upstream
> first even matter?  It seems like the only common code you want to
> support is common code that you wrote in the first place.

That's not the case.

The scheduler code and GEM are the two things with most dependencies
everywhere in the i915 code. So it's not quite fair to generalize that
if we're not ripping those two out and rewriting the driver, we're not
contributing to shared infrastructure.

If there are some opportunities we've missed, I'm happy to be reminded.
I'd also like to mention that we have the dma-fence tracing and buddy
allocator patches (in this series) that could be of interest to have in
the shared infrastructure.

Regards, Joonas

> Alex
> 
> >
> > When the code is in place and working, and we still agree that more
> > code reuse could be beneficial, it will be more viable thing to do
> > when there are less moving parts.
> >
> > > and has a
> > > bus factor of ickle, if he decided to go elsewhere, you will have a
> > > pile of code that nobody gets, I think having a TTM backend would have
> > > a better long term effect on your driver maintainability.
> >
> > Well, as you might notice, the patches are not from ickle.
> >
> > I'm not saying we couldn't improve code sharing. I currently have a
> > priority in making sure we can enable the upcoming platforms, which has
> > a much more direct effect on our short and long term driver
> > maintainability through resourcing :)
> >
> > If the platform support is not there, it's hard to have the headcount
> > to work on refactoring the reusable parts of code out.
> >
> > So I'm hoping we can have an incremental approach to the code
> > refactorings suggested, that doesn't stall the delivery of the features.
> >
> > Regards, Joonas
> >
> > > Dave.
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
  2019-02-14 14:57 ` [RFC PATCH 04/42] drm/i915: introduce intel_memory_region Matthew Auld
  2019-02-14 15:16   ` Chris Wilson
@ 2019-02-26 13:00   ` Tvrtko Ursulin
  2019-02-26 14:20     ` Matthew Auld
  1 sibling, 1 reply; 97+ messages in thread
From: Tvrtko Ursulin @ 2019-02-26 13:00 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx


Hi,

Just some quick comments, not a full review. Possibly a repeat of some 
same comments from way back, not sure.

On 14/02/2019 14:57, Matthew Auld wrote:
> Support memory regions, as defined by a given (start, end), and allow
> creating GEM objects which are backed by said region.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/Makefile                 |   1 +
>   drivers/gpu/drm/i915/i915_drv.h               |   1 +
>   drivers/gpu/drm/i915/i915_gem.c               |   1 +
>   drivers/gpu/drm/i915/i915_gem_object.h        |   9 +
>   drivers/gpu/drm/i915/intel_memory_region.c    | 232 ++++++++++++++++++
>   drivers/gpu/drm/i915/intel_memory_region.h    | 126 ++++++++++
>   drivers/gpu/drm/i915/selftests/huge_pages.c   |  81 ++++++
>   .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
>   .../drm/i915/selftests/intel_memory_region.c  | 128 ++++++++++
>   .../gpu/drm/i915/selftests/mock_gem_device.c  |   1 +
>   drivers/gpu/drm/i915/selftests/mock_region.c  |  71 ++++++
>   drivers/gpu/drm/i915/selftests/mock_region.h  |  35 +++
>   12 files changed, 687 insertions(+)
>   create mode 100644 drivers/gpu/drm/i915/intel_memory_region.c
>   create mode 100644 drivers/gpu/drm/i915/intel_memory_region.h
>   create mode 100644 drivers/gpu/drm/i915/selftests/intel_memory_region.c
>   create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.c
>   create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index e5ce813d1936..96be264fa382 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -88,6 +88,7 @@ i915-y += \
>   	  intel_engine_cs.o \
>   	  intel_hangcheck.o \
>   	  intel_lrc.o \
> +	  intel_memory_region.o \
>   	  intel_mocs.o \
>   	  intel_ringbuffer.o \
>   	  intel_uncore.o \
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 17fe942eaafa..0bea7d889284 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -72,6 +72,7 @@
>   #include "intel_wopcm.h"
>   #include "intel_workarounds.h"
>   #include "intel_uc.h"
> +#include "intel_memory_region.h"
>   
>   #include "i915_gem.h"
>   #include "i915_gem_context.h"
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index b421bc7a2e26..92768ab294a4 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -5706,4 +5706,5 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
>   #include "selftests/i915_gem_object.c"
>   #include "selftests/i915_gem_coherency.c"
>   #include "selftests/i915_gem.c"
> +#include "selftests/intel_memory_region.c"
>   #endif
> diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
> index fab040331cdb..ac52f61e8ad1 100644
> --- a/drivers/gpu/drm/i915/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/i915_gem_object.h
> @@ -87,6 +87,15 @@ struct drm_i915_gem_object {
>   
>   	const struct drm_i915_gem_object_ops *ops;
>   
> +	/**
> +	 * Memory region for this object.
> +	 */
> +	struct intel_memory_region *memory_region;
> +	/**
> +	 * List of memory region blocks allocated for this object.
> +	 */
> +	struct list_head blocks;
> +
>   	struct {
>   		/**
>   		 * @vma.lock: protect the list/tree of vmas
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
> new file mode 100644
> index 000000000000..405d6d51194f
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_memory_region.c
> @@ -0,0 +1,232 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include "intel_memory_region.h"
> +#include "i915_drv.h"
> +
> +static void
> +memory_region_free_pages(struct drm_i915_gem_object *obj,
> +			 struct sg_table *pages)
> +{
> +
> +	struct i915_gem_buddy_block *block, *on;
> +
> +	lockdep_assert_held(&obj->memory_region->mm_lock);
> +
> +	list_for_each_entry_safe(block, on, &obj->blocks, link) {
> +		list_del_init(&block->link);
> +		i915_gem_buddy_free(&obj->memory_region->mm, block);
> +	}
> +
> +	sg_free_table(pages);
> +	kfree(pages);
> +}
> +
> +void
> +i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
> +				   struct sg_table *pages)
> +{
> +	mutex_lock(&obj->memory_region->mm_lock);
> +	memory_region_free_pages(obj, pages);
> +	mutex_unlock(&obj->memory_region->mm_lock);
> +
> +	obj->mm.dirty = false;
> +}
> +
> +int
> +i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
> +{
> +	struct intel_memory_region *mem = obj->memory_region;
> +	resource_size_t size = obj->base.size;
> +	struct sg_table *st;
> +	struct scatterlist *sg;
> +	unsigned int sg_page_sizes;
> +	unsigned long n_pages;
> +
> +	GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.min_size));
> +	GEM_BUG_ON(!list_empty(&obj->blocks));
> +
> +	st = kmalloc(sizeof(*st), GFP_KERNEL);
> +	if (!st)
> +		return -ENOMEM;
> +
> +	n_pages = div64_u64(size, mem->mm.min_size);
> +
> +	if (sg_alloc_table(st, n_pages, GFP_KERNEL)) {

sg_alloc_table takes unsigned int for nents so if you need to do this 
calculation in u64 you should probably add some checks against overflow. 
Although it would probably be simpler and more robust to have it as 
unsigned int and just check before hand the allocation request is not 
exceeding the sg_table API capabilities.

> +		kfree(st);
> +		return -ENOMEM;
> +	}
> +
> +	sg = st->sgl;
> +	st->nents = 0;
> +	sg_page_sizes = 0;
> +
> +	mutex_lock(&mem->mm_lock);
> +
> +	do {
> +		struct i915_gem_buddy_block *block;
> +		unsigned int order;
> +		u64 block_size;
> +		u64 offset;
> +
> +		order = fls(n_pages) - 1;
> +		GEM_BUG_ON(order > mem->mm.max_order);
> +
> +		do {
> +			block = i915_gem_buddy_alloc(&mem->mm, order);
> +			if (!IS_ERR(block))
> +				break;
> +
> +			/* XXX: some kind of eviction pass, local to the device */
> +			if (!order--)

Is it interesting to propagate the more specific error code returned by 
i915_gem_buddy_alloc?

> +				goto err_free_blocks;
> +		} while (1);
> +
> +		n_pages -= 1 << order;
> +
> +		INIT_LIST_HEAD(&block->link);
> +		list_add(&block->link, &obj->blocks);
> +
> +		block_size = i915_gem_buddy_block_size(&mem->mm, block);
> +		offset = i915_gem_buddy_block_offset(block);
> +
> +		sg_dma_address(sg) = mem->region.start + offset;
> +		sg_dma_len(sg) = block_size;
> +
> +		sg->length = block_size;

sg->dma_len and sg->length are unsigned int so again I think block_size 
can follow with some limit checking earlier on.

> +		sg_page_sizes |= block_size;
> +		st->nents++;

If address of this block is consecutive block to the previous one you 
can, considering the overflow of sg->dma_len and sg->length fields, 
coalesce the two by just bumping the lengths and not incrementing the 
st->nents++. That would make the i915_sg_trim below more effective. To 
be fair I have no idea how likely are you to get consecutive blocks with 
the buddy allocator so your decision.

Regards,

Tvrtko

> +
> +		if (!n_pages) {
> +			sg_mark_end(sg);
> +			break;
> +		}
> +
> +		sg = __sg_next(sg);
> +	} while (1);
> +
> +	mutex_unlock(&mem->mm_lock);
> +
> +	i915_sg_trim(st);
> +
> +	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
> +
> +	return 0;
> +
> +err_free_blocks:
> +	memory_region_free_pages(obj, st);
> +	mutex_unlock(&mem->mm_lock);
> +	return -ENOSPC;
> +}
> +
> +int i915_memory_region_init_buddy(struct intel_memory_region *mem)
> +{
> +	return i915_gem_buddy_init(&mem->mm, resource_size(&mem->region),
> +				   mem->min_page_size);
> +}
> +
> +void i915_memory_region_release_buddy(struct intel_memory_region *mem)
> +{
> +	i915_gem_buddy_fini(&mem->mm);
> +}
> +
> +struct drm_i915_gem_object *
> +i915_gem_object_create_region(struct intel_memory_region *mem,
> +			      resource_size_t size,
> +			      unsigned int flags)
> +{
> +	struct drm_i915_gem_object *obj;
> +
> +	if (!mem)
> +		return ERR_PTR(-ENODEV);
> +
> +	size = round_up(size, mem->min_page_size);
> +
> +	GEM_BUG_ON(!size);
> +	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
> +
> +	if (size >> PAGE_SHIFT > INT_MAX)
> +		return ERR_PTR(-E2BIG);
> +
> +	if (overflows_type(size, obj->base.size))
> +		return ERR_PTR(-E2BIG);
> +
> +	obj = mem->ops->object_create(mem, size, flags);
> +	if (IS_ERR(obj))
> +		return obj;
> +
> +	INIT_LIST_HEAD(&obj->blocks);
> +	obj->memory_region = mem;
> +
> +	i915_gem_object_set_cache_coherency(obj, obj->cache_level);
> +
> +	return obj;
> +}
> +
> +struct intel_memory_region *
> +intel_memory_region_create(struct drm_i915_private *i915,
> +			   resource_size_t start,
> +			   resource_size_t size,
> +			   resource_size_t min_page_size,
> +			   resource_size_t io_start,
> +			   const struct intel_memory_region_ops *ops)
> +{
> +	struct intel_memory_region *mem;
> +	int err;
> +
> +	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> +	if (!mem)
> +		return ERR_PTR(-ENOMEM);
> +
> +	mem->i915 = i915;
> +	mem->region = (struct resource)DEFINE_RES_MEM(start, size);
> +	mem->io_start = io_start;
> +	mem->min_page_size = min_page_size;
> +	mem->ops = ops;
> +
> +	mutex_init(&mem->mm_lock);
> +
> +	if (ops->init) {
> +		err = ops->init(mem);
> +		if (err) {
> +			kfree(mem);
> +			mem = ERR_PTR(err);
> +		}
> +	}
> +
> +	return mem;
> +}
> +
> +void
> +intel_memory_region_destroy(struct intel_memory_region *mem)
> +{
> +	if (mem->ops->release)
> +		mem->ops->release(mem);
> +
> +	kfree(mem);
> +}
> +
> +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> +#include "selftests/mock_region.c"
> +#endif
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
> new file mode 100644
> index 000000000000..6d8a954ca75e
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_memory_region.h
> @@ -0,0 +1,126 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#ifndef __INTEL_MEMORY_REGION_H__
> +#define __INTEL_MEMORY_REGION_H__
> +
> +#include <linux/ioport.h>
> +#include <linux/mutex.h>
> +#include <linux/io-mapping.h>
> +
> +#include "i915_gem_buddy.h"
> +
> +struct drm_i915_private;
> +struct drm_i915_gem_object;
> +struct intel_memory_region;
> +struct sg_table;
> +
> +/**
> + *  Base memory type
> + */
> +enum intel_memory_type {
> +	INTEL_SMEM = 0,
> +	INTEL_LMEM,
> +	INTEL_STOLEN,
> +};
> +
> +enum intel_region_id {
> +	INTEL_MEMORY_SMEM = 0,
> +	INTEL_MEMORY_LMEM,
> +	INTEL_MEMORY_STOLEN,
> +	INTEL_MEMORY_UKNOWN, /* Should be last */
> +};
> +
> +#define REGION_SMEM     BIT(INTEL_MEMORY_SMEM)
> +#define REGION_LMEM     BIT(INTEL_MEMORY_LMEM)
> +#define REGION_STOLEN   BIT(INTEL_MEMORY_STOLEN)
> +
> +#define INTEL_MEMORY_TYPE_SHIFT 16
> +
> +#define MEMORY_TYPE_FROM_REGION(r) (ilog2(r >> INTEL_MEMORY_TYPE_SHIFT))
> +#define MEMORY_INSTANCE_FROM_REGION(r) (ilog2(r & 0xffff))
> +
> +/**
> + * Memory regions encoded as type | instance
> + */
> +static const u32 intel_region_map[] = {
> +	[INTEL_MEMORY_SMEM] = BIT(INTEL_SMEM + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
> +	[INTEL_MEMORY_LMEM] = BIT(INTEL_LMEM + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
> +	[INTEL_MEMORY_STOLEN] = BIT(INTEL_STOLEN + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
> +};
> +
> +struct intel_memory_region_ops {
> +	unsigned int flags;
> +
> +	int (*init)(struct intel_memory_region *);
> +	void (*release)(struct intel_memory_region *);
> +
> +	struct drm_i915_gem_object *
> +	(*object_create)(struct intel_memory_region *,
> +			 resource_size_t,
> +			 unsigned int);
> +};
> +
> +struct intel_memory_region {
> +	struct drm_i915_private *i915;
> +
> +	const struct intel_memory_region_ops *ops;
> +
> +	struct io_mapping iomap;
> +	struct resource region;
> +
> +	struct i915_gem_buddy_mm mm;
> +	struct mutex mm_lock;
> +
> +	resource_size_t io_start;
> +	resource_size_t min_page_size;
> +
> +	unsigned int type;
> +	unsigned int instance;
> +	unsigned int id;
> +};
> +
> +int i915_memory_region_init_buddy(struct intel_memory_region *mem);
> +void i915_memory_region_release_buddy(struct intel_memory_region *mem);
> +
> +int i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj);
> +void i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
> +					struct sg_table *pages);
> +
> +struct intel_memory_region *
> +intel_memory_region_create(struct drm_i915_private *i915,
> +			   resource_size_t start,
> +			   resource_size_t size,
> +			   resource_size_t min_page_size,
> +			   resource_size_t io_start,
> +			   const struct intel_memory_region_ops *ops);
> +void
> +intel_memory_region_destroy(struct intel_memory_region *mem);
> +
> +struct drm_i915_gem_object *
> +i915_gem_object_create_region(struct intel_memory_region *mem,
> +			      resource_size_t size,
> +			      unsigned int flags);
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
> index b6d84939592b..b0c8b4955f14 100644
> --- a/drivers/gpu/drm/i915/selftests/huge_pages.c
> +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
> @@ -458,6 +458,86 @@ static int igt_mock_exhaust_device_supported_pages(void *arg)
>   	return err;
>   }
>   
> +
> +static int igt_mock_memory_region_huge_pages(void *arg)
> +{
> +	struct i915_hw_ppgtt *ppgtt = arg;
> +	struct drm_i915_private *i915 = ppgtt->vm.i915;
> +	unsigned long supported = INTEL_INFO(i915)->page_sizes;
> +	struct intel_memory_region *mem;
> +	struct drm_i915_gem_object *obj;
> +	struct i915_vma *vma;
> +	int bit;
> +	int err = 0;
> +
> +	mem = mock_region_create(i915, 0, SZ_2G,
> +				 I915_GTT_PAGE_SIZE_4K, 0);
> +	if (IS_ERR(mem)) {
> +		pr_err("failed to create memory region\n");
> +		return PTR_ERR(mem);
> +	}
> +
> +	for_each_set_bit(bit, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) {
> +		unsigned int page_size = BIT(bit);
> +		resource_size_t phys;
> +
> +		obj = i915_gem_object_create_region(mem, page_size, 0);
> +		if (IS_ERR(obj)) {
> +			err = PTR_ERR(obj);
> +			goto out_destroy_device;
> +		}
> +
> +		pr_info("memory region start(%pa)\n",
> +		        &obj->memory_region->region.start);
> +		pr_info("creating object, size=%x\n", page_size);
> +
> +		vma = i915_vma_instance(obj, &ppgtt->vm, NULL);
> +		if (IS_ERR(vma)) {
> +			err = PTR_ERR(vma);
> +			goto out_put;
> +		}
> +
> +		err = i915_vma_pin(vma, 0, 0, PIN_USER);
> +		if (err)
> +			goto out_close;
> +
> +		phys = i915_gem_object_get_dma_address(obj, 0);
> +		if (!IS_ALIGNED(phys, page_size)) {
> +			pr_err("memory region misaligned(%pa)\n", &phys);
> +			err = -EINVAL;
> +			goto out_close;
> +		}
> +
> +		if (vma->page_sizes.gtt != page_size) {
> +			pr_err("page_sizes.gtt=%u, expected=%u\n",
> +			       vma->page_sizes.gtt, page_size);
> +			err = -EINVAL;
> +			goto out_unpin;
> +		}
> +
> +		i915_vma_unpin(vma);
> +		i915_vma_close(vma);
> +
> +		i915_gem_object_put(obj);
> +	}
> +
> +	goto out_destroy_device;
> +
> +out_unpin:
> +	i915_vma_unpin(vma);
> +out_close:
> +	i915_vma_close(vma);
> +out_put:
> +	i915_gem_object_put(obj);
> +out_destroy_device:
> +	mutex_unlock(&i915->drm.struct_mutex);
> +	i915_gem_drain_freed_objects(i915);
> +	mutex_lock(&i915->drm.struct_mutex);
> +	intel_memory_region_destroy(mem);
> +
> +	return err;
> +}
> +
>   static int igt_mock_ppgtt_misaligned_dma(void *arg)
>   {
>   	struct i915_hw_ppgtt *ppgtt = arg;
> @@ -1697,6 +1777,7 @@ int i915_gem_huge_page_mock_selftests(void)
>   {
>   	static const struct i915_subtest tests[] = {
>   		SUBTEST(igt_mock_exhaust_device_supported_pages),
> +		SUBTEST(igt_mock_memory_region_huge_pages),
>   		SUBTEST(igt_mock_ppgtt_misaligned_dma),
>   		SUBTEST(igt_mock_ppgtt_huge_fill),
>   		SUBTEST(igt_mock_ppgtt_64K),
> diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> index 984e07ed65e5..3e34ee2255db 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> @@ -25,3 +25,4 @@ selftest(gtt, i915_gem_gtt_mock_selftests)
>   selftest(hugepages, i915_gem_huge_page_mock_selftests)
>   selftest(contexts, i915_gem_context_mock_selftests)
>   selftest(buddy, i915_gem_buddy_mock_selftests)
> +selftest(memory_region, intel_memory_region_mock_selftests)
> diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> new file mode 100644
> index 000000000000..2b8d28216d87
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> @@ -0,0 +1,128 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include "../i915_selftest.h"
> +
> +#include "mock_gem_device.h"
> +#include "mock_context.h"
> +#include "mock_drm.h"
> +
> +static void close_objects(struct list_head *objects)
> +{
> +	struct drm_i915_gem_object *obj, *on;
> +
> +	list_for_each_entry_safe(obj, on, objects, st_link) {
> +		if (i915_gem_object_has_pinned_pages(obj))
> +			i915_gem_object_unpin_pages(obj);
> +		/* No polluting the memory region between tests */
> +		__i915_gem_object_put_pages(obj, I915_MM_NORMAL);
> +		i915_gem_object_put(obj);
> +		list_del(&obj->st_link);
> +	}
> +}
> +
> +static int igt_mock_fill(void *arg)
> +{
> +	struct intel_memory_region *mem = arg;
> +	resource_size_t total = resource_size(&mem->region);
> +	resource_size_t page_size;
> +	resource_size_t rem;
> +	unsigned long max_pages;
> +	unsigned long page_num;
> +	LIST_HEAD(objects);
> +	int err = 0;
> +
> +	page_size = mem->mm.min_size;
> +	max_pages = total / page_size;
> +	rem = total;
> +
> +	for_each_prime_number_from(page_num, 1, max_pages) {
> +		resource_size_t size = page_num * page_size;
> +		struct drm_i915_gem_object *obj;
> +
> +		obj = i915_gem_object_create_region(mem, size, 0);
> +		if (IS_ERR(obj)) {
> +			err = PTR_ERR(obj);
> +			break;
> +		}
> +
> +		err = i915_gem_object_pin_pages(obj);
> +		if (err) {
> +			i915_gem_object_put(obj);
> +			break;
> +		}
> +
> +		list_add(&obj->st_link, &objects);
> +		rem -= size;
> +	}
> +
> +	if (err == -ENOMEM)
> +		err = 0;
> +	if (err == -ENOSPC) {
> +		if (page_num * page_size <= rem) {
> +			pr_err("igt_mock_fill failed, space still left in region\n");
> +			err = -EINVAL;
> +		} else {
> +			err = 0;
> +		}
> +	}
> +
> +	close_objects(&objects);
> +
> +	return err;
> +}
> +
> +int intel_memory_region_mock_selftests(void)
> +{
> +	static const struct i915_subtest tests[] = {
> +		SUBTEST(igt_mock_fill),
> +	};
> +	struct intel_memory_region *mem;
> +	struct drm_i915_private *i915;
> +	int err;
> +
> +	i915 = mock_gem_device();
> +	if (!i915)
> +		return -ENOMEM;
> +
> +	mem = mock_region_create(i915, 0, SZ_2G,
> +				 I915_GTT_PAGE_SIZE_4K, 0);
> +	if (IS_ERR(mem)) {
> +		pr_err("failed to create memory region\n");
> +		err = PTR_ERR(mem);
> +		goto out_unref;
> +	}
> +
> +	mutex_lock(&i915->drm.struct_mutex);
> +	err = i915_subtests(tests, mem);
> +	mutex_unlock(&i915->drm.struct_mutex);
> +
> +	i915_gem_drain_freed_objects(i915);
> +	intel_memory_region_destroy(mem);
> +
> +out_unref:
> +	drm_dev_put(&i915->drm);
> +
> +	return err;
> +}
> diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> index 876f4e6dadac..f8901cd12180 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> @@ -32,6 +32,7 @@
>   #include "mock_gem_object.h"
>   #include "mock_gtt.h"
>   #include "mock_uncore.h"
> +#include "mock_region.h"
>   
>   void mock_device_flush(struct drm_i915_private *i915)
>   {
> diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c
> new file mode 100644
> index 000000000000..2c83711f780d
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/selftests/mock_region.c
> @@ -0,0 +1,71 @@
> +/*
> + * Copyright © 2019 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include "mock_region.h"
> +
> +static const struct drm_i915_gem_object_ops mock_region_obj_ops = {
> +	.get_pages = i915_memory_region_get_pages_buddy,
> +	.put_pages = i915_memory_region_put_pages_buddy,
> +};
> +
> +static struct drm_i915_gem_object *
> +mock_object_create(struct intel_memory_region *mem,
> +		   resource_size_t size,
> +		   unsigned int flags)
> +{
> +	struct drm_i915_private *i915 = mem->i915;
> +	struct drm_i915_gem_object *obj;
> +
> +	if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
> +		return ERR_PTR(-E2BIG);
> +
> +	obj = i915_gem_object_alloc(i915);
> +	if (!obj)
> +		return ERR_PTR(-ENOMEM);
> +
> +	drm_gem_private_object_init(&i915->drm, &obj->base, size);
> +	i915_gem_object_init(obj, &mock_region_obj_ops);
> +
> +	obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
> +	obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
> +
> +	return obj;
> +}
> +
> +static const struct intel_memory_region_ops mock_region_ops = {
> +	.init = i915_memory_region_init_buddy,
> +	.release = i915_memory_region_release_buddy,
> +	.object_create = mock_object_create,
> +};
> +
> +struct intel_memory_region *
> +mock_region_create(struct drm_i915_private *i915,
> +		   resource_size_t start,
> +		   resource_size_t size,
> +		   resource_size_t min_page_size,
> +		   resource_size_t io_start)
> +{
> +	return intel_memory_region_create(i915, start, size, min_page_size,
> +					  io_start, &mock_region_ops);
> +}
> diff --git a/drivers/gpu/drm/i915/selftests/mock_region.h b/drivers/gpu/drm/i915/selftests/mock_region.h
> new file mode 100644
> index 000000000000..47718313fa58
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/selftests/mock_region.h
> @@ -0,0 +1,35 @@
> +/*
> + * Copyright © 2019 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#ifndef __MOCK_REGION_H
> +#define __MOCK_REGION_H
> +
> +struct intel_memory_region *
> +mock_region_create(struct drm_i915_private *i915,
> +		   resource_size_t start,
> +		   resource_size_t size,
> +		   resource_size_t min_page_size,
> +		   resource_size_t io_start);
> +
> +#endif /* !__MOCK_REGION_H */
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET
  2019-02-14 14:57 ` [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET Matthew Auld
  2019-02-14 16:05   ` Chris Wilson
@ 2019-02-26 13:34   ` Tvrtko Ursulin
  2019-02-26 13:37     ` Chris Wilson
  1 sibling, 1 reply; 97+ messages in thread
From: Tvrtko Ursulin @ 2019-02-26 13:34 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx


On 14/02/2019 14:57, Matthew Auld wrote:
> From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> 
> CPU mmap implementation depending on the object's backing pages.

depends?

> At the moment we introduce shmem and local-memory BAR fault handlers
> Note that the mmap type is done one at a time to circumvent the DRM
> offset manager limitation. Note that we multiplex mmap_gtt and

Perhaps it is time to sort out the offset manager? I have a feeling that 
would make things much easier/cleaner for us.

And I at least find mmap_origin a confusing term. It is nor a origin of 
a mapping, but location of object backing store what matters, right?

> mmap_offset through the same ioctl, and use the zero extending behaviour
> of drm to differentiate between them, when we inspect the flags.
> 
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/i915_drv.c        |  5 +-
>   drivers/gpu/drm/i915/i915_drv.h        |  3 +
>   drivers/gpu/drm/i915/i915_gem.c        | 94 ++++++++++++++++++++++----
>   drivers/gpu/drm/i915/i915_gem_object.h | 10 +++
>   include/uapi/drm/i915_drm.h            | 30 ++++++++
>   5 files changed, 126 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index b1200d7ebd13..90785030a0dd 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -423,6 +423,7 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
>   	case I915_PARAM_HAS_EXEC_CAPTURE:
>   	case I915_PARAM_HAS_EXEC_BATCH_FIRST:
>   	case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
> +	case I915_PARAM_MMAP_OFFSET_VERSION:
>   		/* For the time being all of these are always true;
>   		 * if some supported hardware does not have one of these
>   		 * features this value needs to be provided from
> @@ -2936,7 +2937,7 @@ const struct dev_pm_ops i915_pm_ops = {
>   static const struct vm_operations_struct i915_gem_vm_ops = {
>   	.fault = i915_gem_fault,
>   	.open = drm_gem_vm_open,
> -	.close = drm_gem_vm_close,
> +	.close = i915_gem_close,
>   };
>   
>   static const struct file_operations i915_driver_fops = {
> @@ -2991,7 +2992,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
>   	DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_OFFSET, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 065953a9264f..c6ae157d0ede 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2770,6 +2770,8 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
>   			struct drm_file *file_priv);
>   int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
>   			struct drm_file *file_priv);
> +int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
> +			       struct drm_file *file_priv);
>   int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
>   			      struct drm_file *file_priv);
>   int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
> @@ -3073,6 +3075,7 @@ void i915_gem_suspend_late(struct drm_i915_private *dev_priv);
>   void i915_gem_resume(struct drm_i915_private *dev_priv);
>   int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma);
>   vm_fault_t i915_gem_fault(struct vm_fault *vmf);
> +void i915_gem_close(struct vm_area_struct *vma);
>   int i915_gem_object_wait(struct drm_i915_gem_object *obj,
>   			 unsigned int flags,
>   			 long timeout);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 48dbb57fbc6d..cc6c88ec749d 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2123,11 +2123,12 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
>   	drm_gem_free_mmap_offset(&obj->base);
>   }
>   
> -int
> -i915_gem_mmap_gtt(struct drm_file *file,
> -		  struct drm_device *dev,
> -		  u32 handle,
> -		  u64 *offset)
> +static int
> +__assign_gem_object_mmap_data(struct drm_file *file,
> +			      u32 handle,
> +			      enum i915_cpu_mmap_origin_type mmap_type,
> +			      u64 mmap_flags,
> +			      u64 *offset)
>   {
>   	struct drm_i915_gem_object *obj;
>   	int ret;
> @@ -2136,14 +2137,35 @@ i915_gem_mmap_gtt(struct drm_file *file,
>   	if (!obj)
>   		return -ENOENT;
>   
> +	if (atomic_read(&obj->mmap_count) &&
> +	    obj->mmap_origin != mmap_type) {

What is the locking for mmap_count? Can it change state between first 
and second part of the conditional? If not, does it need to be atomic?

> +	        /* Re-map object with existing different map-type */
> +		ret = -EINVAL;

Would -EBUSY be a better fit?

> +		goto err;
> +	}
> +
>   	ret = i915_gem_object_create_mmap_offset(obj);

If mmap_count is greater than zero, and type/origin match, why a new 
offset is needed?

> -	if (ret == 0)
> +	if (ret == 0) {
> +		obj->mmap_origin = mmap_type;

Right, so why not obj->mmap_type as well?

> +		obj->mmap_flags = mmap_flags;
>   		*offset = drm_vma_node_offset_addr(&obj->base.vma_node);
> +	}
>   
> + err:
>   	i915_gem_object_put(obj);
>   	return ret;
>   }
>   
> +int
> +i915_gem_mmap_gtt(struct drm_file *file,
> +		  struct drm_device *dev,
> +		  u32 handle,
> +		  u64 *offset)
> +{
> +	return __assign_gem_object_mmap_data(file, handle, I915_MMAP_ORIGIN_GTT,
> +					     0, offset);
> +}

Is there a caller for this function at this point?

> +
>   /**
>    * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
>    * @dev: DRM device
> @@ -2163,9 +2185,45 @@ int
>   i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
>   			struct drm_file *file)
>   {
> -	struct drm_i915_gem_mmap_gtt *args = data;
> +	struct drm_i915_gem_mmap_offset *args = data;
> +	struct drm_i915_private *i915 = to_i915(dev);
> +
> +	if (args->flags & I915_MMAP_OFFSET_FLAGS)
> +		return i915_gem_mmap_offset_ioctl(dev, data, file);
> +
> +	if (!HAS_MAPPABLE_APERTURE(i915)) {
> +		DRM_ERROR("No aperture, cannot mmap via legacy GTT\n");

Maybe best to lose the DRM_ERROR since userspace can hammer on it and it 
is not really an error in the driver.

> +		return -ENODEV;
> +	}
> +
> +	return __assign_gem_object_mmap_data(file, args->handle,
> +					     I915_MMAP_ORIGIN_GTT,
> +					     0, &args->offset);
> +}
> +
> +int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
> +			       struct drm_file *file)
> +{
> +	struct drm_i915_gem_mmap_offset *args = data;
>   
> -	return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
> +	if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB)) &&
> +	    !boot_cpu_has(X86_FEATURE_PAT))
> +		return -ENODEV;
> +
> +        return __assign_gem_object_mmap_data(file, args->handle,
> +					     I915_MMAP_ORIGIN_OFFSET,
> +					     args->flags,
> +					     &args->offset);
> +}
> +
> +void i915_gem_close(struct vm_area_struct *vma)
> +{
> +	struct drm_gem_object *gem = vma->vm_private_data;
> +	struct drm_i915_gem_object *obj = to_intel_bo(gem);
> +
> +	atomic_dec(&obj->mmap_count);
> +
> +	drm_gem_vm_close(vma);
>   }
>   
>   int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
> @@ -2178,12 +2236,19 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
>   		return ret;
>   
>   	obj = to_intel_bo(vma->vm_private_data);
> -	if (obj->memory_region) {
> -		if (obj->mmap_origin == I915_MMAP_ORIGIN_OFFSET) {
> -			vma->vm_flags &= ~VM_PFNMAP;
> -			vma->vm_flags |= VM_MIXEDMAP;
> -		}
> +	if (obj->mmap_origin == I915_MMAP_ORIGIN_OFFSET) {
> +		vma->vm_flags &= ~VM_PFNMAP;
> +		vma->vm_flags |= VM_MIXEDMAP;
> +		if (obj->mmap_flags & I915_MMAP_OFFSET_WC)
> +			vma->vm_page_prot =
> +				pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
> +		else if (obj->mmap_flags & I915_MMAP_OFFSET_WB)
> +			vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
> +		else if (obj->mmap_flags & I915_MMAP_OFFSET_UC)
> +			vma->vm_page_prot =
> +				pgprot_noncached(vm_get_page_prot(vma->vm_flags));
>   	}
> +	atomic_inc(&obj->mmap_count);
>   
>   	return ret;
>   }
> @@ -4228,7 +4293,8 @@ int i915_gem_vmf_fill_pages_cpu(struct drm_i915_gem_object *obj,
>   	vm_fault_t vmf_ret;
>   	pgoff_t pg_off = (vmf->address - area->vm_start) >> PAGE_SHIFT;
>   
> -	if (HAS_MAPPABLE_APERTURE(dev_priv))
> +	if (HAS_MAPPABLE_APERTURE(dev_priv) &&
> +	    obj->mmap_origin == I915_MMAP_ORIGIN_GTT)
>   		return __vmf_fill_pages_gtt(obj, vmf, page_offset);
>   
>   	page = i915_gem_object_get_page(obj, pg_off);
> diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
> index 5c6bbe6f5e84..b37ffe2e17b6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/i915_gem_object.h
> @@ -86,6 +86,12 @@ struct drm_i915_gem_object_ops {
>   			      pgoff_t);
>   };
>   
> +enum i915_cpu_mmap_origin_type {

i915_mmap_type ?

> +	I915_MMAP_ORIGIN_NONE = 0,
> +	I915_MMAP_ORIGIN_GTT,
> +	I915_MMAP_ORIGIN_OFFSET,
> +};
> +
>   struct drm_i915_gem_object {
>   	struct drm_gem_object base;
>   
> @@ -157,6 +163,10 @@ struct drm_i915_gem_object {
>   	unsigned int userfault_count;
>   	struct list_head userfault_link;
>   
> +	enum i915_cpu_mmap_origin_type mmap_origin;
> +	atomic_t mmap_count;
> +	u64 mmap_flags;

Does mmap_flags need to be stored in the object? Is it not only used 
when setting up the mmap?

> +
>   	struct list_head batch_pool_link;
>   	I915_SELFTEST_DECLARE(struct list_head st_link);
>   
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 397810fa2d33..26d2274b5d2b 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -319,6 +319,7 @@ typedef struct _drm_i915_sarea {
>   #define DRM_I915_PERF_ADD_CONFIG	0x37
>   #define DRM_I915_PERF_REMOVE_CONFIG	0x38
>   #define DRM_I915_QUERY			0x39
> +#define DRM_I915_GEM_MMAP_OFFSET   	DRM_I915_GEM_MMAP_GTT
>   
>   #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
>   #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
> @@ -377,6 +378,7 @@ typedef struct _drm_i915_sarea {
>   #define DRM_IOCTL_I915_PERF_ADD_CONFIG	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
>   #define DRM_IOCTL_I915_PERF_REMOVE_CONFIG	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
>   #define DRM_IOCTL_I915_QUERY			DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
> +#define DRM_IOCTL_I915_GEM_MMAP_OFFSET		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_OFFSET, struct drm_i915_gem_mmap_offset)
>   
>   /* Allow drivers to submit batchbuffers directly to hardware, relying
>    * on the security mechanisms provided by hardware.
> @@ -559,6 +561,9 @@ typedef struct drm_i915_irq_wait {
>    */
>   #define I915_PARAM_MMAP_GTT_COHERENT	52
>   
> +/* Mmap offset ioctl */
> +#define I915_PARAM_MMAP_OFFSET_VERSION	55
> +
>   typedef struct drm_i915_getparam {
>   	__s32 param;
>   	/*
> @@ -731,6 +736,31 @@ struct drm_i915_gem_mmap_gtt {
>   	__u64 offset;
>   };
>   
> +struct drm_i915_gem_mmap_offset {
> +	/** Handle for the object being mapped. */
> +	__u32 handle;
> +	__u32 pad;
> +	/**
> +	 * Fake offset to use for subsequent mmap call
> +	 *
> +	 * This is a fixed-size type for 32/64 compatibility.
> +	 */
> +	__u64 offset;
> +
> +	/**
> +	 * Flags for extended behaviour.
> +	 *
> +	 * It is mandatory that either one of the _WC/_WB flags
> +	 * should be passed here.
> +	 */
> +	__u64 flags;
> +#define I915_MMAP_OFFSET_WC (1 << 0)
> +#define I915_MMAP_OFFSET_WB (1 << 1)
> +#define I915_MMAP_OFFSET_UC (1 << 2)

Add explicit GTT as well so userspace can use a single ioctl in all cases?

> +#define I915_MMAP_OFFSET_FLAGS \
> +	(I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB | I915_MMAP_OFFSET_UC)
> +};
> +
>   struct drm_i915_gem_set_domain {
>   	/** Handle for the object */
>   	__u32 handle;
> 
Regards,

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET
  2019-02-26 13:34   ` Tvrtko Ursulin
@ 2019-02-26 13:37     ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-26 13:37 UTC (permalink / raw)
  To: Matthew Auld, Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2019-02-26 13:34:51)
> 
> On 14/02/2019 14:57, Matthew Auld wrote:
> > From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> > 
> > CPU mmap implementation depending on the object's backing pages.
> 
> depends?
> 
> > At the moment we introduce shmem and local-memory BAR fault handlers
> > Note that the mmap type is done one at a time to circumvent the DRM
> > offset manager limitation. Note that we multiplex mmap_gtt and
> 
> Perhaps it is time to sort out the offset manager? I have a feeling that 
> would make things much easier/cleaner for us.

I had skipped the changelog and didn't realise that was being blamed
for getting mmaps so wrong...

I don't buy that excuse.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
  2019-02-14 15:16   ` Chris Wilson
@ 2019-02-26 14:03     ` Matthew Auld
  2019-02-26 14:18       ` Chris Wilson
  0 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-26 14:03 UTC (permalink / raw)
  To: Chris Wilson; +Cc: Intel Graphics Development, Matthew Auld

On Thu, 14 Feb 2019 at 15:16, Chris Wilson <chris@chris-wilson.co.uk> wrote:
>
> Quoting Matthew Auld (2019-02-14 14:57:02)
> > +int
> > +i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
> > +{
> > +       struct intel_memory_region *mem = obj->memory_region;
> > +       resource_size_t size = obj->base.size;
> > +       struct sg_table *st;
> > +       struct scatterlist *sg;
> > +       unsigned int sg_page_sizes;
> > +       unsigned long n_pages;
> > +
> > +       GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.min_size));
> > +       GEM_BUG_ON(!list_empty(&obj->blocks));
> > +
> > +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +       if (!st)
> > +               return -ENOMEM;
> > +
> > +       n_pages = div64_u64(size, mem->mm.min_size);
>
> min_size is a power of two.
>
> n_pages = size >> ilog2(min_size);
>
> would suffice. Keeping min_order would come in handy later.
>
> > +
> > +       if (sg_alloc_table(st, n_pages, GFP_KERNEL)) {
> > +               kfree(st);
> > +               return -ENOMEM;
> > +       }
> > +
> > +       sg = st->sgl;
> > +       st->nents = 0;
> > +       sg_page_sizes = 0;
> > +
> > +       mutex_lock(&mem->mm_lock);
> > +
> > +       do {
> > +               struct i915_gem_buddy_block *block;
> > +               unsigned int order;
> > +               u64 block_size;
> > +               u64 offset;
> > +
> > +               order = fls(n_pages) - 1;
> > +               GEM_BUG_ON(order > mem->mm.max_order);
> > +
> > +               do {
> > +                       block = i915_gem_buddy_alloc(&mem->mm, order);
> > +                       if (!IS_ERR(block))
> > +                               break;
> > +
> > +                       /* XXX: some kind of eviction pass, local to the device */
> > +                       if (!order--)
> > +                               goto err_free_blocks;
> > +               } while (1);
> > +
> > +               n_pages -= 1 << order;
>
> BIT(order) so you don't have sign extension fun. Need to fix
> i915_gem_internal.c!
>
> > +struct intel_memory_region_ops {
> > +       unsigned int flags;
> > +
> > +       int (*init)(struct intel_memory_region *);
> > +       void (*release)(struct intel_memory_region *);
> > +
> > +       struct drm_i915_gem_object *
> > +       (*object_create)(struct intel_memory_region *,
> > +                        resource_size_t,
> > +                        unsigned int);
>
> create_object()
>
> ops is acting as a factory here; and we are not operating on the object
> itself.
>
> > +static int igt_mock_fill(void *arg)
> > +{
> > +       struct intel_memory_region *mem = arg;
> > +       resource_size_t total = resource_size(&mem->region);
> > +       resource_size_t page_size;
> > +       resource_size_t rem;
> > +       unsigned long max_pages;
> > +       unsigned long page_num;
> > +       LIST_HEAD(objects);
> > +       int err = 0;
> > +
> > +       page_size = mem->mm.min_size;
> > +       max_pages = total / page_size;
>
> Hmm, 32b? Can resource_size_t be 64b on a 32b system?
>
> It must be to accommodate PAE.
>
> > +static struct drm_i915_gem_object *
> > +mock_object_create(struct intel_memory_region *mem,
> > +                  resource_size_t size,
> > +                  unsigned int flags)
> > +{
> > +       struct drm_i915_private *i915 = mem->i915;
> > +       struct drm_i915_gem_object *obj;
> > +
> > +       if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
>
> A mix of 64b and 32b types.
>
> if (size >> mem->mm.max_order + mem->mm.min_order)
>
> > +               return ERR_PTR(-E2BIG);
>
> GEM_BUG_ON(overflows_type(size, obj->base.size);
>
> > +       obj = i915_gem_object_alloc(i915);
> > +       if (!obj)
> > +               return ERR_PTR(-ENOMEM);
> > +
> > +       drm_gem_private_object_init(&i915->drm, &obj->base, size);
> > +       i915_gem_object_init(obj, &mock_region_obj_ops);
> > +
> > +       obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
> > +       obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
>
> i915_gem_object_set_cache_coherency() ?

We do that as part of object_create_region(), but maybe that's not so hot?

Also I just noticed that get_pages_buddy() returns -ENOSPC if we can't
satisfy the request, for consistency that should probably be -ENOMEM?

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
  2019-02-26 14:03     ` Matthew Auld
@ 2019-02-26 14:18       ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-26 14:18 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, Matthew Auld

Quoting Matthew Auld (2019-02-26 14:03:10)
> On Thu, 14 Feb 2019 at 15:16, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> >
> > Quoting Matthew Auld (2019-02-14 14:57:02)
> > > +int
> > > +i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
> > > +{
> > > +       struct intel_memory_region *mem = obj->memory_region;
> > > +       resource_size_t size = obj->base.size;
> > > +       struct sg_table *st;
> > > +       struct scatterlist *sg;
> > > +       unsigned int sg_page_sizes;
> > > +       unsigned long n_pages;
> > > +
> > > +       GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.min_size));
> > > +       GEM_BUG_ON(!list_empty(&obj->blocks));
> > > +
> > > +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > > +       if (!st)
> > > +               return -ENOMEM;
> > > +
> > > +       n_pages = div64_u64(size, mem->mm.min_size);
> >
> > min_size is a power of two.
> >
> > n_pages = size >> ilog2(min_size);
> >
> > would suffice. Keeping min_order would come in handy later.
> >
> > > +
> > > +       if (sg_alloc_table(st, n_pages, GFP_KERNEL)) {
> > > +               kfree(st);
> > > +               return -ENOMEM;
> > > +       }
> > > +
> > > +       sg = st->sgl;
> > > +       st->nents = 0;
> > > +       sg_page_sizes = 0;
> > > +
> > > +       mutex_lock(&mem->mm_lock);
> > > +
> > > +       do {
> > > +               struct i915_gem_buddy_block *block;
> > > +               unsigned int order;
> > > +               u64 block_size;
> > > +               u64 offset;
> > > +
> > > +               order = fls(n_pages) - 1;
> > > +               GEM_BUG_ON(order > mem->mm.max_order);
> > > +
> > > +               do {
> > > +                       block = i915_gem_buddy_alloc(&mem->mm, order);
> > > +                       if (!IS_ERR(block))
> > > +                               break;
> > > +
> > > +                       /* XXX: some kind of eviction pass, local to the device */
> > > +                       if (!order--)
> > > +                               goto err_free_blocks;
> > > +               } while (1);
> > > +
> > > +               n_pages -= 1 << order;
> >
> > BIT(order) so you don't have sign extension fun. Need to fix
> > i915_gem_internal.c!
> >
> > > +struct intel_memory_region_ops {
> > > +       unsigned int flags;
> > > +
> > > +       int (*init)(struct intel_memory_region *);
> > > +       void (*release)(struct intel_memory_region *);
> > > +
> > > +       struct drm_i915_gem_object *
> > > +       (*object_create)(struct intel_memory_region *,
> > > +                        resource_size_t,
> > > +                        unsigned int);
> >
> > create_object()
> >
> > ops is acting as a factory here; and we are not operating on the object
> > itself.
> >
> > > +static int igt_mock_fill(void *arg)
> > > +{
> > > +       struct intel_memory_region *mem = arg;
> > > +       resource_size_t total = resource_size(&mem->region);
> > > +       resource_size_t page_size;
> > > +       resource_size_t rem;
> > > +       unsigned long max_pages;
> > > +       unsigned long page_num;
> > > +       LIST_HEAD(objects);
> > > +       int err = 0;
> > > +
> > > +       page_size = mem->mm.min_size;
> > > +       max_pages = total / page_size;
> >
> > Hmm, 32b? Can resource_size_t be 64b on a 32b system?
> >
> > It must be to accommodate PAE.
> >
> > > +static struct drm_i915_gem_object *
> > > +mock_object_create(struct intel_memory_region *mem,
> > > +                  resource_size_t size,
> > > +                  unsigned int flags)
> > > +{
> > > +       struct drm_i915_private *i915 = mem->i915;
> > > +       struct drm_i915_gem_object *obj;
> > > +
> > > +       if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
> >
> > A mix of 64b and 32b types.
> >
> > if (size >> mem->mm.max_order + mem->mm.min_order)
> >
> > > +               return ERR_PTR(-E2BIG);
> >
> > GEM_BUG_ON(overflows_type(size, obj->base.size);
> >
> > > +       obj = i915_gem_object_alloc(i915);
> > > +       if (!obj)
> > > +               return ERR_PTR(-ENOMEM);
> > > +
> > > +       drm_gem_private_object_init(&i915->drm, &obj->base, size);
> > > +       i915_gem_object_init(obj, &mock_region_obj_ops);
> > > +
> > > +       obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
> > > +       obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
> >
> > i915_gem_object_set_cache_coherency() ?
> 
> We do that as part of object_create_region(), but maybe that's not so hot?

I think tidier done together; and maybe you'll feel inspired to clean up
it a bit more as well.

> Also I just noticed that get_pages_buddy() returns -ENOSPC if we can't
> satisfy the request, for consistency that should probably be -ENOMEM?

Yes. ENOSPC returned to userspace currently means "batch could not fit
into the GTT after all constraints applied", and since this errno can
propagate to execbuf, we should strive for uniqueness. In this case not
being able to find memory on the device... ENOMEM. Although -ENOXMEM
would be better to indicate we ran out of memory on the device. But that
doesn't exist, maybe -ENOBUFS?

If we restrict ourselves to errno-base.h (and I think we should try to);
ENOMEM or ENXIO.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
  2019-02-26 13:00   ` Tvrtko Ursulin
@ 2019-02-26 14:20     ` Matthew Auld
  0 siblings, 0 replies; 97+ messages in thread
From: Matthew Auld @ 2019-02-26 14:20 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: Intel Graphics Development, Matthew Auld

On Tue, 26 Feb 2019 at 13:00, Tvrtko Ursulin
<tvrtko.ursulin@linux.intel.com> wrote:
>
>
> Hi,
>
> Just some quick comments, not a full review. Possibly a repeat of some
> same comments from way back, not sure.
>
> On 14/02/2019 14:57, Matthew Auld wrote:
> > Support memory regions, as defined by a given (start, end), and allow
> > creating GEM objects which are backed by said region.
> >
> > Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> > Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > ---
> >   drivers/gpu/drm/i915/Makefile                 |   1 +
> >   drivers/gpu/drm/i915/i915_drv.h               |   1 +
> >   drivers/gpu/drm/i915/i915_gem.c               |   1 +
> >   drivers/gpu/drm/i915/i915_gem_object.h        |   9 +
> >   drivers/gpu/drm/i915/intel_memory_region.c    | 232 ++++++++++++++++++
> >   drivers/gpu/drm/i915/intel_memory_region.h    | 126 ++++++++++
> >   drivers/gpu/drm/i915/selftests/huge_pages.c   |  81 ++++++
> >   .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
> >   .../drm/i915/selftests/intel_memory_region.c  | 128 ++++++++++
> >   .../gpu/drm/i915/selftests/mock_gem_device.c  |   1 +
> >   drivers/gpu/drm/i915/selftests/mock_region.c  |  71 ++++++
> >   drivers/gpu/drm/i915/selftests/mock_region.h  |  35 +++
> >   12 files changed, 687 insertions(+)
> >   create mode 100644 drivers/gpu/drm/i915/intel_memory_region.c
> >   create mode 100644 drivers/gpu/drm/i915/intel_memory_region.h
> >   create mode 100644 drivers/gpu/drm/i915/selftests/intel_memory_region.c
> >   create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.c
> >   create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.h
> >
> > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> > index e5ce813d1936..96be264fa382 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -88,6 +88,7 @@ i915-y += \
> >         intel_engine_cs.o \
> >         intel_hangcheck.o \
> >         intel_lrc.o \
> > +       intel_memory_region.o \
> >         intel_mocs.o \
> >         intel_ringbuffer.o \
> >         intel_uncore.o \
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 17fe942eaafa..0bea7d889284 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -72,6 +72,7 @@
> >   #include "intel_wopcm.h"
> >   #include "intel_workarounds.h"
> >   #include "intel_uc.h"
> > +#include "intel_memory_region.h"
> >
> >   #include "i915_gem.h"
> >   #include "i915_gem_context.h"
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index b421bc7a2e26..92768ab294a4 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -5706,4 +5706,5 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
> >   #include "selftests/i915_gem_object.c"
> >   #include "selftests/i915_gem_coherency.c"
> >   #include "selftests/i915_gem.c"
> > +#include "selftests/intel_memory_region.c"
> >   #endif
> > diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
> > index fab040331cdb..ac52f61e8ad1 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_object.h
> > +++ b/drivers/gpu/drm/i915/i915_gem_object.h
> > @@ -87,6 +87,15 @@ struct drm_i915_gem_object {
> >
> >       const struct drm_i915_gem_object_ops *ops;
> >
> > +     /**
> > +      * Memory region for this object.
> > +      */
> > +     struct intel_memory_region *memory_region;
> > +     /**
> > +      * List of memory region blocks allocated for this object.
> > +      */
> > +     struct list_head blocks;
> > +
> >       struct {
> >               /**
> >                * @vma.lock: protect the list/tree of vmas
> > diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
> > new file mode 100644
> > index 000000000000..405d6d51194f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/intel_memory_region.c
> > @@ -0,0 +1,232 @@
> > +/*
> > + * Copyright © 2018 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#include "intel_memory_region.h"
> > +#include "i915_drv.h"
> > +
> > +static void
> > +memory_region_free_pages(struct drm_i915_gem_object *obj,
> > +                      struct sg_table *pages)
> > +{
> > +
> > +     struct i915_gem_buddy_block *block, *on;
> > +
> > +     lockdep_assert_held(&obj->memory_region->mm_lock);
> > +
> > +     list_for_each_entry_safe(block, on, &obj->blocks, link) {
> > +             list_del_init(&block->link);
> > +             i915_gem_buddy_free(&obj->memory_region->mm, block);
> > +     }
> > +
> > +     sg_free_table(pages);
> > +     kfree(pages);
> > +}
> > +
> > +void
> > +i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
> > +                                struct sg_table *pages)
> > +{
> > +     mutex_lock(&obj->memory_region->mm_lock);
> > +     memory_region_free_pages(obj, pages);
> > +     mutex_unlock(&obj->memory_region->mm_lock);
> > +
> > +     obj->mm.dirty = false;
> > +}
> > +
> > +int
> > +i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)
> > +{
> > +     struct intel_memory_region *mem = obj->memory_region;
> > +     resource_size_t size = obj->base.size;
> > +     struct sg_table *st;
> > +     struct scatterlist *sg;
> > +     unsigned int sg_page_sizes;
> > +     unsigned long n_pages;
> > +
> > +     GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.min_size));
> > +     GEM_BUG_ON(!list_empty(&obj->blocks));
> > +
> > +     st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +     if (!st)
> > +             return -ENOMEM;
> > +
> > +     n_pages = div64_u64(size, mem->mm.min_size);
> > +
> > +     if (sg_alloc_table(st, n_pages, GFP_KERNEL)) {
>
> sg_alloc_table takes unsigned int for nents so if you need to do this
> calculation in u64 you should probably add some checks against overflow.
> Although it would probably be simpler and more robust to have it as
> unsigned int and just check before hand the allocation request is not
> exceeding the sg_table API capabilities.

Yeah, the type stuff here is a little odd, but we do make sure that
the number of pages doesn't exceed INT_MAX at object creation.

>
> > +             kfree(st);
> > +             return -ENOMEM;
> > +     }
> > +
> > +     sg = st->sgl;
> > +     st->nents = 0;
> > +     sg_page_sizes = 0;
> > +
> > +     mutex_lock(&mem->mm_lock);
> > +
> > +     do {
> > +             struct i915_gem_buddy_block *block;
> > +             unsigned int order;
> > +             u64 block_size;
> > +             u64 offset;
> > +
> > +             order = fls(n_pages) - 1;
> > +             GEM_BUG_ON(order > mem->mm.max_order);
> > +
> > +             do {
> > +                     block = i915_gem_buddy_alloc(&mem->mm, order);
> > +                     if (!IS_ERR(block))
> > +                             break;
> > +
> > +                     /* XXX: some kind of eviction pass, local to the device */
> > +                     if (!order--)
>
> Is it interesting to propagate the more specific error code returned by
> i915_gem_buddy_alloc?

It will either return -ENOMEM or -ENOSPC, although I'm now wondering
if returning -ENOSPC from get_pages() is a bad idea. We normally just
return -ENOMEM if we can't satisfy the request for the other
backends...

>
> > +                             goto err_free_blocks;
> > +             } while (1);
> > +
> > +             n_pages -= 1 << order;
> > +
> > +             INIT_LIST_HEAD(&block->link);
> > +             list_add(&block->link, &obj->blocks);
> > +
> > +             block_size = i915_gem_buddy_block_size(&mem->mm, block);
> > +             offset = i915_gem_buddy_block_offset(block);
> > +
> > +             sg_dma_address(sg) = mem->region.start + offset;
> > +             sg_dma_len(sg) = block_size;
> > +
> > +             sg->length = block_size;
>
> sg->dma_len and sg->length are unsigned int so again I think block_size
> can follow with some limit checking earlier on.
>
> > +             sg_page_sizes |= block_size;
> > +             st->nents++;
>
> If address of this block is consecutive block to the previous one you
> can, considering the overflow of sg->dma_len and sg->length fields,
> coalesce the two by just bumping the lengths and not incrementing the
> st->nents++. That would make the i915_sg_trim below more effective. To
> be fair I have no idea how likely are you to get consecutive blocks with
> the buddy allocator so your decision.

Yup, makes sense.

>
> Regards,
>
> Tvrtko
>
> > +
> > +             if (!n_pages) {
> > +                     sg_mark_end(sg);
> > +                     break;
> > +             }
> > +
> > +             sg = __sg_next(sg);
> > +     } while (1);
> > +
> > +     mutex_unlock(&mem->mm_lock);
> > +
> > +     i915_sg_trim(st);
> > +
> > +     __i915_gem_object_set_pages(obj, st, sg_page_sizes);
> > +
> > +     return 0;
> > +
> > +err_free_blocks:
> > +     memory_region_free_pages(obj, st);
> > +     mutex_unlock(&mem->mm_lock);
> > +     return -ENOSPC;
> > +}
> > +
> > +int i915_memory_region_init_buddy(struct intel_memory_region *mem)
> > +{
> > +     return i915_gem_buddy_init(&mem->mm, resource_size(&mem->region),
> > +                                mem->min_page_size);
> > +}
> > +
> > +void i915_memory_region_release_buddy(struct intel_memory_region *mem)
> > +{
> > +     i915_gem_buddy_fini(&mem->mm);
> > +}
> > +
> > +struct drm_i915_gem_object *
> > +i915_gem_object_create_region(struct intel_memory_region *mem,
> > +                           resource_size_t size,
> > +                           unsigned int flags)
> > +{
> > +     struct drm_i915_gem_object *obj;
> > +
> > +     if (!mem)
> > +             return ERR_PTR(-ENODEV);
> > +
> > +     size = round_up(size, mem->min_page_size);
> > +
> > +     GEM_BUG_ON(!size);
> > +     GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
> > +
> > +     if (size >> PAGE_SHIFT > INT_MAX)
> > +             return ERR_PTR(-E2BIG);
> > +
> > +     if (overflows_type(size, obj->base.size))
> > +             return ERR_PTR(-E2BIG);
> > +
> > +     obj = mem->ops->object_create(mem, size, flags);
> > +     if (IS_ERR(obj))
> > +             return obj;
> > +
> > +     INIT_LIST_HEAD(&obj->blocks);
> > +     obj->memory_region = mem;
> > +
> > +     i915_gem_object_set_cache_coherency(obj, obj->cache_level);
> > +
> > +     return obj;
> > +}
> > +
> > +struct intel_memory_region *
> > +intel_memory_region_create(struct drm_i915_private *i915,
> > +                        resource_size_t start,
> > +                        resource_size_t size,
> > +                        resource_size_t min_page_size,
> > +                        resource_size_t io_start,
> > +                        const struct intel_memory_region_ops *ops)
> > +{
> > +     struct intel_memory_region *mem;
> > +     int err;
> > +
> > +     mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> > +     if (!mem)
> > +             return ERR_PTR(-ENOMEM);
> > +
> > +     mem->i915 = i915;
> > +     mem->region = (struct resource)DEFINE_RES_MEM(start, size);
> > +     mem->io_start = io_start;
> > +     mem->min_page_size = min_page_size;
> > +     mem->ops = ops;
> > +
> > +     mutex_init(&mem->mm_lock);
> > +
> > +     if (ops->init) {
> > +             err = ops->init(mem);
> > +             if (err) {
> > +                     kfree(mem);
> > +                     mem = ERR_PTR(err);
> > +             }
> > +     }
> > +
> > +     return mem;
> > +}
> > +
> > +void
> > +intel_memory_region_destroy(struct intel_memory_region *mem)
> > +{
> > +     if (mem->ops->release)
> > +             mem->ops->release(mem);
> > +
> > +     kfree(mem);
> > +}
> > +
> > +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> > +#include "selftests/mock_region.c"
> > +#endif
> > diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
> > new file mode 100644
> > index 000000000000..6d8a954ca75e
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/intel_memory_region.h
> > @@ -0,0 +1,126 @@
> > +/*
> > + * Copyright © 2018 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#ifndef __INTEL_MEMORY_REGION_H__
> > +#define __INTEL_MEMORY_REGION_H__
> > +
> > +#include <linux/ioport.h>
> > +#include <linux/mutex.h>
> > +#include <linux/io-mapping.h>
> > +
> > +#include "i915_gem_buddy.h"
> > +
> > +struct drm_i915_private;
> > +struct drm_i915_gem_object;
> > +struct intel_memory_region;
> > +struct sg_table;
> > +
> > +/**
> > + *  Base memory type
> > + */
> > +enum intel_memory_type {
> > +     INTEL_SMEM = 0,
> > +     INTEL_LMEM,
> > +     INTEL_STOLEN,
> > +};
> > +
> > +enum intel_region_id {
> > +     INTEL_MEMORY_SMEM = 0,
> > +     INTEL_MEMORY_LMEM,
> > +     INTEL_MEMORY_STOLEN,
> > +     INTEL_MEMORY_UKNOWN, /* Should be last */
> > +};
> > +
> > +#define REGION_SMEM     BIT(INTEL_MEMORY_SMEM)
> > +#define REGION_LMEM     BIT(INTEL_MEMORY_LMEM)
> > +#define REGION_STOLEN   BIT(INTEL_MEMORY_STOLEN)
> > +
> > +#define INTEL_MEMORY_TYPE_SHIFT 16
> > +
> > +#define MEMORY_TYPE_FROM_REGION(r) (ilog2(r >> INTEL_MEMORY_TYPE_SHIFT))
> > +#define MEMORY_INSTANCE_FROM_REGION(r) (ilog2(r & 0xffff))
> > +
> > +/**
> > + * Memory regions encoded as type | instance
> > + */
> > +static const u32 intel_region_map[] = {
> > +     [INTEL_MEMORY_SMEM] = BIT(INTEL_SMEM + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
> > +     [INTEL_MEMORY_LMEM] = BIT(INTEL_LMEM + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
> > +     [INTEL_MEMORY_STOLEN] = BIT(INTEL_STOLEN + INTEL_MEMORY_TYPE_SHIFT) | BIT(0),
> > +};
> > +
> > +struct intel_memory_region_ops {
> > +     unsigned int flags;
> > +
> > +     int (*init)(struct intel_memory_region *);
> > +     void (*release)(struct intel_memory_region *);
> > +
> > +     struct drm_i915_gem_object *
> > +     (*object_create)(struct intel_memory_region *,
> > +                      resource_size_t,
> > +                      unsigned int);
> > +};
> > +
> > +struct intel_memory_region {
> > +     struct drm_i915_private *i915;
> > +
> > +     const struct intel_memory_region_ops *ops;
> > +
> > +     struct io_mapping iomap;
> > +     struct resource region;
> > +
> > +     struct i915_gem_buddy_mm mm;
> > +     struct mutex mm_lock;
> > +
> > +     resource_size_t io_start;
> > +     resource_size_t min_page_size;
> > +
> > +     unsigned int type;
> > +     unsigned int instance;
> > +     unsigned int id;
> > +};
> > +
> > +int i915_memory_region_init_buddy(struct intel_memory_region *mem);
> > +void i915_memory_region_release_buddy(struct intel_memory_region *mem);
> > +
> > +int i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj);
> > +void i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
> > +                                     struct sg_table *pages);
> > +
> > +struct intel_memory_region *
> > +intel_memory_region_create(struct drm_i915_private *i915,
> > +                        resource_size_t start,
> > +                        resource_size_t size,
> > +                        resource_size_t min_page_size,
> > +                        resource_size_t io_start,
> > +                        const struct intel_memory_region_ops *ops);
> > +void
> > +intel_memory_region_destroy(struct intel_memory_region *mem);
> > +
> > +struct drm_i915_gem_object *
> > +i915_gem_object_create_region(struct intel_memory_region *mem,
> > +                           resource_size_t size,
> > +                           unsigned int flags);
> > +
> > +#endif
> > diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
> > index b6d84939592b..b0c8b4955f14 100644
> > --- a/drivers/gpu/drm/i915/selftests/huge_pages.c
> > +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
> > @@ -458,6 +458,86 @@ static int igt_mock_exhaust_device_supported_pages(void *arg)
> >       return err;
> >   }
> >
> > +
> > +static int igt_mock_memory_region_huge_pages(void *arg)
> > +{
> > +     struct i915_hw_ppgtt *ppgtt = arg;
> > +     struct drm_i915_private *i915 = ppgtt->vm.i915;
> > +     unsigned long supported = INTEL_INFO(i915)->page_sizes;
> > +     struct intel_memory_region *mem;
> > +     struct drm_i915_gem_object *obj;
> > +     struct i915_vma *vma;
> > +     int bit;
> > +     int err = 0;
> > +
> > +     mem = mock_region_create(i915, 0, SZ_2G,
> > +                              I915_GTT_PAGE_SIZE_4K, 0);
> > +     if (IS_ERR(mem)) {
> > +             pr_err("failed to create memory region\n");
> > +             return PTR_ERR(mem);
> > +     }
> > +
> > +     for_each_set_bit(bit, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) {
> > +             unsigned int page_size = BIT(bit);
> > +             resource_size_t phys;
> > +
> > +             obj = i915_gem_object_create_region(mem, page_size, 0);
> > +             if (IS_ERR(obj)) {
> > +                     err = PTR_ERR(obj);
> > +                     goto out_destroy_device;
> > +             }
> > +
> > +             pr_info("memory region start(%pa)\n",
> > +                     &obj->memory_region->region.start);
> > +             pr_info("creating object, size=%x\n", page_size);
> > +
> > +             vma = i915_vma_instance(obj, &ppgtt->vm, NULL);
> > +             if (IS_ERR(vma)) {
> > +                     err = PTR_ERR(vma);
> > +                     goto out_put;
> > +             }
> > +
> > +             err = i915_vma_pin(vma, 0, 0, PIN_USER);
> > +             if (err)
> > +                     goto out_close;
> > +
> > +             phys = i915_gem_object_get_dma_address(obj, 0);
> > +             if (!IS_ALIGNED(phys, page_size)) {
> > +                     pr_err("memory region misaligned(%pa)\n", &phys);
> > +                     err = -EINVAL;
> > +                     goto out_close;
> > +             }
> > +
> > +             if (vma->page_sizes.gtt != page_size) {
> > +                     pr_err("page_sizes.gtt=%u, expected=%u\n",
> > +                            vma->page_sizes.gtt, page_size);
> > +                     err = -EINVAL;
> > +                     goto out_unpin;
> > +             }
> > +
> > +             i915_vma_unpin(vma);
> > +             i915_vma_close(vma);
> > +
> > +             i915_gem_object_put(obj);
> > +     }
> > +
> > +     goto out_destroy_device;
> > +
> > +out_unpin:
> > +     i915_vma_unpin(vma);
> > +out_close:
> > +     i915_vma_close(vma);
> > +out_put:
> > +     i915_gem_object_put(obj);
> > +out_destroy_device:
> > +     mutex_unlock(&i915->drm.struct_mutex);
> > +     i915_gem_drain_freed_objects(i915);
> > +     mutex_lock(&i915->drm.struct_mutex);
> > +     intel_memory_region_destroy(mem);
> > +
> > +     return err;
> > +}
> > +
> >   static int igt_mock_ppgtt_misaligned_dma(void *arg)
> >   {
> >       struct i915_hw_ppgtt *ppgtt = arg;
> > @@ -1697,6 +1777,7 @@ int i915_gem_huge_page_mock_selftests(void)
> >   {
> >       static const struct i915_subtest tests[] = {
> >               SUBTEST(igt_mock_exhaust_device_supported_pages),
> > +             SUBTEST(igt_mock_memory_region_huge_pages),
> >               SUBTEST(igt_mock_ppgtt_misaligned_dma),
> >               SUBTEST(igt_mock_ppgtt_huge_fill),
> >               SUBTEST(igt_mock_ppgtt_64K),
> > diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> > index 984e07ed65e5..3e34ee2255db 100644
> > --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> > +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
> > @@ -25,3 +25,4 @@ selftest(gtt, i915_gem_gtt_mock_selftests)
> >   selftest(hugepages, i915_gem_huge_page_mock_selftests)
> >   selftest(contexts, i915_gem_context_mock_selftests)
> >   selftest(buddy, i915_gem_buddy_mock_selftests)
> > +selftest(memory_region, intel_memory_region_mock_selftests)
> > diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> > new file mode 100644
> > index 000000000000..2b8d28216d87
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> > @@ -0,0 +1,128 @@
> > +/*
> > + * Copyright © 2018 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#include "../i915_selftest.h"
> > +
> > +#include "mock_gem_device.h"
> > +#include "mock_context.h"
> > +#include "mock_drm.h"
> > +
> > +static void close_objects(struct list_head *objects)
> > +{
> > +     struct drm_i915_gem_object *obj, *on;
> > +
> > +     list_for_each_entry_safe(obj, on, objects, st_link) {
> > +             if (i915_gem_object_has_pinned_pages(obj))
> > +                     i915_gem_object_unpin_pages(obj);
> > +             /* No polluting the memory region between tests */
> > +             __i915_gem_object_put_pages(obj, I915_MM_NORMAL);
> > +             i915_gem_object_put(obj);
> > +             list_del(&obj->st_link);
> > +     }
> > +}
> > +
> > +static int igt_mock_fill(void *arg)
> > +{
> > +     struct intel_memory_region *mem = arg;
> > +     resource_size_t total = resource_size(&mem->region);
> > +     resource_size_t page_size;
> > +     resource_size_t rem;
> > +     unsigned long max_pages;
> > +     unsigned long page_num;
> > +     LIST_HEAD(objects);
> > +     int err = 0;
> > +
> > +     page_size = mem->mm.min_size;
> > +     max_pages = total / page_size;
> > +     rem = total;
> > +
> > +     for_each_prime_number_from(page_num, 1, max_pages) {
> > +             resource_size_t size = page_num * page_size;
> > +             struct drm_i915_gem_object *obj;
> > +
> > +             obj = i915_gem_object_create_region(mem, size, 0);
> > +             if (IS_ERR(obj)) {
> > +                     err = PTR_ERR(obj);
> > +                     break;
> > +             }
> > +
> > +             err = i915_gem_object_pin_pages(obj);
> > +             if (err) {
> > +                     i915_gem_object_put(obj);
> > +                     break;
> > +             }
> > +
> > +             list_add(&obj->st_link, &objects);
> > +             rem -= size;
> > +     }
> > +
> > +     if (err == -ENOMEM)
> > +             err = 0;
> > +     if (err == -ENOSPC) {
> > +             if (page_num * page_size <= rem) {
> > +                     pr_err("igt_mock_fill failed, space still left in region\n");
> > +                     err = -EINVAL;
> > +             } else {
> > +                     err = 0;
> > +             }
> > +     }
> > +
> > +     close_objects(&objects);
> > +
> > +     return err;
> > +}
> > +
> > +int intel_memory_region_mock_selftests(void)
> > +{
> > +     static const struct i915_subtest tests[] = {
> > +             SUBTEST(igt_mock_fill),
> > +     };
> > +     struct intel_memory_region *mem;
> > +     struct drm_i915_private *i915;
> > +     int err;
> > +
> > +     i915 = mock_gem_device();
> > +     if (!i915)
> > +             return -ENOMEM;
> > +
> > +     mem = mock_region_create(i915, 0, SZ_2G,
> > +                              I915_GTT_PAGE_SIZE_4K, 0);
> > +     if (IS_ERR(mem)) {
> > +             pr_err("failed to create memory region\n");
> > +             err = PTR_ERR(mem);
> > +             goto out_unref;
> > +     }
> > +
> > +     mutex_lock(&i915->drm.struct_mutex);
> > +     err = i915_subtests(tests, mem);
> > +     mutex_unlock(&i915->drm.struct_mutex);
> > +
> > +     i915_gem_drain_freed_objects(i915);
> > +     intel_memory_region_destroy(mem);
> > +
> > +out_unref:
> > +     drm_dev_put(&i915->drm);
> > +
> > +     return err;
> > +}
> > diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> > index 876f4e6dadac..f8901cd12180 100644
> > --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> > +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> > @@ -32,6 +32,7 @@
> >   #include "mock_gem_object.h"
> >   #include "mock_gtt.h"
> >   #include "mock_uncore.h"
> > +#include "mock_region.h"
> >
> >   void mock_device_flush(struct drm_i915_private *i915)
> >   {
> > diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c
> > new file mode 100644
> > index 000000000000..2c83711f780d
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/selftests/mock_region.c
> > @@ -0,0 +1,71 @@
> > +/*
> > + * Copyright © 2019 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#include "mock_region.h"
> > +
> > +static const struct drm_i915_gem_object_ops mock_region_obj_ops = {
> > +     .get_pages = i915_memory_region_get_pages_buddy,
> > +     .put_pages = i915_memory_region_put_pages_buddy,
> > +};
> > +
> > +static struct drm_i915_gem_object *
> > +mock_object_create(struct intel_memory_region *mem,
> > +                resource_size_t size,
> > +                unsigned int flags)
> > +{
> > +     struct drm_i915_private *i915 = mem->i915;
> > +     struct drm_i915_gem_object *obj;
> > +
> > +     if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
> > +             return ERR_PTR(-E2BIG);
> > +
> > +     obj = i915_gem_object_alloc(i915);
> > +     if (!obj)
> > +             return ERR_PTR(-ENOMEM);
> > +
> > +     drm_gem_private_object_init(&i915->drm, &obj->base, size);
> > +     i915_gem_object_init(obj, &mock_region_obj_ops);
> > +
> > +     obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
> > +     obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
> > +
> > +     return obj;
> > +}
> > +
> > +static const struct intel_memory_region_ops mock_region_ops = {
> > +     .init = i915_memory_region_init_buddy,
> > +     .release = i915_memory_region_release_buddy,
> > +     .object_create = mock_object_create,
> > +};
> > +
> > +struct intel_memory_region *
> > +mock_region_create(struct drm_i915_private *i915,
> > +                resource_size_t start,
> > +                resource_size_t size,
> > +                resource_size_t min_page_size,
> > +                resource_size_t io_start)
> > +{
> > +     return intel_memory_region_create(i915, start, size, min_page_size,
> > +                                       io_start, &mock_region_ops);
> > +}
> > diff --git a/drivers/gpu/drm/i915/selftests/mock_region.h b/drivers/gpu/drm/i915/selftests/mock_region.h
> > new file mode 100644
> > index 000000000000..47718313fa58
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/selftests/mock_region.h
> > @@ -0,0 +1,35 @@
> > +/*
> > + * Copyright © 2019 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#ifndef __MOCK_REGION_H
> > +#define __MOCK_REGION_H
> > +
> > +struct intel_memory_region *
> > +mock_region_create(struct drm_i915_private *i915,
> > +                resource_size_t start,
> > +                resource_size_t size,
> > +                resource_size_t min_page_size,
> > +                resource_size_t io_start);
> > +
> > +#endif /* !__MOCK_REGION_H */
> >
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 05/42] drm/i915/region: support basic eviction
  2019-02-14 15:25   ` Chris Wilson
@ 2019-02-26 14:58     ` Matthew Auld
  2019-02-26 16:49       ` Chris Wilson
  0 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-26 14:58 UTC (permalink / raw)
  To: Chris Wilson; +Cc: Intel Graphics Development, Matthew Auld

On Thu, 14 Feb 2019 at 15:25, Chris Wilson <chris@chris-wilson.co.uk> wrote:
>
> Quoting Matthew Auld (2019-02-14 14:57:03)
> > Support basic eviction for regions.
> >
> > Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h               |  2 +
> >  drivers/gpu/drm/i915/i915_gem.c               | 16 ++++
> >  drivers/gpu/drm/i915/i915_gem_object.h        |  7 ++
> >  drivers/gpu/drm/i915/i915_gem_shrinker.c      | 59 ++++++++++++++
> >  drivers/gpu/drm/i915/intel_memory_region.c    | 40 +++++++++-
> >  drivers/gpu/drm/i915/intel_memory_region.h    |  7 ++
> >  .../drm/i915/selftests/intel_memory_region.c  | 76 +++++++++++++++++++
> >  drivers/gpu/drm/i915/selftests/mock_region.c  |  1 +
> >  8 files changed, 204 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 0bea7d889284..3df27769b978 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -3196,6 +3196,8 @@ void i915_gem_shrinker_register(struct drm_i915_private *i915);
> >  void i915_gem_shrinker_unregister(struct drm_i915_private *i915);
> >  void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915,
> >                                     struct mutex *mutex);
> > +int i915_gem_shrink_memory_region(struct intel_memory_region *mem,
> > +                                 resource_size_t target);
> >
> >  /* i915_gem_tiling.c */
> >  static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index 92768ab294a4..7f044b643a75 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -4095,6 +4095,22 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
> >             !i915_gem_object_has_pages(obj))
> >                 i915_gem_object_truncate(obj);
> >
> > +       if (obj->memory_region) {
> > +               mutex_lock(&obj->memory_region->obj_lock);
> > +
> > +               switch (obj->mm.madv) {
> > +               case I915_MADV_WILLNEED:
> > +                       list_move(&obj->region_link, &obj->memory_region->objects);
> > +                       break;
> > +               default:
> > +                       list_move(&obj->region_link,
> > +                                 &obj->memory_region->purgeable);
> > +                       break;
> > +               }
> > +
> > +               mutex_unlock(&obj->memory_region->obj_lock);
> > +       }
> > +
> >         args->retained = obj->mm.madv != __I915_MADV_PURGED;
> >         mutex_unlock(&obj->mm.lock);
> >
> > diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
> > index ac52f61e8ad1..76947a6f49f1 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_object.h
> > +++ b/drivers/gpu/drm/i915/i915_gem_object.h
> > @@ -95,6 +95,13 @@ struct drm_i915_gem_object {
> >          * List of memory region blocks allocated for this object.
> >          */
> >         struct list_head blocks;
> > +       /**
> > +        * Element within memory_region->objects or memory_region->purgeable if
> > +        * the object is marked as DONTNEED. Access is protected by
> > +        * memory_region->obj_lock.
>
> Lies. ;-p
>
> > +        */
> > +       struct list_head region_link;
> > +       struct list_head tmp_link;
> >
> >         struct {
> >                 /**
> > diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> > index 6da795c7e62e..713c6c93cf30 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> > @@ -308,6 +308,65 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915)
> >         return freed;
> >  }
> >
> > +int i915_gem_shrink_memory_region(struct intel_memory_region *mem,
> > +                                 resource_size_t target)
>
> If it's not going to be coupled into the mm.shrinker callback, do not put
> it here! And there's no reason why we would ever couple local memory to
> the generic mm shrinker!

Yup.

>
> > +{
> > +       struct drm_i915_private *i915 = mem->i915;
> > +       struct drm_i915_gem_object *obj, *on;
> > +       resource_size_t found;
> > +       LIST_HEAD(purgeable);
> > +       bool unlock;
> > +       int err;
> > +
> > +       if (!shrinker_lock(i915, 0, &unlock))
> > +               return 0;
>
> Don't...
>
> > +
> > +       i915_retire_requests(i915);
>
> And this, don't do this.
>
> > +       err = 0;
> > +       found = 0;
> > +
> > +       mutex_lock(&mem->obj_lock);
>
> That's all the top-level locking we should ever need.
>
> > +       list_for_each_entry(obj, &mem->purgeable, region_link) {
> > +               if (!i915_gem_object_has_pages(obj))
> > +                       continue;
> > +
> > +               if (READ_ONCE(obj->pin_global))
> > +                       continue;
> > +
> > +               if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count)
> > +                       continue;
> > +
> > +               list_add(&obj->tmp_link, &purgeable);
>
> Oh crikey.

What's the crikey for? We do the purging in two passes? Yeah, I guess
that's kinda garbage. There is definitely some leftover baggage from
when we did "interesting" things in here, which needs to be fixed up.

>
> > +
> > +               found += obj->base.size;
> > +               if (found >= target)
> > +                       goto found;
> > +       }
> > +
> > +       err = -ENOSPC;
> > +found:
> > +       mutex_unlock(&mem->obj_lock);
> > +
> > +       list_for_each_entry_safe(obj, on, &purgeable, tmp_link) {
> > +               if (!err)
> > +                       err = i915_gem_object_unbind(obj);
>
> I would advise not to worry about unbinding until you have it decoupled
> from struct_mutex. Or at least defer struct_mutex until you truly need
> it to access the vma, so that it doesn't get abused for anything else.

Ok, I'll just drop the unbind, and kiss for now.

>
> > +               if (!err) {
> > +                       __i915_gem_object_put_pages(obj,
> > +                                                   I915_MM_SHRINKER);
> > +                       if (!i915_gem_object_has_pages(obj))
> > +                               obj->mm.madv = __I915_MADV_PURGED;
>
> But this is racy.
>
> > +               }
> > +
> > +               list_del(&obj->tmp_link);
>
> I'm still going crikey. That's no excuse to invoke struct_mutex.
> -Chris
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 05/42] drm/i915/region: support basic eviction
  2019-02-26 14:58     ` Matthew Auld
@ 2019-02-26 16:49       ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-26 16:49 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, Matthew Auld

Quoting Matthew Auld (2019-02-26 14:58:31)
> On Thu, 14 Feb 2019 at 15:25, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> >
> > Quoting Matthew Auld (2019-02-14 14:57:03)
> > > +       list_for_each_entry(obj, &mem->purgeable, region_link) {
> > > +               if (!i915_gem_object_has_pages(obj))
> > > +                       continue;
> > > +
> > > +               if (READ_ONCE(obj->pin_global))
> > > +                       continue;
> > > +
> > > +               if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count)
> > > +                       continue;
> > > +
> > > +               list_add(&obj->tmp_link, &purgeable);
> >
> > Oh crikey.
> 
> What's the crikey for? We do the purging in two passes? Yeah, I guess
> that's kinda garbage. There is definitely some leftover baggage from
> when we did "interesting" things in here, which needs to be fixed up.

"tmp_link" has a very bad taste (prior experience turned sour), and this
turns out to be lacking in locking. Pesky little global thing.
Alternatives tend to be to dynamically allocate list entries. My favourite
half-baked idea is to use an XArray for a chunked list (so we get storage
allocated for a bunch of entries at once).
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26 12:17           ` Joonas Lahtinen
@ 2019-02-26 17:20             ` Alex Deucher
  2019-02-26 18:52               ` Christian König
  2019-02-26 19:14               ` Alex Deucher
  0 siblings, 2 replies; 97+ messages in thread
From: Alex Deucher @ 2019-02-26 17:20 UTC (permalink / raw)
  To: Joonas Lahtinen; +Cc: Intel Graphics Development, Matthew Auld, dri-devel

On Tue, Feb 26, 2019 at 7:17 AM Joonas Lahtinen
<joonas.lahtinen@linux.intel.com> wrote:
>
> Quoting Alex Deucher (2019-02-25 21:31:43)
> > On Mon, Feb 25, 2019 at 9:35 PM Joonas Lahtinen
> > <joonas.lahtinen@linux.intel.com> wrote:
> > >
> > > Quoting Dave Airlie (2019-02-25 12:24:48)
> > > > On Tue, 19 Feb 2019 at 23:32, Joonas Lahtinen
> > > > <joonas.lahtinen@linux.intel.com> wrote:
> > > > >
> > > > > + dri-devel mailing list, especially for the buddy allocator part
> > > > >
> > > > > Quoting Dave Airlie (2019-02-15 02:47:07)
> > > > > > On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
> > > > > > >
> > > > > > > In preparation for upcoming devices with device local memory, introduce the
> > > > > > > concept of different memory regions, and a simple buddy allocator to manage
> > > > > > > them.
> > > > > >
> > > > > > This is missing the information on why it's not TTM.
> > > > > >
> > > > > > Nothing against extending i915 gem off into doing stuff we already
> > > > > > have examples off in tree, but before you do that it would be good to
> > > > > > have a why we can't use TTM discussion in public.
> > > > >
> > > > > Glad that you asked. It's my fault that it was not included in
> > > > > the cover letter. I anticipated the question, but was travelling
> > > > > for a couple of days at the time this was sent. I didn't want
> > > > > to write a hasty explanation and then disappear, leaving others to
> > > > > take the heat.
> > > > >
> > > > > So here goes the less-hasty version:
> > > > >
> > > > > We did an analysis on the effort needed vs benefit gained of using
> > > > > TTM when this was started initially. The conclusion was that we
> > > > > already share the interesting bits of code through core DRM, really.
> > > > >
> > > > > Re-writing the memory handling to TTM would buy us more fine-grained
> > > > > locking. But it's more a trait of rewriting the memory handling with
> > > > > the information we have learned, than rewriting it to use TTM :)
> > > > >
> > > > > And further, we've been getting rid of struct_mutex at a steady phase
> > > > > in the past years, so we have a clear path to the fine-grained locking
> > > > > already in the not-so-distant future. With all this we did not see
> > > > > much gained from converting over, as the code sharing is already
> > > > > substantial.
> > > > >
> > > > > We also wanted to have the buddy allocator instead of a for loop making
> > > > > drm_mm allocations to make sure we can keep the memory fragmentation
> > > > > at bay. The intent is to move the buddy allocator to core DRM, to the
> > > > > benefit of all the drivers, if there is interest from community. It has
> > > > > been written as a strictly separate component with that in mind.
> > > > >
> > > > > And if you take the buddy allocator out of the patch set, the rest is
> > > > > mostly just vfuncing things up to be able to have different backing
> > > > > storages for objects. We took the opportunity to move over to the more
> > > > > valgrind friendly mmap while touching things, but it's something we
> > > > > have been contemplating anyway. And yeah, loads of selftests.
> > > > >
> > > > > That's really all that needed adding, and most of it is internal to
> > > > > i915 and not to do with uAPI. This means porting over an userspace
> > > > > driver doesn't require a substantial rewrite, but adding new a few
> > > > > new IOCTLs to set the preferred backing storage placements.
> > > > >
> > > > > All the previous GEM abstractions keep applying, so we did not see
> > > > > a justification to rewrite the kernel driver and userspace drivers.
> > > > > It would have just to made things look like TTM, when we already
> > > > > have the important parts of the code shared with TTM drivers
> > > > > behind the GEM interfaces which all our drivers sit on top of.
> > > >
> > > > a) you guys should be the community as well, if the buddy allocator is
> > > > useful in the core DRM get out there and try and see if anyone else
> > > > has a use case for it, like the GPU scheduler we have now (can i915
> > > > use that yet? :-)
> > >
> > > Well, the buddy allocator should be useful for anybody wishing to have
> > > as continuous physical allocations as possible. I have naively assumed
> > > that would be almost everyone. So it would be only a question if others
> > > see the amount of work required to convert over is justified for them.
> > >
> > > For the common DRM scheduler, I think a solid move from the beginning
> > > would have been to factor out the i915 scheduler as it was most advanced
> > > in features :) Now there is a way more trivial common scheduler core with
> > > no easy path to transition without a feature regression.
> >
> > Can you elaborate?  What features are missing from the drm gpu scheduler?
>
> Priority based pre-emption is the big thing coming to mind. But maybe we
> should not derail the discussion in this thread. The discussion should
> be in the archives, or we can start a new thread.

Probably not worth continuing here, but I think there are probably
features that the drm scheduler has that the i915 scheduler does not.
For example, engine load balancing.  So i wouldn't necessarily say
it's more advanced, just different feature sets.  We could all be
enjoying all of these features if we all worked on the same
infrastructure.

>
> > > We'd have to rewrite many of the more advanced features for that codebase
> > > before we could transition over. It's hard to justify such work, for
> > > that it would buy us very little compared to amount of work.
> > >
> > > Situation would be different if there was something gained from
> > > switching over. This would be the situation if the more advanced
> > > scheduler was picked as the shared codebase.
> > >
> > > > b) however this last two paragraphs fill me with no confidence that
> > > > you've looked at TTM at all. It sounds like you took comments about
> > > > TTM made 10 years ago, and didn't update them. There should be no
> > > > major reason for a uapi change just because you adopt TTM. TTM hasn't
> > > > ever had a common uapi across drivers upstream, one was proposed
> > > > initially > 10 years ago.
> > >
> > > This is one part my confusion on what the question was for and other
> > > part bad wording on my behalf.
> > >
> > > So an attempt to re-answer: When this effort was started it was obvious
> > > that the amount of new code required was low (as you can see). Feedback
> > > about what converting to TTM would require vs. give us was gathered from
> > > folks including Daniel and Chris and the unanimous decision was that it
> > > would not be justifiable.
> > >
> > > > All the current TTM using drivers except
> > > > vmware use a GEM based API as well. TTM is an internal driver helper
> > > > for managing pools of RAM.
> > > >
> > > > I'm just not sure what rebuilding a chunk of shared code inside the
> > > > i915 driver is buying you, except a transition path into divergence
> > > > from all the other discrete RAM drivers.
> > >
> > > I guess what I'm trying to say, there isn't that much code being added
> > > that wouldn't be there anyway. The i915 GEM code has already grown to
> > > what it is before this.
> > >
> > > Adding the suggested smaller amount of code vs. doing a much bigger
> > > rewrite is something of a straightforward choice with the amount of
> > > platforms and features in flight, especially when the end result is
> > > the same.
> >
> > Because you will probably never do it.  It's almost always easier to
> > just incrementally add on to existing code.  One could argue that GEM
> > evolved into more or less the exact same thing as TTM anyway so why
> > not bite the bullet and switch at some point?  TTM works fine even for
> > UMA hardware.
>
> By my understanding there are quite a few differences in low on memory
> handling and other more subtle aspects between the two.
> Converting over to TTM would be a pretty big rewrite of i915, and the
> code sharing is already happening for important parts.
>
> > > > Like the gallium aversion in
> > > > userspace, having a TTM aversion in kernel space is going to be the
> > > > wrong path, and I'd rather not have to clean it up in 5 years when you
> > > > guys eventually realise it.
> > > >
> > > > The i915 GEM code get rewritten and refactored quite often
> > >
> > > Well, we continually try to improve things and accommodate upcoming
> > > product requirements and hardware feature. The thing is that we do it
> > > upstream first, so hard to avoid the churn.
> > >
> > > When moving rapidly, it's hard to project what the shared portion of
> > > the code might be or exactly look. I'm myself much more believer in
> > > extracting the generic portions out when the code is there and working.
> > >
> > > The churn would be even bigger if there is a strict requirement to
> > > refactor the common parts out straight from the beginning, before
> > > anything is even proven in practice.
> > >
> > > That'd just mean it gets much harder to sell doing things upstream
> > > first to the management.
> >
> > What does upstream first have to do with contributing to shared code?
> > There is a common misconception in big companies that if you utilize
> > shared infrastructure it will slow you down or you'll lose control of
> > your code which is I think what you are referring to.
>
> That'd be the wrong impression. Quite the contrary, the biggest chunk
> of code here, buddy allocator, was written specifically with the fact
> in mind that we can easily move it to DRM core.
>
> And I think we have a solid track history of contributing to the DRM
> core, so I'm not sure why you'd think that.

I didn't say you don't have a track record of contributing, my point
was that you only seem to use what you contributed in the first place.
This is another example.  I haven't seen Intel use any infrastructure
they didn't write directly.  Off the top of my head:
- drm GPU scheduler
- TTM
- Gallium
- Multi-media (creating VAAPI when there were arguably superior
alternatives, VDPAU and OpenMAX)
- OpenCL

In all those cases Intel did something equivalent in parallel, pushing
its projects while trying to downplay the existing projects.  This
just seems like more of that.

>
> > Ultimately, it
> > does sometimes raise the bar, but in the long term it benefits
> > everyone and usually it doesn't really add that much overhead.
>
> That we both agree on. But in the case of this specific patch series
> it is about rewriting the driver to TTM, which is quite an overhead.
>
> And if most of the important code is shared anyway through DRM core,
> doing the rewrite + covering all the subtle differences, does not
> sound too compelling.

Sometimes it is a lot of overhead.  That's the pact you make when you
put code upstream.  The community wants the best solution for everyone
and to be able to maintain it if you don't.  Sometimes that means
extra overhead.

At the end of the day, I don't really care that much.  I get it, we
all have large projects with scarce resources.  I just think a few
years down the road we'll all regret it as a community.

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26 17:20             ` Alex Deucher
@ 2019-02-26 18:52               ` Christian König
  2019-02-26 19:14               ` Alex Deucher
  1 sibling, 0 replies; 97+ messages in thread
From: Christian König @ 2019-02-26 18:52 UTC (permalink / raw)
  To: Alex Deucher, Joonas Lahtinen
  Cc: Intel Graphics Development, Matthew Auld, dri-devel

Am 26.02.19 um 18:20 schrieb Alex Deucher:
> On Tue, Feb 26, 2019 at 7:17 AM Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com> wrote:
>> Quoting Alex Deucher (2019-02-25 21:31:43)
>>> On Mon, Feb 25, 2019 at 9:35 PM Joonas Lahtinen
>>> <joonas.lahtinen@linux.intel.com> wrote:
>>>> Quoting Dave Airlie (2019-02-25 12:24:48)
>>>>> On Tue, 19 Feb 2019 at 23:32, Joonas Lahtinen
>>>>> <joonas.lahtinen@linux.intel.com> wrote:
>>>>>> + dri-devel mailing list, especially for the buddy allocator part
>>>>>>
>>>>>> Quoting Dave Airlie (2019-02-15 02:47:07)
>>>>>>> On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
>>>>>>>> In preparation for upcoming devices with device local memory, introduce the
>>>>>>>> concept of different memory regions, and a simple buddy allocator to manage
>>>>>>>> them.
>>>>>>> This is missing the information on why it's not TTM.
>>>>>>>
>>>>>>> Nothing against extending i915 gem off into doing stuff we already
>>>>>>> have examples off in tree, but before you do that it would be good to
>>>>>>> have a why we can't use TTM discussion in public.
>>>>>> Glad that you asked. It's my fault that it was not included in
>>>>>> the cover letter. I anticipated the question, but was travelling
>>>>>> for a couple of days at the time this was sent. I didn't want
>>>>>> to write a hasty explanation and then disappear, leaving others to
>>>>>> take the heat.
>>>>>>
>>>>>> So here goes the less-hasty version:
>>>>>>
>>>>>> We did an analysis on the effort needed vs benefit gained of using
>>>>>> TTM when this was started initially. The conclusion was that we
>>>>>> already share the interesting bits of code through core DRM, really.
>>>>>>
>>>>>> Re-writing the memory handling to TTM would buy us more fine-grained
>>>>>> locking. But it's more a trait of rewriting the memory handling with
>>>>>> the information we have learned, than rewriting it to use TTM :)
>>>>>>
>>>>>> And further, we've been getting rid of struct_mutex at a steady phase
>>>>>> in the past years, so we have a clear path to the fine-grained locking
>>>>>> already in the not-so-distant future. With all this we did not see
>>>>>> much gained from converting over, as the code sharing is already
>>>>>> substantial.
>>>>>>
>>>>>> We also wanted to have the buddy allocator instead of a for loop making
>>>>>> drm_mm allocations to make sure we can keep the memory fragmentation
>>>>>> at bay. The intent is to move the buddy allocator to core DRM, to the
>>>>>> benefit of all the drivers, if there is interest from community. It has
>>>>>> been written as a strictly separate component with that in mind.
>>>>>>
>>>>>> And if you take the buddy allocator out of the patch set, the rest is
>>>>>> mostly just vfuncing things up to be able to have different backing
>>>>>> storages for objects. We took the opportunity to move over to the more
>>>>>> valgrind friendly mmap while touching things, but it's something we
>>>>>> have been contemplating anyway. And yeah, loads of selftests.
>>>>>>
>>>>>> That's really all that needed adding, and most of it is internal to
>>>>>> i915 and not to do with uAPI. This means porting over an userspace
>>>>>> driver doesn't require a substantial rewrite, but adding new a few
>>>>>> new IOCTLs to set the preferred backing storage placements.
>>>>>>
>>>>>> All the previous GEM abstractions keep applying, so we did not see
>>>>>> a justification to rewrite the kernel driver and userspace drivers.
>>>>>> It would have just to made things look like TTM, when we already
>>>>>> have the important parts of the code shared with TTM drivers
>>>>>> behind the GEM interfaces which all our drivers sit on top of.
>>>>> a) you guys should be the community as well, if the buddy allocator is
>>>>> useful in the core DRM get out there and try and see if anyone else
>>>>> has a use case for it, like the GPU scheduler we have now (can i915
>>>>> use that yet? :-)
>>>> Well, the buddy allocator should be useful for anybody wishing to have
>>>> as continuous physical allocations as possible. I have naively assumed
>>>> that would be almost everyone. So it would be only a question if others
>>>> see the amount of work required to convert over is justified for them.
>>>>
>>>> For the common DRM scheduler, I think a solid move from the beginning
>>>> would have been to factor out the i915 scheduler as it was most advanced
>>>> in features :) Now there is a way more trivial common scheduler core with
>>>> no easy path to transition without a feature regression.
>>> Can you elaborate?  What features are missing from the drm gpu scheduler?
>> Priority based pre-emption is the big thing coming to mind. But maybe we
>> should not derail the discussion in this thread. The discussion should
>> be in the archives, or we can start a new thread.
> Probably not worth continuing here, but I think there are probably
> features that the drm scheduler has that the i915 scheduler does not.
> For example, engine load balancing.  So i wouldn't necessarily say
> it's more advanced, just different feature sets.  We could all be
> enjoying all of these features if we all worked on the same
> infrastructure.

Actually it is worth continuing. To be honest the DRM scheduler came 
first and the i915 scheduler should have been pushed back a bit more.

Additional to that it does support priority based pre-emption from the 
very beginning, you guys just didn't cared to take a look :(

Regards,
Christian.

>
>>>> We'd have to rewrite many of the more advanced features for that codebase
>>>> before we could transition over. It's hard to justify such work, for
>>>> that it would buy us very little compared to amount of work.
>>>>
>>>> Situation would be different if there was something gained from
>>>> switching over. This would be the situation if the more advanced
>>>> scheduler was picked as the shared codebase.
>>>>
>>>>> b) however this last two paragraphs fill me with no confidence that
>>>>> you've looked at TTM at all. It sounds like you took comments about
>>>>> TTM made 10 years ago, and didn't update them. There should be no
>>>>> major reason for a uapi change just because you adopt TTM. TTM hasn't
>>>>> ever had a common uapi across drivers upstream, one was proposed
>>>>> initially > 10 years ago.
>>>> This is one part my confusion on what the question was for and other
>>>> part bad wording on my behalf.
>>>>
>>>> So an attempt to re-answer: When this effort was started it was obvious
>>>> that the amount of new code required was low (as you can see). Feedback
>>>> about what converting to TTM would require vs. give us was gathered from
>>>> folks including Daniel and Chris and the unanimous decision was that it
>>>> would not be justifiable.
>>>>
>>>>> All the current TTM using drivers except
>>>>> vmware use a GEM based API as well. TTM is an internal driver helper
>>>>> for managing pools of RAM.
>>>>>
>>>>> I'm just not sure what rebuilding a chunk of shared code inside the
>>>>> i915 driver is buying you, except a transition path into divergence
>>>>> from all the other discrete RAM drivers.
>>>> I guess what I'm trying to say, there isn't that much code being added
>>>> that wouldn't be there anyway. The i915 GEM code has already grown to
>>>> what it is before this.
>>>>
>>>> Adding the suggested smaller amount of code vs. doing a much bigger
>>>> rewrite is something of a straightforward choice with the amount of
>>>> platforms and features in flight, especially when the end result is
>>>> the same.
>>> Because you will probably never do it.  It's almost always easier to
>>> just incrementally add on to existing code.  One could argue that GEM
>>> evolved into more or less the exact same thing as TTM anyway so why
>>> not bite the bullet and switch at some point?  TTM works fine even for
>>> UMA hardware.
>> By my understanding there are quite a few differences in low on memory
>> handling and other more subtle aspects between the two.
>> Converting over to TTM would be a pretty big rewrite of i915, and the
>> code sharing is already happening for important parts.
>>
>>>>> Like the gallium aversion in
>>>>> userspace, having a TTM aversion in kernel space is going to be the
>>>>> wrong path, and I'd rather not have to clean it up in 5 years when you
>>>>> guys eventually realise it.
>>>>>
>>>>> The i915 GEM code get rewritten and refactored quite often
>>>> Well, we continually try to improve things and accommodate upcoming
>>>> product requirements and hardware feature. The thing is that we do it
>>>> upstream first, so hard to avoid the churn.
>>>>
>>>> When moving rapidly, it's hard to project what the shared portion of
>>>> the code might be or exactly look. I'm myself much more believer in
>>>> extracting the generic portions out when the code is there and working.
>>>>
>>>> The churn would be even bigger if there is a strict requirement to
>>>> refactor the common parts out straight from the beginning, before
>>>> anything is even proven in practice.
>>>>
>>>> That'd just mean it gets much harder to sell doing things upstream
>>>> first to the management.
>>> What does upstream first have to do with contributing to shared code?
>>> There is a common misconception in big companies that if you utilize
>>> shared infrastructure it will slow you down or you'll lose control of
>>> your code which is I think what you are referring to.
>> That'd be the wrong impression. Quite the contrary, the biggest chunk
>> of code here, buddy allocator, was written specifically with the fact
>> in mind that we can easily move it to DRM core.
>>
>> And I think we have a solid track history of contributing to the DRM
>> core, so I'm not sure why you'd think that.
> I didn't say you don't have a track record of contributing, my point
> was that you only seem to use what you contributed in the first place.
> This is another example.  I haven't seen Intel use any infrastructure
> they didn't write directly.  Off the top of my head:
> - drm GPU scheduler
> - TTM
> - Gallium
> - Multi-media (creating VAAPI when there were arguably superior
> alternatives, VDPAU and OpenMAX)
> - OpenCL
>
> In all those cases Intel did something equivalent in parallel, pushing
> its projects while trying to downplay the existing projects.  This
> just seems like more of that.
>
>>> Ultimately, it
>>> does sometimes raise the bar, but in the long term it benefits
>>> everyone and usually it doesn't really add that much overhead.
>> That we both agree on. But in the case of this specific patch series
>> it is about rewriting the driver to TTM, which is quite an overhead.
>>
>> And if most of the important code is shared anyway through DRM core,
>> doing the rewrite + covering all the subtle differences, does not
>> sound too compelling.
> Sometimes it is a lot of overhead.  That's the pact you make when you
> put code upstream.  The community wants the best solution for everyone
> and to be able to maintain it if you don't.  Sometimes that means
> extra overhead.
>
> At the end of the day, I don't really care that much.  I get it, we
> all have large projects with scarce resources.  I just think a few
> years down the road we'll all regret it as a community.
>
> Alex
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations
  2019-02-14 15:48   ` Chris Wilson
@ 2019-02-26 18:53     ` Matthew Auld
  2019-02-26 18:58       ` Chris Wilson
  0 siblings, 1 reply; 97+ messages in thread
From: Matthew Auld @ 2019-02-26 18:53 UTC (permalink / raw)
  To: Chris Wilson; +Cc: Intel Graphics Development, Matthew Auld

On Thu, 14 Feb 2019 at 15:48, Chris Wilson <chris@chris-wilson.co.uk> wrote:
>
> Quoting Matthew Auld (2019-02-14 14:57:16)
> > We need to support doing relocations from the CPU when dealing with LMEM
> > objects.
>
> Why not just use the GPU reloc? Please do explain the relative merits.

Are you suggesting just default to the GPU reloc path for LMEM, and
don't bother with CPU relocs? I guess that would work, I'm just
wondering if keeping the CPU reloc path around for debug might be
useful, it's at least been useful in the past, although maybe it's not
that relevant for upstream.

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations
  2019-02-26 18:53     ` Matthew Auld
@ 2019-02-26 18:58       ` Chris Wilson
  0 siblings, 0 replies; 97+ messages in thread
From: Chris Wilson @ 2019-02-26 18:58 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, Matthew Auld

Quoting Matthew Auld (2019-02-26 18:53:17)
> On Thu, 14 Feb 2019 at 15:48, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> >
> > Quoting Matthew Auld (2019-02-14 14:57:16)
> > > We need to support doing relocations from the CPU when dealing with LMEM
> > > objects.
> >
> > Why not just use the GPU reloc? Please do explain the relative merits.
> 
> Are you suggesting just default to the GPU reloc path for LMEM, and
> don't bother with CPU relocs? I guess that would work, I'm just
> wondering if keeping the CPU reloc path around for debug might be
> useful, it's at least been useful in the past, although maybe it's not
> that relevant for upstream.

Debug is a good argument; I just want to hear about the relative merits
of each path. At the moment, we only use the GPU path if already busy,
but maybe we need to reconsider? There's even more fun to be had where
reservation is async and we need to defer the relocation processing
until after we've acquired the memory and vma :)
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26 17:20             ` Alex Deucher
  2019-02-26 18:52               ` Christian König
@ 2019-02-26 19:14               ` Alex Deucher
  2019-02-26 23:04                 ` Dave Airlie
  1 sibling, 1 reply; 97+ messages in thread
From: Alex Deucher @ 2019-02-26 19:14 UTC (permalink / raw)
  To: Joonas Lahtinen; +Cc: Intel Graphics Development, Matthew Auld, dri-devel

On Tue, Feb 26, 2019 at 12:20 PM Alex Deucher <alexdeucher@gmail.com> wrote:
>
> On Tue, Feb 26, 2019 at 7:17 AM Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com> wrote:
> >
> > Quoting Alex Deucher (2019-02-25 21:31:43)
> > > On Mon, Feb 25, 2019 at 9:35 PM Joonas Lahtinen
> > > <joonas.lahtinen@linux.intel.com> wrote:
> > > >
> > > > Quoting Dave Airlie (2019-02-25 12:24:48)
> > > > > On Tue, 19 Feb 2019 at 23:32, Joonas Lahtinen
> > > > > <joonas.lahtinen@linux.intel.com> wrote:
> > > > > >
> > > > > > + dri-devel mailing list, especially for the buddy allocator part
> > > > > >
> > > > > > Quoting Dave Airlie (2019-02-15 02:47:07)
> > > > > > > On Fri, 15 Feb 2019 at 00:57, Matthew Auld <matthew.auld@intel.com> wrote:
> > > > > > > >
> > > > > > > > In preparation for upcoming devices with device local memory, introduce the
> > > > > > > > concept of different memory regions, and a simple buddy allocator to manage
> > > > > > > > them.
> > > > > > >
> > > > > > > This is missing the information on why it's not TTM.
> > > > > > >
> > > > > > > Nothing against extending i915 gem off into doing stuff we already
> > > > > > > have examples off in tree, but before you do that it would be good to
> > > > > > > have a why we can't use TTM discussion in public.
> > > > > >
> > > > > > Glad that you asked. It's my fault that it was not included in
> > > > > > the cover letter. I anticipated the question, but was travelling
> > > > > > for a couple of days at the time this was sent. I didn't want
> > > > > > to write a hasty explanation and then disappear, leaving others to
> > > > > > take the heat.
> > > > > >
> > > > > > So here goes the less-hasty version:
> > > > > >
> > > > > > We did an analysis on the effort needed vs benefit gained of using
> > > > > > TTM when this was started initially. The conclusion was that we
> > > > > > already share the interesting bits of code through core DRM, really.
> > > > > >
> > > > > > Re-writing the memory handling to TTM would buy us more fine-grained
> > > > > > locking. But it's more a trait of rewriting the memory handling with
> > > > > > the information we have learned, than rewriting it to use TTM :)
> > > > > >
> > > > > > And further, we've been getting rid of struct_mutex at a steady phase
> > > > > > in the past years, so we have a clear path to the fine-grained locking
> > > > > > already in the not-so-distant future. With all this we did not see
> > > > > > much gained from converting over, as the code sharing is already
> > > > > > substantial.
> > > > > >
> > > > > > We also wanted to have the buddy allocator instead of a for loop making
> > > > > > drm_mm allocations to make sure we can keep the memory fragmentation
> > > > > > at bay. The intent is to move the buddy allocator to core DRM, to the
> > > > > > benefit of all the drivers, if there is interest from community. It has
> > > > > > been written as a strictly separate component with that in mind.
> > > > > >
> > > > > > And if you take the buddy allocator out of the patch set, the rest is
> > > > > > mostly just vfuncing things up to be able to have different backing
> > > > > > storages for objects. We took the opportunity to move over to the more
> > > > > > valgrind friendly mmap while touching things, but it's something we
> > > > > > have been contemplating anyway. And yeah, loads of selftests.
> > > > > >
> > > > > > That's really all that needed adding, and most of it is internal to
> > > > > > i915 and not to do with uAPI. This means porting over an userspace
> > > > > > driver doesn't require a substantial rewrite, but adding new a few
> > > > > > new IOCTLs to set the preferred backing storage placements.
> > > > > >
> > > > > > All the previous GEM abstractions keep applying, so we did not see
> > > > > > a justification to rewrite the kernel driver and userspace drivers.
> > > > > > It would have just to made things look like TTM, when we already
> > > > > > have the important parts of the code shared with TTM drivers
> > > > > > behind the GEM interfaces which all our drivers sit on top of.
> > > > >
> > > > > a) you guys should be the community as well, if the buddy allocator is
> > > > > useful in the core DRM get out there and try and see if anyone else
> > > > > has a use case for it, like the GPU scheduler we have now (can i915
> > > > > use that yet? :-)
> > > >
> > > > Well, the buddy allocator should be useful for anybody wishing to have
> > > > as continuous physical allocations as possible. I have naively assumed
> > > > that would be almost everyone. So it would be only a question if others
> > > > see the amount of work required to convert over is justified for them.
> > > >
> > > > For the common DRM scheduler, I think a solid move from the beginning
> > > > would have been to factor out the i915 scheduler as it was most advanced
> > > > in features :) Now there is a way more trivial common scheduler core with
> > > > no easy path to transition without a feature regression.
> > >
> > > Can you elaborate?  What features are missing from the drm gpu scheduler?
> >
> > Priority based pre-emption is the big thing coming to mind. But maybe we
> > should not derail the discussion in this thread. The discussion should
> > be in the archives, or we can start a new thread.
>
> Probably not worth continuing here, but I think there are probably
> features that the drm scheduler has that the i915 scheduler does not.
> For example, engine load balancing.  So i wouldn't necessarily say
> it's more advanced, just different feature sets.  We could all be
> enjoying all of these features if we all worked on the same
> infrastructure.
>
> >
> > > > We'd have to rewrite many of the more advanced features for that codebase
> > > > before we could transition over. It's hard to justify such work, for
> > > > that it would buy us very little compared to amount of work.
> > > >
> > > > Situation would be different if there was something gained from
> > > > switching over. This would be the situation if the more advanced
> > > > scheduler was picked as the shared codebase.
> > > >
> > > > > b) however this last two paragraphs fill me with no confidence that
> > > > > you've looked at TTM at all. It sounds like you took comments about
> > > > > TTM made 10 years ago, and didn't update them. There should be no
> > > > > major reason for a uapi change just because you adopt TTM. TTM hasn't
> > > > > ever had a common uapi across drivers upstream, one was proposed
> > > > > initially > 10 years ago.
> > > >
> > > > This is one part my confusion on what the question was for and other
> > > > part bad wording on my behalf.
> > > >
> > > > So an attempt to re-answer: When this effort was started it was obvious
> > > > that the amount of new code required was low (as you can see). Feedback
> > > > about what converting to TTM would require vs. give us was gathered from
> > > > folks including Daniel and Chris and the unanimous decision was that it
> > > > would not be justifiable.
> > > >
> > > > > All the current TTM using drivers except
> > > > > vmware use a GEM based API as well. TTM is an internal driver helper
> > > > > for managing pools of RAM.
> > > > >
> > > > > I'm just not sure what rebuilding a chunk of shared code inside the
> > > > > i915 driver is buying you, except a transition path into divergence
> > > > > from all the other discrete RAM drivers.
> > > >
> > > > I guess what I'm trying to say, there isn't that much code being added
> > > > that wouldn't be there anyway. The i915 GEM code has already grown to
> > > > what it is before this.
> > > >
> > > > Adding the suggested smaller amount of code vs. doing a much bigger
> > > > rewrite is something of a straightforward choice with the amount of
> > > > platforms and features in flight, especially when the end result is
> > > > the same.
> > >
> > > Because you will probably never do it.  It's almost always easier to
> > > just incrementally add on to existing code.  One could argue that GEM
> > > evolved into more or less the exact same thing as TTM anyway so why
> > > not bite the bullet and switch at some point?  TTM works fine even for
> > > UMA hardware.
> >
> > By my understanding there are quite a few differences in low on memory
> > handling and other more subtle aspects between the two.
> > Converting over to TTM would be a pretty big rewrite of i915, and the
> > code sharing is already happening for important parts.
> >
> > > > > Like the gallium aversion in
> > > > > userspace, having a TTM aversion in kernel space is going to be the
> > > > > wrong path, and I'd rather not have to clean it up in 5 years when you
> > > > > guys eventually realise it.
> > > > >
> > > > > The i915 GEM code get rewritten and refactored quite often
> > > >
> > > > Well, we continually try to improve things and accommodate upcoming
> > > > product requirements and hardware feature. The thing is that we do it
> > > > upstream first, so hard to avoid the churn.
> > > >
> > > > When moving rapidly, it's hard to project what the shared portion of
> > > > the code might be or exactly look. I'm myself much more believer in
> > > > extracting the generic portions out when the code is there and working.
> > > >
> > > > The churn would be even bigger if there is a strict requirement to
> > > > refactor the common parts out straight from the beginning, before
> > > > anything is even proven in practice.
> > > >
> > > > That'd just mean it gets much harder to sell doing things upstream
> > > > first to the management.
> > >
> > > What does upstream first have to do with contributing to shared code?
> > > There is a common misconception in big companies that if you utilize
> > > shared infrastructure it will slow you down or you'll lose control of
> > > your code which is I think what you are referring to.
> >
> > That'd be the wrong impression. Quite the contrary, the biggest chunk
> > of code here, buddy allocator, was written specifically with the fact
> > in mind that we can easily move it to DRM core.
> >
> > And I think we have a solid track history of contributing to the DRM
> > core, so I'm not sure why you'd think that.
>
> I didn't say you don't have a track record of contributing, my point
> was that you only seem to use what you contributed in the first place.
> This is another example.  I haven't seen Intel use any infrastructure
> they didn't write directly.  Off the top of my head:
> - drm GPU scheduler
> - TTM
> - Gallium
> - Multi-media (creating VAAPI when there were arguably superior
> alternatives, VDPAU and OpenMAX)
> - OpenCL
>
> In all those cases Intel did something equivalent in parallel, pushing
> its projects while trying to downplay the existing projects.  This
> just seems like more of that.
>
> >
> > > Ultimately, it
> > > does sometimes raise the bar, but in the long term it benefits
> > > everyone and usually it doesn't really add that much overhead.
> >
> > That we both agree on. But in the case of this specific patch series
> > it is about rewriting the driver to TTM, which is quite an overhead.
> >
> > And if most of the important code is shared anyway through DRM core,
> > doing the rewrite + covering all the subtle differences, does not
> > sound too compelling.
>
> Sometimes it is a lot of overhead.  That's the pact you make when you
> put code upstream.  The community wants the best solution for everyone
> and to be able to maintain it if you don't.  Sometimes that means
> extra overhead.
>
> At the end of the day, I don't really care that much.  I get it, we
> all have large projects with scarce resources.  I just think a few
> years down the road we'll all regret it as a community.

AMD and others have also spent years tuning TTM for both UMA and VRAM,
but especially VRAM.  It comes across a bit daft to complain about the
effort to move to TTM, but say nothing about the effort to tune GEM
for optimal VRAM performance.  Effort that has already been expended
that you could take advantage of.

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26 19:14               ` Alex Deucher
@ 2019-02-26 23:04                 ` Dave Airlie
  2019-02-27 12:17                   ` Christian König
  0 siblings, 1 reply; 97+ messages in thread
From: Dave Airlie @ 2019-02-26 23:04 UTC (permalink / raw)
  To: Alex Deucher; +Cc: Intel Graphics Development, Matthew Auld, dri-devel

> > At the end of the day, I don't really care that much.  I get it, we
> > all have large projects with scarce resources.  I just think a few
> > years down the road we'll all regret it as a community.
>
> AMD and others have also spent years tuning TTM for both UMA and VRAM,
> but especially VRAM.  It comes across a bit daft to complain about the
> effort to move to TTM, but say nothing about the effort to tune GEM
> for optimal VRAM performance.  Effort that has already been expended
> that you could take advantage of.

I'm with Alex here, the patches you have now are just the start, I
realise you think they are all you'll need, but I expect once Chris
gets going with real VRAM hardware he'll generate reams for stuff.

People have been tuning and making TTM run on VRAM using GPUs for
longer than you've been making VRAM using GPUs, there had better be
good and well thought out reasons for avoiding using it, and so far
you haven't made that argument to me all. In fact your scheduler
arguments works against you. If we should have abstracted i915
scheduler out and used it because it had more features and
pre-existed, then i915 should be using TTM since it's already
abstracted out and has more features.

Like we've pulled other stuff out of TTM like reservation objects, I
don't think i915 uses those yet either when it clearly could be. Maybe
if we started by fixing that, moving to TTM would be less of a
problem.

Anyways, I expect moving to TTM is a big change for i915, and probably
more than you are able to bite off at present, but I'm going to be
watching closely what stuff you add on top of this sort of thing, and
if it starts getting large and messier as you tune it, I'll have to
start reconsidering how big a NO I have to use.

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-26 23:04                 ` Dave Airlie
@ 2019-02-27 12:17                   ` Christian König
  2019-02-27 14:40                     ` Joonas Lahtinen
  0 siblings, 1 reply; 97+ messages in thread
From: Christian König @ 2019-02-27 12:17 UTC (permalink / raw)
  To: Dave Airlie, Alex Deucher
  Cc: Intel Graphics Development, Matthew Auld, dri-devel

Am 27.02.19 um 00:04 schrieb Dave Airlie:
>>> At the end of the day, I don't really care that much.  I get it, we
>>> all have large projects with scarce resources.  I just think a few
>>> years down the road we'll all regret it as a community.
>> AMD and others have also spent years tuning TTM for both UMA and VRAM,
>> but especially VRAM.  It comes across a bit daft to complain about the
>> effort to move to TTM, but say nothing about the effort to tune GEM
>> for optimal VRAM performance.  Effort that has already been expended
>> that you could take advantage of.
> I'm with Alex here, the patches you have now are just the start, I
> realise you think they are all you'll need, but I expect once Chris
> gets going with real VRAM hardware he'll generate reams for stuff.
>
> People have been tuning and making TTM run on VRAM using GPUs for
> longer than you've been making VRAM using GPUs, there had better be
> good and well thought out reasons for avoiding using it, and so far
> you haven't made that argument to me all. In fact your scheduler
> arguments works against you. If we should have abstracted i915
> scheduler out and used it because it had more features and
> pre-existed, then i915 should be using TTM since it's already
> abstracted out and has more features.
>
> Like we've pulled other stuff out of TTM like reservation objects, I
> don't think i915 uses those yet either when it clearly could be. Maybe
> if we started by fixing that, moving to TTM would be less of a
> problem.

Just to make it extra clear: At least I absolutely won't mind if we 
decommission TTM further!

We have optimized TTM as much as we could without a fundamental design 
change, but essentially there are a couple of problem we can't fix 
without touching all drivers at once.

For example the layered design where TTM calls back into the driver to 
move stuff around or allocate something from a domain really needs to go 
away.

So my suggestion is that we filleting TTM into multiple independent 
components which a) can be used to implement the existing TTM interface 
and b) implement a clean and encapsulated functionality.

Those components can then be used by drivers independently of TTM to 
implement the necessary MM.

Regards,
Christian.

>
> Anyways, I expect moving to TTM is a big change for i915, and probably
> more than you are able to bite off at present, but I'm going to be
> watching closely what stuff you add on top of this sort of thing, and
> if it starts getting large and messier as you tune it, I'll have to
> start reconsidering how big a NO I have to use.
>
> Dave.
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [RFC PATCH 00/42] Introduce memory region concept (including device local memory)
  2019-02-27 12:17                   ` Christian König
@ 2019-02-27 14:40                     ` Joonas Lahtinen
  0 siblings, 0 replies; 97+ messages in thread
From: Joonas Lahtinen @ 2019-02-27 14:40 UTC (permalink / raw)
  To: Christian König, Alex Deucher, Dave Airlie, christian.koenig
  Cc: Intel Graphics Development, Matthew Auld, dri-devel

Quoting Christian König (2019-02-27 04:17:01)
> Am 27.02.19 um 00:04 schrieb Dave Airlie:
> >>> At the end of the day, I don't really care that much.  I get it, we
> >>> all have large projects with scarce resources.  I just think a few
> >>> years down the road we'll all regret it as a community.
> >> AMD and others have also spent years tuning TTM for both UMA and VRAM,
> >> but especially VRAM.  It comes across a bit daft to complain about the
> >> effort to move to TTM, but say nothing about the effort to tune GEM
> >> for optimal VRAM performance.  Effort that has already been expended
> >> that you could take advantage of.
> > I'm with Alex here, the patches you have now are just the start, I
> > realise you think they are all you'll need, but I expect once Chris
> > gets going with real VRAM hardware he'll generate reams for stuff.
> >
> > People have been tuning and making TTM run on VRAM using GPUs for
> > longer than you've been making VRAM using GPUs, there had better be
> > good and well thought out reasons for avoiding using it, and so far
> > you haven't made that argument to me all. In fact your scheduler
> > arguments works against you. If we should have abstracted i915
> > scheduler out and used it because it had more features and
> > pre-existed, then i915 should be using TTM since it's already
> > abstracted out and has more features.
> >
> > Like we've pulled other stuff out of TTM like reservation objects, I
> > don't think i915 uses those yet either when it clearly could be. Maybe
> > if we started by fixing that, moving to TTM would be less of a
> > problem.
> 
> Just to make it extra clear: At least I absolutely won't mind if we 
> decommission TTM further!
> 
> We have optimized TTM as much as we could without a fundamental design 
> change, but essentially there are a couple of problem we can't fix 
> without touching all drivers at once.
> 
> For example the layered design where TTM calls back into the driver to 
> move stuff around or allocate something from a domain really needs to go 
> away.
> 
> So my suggestion is that we filleting TTM into multiple independent 
> components which a) can be used to implement the existing TTM interface 
> and b) implement a clean and encapsulated functionality.
> 
> Those components can then be used by drivers independently of TTM to 
> implement the necessary MM.

This is exactly what I was hoping we could do, too. So I'm glad to hear
this suggestion. 

Incrementally extracting and sharing the components would lead to less
disruptions than halting the progress while doing a major rewrite of
the driver.

As I mentioned in IRC, one good step for both the scheduler and memory
management would be to actually map out the feature sets. It is clear
that we have confusion about what the feature set of the respective
components are (at least I do seem to have about TTM / DRM scheduler).

Then when we understand what it is that we actually have, it should be
easier to start discussing which are the components that could be reused.

I think one good way to take on this would be to look into sharing as
much of the test assets as possible. We have plenty of testcases
excercising the low-on-memory conditions and scheduling corner cases
that we've had to tackle. And I'm sure there are tests for the above
mentioned TTM VRAM tuning, too.

I'll look into and discuss the reservation objects Dave mentioned, and
I'm happy to hear about other suggestions.

I'd also like to hear comments about the buddy allocator suggestion. It
should help in enabling >4K page support for pretty much any driver.

Regards, Joonas

> Regards,
> Christian.
> 
> >
> > Anyways, I expect moving to TTM is a big change for i915, and probably
> > more than you are able to bite off at present, but I'm going to be
> > watching closely what stuff you add on top of this sort of thing, and
> > if it starts getting large and messier as you tune it, I'll have to
> > start reconsidering how big a NO I have to use.
> >
> > Dave.
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 97+ messages in thread

end of thread, other threads:[~2019-02-27 14:40 UTC | newest]

Thread overview: 97+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-14 14:56 [RFC PATCH 00/42] Introduce memory region concept (including device local memory) Matthew Auld
2019-02-14 14:56 ` [RFC PATCH 01/42] drm/i915: support 1G pages for the 48b PPGTT Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 02/42] drm/i915: enable platform support for 1G pages Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 03/42] drm/i915: buddy allocator Matthew Auld
2019-02-15 12:34   ` Jani Nikula
2019-02-15 15:03     ` Chris Wilson
2019-02-18 11:35       ` Jani Nikula
2019-02-14 14:57 ` [RFC PATCH 04/42] drm/i915: introduce intel_memory_region Matthew Auld
2019-02-14 15:16   ` Chris Wilson
2019-02-26 14:03     ` Matthew Auld
2019-02-26 14:18       ` Chris Wilson
2019-02-26 13:00   ` Tvrtko Ursulin
2019-02-26 14:20     ` Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 05/42] drm/i915/region: support basic eviction Matthew Auld
2019-02-14 15:25   ` Chris Wilson
2019-02-26 14:58     ` Matthew Auld
2019-02-26 16:49       ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 06/42] drm/i915/region: support continuous allocations Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 07/42] drm/i915/region: support volatile objects Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 08/42] drm/i915: Add memory region information to device_info Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 09/42] drm/i915: support creating LMEM objects Matthew Auld
2019-02-14 15:30   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 10/42] drm/i915/lmem: add helper to get CPU visible pfn Matthew Auld
2019-02-14 15:33   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 11/42] drm/i915/selftests: exercise writes to LMEM Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 12/42] drm/i915/selftests: exercise huge-pages for LMEM Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 13/42] drm/i915: support object clearing via blitter engine Matthew Auld
2019-02-14 15:37   ` Chris Wilson
2019-02-14 15:38   ` Chris Wilson
2019-02-14 15:40   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 14/42] drm/i915: introduce kernel blitter_context Matthew Auld
2019-02-14 15:42   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 15/42] drm/i915: support copying objects via blitter engine Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 16/42] drm/i915: support basic object migration Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 17/42] drm/i915/lmem: support kernel mapping Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 18/42] drm/i915/lmem: support CPU relocations Matthew Auld
2019-02-14 15:48   ` Chris Wilson
2019-02-26 18:53     ` Matthew Auld
2019-02-26 18:58       ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 19/42] drm/i915: add vfunc for pread Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 20/42] drm/i915/lmem: support pread Matthew Auld
2019-02-14 15:50   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 21/42] drm/i915/lmem: support pwrite Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 22/42] drm/i915: define HAS_MAPPABLE_APERTURE Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 23/42] drm/i915: do not map aperture if it is not available Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 24/42] drm/i915: expose missing map_gtt support to users Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 25/42] drm/i915: set num_fence_regs to 0 if there is no aperture Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 26/42] drm/i915: error capture with no ggtt slot Matthew Auld
2019-02-14 15:56   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 27/42] drm/i915: Don't try to place HWS in non-existing mappable region Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 28/42] drm/i915: Split out GTT fault handler to make it generic Matthew Auld
2019-02-14 16:00   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 29/42] drm/i915: Set correct vmf source pages for gem objects Matthew Auld
2019-02-14 16:02   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 30/42] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET Matthew Auld
2019-02-14 16:05   ` Chris Wilson
2019-02-26 13:34   ` Tvrtko Ursulin
2019-02-26 13:37     ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 31/42] drm/i915: cpu-map based dumb buffers Matthew Auld
2019-02-14 16:06   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 32/42] drm/i915: Add fill_pages handler for dma_buf imported objects Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 33/42] UPSTREAM: drm/i915/query: Split out query item checks Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 34/42] drm/i915/query: Expose memory regions through the query uAPI Matthew Auld
2019-02-14 16:31   ` Chris Wilson
2019-02-14 16:33     ` Chris Wilson
2019-02-14 21:12       ` Chris Wilson
2019-02-14 21:15   ` Chris Wilson
2019-02-14 21:21     ` Chris Wilson
2019-02-20 18:56     ` Jason Ekstrand
2019-02-14 14:57 ` [RFC PATCH 35/42] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION Matthew Auld
2019-02-14 16:20   ` Chris Wilson
2019-02-14 14:57 ` [RFC PATCH 36/42] drm/i915/lmem: include debugfs metrics Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 37/42] drm/i915: enumerate and init each supported region Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 38/42] drm/i915: treat shmem as a region Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 39/42] drm/i915: treat stolen " Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 40/42] drm/i915: setup io-mapping for LMEM Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 41/42] HAX drm/i915: add the fake lmem region Matthew Auld
2019-02-14 14:57 ` [RFC PATCH 42/42] HAX drm/i915/lmem: default userspace allocations to LMEM Matthew Auld
2019-02-14 16:13   ` Chris Wilson
2019-02-18 12:44     ` Chris Wilson
2019-02-19 17:44     ` Chris Wilson
2019-02-14 16:22   ` Chris Wilson
2019-02-14 17:58 ` ✗ Fi.CI.CHECKPATCH: warning for Introduce memory region concept (including device local memory) Patchwork
2019-02-14 18:15 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-02-15  0:47 ` [RFC PATCH 00/42] " Dave Airlie
2019-02-19 13:32   ` Joonas Lahtinen
2019-02-25 20:24     ` Dave Airlie
2019-02-26  2:35       ` [Intel-gfx] " Joonas Lahtinen
2019-02-26  5:31         ` Alex Deucher
2019-02-26 10:41           ` Jani Nikula
2019-02-26 12:17           ` Joonas Lahtinen
2019-02-26 17:20             ` Alex Deucher
2019-02-26 18:52               ` Christian König
2019-02-26 19:14               ` Alex Deucher
2019-02-26 23:04                 ` Dave Airlie
2019-02-27 12:17                   ` Christian König
2019-02-27 14:40                     ` Joonas Lahtinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.