feat: add VM snapshot support for fast restore boot#318
Conversation
Trigger a Nanvix VM snapshot after Py_Initialize() completes. On first boot the hypervisor creates a snapshot; subsequent boots restore from it in ~35ms instead of cold-booting. Changes: - Add Modules/nanvix_snapshot.S: standalone assembly syscall helper (int $0x80, syscall 35) in a separate .S file to survive LTO - Add nanvix_snapshot() call in Modules/main.c after initialization, gated by #ifdef __nanvix__ - Compile and link nanvix_snapshot.o in both Docker and non-Docker build paths in Makefile.nanvix, with post-injection validation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds Nanvix VM snapshot triggering to enable fast “restore boot” by snapshotting the VM immediately after CPython initialization completes.
Changes:
- Introduces a Nanvix snapshot syscall helper implemented as a standalone assembly routine.
- Calls the snapshot trigger right after
Py_InitializeFromConfig()succeeds (Nanvix-only). - Updates Nanvix cross-build Makefile to compile/link the snapshot helper in both Docker and non-Docker build flows (via Makefile injection).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
Modules/nanvix_snapshot.S |
New assembly helper exporting nanvix_snapshot() using int $0x80 syscall 35. |
Modules/main.c |
Adds nanvix_snapshot() declaration and calls it after initialization under #ifdef __nanvix__. |
Makefile.nanvix |
Compiles nanvix_snapshot.S and injects nanvix_snapshot.o into the generated build Makefile for linking. |
Comments suppressed due to low confidence (1)
Makefile.nanvix:223
- Same issue in the non-Docker path: the sed substitution appends text after a line that likely ends with a trailing
\continuation inMODULE_OBJS, which will break the generated Makefile. Modify the injection to addModules/nanvix_snapshot.oas its own continued line (or insert before the trailing\) specifically inside theMODULE_OBJS=assignment.
@# Inject the snapshot object into the generated Makefile's MODULE_OBJS
@grep -q "nanvix_snapshot.o" Makefile || \
{ sed -i "/Modules\/main\.o/s|$$| Modules/nanvix_snapshot.o|" Makefile && \
grep -q "nanvix_snapshot.o" Makefile || \
{ echo "Error: failed to inject nanvix_snapshot.o into Makefile"; exit 1; }; }
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $(DOCKER_RUN) sh -c '\ | ||
| grep -q "nanvix_snapshot.o" Makefile || \ | ||
| { sed -i "/Modules\/main\.o/s|$$| Modules/nanvix_snapshot.o|" Makefile && \ | ||
| grep -q "nanvix_snapshot.o" Makefile || \ | ||
| { echo "Error: failed to inject nanvix_snapshot.o into Makefile"; exit 1; }; }' |
There was a problem hiding this comment.
The sed-based Makefile injection appends Modules/nanvix_snapshot.o to the end of the line matching Modules/main.o. In the generated Makefile, that line ends with a trailing \ continuation, so appending after it will move the backslash away from end-of-line and break the MODULE_OBJS definition (likely causing a Makefile parse error). Adjust the injection to insert a new line entry (or insert before the trailing \) within the MODULE_OBJS block instead of appending after end-of-line.
This issue also appears on line 219 of the same file.
Combine multiple performance optimizations to reduce cold-boot hello-world execution time from ~600ms to ~450ms, with VM snapshot support enabling sub-200ms restore-boot. Changes from PR #361 - Non-PIE static linking (~20ms saved): - Switch LDFLAGS from -Wl,-pie -Wl,--export-dynamic to -no-pie - Eliminates 100K R_386_RELATIVE relocations at startup Changes from PR #362 - Compiler flag optimizations (~70ms saved): - Add -O3 -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables to CFLAGS - Remove --with-lto (causes I-cache pressure on constrained microvm) - Add --without-doc-strings and --with-computed-gotos Changes from PR #363 - Test harness optimizations (~40ms saved): - Use --strip-all instead of --strip-debug for smallest binary - Move host binaries (nanvixd, kernel, mkramfs) out of ramfs tree - Build minimal ramfs with only test script and encodings/ - Add -S flag (skip site.py) and PYTHONHASHSEED=0 - Remove timeout wrapper to reduce measurement overhead Changes from PR #318 - VM snapshot support: - Add Modules/nanvix_snapshot.S: assembly syscall helper (int 0x80, nr 35) - Call nanvix_snapshot() after Py_Initialize when NANVIX_SNAPSHOT=1 is set - Enables restore-boot in ~35ms (requires snapshot-capable nanvixd) - Gated by NANVIX_SNAPSHOT=1 env var for backward compatibility
Summary
Trigger a Nanvix VM snapshot after
Py_Initialize()completes. On first boot the hypervisor creates a snapshot; subsequent boots restore from it in ~35 ms instead of cold-booting (~825 ms).Changes
Modules/nanvix_snapshot.S: New file — standalone assembly syscall helper (int $0x80, syscall 35) in a separate.Sfile to survive LTO eliminationModules/main.c: Callnanvix_snapshot()after initialization, gated by#ifdef __nanvix__Makefile.nanvix: Compile and linknanvix_snapshot.oin both Docker and non-Docker build paths, with post-injection validation to fail loudly if the Makefile injection doesn't matchCompanion
Requires nanvix/nanvix snapshot restore CLI flag.
Split from #314.