diff options
Diffstat (limited to 'mm')
-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 | } |