linux - 2 关于linux内核内存检查点的问题(自定义实现)

标签 linux linux-kernel c

我们得到了一个项目,我们在其中实现内存检查点(基本只是查看页面并将找到的数据转储到文件中(还检查有关页面的信息(私有(private),锁定等))和增量,这是我们只看的地方在如果数据先前更改并将其转储到文件中)。我对此的理解是,我们几乎是在构建一个较小规模的内存保存状态版本(我可能是错的,但这正是我从中得到的)。我们目前正在使用 VMA 方法来解决我们的问题以通过给定范围(只要它不低于或高于用户空间范围(这意味着没有内核范围或低于用户空间))以报告找到的数据从我们遇到的页面。我知道 vma_area_struct 用于访问 vma(一些函数包括 find_vma())。我的问题是我不确定我们如何通过使用此 vma_area_struct 检查此给定地址范围(用户给我们)内的各个页面。我只知道 struct page(差不多就是这些),但我仍在详细了解内核,所以我一定会错过一些东西。访问页面时我是否遗漏了有关 vma_area_sruct 的内容?

第二个问题是,我们使用什么来遍历找到的 vma 中的每个单独页面(从给定的开始和结束地址)?

最佳答案

VMA 包含它们的第一个和(在它们之后的)最后一个字节的虚拟地址:

struct vm_area_struct {
     /* The first cache line has the info for VMA tree walking. */

     unsigned long vm_start;         /* Our start address within vm_mm. */
     unsigned long vm_end;           /* The first byte after our end address
                                        within vm_mm. */
...

这意味着为了获取页面的数据,您需要首先弄清楚您的代码在什么上下文中运行?

如果它在进程上下文中,那么一个简单的 copy_from_user 方法可能就足以获取实际数据和一个页面遍历(通过整个 PGD/PUD/PMD/PTE)来获取PFN,然后将其转换为 struct page。 (注意不要使用诱人的virt_to_page(addr),因为这只适用于内核地址)。

就迭代而言,您只需迭代 PAGE_SIZEs,遍历从 VMA 获得的虚拟地址。

请注意,这假定页面实际上已映射。如果不是 (!pte_present(pte_t a)),您可能需要自己重新映射它才能访问数据。

如果您的检查在某些其他上下文(例如 kthread/中断)中运行,您必须在访问之前从交换中重新映射页面,这是完全不同的情况。如果您想要简单的方法,我会在这里查找:https://www.kernel.org/doc/gorman/html/understand/understand014.html了解如何处理交换查找/检索。

关于linux - 2 关于linux内核内存检查点的问题(自定义实现),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53102056/

相关文章:

c++ - C 设置环境变体

java - 打印出从 Java 接收到的字节到 C

java.awt.Robot - 屏幕截图需要多少时间

json - bash:遍历由索引选择的 JSON 数组的成员

linux - Linux中用户空间内存和内核空间内存如何映射到物理内存?

c++ - C/C++ 中的内存对齐

c++ - MsgPack c++ 打包长度超过 32 个字符的字符串[Ubuntu]

shell - 使用一个命令或 shell 程序将 NFS 文件夹安装到节点上

c - 如何在 Linux 上使用 Intel Westmere 1GB 页面?

c - 我如何搜索 argv 是否以 char 结尾