[CRYPTO] api: Added spawns

Spawns lock a specific crypto algorithm in place.  They can then be used
with crypto_spawn_tfm to allocate a tfm for that algorithm.  When the base
algorithm of a spawn is deregistered, all its spawns will be automatically
removed.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c
index ae54942..9b5b156 100644
--- a/crypto/cryptomgr.c
+++ b/crypto/cryptomgr.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/notifier.h>
 #include <linux/rtnetlink.h>
+#include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/workqueue.h>
 
@@ -44,21 +45,25 @@
 	struct cryptomgr_param *param = data;
 	struct crypto_template *tmpl;
 	struct crypto_instance *inst;
+	int err;
 
 	tmpl = crypto_lookup_template(param->template);
 	if (!tmpl)
 		goto err;
 
-	inst = tmpl->alloc(&param->alg, sizeof(param->alg));
-	if (IS_ERR(inst))
-		goto err;
-	else if ((err = crypto_register_instance(tmpl, inst))) {
-		tmpl->free(inst);
-		goto err;
-	}
+	do {
+		inst = tmpl->alloc(&param->alg, sizeof(param->alg));
+		if (IS_ERR(inst))
+			err = PTR_ERR(inst);
+		else if ((err = crypto_register_instance(tmpl, inst)))
+			tmpl->free(inst);
+	} while (err == -EAGAIN && !signal_pending(current));
 
 	crypto_tmpl_put(tmpl);
 
+	if (err)
+		goto err;
+
 out:
 	kfree(param);
 	return;