[RFC 26/26] plugins/amdgpu: Hack to work around GPU virtual address conflicts
Tvrtko Ursulin <[email protected]> Fri, 20 Feb 2026 12:05:14 +0000
| Newsgroups | dev.linux.lists.criu |
|---|---|
| Message-ID | <[email protected]> |
During the restore process buffer objects are created and mapped into the GPU virtual address space to their final addresses, and then their content is attempted to be restored. This step is done by instantiating a libdrm instance and the associated userspace virtual address range manager. This manager is unaware of the previous address range allocations on the same file, which in practice means restore will simply fail. To work around it we add some retries to try different addresses a few times, but for a proper solution we will need to either add a mechanism for reserving ranges in libdrm va manager, or rework the order of the restore operations so that the buffer objects are only mapped into their final locations once their content has been restored. Signed-off-by: Tvrtko Ursulin <[email protected]> --- plugins/amdgpu/amdgpu_plugin.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/amdgpu/amdgpu_plugin.c b/plugins/amdgpu/amdgpu_plugin.c index 239eeebc5111..b2f192a80f65 100644 --- a/plugins/amdgpu/amdgpu_plugin.c +++ b/plugins/amdgpu/amdgpu_plugin.c @@ -573,6 +573,7 @@ int sdma_copy_bo(int shared_fd, uint64_t size, int storage_fd, amdgpu_context_handle h_ctx; uint32_t *ib = NULL; int j, err, err2, packets_per_buffer; + unsigned int retries = 0; buffer_bo_size = min(size, buffer_size); packets_per_buffer = ((buffer_bo_size - 1) / max_copy_size) + 1; @@ -603,6 +604,8 @@ int sdma_copy_bo(int shared_fd, uint64_t size, int storage_fd, return -EINVAL; } +retry_src_va: + retries++; err = amdgpu_va_range_alloc(h_dev, amdgpu_gpu_va_range_general, src_bo_size, 0x1000, 0, &gpu_addr_src, &h_va_src, 0); if (err) { @@ -611,6 +614,8 @@ int sdma_copy_bo(int shared_fd, uint64_t size, int storage_fd, } err = amdgpu_bo_va_op(h_bo_src, 0, src_bo_size, gpu_addr_src, 0, AMDGPU_VA_OP_MAP); if (err) { + if (retries < 1000) + goto retry_src_va; pr_perror("failed to GPU map the src BO"); goto err_src_bo_map; } @@ -639,6 +644,9 @@ int sdma_copy_bo(int shared_fd, uint64_t size, int storage_fd, goto err_dst_bo_prep; } + retries = 0; +retry_dst_va: + retries++; err = amdgpu_va_range_alloc(h_dev, amdgpu_gpu_va_range_general, dst_bo_size, 0x1000, 0, &gpu_addr_dst, &h_va_dst, 0); if (err) { @@ -647,6 +655,8 @@ int sdma_copy_bo(int shared_fd, uint64_t size, int storage_fd, } err = amdgpu_bo_va_op(h_bo_dst, 0, dst_bo_size, gpu_addr_dst, 0, AMDGPU_VA_OP_MAP); if (err) { + if (retries < 1000) + goto retry_dst_va; pr_perror("failed to GPU map the dest BO"); goto err_dst_bo_map; } -- 2.52.0