MINCORE(2)

πŸ’– MINCORE(2) πŸ’–

okay bestie, sit down, we're doing a system call today. this one lives in the System Calls Manual section (that's section 2, iykyk) and it's all about figuring out which of your memory pages are actually here right now. it's giving detective energy. πŸ”βœ¨


🌸 NAME 🌸

mincore β€” determine residency of memory pages

like... which pages are home rn? that's the whole vibe.


πŸŽ€ LIBRARY πŸŽ€

Standard C Library (libc, -lc)

yeah you just link the normal libc, nothing spicy, no extra flag needed beyond -lc. slay.


✨ SYNOPSIS ✨

#include <sys/mman.h>

int
mincore(const void *addr, size_t len, char *vec);

look at her. three arguments, one int return, no drama. πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

so the mincore() system call figures out whether each of the pages in the region starting at addr and going on for len bytes is resident or mapped β€” and which of those two things it tells you depends on the value of the sysctl vm.mincore_mapped. yes, a sysctl controls the whole mood. iconic.

the status comes back in the vec array, and it's literally one character per page. each character is either:

  • 0 if the page is not resident, or
  • a combination of the following flags (these are defined in <sys/mman.h>, bestie, go look):

🧚 the flags 🧚

  • MINCORE_INCORE β€” page is in core (resident). she's here, she's present, main character.
  • MINCORE_REFERENCED β€” page has been referenced by us.
  • MINCORE_MODIFIED β€” page has been modified by us.
  • MINCORE_REFERENCED_OTHER β€” page has been referenced.
  • MINCORE_MODIFIED_OTHER β€” page has been modified.
  • MINCORE_SUPER β€” page is part of a large (β€œsuper”) page. big page energy fr fr.
⚠️ okay important: the info that mincore() gives you may already be out of date by the time the system call returns. like, you asked, the answer came back, and the world moved on. 😭 the only way to actually ensure a page is resident is to lock it into memory with the mlock(2) system call. that's the real ones' move.

πŸ’œ the sysctl situation πŸ’œ

if vm.mincore_mapped is set to a non-zero value (and that's the default, btw), then only the current process' mappings of the pages in the specified virtual address range get examined.

but heads up: this does not preclude the system from returning MINCORE_REFERENCED_OTHER and MINCORE_MODIFIED_OTHER statuses. so don't be shocked when those show up anyway. πŸ™ˆ

otherwise, if the sysctl value is zero, then all resident pages backing the specified address range get examined β€” regardless of the mapping state. the whole neighborhood gets a vibe check. 🌈


πŸ‘‘ RETURN VALUES πŸ‘‘

the mincore() function returns the value 0 if successful. otherwise the value -1 is returned, and the global variable errno gets set to indicate the error.

0 = we ate. -1 = check errno, bestie. πŸ’€


πŸ”₯ ERRORS πŸ”₯

the mincore() system call will fail if:

  • [ENOMEM] β€” the virtual address range specified by the addr and len arguments is not fully mapped. you pointed at a hole, girl.
  • [EFAULT] β€” the vec argument points to an illegal address. that pointer is not it. 🚫

🌈 SEE ALSO 🌈

madvise(2), mlock(2), mprotect(2), msync(2), munmap(2), getpagesize(3)

the whole memory-management friend group honestly. go read them all, they're a package deal. 🫢


⭐ HISTORY ⭐

the mincore() system call first appeared in 4.4BSD. a true elder. she's been doing this since before you were born, respect her. πŸ‘‘


and that's the page!! tysm for reading, you're literally so good at Unix now. πŸ’–

this one came from the fine folks at Debian, dated January 7, 2019 β€” mwah, love that for them. πŸŽ€

πŸ“¦ where this page comes from