From 2f0b97ca02118630132dddf258fbdb5d5f5ec32a Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Tue, 8 Oct 2019 17:01:15 +0100 Subject: drm/i915/region: support contiguous allocations Some kernel internal objects may need to be allocated as a contiguous block, also thinking ahead the various kernel io_mapping interfaces seem to expect it, although this is purely a limitation in the kernel API...so perhaps something to be improved. Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Abdiel Janulgue Cc: Michael J Ruhl Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20191008160116.18379-3-matthew.auld@intel.com --- drivers/gpu/drm/i915/gem/i915_gem_region.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/gem/i915_gem_region.c') diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index 6588e3c99e5d..d94914a86737 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -23,10 +23,10 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) { struct intel_memory_region *mem = obj->mm.region; struct list_head *blocks = &obj->mm.blocks; - unsigned int flags = I915_ALLOC_MIN_PAGE_SIZE; resource_size_t size = obj->base.size; resource_size_t prev_end; struct i915_buddy_block *block; + unsigned int flags; struct sg_table *st; struct scatterlist *sg; unsigned int sg_page_sizes; @@ -41,6 +41,10 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) return -ENOMEM; } + flags = I915_ALLOC_MIN_PAGE_SIZE; + if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) + flags |= I915_ALLOC_CONTIGUOUS; + ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks); if (ret) goto err_free_sg; @@ -55,7 +59,8 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) list_for_each_entry(block, blocks, link) { u64 block_size, offset; - block_size = i915_buddy_block_size(&mem->mm, block); + block_size = min_t(u64, size, + i915_buddy_block_size(&mem->mm, block)); offset = i915_buddy_block_offset(block); GEM_BUG_ON(overflows_type(block_size, sg->length)); @@ -96,10 +101,12 @@ err_free_sg: } void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj, - struct intel_memory_region *mem) + struct intel_memory_region *mem, + unsigned long flags) { INIT_LIST_HEAD(&obj->mm.blocks); obj->mm.region = intel_memory_region_get(mem); + obj->flags |= flags; } void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj) @@ -120,6 +127,8 @@ i915_gem_object_create_region(struct intel_memory_region *mem, * future. */ + GEM_BUG_ON(flags & ~I915_BO_ALLOC_FLAGS); + if (!mem) return ERR_PTR(-ENODEV); -- cgit v1.2.1