*** BLURB HERE ***
Hao Fang (1): uadk/test: move main function to testsuit.c and rm test_sva_perf.c
Longfang Liu (1): uadk: fix some code bugs
Qi Tao (1): uadk: add null pointer check
Wenkai Lin (1): uadk: fix for sec software compute check
drv/hash_mb/hash_mb.c | 6 +- drv/hisi_comp.c | 10 +- drv/hisi_dae.c | 6 +- drv/hisi_hpre.c | 8 +- drv/hisi_sec.c | 21 +- drv/isa_ce_sm3.c | 6 +- drv/isa_ce_sm4.c | 6 +- test/hisi_zip_test/Makefile.am | 2 +- test/hisi_zip_test/test_sva_perf.c | 524 ----------------------------- test/hisi_zip_test/testsuit.c | 474 +++++++++++++++++++++++++- wd_ecc.c | 6 +- wd_util.c | 11 +- 12 files changed, 520 insertions(+), 560 deletions(-) delete mode 100644 test/hisi_zip_test/test_sva_perf.c
Add null pointer check to avoid segment errors.
Signed-off-by: Qi Tao taoqi10@huawei.com --- drv/hash_mb/hash_mb.c | 6 +++--- drv/hisi_comp.c | 8 +++----- drv/hisi_dae.c | 6 +++--- drv/hisi_hpre.c | 8 +++----- drv/hisi_sec.c | 8 +++----- drv/isa_ce_sm3.c | 6 +++--- drv/isa_ce_sm4.c | 6 +++--- 7 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/drv/hash_mb/hash_mb.c b/drv/hash_mb/hash_mb.c index e4a9564f..9ad36b81 100644 --- a/drv/hash_mb/hash_mb.c +++ b/drv/hash_mb/hash_mb.c @@ -217,11 +217,11 @@ static int hash_mb_init(struct wd_alg_driver *drv, void *conf)
static void hash_mb_exit(struct wd_alg_driver *drv) { - struct hash_mb_ctx *priv = (struct hash_mb_ctx *)drv->priv; - - if (!priv) + if(!drv || !drv->priv) return;
+ struct hash_mb_ctx *priv = (struct hash_mb_ctx *)drv->priv; + hash_mb_queue_uninit(&priv->config, priv->config.ctx_num); free(priv); drv->priv = NULL; diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 4c8e18b2..c5569986 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -835,16 +835,14 @@ out:
static void hisi_zip_exit(struct wd_alg_driver *drv) { + if(!drv || !drv->priv) + return; + struct hisi_zip_ctx *priv = (struct hisi_zip_ctx *)drv->priv; struct wd_ctx_config_internal *config; handle_t h_qp; __u32 i;
- if (!priv) { - /* return if already exit */ - return; - } - config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/hisi_dae.c b/drv/hisi_dae.c index 09d23874..864d21ba 100644 --- a/drv/hisi_dae.c +++ b/drv/hisi_dae.c @@ -1604,14 +1604,14 @@ out:
static void dae_exit(struct wd_alg_driver *drv) { + if(!drv || !drv->priv) + return; + struct hisi_dae_ctx *priv = (struct hisi_dae_ctx *)drv->priv; struct wd_ctx_config_internal *config; handle_t h_qp; __u32 i;
- if (!priv) - return; - config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index 37bb5ee1..313cdcc8 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -583,16 +583,14 @@ static int hpre_ecc_init(struct wd_alg_driver *drv, void *conf)
static void hpre_exit(struct wd_alg_driver *drv) { + if(!drv || !drv->priv) + return; + struct hisi_hpre_ctx *priv = (struct hisi_hpre_ctx *)drv->priv; struct wd_ctx_config_internal *config; handle_t h_qp; __u32 i;
- if (!priv) { - /* return if already exit */ - return; - } - config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index 0a1bcc1e..63775869 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -3102,16 +3102,14 @@ out:
static void hisi_sec_exit(struct wd_alg_driver *drv) { + if(!drv || !drv->priv) + return; + struct hisi_sec_ctx *priv = (struct hisi_sec_ctx *)drv->priv; struct wd_ctx_config_internal *config; handle_t h_qp; __u32 i;
- if (!priv) { - /* return if already exit */ - return; - } - config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/isa_ce_sm3.c b/drv/isa_ce_sm3.c index 99cd6404..54c2a9e7 100644 --- a/drv/isa_ce_sm3.c +++ b/drv/isa_ce_sm3.c @@ -392,11 +392,11 @@ static int sm3_ce_drv_init(struct wd_alg_driver *drv, void *conf)
static void sm3_ce_drv_exit(struct wd_alg_driver *drv) { - struct sm3_ce_drv_ctx *sctx = (struct sm3_ce_drv_ctx *)drv->priv; - - if (!sctx) + if(!drv || !drv->priv) return;
+ struct sm3_ce_drv_ctx *sctx = (struct sm3_ce_drv_ctx *)drv->priv; + free(sctx); drv->priv = NULL; } diff --git a/drv/isa_ce_sm4.c b/drv/isa_ce_sm4.c index 3404465b..5e448fa0 100644 --- a/drv/isa_ce_sm4.c +++ b/drv/isa_ce_sm4.c @@ -53,11 +53,11 @@ static int isa_ce_init(struct wd_alg_driver *drv, void *conf)
static void isa_ce_exit(struct wd_alg_driver *drv) { - struct sm4_ce_drv_ctx *sctx = (struct sm4_ce_drv_ctx *)drv->priv; - - if (!sctx) + if(!drv || !drv->priv) return;
+ struct sm4_ce_drv_ctx *sctx = (struct sm4_ce_drv_ctx *)drv->priv; + free(sctx); drv->priv = NULL; }
From: Hao Fang fanghao11@huawei.com
test_suit.c should be the main function file, and these two files have the duplicate code.
Signed-off-by: Hao Fang fanghao11@huawei.com --- test/hisi_zip_test/Makefile.am | 2 +- test/hisi_zip_test/test_sva_perf.c | 524 ----------------------------- test/hisi_zip_test/testsuit.c | 474 +++++++++++++++++++++++++- 3 files changed, 474 insertions(+), 526 deletions(-) delete mode 100644 test/hisi_zip_test/test_sva_perf.c
diff --git a/test/hisi_zip_test/Makefile.am b/test/hisi_zip_test/Makefile.am index f6715820..8b464f58 100644 --- a/test/hisi_zip_test/Makefile.am +++ b/test/hisi_zip_test/Makefile.am @@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS=zip_sva_perf
-zip_sva_perf_SOURCES=test_sva_perf.c test_lib.c testsuit.c +zip_sva_perf_SOURCES=testsuit.c test_lib.c
if WD_STATIC_DRV zip_sva_perf_LDADD=../../.libs/libwd.a ../../.libs/libwd_comp.a \ diff --git a/test/hisi_zip_test/test_sva_perf.c b/test/hisi_zip_test/test_sva_perf.c deleted file mode 100644 index 98670a5b..00000000 --- a/test/hisi_zip_test/test_sva_perf.c +++ /dev/null @@ -1,524 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright 2020-2021 Huawei Technologies Co.,Ltd. All rights reserved. - * Copyright 2020-2021 Linaro ltd. - */ - -/* - * Test performance of the SVA API - */ -#include <asm/unistd.h> /* For __NR_perf_event_open */ -#include <fenv.h> -#include <getopt.h> -#include <inttypes.h> -#include <math.h> -#include <signal.h> -#include <time.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <linux/perf_event.h> - -#include "test_lib.h" -#include "wd_sched.h" - -enum hizip_stats_variable { - ST_SETUP_TIME, - ST_RUN_TIME, - ST_CPU_TIME, - - /* CPU usage */ - ST_USER_TIME, - ST_SYSTEM_TIME, - - /* Faults */ - ST_MINFLT, - ST_MAJFLT, - - /* Context switches */ - ST_INVCTX, - ST_VCTX, - - /* Signals */ - ST_SIGNALS, - - /* Aggregated */ - ST_SPEED, - ST_TOTAL_SPEED, - ST_CPU_IDLE, - ST_FAULTS, - ST_IOPF, - - ST_COMPRESSION_RATIO, - - NUM_STATS -}; - -struct hizip_stats { - double v[NUM_STATS]; -}; - -int perf_event_open(struct perf_event_attr *attr, - pid_t pid, int cpu, int group_fd, - unsigned long flags) -{ - return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); -} - -unsigned long long perf_event_put(int *perf_fds, int nr_fds); - -int perf_event_get(const char *event_name, int **perf_fds, int *nr_fds) -{ - int ret; - int cpu; - FILE *fd; - int nr_cpus; - unsigned int event_id; - char event_id_file[256]; - struct perf_event_attr event = { - .type = PERF_TYPE_TRACEPOINT, - .size = sizeof(event), - .disabled = true, - }; - - *perf_fds = NULL; - *nr_fds = 0; - - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - if (nr_cpus <= 0) { - WD_ERR("invalid number of CPUs\n"); - return nr_cpus; - } - - ret = snprintf(event_id_file, sizeof(event_id_file), - "/sys/kernel/debug/tracing/events/%s/id", event_name); - if (ret >= sizeof(event_id_file)) { - WD_ERR("event_id buffer overflow\n"); - return -EOVERFLOW; - } - fd = fopen(event_id_file, "r"); - if (fd == NULL) { - ret = -errno; - WD_ERR("Couldn't open file %s\n", event_id_file); - return ret; - } - - if (fscanf(fd, "%d", &event_id) != 1) { - WD_ERR("Couldn't parse file %s\n", event_id_file); - return -EINVAL; - } - fclose(fd); - event.config = event_id; - - *perf_fds = calloc(nr_cpus, sizeof(int)); - if (!*perf_fds) - return -ENOMEM; - *nr_fds = nr_cpus; - - /* - * An event is bound to either a CPU or a PID. If we want both, we need - * to open the event on all CPUs. Note that we can't use a perf group - * since they have to be on the same CPU. - */ - for (cpu = 0; cpu < nr_cpus; cpu++) { - int fd = perf_event_open(&event, -1, cpu, -1, 0); - - if (fd < 0) { - WD_ERR("Couldn't get perf event %s on CPU%d: %d\n", - event_name, cpu, errno); - perf_event_put(*perf_fds, cpu); - return fd; - } - - ioctl(fd, PERF_EVENT_IOC_RESET, 0); - ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); - (*perf_fds)[cpu] = fd; - } - - return 0; -} - -/* - * Closes the perf fd and return the sample count. If it wasn't open, return 0. - */ -unsigned long long perf_event_put(int *perf_fds, int nr_fds) -{ - int ret; - int cpu; - uint64_t count, total = 0; - - if (!perf_fds) - return 0; - - for (cpu = 0; cpu < nr_fds; cpu++) { - int fd = perf_fds[cpu]; - - if (fd <= 0) { - WD_ERR("Invalid perf fd %d\n", cpu); - continue; - } - - ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); - - ret = read(fd, &count, sizeof(count)); - if (ret < sizeof(count)) - WD_ERR("Couldn't read perf event for CPU%d\n", cpu); - - total += count; - close(fd); - - } - - free(perf_fds); - return total; -} - -static void set_thp(struct test_options *opts) -{ - char *p; - char s[14]; - FILE *file; - - file = fopen("/sys/kernel/mm/transparent_hugepage/enabled", "r"); - if (!file) - goto out_err; - p = fgets(s, 14, file); - fclose(file); - if (!p) - goto out_err; - - if (strcmp(s, "never") == 0) { - printf("Cannot test THP with enable=never\n"); - return; - } - - file = fopen("/sys/kernel/mm/transparent_hugepage/defrag", "r"); - if (!file) - goto out_err; - p = fgets(s, 14, file); - fclose(file); - if (!p) - goto out_err; - - if (strcmp(s, "defer") == 0 || strcmp(s, "never") == 0) { - printf("Cannot test THP with defrag=%s\n", s); - return; - } - - return; -out_err: - printf("THP unsupported?\n"); -} - -void stat_setup(struct hizip_test_info *info) -{ - clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.setup_time); - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.setup_cputime); - getrusage(RUSAGE_SELF, &info->tv.setup_rusage); -} - -void stat_start(struct hizip_test_info *info) -{ - clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.start_time); - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.start_cputime); - getrusage(RUSAGE_SELF, &info->tv.start_rusage); -} - -void stat_end(struct hizip_test_info *info) -{ - struct test_options *opts = info->opts; - struct hizip_stats *stats = info->stats; - double v; - size_t total_out; - unsigned long total_len; - - total_out = __atomic_load_n(&info->total_out, __ATOMIC_ACQUIRE); - clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.end_time); - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.end_cputime); - getrusage(RUSAGE_SELF, &info->tv.end_rusage); - - stats->v[ST_SETUP_TIME] = (info->tv.start_time.tv_sec - - info->tv.setup_time.tv_sec) * 1000000000 + - info->tv.start_time.tv_nsec - - info->tv.setup_time.tv_nsec; - stats->v[ST_RUN_TIME] = (info->tv.end_time.tv_sec - - info->tv.start_time.tv_sec) * 1000000000 + - info->tv.end_time.tv_nsec - - info->tv.start_time.tv_nsec; - - stats->v[ST_CPU_TIME] = (info->tv.end_cputime.tv_sec - - info->tv.setup_cputime.tv_sec) * 1000000000 + - info->tv.end_cputime.tv_nsec - - info->tv.setup_cputime.tv_nsec; - stats->v[ST_USER_TIME] = (info->tv.end_rusage.ru_utime.tv_sec - - info->tv.setup_rusage.ru_utime.tv_sec) * - 1000000 + - info->tv.end_rusage.ru_utime.tv_usec - - info->tv.setup_rusage.ru_utime.tv_usec; - stats->v[ST_SYSTEM_TIME] = (info->tv.end_rusage.ru_stime.tv_sec - - info->tv.setup_rusage.ru_stime.tv_sec) * - 1000000 + - info->tv.end_rusage.ru_stime.tv_usec - - info->tv.setup_rusage.ru_stime.tv_usec; - - stats->v[ST_MINFLT] = info->tv.end_rusage.ru_minflt - - info->tv.setup_rusage.ru_minflt; - stats->v[ST_MAJFLT] = info->tv.end_rusage.ru_majflt - - info->tv.setup_rusage.ru_majflt; - - stats->v[ST_VCTX] = info->tv.end_rusage.ru_nvcsw - - info->tv.setup_rusage.ru_nvcsw; - stats->v[ST_INVCTX] = info->tv.end_rusage.ru_nivcsw - - info->tv.setup_rusage.ru_nivcsw; - - stats->v[ST_SIGNALS] = info->tv.end_rusage.ru_nsignals - - info->tv.setup_rusage.ru_nsignals; - - /* check last loop is enough, same as below hizip_verify_output */ - stats->v[ST_COMPRESSION_RATIO] = (double)opts->total_len / - total_out * 100; - - total_len = opts->total_len * opts->compact_run_num; - /* ST_RUN_TIME records nanoseconds */ - stats->v[ST_SPEED] = (total_len * opts->thread_num * 1000) / - (1.024 * 1.024 * stats->v[ST_RUN_TIME]); - - stats->v[ST_TOTAL_SPEED] = (total_len * opts->thread_num * 1000) / - ((stats->v[ST_RUN_TIME] + - stats->v[ST_SETUP_TIME]) * 1.024 * 1.024); - - v = stats->v[ST_RUN_TIME] + stats->v[ST_SETUP_TIME]; - stats->v[ST_CPU_IDLE] = (v - stats->v[ST_CPU_TIME]) / v * 100; - stats->v[ST_FAULTS] = stats->v[ST_MAJFLT] + stats->v[ST_MINFLT]; -} - -static void handle_sigbus(int sig) -{ - printf("SIGBUS!\n"); - _exit(0); -} - -int main(int argc, char **argv) -{ - struct test_options opts = { - .alg_type = WD_GZIP, - .op_type = WD_DIR_COMPRESS, - .q_num = 1, - .run_num = 1, - .compact_run_num = 1, - .thread_num = 1, - .sync_mode = 0, - .block_size = 512000, - .total_len = opts.block_size * 10, - .verify = false, - .verbose = false, - .is_decomp = false, - .is_stream = false, - .is_file = false, - .display_stats = STATS_PRETTY, - .children = 0, - .faults = 0, - .data_fmt = 0, - }; - struct option long_options[] = { - {"self", no_argument, 0, 0 }, - {"in", required_argument, 0, 0 }, - {"out", required_argument, 0, 0 }, - {"ilist", required_argument, 0, 0 }, - {"olist", required_argument, 0, 0 }, - {"env", no_argument, 0, 0 }, - {0, 0, 0, 0 }, - }; - int show_help = 0; - int opt, option_idx; - int self = 0; - - opts.fd_in = -1; - opts.fd_out = -1; - opts.fd_ilist = -1; - opts.fd_olist = -1; - opts.alg_type = WD_COMP_ALG_MAX; - while ((opt = getopt_long(argc, argv, COMMON_OPTSTRING "f:o:w:k:r:", - long_options, &option_idx)) != -1) { - switch (opt) { - case 0: - switch (option_idx) { - case 0: /* self */ - self = 1; - break; - case 1: /* in */ - if (optarg) { - opts.fd_in = open(optarg, O_RDONLY); - if (opts.fd_in < 0) { - printf("Fail to open %s\n", - optarg); - show_help = 1; - } else - opts.is_file = true; - } else { - printf("Input file is missing!\n"); - show_help = 1; - } - if (lseek(opts.fd_in, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - } - break; - case 2: /* out */ - if (optarg) { - opts.fd_out = open(optarg, - O_CREAT | O_WRONLY, - S_IWUSR | S_IRGRP | - S_IROTH); - if (opts.fd_out < 0) { - printf("Fail to open %s\n", - optarg); - show_help = 1; - } else - opts.is_file = true; - } else { - printf("Output file is missing!\n"); - show_help = 1; - } - if (lseek(opts.fd_out, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - } - break; - case 3: /* ilist */ - if (!optarg) { - printf("IN list file is missing!\n"); - show_help = 1; - break; - } - opts.fd_ilist = open(optarg, O_RDONLY); - if (opts.fd_ilist < 0) { - printf("Fail to open %s\n", optarg); - show_help = 1; - break; - } - opts.is_file = true; - if (lseek(opts.fd_ilist, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - break; - } - break; - case 4: /* olist */ - if (!optarg) { - printf("OUT list file is missing!\n"); - show_help = 1; - break; - } - opts.fd_olist = open(optarg, - O_CREAT | O_WRONLY, - S_IWUSR | S_IRGRP | - S_IROTH); - if (opts.fd_olist < 0) { - printf("Fail to open %s\n", optarg); - show_help = 1; - break; - } - opts.is_file = true; - if (lseek(opts.fd_olist, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - break; - } - break; - case 5: /* env */ - opts.use_env = true; - break; - default: - show_help = 1; - break; - } - break; - case 'f': - if (strcmp(optarg, "none") == 0) { - opts.display_stats = STATS_NONE; - } else if (strcmp(optarg, "csv") == 0) { - opts.display_stats = STATS_CSV; - } else if (strcmp(optarg, "pretty") == 0) { - opts.display_stats = STATS_PRETTY; - } else { - SYS_ERR_COND(1, "invalid argument to -f: '%s'\n", optarg); - break; - } - break; - case 'o': - switch (optarg[0]) { - case 'p': - opts.option |= PERFORMANCE; - break; - case 't': - opts.option |= TEST_THP; - set_thp(&opts); - break; - default: - SYS_ERR_COND(1, "invalid argument to -o: '%s'\n", optarg); - break; - } - break; - case 'c': - opts.option |= TEST_ZLIB; - break; - case 'r': - opts.children = strtol(optarg, NULL, 0); - if (opts.children < 0) - show_help = 1; - break; - case 'k': - switch (optarg[0]) { - case 'b': - opts.faults |= INJECT_SIG_BIND; - break; - case 't': - opts.faults |= INJECT_TLB_FAULT; - break; - case 'w': - opts.faults |= INJECT_SIG_WORK; - break; - default: - SYS_ERR_COND(1, "invalid argument to -k: '%s'\n", optarg); - break; - } - break; - default: - show_help = parse_common_option(opt, optarg, &opts); - break; - } - } - - signal(SIGBUS, handle_sigbus); - - if (!show_help) { - if (self) - return run_self_test(&opts); - return run_cmd(&opts); - } - - hizip_test_adjust_len(&opts); - - SYS_ERR_COND(show_help || optind > argc, - COMMON_HELP - " -f <format> output format for the statistics\n" - " 'none' do not output statistics\n" - " 'pretty' human readable format\n" - " 'csv' raw, machine readable\n" - " -o <mode> options\n" - " 'perf' prefaults the output pages\n" - " 'thp' try to enable transparent huge pages\n" - " 'zlib' use zlib instead of the device\n" - " -r <children> number of children to create\n" - " -k <mode> kill thread\n" - " 'bind' kills the process after bind\n" - " 'tlb' tries to access an unmapped buffer\n" - " 'work' kills the process while the queue is working\n", - argv[0] - ); - return 0; -} diff --git a/test/hisi_zip_test/testsuit.c b/test/hisi_zip_test/testsuit.c index ac1a5f68..e1b157a7 100644 --- a/test/hisi_zip_test/testsuit.c +++ b/test/hisi_zip_test/testsuit.c @@ -3,12 +3,22 @@ * Copyright 2020-2021 Huawei Technologies Co.,Ltd. All rights reserved. * Copyright 2020-2021 Linaro ltd. */ - #include <linux/perf_event.h> +#include <asm/unistd.h> /* For __NR_perf_event_open */ +#include <fenv.h> +#include <getopt.h> +#include <inttypes.h> +#include <math.h> #include <signal.h> +#include <time.h> +#include <sys/ioctl.h> +#include <sys/mman.h> #include <sys/types.h> #include <sys/wait.h> +#include <unistd.h> + #include "test_lib.h" +#include "wd_sched.h"
#define POLL_STRING_LEN 128
@@ -1370,3 +1380,465 @@ int run_cmd(struct test_options *opts) ret = run_one_cmd(opts); return ret; } + +int perf_event_open(struct perf_event_attr *attr, + pid_t pid, int cpu, int group_fd, + unsigned long flags) +{ + return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); +} + +unsigned long long perf_event_put(int *perf_fds, int nr_fds); + +int perf_event_get(const char *event_name, int **perf_fds, int *nr_fds) +{ + int ret; + int cpu; + FILE *fd; + int nr_cpus; + unsigned int event_id; + char event_id_file[256]; + struct perf_event_attr event = { + .type = PERF_TYPE_TRACEPOINT, + .size = sizeof(event), + .disabled = true, + }; + + *perf_fds = NULL; + *nr_fds = 0; + + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + if (nr_cpus <= 0) { + WD_ERR("invalid number of CPUs\n"); + return nr_cpus; + } + + ret = snprintf(event_id_file, sizeof(event_id_file), + "/sys/kernel/debug/tracing/events/%s/id", event_name); + if (ret >= sizeof(event_id_file)) { + WD_ERR("event_id buffer overflow\n"); + return -EOVERFLOW; + } + fd = fopen(event_id_file, "r"); + if (fd == NULL) { + ret = -errno; + WD_ERR("Couldn't open file %s\n", event_id_file); + return ret; + } + + if (fscanf(fd, "%d", &event_id) != 1) { + WD_ERR("Couldn't parse file %s\n", event_id_file); + return -EINVAL; + } + fclose(fd); + event.config = event_id; + + *perf_fds = calloc(nr_cpus, sizeof(int)); + if (!*perf_fds) + return -ENOMEM; + *nr_fds = nr_cpus; + + /* + * An event is bound to either a CPU or a PID. If we want both, we need + * to open the event on all CPUs. Note that we can't use a perf group + * since they have to be on the same CPU. + */ + for (cpu = 0; cpu < nr_cpus; cpu++) { + int fd = perf_event_open(&event, -1, cpu, -1, 0); + + if (fd < 0) { + WD_ERR("Couldn't get perf event %s on CPU%d: %d\n", + event_name, cpu, errno); + perf_event_put(*perf_fds, cpu); + return fd; + } + + ioctl(fd, PERF_EVENT_IOC_RESET, 0); + ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); + (*perf_fds)[cpu] = fd; + } + + return 0; +} + +/* + * Closes the perf fd and return the sample count. If it wasn't open, return 0. + */ +unsigned long long perf_event_put(int *perf_fds, int nr_fds) +{ + int ret; + int cpu; + uint64_t count, total = 0; + + if (!perf_fds) + return 0; + + for (cpu = 0; cpu < nr_fds; cpu++) { + int fd = perf_fds[cpu]; + + if (fd <= 0) { + WD_ERR("Invalid perf fd %d\n", cpu); + continue; + } + + ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); + + ret = read(fd, &count, sizeof(count)); + if (ret < sizeof(count)) + WD_ERR("Couldn't read perf event for CPU%d\n", cpu); + + total += count; + close(fd); + + } + + free(perf_fds); + return total; +} + +static void set_thp(struct test_options *opts) +{ + char *p; + char s[14]; + FILE *file; + + file = fopen("/sys/kernel/mm/transparent_hugepage/enabled", "r"); + if (!file) + goto out_err; + p = fgets(s, 14, file); + fclose(file); + if (!p) + goto out_err; + + if (strcmp(s, "never") == 0) { + printf("Cannot test THP with enable=never\n"); + return; + } + + file = fopen("/sys/kernel/mm/transparent_hugepage/defrag", "r"); + if (!file) + goto out_err; + p = fgets(s, 14, file); + fclose(file); + if (!p) + goto out_err; + + if (strcmp(s, "defer") == 0 || strcmp(s, "never") == 0) { + printf("Cannot test THP with defrag=%s\n", s); + return; + } + + return; +out_err: + printf("THP unsupported?\n"); +} + +void stat_setup(struct hizip_test_info *info) +{ + clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.setup_time); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.setup_cputime); + getrusage(RUSAGE_SELF, &info->tv.setup_rusage); +} + +void stat_start(struct hizip_test_info *info) +{ + clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.start_time); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.start_cputime); + getrusage(RUSAGE_SELF, &info->tv.start_rusage); +} + +void stat_end(struct hizip_test_info *info) +{ + struct test_options *opts = info->opts; + struct hizip_stats *stats = info->stats; + double v; + size_t total_out; + unsigned long total_len; + + total_out = __atomic_load_n(&info->total_out, __ATOMIC_ACQUIRE); + clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.end_time); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.end_cputime); + getrusage(RUSAGE_SELF, &info->tv.end_rusage); + + stats->v[ST_SETUP_TIME] = (info->tv.start_time.tv_sec - + info->tv.setup_time.tv_sec) * 1000000000 + + info->tv.start_time.tv_nsec - + info->tv.setup_time.tv_nsec; + stats->v[ST_RUN_TIME] = (info->tv.end_time.tv_sec - + info->tv.start_time.tv_sec) * 1000000000 + + info->tv.end_time.tv_nsec - + info->tv.start_time.tv_nsec; + + stats->v[ST_CPU_TIME] = (info->tv.end_cputime.tv_sec - + info->tv.setup_cputime.tv_sec) * 1000000000 + + info->tv.end_cputime.tv_nsec - + info->tv.setup_cputime.tv_nsec; + stats->v[ST_USER_TIME] = (info->tv.end_rusage.ru_utime.tv_sec - + info->tv.setup_rusage.ru_utime.tv_sec) * + 1000000 + + info->tv.end_rusage.ru_utime.tv_usec - + info->tv.setup_rusage.ru_utime.tv_usec; + stats->v[ST_SYSTEM_TIME] = (info->tv.end_rusage.ru_stime.tv_sec - + info->tv.setup_rusage.ru_stime.tv_sec) * + 1000000 + + info->tv.end_rusage.ru_stime.tv_usec - + info->tv.setup_rusage.ru_stime.tv_usec; + + stats->v[ST_MINFLT] = info->tv.end_rusage.ru_minflt - + info->tv.setup_rusage.ru_minflt; + stats->v[ST_MAJFLT] = info->tv.end_rusage.ru_majflt - + info->tv.setup_rusage.ru_majflt; + + stats->v[ST_VCTX] = info->tv.end_rusage.ru_nvcsw - + info->tv.setup_rusage.ru_nvcsw; + stats->v[ST_INVCTX] = info->tv.end_rusage.ru_nivcsw - + info->tv.setup_rusage.ru_nivcsw; + + stats->v[ST_SIGNALS] = info->tv.end_rusage.ru_nsignals - + info->tv.setup_rusage.ru_nsignals; + + /* check last loop is enough, same as below hizip_verify_output */ + stats->v[ST_COMPRESSION_RATIO] = (double)opts->total_len / + total_out * 100; + + total_len = opts->total_len * opts->compact_run_num; + /* ST_RUN_TIME records nanoseconds */ + stats->v[ST_SPEED] = (total_len * opts->thread_num * 1000) / + (1.024 * 1.024 * stats->v[ST_RUN_TIME]); + + stats->v[ST_TOTAL_SPEED] = (total_len * opts->thread_num * 1000) / + ((stats->v[ST_RUN_TIME] + + stats->v[ST_SETUP_TIME]) * 1.024 * 1.024); + + v = stats->v[ST_RUN_TIME] + stats->v[ST_SETUP_TIME]; + stats->v[ST_CPU_IDLE] = (v - stats->v[ST_CPU_TIME]) / v * 100; + stats->v[ST_FAULTS] = stats->v[ST_MAJFLT] + stats->v[ST_MINFLT]; +} + +static void handle_sigbus(int sig) +{ + printf("SIGBUS!\n"); + _exit(0); +} + +int main(int argc, char **argv) +{ + struct test_options opts = { + .alg_type = WD_GZIP, + .op_type = WD_DIR_COMPRESS, + .q_num = 1, + .run_num = 1, + .compact_run_num = 1, + .thread_num = 1, + .sync_mode = 0, + .block_size = 512000, + .total_len = opts.block_size * 10, + .verify = false, + .verbose = false, + .is_decomp = false, + .is_stream = false, + .is_file = false, + .display_stats = STATS_PRETTY, + .children = 0, + .faults = 0, + .data_fmt = 0, + }; + struct option long_options[] = { + {"self", no_argument, 0, 0 }, + {"in", required_argument, 0, 0 }, + {"out", required_argument, 0, 0 }, + {"ilist", required_argument, 0, 0 }, + {"olist", required_argument, 0, 0 }, + {"env", no_argument, 0, 0 }, + {0, 0, 0, 0 }, + }; + int show_help = 0; + int opt, option_idx; + int self = 0; + + opts.fd_in = -1; + opts.fd_out = -1; + opts.fd_ilist = -1; + opts.fd_olist = -1; + opts.alg_type = WD_COMP_ALG_MAX; + while ((opt = getopt_long(argc, argv, COMMON_OPTSTRING "f:o:w:k:r:", + long_options, &option_idx)) != -1) { + switch (opt) { + case 0: + switch (option_idx) { + case 0: /* self */ + self = 1; + break; + case 1: /* in */ + if (optarg) { + opts.fd_in = open(optarg, O_RDONLY); + if (opts.fd_in < 0) { + printf("Fail to open %s\n", + optarg); + show_help = 1; + } else + opts.is_file = true; + } else { + printf("Input file is missing!\n"); + show_help = 1; + } + if (lseek(opts.fd_in, 0, SEEK_SET) < 0) { + printf("Fail on lseek()!\n"); + show_help = 1; + } + break; + case 2: /* out */ + if (optarg) { + opts.fd_out = open(optarg, + O_CREAT | O_WRONLY, + S_IWUSR | S_IRGRP | + S_IROTH); + if (opts.fd_out < 0) { + printf("Fail to open %s\n", + optarg); + show_help = 1; + } else + opts.is_file = true; + } else { + printf("Output file is missing!\n"); + show_help = 1; + } + if (lseek(opts.fd_out, 0, SEEK_SET) < 0) { + printf("Fail on lseek()!\n"); + show_help = 1; + } + break; + case 3: /* ilist */ + if (!optarg) { + printf("IN list file is missing!\n"); + show_help = 1; + break; + } + opts.fd_ilist = open(optarg, O_RDONLY); + if (opts.fd_ilist < 0) { + printf("Fail to open %s\n", optarg); + show_help = 1; + break; + } + opts.is_file = true; + if (lseek(opts.fd_ilist, 0, SEEK_SET) < 0) { + printf("Fail on lseek()!\n"); + show_help = 1; + break; + } + break; + case 4: /* olist */ + if (!optarg) { + printf("OUT list file is missing!\n"); + show_help = 1; + break; + } + opts.fd_olist = open(optarg, + O_CREAT | O_WRONLY, + S_IWUSR | S_IRGRP | + S_IROTH); + if (opts.fd_olist < 0) { + printf("Fail to open %s\n", optarg); + show_help = 1; + break; + } + opts.is_file = true; + if (lseek(opts.fd_olist, 0, SEEK_SET) < 0) { + printf("Fail on lseek()!\n"); + show_help = 1; + break; + } + break; + case 5: /* env */ + opts.use_env = true; + break; + default: + show_help = 1; + break; + } + break; + case 'f': + if (strcmp(optarg, "none") == 0) { + opts.display_stats = STATS_NONE; + } else if (strcmp(optarg, "csv") == 0) { + opts.display_stats = STATS_CSV; + } else if (strcmp(optarg, "pretty") == 0) { + opts.display_stats = STATS_PRETTY; + } else { + SYS_ERR_COND(1, "invalid argument to -f: '%s'\n", optarg); + break; + } + break; + case 'o': + switch (optarg[0]) { + case 'p': + opts.option |= PERFORMANCE; + break; + case 't': + opts.option |= TEST_THP; + set_thp(&opts); + break; + default: + SYS_ERR_COND(1, "invalid argument to -o: '%s'\n", optarg); + break; + } + break; + case 'c': + opts.option |= TEST_ZLIB; + break; + case 'r': + opts.children = strtol(optarg, NULL, 0); + if (opts.children < 0) + show_help = 1; + break; + case 'k': + switch (optarg[0]) { + case 'b': + opts.faults |= INJECT_SIG_BIND; + break; + case 't': + opts.faults |= INJECT_TLB_FAULT; + break; + case 'w': + opts.faults |= INJECT_SIG_WORK; + break; + default: + SYS_ERR_COND(1, "invalid argument to -k: '%s'\n", optarg); + break; + } + break; + default: + show_help = parse_common_option(opt, optarg, &opts); + break; + } + } + + signal(SIGBUS, handle_sigbus); + + if (!show_help) { + if (self) + return run_self_test(&opts); + return run_cmd(&opts); + } + + hizip_test_adjust_len(&opts); + + SYS_ERR_COND(show_help || optind > argc, + COMMON_HELP + " -f <format> output format for the statistics\n" + " 'none' do not output statistics\n" + " 'pretty' human readable format\n" + " 'csv' raw, machine readable\n" + " -o <mode> options\n" + " 'perf' prefaults the output pages\n" + " 'thp' try to enable transparent huge pages\n" + " 'zlib' use zlib instead of the device\n" + " -r <children> number of children to create\n" + " -k <mode> kill thread\n" + " 'bind' kills the process after bind\n" + " 'tlb' tries to access an unmapped buffer\n" + " 'work' kills the process while the queue is working\n", + argv[0] + ); + return 0; +} \ No newline at end of file
From: Wenkai Lin linwenkai6@hisilicon.com
For aead stream mode, the final message is not sent to hardware when the qm V3 version is used or when the length of the message is 0, so software compute check should return true to stop qm_recv process.
Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com --- drv/hisi_sec.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index 63775869..9d698316 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -2647,8 +2647,17 @@ static void parse_aead_bd2(struct hisi_qp *qp, struct hisi_sec_sqe *sqe, static bool soft_compute_check(struct hisi_qp *qp, struct wd_aead_msg *msg) { /* Asynchronous mode does not use the sent message, so ignores it */ - if (msg->cmode == WD_CIPHER_GCM) - return (msg->msg_state == AEAD_MSG_END) && qp->q_info.qp_mode == CTX_MODE_SYNC; + if (qp->q_info.qp_mode == CTX_MODE_ASYNC) + return false; + /* + * For aead gcm stream mode, due to some hardware limitations, + * the final message was not sent to hardware if the qm is + * not higher than v3 version or the input length of the + * message is 0, the software calculation has been executed. + */ + if (msg->msg_state == AEAD_MSG_END && msg->cmode == WD_CIPHER_GCM && + (qp->q_info.hw_type <= HISI_QM_API_VER3_BASE || !msg->in_bytes)) + return true;
return false; }
From: Longfang Liu liulongfang@huawei.com
Upstream: Yes Bugfix or Feature: Bugfix DTS:DTS2024073110036
There are some previously undiscovered issues in these code files. These issues include: 1. Unchecked function return value 2. Unverified external input parameters 3. Illegal assignment operation
Therefore, it needs to be fixed.
Signed-off-by: Longfang Liu liulongfang@huawei.com --- drv/hisi_comp.c | 2 ++ wd_ecc.c | 6 +++--- wd_util.c | 11 +++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index c5569986..b4c216fa 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -510,6 +510,8 @@ static int fill_buf_lz77_zstd_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe, fill_buf_type_sgl(sqe);
seq_start = get_seq_start_list(req); + if (unlikely(!seq_start)) + return -WD_EINVAL;
data->literals_start = req->list_dst; data->sequences_start = seq_start; diff --git a/wd_ecc.c b/wd_ecc.c index b1712c50..292338a6 100644 --- a/wd_ecc.c +++ b/wd_ecc.c @@ -1504,7 +1504,7 @@ static int fill_ecc_msg(struct wd_ecc_msg *msg, struct wd_ecc_req *req, void *key = NULL;
memcpy(&msg->req, req, sizeof(msg->req)); - msg->hash = sess->setup.hash; + memcpy(&msg->hash, &sess->setup.hash, sizeof(msg->hash)); msg->key_bytes = sess->key_size; msg->curve_id = sess->setup.cv.cfg.id; msg->result = WD_EINVAL; @@ -1655,10 +1655,10 @@ static int set_sign_in_param(struct wd_ecc_sign_in *sin,
static int generate_random(struct wd_ecc_sess *sess, struct wd_dtb *k) { - struct wd_rand_mt rand_t = sess->setup.rand; + struct wd_rand_mt *rand_t = &sess->setup.rand; int ret;
- ret = rand_t.cb(k->data, k->dsize, rand_t.usr); + ret = rand_t->cb(k->data, k->dsize, rand_t->usr); if (ret) WD_ERR("failed to do rand cb, ret = %d!\n", ret);
diff --git a/wd_util.c b/wd_util.c index d58e8b85..e908dcb4 100644 --- a/wd_util.c +++ b/wd_util.c @@ -421,8 +421,15 @@ void wd_uninit_async_request_pool(struct wd_async_msg_pool *pool) void *wd_find_msg_in_pool(struct wd_async_msg_pool *pool, int ctx_idx, __u32 tag) { - struct msg_pool *p = &pool->pools[ctx_idx]; - __u32 msg_num = p->msg_num; + struct msg_pool *p; + __u32 msg_num; + + if ((__u32)ctx_idx > pool->pool_num) { + WD_ERR("invalid: message ctx id index is %d!\n", ctx_idx); + return NULL; + } + p = &pool->pools[ctx_idx]; + msg_num = p->msg_num;
/* tag value start from 1 */ if (tag == 0 || tag > msg_num) {