• Andrea Arcangeli's avatar
    powerpc: get_hugepte() don't put_page() the wrong page · acafc792
    Andrea Arcangeli authored
    commit 405e44f2 upstream.
    
    "page" may have changed to point to the next hugepage after the loop
    completed, The references have been taken on the head page, so the
    put_page must happen there too.
    
    This is a longstanding issue pre-thp inclusion.
    
    It's totally unclear how these page_cache_add_speculative and
    pte_val(pte) != pte_val(*ptep) checks are necessary across all the
    powerpc gup_fast code, when x86 doesn't need any of that: there's no way
    the page can be freed with irq disabled so we're guaranteed the
    atomic_inc will happen on a page with page_count > 0 (so not needing the
    speculative check).
    
    The pte check is also meaningless on x86: no need to rollback on x86 if
    the pte changed, because the pte can still change a CPU tick after the
    check succeeded and it won't be rolled back in that case.  The important
    thing is we got a reference on a valid page that was mapped there a CPU
    tick ago.  So not knowing the soft tlb refill code of ppc64 in great
    detail I'm not removing the "speculative" page_count increase and the
    pte checks across all the code, but unless there's a strong reason for
    it they should be later cleaned up too.
    
    If a pte can change from huge to non-huge (like it could happen with
    THP) passing a pte_t *ptep to gup_hugepte() would also require to repeat
    the is_hugepd in gup_hugepte(), but that shouldn't happen with hugetlbfs
    only so I'm not altering that.
    Signed-off-by: default avatarAndrea Arcangeli <aarcange@redhat.com>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Hugh Dickins <hughd@google.com>
    Cc: Johannes Weiner <jweiner@redhat.com>
    Cc: Rik van Riel <riel@redhat.com>
    Cc: Mel Gorman <mgorman@suse.de>
    Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Acked-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    acafc792
hugetlbpage.c 13.1 KB