• Andrea Arcangeli's avatar
    userfaultfd: remap_pages: rmap preparation · 0242f35e
    Andrea Arcangeli authored
    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.
    0242f35e
huge_memory.c 80.1 KB