• Zhang Yi's avatar
    futex: Take hugepages into account when generating futex_key · ab1842f1
    Zhang Yi authored
    commit 13d60f4b upstream.
    
    The futex_keys of process shared futexes are generated from the page
    offset, the mapping host and the mapping index of the futex user space
    address. This should result in an unique identifier for each futex.
    
    Though this is not true when futexes are located in different subpages
    of an hugepage. The reason is, that the mapping index for all those
    futexes evaluates to the index of the base page of the hugetlbfs
    mapping. So a futex at offset 0 of the hugepage mapping and another
    one at offset PAGE_SIZE of the same hugepage mapping have identical
    futex_keys. This happens because the futex code blindly uses
    page->index.
    
    Steps to reproduce the bug:
    
    1. Map a file from hugetlbfs. Initialize pthread_mutex1 at offset 0
       and pthread_mutex2 at offset PAGE_SIZE of the hugetlbfs
       mapping.
    
       The mutexes must be initialized as PTHREAD_PROCESS_SHARED because
       PTHREAD_PROCESS_PRIVATE mutexes are not affected by this issue as
       their keys solely depend on the user space address.
    
    2. Lock mutex1 and mutex2
    
    3. Create thread1 and in the thread function lock mutex1, which
       results in thread1 blocking on the locked mutex1.
    
    4. Create thread2 and in the thread function lock mutex2, which
       results in thread2 blocking on the locked mutex2.
    
    5. Unlock mutex2. Despite the fact that mutex2 got unlocked, thread2
       still blocks on mutex2 because the futex_key points to mutex1.
    
    To solve this issue we need to take the normal page index of the page
    which contains the futex into account, if the futex is in an hugetlbfs
    mapping. In other words, we calculate the normal page mapping index of
    the subpage in the hugetlbfs mapping.
    
    Mappings which are not based on hugetlbfs are not affected and still
    use page->index.
    
    Thanks to Mel Gorman who provided a patch for adding proper evaluation
    functions to the hugetlbfs code to avoid exposing hugetlbfs specific
    details to the futex code.
    
    [ tglx: Massaged changelog ]
    Signed-off-by: default avatarZhang Yi <zhang.yi20@zte.com.cn>
    Reviewed-by: default avatarJiang Biao <jiang.biao2@zte.com.cn>
    Tested-by: default avatarMa Chenggong <ma.chenggong@zte.com.cn>
    Reviewed-by: default avatar'Mel Gorman' <mgorman@suse.de>
    Acked-by: default avatar'Darren Hart' <dvhart@linux.intel.com>
    Cc: 'Peter Zijlstra' <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/000101ce71a6%24a83c5880%24f8b50980%24@comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    ab1842f1
hugetlb.c 83.8 KB