[CRIU] [RFC PATCH 07/20] criu/restore: Introduce restore late stage hook

Felix Kuehling Felix.Kuehling at amd.com
Sat May 1 04:58:32 MSK 2021


From: Rajneesh Bhardwaj <rajneesh.bhardwaj at amd.com>

During criu restore phase when a device is getting restored with the
help of a plugin, some device specific operations need to be delayed
until criu finalizes the VMA placements in address space of the target
process. But by the time criu finalizes this, its too late since pie
phase is over and control is back to criu master process.

This change allows an external trigger to each resuming task to check
whether it has a device specific operation pending such as issuing an
ioctl call. Since this is called from criu master process context,
supply the pid of the target process and give a chance to each plugin
registered to run device specific operation if the target pid is valid.

A consumer for this will be added in a seperate patch.

Signed-off-by: Rajneesh Bhardwaj <rajneesh.bhardwaj at amd.com>
---
 criu/cr-restore.c          | 15 +++++++++++++++
 criu/include/criu-plugin.h |  4 ++++
 criu/plugin.c              |  1 +
 3 files changed, 20 insertions(+)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 0d85db6ce..6ade278ae 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -2451,6 +2451,21 @@ skip_ns_bouncing:
 		pr_err("Unable to flush breakpoints\n");
 
 	finalize_restore();
+	/*
+	 * Some external devices such as GPUs might need a very late
+	 * trigger to kick-off some events, memory notifiers and for
+	 * restarting the previously restored queues during criu restore
+	 * stage. This is needed since criu pie code may shuffle VMAs
+	 * around so things such as registering MMU notifiers (for GPU
+	 * mapped memory) could be done sanely once the pie code hands
+	 * over the control to master process.
+	 */
+	for_each_pstree_item(item) {
+		pr_info("Run late stage hook from criu master for external devices\n");
+		ret = run_plugins(RESUME_DEVICES_LATE, item->pid->real);
+		if (ret < 0)
+			pr_err("criu: restore late stage hook for external plugin failed\n");
+	}
 
 	ret = run_scripts(ACT_PRE_RESUME);
 	if (ret)
diff --git a/criu/include/criu-plugin.h b/criu/include/criu-plugin.h
index 850594ebf..dfd44c209 100644
--- a/criu/include/criu-plugin.h
+++ b/criu/include/criu-plugin.h
@@ -53,6 +53,8 @@ enum {
 
 	CR_PLUGIN_HOOK__UPDATE_VMA_MAP		= 7,
 
+	CR_PLUGIN_HOOK__RESUME_DEVICES_LATE	= 8,
+
 	CR_PLUGIN_HOOK__MAX
 };
 
@@ -68,6 +70,7 @@ DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_EXT_MOUNT, int id, char *mountp
 DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_EXT_LINK, int index, int type, char *kind);
 DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__UPDATE_VMA_MAP, const char* old_path, char *new_path,
                                const uint64_t addr, const uint64_t old_pgoff, uint64_t *new_pgoff);
+DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESUME_DEVICES_LATE, int pid);
 
 enum {
 	CR_PLUGIN_STAGE__DUMP,
@@ -136,5 +139,6 @@ typedef int (cr_plugin_dump_ext_link_t)(int index, int type, char *kind);
 typedef int (cr_plugin_update_vma_offset_t)(const char* old_path, char *new_path,
 					    const uint64_t addr, const uint64_t old_pgoff,
 					    uint64_t *new_pgoff);
+typedef int (cr_plugin_resume_devices_late_t)(int pid);
 
 #endif /* __CRIU_PLUGIN_H__ */
diff --git a/criu/plugin.c b/criu/plugin.c
index 35d171820..fa1096495 100644
--- a/criu/plugin.c
+++ b/criu/plugin.c
@@ -54,6 +54,7 @@ static cr_plugin_desc_t *cr_gen_plugin_desc(void *h, char *path)
 	__assign_hook(RESTORE_EXT_MOUNT,	"cr_plugin_restore_ext_mount");
 	__assign_hook(DUMP_EXT_LINK,		"cr_plugin_dump_ext_link");
 	__assign_hook(UPDATE_VMA_MAP,		"cr_plugin_update_vma_map");
+	__assign_hook(RESUME_DEVICES_LATE,	"cr_plugin_resume_devices_late");
 
 #undef __assign_hook
 
-- 
2.17.1



More information about the CRIU mailing list