public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
Date: Thu, 14 Feb 2019 14:57:02 +0000	[thread overview]
Message-ID: <20190214145740.14521-5-matthew.auld@intel.com> (raw)
In-Reply-To: <20190214145740.14521-1-matthew.auld@intel.com>

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

  parent reply	other threads:[~2019-02-14 14:57 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Matthew Auld [this message]
2019-02-14 15:16   ` [RFC PATCH 04/42] drm/i915: introduce intel_memory_region 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

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20190214145740.14521-5-matthew.auld@intel.com \
    --to=matthew.auld@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

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

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