Skip to content

Commit 48bd77b

Browse files
committed
Add mlockall and munlockall
1 parent 1a9d129 commit 48bd77b

File tree

5 files changed

+232
-0
lines changed

5 files changed

+232
-0
lines changed

src/backend/libc/mm/syscalls.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
33
#[cfg(not(target_os = "redox"))]
44
use super::types::Advice;
5+
#[cfg(any(
6+
linux_kernel,
7+
target_os = "freebsd",
8+
target_os = "netbsd",
9+
target_os = "openbsd",
10+
target_os = "dragonfly",
11+
target_os = "illumos",
12+
))]
13+
use super::types::MlockallFlags;
514
#[cfg(any(target_os = "emscripten", target_os = "linux"))]
615
use super::types::MremapFlags;
716
use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags};
@@ -220,3 +229,36 @@ pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd>
220229
}
221230
ret_owned_fd(userfaultfd(bitflags_bits!(flags)))
222231
}
232+
233+
/// Locks all pages mapped into the address space of the calling process.
234+
///
235+
/// This includes the pages of the code, data and stack segment, as well as shared libraries,
236+
/// user space kernel data, shared memory, and memory-mapped files. All mapped pages are
237+
/// guaranteed to be resident in RAM when the call returns successfully;
238+
/// the pages are guaranteed to stay in RAM until later unlocked.
239+
#[inline]
240+
#[cfg(any(
241+
linux_kernel,
242+
target_os = "freebsd",
243+
target_os = "netbsd",
244+
target_os = "openbsd",
245+
target_os = "dragonfly",
246+
target_os = "illumos",
247+
))]
248+
pub(crate) fn mlockall(flags: MlockallFlags) -> io::Result<()> {
249+
unsafe { ret(c::mlockall(bitflags_bits!(flags))) }
250+
}
251+
252+
/// Unlocks all pages mapped into the address space of the calling process.
253+
#[inline]
254+
#[cfg(any(
255+
linux_kernel,
256+
target_os = "freebsd",
257+
target_os = "netbsd",
258+
target_os = "openbsd",
259+
target_os = "dragonfly",
260+
target_os = "illumos",
261+
))]
262+
pub(crate) fn munlockall() -> io::Result<()> {
263+
unsafe { ret(c::munlockall()) }
264+
}

src/backend/libc/mm/types.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,3 +442,33 @@ bitflags! {
442442
const _ = !0;
443443
}
444444
}
445+
446+
#[cfg(any(
447+
linux_kernel,
448+
target_os = "freebsd",
449+
target_os = "netbsd",
450+
target_os = "openbsd",
451+
target_os = "dragonfly",
452+
target_os = "illumos",
453+
))]
454+
bitflags! {
455+
/// `MCL_*` flags for use with [`mlockall`].
456+
///
457+
/// [`mlockall`]: crate::mm::mlockall
458+
pub struct MlockallFlags: i32 {
459+
// libc doesn't define `MCL_ONFAULT` yet.
460+
// const ONFAULT = libc::MCL_ONFAULT;
461+
/// Lock all pages which will become mapped into the address
462+
/// space of the process in the future. These could be, for
463+
/// instance, new pages required by a growing heap and stack
464+
/// as well as new memory-mapped files or shared memory
465+
/// regions.
466+
const FUTURE = libc::MCL_FUTURE;
467+
/// Lock all pages which are currently mapped into the address
468+
/// space of the process.
469+
const CURRENT = libc::MCL_CURRENT;
470+
471+
/// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags>
472+
const _ = !0;
473+
}
474+
}

src/backend/linux_raw/mm/syscalls.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66
#![allow(unsafe_code)]
77
#![allow(clippy::undocumented_unsafe_blocks)]
88

9+
#[cfg(any(
10+
linux_kernel,
11+
target_os = "freebsd",
12+
target_os = "netbsd",
13+
target_os = "openbsd",
14+
target_os = "dragonfly",
15+
target_os = "illumos",
16+
))]
17+
use super::types::MlockallFlags;
918
use super::types::{
1019
Advice, MapFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags,
1120
UserfaultfdFlags,
@@ -210,3 +219,36 @@ pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<
210219
pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> {
211220
ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags))
212221
}
222+
223+
/// Locks all pages mapped into the address space of the calling process.
224+
///
225+
/// This includes the pages of the code, data and stack segment, as well as shared libraries,
226+
/// user space kernel data, shared memory, and memory-mapped files. All mapped pages are
227+
/// guaranteed to be resident in RAM when the call returns successfully;
228+
/// the pages are guaranteed to stay in RAM until later unlocked.
229+
#[inline]
230+
#[cfg(any(
231+
linux_kernel,
232+
target_os = "freebsd",
233+
target_os = "netbsd",
234+
target_os = "openbsd",
235+
target_os = "dragonfly",
236+
target_os = "illumos",
237+
))]
238+
pub(crate) fn mlockall(flags: MlockallFlags) -> io::Result<()> {
239+
unsafe { ret(syscall_readonly!(__NR_mlockall, flags)) }
240+
}
241+
242+
/// Unlocks all pages mapped into the address space of the calling process.
243+
#[inline]
244+
#[cfg(any(
245+
linux_kernel,
246+
target_os = "freebsd",
247+
target_os = "netbsd",
248+
target_os = "openbsd",
249+
target_os = "dragonfly",
250+
target_os = "illumos",
251+
))]
252+
pub(crate) fn munlockall() -> io::Result<()> {
253+
unsafe { ret(syscall_readonly!(__NR_munlockall)) }
254+
}

