prosen
prosen

Reputation: 31

how to get to struct vm_area_struct from struct page

Basically, I need to identify the process or task using a page, and accordingly make some decisions regarding whether to allow the page to be swapped out or not. Because the swap module in kernel AFAIK deals with mostly struct page, I was wondering whether there is some existing trick that I am missing. From include/linux/mm_types.h (v >= 2.6), the following comment:

suggests we can do this via some physical-to-virtual reverse mappings, but I could not figure out from the rmap functions (in mm/rmap.c) how to achieve what I am looking for.

Thanks in advance for any help, much appreciated.

Upvotes: 3

Views: 3534

Answers (2)

Eric Wheeler
Eric Wheeler

Reputation: 11

Something like this is probably what you want.

This is the prototype:

// [ http://lxr.free-electrons.com/source/include/linux/rmap.h#L27 ]
149 struct anon_vma *page_get_anon_vma(struct page *page);

This is how you might use it: // [ http://lxr.free-electrons.com/source/mm/ksm.c#L1898 ] // [...]

        anon_vma = page_get_anon_vma(page);
1902    anon_vma_lock_read(anon_vma);
1903    anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
1904                                                0, ULONG_MAX) {
1906                         vma = vmac->vma;
1907                         if (page_address < vma->vm_start ||
1908                             page_address >= vma->vm_end)
1909                                 continue;
[...]   }
        anon_vma_unlock_read(anon_vma);

Upvotes: 1

mpe
mpe

Reputation: 2720

To answer your actual question "how to get to struct vm_area_struct from struct page", there are at least two answers.

For anonymous pages you can use page_anon_vma(), which returns an anon_vma - it's stored in page->mapping with a special flag set to indicate it's not a struct address_space (to save space).

From the anon_vma you can walk the anon_vma_chain and each entry points to a vma. From the vma you can get the mm and then a task.

See page_referenced_anon() for an example.

For a file page you look at page->mapping which is a struct address_space, and from there you walk the i_mmap which is a struct prio_tree_root. See page_referenced_file().

I'm not sure that's actually going to help you implement your idea, but there you go.

Upvotes: 2

Related Questions