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

drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes v2

This allows us to move scattered buffers around.

v2: fix a couple of typos, handle scattered to scattered moves as well.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Tested-by: Mike Lothian <mike@fireburn.co.uk>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Christian König and committed by
Alex Deucher
8892f153 63e0ba40

+86 -34
+86 -34
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 260 260 new_mem->mm_node = NULL; 261 261 } 262 262 263 - static int amdgpu_move_blit(struct ttm_buffer_object *bo, 264 - bool evict, bool no_wait_gpu, 265 - struct ttm_mem_reg *new_mem, 266 - struct ttm_mem_reg *old_mem) 263 + static int amdgpu_mm_node_addr(struct ttm_buffer_object *bo, 264 + struct drm_mm_node *mm_node, 265 + struct ttm_mem_reg *mem, 266 + uint64_t *addr) 267 267 { 268 - struct amdgpu_device *adev; 269 - struct amdgpu_ring *ring; 270 - uint64_t old_start, new_start; 271 - struct fence *fence; 272 268 int r; 273 269 274 - adev = amdgpu_get_adev(bo->bdev); 275 - ring = adev->mman.buffer_funcs_ring; 276 - 277 - switch (old_mem->mem_type) { 270 + switch (mem->mem_type) { 278 271 case TTM_PL_TT: 279 - r = amdgpu_ttm_bind(bo, old_mem); 272 + r = amdgpu_ttm_bind(bo, mem); 280 273 if (r) 281 274 return r; 282 275 283 276 case TTM_PL_VRAM: 284 - old_start = (u64)old_mem->start << PAGE_SHIFT; 285 - old_start += bo->bdev->man[old_mem->mem_type].gpu_offset; 277 + *addr = mm_node->start << PAGE_SHIFT; 278 + *addr += bo->bdev->man[mem->mem_type].gpu_offset; 286 279 break; 287 280 default: 288 - DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); 281 + DRM_ERROR("Unknown placement %d\n", mem->mem_type); 289 282 return -EINVAL; 290 283 } 291 - switch (new_mem->mem_type) { 292 - case TTM_PL_TT: 293 - r = amdgpu_ttm_bind(bo, new_mem); 294 - if (r) 295 - return r; 296 284 297 - case TTM_PL_VRAM: 298 - new_start = (u64)new_mem->start << PAGE_SHIFT; 299 - new_start += bo->bdev->man[new_mem->mem_type].gpu_offset; 300 - break; 301 - default: 302 - DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); 303 - return -EINVAL; 304 - } 285 + return 0; 286 + } 287 + 288 + static int amdgpu_move_blit(struct ttm_buffer_object *bo, 289 + bool evict, bool no_wait_gpu, 290 + struct ttm_mem_reg *new_mem, 291 + struct ttm_mem_reg *old_mem) 292 + { 293 + struct amdgpu_device *adev = amdgpu_get_adev(bo->bdev); 294 + struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; 295 + 296 + struct drm_mm_node *old_mm, *new_mm; 297 + uint64_t old_start, old_size, new_start, new_size; 298 + unsigned long num_pages; 299 + struct fence *fence = NULL; 300 + int r; 301 + 302 + BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0); 303 + 305 304 if (!ring->ready) { 306 305 DRM_ERROR("Trying to move memory with ring turned off.\n"); 307 306 return -EINVAL; 308 307 } 309 308 310 - BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0); 311 - 312 - r = amdgpu_copy_buffer(ring, old_start, new_start, 313 - new_mem->num_pages * PAGE_SIZE, /* bytes */ 314 - bo->resv, &fence, false); 309 + old_mm = old_mem->mm_node; 310 + r = amdgpu_mm_node_addr(bo, old_mm, old_mem, &old_start); 315 311 if (r) 316 312 return r; 313 + old_size = old_mm->size; 314 + 315 + 316 + new_mm = new_mem->mm_node; 317 + r = amdgpu_mm_node_addr(bo, new_mm, new_mem, &new_start); 318 + if (r) 319 + return r; 320 + new_size = new_mm->size; 321 + 322 + num_pages = new_mem->num_pages; 323 + while (num_pages) { 324 + unsigned long cur_pages = min(old_size, new_size); 325 + struct fence *next; 326 + 327 + r = amdgpu_copy_buffer(ring, old_start, new_start, 328 + cur_pages * PAGE_SIZE, 329 + bo->resv, &next, false); 330 + if (r) 331 + goto error; 332 + 333 + fence_put(fence); 334 + fence = next; 335 + 336 + num_pages -= cur_pages; 337 + if (!num_pages) 338 + break; 339 + 340 + old_size -= cur_pages; 341 + if (!old_size) { 342 + r = amdgpu_mm_node_addr(bo, ++old_mm, old_mem, 343 + &old_start); 344 + if (r) 345 + goto error; 346 + old_size = old_mm->size; 347 + } else { 348 + old_start += cur_pages * PAGE_SIZE; 349 + } 350 + 351 + new_size -= cur_pages; 352 + if (!new_size) { 353 + r = amdgpu_mm_node_addr(bo, ++new_mm, new_mem, 354 + &new_start); 355 + if (r) 356 + goto error; 357 + 358 + new_size = new_mm->size; 359 + } else { 360 + new_start += cur_pages * PAGE_SIZE; 361 + } 362 + } 317 363 318 364 r = ttm_bo_pipeline_move(bo, fence, evict, new_mem); 365 + fence_put(fence); 366 + return r; 367 + 368 + error: 369 + if (fence) 370 + fence_wait(fence, false); 319 371 fence_put(fence); 320 372 return r; 321 373 }