Monday, September 3, 2012

Replacing your SWAP with the memory of your graphics adapter

If you have a server with a more or less big graphics adapter (big in case that the graphics adapter has a lot of memory) than you can replace your SWAP area with it. This might be something real useful for a graphics adapter in a Linux server with no monitor attached to it.

1. Preperations

The first thing you need to know is the slot number of your graphics adapter:

# lspci | grep VGA
00:02.0 VGA compatible controller: Intel Corporation E7221 Integrated Graphics Controller (rev 05)

The slot number is the number at the beginning of the line, in my case 00:02.0. Then start lspci again with the verbose option to get the amount of memory and the address where it starts:

# lspci | grep VGA
00:02.0 VGA compatible controller: Intel Corporation E7221 Integrated Graphics Controller (rev 05)
[root@dc01: ~ ] lspci -v -s 00:02.0
00:02.0 VGA compatible controller: Intel Corporation E7221 Integrated Graphics Controller (rev 05) (prog-if 00 [VGA controller])
        Subsystem: Fujitsu Technology Solutions Device 1076
        Flags: bus master, fast devsel, latency 0, IRQ 16
        Memory at f0000000 (32-bit, non-prefetchable) [size=512K]
        I/O ports at 2000 [size=8]
        Memory at e0000000 (32-bit, prefetchable) [size=256M]
        Memory at f0080000 (32-bit, non-prefetchable) [size=256K]
        Expansion ROM at <unassigned> [disabled]
        Capabilities: [d0] Power Management version 2
        Kernel driver in use: i915
        Kernel modules: i915

Take note the line that holds the prefetchable memory line: Memory at e0000000 (32-bit, prefetchable) [size=256M]
It shows that the memory of the graphics adapter starts at 0xe0000000 and that the graphics adapter has an amount of 256MB. The next thing you need to do is to convert 256MB in MiB:

# echo 256/1.048576 | bc -l
244.14062500000000000000

Now you can load the phram module with 0xe0000000 as start address and the length of memory you want to use:

# modprobe phram phram=vgaswap,0xe0000000,244Mi

vgaswap is just a name, you can even use the name of your cat here. When modules has loaded successfully then you should have a similar line in your dmesg output:

# dmesg
...
phram: vgaswap device: 0xf400000 at 0xe0000000

Also check /proc/mtd:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 0f400000 00001000 "vgaswap"

With the phram module loaded you need a device which you can use now. Just load the mtdblock module:

# modprobe mtdblock

And check for /dev/mtdblock0:

# ls -la /dev/mtdblock0
brw-rw---- 1 root disk 31, 0 Sep 10 22:50 /dev/mtdblock0

Finally you are ready to create a new SWAP area on it:

# mkswap /dev/mtdblock0
Setting up swapspace version 1, size = 249852 KiB
no label, UUID=d731c00d-0b56-456f-96a5-758995563ddc

Depending on what you need you might want to replace your SWAP area or append your SWAP area.

2. Replace the available SWAP area

First check your current SWAP area:

# free -m
             total       used       free     shared    buffers     cached
...
Swap:          128          0        128

Then disable it:

# grep swap /etc/fstab
/dev/sda1        swap             swap        defaults         0   0
# swapoff /dev/sda1

Check that you don't have any SWAP area available:

# free -m
             total       used       free     shared    buffers     cached
...
Swap:            0          0          0

Finally turn on your new SWAP area:

# swapon /dev/mtdblock0
# free -m
             total       used       free     shared    buffers     cached
...
Swap:          243          0        243

3. Append the available SWAP area

The nice thing with multiple SWAP areas is that you can use SWAP areas by priorities. The memory of a graphics adapter is much faster then a partition of a harddisk. So it is a good to use the memory of your graphics adapter with a higher priority. To use a SWAP area with a higher priority use the swapon command with the -p switch. First check your current SWAP:

# free -m
             total       used       free     shared    buffers     cached
...
Swap:          128          0        128

Then run swapon to append your SWAP area:

# swapon -p 20 /dev/mtdblock0

And check your SWAP:

# free -m
             total       used       free     shared    buffers     cached
...
Swap:          371          0        371

When your machines begins to swap then it will first use the memory of the graphics adapter and then the partition on the harddisk.

4. Automatic start at boot

To use your graphics adapter memory as SWAP area during booting you need to change the rc.S script in /etc/rc.d/. Add the following lines after the root file system will be remounted rw:

# vi /etc/rc.d/rc.S
...
# Remounting the / partition will initialize the new /etc/mtab:
/sbin/mount -w -o remount /

# Enable swapping:
/sbin/modprobe phram phram=vgaswap,0xe0000000,244Mi
/sbin/modprobe mtdblock
/sbin/mkswap /dev/mtdblock0 > /dev/null
/sbin/swapon -a 2> /dev/null
...

Just change the values for your graphics adapter for the phram module. You need to add a second swapon command because when the root file system is not mounted rw then the /dev/mtdblock0 can not be created.
If you only want to use the memory as SWAP area then change the /etc/fstab like this:

# vi /etc/fstab
...
/dev/mtdblock0   swap             swap        defaults       0   0
...

If you want to use both, the memory of your graphics adapter and a partition on a harddisk then change the /etc/fstab like this:

/dev/mtdblock0   swap             swap        pri=20         0   0
/dev/sda1        swap             swap        pri=10         0   0