drm/i915/region: fix max size calculation
We are incorrectly limiting the max allocation size as per the mm max_order, which is effectively the largest power-of-two that we can fit in the region size. However, it's normal to setup the region or allocator with a non-power-of-two size(for example 3G), which we should already handle correctly, except it seems for the early too-big-check. v2: make sure we also exercise the I915_BO_ALLOC_CONTIGUOUS path, which is quite different, since for that we are actually limited by the largest power-of-two that we can fit within the region size. (Chris) Fixes:b908be543e
("drm/i915: support creating LMEM objects") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: CQ Tang <cq.tang@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/20201021103606.241395-1-matthew.auld@intel.com (cherry picked from commit83ebef47f8
) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
parent
3650b228f8
commit
09a729b178
|
@ -87,7 +87,7 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem,
|
|||
min_order = ilog2(size) - ilog2(mem->mm.chunk_size);
|
||||
}
|
||||
|
||||
if (size > BIT(mem->mm.max_order) * mem->mm.chunk_size)
|
||||
if (size > mem->mm.size)
|
||||
return -E2BIG;
|
||||
|
||||
n_pages = size >> ilog2(mem->mm.chunk_size);
|
||||
|
|
|
@ -261,6 +261,82 @@ err_close_objects:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int igt_mock_splintered_region(void *arg)
|
||||
{
|
||||
struct intel_memory_region *mem = arg;
|
||||
struct drm_i915_private *i915 = mem->i915;
|
||||
struct drm_i915_gem_object *obj;
|
||||
unsigned int expected_order;
|
||||
LIST_HEAD(objects);
|
||||
u64 size;
|
||||
int err = 0;
|
||||
|
||||
/*
|
||||
* Sanity check we can still allocate everything even if the
|
||||
* mm.max_order != mm.size. i.e our starting address space size is not a
|
||||
* power-of-two.
|
||||
*/
|
||||
|
||||
size = (SZ_4G - 1) & PAGE_MASK;
|
||||
mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0);
|
||||
if (IS_ERR(mem))
|
||||
return PTR_ERR(mem);
|
||||
|
||||
if (mem->mm.size != size) {
|
||||
pr_err("%s size mismatch(%llu != %llu)\n",
|
||||
__func__, mem->mm.size, size);
|
||||
err = -EINVAL;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
expected_order = get_order(rounddown_pow_of_two(size));
|
||||
if (mem->mm.max_order != expected_order) {
|
||||
pr_err("%s order mismatch(%u != %u)\n",
|
||||
__func__, mem->mm.max_order, expected_order);
|
||||
err = -EINVAL;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
obj = igt_object_create(mem, &objects, size, 0);
|
||||
if (IS_ERR(obj)) {
|
||||
err = PTR_ERR(obj);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
close_objects(mem, &objects);
|
||||
|
||||
/*
|
||||
* While we should be able allocate everything without any flag
|
||||
* restrictions, if we consider I915_BO_ALLOC_CONTIGUOUS then we are
|
||||
* actually limited to the largest power-of-two for the region size i.e
|
||||
* max_order, due to the inner workings of the buddy allocator. So make
|
||||
* sure that does indeed hold true.
|
||||
*/
|
||||
|
||||
obj = igt_object_create(mem, &objects, size, I915_BO_ALLOC_CONTIGUOUS);
|
||||
if (!IS_ERR(obj)) {
|
||||
pr_err("%s too large contiguous allocation was not rejected\n",
|
||||
__func__);
|
||||
err = -EINVAL;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
obj = igt_object_create(mem, &objects, rounddown_pow_of_two(size),
|
||||
I915_BO_ALLOC_CONTIGUOUS);
|
||||
if (IS_ERR(obj)) {
|
||||
pr_err("%s largest possible contiguous allocation failed\n",
|
||||
__func__);
|
||||
err = PTR_ERR(obj);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
out_close:
|
||||
close_objects(mem, &objects);
|
||||
out_put:
|
||||
intel_memory_region_put(mem);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int igt_gpu_write_dw(struct intel_context *ce,
|
||||
struct i915_vma *vma,
|
||||
u32 dword,
|
||||
|
@ -771,6 +847,7 @@ int intel_memory_region_mock_selftests(void)
|
|||
static const struct i915_subtest tests[] = {
|
||||
SUBTEST(igt_mock_fill),
|
||||
SUBTEST(igt_mock_contiguous),
|
||||
SUBTEST(igt_mock_splintered_region),
|
||||
};
|
||||
struct intel_memory_region *mem;
|
||||
struct drm_i915_private *i915;
|
||||
|
|
|
@ -24,7 +24,7 @@ mock_object_create(struct intel_memory_region *mem,
|
|||
struct drm_i915_private *i915 = mem->i915;
|
||||
struct drm_i915_gem_object *obj;
|
||||
|
||||
if (size > BIT(mem->mm.max_order) * mem->mm.chunk_size)
|
||||
if (size > mem->mm.size)
|
||||
return ERR_PTR(-E2BIG);
|
||||
|
||||
obj = i915_gem_object_alloc();
|
||||
|
|
Loading…
Reference in New Issue