__get_user_pages(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ __get_user_pages β€” the high-key iconic guide to pinning user pages in memory ✨

okay so bestie, you found the Linux kernel API manual page for __get_user_pages(9)?? literally the main character of memory pinning fr fr. this is a #LongHeader moment, let's get into it πŸ’…


🌸 NAME 🌸

__get_user_pages β€” pin user pages in memory (like, actually pin them, bestie πŸ’–)


✨ SYNOPSIS ✨

long __get_user_pages (struct mm_struct *mm , unsigned long start ,
       unsigned long nr_pages , unsigned int gup_flags , struct page **pages ,
       int *locked );

πŸŽ€ ARGUMENTS πŸŽ€

  • mm β€” the mm_struct of the target mm. like, whose memory are we even talking about? this is the vibes source 🫢
  • start β€” the starting user address. where the plot begins, no cap.
  • nr_pages β€” number of pages from start to pin. how many we're grabbing, periodt πŸ“
  • gup_flags β€” flags modifying pin behaviour. the ~spice~ of how it all goes down πŸ”₯
  • pages β€” array that receives pointers to the pages pinned. Should be at least nr_pages long. Or NULL, if caller only intends to ensure the pages are faulted in. (so like, the "receipts" array β€” fill it up, or pass NULL if you're just here for the fault-in vibes πŸ™ˆ)
  • locked β€” whether we're still with the mmap_lock held. honestly same, bestie, same.

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so here's the tea: this function Returns either the number of pages pinned (which may be less than the number requested), or an error. Details about the return value are literally giving:

  • If nr_pages is 0, returns 0.
  • If nr_pages is >0, but no pages were pinned, returns -errno.
  • If nr_pages is >0, and some pages were pinned, returns the number of pages pinned. Again, this may be less than nr_pages.
  • 0 return value is possible when the fault would need to be retried.

The caller is responsible for releasing returned pages, via put_page. yes bestie, you gotta clean up your own mess, we don't leave pins hanging πŸ’…

Must be called with mmap_lock held. It may be released. See below. (the plot thickens 😭)

__get_user_pages walks a process's page tables and takes a reference to each struct page that each user address corresponds to at a given instant. That is, it takes the page that would be accessed if a user thread accesses the given user virtual address at that instant. (so like, it's a little snapshot moment in time, iykyk ⭐)

This does not guarantee that the page exists in the user mappings when __get_user_pages returns, and there may even be a completely different page there in some cases (eg. if mmapped pagecache has been invalidated and subsequently re-faulted). However it does guarantee that the page won't be freed completely. And mostly callers simply care that the page contains data that was valid at some point in time. Typically, an IO or similar operation cannot guarantee anything stronger anyway because locks can't be held over the syscall boundary. (so like, it's giving "best effort", not "lifetime guarantee" πŸŽ€)

If gup_flags & FOLL_WRITE == 0, the page must not be written to. If the page is written to, set_page_dirty (or set_page_dirty_lock, as appropriate) must be called after the page is finished with, and before put_page is called. (read-only pin gang, stay in your lane, or like, call the right dirty function 🫢)

If FOLL_UNLOCKABLE is set without FOLL_NOWAIT then the mmap_lock may be released. If this happens *locked will be set to 0 on return. (the lock said "bye" and you gotta recognize πŸ‘‹)

A caller using such a combination of gup_flags must therefore hold the mmap_lock for reading only, and recognize when it's been released. Otherwise, it must be held for either reading or writing and will not be released. (like, either you're in the "might release" club or the "definitely holding" club β€” no in-between ✨)

In most cases, get_user_pages or get_user_pages_fast should be used instead of __get_user_pages. __get_user_pages should be used only if you need some special gup_flags. (ngl unless you're doing something ✨spicy✨, use the other ones, they're giving convenience 🌈)


πŸ‘‘ SEE ALSO πŸ‘‘

okay so if you liked this one (you didn't, but like, slay for reading it 🫢), here's the whole friend group you should also check out:


bestie if you're still here, you're a real one. this manpage is part of the Kernel API Manual and comes from the ./mm source, dated October 2026. go touch some pages (safely, with mmap_lock held 🫢). stay slay, stay pinned. πŸ’–

β€” written by your unix-obsessed bestie, for the group chat 🩷

πŸ“¦ where this page comes from