zram: do not mark idle slots that cannot be idle
authorSergey Senozhatsky <senozhatsky@chromium.org>
Tue, 17 Sep 2024 02:09:10 +0000 (11:09 +0900)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 6 Nov 2024 00:56:22 +0000 (16:56 -0800)
ZRAM_SAME slots cannot be post-processed (writeback or recompress) so do
not mark them ZRAM_IDLE.  Same with ZRAM_WB slots, they cannot be
ZRAM_IDLE because they are not in zsmalloc pool anymore.

Link: https://lkml.kernel.org/r/20240917021020.883356-6-senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
drivers/block/zram/zram_drv.c

index 42f7195b80cb910b6e40ebe6796726aa7cc3c807..41e40866194052ea284eff7025efb8f53a5c82f5 100644 (file)
@@ -392,17 +392,28 @@ static void mark_idle(struct zram *zram, ktime_t cutoff)
                /*
                 * Do not mark ZRAM_UNDER_WB slot as ZRAM_IDLE to close race.
                 * See the comment in writeback_store.
+                *
+                * Also do not mark ZRAM_SAME slots as ZRAM_IDLE, because no
+                * post-processing (recompress, writeback) happens to the
+                * ZRAM_SAME slot.
+                *
+                * And ZRAM_WB slots simply cannot be ZRAM_IDLE.
                 */
                zram_slot_lock(zram, index);
-               if (zram_allocated(zram, index) &&
-                               !zram_test_flag(zram, index, ZRAM_UNDER_WB)) {
+               if (!zram_allocated(zram, index) ||
+                   zram_test_flag(zram, index, ZRAM_WB) ||
+                   zram_test_flag(zram, index, ZRAM_UNDER_WB) ||
+                   zram_test_flag(zram, index, ZRAM_SAME)) {
+                       zram_slot_unlock(zram, index);
+                       continue;
+               }
+
 #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME
-                       is_idle = !cutoff || ktime_after(cutoff,
-                                                        zram->table[index].ac_time);
+               is_idle = !cutoff ||
+                       ktime_after(cutoff, zram->table[index].ac_time);
 #endif
-                       if (is_idle)
-                               zram_set_flag(zram, index, ZRAM_IDLE);
-               }
+               if (is_idle)
+                       zram_set_flag(zram, index, ZRAM_IDLE);
                zram_slot_unlock(zram, index);
        }
 }