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;