• Hugh Dickins's avatar
    SHM_UNLOCK: fix Unevictable pages stranded after swap · 4556a6d9
    Hugh Dickins authored
    commit 24513264 upstream.
    
    Commit cc39c6a9 ("mm: account skipped entries to avoid looping in
    find_get_pages") correctly fixed an infinite loop; but left a problem
    that find_get_pages() on shmem would return 0 (appearing to callers to
    mean end of tree) when it meets a run of nr_pages swap entries.
    
    The only uses of find_get_pages() on shmem are via pagevec_lookup(),
    called from invalidate_mapping_pages(), and from shmctl SHM_UNLOCK's
    scan_mapping_unevictable_pages().  The first is already commented, and
    not worth worrying about; but the second can leave pages on the
    Unevictable list after an unusual sequence of swapping and locking.
    
    Fix that by using shmem_find_get_pages_and_swap() (then ignoring the
    swap) instead of pagevec_lookup().
    
    But I don't want to contaminate vmscan.c with shmem internals, nor
    shmem.c with LRU locking.  So move scan_mapping_unevictable_pages() into
    shmem.c, renaming it shmem_unlock_mapping();...
    4556a6d9
shmem.c 64.5 KB