UFFDIO_MOVE(2const)

πŸ’… UFFDIO_MOVE β€” the manual page, but make it cute

okay bestie, so this is UFFDIO_MOVE(2const), a Linux thing, and it lives in the Standard C library (libc, -lc). yeah, the const page of a userfaultfd ioctl. iconic. let's go πŸ¦‹


✨ NAME ✨

UFFDIO_MOVE β€” move a continuous memory chunk straight into the userfault-registered range, atomically, no drama, no half-moves πŸ’«


πŸ“š LIBRARY πŸ“š

Standard C library (libc, -lc). the usual ride-or-die.


🌸 SYNOPSIS 🌸

like, here's the whole vibe:

#include <linux/userfaultfd.h>  /* Definition of UFFD* constants */
#include <sys/ioctl.h>

int ioctl(int fd, UFFDIO_MOVE, struct uffdio_move *argp);

#include <linux/userfaultfd.h>

struct uffdio_move {
    __u64  dst;   /* Destination of move */
    __u64  src;   /* Source of move */
    __u64  len;   /* Number of bytes to move */
    __u64  mode;  /* Flags controlling behavior of move */
    __s64  move;  /* Number of bytes moved, or negated error */
};

she's serving struct, your honor πŸŽ€


πŸ‘‘ DESCRIPTION πŸ‘‘

so the whole point: you atomically move a continuous memory chunk into the userfault-registered range, and you optionally wake up the thread that's been sitting there blocked. slay πŸ’…

you can bitwise OR the following value into .mode to change how the UFFDIO_MOVE operation behaves:

  • UFFDIO_MOVE_MODE_DONTWAKE β€” do not wake up the thread that's waiting for page-fault resolution. let her sleep, it's fine 😴
  • UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES β€” allow holes in the source virtual range that's being moved. if you don't set this, holes give you an ENOENT error. if you do set it, the holes get accounted as successfully moved memory. it's mostly useful when you're moving hugepage-aligned virtual regions and you have zero clue whether there are transparent hugepages chilling in those regions or not β€” and it saves you from the risk of having to split the hugepage mid-operation. lowkey a glow-up for hugepage girlies πŸ”₯

and .move? the kernel uses that field to hand you back the number of bytes that were actually moved, or an error (a negated errno-style value, so like, negative vibes). note: .move is output-only β€” the UFFDIO_MOVE operation does not read it. she speaks, she does not listen πŸ’€


⭐ RETURN VALUE ⭐

  • on success, 0 is returned β€” and in that case the entire area was moved. periodt 🫢
  • on error, -1 is returned and errno is set to tell you which error it is. rip.

😭 ERRORS 😭

  • EAGAIN β€” the number of bytes moved (i.e. the value returned in the .move field) does not equal the value you specified in the .len field. mismatch energy, we hate to see it.
  • EINVAL β€” either .dst or .len was not a multiple of the system page size, or the range specified by .src and .len, or by .dst and .len, was invalid.
  • EINVAL β€” an invalid bit was specified in the .mode field. (yes, EINVAL again. she contains multitudes πŸ’…)
  • ENOENT β€” the source virtual memory range has unmapped holes and UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES is not set.
  • EEXIST β€” the destination virtual memory range is fully or partially mapped. occupied bestie, move along πŸ™ˆ
  • EBUSY β€” the pages in the source virtual memory range are either pinned or not exclusive to the process. once KSM deduplicates pages, or fork(2) COW-shares pages during fork(2) with child processes, they're no longer exclusive. also, the kernel might only perform lightweight checks for detecting whether the pages are exclusive. so to make the operation more likely to succeed: KSM should be disabled, fork(2) should be avoided, or MADV_DONTFORK should be configured for the source virtual memory area before fork(2). plan ahead, queen 🧚
  • ENOMEM β€” allocating the memory needed for the operation failed. no memory, no move 😭
  • ESRCH β€” the target process has exited at the time of a UFFDIO_MOVE operation. she's gone, bestie πŸ’€

🌈 STANDARDS 🌈

Linux. that's it. that's the standard.


πŸ•°οΈ HISTORY πŸ•°οΈ

Linux 6.8. a modern icon, honestly.


πŸŽ€ SEE ALSO πŸŽ€


ngl the .move field being output-only is the kind of boundary-setting we should all be doing. anyway πŸ’–

and that's the whole page, bestie β€” brought to you by Linux man-pages 6.20, dated 2025-05-17, and lovingly retold by me. go move some memory, but like, atomically βœ¨πŸ¦‹πŸŒΈ

πŸ“¦ 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
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms