From nobody Mon Sep 28 05:45:28 2026 Received: from mta1.migadu.com (out-196.mta1.migadu.com [95.215.58.196]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A09B43DCD8A for ; Tue, 25 Aug 2026 22:06:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787695585; cv=none; b=HRDO7y5ouOqCjOd9spXXHbql+VfjiCT4oYLfvQk713dfT/QfVRPka87T2CmSgKkVHQBtiaT7JF2DLGq5UtFige+yNX9k/+iBeTQSYfeJbXgIWlLRVjikRcrtJMZ5fik+5lgepcARZ6RdViGudzxQdYA+cGuYNOpMGiaetz/0RIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787695585; c=relaxed/simple; bh=0i2T135nstI1Jyb/4jvL3GgYI93oGF3oLzgBiHMSwOI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YP8Kd/dX7gG481XkNYPl6UwFy+1kIryfCCLXLLzrYFVqXAOwy+jRiLqlbNQx/OVUtYMW4PEc5l/5KnjhzrV6vycmJ3w/uY8HgZBDje6YTHpAOCH8GTlI+RQfxr7I9lV3zij6unyAv2d2HZIhnIjxxWBdG1ExlojZLvJMHtjuYYU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Ds1Xz3ad; arc=none smtp.client-ip=95.215.58.196 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Ds1Xz3ad" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=0i2T135nstI1Jyb/4jvL3GgYI93oGF3oLzgBiHMSwOI=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787695581; v=1; x=1788300381; b=Ds1Xz3adEhpHRTmATHDhgyQpwT8gXy4g9I7+BCYZvEP7TR6cWOvgHjaEWQRLpRdEujC3D/eg qKwrGC7zorRbS7khkRgO2XystVtVrur28i8Q0/wREnd3P1emStKwi7It0BLmSiQ18HkI4SDSNAF es4bZPDllq61wFcQMdpyO88A= X-Envelope-To: linux-kernel@vger.kernel.org Received: from localhost (2a03:2880:10ff:11::) by mta10.migadu.com with ESMTPS id 5f226bf144225a4c; Tue, 25 Aug 2026 22:06:21 +0000 X-Mizu-Trace-ID: 5f226bf144225a4c X-Migadu-Flow: FLOW_OUT From: Usama Arif To: davem@davemloft.net, dsterba@suse.com, Herbert Xu , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, terrelln@fb.com Cc: hannes@cmpxchg.org, yosry@kernel.org, nphamcs@gmail.com, chengming.zhou@linux.dev, shakeel.butt@linux.dev, kernel-team@meta.com, Usama Arif Subject: [PATCH 1/2] crypto: zstd - Avoid redundant cstream initialization Date: Tue, 25 Aug 2026 15:06:01 -0700 Message-ID: <20260825220616.3842633-2-usama.arif@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260825220616.3842633-1-usama.arif@linux.dev> References: <20260825220616.3842633-1-usama.arif@linux.dev> 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" zstd_compress() initializes the shared workspace as a CStream before entering the walk loop. If the first source and destination fragments each span the whole request it then hands off to zstd_compress_one(), which initializes that same ctx->wksp as a CCtx, discarding the CStream setup without having compressed a byte. zswap always takes this one-shot path when storing, so every page it stores paid for both. Neither is cheap: zstd_init_cstream() redoes the cwksp layout, zeroes the ZSTD_CCtx, probes for BMI2 through ZSTD_cpuid(), then resets the session and parameters and replays ten validated ZSTD_CCtx_setParameter() calls. Defer the CStream initialization to the first walk iteration that needs it, guarded by a flag because that iteration can be reached more than once. The first inner iteration either takes the one-shot path and returns or initializes the CStream, so the trailing zstd_end_stream() cannot pick up the stale context left in ctx->cctx by an earlier request. Unlike the old call site the new one runs with the walk's fragments mapped, so it has to release them before failing. For a 4 KB crypto_acomp benchmark for compression, twelve runs of nine 30K operation rounds, on the bare-metal host the median per-round mean request time fell from 52,283 ns to 51,038 ns (2.4%). In the one-vCPU KVM guest it fell from 16,675 ns to 15,050 ns (9.8%). The larger improvement in guest is because of the pair of CPUID instructions in ZSTD_cpuid() that the removed initialization runs. Signed-off-by: Usama Arif --- crypto/zstd.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/crypto/zstd.c b/crypto/zstd.c index 556f5d2bdd5fb..d64472f3e11e5 100644 --- a/crypto/zstd.c +++ b/crypto/zstd.c @@ -96,6 +96,7 @@ static int zstd_compress_one(struct acomp_req *req, struc= t zstd_ctx *ctx, =20 static int zstd_compress(struct acomp_req *req) { + bool stream_initialized =3D false; struct crypto_acomp_stream *s; unsigned int pos, scur, dcur; unsigned int total_out =3D 0; @@ -115,12 +116,6 @@ static int zstd_compress(struct acomp_req *req) if (ret) goto out; =20 - ctx->cctx =3D zstd_init_cstream(&ctx->params, 0, ctx->wksp, ctx->wksp_siz= e); - if (!ctx->cctx) { - ret =3D -EINVAL; - goto out; - } - do { dcur =3D acomp_walk_next_dst(&walk); if (!dcur) { @@ -142,6 +137,19 @@ static int zstd_compress(struct acomp_req *req) goto out; } =20 + if (!stream_initialized) { + ctx->cctx =3D zstd_init_cstream(&ctx->params, 0, + ctx->wksp, ctx->wksp_size); + if (!ctx->cctx) { + /* Release in the reverse of the map order. */ + acomp_walk_done_src(&walk, 0); + acomp_walk_done_dst(&walk, 0); + ret =3D -EINVAL; + goto out; + } + stream_initialized =3D true; + } + if (scur) { inbuf.pos =3D 0; inbuf.src =3D walk.src.virt.addr; --=20 2.53.0-Meta From nobody Mon Sep 28 05:45:28 2026 Received: from mta1.migadu.com (out-200.mta1.migadu.com [95.215.58.200]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B2CD3F4DFE for ; Tue, 25 Aug 2026 22:06:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.200 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787695587; cv=none; b=ow+QM+Pk7NPdvAMkC/0ByvSG6WHc2Wu6U5vyaWrCofBPgxWddBDAUq3q42+hVEK5TimexGr8PM5RngRga1HD8ryvH5W4aU8Cs6akXKBUh5HkN6fCzQEAZqHtMARtJR7M/UH1ABt6Xz/XtjzLx6Vp/NsIepQwANjSlEXoO+utItM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787695587; c=relaxed/simple; bh=kfl8eHfriQk9KJ2Dns1uaqm0darKcxxQoENqeOcFaiQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h6amZkARf8Q2rUc/LwwpI4mnwc3s7AYFo5TlyE+M77Ay1DRk9dLTUy4BtwiujGdoKhc2O/YPY+ta/+FC1Srlm5g9uUgNIWo9DrFemUs6MIOg/eSKNiIv5DhTi/b0ZM+yla2yQ75+MzAO0f/jLtXD7NJHnHp+9g4D35eWMw5xnoA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Iwku/njJ; arc=none smtp.client-ip=95.215.58.200 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Iwku/njJ" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=kfl8eHfriQk9KJ2Dns1uaqm0darKcxxQoENqeOcFaiQ=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787695583; v=1; x=1788300383; b=Iwku/njJ9H51NuigwcsfzUNk95uJ9EXLEDwfvM1RAeSjVPTVoliCRXgwm/dVRGalYXgjhHx3 ZxrhWclQDrfxIkhgkAueeozYRl6wlYWgrbHiq0Rhznquh2PY5FpvrYZ+trbKn6Rno2jxreKSRy1 WsdipPS2b2w2RSut3d0kGeZQ= X-Envelope-To: linux-kernel@vger.kernel.org Received: from localhost (2a03:2880:10ff:8::) by mta11.migadu.com with ESMTPS id 20a3fe3baad05ad2; Tue, 25 Aug 2026 22:06:23 +0000 X-Mizu-Trace-ID: 20a3fe3baad05ad2 X-Migadu-Flow: FLOW_OUT From: Usama Arif To: davem@davemloft.net, dsterba@suse.com, Herbert Xu , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, terrelln@fb.com Cc: hannes@cmpxchg.org, yosry@kernel.org, nphamcs@gmail.com, chengming.zhou@linux.dev, shakeel.butt@linux.dev, kernel-team@meta.com, Usama Arif Subject: [PATCH 2/2] crypto: zstd - Avoid redundant dstream initialization Date: Tue, 25 Aug 2026 15:06:02 -0700 Message-ID: <20260825220616.3842633-3-usama.arif@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260825220616.3842633-1-usama.arif@linux.dev> References: <20260825220616.3842633-1-usama.arif@linux.dev> 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" zstd_decompress() initializes the shared workspace as a DStream before entering the walk loop. If the first source and destination fragments each span the whole request it then hands off to zstd_decompress_one(), which initializes that same ctx->wksp as a DCtx, discarding the DStream setup without having decompressed a byte. The two are in fact the same routine, as ZSTD_initStaticDStream() is a tail call to ZSTD_initStaticDCtx() and zstd_init_dstream() discards its max_window_size argument, so the work was done twice byte for byte. zswap takes this path whenever the stored object lies within a single zsmalloc page, which is the common case; an object straddling a page boundary comes back from zs_obj_read_sg_begin() as a two-entry source scatterlist and streams instead. Defer the DStream initialization to the first walk iteration that reaches the streaming path, guarded by a flag because that iteration can be reached more than once. Within this function ctx->dctx is read only by the zstd_decompress_stream() call immediately below, so no stale context can be picked up. As in the previous patch the new call site runs with the walk's fragments mapped and has to release them before failing. For a 4 KB crypto_acomp benchmark for decompression, twelve runs of nine 30K operation rounds, on the bare-metal host the median per-round mean request time fell from 2,317 ns to 1,998 ns (13.8%). In the one-vCPU KVM guest it fell from 3,516 ns to 2,265 ns (35.6%). Signed-off-by: Usama Arif --- crypto/zstd.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/crypto/zstd.c b/crypto/zstd.c index d64472f3e11e5..76bdaca327330 100644 --- a/crypto/zstd.c +++ b/crypto/zstd.c @@ -215,6 +215,7 @@ static int zstd_decompress_one(struct acomp_req *req, s= truct zstd_ctx *ctx, =20 static int zstd_decompress(struct acomp_req *req) { + bool stream_initialized =3D false; struct crypto_acomp_stream *s; unsigned int total_out =3D 0; unsigned int scur, dcur; @@ -232,12 +233,6 @@ static int zstd_decompress(struct acomp_req *req) if (ret) goto out; =20 - ctx->dctx =3D zstd_init_dstream(ZSTD_MAX_SIZE, ctx->wksp, ctx->wksp_size); - if (!ctx->dctx) { - ret =3D -EINVAL; - goto out; - } - do { scur =3D acomp_walk_next_src(&walk); if (scur) { @@ -263,6 +258,19 @@ static int zstd_decompress(struct acomp_req *req) goto out; } =20 + if (!stream_initialized) { + ctx->dctx =3D zstd_init_dstream(ZSTD_MAX_SIZE, ctx->wksp, + ctx->wksp_size); + if (!ctx->dctx) { + /* Release in the reverse of the map order. */ + acomp_walk_done_dst(&walk, 0); + acomp_walk_done_src(&walk, 0); + ret =3D -EINVAL; + goto out; + } + stream_initialized =3D true; + } + outbuf.pos =3D 0; outbuf.dst =3D (u8 *)walk.dst.virt.addr; outbuf.size =3D dcur; --=20 2.53.0-Meta