Split_huge_page() must start with PageLRU(head), and we are holding the lru_lock here. If the head was cleared lru bit unexpected, tracking it. Signed-off-by: Alex Shi <alex.shi@xxxxxxxxxxxxxxxxx> Reviewed-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> Cc: Kirill A. Shutemov <kirill@xxxxxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> Cc: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Mika Penttilä <mika.penttila@xxxxxxxxxxxx> Cc: linux-mm@xxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx --- mm/huge_memory.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index d866b6e43434..28538444197b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2348,15 +2348,19 @@ static void lru_add_page_tail(struct page *head, struct page *page_tail, VM_BUG_ON_PAGE(PageLRU(page_tail), head); lockdep_assert_held(&lruvec_pgdat(lruvec)->lru_lock); - if (!list) - SetPageLRU(page_tail); - - if (likely(PageLRU(head))) - list_add_tail(&page_tail->lru, &head->lru); - else if (list) { + if (list) { /* page reclaim is reclaiming a huge page */ get_page(page_tail); list_add_tail(&page_tail->lru, list); + } else { + /* + * Split start from PageLRU(head), and we are holding the + * lru_lock. + * Do a warning if the head's lru bit was cleared unexpected. + */ + VM_WARN_ON(!PageLRU(head)); + SetPageLRU(page_tail); + list_add_tail(&page_tail->lru, &head->lru); } } -- 1.8.3.1