Saturday, February 28, 2009

Turning off over commit in the Linux kernel

Linux Malloc's never fails (or at least not until you request more than 150% of the available RAM). This is because the Kernel is optimistic - even if you ask for a lot of memory, maybe you won't use it. Seems like a bad bet, but as long as it's true, everything will run fine. As soon as it's false, the kernel starts killing processes randomly. Yuck.

This is because the swap partition does not grow. If you ask for more RAM than your actual ram PLUS your swap partition, Linux will happily "give" it to you, but has no recourse in the situation that you actually touch all those pages.

In the case that you want Malloc to fail if there's not enough available RAM (such as in embedded code), what to do?

The solution is to modify the kernel, or use syscntrl at run-time. I prefer the permanent solution, so here's how to do it.

In mm/mmap.c, about one page down are two variables which control the "over commit" strategy. Starting around line 80:

int sysctl_overcommit_memory = OVERCOMMIT_NEVER;
/* default = OVERCOMMIT_GUESS; heuristic overcommit */

int sysctl_overcommit_ratio = 0;
/* default is 50% */


Postscript: doing this often results in mallocs failing even when there is clearly lots of RAM remaining. It seems that Linux makes the general assumption that over commit is on, and kind of breaks if it's turned off. A better strategy may be to allow the default (default = OVERCOMMIT_GUESS; heuristic overcommit), and modify the code to be slightly more conservative. I find that heuristic overcommit tends to guess that there is about 2% more RAM available than really is. This would probably vary between machines/kernels/apps running a bit, though I haven't tested it.

No comments: