diff options
-rw-r--r-- | mm/zswap.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/mm/zswap.c b/mm/zswap.c index 001474c1a594..0ffcad03baea 100644 --- a/mm/zswap.c +++ b/mm/zswap.c | |||
@@ -387,7 +387,7 @@ static void zswap_free_entry(struct zswap_tree *tree, struct zswap_entry *entry) | |||
387 | enum zswap_get_swap_ret { | 387 | enum zswap_get_swap_ret { |
388 | ZSWAP_SWAPCACHE_NEW, | 388 | ZSWAP_SWAPCACHE_NEW, |
389 | ZSWAP_SWAPCACHE_EXIST, | 389 | ZSWAP_SWAPCACHE_EXIST, |
390 | ZSWAP_SWAPCACHE_NOMEM | 390 | ZSWAP_SWAPCACHE_FAIL, |
391 | }; | 391 | }; |
392 | 392 | ||
393 | /* | 393 | /* |
@@ -401,9 +401,10 @@ enum zswap_get_swap_ret { | |||
401 | * added to the swap cache, and returned in retpage. | 401 | * added to the swap cache, and returned in retpage. |
402 | * | 402 | * |
403 | * If success, the swap cache page is returned in retpage | 403 | * If success, the swap cache page is returned in retpage |
404 | * Returns 0 if page was already in the swap cache, page is not locked | 404 | * Returns ZSWAP_SWAPCACHE_EXIST if page was already in the swap cache |
405 | * Returns 1 if the new page needs to be populated, page is locked | 405 | * Returns ZSWAP_SWAPCACHE_NEW if the new page needs to be populated, |
406 | * Returns <0 on error | 406 | * the new page is added to swapcache and locked |
407 | * Returns ZSWAP_SWAPCACHE_FAIL on error | ||
407 | */ | 408 | */ |
408 | static int zswap_get_swap_cache_page(swp_entry_t entry, | 409 | static int zswap_get_swap_cache_page(swp_entry_t entry, |
409 | struct page **retpage) | 410 | struct page **retpage) |
@@ -475,7 +476,7 @@ static int zswap_get_swap_cache_page(swp_entry_t entry, | |||
475 | if (new_page) | 476 | if (new_page) |
476 | page_cache_release(new_page); | 477 | page_cache_release(new_page); |
477 | if (!found_page) | 478 | if (!found_page) |
478 | return ZSWAP_SWAPCACHE_NOMEM; | 479 | return ZSWAP_SWAPCACHE_FAIL; |
479 | *retpage = found_page; | 480 | *retpage = found_page; |
480 | return ZSWAP_SWAPCACHE_EXIST; | 481 | return ZSWAP_SWAPCACHE_EXIST; |
481 | } | 482 | } |
@@ -529,11 +530,11 @@ static int zswap_writeback_entry(struct zbud_pool *pool, unsigned long handle) | |||
529 | 530 | ||
530 | /* try to allocate swap cache page */ | 531 | /* try to allocate swap cache page */ |
531 | switch (zswap_get_swap_cache_page(swpentry, &page)) { | 532 | switch (zswap_get_swap_cache_page(swpentry, &page)) { |
532 | case ZSWAP_SWAPCACHE_NOMEM: /* no memory */ | 533 | case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */ |
533 | ret = -ENOMEM; | 534 | ret = -ENOMEM; |
534 | goto fail; | 535 | goto fail; |
535 | 536 | ||
536 | case ZSWAP_SWAPCACHE_EXIST: /* page is unlocked */ | 537 | case ZSWAP_SWAPCACHE_EXIST: |
537 | /* page is already in the swap cache, ignore for now */ | 538 | /* page is already in the swap cache, ignore for now */ |
538 | page_cache_release(page); | 539 | page_cache_release(page); |
539 | ret = -EEXIST; | 540 | ret = -EEXIST; |
@@ -594,7 +595,12 @@ static int zswap_writeback_entry(struct zbud_pool *pool, unsigned long handle) | |||
594 | 595 | ||
595 | fail: | 596 | fail: |
596 | spin_lock(&tree->lock); | 597 | spin_lock(&tree->lock); |
597 | zswap_entry_put(entry); | 598 | refcount = zswap_entry_put(entry); |
599 | if (refcount <= 0) { | ||
600 | /* invalidate happened, consider writeback as success */ | ||
601 | zswap_free_entry(tree, entry); | ||
602 | ret = 0; | ||
603 | } | ||
598 | spin_unlock(&tree->lock); | 604 | spin_unlock(&tree->lock); |
599 | return ret; | 605 | return ret; |
600 | } | 606 | } |