From 0951f91ba62c25a3bad11bdb16384692c640a0aa Mon Sep 17 00:00:00 2001
From: Kai Ye <yekai13@huawei.com>
Date: Wed, 22 Jun 2022 10:26:28 +0800
Subject: [PATCH 125/167] uadk: support some uadk dfx stronger features

1. Add the function of setting the uadk log level, include error, info,
   debug by syslog. the uadk log can be printed in message or syslog
   file default. You can set your own uadk.log file in rsyslog.conf.
   If selected the static compilation, the syslog will not be used.
2. The number of packets in a queue can be read through the
   'uadk_tool'. the maximum number of queues supported is 1024.
3. The 'uadk_tool' supports displaying the library build date. supports
   displaying the environment variables. more details, use 'uadk_tool dfx
   --help or uadk_tool --help'.

Signed-off-by: Kai Ye <yekai13@huawei.com>
---
 Makefile.am                                   |   5 +
 include/wd.h                                  |  69 +++--
 include/wd_alg_common.h                       |   1 +
 include/wd_util.h                             |  25 +-
 test/hisi_zip_test/test_lib.c                 |   2 +
 uadk_tool/Makefile.am                         |  11 +-
 .../{ => benchmark}/sec_soft_benchmark.c      |   0
 .../{ => benchmark}/sec_soft_benchmark.h      |   0
 .../{ => benchmark}/sec_uadk_benchmark.c      |   0
 .../{ => benchmark}/sec_uadk_benchmark.h      |   0
 uadk_tool/{ => benchmark}/sec_wd_benchmark.c  |   0
 uadk_tool/{ => benchmark}/sec_wd_benchmark.h  |   0
 uadk_tool/{ => benchmark}/uadk_benchmark.c    |   3 +-
 uadk_tool/{ => benchmark}/uadk_benchmark.h    |   2 +-
 uadk_tool/dfx/uadk_dfx.c                      | 253 ++++++++++++++++++
 uadk_tool/{ => dfx}/uadk_dfx.h                |   3 -
 uadk_tool/uadk_dfx.c                          |  79 ------
 uadk_tool/uadk_tool.c                         |  21 +-
 wd.c                                          |  79 +++++-
 wd_aead.c                                     |   4 +-
 wd_cipher.c                                   |   3 +
 wd_comp.c                                     |   2 +
 wd_dh.c                                       |   2 +
 wd_digest.c                                   |   2 +
 wd_ecc.c                                      |   6 +-
 wd_rsa.c                                      |   2 +
 wd_util.c                                     |  91 ++++++-
 27 files changed, 528 insertions(+), 137 deletions(-)
 rename uadk_tool/{ => benchmark}/sec_soft_benchmark.c (100%)
 rename uadk_tool/{ => benchmark}/sec_soft_benchmark.h (100%)
 rename uadk_tool/{ => benchmark}/sec_uadk_benchmark.c (100%)
 rename uadk_tool/{ => benchmark}/sec_uadk_benchmark.h (100%)
 rename uadk_tool/{ => benchmark}/sec_wd_benchmark.c (100%)
 rename uadk_tool/{ => benchmark}/sec_wd_benchmark.h (100%)
 rename uadk_tool/{ => benchmark}/uadk_benchmark.c (99%)
 rename uadk_tool/{ => benchmark}/uadk_benchmark.h (97%)
 create mode 100644 uadk_tool/dfx/uadk_dfx.c
 rename uadk_tool/{ => dfx}/uadk_dfx.h (59%)
 delete mode 100644 uadk_tool/uadk_dfx.c

diff --git a/Makefile.am b/Makefile.am
index d7e49f7..7a097f9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,7 +23,11 @@ MINOR = 3
 REVISION = 21
 UADK_VERSION = -version-number ${MAJOR}:${MINOR}:${REVISION}
 
+DAY = 11
+MONTH = Jun
+YEAR = 2022
 AM_CFLAGS+= -DUADK_VERSION_NUMBER="\"libwd version: ${MAJOR}.${MINOR}.${REVISION}\""
+AM_CFLAGS+= -DUADK_RELEASED_TIME="\"Released ${MONTH} ${DAY}, ${YEAR}\""
 
 include_HEADERS = include/wd.h include/wd_cipher.h include/wd_aead.h \
 		  include/wd_comp.h include/wd_dh.h include/wd_digest.h \
@@ -78,6 +82,7 @@ libhisi_hpre_la_SOURCES=drv/hisi_hpre.c drv/hisi_qm_udrv.c \
 		hisi_qm_udrv.h wd_hpre_drv.h
 if WD_STATIC_DRV
 AM_CFLAGS += -DWD_STATIC_DRV
+AM_CFLAGS += -DWD_NO_LOG
 
 libwd_la_LIBADD = $(libwd_la_OBJECTS) -lnuma
 
diff --git a/include/wd.h b/include/wd.h
index 56c4109..8c45522 100644
--- a/include/wd.h
+++ b/include/wd.h
@@ -8,9 +8,11 @@
 #define __WD_H
 #include <errno.h>
 #include <fcntl.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
+#include <syslog.h>
 #include <unistd.h>
 #include <asm/types.h>
 #include "uacce.h"
