From nobody Tue Dec 2 00:04:03 2025 Received: from out30-101.freemail.mail.aliyun.com (out30-101.freemail.mail.aliyun.com [115.124.30.101]) (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 3C59A329E66 for ; Tue, 25 Nov 2025 17:01:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.101 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764090080; cv=none; b=Vz9ZuiAt9mV75cYTcZIpHON6AZ4kw6NZauh7iTFjrP+ykXY2+62e+7+3JR1AwRxil2lKBXUwsfX4JFw+WhiZkebpMnRSLnO2JCySO9U3NoTI+Ru/wAS0Tw+L39UlqIY/6VAqKGcyn28F8wZecbmY7eiJffnW2bDqz2NuqO+t/94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764090080; c=relaxed/simple; bh=7AGOroJeeLB6AQBwgKyG358YHP1yOMkaoZv1fqf4h6E=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=KnozGjJQGWGtj673tpp+1Dyytrmya+lDPos6SkW2zynW+sp8yWE4BwSMJR6BwyCircEI5OVBKR4HMOIPnKWTj7fFFegq06owQ5slvQMLo576DpF4vcASAo3MKNAjOy3aBSbvrxWdVDiT+U4SHbI8LNTH/thsdBkOKxCYxOy/8pE= 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=dWOCGId+; arc=none smtp.client-ip=115.124.30.101 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="dWOCGId+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1764090068; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=Tro2eiXSL6EiV/om/2cjVBkgx7lHHnAf4trK1SQkwCk=; b=dWOCGId+8ghdfn+CfHB6+v9q10M3PGxvcQn4InW3kPmpW0RmhtpimNJzE44n/kf3j13gxHmV/YFrzGMiSVWYnR7jTqHas2W4VFcwuJxo2QICWw5Qq3Y51D0tHcdotdncxlgiSfb4c0HbMqre92HD12i3goeoDtuLEmluokW5k3k= Received: from x31i01179.sqa.na131.tbsite.net(mailfrom:hsiangkao@linux.alibaba.com fp:SMTPD_---0WtOkaCN_1764090063 cluster:ay36) by smtp.aliyun-inc.com; Wed, 26 Nov 2025 01:01:08 +0800 From: Gao Xiang To: linux-erofs@lists.ozlabs.org Cc: LKML , Gao Xiang Subject: [PATCH] erofs: tidy up z_erofs_lz4_handle_overlap() Date: Wed, 26 Nov 2025 01:01:02 +0800 Message-ID: <20251125170102.3604700-1-hsiangkao@linux.alibaba.com> X-Mailer: git-send-email 2.43.5 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" - Add some useful comments to explain inplace I/Os and decompression; - Rearrange the code to get rid of one unnecessary goto. Signed-off-by: Gao Xiang Reviewed-by: Chao Yu --- fs/erofs/decompressor.c | 85 ++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index 354762c9723f..2f4cef67cf64 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -105,44 +105,58 @@ static int z_erofs_lz4_prepare_dstpages(struct z_erof= s_decompress_req *rq, return kaddr ? 1 : 0; } =20 -static void *z_erofs_lz4_handle_overlap(struct z_erofs_decompress_req *rq, +static void *z_erofs_lz4_handle_overlap(const struct z_erofs_decompress_re= q *rq, void *inpage, void *out, unsigned int *inputmargin, int *maptype, bool may_inplace) { - unsigned int oend, omargin, total, i; + unsigned int oend, omargin, cnt, i; struct page **in; - void *src, *tmp; - - if (rq->inplace_io) { - oend =3D rq->pageofs_out + rq->outputsize; - omargin =3D PAGE_ALIGN(oend) - oend; - if (rq->partial_decoding || !may_inplace || - omargin < LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize)) - goto docopy; + void *src; =20 + /* + * If in-place I/O isn't used, for example, the bounce compressed cache + * can hold data for incomplete read requests. Just map the compressed + * buffer as well and decompress directly. + */ + if (!rq->inplace_io) { + if (rq->inpages <=3D 1) { + *maptype =3D 0; + return inpage; + } + kunmap_local(inpage); + src =3D erofs_vm_map_ram(rq->in, rq->inpages); + if (!src) + return ERR_PTR(-ENOMEM); + *maptype =3D 1; + return src; + } + /* + * Then, deal with in-place I/Os. The reasons why in-place I/O is useful + * are: (1) It minimizes memory footprint during the I/O submission, + * which is useful for slow storage (including network devices and + * low-end HDDs/eMMCs) but with a lot inflight I/Os; (2) If in-place + * decompression can also be applied, it will reuse the unique buffer so + * that no extra CPU D-cache is polluted with temporary compressed data + * for extreme performance. + */ + oend =3D rq->pageofs_out + rq->outputsize; + omargin =3D PAGE_ALIGN(oend) - oend; + if (!rq->partial_decoding && may_inplace && + omargin >=3D LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize)) { for (i =3D 0; i < rq->inpages; ++i) if (rq->out[rq->outpages - rq->inpages + i] !=3D rq->in[i]) - goto docopy; - kunmap_local(inpage); - *maptype =3D 3; - return out + ((rq->outpages - rq->inpages) << PAGE_SHIFT); - } - - if (rq->inpages <=3D 1) { - *maptype =3D 0; - return inpage; + break; + if (i >=3D rq->inpages) { + kunmap_local(inpage); + *maptype =3D 3; + return out + ((rq->outpages - rq->inpages) << PAGE_SHIFT); + } } - kunmap_local(inpage); - src =3D erofs_vm_map_ram(rq->in, rq->inpages); - if (!src) - return ERR_PTR(-ENOMEM); - *maptype =3D 1; - return src; - -docopy: - /* Or copy compressed data which can be overlapped to per-CPU buffer */ - in =3D rq->in; + /* + * If in-place decompression can't be applied, copy compressed data that + * may potentially overlap during decompression to a per-CPU buffer. + */ src =3D z_erofs_get_gbuf(rq->inpages); if (!src) { DBG_BUGON(1); @@ -150,20 +164,13 @@ static void *z_erofs_lz4_handle_overlap(struct z_erof= s_decompress_req *rq, return ERR_PTR(-EFAULT); } =20 - tmp =3D src; - total =3D rq->inputsize; - while (total) { - unsigned int page_copycnt =3D - min_t(unsigned int, total, PAGE_SIZE - *inputmargin); - + for (i =3D 0, in =3D rq->in; i < rq->inputsize; i +=3D cnt, ++in) { + cnt =3D min_t(u32, rq->inputsize - i, PAGE_SIZE - *inputmargin); if (!inpage) inpage =3D kmap_local_page(*in); - memcpy(tmp, inpage + *inputmargin, page_copycnt); + memcpy(src + i, inpage + *inputmargin, cnt); kunmap_local(inpage); inpage =3D NULL; - tmp +=3D page_copycnt; - total -=3D page_copycnt; - ++in; *inputmargin =3D 0; } *maptype =3D 2; --=20 2.43.5