diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index dfb342e0db9b..e5aaaad159ef 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -582,11 +582,8 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
582 | 582 | ||
583 | sc->nr_scanned++; | 583 | sc->nr_scanned++; |
584 | 584 | ||
585 | if (unlikely(!page_evictable(page, NULL))) { | 585 | if (unlikely(!page_evictable(page, NULL))) |
586 | unlock_page(page); | 586 | goto cull_mlocked; |
587 | putback_lru_page(page); | ||
588 | continue; | ||
589 | } | ||
590 | 587 | ||
591 | if (!sc->may_swap && page_mapped(page)) | 588 | if (!sc->may_swap && page_mapped(page)) |
592 | goto keep_locked; | 589 | goto keep_locked; |
@@ -624,9 +621,19 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
624 | * Anonymous process memory has backing store? | 621 | * Anonymous process memory has backing store? |
625 | * Try to allocate it some swap space here. | 622 | * Try to allocate it some swap space here. |
626 | */ | 623 | */ |
627 | if (PageAnon(page) && !PageSwapCache(page)) | 624 | if (PageAnon(page) && !PageSwapCache(page)) { |
625 | switch (try_to_munlock(page)) { | ||
626 | case SWAP_FAIL: /* shouldn't happen */ | ||
627 | case SWAP_AGAIN: | ||
628 | goto keep_locked; | ||
629 | case SWAP_MLOCK: | ||
630 | goto cull_mlocked; | ||
631 | case SWAP_SUCCESS: | ||
632 | ; /* fall thru'; add to swap cache */ | ||
633 | } | ||
628 | if (!add_to_swap(page, GFP_ATOMIC)) | 634 | if (!add_to_swap(page, GFP_ATOMIC)) |
629 | goto activate_locked; | 635 | goto activate_locked; |
636 | } | ||
630 | #endif /* CONFIG_SWAP */ | 637 | #endif /* CONFIG_SWAP */ |
631 | 638 | ||
632 | mapping = page_mapping(page); | 639 | mapping = page_mapping(page); |
@@ -641,6 +648,8 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
641 | goto activate_locked; | 648 | goto activate_locked; |
642 | case SWAP_AGAIN: | 649 | case SWAP_AGAIN: |
643 | goto keep_locked; | 650 | goto keep_locked; |
651 | case SWAP_MLOCK: | ||
652 | goto cull_mlocked; | ||
644 | case SWAP_SUCCESS: | 653 | case SWAP_SUCCESS: |
645 | ; /* try to free the page below */ | 654 | ; /* try to free the page below */ |
646 | } | 655 | } |
@@ -731,6 +740,11 @@ free_it: | |||
731 | } | 740 | } |
732 | continue; | 741 | continue; |
733 | 742 | ||
743 | cull_mlocked: | ||
744 | unlock_page(page); | ||
745 | putback_lru_page(page); | ||
746 | continue; | ||
747 | |||
734 | activate_locked: | 748 | activate_locked: |
735 | /* Not a candidate for swapping, so reclaim swap space. */ | 749 | /* Not a candidate for swapping, so reclaim swap space. */ |
736 | if (PageSwapCache(page) && vm_swap_full()) | 750 | if (PageSwapCache(page) && vm_swap_full()) |
@@ -742,7 +756,7 @@ keep_locked: | |||
742 | unlock_page(page); | 756 | unlock_page(page); |
743 | keep: | 757 | keep: |
744 | list_add(&page->lru, &ret_pages); | 758 | list_add(&page->lru, &ret_pages); |
745 | VM_BUG_ON(PageLRU(page)); | 759 | VM_BUG_ON(PageLRU(page) || PageUnevictable(page)); |
746 | } | 760 | } |
747 | list_splice(&ret_pages, page_list); | 761 | list_splice(&ret_pages, page_list); |
748 | if (pagevec_count(&freed_pvec)) | 762 | if (pagevec_count(&freed_pvec)) |
@@ -2329,12 +2343,13 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | |||
2329 | * @vma: the VMA in which the page is or will be mapped, may be NULL | 2343 | * @vma: the VMA in which the page is or will be mapped, may be NULL |
2330 | * | 2344 | * |
2331 | * Test whether page is evictable--i.e., should be placed on active/inactive | 2345 | * Test whether page is evictable--i.e., should be placed on active/inactive |
2332 | * lists vs unevictable list. | 2346 | * lists vs unevictable list. The vma argument is !NULL when called from the |
2347 | * fault path to determine how to instantate a new page. | ||
2333 | * | 2348 | * |
2334 | * Reasons page might not be evictable: | 2349 | * Reasons page might not be evictable: |
2335 | * (1) page's mapping marked unevictable | 2350 | * (1) page's mapping marked unevictable |
2351 | * (2) page is part of an mlocked VMA | ||
2336 | * | 2352 | * |
2337 | * TODO - later patches | ||
2338 | */ | 2353 | */ |
2339 | int page_evictable(struct page *page, struct vm_area_struct *vma) | 2354 | int page_evictable(struct page *page, struct vm_area_struct *vma) |
2340 | { | 2355 | { |
@@ -2342,7 +2357,8 @@ int page_evictable(struct page *page, struct vm_area_struct *vma) | |||
2342 | if (mapping_unevictable(page_mapping(page))) | 2357 | if (mapping_unevictable(page_mapping(page))) |
2343 | return 0; | 2358 | return 0; |
2344 | 2359 | ||
2345 | /* TODO: test page [!]evictable conditions */ | 2360 | if (PageMlocked(page) || (vma && is_mlocked_vma(vma, page))) |
2361 | return 0; | ||
2346 | 2362 | ||
2347 | return 1; | 2363 | return 1; |
2348 | } | 2364 | } |