From 282d7d06d0585d117ab62263ab3722950e9693f0 Mon Sep 17 00:00:00 2001
From: Wenkai Lin <linwenkai6@hisilicon.com>
Date: Sat, 15 Jan 2022 16:53:59 +0800
Subject: [PATCH 46/53] uadk: fix environment uninit repeatly error

use wd_uninit_env_config to restore wd_init_env_config do,
move setting gloab environment config to wd_init_env_config.
function should not be set to NULL, because it may used to
uninit resource.

Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
---
 include/wd_util.h |  7 ++--
 wd_aead.c         |  4 +--
 wd_cipher.c       |  4 +--
 wd_comp.c         |  4 +--
 wd_dh.c           |  4 +--
 wd_digest.c       |  4 +--
 wd_ecc.c          |  4 +--
 wd_rsa.c          |  4 +--
 wd_util.c         | 88 ++++++++++++++++++++++++++++++-----------------
 9 files changed, 74 insertions(+), 49 deletions(-)

diff --git a/include/wd_util.h b/include/wd_util.h
index ef95907..2d3c1e4 100644
--- a/include/wd_util.h
+++ b/include/wd_util.h
@@ -66,8 +66,6 @@ struct wd_env_config {
 	struct wd_env_config_per_numa *config_per_numa;
 	/* Let's make it as a gobal config, not per numa */
 	bool enable_internal_poll;
-	int (*alg_poll_ctx)(__u32, __u32, __u32 *);
-	void (*alg_uninit)(void);
 
 	/* resource config */
 	struct wd_sched *sched;
@@ -263,8 +261,11 @@ int wd_alg_env_init(struct wd_env_config *config,
  * wd_alg_env_uninit() - uninit specific wd algorithm environment configuration.
  * @config: Pointer of wd_env_config which is used to store environment
  *          variable information.
+ * @ops: Define functions which will be used by specific wd algorithm
+ *	 environment init.
  */
-void wd_alg_env_uninit(struct wd_env_config *env_config);
+void wd_alg_env_uninit(struct wd_env_config *env_config,
+		       const struct wd_alg_ops *ops);
 
 /*
  * wd_add_task_to_async_queue() - Add an async request to its related async
diff --git a/wd_aead.c b/wd_aead.c
index 670bb33..32d06ec 100644
--- a/wd_aead.c
+++ b/wd_aead.c
@@ -716,7 +716,7 @@ int wd_aead_env_init(struct wd_sched *sched)
 
 void wd_aead_env_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_aead_env_config);
+	return wd_alg_env_uninit(&wd_aead_env_config, &wd_aead_ops);
 }
 
 int wd_aead_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
@@ -734,7 +734,7 @@ int wd_aead_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
 
 void wd_aead_ctx_num_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_aead_env_config);
+	return wd_alg_env_uninit(&wd_aead_env_config, &wd_aead_ops);
 }
 
 int wd_aead_get_env_param(__u32 node, __u32 type, __u32 mode,
diff --git a/wd_cipher.c b/wd_cipher.c
index 85f7e65..5be3123 100644
--- a/wd_cipher.c
+++ b/wd_cipher.c
@@ -634,7 +634,7 @@ int wd_cipher_env_init(struct wd_sched *sched)
 
 void wd_cipher_env_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_cipher_env_config);
+	return wd_alg_env_uninit(&wd_cipher_env_config, &wd_cipher_ops);
 }
 
 int wd_cipher_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
@@ -652,7 +652,7 @@ int wd_cipher_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
 
 void wd_cipher_ctx_num_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_cipher_env_config);
+	return wd_alg_env_uninit(&wd_cipher_env_config, &wd_cipher_ops);
 }
 
 int wd_cipher_get_env_param(__u32 node, __u32 type, __u32 mode,
diff --git a/wd_comp.c b/wd_comp.c
index fc355a9..7868551 100644
--- a/wd_comp.c
+++ b/wd_comp.c
@@ -775,7 +775,7 @@ int wd_comp_env_init(struct wd_sched *sched)
 
 void wd_comp_env_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_comp_env_config);
+	return wd_alg_env_uninit(&wd_comp_env_config, &wd_comp_ops);
 }
 
 int wd_comp_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
@@ -798,7 +798,7 @@ int wd_comp_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
 
 void wd_comp_ctx_num_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_comp_env_config);
+	return wd_alg_env_uninit(&wd_comp_env_config, &wd_comp_ops);
 }
 
 int wd_comp_get_env_param(__u32 node, __u32 type, __u32 mode,
diff --git a/wd_dh.c b/wd_dh.c
index 7b849ac..1784099 100644
--- a/wd_dh.c
+++ b/wd_dh.c
@@ -564,7 +564,7 @@ int wd_dh_env_init(struct wd_sched *sched)
 
 void wd_dh_env_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_dh_env_config);
+	return wd_alg_env_uninit(&wd_dh_env_config, &wd_dh_ops);
 }
 
 int wd_dh_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
@@ -582,7 +582,7 @@ int wd_dh_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
 
 void wd_dh_ctx_num_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_dh_env_config);
+	return wd_alg_env_uninit(&wd_dh_env_config, &wd_dh_ops);
 }
 
 int wd_dh_get_env_param(__u32 node, __u32 type, __u32 mode,
diff --git a/wd_digest.c b/wd_digest.c
index 2b3661d..525d6a9 100644
--- a/wd_digest.c
+++ b/wd_digest.c
@@ -525,7 +525,7 @@ int wd_digest_env_init(struct wd_sched *sched)
 
 void wd_digest_env_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_digest_env_config);
+	return wd_alg_env_uninit(&wd_digest_env_config, &wd_digest_ops);
 }
 
 int wd_digest_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
@@ -543,7 +543,7 @@ int wd_digest_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
 
 void wd_digest_ctx_num_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_digest_env_config);
+	return wd_alg_env_uninit(&wd_digest_env_config, &wd_digest_ops);
 }
 
 int wd_digest_get_env_param(__u32 node, __u32 type, __u32 mode,
diff --git a/wd_ecc.c b/wd_ecc.c
index e37fb39..e324473 100644
--- a/wd_ecc.c
+++ b/wd_ecc.c
@@ -2286,7 +2286,7 @@ int wd_ecc_env_init(struct wd_sched *sched)
 
 void wd_ecc_env_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_ecc_env_config);
+	return wd_alg_env_uninit(&wd_ecc_env_config, &wd_ecc_ops);
 }
 
 int wd_ecc_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
@@ -2304,7 +2304,7 @@ int wd_ecc_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
 
 void wd_ecc_ctx_num_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_ecc_env_config);
+	return wd_alg_env_uninit(&wd_ecc_env_config, &wd_ecc_ops);
 }
 
 int wd_ecc_get_env_param(__u32 node, __u32 type, __u32 mode,
diff --git a/wd_rsa.c b/wd_rsa.c
index b6cc0d1..1f911b4 100644
--- a/wd_rsa.c
+++ b/wd_rsa.c
@@ -1160,7 +1160,7 @@ int wd_rsa_env_init(struct wd_sched *sched)
 
 void wd_rsa_env_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_rsa_env_config);
+	return wd_alg_env_uninit(&wd_rsa_env_config, &wd_rsa_ops);
 }
 
 int wd_rsa_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
@@ -1178,7 +1178,7 @@ int wd_rsa_ctx_num_init(__u32 node, __u32 type, __u32 num, __u8 mode)
 
 void wd_rsa_ctx_num_uninit(void)
 {
-	return wd_alg_env_uninit(&wd_rsa_env_config);
+	return wd_alg_env_uninit(&wd_rsa_env_config, &wd_rsa_ops);
 }
 
 int wd_rsa_get_env_param(__u32 node, __u32 type, __u32 mode,
diff --git a/wd_util.c b/wd_util.c
index 6cae768..38599c2 100644
--- a/wd_util.c
+++ b/wd_util.c
@@ -868,11 +868,27 @@ static int wd_parse_ctx_attr(struct wd_env_config *env_config,
 }
 
 static int wd_init_env_config(struct wd_env_config *config,
-			      struct wd_ctx_attr *attr)
+			      struct wd_ctx_attr *attr,
+			      const struct wd_alg_ops *ops,
+			      const struct wd_config_variable *table,
+			      __u32 table_size)
 {
+	config->op_type_num = ops->op_type_num;
+	config->table_size = table_size;
+	config->table = table;
+
 	return attr ? wd_parse_ctx_attr(config, attr) : wd_parse_env(config);
 }
 
+static void wd_uninit_env_config(struct wd_env_config *config)
+{
+	config->op_type_num = 0;
+	config->table_size = 0;
+	config->table = NULL;
+
+	wd_free_env(config);
+}
+
 static __u8 get_ctx_mode(struct wd_env_config_per_numa *config, int idx)
 {
 	struct wd_ctx_range **ctx_table = config->ctx_table;
@@ -1051,7 +1067,8 @@ static int wd_sched_fill_table(struct wd_env_config_per_numa *config_numa,
 	return 0;
 }
 
-static int wd_init_sched_config(struct wd_env_config *config)
+static int wd_init_sched_config(struct wd_env_config *config,
+				void *alg_poll_ctx)
 {
 	struct wd_env_config_per_numa *config_numa;
 	int i, j, ret, max_node, type_num;
@@ -1063,7 +1080,7 @@ static int wd_init_sched_config(struct wd_env_config *config)
 		return -WD_EINVAL;
 
 	if (!config->enable_internal_poll)
-		func = config->alg_poll_ctx;
+		func = alg_poll_ctx;
 
 	config->internal_sched = false;
 	type_num = config->op_type_num;
@@ -1340,7 +1357,8 @@ static void wd_uninit_one_task_queue(struct async_task_queue *task_queue)
 }
 
 static int wd_init_async_polling_thread_per_numa(struct wd_env_config *config,
-				struct wd_env_config_per_numa *config_numa)
+				struct wd_env_config_per_numa *config_numa,
+				void *alg_poll_ctx)
 {
 	struct async_task_queue *task_queue, *queue_head;
 	int i, j, ret;
@@ -1365,7 +1383,7 @@ static int wd_init_async_polling_thread_per_numa(struct wd_env_config *config,
 
 	task_queue = queue_head;
 	for (i = 0; i < num; task_queue++, i++) {
-		ret = wd_init_one_task_queue(task_queue, config->alg_poll_ctx);
+		ret = wd_init_one_task_queue(task_queue, alg_poll_ctx);
 		if (ret) {
 			for (j = 0; j < i; task_queue++, j++)
 				wd_uninit_one_task_queue(task_queue);
@@ -1386,6 +1404,9 @@ static void wd_uninit_async_polling_thread_per_numa(struct wd_env_config *cfg,
 	double num;
 	int i;
 
+	if (!config_numa || !config_numa->async_task_queue_array)
+		return;
+
 	head = config_numa->async_task_queue_array;
 	task_queue = head;
 	num = fmin(config_numa->async_poll_num, config_numa->async_ctx_num);
@@ -1396,7 +1417,8 @@ static void wd_uninit_async_polling_thread_per_numa(struct wd_env_config *cfg,
 	config_numa->async_task_queue_array = NULL;
 }
 
-static int wd_init_async_polling_thread(struct wd_env_config *config)
+static int wd_init_async_polling_thread(struct wd_env_config *config,
+					void *alg_poll_ctx)
 {
 	struct wd_env_config_per_numa *config_numa;
 	int i, ret;
@@ -1405,12 +1427,19 @@ static int wd_init_async_polling_thread(struct wd_env_config *config)
 		return 0;
 
 	FOREACH_NUMA(i, config, config_numa) {
-		ret = wd_init_async_polling_thread_per_numa(config, config_numa);
+		ret = wd_init_async_polling_thread_per_numa(config, config_numa,
+							    alg_poll_ctx);
 		if (ret)
-			return ret;
+			goto out;
 	}
 
 	return 0;
+
+out:
+	FOREACH_NUMA(i, config, config_numa)
+		wd_uninit_async_polling_thread_per_numa(config, config_numa);
+
+	return ret;
 }
 
 static void wd_uninit_async_polling_thread(struct wd_env_config *config)
@@ -1434,7 +1463,7 @@ static int wd_init_resource(struct wd_env_config *config,
 	if (ret)
 		return ret;
 
-	ret = wd_init_sched_config(config);
+	ret = wd_init_sched_config(config, ops->alg_poll_ctx);
 	if (ret)
 		goto err_uninit_ctx;
 
@@ -1442,7 +1471,7 @@ static int wd_init_resource(struct wd_env_config *config,
 	if (ret)
 		goto err_uninit_sched;
 
-	ret = wd_init_async_polling_thread(config);
+	ret = wd_init_async_polling_thread(config, ops->alg_poll_ctx);
 	if (ret)
 		goto err_uninit_alg;
 
@@ -1461,13 +1490,19 @@ err_uninit_ctx:
 	return ret;
 }
 
-static void wd_uninit_resource(struct wd_env_config *config)
+static void wd_uninit_resource(struct wd_env_config *config,
+			       const struct wd_alg_ops *ops)
 {
 	wd_uninit_async_polling_thread(config);
-	config->alg_uninit();
-	if (config->internal_sched)
+	ops->alg_uninit();
+
+	if (config->internal_sched) {
 		wd_uninit_sched_config(config->sched);
+		config->sched = NULL;
+	}
+
 	wd_free_ctx(config->ctx_config);
+	config->ctx_config = NULL;
 }
 
 int wd_alg_env_init(struct wd_env_config *env_config,
@@ -1478,43 +1513,32 @@ int wd_alg_env_init(struct wd_env_config *env_config,
 {
 	int ret;
 
-	env_config->op_type_num = ops->op_type_num;
-	env_config->alg_poll_ctx = ops->alg_poll_ctx;
-	env_config->table = table;
-	env_config->table_size = table_size;
-
 	ret = wd_alloc_numa(env_config, ops);
 	if (ret)
 		return ret;
 
-	ret = wd_init_env_config(env_config, ctx_attr);
+	ret = wd_init_env_config(env_config, ctx_attr, ops, table, table_size);
 	if (ret)
 		goto free_numa;
 
 	ret = wd_init_resource(env_config, ops);
 	if (ret)
-		goto free_env;
-
-	/* Use alg_uninit as a sign of initialization complete */
-	env_config->alg_uninit = ops->alg_uninit;
+		goto uninit_env_config;
 
 	return 0;
 
-free_env:
-	wd_free_env(env_config);
+uninit_env_config:
+	wd_uninit_env_config(env_config);
 free_numa:
 	wd_free_numa(env_config);
 	return ret;
 }
 
-void wd_alg_env_uninit(struct wd_env_config *env_config)
+void wd_alg_env_uninit(struct wd_env_config *env_config,
+		       const struct wd_alg_ops *ops)
 {
-	/* Check whether the initialization is complete */
-	if (!env_config->alg_uninit)
-		return;
-
-	wd_uninit_resource(env_config);
-	wd_free_env(env_config);
+	wd_uninit_resource(env_config, ops);
+	wd_uninit_env_config(env_config);
 	wd_free_numa(env_config);
 }
 
-- 
2.25.1

