erofs: avoid consecutive detection for Highmem memory
authorGao Xiang <hsiangkao@linux.alibaba.com>
Fri, 8 Jul 2022 10:10:01 +0000 (18:10 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Aug 2022 12:23:12 +0000 (14:23 +0200)
[ Upstream commit 448b5a1548d87c246c3d0c3df8480d3c6eb6c11a ]

Currently, vmap()s are avoided if physical addresses are
consecutive for decompressed buffers.

I observed that is very common for 4KiB pclusters since the
numbers of decompressed pages are almost 2 or 3.

However, such detection doesn't work for Highmem pages on
32-bit machines, let's fix it now.

Reported-by: Liu Jinbao <liujinbao1@xiaomi.com>
Fixes: 7fc45dbc938a ("staging: erofs: introduce generic decompression backend")
Link: https://lore.kernel.org/r/20220708101001.21242-1-hsiangkao@linux.alibaba.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/erofs/decompressor.c

index ad3f313..8193c14 100644 (file)
@@ -93,14 +93,18 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
 
                if (page) {
                        __clear_bit(j, bounced);
-                       if (kaddr) {
-                               if (kaddr + PAGE_SIZE == page_address(page))
+                       if (!PageHighMem(page)) {
+                               if (!i) {
+                                       kaddr = page_address(page);
+                                       continue;
+                               }
+                               if (kaddr &&
+                                   kaddr + PAGE_SIZE == page_address(page)) {
                                        kaddr += PAGE_SIZE;
-                               else
-                                       kaddr = NULL;
-                       } else if (!i) {
-                               kaddr = page_address(page);
+                                       continue;
+                               }
                        }
+                       kaddr = NULL;
                        continue;
                }
                kaddr = NULL;