• Hugh Dickins's avatar
    memfd: fix F_SEAL_WRITE after shmem huge page allocated · f2b277c4
    Hugh Dickins authored
    Wangyong reports: after enabling tmpfs filesystem to support transparent
    hugepage with the following command:
    
      echo always > /sys/kernel/mm/transparent_hugepage/shmem_enabled
    
    the docker program tries to add F_SEAL_WRITE through the following
    command, but it fails unexpectedly with errno EBUSY:
    
      fcntl(5, F_ADD_SEALS, F_SEAL_WRITE) = -1.
    
    That is because memfd_tag_pins() and memfd_wait_for_pins() were never
    updated for shmem huge pages: checking page_mapcount() against
    page_count() is hopeless on THP subpages - they need to check
    total_mapcount() against page_count() on THP heads only.
    
    Make memfd_tag_pins() (compared > 1) as strict as memfd_wait_for_pins()
    (compared != 1): either can be justified, but given the non-atomic
    total_mapcount() calculation, it is better now to be strict.  Bear in
    mind that total_mapcount() itself scans all of the THP subpages, when
    choosing to take an XA_CHECK_SCHED latency break.
    
    Also fix the unlikely xa_is_value() case in memfd_wait_for_pins(): if a
    page has been swapped out since memfd_tag_pins(), then its refcount must
    have fallen, and so it can safely be untagged.
    
    Link: https://lkml.kernel.org/r/a4f79248-df75-2c8c-3df-ba3317ccb5da@google.comSigned-off-by: default avatarHugh Dickins <hughd@google.com>
    Reported-by: default avatarZeal Robot <zealci@zte.com.cn>
    Reported-by: default avatarwangyong <wang.yong12@zte.com.cn>
    Cc: Mike Kravetz <mike.kravetz@oracle.com>
    Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
    Cc: CGEL ZTE <cgel.zte@gmail.com>
    Cc: Kirill A. Shutemov <kirill@shutemov.name>
    Cc: Song Liu <songliubraving@fb.com>
    Cc: Yang Yang <yang.yang29@zte.com.cn>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    f2b277c4
memfd.c 8.23 KB