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: 17+ 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
-- strict thread matches above, loose matches on Subject: below --
2023-01-06 4:46 [PATCH v2 1/5] crypto: Introduce crypto_pool kernel test robot
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 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.