get_mempolicy(2)

๐Ÿ’– get_mempolicy(2) โ€” the System Calls Manual page, bestie edition ๐Ÿ’–

okay so you opened get_mempolicy(2) from the System Calls Manual and you want the tea? say less. this is the little syscall that peeks at your NUMA memory policy and tells you what's up. let's go ๐Ÿฆ‹


โœจ NAME โœจ

get_mempolicy โ€” retrieve NUMA memory policy for a thread

๐Ÿ“š LIBRARY ๐Ÿ“š

NUMA (Non-Uniform Memory Access) policy library โ€” that's libnuma, and you link it with -lnuma. ๐Ÿ’…

๐ŸŒธ SYNOPSIS ๐ŸŒธ

#include <numaif.h>

long get_mempolicy(unsigned long maxnode;
                   int *mode,
                   unsigned long nodemask[(maxnode + ULONG_WIDTH - 1)
                                          / ULONG_WIDTH],
                   unsigned long maxnode, void *addr,
                   unsigned long flags);

(yes bestie, that first line really does say unsigned long maxnode; โ€” that's the page, we don't edit the page, we respect the page ๐Ÿซถ)

๐Ÿ‘‘ DESCRIPTION ๐Ÿ‘‘

get_mempolicy() pulls up the NUMA policy โ€” either the one for the calling thread or the one for a memory address โ€” and which one you get depends entirely on how you set flags. main character decision energy tbh.

so real talk: a NUMA machine has a bunch of different memory controllers, and each one sits at a different distance from specific CPUs. the memory policy is literally what decides which node your memory gets allocated from for the thread. that's the whole vibe.

If flags is specified as 0, then info about the calling thread's default policy comes back (the one set by set_mempolicy(2)), and it lands in the buffers that mode and nodemask point at. here's the slay part: whatever you get back in those arguments can be used to restore the thread's policy to exactly what it was at the moment of the get_mempolicy() call, using set_mempolicy(2). time machine but for memory policy โœจ. and when flags is 0, addr must be specified as NULL. no exceptions.

If flags specifies MPOL_F_MEMS_ALLOWED (available since Linux 2.6.24), the mode argument gets ignored entirely โ€” rude but true โ€” and instead you get back in nodemask the set of nodes (memories) that the thread is allowed to specify in later calls to mbind(2) or set_mempolicy(2) (in the absence of any mode flags). โš ๏ธ heads up: it is not permitted to combine MPOL_F_MEMS_ALLOWED with either MPOL_F_ADDR or MPOL_F_NODE. that combo is giving illegal, don't do it.

If flags specifies MPOL_F_ADDR, then you get info about the policy governing the memory address you passed in addr. and lowkey this policy can be different from the thread's default policy โ€” that happens if mbind(2) or one of the helper functions described in numa(3) was used to establish a policy for the memory range that contains addr. plot twist, but a legal one.

If the mode argument is not NULL, then get_mempolicy() stores the policy mode and any optional mode flags of the requested NUMA policy into the location that mode points to. if nodemask is not NULL, then the nodemask associated with the policy gets stored at the location nodemask points to. maxnode specifies the number of node IDs that can be stored into nodemask โ€” that is, the maximum node ID plus one. and the value you give for maxnode is always rounded to a multiple of sizeof(unsigned long)*8. always. ๐Ÿ’ฏ

If flags specifies both MPOL_F_NODE and MPOL_F_ADDR, get_mempolicy() returns the node ID of the node on which the address addr is allocated, straight into the location pointed to by mode. and if no page has even been allocated for that address yet? ๐Ÿ˜ญ it will allocate a page as if the thread had performed a read (load) access to that address, and then return the ID of the node where that page ended up. so yes, it can make memory happen. obsessed.

If flags specifies MPOL_F_NODE but not MPOL_F_ADDR, and the thread's current policy is MPOL_INTERLEAVE or MPOL_WEIGHTED_INTERLEAVE, then get_mempolicy() returns โ€” in the location pointed to by a non-NULL mode argument โ€” the node ID of the next node that will be used for interleaving of internal kernel pages allocated on behalf of the thread. and which allocations count, you ask? these ones:

  • pages for memory-mapped files in process memory ranges mapped using the mmap(2) call with the MAP_PRIVATE flag, for read accesses
  • memory ranges mapped with the MAP_SHARED flag, for all accesses

Other flag values are reserved. don't get creative. ๐Ÿ™ˆ

For an overview of the possible policies, go see set_mempolicy(2). ๐Ÿ“–

๐ŸŒˆ RETURN VALUE ๐ŸŒˆ

On success, get_mempolicy() returns 0. on error, -1 is returned and errno is set to indicate the error. the classic duo, iconic, no notes.

๐Ÿ’€ ERRORS ๐Ÿ’€

  • EFAULT โ€” part of all of the memory range specified by nodemask and maxnode points outside your accessible address space. bestie that memory is not yours, hands off.
  • EINVAL โ€” ooh okay this one has range, buckle up:
    • the value specified by maxnode is less than the number of node IDs supported by the system.
    • or flags specified values other than MPOL_F_NODE or MPOL_F_ADDR.
    • or flags specified MPOL_F_ADDR and addr is NULL.
    • or flags did not specify MPOL_F_ADDR and addr is not NULL.
    • or, flags specified MPOL_F_NODE but not MPOL_F_ADDR and the current thread policy is neither MPOL_INTERLEAVE nor MPOL_WEIGHTED_INTERLEAVE.
    • or, flags specified MPOL_F_MEMS_ALLOWED with either MPOL_F_ADDR or MPOL_F_NODE.
    • (And there are other EINVAL cases.) and that's the truth, the page said it, not me ๐Ÿคทโ€โ™€๏ธ

๐ŸŽ€ STANDARDS ๐ŸŽ€

Linux. just Linux. periodt.

๐Ÿฆ‹ HISTORY ๐Ÿฆ‹

Linux 2.6.7. ancient in the best way, a real vintage icon.

โญ NOTES โญ

For information on library support, go check out numa(7). ๐Ÿ’œ

๐Ÿ”ฅ SEE ALSO ๐Ÿ”ฅ

getcpu(2), mbind(2), mmap(2), set_mempolicy(2), numa(3), numa(7), numactl(8)


and that's the whole page, bestie ๐Ÿ’– this was Linux man-pages 6.20, dated 2026-02-08 โ€” go forth and interrogate your memory policies with confidence, you absolute NUMA queen ๐Ÿ‘‘๐ŸŒธ

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft-var
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms