userfaultfd: remap_pages: rmap preparation
As far as the rmap code is concerned, rmap_pages only alters the page->mapping and page->index. It does it while holding the page lock. However there are a few places that in presence of anon pages are allowed to do rmap walks without the page lock (split_huge_page and page_referenced_anon). Those places that are doing rmap walks without taking the page lock first, must be updated to re-check that the page->mapping didn't change after they obtained the anon_vma lock. remap_pages takes the anon_vma lock for writing before altering the page->mapping, so if the page->mapping is still the same after obtaining the anon_vma lock (without the page lock), the rmap walks can go ahead safely (and remap_pages will wait them to complete before proceeding). remap_pages serializes against itself with the page lock. All other places taking the anon_vma lock while holding the mmap_sem for writing, don't need to check if the page->mapping has changed after taking the anon_vma lock, regardless of the page lock, because remap_pages holds the mmap_sem for reading. There's one constraint enforced to allow this simplification: the source pages passed to remap_pages must be mapped only in one vma, but this is not a limitation when used to handle userland page faults. The source addresses passed to remap_pages should be set as VM_DONTCOPY with MADV_DONTFORK to avoid any risk of the mapcount of the pages increasing, if fork runs in parallel in another thread, before or while remap_pages runs.
Showing
Please register or sign in to comment