]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Aug 2022 07:59:09 +0000 (09:59 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Aug 2022 07:59:09 +0000 (09:59 +0200)
added patches:
revert-zram-remove-double-compression-logic.patch

queue-5.19/revert-zram-remove-double-compression-logic.patch [new file with mode: 0644]
queue-5.19/series

diff --git a/queue-5.19/revert-zram-remove-double-compression-logic.patch b/queue-5.19/revert-zram-remove-double-compression-logic.patch
new file mode 100644 (file)
index 0000000..9b08791
--- /dev/null
@@ -0,0 +1,143 @@
+From 37887783b3fef877bf34b8992c9199864da4afcb Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Wed, 10 Aug 2022 09:06:09 +0200
+Subject: Revert "zram: remove double compression logic"
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 37887783b3fef877bf34b8992c9199864da4afcb upstream.
+
+This reverts commit e7be8d1dd983156b ("zram: remove double compression
+logic") as it causes zram failures.  It does not revert cleanly, PTR_ERR
+handling was introduced in the meantime.  This is handled by appropriate
+IS_ERR.
+
+When under memory pressure, zs_malloc() can fail.  Before the above
+commit, the allocation was retried with direct reclaim enabled (GFP_NOIO).
+After the commit, it is not -- only __GFP_KSWAPD_RECLAIM is tried.
+
+So when the failure occurs under memory pressure, the overlaying
+filesystem such as ext2 (mounted by ext4 module in this case) can emit
+failures, making the (file)system unusable:
+  EXT4-fs warning (device zram0): ext4_end_bio:343: I/O error 10 writing to inode 16386 starting block 159744)
+  Buffer I/O error on device zram0, logical block 159744
+
+With direct reclaim, memory is really reclaimed and allocation succeeds,
+eventually.  In the worst case, the oom killer is invoked, which is proper
+outcome if user sets up zram too large (in comparison to available RAM).
+
+This very diff doesn't apply to 5.19 (stable) cleanly (see PTR_ERR note
+above). Use revert of e7be8d1dd983 directly.
+
+Link: https://bugzilla.suse.com/show_bug.cgi?id=1202203
+Link: https://lkml.kernel.org/r/20220810070609.14402-1-jslaby@suse.cz
+Fixes: e7be8d1dd983 ("zram: remove double compression logic")
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Cc: Alexey Romanov <avromanov@sberdevices.ru>
+Cc: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+Cc: Lukas Czerner <lczerner@redhat.com>
+Cc: <stable@vger.kernel.org>   [5.19]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/zram/zram_drv.c |   42 ++++++++++++++++++++++++++++++++----------
+ drivers/block/zram/zram_drv.h |    1 +
+ 2 files changed, 33 insertions(+), 10 deletions(-)
+
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1144,14 +1144,15 @@ static ssize_t bd_stat_show(struct devic
+ static ssize_t debug_stat_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+ {
+-      int version = 2;
++      int version = 1;
+       struct zram *zram = dev_to_zram(dev);
+       ssize_t ret;
+       down_read(&zram->init_lock);
+       ret = scnprintf(buf, PAGE_SIZE,
+-                      "version: %d\n%8llu\n",
++                      "version: %d\n%8llu %8llu\n",
+                       version,
++                      (u64)atomic64_read(&zram->stats.writestall),
+                       (u64)atomic64_read(&zram->stats.miss_free));
+       up_read(&zram->init_lock);
+@@ -1367,6 +1368,7 @@ static int __zram_bvec_write(struct zram
+       }
+       kunmap_atomic(mem);
++compress_again:
+       zstrm = zcomp_stream_get(zram->comp);
+       src = kmap_atomic(page);
+       ret = zcomp_compress(zstrm, src, &comp_len);
+@@ -1375,20 +1377,39 @@ static int __zram_bvec_write(struct zram
+       if (unlikely(ret)) {
+               zcomp_stream_put(zram->comp);
+               pr_err("Compression failed! err=%d\n", ret);
++              zs_free(zram->mem_pool, handle);
+               return ret;
+       }
+       if (comp_len >= huge_class_size)
+               comp_len = PAGE_SIZE;
+-
+-      handle = zs_malloc(zram->mem_pool, comp_len,
+-                      __GFP_KSWAPD_RECLAIM |
+-                      __GFP_NOWARN |
+-                      __GFP_HIGHMEM |
+-                      __GFP_MOVABLE);
+-
+-      if (unlikely(!handle)) {
++      /*
++       * handle allocation has 2 paths:
++       * a) fast path is executed with preemption disabled (for
++       *  per-cpu streams) and has __GFP_DIRECT_RECLAIM bit clear,
++       *  since we can't sleep;
++       * b) slow path enables preemption and attempts to allocate
++       *  the page with __GFP_DIRECT_RECLAIM bit set. we have to
++       *  put per-cpu compression stream and, thus, to re-do
++       *  the compression once handle is allocated.
++       *
++       * if we have a 'non-null' handle here then we are coming
++       * from the slow path and handle has already been allocated.
++       */
++      if (!handle)
++              handle = zs_malloc(zram->mem_pool, comp_len,
++                              __GFP_KSWAPD_RECLAIM |
++                              __GFP_NOWARN |
++                              __GFP_HIGHMEM |
++                              __GFP_MOVABLE);
++      if (!handle) {
+               zcomp_stream_put(zram->comp);
++              atomic64_inc(&zram->stats.writestall);
++              handle = zs_malloc(zram->mem_pool, comp_len,
++                              GFP_NOIO | __GFP_HIGHMEM |
++                              __GFP_MOVABLE);
++              if (handle)
++                      goto compress_again;
+               return -ENOMEM;
+       }
+@@ -1946,6 +1967,7 @@ static int zram_add(void)
+       if (ZRAM_LOGICAL_BLOCK_SIZE == PAGE_SIZE)
+               blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
++      blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, zram->disk->queue);
+       ret = device_add_disk(NULL, zram->disk, zram_disk_groups);
+       if (ret)
+               goto out_cleanup_disk;
+--- a/drivers/block/zram/zram_drv.h
++++ b/drivers/block/zram/zram_drv.h
+@@ -81,6 +81,7 @@ struct zram_stats {
+       atomic64_t huge_pages_since;    /* no. of huge pages since zram set up */
+       atomic64_t pages_stored;        /* no. of pages currently stored */
+       atomic_long_t max_used_pages;   /* no. of maximum pages stored */
++      atomic64_t writestall;          /* no. of write slow paths */
+       atomic64_t miss_free;           /* no. of missed free */
+ #ifdef        CONFIG_ZRAM_WRITEBACK
+       atomic64_t bd_count;            /* no. of pages in backing device */
index 889eb5f03148f7d45e9873f40b667eb02682700c..f254039ebff1fb6dec6f8b17e9b000417b3b430e 100644 (file)
@@ -129,3 +129,4 @@ xen-privcmd-fix-error-exit-of-privcmd_ioctl_dm_op.patch
 riscv-signal-fix-missing-prototype-warning.patch
 riscv-traps-add-missing-prototype.patch
 riscv-dts-microchip-correct-l2-cache-interrupts.patch
+revert-zram-remove-double-compression-logic.patch