diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 111 |
1 files changed, 83 insertions, 28 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 99b434b674c0..2624edcfb420 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -553,7 +553,7 @@ void putback_lru_page(struct page *page) | |||
553 | redo: | 553 | redo: |
554 | ClearPageUnevictable(page); | 554 | ClearPageUnevictable(page); |
555 | 555 | ||
556 | if (page_evictable(page, NULL)) { | 556 | if (page_evictable(page)) { |
557 | /* | 557 | /* |
558 | * For evictable pages, we can use the cache. | 558 | * For evictable pages, we can use the cache. |
559 | * In event of a race, worst case is we end up with an | 559 | * In event of a race, worst case is we end up with an |
@@ -587,7 +587,7 @@ redo: | |||
587 | * page is on unevictable list, it never be freed. To avoid that, | 587 | * page is on unevictable list, it never be freed. To avoid that, |
588 | * check after we added it to the list, again. | 588 | * check after we added it to the list, again. |
589 | */ | 589 | */ |
590 | if (lru == LRU_UNEVICTABLE && page_evictable(page, NULL)) { | 590 | if (lru == LRU_UNEVICTABLE && page_evictable(page)) { |
591 | if (!isolate_lru_page(page)) { | 591 | if (!isolate_lru_page(page)) { |
592 | put_page(page); | 592 | put_page(page); |
593 | goto redo; | 593 | goto redo; |
@@ -674,8 +674,10 @@ static enum page_references page_check_references(struct page *page, | |||
674 | static unsigned long shrink_page_list(struct list_head *page_list, | 674 | static unsigned long shrink_page_list(struct list_head *page_list, |
675 | struct zone *zone, | 675 | struct zone *zone, |
676 | struct scan_control *sc, | 676 | struct scan_control *sc, |
677 | enum ttu_flags ttu_flags, | ||
677 | unsigned long *ret_nr_dirty, | 678 | unsigned long *ret_nr_dirty, |
678 | unsigned long *ret_nr_writeback) | 679 | unsigned long *ret_nr_writeback, |
680 | bool force_reclaim) | ||
679 | { | 681 | { |
680 | LIST_HEAD(ret_pages); | 682 | LIST_HEAD(ret_pages); |
681 | LIST_HEAD(free_pages); | 683 | LIST_HEAD(free_pages); |
@@ -689,10 +691,10 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
689 | 691 | ||
690 | mem_cgroup_uncharge_start(); | 692 | mem_cgroup_uncharge_start(); |
691 | while (!list_empty(page_list)) { | 693 | while (!list_empty(page_list)) { |
692 | enum page_references references; | ||
693 | struct address_space *mapping; | 694 | struct address_space *mapping; |
694 | struct page *page; | 695 | struct page *page; |
695 | int may_enter_fs; | 696 | int may_enter_fs; |
697 | enum page_references references = PAGEREF_RECLAIM_CLEAN; | ||
696 | 698 | ||
697 | cond_resched(); | 699 | cond_resched(); |
698 | 700 | ||
@@ -707,7 +709,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
707 | 709 | ||
708 | sc->nr_scanned++; | 710 | sc->nr_scanned++; |
709 | 711 | ||
710 | if (unlikely(!page_evictable(page, NULL))) | 712 | if (unlikely(!page_evictable(page))) |
711 | goto cull_mlocked; | 713 | goto cull_mlocked; |
712 | 714 | ||
713 | if (!sc->may_unmap && page_mapped(page)) | 715 | if (!sc->may_unmap && page_mapped(page)) |
@@ -758,7 +760,9 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
758 | wait_on_page_writeback(page); | 760 | wait_on_page_writeback(page); |
759 | } | 761 | } |
760 | 762 | ||
761 | references = page_check_references(page, sc); | 763 | if (!force_reclaim) |
764 | references = page_check_references(page, sc); | ||
765 | |||
762 | switch (references) { | 766 | switch (references) { |
763 | case PAGEREF_ACTIVATE: | 767 | case PAGEREF_ACTIVATE: |
764 | goto activate_locked; | 768 | goto activate_locked; |
@@ -788,7 +792,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
788 | * processes. Try to unmap it here. | 792 | * processes. Try to unmap it here. |
789 | */ | 793 | */ |
790 | if (page_mapped(page) && mapping) { | 794 | if (page_mapped(page) && mapping) { |
791 | switch (try_to_unmap(page, TTU_UNMAP)) { | 795 | switch (try_to_unmap(page, ttu_flags)) { |
792 | case SWAP_FAIL: | 796 | case SWAP_FAIL: |
793 | goto activate_locked; | 797 | goto activate_locked; |
794 | case SWAP_AGAIN: | 798 | case SWAP_AGAIN: |
@@ -960,6 +964,33 @@ keep: | |||
960 | return nr_reclaimed; | 964 | return nr_reclaimed; |
961 | } | 965 | } |
962 | 966 | ||
967 | unsigned long reclaim_clean_pages_from_list(struct zone *zone, | ||
968 | struct list_head *page_list) | ||
969 | { | ||
970 | struct scan_control sc = { | ||
971 | .gfp_mask = GFP_KERNEL, | ||
972 | .priority = DEF_PRIORITY, | ||
973 | .may_unmap = 1, | ||
974 | }; | ||
975 | unsigned long ret, dummy1, dummy2; | ||
976 | struct page *page, *next; | ||
977 | LIST_HEAD(clean_pages); | ||
978 | |||
979 | list_for_each_entry_safe(page, next, page_list, lru) { | ||
980 | if (page_is_file_cache(page) && !PageDirty(page)) { | ||
981 | ClearPageActive(page); | ||
982 | list_move(&page->lru, &clean_pages); | ||
983 | } | ||
984 | } | ||
985 | |||
986 | ret = shrink_page_list(&clean_pages, zone, &sc, | ||
987 | TTU_UNMAP|TTU_IGNORE_ACCESS, | ||
988 | &dummy1, &dummy2, true); | ||
989 | list_splice(&clean_pages, page_list); | ||
990 | __mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret); | ||
991 | return ret; | ||
992 | } | ||
993 | |||
963 | /* | 994 | /* |
964 | * Attempt to remove the specified page from its LRU. Only take this page | 995 | * Attempt to remove the specified page from its LRU. Only take this page |
965 | * if it is of the appropriate PageActive status. Pages which are being | 996 | * if it is of the appropriate PageActive status. Pages which are being |
@@ -978,8 +1009,8 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode) | |||
978 | if (!PageLRU(page)) | 1009 | if (!PageLRU(page)) |
979 | return ret; | 1010 | return ret; |
980 | 1011 | ||
981 | /* Do not give back unevictable pages for compaction */ | 1012 | /* Compaction should not handle unevictable pages but CMA can do so */ |
982 | if (PageUnevictable(page)) | 1013 | if (PageUnevictable(page) && !(mode & ISOLATE_UNEVICTABLE)) |
983 | return ret; | 1014 | return ret; |
984 | 1015 | ||
985 | ret = -EBUSY; | 1016 | ret = -EBUSY; |
@@ -1186,7 +1217,7 @@ putback_inactive_pages(struct lruvec *lruvec, struct list_head *page_list) | |||
1186 | 1217 | ||
1187 | VM_BUG_ON(PageLRU(page)); | 1218 | VM_BUG_ON(PageLRU(page)); |
1188 | list_del(&page->lru); | 1219 | list_del(&page->lru); |
1189 | if (unlikely(!page_evictable(page, NULL))) { | 1220 | if (unlikely(!page_evictable(page))) { |
1190 | spin_unlock_irq(&zone->lru_lock); | 1221 | spin_unlock_irq(&zone->lru_lock); |
1191 | putback_lru_page(page); | 1222 | putback_lru_page(page); |
1192 | spin_lock_irq(&zone->lru_lock); | 1223 | spin_lock_irq(&zone->lru_lock); |
@@ -1278,8 +1309,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, | |||
1278 | if (nr_taken == 0) | 1309 | if (nr_taken == 0) |
1279 | return 0; | 1310 | return 0; |
1280 | 1311 | ||
1281 | nr_reclaimed = shrink_page_list(&page_list, zone, sc, | 1312 | nr_reclaimed = shrink_page_list(&page_list, zone, sc, TTU_UNMAP, |
1282 | &nr_dirty, &nr_writeback); | 1313 | &nr_dirty, &nr_writeback, false); |
1283 | 1314 | ||
1284 | spin_lock_irq(&zone->lru_lock); | 1315 | spin_lock_irq(&zone->lru_lock); |
1285 | 1316 | ||
@@ -1439,7 +1470,7 @@ static void shrink_active_list(unsigned long nr_to_scan, | |||
1439 | page = lru_to_page(&l_hold); | 1470 | page = lru_to_page(&l_hold); |
1440 | list_del(&page->lru); | 1471 | list_del(&page->lru); |
1441 | 1472 | ||
1442 | if (unlikely(!page_evictable(page, NULL))) { | 1473 | if (unlikely(!page_evictable(page))) { |
1443 | putback_lru_page(page); | 1474 | putback_lru_page(page); |
1444 | continue; | 1475 | continue; |
1445 | } | 1476 | } |
@@ -1729,6 +1760,28 @@ static bool in_reclaim_compaction(struct scan_control *sc) | |||
1729 | return false; | 1760 | return false; |
1730 | } | 1761 | } |
1731 | 1762 | ||
1763 | #ifdef CONFIG_COMPACTION | ||
1764 | /* | ||
1765 | * If compaction is deferred for sc->order then scale the number of pages | ||
1766 | * reclaimed based on the number of consecutive allocation failures | ||
1767 | */ | ||
1768 | static unsigned long scale_for_compaction(unsigned long pages_for_compaction, | ||
1769 | struct lruvec *lruvec, struct scan_control *sc) | ||
1770 | { | ||
1771 | struct zone *zone = lruvec_zone(lruvec); | ||
1772 | |||
1773 | if (zone->compact_order_failed <= sc->order) | ||
1774 | pages_for_compaction <<= zone->compact_defer_shift; | ||
1775 | return pages_for_compaction; | ||
1776 | } | ||
1777 | #else | ||
1778 | static unsigned long scale_for_compaction(unsigned long pages_for_compaction, | ||
1779 | struct lruvec *lruvec, struct scan_control *sc) | ||
1780 | { | ||
1781 | return pages_for_compaction; | ||
1782 | } | ||
1783 | #endif | ||
1784 | |||
1732 | /* | 1785 | /* |
1733 | * Reclaim/compaction is used for high-order allocation requests. It reclaims | 1786 | * Reclaim/compaction is used for high-order allocation requests. It reclaims |
1734 | * order-0 pages before compacting the zone. should_continue_reclaim() returns | 1787 | * order-0 pages before compacting the zone. should_continue_reclaim() returns |
@@ -1776,6 +1829,9 @@ static inline bool should_continue_reclaim(struct lruvec *lruvec, | |||
1776 | * inactive lists are large enough, continue reclaiming | 1829 | * inactive lists are large enough, continue reclaiming |
1777 | */ | 1830 | */ |
1778 | pages_for_compaction = (2UL << sc->order); | 1831 | pages_for_compaction = (2UL << sc->order); |
1832 | |||
1833 | pages_for_compaction = scale_for_compaction(pages_for_compaction, | ||
1834 | lruvec, sc); | ||
1779 | inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE); | 1835 | inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE); |
1780 | if (nr_swap_pages > 0) | 1836 | if (nr_swap_pages > 0) |
1781 | inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON); | 1837 | inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON); |
@@ -2839,6 +2895,14 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx) | |||
2839 | */ | 2895 | */ |
2840 | set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); | 2896 | set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); |
2841 | 2897 | ||
2898 | /* | ||
2899 | * Compaction records what page blocks it recently failed to | ||
2900 | * isolate pages from and skips them in the future scanning. | ||
2901 | * When kswapd is going to sleep, it is reasonable to assume | ||
2902 | * that pages and compaction may succeed so reset the cache. | ||
2903 | */ | ||
2904 | reset_isolation_suitable(pgdat); | ||
2905 | |||
2842 | if (!kthread_should_stop()) | 2906 | if (!kthread_should_stop()) |
2843 | schedule(); | 2907 | schedule(); |
2844 | 2908 | ||
@@ -3101,9 +3165,9 @@ int kswapd_run(int nid) | |||
3101 | if (IS_ERR(pgdat->kswapd)) { | 3165 | if (IS_ERR(pgdat->kswapd)) { |
3102 | /* failure at boot is fatal */ | 3166 | /* failure at boot is fatal */ |
3103 | BUG_ON(system_state == SYSTEM_BOOTING); | 3167 | BUG_ON(system_state == SYSTEM_BOOTING); |
3104 | printk("Failed to start kswapd on node %d\n",nid); | ||
3105 | pgdat->kswapd = NULL; | 3168 | pgdat->kswapd = NULL; |
3106 | ret = -1; | 3169 | pr_err("Failed to start kswapd on node %d\n", nid); |
3170 | ret = PTR_ERR(pgdat->kswapd); | ||
3107 | } | 3171 | } |
3108 | return ret; | 3172 | return ret; |
3109 | } | 3173 | } |
@@ -3350,27 +3414,18 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | |||
3350 | /* | 3414 | /* |
3351 | * page_evictable - test whether a page is evictable | 3415 | * page_evictable - test whether a page is evictable |
3352 | * @page: the page to test | 3416 | * @page: the page to test |
3353 | * @vma: the VMA in which the page is or will be mapped, may be NULL | ||
3354 | * | 3417 | * |
3355 | * Test whether page is evictable--i.e., should be placed on active/inactive | 3418 | * Test whether page is evictable--i.e., should be placed on active/inactive |
3356 | * lists vs unevictable list. The vma argument is !NULL when called from the | 3419 | * lists vs unevictable list. |
3357 | * fault path to determine how to instantate a new page. | ||
3358 | * | 3420 | * |
3359 | * Reasons page might not be evictable: | 3421 | * Reasons page might not be evictable: |
3360 | * (1) page's mapping marked unevictable | 3422 | * (1) page's mapping marked unevictable |
3361 | * (2) page is part of an mlocked VMA | 3423 | * (2) page is part of an mlocked VMA |
3362 | * | 3424 | * |
3363 | */ | 3425 | */ |
3364 | int page_evictable(struct page *page, struct vm_area_struct *vma) | 3426 | int page_evictable(struct page *page) |
3365 | { | 3427 | { |
3366 | 3428 | return !mapping_unevictable(page_mapping(page)) && !PageMlocked(page); | |
3367 | if (mapping_unevictable(page_mapping(page))) | ||
3368 | return 0; | ||
3369 | |||
3370 | if (PageMlocked(page) || (vma && mlocked_vma_newpage(vma, page))) | ||
3371 | return 0; | ||
3372 | |||
3373 | return 1; | ||
3374 | } | 3429 | } |
3375 | 3430 | ||
3376 | #ifdef CONFIG_SHMEM | 3431 | #ifdef CONFIG_SHMEM |
@@ -3408,7 +3463,7 @@ void check_move_unevictable_pages(struct page **pages, int nr_pages) | |||
3408 | if (!PageLRU(page) || !PageUnevictable(page)) | 3463 | if (!PageLRU(page) || !PageUnevictable(page)) |
3409 | continue; | 3464 | continue; |
3410 | 3465 | ||
3411 | if (page_evictable(page, NULL)) { | 3466 | if (page_evictable(page)) { |
3412 | enum lru_list lru = page_lru_base_type(page); | 3467 | enum lru_list lru = page_lru_base_type(page); |
3413 | 3468 | ||
3414 | VM_BUG_ON(PageActive(page)); | 3469 | VM_BUG_ON(PageActive(page)); |