如何找到给定地址的准备工作?

时间:2012-03-09 19:46:27

标签: linux memory linux-kernel

我正在尝试编写一个函数,对给定pte中的每个vm_area_struct进行写保护。为给定地址提供ptep的函数是什么?我有:

pte_t *ptep;
for (addr = start; addr < end; addr += PAGE_SIZE) {
    ptep = WHATS_THIS_FUNCTION_CALLED(addr);
    ptep_set_wrprotect(mm, addr, ptep);
}

WHATS_THIS_FUNCTION_CALLED叫什么?

2 个答案:

答案 0 :(得分:1)

您的问题的简短回答是使用__get_locked_pte。但是,我建议反对它,因为有更好的(在资源争用方面有效和公平)方法来实现你的目标。

在linux中,遍历页表的典型习惯是嵌套for循环四层深(四是linux支持的页表级数)。有关示例,请参阅copy_page_rangeapply_to_page_range in mm/memory.c。实际上,如果仔细查看copy_page_range,就会在kernel / fork.c中从dup_mmap分叉时调用它。它基本上在整个vm_area_struct上运行。

您可以复制其中任何一个函数中使用的习语。但是,有一些警告。例如,copy_page_range通过在copy_huge_pmd内使用完全独立的copy_pmd_range来完全支持透明大页(2.6.38)。除非您想要编写两个单独的函数(一个用于普通页面,一个用于透明大页面,请参阅Gracefull fallback中的Documentation/vm/transhuge.txt

关键是linux中的虚拟内存非常复杂,所以一定要完全理解每个可能的用例。 mm/memory.c中的follow_page应该证明如何涵盖所有基础。

答案 1 :(得分:0)

我相信您正在寻找定义here的函数virt_to_pte或您自己重新实现它。

此函数使用pte_offset_kernel(pmd_t * dir, unsigned long address),它采用pmd(页面中级目录)结构和地址,但也可以使用pte_offset(pmd_t * dir, unsigned long address)

有关详细信息,请参阅Linux Device Drivers 3rd Edition Chapter 15Linux Device Drivers, 2nd Edition Chapter 13 mmap and DMA