[PATCH] drm: round_up the size to the alignment value

Christian König christian.koenig at amd.com
Wed Mar 30 09:07:44 UTC 2022


Am 30.03.22 um 11:04 schrieb Arunpravin Paneer Selvam:
> Round up the size value to the min_page_size and trim the last block to
> the required size.
>
> This solves a bug detected when size is not aligned with the min_page_size.
> Unigine Heaven has allocation requests for example required pages are 257
> and alignment request is 256. To allocate the left over 1 page, continues
> the iteration to find the order value which is 0 and when it compares with
> min_order = 8, triggers the BUG_ON(order < min_order). To avoid this issue
> we round_up the size value to the min_page_size and trim the last block to
> the computed required size value.

Well, Matthew and you convinced me to *not* do it like this.

Has that conclusion changed somehow?

Regards,
Christian.

>
> Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam at amd.com>
> ---
>   drivers/gpu/drm/drm_buddy.c | 31 +++++++++++++++++++++++++++++++
>   1 file changed, 31 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
> index 72f52f293249..98d7ec359b08 100644
> --- a/drivers/gpu/drm/drm_buddy.c
> +++ b/drivers/gpu/drm/drm_buddy.c
> @@ -641,6 +641,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>   	unsigned int min_order, order;
>   	unsigned long pages;
>   	LIST_HEAD(allocated);
> +	u64 cur_size;
>   	int err;
>   
>   	if (size < mm->chunk_size)
> @@ -665,6 +666,11 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>   	if (start + size == end)
>   		return __drm_buddy_alloc_range(mm, start, size, blocks);
>   
> +	cur_size = size;
> +
> +	if (!IS_ALIGNED(size, min_page_size))
> +		size = round_up(size, min_page_size);
> +
>   	pages = size >> ilog2(mm->chunk_size);
>   	order = fls(pages) - 1;
>   	min_order = ilog2(min_page_size) - ilog2(mm->chunk_size);
> @@ -702,6 +708,31 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>   			break;
>   	} while (1);
>   
> +
> +	/*
> +	 * If size value rounded up to min_page_size, trim the last block
> +	 * to the required size
> +	 */
> +	if (cur_size != size) {
> +		struct drm_buddy_block *trim_block;
> +		LIST_HEAD(trim_list);
> +		u64 required_size;
> +
> +		trim_block = list_last_entry(&allocated, typeof(*trim_block), link);
> +		list_move_tail(&trim_block->link, &trim_list);
> +		/*
> +		 * Compute the required_size value by subtracting the last block size
> +		 * with (aligned size - original size)
> +		 */
> +		required_size = drm_buddy_block_size(mm, trim_block) - (size - cur_size);
> +
> +		drm_buddy_block_trim(mm,
> +				     required_size,
> +				     &trim_list);
> +
> +		list_splice_tail(&trim_list, &allocated);
> +	}
> +
>   	list_splice_tail(&allocated, blocks);
>   	return 0;
>   
>
> base-commit: ec57376fba5abc0e571617ff88e2ade7970c2e4b



More information about the dri-devel mailing list