diff --git a/crypto/algapi.c b/crypto/algapi.c index a0f9e807fdb4a3299afb8c4de3eb2e855bf7efd0..aaf615309c232298853b961e97297f4eeba6b7ff 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "internal.h" @@ -87,13 +88,37 @@ static void crypto_free_instance(struct crypto_instance *inst) inst->alg.cra_type->free(inst); } -static void crypto_destroy_instance(struct crypto_alg *alg) +static void crypto_destroy_instance_workfn(struct work_struct *w) { - struct crypto_instance *inst = (void *)alg; + struct crypto_instance_freework *work = container_of(w, + struct crypto_instance_freework, free_work); + struct crypto_instance *inst = work->instance; struct crypto_template *tmpl = inst->tmpl; crypto_free_instance(inst); crypto_tmpl_put(tmpl); + + kfree(work); +} + +static void crypto_destroy_instance(struct crypto_alg *alg +{ + struct crypto_instance_freework *work; + struct crypto_instance *inst = container_of(alg, + struct crypto_instance, + alg); + struct crypto_template *tmpl = inst->tmpl; + + work = kzalloc(sizeof(*work), GFP_ATOMIC); + if (!work) { + crypto_free_instance(inst); + crypto_tmpl_put(tmpl); + return; + } + work->instance = inst; + + INIT_WORK(&work->free_work, crypto_destroy_instance_workfn); + schedule_work(&work->free_work); } static struct list_head *crypto_more_spawns(struct crypto_alg *alg, diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 6b9cd6597617925d68dcd9d8f67a90bc5d9a92a1..474140cd233c47d8a6d1200826146274e9d97536 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -46,6 +46,11 @@ struct crypto_type { unsigned int tfmsize; }; +struct crypto_instance_freework { + struct crypto_instance *instance; + struct work_struct free_work; +}; + struct crypto_instance { struct crypto_alg alg;