Blowfish is a VM memory overcommitment framework built on disaggregated memory, which performs timely cold (and free) memory reclamation and restoration.
For more details, please refer to our paper.
blowfish/
├── setup.sh # Host preparation (see Build and Install Blowfish)
├── bench/
│ ├── run_all.py # Main evaluation orchestration script
│ ├── run_auto.py # Single benchmark run
│ ├── build.py # Build guest kernels and QEMU in one step
│ ├── scripts/ # QEMU, SSH, cgroup helpers, etc.
│ ├── vm/ # VM helper scripts
│ ├── resources/ # Place your VM disk image here
│ └── results/ # Default results directory
├── scripts/
│ ├── network/ # Example libvirt default.xml + README
│ ├── vfio/ # Enable VFs and bind VFIO
│ ├── remoteswap/ # Swapping over RDMA
│ ├── vm/ # Scripts to SSH into VM or destroy VM
│ └── cpu_freq/ # Pin frequency, disable turbo, etc.
├── guest-linux-6.1.0/ # Guest kernel
├── host-linux-6.1.0/ # Host kernel
├── qemu/ # QEMU
├── env/ # Conda environment file
├── apps/ # Application scripts
└── ...
- Virtualization: working
/dev/kvm; Intel with EPT recommended. - RDMA / Remoteswap: Blowfish builds on an RDMA-based remoteswap stack. See
scripts/remoteswap/README.md. - VFIO / PCI passthrough: required for modes that pass through a device. See
scripts/vfio/README.md. - Networking: scripts default to
--net-mode libvirt; you need a libvirt network. Seescripts/network/README.md. - QEMU / guest image: prepare a compatible QEMU disk image under
bench/resourcesbefore the first run. - Privileges: scripts may invoke
sudofor cgroup setup or delegation.
cd /path/to/blowfish/host-linux-6.1.0
./build_kernel.sh build
sudo ./build_kernel.sh install
# Update GRUB and rebootAfter reboot, check transparent huge pages (THP):
cat /sys/kernel/mm/transparent_hugepage/enabled
# expect [always]To apply always until the next reboot:
echo always | sudo tee /sys/kernel/mm/transparent_hugepage/enabledTo make it persistent, add transparent_hugepage=always to the kernel command line (for example in /etc/default/grub under GRUB_CMDLINE_LINUX_DEFAULT), run sudo update-grub, then reboot.
sudo cat /sys/module/kvm/parameters/tdp_mmu
# If the value is `N`,
# add to `/etc/modprobe.d/kvm.conf`, for example:
options kvm tdp_mmu=Y
# Reload modules and verify tdp_mmu again.Install Mellanox OFED drivers on both machines (host node and memory node) with InfiniBand connected. On the memory node:
cd /path/to/blowfish/scripts/remoteswap/server
make
# ./rswap-server <memory-server-ip> <memory-server-port> <pool-size-GB> <cores-on-host-server>On the cpu node:
cd /path/to/blowfish/scripts/remoteswap/client
make
# Edit manage_rswap_client.sh:
# set IP, port, pool size, swap file path, etc.For details, see scripts/remoteswap/README.md.
The repo-root setup.sh invokes enable_vf.sh and bind_vfio.py before evaluation. The goal is to virtualize the InfiniBand NIC and pass it through to the VM.
Edit scripts/vfio/enable_vf.sh (or your own SR-IOV enablement scripts) for your topology. After SR-IOV is configured successfully, you should see devices similar to:
lspci | grep ib
b1:00.2 Infiniband controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function]
b1:00.3 Infiniband controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function]For details, see scripts/vfio/README.md.
Configure networking so the guest has connectivity. We ship an example libvirt network definition. After configuring the network, verify:
virsh net-list --all
virsh net-dumpxml defaultFor details, see scripts/network/README.md.
cd /path/to/blowfish
bash setup.shsetup.sh currently:
- Runs
sudo /etc/init.d/openibd restartand waits for the RDMA stack. - Runs
make clean && makeunderscripts/remoteswap/client/, thensudo ./manage_rswap_client.sh installto install remoteswap (configure Remoteswap first). - Runs
sudo chown "$USER" /dev/kvmso your user can create VMs. - CPU: disables turbo and applies fixed-frequency helpers (
scripts/cpu_freq/). - SR-IOV: runs
scripts/vfio/enable_vf.sh(configure VFIO / SR-IOV first). - VFIO bind: runs
sudo python3 scripts/vfio/bind_vfio.py, which lists IOMMU groups. Enter the group id for the InfiniBand VF you want, then note its BDF (e.g.b1:00.3). Match that BDF to the defaults in the bench scripts or pass--vfio-devtorun_all.py/run_auto.pywhere required.
To boot a VM, provide a suitable disk image under the expected path (bench/resources); for example, you can create one with virt-install or get one from https://www.debian.org/distrib/. The default guest login in the scripts is user debian, and passwordless sudo for that user is expected. If you change the username, update the relevant bench/VM scripts accordingly.
conda env create -f /path/to/blowfish/env/environment.yml
conda activate blowfish
cd /path/to/blowfish/bench
# Build guest kernels and QEMU (LLVM required)
./build.py
# Install applications and upload benchmark scripts, see apps/-
APP_SCRIPT_PRESETSinbench/run_auto.pydefines benchmark presets (e.g.,tc->/home/debian/code_tc/test_tc.sh). -
APP_RESOURCE_PRESETSinbench/run_all.pysupplies default guest RAM (-m) and vCPU (-c) when omitted.
Adding a new preset: extend APP_SCRIPT_PRESETS in run_auto.py, add matching APP_RESOURCE_PRESETS in run_all.py, place the script on the guest at the declared path, then run with --app yourname.
See apps/ for more details about different applications.
cd /path/to/blowfish/bench
# Run the full evaluation suite
./run_all.py
# Or list options
./run_all.py --helpOutputs: by default under /path/to/blowfish/bench/results/.
run_all.py may invoke sudo several times. The script tries to refresh credentials early, but you can still be prompted again if the sudo timestamp expires. To extend the password cache, run sudo visudo and add a line such as:
Defaults timestamp_timeout=120
- Hermit: Public remoteswap prototype.
- Hyperalloc: Blowfish's baseline.