On Sun, 13 Sept 2026 at 18:49, David Gow <[email protected]> wrote:
>
> The standard roundup_pow_of_two() and rounddown_pow_of_two() macros use
> unsigned long internally, which on 32-bit architectures (like arm32) is
> a 32-bit type.
>
> drm_test_buddy_alloc_exceeds_max_order() uses these on a u64 value,
> where they silently truncate the 10GB allocation, giving unexpected
> success in DRM-CI. (see below the snip).
>
> Fix this by replacing the those macros with safe 64-bit power-of-two
> calculations using ilog2().
If we are going to do this, but fix it properly later, I'd rather we
add the 2 64-bit macros to the buddy allocator and use them,rather
than open-coding this, then knowing we did it later.
so add 64-bit rounddown/roundup macros earlier in this file with a
comment, then use them here.
Dave.
>
> Fixes: 0a1844bf0b532 ("drm/buddy: Improve contiguous memory allocation")
> Signed-off-by: Jim Cromie <[email protected]>
> Signed-off-by: David Gow <[email protected]>
> ---
>
> This is a straightforward rebase of patch 39 of v12 of this series:
> https://lore.kernel.org/all/[email protected]/
>
> The only changes are updating the buddy path (as it's no longer a part of
> DRM), and adding the Fixes tag.
>
> This is a fairly hacky solution: I've got a nicer series which adds clearer
> helpers and generally cleans up all of these macros on 32-bit systems, but
> it's much larger (and growing as more things need cleaning up), so I'd
> rather have this more urgent fix go in immediately, and save the cleanup
> for a less-urgent follow-up series:
> https://lore.kernel.org/all/[email protected]/
>
> As noted in the original series, this is causing KUnit test failures on
> all 32-bit architectures:
> [09:01:26] # gpu_test_buddy_alloc_exceeds_max_order: EXPECTATION FAILED
> at drivers/gpu/tests/gpu_buddy_test.c:1429
> [09:01:26] Expected err == -22, but
> [09:01:26] err == 0 (0x0)
> [09:01:26] WARNING: drivers/gpu/buddy.c:508 at gpu_buddy_fini+0x244/0x2e0,
> CPU#0: kunit_try_catch/1595
> [09:01:26] # gpu_test_buddy_alloc_exceeds_max_order:
> drivers/gpu/buddy.c:508:
> gpu_buddy_assert(gpu_buddy_block_is_free(mm->roots[i]))
> [09:01:26] WARNING: drivers/gpu/buddy.c:516 at gpu_buddy_fini+0x284/0x2e0,
> CPU#0: kunit_try_catch/1595
> [09:01:26] # gpu_test_buddy_alloc_exceeds_max_order:
> drivers/gpu/buddy.c:508:
> gpu_buddy_assert(gpu_buddy_block_is_free(mm->roots[i]))
> [09:01:26] WARNING: drivers/gpu/buddy.c:516 at gpu_buddy_fini+0x284/0x2e0,
> CPU#0: kunit_try_catch/1595
> [09:01:26] # gpu_test_buddy_alloc_exceeds_max_order:
> drivers/gpu/buddy.c:519: gpu_buddy_assert(!mm->used_scoreboard[i])
> [09:01:26] [FAILED] gpu_test_buddy_alloc_exceeds_max_order
>
> Cheers,
> -- David
>
> ---
> drivers/gpu/buddy.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/buddy.c b/drivers/gpu/buddy.c
> index 26e7a48b55f3..964a5ae78f1b 100644
> --- a/drivers/gpu/buddy.c
> +++ b/drivers/gpu/buddy.c
> @@ -1188,7 +1188,7 @@ static int __alloc_contig_try_harder(struct gpu_buddy
> *mm,
> u64 modify_size;
> int err;
>
> - modify_size = rounddown_pow_of_two(size);
> + modify_size = 1ULL << ilog2(size);
> order = ilog2(modify_size) - ilog2(mm->chunk_size);
> if (order == 0)
> return -ENOSPC;
> @@ -1435,7 +1435,7 @@ int gpu_buddy_alloc_blocks(struct gpu_buddy *mm,
>
> /* Roundup the size to power of 2 */
> if (flags & GPU_BUDDY_CONTIGUOUS_ALLOCATION) {
> - size = roundup_pow_of_two(size);
> + size = 1ULL << (ilog2(size - 1) + 1);
> min_block_size = size;
> /*
> * Normalize the requested size to min_block_size for regular
> allocations.
> --
> 2.55.0
>