Jump to content

I'm probably insane. ;-) I've put my whole / into a tmpfs. Here are the steps I've done.

Recommended Posts

/ in RAM ---preliminary guide---
Caution! Entering this is probably Gentoo-is-for-ricers territory! 😉
Battery backed system (notebook, UPS) strongly recommended!
This has been executed on a Thinkpad T480s, 40 GB RAM, NVMe SSD, BIOS boot.

Section 1: Initial setup.

Boot Funtoo Undead USB or any other suitable Linux distro.

Create tmpfs mount point.

mkdir /mnt/tmpfs

Mount tmpfs. Adjust size to your needs. 12 GiB is probably the absolute minimum for a usable desktop configuration. My freshly installed system with workstation flavor, xfce mix-in and Libreoffice + Gimp eats exactly 9682 MiB now, so there's some headroom.

mount -t tmpfs -o size=24576M tmpfs /mnt/tmpfs/

Enter tmpfs.

cd /mnt/tmpfs/

Fill container with zeros.

dd if=/dev/zero of=loop bs=1M 

Setup loop device.

losetup /dev/loop0 /mnt/tmpfs/loop

Create boot and RAID partitions on SSD/HDD.

Create MD device, replace /dev/nvme0n1p2 with your actual SSD/HDD RAID1 partition.

mdadm --create /dev/md0 /dev/loop0 /dev/nvme0n1p2 --level=1 --raid-devices=2

Disable SSD/HDD

mdadm -f /dev/md0 /dev/nvme0n1p2 && mdadm --manage -r /dev/md0 /dev/nvme0n1p2

Follow on with chapter 5 Funtoo install guide.


/etc/fstab for my particular minimalistic test system. Get the UUIDs from blkid output.

UUID=91c884e5-bd41-4c0e-b1bf-b68fe6317abd	/boot	ext2	noauto,noatime	1 2
UUID=3e84cb4c-8b13-4cbc-ac3d-7bd9ca56a00d	/	xfs	noatime    	0 1

Add domdadm to the kernel parameters in /etc/boot.conf.

Create /mnt/tmpfs.

mkdir /mnt/tmpfs

After exiting the chroot, rebuild the array.

mdadm --manage -a /dev/md0 /dev/nvme0n1p2

Wait until this shows "state: clean".

mdadm -D /dev/md0

Unmount everything and reboot.

Section 2: After every reboot issue this.

mount -t tmpfs -o size=24576M tmpfs /mnt/tmpfs/ && cd /mnt/tmpfs/ && dd if=/dev/zero of=loop bs=1M; losetup /dev/loop0 /mnt/tmpfs/loop

Rebuild the array. For some weird reason, /dev/md0 is renamed to /dev/md127.

mdadm --manage -a /dev/md127 /dev/loop0

Wait until the array is rebuilt.

mdadm -D /dev/md127

Disable SSD/HDD.

mdadm -f /dev/md127 /dev/nvme0n1p2; mdadm --manage -r /dev/md127 /dev/nvme0n1p2

Section 3: Securely shutting down.

Write to SSD/HDD.

mdadm --manage -a /dev/md127 /dev/nvme0n1p2

Wait until the array is rebuilt.

mdadm -D /dev/md127


shutdown -h now


I hope I haven't missed something and everything is in the right order. Also I'm working now on automating the startup and shutdown, I'll update then (this is a side project, can take some weeks to finish).

Some preliminal, crude performance metric on reading small files (tmpfs):

echo 3 > /proc/sys/vm/drop_caches & time eix-update


real    0m3.748s
user    0m2.339s
sys     0m2.438s

And NVMe (Samsung PM981 1 TB):

echo 3 > /proc/sys/vm/drop_caches & time eix-update


real    0m10.818s
user    0m3.369s
sys    0m4.864s


I expect some more drastic gains on better hardware that's incoming soon. A Dual EPYC 7551 build. 16 channel DDR4 vs. that Thinkpad's half-a**ed dual channel DDR4 implementation (8 GiB soldered on + 32 GiB stick). I ain't need no Optane 90xP. 😉

Best regards

Link to post
Share on other sites
Posted (edited)

I've made a rudimentary script to start/stop everything (called rfsrd, root filesystem RAM disk), seems to work without issues:

# configuration begins
# tmpfs size in MiB
# MD device
# SSD/HDD device
# loop device
# configuration ends

while [ $i -lt 1 ]; do
	case $1 in
		echo Usage: rfsrd --start
		echo "       Rebuilds RAMdisk and halts SSD/HDD."
		echo "       rfsrd --stop"
		echo "       Rebuilds SSD/HDD and halts RAMdisk."
		let i=i+1
		echo Rebuilding RAMdisk.
		mount -t tmpfs -o size=$size'M' tmpfs /mnt/tmpfs/ && cd /mnt/tmpfs/ && dd if=/dev/zero of=loop bs=1M; losetup $loopdevice /mnt/tmpfs/loop
		mdadm --manage -a $md $loopdevice
			while [ $j -lt 1 ]; do
				mdadm -D $md | grep "Rebuild Status"
				sleep 5
					if [ -z "$(mdadm -D $md | grep 'Rebuild Status')" ]; then
						mdadm -f $md $ssdhdd; mdadm --manage -r $md $ssdhdd
						let j=j+1
						echo "doing nothing" > /dev/null
		echo Done rebuilding RAMdisk.
		let i=i+1
		echo Rebuilding SSD/HDD.
		mdadm --manage -a $md $ssdhdd
			while [ $k -lt 1 ]; do
				mdadm -D $md | grep "Rebuild Status"
				sleep 5
					if [ -z "$(mdadm -D $md | grep 'Rebuild Status')" ]; then
						mdadm -f $md $loopdevice; mdadm --manage -r $md $loopdevice
						let k=k+1
						echo "doing nothing" > /dev/null
		echo Done rebuilding SSD/HDD.
		let i=i+1
		echo "Invalid argument, run rfsrd --help for more info."
		let i=i+1
	sleep 0.1

I think I'm going to put that stuff and everything that follows (integration into OpenRC) onto a Github tomorrow...

Github repo online: https://github.com/TheDevilsMom/rootfsramdisk

Edited by thedevilsmom
Added repo
Link to post
Share on other sites

Thanks! MOAR to come soon once I'm done tinkering with my new dual EPYC 7551 rig. Quick testing shows it can run all cores @ 3GHz under 1V, but the noise and heat... I need a water loop for that, radiators blowing hot air straight out of the window. I don't want to have my AC running against ~600W of heat, ruins my XMR mining efficiency.

Now I've put that thing two doors away. Video via DisplayPort over fiber (helluva expensive). Keyboard/mouse over LAN through abusing Synergy on my Notebook (Server) and EPYC rig (client).

Next step is using multiple RAID0ed containers each in it's own tmpfs to spread the loopdevice and tmpfs overhead over multiple cores (I've got some performance boost that way on my Thinkpad).

dd if=/dev/mdxxx of=/dev/null bs=1M results in one core loaded fully by dd with about 6.8 GiB/s of throughput. Smaller bs values result in higher loop device CPU load (and dd fully loading one core again).

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...