在 2022/11/26 10:38, fanghao (A) 写道:
在 2022/11/24 15:43, liulongfang 写道:
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: liulongfang liulongfang@huawei.com
drv/hisi_comp.c | 101 +++++++++++++++++++++--- include/drv/wd_comp_drv.h | 27 ------- wd_comp.c | 158 ++++++++++++++++++-------------------- 3 files changed, 163 insertions(+), 123 deletions(-)
diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 2eede39..0038d6f 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,92 @@ 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, +static struct wd_alg_driver hisi_zlib_driver = { + .drv_name = "hisi_zip", + .alg_name = "zlib", + .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 hisi_gzip_driver = { + .drv_name = "hisi_zip", + .alg_name = "gzip", + .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 hisi_deflate_driver = { + .drv_name = "hisi_zip", + .alg_name = "deflate", + .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 hisi_lz77_zstd_driver = { + .drv_name = "hisi_zip", + .alg_name = "lz77_zstd", + .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, }; -WD_COMP_SET_DRIVER(hisi_zip); +static void __attribute__((constructor)) hisi_zip_probe(void) +{ + int ret;
+ WD_ERR("Info: register ZIP alg drivers!\n"); + ret = wd_alg_driver_register(&hisi_zlib_driver); + if (ret) + WD_ERR("Error: register zlib failed!\n");
+ ret = wd_alg_driver_register(&hisi_gzip_driver); + if (ret) + WD_ERR("Error: register gzip failed!\n");
+ ret = wd_alg_driver_register(&hisi_deflate_driver); + if (ret) + WD_ERR("Error: register deflate failed!\n");
+ ret = wd_alg_driver_register(&hisi_lz77_zstd_driver); + if (ret) + WD_ERR("Error: register lz77_zstd failed!\n"); +}
optimize the duplicate code,can combine to one driver?
.alg_name = "zlib\ngzip\ndeflate\nlz77_zstd",
This should not be done, because after this assignment, the query algorithm in alg_list will become more complicated and unclear. I understand that your purpose is to reduce repetitive code, which can actually be handled by defining function macros.
Thansk. Longfang.
and in the wd alg layer can search a alg name from a string.
+static void __attribute__((destructor)) hisi_zip_remove(void) +{ + wd_alg_driver_unregister(&hisi_zlib_driver);
+ wd_alg_driver_unregister(&hisi_gzip_driver);
+ wd_alg_driver_unregister(&hisi_deflate_driver);
+ wd_alg_driver_unregister(&hisi_lz77_zstd_driver); +}
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..a12769a 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,16 +63,11 @@ static struct wd_ctx_params wd_comp_ctx_params = { .bmp = NULL, }; -#ifdef WD_STATIC_DRV -static void wd_comp_set_static_drv(void) -{ - wd_comp_setting.driver = wd_comp_get_driver(); - if (!wd_comp_setting.driver) - WD_ERR("failed to get driver!\n"); -} -#else static void __attribute__((constructor)) wd_comp_open_driver(void) { + if (wd_comp_setting.dlh_list) + return;
wd_comp_setting.dlhandle = dlopen("libhisi_zip.so", RTLD_NOW); if (!wd_comp_setting.dlhandle) WD_ERR("failed to open libhisi_zip.so, %s\n", dlerror()); @@ -87,16 +78,27 @@ static void __attribute__((destructor)) wd_comp_close_driver(void) if (wd_comp_setting.dlhandle) dlclose(wd_comp_setting.dlhandle); } -#endif -void wd_comp_set_driver(struct wd_comp_driver *drv) +static void wd_comp_get_driver(void) { - wd_comp_setting.driver = drv; + struct wd_alg_driver *driver = NULL; + const char *alg_name = "zlib";
+ /* + * Compatible with the normal acquisition of device + * drivers in the init interface + */ + driver = wd_request_drv(alg_name, false); + if (!driver) { + WD_ERR("failed to get %s driver support\n", alg_name); + return; + }
+ wd_comp_setting.driver = driver; } int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) { - void *priv; bool flag; int ret; @@ -120,19 +122,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 +131,19 @@ 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; + if (!wd_comp_setting.driver) + wd_comp_get_driver();
+ 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; - } wd_alg_set_init(&wd_comp_setting.status); 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: @@ -179,16 +162,14 @@ 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_comp_setting.driver = NULL; wd_alg_clear_init(&wd_comp_setting.status); } @@ -196,8 +177,8 @@ void wd_comp_uninit(void) 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 +196,62 @@ 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 could set by env param. + * Than open tham by wd_dlopen_drv() + * Find 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_request(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_dlopen; } - 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_dlopen; + } wd_alg_set_init(&wd_comp_setting.status2); return 0; -out_freesched: - wd_sched_rr_release(wd_comp_sched);
+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_sched_rr_release(wd_comp_sched); + wd_alg_attrs_uninit(&wd_comp_init_attrs); wd_alg_clear_init(&wd_comp_setting.status2); } @@ -297,7 +285,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 +501,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 +761,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;
.