From: "Kanchana P. Sridhar" <kanchanapsridhar2026@gmail.com>
To: hannes@cmpxchg.org, yosry@kernel.org, nphamcs@gmail.com,
chengming.zhou@linux.dev, akpm@linux-foundation.org,
linux-mm@kvack.org, herbert@gondor.apana.org.au,
davem@davemloft.net, linux-crypto@vger.kernel.org,
kanchanapsridhar2026@gmail.com, linux-kernel@vger.kernel.org
Cc: rientjes@google.com, willy@infradead.org, senozhatsky@chromium.org
Subject: [PATCH v2 3/8] crypto: acomp - Add trivial segmentation wrapper.
Date: Tue, 27 Oct 2026 20:04:58 -0700 [thread overview]
Message-ID: <20261028030503.17923-4-kanchanapsridhar2026@gmail.com> (raw)
In-Reply-To: <20261028030503.17923-1-kanchanapsridhar2026@gmail.com>
This patch provides a wrapper for existing algorithms so that they can
accept a single segment while returning the compressed length or error
through the dst SG list length.
This trivial segmentation wrapper only supports compression with a
segment count of exactly one.
The reason is that the first user zswap will only allocate the
extra memory if the underlying algorithm supports segmentation,
and otherwise only one segment will be given at a time.
Having this wrapper means that the same calling convention can
be used for all algorithms, regardless of segmentation support.
To gain latency in the zswap_store() hot path impacted by this patch:
1) The most common code path is invoked first in
crypto_acomp_compress().
2) The helper functions used in (1) are made __always_inline.
Co-developed-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Kanchana P Sridhar <kanchana.p.sridhar@intel.com>
Signed-off-by: Kanchana P. Sridhar <kanchanapsridhar2026@gmail.com>
---
crypto/acompress.c | 39 ++++++++++++++++++++++++-----
include/crypto/acompress.h | 3 ++-
include/crypto/internal/acompress.h | 4 +--
include/linux/crypto.h | 2 +-
4 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/crypto/acompress.c b/crypto/acompress.c
index c8b4b8589769..c55b0e8eff3d 100644
--- a/crypto/acompress.c
+++ b/crypto/acompress.c
@@ -166,14 +166,20 @@ static void acomp_save_req(struct acomp_req *req, crypto_completion_t cplt)
state->compl = req->base.complete;
state->data = req->base.data;
+ state->unit_size = req->unit_size;
+ state->flags = req->base.flags & (CRYPTO_ACOMP_REQ_SRC_VIRT |
+ CRYPTO_ACOMP_REQ_DST_VIRT);
+
req->base.complete = cplt;
req->base.data = req;
+ req->unit_size = 0;
}
static void acomp_restore_req(struct acomp_req *req)
{
req->base.complete = req->chain.compl;
req->base.data = req->chain.data;
+ req->unit_size = req->chain.unit_size;
}
static void acomp_reqchain_virt(struct acomp_req *req)
@@ -192,9 +198,6 @@ static void acomp_virt_to_sg(struct acomp_req *req)
{
struct acomp_req_chain *state = &req->chain;
- state->flags = req->base.flags & (CRYPTO_ACOMP_REQ_SRC_VIRT |
- CRYPTO_ACOMP_REQ_DST_VIRT);
-
if (acomp_request_src_isvirt(req)) {
unsigned int slen = req->slen;
const u8 *svirt = req->svirt;
@@ -242,6 +245,10 @@ static int acomp_reqchain_finish(struct acomp_req *req, int err)
{
acomp_reqchain_virt(req);
acomp_restore_req(req);
+
+ if (req->unit_size)
+ req->dst->length = unlikely(err) ? err : req->dlen;
+
return err;
}
@@ -266,10 +273,13 @@ static int acomp_do_req_chain(struct acomp_req *req, bool comp)
{
int err;
+ if (unlikely(req->unit_size && req->slen > req->unit_size))
+ return -ENOSYS;
+
acomp_save_req(req, acomp_reqchain_done);
err = acomp_do_one_req(req, comp);
- if (err == -EBUSY || err == -EINPROGRESS)
+ if (unlikely(err == -EBUSY || err == -EINPROGRESS))
return err;
return acomp_reqchain_finish(req, err);
@@ -279,10 +289,27 @@ int crypto_acomp_compress(struct acomp_req *req)
{
struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+ if (likely((req->unit_size == req->slen) && acomp_request_issg(req) &&
+ !crypto_acomp_req_seg(tfm) && !acomp_req_on_stack(req))) {
+ int err = tfm->compress(req);
+
+ req->dst->length = unlikely(err) ? err : req->dlen;
+ return err;
+ }
+
if (acomp_req_on_stack(req) && acomp_is_async(tfm))
return -EAGAIN;
+
+ if (req->unit_size && acomp_request_issg(req)) {
+ if (!crypto_acomp_req_seg(tfm))
+ return acomp_do_req_chain(req, true);
+
+ return tfm->compress(req);
+ }
+
if (crypto_acomp_req_virt(tfm) || acomp_request_issg(req))
- return crypto_acomp_reqtfm(req)->compress(req);
+ return tfm->compress(req);
+
return acomp_do_req_chain(req, true);
}
EXPORT_SYMBOL_GPL(crypto_acomp_compress);
@@ -294,7 +321,7 @@ int crypto_acomp_decompress(struct acomp_req *req)
if (acomp_req_on_stack(req) && acomp_is_async(tfm))
return -EAGAIN;
if (crypto_acomp_req_virt(tfm) || acomp_request_issg(req))
- return crypto_acomp_reqtfm(req)->decompress(req);
+ return tfm->decompress(req);
return acomp_do_req_chain(req, false);
}
EXPORT_SYMBOL_GPL(crypto_acomp_decompress);
diff --git a/include/crypto/acompress.h b/include/crypto/acompress.h
index 6462fc46f4ec..e64cf422510b 100644
--- a/include/crypto/acompress.h
+++ b/include/crypto/acompress.h
@@ -67,6 +67,7 @@ struct acomp_req_chain {
struct folio *dfolio;
};
u32 flags;
+ u32 unit_size;
};
/**
@@ -294,7 +295,7 @@ static inline void *acomp_request_extra(struct acomp_req *req)
return (void *)((char *)req + len);
}
-static inline bool acomp_req_on_stack(struct acomp_req *req)
+static __always_inline bool acomp_req_on_stack(struct acomp_req *req)
{
return crypto_req_on_stack(&req->base);
}
diff --git a/include/crypto/internal/acompress.h b/include/crypto/internal/acompress.h
index 93ae59623f13..0c0d3fc8a9fc 100644
--- a/include/crypto/internal/acompress.h
+++ b/include/crypto/internal/acompress.h
@@ -146,7 +146,7 @@ void crypto_unregister_acomp(struct acomp_alg *alg);
int crypto_register_acomps(struct acomp_alg *algs, int count);
void crypto_unregister_acomps(struct acomp_alg *algs, int count);
-static inline bool acomp_request_issg(struct acomp_req *req)
+static __always_inline bool acomp_request_issg(struct acomp_req *req)
{
return !(req->base.flags & (CRYPTO_ACOMP_REQ_SRC_VIRT |
CRYPTO_ACOMP_REQ_DST_VIRT));
@@ -189,7 +189,7 @@ static inline bool crypto_acomp_req_virt(struct crypto_acomp *tfm)
return crypto_tfm_req_virt(&tfm->base);
}
-static inline bool crypto_acomp_req_seg(struct crypto_acomp *tfm)
+static __always_inline bool crypto_acomp_req_seg(struct crypto_acomp *tfm)
{
return crypto_tfm_req_seg(&tfm->base);
}
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 78c699ac3f82..0628b62e4946 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -492,7 +492,7 @@ static inline bool crypto_tfm_is_async(struct crypto_tfm *tfm)
return tfm->__crt_alg->cra_flags & CRYPTO_ALG_ASYNC;
}
-static inline bool crypto_req_on_stack(struct crypto_async_request *req)
+static __always_inline bool crypto_req_on_stack(struct crypto_async_request *req)
{
return req->flags & CRYPTO_TFM_REQ_ON_STACK;
}
--
2.39.5
next prev parent reply other threads:[~2026-10-28 3:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 3:04 [PATCH v2 0/8] Batched zswap_store() framework with compression batching Kanchana P. Sridhar
2026-10-28 3:04 ` [PATCH v2 1/8] crypto: acomp - Define a unit_size in struct acomp_req to enable batching. mm: zswap: Set the unit size for zswap to PAGE_SIZE Kanchana P. Sridhar
2026-10-28 3:04 ` [PATCH v2 2/8] crypto: acomp - Add bit to indicate segmentation support Kanchana P. Sridhar
2026-10-28 3:04 ` Kanchana P. Sridhar [this message]
2026-10-28 3:04 ` [PATCH v2 4/8] crypto: acomp - Add API to get a compression algorithm's batch-size Kanchana P. Sridhar
2026-10-28 3:05 ` [PATCH v2 5/8] mm: zswap: Store the folio's node id in the zswap_entry Kanchana P. Sridhar
2026-10-28 3:05 ` [PATCH v2 6/8] mm: zswap: Store large folios in batches Kanchana P. Sridhar
2026-10-28 3:05 ` [PATCH v2 7/8] mm: zswap: Batched zswap_compress() for storing " Kanchana P. Sridhar
2026-10-28 3:05 ` [PATCH v2 8/8] mm: zswap: Refactor and optimize zswap_store_pages() batch operations Kanchana P. Sridhar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261028030503.17923-4-kanchanapsridhar2026@gmail.com \
--to=kanchanapsridhar2026@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=chengming.zhou@linux.dev \
--cc=davem@davemloft.net \
--cc=hannes@cmpxchg.org \
--cc=herbert@gondor.apana.org.au \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--cc=rientjes@google.com \
--cc=senozhatsky@chromium.org \
--cc=willy@infradead.org \
--cc=yosry@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®