@@ -25,39 +27,37 @@ extern "C" {
 #define MAX_DEV_NAME_LEN		256
 #define LINUX_CRTDIR_SIZE		1
 #define LINUX_PRTDIR_SIZE		2
+#define WD_CTX_CNT_NUM			1024
+#define WD_IPC_KEY			0x500011
 
 typedef void (*wd_log)(const char *format, ...);
 
-#ifndef WD_ERR
-#ifndef WITH_LOG_FILE
-extern wd_log log_out;
-
-#define __WD_FILENAME__ (strrchr(__FILE__, '/') ?	\
-		((char *)((uintptr_t)strrchr(__FILE__, '/') + 1)) : __FILE__)
-
-#define WD_ERR(format, args...)	\
-	(log_out ? log_out("[%s, %d, %s]:"format,	\
-	__WD_FILENAME__, __LINE__, __func__, ##args) : 	\
-	fprintf(stderr, format, ##args))
+#ifndef WD_NO_LOG
+#define WD_DEBUG(fmt, args...)  \
+	do {\
+		openlog("uadk-debug", LOG_CONS | LOG_PID, LOG_LOCAL5);\
+		syslog(LOG_DEBUG, fmt, ##args);\
+	} while (0)
+
+#define WD_INFO(fmt, args...)  \
+	do {\
+		openlog("uadk-info", LOG_CONS | LOG_PID, LOG_LOCAL5);\
+		syslog(LOG_INFO, fmt, ##args);\
+	} while (0)
+
+#define WD_ERR(fmt, args...)  \
+	do {\
+		openlog("uadk-err", LOG_CONS | LOG_PID, LOG_LOCAL5);\
+		syslog(LOG_ERR, fmt, ##args);\
+	} while (0)
 #else
-extern FILE *flog_fd;
-#define WD_ERR(format, args...)	do {			\
-	if (!flog_fd)					\
-		flog_fd = fopen(WITH_LOG_FILE, "a+");	\
-	if (flog_fd)					\
-		fprintf(flog_fd, format, ##args);	\
-	else						\
-		fprintf(stderr, "log %s not exists!",	\
-			WITH_LOG_FILE);			\
-} while (0)
-#endif
+#define OPEN_LOG(s)
+#define WD_DEBUG(fmt, args...)   fprintf(stderr, fmt, ##args)
+#define WD_INFO(fmt, args...)    fprintf(stderr, fmt, ##args)
+#define WD_ERR(fmt, args...)     fprintf(stderr, fmt, ##args)
 #endif
 
-#ifdef DEBUG_LOG
-#define dbg(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__)
-#else
-#define dbg(msg, ...)
-#endif
+#define WD_CONSOLE printf
 
 /* WD error code */
 #define	WD_SUCCESS			0
@@ -488,6 +488,21 @@ void wd_mempool_stats(handle_t mempool, struct wd_mempool_stats *stats);
  */
 void wd_blockpool_stats(handle_t blkpool, struct wd_blockpool_stats *stats);
 
+/**
+ * wd_get_version() - Get the libwd version number and released time.
+ */
+void wd_get_version(void);
+
+/**
+ * wd_need_debug() - Get the debug flag from rsyslog.cnf
+ */
+bool wd_need_debug(void);
+
+/**
+ * wd_need_info() - Get the info flag from rsyslog.cnf
+ */
+bool wd_need_info(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/wd_alg_common.h b/include/wd_alg_common.h
index 855f71d..c455dc3 100644
--- a/include/wd_alg_common.h
+++ b/include/wd_alg_common.h
@@ -76,6 +76,7 @@ struct wd_ctx_config_internal {
 	void *priv;
 	int pid;
 	bool epoll_en;
+	unsigned long *msg_cnt;
 };
 
 /**
diff --git a/include/wd_util.h b/include/wd_util.h
index eb250f0..83a9684 100644
--- a/include/wd_util.h
+++ b/include/wd_util.h
@@ -8,6 +8,8 @@
 #define __WD_UTIL_H
 
 #include <stdbool.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
 #include <asm/types.h>
 #include "wd_alg_common.h"
 
@@ -292,7 +294,7 @@ int wd_add_task_to_async_queue(struct wd_env_config *config, __u32 idx);
  */
 void dump_env_info(struct wd_env_config *config);
 
-/*
+/**
  * wd_alg_get_env_param() - get specific ctx number.
  * @config: Pointer of wd_env_config which is used to store environment
  *          variable information.
@@ -304,7 +306,7 @@ int wd_alg_get_env_param(struct wd_env_config *env_config,
 			 struct wd_ctx_attr attr,
 			 __u32 *num, __u8 *is_enable);
 
-/*
+/**
  * wd_set_ctx_attr() - set node type and mode for ctx
  * @ctx_attr: ctx attributes pointer.
  * @node: numa id.
@@ -315,7 +317,7 @@ int wd_alg_get_env_param(struct wd_env_config *env_config,
 int wd_set_ctx_attr(struct wd_ctx_attr *ctx_attr,
 		    __u32 node, __u32 type, __u8 mode, __u32 num);
 
-/*
+/**
  * wd_check_ctx() - check ctx mode and index
  * @config: ctx config pointer.
  * @mode: synchronous or asynchronous mode.
@@ -354,6 +356,23 @@ int wd_handle_msg_sync(struct wd_msg_handle *msg_handle, handle_t ctx,
  */
 int wd_init_param_check(struct wd_ctx_config *config, struct wd_sched *sched);
 
+/**
+ * wd_dfx_msg_cnt() - Message counter interface for ctx
+ * @msg: Shared memory addr.
+ * @numSize: Number of elements.
+ * @index: Indicates the CTX index.
+ */
+static inline void wd_dfx_msg_cnt(unsigned long *msg, __u32 numsize, __u32 idx)
+{
+	bool ret;
+
+	ret = wd_need_info();
+	if (idx > numsize || !ret)
+		return;
+
+	msg[idx]++;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/test/hisi_zip_test/test_lib.c b/test/hisi_zip_test/test_lib.c
index 374244a..5918699 100644
--- a/test/hisi_zip_test/test_lib.c
+++ b/test/hisi_zip_test/test_lib.c
@@ -22,6 +22,8 @@ struct check_rand_ctx {
 	unsigned short state[3];
 };
 
+#define dbg(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__)
+
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_spinlock_t lock;
 static int count = 0;
diff --git a/uadk_tool/Makefile.am b/uadk_tool/Makefile.am
index da5b229..f04b2f0 100644
--- a/uadk_tool/Makefile.am
+++ b/uadk_tool/Makefile.am
@@ -1,13 +1,16 @@
 ACLOCAL_AMFLAGS = -I m4 -I./include
-AM_CFLAGS=-Wall -fno-strict-aliasing -I$(top_srcdir) -I$(top_srcdir)/include \
+AUTOMAKE_OPTIONS = foreign subdir-objects
+AM_CFLAGS=-Wall -fno-strict-aliasing -I$(top_srcdir) -I$(top_srcdir)/benchmark/include \
 			-pthread
 
 #AUTOMAKE_OPTIONS = subdir-objects
 
 bin_PROGRAMS=uadk_tool
 
-uadk_tool_SOURCES=uadk_tool.c uadk_dfx.c uadk_benchmark.c \
-			sec_uadk_benchmark.c sec_wd_benchmark.c
+uadk_tool_SOURCES=uadk_tool.c dfx/uadk_dfx.c dfx/uadk_dfx.h \
+			benchmark/uadk_benchmark.c benchmark/uadk_benchmark.h \
+			benchmark/sec_uadk_benchmark.c benchmark/sec_uadk_benchmark.h \
+			benchmark/sec_wd_benchmark.c benchmark/sec_wd_benchmark.h
 
 if WD_STATIC_DRV
 AM_CFLAGS+=-Bstatic
@@ -27,7 +30,7 @@ uadk_tool_LDFLAGS=-Wl,-rpath,'/usr/local/lib'
 if WITH_OPENSSL_DIR
 AM_CFLAGS+= -DWITH_OPENSSL_DIR -I$(with_openssl_dir)/include
 
-uadk_tool_SOURCES+=sec_soft_benchmark.c
+uadk_tool_SOURCES+=benchmark/sec_soft_benchmark.c benchmark/sec_soft_benchmark.h
 
 if WD_STATIC_DRV
 uadk_tool_LDADD+= $(with_openssl_dir)/libcrypto.a
diff --git a/uadk_tool/sec_soft_benchmark.c b/uadk_tool/benchmark/sec_soft_benchmark.c
similarity index 100%
rename from uadk_tool/sec_soft_benchmark.c
rename to uadk_tool/benchmark/sec_soft_benchmark.c
diff --git a/uadk_tool/sec_soft_benchmark.h b/uadk_tool/benchmark/sec_soft_benchmark.h
similarity index 100%
rename from uadk_tool/sec_soft_benchmark.h
rename to uadk_tool/benchmark/sec_soft_benchmark.h
diff --git a/uadk_tool/sec_uadk_benchmark.c b/uadk_tool/benchmark/sec_uadk_benchmark.c
similarity index 100%
rename from uadk_tool/sec_uadk_benchmark.c
rename to uadk_tool/benchmark/sec_uadk_benchmark.c
diff --git a/uadk_tool/sec_uadk_benchmark.h b/uadk_tool/benchmark/sec_uadk_benchmark.h
similarity index 100%
rename from uadk_tool/sec_uadk_benchmark.h
rename to uadk_tool/benchmark/sec_uadk_benchmark.h
diff --git a/uadk_tool/sec_wd_benchmark.c b/uadk_tool/benchmark/sec_wd_benchmark.c
similarity index 100%
rename from uadk_tool/sec_wd_benchmark.c
rename to uadk_tool/benchmark/sec_wd_benchmark.c
diff --git a/uadk_tool/sec_wd_benchmark.h b/uadk_tool/benchmark/sec_wd_benchmark.h
similarity index 100%
rename from uadk_tool/sec_wd_benchmark.h
rename to uadk_tool/benchmark/sec_wd_benchmark.h
diff --git a/uadk_tool/uadk_benchmark.c b/uadk_tool/benchmark/uadk_benchmark.c
similarity index 99%
rename from uadk_tool/uadk_benchmark.c
rename to uadk_tool/benchmark/uadk_benchmark.c
index 8c3c96f..84941d5 100644
--- a/uadk_tool/uadk_benchmark.c
+++ b/uadk_tool/benchmark/uadk_benchmark.c
@@ -567,7 +567,7 @@ static void print_help(void)
 	ACC_TST_PRT("UPDATE:2021-7-28\n");
 }
 
-void benchmark_cmd_parse(int argc, char *argv[], struct acc_option *option)
+int acc_cmd_parse(int argc, char *argv[], struct acc_option *option)
 {
 	int option_index = 0;
 	int c;
@@ -638,6 +638,7 @@ void benchmark_cmd_parse(int argc, char *argv[], struct acc_option *option)
 			exit(-1);
 		}
 	}
+	return 0;
 }
 
 int acc_option_convert(struct acc_option *option)
diff --git a/uadk_tool/uadk_benchmark.h b/uadk_tool/benchmark/uadk_benchmark.h
similarity index 97%
rename from uadk_tool/uadk_benchmark.h
rename to uadk_tool/benchmark/uadk_benchmark.h
index 7ce0426..2cb3dc0 100644
--- a/uadk_tool/uadk_benchmark.h
+++ b/uadk_tool/benchmark/uadk_benchmark.h
@@ -170,7 +170,7 @@ extern void add_recv_data(u32 cnt);
 extern void add_send_complete(void);
 extern u32 get_recv_time(void);
 
-void benchmark_cmd_parse(int argc, char *argv[], struct acc_option *option);
+int acc_cmd_parse(int argc, char *argv[], struct acc_option *option);
 int acc_default_case(struct acc_option *option);
 int acc_option_convert(struct acc_option *option);
 int acc_benchmark_run(struct acc_option *option);
diff --git a/uadk_tool/dfx/uadk_dfx.c b/uadk_tool/dfx/uadk_dfx.c
new file mode 100644
index 0000000..796135a
--- /dev/null
+++ b/uadk_tool/dfx/uadk_dfx.c
@@ -0,0 +1,253 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include "include/wd.h"
+#include "uadk_dfx.h"
+
+#define uadk_build_date()	printf("built on: %s %s\n", __DATE__, __TIME__)
+#define ARRAY_SIZE(x)		(sizeof(x) / sizeof((x)[0]))
+#define PRIVILEGE_FLAG		666
+
+struct uadk_env_var {
+	const char *module;
+	const char *alg;
+	const char *ctx_num_var;
+	const char *epoll_en_var;
+};
+
+struct uadk_env_table {
+	int sync_ctx_num;
+	int sync_numa;
+	int async_ctx_num;
+	int async_numa;
+	int poll_en;
+};
+
+enum dfx_op_type {
+	DISPLAY_VERSION = 2,
+	DISPLAY_DATE,
+	DISPLAY_DIR,
+	DISPLAY_ENV,
+	DISPLAY_COUNT,
+	DISPLAY_HELP,
+};
+
+const char *uadk_modules[] = {"sec", "hpre", "zip"};
+
+const struct uadk_env_var env_vars[] = {
+	{.module = "sec", .alg = "CIPHER", .ctx_num_var = "WD_CIPHER_CTX_NUM",
+	 .epoll_en_var = "WD_CIPHER_EPOLL_EN"},
+	{.module = "sec", .alg = "AEAD", .ctx_num_var = "WD_AEAD_CTX_NUM",
+	 .epoll_en_var = "WD_AEAD_EPOLL_EN"},
+	{.module = "sec", .alg = "DIGEST", .ctx_num_var = "WD_DIGEST_CTX_NUM",
+	 .epoll_en_var = "WD_DIGEST_EPOLL_EN"},
+	{.module = "hpre", .alg = "DH", .ctx_num_var = "WD_DH_CTX_NUM",
+	 .epoll_en_var = "WD_DH_EPOLL_EN"},
+	{.module = "hpre", .alg = "RSA", .ctx_num_var = "WD_RSA_CTX_NUM",
+	 .epoll_en_var = "WD_RSA_EPOLL_EN"},
+	{.module = "hpre", .alg = "ECC", .ctx_num_var = "WD_ECC_CTX_NUM",
+	 .epoll_en_var = "WD_ECC_EPOLL_EN"},
+	{.module = "zip", .alg = "COMP", .ctx_num_var = "WD_COMP_CTX_NUM",
+	 .epoll_en_var = "WD_COMP_EPOLL_EN"},
+};
+
+static void dump_ctx_count(unsigned long *count)
+{
+	__u32 idx = 0;
+	int i;
+
+	if (!count)
+		return;
+
+	printf("displays the ctx counter value...\n");
+	for (i = 0; i < WD_CTX_CNT_NUM; i++) {
+		if (count[i]) {
+			printf("ctx-[%d]:%lu \t", i, count[i]);
+			idx++;
+		} else {
+			continue;
+		}
+
+		if ((idx & 0x3) == 0)
+			printf("\n");
+	}
+	printf("\n");
+}
+
+static int get_shared_id(void)
+{
+	int shm;
+
+	shm = shmget(WD_IPC_KEY, sizeof(unsigned long) * WD_CTX_CNT_NUM,
+		     IPC_CREAT | PRIVILEGE_FLAG);
+	if (shm < 0) {
+		printf("failed to get the shared memory id.\n");
+		return -EINVAL;
+	}
+
+	return shm;
+}
+
+static int uadk_shared_read(void)
+{
+	unsigned long *shared;
+	void *ptr;
+	int shm;
+
+	shm = get_shared_id();
+	if (shm < 0)
+		return -EINVAL;
+
+	ptr = (int *)shmat(shm, NULL, 0);
+	if (ptr < 0) {
+		printf("failed to get the shared memory addr.\n");
+		return -EINVAL;
+	}
+
+	shared = (unsigned long *)ptr;
+
+	printf("get the shared memory addr successful.\n");
+	dump_ctx_count(shared);
+
+	shmdt(ptr);
+
+	return 0;
+}
+
+bool uadk_check_module(const char *module)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(uadk_modules); i++) {
+		if (!strncmp(module, uadk_modules[i], strlen(module)))
+			return true;
+	}
+
+	return false;
+}
+
+static void uadk_ctx_env_config(const char *s)
+{
+	char *env_setion;
+
+	if (!s) {
+		printf("input ctx env config is NULL.\n");
+		return;
+	}
+
+	env_setion = getenv(s);
+	if (!env_setion) {
+		printf("not found the %s env config!\n", s);
+		return;
+	}
+
+	printf("%s=%s\n", s, env_setion);
+}
+
+static void uadk_parse_env_config(const char *module)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(env_vars); i++) {
+		if (!strncmp(module, env_vars[i].module, strlen(module))) {
+			uadk_ctx_env_config(env_vars[i].ctx_num_var);
+			uadk_ctx_env_config(env_vars[i].epoll_en_var);
+		}
+	}
+}
+
+static void uadk_exe_path(void)
+{
+	char dir[PATH_MAX] = {0};
+	int n;
+
+	n = readlink("/proc/self/exe", dir, PATH_MAX);
+	if (n < 0 || n >= PATH_MAX)
+		printf("uadk tool failed to get the exe path.\n");
+
+	dir[PATH_MAX - 1] = '\0';
+	printf("exe path: %s\n", dir);
+}
+
+void print_dfx_help(void)
+{
+	printf("NAME\n");
+	printf("    uadk_tool dfx : uadk library dfx function, etc\n");
+	printf("USAGE\n");
+	printf("    uadk_tool dfx [--version] = Show library version\n");
+	printf("    uadk_tool dfx [--date]    = Show build date\n");
+	printf("    uadk_tool dfx [--dir]     = Show library dir\n");
+	printf("    uadk_tool dfx [--env]     = Show environment variables\n");
+	printf("    uadk_tool dfx [--count]   = Show the ctx message count\n");
+	printf("    uadk_tool dfx [--help]    = usage\n");
+	printf("Example\n");
+	printf("    uadk_tool dfx --version\n");
+	printf("    uadk_tool dfx --env sec\n");
+	printf("    uadk_tool dfx --count\n");
+}
+
+void dfx_cmd_parse(int argc, char *argv[])
+{
+	bool check_module = false;
+	char *input_module = NULL;
+	int option_index = 0;
+	int opt;
+
+	static struct option long_options[] = {
+		{"version", no_argument, 0,  2},
+		{"date",    no_argument, 0,  3},
+		{"dir",     no_argument, 0,  4},
+		{"env",     required_argument, 0,  5},
+		{"count",   no_argument, 0,  6},
+		{"help",    no_argument, 0,  7},
+		{0, 0, 0, 0}
+	};
+
+	while (1) {
+		opt = getopt_long(argc, argv, "", long_options, &option_index);
+		if (opt == -1)
+			break;
+
+		switch (opt) {
+		case DISPLAY_VERSION:
+			wd_get_version();
+			break;
+		case DISPLAY_DATE:
+			uadk_build_date();
+			break;
+		case DISPLAY_DIR:
+			uadk_exe_path();
+			break;
+		case DISPLAY_ENV:
+			input_module = optarg;
+			check_module = uadk_check_module(input_module);
+			if (check_module) {
+				uadk_parse_env_config(input_module);
+			} else {
+				print_dfx_help();
+				printf("failed to parse module parameter!\n");
+			}
+			break;
+		case DISPLAY_COUNT:
+			uadk_shared_read();
+			break;
+		case DISPLAY_HELP:
+			print_dfx_help();
+			break;
+		default:
+			printf("bad input parameter, exit!\n");
+			print_dfx_help();
+			break;
+		}
+	}
+}
diff --git a/uadk_tool/uadk_dfx.h b/uadk_tool/dfx/uadk_dfx.h
similarity index 59%
rename from uadk_tool/uadk_dfx.h
rename to uadk_tool/dfx/uadk_dfx.h
index 5f5d9e7..8dc1da1 100644
--- a/uadk_tool/uadk_dfx.h
+++ b/uadk_tool/dfx/uadk_dfx.h
@@ -2,9 +2,6 @@
 #ifndef UADK_DFX_H
 #define UADK_DFX_H
 
-#define UADK_VERSION_TEXT    "UADK 2.3.22, Released Dec 20th, 2021"
-#define UADK_VERSION_TAG     "4b9c69d"
-
 void print_dfx_help(void);
 void dfx_cmd_parse(int argc, char *argv[]);
 #endif
diff --git a/uadk_tool/uadk_dfx.c b/uadk_tool/uadk_dfx.c
deleted file mode 100644
index 96c4919..0000000
--- a/uadk_tool/uadk_dfx.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0 */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <limits.h>
-#include "uadk_dfx.h"
-
-#define print_date()	printf("built on: %s %s\n", __DATE__, __TIME__)
-
-static void print_version(void)
-{
-	printf("%s\n", UADK_VERSION_TEXT);
-	printf("%s\n", UADK_VERSION_TAG);
-}
-
-static void print_exe_path(void)
-{
-	char dir[PATH_MAX] = {0};
-	int n;
-
-	n = readlink("/proc/self/exe", dir, PATH_MAX);
-	if (n < 0 || n >= PATH_MAX)
-		printf("uadk tool failed to get the exe path.\n");
-
-	printf("exe path: %s\n", dir);
-}
-
-void print_dfx_help(void)
-{
-	printf("NAME\n");
-	printf("    uadk_tool --dfx : uadk library dfx function, etc\n");
-	printf("USAGE\n");
-	printf("        uadk_tool --dfx [--version] = Show library version\n");
-	printf("        uadk_tool --dfx [--date]    = Show build date\n");
-	printf("        uadk_tool --dfx [--dir]     = Show library dir\n");
-	printf("        uadk_tool --dfx [--help]    = usage\n");
-}
-
-void dfx_cmd_parse(int argc, char *argv[])
-{
-	int option_index = 0;
-	int c;
-
-	static struct option long_options[] = {
-		{"version", no_argument, 0,  2},
-		{"date",    no_argument, 0,  3},
-		{"dir",     no_argument, 0,  4},
-		{"help",    no_argument, 0,  5},
-		{0, 0, 0, 0}
-	};
-
-	while (1) {
-		c = getopt_long(argc, argv, "", long_options, &option_index);
-		if (c == -1)
-			break;
-
-		switch (c) {
-		case 2:
-			print_version();
-			break;
-		case 3:
-			print_date();
-			break;
-		case 4:
-			print_exe_path();
-			break;
-		case 5:
-			print_dfx_help();
-			break;
-		default:
-			printf("bad input parameter, exit\n");
-			exit(-1);
-		}
-	}
-}
diff --git a/uadk_tool/uadk_tool.c b/uadk_tool/uadk_tool.c
index 88beeba..ce83d7a 100644
--- a/uadk_tool/uadk_tool.c
+++ b/uadk_tool/uadk_tool.c
@@ -1,12 +1,9 @@
 /* SPDX-License-Identifier: Apache-2.0 */
 
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <time.h>
-#include <limits.h>
-#include "uadk_dfx.h"
-#include "uadk_benchmark.h"
+#include "dfx/uadk_dfx.h"
+#include "benchmark/uadk_benchmark.h"
 
 static void print_tool_help(void)
 {
@@ -18,17 +15,21 @@ static void print_tool_help(void)
 int main(int argc, char **argv)
 {
 	struct acc_option option = {0};
+	int index = 1;
 	int ret;
 
-	if (argc > 1) {
-		if (!strcmp("dfx", argv[1])) {
+	if (argc > index) {
+		if (!strcmp("dfx", argv[index])) {
 			dfx_cmd_parse(argc, argv);
-		} else if (!strcmp("benchmark", argv[1])) {
+		} else if (!strcmp("benchmark", argv[index])) {
 			printf("start UADK benchmark test.\n");
-			if (!argv[2])
+			if (!argv[++index])
 				acc_default_case(&option);
 
-			benchmark_cmd_parse(argc, argv, &option);
+			ret = acc_cmd_parse(argc, argv, &option);
+			if (ret)
+				return ret;
+
 			ret = acc_option_convert(&option);
 			if (ret)
 				return ret;
diff --git a/wd.c b/wd.c
index 3ce9c1e..2dbb2ab 100644
--- a/wd.c
+++ b/wd.c
@@ -14,6 +14,7 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
 #include <numa.h>
 #include <sched.h>
 
@@ -22,7 +23,14 @@
 
 #define SYS_CLASS_DIR			"/sys/class/uacce"
 
-const char *WD_VERSION = UADK_VERSION_NUMBER;
+enum UADK_LOG_LEVEL {
+	LOG_NONE = 0,
+	WD_LOG_ERROR,
+	WD_LOG_INFO,
+	WD_LOG_DEBUG,
+};
+
+static int uadk_log_level;
 
 struct wd_ctx_h {
 	int fd;
@@ -35,6 +43,54 @@ struct wd_ctx_h {
 	void *priv;
 };
 
+static void wd_parse_log_level(void)
+{
+	const char *syslog_file = "/etc/rsyslog.conf";
+	const char *log_dir = "/var/log/uadk.log";
+	bool log_debug = false;
+	bool log_info = false;
+	struct stat file_info;
+	char *file_contents;
+	FILE *in_file;
+
+	in_file = fopen(syslog_file, "r");
+	if (!in_file) {
+		WD_ERR("failed to open the rsyslog.conf file.\n");
+		return;
+	}
+
+	if (stat(syslog_file, &file_info) == -1) {
+		WD_ERR("failed to get file information.\n");
+		goto close_file;
+	}
+
+	file_contents = malloc(file_info.st_size);
+	if (!file_contents) {
+		WD_ERR("failed to get file contents memory.\n");
+		goto close_file;
+	}
+
+	while (fscanf(in_file, "%[^\n ] ", file_contents) != EOF) {
+		if (!strcmp("local5.debug", file_contents))
+			log_debug = true;
+		else if (!strcmp("local5.info", file_contents))
+			log_info = true;
+
+		if (log_debug && !strcmp(log_dir, file_contents)) {
+			uadk_log_level = WD_LOG_DEBUG;
+			break;
+		} else if (log_info && !strcmp(log_dir, file_contents)) {
+			uadk_log_level = WD_LOG_INFO;
+			break;
+		}
+	}
+
+	free(file_contents);
+
+close_file:
+	fclose(in_file);
+}
+
 static int get_raw_attr(const char *dev_root, const char *attr, char *buf,
 			size_t sz)
 {
@@ -189,6 +245,8 @@ static struct uacce_dev *read_uacce_sysfs(const char *dev_name)
 	if (!dev_name)
 		return NULL;
 
+	wd_parse_log_level();
+
 	dev = calloc(1, sizeof(struct uacce_dev));
 	if (!dev)
 		return NULL;
@@ -731,3 +789,22 @@ int wd_ctx_set_io_cmd(handle_t h_ctx, unsigned long cmd, void *arg)
 
 	return ioctl(ctx->fd, cmd, arg);
 }
+
+void wd_get_version(void)
+{
+	const char *wd_released_time = UADK_RELEASED_TIME;
+	const char *wd_version = UADK_VERSION_NUMBER;
+
+	WD_CONSOLE("%s\n", wd_version);
+	WD_CONSOLE("%s\n", wd_released_time);
+}
+
+bool wd_need_debug(void)
+{
+	return uadk_log_level >= WD_LOG_DEBUG;
+}
+
+bool wd_need_info(void)
+{
+	return uadk_log_level >= WD_LOG_INFO;
+}
diff --git a/wd_aead.c b/wd_aead.c
index 7c07271..0c54de3 100644
--- a/wd_aead.c
+++ b/wd_aead.c
@@ -413,7 +413,7 @@ int wd_aead_init(struct wd_ctx_config *config, struct wd_sched *sched)
 	wd_aead_set_static_drv();
 #endif
 
-	/* init sync request pool */
+	/* init async request pool */
 	ret = wd_init_async_request_pool(&wd_aead_setting.pool,
 				config->ctx_num, WD_POOL_MAX_ENTRIES,
 				sizeof(struct wd_aead_msg));
@@ -531,6 +531,7 @@ int wd_do_aead_sync(handle_t h_sess, struct wd_aead_req *req)
 	if (unlikely(ret))
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 	ret = send_recv_sync(ctx, &msg);
 	req->state = msg.result;
@@ -563,6 +564,7 @@ int wd_do_aead_async(handle_t h_sess, struct wd_aead_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	msg_id = wd_get_msg_from_pool(&wd_aead_setting.pool,
diff --git a/wd_cipher.c b/wd_cipher.c
index a7e393b..0cd2e42 100644
--- a/wd_cipher.c
+++ b/wd_cipher.c
@@ -442,7 +442,9 @@ int wd_do_cipher_sync(handle_t h_sess, struct wd_cipher_req *req)
 	if (unlikely(ret))
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
+
 	ret = send_recv_sync(ctx, &msg);
 	req->state = msg.result;
 
@@ -472,6 +474,7 @@ int wd_do_cipher_async(handle_t h_sess, struct wd_cipher_req *req)
 		return ret;
 
 	ctx = config->ctxs + idx;
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 
 	msg_id = wd_get_msg_from_pool(&wd_cipher_setting.pool, idx,
 				   (void **)&msg);
diff --git a/wd_comp.c b/wd_comp.c
index 9107d60..eacebd3 100644
--- a/wd_comp.c
+++ b/wd_comp.c
@@ -406,6 +406,7 @@ static int wd_comp_sync_job(struct wd_comp_sess *sess,
 	if (unlikely(ret))
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	msg_handle.send = wd_comp_setting.driver->comp_send;
@@ -656,6 +657,7 @@ int wd_do_comp_async(handle_t h_sess, struct wd_comp_req *req)
 	if (unlikely(ret))
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	tag = wd_get_msg_from_pool(&wd_comp_setting.pool, idx, (void **)&msg);
diff --git a/wd_dh.c b/wd_dh.c
index 9571ab6..461f04e 100644
--- a/wd_dh.c
+++ b/wd_dh.c
@@ -212,6 +212,7 @@ int wd_do_dh_sync(handle_t sess, struct wd_dh_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	memset(&msg, 0, sizeof(struct wd_dh_msg));
@@ -257,6 +258,7 @@ int wd_do_dh_async(handle_t sess, struct wd_dh_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	mid = wd_get_msg_from_pool(&wd_dh_setting.pool, idx, (void **)&msg);
diff --git a/wd_digest.c b/wd_digest.c
index 0fff7c8..ae37e32 100644
--- a/wd_digest.c
+++ b/wd_digest.c
@@ -340,6 +340,7 @@ int wd_do_digest_sync(handle_t h_sess, struct wd_digest_req *req)
 	if (unlikely(ret))
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 	ret = send_recv_sync(ctx, dsess, &msg);
 	req->state = msg.result;
@@ -372,6 +373,7 @@ int wd_do_digest_async(handle_t h_sess, struct wd_digest_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	msg_id = wd_get_msg_from_pool(&wd_digest_setting.pool, idx,
diff --git a/wd_ecc.c b/wd_ecc.c
index 76c9d5f..1ff6ed3 100644
--- a/wd_ecc.c
+++ b/wd_ecc.c
@@ -853,14 +853,14 @@ static int fill_user_curve_cfg(struct wd_ecc_curve *param,
 	if (setup->cv.type == WD_CV_CFG_ID) {
 		curve_id = setup->cv.cfg.id;
 		ret = fill_param_by_id(param, setup->key_bits, curve_id);
-		dbg("set curve id %u!\n", curve_id);
+		WD_DEBUG("set curve id %u!\n", curve_id);
 	} else if (setup->cv.type == WD_CV_CFG_PARAM) {
 		ret = set_key_cv(param, src_param);
 		if (ret) {
 			WD_ERR("failed to set key cv!\n");
 			return ret;
 		}
-		dbg("set curve by user param!\n");
+		WD_DEBUG("set curve by user param!\n");
 	} else {
 		WD_ERR("invalid: fill curve cfg type %u is error!\n", setup->cv.type);
 		return -WD_EINVAL;
@@ -1407,6 +1407,7 @@ int wd_do_ecc_sync(handle_t h_sess, struct wd_ecc_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	memset(&msg, 0, sizeof(struct wd_ecc_msg));
@@ -2086,6 +2087,7 @@ int wd_do_ecc_async(handle_t sess, struct wd_ecc_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	mid = wd_get_msg_from_pool(&wd_ecc_setting.pool, idx, (void **)&msg);
diff --git a/wd_rsa.c b/wd_rsa.c
index 868e78b..e76da09 100644
--- a/wd_rsa.c
+++ b/wd_rsa.c
@@ -272,6 +272,7 @@ int wd_do_rsa_sync(handle_t h_sess, struct wd_rsa_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	memset(&msg, 0, sizeof(struct wd_rsa_msg));
@@ -317,6 +318,7 @@ int wd_do_rsa_async(handle_t sess, struct wd_rsa_req *req)
 	if (ret)
 		return ret;
 
+	wd_dfx_msg_cnt(config->msg_cnt, WD_CTX_CNT_NUM, idx);
 	ctx = config->ctxs + idx;
 
 	mid = wd_get_msg_from_pool(&wd_rsa_setting.pool, idx, (void **)&msg);
diff --git a/wd_util.c b/wd_util.c
index de77d1e..04a2a5b 100644
--- a/wd_util.c
+++ b/wd_util.c
@@ -20,6 +20,7 @@
 #define WD_BALANCE_THRHD		1280
 #define WD_RECV_MAX_CNT_SLEEP		60000000
 #define WD_RECV_MAX_CNT_NOSLEEP		200000000
+#define PRIVILEGE_FLAG			600
 
 struct msg_pool {
 	/* message array allocated dynamically */
@@ -70,11 +71,76 @@ static void clone_ctx_to_internal(struct wd_ctx *ctx,
 	ctx_in->ctx_mode = ctx->ctx_mode;
 }
 
+static int get_shared_memory_id(__u32 numsize)
+{
+	int shm;
+
+	shm = shmget(WD_IPC_KEY, sizeof(unsigned long) * numsize,
+		IPC_CREAT | PRIVILEGE_FLAG);
+	if (shm < 0) {
+		WD_ERR("failed to get shared memory id.\n");
+		return -WD_EINVAL;
+	}
+
+	return shm;
+}
+
+static unsigned long *wd_shared_create(__u32 numsize)
+{
+	bool need_info = wd_need_info();
+	void *ptr;
+	int shm;
+
+	if (!need_info)
+		return NULL;
+
+	if (numsize > WD_CTX_CNT_NUM) {
+		WD_ERR("invalid: input parameter is err!\n");
+		return NULL;
+	}
+
+	shm = get_shared_memory_id(numsize);
+	if (shm < 0)
+		return NULL;
+
+	ptr = shmat(shm, NULL, 0);
+	if (ptr == (void *)-1) {
+		WD_ERR("failed to get shared memory addr.\n");
+		return NULL;
+	}
+
+	memset(ptr, 0, sizeof(unsigned long) * numsize);
+
+	return ptr;
+}
+
+static void wd_shared_delete(__u32 numsize)
+{
+	bool need_info = wd_need_info();
+	int shm;
+
+	if (!need_info)
+		return;
+
+	if (numsize > WD_CTX_CNT_NUM) {
+		WD_ERR("invalid: input parameter is err!\n");
+		return;
+	}
+
+	shm = get_shared_memory_id(numsize);
+	if (shm < 0)
+		return;
+
+	/* deleted shared memory */
+	shmctl(shm, IPC_RMID, NULL);
+}
+
 int wd_init_ctx_config(struct wd_ctx_config_internal *in,
 		       struct wd_ctx_config *cfg)
 {
+	bool need_info = wd_need_info();
 	struct wd_ctx_internal *ctxs;
-	int i, ret;
+	int i, j, ret;
 
 	if (!cfg->ctx_num) {
 		WD_ERR("invalid: ctx_num is 0!\n");
@@ -87,25 +153,29 @@ int wd_init_ctx_config(struct wd_ctx_config_internal *in,
 		return -WD_EEXIST;
 	}
 
+	in->msg_cnt = wd_shared_create(WD_CTX_CNT_NUM);
+	if (!in->msg_cnt && need_info)
+		return -WD_EINVAL;
+
 	ctxs = calloc(1, cfg->ctx_num * sizeof(struct wd_ctx_internal));
 	if (!ctxs) {
 		WD_ERR("failed to alloc memory for internal ctxs!\n");
+		wd_shared_delete(WD_CTX_CNT_NUM);
 		return -WD_ENOMEM;
 	}
 
 	for (i = 0; i < cfg->ctx_num; i++) {
 		if (!cfg->ctxs[i].ctx) {
 			WD_ERR("invalid: ctx is NULL!\n");
-			free(ctxs);
-			return -WD_EINVAL;
+			ret = -WD_EINVAL;
+			goto err_out;
 		}
 
 		clone_ctx_to_internal(cfg->ctxs + i, ctxs + i);
 		ret = pthread_spin_init(&ctxs[i].lock, PTHREAD_PROCESS_SHARED);
 		if (ret) {
 			WD_ERR("failed to init ctxs lock!\n");
-			free(ctxs);
-			return ret;
+			goto err_out;
 		}
 	}
 
@@ -115,6 +185,14 @@ int wd_init_ctx_config(struct wd_ctx_config_internal *in,
 	in->ctx_num = cfg->ctx_num;
 
 	return 0;
+
+err_out:
+	for (j = 0; j < i; j++)
+		pthread_spin_destroy(&ctxs[j].lock);
+
+	wd_shared_delete(WD_CTX_CNT_NUM);
+	free(ctxs);
+	return ret;
 }
 
 int wd_init_sched(struct wd_sched *in, struct wd_sched *from)
@@ -161,6 +239,9 @@ void wd_clear_ctx_config(struct wd_ctx_config_internal *in)
 		free(in->ctxs);
 		in->ctxs = NULL;
 	}
+
+	wd_shared_delete(WD_CTX_CNT_NUM);
+	in->msg_cnt = NULL;
 }
 
 void wd_memset_zero(void *data, __u32 size)
-- 
2.27.0

