From: Herbert Xu <herbert@gondor.apana.org.au>
To: Eric Biggers <ebiggers@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
"David S. Miller" <davem@davemloft.net>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Linux Crypto Mailing List <linux-crypto@vger.kernel.org>
Subject: Chaining is dead
Date: Sun, 30 Mar 2025 10:33:23 +0800 [thread overview]
Message-ID: <Z-itc_Qd5LLn19pH@gondor.apana.org.au> (raw)
In-Reply-To: <Z-N55Yjve6wTnPqm@gondor.apana.org.au>
On Wed, Mar 26, 2025 at 11:52:05AM +0800, Herbert Xu wrote:
>
> they don't need it. Take ext4 as an example:
>
> ext4 calls verity
> schedule_work(verity_work);
> return asynchronously!
>
> verity_work:
> do the crypto work
> __read_end_io(bio);
I went ahead and removed the work queue for fsverity and fscrypt
(except for the reading of the Merkle tree which is still done in
a work queue because I'm too lazy to make that async), and it
actually turned out to be slower than using a work queue.
I was testing with an encrypted 8GB file over ext4 mounted over a
loopback device in tmpfs. The encryption is with xts-vaes. It turns
out that not using a work queue actually made reading the entire file
go from 2.4s to 2.5s.
I then tried passing the whole bio (256KB per crypto request in my
test as opposed to the data unit size of 4KB per crypto request)
through using chaining to skcipher, with xts-vaes doing the requests
one-by-one. Against my expectations, this didn't speed things up at
all (but at least it didn't slow things down either). All the
benefits of aggregating the data were offset by the extra setup cost
of creating the chained requests.
So chaining is clearly not the way to go because it involves cutting
up into data units at the start of the process, rather than the end.
Finally I hacked up a patch (this goes on top of the skcipher branch
in cryptodev) to pass the whole bio through the Crypto API all the
way to xts-vaes which then unbundled it. This turned out to be a
winner, taking the read time for 8GB from 2.4s down to 2.1s.
In view of this result, I'm going to throw away chaining, and instead
work on an interface that can take a whole bio (or folio), then cut
it up into the specified data unit size before processing.
The bottom-end of the interface should be able to feed two (or whatever
number you fancy) data units to the actual algorithm.
This should work just as well for compression, since their batching
input is simply a order-N folio. The compression output is a bit
harder because the data unit size is not constant, but I think I
have a way of making it work by adding a bit to the scatterlist data
structure to indicate the end of each data unit.
PS For fsverity a 256KB bio size equates to 64 units of hash input.
My strategy is to allocate the whole thing if we can (2KB or 4KB
depending on your digest size), and if that fails, fall back to
a stack buffer of 512 bytes (or whatever number that keeps the
compiler quiet regarding stack usage). Even if we're on the stack,
it should still give more than enough to data to satiate your
multibuffer hash code.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 4f721760ebf1..57d149c223bd 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -17,6 +17,7 @@
* Copyright 2024 Google LLC
*/
+#include <linux/bio.h>
#include <linux/hardirq.h>
#include <linux/types.h>
#include <linux/module.h>
@@ -480,7 +481,7 @@ xts_crypt_slowpath(struct skcipher_request *req, xts_crypt_func crypt_func)
/* __always_inline to avoid indirect call in fastpath */
static __always_inline int
-xts_crypt(struct skcipher_request *req, xts_encrypt_iv_func encrypt_iv,
+xts_crypt_one(struct skcipher_request *req, xts_encrypt_iv_func encrypt_iv,
xts_crypt_func crypt_func)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
@@ -511,6 +512,42 @@ xts_crypt(struct skcipher_request *req, xts_encrypt_iv_func encrypt_iv,
return xts_crypt_slowpath(req, crypt_func);
}
+static __always_inline int
+xts_crypt(struct skcipher_request *req, xts_encrypt_iv_func encrypt_iv,
+ xts_crypt_func crypt_func)
+{
+ unsigned int du_bits = req->cryptlen;
+ unsigned int du_size = 1U << du_bits;
+ __le64 *iv = (void *)req->iv;
+ struct folio_iter fi;
+ struct bio *bio;
+ int err;
+
+ if (!(req->base.flags & CRYPTO_SKCIPHER_REQ_BIO))
+ return xts_crypt_one(req, encrypt_iv, crypt_func);
+
+ bio = (void *)req->src;
+
+ for (bio_first_folio(&fi, bio, 0); fi.folio; bio_next_folio(&fi, bio)) {
+ size_t i = fi.offset;
+
+ for (; i < fi.offset + fi.length; i += du_size) {
+ skcipher_request_set_folio(req, fi.folio, i, fi.folio, i, du_size, iv);
+ err = xts_crypt_one(req, encrypt_iv, crypt_func);
+ if (err)
+ goto out;
+
+ *iv = cpu_to_le64(le64_to_cpu(*iv) + 1);
+ }
+ }
+
+out:
+ req->src = (void *)bio;
+ req->dst = (void *)bio;
+ req->cryptlen = du_bits;
+ return err;
+}
+
static void aesni_xts_encrypt_iv(const struct crypto_aes_ctx *tweak_key,
u8 iv[AES_BLOCK_SIZE])
{
diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c
index 0ad8c30b8fa5..9f52dc7f7889 100644
--- a/fs/crypto/bio.c
+++ b/fs/crypto/bio.c
@@ -7,6 +7,7 @@
* Copyright (C) 2015, Motorola Mobility
*/
+#include <crypto/skcipher.h>
#include <linux/pagemap.h>
#include <linux/module.h>
#include <linux/bio.h>
@@ -30,16 +31,49 @@
*/
bool fscrypt_decrypt_bio(struct bio *bio)
{
+ struct folio *folio = bio_first_folio_all(bio);
+ const struct inode *inode = folio->mapping->host;
+ const struct fscrypt_inode_info *ci = inode->i_crypt_info;
+ const unsigned int du_bits = ci->ci_data_unit_bits;
+ struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
+ SKCIPHER_REQUEST_ON_STACK(req, tfm, sizeof(bio));
+ struct bio **ctx = skcipher_request_extra(req);
+ DECLARE_CRYPTO_WAIT(wait);
struct folio_iter fi;
+ union fscrypt_iv iv;
+ u64 index;
+ int err;
- bio_for_each_folio_all(fi, bio) {
- int err = fscrypt_decrypt_pagecache_blocks(fi.folio, fi.length,
- fi.offset);
+ *ctx = bio;
- if (err) {
- bio->bi_status = errno_to_blk_status(err);
- return false;
- }
+ bio_first_folio(&fi, bio, 0);
+ if (!fi.folio)
+ return true;
+
+ index = fi.offset;
+ index = ((u64)fi.folio->index << (PAGE_SHIFT - du_bits)) +
+ (index >> du_bits);
+ fscrypt_generate_iv(&iv, index, ci);
+
+ skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+ CRYPTO_SKCIPHER_REQ_BIO,
+ NULL, NULL);
+ skcipher_request_set_crypt(req, (struct scatterlist *)bio,
+ (struct scatterlist *)bio, du_bits, &iv);
+
+ err = crypto_skcipher_decrypt(req);
+ if (err == -EAGAIN) {
+ req = SKCIPHER_REQUEST_CLONE(req, GFP_ATOMIC);
+ skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+ CRYPTO_SKCIPHER_REQ_BIO,
+ crypto_req_done, &wait);
+ err = crypto_skcipher_decrypt(req);
+ }
+ err = crypto_wait_req(err, &wait);
+ skcipher_request_free(req);
+ if (err) {
+ bio->bi_status = errno_to_blk_status(err);
+ return false;
}
return true;
}
diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
index e159ea68124e..931585f864d1 100644
--- a/include/crypto/skcipher.h
+++ b/include/crypto/skcipher.h
@@ -26,6 +26,8 @@
#define CRYPTO_SKCIPHER_REQ_CONT 0x00000001
/* Set this bit if the skcipher operation is not final. */
#define CRYPTO_SKCIPHER_REQ_NOTFINAL 0x00000002
+/* Set this bit if the skcipher is made of bio. */
+#define CRYPTO_SKCIPHER_REQ_BIO 0x00000004
/**
* struct skcipher_request - Symmetric key cipher request
next prev parent reply other threads:[~2025-03-30 2:33 UTC|newest]
Thread overview: 204+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-03 4:40 [GIT PULL] Crypto Update for 5.9 Herbert Xu
2020-08-03 17:55 ` pr-tracker-bot
2020-08-30 22:33 ` [GIT PULL] Crypto Fixes " Herbert Xu
2020-08-30 23:02 ` pr-tracker-bot
2020-09-10 0:34 ` Herbert Xu
2020-09-10 2:48 ` pr-tracker-bot
2020-10-26 1:11 ` [GIT PULL] Crypto Fixes for 5.10 Herbert Xu
2020-10-26 17:52 ` pr-tracker-bot
2020-12-27 11:32 ` [GIT PULL] Crypto Fixes for 5.11 Herbert Xu
2020-12-27 17:27 ` pr-tracker-bot
2021-01-08 3:54 ` Herbert Xu
2021-01-08 20:36 ` pr-tracker-bot
2021-01-18 5:13 ` Herbert Xu
2021-01-18 21:16 ` pr-tracker-bot
2021-01-25 22:36 ` Herbert Xu
2021-01-26 0:01 ` pr-tracker-bot
2021-07-08 3:09 ` [GIT PULL] Crypto Fixes for 5.14 Herbert Xu
2021-07-09 19:20 ` pr-tracker-bot
2021-08-17 1:36 ` Herbert Xu
2021-08-17 2:27 ` pr-tracker-bot
2021-09-29 2:38 ` [GIT PULL] Crypto Fixes for 5.15 Herbert Xu
2021-09-29 14:51 ` pr-tracker-bot
2021-10-29 4:14 ` Herbert Xu
2021-10-29 17:39 ` Linus Torvalds
2021-11-02 4:01 ` Herbert Xu
2021-10-29 18:49 ` pr-tracker-bot
2021-11-12 10:48 ` [GIT PULL] Crypto Fixes for 5.16 Herbert Xu
2021-11-12 20:42 ` pr-tracker-bot
2021-12-22 5:13 ` Herbert Xu
2021-12-22 19:02 ` pr-tracker-bot
2022-02-09 2:33 ` [GIT PULL] Crypto Fixes for 5.17 Herbert Xu
2022-02-09 18:01 ` pr-tracker-bot
2022-03-16 1:13 ` Herbert Xu
2022-03-17 20:40 ` pr-tracker-bot
2022-03-31 3:16 ` [GIT PULL] Crypto Fixes for 5.18 Herbert Xu
2022-03-31 19:12 ` pr-tracker-bot
2022-05-20 5:41 ` Herbert Xu
2022-05-20 6:10 ` pr-tracker-bot
2022-05-27 11:29 ` [GIT PULL] Crypto Fixes for 5.19 Herbert Xu
2022-05-28 1:21 ` pr-tracker-bot
2022-06-17 8:29 ` Herbert Xu
2022-06-17 15:29 ` pr-tracker-bot
2022-06-30 7:56 ` Herbert Xu
2022-06-30 17:28 ` pr-tracker-bot
2022-08-31 8:55 ` [GIT PULL] Crypto Fixes for 6.0 Herbert Xu
2022-08-31 17:20 ` pr-tracker-bot
2022-10-17 4:38 ` [GIT PULL] Crypto Fixes for 6.1 Herbert Xu
2022-10-17 17:51 ` pr-tracker-bot
2022-10-28 4:58 ` Herbert Xu
2022-10-28 17:00 ` Linus Torvalds
2022-11-02 9:49 ` Herbert Xu
2022-10-28 17:02 ` pr-tracker-bot
2023-01-06 9:15 ` [GIT PULL] Crypto Fixes for 6.2 Herbert Xu
2023-01-06 21:19 ` pr-tracker-bot
2023-03-05 10:15 ` [GIT PULL] Crypto Fixes for 6.3 Herbert Xu
2023-03-05 19:37 ` pr-tracker-bot
2023-05-07 13:19 ` [GIT PULL] Crypto Fixes for 6.4 Herbert Xu
2023-05-07 18:12 ` pr-tracker-bot
2023-05-29 3:41 ` Herbert Xu
2023-05-29 11:39 ` pr-tracker-bot
2023-07-09 23:51 ` [GIT PULL] Crypto Fixes for 6.5 Herbert Xu
2023-07-10 17:20 ` pr-tracker-bot
2023-08-21 3:37 ` Herbert Xu
2023-08-21 5:09 ` pr-tracker-bot
2023-08-31 5:16 ` [GIT PULL] Crypto Fixes for 6.6 Herbert Xu
2023-09-01 23:19 ` pr-tracker-bot
2023-09-22 2:10 ` Herbert Xu
2023-09-22 16:43 ` pr-tracker-bot
2023-10-10 8:46 ` Herbert Xu
2023-10-10 18:54 ` pr-tracker-bot
2023-10-21 9:23 ` Herbert Xu
2023-10-21 17:57 ` pr-tracker-bot
2023-11-09 4:30 ` [GIT PULL] Crypto Fixes for 6.7 Herbert Xu
2023-11-10 1:30 ` pr-tracker-bot
2022-08-02 6:05 ` [GIT PULL] Crypto Update for 5.20 Herbert Xu
2022-08-03 0:57 ` pr-tracker-bot
2022-10-04 8:54 ` [GIT PULL] Crypto Update for 6.1 Herbert Xu
2022-10-10 20:56 ` pr-tracker-bot
2022-12-14 8:15 ` [GIT PULL] Crypto Update for 6.2 Herbert Xu
2022-12-14 22:25 ` pr-tracker-bot
2023-02-20 5:22 ` [GIT PULL] Crypto Update for 6.3 Herbert Xu
2023-02-22 2:50 ` pr-tracker-bot
2023-04-24 4:52 ` [GIT PULL] Crypto Update for 6.4 Herbert Xu
2023-04-26 17:06 ` pr-tracker-bot
2023-06-29 5:06 ` [GIT PULL] Crypto Update for 6.5 Herbert Xu
2023-07-01 5:04 ` pr-tracker-bot
2023-08-28 9:22 ` [GIT PULL] Crypto Update for 6.6 Herbert Xu
2023-08-29 19:00 ` pr-tracker-bot
2023-11-02 6:56 ` [GIT PULL] Crypto Update for 6.7 Herbert Xu
2023-11-03 2:34 ` Linus Torvalds
2023-11-03 5:52 ` Herbert Xu
2023-11-03 6:32 ` Linus Torvalds
2023-11-06 10:00 ` [PATCH] crypto: jitterentropy - Hide esoteric Kconfig options under FIPS and EXPERT Herbert Xu
2023-11-06 15:25 ` Stephan Mueller
2023-11-10 9:04 ` Geert Uytterhoeven
2023-11-03 2:37 ` [GIT PULL] Crypto Update for 6.7 pr-tracker-bot
2024-01-09 22:17 ` [GIT PULL] Crypto Update for 6.8 Herbert Xu
2024-01-10 20:38 ` pr-tracker-bot
2024-02-01 5:32 ` [GIT PULL] Crypto Fixes " Herbert Xu
2024-02-01 18:23 ` pr-tracker-bot
2024-02-08 4:29 ` Herbert Xu
2024-02-08 6:24 ` pr-tracker-bot
2024-02-21 9:10 ` Herbert Xu
2024-02-21 17:17 ` pr-tracker-bot
2024-02-28 8:07 ` Herbert Xu
2024-02-28 17:48 ` pr-tracker-bot
2024-03-06 9:47 ` Herbert Xu
2024-03-06 16:33 ` pr-tracker-bot
2024-03-25 9:47 ` [GIT PULL] Crypto Fixes for 6.9 Herbert Xu
2024-03-25 18:18 ` pr-tracker-bot
2024-05-20 3:26 ` [GIT PULL] Crypto Fixes for 6.10 Herbert Xu
2024-05-20 16:33 ` pr-tracker-bot
2024-05-29 4:17 ` Herbert Xu
2024-05-29 17:11 ` pr-tracker-bot
2024-06-28 0:40 ` Herbert Xu
2024-06-28 1:01 ` pr-tracker-bot
2024-09-23 3:08 ` [GIT PULL] Crypto Fixes for 6.12 Herbert Xu
2024-09-24 18:04 ` pr-tracker-bot
2024-10-16 5:37 ` Herbert Xu
2024-10-16 20:51 ` pr-tracker-bot
2024-10-21 5:45 ` Herbert Xu
2024-10-21 18:27 ` pr-tracker-bot
2024-11-15 11:51 ` Herbert Xu
2024-11-15 18:59 ` pr-tracker-bot
2024-12-14 9:21 ` [GIT PULL] Crypto Fixes for 6.13 Herbert Xu
2024-12-14 17:18 ` pr-tracker-bot
2025-03-31 4:50 ` [GIT PULL] Crypto Fixes for 6.15 Herbert Xu
2025-04-05 2:23 ` Herbert Xu
2025-04-05 3:09 ` pr-tracker-bot
2025-04-16 5:16 ` Herbert Xu
2025-04-16 15:24 ` pr-tracker-bot
2025-04-24 9:07 ` Herbert Xu
2025-04-24 16:29 ` pr-tracker-bot
2025-04-30 2:47 ` Herbert Xu
2025-04-30 4:19 ` pr-tracker-bot
2025-05-21 1:59 ` Herbert Xu
2025-05-21 3:15 ` pr-tracker-bot
2024-03-15 3:04 ` [GIT PULL] Crypto Update for 6.9 Herbert Xu
2024-03-15 21:51 ` Linus Torvalds
2024-03-16 4:39 ` Herbert Xu
2024-03-15 21:59 ` pr-tracker-bot
2024-05-13 3:50 ` [GIT PULL] Crypto Update for 6.10 Herbert Xu
2024-05-13 22:12 ` Linus Torvalds
2024-05-14 5:17 ` Herbert Xu
2024-05-14 5:41 ` Linus Torvalds
2024-05-14 6:02 ` Herbert Xu
2024-05-14 6:54 ` Lukas Wunner
2024-05-14 17:07 ` Linus Torvalds
2024-05-13 22:38 ` pr-tracker-bot
2024-07-18 13:49 ` [GIT PULL] Crypto Update for 6.11 Herbert Xu
2024-07-19 18:09 ` pr-tracker-bot
2024-09-16 3:59 ` [GIT PULL] Crypto Update for 6.12 Herbert Xu
2024-09-16 4:55 ` pr-tracker-bot
2024-11-18 3:18 ` [GIT PULL] Crypto Update for 6.13 Herbert Xu
2024-11-19 19:06 ` pr-tracker-bot
2025-01-23 11:10 ` [GIT PULL] Crypto Update for 6.14 Herbert Xu
2025-01-24 16:05 ` pr-tracker-bot
2025-03-25 5:53 ` [GIT PULL] Crypto Update for 6.15 Herbert Xu
2025-03-25 15:25 ` Eric Biggers
2025-03-25 16:59 ` Ard Biesheuvel
2025-03-26 1:49 ` Herbert Xu
2025-03-26 2:16 ` Herbert Xu
2025-03-26 3:34 ` Eric Biggers
2025-03-26 3:52 ` Herbert Xu
2025-03-30 2:33 ` Herbert Xu [this message]
2025-03-31 16:56 ` Chaining is dead Eric Biggers
2025-04-01 2:44 ` Herbert Xu
2025-04-01 3:33 ` Eric Biggers
2025-04-01 3:55 ` Herbert Xu
2025-04-01 4:08 ` Eric Biggers
2025-04-01 4:14 ` Herbert Xu
2025-04-01 7:20 ` Milan Broz
2025-04-01 3:30 ` Herbert Xu
2025-04-01 3:39 ` Eric Biggers
2025-04-04 8:46 ` Christoph Hellwig
2025-03-26 3:20 ` [GIT PULL] Crypto Update for 6.15 Eric Biggers
2025-03-26 3:30 ` Herbert Xu
2025-03-29 17:40 ` Linus Torvalds
2025-03-29 18:06 ` Eric Biggers
2025-03-29 18:17 ` Linus Torvalds
2025-03-29 18:19 ` Linus Torvalds
2025-03-29 18:38 ` Eric Biggers
2025-03-29 18:52 ` Linus Torvalds
2025-03-29 18:24 ` pr-tracker-bot
2020-10-12 3:32 ` [GIT PULL] Crypto Update for 5.10 Herbert Xu
2020-10-13 16:24 ` pr-tracker-bot
2020-12-14 5:55 ` [GIT PULL] Crypto Update for 5.11 Herbert Xu
2020-12-14 20:56 ` pr-tracker-bot
2021-02-15 2:47 ` [GIT PULL] Crypto Update for 5.12 Herbert Xu
2021-02-22 1:28 ` pr-tracker-bot
2021-04-26 12:32 ` [GIT PULL] Crypto Update for 5.13 Herbert Xu
2021-04-26 15:59 ` pr-tracker-bot
2021-06-28 11:00 ` [GIT PULL] Crypto Update for 5.14 Herbert Xu
2021-06-28 23:36 ` pr-tracker-bot
2021-08-30 8:28 ` [GIT PULL] Crypto Update for 5.15 Herbert Xu
2021-08-30 20:17 ` pr-tracker-bot
2021-11-02 3:52 ` [GIT PULL] Crypto Update for 5.16 Herbert Xu
2021-11-02 4:27 ` pr-tracker-bot
2022-01-11 2:04 ` [GIT PULL] Crypto Update for 5.17 Herbert Xu
2022-01-11 20:53 ` pr-tracker-bot
2022-03-20 23:42 ` [GIT PULL] Crypto Update for 5.18 Herbert Xu
2022-03-21 23:14 ` Linus Torvalds
2022-03-22 5:49 ` Herbert Xu
2022-03-21 23:18 ` pr-tracker-bot
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=Z-itc_Qd5LLn19pH@gondor.apana.org.au \
--to=herbert@gondor.apana.org.au \
--cc=davem@davemloft.net \
--cc=ebiggers@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@linux-foundation.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