aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2012-06-22 08:08:29 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2012-06-22 08:08:29 -0400
commit398710379f516012c52d2ae396a9ba919bd6a7ab (patch)
treebfdc735759f0f32c883a36a53534a729fdc0f87c /crypto
parent3387e7d69048f5ab02729825f9611754850d9a87 (diff)
crypto: algapi - Move larval completion into algboss
It has been observed that sometimes the crypto allocation code will get stuck for 60 seconds or multiples thereof. This is usually caused by an algorithm failing to pass the self-test. If an algorithm fails to be constructed, we will immediately notify all larval waiters. However, if it succeeds in construction, but then fails the self-test, we won't notify anyone at all. This patch fixes this by merging the notification in the case where the algorithm fails to be constructed with that of the the case where it pases the self-test. This way regardless of what happens, we'll give the larval waiters an answer. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/algapi.c17
-rw-r--r--crypto/algboss.c17
-rw-r--r--crypto/internal.h1
3 files changed, 9 insertions, 26 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 056571b85445..c3b9bfeeb7ff 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -24,22 +24,6 @@
24 24
25static LIST_HEAD(crypto_template_list); 25static LIST_HEAD(crypto_template_list);
26 26
27void crypto_larval_error(const char *name, u32 type, u32 mask)
28{
29 struct crypto_alg *alg;
30
31 alg = crypto_alg_lookup(name, type, mask);
32
33 if (alg) {
34 if (crypto_is_larval(alg)) {
35 struct crypto_larval *larval = (void *)alg;
36 complete_all(&larval->completion);
37 }
38 crypto_mod_put(alg);
39 }
40}
41EXPORT_SYMBOL_GPL(crypto_larval_error);
42
43static inline int crypto_set_driver_name(struct crypto_alg *alg) 27static inline int crypto_set_driver_name(struct crypto_alg *alg)
44{ 28{
45 static const char suffix[] = "-generic"; 29 static const char suffix[] = "-generic";
@@ -295,7 +279,6 @@ found:
295 continue; 279 continue;
296 280
297 larval->adult = alg; 281 larval->adult = alg;
298 complete_all(&larval->completion);
299 continue; 282 continue;
300 } 283 }
301 284
diff --git a/crypto/algboss.c b/crypto/algboss.c
index 791d194958fa..f97027e7d996 100644
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <crypto/internal/aead.h> 13#include <crypto/internal/aead.h>
14#include <linux/completion.h>
14#include <linux/ctype.h> 15#include <linux/ctype.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/init.h> 17#include <linux/init.h>
@@ -47,6 +48,8 @@ struct cryptomgr_param {
47 char larval[CRYPTO_MAX_ALG_NAME]; 48 char larval[CRYPTO_MAX_ALG_NAME];
48 char template[CRYPTO_MAX_ALG_NAME]; 49 char template[CRYPTO_MAX_ALG_NAME];
49 50
51 struct completion *completion;
52
50 u32 otype; 53 u32 otype;
51 u32 omask; 54 u32 omask;
52}; 55};
@@ -66,7 +69,7 @@ static int cryptomgr_probe(void *data)
66 69
67 tmpl = crypto_lookup_template(param->template); 70 tmpl = crypto_lookup_template(param->template);
68 if (!tmpl) 71 if (!tmpl)
69 goto err; 72 goto out;
70 73
71 do { 74 do {
72 if (tmpl->create) { 75 if (tmpl->create) {
@@ -83,16 +86,10 @@ static int cryptomgr_probe(void *data)
83 86
84 crypto_tmpl_put(tmpl); 87 crypto_tmpl_put(tmpl);
85 88
86 if (err)
87 goto err;
88
89out: 89out:
90 complete(param->completion);
90 kfree(param); 91 kfree(param);
91 module_put_and_exit(0); 92 module_put_and_exit(0);
92
93err:
94 crypto_larval_error(param->larval, param->otype, param->omask);
95 goto out;
96} 93}
97 94
98static int cryptomgr_schedule_probe(struct crypto_larval *larval) 95static int cryptomgr_schedule_probe(struct crypto_larval *larval)
@@ -192,10 +189,14 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
192 189
193 memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); 190 memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
194 191
192 param->completion = &larval->completion;
193
195 thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe"); 194 thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe");
196 if (IS_ERR(thread)) 195 if (IS_ERR(thread))
197 goto err_free_param; 196 goto err_free_param;
198 197
198 wait_for_completion_interruptible(&larval->completion);
199
199 return NOTIFY_STOP; 200 return NOTIFY_STOP;
200 201
201err_free_param: 202err_free_param:
diff --git a/crypto/internal.h b/crypto/internal.h
index b865ca1a8613..9ebedae3fb54 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -83,7 +83,6 @@ void crypto_exit_compress_ops(struct crypto_tfm *tfm);
83struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask); 83struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
84void crypto_larval_kill(struct crypto_alg *alg); 84void crypto_larval_kill(struct crypto_alg *alg);
85struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask); 85struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask);
86void crypto_larval_error(const char *name, u32 type, u32 mask);
87void crypto_alg_tested(const char *name, int err); 86void crypto_alg_tested(const char *name, int err);
88 87
89void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, 88void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,