Update the current driver adaptation and usage method, from fixed use of Hisilicon device driver to automatic registration of the driver according to the algorithm.
When the algorithm API layer uses the driver, it is no longer bound to the fixed device driver, but dynamically obtained and stored according to the algorithm query to use.
Update the driver and API layer of the zip and sec module, keep the function of the init interface unchanged, update the implementation of the init2 interface and match the dynamic loading function.
Changes v6 -> v7: - Added dynamically loaded design documents.
Changes v5 -> v6: - Rebase based on the patch of the zlib interface.
Changes v4 -> v5: - Enhance the inclusiveness of the init2 interface.
Changes v3 -> v4: - Remove the template instance code of cipher. - Split the scheduler code into a separate patch.
Changes v2 -> v3: - Add dynamic library file search function - Fix some memory handling issues
Changes v1 -> v2: - Fixed the compatibility method with the previous library file loading
Longfang Liu (6): uadk: Add driver dynamic loading function uadk: update scheduler for dynamic loading uadk: improve the dynamic loading public framework uadk/doc: adding dynamically loaded design documents uadk: added ability to query supported algorithms uadk/zip: Adapt the zip module to the dynamic loading framework
Makefile.am | 4 +- ...sion_and_modular_dynamic_loading_design.md | 432 ++++++++++++++ drv/hisi_comp.c | 59 +- include/drv/wd_comp_drv.h | 27 - include/wd.h | 12 + include/wd_alg.h | 95 +++ include/wd_alg_common.h | 11 + include/wd_sched.h | 6 +- include/wd_util.h | 63 +- libwd.map | 8 + wd.c | 56 +- wd_alg.c | 265 +++++++++ wd_comp.c | 243 ++++---- wd_sched.c | 105 +++- wd_util.c | 549 +++++++++++++++++- 15 files changed, 1769 insertions(+), 166 deletions(-) create mode 100644 docs/UADK_framework_expansion_and_modular_dynamic_loading_design.md create mode 100644 include/wd_alg.h create mode 100644 wd_alg.c
According to the logical layering of UADK, the device driver has been updated from the previous fixed binding HiSilicon accelerator to the dynamic registration method through the algorithm linked list method.
After the update, it can support the use of instruction acceleration and third-party device drivers.
Signed-off-by: Longfang Liu liulongfang@huawei.com --- Makefile.am | 4 +- include/wd_alg.h | 95 ++++++++++++++ include/wd_alg_common.h | 1 + libwd.map | 8 ++ wd_alg.c | 265 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 include/wd_alg.h create mode 100644 wd_alg.c
diff --git a/Makefile.am b/Makefile.am index ee8454b..1ea6d6b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,7 +33,7 @@ AM_CFLAGS+= -DUADK_RELEASED_TIME=""Released ${MONTH} ${DAY}, ${YEAR}"" pkginclude_HEADERS = include/wd.h include/wd_cipher.h include/wd_aead.h \ include/wd_comp.h include/wd_dh.h include/wd_digest.h \ include/wd_rsa.h include/uacce.h include/wd_alg_common.h \ - include/wd_ecc.h include/wd_sched.h + include/wd_ecc.h include/wd_sched.h include/wd_alg.h
nobase_pkginclude_HEADERS = v1/wd.h v1/wd_cipher.h v1/wd_aead.h v1/uacce.h v1/wd_dh.h \ v1/wd_digest.h v1/wd_rsa.h v1/wd_bmm.h @@ -41,7 +41,7 @@ nobase_pkginclude_HEADERS = v1/wd.h v1/wd_cipher.h v1/wd_aead.h v1/uacce.h v1/wd lib_LTLIBRARIES=libwd.la libwd_comp.la libwd_crypto.la libhisi_zip.la \ libhisi_hpre.la libhisi_sec.la
-libwd_la_SOURCES=wd.c wd_mempool.c wd.h \ +libwd_la_SOURCES=wd.c wd_mempool.c wd.h wd_alg.c wd_alg.h \ v1/wd.c v1/wd.h v1/wd_adapter.c v1/wd_adapter.h \ v1/wd_rng.c v1/wd_rng.h \ v1/wd_rsa.c v1/wd_rsa.h \ diff --git a/include/wd_alg.h b/include/wd_alg.h new file mode 100644 index 0000000..e25e191 --- /dev/null +++ b/include/wd_alg.h @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + * Copyright 2023 Huawei Technologies Co.,Ltd. All rights reserved. + */ + +#ifndef __WD_ALG_H +#define __WD_ALG_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> + +#ifdef __cplusplus +extern "C" { +#endif + +#define handle_t uintptr_t +enum alg_priority { + UADK_ALG_SOFT = 0x0, + UADK_ALG_CE_INSTR = 0x1, + UADK_ALG_SVE_INSTR = 0x2, + UADK_ALG_HW = 0x3 +}; + +/** + * @drv_name: name of the current device driver + * @alg_name: name of the algorithm supported by the driver + * @priority: priority of the type of algorithm supported by the driver + * @queue_num: number of device queues required by the device to + * execute the algorithm task + * @op_type_num: number of modes in which the device executes the + * algorithm business and requires queues to be executed separately + * @priv_size: parameter memory size passed between the internal + * interfaces of the driver + * @fallback: soft calculation driver handle when performing soft + * calculation supplement + * @init: callback interface for initializing device drivers + * @exit: callback interface for destroying device drivers + * @send: callback interface used to send task packets to + * hardware devices. + * @recv: callback interface used to retrieve the calculation + * result of the task packets from the hardware device. + * @get_usage: callback interface used to obtain the + * utilization rate of devices. + */ +struct wd_alg_driver { + const char *drv_name; + const char *alg_name; + int priority; + int queue_num; + int op_type_num; + int priv_size; + handle_t fallback; + + int (*init)(void *conf, void *priv); + void (*exit)(void *priv); + int (*send)(handle_t ctx, void *drv_msg); + int (*recv)(handle_t ctx, void *drv_msg); + int (*get_usage)(void *param); +}; + +int wd_alg_driver_register(struct wd_alg_driver *drv); +void wd_alg_driver_unregister(struct wd_alg_driver *drv); + +struct wd_alg_list { + const char *alg_name; + const char *drv_name; + bool available; + int priority; + int refcnt; + + struct wd_alg_driver *drv; + struct wd_alg_list *next; +}; + +struct wd_alg_driver *wd_request_drv(const char *alg_name, bool hw_mask); +void wd_release_drv(struct wd_alg_driver *drv); + +bool wd_drv_alg_support(const char *alg_name, + struct wd_alg_driver *drv); +void wd_enable_drv(struct wd_alg_driver *drv); +void wd_disable_drv(struct wd_alg_driver *drv); + +struct wd_alg_list *wd_get_alg_head(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/wd_alg_common.h b/include/wd_alg_common.h index 56539cc..d04b046 100644 --- a/include/wd_alg_common.h +++ b/include/wd_alg_common.h @@ -10,6 +10,7 @@ #include <pthread.h> #include <stdbool.h> #include "wd.h" +#include "wd_alg.h"
#ifdef __cplusplus extern "C" { diff --git a/libwd.map b/libwd.map index 459f9ba..5522ec0 100644 --- a/libwd.map +++ b/libwd.map @@ -41,5 +41,13 @@ global: wd_add_dev_to_list; wd_find_dev_by_numa;
+ wd_alg_driver_register; + wd_alg_driver_unregister; + wd_request_drv; + wd_release_drv; + wd_drv_alg_support; + wd_enable_drv; + wd_disable_drv; + wd_get_alg_head; local: *; }; diff --git a/wd_alg.c b/wd_alg.c new file mode 100644 index 0000000..5e4edaf --- /dev/null +++ b/wd_alg.c @@ -0,0 +1,265 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2023 Huawei Technologies Co.,Ltd. All rights reserved. + */ + +#define _GNU_SOURCE +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> + +#include "wd.h" +#include "wd_alg.h" + +#define SYS_CLASS_DIR "/sys/class/uacce" +static struct wd_alg_list alg_list_head; +static struct wd_alg_list *alg_list_tail = &alg_list_head; + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +static bool wd_check_accel_dev(const char *dev_name) +{ + struct dirent *dev_dir; + DIR *wd_class; + + wd_class = opendir(SYS_CLASS_DIR); + if (!wd_class) { + WD_ERR("UADK framework isn't enabled in system!\n"); + return false; + } + + while ((dev_dir = readdir(wd_class)) != NULL) { + if (!strncmp(dev_dir->d_name, ".", LINUX_CRTDIR_SIZE) || + !strncmp(dev_dir->d_name, "..", LINUX_PRTDIR_SIZE)) + continue; + + if (!strncmp(dev_dir->d_name, dev_name, strlen(dev_name))) { + closedir(wd_class); + return true; + } + } + closedir(wd_class); + + return false; +} + +int wd_alg_driver_register(struct wd_alg_driver *drv) +{ + struct wd_alg_list *new_alg; + + if (!drv) { + WD_ERR("invalid: register drv is NULL!\n"); + return -WD_EINVAL; + } + + new_alg = calloc(1, sizeof(struct wd_alg_list)); + if (!new_alg) { + WD_ERR("failed to alloc alg driver memory!\n"); + return -WD_ENOMEM; + } + + new_alg->alg_name = drv->alg_name; + new_alg->drv_name = drv->drv_name; + new_alg->priority = drv->priority; + new_alg->drv = drv; + new_alg->refcnt = 0; + new_alg->next = NULL; + + if (drv->priority == UADK_ALG_HW) { + /* If not find dev, remove this driver node */ + new_alg->available = wd_check_accel_dev(drv->drv_name); + if (!new_alg->available) { + free(new_alg); + WD_ERR("failed to find alg driver's device!\n"); + return -WD_ENODEV; + } + } else { + /* Should find the CPU if not support SVE or CE */ + new_alg->available = true; + } + + pthread_mutex_lock(&mutex); + alg_list_tail->next = new_alg; + alg_list_tail = new_alg; + pthread_mutex_unlock(&mutex); + + return 0; +} + +void wd_alg_driver_unregister(struct wd_alg_driver *drv) +{ + struct wd_alg_list *npre = &alg_list_head; + struct wd_alg_list *pnext = npre->next; + + /* Alg driver list has no drivers */ + if (!pnext || !drv) + return; + + pthread_mutex_lock(&mutex); + while (pnext) { + if (!strcmp(drv->alg_name, pnext->alg_name) && + !strcmp(drv->drv_name, pnext->drv_name) && + drv->priority == pnext->priority) { + break; + } + npre = pnext; + pnext = pnext->next; + } + + /* The current algorithm is not registered */ + if (!pnext) { + pthread_mutex_unlock(&mutex); + return; + } + + /* Used to locate the problem and ensure symmetrical use driver */ + if (pnext->refcnt > 0) + WD_ERR("driver<%s> still in used: %d\n", pnext->drv_name, pnext->refcnt); + + if (pnext == alg_list_tail) + alg_list_tail = npre; + + npre->next = pnext->next; + free(pnext); + pthread_mutex_unlock(&mutex); +} + +struct wd_alg_list *wd_get_alg_head(void) +{ + return &alg_list_head; +} + +bool wd_drv_alg_support(const char *alg_name, + struct wd_alg_driver *drv) +{ + struct wd_alg_list *head = &alg_list_head; + struct wd_alg_list *pnext = head->next; + + while (pnext) { + if (!strcmp(alg_name, pnext->alg_name) && + !strcmp(drv->drv_name, pnext->drv_name)) { + return true; + } + pnext = pnext->next; + } + + return false; +} + +void wd_enable_drv(struct wd_alg_driver *drv) +{ + struct wd_alg_list *head = &alg_list_head; + struct wd_alg_list *pnext = head->next; + + if (!pnext || !drv) + return; + + pthread_mutex_lock(&mutex); + while (pnext) { + if (!strcmp(drv->alg_name, pnext->alg_name) && + !strcmp(drv->drv_name, pnext->drv_name) && + drv->priority == pnext->priority) { + break; + } + pnext = pnext->next; + } + + if (drv->priority == UADK_ALG_HW) { + /* If not find dev, remove this driver node */ + pnext->available = wd_check_accel_dev(drv->drv_name); + } else { + /* Should find the CPU if not support SVE or CE */ + pnext->available = true; + } + pthread_mutex_unlock(&mutex); +} + +void wd_disable_drv(struct wd_alg_driver *drv) +{ + struct wd_alg_list *head = &alg_list_head; + struct wd_alg_list *pnext = head->next; + + if (!pnext || !drv) + return; + + pthread_mutex_lock(&mutex); + while (pnext) { + if (!strcmp(drv->alg_name, pnext->alg_name) && + !strcmp(drv->drv_name, pnext->drv_name) && + drv->priority == pnext->priority) { + break; + } + pnext = pnext->next; + } + + pnext->available = false; + pthread_mutex_unlock(&mutex); +} + +struct wd_alg_driver *wd_request_drv(const char *alg_name, bool hw_mask) +{ + struct wd_alg_list *head = &alg_list_head; + struct wd_alg_list *pnext = head->next; + struct wd_alg_list *select_node = NULL; + struct wd_alg_driver *drv = NULL; + int tmp_priority = -1; + + if (!pnext || !alg_name) { + WD_ERR("invalid: request alg param is error!\n"); + return NULL; + } + + /* Check the list to get an best driver */ + pthread_mutex_lock(&mutex); + while (pnext) { + /* hw_mask true mean not to used hardware dev */ + if (hw_mask && pnext->drv->priority == UADK_ALG_HW) { + pnext = pnext->next; + continue; + } + + if (!strcmp(alg_name, pnext->alg_name) && pnext->available && + pnext->drv->priority > tmp_priority) { + tmp_priority = pnext->drv->priority; + select_node = pnext; + drv = pnext->drv; + } + pnext = pnext->next; + } + + if (select_node) + select_node->refcnt++; + pthread_mutex_unlock(&mutex); + + return drv; +} + +void wd_release_drv(struct wd_alg_driver *drv) +{ + struct wd_alg_list *head = &alg_list_head; + struct wd_alg_list *pnext = head->next; + struct wd_alg_list *select_node = NULL; + + if (!pnext || !drv) + return; + + pthread_mutex_lock(&mutex); + while (pnext) { + if (!strcmp(drv->alg_name, pnext->alg_name) && + !strcmp(drv->drv_name, pnext->drv_name) && + drv->priority == pnext->priority) { + select_node = pnext; + break; + } + pnext = pnext->next; + } + + if (select_node && select_node->refcnt > 0) + select_node->refcnt--; + pthread_mutex_unlock(&mutex); +} +
The dynamic loading function of uadk requires two new types of scheduler modes, which are used to adapt to instruction acceleration without hardware resources and SVE acceleration that needs to be bound to CPU cores.
Signed-off-by: Longfang Liu liulongfang@huawei.com --- include/wd_sched.h | 6 ++- wd_sched.c | 105 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 105 insertions(+), 6 deletions(-)
diff --git a/include/wd_sched.h b/include/wd_sched.h index 2ae6103..a492d70 100644 --- a/include/wd_sched.h +++ b/include/wd_sched.h @@ -18,7 +18,11 @@ extern "C" { enum sched_policy_type { /* requests will be sent to ctxs one by one */ SCHED_POLICY_RR = 0, - SCHED_POLICY_BUTT + /* requests will no need ctxs */ + SCHED_POLICY_NONE, + /* requests will need a fixed ctx */ + SCHED_POLICY_SINGLE, + SCHED_POLICY_BUTT, };
struct sched_params { diff --git a/wd_sched.c b/wd_sched.c index 98f4cfd..9a52c4d 100644 --- a/wd_sched.c +++ b/wd_sched.c @@ -347,6 +347,82 @@ static int session_sched_poll_policy(handle_t h_sched_ctx, __u32 expect, __u32 * return 0; }
+static handle_t sched_none_init(handle_t h_sched_ctx, void *sched_param) +{ + return (handle_t)0; +} + +static __u32 sched_none_pick_next_ctx(handle_t sched_ctx, + void *sched_key, const int sched_mode) +{ + return 0; +} + +static int sched_none_poll_policy(handle_t h_sched_ctx, + __u32 expect, __u32 *count) +{ + struct wd_sched_ctx *sched_ctx = (struct wd_sched_ctx *)h_sched_ctx; + __u32 loop_times = MAX_POLL_TIMES + expect; + __u32 poll_num = 0; + int ret; + + while (loop_times > 0) { + /* Default use ctx 0 */ + ret = sched_ctx->poll_func(0, 1, &poll_num); + if ((ret < 0) && (ret != -EAGAIN)) + return ret; + else if (ret == -EAGAIN) + continue; + + *count += poll_num; + if (*count == expect) + break; + } + + return 0; +} + +static handle_t sched_single_init(handle_t h_sched_ctx, void *sched_param) +{ + return (handle_t)0; +} + +static __u32 sched_single_pick_next_ctx(handle_t sched_ctx, + void *sched_key, const int sched_mode) +{ +#define CTX_ASYNC 1 +#define CTX_SYNC 0 + + if (sched_mode) + return CTX_ASYNC; + else + return CTX_SYNC; +} + +static int sched_single_poll_policy(handle_t h_sched_ctx, + __u32 expect, __u32 *count) +{ + struct wd_sched_ctx *sched_ctx = (struct wd_sched_ctx *)h_sched_ctx; + __u32 loop_times = MAX_POLL_TIMES + expect; + __u32 poll_num = 0; + int ret; + + while (loop_times > 0) { + /* Default async mode use ctx 0 */ + ret = sched_ctx->poll_func(0, 1, &poll_num); + if ((ret < 0) && (ret != -EAGAIN)) + return ret; + else if (ret == -EAGAIN) + continue; + + *count += poll_num; + if (*count == expect) + break; + } + + return 0; +} + static struct wd_sched sched_table[SCHED_POLICY_BUTT] = { { .name = "RR scheduler", @@ -354,7 +430,19 @@ static struct wd_sched sched_table[SCHED_POLICY_BUTT] = { .sched_init = session_sched_init, .pick_next_ctx = session_sched_pick_next_ctx, .poll_policy = session_sched_poll_policy, - }, + }, { + .name = "None scheduler", + .sched_policy = SCHED_POLICY_SINGLE, + .sched_init = sched_none_init, + .pick_next_ctx = sched_none_pick_next_ctx, + .poll_policy = sched_none_poll_policy, + }, { + .name = "Single scheduler", + .sched_policy = SCHED_POLICY_SINGLE, + .sched_init = sched_single_init, + .pick_next_ctx = sched_single_pick_next_ctx, + .poll_policy = sched_single_poll_policy, + } };
static int wd_sched_get_nearby_numa_id(struct wd_sched_info *sched_info, int node, int numa_num) @@ -463,9 +551,12 @@ void wd_sched_rr_release(struct wd_sched *sched)
sched_ctx = (struct wd_sched_ctx *)sched->h_sched_ctx; if (!sched_ctx) - goto out; + goto ctx_out;
sched_info = sched_ctx->sched_info; + if (!sched_info) + goto info_out; + for (i = 0; i < sched_ctx->numa_num; i++) { for (j = 0; j < SCHED_MODE_BUTT; j++) { if (sched_info[i].ctx_region[j]) { @@ -475,9 +566,9 @@ void wd_sched_rr_release(struct wd_sched *sched) } }
+info_out: free(sched_ctx); - -out: +ctx_out: free(sched);
return; @@ -531,8 +622,11 @@ struct wd_sched *wd_sched_rr_alloc(__u8 sched_type, __u8 type_num, }
sched->h_sched_ctx = (handle_t)sched_ctx; - sched_info = sched_ctx->sched_info; + if (sched_type == SCHED_POLICY_NONE || + sched_type == SCHED_POLICY_SINGLE) + goto simple_ok;
+ sched_info = sched_ctx->sched_info; for (i = 0; i < numa_num; i++) { for (j = 0; j < SCHED_MODE_BUTT; j++) { sched_info[i].ctx_region[j] = @@ -542,6 +636,7 @@ struct wd_sched *wd_sched_rr_alloc(__u8 sched_type, __u8 type_num, } }
+simple_ok: sched_ctx->poll_func = func; sched_ctx->policy = sched_type; sched_ctx->type_num = type_num;
After the dynamic loading function is added, device resource initialization, driver acquisition, and scheduler initialization functions need to be extracted into the public framework.
so that the algorithm can quickly adapt to the dynamic loading function internally.
Signed-off-by: Longfang Liu liulongfang@huawei.com --- include/wd_alg_common.h | 10 + include/wd_util.h | 63 ++++- wd_comp.c | 2 +- wd_util.c | 549 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 620 insertions(+), 4 deletions(-)
diff --git a/include/wd_alg_common.h b/include/wd_alg_common.h index d04b046..31208ad 100644 --- a/include/wd_alg_common.h +++ b/include/wd_alg_common.h @@ -28,6 +28,13 @@ extern "C" { #define CTX_TYPE_INVALID 9999 #define POLL_TIME 1000
+enum alg_task_type { + TASK_MIX = 0x0, + TASK_HW, + TASK_INSTR, + TASK_MAX_TYPE, +}; + enum wd_ctx_mode { CTX_MODE_SYNC = 0, CTX_MODE_ASYNC, @@ -130,6 +137,9 @@ struct wd_sched { handle_t h_sched_ctx; };
+typedef int (*wd_alg_init)(struct wd_ctx_config *config, struct wd_sched *sched); +typedef int (*wd_alg_poll_ctx)(__u32 idx, __u32 expt, __u32 *count); + struct wd_datalist { void *data; __u32 len; diff --git a/include/wd_util.h b/include/wd_util.h index d4b2814..a730f36 100644 --- a/include/wd_util.h +++ b/include/wd_util.h @@ -117,9 +117,12 @@ struct wd_msg_handle { struct wd_init_attrs { __u32 sched_type; char *alg; + struct wd_alg_driver *driver; struct wd_sched *sched; struct wd_ctx_params *ctx_params; struct wd_ctx_config *ctx_config; + wd_alg_init alg_init; + wd_alg_poll_ctx alg_poll_ctx; };
/* @@ -415,13 +418,69 @@ static inline void wd_alg_clear_init(enum wd_status *status) }
/** - * wd_alg_pre_init() - Request the ctxs and initialize the sched_domain + * wd_ctx_param_init() - Initialize the current device driver according + * to the obtained queue resource and the applied driver. + * @config: device resources requested by the current algorithm. + * @driver: device driver for the current algorithm application. + * @drv_priv: the parameter pointer of the current device driver. + * + * Return 0 if succeed and other error number if fail. + */ +int wd_ctx_param_init(struct wd_ctx_params *ctx_params, + struct wd_ctx_params *user_ctx_params, + struct wd_ctx_nums *ctx_set_num, + struct wd_alg_driver *driver, int max_op_type); + +/** + * wd_alg_attrs_init() - Request the ctxs and initialize the sched_domain * with the given devices list, ctxs number and numa mask. * @attrs: the algorithm initialization parameters. * * Return device if succeed and other error number if fail. */ -int wd_alg_pre_init(struct wd_init_attrs *attrs); +int wd_alg_attrs_init(struct wd_init_attrs *attrs); +void wd_alg_attrs_uninit(struct wd_init_attrs *attrs); + +/** + * wd_alg_drv_bind() - Request the ctxs and initialize the sched_domain + * with the given devices list, ctxs number and numa mask. + * @task_type: the type of task specified by the current algorithm. + * @alg_name: the name of the algorithm specified by the task. + * + * Return device driver if succeed and other NULL if fail. + */ +struct wd_alg_driver *wd_alg_drv_bind(int task_type, char *alg_name); +void wd_alg_drv_unbind(struct wd_alg_driver *drv); + +/** + * wd_alg_init_driver() - Initialize the current device driver according + * to the obtained queue resource and the applied driver. + * @config: device resources requested by the current algorithm. + * @driver: device driver for the current algorithm application. + * @drv_priv: the parameter pointer of the current device driver. + * + * Return 0 if succeed and other error number if fail. + */ +int wd_alg_init_driver(struct wd_ctx_config_internal *config, + struct wd_alg_driver *driver, void **drv_priv); +void wd_alg_uninit_driver(struct wd_ctx_config_internal *config, + struct wd_alg_driver *driver, void **drv_priv); + +/** + * wd_dlopen_drv() - Open the dynamic library file of the device driver. + * @cust_lib_dir: the file path of the dynamic library file. + */ +void *wd_dlopen_drv(const char *cust_lib_dir); +void wd_dlclose_drv(void *dlh_list); + +/** + * wd_get_lib_file_path() - Find the path of the dynamic library file in + * the current system. + * @lib_file: the name of the library file. + * @lib_path: the found dynamic library file path. + * @is_dir: Specify whether to query the file dir or the file path. + */ +int wd_get_lib_file_path(char *lib_file, char *lib_path, bool is_dir);
/** * wd_dfx_msg_cnt() - Message counter interface for ctx diff --git a/wd_comp.c b/wd_comp.c index cca6eb9..ecfa573 100644 --- a/wd_comp.c +++ b/wd_comp.c @@ -248,7 +248,7 @@ int wd_comp_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_par wd_comp_sched->name = SCHED_RR_NAME; wd_comp_init_attrs.sched = wd_comp_sched;
- ret = wd_alg_pre_init(&wd_comp_init_attrs); + ret = wd_alg_attrs_init(&wd_comp_init_attrs); if (ret) goto out_freesched;
diff --git a/wd_util.c b/wd_util.c index 433dd56..dab4fc8 100644 --- a/wd_util.c +++ b/wd_util.c @@ -5,6 +5,8 @@ */
#define _GNU_SOURCE +#include <dirent.h> +#include <dlfcn.h> #include <pthread.h> #include <semaphore.h> #include <string.h> @@ -23,6 +25,8 @@ #define WD_INIT_SLEEP_UTIME 1000 #define WD_INIT_RETRY_TIMES 10000
+#define DEF_DRV_LIB_FILE "libwd.so" + struct msg_pool { /* message array allocated dynamically */ void *msgs; @@ -64,6 +68,72 @@ struct async_task_queue { int (*alg_poll_ctx)(__u32, __u32, __u32 *); };
+struct drv_lib_list { + void *dlhandle; + struct drv_lib_list *next; +}; + +struct acc_alg_item { + char *name; + char *algtype; +}; + +static struct acc_alg_item alg_options[] = { + {"zlib", "zlib-deflate"}, + {"gzip", "gzip"}, + {"deflate", "deflate"}, + {"lz77_zstd", "lz77_zstd"}, + + {"rsa", "rsa"}, + {"dh", "dh"}, + {"ecdh", "ecdh"}, + {"x25519", "x25519"}, + {"x448", "x448"}, + {"ecdsa", "ecdsa"}, + {"sm2", "sm2"}, + + {"ecb(aes)", "cipher"}, + {"cbc(aes)", "cipher"}, + {"xts(aes)", "cipher"}, + {"ofb(aes)", "cipher"}, + {"cfb(aes)", "cipher"}, + {"ctr(aes)", "cipher"}, + {"cbc-cs1(aes)", "cipher"}, + {"cbc-cs2(aes)", "cipher"}, + {"cbc-cs3(aes)", "cipher"}, + {"ecb(sm4)", "cipher"}, + {"xts(sm4)", "cipher"}, + {"cbc(sm4)", "cipher"}, + {"ofb(sm4)", "cipher"}, + {"cfb(sm4)", "cipher"}, + {"ctr(sm4)", "cipher"}, + {"cbc-cs1(sm4)", "cipher"}, + {"cbc-cs2(sm4)", "cipher"}, + {"cbc-cs3(sm4)", "cipher"}, + {"ecb(des)", "cipher"}, + {"cbc(des)", "cipher"}, + {"ecb(des3_ede)", "cipher"}, + {"cbc(des3_ede)", "cipher"}, + + {"ccm(aes)", "aead"}, + {"gcm(aes)", "aead"}, + {"ccm(sm4)", "aead"}, + {"gcm(sm4)", "aead"}, + {"authenc(hmac(sha256),cbc(aes))", "aead"}, + {"authenc(hmac(sha256),cbc(sm4))", "aead"}, + + {"sm3", "digest"}, + {"md5", "digest"}, + {"sha1", "digest"}, + {"sha256", "digest"}, + {"sha224", "digest"}, + {"sha384", "digest"}, + {"sha512", "digest"}, + {"sha512-224", "digest"}, + {"sha512-256", "digest"}, + {"", ""} +}; + static void clone_ctx_to_internal(struct wd_ctx *ctx, struct wd_ctx_internal *ctx_in) { @@ -1779,6 +1849,358 @@ int wd_init_param_check(struct wd_ctx_config *config, struct wd_sched *sched) return 0; }
+static void wd_get_alg_type(const char *alg_name, char *alg_type) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(alg_options); i++) { + if (strcmp(alg_name, alg_options[i].name) == 0) { + (void)strcpy(alg_type, alg_options[i].algtype); + break; + } + } +} + +/** + * There are many other .so files in this file directory (/root/lib/), + * and it is necessary to screen out valid uadk driver files + * through this function. + */ +static int file_check_valid(char *lib_file) +{ +#define FILE_HEAD_SZ 4 +#define FILE_TAIL_SZ 4 + int file_len = strlen(lib_file); + char file_head[FILE_HEAD_SZ] = "lib"; + char file_tail[FILE_TAIL_SZ] = ".so"; + int i, j; + + /* Lib file name is libxx_xxx.so */ + for (i = 0; i < FILE_HEAD_SZ - 1; i++) { + if (lib_file[i] != file_head[i]) + return -EINVAL; + } + + for (i = file_len - (FILE_TAIL_SZ - 1), j = 0; + i < file_len && j < FILE_TAIL_SZ; i++, j++) { + if (lib_file[i] != file_tail[j]) + return -EINVAL; + } + + return 0; +} + +static int wd_alg_init_fallback(struct wd_alg_driver *fb_driver) +{ + if (!fb_driver->init) { + WD_ERR("soft sec driver have no init interface.\n"); + return -WD_EINVAL; + } + + fb_driver->init(NULL, NULL); + + return 0; +} + +static void wd_alg_uninit_fallback(struct wd_alg_driver *fb_driver) +{ + if (!fb_driver->exit) { + WD_ERR("soft sec driver have no exit interface.\n"); + return; + } + + fb_driver->exit(NULL); +} + +int wd_alg_init_driver(struct wd_ctx_config_internal *config, + struct wd_alg_driver *driver, void **drv_priv) +{ + void *priv; + int ret; + + /* Init ctx related resources in specific driver */ + priv = calloc(1, driver->priv_size); + if (!priv) + return -WD_ENOMEM; + + if (!driver->init) { + driver->fallback = 0; + WD_ERR("driver have no init interface.\n"); + ret = -WD_EINVAL; + goto err_alloc; + } + + ret = driver->init(config, priv); + if (ret < 0) { + WD_ERR("driver init failed.\n"); + goto err_alloc; + } + + if (driver->fallback) { + ret = wd_alg_init_fallback((struct wd_alg_driver *)driver->fallback); + if (ret) { + driver->fallback = 0; + WD_ERR("soft alg driver init failed.\n"); + } + } + *drv_priv = priv; + + return 0; + +err_alloc: + free(priv); + return ret; +} + +void wd_alg_uninit_driver(struct wd_ctx_config_internal *config, + struct wd_alg_driver *driver, void **drv_priv) +{ + void *priv = *drv_priv; + + driver->exit(priv); + /* Ctx config just need clear once */ + if (driver->priority == UADK_ALG_HW) + wd_clear_ctx_config(config); + + if (driver->fallback) + wd_alg_uninit_fallback((struct wd_alg_driver *)driver->fallback); + + if (priv) { + free(priv); + priv = NULL; + } +} + +void wd_dlclose_drv(void *dlh_list) +{ + struct drv_lib_list *dlhead = (struct drv_lib_list *)dlh_list; + struct drv_lib_list *dlnode; + + if (!dlhead) { + WD_INFO("driver so file list is empty.\n"); + return; + } + + while (dlhead) { + dlnode = dlhead; + dlhead = dlhead->next; + dlclose(dlnode); + free(dlnode); + } +} + +static void add_lib_to_list(struct drv_lib_list *head, + struct drv_lib_list *node) +{ + struct drv_lib_list *tmp = head; + + while (tmp->next) + tmp = tmp->next; + + tmp->next = node; +} + +int wd_ctx_param_init(struct wd_ctx_params *ctx_params, + struct wd_ctx_params *user_ctx_params, + struct wd_ctx_nums *ctx_set_num, + struct wd_alg_driver *driver, int max_op_type) +{ + int i; + + if (!user_ctx_params) { + ctx_params->bmp = NULL; + ctx_params->ctx_set_num = ctx_set_num; + ctx_params->op_type_num = driver->op_type_num; + if (ctx_params->op_type_num > max_op_type) { + WD_ERR("fail to check driver op type numbers.\n"); + return -WD_EAGAIN; + } + + for (i = 0; i < ctx_params->op_type_num; i++) { + ctx_set_num[i].sync_ctx_num = driver->queue_num; + ctx_set_num[i].async_ctx_num = driver->queue_num; + } + } else { + ctx_params->bmp = user_ctx_params->bmp; + ctx_params->ctx_set_num = user_ctx_params->ctx_set_num; + ctx_params->op_type_num = user_ctx_params->op_type_num; + if (ctx_params->op_type_num > max_op_type) { + WD_ERR("fail to check user op type numbers.\n"); + return -WD_EINVAL; + } + } + + return 0; +} + +static void dladdr_empty(void) {} +int wd_get_lib_file_path(char *lib_file, char *lib_path, bool is_dir) +{ + char file_path[PATH_STR_SIZE] = {0}; + Dl_info file_info; + int len, rc, i; + + /* Get libwd.so file's system path */ + rc = dladdr((void *)dladdr_empty, &file_info); + if (!rc) { + WD_ERR("fail to get lib file path.\n"); + return -WD_EINVAL; + } + strncpy(file_path, file_info.dli_fname, PATH_STR_SIZE - 1); + + /* Clear the file path's tail file name */ + len = strlen(file_path) - 1; + for (i = len; i >= 0; i--) { + if (file_path[i] == '/') { + memset(&file_path[i], 0, PATH_STR_SIZE - i + 1); + break; + } + } + + if (is_dir) { + (void)snprintf(lib_path, PATH_STR_SIZE, "%s", file_path); + return 0; + } + + len = snprintf(lib_path, PATH_STR_SIZE, "%s/%s", file_path, lib_file); + if (len < 0) + return -WD_EINVAL; + + return 0; +} + +void *wd_dlopen_drv(const char *cust_lib_dir) +{ + typedef int (*alg_ops)(struct wd_alg_driver *drv); + struct drv_lib_list *node, *head = NULL; + char lib_dir_path[PATH_STR_SIZE] = {0}; + char lib_path[PATH_STR_SIZE] = {0}; + struct dirent *lib_dir; + alg_ops dl_func = NULL; + DIR *wd_dir; + int ret; + + if (!cust_lib_dir) { + ret = wd_get_lib_file_path(NULL, lib_dir_path, true); + if (ret) + return NULL; + } else { + (void)snprintf(lib_path, PATH_STR_SIZE, "%s/%s", cust_lib_dir, DEF_DRV_LIB_FILE); + ret = access(lib_path, F_OK); + if (ret) + return NULL; + + strncpy(lib_dir_path, cust_lib_dir, PATH_STR_SIZE - 1); + } + + wd_dir = opendir(lib_dir_path); + if (!wd_dir) { + WD_ERR("UADK driver lib dir: %s not exist!\n", lib_dir_path); + return NULL; + } + + while ((lib_dir = readdir(wd_dir)) != NULL) { + if (!strncmp(lib_dir->d_name, ".", LINUX_CRTDIR_SIZE) || + !strncmp(lib_dir->d_name, "..", LINUX_PRTDIR_SIZE)) + continue; + + ret = file_check_valid(lib_dir->d_name); + if (ret) + continue; + + node = calloc(1, sizeof(*node)); + if (!node) + goto free_list; + + ret = snprintf(lib_path, PATH_STR_SIZE, "%s/%s", lib_dir_path, lib_dir->d_name); + if (ret < 0) + goto free_node; + + node->dlhandle = dlopen(lib_path, RTLD_NOW); + if (!node->dlhandle) { + free(node); + /* there are many other files need to skip */ + continue; + } + + dl_func = dlsym(node->dlhandle, "wd_alg_driver_register"); + if (dl_func == NULL) { + dlclose(node->dlhandle); + free(node); + continue; + } + + if (!head) + head = node; + else + add_lib_to_list(head, node); + } + closedir(wd_dir); + + return (void *)head; + +free_node: + free(node); +free_list: + closedir(wd_dir); + wd_dlclose_drv(head); + return NULL; +} + +struct wd_alg_driver *wd_alg_drv_bind(int task_type, char *alg_name) +{ + struct wd_alg_driver *set_driver = NULL; + struct wd_alg_driver *drv; + + /* Get alg driver and dev name */ + switch (task_type) { + case TASK_INSTR: + drv = wd_request_drv(alg_name, true); + if (!drv) { + WD_ERR("no soft %s driver support\n", alg_name); + return NULL; + } + set_driver = drv; + set_driver->fallback = 0; + break; + case TASK_HW: + case TASK_MIX: + drv = wd_request_drv(alg_name, false); + if (!drv) { + WD_ERR("no HW %s driver support\n", alg_name); + return NULL; + } + set_driver = drv; + set_driver->fallback = 0; + if (task_type == TASK_MIX) { + drv = wd_request_drv(alg_name, true); + if (!drv) { + set_driver->fallback = 0; + WD_ERR("no soft %s driver support\n", alg_name); + } else { + set_driver->fallback = (handle_t)drv; + WD_ERR("successful to get soft driver\n"); + } + } + break; + } + + return set_driver; +} + +void wd_alg_drv_unbind(struct wd_alg_driver *drv) +{ + struct wd_alg_driver *fb_drv = NULL; + + if (!drv) + return; + + fb_drv = (struct wd_alg_driver *)drv->fallback; + if (fb_drv) + wd_release_drv(fb_drv); + wd_release_drv(drv); +} + bool wd_alg_try_init(enum wd_status *status) { enum wd_status expected; @@ -1960,7 +2382,7 @@ free_ctxs: return ret; }
-int wd_alg_pre_init(struct wd_init_attrs *attrs) +static int wd_alg_ctx_init(struct wd_init_attrs *attrs) { struct wd_ctx_config *ctx_config = attrs->ctx_config; struct wd_ctx_params *ctx_params = attrs->ctx_params; @@ -2034,3 +2456,128 @@ out_freelist:
return ret; } + +static void wd_alg_ctx_uninit(struct wd_ctx_config *ctx_config) +{ + int i; + + for (i = 0; i < ctx_config->ctx_num; i++) + if (ctx_config->ctxs[i].ctx) { + wd_release_ctx(ctx_config->ctxs[i].ctx); + ctx_config->ctxs[i].ctx = 0; + } + + free(ctx_config->ctxs); +} + +int wd_alg_attrs_init(struct wd_init_attrs *attrs) +{ + wd_alg_poll_ctx alg_poll_func = attrs->alg_poll_ctx; + wd_alg_init alg_init_func = attrs->alg_init; + __u32 sched_type = attrs->sched_type; + struct wd_ctx_config *ctx_config = NULL; + struct wd_sched *alg_sched = NULL; + char alg_type[WD_NAME_SIZE]; + char *alg = attrs->alg; + int driver_type = UADK_ALG_HW; + int ret; + + if (!attrs->ctx_params) + return -WD_EINVAL; + + if (attrs->driver) + driver_type = attrs->driver->priority; + + switch (driver_type) { + case UADK_ALG_SOFT: + case UADK_ALG_CE_INSTR: + /* No need to alloc resource */ + if (sched_type != SCHED_POLICY_NONE) + return -WD_EINVAL; + + alg_sched = wd_sched_rr_alloc(SCHED_POLICY_NONE, 1, 1, alg_poll_func); + if (!alg_sched) { + WD_ERR("fail to alloc scheduler\n"); + return -WD_EINVAL; + } + attrs->sched = alg_sched; + + ret = wd_sched_rr_instance(alg_sched, NULL); + if (ret) { + WD_ERR("fail to instance scheduler\n"); + goto out_freesched; + } + break; + case UADK_ALG_SVE_INSTR: + /* Todo lock cpu core */ + if (sched_type != SCHED_POLICY_SINGLE) + return -WD_EINVAL; + + alg_sched = wd_sched_rr_alloc(SCHED_POLICY_SINGLE, 1, 1, alg_poll_func); + if (!alg_sched) { + WD_ERR("fail to alloc scheduler\n"); + return -WD_EINVAL; + } + attrs->sched = alg_sched; + + ret = wd_sched_rr_instance(alg_sched, NULL); + if (ret) { + WD_ERR("fail to instance scheduler\n"); + goto out_freesched; + } + break; + case UADK_ALG_HW: + wd_get_alg_type(alg, alg_type); + attrs->alg = alg_type; + + ctx_config = calloc(1, sizeof(*ctx_config)); + if (!ctx_config) { + WD_ERR("fail to alloc ctx config\n"); + return -WD_ENOMEM; + } + attrs->ctx_config = ctx_config; + + alg_sched = wd_sched_rr_alloc(sched_type, attrs->ctx_params->op_type_num, + numa_max_node() + 1, alg_poll_func); + if (!alg_sched) { + WD_ERR("fail to instance scheduler\n"); + ret = -WD_EINVAL; + goto out_ctx_config; + } + attrs->sched = alg_sched; + + ret = wd_alg_ctx_init(attrs); + if (ret) { + WD_ERR("fail to init ctx\n"); + goto out_freesched; + } + + ret = alg_init_func(ctx_config, alg_sched); + if (ret) + goto out_pre_init; + } + + return 0; + +out_pre_init: + wd_alg_ctx_uninit(ctx_config); +out_freesched: + wd_sched_rr_release(alg_sched); +out_ctx_config: + if (ctx_config) + free(ctx_config); + return ret; +} + +void wd_alg_attrs_uninit(struct wd_init_attrs *attrs) +{ + struct wd_ctx_config *ctx_config = attrs->ctx_config; + struct wd_sched *alg_sched = attrs->sched; + + if (ctx_config) { + wd_alg_ctx_uninit(ctx_config); + free(ctx_config); + } + wd_sched_rr_release(alg_sched); +} +
After the driver dynamic loading function is added, the corresponding function of querying all algorithms supported on the current UADK is added.
Signed-off-by: Longfang Liu liulongfang@huawei.com --- include/wd.h | 12 +++++++++++ wd.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/include/wd.h b/include/wd.h index e102fe2..21af7ff 100644 --- a/include/wd.h +++ b/include/wd.h @@ -29,6 +29,7 @@ extern "C" { #define LINUX_PRTDIR_SIZE 2 #define WD_CTX_CNT_NUM 1024 #define WD_IPC_KEY 0x500011 +#define CRYPTO_MAX_ALG_NAME 128
/* Required compiler attributes */ #define likely(x) __builtin_expect(!!(x), 1) @@ -578,6 +579,17 @@ bool wd_need_debug(void); */ bool wd_need_info(void);
+struct wd_capability { + char alg_name[CRYPTO_MAX_ALG_NAME]; + char drv_name[CRYPTO_MAX_ALG_NAME]; + int priority; + + struct wd_capability *next; +}; + +struct wd_capability *wd_get_alg_cap(void); +void wd_release_alg_cap(struct wd_capability *head); + #ifdef __cplusplus } #endif diff --git a/wd.c b/wd.c index 629c0df..c882c1f 100644 --- a/wd.c +++ b/wd.c @@ -19,7 +19,7 @@ #include <sched.h>
#include "wd.h" - +#include "wd_alg.h" #define SYS_CLASS_DIR "/sys/class/uacce"
enum UADK_LOG_LEVEL { @@ -882,3 +882,57 @@ char *wd_ctx_get_dev_name(handle_t h_ctx)
return ctx->dev_name; } + +void wd_release_alg_cap(struct wd_capability *head) +{ + struct wd_capability *cap_pnext = head; + struct wd_capability *cap_node = NULL; + + while (cap_pnext) { + cap_node = cap_pnext; + cap_pnext = cap_pnext->next; + free(cap_node); + } + + if (head) + free(head); +} + +struct wd_capability *wd_get_alg_cap(void) +{ + struct wd_alg_list *head = wd_get_alg_head(); + struct wd_alg_list *pnext = head->next; + struct wd_capability *cap_head = NULL; + struct wd_capability *cap_node = NULL; + struct wd_capability *cap_pnext = NULL; + int i = 0; + + while (pnext) { + cap_node = calloc(1, sizeof(struct wd_capability)); + if (!cap_head) { + WD_ERR("fail to alloc wd capability head\n"); + goto alloc_err; + } + + strcpy(cap_node->alg_name, pnext->alg_name); + strcpy(cap_node->drv_name, pnext->drv_name); + cap_node->priority = pnext->priority; + cap_node->next = NULL; + + cap_pnext->next = cap_node; + cap_pnext = cap_node; + pnext = pnext->next; + if (i == 0) { + cap_head = cap_node; + cap_pnext = cap_head; + } + i++; + } + + return cap_head; + +alloc_err: + wd_release_alg_cap(cap_head); + return NULL; +} +
After adding the zip module of the init2 interface, combine its initialization part with dynamic loading, and transform the HiSilicon driver of zip, and use the dynamic loading function to realize the connection between the driver and the algorithm layer.
Signed-off-by: Longfang Liu liulongfang@huawei.com --- drv/hisi_comp.c | 59 +++++++-- include/drv/wd_comp_drv.h | 27 ----- wd_comp.c | 243 ++++++++++++++++++++------------------ 3 files changed, 175 insertions(+), 154 deletions(-)
diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 2eede39..01e2ad8 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -13,7 +13,7 @@
#define ZLIB_HEADER "\x78\x9c" #define ZLIB_HEADER_SZ 2 - +#define ZIP_CTX_Q_NUM_DEF 1 /* * We use a extra field for gzip block length. So the fourth byte is \x04. * This is necessary because our software don't know the size of block when @@ -771,8 +771,9 @@ static void hisi_zip_sqe_ops_adapt(handle_t h_qp) } }
-static int hisi_zip_init(struct wd_ctx_config_internal *config, void *priv) +static int hisi_zip_init(void *conf, void *priv) { + struct wd_ctx_config_internal *config = conf; struct hisi_zip_ctx *zip_ctx = (struct hisi_zip_ctx *)priv; struct hisi_qm_priv qm_priv; handle_t h_qp = 0; @@ -1055,14 +1056,50 @@ static int hisi_zip_comp_recv(handle_t ctx, void *comp_msg) return parse_zip_sqe(qp, &sqe, recv_msg); }
-struct wd_comp_driver hisi_zip = { - .drv_name = "hisi_zip", - .alg_name = "zlib\ngzip\ndeflate\nlz77_zstd", - .drv_ctx_size = sizeof(struct hisi_zip_ctx), - .init = hisi_zip_init, - .exit = hisi_zip_exit, - .comp_send = hisi_zip_comp_send, - .comp_recv = hisi_zip_comp_recv, +#define GEN_ZIP_ALG_DRIVER(zip_alg_name) \ +{\ + .drv_name = "hisi_zip",\ + .alg_name = zip_alg_name,\ + .priority = UADK_ALG_HW,\ + .priv_size = sizeof(struct hisi_zip_ctx),\ + .queue_num = ZIP_CTX_Q_NUM_DEF,\ + .op_type_num = 2,\ + .fallback = 0,\ + .init = hisi_zip_init,\ + .exit = hisi_zip_exit,\ + .send = hisi_zip_comp_send,\ + .recv = hisi_zip_comp_recv,\ +} + +static struct wd_alg_driver zip_alg_driver[] = { + GEN_ZIP_ALG_DRIVER("zlib"), + GEN_ZIP_ALG_DRIVER("gzip"), + + GEN_ZIP_ALG_DRIVER("deflate"), + GEN_ZIP_ALG_DRIVER("lz77_zstd"), };
-WD_COMP_SET_DRIVER(hisi_zip); +static void __attribute__((constructor)) hisi_zip_probe(void) +{ + int alg_num = ARRAY_SIZE(zip_alg_driver); + int i, ret; + + WD_INFO("Info: register ZIP alg drivers!\n"); + + for (i = 0; i < alg_num; i++) { + ret = wd_alg_driver_register(&zip_alg_driver[i]); + if (ret) + WD_ERR("Error: register ZIP %s failed!\n", + zip_alg_driver[i].alg_name); + } +} + +static void __attribute__((destructor)) hisi_zip_remove(void) +{ + int alg_num = ARRAY_SIZE(zip_alg_driver); + int i; + + for (i = 0; i < alg_num; i++) + wd_alg_driver_unregister(&zip_alg_driver[i]); +} + diff --git a/include/drv/wd_comp_drv.h b/include/drv/wd_comp_drv.h index 4aeaee4..213cf2d 100644 --- a/include/drv/wd_comp_drv.h +++ b/include/drv/wd_comp_drv.h @@ -55,35 +55,8 @@ struct wd_comp_msg { __u32 tag; };
-struct wd_comp_driver { - const char *drv_name; - const char *alg_name; - __u32 drv_ctx_size; - int (*init)(struct wd_ctx_config_internal *config, void *priv); - void (*exit)(void *priv); - int (*comp_send)(handle_t ctx, void *comp_msg); - int (*comp_recv)(handle_t ctx, void *comp_msg); -}; - -void wd_comp_set_driver(struct wd_comp_driver *drv); -struct wd_comp_driver *wd_comp_get_driver(void); - struct wd_comp_msg *wd_comp_get_msg(__u32 idx, __u32 tag);
-#ifdef WD_STATIC_DRV -#define WD_COMP_SET_DRIVER(drv) \ -struct wd_comp_driver *wd_comp_get_driver(void) \ -{ \ - return &drv; \ -} -#else -#define WD_COMP_SET_DRIVER(drv) \ -static void __attribute__((constructor)) set_comp_driver(void) \ -{ \ - wd_comp_set_driver(&(drv)); \ -} -#endif - #ifdef __cplusplus } #endif diff --git a/wd_comp.c b/wd_comp.c index ecfa573..b7e0eb7 100644 --- a/wd_comp.c +++ b/wd_comp.c @@ -19,8 +19,6 @@ #define HW_CTX_SIZE (64 * 1024) #define STREAM_CHUNK (128 * 1024)
-#define SCHED_RR_NAME "sched_rr" - #define swap_byte(x) \ ((((x) & 0x000000ff) << 24) | \ (((x) & 0x0000ff00) << 8) | \ @@ -42,56 +40,61 @@ struct wd_comp_sess {
struct wd_comp_setting { enum wd_status status; - enum wd_status status2; struct wd_ctx_config_internal config; struct wd_sched sched; - struct wd_comp_driver *driver; + struct wd_async_msg_pool pool; + struct wd_alg_driver *driver; void *priv; void *dlhandle; - struct wd_async_msg_pool pool; + void *dlh_list; } wd_comp_setting;
struct wd_env_config wd_comp_env_config; - static struct wd_init_attrs wd_comp_init_attrs; -static struct wd_ctx_config wd_comp_ctx; -static struct wd_sched *wd_comp_sched; - -static struct wd_ctx_nums wd_comp_ctx_num[] = { - {1, 1}, {1, 1}, {} -};
-static struct wd_ctx_params wd_comp_ctx_params = { - .op_type_num = WD_DIR_MAX, - .ctx_set_num = wd_comp_ctx_num, - .bmp = NULL, -}; - -#ifdef WD_STATIC_DRV -static void wd_comp_set_static_drv(void) +static void wd_comp_close_driver(void) { - wd_comp_setting.driver = wd_comp_get_driver(); - if (!wd_comp_setting.driver) - WD_ERR("failed to get driver!\n"); + if (wd_comp_setting.dlhandle) { + wd_release_drv(wd_comp_setting.driver); + dlclose(wd_comp_setting.dlhandle); + wd_comp_setting.dlhandle = NULL; + } } -#else -static void __attribute__((constructor)) wd_comp_open_driver(void) + +static int wd_comp_open_driver(void) { - wd_comp_setting.dlhandle = dlopen("libhisi_zip.so", RTLD_NOW); - if (!wd_comp_setting.dlhandle) + struct wd_alg_driver *driver = NULL; + char lib_path[PATH_STR_SIZE]; + const char *alg_name = "zlib"; + int ret; + + /* + * Compatible with the normal acquisition of device + * drivers in the init interface + */ + if (wd_comp_setting.dlh_list) + return 0; + + ret = wd_get_lib_file_path("libhisi_zip.so", lib_path, false); + if (ret) + return ret; + + wd_comp_setting.dlhandle = dlopen(lib_path, RTLD_NOW); + if (!wd_comp_setting.dlhandle) { WD_ERR("failed to open libhisi_zip.so, %s\n", dlerror()); -} + return -WD_EINVAL; + }
-static void __attribute__((destructor)) wd_comp_close_driver(void) -{ - if (wd_comp_setting.dlhandle) - dlclose(wd_comp_setting.dlhandle); -} -#endif + driver = wd_request_drv(alg_name, false); + if (!driver) { + wd_comp_close_driver(); + WD_ERR("failed to get %s driver support\n", alg_name); + return -WD_EINVAL; + }
-void wd_comp_set_driver(struct wd_comp_driver *drv) -{ - wd_comp_setting.driver = drv; + wd_comp_setting.driver = driver; + + return 0; }
static void wd_comp_clear_status(void) @@ -101,13 +104,8 @@ static void wd_comp_clear_status(void)
static int wd_comp_init_nolock(struct wd_ctx_config *config, struct wd_sched *sched) { - void *priv; int ret;
- ret = wd_init_param_check(config, sched); - if (ret) - return ret; - ret = wd_set_epoll_en("WD_COMP_EPOLL_EN", &wd_comp_setting.config.epoll_en); if (ret < 0) @@ -120,19 +118,6 @@ static int wd_comp_init_nolock(struct wd_ctx_config *config, struct wd_sched *sc ret = wd_init_sched(&wd_comp_setting.sched, sched); if (ret < 0) goto out_clear_ctx_config; - /* - * Fix me: ctx could be passed into wd_comp_set_static_drv to help to - * choose static compiled vendor driver. For dynamic vendor driver, - * wd_comp_open_driver will be called in the process of opening - * libwd_comp.so to load related driver dynamic library. Vendor driver - * pointer will be passed to wd_comp_setting.driver in the process of - * opening of vendor driver dynamic library. A configure file could be - * introduced to help to define which vendor driver lib should be - * loaded. - */ -#ifdef WD_STATIC_DRV - wd_comp_set_static_drv(); -#endif
/* fix me: sadly find we allocate async pool for every ctx */ ret = wd_init_async_request_pool(&wd_comp_setting.pool, @@ -141,24 +126,14 @@ static int wd_comp_init_nolock(struct wd_ctx_config *config, struct wd_sched *sc if (ret < 0) goto out_clear_sched;
- /* init ctx related resources in specific driver */ - priv = calloc(1, wd_comp_setting.driver->drv_ctx_size); - if (!priv) { - ret = -WD_ENOMEM; + ret = wd_alg_init_driver(&wd_comp_setting.config, + wd_comp_setting.driver, + &wd_comp_setting.priv); + if (ret) goto out_clear_pool; - } - wd_comp_setting.priv = priv; - ret = wd_comp_setting.driver->init(&wd_comp_setting.config, priv); - if (ret < 0) { - WD_ERR("failed to do driver init, ret = %d!\n", ret); - goto out_free_priv; - }
return 0;
-out_free_priv: - free(priv); - wd_comp_setting.priv = NULL; out_clear_pool: wd_uninit_async_request_pool(&wd_comp_setting.pool); out_clear_sched: @@ -175,16 +150,14 @@ static void wd_comp_uninit_nolock(void) if (!priv) return;
- wd_comp_setting.driver->exit(priv); - free(priv); - wd_comp_setting.priv = NULL; - /* uninit async request pool */ wd_uninit_async_request_pool(&wd_comp_setting.pool);
/* unset config, sched, driver */ wd_clear_sched(&wd_comp_setting.sched); - wd_clear_ctx_config(&wd_comp_setting.config); + + wd_alg_uninit_driver(&wd_comp_setting.config, + wd_comp_setting.driver, &priv); }
int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) @@ -198,28 +171,43 @@ int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) if (!flag) return 0;
+ ret = wd_init_param_check(config, sched); + if (ret) + goto out_clear_init; + + ret = wd_comp_open_driver(); + if (ret) + goto out_clear_init; + ret = wd_comp_init_nolock(config, sched); - if (ret) { - wd_alg_clear_init(&wd_comp_setting.status); - goto out; - } + if (ret) + goto out_clear_driver;
wd_alg_set_init(&wd_comp_setting.status);
-out: + return 0; + +out_clear_driver: + wd_comp_close_driver(); +out_clear_init: + wd_alg_clear_init(&wd_comp_setting.status); return ret; }
void wd_comp_uninit(void) { wd_comp_uninit_nolock(); + + wd_comp_close_driver(); wd_alg_clear_init(&wd_comp_setting.status); }
int wd_comp_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_params *ctx_params) { + struct wd_ctx_nums comp_ctx_num[WD_DIR_MAX] = {0}; + struct wd_ctx_params comp_ctx_params; + int ret = 0; bool flag; - int ret;
pthread_atfork(NULL, NULL, wd_comp_clear_status);
@@ -227,61 +215,84 @@ int wd_comp_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_par if (!flag) return 0;
- if (!alg) { - WD_ERR("invalid: alg is NULL!\n"); + if (!alg || sched_type > SCHED_POLICY_BUTT || + task_type < 0 || task_type > TASK_MAX_TYPE) { + WD_ERR("invalid: input param is wrong!\n"); ret = -WD_EINVAL; goto out_uninit; }
- wd_comp_init_attrs.alg = alg; - wd_comp_init_attrs.sched_type = sched_type; + /* + * Driver lib file path could set by env param. + * than open tham by wd_dlopen_drv() + * use NULL means dynamic query path + */ + wd_comp_setting.dlh_list = wd_dlopen_drv(NULL); + if (!wd_comp_setting.dlh_list) { + WD_ERR("fail to open driver lib files.\n"); + goto out_uninit; + }
- wd_comp_init_attrs.ctx_params = ctx_params ? ctx_params : &wd_comp_ctx_params; - wd_comp_init_attrs.ctx_config = &wd_comp_ctx; +res_retry: + memset(&wd_comp_setting.config, 0, sizeof(struct wd_ctx_config_internal));
- wd_comp_sched = wd_sched_rr_alloc(sched_type, wd_comp_init_attrs.ctx_params->op_type_num, - numa_max_node() + 1, wd_comp_poll_ctx); - if (!wd_comp_sched) { - ret = -WD_EINVAL; - goto out_uninit; + /* Get alg driver and dev name */ + wd_comp_setting.driver = wd_alg_drv_bind(task_type, alg); + if (!wd_comp_setting.driver) { + WD_ERR("fail to bind a valid driver.\n"); + goto out_dlopen; } - wd_comp_sched->name = SCHED_RR_NAME; - wd_comp_init_attrs.sched = wd_comp_sched;
- ret = wd_alg_attrs_init(&wd_comp_init_attrs); - if (ret) - goto out_freesched; + ret = wd_ctx_param_init(&comp_ctx_params, ctx_params, + comp_ctx_num, wd_comp_setting.driver, + WD_DIR_MAX); + if (ret) { + if (ret == -WD_EAGAIN) { + wd_disable_drv(wd_comp_setting.driver); + wd_alg_drv_unbind(wd_comp_setting.driver); + goto res_retry; + } + goto out_driver; + }
- ret = wd_comp_init_nolock(&wd_comp_ctx, wd_comp_sched); - if (ret) - goto out_freesched; + wd_comp_init_attrs.alg = alg; + wd_comp_init_attrs.sched_type = sched_type; + wd_comp_init_attrs.driver = wd_comp_setting.driver; + wd_comp_init_attrs.ctx_params = &comp_ctx_params; + wd_comp_init_attrs.alg_init = wd_comp_init_nolock; + wd_comp_init_attrs.alg_poll_ctx = wd_comp_poll_ctx; + ret = wd_alg_attrs_init(&wd_comp_init_attrs); + if (ret) { + if (ret == -WD_ENODEV) { + wd_disable_drv(wd_comp_setting.driver); + wd_alg_drv_unbind(wd_comp_setting.driver); + goto res_retry; + } + WD_ERR("fail to init alg attrs.\n"); + goto out_driver; + }
wd_alg_set_init(&wd_comp_setting.status);
return 0;
-out_freesched: - wd_sched_rr_release(wd_comp_sched); - +out_driver: + wd_alg_drv_unbind(wd_comp_setting.driver); +out_dlopen: + wd_dlclose_drv(wd_comp_setting.dlh_list); out_uninit: wd_alg_clear_init(&wd_comp_setting.status); - return ret; }
void wd_comp_uninit2(void) { - int i; - wd_comp_uninit_nolock();
- for (i = 0; i < wd_comp_ctx.ctx_num; i++) - if (wd_comp_ctx.ctxs[i].ctx) { - wd_release_ctx(wd_comp_ctx.ctxs[i].ctx); - wd_comp_ctx.ctxs[i].ctx = 0; - } - - wd_sched_rr_release(wd_comp_sched); + wd_alg_attrs_uninit(&wd_comp_init_attrs); + wd_alg_drv_unbind(wd_comp_setting.driver); + wd_dlclose_drv(wd_comp_setting.dlh_list); + wd_comp_setting.dlh_list = NULL; wd_alg_clear_init(&wd_comp_setting.status); }
@@ -315,7 +326,7 @@ int wd_comp_poll_ctx(__u32 idx, __u32 expt, __u32 *count) ctx = config->ctxs + idx;
do { - ret = wd_comp_setting.driver->comp_recv(ctx->ctx, &resp_msg); + ret = wd_comp_setting.driver->recv(ctx->ctx, &resp_msg); if (unlikely(ret < 0)) { if (ret == -WD_HW_EACCESS) WD_ERR("wd comp recv hw error!\n"); @@ -546,8 +557,8 @@ static int wd_comp_sync_job(struct wd_comp_sess *sess, 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; - msg_handle.recv = wd_comp_setting.driver->comp_recv; + msg_handle.send = wd_comp_setting.driver->send; + msg_handle.recv = wd_comp_setting.driver->recv;
pthread_spin_lock(&ctx->lock); ret = wd_handle_msg_sync(&msg_handle, ctx->ctx, msg, @@ -806,7 +817,7 @@ int wd_do_comp_async(handle_t h_sess, struct wd_comp_req *req) msg->tag = tag; msg->stream_mode = WD_COMP_STATELESS;
- ret = wd_comp_setting.driver->comp_send(ctx->ctx, msg); + ret = wd_comp_setting.driver->send(ctx->ctx, msg); if (unlikely(ret < 0)) { WD_ERR("wd comp send error, ret = %d!\n", ret); goto fail_with_msg;
Add a complete design description document for the new dynamic loading function of UADK, which is convenient for users to understand and use this new function.
Signed-off-by: Longfang Liu liulongfang@huawei.com --- ...sion_and_modular_dynamic_loading_design.md | 432 ++++++++++++++++++ 1 file changed, 432 insertions(+) create mode 100644 docs/UADK_framework_expansion_and_modular_dynamic_loading_design.md
diff --git a/docs/UADK_framework_expansion_and_modular_dynamic_loading_design.md b/docs/UADK_framework_expansion_and_modular_dynamic_loading_design.md new file mode 100644 index 0000000..1761a6f --- /dev/null +++ b/docs/UADK_framework_expansion_and_modular_dynamic_loading_design.md @@ -0,0 +1,432 @@ +## UADK framework expansion and modular dynamic loading design + +author:Liu Longfang Date:2022/10/20 +### **UADK Existing Framework:** +` ` In the current UADK user-mode framework that supports SVA features, UACCE is still relied on to obtain a unified accelerator device control interface, but it is no longer strongly coupled with hardware devices like warpdrive, and is also divided into three layers internally: the algorithm interface layer, The framework interface layer and the user-mode driver layer are divided by the algorithm library, control plane, and data plane seen by the user. The entire framework structure is as follows: + +<svg xmlns:ev="http://www.w3.org/2001/xml-events" width="1000" xmlns:xlink="http://www.w3.org/1999/xlink" height="500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 1000"><style type="text/css"><![CDATA[ +.st1 {fill:#000000;font-family:宋体;font-size:18pt} +.st2 {fill:#000000;font-family:微软雅黑;font-size:14pt} +.st3 {fill:#1f6391;font-family:微软雅黑;font-size:12pt} +]]></style><defs/><g transform="translate(5,5)" id="page1"><rect x="0" stroke="#808080" fill="#ffffff" width="2245" height="1587" y="0"/><g transform="translate(314.43,148.27)"><path d="M178.5,68.3L178.5,0L0,0L0,68.3L178.5,68.3z" stroke="#3498db" fill="#00b0f0" id="shape1"/><text class="st1"><tspan x="47.2" y="43.6">ALG API</tspan></text></g><g transform="translate(312.43,386.07)"><path d="M180.5,64.9L180.5,0L0,0L0,64.9L180.5,64.9z" stroke="#3498db" fill="#92d050" id="shape2"/><text class="st1"><tspan x="54.2" y="41.9">WD API</tspan></text></g><g transform="translate(512.01,648.27)"><path d="M362.1,55.9L362.1,0L0,0L0,55.9L362.1,55.9z" stroke="#3498db" fill="#ee7c31" id="shape3"/><text class="st1"><tspan x="151.1" y="37.4">UACCE</tspan></text></g><path d="M0,0L532.9,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,495.6,606.4)" stroke-width="2" id="shape4"/><g transform="translate(590.39,399.5)"><path d="M316.5,38L316.5,0L0,0L0,38L316.5,38z" stroke="#3498db" fill="#92d050" id="shape5"/><text class="st1"><tspan x="128.3" y="28.5">libwd</tspan></text></g><g transform="translate(512.01,817.23)"><path d="M586.9,54.1L586.9,0L0,0L0,54.1L586.9,54.1z" stroke="#3498db" fill="#00b0f0" id="shape6"/><text class="st1"><tspan x="221.4" y="36.6">Hisi acc dev</tspan></text></g><g transform="translate(512.02,741.68)"><path d="M499.7,38L499.7,0L0,0L0,38L499.7,38z" stroke="#3498db" fill="#7eccb6" id="shape7"/><text class="st1"><tspan x="148.4" y="28.5">Hisi acc k-driver</tspan></text></g><g transform="translate(1277.56,550.32)"><path d="M209.7,38L209.7,0L0,0L0,38L209.7,38z" stroke="#3498db" fill="#00b0f0" id="shape8"/><text class="st1"><tspan x="9.3" y="28.5">Hisi acc udriver</tspan></text></g><path d="M0,0L1099,0" stroke="#236ea1" fill="none" transform="translate(446.89,629.18)" stroke-width="2" id="shape9"/><g transform="translate(590.39,163.4)"><path d="M316.5,38L316.5,0L0,0L0,38L316.5,38z" stroke="#3498db" fill="#92d050" id="shape10"/><text class="st1"><tspan x="20.3" y="28.5">libwd_crypto/libwd_comp</tspan></text></g><g transform="translate(1382.4,588.32)" id="shape11"><path d="M0,13.9L0,256L-269.6,256" stroke="#236ea1" fill="none" stroke-width="5.33333"/><path stroke-linecap="round" d="M-6.9,13.9L0,0L6.9,13.9L-6.9,13.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M-269.6,262.9L-283.5,256L-269.6,249.1L-269.6,262.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(611.92,507.32)"><path d="M273.5,42.8L273.5,0L0,0L0,42.8L273.5,42.8z" stroke="#3498db" fill="#00b050" id="shape12"/><text class="st1"><tspan x="83.2" y="30.9">scheduler</tspan></text></g><g transform="translate(1288.83,153.9)"><path d="M187.7,57L187.7,0L0,0L0,57L187.7,57z" stroke="#3498db" fill="#7eccb6" id="shape13"/><text class="st1"><tspan x="10.3" y="38">xxx driver ops</tspan></text></g><g transform="translate(1382.68,210.9)" id="shape14"><path d="M0,0L0,307.4L-0.2,335" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-0.3,339.4L2.8,334.3C1.9,334.8,.9,335,-0.2,335C-1.3,335,-2.4,334.7,-3.2,334.2L-0.3,339.4" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(906.91,182.4)" id="shape15"><path d="M0,0L377.5,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M381.9,0L376.7,-3C377.2,-2.1,377.5,-1.1,377.5,0C377.5,1.1,377.2,2.1,376.7,3L381.9,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(748.65,399.5)" id="shape16"><path d="M0,0L0,-193.7" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M0,-198.1L-3,-192.9C-2.1,-193.4,-1.1,-193.7,0,-193.7C1.1,-193.7,2.1,-193.4,3,-192.9L0,-198.1" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(597.17,438.38)" id="shape17"><path d="M0,0L1,201.8" stroke="#236ea1" fill="none" stroke-width="2.66667"/><path stroke-linecap="round" d="M1,209L5.9,200.5C4.4,201.3,2.8,201.8,1,201.8C-0.8,201.8,-2.5,201.4,-3.9,200.5L1,209" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(365.17,711.68)" id="shape18"><text class="st2"><tspan x="9" y="13">Kernel</tspan><tspan x="11" y="38">space</tspan></text></g><g transform="translate(365.17,282.3)" id="shape19"><text class="st2"><tspan x="17" y="13">User</tspan><tspan x="11" y="38">space</tspan></text></g><path d="M0,0L532.9,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,1546.8,596.4)" stroke-width="2" id="shape20"/><g transform="translate(1573.47,489.8)"><path d="M169.5,60.3L169.5,0L0,0L0,60.3L169.5,60.3z" stroke="#3498db" fill="#92d050" id="shape21"/><text class="st1"><tspan x="25.3" y="39.6">libxxx_drv</tspan></text></g><g transform="translate(76.93,399.5)" id="shape22"><text class="st2"><tspan x="26.3" y="25.5">control cmd</tspan></text></g><path d="M4.4,64.6L4.4,9L0,9L8.9,0L17.7,9L13.3,9L13.3,64.6L4.4,64.6z" stroke="#dd7195" fill="#dd7195" transform="matrix(0,1,-1,0,284.8,413.2)" id="shape23"/><g transform="translate(76.93,163.4)" id="shape24"><text class="st2"><tspan x="27.3" y="25.5">data stream</tspan></text></g><path d="M13.2,5.5L62.8,5.5L62.8,0L76,11L62.8,22L62.8,16.5L13.2,16.5L13.2,22L0,11L13.2,0L13.2,5.5z" stroke="#2da2bf" fill="#2da2bf" transform="translate(214.47,171.4)" id="shape25"/><g transform="translate(406.43,49.68)" id="shape26"><text class="st2"><tspan x="10.3" y="25.5">symble visibility</tspan></text></g><g transform="translate(748.65,507.32)" id="shape27"><path d="M0,0L0,-65.4" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,-69.8L-3,-64.6C-2.1,-65.1,-1.1,-65.4,0,-65.4C1.1,-65.4,2.1,-65.1,3,-64.6L0,-69.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(748.31,647.38)" id="shape28"><path d="M0,-6L.3,-97.3" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M3,-6L0,0L-3,-6L3,-6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><path d="M0,0L532.8,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,1250.4,603.1)" stroke-width="2" id="shape29"/><g transform="translate(864.44,61.68)" id="shape30"><text class="st2"><tspan x="42.3" y="25.5">API level</tspan></text></g><g transform="translate(1296.89,61.68)" id="shape31"><text class="st2"><tspan x="32.3" y="25.5">User driver</tspan></text></g><g transform="translate(693.09,704.12)" id="shape32"><path d="M0,0L-0,31.9" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-0,36.3L3,31.1C2.1,31.6,1.1,31.9,-0,31.9C-1.1,31.9,-2.1,31.6,-3,31.1L-0,36.3" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(761.89,779.68)" id="shape33"><path d="M0,0L0,31.7" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,36.1L3,30.9C2.1,31.4,1.1,31.7,0,31.7C-1.1,31.7,-2.1,31.4,-3,30.9L0,36.1" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(913.31,193.38)" id="shape34"><path d="M0,0L384.8,350" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M388,353L386.2,347.3C386,348.3,385.5,349.2,384.8,350C384,350.9,383.1,351.4,382.1,351.7L388,353" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1052.16,310.83)" id="shape35"><text class="st2"><tspan x="31.4" y="25.5">dlopen</tspan></text></g><path d="M25.2,10.5L58.5,10.5L58.5,0L83.7,21L58.5,41.9L58.5,31.5L25.2,31.5L25.2,41.9L0,21L25.2,0L25.2,10.5z" stroke="#2da2bf" fill="#0070c0" transform="translate(499.79,161.29)" id="shape36"/><path d="M25.2,10.5L58.5,10.5L58.5,0L83.7,21L58.5,41.9L58.5,31.5L25.2,31.5L25.2,41.9L0,21L25.2,0L25.2,10.5z" stroke="#2da2bf" fill="#0070c0" transform="translate(499.79,399.36)" id="shape37"/><g transform="translate(1573.47,409.79)" id="shape38"><text class="st3"><tspan x="4.4" y="18.4">Each udriver compilation </tspan><tspan x="4.4" y="39.4">generates a separate </tspan><tspan x="4.4" y="60.4">library file</tspan></text></g></g></svg> + + + The external interface has two parts, the framework interface part and the algorithm interface part. The framework interface part is mainly the external control interface of libwd, which mainly deals with the processing of process-level resources, the operation of hardware devices, the queue allocation operation, and the initialization of the matching scheduler. + + The second part is the interface related to the algorithm, which is mainly the data layer interface for performing task services. Since we mainly support two types of algorithms, encryption and compression, all algorithm interfaces are compiled into two libraries, crypto library and comp library. + + In addition to the external interface, the rest is the user-mode driver layer, which is strongly related to the operation of the device. The corresponding algorithm operation interface will have a southbound interface to connect to the user-mode driver, and the task data will be sent to the user-mode driver through these internal interfaces. and then sent by the device driver to the hardware device for processing. + +There is no major problem with the whole framework, and the algorithm function and operating efficiency are relatively good, but the small problem is that it is too deeply coupled with Kunpeng's accelerator: + +1. The control layer interface is fully functional, and there are a large number of device operation interfaces for Kunpeng acceleration devices. + +2. The connection between the API layer and the user-mode driver layer is realized through static coding. Although it is layered through the compiled library, in fact it can only call the interface of the Kunpeng accelerator user-mode driver, and the name of the driver's ops is different depending on the type of algorithm. There is no unification. For other instruction acceleration modes, by installing the corresponding driver, even if the driver is implemented according to the standard driver_ops, it still cannot be linked and used. + + + +### **UADK New Framework Design:** + The new framework is just an extension of the original framework. The basic layering remains unchanged. It is still three parts. It just optimizes the device driver adaptation method, and adds support for software computing, instruction acceleration, and third-party acceleration devices. and unified the southbound interface for user-mode drivers: + +<svg xmlns:ev="http://www.w3.org/2001/xml-events" width="1000" xmlns:xlink="http://www.w3.org/1999/xlink" height="500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 1000"><style type="text/css"><![CDATA[ +.st1 {fill:#000000;font-family:宋体;font-size:18pt} +.st2 {fill:#000000;font-family:微软雅黑;font-size:14pt} +.st3 {fill:#1f6391;font-family:微软雅黑;font-size:12pt} +]]></style><defs/><g transform="translate(5,5)" id="page1"><rect x="0" stroke="#808080" fill="#ffffff" width="2245" height="1587" y="0"/><g transform="translate(243.69,124.59)"><path d="M160.1,68.3L160.1,0L0,0L0,68.3L160.1,68.3z" stroke="#3498db" fill="#00b0f0" id="shape1"/><text class="st1"><tspan x="38.1" y="43.6">ALG API</tspan></text></g><g transform="translate(243.69,362.39)"><path d="M160.1,64.9L160.1,0L0,0L0,64.9L160.1,64.9z" stroke="#3498db" fill="#92d050" id="shape2"/><text class="st1"><tspan x="44.1" y="41.9">WD API</tspan></text></g><g transform="translate(422.92,624.59)"><path d="M362.1,55.9L362.1,0L0,0L0,55.9L362.1,55.9z" stroke="#3498db" fill="#ee7c31" id="shape3"/><text class="st1"><tspan x="151.1" y="37.4">UACCE</tspan></text></g><path d="M0,0L532.9,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,406.6,582.7)" stroke-width="2" id="shape4"/><g transform="translate(501.29,375.82)"><path d="M316.5,38L316.5,0L0,0L0,38L316.5,38z" stroke="#3498db" fill="#92d050" id="shape5"/><text class="st1"><tspan x="128.3" y="28.5">libwd</tspan></text></g><g transform="translate(1282.88,793.56)"><path d="M221.9,54.1L221.9,0L0,0L0,54.1L221.9,54.1z" stroke="#3498db" fill="#ffc000" id="shape6"/><text class="st1"><tspan x="27.4" y="36.6">others acc dev</tspan></text></g><g transform="translate(1270.97,718)"><path d="M245.7,38L245.7,0L0,0L0,38L245.7,38z" stroke="#3498db" fill="#7eccb6" id="shape7"/><text class="st1"><tspan x="9.3" y="28.5">others acc k-driver</tspan></text></g><g transform="translate(1144.87,494.79)"><path d="M213.9,38L213.9,0L0,0L0,38L213.9,38z" stroke="#3498db" fill="#00b0f0" id="shape8"/><text class="st1"><tspan x="11.5" y="28.5">Hisi acc udriver</tspan></text></g><path d="M0,0L1651.7,0" stroke="#236ea1" fill="none" transform="translate(357.79,605.5)" stroke-width="2" id="shape9"/><g transform="translate(501.29,139.72)"><path d="M316.5,38L316.5,0L0,0L0,38L316.5,38z" stroke="#3498db" fill="#92d050" id="shape10"/><text class="st1"><tspan x="20.3" y="28.5">libwd_crypto/libwd_comp</tspan></text></g><g transform="translate(958.38,394.82)" id="shape11"><path d="M0,0L-136.2,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-140.6,0L-135.4,3C-135.9,2.1,-136.2,1.1,-136.2,0C-136.2,-1.1,-135.9,-2.1,-135.4,-3L-140.6,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(522.83,483.64)"><path d="M273.5,42.8L273.5,0L0,0L0,42.8L273.5,42.8z" stroke="#3498db" fill="#00b050" id="shape12"/><text class="st1"><tspan x="83.2" y="30.9">scheduler</tspan></text></g><g transform="translate(1251.82,191.72)" id="shape13"><path d="M0,0L0,298.7" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,303.1L3,297.9C2.1,298.4,1.1,298.7,0,298.7C-1.1,298.7,-2.1,298.4,-3,297.9L0,303.1" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(817.81,158.72)" id="shape14"><path d="M0,0L344.3,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M348.7,0L343.5,-3C344,-2.1,344.3,-1.1,344.3,0C344.3,1.1,344,2.1,343.5,3L348.7,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1032.84,361.82)" id="shape15"><path d="M0,0L0,-184.6L145.3,-184.6" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M149.7,-184.6L144.5,-187.6C145,-186.7,145.3,-185.7,145.3,-184.6C145.3,-183.5,145,-182.5,144.5,-181.6L149.7,-184.6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(659.55,375.82)" id="shape16"><path d="M0,0L0,-193.7" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M0,-198.1L-3,-192.9C-2.1,-193.4,-1.1,-193.7,0,-193.7C1.1,-193.7,2.1,-193.4,3,-192.9L0,-198.1" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1605.29,379.29)"><path d="M197.2,38L197.2,0L0,0L0,38L197.2,38z" stroke="#3498db" fill="#92d050" id="shape17"/><text class="st1"><tspan x="15.1" y="28.5">CPU CE udriver</tspan></text></g><g transform="translate(1754.72,328.29)"><path d="M214.8,38L214.8,0L0,0L0,38L214.8,38z" stroke="#3498db" fill="#92d050" id="shape18"/><text class="st1"><tspan x="17.4" y="28.5">CPU SVE udriver</tspan></text></g><g transform="translate(1337.15,158.72)" id="shape19"><path d="M0,0L366.8,0L366.8,216.2" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M366.8,220.6L369.8,215.4C368.9,215.9,367.9,216.2,366.8,216.2C365.7,216.2,364.6,215.9,363.8,215.4L366.8,220.6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1337.15,158.72)" id="shape20"><path d="M0,0L525,0L525,165.2" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M525,169.6L528,164.4C527.1,164.9,526.1,165.2,525,165.2C523.9,165.2,522.9,164.9,522,164.4L525,169.6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(508.07,414.7)" id="shape21"><path d="M0,0L1,200.2" stroke="#236ea1" fill="none" stroke-width="4"/><path stroke-linecap="round" d="M1,209L7,198.6C5.2,199.6,3.1,200.2,1,200.2C-1.2,200.2,-3.3,199.7,-5,198.6L1,209" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(276.07,688)" id="shape22"><text class="st2"><tspan x="9" y="13">Kernel</tspan><tspan x="11" y="38">space</tspan></text></g><g transform="translate(276.07,258.62)" id="shape23"><text class="st2"><tspan x="17" y="13">User</tspan><tspan x="11" y="38">space</tspan></text></g><path d="M0,0L551.6,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,2005,595.4)" stroke-width="2" id="shape24"/><g transform="translate(2015.19,472.49)"><path d="M140.4,60.3L140.4,0L0,0L0,60.3L140.4,60.3z" stroke="#3498db" fill="#92d050" id="shape25"/><text class="st1"><tspan x="10.2" y="39.6">libxxx_drv</tspan></text></g><g transform="translate(25.53,375.82)" id="shape26"><text class="st2"><tspan x="26.3" y="25.5">control cmd</tspan></text></g><path d="M4.4,64.6L4.4,9L0,9L8.9,0L17.7,9L13.3,9L13.3,64.6L4.4,64.6z" stroke="#dd7195" fill="#dd7195" transform="matrix(0,1,-1,0,233.4,389.6)" id="shape27"/><g transform="translate(25.53,139.72)" id="shape28"><text class="st2"><tspan x="27.3" y="25.5">data stream</tspan></text></g><path d="M13.2,5.5L62.8,5.5L62.8,0L76,11L62.8,22L62.8,16.5L13.2,16.5L13.2,22L0,11L13.2,0L13.2,5.5z" stroke="#2da2bf" fill="#2da2bf" transform="translate(163.07,147.72)" id="shape29"/><g transform="translate(317.34,26)" id="shape30"><text class="st2"><tspan x="10.3" y="25.5">symble visibility</tspan></text></g><g transform="translate(902.92,488.43)" id="shape31"><text class="st2"><tspan x="19.4" y="13">dlopen()-></tspan><tspan x="16.4" y="38">register alg</tspan></text></g><g transform="translate(1662.55,535.32)"><path d="M327.6,54.1L327.6,0L0,0L0,54.1L327.6,54.1z" stroke="#3498db" fill="#00b0f0" id="shape32"/><text class="st1"><tspan x="116.3" y="36.6">CPU core</tspan></text></g><g transform="translate(1703.9,417.29)" id="shape33"><path d="M0,13.9L0,100.2" stroke="#236ea1" fill="none" stroke-width="5.33333"/><path stroke-linecap="round" d="M-6.9,13.9L0,0L6.9,13.9L-6.9,13.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M6.9,100.2L0,114.1L-6.9,100.2L6.9,100.2" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1862.11,366.29)" id="shape34"><path d="M0,13.9L0,152.7" stroke="#236ea1" fill="none" stroke-width="5.33333"/><path stroke-linecap="round" d="M-6.9,13.9L0,0L6.9,13.9L-6.9,13.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M6.9,152.7L0,166.5L-6.9,152.7L6.9,152.7" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(659.55,483.64)" id="shape35"><path d="M0,0L0,-65.4" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,-69.8L-3,-64.6C-2.1,-65.1,-1.1,-65.4,0,-65.4C1.1,-65.4,2.1,-65.1,3,-64.6L0,-69.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(659.07,620.66)" id="shape36"><path d="M0,-6L.5,-94.2" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M3,-6L0,0L-3,-6L3,-6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><path d="M0,0L553.3,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,1143,601.6)" stroke-width="2" id="shape37"/><g transform="translate(775.34,38)" id="shape38"><text class="st2"><tspan x="42.3" y="25.5">API level</tspan></text></g><g transform="translate(1417.64,38)" id="shape39"><text class="st2"><tspan x="32.3" y="25.5">User driver</tspan></text></g><g transform="translate(558.87,682.43)" id="shape40"><path d="M0,0L0,31.2" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,35.6L3,30.4C2.1,30.9,1.1,31.2,0,31.2C-1.1,31.2,-2.1,30.9,-3,30.4L0,35.6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1393.82,756)" id="shape41"><path d="M0,0L-0,33.2" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-0,37.6L3,32.4C2.1,32.9,1.1,33.2,-0,33.2C-1.1,33.2,-2.1,32.9,-3,32.4L-0,37.6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(785.07,652.52)" id="shape42"><path d="M0,0L608.7,0L608.7,61.1" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M608.7,65.5L611.7,60.3C610.9,60.8,609.8,61.1,608.7,61.1C607.7,61.1,606.6,60.8,605.7,60.3L608.7,65.5" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1421.04,450.12)"><path d="M232.2,38L232.2,0L0,0L0,38L232.2,38z" stroke="#3498db" fill="#ffc000" id="shape43"/><text class="st1"><tspan x="8.1" y="28.5">others acc udriver</tspan></text></g><g transform="translate(1537.13,488.12)" id="shape44"><path d="M0,13.9L0,332.5L-18.5,332.5" stroke="#236ea1" fill="none" stroke-width="5.33333"/><path stroke-linecap="round" d="M-6.9,13.9L0,0L6.9,13.9L-6.9,13.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M-18.5,339.4L-32.4,332.5L-18.5,325.6L-18.5,339.4" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1337.15,158.72)" id="shape45"><path d="M0,0L200,0L200,287" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M200,291.4L203,286.2C202.1,286.7,201.1,287,200,287C198.9,287,197.9,286.7,197,286.2L200,291.4" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(422.92,793.56)"><path d="M586.9,54.1L586.9,0L0,0L0,54.1L586.9,54.1z" stroke="#3498db" fill="#00b0f0" id="shape46"/><text class="st1"><tspan x="221.4" y="36.6">Hisi acc dev</tspan></text></g><g transform="translate(422.92,718)"><path d="M499.7,38L499.7,0L0,0L0,38L499.7,38z" stroke="#3498db" fill="#7eccb6" id="shape47"/><text class="st1"><tspan x="148.4" y="28.5">Hisi acc k-driver</tspan></text></g><g transform="translate(672.79,756)" id="shape48"><path d="M0,0L0,31.7" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,36.1L3,30.9C2.1,31.4,1.1,31.7,0,31.7C-1.1,31.7,-2.1,31.4,-3,30.9L0,36.1" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><path d="M25.2,10.5L58.5,10.5L58.5,0L83.7,21L58.5,41.9L58.5,31.5L25.2,31.5L25.2,41.9L0,21L25.2,0L25.2,10.5z" stroke="#2da2bf" fill="#0070c0" transform="translate(410.7,137.75)" id="shape49"/><path d="M25.2,10.5L58.5,10.5L58.5,0L83.7,21L58.5,41.9L58.5,31.5L25.2,31.5L25.2,41.9L0,21L25.2,0L25.2,10.5z" stroke="#2da2bf" fill="#0070c0" transform="translate(410.7,375.82)" id="shape50"/><g transform="translate(2015.19,382.16)" id="shape51"><text class="st3"><tspan x="4.4" y="18.4">Each udriver compilation </tspan><tspan x="4.4" y="39.4">generates a separate </tspan><tspan x="4.4" y="60.4">library file</tspan></text></g><g transform="translate(958.38,361.82)" id="shape52"><path d="M0,33C-0,14.8,33.3,-0,74.5,-0C115.6,-0,148.9,14.8,148.9,33C148.9,51.2,115.6,66,74.5,66C33.3,66,0,51.2,0,33z" stroke="#3498db" fill="#00b050"/><text class="st1"><tspan x="26.5" y="42.5">alg list</tspan></text></g><g transform="translate(1166.5,125.72)" id="shape53"><path d="M0,33C-0,14.8,38.2,0,85.3,0C132.4,0,170.6,14.8,170.6,33C170.6,51.2,132.4,66,85.3,66C38.2,66,0,51.2,0,33z" stroke="#3498db" fill="#7eccb6"/><text class="st1"><tspan x="25.3" y="42.5">driver ops</tspan></text></g><g transform="translate(1251.82,532.79)" id="shape54"><path d="M0,13.9L0,287.8L-228.2,287.8" stroke="#236ea1" fill="none" stroke-width="5.33333"/><path stroke-linecap="round" d="M-6.9,13.9L0,0L6.9,13.9L-6.9,13.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M-228.2,294.8L-242,287.8L-228.2,280.9L-228.2,294.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1144.87,513.79)" id="shape55"><path d="M0,0L-112,0L-112,-81.6" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M-112,-86L-115,-80.8C-114.1,-81.3,-113.1,-81.6,-112,-81.6C-110.9,-81.6,-109.9,-81.3,-109,-80.8L-112,-86" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g></g></svg> + + + The interface of the control layer still exists, and the internal optimization abstraction is carried out. The interface specific to a certain device operation is no longer added, but the original supported interface is still preserved to ensure compatibility, and only the optimized interface is added. + + The original business data layer interface remains unchanged, and the supported algorithms remain unchanged to ensure that the task execution operation does not change and ensure compatibility. By adding the initialization init2 interface, it is convenient for users to use, reduces the process of initialization operations, and reduces the complexity of use. + + Optimize the API layer and user mode driver layer through the following data structure, and add a new algorithm support list component: + +``` +struct wd_alg_list { + const char *alg_name; + const char *drv_name; + int priority; + bool available; + int refcnt; + + struct wd_alg_driver *drv; + struct wd_alg_list *next; +}; + +struct wd_alg_driver *wd_request_drv(const char *alg_name, bool hw_mask); +void wd_release_drv(struct wd_alg_driver *drv); +``` + + The southbound driver interface is unified, no longer differentiated according to the algorithm class, and the user-mode driver is triggered through dlopen to perform a unified registration operation. + +``` +struct wd_alg_driver { + const char *drv_name; + const char *alg_name; + int priority; + int queue_num; + int op_type_num; + int priv_size; + handle_t fallback; + + int (*init)(void *conf, void *priv); + void (*exit)(void *priv); + int (*send)(handle_t ctx, void *drv_msg); + int (*recv)(handle_t ctx, void *drv_msg); + int (*get_usage)(void *param); +}; + +int wd_alg_driver_register(struct wd_alg_driver *drv); +void wd_alg_driver_unregister(struct wd_alg_driver *drv); +``` + + When the control layer process is initialized, directly load all device driver so files in the specified directory through dlopen, and guide the device driver to register on the algorithm list. + + The user queries the supported algorithm driver from the algorithm list according to the specified algorithm, and finds the optimal device driver for use according to the priority. + + In order to match the device resources on the uacce framework based on the algorithm class declaration method, it is necessary to map through the corresponding matching function, obtain the corresponding algorithm class through the algorithm name, and then perform resource application and mapping operations on the device: + +``` +static struct acc_alg_item alg_options[] = { + {"zlib", "zlib-deflate"}, + {"gzip", "gzip"}, + {"deflate", "deflate"}, + {"lz77_zstd", "lz77_zstd"}, + + {"rsa", "rsa"}, + {"dh", "dh"}, + {"ecdh", "ecdh"}, + {"x25519", "x25519"}, + {"x448", "x448"}, + {"ecdsa", "ecdsa"}, + {"sm2", "sm2"}, + ... + {"", ""} +}; + +static void wd_get_alg_type(const char *alg_name, char *alg_type) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(alg_options); i++) { + if (strcmp(alg_name, alg_options[i].name) == 0) { + (void)strcpy(alg_type, alg_options[i].algtype); + break; + } + } +} +``` + + At the same time, when the corresponding algorithm module allocates sessions, it needs to check whether the device drivers and resources applied for through the sub-algorithm support the current algorithm, and only those that pass the check can continue to execute the task: + +``` +int wd_drv_alg_support(const char *alg_name, + struct wd_alg_driver *drv) +{ + struct wd_alg_list *head = &alg_list_head; + struct wd_alg_list *pnext = head->next; + + while (pnext) { + if (!strcmp(alg_name, pnext->alg_name) && + !strcmp(drv->drv_name, pnext->drv_name)) { + return true; + } + pnext = pnext->next; + } + + return false; +} +``` + + In the specific implementation of the function code, the algorithm matching check is required when the session is allocated: + +``` +handle_t wd_cipher_alloc_sess(struct wd_cipher_sess_setup *setup) +{ + struct wd_cipher_sess *sess = NULL; + int ret; + + ... + sess->alg_name = wd_cipher_alg_name[setup->alg][setup->mode]; + sess->alg = setup->alg; + sess->mode = setup->mode; + ret = wd_drv_alg_support(sess->alg_name, wd_cipher_setting.driver); + if (ret) { + WD_ERR("failed to support this algorithm: %s!\n", sess->alg_name); + goto err_sess; + } + + ... + return (handle_t)sess; + +err_sess: + if (sess->sched_key) + free(sess->sched_key); + free(sess); + return (handle_t)0; +} +``` + + + +### **Modular Dynamic Loading Design:** +` ` In order to eliminate the strong coupling between the previous API layer and the user mode driver layer, an algorithm support list component is added. This list is placed on a public framework. When users use the resource allocation interface to apply for resources, they will query the device driver according to the algorithm name. And in the acquisition process, the optimal device driver is searched by priority. + +<svg xmlns:ev="http://www.w3.org/2001/xml-events" width="1000" xmlns:xlink="http://www.w3.org/1999/xlink" height="380" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2255 804"><style type="text/css"><![CDATA[ +.st2 {fill:#000000;font-family:宋体;font-size:18pt} +.st1 {fill:#000000;font-family:微软雅黑;font-size:10pt} +.st4 {fill:#000000;font-family:微软雅黑;font-size:14pt} +.st3 {fill:#1f6391;font-family:宋体;font-size:10pt} +.st6 {fill:#1f6391;font-family:微软雅黑;font-size:12pt} +.st5 {fill:#1f6391;font-family:微软雅黑;font-size:14pt} +]]></style><defs/><g transform="translate(5,5)" id="page1"><rect x="0" stroke="#808080" fill="#ffffff" width="2245" height="794" y="0"/><g transform="translate(701.64,305.67)"><path d="M100.1,62L100.1,0L0,0L0,62L100.1,62z" stroke="#3498db" fill="#00b050" id="shape1"/><text class="st1"><tspan x="8.1" y="16.5">alg_name:x1x</tspan><tspan x="8.1" y="35.5">alg driver;</tspan><tspan x="8.1" y="54.5">next;</tspan></text></g><g transform="translate(499.64,315.28)"><path d="M124.1,42.8L124.1,0L0,0L0,42.8L124.1,42.8z" stroke="#3498db" fill="#00b0f0" id="shape2"/><text class="st2"><tspan x="8.1" y="30.9">List_Head</tspan></text></g><g transform="translate(623.78,336.67)" id="shape3"><path d="M0,0L73.5,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M77.9,0L72.7,-3C73.2,-2.1,73.5,-1.1,73.5,0C73.5,1.1,73.2,2.1,72.7,3L77.9,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(879.64,305.67)"><path d="M100.1,62L100.1,0L0,0L0,62L100.1,62z" stroke="#3498db" fill="#00b050" id="shape4"/><text class="st1"><tspan x="8.1" y="16.5">alg_name:x2x</tspan><tspan x="8.1" y="35.5">alg driver;</tspan><tspan x="8.1" y="54.5">next;</tspan></text></g><g transform="translate(801.78,336.67)" id="shape5"><path d="M0,0L73.5,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M77.9,0L72.7,-3C73.2,-2.1,73.5,-1.1,73.5,0C73.5,1.1,73.2,2.1,72.7,3L77.9,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1056.64,305.67)"><path d="M100.1,62L100.1,0L0,0L0,62L100.1,62z" stroke="#3498db" fill="#00b050" id="shape6"/><text class="st1"><tspan x="8.1" y="16.5">alg_name:x2x</tspan><tspan x="8.1" y="35.5">alg driver;</tspan><tspan x="8.1" y="54.5">next;</tspan></text></g><g transform="translate(979.78,336.67)" id="shape7"><path d="M0,0L72.5,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M76.9,0L71.7,-3C72.2,-2.1,72.5,-1.1,72.5,0C72.5,1.1,72.2,2.1,71.7,3L76.9,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(681.82,169.52)"><path d="M140.4,60.3L140.4,0L0,0L0,60.3L140.4,60.3z" stroke="#3498db" fill="#92d050" id="shape8"/><text class="st2"><tspan x="10.2" y="39.6">libxx1_drv</tspan></text></g><g transform="translate(958.82,169.52)"><path d="M140.4,60.3L140.4,0L0,0L0,60.3L140.4,60.3z" stroke="#3498db" fill="#92d050" id="shape9"/><text class="st2"><tspan x="10.2" y="39.6">libxx2_drv</tspan></text></g><g transform="translate(1235.82,169.52)"><path d="M140.4,60.3L140.4,0L0,0L0,60.3L140.4,60.3z" stroke="#3498db" fill="#92d050" id="shape10"/><text class="st2"><tspan x="10.2" y="39.6">libxx3_drv</tspan></text></g><g transform="translate(1235.81,305.67)"><path d="M100.1,62L100.1,0L0,0L0,62L100.1,62z" stroke="#3498db" fill="#00b050" id="shape11"/><text class="st1"><tspan x="8.1" y="16.5">alg_name:x3x</tspan><tspan x="8.1" y="35.5">alg driver;</tspan><tspan x="8.1" y="54.5">next;</tspan></text></g><g transform="translate(1156.78,336.67)" id="shape12"><path d="M0,0L74.6,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M79,0L73.8,-3C74.3,-2.1,74.6,-1.1,74.6,0C74.6,1.1,74.3,2.1,73.8,3L79,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1414.99,305.67)"><path d="M100.1,62L100.1,0L0,0L0,62L100.1,62z" stroke="#3498db" fill="#00b050" id="shape13"/><text class="st1"><tspan x="8.1" y="16.5">alg_name:x3x</tspan><tspan x="8.1" y="35.5">alg driver;</tspan><tspan x="8.1" y="54.5">next;</tspan></text></g><g transform="translate(752.02,229.82)" id="shape14"><path d="M0,0L-0.3,71.5" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M-0.3,75.8L2.7,70.7C1.8,71.2,.8,71.5,-0.3,71.5C-1.4,71.5,-2.4,71.2,-3.3,70.6L-0.3,75.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><rect x="-28" fill="#ffffff" width="57.2" height="15" y="30.4"/><text class="st3"><tspan x="-28.2" y="42.4">register</tspan></text></g><g transform="translate(1029.02,229.82)" id="shape15"><path d="M0,0L-95.8,73.2" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M-99.3,75.8L-93.4,75.1C-94.3,74.7,-95.2,74.1,-95.8,73.2C-96.5,72.3,-96.9,71.3,-97,70.3L-99.3,75.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><rect x="-77.5" fill="#ffffff" width="57.2" height="15" y="30.4"/><text class="st3"><tspan x="-77.7" y="42.4">register</tspan></text></g><g transform="translate(1029.02,229.82)" id="shape16"><path d="M0,0L74.5,72.8" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M77.7,75.8L76.1,70.1C75.8,71.1,75.3,72,74.5,72.8C73.8,73.6,72.9,74.1,71.9,74.4L77.7,75.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><rect x="11" fill="#ffffff" width="57.2" height="15" y="30.4"/><text class="st3"><tspan x="10.8" y="42.4">register</tspan></text></g><g transform="translate(1306.02,229.82)" id="shape17"><path d="M0,0L-19,71.6" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M-20.1,75.8L-15.9,71.6C-16.9,71.9,-18,71.9,-19,71.6C-20.1,71.3,-21,70.8,-21.7,70.1L-20.1,75.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><rect x="-38" fill="#ffffff" width="57.2" height="15" y="30.4"/><text class="st3"><tspan x="-38.1" y="42.4">register</tspan></text></g><g transform="translate(1306.02,229.82)" id="shape18"><path d="M0,0L155.1,74" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M159,75.8L155.6,70.9C155.7,71.9,155.5,73,155.1,74C154.6,74.9,153.9,75.7,153.1,76.3L159,75.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><rect x="51.6" fill="#ffffff" width="57.2" height="15" y="30.4"/><text class="st3"><tspan x="51.5" y="42.4">register</tspan></text></g><g transform="translate(1335.95,336.67)" id="shape19"><path d="M0,0L74.6,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M79,0L73.8,-3C74.4,-2.1,74.6,-1.1,74.6,0C74.6,1.1,74.4,2.1,73.8,3L79,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(246.01,167.25)"><path d="M180.5,64.9L180.5,0L0,0L0,64.9L180.5,64.9z" stroke="#3498db" fill="#92d050" id="shape20"/><text class="st2"><tspan x="54.2" y="41.9">WD API</tspan></text></g><g transform="translate(31.51,180.67)" id="shape21"><text class="st4"><tspan x="26.3" y="25.5">control cmd</tspan></text></g><path d="M4.4,64.6L4.4,9L0,9L8.9,0L17.7,9L13.3,9L13.3,64.6L4.4,64.6z" stroke="#dd7195" fill="#dd7195" transform="matrix(0,1,-1,0,239.4,194.4)" id="shape22"/><g transform="translate(426.49,199.67)" id="shape23"><path d="M0,0L250.9,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M255.3,0L250.1,-3C250.6,-2.1,250.9,-1.1,250.9,0C250.9,1.1,250.6,2.1,250.1,3L255.3,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><rect x="95.8" fill="#ffffff" width="65.4" height="25" y="-12.5"/><text class="st5"><tspan x="95.7" y="6.5">dlopen</tspan></text></g><g transform="translate(822.22,199.67)" id="shape24"><path d="M0,0L132.2,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M136.6,0L131.4,-3C131.9,-2.1,132.2,-1.1,132.2,0C132.2,1.1,131.9,2.1,131.4,3L136.6,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1099.22,199.67)" id="shape25"><path d="M0,0L132.2,0" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M136.6,0L131.4,-3C131.9,-2.1,132.2,-1.1,132.2,0C132.2,1.1,131.9,2.1,131.4,3L136.6,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><path d="M0,0L532.9,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,466,695.1)" stroke-width="2" id="shape26"/><g transform="translate(248.01,619.54)"><path d="M178.5,68.3L178.5,0L0,0L0,68.3L178.5,68.3z" stroke="#3498db" fill="#00b0f0" id="shape27"/><text class="st2"><tspan x="47.2" y="43.6">ALG API</tspan></text></g><g transform="translate(31.51,634.67)" id="shape28"><text class="st4"><tspan x="27.3" y="25.5">data stream</tspan></text></g><path d="M13.2,5.5L62.8,5.5L62.8,0L76,11L62.8,22L62.8,16.5L13.2,16.5L13.2,22L0,11L13.2,0L13.2,5.5z" stroke="#2da2bf" fill="#2da2bf" transform="translate(169.05,642.67)" id="shape29"/><g transform="translate(556.24,634.67)"><path d="M316.5,38L316.5,0L0,0L0,38L316.5,38z" stroke="#3498db" fill="#92d050" id="shape30"/><text class="st2"><tspan x="20.3" y="28.5">libwd_crypto/libwd_comp</tspan></text></g><g transform="translate(1235.81,625.17)"><path d="M156.2,57L156.2,0L0,0L0,57L156.2,57z" stroke="#3498db" fill="#7eccb6" id="shape31"/><text class="st2"><tspan x="18.1" y="38">driver ops</tspan></text></g><path d="M0,0L532.9,0" stroke="#236ea1" stroke-dasharray="2,5" fill="none" transform="matrix(0,-1,1,0,1537,679.1)" stroke-width="2" id="shape32"/><g transform="translate(1576.06,625.18)"><path d="M200.7,54.1L200.7,0L0,0L0,54.1L200.7,54.1z" stroke="#3498db" fill="#00b0f0" id="shape33"/><text class="st2"><tspan x="58.4" y="36.6">ACC dev</tspan></text></g><g transform="translate(714.5,634.67)" id="shape34"><path d="M0,0L-150.7,-272.8" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M-152.8,-276.6L-152.9,-270.6C-152.4,-271.5,-151.6,-272.2,-150.7,-272.8C-149.7,-273.3,-148.7,-273.5,-147.7,-273.5L-152.8,-276.6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><rect x="-90.3" fill="#ffffff" width="28.6" height="15" y="-145.8"/><text class="st3"><tspan x="-90.4" y="-133.8">find</tspan></text></g><g transform="translate(1106.71,367.67)" id="shape35"><path d="M0,0L204.4,254.1" stroke="#236ea1" stroke-dasharray="11,5,2.5,5" fill="none"/><path stroke-linecap="round" d="M207.2,257.5L206.3,251.6C205.9,252.5,205.3,253.4,204.4,254.1C203.6,254.8,202.6,255.2,201.6,255.3L207.2,257.5" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(426.49,653.67)" id="shape36"><path d="M9.8,0L120,0" stroke="#236ea1" fill="none" stroke-width="2.66667"/><path stroke-linecap="round" d="M9.8,4.9L0,0L9.8,-4.9L9.8,4.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M120,-4.9L129.8,0L120,4.9L120,-4.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(872.76,653.67)" id="shape37"><path d="M9.8,0L353.3,0" stroke="#236ea1" fill="none" stroke-width="2.66667"/><path stroke-linecap="round" d="M9.8,4.9L0,0L9.8,-4.9L9.8,4.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M353.3,-4.9L363.1,0L353.3,4.9L353.3,-4.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(1391.96,653.67)" id="shape38"><path d="M9.8,-0.1L174.3,-1.3" stroke="#236ea1" fill="none" stroke-width="2.66667"/><path stroke-linecap="round" d="M9.8,4.8L0,0L9.8,-5L9.8,4.8" stroke="#236ea1" fill="#236ea1" stroke-width="1"/><path stroke-linecap="round" d="M174.3,-6.2L184.1,-1.4L174.3,3.6L174.3,-6.2" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(499.64,98.6)" id="shape39"><text class="st6"><tspan x="4.1" y="9.1">Find the "so" file from the fixed directory, and detect whether </tspan><tspan x="4.1" y="30.1">the "so" internal interface has a driver registration interface </tspan><tspan x="4.1" y="51.1">wd_alg_driver_register()</tspan></text></g></g></svg> +` ` In order to query the corresponding device driver files more accurately, you can query the user mode driver so file in the system dynamic library directory. Then check whether it contains an algorithm-driven registration interface, and if there is a corresponding interface, open it through dlopen. The algorithm registration operation will be triggered during the opening process, and then the algorithms supported by the device driver will be registered on the algorithm list. + + The complete dynamic loading processing flow is shown in the following figure: + +<svg xmlns:ev="http://www.w3.org/2001/xml-events" width="755" xmlns:xlink="http://www.w3.org/1999/xlink" height="813" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1133 1220"><style type="text/css"><![CDATA[ +.st2 {fill:#000000;font-family:微软雅黑;font-size:12pt} +.st5 {fill:#000000;font-family:微软雅黑;font-size:14pt} +.st4 {fill:#1f6391;font-family:微软雅黑;font-size:12pt} +.st1 {fill:#ffffff;font-family:微软雅黑;font-size:12pt} +.st3 {fill:#ffffff} +]]></style><defs/><g transform="translate(5,5)" id="page1"><rect x="0" stroke="#808080" fill="#ffffff" width="1123" height="1587" y="0"/><g transform="translate(449.5,50)"><path d="M20,40L74,40C85,40,94,31,94,20C94,9,85,0,74,0L20,0C9,0,0,9,0,20C0,31,9,40,20,40z" stroke="#83b3e3" fill="#2d85c1" id="shape1"/><text class="st1"><tspan x="30" y="25.5">start</tspan></text></g><g transform="translate(419,128)"><path d="M156,37L156,0L0,0L0,37L156,37z" stroke="#83b3e3" fill="#2d85c1" id="shape2"/><text class="st1"><tspan x="31" y="24">wd_xxx_init2</tspan></text></g><g transform="translate(496.5,90)" id="shape3"><path d="M0,0L.4,33.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M.5,38L3.4,32.8C2.6,33.3,1.5,33.6,.4,33.6C-0.7,33.6,-1.7,33.3,-2.6,32.8L.5,38" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(450,1159)"><path d="M20,40L74,40C85,40,94,31,94,20C94,9,85,0,74,0L20,0C9,0,0,9,0,20C0,31,9,40,20,40z" stroke="#83b3e3" fill="#2d85c1" id="shape4"/><text class="st1"><tspan x="33" y="25.5">end</tspan></text></g><g transform="translate(419,210.5)"><path d="M156,37L156,0L0,0L0,37L156,37z" stroke="#83b3e3" fill="#2d85c1" id="shape5"/><text class="st1"><tspan x="21" y="24">wd_dlopen_drv</tspan></text></g><g transform="translate(497,165)" id="shape6"><path d="M0,0L0,41.1" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,45.5L3,40.3C2.1,40.8,1.1,41.1,0,41.1C-1.1,41.1,-2.1,40.8,-3,40.3L0,45.5" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(382.2,584.15)"><path d="M114.8,59.7L229.6,29.9L114.8,0L0,29.9L114.8,59.7z" stroke="#83b3e3" fill="#2d85c1" id="shape7"/><text class="st1"><tspan x="45.3" y="35.4">wd_ctx_param_init</tspan></text></g><g transform="translate(497,643.85)" id="shape8"><path d="M0,0L0,54.8" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,59.2L3,54C2.1,54.5,1.1,54.8,0,54.8C-1.1,54.8,-2.1,54.5,-3,54L0,59.2" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(497,762.78)" id="shape9"><path d="M0,0L0,391.8" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,396.2L3,391C2.1,391.5,1.1,391.8,0,391.8C-1.1,391.8,-2.1,391.5,-3,391L0,396.2" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(419,437.5)"><path d="M156,37L156,0L0,0L0,37L156,37z" stroke="#83b3e3" fill="#2d85c1" id="shape10"/><text class="st1"><tspan x="16" y="24">wd_alg_drv_bind</tspan></text></g><g transform="translate(647,211.5)"><path d="M187.3,35.8L187.3,0L0,0L0,35.8L187.3,35.8z" stroke="#83b3e3" fill="#92d050" id="shape11"/><text class="st1"><tspan x="18.1" y="23.4">wd_get_lib_file_path</tspan></text></g><g transform="translate(575,229)" id="shape12"><path d="M0,0L40,0L67.6,.3" stroke="#236ea1" stroke-dasharray="11,5" fill="none"/><path stroke-linecap="round" d="M72,.4L66.8,-2.7C67.3,-1.8,67.6,-0.7,67.6,.3C67.6,1.4,67.3,2.5,66.8,3.3L72,.4" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(740.63,247.3)" id="shape13"><path d="M0,0L0,14.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,19L3,13.8C2.1,14.3,1.1,14.6,0,14.6C-1.1,14.6,-2.1,14.3,-3,13.8L0,19" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(611.8,732.93)" id="shape14"><path d="M0,0L38.9,0" stroke="#236ea1" stroke-dasharray="11,5" fill="none"/><path stroke-linecap="round" d="M43.3,0L38.1,-3C38.6,-2.1,38.9,-1.1,38.9,0C38.9,1.1,38.6,2.1,38.1,3L43.3,0" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(740.63,302)" id="shape15"><path d="M0,0L0,14.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,19L3,13.8C2.1,14.3,1.1,14.6,0,14.6C-1.1,14.6,-2.1,14.3,-3,13.8L0,19" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(575,456)" id="shape16"><path d="M0,0L47.3,0L74.9,-0.3" stroke="#236ea1" stroke-dasharray="11,5" fill="none"/><path stroke-linecap="round" d="M79.3,-0.4L74,-3.3C74.5,-2.5,74.9,-1.4,74.9,-0.3C74.9,.7,74.6,1.8,74.1,2.7L79.3,-0.4" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(497,474.5)" id="shape17"><path d="M0,0L0,105.3" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,109.6L3,104.5C2.1,105,1.1,105.3,0,105.3C-1.1,105.3,-2.1,105,-3,104.5L0,109.6" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(164,544)"><path d="M156,37L156,0L0,0L0,37L156,37z" stroke="#83b3e3" fill="#2d85c1" id="shape18"/><text class="st1"><tspan x="21" y="24">wd_disable_drv</tspan></text></g><g transform="translate(164,468)"><path d="M156,37L156,0L0,0L0,37L156,37z" stroke="#83b3e3" fill="#2d85c1" id="shape19"/><text class="st1"><tspan x="6" y="24">wd_alg_drv_unbind</tspan></text></g><g transform="translate(242,544)" id="shape20"><path d="M0,0L0,-34.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,-39L-3,-33.8C-2.1,-34.3,-1.1,-34.6,0,-34.6C1.1,-34.6,2.1,-34.3,3,-33.8L0,-39" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(382.2,614)" id="shape21"><path d="M0,0L-140.2,0L-140.2,-28.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-140.2,-33L-143.2,-27.8C-142.3,-28.3,-141.3,-28.6,-140.2,-28.6C-139.1,-28.6,-138.1,-28.3,-137.2,-27.8L-140.2,-33" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(242,468)" id="shape22"><path d="M0,0L0,-80.3L250.6,-80.3" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M255,-80.3L249.8,-83.3C250.3,-82.4,250.6,-81.4,250.6,-80.3C250.6,-79.2,250.3,-78.2,249.8,-77.3L255,-80.3" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(382.2,703.07)"><path d="M114.8,59.7L229.6,29.9L114.8,0L0,29.9L114.8,59.7z" stroke="#83b3e3" fill="#2d85c1" id="shape23"/><text class="st1"><tspan x="52.3" y="35.4">wd_alg_attrs_init</tspan></text></g><g transform="translate(382.2,732.93)" id="shape24"><path d="M0,0L-140.2,0L-140.2,-147.5" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-140.2,-151.9L-143.2,-146.7C-142.3,-147.2,-141.3,-147.5,-140.2,-147.5C-139.1,-147.5,-138.1,-147.2,-137.2,-146.7L-140.2,-151.9" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(662.63,321)"><path d="M156,35.7L156,0L0,0L0,35.7L156,35.7z" stroke="#83b3e3" fill="#92d050" id="shape25"/><text class="st1"><tspan x="52" y="23.4">dlopen</tspan></text></g><g transform="translate(662.63,266.3)"><path d="M156,35.7L156,0L0,0L0,35.7L156,35.7z" stroke="#83b3e3" fill="#92d050" id="shape26"/><text class="st1"><tspan x="54" y="23.4">dladdr</tspan></text></g><g transform="translate(655.13,715.03)"><path d="M171,35.8L171,0L0,0L0,35.8L171,35.8z" stroke="#83b3e3" fill="#92d050" id="shape27"/><text class="st1"><tspan x="23" y="23.4">wd_get_alg_type</tspan></text></g><g transform="translate(655.13,776.8)"><path d="M171.1,35.8L171.1,0L0,0L0,35.8L171.1,35.8z" stroke="#83b3e3" fill="#92d050" id="shape28"/><text class="st1"><tspan x="18.1" y="23.4">wd_sched_rr_alloc</tspan></text></g><g transform="translate(655.13,838.58)"><path d="M172.1,35.8L172.1,0L0,0L0,35.8L172.1,35.8z" stroke="#83b3e3" fill="#92d050" id="shape29"/><text class="st1"><tspan x="30.1" y="23.4">wd_alg_ctx_init</tspan></text></g><g transform="translate(654.26,900.35)"><path d="M172.9,35.8L172.9,0L0,0L0,35.8L172.9,35.8z" stroke="#83b3e3" fill="#92d050" id="shape30"/><text class="st1"><tspan x="5.4" y="23.4">wd_sched_rr_instance</tspan></text></g><g transform="translate(740.63,750.82)" id="shape31"><path d="M0,0L0,10L0,21.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M.1,26L3,20.8C2.2,21.3,1.1,21.6,0,21.6C-1,21.6,-2.1,21.3,-3,20.8L.1,26" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(740.69,812.6)" id="shape32"><path d="M0,0L0,10L.4,21.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M.5,26L3.3,20.7C2.5,21.2,1.5,21.6,.4,21.6C-0.7,21.6,-1.8,21.4,-2.7,20.9L.5,26" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(741.19,874.38)" id="shape33"><path d="M0,0L0,10L-0.4,21.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-0.5,26L2.7,20.9C1.8,21.4,.7,21.6,-0.4,21.6C-1.5,21.6,-2.5,21.2,-3.3,20.7L-0.5,26" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(654.13,962.13)"><path d="M173,35.8L173,0L0,0L0,35.8L173,35.8z" stroke="#83b3e3" fill="#0070c0" id="shape34"/><text class="st2"><tspan class="st3" x="39" y="23.4">alg_init_func</tspan></text></g><g transform="translate(740.69,936.15)" id="shape35"><path d="M0,0L0,10L-0,21.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-0.1,26L3,20.8C2.1,21.3,1,21.6,-0,21.6C-1.1,21.6,-2.2,21.3,-3,20.8L-0.1,26" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(497,247.5)" id="shape36"><path d="M0,0L0,185.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,190L3,184.8C2.1,185.3,1.1,185.6,0,185.6C-1.1,185.6,-2.1,185.3,-3,184.8L0,190" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(493.26,648.7)" id="shape37"><text class="st4"><tspan x="11.4" y="17">Y</tspan></text></g><g transform="translate(493.26,776.8)" id="shape38"><text class="st4"><tspan x="11.4" y="17">Y</tspan></text></g><g transform="translate(334.26,584.15)" id="shape39"><text class="st4"><tspan x="10.4" y="17">N</tspan></text></g><g transform="translate(334.26,703.07)" id="shape40"><text class="st4"><tspan x="10.4" y="17">N</tspan></text></g><g transform="translate(172.51,61.67)" id="shape41"><text class="st5"><tspan x="4.3" y="13">Dynamic loading </tspan><tspan x="47.3" y="38">process</tspan></text></g><g transform="translate(654.26,437.7)"><path d="M171,35.8L171,0L0,0L0,35.8L171,35.8z" stroke="#83b3e3" fill="#92d050" id="shape42"/><text class="st1"><tspan x="27" y="23.4">wd_request_drv</tspan></text></g><g transform="translate(654.26,499.7)"><path d="M171,35.8L171,0L0,0L0,35.8L171,35.8z" stroke="#83b3e3" fill="#92d050" id="shape43"/><text class="st1"><tspan x="27" y="12.9">wd_request_drv</tspan><tspan x="51" y="33.9">(fallback)</tspan></text></g><g transform="translate(739.76,473.5)" id="shape44"><path d="M0,0L0,21.8" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,26.2L3,21C2.1,21.5,1.1,21.8,0,21.8C-1.1,21.8,-2.1,21.5,-3,21L0,26.2" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(662.63,377.1)"><path d="M156,35.7L156,0L0,0L0,35.7L156,35.7z" stroke="#83b3e3" fill="#92d050" id="shape45"/><text class="st1"><tspan x="56" y="23.4">dlsym</tspan></text></g><g transform="translate(740.63,356.7)" id="shape46"><path d="M0,0L0,16" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,20.4L3,15.2C2.1,15.7,1.1,16,0,16C-1.1,16,-2.1,15.7,-3,15.2L0,20.4" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(655.13,1023.9)"><path d="M172.1,35.8L172.1,0L0,0L0,35.8L172.1,35.8z" stroke="#83b3e3" fill="#92d050" id="shape47"/><text class="st1"><tspan x="17.1" y="23.4">wd_init_ctx_config</tspan></text></g><g transform="translate(655.13,1085.68)"><path d="M172.1,35.8L172.1,0L0,0L0,35.8L172.1,35.8z" stroke="#83b3e3" fill="#92d050" id="shape48"/><text class="st1"><tspan x="34.1" y="23.4">wd_init_sched</tspan></text></g><g transform="translate(655.13,1147.45)"><path d="M172.1,35.8L172.1,0L0,0L0,35.8L172.1,35.8z" stroke="#83b3e3" fill="#92d050" id="shape49"/><text class="st1"><tspan x="19.1" y="23.4">wd_alg_init_driver</tspan></text></g><g transform="translate(740.63,997.93)" id="shape50"><path d="M0,0L0,10L.4,21.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M.6,26L3.4,20.7C2.5,21.2,1.5,21.5,.4,21.6C-0.7,21.6,-1.7,21.4,-2.6,20.9L.6,26" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(741.19,1059.7)" id="shape51"><path d="M0,0L-0,21.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M-0,26L3,20.8C2.1,21.3,1.1,21.6,-0,21.6C-1.1,21.6,-2.1,21.3,-3,20.8L-0,26" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g><g transform="translate(741.19,1121.48)" id="shape52"><path d="M0,0L0,21.6" stroke="#236ea1" fill="none"/><path stroke-linecap="round" d="M0,26L3,20.8C2.1,21.3,1.1,21.6,0,21.6C-1.1,21.6,-2.1,21.3,-3,20.8L0,26" stroke="#236ea1" fill="#236ea1" stroke-width="1"/></g></g></svg> + + When registering an algorithm, it is distinguished whether it is software computing or hardware computing. Software computing is directly registered, and hardware computing is to detect whether the current algorithm is supported by the corresponding device during registration. If the supported device exists, register it, otherwise skip it. + +` ` When the normal task is sent, according to the algorithm device driver dynamically found from the algorithm list when the device resource is initialized, the task data is sent to the corresponding device driver through the unified driver ops. Then send the data to the accelerator device through the encapsulation interface driven by the device, and obtain the data processing result after the processing is completed. + +` ` In order to realize the dynamic loading function of the device driver, the device driver will be adapted through a unified driver ops, and an independent driver so library file will be compiled and generated. Deploy the driver's so file to the system dynamic library file directory on the server that needs to use UADK, and then automatically open and load it through the dlopen method inside the resource initialization interface. When loading the driver library file, the supported algorithm will be triggered to register to the algorithm List. + +` ` In addition, on the basis of the original model that supports hardware acceleration alone, software computing supplementary support is provided in the driver through the fallback method. Implement software and hardware hybrid computing support. + +### **Implementation Plan Description** + Through the update of the init2 interface, the adaptation and initialization of dynamic loading are realized. At the same time, a pair of new initialization interfaces will be added. The cipher module corresponds to the newly added interface: + +``` +int wd_cipher_init2(char *alg, __u32 sched_type, int task_type, struct wd_ctx_params *ctx_params); + +#define wd_cipher_init2_(alg, sched_type, task_type) \ + wd_cipher_init2(alg, sched_type, task_type, NULL) + +void wd_comp_uninit2(void); +``` + +` ` Other parts remain basically unchanged to ensure compatibility and use with the original framework. But the initialization will be processed internally, and the initialization interface will be reused: + +``` +int wd_cipher_init2(char *alg, __u32 sched_type, int task_type, +struct wd_ctx_params *ctx_params) +{ + struct wd_ctx_nums cipher_ctx_num[WD_CIPHER_DECRYPTION + 1] = {0}; + struct wd_ctx_params cipher_ctx_params = {0}; + enum wd_status status; + int i, ret = 0; + bool flag; + + … + wd_cipher_setting.dlh_list = wd_dlopen_drv(NULL); + if (!wd_cipher_setting.dlh_list) { + WD_ERR("fail to open driver lib files.\n"); + goto out_uninit; + } + +res_retry: + memset(&wd_cipher_setting.config, 0, sizeof(struct wd_ctx_config_internal)); + /* Get alg driver and dev name */ + wd_cipher_setting.driver = wd_alg_drv_bind(task_type, alg); + if (!wd_cipher_setting.driver) { + WD_ERR("fail to bind a valid driver.\n"); + goto out_dlopen; + } + + cipher_ctx_params.bmp = NULL; + cipher_ctx_params.ctx_set_num = cipher_ctx_num; + cipher_ctx_params.op_type_num = wd_cipher_setting.driver->op_type_num; + if (cipher_ctx_params.op_type_num > WD_CIPHER_DECRYPTION + 1) { + WD_ERR("fail to check driver op type numbers.\n"); + wd_disable_drv(wd_cipher_setting.driver); + goto res_retry; + } + for (i = 0; i < cipher_ctx_params.op_type_num; i++) { + cipher_ctx_num[i].sync_ctx_num = wd_cipher_setting.driver->queue_num; + cipher_ctx_num[i].async_ctx_num = wd_cipher_setting.driver->queue_num; + } + + wd_cipher_init_attrs.alg = alg; + wd_cipher_init_attrs.sched_type = sched_type; + wd_cipher_init_attrs.driver = wd_cipher_setting.driver; + wd_cipher_init_attrs.ctx_params = ctx_params ? ctx_params : &cipher_ctx_params; + wd_cipher_init_attrs.alg_init = wd_cipher_init; + wd_cipher_init_attrs.alg_poll_ctx = wd_cipher_poll_ctx; + ret = wd_alg_attrs_init(&wd_cipher_init_attrs); + if (ret) { + if (ret == -WD_ENODEV) { + wd_disable_drv(wd_cipher_setting.driver); + goto res_retry; + } + WD_ERR("fail to init alg attrs.\n"); + goto out_driver; + } + + wd_alg_set_init(&wd_cipher_setting.status2); + + return 0; + +out_driver: + wd_alg_drv_unbind(wd_cipher_setting.driver); +out_dlopen: + wd_dlclose_drv(wd_cipher_setting.dlh_list); +out_uninit: + wd_alg_clear_init(&wd_cipher_setting.status2); + return ret; +} +``` + + The uninitialization interface is also reused when releasing the current algorithm resources: + +``` +void wd_cipher_uninit2(void) +{ + wd_cipher_uninit(); + + wd_alg_attrs_uninit(&wd_cipher_init_attrs); + + wd_alg_drv_release(wd_cipher_setting.driver); + wd_dlclose_drv(wd_cipher_setting.dlh_list); + wd_alg_clear_init(&wd_cipher_setting.status2); +} +``` + + Special attention is required. In order to maintain the commonality of each module, all internal resource initialization parts use public functions, and realize processing through a unified data structure: + +``` +struct wd_init_attrs { + __u32 sched_type; + char *alg; + struct wd_alg_driver *driver; + struct wd_sched *sched; + struct wd_ctx_params *ctx_params; + struct wd_ctx_config *ctx_config; + wd_alg_init alg_init; + wd_alg_poll_ctx alg_poll_ctx; +}; +``` + + + Moreover, the framework provides multiple internal public functions to complete the public processing of resource initialization: + +``` +int wd_alg_attrs_init(struct wd_init_attrs *alg_init_attrs); +void wd_alg_attrs_uninit(struct wd_init_attrs *attrs); + +struct wd_alg_driver *wd_alg_drv_request(int task_type, char *alg_name); +void wd_alg_drv_release(struct wd_alg_driver *drv); + +int wd_alg_init_driver(struct wd_ctx_config_internal *config, + struct wd_alg_driver *driver, void **drv_priv); +void wd_alg_uninit_driver(struct wd_ctx_config_internal *config, + struct wd_alg_driver *driver, void *drv_priv); + +void *wd_dlopen_drv(const char *cust_lib_dir); +void wd_dlclose_drv(void *dlh_list); +``` + + + Finally, the driver's fallback supports the initialization of the driver that performs software calculations synchronously when the algorithm is initialized: + +``` +static int wd_alg_init_fallback(struct wd_alg_driver *fb_driver) +{ + if (!fb_driver->init) { + WD_ERR("soft sec driver have no init interface.\n"); + return -WD_EINVAL; + } + + fb_driver->init(NULL, NULL); + + return 0; +} +``` + +``` +static void wd_alg_uninit_fallback(struct wd_alg_driver *fb_driver) +{ + if (!fb_driver->exit) { + WD_ERR("soft sec driver have no exit interface.\n"); + return; + } + + fb_driver->exit(NULL); +} +``` + +` ` When implemented inside the driver, the sending and receiving interface of the hardware computing can be used to call the software computing through the callback interface of the fallback to process the message. + +### **Running Result Presentation** + Currently, the adaptation of the cipher algorithm of the SEC module and the algorithm of the ZIP module has been completed, and the uadk_tool has been adjusted accordingly. Through the test of uadk_tool, the current dynamic loading function test is normal: + +``` +[root@localhost libs_dy]# ./uadk_tool benchmark --alg aes-128-ecb --mode sva --opt 0 --sync --pktlen 1024 --seconds 5 --thread 1 --multi 1 --ctxnum 1 --prefetch +start UADK benchmark test. +start UADK benchmark test. + [--algname]: aes-128-ecb + [--mode]: 1 + [--optype]: 0 + [--syncmode]:0 + [--pktlen]: 1024 + [--seconds]: 5 + [--thread]: 1 + [--multi]: 1 + [--ctxnum]: 1 + [--algclass]:cipher + [--acctype]: 0 + [--prefetch]:1 + [--engine]: +algname: length: perf: iops: CPU_rate: +aes-128-ecb 1024Bytes 430231.6KB/s 430.2Kops 99.80% +``` + +``` +[root@localhost libs_dy]# ./uadk_tool benchmark --alg aes-128-cbc --mode sva --opt 0 --sync --pktlen 1024 --seconds 5 --thread 1 --multi 1 --ctxnum 1 --prefetch +start UADK benchmark test. +start UADK benchmark test. + [--algname]: aes-128-cbc + [--mode]: 1 + [--optype]: 0 + [--syncmode]:0 + [--pktlen]: 1024 + [--seconds]: 5 + [--thread]: 1 + [--multi]: 1 + [--ctxnum]: 1 + [--algclass]:cipher + [--acctype]: 0 + [--prefetch]:1 + [--engine]: +algname: length: perf: iops: CPU_rate: +aes-128-cbc 1024Bytes 424744.6KB/s 424.7Kops 99.80% +``` + +``` +[root@localhost libs_dy]# ./uadk_tool benchmark --alg zlib --mode sva --opt 0 --sync --pktlen 1024 --seconds 5 --thread 1 --multi 1 --ctxnum 1 --prefetch +start UADK benchmark test. +start UADK benchmark test. + [--algname]: zlib + [--mode]: 1 + [--optype]: 0 + [--syncmode]:0 + [--pktlen]: 1024 + [--seconds]: 5 + [--thread]: 1 + [--multi]: 1 + [--ctxnum]: 1 + [--algclass]:zlib + [--acctype]: 2 + [--prefetch]:1 + [--engine]: +algname: length: perf: iops: CPU_rate: +zlib 1024Bytes 354857.8KB/s 354.9Kops 99.80% +compress data file: ./zip_1024.zlib has exist! +``` +