C “怎么做?”;钉住;Linux中的页面本身(或实际上是“pin”)

C “怎么做?”;钉住;Linux中的页面本身(或实际上是“pin”),c,memory-management,linux-kernel,linux-device-driver,C,Memory Management,Linux Kernel,Linux Device Driver,我在Linux内核驱动程序中使用get\u user\u pages来固定内存,以实现[硬件]DMA。这一切似乎都很好——但我很难证明“钉住”是正确的 当我在执行get\u user\u pages之后检查物理页面上的标志时,页面不会显示为“锁定”(人们可能认为它们应该是锁定的)。事实上,我看不出其他“活动”页面的标志与我通过get\u user\u页面锁定的页面的标志之间有什么区别 我看到的唯一区别是get_user_页面在页面上进行了refcount。因此,我想我的问题是——仅保留此引用是否

我在Linux内核驱动程序中使用
get\u user\u pages
来固定内存,以实现[硬件]DMA。这一切似乎都很好——但我很难证明“钉住”是正确的

当我在执行
get\u user\u pages
之后检查物理页面上的标志时,页面不会显示为“锁定”(人们可能认为它们应该是锁定的)。事实上,我看不出其他“活动”页面的标志与我通过
get\u user\u页面
锁定的页面的标志之间有什么区别

我看到的唯一区别是get_user_页面在页面上进行了refcount。因此,我想我的问题是——仅保留此引用是否足以保证此页面永远不会被交换、移动,或者我的用户空间的vaddr仍然/始终引用相同的底层页面


我能找到的所有驱动程序源似乎都使用了这种机制,文档似乎表明这是正确的方法-但我很难“证明”这将为我提供正确、可靠的预期行为。

持有refcount看起来足以防止页面被推出、失效或迁移;因此,dma类型的操作是安全的。迁移在Documentation/vm/page_migrate中讨论;其他的则需要在vm代码中进行探索。简短的版本是,推送页面需要删除其所有引用

请注意,refcount和mapcount是不同的概念——mapcount只是意味着有人对它有一个虚拟引用;refcount意味着它们有一个对它的实际引用。调出的页面可能具有较大的映射数


还要注意的是,到目前为止,还有一个不那么晦涩的界面。

Hi@mevets,这是否意味着用户进程中的常规RAM在结构页面上从不进行引用计数;参考计数!=0表示此页上有挂起的操作,因此您只能更新某些部分。阅读pte是没有用的,它只是存储在页面结构中的信息的投影。我试图编辑一张物理内存、页面、VNode和映射之间关系的图表。我帮了大家一个忙,把它删掉了。在常规RAM的程序概念和内核中的实现之间存在着无数的抽象。如果你改变主意,请随时发布该图。对于像我这样的乔·施莫斯来说,任何一点额外的信息都会有很大帮助