diff options
author | Matthew Auld <matthew.auld@intel.com> | 2021-01-26 13:30:19 +0300 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2021-03-24 21:30:35 +0300 |
commit | a29a22917d4cf14ad4e7a8c4c503629d5a771f06 (patch) | |
tree | 12c4b8765b23abc8bf0e012620679d3ac2331c0f /drivers/gpu/drm | |
parent | b3f0c15a8ef16ce402a2a51f98b43b485c2e0c6d (diff) | |
download | linux-a29a22917d4cf14ad4e7a8c4c503629d5a771f06.tar.xz |
drm/i915/buddy: document the unused header bits
The largest possible order is (63-PAGE_SHIFT), given that our min chunk
size is PAGE_SIZE. With that we should only need at most 6 bits to
represent all possible orders, giving us back 4 bits for other potential
uses. Include a simple selftest to verify this.
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/20210126103019.177622-1-matthew.auld@intel.com
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_buddy.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_buddy.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_buddy.c | 48 |
3 files changed, 56 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_buddy.c b/drivers/gpu/drm/i915/i915_buddy.c index 20babbdb297d..3a2f6eecb2fc 100644 --- a/drivers/gpu/drm/i915/i915_buddy.c +++ b/drivers/gpu/drm/i915/i915_buddy.c @@ -48,6 +48,8 @@ static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_block *parent { struct i915_buddy_block *block; + GEM_BUG_ON(order > I915_BUDDY_MAX_ORDER); + block = kmem_cache_zalloc(global.slab_blocks, GFP_KERNEL); if (!block) return NULL; @@ -56,6 +58,7 @@ static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_block *parent block->header |= order; block->parent = parent; + GEM_BUG_ON(block->header & I915_BUDDY_HEADER_UNUSED); return block; } diff --git a/drivers/gpu/drm/i915/i915_buddy.h b/drivers/gpu/drm/i915/i915_buddy.h index ed41f3507cdc..9ce5200f4001 100644 --- a/drivers/gpu/drm/i915/i915_buddy.h +++ b/drivers/gpu/drm/i915/i915_buddy.h @@ -15,7 +15,9 @@ struct i915_buddy_block { #define I915_BUDDY_ALLOCATED (1 << 10) #define I915_BUDDY_FREE (2 << 10) #define I915_BUDDY_SPLIT (3 << 10) -#define I915_BUDDY_HEADER_ORDER GENMASK_ULL(9, 0) +/* Free to be used, if needed in the future */ +#define I915_BUDDY_HEADER_UNUSED GENMASK_ULL(9, 6) +#define I915_BUDDY_HEADER_ORDER GENMASK_ULL(5, 0) u64 header; struct i915_buddy_block *left; @@ -34,7 +36,8 @@ struct i915_buddy_block { struct list_head tmp_link; }; -#define I915_BUDDY_MAX_ORDER I915_BUDDY_HEADER_ORDER +/* Order-zero must be at least PAGE_SIZE */ +#define I915_BUDDY_MAX_ORDER (63 - PAGE_SHIFT) /* * Binary Buddy System. diff --git a/drivers/gpu/drm/i915/selftests/i915_buddy.c b/drivers/gpu/drm/i915/selftests/i915_buddy.c index 632b912b0bc9..f0f5c4df8dbc 100644 --- a/drivers/gpu/drm/i915/selftests/i915_buddy.c +++ b/drivers/gpu/drm/i915/selftests/i915_buddy.c @@ -727,6 +727,53 @@ err_fini: return err; } +static int igt_buddy_alloc_limit(void *arg) +{ + struct i915_buddy_block *block; + struct i915_buddy_mm mm; + const u64 size = U64_MAX; + int err; + + err = i915_buddy_init(&mm, size, PAGE_SIZE); + if (err) + return err; + + if (mm.max_order != I915_BUDDY_MAX_ORDER) { + pr_err("mm.max_order(%d) != %d\n", + mm.max_order, I915_BUDDY_MAX_ORDER); + err = -EINVAL; + goto out_fini; + } + + block = i915_buddy_alloc(&mm, mm.max_order); + if (IS_ERR(block)) { + err = PTR_ERR(block); + goto out_fini; + } + + if (i915_buddy_block_order(block) != mm.max_order) { + pr_err("block order(%d) != %d\n", + i915_buddy_block_order(block), mm.max_order); + err = -EINVAL; + goto out_free; + } + + if (i915_buddy_block_size(&mm, block) != + BIT_ULL(mm.max_order) * PAGE_SIZE) { + pr_err("block size(%llu) != %llu\n", + i915_buddy_block_size(&mm, block), + BIT_ULL(mm.max_order) * PAGE_SIZE); + err = -EINVAL; + goto out_free; + } + +out_free: + i915_buddy_free(&mm, block); +out_fini: + i915_buddy_fini(&mm); + return err; +} + int i915_buddy_mock_selftests(void) { static const struct i915_subtest tests[] = { @@ -735,6 +782,7 @@ int i915_buddy_mock_selftests(void) SUBTEST(igt_buddy_alloc_pathological), SUBTEST(igt_buddy_alloc_smoke), SUBTEST(igt_buddy_alloc_range), + SUBTEST(igt_buddy_alloc_limit), }; return i915_subtests(tests, NULL); |