zram: add incompressible writeback
authorSergey Senozhatsky <senozhatsky@chromium.org>
Wed, 9 Nov 2022 11:50:46 +0000 (20:50 +0900)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 30 Nov 2022 23:58:53 +0000 (15:58 -0800)
Add support for incompressible pages writeback:

  echo incompressible > /sys/block/zramX/writeback

Link: https://lkml.kernel.org/r/20221109115047.2921851-13-senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Acked-by: Minchan Kim <minchan@kernel.org>
Cc: Alexey Romanov <avromanov@sberdevices.ru>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Documentation/admin-guide/blockdev/zram.rst
drivers/block/zram/zram_drv.c

index d898b7a..f14c8c2 100644 (file)
@@ -348,8 +348,13 @@ this can be accomplished with::
 
         echo huge_idle > /sys/block/zramX/writeback
 
+If a user chooses to writeback only incompressible pages (pages that none of
+algorithms can compress) this can be accomplished with::
+
+       echo incompressible > /sys/block/zramX/writeback
+
 If an admin wants to write a specific page in zram device to the backing device,
-they could write a page index into the interface.
+they could write a page index into the interface::
 
        echo "page_index=1251" > /sys/block/zramX/writeback
 
index 798c421..25b7ff2 100644 (file)
@@ -645,10 +645,10 @@ static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec,
 
 #define PAGE_WB_SIG "page_index="
 
-#define PAGE_WRITEBACK 0
-#define HUGE_WRITEBACK (1<<0)
-#define IDLE_WRITEBACK (1<<1)
-
+#define PAGE_WRITEBACK                 0
+#define HUGE_WRITEBACK                 (1<<0)
+#define IDLE_WRITEBACK                 (1<<1)
+#define INCOMPRESSIBLE_WRITEBACK       (1<<2)
 
 static ssize_t writeback_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t len)
@@ -669,6 +669,8 @@ static ssize_t writeback_store(struct device *dev,
                mode = HUGE_WRITEBACK;
        else if (sysfs_streq(buf, "huge_idle"))
                mode = IDLE_WRITEBACK | HUGE_WRITEBACK;
+       else if (sysfs_streq(buf, "incompressible"))
+               mode = INCOMPRESSIBLE_WRITEBACK;
        else {
                if (strncmp(buf, PAGE_WB_SIG, sizeof(PAGE_WB_SIG) - 1))
                        return -EINVAL;
@@ -731,11 +733,15 @@ static ssize_t writeback_store(struct device *dev,
                        goto next;
 
                if (mode & IDLE_WRITEBACK &&
-                         !zram_test_flag(zram, index, ZRAM_IDLE))
+                   !zram_test_flag(zram, index, ZRAM_IDLE))
                        goto next;
                if (mode & HUGE_WRITEBACK &&
-                         !zram_test_flag(zram, index, ZRAM_HUGE))
+                   !zram_test_flag(zram, index, ZRAM_HUGE))
                        goto next;
+               if (mode & INCOMPRESSIBLE_WRITEBACK &&
+                   !zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE))
+                       goto next;
+
                /*
                 * Clearing ZRAM_UNDER_WB is duty of caller.
                 * IOW, zram_free_page never clear it.