• Peter Xu's avatar
    mm/thp: Split huge pmds/puds if they're pinned when fork() · d042035e
    Peter Xu authored
    Pinned pages shouldn't be write-protected when fork() happens, because
    follow up copy-on-write on these pages could cause the pinned pages to
    be replaced by random newly allocated pages.
    
    For huge PMDs, we split the huge pmd if pinning is detected.  So that
    future handling will be done by the PTE level (with our latest changes,
    each of the small pages will be copied).  We can achieve this by let
    copy_huge_pmd() return -EAGAIN for pinned pages, so that we'll
    fallthrough in copy_pmd_range() and finally land the next
    copy_pte_range() call.
    
    Huge PUDs will be even more special - so far it does not support
    anonymous pages.  But it can actually be done the same as the huge PMDs
    even if the split huge PUDs means to erase the PUD entries.  It'll
    guarantee the follow up fault ins will remap the same pages in either
    parent/child later.
    
    This might not be the most efficient way, but it should be easy and
    clean enough.  It should be fine, since we're tackling with a very rare
    case just to make sure userspaces that pinned some thps will still work
    even without MADV_DONTFORK and after they fork()ed.
    Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d042035e
huge_memory.c 82 KB