• David Hildenbrand's avatar
    selftests/vm: cow: add COW tests for collapsing of PTE-mapped anon THP · dee2ad12
    David Hildenbrand authored
    Currently, anonymous PTE-mapped THPs cannot be collapsed in-place:
    collapsing (e.g., via MADV_COLLAPSE) implies allocating a fresh THP and
    mapping that new THP via a PMD: as it's a fresh anon THP, it will get the
    exclusive flag set on the head page and everybody is happy.
    
    However, if the kernel would ever support in-place collapse of anonymous
    THPs (replacing a page table mapping each sub-page of a THP via PTEs with
    a single PMD mapping the complete THP), exclusivity information stored for
    each sub-page would have to be collapsed accordingly:
    
    (1) All PTEs map !exclusive anon sub-pages: the in-place collapsed THP
        must not not have the exclusive flag set on the head page mapped by
        the PMD. This is the easiest case to handle ("simply don't set any
        exclusive flags").
    
    (2) All PTEs map exclusive anon sub-pages: when collapsing, we have to
        clear the exclusive flag from all tail pages and only leave the
        exclusive flag set for the head page. Otherwise, fork() after
        collapse would not clear the exclusive flags from the tail pages
        and we'd be in trouble once PTE-mapping the shared THP when writing
        to shared tail pages that still have the exclusive flag set. This
        would effectively revert what the PTE-mapping code does when
        propagating the exclusive flag to all sub-pages.
    
    (3) PTEs map a mixture of exclusive and !exclusive anon sub-pages (can
        happen e.g., due to MADV_DONTFORK before fork()). We must not
        collapse the THP in-place, otherwise bad things may happen:
        the exclusive flags of sub-pages would get ignored and the
        exclusive flag of the head page would get used instead.
    
    Now that we have MADV_COLLAPSE in place to trigger collapsing a THP, let's
    add some test cases that would bail out early, if we'd
    voluntarily/accidantially unlock in-place collapse for anon THPs and
    forget about taking proper care of exclusive flags.
    
    Running the test on a kernel with MADV_COLLAPSE support:
      # [INFO] Anonymous THP tests
      # [RUN] Basic COW after fork() when collapsing before fork()
      ok 169 No leak from parent into child
      # [RUN] Basic COW after fork() when collapsing after fork() (fully shared)
      ok 170 # SKIP MADV_COLLAPSE failed: Invalid argument
      # [RUN] Basic COW after fork() when collapsing after fork() (lower shared)
      ok 171 No leak from parent into child
      # [RUN] Basic COW after fork() when collapsing after fork() (upper shared)
      ok 172 No leak from parent into child
    
    For now, MADV_COLLAPSE always seems to fail if all PTEs map shared
    sub-pages.
    
    Link: https://lkml.kernel.org/r/20230104144905.460075-1-david@redhat.comSigned-off-by: default avatarDavid Hildenbrand <david@redhat.com>
    Cc: Shuah Khan <shuah@kernel.org>
    Cc: Hugh Dickins <hughd@google.com>
    Cc: Peter Xu <peterx@redhat.com>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Cc: Nadav Amit <nadav.amit@gmail.com>
    Cc: Zach O'Keefe <zokeefe@google.com>
    Cc: Andrea Arcangeli <aarcange@redhat.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    dee2ad12
cow.c 42.1 KB