I am using get_user_pages
in a Linux kernel driver to pin memory for the purposes of [hardware] DMA. It all seems to work fine - but I am having a hard time proving that the "pinning" is doing the proper thing.
When I inspect the flags on the physical pages after doing get_user_pages
- the pages don't appear "locked" (as one might think they should be). In fact, I see no difference between the flags of otherwise "active" pages vs. those I have "pinned" via get_user_pages
.
The only difference I see is that get_user_pages has taken a refcount on the page. So I guess my question is - is holding this reference alone sufficient to guarantee that this page will never be swapped-out, moved, or that my user-space's vaddr will still/always reference the same underlying page?
All the driver source I can find seems to use this mechanism, and documentation seems to indicate that this is the correct way - but I am having a hard time "proving" that this will give me the correct, reliable, intended behavior.
Holding a refcount looks sufficient to prevent the page from being pushed out, invalidated or migrated; thus safe for dma-type operations. Migration is discussed in Documentation/vm/page_migrate; the others require spelunking in the vm code. The short version is that to push a page requires getting all of its references dropped.
Notice that refcount and mapcount are different notions -- mapcount just means somebody has a virtual reference to it; refcount means they have an actual reference to it. A swapped out page can have a large mapcount.
Also note that as of https://lkml.org/lkml/2019/11/25/684 there is a less obscure interface for this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With