WIP: update tizen_qemu_defconfig
[platform/kernel/linux-starfive.git] / mm / zswap.c
index 2d48fd5..b3829ad 100644 (file)
@@ -1002,6 +1002,22 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
                goto fail;
 
        case ZSWAP_SWAPCACHE_NEW: /* page is locked */
+               /*
+                * Having a local reference to the zswap entry doesn't exclude
+                * swapping from invalidating and recycling the swap slot. Once
+                * the swapcache is secured against concurrent swapping to and
+                * from the slot, recheck that the entry is still current before
+                * writing.
+                */
+               spin_lock(&tree->lock);
+               if (zswap_rb_search(&tree->rbroot, entry->offset) != entry) {
+                       spin_unlock(&tree->lock);
+                       delete_from_swap_cache(page_folio(page));
+                       ret = -ENOMEM;
+                       goto fail;
+               }
+               spin_unlock(&tree->lock);
+
                /* decompress */
                acomp_ctx = raw_cpu_ptr(entry->pool->acomp_ctx);
                dlen = PAGE_SIZE;
@@ -1122,9 +1138,16 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
                goto reject;
        }
 
+       /*
+        * XXX: zswap reclaim does not work with cgroups yet. Without a
+        * cgroup-aware entry LRU, we will push out entries system-wide based on
+        * local cgroup limits.
+        */
        objcg = get_obj_cgroup_from_page(page);
-       if (objcg && !obj_cgroup_may_zswap(objcg))
-               goto shrink;
+       if (objcg && !obj_cgroup_may_zswap(objcg)) {
+               ret = -ENOMEM;
+               goto reject;
+       }
 
        /* reclaim space if needed */
        if (zswap_is_full()) {