Prohibit swapping, or at least count/measure swaps?

Would like to ensure a program never swaps, and only uses RAM and CPU caches. Running on Linux.

I am not an expert at this level of computing, but am trying to learn.

Looking at libc, would mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT) be the correct approach?

If so, would it still be possible that some shared library would be swapped before execution begins in fn main() (I assume the earliest mlockall could be called would be the top of main...) but at least the MCL_ONFAULT would lock it the next time it got read?

(Ideally, the requirement not to swap would apply only to initialized memory, not to all allocated memory, since when data structures reallocate and double in size for the last time during an execution it's likely that much of the recently-allocated memory will never be "used"--written to or read from--by the program. But this feels like too much to ask on top of what already seems to be a thorny requirement.)

(If impossible to ensure no swapping, then would like to count/measure swaps to know whether it happened or not/how much, but perhaps this is harder with libc's RUSAGE ru_nswap being unmaintained on Linux.)

(

Follow up question would be, once the memory usage is constrained to RAM and caches, how to correctly limit it -- libc's setrlimt with which of the following?

  • RLIMIT_AS
  • RLIMIT_DATA
  • RLIMIT_RSS

)

Since this is not a Rust-specific question, you may want to check SO, for example:
https://stackoverflow.com/questions/578137/can-i-tell-linux-not-to-swap-out-a-particular-processes-memory

You may want to replace the #[global_allocator] with one that locks memory and supports some allocation auditing.

The idea would be to write an allocator that itself would call things like libc's mlockall, or other external libraries? Looking at std::alloc::Layout, it seems to be agnostic to swapping, right?

ok; more support for mlockall

The SO answers also mention other options such as putting it into a cgroup

cgroup via swappiness looks more like delay/defer rather than prevent:

https://www.kernel.org/doc/Documentation/sysctl/vm.txt > swappiness

A value of 0 instructs the kernel not to initiate swap until the amount of free and file-backed pages is less than the high water mark in a zone.

(emph added)

but I might be failing to recognize another cgroups feature that does prevention

memory.swap.max

A read-write single value file which exists on non-root cgroups. The default is “max”.

Swap usage hard limit. If a cgroup’s swap usage reaches this limit, anonymous memory of the cgroup will not be swapped out.

1 Like

If (more than likely) your running systemd, it has the setting for cgroup control.
If service then in config file.
Regular users can

systemd-run --user --collect --scope -p MemorySwapMax=0 -- ./target/release/app

It does not stop other swapping and inadvertently making the app perform worse.

do you know whether, in the case of two processes---one in a cgroup with memory.swap.max = 0, the other not---sharing a single page, could the latter process without the limit still end up swapping the shared page? E.g. some common dependency like glibc?

glibc's .text sections are backed by a file, so it never goes into swap. it just gets evicted from the page cache under memory pressure.