From: Eric Biggers <ebiggers@kernel.org>
To: Yuwen Chen <ywen.chen@foxmail.com>
Cc: davem@davemloft.net, herbert@gondor.apana.org.au,
jaegeuk@kernel.org, linux-crypto@vger.kernel.org,
linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org,
tytso@mit.edu
Subject: Re: [PATCH v2] fscrypt: improve filename encryption and decryption performance
Date: Thu, 3 Jul 2025 22:14:41 -0700 [thread overview]
Message-ID: <20250704051441.GA4199@sol> (raw)
In-Reply-To: <tencent_583C288FFF6BA70BAF0880FB7A5CCAB5EA05@qq.com>
On Fri, Jul 04, 2025 at 12:13:22PM +0800, Yuwen Chen wrote:
> With the CONFIG_UNICODE configuration enabled, the fname_decrypt
> and fscrypt_fname_encrypt functions may be called very frequently.
> Since filenames are generally short, the frequent invocation of
> memory allocation and release operations by these two functions
> will lead to very poor performance.
>
> Use the following program to conduct a file-creation test in
> the private program directory(/data/media/0/Android/data/*)
> of Android.
>
> int main(int argc, char **argv)
> {
> size_t fcnt = 0;
> char path[PATH_MAX];
> char buf[4096] = {0};
> int i, fd;
>
> if (argc < 2)
> return - EINVAL;
>
> fcnt = atoi(argv[1]);
> for (i = 0; i < fcnt; i++) {
> snprintf(path, sizeof(path), "./%d", i);
> fd = open(path, O_RDWR | O_CREAT, 0600);
> if (fd < 0)
> return - 1;
> write(fd, buf, sizeof(buf));
> close(fd);
> }
> return 0;
> }
>
> The test platform is Snapdragon 8s Gen4, with a kernel version
> of v6.6 and a userdebug version.
>
> Before this submission was merged, when creating 2000 files,
> the performance test results are as follows:
> $ time /data/file_creater 2000
> 0m14.83s real 0m00.00s user 0m14.30s system
> 0m15.61s real 0m00.00s user 0m15.04s system
> 0m14.72s real 0m00.01s user 0m14.18s system
>
> After this submission was merged, the performance is as follows:
> $ time /data/file_creater 2000
> 0m07.64s real 0m00.00s user 0m07.37s system
> 0m07.66s real 0m00.00s user 0m07.40s system
> 0m08.67s real 0m00.01s user 0m08.35s system
>
> Signed-off-by: Yuwen Chen <ywen.chen@foxmail.com>
> ---
> fs/crypto/fname.c | 22 ++++++++++++++--------
> include/crypto/skcipher.h | 9 +++++++++
> 2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
> index 010f9c0a4c2f1..168b2a88fa23b 100644
> --- a/fs/crypto/fname.c
> +++ b/fs/crypto/fname.c
> @@ -92,14 +92,20 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
> int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
> u8 *out, unsigned int olen)
> {
> - struct skcipher_request *req = NULL;
> DECLARE_CRYPTO_WAIT(wait);
> const struct fscrypt_inode_info *ci = inode->i_crypt_info;
> struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
> + SKCIPHER_REQUEST_ON_STACK(req, tfm, MAX_SKCIPHER_REQSIZE);
> union fscrypt_iv iv;
> struct scatterlist sg;
> int res;
>
> + /*
> + * When the size of the statically - allocated skcipher_request
> + * structure is insufficient, remind us to make modifications.
> + */
> + BUG_ON(MAX_SKCIPHER_REQSIZE < crypto_skcipher_reqsize(tfm));
> +
> /*
> * Copy the filename to the output buffer for encrypting in-place and
> * pad it with the needed number of NUL bytes.
> @@ -124,7 +130,6 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
>
> /* Do the encryption */
> res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
> - skcipher_request_free(req);
> if (res < 0) {
> fscrypt_err(inode, "Filename encryption failed: %d", res);
> return res;
I'm guessing you have some debugging options enabled in your kconfig. Usually
the allocations aren't quite *that* expensive. That being said, it's always
been really annoying that they have to be there.
Unfortunately, as far as I know, you actually can't just allocate the
skcipher_request on the stack like that, since the legacy crypto API assumes
that the request memory is DMA-able. On-stack requests also might not be
properly aligned (see
https://lore.kernel.org/all/CA+55aFxJOzMim_d-O2E2yip8JWo0NdYs_72sNwFKSkTjy8q0Sw@mail.gmail.com/
-- may be outdated, but I haven't heard otherwise).
The problem is really that the legacy crypto API (crypto_skcipher in this case)
was never really designed for efficient CPU-based crypto in the first place.
The correct solution is to add simple library APIs for the algorithms to
lib/crypto/, then update fscrypt to use that instead of crypto_skcipher.
I plan to do that, but I'm first focusing on other related things, such as doing
the same for fsverity.
- Eric
next prev parent reply other threads:[~2025-07-04 5:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-03 6:19 [PATCH] fscrypt: improve filename encryption and decryption performance Yuwen Chen
2025-07-04 4:13 ` [PATCH v2] " Yuwen Chen
2025-07-04 5:14 ` Eric Biggers [this message]
2025-07-08 7:33 ` Yuwen Chen
2025-07-08 18:20 ` Eric Biggers
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=20250704051441.GA4199@sol \
--to=ebiggers@kernel.org \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=jaegeuk@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=ywen.chen@foxmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.