Chapter 9. Using mlock() system calls on RHEL for Real Time
The RHEL for Real-Time memory lock (mlock()
) function enables the real-time calling processes to lock or unlock a specified range of the address space. This range prevents Linux from paging the locked memory when swapping memory space. After you allocate the physical page to the page table entry, references to that page become fast. The mlock()
system calls include two functions: mlock()
and mlockall()
. Similarly, munlock()
system call includes the munlock()
and munlockall()
functions.
9.1. mlock() and munlock() system calls
The mlock()
and mlockall()
system calls lock a specified memory range and do not page this memory. The following are the mlock()
system call groups:
-
mlock()
system calls: lock a specified range of address. -
munlock()
system calls: unlock a specified range of address.
The mlock()
system calls, lock pages in the address range starting at addr
and continuing for len
bytes. When the call returns successfully, all pages that contain a part of the specified address range stay in the memory until unlocked later.
With mlockall()
system calls, you can lock all mapped pages into the specified address range. Memory locks do not stack. Any page locked by several calls will unlock the specified address range or the entire region with a single munlock()
system call. With munlockall()
system calls, you can unlock the entire program space.
The status of the pages contained in a specific range depends on the value in the flags
argument. The flags
argument can be 0 or MLOCK_ONFAULT
.
Memory locks are not inherited by a child process through fork and automatically removed when a process terminates.
Use mlock()
system calls with caution. Excessive use can cause out-of-memory (OOM) errors. When an application is large or if it has a large data domain, the mlock()
calls can cause thrashing when the system is not able to allocate memory for other tasks.
When using mlockall()
calls for real-time processes, ensure that you reserve sufficient stack pages.
9.2. Using mlock() system calls to lock pages
The real-time mlock()
system calls use the addr
parameter to specify the start of an address range and len
to define the length of the address space in bytes. The alloc_workbuf()
function dynamically allocates a memory buffer and locks it. Memory allocation is done by the posix_memalig()
function to align the memory area to a page. The function free_workbuf()
unlocks the memory area.
Prerequisites:
-
You have root privileges or the
CAP_IPC_LOCK
capability to usemlockall()
ormlock()
on large buffers
Procedure
To lock pages with
mlock()
system call, run the following command:#include <stdlib.h> #include <unistd.h> #include <sys/mman.h> void *alloc_workbuf(size_t size) { void ptr; int retval; // alloc memory aligned to a page, to prevent two mlock() in the same page. retval = posix_memalign(&ptr, (size_t) sysconf(_SC_PAGESIZE), size); // return NULL on failure if (retval) return NULL; // lock this buffer into RAM if (mlock(ptr, size)) { free(ptr); return NULL; } return ptr; } void free_workbuf(void *ptr, size_t size) { // unlock the address range munlock(ptr, size); // free the memory free(ptr); }
Verification
The real-time mlock()
and munlock()
calls return 0 when successful. In case of an error, they return -1 and set a errno
to indicate the error.
9.3. Using mlockall() system calls to lock all mapped pages
To lock and unlock real-time memory with mlockall()
and munlockall()
system calls, set the flags
argument to 0 or one of the constants: MCL_CURRENT
or MCL_FUTURE
. With MCL_FUTURE
, a future system call, such as mmap2()
, sbrk2()
, or malloc3()
, might fail, because it causes the number of locked bytes to exceed the permitted maximum.
Prerequisites
- You have root permissions on the system.
Procedure
To use
mlockall()
andmunlockall()
real-time system calls :Lock all mapped pages by using
mlockall()
system call:#include <sys/mman.h> int mlockall (int flags)
Unlock all mapped pages by using
munlockall()
system call:#include <sys/mman.h> int munlockall (void)
Additional resources
-
capabilities(7)
man page -
mlock(2)
man page -
mlock(3)
man page -
move_pages(2)
man page -
posix_memalign(3)
man page -
posix_memalign(3p)
man page
9.4. Using mmap() system calls to map files or devices into memory
For large memory allocations on real-time systems, the memory allocation (malloc
) method uses the mmap()
system call to find memory space. You can assign and lock memory areas by setting MAP_LOCKED
in the flags
parameter. As mmap()
assigns memory on a page basis, it avoids two locks on the same page, which prevents the double-lock or single-unlock problems.
Prerequisites
- You have root permissions on the system.
Procedure
To map a specific process-address space:
#include <sys/mman.h> #include <stdlib.h> void *alloc_workbuf(size_t size) { void *ptr; ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_LOCKED, -1, 0); if (ptr == MAP_FAILED) return NULL; return ptr; } void free_workbuf(void *ptr, size_t size) { munmap(ptr, size); }
Verification
-
When the
mmap()
function completes successfully, it returns a pointer to the mapped area. On error, it returns theMAP_FAILED
value and sets aerrno
to indicate the error. -
When the
munmap()
function completes successfully, it returns0
. On error, it returns-1
and sets anerrno
to indicate the error.
Additional resources
-
mmap(2)
man page -
mlockall(2)
man page
9.5. Parameters for mlock() system calls
The parameters for memory lock system call and the functions they perform are listed and described in the mlock
parameters table.
Parameter | Description |
---|---|
|
Specifies the process address space to lock or unlock. When NULL, the kernel chooses the page-aligned arrangement of data in the memory. If |
| Specifies the length of the mapping, which must be greater than 0. |
| Specifies the file descriptor. |
|
|
|
Controls the mapping visibility to other processes that map the same file. It takes one of the values: |
| Locks all pages that are currently mapped into a process. |
| Sets the mode to lock subsequent memory allocations. These could be new pages required by a growing heap and stack, new memory-mapped files, or shared memory regions. |