How to unmap struct page from all PTEs mapping it
Asked Answered
A

0

3

I want to be able to remove a page from page cache so that next access to this page (by any process) will trigger a page fault. I'm doing this from the kernel, and I have a pointer to struct page I wish to remove. Deleting from page cache is easy (done by __delete_from_page_cache()), but I don't know how to "unmap" this page from all processes mapping it into their VMAs. I tried using try_to_unmap(my_page, cpu_page, TTU_UNMAP|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS) from rmap.c but it doesn't seem to do what I want it to. Any help is highly appreciated. Thank you!

Astrahan answered 17/4, 2018 at 20:47 Comment(6)
Shouldn't you call delete_from_page_cache instead of __delete_from_page_cache to get the lock on the page tree? I suppose try_to_unmap is returning false then, right? Which Linux kernel version are you using?Kellner
Hi Hadi. Thank you for your advise. You might be right about using delete_from_page_cache() and not __delete_from_page_cache(), I will look into it. I don't think it will solve my problem though since the page is deleted from cache (at the end of the run I try to delete it again and get a warning it is not there). try_to_unmap() doesn't fail but I when after calling it and trying to access same page from other process mapping it, I don't get a page fault. I'm using ubuntu with linux 4.4.15 which I modified.Astrahan
It doesn't seem to me that these functions are the right entry points because they don't acquire the page lock. I think that something similar to shrink_page_list needs to be done. The major steps are the following. First a lock is acquired on the page descriptor by calling trylock_page (which is absolutely critical for correctness)...Kellner
...Second, try_to_unmap is called to unmap the page from address spaces (you can pass these flags though TTU_UNMAP | TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS). Different things need to be done depending on the result of that operation. Then, assuming the result was SWAP_SUCCESS, if the page is dirty, flush the TLBs of all cores, and write it back if required. Finally, the page is removed from the swap cache. The closest that I could find for removing pages from the page cache is invalidate_mapping_pages, which removes a range of pages, not just one...Kellner
...But the important part is calling invalidate_inode_page in a critical section guarded by the page lock. It is this function that eventually calls __delete_from_page_cache. However, it does not handle cases where the page is dirty, locked, under writeback or mapped into pagetables. So have to handle these cases similar to what's done in shrink_page_list. For example, you have to call try_to_unmap before attempting to remove the page from the cache.Kellner
thank you very much for the detailed reply!!! I will try to follow your advise and see if it works.Astrahan

© 2022 - 2024 — McMap. All rights reserved.