From: Jakub Kicinski <kuba@kernel.org>
To: Dmitry Safonov <dima@arista.com>
Cc: linux-kernel@vger.kernel.org, David Ahern <dsahern@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
"David S. Miller" <davem@davemloft.net>,
Andy Lutomirski <luto@amacapital.net>,
Bob Gilligan <gilligan@arista.com>,
Dmitry Safonov <0x7f454c46@gmail.com>,
Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>,
Leonard Crestez <cdleonard@gmail.com>,
Paolo Abeni <pabeni@redhat.com>,
Salam Noureddine <noureddine@arista.com>,
netdev@vger.kernel.org, linux-crypto@vger.kernel.org
Subject: Re: [PATCH v2 1/5] crypto: Introduce crypto_pool
Date: Fri, 6 Jan 2023 17:53:26 -0800 [thread overview]
Message-ID: <20230106175326.2d6a4dcd@kernel.org> (raw)
In-Reply-To: <20230103184257.118069-2-dima@arista.com>
On Tue, 3 Jan 2023 18:42:53 +0000 Dmitry Safonov wrote:
> Introduce a per-CPU pool of async crypto requests that can be used
> in bh-disabled contexts (designed with net RX/TX softirqs as users in
> mind). Allocation can sleep and is a slow-path.
> Initial implementation has only ahash as a backend and a fix-sized array
> of possible algorithms used in parallel.
>
> Signed-off-by: Dmitry Safonov <dima@arista.com>
> +config CRYPTO_POOL
> + tristate "Per-CPU crypto pool"
> + default n
> + help
> + Per-CPU pool of crypto requests ready for usage in atomic contexts.
Let's make it a hidden symbol? It seems like a low-level library
which gets select'ed, so no point bothering users with questions.
config CRYPTO_POOL
tristate
that's it.
> +static int crypto_pool_scratch_alloc(void)
This isn't called by anything in this patch..
crypto_pool_alloc_ahash() should call it I'm guessing?
> +{
> + int cpu;
> +
> + lockdep_assert_held(&cpool_mutex);
> +
> + for_each_possible_cpu(cpu) {
> + void *scratch = per_cpu(crypto_pool_scratch, cpu);
> +
> + if (scratch)
> + continue;
> +
> + scratch = kmalloc_node(scratch_size, GFP_KERNEL,
> + cpu_to_node(cpu));
> + if (!scratch)
> + return -ENOMEM;
> + per_cpu(crypto_pool_scratch, cpu) = scratch;
> + }
> + return 0;
> +}
> +out_free:
> + if (!IS_ERR_OR_NULL(hash) && e->needs_key)
> + crypto_free_ahash(hash);
> +
> + for_each_possible_cpu(cpu) {
> + if (*per_cpu_ptr(e->req, cpu) == NULL)
> + break;
> + hash = crypto_ahash_reqtfm(*per_cpu_ptr(e->req, cpu));
Could you use a local variable here instead of @hash?
That way you won't need the two separate free_ahash()
one before and one after the loop..
> + ahash_request_free(*per_cpu_ptr(e->req, cpu));
I think using @req here would be beneficial as well :S
> + if (e->needs_key) {
> + crypto_free_ahash(hash);
> + hash = NULL;
> + }
> + }
> +
> + if (hash)
> + crypto_free_ahash(hash);
This error handling is tricky as hell, please just add a separate
variable to hold the
> +out_free_req:
> + free_percpu(e->req);
> +out_free_alg:
> + kfree(e->alg);
> + e->alg = NULL;
> + return ret;
> +}
> +
> +/**
> + * crypto_pool_alloc_ahash - allocates pool for ahash requests
> + * @alg: name of async hash algorithm
> + */
> +int crypto_pool_alloc_ahash(const char *alg)
> +{
> + int i, ret;
> +
> + /* slow-path */
> + mutex_lock(&cpool_mutex);
> +
> + for (i = 0; i < cpool_populated; i++) {
> + if (cpool[i].alg && !strcmp(cpool[i].alg, alg)) {
> + if (kref_read(&cpool[i].kref) > 0) {
In the current design we can as well resurrect a pool waiting to
be destroyed, right? Just reinit the ref and we're good.
Otherwise the read() + get() looks quite suspicious to a reader.
> + kref_get(&cpool[i].kref);
> + ret = i;
> + goto out;
> + } else {
> + break;
> + }
> + }
> + }
> +
> + for (i = 0; i < cpool_populated; i++) {
> + if (!cpool[i].alg)
> + break;
> + }
> + if (i >= CPOOL_SIZE) {
> + ret = -ENOSPC;
> + goto out;
> + }
> +
> + ret = __cpool_alloc_ahash(&cpool[i], alg);
> + if (!ret) {
> + ret = i;
> + if (i == cpool_populated)
> + cpool_populated++;
> + }
> +out:
> + mutex_unlock(&cpool_mutex);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(crypto_pool_alloc_ahash);
> +/**
> + * crypto_pool_add - increases number of users (refcounter) for a pool
> + * @id: crypto_pool that was previously allocated by crypto_pool_alloc_ahash()
> + */
> +void crypto_pool_add(unsigned int id)
> +{
> + if (WARN_ON_ONCE(id > cpool_populated || !cpool[id].alg))
> + return;
> + kref_get(&cpool[id].kref);
> +}
> +EXPORT_SYMBOL_GPL(crypto_pool_add);
> +
> +/**
> + * crypto_pool_get - disable bh and start using crypto_pool
> + * @id: crypto_pool that was previously allocated by crypto_pool_alloc_ahash()
> + * @c: returned crypto_pool for usage (uninitialized on failure)
> + */
> +int crypto_pool_get(unsigned int id, struct crypto_pool *c)
Is there a precedent somewhere for the _add() and _get() semantics
you're using here? I don't think I've seen _add() for taking a
reference, maybe _get() -> start(), _add() -> _get()?
> +{
> + struct crypto_pool_ahash *ret = (struct crypto_pool_ahash *)c;
> +
> + local_bh_disable();
> + if (WARN_ON_ONCE(id > cpool_populated || !cpool[id].alg)) {
> + local_bh_enable();
> + return -EINVAL;
> + }
> + ret->req = *this_cpu_ptr(cpool[id].req);
> + ret->base.scratch = this_cpu_read(crypto_pool_scratch);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(crypto_pool_get);
next prev parent reply other threads:[~2023-01-07 1:53 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-03 18:42 [PATCH v2 0/5] net/crypto: Introduce crypto_pool Dmitry Safonov
2023-01-03 18:42 ` [PATCH v2 1/5] crypto: " Dmitry Safonov
2023-01-07 1:53 ` Jakub Kicinski [this message]
2023-01-09 20:59 ` Dmitry Safonov
2023-01-09 21:11 ` Dmitry Safonov
2023-01-03 18:42 ` [PATCH v2 2/5] crypto/pool: Add crypto_pool_reserve_scratch() Dmitry Safonov
2023-01-07 2:04 ` Jakub Kicinski
2023-01-09 21:08 ` Dmitry Safonov
2023-01-03 18:42 ` [PATCH v2 3/5] crypto/net/tcp: Use crypto_pool for TCP-MD5 Dmitry Safonov
2023-01-07 2:05 ` Jakub Kicinski
2023-01-09 21:16 ` Dmitry Safonov
2023-01-03 18:42 ` [PATCH v2 4/5] crypto/net/ipv6: sr: Switch to using crypto_pool Dmitry Safonov
2023-01-03 18:42 ` [PATCH v2 5/5] crypto/Documentation: Add crypto_pool kernel API Dmitry Safonov
2023-01-04 13:17 ` kernel test robot
2023-01-07 2:06 ` Jakub Kicinski
2023-01-09 21:23 ` Dmitry Safonov
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=20230106175326.2d6a4dcd@kernel.org \
--to=kuba@kernel.org \
--cc=0x7f454c46@gmail.com \
--cc=cdleonard@gmail.com \
--cc=davem@davemloft.net \
--cc=dima@arista.com \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=gilligan@arista.com \
--cc=herbert@gondor.apana.org.au \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=netdev@vger.kernel.org \
--cc=noureddine@arista.com \
--cc=pabeni@redhat.com \
--cc=yoshfuji@linux-ipv6.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;
as well as URLs for NNTP newsgroup(s).