mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
[CRYPTO] api: Add crypto_alg reference counting
Up until now we've relied on module reference counting to ensure that the crypto_alg structures don't disappear from under us. This was good enough as long as each crypto_alg came from exactly one module. However, with parameterised crypto algorithms a crypto_alg object may need two or more modules to operate. This means that we need to count the references to the crypto_alg object directly. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
72fa491912
commit
6521f30273
3 changed files with 32 additions and 6 deletions
32
crypto/api.c
32
crypto/api.c
|
@ -29,13 +29,26 @@
|
|||
LIST_HEAD(crypto_alg_list);
|
||||
DECLARE_RWSEM(crypto_alg_sem);
|
||||
|
||||
static inline int crypto_mod_get(struct crypto_alg *alg)
|
||||
static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
|
||||
{
|
||||
return try_module_get(alg->cra_module);
|
||||
atomic_inc(&alg->cra_refcnt);
|
||||
return alg;
|
||||
}
|
||||
|
||||
static inline void crypto_mod_put(struct crypto_alg *alg)
|
||||
static inline void crypto_alg_put(struct crypto_alg *alg)
|
||||
{
|
||||
if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
|
||||
alg->cra_destroy(alg);
|
||||
}
|
||||
|
||||
static struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
|
||||
{
|
||||
return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL;
|
||||
}
|
||||
|
||||
static void crypto_mod_put(struct crypto_alg *alg)
|
||||
{
|
||||
crypto_alg_put(alg);
|
||||
module_put(alg->cra_module);
|
||||
}
|
||||
|
||||
|
@ -274,6 +287,7 @@ int crypto_register_alg(struct crypto_alg *alg)
|
|||
}
|
||||
|
||||
list_add(&alg->cra_list, &crypto_alg_list);
|
||||
atomic_set(&alg->cra_refcnt, 1);
|
||||
out:
|
||||
up_write(&crypto_alg_sem);
|
||||
return ret;
|
||||
|
@ -284,8 +298,6 @@ int crypto_unregister_alg(struct crypto_alg *alg)
|
|||
int ret = -ENOENT;
|
||||
struct crypto_alg *q;
|
||||
|
||||
BUG_ON(!alg->cra_module);
|
||||
|
||||
down_write(&crypto_alg_sem);
|
||||
list_for_each_entry(q, &crypto_alg_list, cra_list) {
|
||||
if (alg == q) {
|
||||
|
@ -296,7 +308,15 @@ int crypto_unregister_alg(struct crypto_alg *alg)
|
|||
}
|
||||
out:
|
||||
up_write(&crypto_alg_sem);
|
||||
return ret;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
|
||||
if (alg->cra_destroy)
|
||||
alg->cra_destroy(alg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_alg_available(const char *name, u32 flags)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue