-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drm/i915: introduce intel_memory_region
Support memory regions, as defined by a given (start, end), and allow creating GEM objects which are backed by said region. The immediate goal here is to have something to represent our device memory, but later on we also want to represent every memory domain with a region, so stolen, shmem, and of course device. At some point we are probably going to want use a common struct here, such that we are better aligned with say TTM. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20191008160116.18379-2-matthew.auld@intel.com
- Loading branch information
Matthew Auld
authored and
Chris Wilson
committed
Oct 8, 2019
1 parent
d99f7b0
commit 232a6eb
Showing
13 changed files
with
729 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// SPDX-License-Identifier: MIT | ||
/* | ||
* Copyright © 2019 Intel Corporation | ||
*/ | ||
|
||
#include "intel_memory_region.h" | ||
#include "i915_gem_region.h" | ||
#include "i915_drv.h" | ||
|
||
void | ||
i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj, | ||
struct sg_table *pages) | ||
{ | ||
__intel_memory_region_put_pages_buddy(obj->mm.region, &obj->mm.blocks); | ||
|
||
obj->mm.dirty = false; | ||
sg_free_table(pages); | ||
kfree(pages); | ||
} | ||
|
||
int | ||
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; | ||
struct sg_table *st; | ||
struct scatterlist *sg; | ||
unsigned int sg_page_sizes; | ||
int ret; | ||
|
||
st = kmalloc(sizeof(*st), GFP_KERNEL); | ||
if (!st) | ||
return -ENOMEM; | ||
|
||
if (sg_alloc_table(st, size >> ilog2(mem->mm.chunk_size), GFP_KERNEL)) { | ||
kfree(st); | ||
return -ENOMEM; | ||
} | ||
|
||
ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks); | ||
if (ret) | ||
goto err_free_sg; | ||
|
||
GEM_BUG_ON(list_empty(blocks)); | ||
|
||
sg = st->sgl; | ||
st->nents = 0; | ||
sg_page_sizes = 0; | ||
prev_end = (resource_size_t)-1; | ||
|
||
list_for_each_entry(block, blocks, link) { | ||
u64 block_size, offset; | ||
|
||
block_size = i915_buddy_block_size(&mem->mm, block); | ||
offset = i915_buddy_block_offset(block); | ||
|
||
GEM_BUG_ON(overflows_type(block_size, sg->length)); | ||
|
||
if (offset != prev_end || | ||
add_overflows_t(typeof(sg->length), sg->length, block_size)) { | ||
if (st->nents) { | ||
sg_page_sizes |= sg->length; | ||
sg = __sg_next(sg); | ||
} | ||
|
||
sg_dma_address(sg) = mem->region.start + offset; | ||
sg_dma_len(sg) = block_size; | ||
|
||
sg->length = block_size; | ||
|
||
st->nents++; | ||
} else { | ||
sg->length += block_size; | ||
sg_dma_len(sg) += block_size; | ||
} | ||
|
||
prev_end = offset + block_size; | ||
}; | ||
|
||
sg_page_sizes |= sg->length; | ||
sg_mark_end(sg); | ||
i915_sg_trim(st); | ||
|
||
__i915_gem_object_set_pages(obj, st, sg_page_sizes); | ||
|
||
return 0; | ||
|
||
err_free_sg: | ||
sg_free_table(st); | ||
kfree(st); | ||
return ret; | ||
} | ||
|
||
void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj, | ||
struct intel_memory_region *mem) | ||
{ | ||
INIT_LIST_HEAD(&obj->mm.blocks); | ||
obj->mm.region = intel_memory_region_get(mem); | ||
} | ||
|
||
void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj) | ||
{ | ||
intel_memory_region_put(obj->mm.region); | ||
} | ||
|
||
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; | ||
|
||
/* | ||
* NB: Our use of resource_size_t for the size stems from using struct | ||
* resource for the mem->region. We might need to revisit this in the | ||
* future. | ||
*/ | ||
|
||
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)); | ||
|
||
/* | ||
* XXX: 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); | ||
|
||
return mem->ops->create_object(mem, size, flags); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* SPDX-License-Identifier: MIT */ | ||
/* | ||
* Copyright © 2019 Intel Corporation | ||
*/ | ||
|
||
#ifndef __I915_GEM_REGION_H__ | ||
#define __I915_GEM_REGION_H__ | ||
|
||
#include <linux/types.h> | ||
|
||
struct intel_memory_region; | ||
struct drm_i915_gem_object; | ||
struct sg_table; | ||
|
||
int i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj); | ||
void i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj, | ||
struct sg_table *pages); | ||
|
||
void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj, | ||
struct intel_memory_region *mem); | ||
void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj); | ||
|
||
struct drm_i915_gem_object * | ||
i915_gem_object_create_region(struct intel_memory_region *mem, | ||
resource_size_t size, | ||
unsigned int flags); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.