diff options
Diffstat (limited to 'mm/swapfile.c')
| -rw-r--r-- | mm/swapfile.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index 39aa9d129612..e5fd5385f0cc 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
| @@ -397,18 +397,24 @@ void free_swap_and_cache(swp_entry_t entry) | |||
| 397 | 397 | ||
| 398 | p = swap_info_get(entry); | 398 | p = swap_info_get(entry); |
| 399 | if (p) { | 399 | if (p) { |
| 400 | if (swap_entry_free(p, swp_offset(entry)) == 1) | 400 | if (swap_entry_free(p, swp_offset(entry)) == 1) { |
| 401 | page = find_trylock_page(&swapper_space, entry.val); | 401 | page = find_get_page(&swapper_space, entry.val); |
| 402 | if (page && unlikely(TestSetPageLocked(page))) { | ||
| 403 | page_cache_release(page); | ||
| 404 | page = NULL; | ||
| 405 | } | ||
| 406 | } | ||
| 402 | spin_unlock(&swap_lock); | 407 | spin_unlock(&swap_lock); |
| 403 | } | 408 | } |
| 404 | if (page) { | 409 | if (page) { |
| 405 | int one_user; | 410 | int one_user; |
| 406 | 411 | ||
| 407 | BUG_ON(PagePrivate(page)); | 412 | BUG_ON(PagePrivate(page)); |
| 408 | page_cache_get(page); | ||
| 409 | one_user = (page_count(page) == 2); | 413 | one_user = (page_count(page) == 2); |
| 410 | /* Only cache user (+us), or swap space full? Free it! */ | 414 | /* Only cache user (+us), or swap space full? Free it! */ |
| 411 | if (!PageWriteback(page) && (one_user || vm_swap_full())) { | 415 | /* Also recheck PageSwapCache after page is locked (above) */ |
| 416 | if (PageSwapCache(page) && !PageWriteback(page) && | ||
| 417 | (one_user || vm_swap_full())) { | ||
| 412 | delete_from_swap_cache(page); | 418 | delete_from_swap_cache(page); |
| 413 | SetPageDirty(page); | 419 | SetPageDirty(page); |
| 414 | } | 420 | } |
