On 30/03/22 2:37 pm, Christian König wrote:
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?
Yes, now he is ok to handle rounding + trimming in drm buddy
Regards, Christian.
Signed-off-by: Arunpravin Paneer Selvam Arunpravin.PaneerSelvam@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