Memory Management Approach for Swapless Embedded Systems

This article presents a strategy for managing memory allocation in swapless, embedded systems to help you avoid system slowness and the dreaded Out-of-Memory killer exception.
Low Memory Watermark (LMW) Module

LMW is a kernel module based on the Linux Security Module (LSM) framework. It implements a heuristic to check the physical memory consumption threshold for denying memory allocation and notifying user space to free up memory. A user-space process terminator can be employed to free up memory. Formulas for low memory watermark thresholds are as follows:

  • deny_threshold = physical_memory * deny_percentage

  • notify_threshold = physical_memory * notify_percentage

physical_memory is the system's main memory and is represented by the kernel global variable totalram_pages. deny_percentage and notify_percentage are tunable kernel parameters, and the value of these can be altered through the sysctl interface. These parameters are bound to the /proc filesystem and can be written to and read from, using standard commands such as echo and cat. These parameters may be handled as follows:

$ echo 110 > /proc/sys/vm/lowmem_deny_watermark

$ echo 90 > /proc/sys/vm/lowmem_notify_watermark

$ cat /proc/sys/vm/lowmem_deny_watermark

$ cat /proc/sys/vm/lowmem_notify_watermark

The LWM architecture is illustrated in Figure 2. Basically, LWM overrides the kernel default overcommit behaviour by setting the vm_enough_memory function pointer field in the security_operations structure to point to the function low_vm_enough_memory(). low_vm_enough_memory() implements a heuristic based on the formula described earlier. Binding vm_enough_memory to low_vm_enough_memory() permits interception of all requests for allocation of memory pages in order to verify whether the committed virtual memory has reached the MAT or ST watermarks. Listing 1 presents how the MAT and ST watermarks are implemented in the low_vm_enough_memory() function.

Figure 2. Low Memory Watermark Architecture

The code in Listing 1 is explained below:

  • Lines 7, 8: verify whether the current process has root privileges.

  • Lines 10, 11: if MAT or ST watermarks are zero, perform the default overcommit behaviour.

  • Lines 13–16: calculate the low memory watermark thresholds.

  • Line 18: the pages are committed to update the amount of vm_committed_space.

  • Line 19: the amount of committed memory is acquired.

  • Line 20: verify whether committed memory has reached the MAT watermark.

  • Line 21: set a flag state to 1 if MAT has been reached—state=1 means any (or both) of the two thresholds was reached.

  • Lines 22, 23: do not deny memory allocation for root programs—allocation is successful for these.

  • Line 24: uncommit the current committed pages since MAT was reached.

  • Line 25: return no memory available message.

  • Line 26: verify whether committed memory has reached the ST watermark.

  • Lines 27, 28: set the state to 1, and allocation has succeeded.

  • Line 30: set the state to 0 (if no threshold was reached).

  • Line 31: memory allocation has succeeded.

The enter_watermark_state() function determines whether the low memory watermark condition has been reached and eventually sends the LMS to user space. A global boolean variable, lowmem_watermark_reached, marks the state of entering or exiting from low memory watermark conditions, being assigned to a value of 1 or 0, respectively. LMS is dispatched whenever a change in the value of this variable occurs.


Geek Guide
The DevOps Toolbox

Tools and Technologies for Scale and Reliability
by Linux Journal Editor Bill Childers

Get your free copy today

Sponsored by IBM

8 Signs You're Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
On Demand
Moderated by Linux Journal Contributor Mike Diehl

Sign up and watch now

Sponsored by Skybot