From nobody Mon Oct 6 13:58:50 2025 Received: from out30-99.freemail.mail.aliyun.com (out30-99.freemail.mail.aliyun.com [115.124.30.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E5EF2E1C6F; Tue, 22 Jul 2025 10:00:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.99 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753178446; cv=none; b=LpmyFvYYtMxWlBDUnDHBHlKV0k+3qebayFU0coEtAAywDlDy/+r4EZ+X7S4y/1yqImWWwotenaShJgavqKzW7FckdWisS6+IY2HnH6OsH3cMkE4/ciN9/UrRQeriWEobUsvYV54eGYXL6yDmM77XiFue+hm/wfbY8gwurKu27pI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753178446; c=relaxed/simple; bh=g7DTeiU4l5ar4apv/BbvkLZpwqIuHBj5jZ5VmSEh0rY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fxcCX5V7jG/pzdxCetROj5YUs19yiabFC0X3bcQlLB5M+TbzrYt70cH6xqu/3eCnwwbp6YmNdTv5eYF51f7kB+BsiFV6sM59JUbCsnZAIF1Twe5Ou38YV7WVGVkxhdjRWtboNhc8/vsrRNLJnLLthKqyw3hhJhOds53NEmMHjE4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=x5dJz2Na; arc=none smtp.client-ip=115.124.30.99 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="x5dJz2Na" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1753178441; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=cx+jOLR3PxH0EA25EZkKjnVRPI1GcY1CKzTmwRgcd+w=; b=x5dJz2NazUnQJ/4TXNhSa35C/SwlhTV9bg3hejBKC1RmHeZVqsmZPFxfwu5MWGnYpgysvxD4Z9d+RR4qeS3iAg7ZKkBCiXG49OKrJhWeJA99t+H8arF5FzUUOj1vUfmtEl3QuZw5WvsMDdC+PM0Jbxwr7B+/+PHA2Zu67O6WqNk= Received: from x31i01179.sqa.na131.tbsite.net(mailfrom:hsiangkao@linux.alibaba.com fp:SMTPD_---0WjVvTsC_1753178440 cluster:ay36) by smtp.aliyun-inc.com; Tue, 22 Jul 2025 18:00:41 +0800 From: Gao Xiang To: stable@vger.kernel.org, Greg Kroah-Hartman , Jan Kiszka , Stefan Kerkmann Cc: linux-erofs@lists.ozlabs.org, LKML , Gao Xiang Subject: [PATCH 6.1.y 5/5] erofs: address D-cache aliasing Date: Tue, 22 Jul 2025 18:00:29 +0800 Message-ID: <20250722100029.3052177-6-hsiangkao@linux.alibaba.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250722100029.3052177-1-hsiangkao@linux.alibaba.com> References: <20250722100029.3052177-1-hsiangkao@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" commit 27917e8194f91dffd8b4825350c63cb68e98ce58 upstream. Flush the D-cache before unlocking folios for compressed inodes, as they are dirtied during decompression. Avoid calling flush_dcache_folio() on every CPU write, since it's more like playing whack-a-mole without real benefit. It has no impact on x86 and arm64/risc-v: on x86, flush_dcache_folio() is a no-op, and on arm64/risc-v, PG_dcache_clean (PG_arch_1) is clear for new page cache folios. However, certain ARM boards are affected, as reported. Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") Closes: https://lore.kernel.org/r/c1e51e16-6cc6-49d0-a63e-4e9ff6c4dd53@peng= utronix.de Closes: https://lore.kernel.org/r/38d43fae-1182-4155-9c5b-ffc7382d9917@siem= ens.com Tested-by: Jan Kiszka Tested-by: Stefan Kerkmann Link: https://lore.kernel.org/r/20250709034614.2780117-2-hsiangkao@linux.al= ibaba.com Signed-off-by: Gao Xiang --- fs/erofs/decompressor.c | 6 ++---- fs/erofs/zdata.c | 32 +++++++++++++++++++------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index b1746215efe6..e524c0b432f3 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -342,14 +342,12 @@ static int z_erofs_transform_plain(struct z_erofs_dec= ompress_req *rq, =20 if (outpages > inpages) { DBG_BUGON(!rq->out[outpages - 1]); - if (rq->out[outpages - 1] !=3D rq->in[inpages - 1]) { + if (rq->out[outpages - 1] !=3D rq->in[inpages - 1]) memcpy_to_page(rq->out[outpages - 1], 0, src + (interlaced_offset ? 0 : righthalf), lefthalf); - } else if (!interlaced_offset) { + else if (!interlaced_offset) memmove(src, src + righthalf, lefthalf); - flush_dcache_page(rq->in[inpages - 1]); - } } kunmap_local(src); return 0; diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index b05ca443cfdf..5e6580217318 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -123,9 +123,11 @@ static inline unsigned int z_erofs_pclusterpages(struc= t z_erofs_pcluster *pcl) =20 /* * bit 30: I/O error occurred on this page + * bit 29: CPU has dirty data in D-cache (needs aliasing handling); * bit 0 - 29: remaining parts to complete this page */ -#define Z_EROFS_PAGE_EIO (1 << 30) +#define Z_EROFS_ONLINEPAGE_EIO 30 +#define Z_EROFS_ONLINEPAGE_DIRTY 29 =20 static inline void z_erofs_onlinepage_init(struct page *page) { @@ -144,7 +146,7 @@ static inline void z_erofs_onlinepage_split(struct page= *page) atomic_inc((atomic_t *)&page->private); } =20 -static void z_erofs_onlinepage_endio(struct page *page, int err) +static void z_erofs_onlinepage_end(struct page *page, int err, bool dirty) { int orig, v; =20 @@ -152,16 +154,20 @@ static void z_erofs_onlinepage_endio(struct page *pag= e, int err) =20 do { orig =3D atomic_read((atomic_t *)&page->private); - v =3D (orig - 1) | (err ? Z_EROFS_PAGE_EIO : 0); + DBG_BUGON(orig <=3D 0); + v =3D dirty << Z_EROFS_ONLINEPAGE_DIRTY; + v |=3D (orig - 1) | (!!err << Z_EROFS_ONLINEPAGE_EIO); } while (atomic_cmpxchg((atomic_t *)&page->private, orig, v) !=3D orig); =20 - if (!(v & ~Z_EROFS_PAGE_EIO)) { - set_page_private(page, 0); - ClearPagePrivate(page); - if (!(v & Z_EROFS_PAGE_EIO)) - SetPageUptodate(page); - unlock_page(page); - } + if (v & (BIT(Z_EROFS_ONLINEPAGE_DIRTY) - 1)) + return; + set_page_private(page, 0); + ClearPagePrivate(page); + if (v & BIT(Z_EROFS_ONLINEPAGE_DIRTY)) + flush_dcache_page(page); + if (!(v & BIT(Z_EROFS_ONLINEPAGE_EIO))) + SetPageUptodate(page); + unlock_page(page); } =20 #define Z_EROFS_ONSTACK_PAGES 32 @@ -925,7 +931,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompre= ss_frontend *fe, goto repeat; =20 out: - z_erofs_onlinepage_endio(page, err); + z_erofs_onlinepage_end(page, err, false); return err; } =20 @@ -1028,7 +1034,7 @@ static void z_erofs_fill_other_copies(struct z_erofs_= decompress_backend *be, cur +=3D len; } kunmap_local(dst); - z_erofs_onlinepage_endio(bvi->bvec.page, err); + z_erofs_onlinepage_end(bvi->bvec.page, err, true); list_del(p); kfree(bvi); } @@ -1196,7 +1202,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs= _decompress_backend *be, /* recycle all individual short-lived pages */ if (z_erofs_put_shortlivedpage(be->pagepool, page)) continue; - z_erofs_onlinepage_endio(page, err); + z_erofs_onlinepage_end(page, err, true); } =20 if (be->decompressed_pages !=3D be->onstack_pages) --=20 2.43.5