lkml.org 
[lkml]   [2021]   [Jun]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 081/101] mm: thp: replace DEBUG_VM BUG with VM_WARN when unmap fails for split
    Date
    From: Yang Shi <shy828301@gmail.com>

    [ Upstream commit 504e070dc08f757bccaed6d05c0f53ecbfac8a23 ]

    When debugging the bug reported by Wang Yugui [1], try_to_unmap() may
    fail, but the first VM_BUG_ON_PAGE() just checks page_mapcount() however
    it may miss the failure when head page is unmapped but other subpage is
    mapped. Then the second DEBUG_VM BUG() that check total mapcount would
    catch it. This may incur some confusion.

    As this is not a fatal issue, so consolidate the two DEBUG_VM checks
    into one VM_WARN_ON_ONCE_PAGE().

    [1] https://lore.kernel.org/linux-mm/20210412180659.B9E3.409509F4@e16-tech.com/

    Link: https://lkml.kernel.org/r/d0f0db68-98b8-ebfb-16dc-f29df24cf012@google.com
    Signed-off-by: Yang Shi <shy828301@gmail.com>
    Reviewed-by: Zi Yan <ziy@nvidia.com>
    Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
    Signed-off-by: Hugh Dickins <hughd@google.com>
    Cc: Alistair Popple <apopple@nvidia.com>
    Cc: Jan Kara <jack@suse.cz>
    Cc: Jue Wang <juew@google.com>
    Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
    Cc: Miaohe Lin <linmiaohe@huawei.com>
    Cc: Minchan Kim <minchan@kernel.org>
    Cc: Naoya Horiguchi <naoya.horiguchi@nec.com>
    Cc: Oscar Salvador <osalvador@suse.de>
    Cc: Peter Xu <peterx@redhat.com>
    Cc: Ralph Campbell <rcampbell@nvidia.com>
    Cc: Shakeel Butt <shakeelb@google.com>
    Cc: Wang Yugui <wangyugui@e16-tech.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

    Note on stable backport: fixed up variables in split_huge_page_to_list().

    Signed-off-by: Hugh Dickins <hughd@google.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    mm/huge_memory.c | 24 +++++++-----------------
    1 file changed, 7 insertions(+), 17 deletions(-)

    diff --git a/mm/huge_memory.c b/mm/huge_memory.c
    index 14136390d641..6301ecc1f679 100644
    --- a/mm/huge_memory.c
    +++ b/mm/huge_memory.c
    @@ -2344,15 +2344,15 @@ static void unmap_page(struct page *page)
    {
    enum ttu_flags ttu_flags = TTU_IGNORE_MLOCK | TTU_SYNC |
    TTU_RMAP_LOCKED | TTU_SPLIT_HUGE_PMD;
    - bool unmap_success;

    VM_BUG_ON_PAGE(!PageHead(page), page);

    if (PageAnon(page))
    ttu_flags |= TTU_SPLIT_FREEZE;

    - unmap_success = try_to_unmap(page, ttu_flags);
    - VM_BUG_ON_PAGE(!unmap_success, page);
    + try_to_unmap(page, ttu_flags);
    +
    + VM_WARN_ON_ONCE_PAGE(page_mapped(page), page);
    }

    static void remap_page(struct page *page, unsigned int nr)
    @@ -2642,7 +2642,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
    struct deferred_split *ds_queue = get_deferred_split_queue(head);
    struct anon_vma *anon_vma = NULL;
    struct address_space *mapping = NULL;
    - int count, mapcount, extra_pins, ret;
    + int extra_pins, ret;
    unsigned long flags;
    pgoff_t end;

    @@ -2702,7 +2702,6 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
    }

    unmap_page(head);
    - VM_BUG_ON_PAGE(compound_mapcount(head), head);

    /* prevent PageLRU to go away from under us, and freeze lru stats */
    spin_lock_irqsave(&pgdata->lru_lock, flags);
    @@ -2721,9 +2720,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)

    /* Prevent deferred_split_scan() touching ->_refcount */
    spin_lock(&ds_queue->split_queue_lock);
    - count = page_count(head);
    - mapcount = total_mapcount(head);
    - if (!mapcount && page_ref_freeze(head, 1 + extra_pins)) {
    + if (page_ref_freeze(head, 1 + extra_pins)) {
    if (!list_empty(page_deferred_list(head))) {
    ds_queue->split_queue_len--;
    list_del(page_deferred_list(head));
    @@ -2739,16 +2736,9 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
    __split_huge_page(page, list, end, flags);
    ret = 0;
    } else {
    - if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) {
    - pr_alert("total_mapcount: %u, page_count(): %u\n",
    - mapcount, count);
    - if (PageTail(page))
    - dump_page(head, NULL);
    - dump_page(page, "total_mapcount(head) > 0");
    - BUG();
    - }
    spin_unlock(&ds_queue->split_queue_lock);
    -fail: if (mapping)
    +fail:
    + if (mapping)
    xa_unlock(&mapping->i_pages);
    spin_unlock_irqrestore(&pgdata->lru_lock, flags);
    remap_page(head, thp_nr_pages(head));
    --
    2.30.2
    \
     
     \ /
      Last update: 2021-06-28 16:39    [W:5.154 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site