• Kirill A. Shutemov's avatar
    mm, thp: fix mlocking THP page with migration enabled · e125fe40
    Kirill A. Shutemov authored
    A transparent huge page is represented by a single entry on an LRU list.
    Therefore, we can only make unevictable an entire compound page, not
    individual subpages.
    
    If a user tries to mlock() part of a huge page, we want the rest of the
    page to be reclaimable.
    
    We handle this by keeping PTE-mapped huge pages on normal LRU lists: the
    PMD on border of VM_LOCKED VMA will be split into PTE table.
    
    Introduction of THP migration breaks[1] the rules around mlocking THP
    pages.  If we had a single PMD mapping of the page in mlocked VMA, the
    page will get mlocked, regardless of PTE mappings of the page.
    
    For tmpfs/shmem it's easy to fix by checking PageDoubleMap() in
    remove_migration_pmd().
    
    Anon THP pages can only be shared between processes via fork().  Mlocked
    page can only be shared if parent mlocked it before forking, otherwise CoW
    will be triggered on mlock().
    
    For Anon-THP, we can fix the issue by munlocking the page on removing PTE
    migration entry for the page.  PTEs for the page will always come after
    mlocked PMD: rmap walks VMAs from oldest to newest.
    
    Test-case:
    
    	#include <unistd.h>
    	#include <sys/mman.h>
    	#include <sys/wait.h>
    	#include <linux/mempolicy.h>
    	#include <numaif.h>
    
    	int main(void)
    	{
    	        unsigned long nodemask = 4;
    	        void *addr;
    
    		addr = mmap((void *)0x20000000UL, 2UL << 20, PROT_READ | PROT_WRITE,
    			MAP_PRIVATE | MAP_ANONYMOUS | MAP_LOCKED, -1, 0);
    
    	        if (fork()) {
    			wait(NULL);
    			return 0;
    	        }
    
    	        mlock(addr, 4UL << 10);
    	        mbind(addr, 2UL << 20, MPOL_PREFERRED | MPOL_F_RELATIVE_NODES,
    	                &nodemask, 4, MPOL_MF_MOVE);
    
    	        return 0;
    	}
    
    [1] https://lkml.kernel.org/r/CAOMGZ=G52R-30rZvhGxEbkTw7rLLwBGadVYeo--iizcD3upL3A@mail.gmail.com
    
    Link: http://lkml.kernel.org/r/20180917133816.43995-1-kirill.shutemov@linux.intel.com
    Fixes: 616b8371 ("mm: thp: enable thp migration in generic path")
    Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
    Reported-by: default avatarVegard Nossum <vegard.nossum@oracle.com>
    Reviewed-by: default avatarZi Yan <zi.yan@cs.rutgers.edu>
    Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Cc: Andrea Arcangeli <aarcange@redhat.com>
    Cc: <stable@vger.kernel.org>	[4.14+]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    e125fe40
huge_memory.c 81 KB