split_huge_page() must start with PageLRU(head), but lru bit *maybe* cleared by isolate_lru_page, anyway the head still in lru list, since we still held the lru_lock. Signed-off-by: Alex Shi <alex.shi@xxxxxxxxxxxxxxxxx> 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 | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index d866b6e43434..4fe7b92c9330 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2348,15 +2348,18 @@ 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), but lru bit maybe cleared + * by isolate_lru_page, but head still in lru list, since we + * held the lru_lock. + */ + SetPageLRU(page_tail); + list_add_tail(&page_tail->lru, &head->lru); } } -- 1.8.3.1