|
@@ -387,7 +387,7 @@ static void zswap_free_entry(struct zswap_tree *tree, struct zswap_entry *entry)
|
|
|
enum zswap_get_swap_ret {
|
|
|
ZSWAP_SWAPCACHE_NEW,
|
|
|
ZSWAP_SWAPCACHE_EXIST,
|
|
|
- ZSWAP_SWAPCACHE_NOMEM
|
|
|
+ ZSWAP_SWAPCACHE_FAIL,
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -401,9 +401,10 @@ enum zswap_get_swap_ret {
|
|
|
* added to the swap cache, and returned in retpage.
|
|
|
*
|
|
|
* If success, the swap cache page is returned in retpage
|
|
|
- * Returns 0 if page was already in the swap cache, page is not locked
|
|
|
- * Returns 1 if the new page needs to be populated, page is locked
|
|
|
- * Returns <0 on error
|
|
|
+ * Returns ZSWAP_SWAPCACHE_EXIST if page was already in the swap cache
|
|
|
+ * Returns ZSWAP_SWAPCACHE_NEW if the new page needs to be populated,
|
|
|
+ * the new page is added to swapcache and locked
|
|
|
+ * Returns ZSWAP_SWAPCACHE_FAIL on error
|
|
|
*/
|
|
|
static int zswap_get_swap_cache_page(swp_entry_t entry,
|
|
|
struct page **retpage)
|
|
@@ -475,7 +476,7 @@ static int zswap_get_swap_cache_page(swp_entry_t entry,
|
|
|
if (new_page)
|
|
|
page_cache_release(new_page);
|
|
|
if (!found_page)
|
|
|
- return ZSWAP_SWAPCACHE_NOMEM;
|
|
|
+ return ZSWAP_SWAPCACHE_FAIL;
|
|
|
*retpage = found_page;
|
|
|
return ZSWAP_SWAPCACHE_EXIST;
|
|
|
}
|
|
@@ -529,11 +530,11 @@ static int zswap_writeback_entry(struct zbud_pool *pool, unsigned long handle)
|
|
|
|
|
|
/* try to allocate swap cache page */
|
|
|
switch (zswap_get_swap_cache_page(swpentry, &page)) {
|
|
|
- case ZSWAP_SWAPCACHE_NOMEM: /* no memory */
|
|
|
+ case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
|
|
|
ret = -ENOMEM;
|
|
|
goto fail;
|
|
|
|
|
|
- case ZSWAP_SWAPCACHE_EXIST: /* page is unlocked */
|
|
|
+ case ZSWAP_SWAPCACHE_EXIST:
|
|
|
/* page is already in the swap cache, ignore for now */
|
|
|
page_cache_release(page);
|
|
|
ret = -EEXIST;
|
|
@@ -594,7 +595,12 @@ static int zswap_writeback_entry(struct zbud_pool *pool, unsigned long handle)
|
|
|
|
|
|
fail:
|
|
|
spin_lock(&tree->lock);
|
|
|
- zswap_entry_put(entry);
|
|
|
+ refcount = zswap_entry_put(entry);
|
|
|
+ if (refcount <= 0) {
|
|
|
+ /* invalidate happened, consider writeback as success */
|
|
|
+ zswap_free_entry(tree, entry);
|
|
|
+ ret = 0;
|
|
|
+ }
|
|
|
spin_unlock(&tree->lock);
|
|
|
return ret;
|
|
|
}
|