Common Problem: vmalloc too small

From MythTV Official Wiki
Jump to: navigation, search

The Symptom

You are likely here because you tried to boot your computer and one or more kernel drivers failed to load, resulting in one or more of your pieces of hardware failing to work. If you examined your system logs carefully, you may even find some of the following messages appearing amongst all the other chatter that happens during the booting phase:

allocation failed: out of vmalloc space - use vmalloc=<size> to increase size.

You may also see one or more of the following messages:

cx18-1: ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h

Firstly, do not change things in page.h as suggested--there is a far easier way to fix this once you understand the problem. Fixing this is actually relatively simple, but it's important that you understand what causes it so that you can remedy it correctly.

The Problem

The kernel reserves a small chunk of memory at boot time for use as virtual addressing space. This space is used by drivers and the kernel (among other things) to map hardware to chunks of memory in fixed places. If your 32-bit machine has 1Gb or less of RAM the Linux kernel reserves a minimum of 128Mb for virtual memory addressing (if you have more RAM, it may have reserved slightly more--256Mb at 2GB I think). Many of the tuner driver modules used by hardware relevant to MythTV use up chunks of this memory, as does the restricted nVidia video card driver (without which VDPAU/XvMC accelleration will not work). It is for these reasons that if you migrate to a new machine with less RAM or add more tuner cards you may see the above error when everything was fine before.

You are not likely to see these errors occur on a 64-bit platform using a 64-bit kernel as the default allocation in that case is 1Gb. If you do, you may have somehow been booting a kernel built for a 32-bit CPU.

The Solution

To get around this problem you will need to increase the default vmalloc size the kernel uses, which is done by passing the kernel the vmalloc= parameter at boot time. Do not go overboard and pick an arbitrarily massive number for this--you may not like the result. First look in /proc/meminfo at the VmallocTotal line to find out what the current value is and round that to the nearest 64Mb (122880kB is what shows here on a 32-bit machine with 1Gb of RAM, although strangely large numbers may appear for very small amounts of RAM--assume 128Mb if this happens... and buy more RAM). Now increase that number by 64Mb (128Mb + 64Mb is 192Mb) and test to see if all the devices/drivers initialize after a reboot. If they don't, add another 64Mb and try again until everything works.

lilo

If you are using LILO to boot your machine, to pass the vmalloc= parameter to the kernel simply add it to the global (or image-specific) append= line in /etc/lilo.conf. It should look something like this when you're done:

# Linux bootable partition config begins
image = /boot/vmlinuz
  root = /dev/hda1
  append = "vmalloc=192M"
  label = Linux
  read-only
# Linux bootable partition config ends

You will need to re-run lilo as root after this for the change to take effect.

As an alternative during testing the testing phase, you can simply type the kernel parameter manually when the machine boots by pressing CTRL to stop LILO from booting and make it present you with a prompt where you'd type the image name followed by the kernel parameter, like "Linux vmalloc=192M". If you did it correctly you will be able to see your option appear in /proc/cmdline after the machine has booted.

grub

If you are using GRUB to boot your machine, to pass the vmalloc= parameter to the kernel simply add it to the global kopt parameter in /boot/grub/menu.lst, which will look something like this:

kopt=root=UUID=1029384-7e40-ffd2-9968-7a8b9e78f9g7s ro vmalloc=192M

You could also append that argument to an individual kernel in it's particular stanza in menu.lst if you didn't wish to apply this setting to all your kernels. Alternatively, you can append your new vmalloc argument to the GRUB_CMDLINE_LINUX_DEFAULT variable in /etc/default/grub (if your distribution uses this file--not all do).

Remember, if you did it correctly you will be able to see your option appear in /proc/cmdline after the machine has booted.

grub2

You can use the line GRUB_CMDLINE_LINUX="" in /etc/default/grub to pass the vmalloc= parameter to the kernel like this:

GRUB_CMDLINE_LINUX="vmalloc=256MB"

other bootloaders

Consult your documentation.