From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Matthew Auld <matthew.auld@intel.com>, intel-gfx@lists.freedesktop.org
Subject: Re: [RFC PATCH 04/42] drm/i915: introduce intel_memory_region
Date: Tue, 26 Feb 2019 13:00:28 +0000 [thread overview]
Message-ID: <0b6d3fca-a482-9b57-35fe-fd1ce03196b9@linux.intel.com> (raw)
In-Reply-To: <20190214145740.14521-5-matthew.auld@intel.com>
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
next prev parent reply other threads:[~2019-02-26 13:00 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 ` [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 [this message]
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=0b6d3fca-a482-9b57-35fe-fd1ce03196b9@linux.intel.com \
--to=tvrtko.ursulin@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=matthew.auld@intel.com \
/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