From: Zongyu Wu <wuzongyu1@huawei.com> For compression algorithms in the updated UADK framework, the API layer needs to be adapted to the new UADK heterogeneous hybrid acceleration framework, thereby ensuring that both compression and decompression algorithms can achieve heterogeneous hybrid acceleration. Signed-off-by: Zongyu Wu <wuzongyu1@huawei.com> Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> --- drv/hisi_comp.c | 36 ++++----- wd_comp.c | 194 ++++++++++++++++++++++++++++++++++------------- wd_zlibwrapper.c | 12 ++- 3 files changed, 165 insertions(+), 77 deletions(-) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 97bcf39..c75e734 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -5,6 +5,7 @@ #include "drv/wd_comp_drv.h" #include "drv/hisi_comp_huf.h" #include "hisi_qm_udrv.h" +#include "wd_drv.h" #define ZLIB 0 #define GZIP 1 @@ -15,6 +16,7 @@ #define ZLIB_HEADER "\x78\x9c" #define ZLIB_HEADER_SZ 2 #define ZIP_CTX_Q_NUM_DEF 1 +#define WD_COMP_ALG_TYPE_V1 "deflate" /* * 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 @@ -1473,11 +1475,11 @@ static void hisi_zip_sqe_ops_adapt(handle_t h_qp) } } -static int hisi_zip_init(struct wd_alg_driver *drv, void *conf) +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; - struct hisi_zip_ctx *priv; handle_t h_qp = 0; handle_t h_ctx; __u32 i, j; @@ -1487,11 +1489,7 @@ static int hisi_zip_init(struct wd_alg_driver *drv, void *conf) return -WD_EINVAL; } - priv = malloc(sizeof(struct hisi_zip_ctx)); - if (!priv) - return -WD_EINVAL; - - memcpy(&priv->config, config, sizeof(struct wd_ctx_config_internal)); + memcpy(&zip_ctx->config, config, sizeof(struct wd_ctx_config_internal)); /* allocate qp for each context */ for (i = 0; i < config->ctx_num; i++) { h_ctx = config->ctxs[i].ctx; @@ -1509,7 +1507,6 @@ static int hisi_zip_init(struct wd_alg_driver *drv, void *conf) } hisi_zip_sqe_ops_adapt(h_qp); - drv->priv = priv; return 0; out: @@ -1517,28 +1514,20 @@ out: h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[j].ctx); hisi_qm_free_qp(h_qp); } - free(priv); return -WD_EINVAL; } -static void hisi_zip_exit(struct wd_alg_driver *drv) +static void hisi_zip_exit(void *priv) { - struct wd_ctx_config_internal *config; - struct hisi_zip_ctx *priv; + struct hisi_zip_ctx *zip_ctx = (struct hisi_zip_ctx *)priv; + struct wd_ctx_config_internal *config = &zip_ctx->config; handle_t h_qp; __u32 i; - if (!drv || !drv->priv) - return; - - priv = (struct hisi_zip_ctx *)drv->priv; - config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); hisi_qm_free_qp(h_qp); } - free(priv); - drv->priv = NULL; } static int fill_zip_comp_sqe(struct hisi_qp *qp, struct wd_comp_msg *msg, @@ -1593,7 +1582,7 @@ static int fill_zip_comp_sqe(struct hisi_qp *qp, struct wd_comp_msg *msg, return 0; } -static int hisi_zip_comp_send(struct wd_alg_driver *drv, handle_t ctx, void *comp_msg) +static int hisi_zip_comp_send(handle_t ctx, void *comp_msg) { struct hisi_qp *qp = wd_ctx_get_priv(ctx); struct wd_comp_msg *msg = comp_msg; @@ -1785,7 +1774,7 @@ static int parse_zip_sqe(struct hisi_qp *qp, struct hisi_zip_sqe *sqe, return 0; } -static int hisi_zip_comp_recv(struct wd_alg_driver *drv, handle_t ctx, void *comp_msg) +static int hisi_zip_comp_recv(handle_t ctx, void *comp_msg) { struct hisi_qp *qp = wd_ctx_get_priv(ctx); struct wd_comp_msg *recv_msg = comp_msg; @@ -1838,7 +1827,7 @@ static int hisi_zip_get_usage(void *param) return -WD_EINVAL; } - priv = (struct hisi_zip_ctx *)drv->priv; + priv = (struct hisi_zip_ctx *)drv->drv_data; if (!priv) return -WD_EACCES; @@ -1866,6 +1855,7 @@ static int hisi_zip_get_usage(void *param) .alg_name = (zip_alg_name),\ .calc_type = UADK_ALG_HW,\ .priority = 100,\ + .priv_size = sizeof(struct hisi_zip_ctx),\ .queue_num = ZIP_CTX_Q_NUM_DEF,\ .op_type_num = 2,\ .fallback = 0,\ @@ -1874,6 +1864,8 @@ static int hisi_zip_get_usage(void *param) .send = hisi_zip_comp_send,\ .recv = hisi_zip_comp_recv,\ .get_usage = hisi_zip_get_usage, \ + .alloc_ctx = wd_hw_alloc_ctx, \ + .free_ctx = wd_hw_free_ctx, \ } static struct wd_alg_driver zip_alg_driver[] = { diff --git a/wd_comp.c b/wd_comp.c index df32ea5..35af141 100644 --- a/wd_comp.c +++ b/wd_comp.c @@ -171,31 +171,24 @@ out_clear_ctx_config: return ret; } -static int wd_comp_uninit_nolock(void) +static void wd_comp_uninit_nolock(void) { - enum wd_status status; - - wd_alg_get_init(&wd_comp_setting.status, &status); - if (status == WD_UNINIT) - return -WD_EINVAL; - /* 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_alg_uninit_driver(&wd_comp_setting.config, - wd_comp_setting.driver); - - return 0; } int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) { + __u32 drv_count; int ret; - pthread_atfork(NULL, NULL, wd_comp_clear_status); + if (!wd_comp_atfork_registered) { + if (pthread_atfork(NULL, NULL, wd_comp_clear_status) == 0) + wd_comp_atfork_registered = true; + } ret = wd_alg_try_init(&wd_comp_setting.status); if (ret) @@ -213,10 +206,37 @@ int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) if (ret) goto out_clear_driver; + ret = wd_get_drv_array(WD_COMP_ALG_TYPE_V1, TASK_HW, "hisi_zip", + &wd_comp_setting.config.drv_array, &drv_count); + if (ret) { + WD_ERR("driver discovery failed!\n"); + goto out_uninit_nolock; + } + + wd_comp_setting.config.drv_count = drv_count; + wd_comp_setting.init_type = WD_TYPE_V1; + ret = wd_ctx_bind_drivers(&wd_comp_setting.config, NULL, WD_TYPE_V1); + if (ret) { + WD_ERR("driver binding failed!\n"); + goto out_free_drv_array; + } + + ret = wd_alg_init_driver(&wd_comp_setting.config); + if (ret) + goto out_unbind_drivers; + wd_alg_set_init(&wd_comp_setting.status); return 0; +out_unbind_drivers: + wd_ctx_unbind_drivers(&wd_comp_setting.config); +out_free_drv_array: + wd_put_drv_array(wd_comp_setting.config.drv_array, drv_count); + wd_comp_setting.config.drv_array = NULL; + wd_comp_setting.config.drv_count = 0; +out_uninit_nolock: + wd_comp_uninit_nolock(); out_clear_driver: wd_comp_close_driver(WD_TYPE_V1); out_clear_init: @@ -226,12 +246,21 @@ out_clear_init: void wd_comp_uninit(void) { - int ret; + enum wd_status status; - ret = wd_comp_uninit_nolock(); - if (ret) + wd_alg_get_init(&wd_comp_setting.status, &status); + if (status != WD_INIT) return; + wd_alg_uninit_driver(&wd_comp_setting.config); + wd_ctx_unbind_drivers(&wd_comp_setting.config); + + wd_put_drv_array(wd_comp_setting.config.drv_array, + wd_comp_setting.config.drv_count); + wd_comp_setting.config.drv_array = NULL; + wd_comp_setting.config.drv_count = 0; + + wd_comp_uninit_nolock(); wd_comp_close_driver(WD_TYPE_V1); wd_alg_clear_init(&wd_comp_setting.status); } @@ -241,9 +270,13 @@ int wd_comp_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_par struct wd_ctx_nums comp_ctx_num[WD_DIR_MAX] = {0}; struct wd_ctx_params comp_ctx_params = {0}; int state, ret = -WD_EINVAL; + int try_cnt = 0; bool flag; - pthread_atfork(NULL, NULL, wd_comp_clear_status); + if (!wd_comp_atfork_registered) { + if (pthread_atfork(NULL, NULL, wd_comp_clear_status) == 0) + wd_comp_atfork_registered = true; + } state = wd_alg_try_init(&wd_comp_setting.status); if (state) @@ -266,38 +299,33 @@ int wd_comp_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_par goto out_uninit; while (ret != 0) { - memset(&wd_comp_setting.config, 0, sizeof(struct wd_ctx_config_internal)); - - /* Get alg driver and dev name */ - wd_comp_setting.driver = wd_alg_drv_bind(task_type, alg); - if (!wd_comp_setting.driver) { - WD_ERR("failed to bind %s driver.\n", alg); + if (try_cnt++ >= WD_INIT2_MAX_RETRY) { + WD_ERR("failed to init2 after %d retries.\n", + WD_INIT2_MAX_RETRY); goto out_dlclose; } + memset(&wd_comp_setting.config, 0, sizeof(struct wd_ctx_config_internal)); + /* Init ctx param and prepare for ctx request */ comp_ctx_params.ctx_set_num = comp_ctx_num; ret = wd_ctx_param_init(&comp_ctx_params, ctx_params, - wd_comp_setting.driver, WD_COMP_TYPE, WD_DIR_MAX); + alg, WD_COMP_TYPE, WD_DIR_MAX); if (ret) { if (ret == -WD_EAGAIN) { - wd_disable_drv(wd_comp_setting.driver); - wd_alg_drv_unbind(wd_comp_setting.driver); continue; } - goto out_unbind_drv; + goto out_dlclose; } (void)strcpy(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.task_type = task_type; 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); wd_ctx_param_uninit(&comp_ctx_params); continue; } @@ -306,15 +334,31 @@ int wd_comp_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_par } } + wd_comp_setting.init_type = WD_TYPE_V2; + ret = wd_ctx_bind_drivers(&wd_comp_setting.config, + wd_comp_init_attrs.ctx_config_internal, + WD_TYPE_V2); + if (ret) { + WD_ERR("driver binding failed!\n"); + goto out_uninit_nolock; + } + + ret = wd_alg_init_driver(&wd_comp_setting.config); + if (ret) + goto out_unbind_drivers; + wd_alg_set_init(&wd_comp_setting.status); wd_ctx_param_uninit(&comp_ctx_params); - return 0; + return ret; +out_unbind_drivers: + wd_ctx_unbind_drivers(&wd_comp_setting.config); +out_uninit_nolock: + wd_comp_uninit_nolock(); + wd_alg_attrs_uninit(&wd_comp_init_attrs); out_params_uninit: wd_ctx_param_uninit(&comp_ctx_params); -out_unbind_drv: - wd_alg_drv_unbind(wd_comp_setting.driver); out_dlclose: wd_comp_close_driver(WD_TYPE_V2); out_uninit: @@ -324,14 +368,19 @@ out_uninit: void wd_comp_uninit2(void) { - int ret; + enum wd_status status; - ret = wd_comp_uninit_nolock(); - if (ret) + wd_alg_get_init(&wd_comp_setting.status, &status); + if (status != WD_INIT) return; + wd_alg_uninit_driver(&wd_comp_setting.config); + wd_ctx_unbind_drivers(&wd_comp_setting.config); + wd_comp_setting.config.drv_array = NULL; + wd_comp_setting.config.drv_count = 0; + wd_comp_uninit_nolock(); + wd_alg_attrs_uninit(&wd_comp_init_attrs); - wd_alg_drv_unbind(wd_comp_setting.driver); wd_comp_close_driver(WD_TYPE_V2); wd_alg_clear_init(&wd_comp_setting.status); } @@ -366,7 +415,7 @@ int wd_comp_poll_ctx(__u32 idx, __u32 expt, __u32 *count) ctx = config->ctxs + idx; do { - ret = wd_alg_driver_recv(wd_comp_setting.driver, ctx->ctx, &resp_msg); + ret = ctx->drv->recv(ctx->ctx, &resp_msg); if (unlikely(ret < 0)) { if (ret == -WD_HW_EACCESS) WD_ERR("wd comp recv hw error!\n"); @@ -397,6 +446,11 @@ int wd_comp_poll_ctx(__u32 idx, __u32 expt, __u32 *count) static int wd_comp_check_sess_params(struct wd_comp_sess_setup *setup) { + if (!setup) { + WD_ERR("invalid: setup is NULL!\n"); + return -WD_EINVAL; + } + if (setup->alg_type >= WD_COMP_ALG_MAX) { WD_ERR("invalid: alg_type is %u!\n", setup->alg_type); return -WD_EINVAL; @@ -443,12 +497,11 @@ static void wd_free_ctx_buf(struct wd_mm_ops *mm_ops, struct wd_comp_sess *sess) handle_t wd_comp_alloc_sess(struct wd_comp_sess_setup *setup) { + struct wd_sched_params params = {0}; + const char *target_alg_name; struct wd_comp_sess *sess; int ret; - if (!setup) - return (handle_t)0; - ret = wd_comp_check_sess_params(setup); if (ret) return (handle_t)0; @@ -457,6 +510,14 @@ handle_t wd_comp_alloc_sess(struct wd_comp_sess_setup *setup) if (!sess) return (handle_t)0; + target_alg_name = wd_comp_alg_name[setup->alg_type]; + + ret = wd_drv_alg_support(target_alg_name, &wd_comp_setting.config); + if (!ret) { + WD_ERR("failed to support algorithm: %s!\n", target_alg_name); + goto sess_err; + } + /* Memory type set */ ret = wd_mem_ops_init(wd_comp_setting.config.ctxs[0].ctx, &setup->mm_ops, setup->mm_type); if (ret) { @@ -472,6 +533,8 @@ handle_t wd_comp_alloc_sess(struct wd_comp_sess_setup *setup) sess->comp_lv = setup->comp_lv; sess->win_sz = setup->win_sz; sess->stream_pos = WD_COMP_STREAM_NEW; + sess->strm_ctx_fixed = false; + sess->strm_sync_ctx_idx = 0; sess->mm_type = setup->mm_type; memcpy(&sess->mm_ops, &setup->mm_ops, sizeof(struct wd_mm_ops)); @@ -484,6 +547,12 @@ handle_t wd_comp_alloc_sess(struct wd_comp_sess_setup *setup) goto sched_err; } + /* Set compat filtering parameters for session-ctx matching */ + params.alg_name = target_alg_name; + params.ctxs = wd_comp_setting.config.ctxs; + wd_comp_setting.sched.set_param(wd_comp_setting.sched.h_sched_ctx, + sess->sched_key, ¶ms); + return (handle_t)sess; sched_err: @@ -503,8 +572,14 @@ void wd_comp_free_sess(handle_t h_sess) if (sess->ctx_buf) wd_free_ctx_buf(&sess->mm_ops, sess); - if (sess->sched_key) - free(sess->sched_key); + if (sess->sched_key) { + if (wd_comp_setting.sched.sched_uninit) + wd_comp_setting.sched.sched_uninit( + wd_comp_setting.sched.h_sched_ctx, + (handle_t)sess->sched_key); + else + free(sess->sched_key); + } free(sess); } @@ -655,9 +730,23 @@ static int wd_comp_sync_job(struct wd_comp_sess *sess, __u32 idx; int ret; - idx = wd_comp_setting.sched.pick_next_ctx(h_sched_ctx, - sess->sched_key, - CTX_MODE_SYNC); + if (msg->stream_mode == WD_COMP_STATEFUL) { + if (!sess->strm_ctx_fixed) { + idx = wd_comp_setting.sched.pick_next_ctx(h_sched_ctx, + sess->sched_key, CTX_MODE_SYNC); + if (unlikely(idx >= config->ctx_num)) + return -WD_EINVAL; + + sess->strm_sync_ctx_idx = idx; + sess->strm_ctx_fixed = true; + } else { + idx = sess->strm_sync_ctx_idx; + } + } else { + idx = wd_comp_setting.sched.pick_next_ctx(h_sched_ctx, + sess->sched_key, CTX_MODE_SYNC); + } + ret = wd_check_ctx(config, CTX_MODE_SYNC, idx); if (unlikely(ret)) return ret; @@ -665,12 +754,12 @@ static int wd_comp_sync_job(struct wd_comp_sess *sess, wd_dfx_msg_cnt(config, WD_CTX_CNT_NUM, idx); ctx = config->ctxs + idx; - msg_handle.send = wd_comp_setting.driver->send; - msg_handle.recv = wd_comp_setting.driver->recv; + msg_handle.send = ctx->drv->send; + msg_handle.recv = ctx->drv->recv; pthread_spin_lock(&ctx->lock); - ret = wd_handle_msg_sync(wd_comp_setting.driver, &msg_handle, ctx->ctx, - msg, NULL, config->epoll_en); + ret = wd_handle_msg_sync(&msg_handle, ctx->ctx, msg, + NULL, config->epoll_en); pthread_spin_unlock(&ctx->lock); return ret; @@ -811,7 +900,6 @@ int wd_do_comp_strm(handle_t h_sess, struct wd_comp_req *req) msg.stream_mode = WD_COMP_STATEFUL; src_len = req->src_len; - ret = wd_comp_sync_job(sess, req, &msg); if (unlikely(ret)) return ret; @@ -860,13 +948,13 @@ int wd_do_comp_async(handle_t h_sess, struct wd_comp_req *req) tag = wd_get_msg_from_pool(&wd_comp_setting.pool, idx, (void **)&msg); if (unlikely(tag < 0)) { WD_ERR("failed to get msg from pool!\n"); - return tag; + return -WD_EBUSY; } fill_comp_msg(sess, msg, req); msg->tag = tag; msg->stream_mode = WD_COMP_STATELESS; - ret = wd_alg_driver_send(wd_comp_setting.driver, ctx->ctx, msg); + ret = ctx->drv->send(ctx->ctx, msg); if (unlikely(ret < 0)) { if (ret != -WD_EBUSY) WD_ERR("wd comp send error, ret = %d!\n", ret); diff --git a/wd_zlibwrapper.c b/wd_zlibwrapper.c index 8f32f0f..92e1f1a 100644 --- a/wd_zlibwrapper.c +++ b/wd_zlibwrapper.c @@ -39,6 +39,8 @@ enum alg_win_bits { static pthread_mutex_t wd_zlib_mutex = PTHREAD_MUTEX_INITIALIZER; static int zlib_status; +static bool wd_zlib_atfork_registered; + static void wd_zlib_unlock(void) { zlib_status = WD_ZLIB_UNINIT; @@ -236,7 +238,10 @@ static int wd_zlib_do_request(z_streamp strm, int flush, enum wd_comp_op_type ty /* === Compression === */ int wd_deflate_init(z_streamp strm, int level, int windowbits) { - pthread_atfork(NULL, NULL, wd_zlib_unlock); + if (!wd_zlib_atfork_registered) { + if (pthread_atfork(NULL, NULL, wd_zlib_unlock) == 0) + wd_zlib_atfork_registered = true; + } return wd_zlib_init(strm, level, windowbits, WD_DIR_COMPRESS); } @@ -270,7 +275,10 @@ int wd_deflate_end(z_streamp strm) /* === Decompression === */ int wd_inflate_init(z_streamp strm, int windowbits) { - pthread_atfork(NULL, NULL, wd_zlib_unlock); + if (!wd_zlib_atfork_registered) { + if (pthread_atfork(NULL, NULL, wd_zlib_unlock) == 0) + wd_zlib_atfork_registered = true; + } return wd_zlib_init(strm, 0, windowbits, WD_DIR_DECOMPRESS); } -- 2.43.0