Using Graphics Card Memory as Swap

From Gentoo Linux Wiki
Jump to: navigation, search

Graphics cards contain a lot of very fast RAM, typically between 64 and 512 MB. With Linux, it's possible to use it as swap space, or even as RAM disk.

Contents

[edit] Be warned

It's nice to have fast swap or RAM disk on your home computer but be warned, if a binary driver is loaded for X, it may freeze the whole system or create graphical glitches. Usually there is no way to tell the driver how much memory could be used, so it won't know the upper limit. However, the VESA driver can be used because it provides the possibility to set the video RAM size.

So, Direct Rendering or fast swap. Your choice. Also, due to limitations within the MTD subsystem the max size per device is 256MB.

Unlike motherboard RAM and hard drives, there aren't any known video cards that have ECC memory. This may not be a big deal for graphics rendering, but you definitely don't want to put critical data in it or use this feature on servers.

[edit] Kernel Configuration

To use the graphics (and possibly any other) card's memory, it needs to be mapped by the kernel. By default only the system RAM is considered as usable RAM, to access memory from the PCI address space one needs a driver which registers them. In 2.6 kernels this driver is called Memory Technology Device (MTD). You need to enable this and some other key features in your kernel:

Linux Kernel Configuration: Enable MTD kernel features
Device Drivers  --->
    <M> Memory Technology Device (MTD) support  --->
        <M> Direct char device access to MTD devices
        <M> Common interface to block layer for MTD 'translation layers
        <M> Caching block device access to MTD devices
        Self-contained MTD device drivers  --->
            <M> Physical system RAM

[edit] Finding the memory

Now let's search for the video memory in the PCI space. The easiest way is to use lspci(sys-apps/pciutils). Start with looking up your graphics card:

lspci | grep VGA

An example output would be:

02:00.0 VGA compatible controller: ATI Technologies Inc R300 AD [Radeon 9500 Pro]

That's the graphics card. now we need to use lspci again to check the card for more details. To to this we tell lspci to be verbose when checking the PCI slot 02:00.0, as the previous lspci output indicated the graphics card sits there:

lspci -vvv -s 02:00.0
0000:02:00.0 VGA compatible controller: ATI Technologies Inc R300 AD [Radeon 9500 Pro] (prog-if 00 [VGA])
       Subsystem: PC Partner Limited: Unknown device 7c07
       Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B-
       Status: Cap+ 66Mhz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
       Latency: 32 (2000ns min), cache line size 08
       Interrupt: pin A routed to IRQ 255
       Region 0: Memory at d8000000 (32-bit, prefetchable) [size=128M]
       Region 1: I/O ports at b000 [size=256]
       Region 2: Memory at e9000000 (32-bit, non-prefetchable) [size=64K]
       Expansion ROM at e8000000 [disabled] [size=128K]
       Capabilities: [58] AGP version 3.0
               Status: RQ=256 Iso- ArqSz=0 Cal=0 SBA+ ITACoh- GART64- HTrans- 64bit- FW+ AGP3+ Rate=x4,x8
               Command: RQ=1 ArqSz=0 Cal=0 SBA+ AGP- GART64- 64bit- FW- Rate=<none>
       Capabilities: [50] Power Management version 2
               Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
               Status: D0 PME-Enable- DSel=0 DScale=0 PME-

What we need to look for is a prefetchable memory region, here Region 0. The start of the memory space is 0xd8000000, a 32 bit hex value.

[edit] Mapping the memory

To actually access the memory from PCI space, you need to tell the MTD driver where it starts and how much of it you want to allocate. This we do by telling the phram module where the memory region begins and how much of it we want as VRAM. Continuting from the example above, we here allocate 124MiB starting from 0xd8400000:

Note: 124Mi might seem odd, but is correct.
modprobe phram phram=VRAM,0xd8400000,124Mi

Check with /proc/mtd that the MTD device is created:

cat /proc/mtd
dev:    size   erasesize  name
mtd0: 07c00000 00004000 "mtd0"

[edit] Using it

To have this show up as a device in /dev you'll need to load the mtdblock module:

modprobe mtdblock

udev will now automatically create the /dev/mtdblock0 node.

Now, you can either use the device as a RAM Disk, or as swap. Either way, you need to create a FS on it, we'll here go with the swap way:

mkswap /dev/mtdblock0
swapon /dev/mtdblock0

This will create the swap structure in the video card's RAM, and also activate it as system swap. To specify the priority (which swap source will be used first in the swap list), use swapon's switch, -p N where N is a number between 0 and 32767, the higher the number, the higher the priority. Example:

swapon /dev/mtdblock0 -p 10

Without specifying priority, the next lowest will be used. Also, this can be added to /etc/fstab, so you won't need to manually add this after every boot:

File: /etc/fstab
# <fs>                          <mountpoint>    <type>          <opts>                  <dump/pass>
...
/dev/mtdblock0                  none            swap            sw,pri=10

In the options field, the pri= is the same as swapon's -p switch. Please read the troubleshooting section, before closing this page.

Personal tools