summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_memory_region.c
diff options
context:
space:
mode:
authorVenkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>2020-11-30 13:47:21 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2020-11-30 18:18:26 +0000
commitd2cf0125d4a133a857d3327f7ac1625c84624219 (patch)
tree98a51d23bf8bf9d2fc44bd6116fc5c976ba42c54 /drivers/gpu/drm/i915/intel_memory_region.c
parente96434e1137e9a110014e2d5717348623f68ea77 (diff)
drm/i915/lmem: Limit block size to 4G
Block sizes are only limited by the largest power-of-two that will fit in the region size, but to construct an object we also require feeding it into an sg list, where the upper limit of the sg entry is at most UINT_MAX. Therefore to prevent issues with allocating blocks that are too large, add the flag I915_ALLOC_MAX_SEGMENT_SIZE which should limit block sizes to the i915_sg_segment_size(). v2: (matt) - query the max segment. - prefer flag to limit block size to 4G, since it's best not to assume the user will feed the blocks into an sg list. - simple selftest so we don't have to guess. Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Cc: CQ Tang <cq.tang@intel.com> Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com> Signed-off-by: Matthew Auld <matthew.auld@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/20201130134721.54457-1-matthew.auld@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_memory_region.c')
-rw-r--r--drivers/gpu/drm/i915/intel_memory_region.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index b326993a1026..ae36e2f6d6e3 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -72,6 +72,7 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem,
struct list_head *blocks)
{
unsigned int min_order = 0;
+ unsigned int max_order;
unsigned long n_pages;
GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.chunk_size));
@@ -92,13 +93,28 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem,
n_pages = size >> ilog2(mem->mm.chunk_size);
+ /*
+ * If we going to feed this into an sg list we should limit the block
+ * sizes such that we don't exceed the i915_sg_segment_size().
+ */
+ if (flags & I915_ALLOC_MAX_SEGMENT_SIZE) {
+ unsigned int max_segment = i915_sg_segment_size();
+
+ if (GEM_WARN_ON(max_segment < mem->mm.chunk_size))
+ max_order = 0;
+ else
+ max_order = ilog2(max_segment) - ilog2(mem->mm.chunk_size);
+ } else {
+ max_order = mem->mm.max_order;
+ }
+
mutex_lock(&mem->mm_lock);
do {
struct i915_buddy_block *block;
unsigned int order;
- order = fls(n_pages) - 1;
+ order = min_t(u32, fls(n_pages) - 1, max_order);
GEM_BUG_ON(order > mem->mm.max_order);
GEM_BUG_ON(order < min_order);