lkml.org 
[lkml]   [2011]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[189/262] s390: gup_huge_pmd() support THP tail recounting
    3.0-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Andrea Arcangeli <aarcange@redhat.com>

    commit 220a2eb228d032acde60e9fd044ca802706ff583 upstream.

    Up to this point the code assumed old refcounting for hugepages (pre-thp).
    This updates the code directly to the thp mapcount tail page refcounting.

    Signed-off-by: Andrea 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>
    Cc: David Gibson <david@gibson.dropbear.id.au>
    Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
    Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
    Cc: David Miller <davem@davemloft.net>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    arch/s390/mm/gup.c | 24 +++++++++++++++++++++++-
    1 file changed, 23 insertions(+), 1 deletion(-)

    --- a/arch/s390/mm/gup.c
    +++ b/arch/s390/mm/gup.c
    @@ -48,11 +48,22 @@ static inline int gup_pte_range(pmd_t *p
    return 1;
    }

    +static inline void get_huge_page_tail(struct page *page)
    +{
    + /*
    + * __split_huge_page_refcount() cannot run
    + * from under us.
    + */
    + VM_BUG_ON(page_mapcount(page) < 0);
    + VM_BUG_ON(atomic_read(&page->_count) != 0);
    + atomic_inc(&page->_mapcount);
    +}
    +
    static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
    unsigned long end, int write, struct page **pages, int *nr)
    {
    unsigned long mask, result;
    - struct page *head, *page;
    + struct page *head, *page, *tail;
    int refs;

    result = write ? 0 : _SEGMENT_ENTRY_RO;
    @@ -64,6 +75,7 @@ static inline int gup_huge_pmd(pmd_t *pm
    refs = 0;
    head = pmd_page(pmd);
    page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
    + tail = page;
    do {
    VM_BUG_ON(compound_head(page) != head);
    pages[*nr] = page;
    @@ -81,6 +93,16 @@ static inline int gup_huge_pmd(pmd_t *pm
    *nr -= refs;
    while (refs--)
    put_page(head);
    + } else {
    + /*
    + * Any tail page need their mapcount reference taken
    + * before we return.
    + */
    + while (refs--) {
    + if (PageTail(tail))
    + get_huge_page_tail(tail);
    + tail++;
    + }
    }

    return 1;



    \
     
     \ /
      Last update: 2011-11-10 05:55    [W:4.101 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site