mm/mlock.c
Source file repositories/reference/linux-study-clean/mm/mlock.c
File Facts
- System
- Linux kernel
- Corpus path
mm/mlock.c- Extension
.c- Size
- 21415 bytes
- Lines
- 832
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: syscall or user/kernel boundary
- Status
- core implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/capability.hlinux/mman.hlinux/mm.hlinux/sched/user.hlinux/swap.hlinux/swapops.hlinux/pagemap.hlinux/folio_batch.hlinux/pagewalk.hlinux/mempolicy.hlinux/syscalls.hlinux/sched.hlinux/export.hlinux/rmap.hlinux/mmzone.hlinux/hugetlb.hlinux/memcontrol.hlinux/mm_inline.hlinux/secretmem.hinternal.h
Detected Declarations
syscall mlocksyscall mlock2syscall munlocksyscall mlockallsyscall munlockallstruct mlock_fbatchfunction can_do_mlockfunction mlock_folio_batchfunction mlock_drain_localfunction mlock_drain_remotefunction need_mlock_drainfunction mlock_foliofunction mlock_new_foliofunction munlock_foliofunction folio_mlock_stepfunction allow_mlock_munlockfunction mlock_pte_rangefunction munlockfunction mlock_fixupfunction vma_flags_testfunction apply_vma_lock_flagsfunction for_each_vma_rangefunction get_user_pagesfunction do_mlockfunction mlockallfunction for_each_vmafunction user_shm_lockfunction user_shm_unlockexport can_do_mlock
Annotated Snippet
SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
{
return do_mlock(start, len, VM_LOCKED);
}
SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)
{
vm_flags_t vm_flags = VM_LOCKED;
if (flags & ~MLOCK_ONFAULT)
return -EINVAL;
if (flags & MLOCK_ONFAULT)
vm_flags |= VM_LOCKONFAULT;
return do_mlock(start, len, vm_flags);
}
SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
{
int ret;
start = untagged_addr(start);
len = PAGE_ALIGN(len + (offset_in_page(start)));
start &= PAGE_MASK;
if (mmap_write_lock_killable(current->mm))
return -EINTR;
ret = apply_vma_lock_flags(start, len, 0);
mmap_write_unlock(current->mm);
return ret;
}
/*
* Take the MCL_* flags passed into mlockall (or 0 if called from munlockall)
* and translate into the appropriate modifications to mm->def_flags and/or the
* flags for all current VMAs.
*
* There are a couple of subtleties with this. If mlockall() is called multiple
* times with different flags, the values do not necessarily stack. If mlockall
* is called once including the MCL_FUTURE flag and then a second time without
* it, VM_LOCKED and VM_LOCKONFAULT will be cleared from mm->def_flags.
*/
static int apply_mlockall_flags(int flags)
{
VMA_ITERATOR(vmi, current->mm, 0);
struct vm_area_struct *vma, *prev = NULL;
vm_flags_t to_add = 0;
current->mm->def_flags &= ~VM_LOCKED_MASK;
if (flags & MCL_FUTURE) {
current->mm->def_flags |= VM_LOCKED;
if (flags & MCL_ONFAULT)
current->mm->def_flags |= VM_LOCKONFAULT;
if (!(flags & MCL_CURRENT))
goto out;
}
if (flags & MCL_CURRENT) {
to_add |= VM_LOCKED;
if (flags & MCL_ONFAULT)
to_add |= VM_LOCKONFAULT;
}
for_each_vma(vmi, vma) {
int error;
vm_flags_t newflags;
newflags = vma->vm_flags & ~VM_LOCKED_MASK;
newflags |= to_add;
error = mlock_fixup(&vmi, vma, &prev, vma->vm_start, vma->vm_end,
newflags);
/* Ignore errors, but prev needs fixing up. */
if (error)
prev = vma;
cond_resched();
}
out:
return 0;
}
SYSCALL_DEFINE1(mlockall, int, flags)
{
unsigned long lock_limit;
int ret;
Annotation
- Immediate include surface: `linux/capability.h`, `linux/mman.h`, `linux/mm.h`, `linux/sched/user.h`, `linux/swap.h`, `linux/swapops.h`, `linux/pagemap.h`, `linux/folio_batch.h`.
- Detected declarations: `syscall mlock`, `syscall mlock2`, `syscall munlock`, `syscall mlockall`, `syscall munlockall`, `struct mlock_fbatch`, `function can_do_mlock`, `function mlock_folio_batch`, `function mlock_drain_local`, `function mlock_drain_remote`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: core implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.