[PATCH 1/8] uadk: support get device usage
From: Weili Qian <qianweili@huawei.com> UADK adds the ability to obtain device usage. When the device is not bound to a driver, it retrieves the usage through sysfs files. When the device is bound to a driver, it directly reads the hardware registers to obtain the usage. Upstream: Yes AR: AR20230722287656 Feature or Bugfix: Feature Signed-off-by: Weili Qian <qianweili@huawei.com> --- drv/hisi_comp.c | 39 +++++++++ drv/hisi_dae.c | 5 -- drv/hisi_dae.h | 1 + drv/hisi_dae_common.c | 38 +++++++++ drv/hisi_dae_join_gather.c | 1 + drv/hisi_hpre.c | 69 ++++++++++++++-- drv/hisi_qm_udrv.c | 36 +++++++++ drv/hisi_qm_udrv.h | 1 + drv/hisi_sec.c | 35 +++++++- drv/hisi_udma.c | 35 +++++++- include/wd.h | 8 ++ include/wd_alg.h | 9 +++ libwd.map | 3 + wd.c | 162 +++++++++++++++++++++++++++++++++++++ wd_alg.c | 124 ++++++++++++++++++++++++++++ wd_util.c | 93 ++------------------- 16 files changed, 560 insertions(+), 99 deletions(-) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 65dcf8e..cad21fa 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -1755,6 +1755,44 @@ static int hisi_zip_comp_recv(struct wd_alg_driver *drv, handle_t ctx, void *com return 0; } +static int hisi_zip_get_usage(void *param) +{ + struct hisi_dev_usage *zip_usage = (struct hisi_dev_usage *)param; + struct wd_alg_driver *drv = zip_usage->drv; + struct wd_ctx_config_internal *config; + struct hisi_zip_ctx *priv; + char *ctx_dev_name; + handle_t ctx = 0; + handle_t qp = 0; + __u32 i; + + if (zip_usage->alg_op_type >= drv->op_type_num) { + WD_ERR("invalid: alg_op_type %u is error!\n", zip_usage->alg_op_type); + return -WD_EINVAL; + } + + priv = (struct hisi_zip_ctx *)drv->priv; + if (!priv) + return -WD_EACCES; + + config = &priv->config; + for (i = 0; i < config->ctx_num; i++) { + ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx); + if (!strcmp(zip_usage->dev_name, ctx_dev_name)) { + ctx = config->ctxs[i].ctx; + break; + } + } + + if (ctx) + qp = (handle_t)wd_ctx_get_priv(ctx); + + if (qp) + return hisi_qm_get_usage(qp, zip_usage->alg_op_type); + + return -WD_EACCES; +} + #define GEN_ZIP_ALG_DRIVER(zip_alg_name) \ {\ .drv_name = "hisi_zip",\ @@ -1768,6 +1806,7 @@ static int hisi_zip_comp_recv(struct wd_alg_driver *drv, handle_t ctx, void *com .exit = hisi_zip_exit,\ .send = hisi_zip_comp_send,\ .recv = hisi_zip_comp_recv,\ + .get_usage = hisi_zip_get_usage, \ } static struct wd_alg_driver zip_alg_driver[] = { diff --git a/drv/hisi_dae.c b/drv/hisi_dae.c index 49387aa..d7b34c2 100644 --- a/drv/hisi_dae.c +++ b/drv/hisi_dae.c @@ -1283,11 +1283,6 @@ static int agg_hash_table_init(struct wd_alg_driver *drv, hash_table, agg_ctx->row_size); } -static int dae_get_usage(void *param) -{ - return 0; -} - static int dae_get_extend_ops(void *ops) { struct wd_agg_ops *agg_ops = (struct wd_agg_ops *)ops; diff --git a/drv/hisi_dae.h b/drv/hisi_dae.h index 050b872..f82b13c 100644 --- a/drv/hisi_dae.h +++ b/drv/hisi_dae.h @@ -220,6 +220,7 @@ int get_free_ext_addr(struct dae_extend_addr *ext_addr); void put_ext_addr(struct dae_extend_addr *ext_addr, int idx); __u32 get_data_type_size(enum dae_data_type type, __u16 data_info); int dae_decimal_precision_check(__u16 data_info, bool longdecimal); +int dae_get_usage(void *param); #ifdef __cplusplus } diff --git a/drv/hisi_dae_common.c b/drv/hisi_dae_common.c index 5cfc105..c077d1d 100644 --- a/drv/hisi_dae_common.c +++ b/drv/hisi_dae_common.c @@ -389,3 +389,41 @@ void dae_exit(struct wd_alg_driver *drv) free(priv); drv->priv = NULL; } + +int dae_get_usage(void *param) +{ + struct hisi_dev_usage *dae_usage = (struct hisi_dev_usage *)param; + struct wd_alg_driver *drv = dae_usage->drv; + struct wd_ctx_config_internal *config; + struct hisi_dae_ctx *priv; + char *ctx_dev_name; + handle_t ctx = 0; + handle_t qp = 0; + __u32 i; + + if (dae_usage->alg_op_type >= drv->op_type_num) { + WD_ERR("invalid: alg_op_type %u is error!\n", dae_usage->alg_op_type); + return -WD_EINVAL; + } + + priv = (struct hisi_dae_ctx *)drv->priv; + if (!priv) + return -WD_EACCES; + + config = &priv->config; + for (i = 0; i < config->ctx_num; i++) { + ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx); + if (!strcmp(dae_usage->dev_name, ctx_dev_name)) { + ctx = config->ctxs[i].ctx; + break; + } + } + + if (ctx) + qp = (handle_t)wd_ctx_get_priv(ctx); + + if (qp) + return hisi_qm_get_usage(qp, DAE_SQC_ALG_TYPE); + + return -WD_EACCES; +} diff --git a/drv/hisi_dae_join_gather.c b/drv/hisi_dae_join_gather.c index 63c7670..92fae1a 100644 --- a/drv/hisi_dae_join_gather.c +++ b/drv/hisi_dae_join_gather.c @@ -1007,6 +1007,7 @@ static int join_gather_get_extend_ops(void *ops) .send = join_gather_send,\ .recv = join_gather_recv,\ .get_extend_ops = join_gather_get_extend_ops,\ + .get_usage = dae_get_usage,\ } static struct wd_alg_driver join_gather_driver[] = { diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index f3f2451..3c41826 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -2777,9 +2777,68 @@ static int ecc_recv(struct wd_alg_driver *drv, handle_t ctx, void *ecc_msg) return ecc_sqe_parse((struct hisi_qp *)h_qp, msg, &hw_msg); } -static int hpre_get_usage(void *param) +static handle_t hpre_find_dev_qp(struct wd_alg_driver *drv, const char *dev_name) { - return WD_SUCCESS; + struct wd_ctx_config_internal *config; + struct hisi_hpre_ctx *priv; + char *ctx_dev_name; + handle_t ctx = 0; + handle_t qp = 0; + __u32 i; + + priv = (struct hisi_hpre_ctx *)drv->priv; + if (!priv) + return 0; + + config = &priv->config; + for (i = 0; i < config->ctx_num; i++) { + ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx); + if (!strcmp(ctx_dev_name, dev_name)) { + ctx = config->ctxs[i].ctx; + break; + } + } + + if (ctx) + qp = (handle_t)wd_ctx_get_priv(ctx); + + return qp; +} + +static int hpre_ecc_get_usage(void *param) +{ + struct hisi_dev_usage *hpre_usage = (struct hisi_dev_usage *)param; + struct wd_alg_driver *drv = hpre_usage->drv; + handle_t qp; + + if (hpre_usage->alg_op_type >= drv->op_type_num) { + WD_ERR("invalid: alg_op_type %u is error!\n", hpre_usage->alg_op_type); + return -WD_EINVAL; + } + + qp = hpre_find_dev_qp(drv, hpre_usage->dev_name); + if (qp) + return hisi_qm_get_usage(qp, HPRE_HW_V3_ECC_ALG_TYPE); + + return -WD_EACCES; +} + +static int hpre_rsa_get_usage(void *param) +{ + struct hisi_dev_usage *hpre_usage = (struct hisi_dev_usage *)param; + struct wd_alg_driver *drv = hpre_usage->drv; + handle_t qp; + + if (hpre_usage->alg_op_type >= drv->op_type_num) { + WD_ERR("invalid: alg_op_type %u is error!\n", hpre_usage->alg_op_type); + return -WD_EINVAL; + } + + qp = hpre_find_dev_qp(drv, hpre_usage->dev_name); + if (qp) + return hisi_qm_get_usage(qp, HPRE_HW_V2_ALG_TYPE); + + return -WD_EACCES; } static int ecc_sess_eops_init(struct wd_alg_driver *drv, void **params) @@ -2886,7 +2945,7 @@ static int hpre_ecc_get_extend_ops(void *ops) .exit = hpre_exit,\ .send = ecc_send,\ .recv = ecc_recv,\ - .get_usage = hpre_get_usage,\ + .get_usage = hpre_ecc_get_usage,\ .get_extend_ops = hpre_ecc_get_extend_ops,\ } @@ -2910,7 +2969,7 @@ static struct wd_alg_driver hpre_rsa_driver = { .exit = hpre_exit, .send = rsa_send, .recv = rsa_recv, - .get_usage = hpre_get_usage, + .get_usage = hpre_rsa_get_usage, }; static struct wd_alg_driver hpre_dh_driver = { @@ -2925,7 +2984,7 @@ static struct wd_alg_driver hpre_dh_driver = { .exit = hpre_exit, .send = dh_send, .recv = dh_recv, - .get_usage = hpre_get_usage, + .get_usage = hpre_rsa_get_usage, }; #ifdef WD_STATIC_DRV diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c index 216b80a..4ddf8a8 100644 --- a/drv/hisi_qm_udrv.c +++ b/drv/hisi_qm_udrv.c @@ -42,6 +42,12 @@ #define ADDR_ALIGN_64(addr) ((((uintptr_t)(addr) >> 6) + 1) << 6) +#define QM_TYPE_USAGE_OFFSET 0x1100 +#define QM_DEV_USAGE_OFFSET 16 +#define QM_CHANNEL_ADDR_INTRVL 0x4 +#define QM_MAX_DEV_USAGE 100 +#define QM_DEV_USAGE_RATE 100 + struct hisi_qm_type { __u16 qm_ver; int qm_db_offs; @@ -154,6 +160,36 @@ static struct hisi_qm_type qm_type[] = { } }; +int hisi_qm_get_usage(handle_t h_qp, __u8 type) +{ + struct hisi_qp *qp = (struct hisi_qp *)h_qp; + struct hisi_qm_queue_info *q_info; + __u16 count, usage; + __u32 val; + + if (!qp) + return -WD_EINVAL; + + q_info = &qp->q_info; + if (q_info->hw_type < HISI_QM_API_VER5_BASE) { + WD_ERR("invalid: device not support get usage!\n"); + return -WD_EINVAL; + } + + val = wd_ioread32(q_info->mmio_base + QM_TYPE_USAGE_OFFSET + + type * QM_CHANNEL_ADDR_INTRVL); + count = val >> QM_DEV_USAGE_OFFSET; + if (!count) { + WD_ERR("failed to get dev count usage!\n"); + return -WD_EINVAL; + } + + usage = (__u16)val * QM_DEV_USAGE_RATE / count; + usage = usage > QM_MAX_DEV_USAGE ? QM_MAX_DEV_USAGE : usage; + + return usage; +} + static void hisi_qm_fill_sqe(const void *sqe, struct hisi_qm_queue_info *info, __u16 tail, __u16 num) { diff --git a/drv/hisi_qm_udrv.h b/drv/hisi_qm_udrv.h index f066881..a7222ce 100644 --- a/drv/hisi_qm_udrv.h +++ b/drv/hisi_qm_udrv.h @@ -210,6 +210,7 @@ int hisi_qm_get_free_sqe_num(handle_t h_qp); */ __u32 hisi_qm_get_list_size(struct wd_datalist *start_node, struct wd_datalist *end_node); +int hisi_qm_get_usage(handle_t h_qp, __u8 type); #ifdef __cplusplus } diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index e64fd5c..53bf334 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -600,7 +600,40 @@ static int aead_recv(struct wd_alg_driver *drv, handle_t ctx, void *msg) static int hisi_sec_get_usage(void *param) { - return 0; + struct hisi_dev_usage *sec_usage = (struct hisi_dev_usage *)param; + struct wd_alg_driver *drv = sec_usage->drv; + struct wd_ctx_config_internal *config; + struct hisi_sec_ctx *priv; + char *ctx_dev_name; + handle_t ctx = 0; + handle_t qp = 0; + __u32 i; + + if (sec_usage->alg_op_type >= drv->op_type_num) { + WD_ERR("invalid: alg_op_type %u is error!\n", sec_usage->alg_op_type); + return -WD_EINVAL; + } + + priv = (struct hisi_sec_ctx *)drv->priv; + if (!priv) + return -WD_EACCES; + + config = &priv->config; + for (i = 0; i < config->ctx_num; i++) { + ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx); + if (!strcmp(sec_usage->dev_name, ctx_dev_name)) { + ctx = config->ctxs[i].ctx; + break; + } + } + + if (ctx) + qp = (handle_t)wd_ctx_get_priv(ctx); + + if (qp) + return hisi_qm_get_usage(qp, 0); + + return -WD_EACCES; } static int eops_param_check(struct wd_alg_driver *drv, struct wd_mm_ops *mm_ops) diff --git a/drv/hisi_udma.c b/drv/hisi_udma.c index 37f0550..a9f5607 100644 --- a/drv/hisi_udma.c +++ b/drv/hisi_udma.c @@ -521,7 +521,40 @@ static void udma_exit(struct wd_alg_driver *drv) static int udma_get_usage(void *param) { - return 0; + struct hisi_dev_usage *udma_usage = (struct hisi_dev_usage *)param; + struct wd_alg_driver *drv = udma_usage->drv; + struct wd_ctx_config_internal *config; + struct hisi_udma_ctx *priv; + char *ctx_dev_name; + handle_t ctx = 0; + handle_t qp = 0; + __u32 i; + + if (udma_usage->alg_op_type >= drv->op_type_num) { + WD_ERR("invalid: alg_op_type %u is error!\n", udma_usage->alg_op_type); + return -WD_EINVAL; + } + + priv = (struct hisi_udma_ctx *)drv->priv; + if (!priv) + return -WD_EACCES; + + config = &priv->config; + for (i = 0; i < config->ctx_num; i++) { + ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx); + if (!strcmp(udma_usage->dev_name, ctx_dev_name)) { + ctx = config->ctxs[i].ctx; + break; + } + } + + if (ctx) + qp = (handle_t)wd_ctx_get_priv(ctx); + + if (qp) + return hisi_qm_get_usage(qp, UDMA_ALG_TYPE); + + return -WD_EACCES; } static struct wd_alg_driver udma_driver = { diff --git a/include/wd.h b/include/wd.h index b97e5c7..abc745d 100644 --- a/include/wd.h +++ b/include/wd.h @@ -627,6 +627,14 @@ struct wd_capability { struct wd_capability *wd_get_alg_cap(void); void wd_release_alg_cap(struct wd_capability *head); +/** + * wd_get_dev_usage() - Get the device bandwidth usage. + * @dev: Indicate device. + * @alg_name: Indicates the intention to query the bandwidth usage of the algorithm on the device. + * @alg_op_type: algorithm type. + */ +int wd_get_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_type); + #ifdef __cplusplus } #endif diff --git a/include/wd_alg.h b/include/wd_alg.h index 5ff73ca..878c595 100644 --- a/include/wd_alg.h +++ b/include/wd_alg.h @@ -115,6 +115,12 @@ struct wd_alg_driver { int (*get_extend_ops)(void *ops); }; +struct hisi_dev_usage { + struct wd_alg_driver *drv; + char *dev_name; + __u8 alg_op_type; +}; + /* * wd_alg_driver_register() - Register a device driver. * @wd_alg_driver: a device driver that supports an algorithm. @@ -145,6 +151,7 @@ struct wd_alg_list { struct wd_alg_driver *drv; struct wd_alg_list *next; + char alg_type[ALG_NAME_SIZE]; }; /* @@ -178,6 +185,8 @@ int wd_alg_driver_init(struct wd_alg_driver *drv, void *conf); void wd_alg_driver_exit(struct wd_alg_driver *drv); int wd_alg_driver_send(struct wd_alg_driver *drv, handle_t ctx, void *msg); int wd_alg_driver_recv(struct wd_alg_driver *drv, handle_t ctx, void *msg); +int wd_alg_get_dev_usage(const char *dev_name, const char *alg_type, __u8 op_type); +int wd_get_alg_type(const char *alg_name, char *alg_type); struct wd_alg_list *wd_get_alg_head(void); diff --git a/libwd.map b/libwd.map index 90eb5c5..1267a8d 100644 --- a/libwd.map +++ b/libwd.map @@ -22,6 +22,7 @@ global: wd_ctx_set_io_cmd; wd_ctx_get_region_size; wd_ctx_get_dev_name; + wd_get_dev_usage; wd_block_alloc; wd_block_free; @@ -53,6 +54,8 @@ global: wd_alg_driver_exit; wd_alg_driver_send; wd_alg_driver_recv; + wd_alg_get_dev_usage; + wd_get_alg_type; wd_find_ctx; wd_get_dev_id; diff --git a/wd.c b/wd.c index 657fbae..7f26f84 100644 --- a/wd.c +++ b/wd.c @@ -23,6 +23,7 @@ #include "wd_internal.h" #define SYS_CLASS_DIR "/sys/class/uacce" #define FILE_MAX_SIZE (8 << 20) +#define WD_DEV_USAGE_SIZE 256 enum UADK_LOG_LEVEL { WD_LOG_NONE = 0, @@ -34,6 +35,27 @@ enum UADK_LOG_LEVEL { static int uadk_log_level = WD_LOG_INVALID; +struct dev_usage_info { + char *dev_name; + __u8 alg_op_type; + int (*usage_parse_fn)(char *buf, const char *alg_name, __u8 alg_op_type); +}; + +static const char * const hpre_ecc_algs[] = { + "sm2", + "ecdh", + "x448", + "x25519", + "ecdsa" +}; + +static const char * const zip_dae_algs[] = { + "udma", + "hashagg", + "hashjoin", + "gather", +}; + static int wd_check_ctx_type(handle_t h_ctx) { struct wd_ctx_h *ctx = (struct wd_ctx_h *)h_ctx; @@ -986,3 +1008,143 @@ alloc_err: return NULL; } +static int wd_parse_usage_value(char *buf, const char *type_name) +{ + char *str; + int ret; + + str = strstr(buf, type_name); + if (!str) + return -WD_EINVAL; + + str += strlen(type_name); + ret = strtol(str, NULL, 10); + if (ret < 0) + WD_ERR("fail to get device usage value, ret %d!\n", ret); + + return ret; +} + +/* + * The format of the string obtained from sysfs is fixed + * and does not need to consider other scenarios. + */ +static int wd_zip_usage_parse_fn(char *buf, const char *alg_name, __u8 alg_op_type) +{ + size_t size = ARRAY_SIZE(zip_dae_algs); + size_t i; + + for (i = 0; i < size; i++) { + if (!strcmp(alg_name, zip_dae_algs[i])) { + if (alg_op_type != 0) { + WD_ERR("invalid: alg_name %s alg_op_type error!\n", alg_name); + return -WD_EINVAL; + } + return wd_parse_usage_value(buf, "DAE: "); + } + } + + if (alg_op_type == 0) + return wd_parse_usage_value(buf, "COMPRESS: "); + + return wd_parse_usage_value(buf, "DECOMPRESS: "); +} + +static int wd_sec_usage_parse_fn(char *buf, const char *alg_name, __u8 alg_op_type) +{ + return wd_parse_usage_value(buf, "SEC: "); +} + +static int wd_hpre_usage_parse_fn(char *buf, const char *alg_name, __u8 alg_op_type) +{ + size_t size = ARRAY_SIZE(hpre_ecc_algs); + size_t i; + + for (i = 0; i < size; i++) { + if (!strcmp(alg_name, hpre_ecc_algs[i])) + return wd_parse_usage_value(buf, "ECC: "); + } + + return wd_parse_usage_value(buf, "RSA: "); +} + +static const struct dev_usage_info dev_usage_parse[] = { + { + .dev_name = "hisi_zip", + .alg_op_type = 2, + .usage_parse_fn = wd_zip_usage_parse_fn + }, { + .dev_name = "hisi_sec", + .alg_op_type = 1, + .usage_parse_fn = wd_sec_usage_parse_fn + }, { + .dev_name = "hisi_hpre", + .alg_op_type = 1, + .usage_parse_fn = wd_hpre_usage_parse_fn + }, +}; + +static int wd_parse_dev_usage(struct uacce_dev *dev, char *buf, + const char *alg_name, __u8 alg_op_type) +{ + size_t size = ARRAY_SIZE(dev_usage_parse); + size_t i; + + for (i = 0; i < size; i++) { + if (strstr(dev->dev_root, dev_usage_parse[i].dev_name)) + break; + } + + if (i == size) { + WD_ERR("failed to find parse function!\n"); + return -WD_EINVAL; + } + + if (alg_op_type >= dev_usage_parse[i].alg_op_type) { + WD_ERR("invalid: alg_op_type %u is error!\n", alg_op_type); + return -WD_EINVAL; + } + + return dev_usage_parse[i].usage_parse_fn(buf, alg_name, alg_op_type); +} + +static int wd_read_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_type) +{ + char buf[WD_DEV_USAGE_SIZE]; + int ret; + + ret = access_attr(dev->dev_root, "dev_usage", F_OK); + if (ret) { + WD_ERR("failed to access dev_usage!\n"); + return ret; + } + + ret = get_str_attr(dev, "dev_usage", buf, WD_DEV_USAGE_SIZE); + if (ret < 0) + return ret; + + return wd_parse_dev_usage(dev, buf, alg_name, alg_op_type); +} + +int wd_get_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_type) +{ + char *dev_name; + int ret; + + if (!dev || !alg_name) { + WD_ERR("invalid: dev or alg name is NULL!\n"); + return -WD_EINVAL; + } + + if (!dev_has_alg(dev->algs, alg_name)) { + WD_ERR("invalid: dev does not support alg %s!\n", alg_name); + return -WD_EINVAL; + } + + dev_name = wd_get_accel_name(dev->char_dev_path, 0); + ret = wd_alg_get_dev_usage(dev_name, alg_name, alg_op_type); + if (ret == -WD_EACCES) + return wd_read_dev_usage(dev, alg_name, alg_op_type); + + return ret; +} diff --git a/wd_alg.c b/wd_alg.c index 9c7c0fd..c819d32 100644 --- a/wd_alg.c +++ b/wd_alg.c @@ -24,6 +24,97 @@ static struct wd_alg_list *alg_list_tail = &alg_list_head; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +struct acc_alg_item { + const char *name; + const char *algtype; +}; + +static struct acc_alg_item alg_options[] = { + {"zlib", "zlib"}, + {"gzip", "gzip"}, + {"deflate", "deflate"}, + {"lz77_zstd", "lz77_zstd"}, + {"lz4", "lz4"}, + {"lz77_only", "lz77_only"}, + {"hashagg", "hashagg"}, + {"udma", "udma"}, + {"hashjoin", "hashjoin"}, + {"gather", "gather"}, + {"join-gather", "hashjoin"}, + + {"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(generic,cbc(aes))", "aead"}, + {"authenc(generic,cbc(sm4))", "aead"}, + + {"sm3", "digest"}, + {"md5", "digest"}, + {"sha1", "digest"}, + {"sha256", "digest"}, + {"sha224", "digest"}, + {"sha384", "digest"}, + {"sha512", "digest"}, + {"sha512-224", "digest"}, + {"sha512-256", "digest"}, + {"cmac(aes)", "digest"}, + {"gmac(aes)", "digest"}, + {"xcbc-mac-96(aes)", "digest"}, + {"xcbc-prf-128(aes)", "digest"}, + {"", ""} +}; + +int wd_get_alg_type(const char *alg_name, char *alg_type) +{ + __u64 i; + + if (!alg_name || !alg_type) { + WD_ERR("invalid: alg_name or alg_type is NULL!\n"); + return -WD_EINVAL; + } + + 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); + return 0; + } + } + + return -WD_EINVAL; +} + static bool wd_check_accel_dev(const char *dev_name) { struct dirent *dev_dir; @@ -182,6 +273,7 @@ int wd_alg_driver_register(struct wd_alg_driver *drv) return -WD_ENOMEM; } + (void)wd_get_alg_type(drv->alg_name, new_alg->alg_type); strncpy(new_alg->alg_name, drv->alg_name, ALG_NAME_SIZE - 1); strncpy(new_alg->drv_name, drv->drv_name, DEV_NAME_LEN - 1); new_alg->priority = drv->priority; @@ -393,3 +485,35 @@ int wd_alg_driver_recv(struct wd_alg_driver *drv, handle_t ctx, void *msg) return drv->recv(drv, ctx, msg); } +int wd_alg_get_dev_usage(const char *dev_name, const char *alg_type, __u8 alg_op_type) +{ + struct wd_alg_list *pnext = alg_list_head.next; + struct hisi_dev_usage dev_usage; + struct wd_alg_driver *drv; + + if (!dev_name || !alg_type) { + WD_ERR("dev_name or alg_type is NULL!\n"); + return -WD_EINVAL; + } + + while (pnext) { + if (strstr(dev_name, pnext->drv_name) && + !strcmp(alg_type, pnext->alg_type)) + break; + + pnext = pnext->next; + } + + if (!pnext) + return -WD_EACCES; + + drv = pnext->drv; + if (!drv->get_usage) + return -WD_EINVAL; + + dev_usage.drv = drv; + dev_usage.alg_op_type = alg_op_type; + dev_usage.dev_name = dev_name; + + return drv->get_usage(&dev_usage); +} diff --git a/wd_util.c b/wd_util.c index daa7309..bec23f5 100644 --- a/wd_util.c +++ b/wd_util.c @@ -98,78 +98,6 @@ struct drv_lib_list { struct drv_lib_list *next; }; -struct acc_alg_item { - const char *name; - const char *algtype; -}; - -static struct acc_alg_item alg_options[] = { - {"zlib", "zlib"}, - {"gzip", "gzip"}, - {"deflate", "deflate"}, - {"lz77_zstd", "lz77_zstd"}, - {"lz4", "lz4"}, - {"lz77_only", "lz77_only"}, - {"hashagg", "hashagg"}, - {"udma", "udma"}, - {"hashjoin", "hashjoin"}, - {"gather", "gather"}, - {"join-gather", "hashjoin"}, - - {"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(generic,cbc(aes))", "aead"}, - {"authenc(generic,cbc(sm4))", "aead"}, - - {"sm3", "digest"}, - {"md5", "digest"}, - {"sha1", "digest"}, - {"sha256", "digest"}, - {"sha224", "digest"}, - {"sha384", "digest"}, - {"sha512", "digest"}, - {"sha512-224", "digest"}, - {"sha512-256", "digest"}, - {"cmac(aes)", "digest"}, - {"gmac(aes)", "digest"}, - {"xcbc-mac-96(aes)", "digest"}, - {"xcbc-prf-128(aes)", "digest"}, - {"", ""} -}; - static void *wd_internal_alloc(void *usr, size_t size) { if (size != 0) @@ -2013,18 +1941,6 @@ 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) -{ - __u64 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; - } - } -} - static int wd_alg_init_fallback(struct wd_alg_driver *fb_driver) { if (!fb_driver->init) { @@ -2175,7 +2091,7 @@ static int wd_env_set_ctx_nums(const char *alg_name, const char *name, const cha char *left, *section, *start; struct uacce_dev_list *list; int is_comp; - int ret = 0; + int ret; /* COMP environment variable's format is different, mark it */ is_comp = strncmp(name, "WD_COMP_CTX_NUM", strlen(name)) ? 0 : 1; @@ -2186,7 +2102,9 @@ static int wd_env_set_ctx_nums(const char *alg_name, const char *name, const cha if (!start) return -WD_ENOMEM; - wd_get_alg_type(alg_name, alg_type); + ret = wd_get_alg_type(alg_name, alg_type); + if (ret) + return ret; list = wd_get_accel_list(alg_type); if (!list) { WD_ERR("failed to get devices!\n"); @@ -3098,7 +3016,8 @@ int wd_alg_attrs_init(struct wd_init_attrs *attrs) } break; case UADK_ALG_HW: - wd_get_alg_type(alg, alg_type); + if (wd_get_alg_type(alg, alg_type)) + return -WD_EINVAL; (void)strcpy(attrs->alg, alg_type); ctx_config = calloc(1, sizeof(*ctx_config)); -- 2.33.0
From: lizhi <lizhi206@huawei.com> Uadk supports obtaining device bandwidth usage through device name, algorithm name, and op_type. Upstream: Yes AR: AR20230722287656 Feature or Bugfix: Feature Signed-off-by: lizhi <lizhi206@huawei.com> --- uadk_tool/dfx/uadk_dfx.c | 96 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/uadk_tool/dfx/uadk_dfx.c b/uadk_tool/dfx/uadk_dfx.c index a344082..2734723 100644 --- a/uadk_tool/dfx/uadk_dfx.c +++ b/uadk_tool/dfx/uadk_dfx.c @@ -17,6 +17,12 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define PRIVILEGE_FLAG 0666 +enum dfx_usage_type { + DISPLAY_DEVICE = 0, + DISPLAY_ALG_NAME, + DISPLAY_OP_TYPE +}; + struct uadk_env_var { const char *module; const char *alg; @@ -37,6 +43,7 @@ enum dfx_op_type { DISPLAY_DIR, DISPLAY_ENV, DISPLAY_COUNT, + DISPLAY_USAGE, DISPLAY_HELP, }; @@ -177,6 +184,77 @@ static void uadk_exe_path(void) printf("exe path: %s\n", dir); } +static void uadk_dev_usage_read(int argc, char *argv[]) +{ + char device[64] = "hisi_sec2-0"; + char alg_name[256] = "cipher"; + struct uacce_dev_list *list; + struct uacce_dev_list *tmp = NULL; + struct uacce_dev *dev = NULL; + int option_index = 0; + int op_type = 0, ret; + char *dev_name; + int opt; + + static struct option long_options[] = { + {"device", required_argument, 0, 0}, + {"alg_name", required_argument, 0, 1}, + {"op_type", required_argument, 0, 2}, + {0, 0, 0, 0} + }; + + while (1) { + opt = getopt_long(argc, argv, "", long_options, &option_index); + if (opt == -1) + break; + + switch (opt) { + case DISPLAY_DEVICE: + strcpy(device, optarg); + break; + case DISPLAY_ALG_NAME: + strcpy(alg_name, optarg); + break; + case DISPLAY_OP_TYPE: + op_type = strtol(optarg, NULL, 0); + break; + default: + printf("bad input parameter, exit!\n"); + return; + } + } + + list = wd_get_accel_list(alg_name); + if (!list) { + printf("no device support alg_name %s, exit!\n", alg_name); + return; + } + + for (tmp = list; tmp != NULL; tmp = tmp->next) { + dev_name = strrchr(tmp->dev->dev_root, '/') + 1; + if (!strcmp(dev_name, device)) { + dev = tmp->dev; + break; + } + } + + if (!dev) { + printf("no device name is %s, exit!\n", device); + goto free_list; + } + + ret = wd_get_dev_usage(dev, alg_name, op_type); + if (ret < 0) { + printf("failed to get usage ret %d!\n", ret); + goto free_list; + } + + printf("%s %s op type %d usage is %d\n", device, alg_name, op_type, ret); + +free_list: + wd_free_list_accels(list); +} + void print_dfx_help(void) { printf("NAME\n"); @@ -205,6 +283,7 @@ void dfx_cmd_parse(int argc, char *argv[]) {"dir", no_argument, 0, DISPLAY_DIR}, {"env", required_argument, 0, DISPLAY_ENV}, {"count", no_argument, 0, DISPLAY_COUNT}, + {"usage", no_argument, 0, DISPLAY_USAGE}, {"help", no_argument, 0, DISPLAY_HELP}, {0, 0, 0, 0} }; @@ -212,15 +291,15 @@ void dfx_cmd_parse(int argc, char *argv[]) while (1) { opt = getopt_long(argc, argv, "", long_options, &option_index); if (opt == -1) - break; + return; switch (opt) { case DISPLAY_VERSION: wd_get_version(); - break; + return; case DISPLAY_DIR: uadk_exe_path(); - break; + return; case DISPLAY_ENV: input_module = optarg; check_module = uadk_check_module(input_module); @@ -230,17 +309,20 @@ void dfx_cmd_parse(int argc, char *argv[]) print_dfx_help(); printf("failed to parse module parameter!\n"); } - break; + return; case DISPLAY_COUNT: uadk_shared_read(); - break; + return; + case DISPLAY_USAGE: + uadk_dev_usage_read(argc, argv); + return; case DISPLAY_HELP: print_dfx_help(); - break; + return; default: printf("bad input parameter, exit!\n"); print_dfx_help(); - break; + return; } } } -- 2.33.0
From: lizhi <lizhi206@huawei.com> When the last line of the algorithm name matches, the lack of a newline character will cause the algorithm match to fail. Therefore, only check the terminator. Upstream: Yes AR: AR20230722287656 Feature or Bugfix: Feature Signed-off-by: lizhi <lizhi206@huawei.com> --- wd.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/wd.c b/wd.c index 7f26f84..c7dfc10 100644 --- a/wd.c +++ b/wd.c @@ -1126,22 +1126,42 @@ static int wd_read_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 a return wd_parse_dev_usage(dev, buf, alg_name, alg_op_type); } +static bool check_dev_alg_name(const char *dev_algs, const char *alg_name) +{ + char *str; + + str = strstr(dev_algs, alg_name); + if (!str) + return false; + + if (*(str + strlen(alg_name)) == '\n' || + *(str + strlen(alg_name)) == '\0') + return true; + + return false; +} + int wd_get_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_type) { char *dev_name; int ret; - if (!dev || !alg_name) { + if (!dev || !alg_name || !dev->algs) { WD_ERR("invalid: dev or alg name is NULL!\n"); return -WD_EINVAL; } - if (!dev_has_alg(dev->algs, alg_name)) { + if (!check_dev_alg_name(dev->algs, alg_name)) { WD_ERR("invalid: dev does not support alg %s!\n", alg_name); return -WD_EINVAL; } dev_name = wd_get_accel_name(dev->char_dev_path, 0); + if (!dev_name) { + WD_ERR("failed to get dev_nmae!\n"); + return -WD_EINVAL; + } + ret = wd_alg_get_dev_usage(dev_name, alg_name, alg_op_type); if (ret == -WD_EACCES) return wd_read_dev_usage(dev, alg_name, alg_op_type); -- 2.33.0
From: Weili Qian <qianweili@huawei.com> Add missing const qualifier to "dev_name" in struct dev_usage_info {} and "alg_name" in struct wd_ctx_config_internal {}. Fixes a warning: Assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]. Upstream: Yes AR: AR20230722287656 Feature or Bugfix: Feature Signed-off-by: Weili Qian <qianweili@huawei.com> --- include/wd_alg.h | 2 +- include/wd_internal.h | 2 +- wd.c | 2 +- wd_util.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/wd_alg.h b/include/wd_alg.h index 878c595..7a3ae5f 100644 --- a/include/wd_alg.h +++ b/include/wd_alg.h @@ -117,7 +117,7 @@ struct wd_alg_driver { struct hisi_dev_usage { struct wd_alg_driver *drv; - char *dev_name; + const char *dev_name; __u8 alg_op_type; }; diff --git a/include/wd_internal.h b/include/wd_internal.h index d899555..1f2fb31 100644 --- a/include/wd_internal.h +++ b/include/wd_internal.h @@ -55,7 +55,7 @@ struct wd_ctx_config_internal { void *priv; bool epoll_en; unsigned long *msg_cnt; - char *alg_name; + const char *alg_name; }; struct wd_datalist { diff --git a/wd.c b/wd.c index c7dfc10..dcb1dc4 100644 --- a/wd.c +++ b/wd.c @@ -36,7 +36,7 @@ enum UADK_LOG_LEVEL { static int uadk_log_level = WD_LOG_INVALID; struct dev_usage_info { - char *dev_name; + const char *dev_name; __u8 alg_op_type; int (*usage_parse_fn)(char *buf, const char *alg_name, __u8 alg_op_type); }; diff --git a/wd_util.c b/wd_util.c index bec23f5..2fdc4e7 100644 --- a/wd_util.c +++ b/wd_util.c @@ -296,7 +296,7 @@ int wd_init_ctx_config(struct wd_ctx_config_internal *in, goto err_out; } - ret = wd_insert_ctx_list(cfg->ctxs[i].ctx, in->alg_name); + ret = wd_insert_ctx_list(cfg->ctxs[i].ctx, (char *)in->alg_name); if (ret) { WD_ERR("failed to add ctx to mem list!\n"); goto err_out; -- 2.33.0
From: Longfang Liu <liulongfang@huawei.com> Upstream: Yes AR: AR20250321500724 Feature or Bugfix: Feature The original timer in uadk_tool requires re-triggering upon expiration, leading to nested timing and potential inaccuracy. This update improves the timer mechanism. Additionally, the random number generator used a fixed seed during initialization, resulting in insufficient randomness; this has been updated. Furthermore, for non-aligned random length values, the generated result could be empty—this issue has also been fixed. Signed-off-by: Longfang Liu <liulongfang@huawei.com> --- uadk_tool/benchmark/uadk_benchmark.c | 64 +++++++++++++++++++++------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/uadk_tool/benchmark/uadk_benchmark.c b/uadk_tool/benchmark/uadk_benchmark.c index f57c4f9..d8f066f 100644 --- a/uadk_tool/benchmark/uadk_benchmark.c +++ b/uadk_tool/benchmark/uadk_benchmark.c @@ -308,39 +308,71 @@ int get_pid_cpu_time(u32 *ptime) return 0; } -static void alarm_end(int sig) +static void alarm_end(int sig, siginfo_t *info, void *context) { if (sig == SIGALRM) { set_run_state(0); alarm(0); } - signal(SIGALRM, alarm_end); - alarm(1); } void time_start(u32 seconds) { + struct sigaction sa = { + .sa_sigaction = alarm_end, + .sa_flags = SA_SIGINFO | SA_RESETHAND + }; + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + set_run_state(1); init_recv_data(); - signal(SIGALRM, alarm_end); + alarm(seconds); } void get_rand_data(u8 *addr, u32 size) { - unsigned short rand_state[3] = { - (0xae >> 16) & 0xffff, 0xae & 0xffff, 0x330e}; - static __thread u64 rand_seed = 0x330eabcd; - u64 rand48 = 0; - int i; + static __thread unsigned short rand_state[3] = {0}; + static __thread int initialized = 0; + + static const uint32_t LCG_A = 1664525U; + static const uint32_t LCG_C = 1013904223U; + u32 remainder = size & 0x7; + u32 num_u64 = size >> 3; + u64 rand48_result = 0; + u8 *remainder_addr; + u32 init_seed; + u32 i; + + if (!initialized) { + /* Use the data address value as the initial seed for the random number */ + init_seed = (u32)(uintptr_t)addr ^ 0x9e370001U; + init_seed = LCG_A * init_seed + LCG_C; + rand_state[0] = (u16)(init_seed & 0xFFFF); + init_seed = LCG_A * init_seed + LCG_C; + rand_state[1] = (u16)(init_seed & 0xFFFF); + init_seed = LCG_A * init_seed + LCG_C; + rand_state[2] = (u16)(init_seed & 0xFFFF); + + initialized = 1; + } + + for (i = 0; i < num_u64; i++) { + /* Use nrand48��it will auto update rand_state */ + rand48_result = nrand48(rand_state); + *((u64 *)addr + i) = rand48_result; + } + + if (remainder > 0) { + rand48_result = nrand48(rand_state); - // only 32bit valid, other 32bit is zero - for (i = 0; i < size >> 3; i++) { - rand_state[0] = (u16)rand_seed; - rand_state[1] = (u16)(rand_seed >> 16); - rand48 = nrand48(rand_state); - *((u64 *)addr + i) = rand48; - rand_seed = rand48; + remainder_addr = addr + (num_u64 << 3); + remainder_addr[0] = (u8)(rand48_result); + if (remainder > 1) + remainder_addr[1] = (u8)(rand48_result >> 8); + if (remainder > 2) + remainder_addr[2] = (u8)(rand48_result >> 16); } } -- 2.33.0
From: Zongyu Wu <wuzongyu1@huawei.com> When the input block size is smaller than the minimum limit, it may cause reading from an invalid memory address, leading to a segmentation fault. An additional check should be added to prevent the block size from being less than the minimum allowed value. Upstream: Yes AR: AR20230706877877 DTS:DTS2025112007924 Feature or Bugfix: Bugfix Signed-off-by: Zongyu Wu <wuzongyu1@huawei.com> --- uadk_tool/benchmark/zip_wd_benchmark.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/uadk_tool/benchmark/zip_wd_benchmark.c b/uadk_tool/benchmark/zip_wd_benchmark.c index 8388fd0..8b66da1 100644 --- a/uadk_tool/benchmark/zip_wd_benchmark.c +++ b/uadk_tool/benchmark/zip_wd_benchmark.c @@ -22,6 +22,8 @@ #define CHUNK_SIZE (128 * 1024) #define MAX_UNRECV_PACKET_NUM 2 #define MAX_POOL_CREATE_FAIL_TIME 10 +#define MIN_CTX_BUF_SIZE 65536 +#define STREAM_MODE_TYPE 2 #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) @@ -323,6 +325,10 @@ static int init_zip_wd_queue(struct acc_option *options) else outsize = g_pktlen * DECOMP_LEN_RATE; + /* Stream mode block size should bigger than 64K */ + if (options->optype >= STREAM_MODE_TYPE && outsize < MIN_CTX_BUF_SIZE) + outsize = MIN_CTX_BUF_SIZE; + g_thread_queue.bd_res = malloc(g_thread_num * sizeof(struct thread_bd_res)); if (!g_thread_queue.bd_res) { ZIP_TST_PRT("malloc thread res memory fail!\n"); -- 2.33.0
From: Weili Qian <qianweili@huawei.com> Because wd_get_accel_name() allocates memory, the caller needs to release the memory. Currently, the memory has not been released, fix it. Upstream: Yes AR: AR20230722287656 DTS: DTS2025112149705 Feature or Bugfix: Feature Signed-off-by: Weili Qian <qianweili@huawei.com> --- drv/hisi_qm_udrv.c | 4 +++- wd.c | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c index 4ddf8a8..d4feea5 100644 --- a/drv/hisi_qm_udrv.c +++ b/drv/hisi_qm_udrv.c @@ -184,8 +184,10 @@ int hisi_qm_get_usage(handle_t h_qp, __u8 type) return -WD_EINVAL; } + if (count <= (__u16)val) + return QM_MAX_DEV_USAGE; + usage = (__u16)val * QM_DEV_USAGE_RATE / count; - usage = usage > QM_MAX_DEV_USAGE ? QM_MAX_DEV_USAGE : usage; return usage; } diff --git a/wd.c b/wd.c index dcb1dc4..ec20c3f 100644 --- a/wd.c +++ b/wd.c @@ -1163,6 +1163,7 @@ int wd_get_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_ty } ret = wd_alg_get_dev_usage(dev_name, alg_name, alg_op_type); + free(dev_name); if (ret == -WD_EACCES) return wd_read_dev_usage(dev, alg_name, alg_op_type); -- 2.33.0
From: Weili Qian <qianweili@huawei.com> To avoid overflow after multiplying the data, the variable type is cast to int. Upstream: Yes AR: AR20230722287656 DTS: DTS2025112149705 Feature or Bugfix: Bugfix Signed-off-by: Weili Qian <qianweili@huawei.com> --- drv/hisi_qm_udrv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c index d4feea5..a47c596 100644 --- a/drv/hisi_qm_udrv.c +++ b/drv/hisi_qm_udrv.c @@ -164,8 +164,9 @@ int hisi_qm_get_usage(handle_t h_qp, __u8 type) { struct hisi_qp *qp = (struct hisi_qp *)h_qp; struct hisi_qm_queue_info *q_info; - __u16 count, usage; + __u16 count; __u32 val; + int usage; if (!qp) return -WD_EINVAL; @@ -187,7 +188,7 @@ int hisi_qm_get_usage(handle_t h_qp, __u8 type) if (count <= (__u16)val) return QM_MAX_DEV_USAGE; - usage = (__u16)val * QM_DEV_USAGE_RATE / count; + usage = (int)((__u16)val) * QM_DEV_USAGE_RATE / count; return usage; } -- 2.33.0
participants (1)
-
ZongYu Wu