diff options
Diffstat (limited to 'mm/swap.c')
-rw-r--r-- | mm/swap.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -737,7 +737,7 @@ EXPORT_SYMBOL(__pagevec_release); | |||
737 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 737 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
738 | /* used by __split_huge_page_refcount() */ | 738 | /* used by __split_huge_page_refcount() */ |
739 | void lru_add_page_tail(struct page *page, struct page *page_tail, | 739 | void lru_add_page_tail(struct page *page, struct page *page_tail, |
740 | struct lruvec *lruvec) | 740 | struct lruvec *lruvec, struct list_head *list) |
741 | { | 741 | { |
742 | int uninitialized_var(active); | 742 | int uninitialized_var(active); |
743 | enum lru_list lru; | 743 | enum lru_list lru; |
@@ -749,7 +749,8 @@ void lru_add_page_tail(struct page *page, struct page *page_tail, | |||
749 | VM_BUG_ON(NR_CPUS != 1 && | 749 | VM_BUG_ON(NR_CPUS != 1 && |
750 | !spin_is_locked(&lruvec_zone(lruvec)->lru_lock)); | 750 | !spin_is_locked(&lruvec_zone(lruvec)->lru_lock)); |
751 | 751 | ||
752 | SetPageLRU(page_tail); | 752 | if (!list) |
753 | SetPageLRU(page_tail); | ||
753 | 754 | ||
754 | if (page_evictable(page_tail)) { | 755 | if (page_evictable(page_tail)) { |
755 | if (PageActive(page)) { | 756 | if (PageActive(page)) { |
@@ -767,7 +768,11 @@ void lru_add_page_tail(struct page *page, struct page *page_tail, | |||
767 | 768 | ||
768 | if (likely(PageLRU(page))) | 769 | if (likely(PageLRU(page))) |
769 | list_add_tail(&page_tail->lru, &page->lru); | 770 | list_add_tail(&page_tail->lru, &page->lru); |
770 | else { | 771 | else if (list) { |
772 | /* page reclaim is reclaiming a huge page */ | ||
773 | get_page(page_tail); | ||
774 | list_add_tail(&page_tail->lru, list); | ||
775 | } else { | ||
771 | struct list_head *list_head; | 776 | struct list_head *list_head; |
772 | /* | 777 | /* |
773 | * Head page has not yet been counted, as an hpage, | 778 | * Head page has not yet been counted, as an hpage, |