diff --git a/crypto/algapi.c b/crypto/algapi.c
index 1c2185b5b005ef4d82a22a2130c953f86f735bc8..f137a432061f4224ccbff0bef41c58d95c859921 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -84,36 +84,47 @@ static void crypto_destroy_instance(struct crypto_alg *alg)
 	crypto_tmpl_put(tmpl);
 }
 
-static void crypto_remove_spawns(struct list_head *spawns,
-				 struct list_head *list)
+static void crypto_remove_spawn(struct crypto_spawn *spawn,
+				struct list_head *list,
+				struct list_head *secondary_spawns)
 {
-	struct crypto_spawn *spawn, *n;
+	struct crypto_instance *inst = spawn->inst;
+	struct crypto_template *tmpl = inst->tmpl;
 
-	list_for_each_entry_safe(spawn, n, spawns, list) {
-		struct crypto_instance *inst = spawn->inst;
-		struct crypto_template *tmpl = inst->tmpl;
+	list_del_init(&spawn->list);
+	spawn->alg = NULL;
 
-		list_del_init(&spawn->list);
-		spawn->alg = NULL;
+	if (crypto_is_dead(&inst->alg))
+		return;
 
-		if (crypto_is_dead(&inst->alg))
-			continue;
+	inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
+	if (!tmpl || !crypto_tmpl_get(tmpl))
+		return;
+
+	crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg);
+	list_move(&inst->alg.cra_list, list);
+	hlist_del(&inst->list);
+	inst->alg.cra_destroy = crypto_destroy_instance;
+
+	list_splice(&inst->alg.cra_users, secondary_spawns);
+}
+
+static void crypto_remove_spawns(struct list_head *spawns,
+				 struct list_head *list, u32 new_type)
+{
+	struct crypto_spawn *spawn, *n;
+	LIST_HEAD(secondary_spawns);
 
-		inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
-		if (!tmpl || !crypto_tmpl_get(tmpl))
+	list_for_each_entry_safe(spawn, n, spawns, list) {
+		if ((spawn->alg->cra_flags ^ new_type) & spawn->mask)
 			continue;
 
-		crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg);
-		list_move(&inst->alg.cra_list, list);
-		hlist_del(&inst->list);
-		inst->alg.cra_destroy = crypto_destroy_instance;
+		crypto_remove_spawn(spawn, list, &secondary_spawns);
+	}
 
-		if (!list_empty(&inst->alg.cra_users)) {
-			if (&n->list == spawns)
-				n = list_entry(inst->alg.cra_users.next,
-					       typeof(*n), list);
-			__list_splice(&inst->alg.cra_users, spawns->prev);
-		}
+	while (!list_empty(&secondary_spawns)) {
+		list_for_each_entry_safe(spawn, n, &secondary_spawns, list)
+			crypto_remove_spawn(spawn, list, &secondary_spawns);
 	}
 }
 
@@ -164,7 +175,7 @@ static int __crypto_register_alg(struct crypto_alg *alg,
 		    q->cra_priority > alg->cra_priority)
 			continue;
 
-		crypto_remove_spawns(&q->cra_users, list);
+		crypto_remove_spawns(&q->cra_users, list, alg->cra_flags);
 	}
 	
 	list_add(&alg->cra_list, &crypto_alg_list);
@@ -214,7 +225,7 @@ static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)
 
 	crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg);
 	list_del_init(&alg->cra_list);
-	crypto_remove_spawns(&alg->cra_users, list);
+	crypto_remove_spawns(&alg->cra_users, list, alg->cra_flags);
 
 	return 0;
 }
@@ -351,11 +362,12 @@ err:
 EXPORT_SYMBOL_GPL(crypto_register_instance);
 
 int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
-		      struct crypto_instance *inst)
+		      struct crypto_instance *inst, u32 mask)
 {
 	int err = -EAGAIN;
 
 	spawn->inst = inst;
+	spawn->mask = mask;
 
 	down_write(&crypto_alg_sem);
 	if (!crypto_is_moribund(alg)) {
@@ -494,7 +506,8 @@ struct crypto_instance *crypto_alloc_instance(const char *name,
 		goto err_free_inst;
 
 	spawn = crypto_instance_ctx(inst);
-	err = crypto_init_spawn(spawn, alg, inst);
+	err = crypto_init_spawn(spawn, alg, inst,
+				CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
 
 	if (err)
 		goto err_free_inst;
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 469f511315c513cc41cb956e6d0c7b4b291db3a4..7847fc2a03f0e015a65bb692f704c6bdb1464fc3 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -51,6 +51,7 @@ struct crypto_spawn {
 	struct list_head list;
 	struct crypto_alg *alg;
 	struct crypto_instance *inst;
+	u32 mask;
 };
 
 struct crypto_queue {
@@ -103,7 +104,7 @@ void crypto_unregister_template(struct crypto_template *tmpl);
 struct crypto_template *crypto_lookup_template(const char *name);
 
 int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
-		      struct crypto_instance *inst);
+		      struct crypto_instance *inst, u32 mask);
 void crypto_drop_spawn(struct crypto_spawn *spawn);
 struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
 				    u32 mask);