diff --git a/crypto/algapi.c b/crypto/algapi.c index 42dca17dc2d97cd6be9c2cc198ff9583035bd629..bb8f11aafa6386e482229ad7a0176128326eab8c 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "internal.h" @@ -68,13 +69,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); } /* diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 18dd7a4aaf7da625cab3eb1835c79ef1115a3761..4712ee620463ad1c363431d862a38e6e2e37e953 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -10,6 +10,7 @@ #include #include #include +#include /* * Maximum values for blocksize and alignmask, used to allocate @@ -43,6 +44,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;