[PATCH] drm/buddy: Add start address support to trim function
Matthew Auld
matthew.auld at intel.com
Wed Jul 10 12:50:22 UTC 2024
On 10/07/2024 07:03, Paneer Selvam, Arunpravin wrote:
> Thanks Alex.
>
> Hi Matthew,
> Any comments?
Do we not pass the required address alignment when allocating the pages
in the first place?
>
> Thanks,
> Arun.
>
> On 7/9/2024 1:42 AM, Alex Deucher wrote:
>> On Thu, Jul 4, 2024 at 4:40 AM Arunpravin Paneer Selvam
>> <Arunpravin.PaneerSelvam at amd.com> wrote:
>>> - Add a new start parameter in trim function to specify exact
>>> address from where to start the trimming. This would help us
>>> in situations like if drivers would like to do address alignment
>>> for specific requirements.
>>>
>>> - Add a new flag DRM_BUDDY_TRIM_DISABLE. Drivers can use this
>>> flag to disable the allocator trimming part. This patch enables
>>> the drivers control trimming and they can do it themselves
>>> based on the application requirements.
>>>
>>> v1:(Matthew)
>>> - check new_start alignment with min chunk_size
>>> - use range_overflows()
>>>
>>> Signed-off-by: Arunpravin Paneer Selvam
>>> <Arunpravin.PaneerSelvam at amd.com>
>> Series is:
>> Acked-by: Alex Deucher <alexander.deucher at amd.com>
>>
>> I'd like to take this series through the amdgpu tree if there are no
>> objections as it's required for display buffers on some chips and I'd
>> like to make sure it lands in 6.11.
>>
>> Thanks,
>>
>> Alex
>>
>>> ---
>>> drivers/gpu/drm/drm_buddy.c | 25 +++++++++++++++++++++++--
>>> drivers/gpu/drm/xe/xe_ttm_vram_mgr.c | 2 +-
>>> include/drm/drm_buddy.h | 2 ++
>>> 3 files changed, 26 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
>>> index 94f8c34fc293..8cebe1fa4e9d 100644
>>> --- a/drivers/gpu/drm/drm_buddy.c
>>> +++ b/drivers/gpu/drm/drm_buddy.c
>>> @@ -851,6 +851,7 @@ static int __alloc_contig_try_harder(struct
>>> drm_buddy *mm,
>>> * drm_buddy_block_trim - free unused pages
>>> *
>>> * @mm: DRM buddy manager
>>> + * @start: start address to begin the trimming.
>>> * @new_size: original size requested
>>> * @blocks: Input and output list of allocated blocks.
>>> * MUST contain single block as input to be trimmed.
>>> @@ -866,11 +867,13 @@ static int __alloc_contig_try_harder(struct
>>> drm_buddy *mm,
>>> * 0 on success, error code on failure.
>>> */
>>> int drm_buddy_block_trim(struct drm_buddy *mm,
>>> + u64 *start,
>>> u64 new_size,
>>> struct list_head *blocks)
>>> {
>>> struct drm_buddy_block *parent;
>>> struct drm_buddy_block *block;
>>> + u64 block_start, block_end;
>>> LIST_HEAD(dfs);
>>> u64 new_start;
>>> int err;
>>> @@ -882,6 +885,9 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
>>> struct drm_buddy_block,
>>> link);
>>>
>>> + block_start = drm_buddy_block_offset(block);
>>> + block_end = block_start + drm_buddy_block_size(mm, block);
>>> +
>>> if (WARN_ON(!drm_buddy_block_is_allocated(block)))
>>> return -EINVAL;
>>>
>>> @@ -894,6 +900,20 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
>>> if (new_size == drm_buddy_block_size(mm, block))
>>> return 0;
>>>
>>> + new_start = block_start;
>>> + if (start) {
>>> + new_start = *start;
>>> +
>>> + if (new_start < block_start)
>>> + return -EINVAL;
>>> +
>>> + if (!IS_ALIGNED(new_start, mm->chunk_size))
>>> + return -EINVAL;
>>> +
>>> + if (range_overflows(new_start, new_size, block_end))
>>> + return -EINVAL;
>>> + }
>>> +
>>> list_del(&block->link);
>>> mark_free(mm, block);
>>> mm->avail += drm_buddy_block_size(mm, block);
>>> @@ -904,7 +924,6 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
>>> parent = block->parent;
>>> block->parent = NULL;
>>>
>>> - new_start = drm_buddy_block_offset(block);
>>> list_add(&block->tmp_link, &dfs);
>>> err = __alloc_range(mm, &dfs, new_start, new_size, blocks,
>>> NULL);
>>> if (err) {
>>> @@ -1066,7 +1085,8 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>>> } while (1);
>>>
>>> /* Trim the allocated block to the required size */
>>> - if (original_size != size) {
>>> + if (!(flags & DRM_BUDDY_TRIM_DISABLE) &&
>>> + original_size != size) {
>>> struct list_head *trim_list;
>>> LIST_HEAD(temp);
>>> u64 trim_size;
>>> @@ -1083,6 +1103,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>>> }
>>>
>>> drm_buddy_block_trim(mm,
>>> + NULL,
>>> trim_size,
>>> trim_list);
>>>
>>> diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
>>> b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
>>> index fe3779fdba2c..423b261ea743 100644
>>> --- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
>>> +++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
>>> @@ -150,7 +150,7 @@ static int xe_ttm_vram_mgr_new(struct
>>> ttm_resource_manager *man,
>>> } while (remaining_size);
>>>
>>> if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
>>> - if (!drm_buddy_block_trim(mm, vres->base.size,
>>> &vres->blocks))
>>> + if (!drm_buddy_block_trim(mm, NULL, vres->base.size,
>>> &vres->blocks))
>>> size = vres->base.size;
>>> }
>>>
>>> diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h
>>> index 82570f77e817..0c2f735f0265 100644
>>> --- a/include/drm/drm_buddy.h
>>> +++ b/include/drm/drm_buddy.h
>>> @@ -27,6 +27,7 @@
>>> #define DRM_BUDDY_CONTIGUOUS_ALLOCATION BIT(2)
>>> #define DRM_BUDDY_CLEAR_ALLOCATION BIT(3)
>>> #define DRM_BUDDY_CLEARED BIT(4)
>>> +#define DRM_BUDDY_TRIM_DISABLE BIT(5)
>>>
>>> struct drm_buddy_block {
>>> #define DRM_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12)
>>> @@ -155,6 +156,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>>> unsigned long flags);
>>>
>>> int drm_buddy_block_trim(struct drm_buddy *mm,
>>> + u64 *start,
>>> u64 new_size,
>>> struct list_head *blocks);
>>>
>>> --
>>> 2.25.1
>>>
>
More information about the amd-gfx
mailing list