Skip to content

Commit d507ae0

Browse files
arunpravin24alexdeucher
authored andcommitted
drm/buddy: Add start address support to trim function
- 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 <[email protected]> Acked-by: Alex Deucher <[email protected]> Acked-by: Christian König <[email protected]> Signed-off-by: Alex Deucher <[email protected]> (cherry picked from commit db65eb4)
1 parent e8097cf commit d507ae0

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

drivers/gpu/drm/drm_buddy.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ static int __alloc_contig_try_harder(struct drm_buddy *mm,
851851
* drm_buddy_block_trim - free unused pages
852852
*
853853
* @mm: DRM buddy manager
854+
* @start: start address to begin the trimming.
854855
* @new_size: original size requested
855856
* @blocks: Input and output list of allocated blocks.
856857
* MUST contain single block as input to be trimmed.
@@ -866,11 +867,13 @@ static int __alloc_contig_try_harder(struct drm_buddy *mm,
866867
* 0 on success, error code on failure.
867868
*/
868869
int drm_buddy_block_trim(struct drm_buddy *mm,
870+
u64 *start,
869871
u64 new_size,
870872
struct list_head *blocks)
871873
{
872874
struct drm_buddy_block *parent;
873875
struct drm_buddy_block *block;
876+
u64 block_start, block_end;
874877
LIST_HEAD(dfs);
875878
u64 new_start;
876879
int err;
@@ -882,6 +885,9 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
882885
struct drm_buddy_block,
883886
link);
884887

888+
block_start = drm_buddy_block_offset(block);
889+
block_end = block_start + drm_buddy_block_size(mm, block);
890+
885891
if (WARN_ON(!drm_buddy_block_is_allocated(block)))
886892
return -EINVAL;
887893

@@ -894,6 +900,20 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
894900
if (new_size == drm_buddy_block_size(mm, block))
895901
return 0;
896902

903+
new_start = block_start;
904+
if (start) {
905+
new_start = *start;
906+
907+
if (new_start < block_start)
908+
return -EINVAL;
909+
910+
if (!IS_ALIGNED(new_start, mm->chunk_size))
911+
return -EINVAL;
912+
913+
if (range_overflows(new_start, new_size, block_end))
914+
return -EINVAL;
915+
}
916+
897917
list_del(&block->link);
898918
mark_free(mm, block);
899919
mm->avail += drm_buddy_block_size(mm, block);
@@ -904,7 +924,6 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
904924
parent = block->parent;
905925
block->parent = NULL;
906926

907-
new_start = drm_buddy_block_offset(block);
908927
list_add(&block->tmp_link, &dfs);
909928
err = __alloc_range(mm, &dfs, new_start, new_size, blocks, NULL);
910929
if (err) {
@@ -1066,7 +1085,8 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
10661085
} while (1);
10671086

10681087
/* Trim the allocated block to the required size */
1069-
if (original_size != size) {
1088+
if (!(flags & DRM_BUDDY_TRIM_DISABLE) &&
1089+
original_size != size) {
10701090
struct list_head *trim_list;
10711091
LIST_HEAD(temp);
10721092
u64 trim_size;
@@ -1083,6 +1103,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
10831103
}
10841104

10851105
drm_buddy_block_trim(mm,
1106+
NULL,
10861107
trim_size,
10871108
trim_list);
10881109

drivers/gpu/drm/xe/xe_ttm_vram_mgr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ static int xe_ttm_vram_mgr_new(struct ttm_resource_manager *man,
150150
} while (remaining_size);
151151

152152
if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
153-
if (!drm_buddy_block_trim(mm, vres->base.size, &vres->blocks))
153+
if (!drm_buddy_block_trim(mm, NULL, vres->base.size, &vres->blocks))
154154
size = vres->base.size;
155155
}
156156

include/drm/drm_buddy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#define DRM_BUDDY_CONTIGUOUS_ALLOCATION BIT(2)
2828
#define DRM_BUDDY_CLEAR_ALLOCATION BIT(3)
2929
#define DRM_BUDDY_CLEARED BIT(4)
30+
#define DRM_BUDDY_TRIM_DISABLE BIT(5)
3031

3132
struct drm_buddy_block {
3233
#define DRM_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12)
@@ -155,6 +156,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
155156
unsigned long flags);
156157

157158
int drm_buddy_block_trim(struct drm_buddy *mm,
159+
u64 *start,
158160
u64 new_size,
159161
struct list_head *blocks);
160162

0 commit comments

Comments
 (0)