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 | 186 +++++++++++++++++++------------------- 3 files changed, 143 insertions(+), 129 deletions(-)
diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 2eede39..9f595d1 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 2 /* * 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_ERR("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 bb142a7..7a667b0 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) | \ @@ -45,17 +43,15 @@ struct wd_comp_setting { 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}, {} @@ -67,36 +63,45 @@ static struct wd_ctx_params wd_comp_ctx_params = { .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); + } } -#else -static void __attribute__((constructor)) wd_comp_open_driver(void) + +static int wd_comp_open_driver(void) { + struct wd_alg_driver *driver = NULL; + const char *alg_name = "zlib"; + + /* + * Compatible with the normal acquisition of device + * drivers in the init interface + */ + if (wd_comp_setting.dlh_list) + return 0; + wd_comp_setting.dlhandle = dlopen("libhisi_zip.so", RTLD_NOW); - if (!wd_comp_setting.dlhandle) + 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_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; }
int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) { - void *priv; bool flag; int ret;
@@ -120,19 +125,6 @@ int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) 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, @@ -142,25 +134,24 @@ int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) 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; - 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; + if (!wd_comp_setting.driver) { + ret = wd_comp_open_driver(); + if (ret) + goto out_clear_pool; }
+ ret = wd_alg_init_driver(&wd_comp_setting.config, + wd_comp_setting.driver, + &wd_comp_setting.priv); + if (ret) + goto out_clear_driver; + wd_alg_set_init(&wd_comp_setting.status);
return 0;
-out_free_priv: - free(priv); - wd_comp_setting.priv = NULL; +out_clear_driver: + wd_comp_close_driver(); out_clear_pool: wd_uninit_async_request_pool(&wd_comp_setting.pool); out_clear_sched: @@ -179,25 +170,26 @@ void wd_comp_uninit(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, wd_comp_setting.priv); + + wd_alg_drv_unbind(wd_comp_setting.driver); + wd_comp_setting.driver = NULL;
+ 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) { enum wd_status status; + int ret = 0; bool flag; - int ret;
wd_alg_get_init(&wd_comp_setting.status, &status); if (status == WD_INIT) { @@ -215,55 +207,67 @@ int wd_comp_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_par 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() + * default dir in the /root/lib/xxx.so and then dlopen + */ + 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: + /* Get alg driver and dev name */ + wd_comp_setting.driver = wd_alg_drv_bind(task_type, alg); + if (!wd_comp_setting.driver) + goto out_dlopen;
- 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; + if (sched_type < 0 || sched_type > SCHED_POLICY_BUTT) { + WD_ERR("fail to check sched_type: %d\n", sched_type); + goto out_driver; } - wd_comp_sched->name = SCHED_RR_NAME; - wd_comp_init_attrs.sched = wd_comp_sched; + memset(&wd_comp_setting.config, 0, sizeof(struct wd_ctx_config_internal));
+ 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 = ctx_params ? ctx_params : + &wd_comp_ctx_params; + wd_comp_init_attrs.alg_init = wd_comp_init; + wd_comp_init_attrs.alg_poll_ctx = wd_comp_poll_ctx; ret = wd_alg_attrs_init(&wd_comp_init_attrs); - if (ret) - goto out_freesched; - - ret = wd_comp_init(&wd_comp_ctx, wd_comp_sched); - if (ret) - goto out_freesched; + if (ret) { + if (ret == -WD_ENODEV) { + wd_disable_drv(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.status2);
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.status2); - return ret; }
void wd_comp_uninit2(void) { - int i; - wd_comp_uninit();
- 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_alg_attrs_uninit(&wd_comp_init_attrs);
- wd_sched_rr_release(wd_comp_sched); + wd_alg_drv_unbind(wd_comp_setting.driver); + wd_dlclose_drv(wd_comp_setting.dlh_list); wd_alg_clear_init(&wd_comp_setting.status2); }
@@ -297,7 +301,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"); @@ -513,8 +517,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, @@ -773,7 +777,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;