Motivation
We have two x86_64 guest kernel artifacts today — gocracker-guest-standard-vmlinux (41 MiB uncompressed, 10 MiB gzipped, 90 KB config) and the virtiofs variant. Both are built from a generic guest config close to Firecracker's standard shape.
The arm64 side already ships a paired standard / minimal split (56 MiB → 5.6 MiB Image, 334 KB → 62 KB config). The minimal profile boots measurably faster because there is less to decompress, less to copy into guest RAM, and fewer subsystems to initialise before userspace.
Goal
Introduce a minimal profile for x86_64 that mirrors the arm64 shape and is the new default for microVM boots. Target: knock ~10–30 ms off the boot_ms median on the Firecracker-parity benchmark (that's the range Firecracker attribute to their own stripped config vs. a generic one — see their guest_configs).
What to drop
Starting from the current tools/kernel/guest-common-x86_64.fragment base, the candidates for removal on a microVM target:
CONFIG_ACPI — microVMs boot on MPTable / direct boot; ACPI is only needed for the full Linux boot path. Firecracker's guest config leaves it off.
CONFIG_PCI — our transport is virtio-mmio; PCI support is dead weight.
CONFIG_X86_MCE and intel perf counter support — not needed inside a guest.
CONFIG_HYPERV*, CONFIG_XEN* — we only run on bare KVM.
CONFIG_NUMA, CONFIG_NUMA_BALANCING — 1-node guests.
CONFIG_SOUND, CONFIG_DRM, CONFIG_USB, CONFIG_INPUT_* (beyond the null console).
CONFIG_AGP, CONFIG_PCCARD, CONFIG_THERMAL — no hardware of this kind is exposed.
CONFIG_IPV6 is arguable — keep it on by default, allow opt-out for workloads that only speak IPv4.
What to keep
Anything already in guest-common-x86_64.fragment: DEVTMPFS, TMPFS, EXT4, 8250 serial console, virtio (mmio + blk + net + rng), vsock, unix/inet/packet sockets, DNS resolver, ELF binfmt, initrd decompressors (gzip / xz / zstd / lz4), and the debug-info stripping flags. These are all load-bearing for gocracker run.
Proposed work
- Add a
guest-minimal-x86_64.fragment next to the existing one, listing the disables above.
- Extend tools/build-guest-kernel.sh with
--profile minimal that applies guest-common-x86_64.fragment + guest-minimal-x86_64.fragment on top of a KVM-guest base config (kernel/configs/kvm_guest.config is a reasonable starting point — it is already minimal).
- Check the resulting artifact in to
artifacts/kernels/gocracker-guest-minimal-vmlinux (and .gz), matching the arm64 naming convention.
- Add a
make bench-kernel target (or extend the existing boot-time bench driver — see also the re-benchmark work tracked separately) that measures standard vs minimal with three rootfs sizes (64 MiB alpine, 256 MiB generic, 4 GiB app).
- Update README.md's "Boot-time benchmark" section with the minimal vs standard numbers.
- Consider flipping the default in pkg/container to prefer
minimal when available, with a documented env var / flag to opt into standard.
Risks / open questions
- Host/kernel combos that rely on ACPI: some KVM host setups advertise ACPI tables; dropping
CONFIG_ACPI means the guest ignores them. Needs a smoke test on both x86_64 paths we care about (MPTable boot and ACPI boot). The existing TestBootAndHaltACPI covers this.
- Compatibility with
gocracker run on generic workloads: if a user image expects a PCI network interface or the DRM console, the minimal kernel breaks them. Mitigation: standard stays available and is the fallback; minimal is opt-in until the benchmark + test matrix covers the common cases.
- Maintenance cost: every new driver dependency in the VMM (a new virtio device, a new architecture feature) has to be mirrored in the minimal fragment. Cheap if the fragment stays small.
Related code
Effort estimate
~1 day for the fragment + build script, ~1 day for the benchmark integration and README update, assuming the existing boot-time bench harness is available. The fragment itself is a 30-line diff; the rest is running, measuring, and documenting.
Motivation
We have two x86_64 guest kernel artifacts today — gocracker-guest-standard-vmlinux (41 MiB uncompressed, 10 MiB gzipped, 90 KB config) and the virtiofs variant. Both are built from a generic guest config close to Firecracker's standard shape.
The arm64 side already ships a paired
standard/minimalsplit (56 MiB → 5.6 MiB Image, 334 KB → 62 KB config). The minimal profile boots measurably faster because there is less to decompress, less to copy into guest RAM, and fewer subsystems to initialise before userspace.Goal
Introduce a
minimalprofile for x86_64 that mirrors the arm64 shape and is the new default for microVM boots. Target: knock ~10–30 ms off theboot_msmedian on the Firecracker-parity benchmark (that's the range Firecracker attribute to their own stripped config vs. a generic one — see their guest_configs).What to drop
Starting from the current tools/kernel/guest-common-x86_64.fragment base, the candidates for removal on a microVM target:
CONFIG_ACPI— microVMs boot on MPTable / direct boot; ACPI is only needed for the full Linux boot path. Firecracker's guest config leaves it off.CONFIG_PCI— our transport is virtio-mmio; PCI support is dead weight.CONFIG_X86_MCEand intel perf counter support — not needed inside a guest.CONFIG_HYPERV*,CONFIG_XEN*— we only run on bare KVM.CONFIG_NUMA,CONFIG_NUMA_BALANCING— 1-node guests.CONFIG_SOUND,CONFIG_DRM,CONFIG_USB,CONFIG_INPUT_*(beyond the null console).CONFIG_AGP,CONFIG_PCCARD,CONFIG_THERMAL— no hardware of this kind is exposed.CONFIG_IPV6is arguable — keep it on by default, allow opt-out for workloads that only speak IPv4.What to keep
Anything already in guest-common-x86_64.fragment: DEVTMPFS, TMPFS, EXT4, 8250 serial console, virtio (mmio + blk + net + rng), vsock, unix/inet/packet sockets, DNS resolver, ELF binfmt, initrd decompressors (gzip / xz / zstd / lz4), and the debug-info stripping flags. These are all load-bearing for
gocracker run.Proposed work
guest-minimal-x86_64.fragmentnext to the existing one, listing the disables above.--profile minimalthat appliesguest-common-x86_64.fragment+guest-minimal-x86_64.fragmenton top of a KVM-guest base config (kernel/configs/kvm_guest.configis a reasonable starting point — it is already minimal).artifacts/kernels/gocracker-guest-minimal-vmlinux(and.gz), matching the arm64 naming convention.make bench-kerneltarget (or extend the existing boot-time bench driver — see also the re-benchmark work tracked separately) that measuresstandardvsminimalwith three rootfs sizes (64 MiB alpine, 256 MiB generic, 4 GiB app).minimalwhen available, with a documented env var / flag to opt intostandard.Risks / open questions
CONFIG_ACPImeans the guest ignores them. Needs a smoke test on both x86_64 paths we care about (MPTable boot and ACPI boot). The existing TestBootAndHaltACPI covers this.gocracker runon generic workloads: if a user image expects a PCI network interface or the DRM console, the minimal kernel breaks them. Mitigation:standardstays available and is the fallback;minimalis opt-in until the benchmark + test matrix covers the common cases.Related code
Effort estimate
~1 day for the fragment + build script, ~1 day for the benchmark integration and README update, assuming the existing boot-time bench harness is available. The fragment itself is a 30-line diff; the rest is running, measuring, and documenting.