有没有办法检查指定进程是否使用了相关页面?
即我有一个指向struct page
和struct task_struct
的指针,我想获得一个布尔值,表示该页面是否在进程的VMA中。目前我坚持在进程的VMA中获取页面的虚拟地址。如果我得到它,我将能够遍历pgd
并查看它是否存在。
我已尝试在vma_address()
(mm/rmap.c
)中采用该方法,但在循环任务mm_struct->mmap
时,虚拟地址对于每个vm_area_struct
来说似乎不同列表。这与find_vma()
(在'mm / mmap.c`中)相矛盾,它使用作为参数提供的固定地址扫描任务的VMA(尽管搜索相应的rb-tree)。
那么,做这些事情的正确方法是什么?
答案 0 :(得分:2)
事实证明,只有这样才能扫描整个VMA跳跃PAGE_SIZE
,如下所示:
struct page *page_by_address(const struct mm_struct *const mm,
const unsigned long address)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
struct page *page = NULL;
pgd = pgd_offset(mm, address);
if (!pgd_present(*pgd))
goto do_return;
pud = pud_offset(pgd, address);
if (!pud_present(*pud))
goto do_return;
pmd = pmd_offset(pud, address);
if (!pmd_present(*pmd))
goto do_return;
pte = pte_offset_kernel(pmd, address);
if (!pte_present(*pte))
goto do_return;
page = pte_page(*pte);
do_return:
return page;
}
int contains_page(const struct mm_struct *const mm, struct page *const page)
{
int contains = 0;
if (mm != NULL) {
const struct vm_area_struct *vma = mm->mmap;
while (vma != NULL) {
unsigned long address;
for (address = vma->vm_start; !contains && address < vma->vm_end; address += PAGE_SIZE) {
contains = (page_by_address(mm, address) == page);
}
vma = vma->vm_next;
}
}
return contains;
}
答案 1 :(得分:0)
for vma in task_struct:
call page_address_in_vma(page, vma)