Reputation: 31
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
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
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