src/backend/linux_raw/mm/types.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,42 @@ bitflags! {
262262
const _ = !0;
263263
}
264264
}
265+
266+
#[cfg(any(
267+
linux_kernel,
268+
target_os = "freebsd",
269+
target_os = "netbsd",
270+
target_os = "openbsd",
271+
target_os = "dragonfly",
272+
target_os = "illumos",
273+
))]
274+
bitflags! {
275+
/// `MCL_*` flags for use with [`mlockall`].
276+
///
277+
/// [`mlockall`]: crate::mm::mlockall
278+
pub struct MlockallFlags: u32 {
279+
/// Used together with `MCL_CURRENT`, `MCL_FUTURE`, or both. Mark
280+
/// all current (with `MCL_CURRENT`) or future (with `MCL_FUTURE`)
281+
/// mappings to lock pages when they are faulted in. When
282+
/// used with `MCL_CURRENT`, all present pages are locked, but
283+
/// `mlockall()` will not fault in non-present pages. When used
284+
/// with `MCL_FUTURE`, all future mappings will be marked to
285+
/// lock pages when they are faulted in, but they will not be
286+
/// populated by the lock when the mapping is created.
287+
/// `MCL_ONFAULT` must be used with either `MCL_CURRENT` or
288+
/// `MCL_FUTURE` or both.
289+
const ONFAULT = linux_raw_sys::general::MCL_ONFAULT;
290+
/// Lock all pages which will become mapped into the address
291+
/// space of the process in the future. These could be, for
292+
/// instance, new pages required by a growing heap and stack
293+
/// as well as new memory-mapped files or shared memory
294+
/// regions.
295+
const FUTURE = linux_raw_sys::general::MCL_FUTURE;
296+
/// Lock all pages which are currently mapped into the address
297+
/// space of the process.
298+
const CURRENT = linux_raw_sys::general::MCL_CURRENT;
299+
300+
/// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags>
301+
const _ = !0;
302+
}
303+
}

src/mm/mmap.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ use core::ffi::c_void;
1212

1313
#[cfg(linux_kernel)]
1414
pub use backend::mm::types::MlockFlags;
15+
#[cfg(any(
16+
linux_kernel,
17+
target_os = "freebsd",
18+
target_os = "netbsd",
19+
target_os = "openbsd",
20+
target_os = "dragonfly",
21+
target_os = "illumos",
22+
))]
23+
pub use backend::mm::types::MlockallFlags;
1524
#[cfg(any(target_os = "emscripten", target_os = "linux"))]
1625
pub use backend::mm::types::MremapFlags;
1726
pub use backend::mm::types::{MapFlags, MprotectFlags, ProtFlags};
@@ -340,3 +349,73 @@ pub unsafe fn mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io:
340349
pub unsafe fn munlock(ptr: *mut c_void, len: usize) -> io::Result<()> {
341350
backend::mm::syscalls::munlock(ptr, len)
342351
}
352+
353+
/// Locks all pages mapped into the address space of the calling process.
354+
///
355+
/// This includes the pages of the code, data and stack segment, as well as shared libraries,
356+
/// user space kernel data, shared memory, and memory-mapped files. All mapped pages are
357+
/// guaranteed to be resident in RAM when the call returns successfully;
358+
/// the pages are guaranteed to stay in RAM until later unlocked.
359+
///
360+
/// # References
361+
/// - [POSIX]
362+
/// - [Linux]
363+
/// - [FreeBSD]
364+
/// - [NetBSD]
365+
/// - [OpenBSD]
366+
/// - [DragonFly BSD]
367+
/// - [illumos]
368+
/// - [glibc]
369+
///
370+
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mlockall.html
371+
/// [Linux]: https://man7.org/linux/man-pages/man2/mlockall.2.html
372+
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mlockall&sektion=2
373+
/// [NetBSD]: https://man.netbsd.org/mlockall.2
374+
/// [OpenBSD]: https://man.openbsd.org/mlockall.2
375+
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=mlockall&section=2
376+
/// [illumos]: https://illumos.org/man/3C/mlockall
377+
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Page-Lock-Functions.html#index-mlockall
378+
#[cfg(any(
379+
linux_kernel,
380+
target_os = "freebsd",
381+
target_os = "netbsd",
382+
target_os = "openbsd",
383+
target_os = "dragonfly",
384+
target_os = "illumos",
385+
))]
386+
pub fn mlockall(flags: MlockallFlags) -> io::Result<()> {
387+
backend::mm::syscalls::mlockall(flags)
388+
}
389+
390+
/// Unlocks all pages mapped into the address space of the calling process.
391+
///
392+
/// # References
393+
/// - [POSIX]
394+
/// - [Linux]
395+
/// - [FreeBSD]
396+
/// - [NetBSD]
397+
/// - [OpenBSD]
398+
/// - [DragonFly BSD]
399+
/// - [illumos]
400+
/// - [glibc]
401+
///
402+
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/munlockall.html
403+
/// [Linux]: https://man7.org/linux/man-pages/man2/munlockall.2.html
404+
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=munlockall&sektion=2
405+
/// [NetBSD]: https://man.netbsd.org/munlockall.2
406+
/// [OpenBSD]: https://man.openbsd.org/munlockall.2
407+
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=munlockall&section=2
408+
/// [illumos]: https://illumos.org/man/3C/munlockall
409+
/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Page-Lock-Functions.html#index-munlockall
410+
#[inline]
411+
#[cfg(any(
412+
linux_kernel,
413+
target_os = "freebsd",
414+
target_os = "netbsd",
415+
target_os = "openbsd",
416+
target_os = "dragonfly",
417+
target_os = "illumos",
418+
))]
419+
pub fn munlockall() -> io::Result<()> {
420+
backend::mm::syscalls::munlockall()
421+
}

0 commit comments

Comments
 (0)