summaryrefslogtreecommitdiff
path: root/crypto/algapi.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2025-03-17 16:33:57 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2025-04-07 13:22:25 +0800
commit138804c2c18ca8bd1443dea173b3cc2643995919 (patch)
treef115ea67cd14f704d971fd753ca3c54b9ba9239d /crypto/algapi.c
parent3860642e0a87c8aef3c4285f3bb4ad473cfd514f (diff)
crypto: api - Ensure cra_type->destroy is done in process context
Move the cra_type->destroy call out of crypto_alg_put and into crypto_unregister_alg and crypto_free_instance. This ensures that it's always done in process context so calls such as flush_work can be done. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/algapi.c')
-rw-r--r--crypto/algapi.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 22bf80aad82b..5b8a4c787387 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -66,7 +66,13 @@ static int crypto_check_alg(struct crypto_alg *alg)
static void crypto_free_instance(struct crypto_instance *inst)
{
- inst->alg.cra_type->free(inst);
+ struct crypto_alg *alg = &inst->alg;
+ const struct crypto_type *type;
+
+ type = alg->cra_type;
+ if (type->destroy)
+ type->destroy(alg);
+ type->free(inst);
}
static void crypto_destroy_instance_workfn(struct work_struct *w)
@@ -150,7 +156,6 @@ static void crypto_remove_instance(struct crypto_instance *inst,
list_del_init(&inst->alg.cra_list);
hlist_del(&inst->list);
hlist_add_head(&inst->list, &tmpl->dead);
- inst->alg.cra_destroy = crypto_destroy_instance;
BUG_ON(!list_empty(&inst->alg.cra_users));
@@ -479,7 +484,8 @@ void crypto_unregister_alg(struct crypto_alg *alg)
if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1))
return;
- crypto_alg_put(alg);
+ if (alg->cra_type && alg->cra_type->destroy)
+ alg->cra_type->destroy(alg);
crypto_remove_final(&list);
}
@@ -637,6 +643,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
inst->alg.cra_module = tmpl->module;
inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
+ inst->alg.cra_destroy = crypto_destroy_instance;
down_write(&crypto_alg_sem);