Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <Arunpravin.PaneerSelvam@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit db65eb46de135338d6177f8853e0fd208f19d63e)

authored by

Arunpravin Paneer Selvam and committed by
Alex Deucher
d507ae0d e8097cf1

+26 -3
+23 -2
drivers/gpu/drm/drm_buddy.c
··· 851 851 * drm_buddy_block_trim - free unused pages 852 852 * 853 853 * @mm: DRM buddy manager 854 + * @start: start address to begin the trimming. 854 855 * @new_size: original size requested 855 856 * @blocks: Input and output list of allocated blocks. 856 857 * MUST contain single block as input to be trimmed. ··· 867 866 * 0 on success, error code on failure. 868 867 */ 869 868 int drm_buddy_block_trim(struct drm_buddy *mm, 869 + u64 *start, 870 870 u64 new_size, 871 871 struct list_head *blocks) 872 872 { 873 873 struct drm_buddy_block *parent; 874 874 struct drm_buddy_block *block; 875 + u64 block_start, block_end; 875 876 LIST_HEAD(dfs); 876 877 u64 new_start; 877 878 int err; ··· 884 881 block = list_first_entry(blocks, 885 882 struct drm_buddy_block, 886 883 link); 884 + 885 + block_start = drm_buddy_block_offset(block); 886 + block_end = block_start + drm_buddy_block_size(mm, block); 887 887 888 888 if (WARN_ON(!drm_buddy_block_is_allocated(block))) 889 889 return -EINVAL; ··· 900 894 if (new_size == drm_buddy_block_size(mm, block)) 901 895 return 0; 902 896 897 + new_start = block_start; 898 + if (start) { 899 + new_start = *start; 900 + 901 + if (new_start < block_start) 902 + return -EINVAL; 903 + 904 + if (!IS_ALIGNED(new_start, mm->chunk_size)) 905 + return -EINVAL; 906 + 907 + if (range_overflows(new_start, new_size, block_end)) 908 + return -EINVAL; 909 + } 910 + 903 911 list_del(&block->link); 904 912 mark_free(mm, block); 905 913 mm->avail += drm_buddy_block_size(mm, block); ··· 924 904 parent = block->parent; 925 905 block->parent = NULL; 926 906 927 - new_start = drm_buddy_block_offset(block); 928 907 list_add(&block->tmp_link, &dfs); 929 908 err = __alloc_range(mm, &dfs, new_start, new_size, blocks, NULL); 930 909 if (err) { ··· 1085 1066 } while (1); 1086 1067 1087 1068 /* Trim the allocated block to the required size */ 1088 - if (original_size != size) { 1069 + if (!(flags & DRM_BUDDY_TRIM_DISABLE) && 1070 + original_size != size) { 1089 1071 struct list_head *trim_list; 1090 1072 LIST_HEAD(temp); 1091 1073 u64 trim_size; ··· 1103 1083 } 1104 1084 1105 1085 drm_buddy_block_trim(mm, 1086 + NULL, 1106 1087 trim_size, 1107 1088 trim_list); 1108 1089
+1 -1
drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
··· 150 150 } while (remaining_size); 151 151 152 152 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)) 154 154 size = vres->base.size; 155 155 } 156 156
+2
include/drm/drm_buddy.h
··· 27 27 #define DRM_BUDDY_CONTIGUOUS_ALLOCATION BIT(2) 28 28 #define DRM_BUDDY_CLEAR_ALLOCATION BIT(3) 29 29 #define DRM_BUDDY_CLEARED BIT(4) 30 + #define DRM_BUDDY_TRIM_DISABLE BIT(5) 30 31 31 32 struct drm_buddy_block { 32 33 #define DRM_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12) ··· 156 155 unsigned long flags); 157 156 158 157 int drm_buddy_block_trim(struct drm_buddy *mm, 158 + u64 *start, 159 159 u64 new_size, 160 160 struct list_head *blocks); 161 161