@@ -916,79 +916,44 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
916916 xe_pm_runtime_get_noresume (xe );
917917 }
918918
919- if (xe_bo_is_pinned (bo ) && !xe_bo_is_user (bo )) {
920- /*
921- * Kernel memory that is pinned should only be moved on suspend
922- * / resume, some of the pinned memory is required for the
923- * device to resume / use the GPU to move other evicted memory
924- * (user memory) around. This likely could be optimized a bit
925- * further where we find the minimum set of pinned memory
926- * required for resume but for simplity doing a memcpy for all
927- * pinned memory.
928- */
929- ret = xe_bo_vmap (bo );
930- if (!ret ) {
931- ret = ttm_bo_move_memcpy (ttm_bo , ctx , new_mem );
932-
933- /* Create a new VMAP once kernel BO back in VRAM */
934- if (!ret && resource_is_vram (new_mem )) {
935- struct xe_vram_region * vram = res_to_mem_region (new_mem );
936- void __iomem * new_addr = vram -> mapping +
937- (new_mem -> start << PAGE_SHIFT );
919+ if (move_lacks_source ) {
920+ u32 flags = 0 ;
938921
939- if (XE_WARN_ON (new_mem -> start == XE_BO_INVALID_OFFSET )) {
940- ret = - EINVAL ;
941- xe_pm_runtime_put (xe );
942- goto out ;
943- }
922+ if (mem_type_is_vram (new_mem -> mem_type ))
923+ flags |= XE_MIGRATE_CLEAR_FLAG_FULL ;
924+ else if (handle_system_ccs )
925+ flags |= XE_MIGRATE_CLEAR_FLAG_CCS_DATA ;
944926
945- xe_assert (xe , new_mem -> start ==
946- bo -> placements -> fpfn );
947-
948- iosys_map_set_vaddr_iomem (& bo -> vmap , new_addr );
949- }
950- }
927+ fence = xe_migrate_clear (migrate , bo , new_mem , flags );
951928 } else {
952- if (move_lacks_source ) {
953- u32 flags = 0 ;
954-
955- if (mem_type_is_vram (new_mem -> mem_type ))
956- flags |= XE_MIGRATE_CLEAR_FLAG_FULL ;
957- else if (handle_system_ccs )
958- flags |= XE_MIGRATE_CLEAR_FLAG_CCS_DATA ;
959-
960- fence = xe_migrate_clear (migrate , bo , new_mem , flags );
961- }
962- else
963- fence = xe_migrate_copy (migrate , bo , bo , old_mem ,
964- new_mem , handle_system_ccs );
965- if (IS_ERR (fence )) {
966- ret = PTR_ERR (fence );
967- xe_pm_runtime_put (xe );
968- goto out ;
969- }
970- if (!move_lacks_source ) {
971- ret = ttm_bo_move_accel_cleanup (ttm_bo , fence , evict ,
972- true, new_mem );
973- if (ret ) {
974- dma_fence_wait (fence , false);
975- ttm_bo_move_null (ttm_bo , new_mem );
976- ret = 0 ;
977- }
978- } else {
979- /*
980- * ttm_bo_move_accel_cleanup() may blow up if
981- * bo->resource == NULL, so just attach the
982- * fence and set the new resource.
983- */
984- dma_resv_add_fence (ttm_bo -> base .resv , fence ,
985- DMA_RESV_USAGE_KERNEL );
929+ fence = xe_migrate_copy (migrate , bo , bo , old_mem , new_mem ,
930+ handle_system_ccs );
931+ }
932+ if (IS_ERR (fence )) {
933+ ret = PTR_ERR (fence );
934+ xe_pm_runtime_put (xe );
935+ goto out ;
936+ }
937+ if (!move_lacks_source ) {
938+ ret = ttm_bo_move_accel_cleanup (ttm_bo , fence , evict , true,
939+ new_mem );
940+ if (ret ) {
941+ dma_fence_wait (fence , false);
986942 ttm_bo_move_null (ttm_bo , new_mem );
943+ ret = 0 ;
987944 }
988-
989- dma_fence_put (fence );
945+ } else {
946+ /*
947+ * ttm_bo_move_accel_cleanup() may blow up if
948+ * bo->resource == NULL, so just attach the
949+ * fence and set the new resource.
950+ */
951+ dma_resv_add_fence (ttm_bo -> base .resv , fence ,
952+ DMA_RESV_USAGE_KERNEL );
953+ ttm_bo_move_null (ttm_bo , new_mem );
990954 }
991955
956+ dma_fence_put (fence );
992957 xe_pm_runtime_put (xe );
993958
994959out :
@@ -1125,59 +1090,90 @@ long xe_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo,
11251090 */
11261091int xe_bo_evict_pinned (struct xe_bo * bo )
11271092{
1128- struct ttm_place place = {
1129- .mem_type = XE_PL_TT ,
1130- };
1131- struct ttm_placement placement = {
1132- .placement = & place ,
1133- .num_placement = 1 ,
1134- };
1135- struct ttm_operation_ctx ctx = {
1136- .interruptible = false,
1137- .gfp_retry_mayfail = true,
1138- };
1139- struct ttm_resource * new_mem ;
1140- int ret ;
1093+ struct xe_device * xe = ttm_to_xe_device (bo -> ttm .bdev );
1094+ struct xe_bo * backup ;
1095+ bool unmap = false;
1096+ int ret = 0 ;
11411097
1142- xe_bo_assert_held (bo );
1098+ xe_bo_lock (bo , false );
11431099
1144- if (WARN_ON (!bo -> ttm .resource ))
1145- return - EINVAL ;
1100+ if (WARN_ON (!bo -> ttm .resource )) {
1101+ ret = - EINVAL ;
1102+ goto out_unlock_bo ;
1103+ }
11461104
1147- if (WARN_ON (!xe_bo_is_pinned (bo )))
1148- return - EINVAL ;
1105+ if (WARN_ON (!xe_bo_is_pinned (bo ))) {
1106+ ret = - EINVAL ;
1107+ goto out_unlock_bo ;
1108+ }
11491109
11501110 if (!xe_bo_is_vram (bo ))
1151- return 0 ;
1111+ goto out_unlock_bo ;
11521112
1153- ret = ttm_bo_mem_space (& bo -> ttm , & placement , & new_mem , & ctx );
1154- if (ret )
1155- return ret ;
1113+ backup = xe_bo_create_locked (xe , NULL , NULL , bo -> size , ttm_bo_type_kernel ,
1114+ XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
1115+ XE_BO_FLAG_PINNED );
1116+ if (IS_ERR (backup )) {
1117+ ret = PTR_ERR (backup );
1118+ goto out_unlock_bo ;
1119+ }
1120+
1121+ if (xe_bo_is_user (bo )) {
1122+ struct xe_migrate * migrate ;
1123+ struct dma_fence * fence ;
1124+
1125+ if (bo -> tile )
1126+ migrate = bo -> tile -> migrate ;
1127+ else
1128+ migrate = mem_type_to_migrate (xe , bo -> ttm .resource -> mem_type );
1129+
1130+ ret = dma_resv_reserve_fences (bo -> ttm .base .resv , 1 );
1131+ if (ret )
1132+ goto out_backup ;
1133+
1134+ ret = dma_resv_reserve_fences (backup -> ttm .base .resv , 1 );
1135+ if (ret )
1136+ goto out_backup ;
11561137
1157- if (! bo -> ttm .ttm ) {
1158- bo -> ttm .ttm = xe_ttm_tt_create ( & bo -> ttm , 0 );
1159- if (! bo -> ttm . ttm ) {
1160- ret = - ENOMEM ;
1161- goto err_res_free ;
1138+ fence = xe_migrate_copy ( migrate , bo , backup , bo -> ttm .resource ,
1139+ backup -> ttm .resource , false );
1140+ if (IS_ERR ( fence ) ) {
1141+ ret = PTR_ERR ( fence ) ;
1142+ goto out_backup ;
11621143 }
1163- }
11641144
1165- ret = ttm_bo_populate (& bo -> ttm , & ctx );
1166- if (ret )
1167- goto err_res_free ;
1145+ dma_resv_add_fence (bo -> ttm .base .resv , fence ,
1146+ DMA_RESV_USAGE_KERNEL );
1147+ dma_resv_add_fence (backup -> ttm .base .resv , fence ,
1148+ DMA_RESV_USAGE_KERNEL );
1149+ dma_fence_put (fence );
1150+ } else {
1151+ ret = xe_bo_vmap (backup );
1152+ if (ret )
1153+ goto out_backup ;
11681154
1169- ret = dma_resv_reserve_fences (bo -> ttm .base .resv , 1 );
1170- if (ret )
1171- goto err_res_free ;
1155+ if (iosys_map_is_null (& bo -> vmap )) {
1156+ ret = xe_bo_vmap (bo );
1157+ if (ret )
1158+ goto out_backup ;
1159+ unmap = true;
1160+ }
11721161
1173- ret = xe_bo_move ( & bo -> ttm , false, & ctx , new_mem , NULL );
1174- if ( ret )
1175- goto err_res_free ;
1162+ xe_map_memcpy_from ( xe , backup -> vmap . vaddr , & bo -> vmap , 0 ,
1163+ bo -> size );
1164+ }
11761165
1177- return 0 ;
1166+ bo -> backup_obj = backup ;
11781167
1179- err_res_free :
1180- ttm_resource_free (& bo -> ttm , & new_mem );
1168+ out_backup :
1169+ xe_bo_vunmap (backup );
1170+ xe_bo_unlock (backup );
1171+ if (ret )
1172+ xe_bo_put (backup );
1173+ out_unlock_bo :
1174+ if (unmap )
1175+ xe_bo_vunmap (bo );
1176+ xe_bo_unlock (bo );
11811177 return ret ;
11821178}
11831179
@@ -1198,47 +1194,82 @@ int xe_bo_restore_pinned(struct xe_bo *bo)
11981194 .interruptible = false,
11991195 .gfp_retry_mayfail = false,
12001196 };
1201- struct ttm_resource * new_mem ;
1202- struct ttm_place * place = & bo -> placements [0 ];
1197+ struct xe_device * xe = ttm_to_xe_device (bo -> ttm .bdev );
1198+ struct xe_bo * backup = bo -> backup_obj ;
1199+ bool unmap = false;
12031200 int ret ;
12041201
1205- xe_bo_assert_held (bo );
1202+ if (!backup )
1203+ return 0 ;
12061204
1207- if (WARN_ON (!bo -> ttm .resource ))
1208- return - EINVAL ;
1205+ xe_bo_lock (backup , false);
12091206
1210- if (WARN_ON (!xe_bo_is_pinned (bo )))
1211- return - EINVAL ;
1207+ ret = ttm_bo_validate (& backup -> ttm , & backup -> placement , & ctx );
1208+ if (ret )
1209+ goto out_backup ;
12121210
1213- if (WARN_ON (xe_bo_is_vram (bo )))
1214- return - EINVAL ;
1211+ if (WARN_ON (!dma_resv_trylock (bo -> ttm .base .resv ))) {
1212+ ret = - EBUSY ;
1213+ goto out_backup ;
1214+ }
12151215
1216- if (WARN_ON (!bo -> ttm .ttm && !xe_bo_is_stolen (bo )))
1217- return - EINVAL ;
1216+ if (xe_bo_is_user (bo )) {
1217+ struct xe_migrate * migrate ;
1218+ struct dma_fence * fence ;
12181219
1219- if (!mem_type_is_vram (place -> mem_type ))
1220- return 0 ;
1220+ if (bo -> tile )
1221+ migrate = bo -> tile -> migrate ;
1222+ else
1223+ migrate = mem_type_to_migrate (xe , bo -> ttm .resource -> mem_type );
12211224
1222- ret = ttm_bo_mem_space ( & bo -> ttm , & bo -> placement , & new_mem , & ctx );
1223- if (ret )
1224- return ret ;
1225+ ret = dma_resv_reserve_fences ( bo -> ttm . base . resv , 1 );
1226+ if (ret )
1227+ goto out_unlock_bo ;
12251228
1226- ret = ttm_bo_populate ( & bo -> ttm , & ctx );
1227- if (ret )
1228- goto err_res_free ;
1229+ ret = dma_resv_reserve_fences ( backup -> ttm . base . resv , 1 );
1230+ if (ret )
1231+ goto out_unlock_bo ;
12291232
1230- ret = dma_resv_reserve_fences (bo -> ttm .base .resv , 1 );
1231- if (ret )
1232- goto err_res_free ;
1233+ fence = xe_migrate_copy (migrate , backup , bo ,
1234+ backup -> ttm .resource , bo -> ttm .resource ,
1235+ false);
1236+ if (IS_ERR (fence )) {
1237+ ret = PTR_ERR (fence );
1238+ goto out_unlock_bo ;
1239+ }
12331240
1234- ret = xe_bo_move (& bo -> ttm , false, & ctx , new_mem , NULL );
1235- if (ret )
1236- goto err_res_free ;
1241+ dma_resv_add_fence (bo -> ttm .base .resv , fence ,
1242+ DMA_RESV_USAGE_KERNEL );
1243+ dma_resv_add_fence (backup -> ttm .base .resv , fence ,
1244+ DMA_RESV_USAGE_KERNEL );
1245+ dma_fence_put (fence );
1246+ } else {
1247+ ret = xe_bo_vmap (backup );
1248+ if (ret )
1249+ goto out_unlock_bo ;
12371250
1238- return 0 ;
1251+ if (iosys_map_is_null (& bo -> vmap )) {
1252+ ret = xe_bo_vmap (bo );
1253+ if (ret )
1254+ goto out_unlock_bo ;
1255+ unmap = true;
1256+ }
1257+
1258+ xe_map_memcpy_to (xe , & bo -> vmap , 0 , backup -> vmap .vaddr ,
1259+ bo -> size );
1260+ }
12391261
1240- err_res_free :
1241- ttm_resource_free (& bo -> ttm , & new_mem );
1262+ bo -> backup_obj = NULL ;
1263+
1264+ out_unlock_bo :
1265+ if (unmap )
1266+ xe_bo_vunmap (bo );
1267+ xe_bo_unlock (bo );
1268+ out_backup :
1269+ xe_bo_vunmap (backup );
1270+ xe_bo_unlock (backup );
1271+ if (!bo -> backup_obj )
1272+ xe_bo_put (backup );
12421273 return ret ;
12431274}
12441275
@@ -2195,22 +2226,6 @@ int xe_bo_pin(struct xe_bo *bo)
21952226 if (err )
21962227 return err ;
21972228
2198- /*
2199- * For pinned objects in on DGFX, which are also in vram, we expect
2200- * these to be in contiguous VRAM memory. Required eviction / restore
2201- * during suspend / resume (force restore to same physical address).
2202- */
2203- if (IS_DGFX (xe ) && !(IS_ENABLED (CONFIG_DRM_XE_DEBUG ) &&
2204- bo -> flags & XE_BO_FLAG_INTERNAL_TEST )) {
2205- if (mem_type_is_vram (place -> mem_type )) {
2206- xe_assert (xe , place -> flags & TTM_PL_FLAG_CONTIGUOUS );
2207-
2208- place -> fpfn = (xe_bo_addr (bo , 0 , PAGE_SIZE ) -
2209- vram_region_gpu_offset (bo -> ttm .resource )) >> PAGE_SHIFT ;
2210- place -> lpfn = place -> fpfn + (bo -> size >> PAGE_SHIFT );
2211- }
2212- }
2213-
22142229 if (mem_type_is_vram (place -> mem_type ) || bo -> flags & XE_BO_FLAG_GGTT ) {
22152230 spin_lock (& xe -> pinned .lock );
22162231 list_add_tail (& bo -> pinned_link , & xe -> pinned .kernel_bo_present );
0 commit comments