检查页面是否在任务的VMA中

时间:2011-12-13 12:22:32

标签: linux memory-management linux-kernel kernel

有没有办法检查指定进程是否使用了相关页面? 即我有一个指向struct pagestruct task_struct的指针,我想获得一个布尔值,表示该页面是否在进程的VMA中。目前我坚持在进程的VMA中获取页面的虚拟地址。如果我得到它,我将能够遍历pgd并查看它是否存在。

我已尝试在vma_address()mm/rmap.c)中采用该方法,但在循环任务mm_struct->mmap时,虚拟地址对于每个vm_area_struct来说似乎不同列表。这与find_vma()(在'mm / mmap.c`中)相矛盾,它使用作为参数提供的固定地址扫描任务的VMA(尽管搜索相应的rb-tree)。

那么,做这些事情的正确方法是什么?

2 个答案:

答案 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)

Refer to this link