Skip to content
  • Collin Fijalkovich's avatar
    mm, thp: relax the VM_DENYWRITE constraint on file-backed THPs · eb6ecbed
    Collin Fijalkovich authored
    Transparent huge pages are supported for read-only non-shmem files, but
    are only used for vmas with VM_DENYWRITE.  This condition ensures that
    file THPs are protected from writes while an application is running
    (ETXTBSY).  Any existing file THPs are then dropped from the page cache
    when a file is opened for write in do_dentry_open().  Since sys_mmap
    ignores MAP_DENYWRITE, this constrains the use of file THPs to vmas
    produced by execve().
    
    Systems that make heavy use of shared libraries (e.g.  Android) are unable
    to apply VM_DENYWRITE through the dynamic linker, preventing them from
    benefiting from the resultant reduced contention on the TLB.
    
    This patch reduces the constraint on file THPs allowing use with any
    executable mapping from a file not opened for write (see
    inode_is_open_for_write()).  It also introduces additional conditions to
    ensure that files opened for write will never be backed by file THPs.
    
    Restricting the use of THPs to executable mappings eliminates the risk
    that a read-only file later opened for write would encounter significant
    latencies due to page cache truncation.
    
    The ld linker flag '-z max-page-size=(hugepage size)' can be used to
    produce executables with the necessary layout.  The dynamic linker must
    map these file's segments at a hugepage size aligned vma for the mapping
    to be backed with THPs.
    
    Comparison of the performance characteristics of 4KB and 2MB-backed
    libraries follows; the Android dex2oat tool was used to AOT compile an
    example application on a single ARM core.
    
    4KB Pages:
    ==========
    
    count              event_name            # count / runtime
    598,995,035,942    cpu-cycles            # 1.800861 GHz
     81,195,620,851    raw-stall-frontend    # 244.112 M/sec
    347,754,466,597    iTLB-loads            # 1.046 G/sec
      2,970,248,900    iTLB-load-misses      # 0.854122% miss rate
    
    Total test time: 332.854998 seconds.
    
    2MB Pages:
    ==========
    
    count              event_name            # count / runtime
    592,872,663,047    cpu-cycles            # 1.800358 GHz
     76,485,624,143    raw-stall-frontend    # 232.261 M/sec
    350,478,413,710    iTLB-loads            # 1.064 G/sec
        803,233,322    iTLB-load-misses      # 0.229182% miss rate
    
    Total test time: 329.826087 seconds
    
    A check of /proc/$(pidof dex2oat64)/smaps shows THPs in use:
    
    /apex/com.android.art/lib64/libart.so
    FilePmdMapped:      4096 kB
    
    /apex/com.android.art/lib64/libart-compiler.so
    FilePmdMapped:      2048 kB
    
    Link: https://lkml.kernel.org/r/20210406000930.3455850-1-cfijalkovich@google.com
    
    
    Signed-off-by: default avatarCollin Fijalkovich <cfijalkovich@google.com>
    Acked-by: default avatarHugh Dickins <hughd@google.com>
    Reviewed-by: default avatarWilliam Kucharski <william.kucharski@oracle.com>
    Acked-by: default avatarSong Liu <song@kernel.org>
    Cc: Suren Baghdasaryan <surenb@google.com>
    Cc: Hridya Valsaraju <hridya@google.com>
    Cc: Kalesh Singh <kaleshsingh@google.com>
    Cc: Tim Murray <timmurray@google.com>
    Cc: Matthew Wilcox <willy@infradead.org>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    eb6ecbed