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 <[email protected]>
>> ---
>>   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
> 

Reply via email to