[RFC 25/26] plugins/amdgpu: Hack to save a fd number which works for vma restore
Tvrtko Ursulin <[email protected]> Fri, 20 Feb 2026 12:05:13 +0000
| Newsgroups | dev.linux.lists.criu |
|---|---|
| Message-ID | <[email protected]> |
Another problem with VMA restore inside a forked process is that the file descriptor plugin creates to pass to CRIU core to mmap() against is present only in the process enumerating the VMAs. If there is a child process this fd will be invalid and the restore will fail. In this patch we work around that by trying to guess the real (restored) file descriptor associated with this VMA and store that in the VMA metadata used for restore. This works for a simple case when processes have identical set of file descriptor in a linear growing order, but probably not much more that that. To fix this properly a deeper discussion on the design is required. Signed-off-by: Tvrtko Ursulin <[email protected]> --- plugins/amdgpu/amdgpu_plugin.c | 17 +++++++++++++++-- plugins/amdgpu/amdgpu_plugin_drm.c | 4 ++-- plugins/amdgpu/amdgpu_plugin_drm.h | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/plugins/amdgpu/amdgpu_plugin.c b/plugins/amdgpu/amdgpu_plugin.c index 83d16272237f..239eeebc5111 100644 --- a/plugins/amdgpu/amdgpu_plugin.c +++ b/plugins/amdgpu/amdgpu_plugin.c @@ -1863,7 +1863,7 @@ static int amdgpu_plugin_restore_drm_file(int id, bool *retry_needed) CriuRenderNode *rd; unsigned char *buf; size_t img_size; - int fd, ret; + int probed_fd, fd, ret; /* This is restorer plugin for renderD nodes. Criu doesn't guarantee * that they will be called before the plugin is called for kfd file @@ -1963,7 +1963,20 @@ static int amdgpu_plugin_restore_drm_file(int id, bool *retry_needed) return -1; } - ret = amdgpu_plugin_drm_restore_file(fd, rd); + /* + * HACK! to figure out the final/restored fd we need to restore vmas. + * It will not work if non-linear fd space, neither inside a forked + * process which inherits the vma but does not have the same device + * kept open or under the same fd. + */ + probed_fd = dup(fd); + if (probed_fd < 0) { + pr_perror("Failed to probe fd\n"); + return -1; + } + close(probed_fd); + + ret = amdgpu_plugin_drm_restore_file(fd, rd, probed_fd); if (ret == 1) *retry_needed = true; if (ret < 0) { diff --git a/plugins/amdgpu/amdgpu_plugin_drm.c b/plugins/amdgpu/amdgpu_plugin_drm.c index 30a0626b7b5f..6fb523e31720 100644 --- a/plugins/amdgpu/amdgpu_plugin_drm.c +++ b/plugins/amdgpu/amdgpu_plugin_drm.c @@ -453,7 +453,7 @@ exit: return ret; } -int amdgpu_plugin_drm_restore_file(int fd, CriuRenderNode *rd) +int amdgpu_plugin_drm_restore_file(int fd, CriuRenderNode *rd, int probed_fd) { int ret = 0; bool retry_needed = false; @@ -551,7 +551,7 @@ int amdgpu_plugin_drm_restore_file(int fd, CriuRenderNode *rd) } ret = save_vma_updates(boinfo->offset, boinfo->addr, - mmap_args.out.addr_ptr, fd); + mmap_args.out.addr_ptr, probed_fd); if (ret < 0) goto exit; } diff --git a/plugins/amdgpu/amdgpu_plugin_drm.h b/plugins/amdgpu/amdgpu_plugin_drm.h index f76e29f7f73f..7a05e01dcebc 100644 --- a/plugins/amdgpu/amdgpu_plugin_drm.h +++ b/plugins/amdgpu/amdgpu_plugin_drm.h @@ -24,7 +24,7 @@ int amdgpu_plugin_drm_handle_device_vma(int fd, const struct stat *drm); */ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm); -int amdgpu_plugin_drm_restore_file(int fd, CriuRenderNode *rd); +int amdgpu_plugin_drm_restore_file(int fd, CriuRenderNode *rd, int probed_fd); int amdgpu_plugin_drm_unpause_file(int fd); -- 2.52.0