
From: Hao Fang <fanghao11@huawei.com> The zip_sva_perf tool has been replaced by uadk_tool. Signed-off-by: Hao Fang <fanghao11@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- cleanup.sh | 5 +- configure.ac | 1 - test/Makefile.am | 4 - test/hisi_zip_test/Makefile.am | 23 - test/hisi_zip_test/test_lib.c | 1874 -------------------------------- test/hisi_zip_test/test_lib.h | 352 ------ test/hisi_zip_test/testsuit.c | 1844 ------------------------------- 7 files changed, 2 insertions(+), 4101 deletions(-) delete mode 100644 test/hisi_zip_test/Makefile.am delete mode 100644 test/hisi_zip_test/test_lib.c delete mode 100644 test/hisi_zip_test/test_lib.h delete mode 100644 test/hisi_zip_test/testsuit.c diff --git a/cleanup.sh b/cleanup.sh index 60adc988..b7997f2a 100755 --- a/cleanup.sh +++ b/cleanup.sh @@ -10,9 +10,8 @@ FILES="aclocal.m4 autom4te.cache compile config.guess config.h.in config.log \ ar-lib m4 Makefile.in missing src/Makefile src/Makefile.in \ test/Makefile test/Makefile.in test/hisi_hpre_test/Makefile.in \ test/hisi_hpre_test/Makefile test/hisi_sec_test/Makefile \ - test/hisi_sec_test/Makefile.in test/hisi_zip_test/Makefile \ - test/hisi_zip_test/Makefile.in uadk_tool/Makefile \ - uadk_tool/Makefile.in \ + test/hisi_sec_test/Makefile.in \ + uadk_tool/Makefile uadk_tool/Makefile.in \ v1/Makefile.in v1/Makefile.in v1/test/Makefile v1/test/Makefile.in \ v1/test/test_mm/Makefile v1/test/test_mm/Makefile.in \ v1/test/bmm_test/Makefile v1/test/bmm_test/Makefile.in" diff --git a/configure.ac b/configure.ac index de70457a..f5c625cc 100644 --- a/configure.ac +++ b/configure.ac @@ -95,7 +95,6 @@ AC_CONFIG_FILES([Makefile lib/libwd_crypto.pc lib/libwd_comp.pc lib/libwd.pc test/Makefile test/hisi_hpre_test/Makefile - test/hisi_zip_test/Makefile uadk_tool/Makefile sample/Makefile v1/test/Makefile diff --git a/test/Makefile.am b/test/Makefile.am index 5666000c..c7918f32 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,8 +16,4 @@ SUBDIRS = . if HAVE_CRYPTO SUBDIRS += hisi_hpre_test -if HAVE_ZLIB -SUBDIRS += hisi_zip_test -endif - endif diff --git a/test/hisi_zip_test/Makefile.am b/test/hisi_zip_test/Makefile.am deleted file mode 100644 index 8b464f58..00000000 --- a/test/hisi_zip_test/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -AM_CFLAGS=-Wall -Werror -fno-strict-aliasing -I$(top_srcdir)/include -AUTOMAKE_OPTIONS = subdir-objects - -bin_PROGRAMS=zip_sva_perf - -zip_sva_perf_SOURCES=testsuit.c test_lib.c - -if WD_STATIC_DRV -zip_sva_perf_LDADD=../../.libs/libwd.a ../../.libs/libwd_comp.a \ - ../../.libs/libhisi_zip.a -ldl -lpthread -lnuma $(libcrypto_LIBS) -else -zip_sva_perf_LDADD=-L../../.libs -l:libwd.so.2 -l:libwd_comp.so.2 \ - -lpthread -lnuma $(libcrypto_LIBS) -endif -zip_sva_perf_LDFLAGS=-Wl,-rpath,'/usr/local/lib' - -# For statistics -zip_sva_perf_LDADD+=-lm - -if HAVE_ZLIB -zip_sva_perf_LDADD+=-lz -zip_sva_perf_CPPFLAGS=-DUSE_ZLIB -endif diff --git a/test/hisi_zip_test/test_lib.c b/test/hisi_zip_test/test_lib.c deleted file mode 100644 index 384be496..00000000 --- a/test/hisi_zip_test/test_lib.c +++ /dev/null @@ -1,1874 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright 2020-2021 Huawei Technologies Co.,Ltd. All rights reserved. - * Copyright 2020-2021 Linaro ltd. - */ - -#include <pthread.h> -#include <signal.h> -#include <math.h> -#include <sys/mman.h> -#include <zlib.h> - -#include "test_lib.h" - -#define SCHED_RR_NAME "sched_rr" - -struct check_rand_ctx { - int off; - unsigned long global_off; - __u32 last; - unsigned short state[3]; -}; - -#define dbg(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__) - -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_spinlock_t lock; -static int count = 0; - -static struct wd_ctx_config *g_conf; - -int sum_pend = 0, sum_thread_end = 0; - -__attribute__((constructor)) -void lock_constructor(void) -{ - if (pthread_spin_init(&lock, PTHREAD_PROCESS_SHARED) != 0) - exit(1); -} - -__attribute__((destructor)) -void lock_destructor(void) -{ - if (pthread_spin_destroy(&lock) != 0) - exit(1); -} - -void *mmap_alloc(size_t len) -{ - void *p; - long page_size = sysconf(_SC_PAGESIZE); - - if (len % page_size) - return malloc(len); - - p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); - if (p == MAP_FAILED) - WD_ERR("Failed to allocate %zu bytes\n", len); - - return p == MAP_FAILED ? NULL : p; -} - -int mmap_free(void *addr, size_t len) -{ - long page_size = sysconf(_SC_PAGESIZE); - - if (len % page_size) { - free(addr); - return 0; - } - - return munmap(addr, len); -} - -static int hizip_check_rand(unsigned char *buf, unsigned int size, void *opaque) -{ - int i; - int *j; - __u32 n; - struct check_rand_ctx *rand_ctx = opaque; - - j = &rand_ctx->off; - for (i = 0; i < size; i += 4) { - if (*j) { - /* Something left from a previous run */ - n = rand_ctx->last; - } else { - n = nrand48(rand_ctx->state); - rand_ctx->last = n; - } - for (; *j < 4 && i + *j < size; (*j)++) { - char expected = (n >> (8 * *j)) & 0xff; - char actual = buf[i + *j]; - - if (expected != actual) { - WD_ERR("Invalid decompressed char at offset %lu: expected 0x%x != 0x%x\n", - rand_ctx->global_off + i + *j, expected, - actual); - return -EINVAL; - } - } - if (*j == 4) - *j = 0; - } - rand_ctx->global_off += size; - return 0; -} - -static struct wd_datalist *get_datalist(void *addr, __u32 size) -{ - int count = (int)ceil((double)size / SGE_SIZE); - struct wd_datalist *head, *cur, *tmp; - int i; - - head = calloc(1, sizeof(struct wd_datalist)); - if (!head) { - WD_ERR("failed to alloc datalist head\n"); - return NULL; - } - - cur = head; - - for (i = 0; i < count; i++) { - cur->data = addr; - cur->len = (size > SGE_SIZE) ? SGE_SIZE : size; - addr += SGE_SIZE; - size -= SGE_SIZE; - if (i != count - 1) { - tmp = calloc(1, sizeof(struct wd_datalist)); - cur->next = tmp; - cur = tmp; - } - } - - return head; -} - -/** - * compress() - compress memory buffer. - * @alg_type: alg_type. - * - * This function compress memory buffer. - */ -int hw_blk_compress(int alg_type, int blksize, __u8 data_fmt, void *priv, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_datalist *list; - struct wd_comp_req req; - int ret = 0; - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_COMPRESS; - setup.comp_lv = WD_COMP_L8; - setup.win_sz = WD_COMP_WS_8K; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - - if (data_fmt) { - WD_ERR("now sge size is %u\n", SGE_SIZE); - list = get_datalist(src, (__u32)srclen); - req.list_src = list; - list = get_datalist(dst, (__u32)*dstlen); - req.list_dst = list; - } else { - req.src = src; - req.dst = dst; - } - - req.src_len = srclen; - req.dst_len = *dstlen; - req.op_type = WD_DIR_COMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - req.priv = priv; - - dbg("%s:input req: src_len: %d, dst_len:%d, data_fmt:%d\n", - __func__, req.src_len, req.dst_len, req.data_fmt); - - ret = wd_do_comp_sync(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:input req: src_len: %d, dst_len:%d, data_fmt:%d\n", - __func__, req.src_len, req.dst_len, req.data_fmt); - - wd_comp_free_sess(h_sess); - - return ret; -} - -int hw_blk_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_datalist *list; - struct wd_comp_req req; - int ret = 0; - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - - if (data_fmt) { - WD_ERR("now sge size is %u\n", SGE_SIZE); - list = get_datalist(src, (__u32)srclen); - req.list_src = list; - list = get_datalist(dst, (__u32)*dstlen); - req.list_dst = list; - } else { - req.src = src; - req.dst = dst; - } - - req.src_len = srclen; - req.dst_len = *dstlen; - req.op_type = WD_DIR_DECOMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - - dbg("%s:input req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - - ret = wd_do_comp_sync(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:output req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - wd_comp_free_sess(h_sess); - - return ret; -} - -int hw_stream_compress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_comp_req req; - int ret = 0; - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_COMPRESS; - setup.comp_lv = WD_COMP_L8; - setup.win_sz = WD_COMP_WS_8K; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - req.src = src; - req.src_len = srclen; - req.dst = dst; - req.dst_len = *dstlen; - req.op_type = WD_DIR_COMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - - dbg("%s:input req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - ret = wd_do_comp_sync2(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:output req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - wd_comp_free_sess(h_sess); - - return ret; -} - - -int hw_stream_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_comp_req req; - int ret = 0; - - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - req.src = src; - req.src_len = srclen; - req.dst = dst; - req.dst_len = *dstlen; - req.op_type = WD_DIR_DECOMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - - dbg("%s:input req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - - ret = wd_do_comp_sync2(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:output req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - wd_comp_free_sess(h_sess); - - return ret; -} - -void hizip_prepare_random_input_data(char *buf, size_t len, size_t block_size) -{ - __u32 seed = 0; - unsigned short rand_state[3] = {(seed >> 16) & 0xffff, seed & 0xffff, 0x330e}; - - unsigned long remain_size; - __u32 size; - size_t i, j; - - /* - * TODO: change state for each buffer, to make sure there is no TLB - * aliasing. - */ - remain_size = len; - - while (remain_size > 0) { - if (remain_size > block_size) - size = block_size; - else - size = remain_size; - /* - * Prepare the input buffer with a reproducible sequence of - * numbers. nrand48() returns a pseudo-random number in the - * interval [0; 2^31). It's not really possible to compress a - * pseudo-random stream using deflate, since it can't find any - * string repetition. As a result the output size is bigger, - * with a ratio of 1.041. - */ - for (i = 0; i < size; i += 4) { - __u64 n = nrand48(rand_state); - - for (j = 0; j < 4 && i + j < size; j++) - buf[i + j] = (n >> (8 * j)) & 0xff; - } - - buf += size; - remain_size -= size; - } -} - -int hizip_prepare_random_compressed_data(char *buf, size_t out_len, size_t in_len, - size_t *produced, - struct test_options *opts) -{ - off_t off; - int ret = -EINVAL; - void *init_buf = mmap_alloc(in_len); - size_t in_block_size = opts->block_size; - size_t out_block_size = 2 * in_block_size; - - if (!init_buf) - return -ENOMEM; - - hizip_prepare_random_input_data(init_buf, in_len, opts->block_size); - - /* Compress each chunk separately since we're working in stateless mode */ - for (off = 0; off < in_len; off += in_block_size) { - ret = zlib_deflate(buf, out_block_size, init_buf + off, - in_block_size, produced, opts->alg_type); - if (ret) - break; - buf += out_block_size; - } - - munmap(init_buf, in_len); - return ret; -} - -int hizip_verify_random_output(struct test_options *opts, - struct hizip_test_info *info, - size_t out_sz) -{ - int ret; - int seed = 0; - off_t off = 0; - size_t checked = 0; - size_t total_checked = 0; - struct check_rand_ctx rand_ctx = { - .state = {(seed >> 16) & 0xffff, seed & 0xffff, 0x330e}, - }; - - if (!opts->verify) - return 0; - - if (opts->op_type == WD_DIR_DECOMPRESS) - /* Check plain output */ - return hizip_check_rand((void *)info->out_buf, out_sz, - &rand_ctx); - - do { - ret = hizip_check_output(info->out_buf + off, out_sz, - &checked, hizip_check_rand, &rand_ctx); - if (ret) { - WD_ERR("Check output failed with %d\n", ret); - return ret; - } - total_checked += checked; - off += opts->block_size * EXPANSION_RATIO; - } while (!ret && total_checked < opts->total_len); - - if (rand_ctx.global_off != opts->total_len) { - WD_ERR("Invalid output size %lu != %lu\n", - rand_ctx.global_off, opts->total_len); - return -EINVAL; - } - return 0; -} - -static void *async_cb(struct wd_comp_req *req, void *data) -{ - return NULL; -} - -void *send_thread_func(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - size_t src_block_size, dst_block_size; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - handle_t h_sess; - int j, ret; - size_t left; - - if (opts->op_type == WD_DIR_COMPRESS) { - src_block_size = opts->block_size; - dst_block_size = opts->block_size * EXPANSION_RATIO; - } else { - src_block_size = opts->block_size * EXPANSION_RATIO; - dst_block_size = opts->block_size; - } - - memset(&setup, 0, sizeof(struct wd_comp_sess_setup)); - setup.alg_type = opts->alg_type; - setup.op_type = opts->op_type; - setup.comp_lv = WD_COMP_L8; - setup.win_sz = WD_COMP_WS_8K; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) - return NULL; - - for (j = 0; j < opts->compact_run_num; j++) { - if (opts->option & TEST_ZLIB) { - ret = zlib_deflate(info->out_buf, info->out_size, - info->in_buf, info->in_size, - &tdata->sum, opts->alg_type); - continue; - } - /* not TEST_ZLIB */ - left = opts->total_len; - tdata->req.op_type = opts->op_type; - tdata->req.src = info->in_buf; - tdata->req.dst = info->out_buf; - tdata->sum = 0; - while (left > 0) { - tdata->req.src_len = src_block_size; - tdata->req.dst_len = dst_block_size; - tdata->req.cb_param = &tdata->req; - if (opts->sync_mode) { - tdata->req.cb = async_cb; - count++; - ret = wd_do_comp_async(h_sess, &tdata->req); - } else { - tdata->req.cb = NULL; - ret = wd_do_comp_sync(h_sess, &tdata->req); - if (info->opts->faults & INJECT_SIG_WORK) - kill(getpid(), SIGTERM); - } - if (ret < 0) { - WD_ERR("do comp test fail with %d\n", ret); - return (void *)(uintptr_t)ret; - } else if (tdata->req.status) { - return (void *)(uintptr_t)tdata->req.status; - } - if (opts->op_type == WD_DIR_COMPRESS) - left -= src_block_size; - else - left -= dst_block_size; - tdata->req.src += src_block_size; - /* - * It's BLOCK (STATELESS) mode, so user needs to - * combine output buffer by himself. - */ - tdata->req.dst += dst_block_size; - tdata->sum += tdata->req.dst_len; - if (tdata->sum > info->out_size) { - fprintf(stderr, - "%s: exceed OUT limits (%ld > %ld)\n", - __func__, - tdata->sum, info->out_size); - break; - } - } - /* info->total_out are accessed by multiple threads */ - __atomic_add_fetch(&info->total_out, tdata->sum, - __ATOMIC_RELEASE); - } - wd_comp_free_sess(h_sess); - return NULL; -} - -int lib_poll_func(__u32 pos, __u32 expect, __u32 *count) -{ - int ret; - - ret = wd_comp_poll_ctx(pos, expect, count); - if (ret < 0) - return ret; - return 0; -} - -void *poll_thread_func(void *arg) -{ - struct hizip_test_info *info = (struct hizip_test_info *)arg; - int ret = 0, total = 0; - __u32 expected = 0, received; - - if (!info->opts->sync_mode) - return NULL; - while (1) { - if (info->opts->faults & INJECT_SIG_WORK) - kill(getpid(), SIGTERM); - - pthread_mutex_lock(&mutex); - if (!expected) - expected = 1; - if (count == 0) { - pthread_mutex_unlock(&mutex); - usleep(10); - continue; - } - expected = 1; - received = 0; - ret = wd_comp_poll(expected, &received); - if (ret == 0) - total += received; - if (count == total) { - pthread_mutex_unlock(&mutex); - break; - } else { - if (count > total) - expected = count - total; - pthread_mutex_unlock(&mutex); - usleep(10); - } - } - pthread_exit(NULL); -} - -int create_send_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg)) -{ - pthread_attr_t attr; - thread_data_t *tdatas; - int i, j, num, ret; - - num = opts->thread_num; - info->send_tds = calloc(1, sizeof(pthread_t) * num); - if (!info->send_tds) - return -ENOMEM; - info->send_tnum = num; - tdatas = calloc(1, sizeof(thread_data_t) * num); - if (!tdatas) { - ret = -ENOMEM; - goto out; - } - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - for (i = 0; i < num; i++) { - tdatas[i].info = info; - ret = pthread_create(&info->send_tds[i], &attr, - send_thread_func, &tdatas[i]); - if (ret < 0) { - fprintf(stderr, "Fail to create send thread %d (%d)\n", - i, ret); - goto out_thd; - } - } - pthread_attr_destroy(&attr); - g_conf = &info->ctx_conf; - return 0; -out_thd: - for (j = 0; j < i; j++) - pthread_cancel(info->send_tds[j]); - free(tdatas); -out: - free(info->send_tds); - return ret; -} - -int create_poll_threads(struct hizip_test_info *info, - void *(*poll_thread_func)(void *arg), - int num) -{ - struct test_options *opts = info->opts; - pthread_attr_t attr; - int i, ret; - - if (!opts->sync_mode) - return 0; - info->poll_tds = calloc(1, sizeof(pthread_t) * num); - if (!info->poll_tds) - return -ENOMEM; - info->poll_tnum = num; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - for (i = 0; i < num; i++) { - ret = pthread_create(&info->poll_tds[i], &attr, - poll_thread_func, info); - if (ret < 0) { - fprintf(stderr, "Fail to create send thread %d (%d)\n", - i, ret); - goto out; - } - } - pthread_attr_destroy(&attr); - count = 0; - return 0; -out: - free(info->poll_tds); - return ret; -} - -void free_threads(struct hizip_test_info *info) -{ - if (info->send_tds) - free(info->send_tds); - if (info->poll_tds) - free(info->poll_tds); -} - -int attach_threads(struct test_options *opts, struct hizip_test_info *info) -{ - int i, ret; - void *tret; - - if (opts->sync_mode) { - for (i = 0; i < info->poll_tnum; i++) { - ret = pthread_join(info->poll_tds[i], NULL); - if (ret < 0) - fprintf(stderr, "Fail on poll thread with %d\n", - ret); - } - } - for (i = 0; i < info->send_tnum; i++) { - ret = pthread_join(info->send_tds[i], &tret); - if (ret < 0) - fprintf(stderr, "Fail on send thread with %d\n", ret); - } - return (int)(uintptr_t)tret; -} - -void gen_random_data(void *buf, size_t len) -{ - int i; - uint32_t seed = 0; - unsigned short rand_state[3] = {(seed >> 16) & 0xffff, - seed & 0xffff, - 0x330e}; - - for (i = 0; i < len >> 3; i++) - *((uint64_t *)buf + i) = nrand48(rand_state); -} - -int calculate_md5(comp_md5_t *md5, const void *buf, size_t len) -{ - if (!md5 || !buf || !len) - return -EINVAL; - MD5_Init(&md5->md5_ctx); - MD5_Update(&md5->md5_ctx, buf, len); - MD5_Final(md5->md, &md5->md5_ctx); - return 0; -} - -void dump_md5(comp_md5_t *md5) -{ - int i; - - for (i = 0; i < MD5_DIGEST_LENGTH - 1; i++) - printf("%02x-", md5->md[i]); - printf("%02x\n", md5->md[i]); -} - -int cmp_md5(comp_md5_t *orig, comp_md5_t *final) -{ - int i; - - if (!orig || !final) - return -EINVAL; - for (i = 0; i < MD5_DIGEST_LENGTH; i++) { - if (orig->md[i] != final->md[i]) { - printf("Original MD5: "); - dump_md5(orig); - printf("Final MD5: "); - dump_md5(final); - return -EINVAL; - } - } - return 0; -} - -static void *async2_cb(struct wd_comp_req *req, void *data) -{ - sem_t *sem = (sem_t *)data; - - if (sem) - sem_post(sem); - return NULL; -} - -/* used in BATCH mode */ -static void *async5_cb(struct wd_comp_req *req, void *data) -{ - thread_data_t *tdata = (thread_data_t *)data; - - pthread_spin_lock(&lock); - tdata->pcnt++; - if (tdata->batch_flag && (tdata->pcnt == tdata->bcnt)) { - tdata->pcnt = 0; - tdata->bcnt = 0; - tdata->batch_flag = 0; - pthread_spin_unlock(&lock); - sem_post(&tdata->sem); - } else - pthread_spin_unlock(&lock); - return NULL; -} - -void init_chunk_list(chunk_list_t *list, void *buf, size_t buf_sz, - size_t chunk_sz) -{ - chunk_list_t *p = NULL; - int i, count; - size_t sum; - - count = (buf_sz + chunk_sz - 1) / chunk_sz; - for (i = 0, sum = 0, p = list; i < count && sum <= buf_sz; i++, p++) { - p->addr = buf + sum; - p->size = MIN(buf_sz - sum, chunk_sz); - if (i == count - 1) - p->next = NULL; - else - p->next = p + 1; - sum += p->size; - } -} - -chunk_list_t *create_chunk_list(void *buf, size_t buf_sz, size_t chunk_sz) -{ - chunk_list_t *list; - int count; - - count = (buf_sz + chunk_sz - 1) / chunk_sz; - if (count > HIZIP_CHUNK_LIST_ENTRIES) - count = HIZIP_CHUNK_LIST_ENTRIES; - if (buf_sz / chunk_sz > count) - return NULL; - /* allocate entries with additional one */ - list = malloc(sizeof(chunk_list_t) * (count + 1)); - if (!list) - return NULL; - init_chunk_list(list, buf, buf_sz, chunk_sz); - return list; -} - -void free_chunk_list(chunk_list_t *list) -{ - free(list); -} - -/* - * Deflate a data block with compressed header. - */ -static int chunk_deflate2(void *in, size_t in_sz, void *out, size_t *out_sz, - struct test_options *opts) -{ - int alg_type = opts->alg_type; - z_stream strm; - int windowBits; - int ret; - - switch (alg_type) { - case WD_ZLIB: - windowBits = 15; - break; - case WD_DEFLATE: - windowBits = -15; - break; - case WD_GZIP: - windowBits = 15 + 16; - break; - default: - printf("algorithm %d unsupported by zlib\n", alg_type); - return -EINVAL; - } - memset(&strm, 0, sizeof(z_stream)); - strm.next_in = in; - strm.avail_in = in_sz; - strm.next_out = out; - strm.avail_out = *out_sz; - - ret = deflateInit2(&strm, Z_BEST_SPEED, Z_DEFLATED, windowBits, - 8, Z_DEFAULT_STRATEGY); - if (ret != Z_OK) { - printf("deflateInit2: %d\n", ret); - return -EINVAL; - } - - do { - ret = deflate(&strm, Z_FINISH); - if ((ret == Z_STREAM_ERROR) || (ret == Z_BUF_ERROR)) { - printf("defalte error %d - %s\n", ret, strm.msg); - ret = -ENOSR; - break; - } else if (!strm.avail_in) { - if (ret != Z_STREAM_END) - printf("deflate unexpected return: %d\n", ret); - ret = 0; - break; - } else if (!strm.avail_out) { - printf("deflate out of memory\n"); - ret = -ENOSPC; - break; - } - } while (ret == Z_OK); - - deflateEnd(&strm); - *out_sz = *out_sz - strm.avail_out; - return ret; -} - - -/* - * This function is used in BLOCK mode. Each compressing in BLOCK mode - * produces compression header. - */ -static int chunk_inflate2(void *in, size_t in_sz, void *out, size_t *out_sz, - struct test_options *opts) -{ - z_stream strm; - int ret; - - memset(&strm, 0, sizeof(z_stream)); - /* Window size of 15, +32 for auto-decoding gzip/zlib */ - ret = inflateInit2(&strm, 15 + 32); - if (ret != Z_OK) { - printf("zlib inflateInit: %d\n", ret); - return -EINVAL; - } - - strm.next_in = in; - strm.avail_in = in_sz; - strm.next_out = out; - strm.avail_out = *out_sz; - do { - ret = inflate(&strm, Z_NO_FLUSH); - if ((ret < 0) || (ret == Z_NEED_DICT)) { - printf("zlib error %d - %s\n", ret, strm.msg); - goto out; - } - if (!strm.avail_out) { - if (!strm.avail_in || (ret == Z_STREAM_END)) - break; - printf("%s: avail_out is empty!\n", __func__); - goto out; - } - } while (strm.avail_in && (ret != Z_STREAM_END)); - inflateEnd(&strm); - *out_sz = *out_sz - strm.avail_out; - return 0; -out: - inflateEnd(&strm); - ret = -EINVAL; - return ret; -} - -/* - * Compress a list of chunk data and produce a list of chunk data by software. - * in_list & out_list should be formated first. - */ -int sw_deflate2(chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts) -{ - chunk_list_t *p, *q; - int ret = -EINVAL; - - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - ret = chunk_deflate2(p->addr, p->size, q->addr, &q->size, - opts); - if (ret) - return ret; - } - return ret; -} - -/* - * Compress a list of chunk data and produce a list of chunk data by software. - * in_list & out_list should be formated first. - */ -int sw_inflate2(chunk_list_t *in_list, chunk_list_t *out_list, - struct test_options *opts) -{ - chunk_list_t *p, *q; - int ret = -EINVAL; - - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - ret = chunk_inflate2(p->addr, p->size, q->addr, &q->size, - opts); - if (ret) - return ret; - } - return ret; -} - -int hw_deflate4(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem) -{ - struct wd_comp_req *reqs; - chunk_list_t *p = in_list, *q = out_list; - int i, ret; - - if (!in_list || !out_list || !opts || !sem) - return -EINVAL; - /* reqs array could make async operations in parallel */ - reqs = malloc(sizeof(struct wd_comp_req) * HIZIP_CHUNK_LIST_ENTRIES); - if (!reqs) - return -ENOMEM; - - for (i = 0; p && q; p = p->next, q = q->next, i++) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_COMPRESS; - - if (opts->sync_mode) { - reqs[i].cb = async2_cb; - reqs[i].cb_param = sem; - } - do { - if (opts->sync_mode) { - ret = wd_do_comp_async(h_dfl, &reqs[i]); - if (!ret) { - __atomic_add_fetch(&sum_pend, 1, - __ATOMIC_ACQ_REL); - sem_wait(sem); - } - } else - ret = wd_do_comp_sync(h_dfl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - q->size = reqs[i].dst_len; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - i++; - } - free(reqs); - return 0; -out: - free(reqs); - return ret; -} - -int hw_inflate4(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem) -{ - struct wd_comp_req *reqs; - chunk_list_t *p, *q; - int i = 0, ret; - - /* reqs array could make async operations in parallel */ - reqs = calloc(1, sizeof(struct wd_comp_req) * HIZIP_CHUNK_LIST_ENTRIES); - if (!reqs) - return -ENOMEM; - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_DECOMPRESS; - if (opts->sync_mode) { - reqs[i].cb = async2_cb; - reqs[i].cb_param = sem; - } - do { - if (opts->sync_mode) { - ret = wd_do_comp_async(h_ifl, &reqs[i]); - if (!ret) { - __atomic_add_fetch(&sum_pend, 1, - __ATOMIC_ACQ_REL); - sem_wait(sem); - } - } else - ret = wd_do_comp_sync(h_ifl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - q->size = reqs[i].dst_len; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - i++; - } - free(reqs); - return 0; -out: - free(reqs); - return ret; -} - -/* used in BATCH mode */ -int hw_deflate5(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata) -{ - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_req *reqs = tdata->reqs; - chunk_list_t *p = in_list, *q = out_list; - int i = 0, ret = 0; - - if (!in_list || !out_list || !opts) - return -EINVAL; - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_COMPRESS; - reqs[i].data_fmt = opts->data_fmt; - if (opts->sync_mode) { - reqs[i].cb = async5_cb; - reqs[i].cb_param = tdata; - } else { - reqs[i].cb = NULL; - reqs[i].cb_param = NULL; - } - if (opts->sync_mode) { - do { - ret = wd_do_comp_async(h_dfl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret < 0) - goto out; - __atomic_add_fetch(&sum_pend, 1, __ATOMIC_ACQ_REL); - pthread_spin_lock(&lock); - tdata->bcnt++; - if (((i + 1) == opts->batch_num) || !p->next) { - tdata->batch_flag = 1; - pthread_spin_unlock(&lock); - sem_wait(&tdata->sem); - } else - pthread_spin_unlock(&lock); - } else { - do { - ret = wd_do_comp_sync(h_dfl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - } - q->size = reqs[i].dst_len; - i = (i + 1) % opts->batch_num; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - } - return 0; -out: - return ret; -} - -/* used in BATCH mode */ -int hw_inflate5(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata) -{ - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_req *reqs = tdata->reqs; - chunk_list_t *p = in_list, *q = out_list; - int ret = 0, i = 0; - - if (!in_list || !out_list || !opts) - return -EINVAL; - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_DECOMPRESS; - reqs[i].data_fmt = opts->data_fmt; - if (opts->sync_mode) { - reqs[i].cb = async5_cb; - reqs[i].cb_param = tdata; - } else { - reqs[i].cb = NULL; - reqs[i].cb_param = NULL; - } - if (opts->sync_mode) { - do { - ret = wd_do_comp_async(h_ifl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret < 0) - goto out; - __atomic_add_fetch(&sum_pend, 1, __ATOMIC_ACQ_REL); - pthread_spin_lock(&lock); - tdata->bcnt++; - if (((i + 1) == opts->batch_num) || !p->next) { - tdata->batch_flag = 1; - pthread_spin_unlock(&lock); - sem_wait(&tdata->sem); - } else - pthread_spin_unlock(&lock); - } else { - do { - ret = wd_do_comp_sync(h_ifl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - } - q->size = reqs[i].dst_len; - i = (i + 1) % opts->batch_num; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - } - return 0; -out: - return ret; -} - -/* - * info->in_buf & info->out_buf should be allocated first. - * Thread 0 shares info->out_buf. Other threads need to create its own - * dst buffer. - */ -int create_send_tdata(struct test_options *opts, - struct hizip_test_info *info) -{ - thread_data_t *tdata; - chunk_list_t *in_list, *out_list; - int i, j, num, ret; - - if (!opts || !info || !info->in_chunk_sz || !info->out_chunk_sz) - return -EINVAL; - num = opts->thread_num; - info->send_tds = calloc(1, sizeof(pthread_t) * num); - if (!info->send_tds) - return -ENOMEM; - info->send_tnum = num; - info->tdatas = calloc(1, sizeof(thread_data_t) * num); - if (!info->tdatas) { - ret = -ENOMEM; - goto out; - } - if (!opts->batch_num) - opts->batch_num = 1; - else if (opts->batch_num > HIZIP_CHUNK_LIST_ENTRIES) - opts->batch_num = HIZIP_CHUNK_LIST_ENTRIES; - if (opts->is_stream) { - in_list = create_chunk_list(info->in_buf, info->in_size, - info->in_size); - } else { - in_list = create_chunk_list(info->in_buf, info->in_size, - info->in_chunk_sz); - } - if (!in_list) { - ret = -EINVAL; - goto out_in; - } - if (opts->option & TEST_THP) { - ret = madvise(info->in_buf, info->in_size, MADV_HUGEPAGE); - if (ret) { - printf("madvise(MADV_HUGEPAGE)"); - goto out_in; - } - } - for (i = 0; i < num; i++) { - tdata = &info->tdatas[i]; - /* src address is shared among threads */ - tdata->tid = i; - tdata->src_sz = info->in_size; - tdata->src = info->in_buf; - tdata->in_list = in_list; - tdata->dst_sz = info->out_size; - tdata->dst = mmap_alloc(tdata->dst_sz); - if (!tdata->dst) { - ret = -ENOMEM; - goto out_dst; - } - if (opts->option & TEST_THP) { - ret = madvise(tdata->dst, tdata->dst_sz, MADV_HUGEPAGE); - if (ret) { - printf("madvise(MADV_HUGEPAGE)"); - goto out_dst; - } - } - /* - * Without memset, valgrind reports uninitialized buf - * for writing to file. - */ - memset(tdata->dst, 0, tdata->dst_sz); - if (opts->is_stream) { - out_list = create_chunk_list(tdata->dst, - tdata->dst_sz, - tdata->dst_sz); - } else { - out_list = create_chunk_list(tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - } - tdata->out_list = out_list; - if (!tdata->out_list) { - ret = -EINVAL; - goto out_list; - } - calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - tdata->reqs = malloc(sizeof(struct wd_comp_req) * - opts->batch_num); - if (!tdata->reqs) - goto out_list; - sem_init(&tdata->sem, 0, 0); - tdata->info = info; - } - return 0; -out_list: - mmap_free(tdata->dst, tdata->dst_sz); -out_dst: - for (j = 0; j < i; j++) { - pthread_cancel(info->send_tds[j]); - free_chunk_list(info->tdatas[j].out_list); - mmap_free(info->tdatas[j].dst, info->tdatas[j].dst_sz); - } - free_chunk_list(in_list); -out_in: - free(info->tdatas); -out: - free(info->send_tds); - return ret; -} - -int create_poll_tdata(struct test_options *opts, - struct hizip_test_info *info, - int poll_num) -{ - thread_data_t *tdatas; - int i, ret; - - if (opts->sync_mode == 0) - return 0; - else if (poll_num <= 0) - return -EINVAL; - info->poll_tnum = poll_num; - info->poll_tds = calloc(1, sizeof(pthread_t) * poll_num); - if (!info->poll_tds) - return -ENOMEM; - info->p_tdatas = calloc(1, sizeof(thread_data_t) * poll_num); - if (!info->p_tdatas) { - ret = -ENOMEM; - goto out; - } - tdatas = info->p_tdatas; - for (i = 0; i < poll_num; i++) { - tdatas[i].tid = i; - tdatas[i].info = info; - } - return 0; -out: - free(info->poll_tds); - return ret; -} - -/* - * Free source and destination buffer contained in sending threads. - * Free sending threads and polling threads. - */ -void free2_threads(struct hizip_test_info *info) -{ - thread_data_t *tdatas = info->tdatas; - int i; - - if (info->send_tds) - free(info->send_tds); - if (info->poll_tds) { - free(info->poll_tds); - free(info->p_tdatas); - } - free_chunk_list(tdatas[0].in_list); - for (i = 0; i < info->send_tnum; i++) { - free_chunk_list(tdatas[i].out_list); - free(tdatas[i].reqs); - } - /* info->out_buf is bound to tdatas[0].dst */ - for (i = 0; i < info->send_tnum; i++) - mmap_free(tdatas[i].dst, tdatas[i].dst_sz); - free(info->tdatas); - mmap_free(info->in_buf, info->in_size); -} - -int attach2_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg), - void *(*poll_thread_func)(void *arg)) -{ - int i, j, ret, num; - void *tret; - pthread_attr_t attr; - - num = opts->thread_num; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - for (i = 0; i < num; i++) { - ret = pthread_create(&info->send_tds[i], &attr, - send_thread_func, &info->tdatas[i]); - if (ret < 0) { - printf("Fail to create send thread %d (%d)\n", i, ret); - goto out; - } - } - if (opts->sync_mode && !opts->use_env) { - for (i = 0; i < opts->poll_num; i++) { - ret = pthread_create(&info->poll_tds[i], &attr, - poll_thread_func, - &info->tdatas[i]); - if (ret < 0) { - printf("Fail to create poll thread %d (%d)\n", - i, ret); - goto out_poll; - } - } - for (i = 0; i < info->poll_tnum; i++) { - ret = pthread_join(info->poll_tds[i], &tret); - if (ret < 0) { - fprintf(stderr, "Fail on poll thread with %d\n", - ret); - goto out_poll; - } - } - } - for (i = 0; i < info->send_tnum; i++) { - ret = pthread_join(info->send_tds[i], &tret); - if (ret < 0) { - fprintf(stderr, "Fail on send thread with %d\n", ret); - goto out_poll; - } - } - pthread_attr_destroy(&attr); - return (int)(uintptr_t)tret; -out_poll: - for (j = 0; j < i; j++) - pthread_cancel(info->poll_tds[j]); - i = opts->thread_num; -out: - for (j = 0; j < i; j++) - pthread_cancel(info->send_tds[j]); - pthread_attr_destroy(&attr); - return ret; -} - -void *poll2_thread_func(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - __u32 received; - int ret = 0; - struct timeval start_tvl, end_tvl; - int pending; - int end_threads; - - gettimeofday(&start_tvl, NULL); - while (1) { - end_threads = __atomic_load_n(&sum_thread_end, - __ATOMIC_ACQUIRE); - pending = __atomic_load_n(&sum_pend, __ATOMIC_ACQUIRE); - if ((end_threads == info->send_tnum) && (pending == 0)) - break; - else if (pending == 0) - continue; - received = 0; - ret = wd_comp_poll(pending, &received); - if (ret == 0) { - __atomic_sub_fetch(&sum_pend, - received, - __ATOMIC_ACQ_REL); - } - } - gettimeofday(&end_tvl, NULL); - timersub(&end_tvl, &start_tvl, &start_tvl); - pthread_exit(NULL); -} - -/* - * Choose a device and check whether it can afford the requested contexts. - * Return a list whose the first device is chosen. - */ -struct uacce_dev_list *get_dev_list(struct test_options *opts, - int children) -{ - struct uacce_dev_list *list, *p, *head = NULL, *prev = NULL; - int max_q_num; - - list = wd_get_accel_list("zlib"); - if (!list) - return NULL; - - p = list; - /* Find one device matching the requested contexts. */ - while (p) { - max_q_num = wd_get_avail_ctx(p->dev); - /* - * Check whether there's enough contexts. - * There may be multiple taskes running together. - * The number of multiple taskes is specified in children. - */ - if (max_q_num < 4 * opts->q_num * children) { - if (!head) - head = p; - prev = p; - p = p->next; - } else - break; - } - - if (!p) { - WD_ERR("Request too much contexts: %d\n", - opts->q_num * 4 * children); - goto out; - } - - /* Adjust p to the head of list if p is in the middle. */ - if (p && (p != list)) { - prev->next = p->next; - p->next = head; - return p; - } - return list; -out: - wd_free_list_accels(list); - return NULL; -} - -/* - * Initialize context numbers by the four times of opts->q_num. - * [sync, async] * [compress, decompress] = 4 - */ -int init_ctx_config(struct test_options *opts, void *priv, - struct wd_sched **sched) -{ - struct hizip_test_info *info = priv; - struct wd_ctx_config *ctx_conf = &info->ctx_conf; - struct sched_params param; - int i, j, ret = -EINVAL; - int q_num = opts->q_num; - - - __atomic_store_n(&sum_pend, 0, __ATOMIC_RELEASE); - __atomic_store_n(&sum_thread_end, 0, __ATOMIC_RELEASE); - *sched = wd_sched_rr_alloc(SCHED_POLICY_RR, 2, 2, lib_poll_func); - if (!*sched) { - WD_ERR("wd_sched_rr_alloc fail\n"); - goto out_sched; - } - - (*sched)->name = SCHED_RR_NAME; - - memset(ctx_conf, 0, sizeof(struct wd_ctx_config)); - ctx_conf->ctx_num = q_num * 4; - ctx_conf->ctxs = calloc(1, q_num * 4 * sizeof(struct wd_ctx)); - if (!ctx_conf->ctxs) { - WD_ERR("Not enough memory to allocate contexts.\n"); - ret = -ENOMEM; - goto out_ctx; - } - for (i = 0; i < ctx_conf->ctx_num; i++) { - ctx_conf->ctxs[i].ctx = wd_request_ctx(info->list->dev); - if (!ctx_conf->ctxs[i].ctx) { - WD_ERR("Fail to allocate context #%d\n", i); - ret = -EINVAL; - goto out_req; - } - } - /* - * All contexts for 2 modes & 2 types. - * The test only uses one kind of contexts at the same time. - */ - for (i = 0; i < q_num; i++) { - ctx_conf->ctxs[i].ctx_mode = 0; - ctx_conf->ctxs[i].op_type = 0; - } - param.numa_id = 0; - param.mode = 0; - param.type = 0; - param.begin = 0; - param.end = q_num - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - for (i = q_num; i < q_num * 2; i++) { - ctx_conf->ctxs[i].ctx_mode = 0; - ctx_conf->ctxs[i].op_type = 1; - } - param.mode = 0; - param.type = 1; - param.begin = q_num; - param.end = q_num * 2 - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - for (i = q_num * 2; i < q_num * 3; i++) { - ctx_conf->ctxs[i].ctx_mode = 1; - ctx_conf->ctxs[i].op_type = 0; - } - param.mode = 1; - param.type = 0; - param.begin = q_num * 2; - param.end = q_num * 3 - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - for (i = q_num * 3; i < q_num * 4; i++) { - ctx_conf->ctxs[i].ctx_mode = 1; - ctx_conf->ctxs[i].op_type = 1; - } - param.mode = 1; - param.type = 1; - param.begin = q_num * 3; - param.end = q_num * 4 - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - - ret = wd_comp_init(ctx_conf, *sched); - if (ret) - goto out_fill; - return ret; - -out_fill: - for (i = 0; i < ctx_conf->ctx_num; j++) - wd_release_ctx(ctx_conf->ctxs[i].ctx); -out_req: - free(ctx_conf->ctxs); -out_ctx: - wd_sched_rr_release(*sched); -out_sched: - return ret; -} - -void uninit_config(void *priv, struct wd_sched *sched) -{ - struct hizip_test_info *info = priv; - struct wd_ctx_config *ctx_conf = &info->ctx_conf; - int i; - - wd_comp_uninit(); - for (i = 0; i < ctx_conf->ctx_num; i++) - wd_release_ctx(ctx_conf->ctxs[i].ctx); - free(ctx_conf->ctxs); - wd_sched_rr_release(sched); -} - - -int parse_common_option(const char opt, const char *optarg, - struct test_options *opts) -{ - switch (opt) { - case 'b': - opts->block_size = strtol(optarg, NULL, 0); - if (opts->block_size <= 0) - return 1; - break; - case 'l': - opts->compact_run_num = strtol(optarg, NULL, 0); - if (opts->compact_run_num <= 0) - return 1; - break; - case 'n': - opts->run_num = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->run_num > MAX_RUNS, - "No more than %d runs supported\n", MAX_RUNS); - if (opts->run_num <= 0) - return 1; - break; - case 'q': - opts->q_num = strtol(optarg, NULL, 0); - if (opts->q_num <= 0) - return 1; - break; - case 'd': - opts->op_type = WD_DIR_DECOMPRESS; - break; - case 'F': - opts->is_file = true; - break; - case 'S': - opts->is_stream = MODE_STREAM; - break; - case 's': - opts->total_len = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->total_len <= 0, "invalid size '%s'\n", - optarg); - break; - case 't': - opts->thread_num = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->thread_num < 0, "invalid thread num '%s'\n", - optarg); - break; - case 'm': - opts->sync_mode = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->sync_mode < 0 || opts->sync_mode > 1, - "invalid sync mode '%s'\n", optarg); - break; - case 'V': - opts->verify = true; - break; - case 'v': - opts->verbose = true; - break; - case 'a': - opts->alg_type = WD_DEFLATE; - break; - case 'z': - opts->alg_type = WD_ZLIB; - break; - case 'L': - opts->data_fmt = WD_SGL_BUF; - break; - case 'Z': - opts->alg_type = WD_LZ77_ZSTD; - break; - default: - return 1; - } - - return 0; -} - -#ifdef HAVE_ZLIB - -#include <zlib.h> - -/* - * Try to decompress a buffer using zLib's inflate(). Call compare_output with - * the decompressed stream as argument - * - * Return 0 on success, or an error. - */ -int hizip_check_output(void *buf, size_t size, size_t *checked, - check_output_fn compare_output, void *opaque) -{ - int ret, ret2; - unsigned char *out_buffer; - const size_t out_buf_size = 0x100000; - z_stream stream = { - .next_in = buf, - .avail_in = size, - }; - - out_buffer = calloc(1, out_buf_size); - if (!out_buffer) - return -ENOMEM; - - stream.next_out = out_buffer; - stream.avail_out = out_buf_size; - - /* Window size of 15, +32 for auto-decoding gzip/zlib */ - ret = inflateInit2(&stream, 15 + 32); - if (ret != Z_OK) { - WD_ERR("zlib inflateInit: %d\n", ret); - ret = -EINVAL; - goto out_free_buf; - } - - do { - ret = inflate(&stream, Z_NO_FLUSH); - if (ret < 0 || ret == Z_NEED_DICT) { - WD_ERR("zlib error %d - %s\n", ret, stream.msg); - ret = -ENOSR; - break; - } - - ret2 = compare_output(out_buffer, out_buf_size - - stream.avail_out, opaque); - /* compare_output should print diagnostic messages. */ - if (ret2) { - ret = Z_STREAM_ERROR; - break; - } - - if (!stream.avail_out) { - stream.next_out = out_buffer; - stream.avail_out = out_buf_size; - } - } while (ret != Z_STREAM_END); - - if (ret == Z_STREAM_END || ret == Z_OK) { - *checked = stream.total_out; - ret = 0; - } - - inflateEnd(&stream); -out_free_buf: - free(out_buffer); - return ret; -} - -int zlib_deflate(void *output, unsigned int out_size, - void *input, unsigned int in_size, - unsigned long *produced, int alg_type) -{ - int ret; - int windowBits; - z_stream stream = { - .next_in = input, - .avail_in = in_size, - .next_out = output, - .avail_out = out_size, - }; - - switch (alg_type) { - case WD_ZLIB: - windowBits = 15; - break; - case WD_DEFLATE: - windowBits = -15; - break; - case WD_GZIP: - windowBits = 15 + 16; - break; - default: - WD_ERR("algorithm %d unsupported by zlib\n", alg_type); - return -EINVAL; - } - - ret = deflateInit2(&stream, Z_BEST_SPEED, Z_DEFLATED, windowBits, 9, - Z_DEFAULT_STRATEGY); - if (ret != Z_OK) { - WD_ERR("zlib deflateInit: %d\n", ret); - return -EINVAL; - } - - do { - ret = deflate(&stream, Z_FINISH); - if (ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR) { - WD_ERR("zlib error %d - %s\n", ret, stream.msg); - ret = -ENOSR; - break; - } else if (!stream.avail_in) { - if (ret != Z_STREAM_END) - WD_ERR("unexpected deflate return value %d\n", ret); - *produced = stream.total_out; - ret = 0; - break; - } else if (!stream.avail_out) { - WD_ERR("No more output available\n"); - ret = -ENOSPC; - break; - } - } while (ret == Z_OK); - - deflateEnd(&stream); - - return ret; -} -#endif diff --git a/test/hisi_zip_test/test_lib.h b/test/hisi_zip_test/test_lib.h deleted file mode 100644 index 70d2c9d6..00000000 --- a/test/hisi_zip_test/test_lib.h +++ /dev/null @@ -1,352 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright 2020-2021 Huawei Technologies Co.,Ltd. All rights reserved. - * Copyright 2020-2021 Linaro ltd. - */ - -#ifndef TEST_LIB_H_ -#define TEST_LIB_H_ - -#include <errno.h> -#include <openssl/md5.h> -#include <semaphore.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <sys/resource.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <unistd.h> -#include "config.h" -#include "wd_comp.h" -#include "wd_sched.h" - -#define SYS_ERR_COND(cond, msg, ...) \ -do { \ - if (cond) { \ - if (errno) \ - perror(msg); \ - else \ - fprintf(stderr, msg, ##__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } \ -} while (0) - -enum mode { - MODE_BLOCK, - MODE_STREAM, -}; - -#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) -#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) -#define MIN(a, b) ((a < b) ? a : b) - -/* - * I observed a worst case of 1.041x expansion with random data, but let's say 2 - * just in case. TODO: reduce this - */ -#define EXPANSION_RATIO 2 -/* The INFLATION_RATIO is high for text file. */ -#define INFLATION_RATIO 24 - -#define SGE_SIZE (8 * 1024) - -#define HIZIP_CHUNK_LIST_ENTRIES 32768 - -struct test_options { - int alg_type; - int op_type; - - /* bytes of data for a request */ - int block_size; - int q_num; - unsigned long total_len; - -#define MAX_RUNS 1024 - int run_num; - /* tasks running in parallel */ - int compact_run_num; - - /* send thread number */ - int thread_num; - /* poll thread number -- ASYNC */ - int poll_num; - /* 0: sync mode, 1: async mode */ - int sync_mode; - /* - * positive value: the number of messages are sent at a time. - * 0: batch mode is disabled. - * batch mode is only valid for ASYNC operations. - */ - int batch_num; - /* input file */ - int fd_in; - /* output file */ - int fd_out; - /* inlist file */ - int fd_ilist; - /* outlist file */ - int fd_olist; - - /* 0: pbuffer, 1: sgl */ - __u8 data_fmt; - - bool verify; - bool verbose; - bool is_decomp; - bool is_stream; - bool is_file; - bool use_env; - - int warmup_num; - -#define PERFORMANCE (1UL << 0) -#define TEST_ZLIB (1UL << 1) -#define TEST_THP (1UL << 2) - unsigned long option; - -#define STATS_NONE 0 -#define STATS_PRETTY 1 -#define STATS_CSV 2 - unsigned long display_stats; - - /* bind test case related below */ - int children; - -#define INJECT_SIG_BIND (1UL << 0) -#define INJECT_SIG_WORK (1UL << 1) -#define INJECT_TLB_FAULT (1UL << 2) - unsigned long faults; - -}; - -typedef struct _comp_md5_t { - MD5_CTX md5_ctx; - unsigned char md[MD5_DIGEST_LENGTH]; -} comp_md5_t; - -typedef struct hizip_chunk_list { - void *addr; - size_t size; - struct hizip_chunk_list *next; -} chunk_list_t; - -typedef struct _thread_data_t { - struct hizip_test_info *info; - struct wd_comp_req req; - comp_md5_t md5; - void *src; - void *dst; - size_t src_sz; - size_t dst_sz; - size_t sum; /* produced bytes for OUT */ - int tid; /* thread ID */ - int bcnt; /* batch mode: count */ - int pcnt; /* batch mode: poll count */ - int flush_bcnt; /* batch mode: flush count that is less batch_num */ - /* - * batch mode: set flag and wait batch end in sending thread. - * Clear batch flag if pcnt == bcnt in polling thread. - * batch_flag could replace flush_bcnt. - */ - int batch_flag; - sem_t sem; - chunk_list_t *in_list; - chunk_list_t *out_list; - struct wd_comp_req *reqs; -} thread_data_t; - -struct hizip_test_info { - struct test_options *opts; - char *in_buf, *out_buf; - size_t in_size, out_size; - /* in_chunk_sz & out_chunk_sz are used to format entries in list */ - size_t in_chunk_sz, out_chunk_sz; - size_t total_out; - struct uacce_dev_list *list; - handle_t h_sess; - struct wd_ctx_config ctx_conf; - pthread_t *send_tds; - int send_tnum; - pthread_t *poll_tds; - int poll_tnum; - /* tdatas: send thread data array, p_tdatas: poll thread data array */ - thread_data_t *tdatas; - thread_data_t *p_tdatas; - struct hizip_stats *stats; - struct { - struct timespec setup_time; - struct timespec start_time; - struct timespec end_time; - struct timespec setup_cputime; - struct timespec start_cputime; - struct timespec end_cputime; - struct rusage setup_rusage; - struct rusage start_rusage; - struct rusage end_rusage; - } tv; -}; - -extern int sum_pend, sum_thread_end; - -void *send_thread_func(void *arg); -void *poll_thread_func(void *arg); -void *sw_dfl_sw_ifl(void *arg); -int create_send_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg)); -int create_poll_threads(struct hizip_test_info *info, - void *(*poll_thread_func)(void *arg), - int num); -void free_threads(struct hizip_test_info *info); -int attach_threads(struct test_options *opts, - struct hizip_test_info *info); - -void gen_random_data(void *buf, size_t len); -int calculate_md5(comp_md5_t *md5, const void *buf, size_t len); -void dump_md5(comp_md5_t *md5); -int cmp_md5(comp_md5_t *orig, comp_md5_t *final); -void init_chunk_list(chunk_list_t *list, void *buf, size_t buf_sz, - size_t chunk_sz); -chunk_list_t *create_chunk_list(void *buf, size_t buf_sz, size_t chunk_sz); -void free_chunk_list(chunk_list_t *list); -int sw_deflate2(chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts); -int sw_inflate2(chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts); -int hw_deflate4(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem); -int hw_inflate4(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem); -int hw_deflate5(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata); -int hw_inflate5(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata); -int create_send_tdata(struct test_options *opts, - struct hizip_test_info *info); -int create_poll_tdata(struct test_options *opts, - struct hizip_test_info *info, - int poll_num); -void free2_threads(struct hizip_test_info *info); -int attach2_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg), - void *(*poll_thread_func)(void *arg)); -void *poll2_thread_func(void *arg); -int run_self_test(struct test_options *opts); -int run_cmd(struct test_options *opts); -int init_ctx_config(struct test_options *opts, - void *priv, - struct wd_sched **sched - ); -void uninit_config(void *priv, struct wd_sched *sched); -struct uacce_dev_list *get_dev_list(struct test_options *opts, int children); - -void hizip_prepare_random_input_data(char *buf, size_t len, size_t block_size); -int hizip_prepare_random_compressed_data(char *buf, size_t out_len, - size_t in_len, size_t *produced, - struct test_options *opts); - -int hizip_verify_random_output(struct test_options *opts, - struct hizip_test_info *info, - size_t out_sz); - -void *mmap_alloc(size_t len); -int mmap_free(void *addr, size_t len); - -int lib_poll_func(__u32 pos, __u32 expect, __u32 *count); -typedef int (*check_output_fn)(unsigned char *buf, unsigned int size, void *opaque); - -/* for block interface */ -int hw_blk_compress(int alg_type, int blksize, __u8 data_fmt, void *priv, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -int hw_blk_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -/* for stream memory interface */ -int hw_stream_compress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -int hw_stream_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -#ifdef USE_ZLIB -int hizip_check_output(void *buf, size_t size, size_t *checked, - check_output_fn check_output, void *opaque); -int zlib_deflate(void *output, unsigned int out_size, - void *input, unsigned int in_size, unsigned long *produced, - int alg_type); -#else -static inline int hizip_check_output(void *buf, size_t size, size_t *checked, - check_output_fn check_output, - void *opaque) -{ - static bool printed = false; - - if (!printed) { - WD_ERR("no zlib available, output buffer won't be checked\n"); - printed = true; - } - return -ENOSYS; -} -static inline int zlib_deflate(void *output, unsigned int out_size, void *input, - unsigned int in_size, unsigned long *produced, - int alg_type) -{ - WD_ERR("no zlib available\n"); - return -ENOSYS; -} -#endif - -static inline void hizip_test_adjust_len(struct test_options *opts) -{ - /* - * Align size to the next block. We allow non-power-of-two block sizes. - */ - opts->total_len = (opts->total_len + opts->block_size - 1) / - opts->block_size * opts->block_size; -} - -#define COMMON_OPTSTRING "hb:n:q:l:FSs:Vvzt:m:dacLZ" - -#define COMMON_HELP "%s [opts]\n" \ - " -b <size> block size\n" \ - " -n <num> number of runs\n" \ - " -q <num> number of queues\n" \ - " -l <num> number of compact runs\n" \ - " -F input file, default no input\n" \ - " -S stream mode, default block mode\n" \ - " -s <size> total size\n" \ - " -V verify output\n" \ - " -v display detailed performance information\n" \ - " -a test deflate algorithm, default gzip\n" \ - " -z test zlib algorithm, default gzip\n" \ - " -t <num> number of thread per process\n" \ - " -m <mode> mode of queues: 0 sync, 1 async\n" \ - " -d test decompression, default compression\n" \ - " -c use cpu to do zlib\n" \ - " -L test sgl type buffer, default pbuffer\n" \ - " -Z test lz77_zstd algorithm, default gzip\n" \ - "\n\n" - -int parse_common_option(const char opt, const char *optarg, - struct test_options *opts); -#endif /* TEST_LIB_H_ */ diff --git a/test/hisi_zip_test/testsuit.c b/test/hisi_zip_test/testsuit.c deleted file mode 100644 index e1b157a7..00000000 --- a/test/hisi_zip_test/testsuit.c +++ /dev/null @@ -1,1844 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * 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 - -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]; -}; - -extern int perf_event_open(struct perf_event_attr *attr, - pid_t pid, int cpu, int group_fd, - unsigned long flags); -extern int perf_event_get(const char *event_name, int **perf_fds, int *nr_fds); -extern unsigned long long perf_event_put(int *perf_fds, int nr_fds); -extern void stat_setup(struct hizip_test_info *info); -extern void stat_start(struct hizip_test_info *info); -extern void stat_end(struct hizip_test_info *info); - -static size_t count_chunk_list_sz(chunk_list_t *list) -{ - size_t sum = 0; - chunk_list_t *p; - - for (p = list; p; p = p->next) - sum += p->size; - return sum; -} - -static void *sw_dfl_hw_ifl(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_ifl; - void *tbuf; - size_t tbuf_sz; - chunk_list_t *tlist; - comp_md5_t final_md5 = {{0}}; - int i, ret; - __u32 tout_sz; - - tbuf_sz = tdata->src_sz * EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) - return (void *)(uintptr_t)(-ENOMEM); - tlist = create_chunk_list(tbuf, tbuf_sz, - info->in_chunk_sz * EXPANSION_RATIO); - if (!tlist) { - ret = -ENOMEM; - goto out; - } - if (opts->option & PERFORMANCE) { - /* hack: - * memset buffer and trigger page fault early in the cpu - * instead of later in the SMMU - * Enhance performance in sva case - * no impact to non-sva case - */ - memset(tbuf, 5, tbuf_sz); - } - if (opts->is_stream) { - /* STREAM mode: only one entry in the list */ - init_chunk_list(tdata->in_list, tdata->src, - tdata->src_sz, tdata->src_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, tbuf_sz); - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, tdata->dst_sz); - ret = sw_deflate2(tdata->in_list, tlist, opts); - if (ret) { - printf("Fail to deflate by zlib: %d\n", ret); - goto out_strm; - } - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tlist->addr, - tlist->size); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out_strm; - } - ret = calculate_md5(&tdata->md5, tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = calculate_md5(&final_md5, tdata->out_list->addr, - tout_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_strm; - } - } - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - return NULL; - } - - /* BLOCK mode */ - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) { - ret = -EINVAL; - goto out_strm; - } - - init_chunk_list(tdata->in_list, tdata->src, tdata->src_sz, - info->in_chunk_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, - info->in_chunk_sz * EXPANSION_RATIO); - init_chunk_list(tdata->out_list, tdata->dst, tdata->dst_sz, - info->out_chunk_sz); - ret = sw_deflate2(tdata->in_list, tlist, opts); - if (ret) { - printf("Fail to deflate by zlib: %d\n", ret); - goto out_run; - } - ret = hw_inflate4(h_ifl, tlist, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out_run; - } - ret = calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = calculate_md5(&final_md5, tdata->dst, tdata->dst_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_run; - } - } - wd_comp_free_sess(h_ifl); - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out_run: - wd_comp_free_sess(h_ifl); -out_strm: - free_chunk_list(tlist); -out: - mmap_free(tbuf, tbuf_sz); - return (void *)(uintptr_t)(ret); -} - -static void *hw_dfl_sw_ifl(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl; - void *tbuf; - size_t tbuf_sz; - chunk_list_t *tlist; - comp_md5_t final_md5 = {{0}}; - int i, ret; - __u32 tmp_sz; - - tbuf_sz = tdata->src_sz * EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) - return (void *)(uintptr_t)(-ENOMEM); - tlist = create_chunk_list(tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - if (!tlist) { - ret = -ENOMEM; - goto out; - } - if (opts->option & PERFORMANCE) { - /* hack: - * memset buffer and trigger page fault early in the cpu - * instead of later in the SMMU - * Enhance performance in sva case - * no impact to non-sva case - */ - memset(tbuf, 5, tbuf_sz); - } - if (opts->is_stream) { - /* STREAM mode: only one entry in the list */ - init_chunk_list(tdata->in_list, tdata->src, - tdata->src_sz, tdata->src_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, tbuf_sz); - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, tdata->dst_sz); - tmp_sz = tbuf_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tlist->addr, - &tmp_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out_strm; - } - tlist->size = tmp_sz; // write back - ret = sw_inflate2(tlist, tdata->out_list, opts); - if (ret) { - printf("Fail to inflate by zlib: %d\n", ret); - goto out_strm; - } - ret = calculate_md5(&tdata->md5, tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = calculate_md5(&final_md5, tdata->out_list->addr, - tdata->out_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_strm; - } - } - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - return NULL; - } - - /* BLOCK mode */ - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) { - ret = -EINVAL; - goto out_strm; - } - - init_chunk_list(tdata->in_list, tdata->src, tdata->src_sz, - info->in_chunk_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - init_chunk_list(tdata->out_list, tdata->dst, tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate4(h_dfl, tdata->in_list, tlist, opts, - &tdata->sem); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out_run; - } - ret = sw_inflate2(tlist, tdata->out_list, opts); - if (ret) { - printf("Fail to inflate by zlib: %d\n", ret); - goto out_run; - } - ret = calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = calculate_md5(&final_md5, tdata->dst, tdata->dst_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_run; - } - } - wd_comp_free_sess(h_dfl); - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out_run: - wd_comp_free_sess(h_dfl); -out_strm: - free_chunk_list(tlist); -out: - mmap_free(tbuf, tbuf_sz); - return (void *)(uintptr_t)(ret); -} - -static void *hw_dfl_hw_ifl(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl, h_ifl; - void *tbuf; - size_t tbuf_sz; - chunk_list_t *tlist; - comp_md5_t final_md5 = {{0}}; - int i, ret; - __u32 tmp_sz, tout_sz; - - tbuf_sz = tdata->src_sz * EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) - return (void *)(uintptr_t)(-ENOMEM); - if (opts->option & PERFORMANCE) { - /* hack: - * memset buffer and trigger page fault early in the cpu - * instead of later in the SMMU - * Enhance performance in sva case - * no impact to non-sva case - */ - memset(tbuf, 5, tbuf_sz); - } - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tmp_sz = tbuf_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tbuf, - &tmp_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out; - } - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tbuf, - tmp_sz); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out; - } - ret = calculate_md5(&tdata->md5, tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out; - } - ret = calculate_md5(&final_md5, tdata->dst, tout_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out; - } - } - mmap_free(tbuf, tbuf_sz); - return NULL; - } - - /* BLOCK mode */ - tlist = create_chunk_list(tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - if (!tlist) { - ret = -ENOMEM; - goto out; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) { - ret = -EINVAL; - goto out_dfl; - } - - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) { - ret = -EINVAL; - goto out_ifl; - } - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate4(h_dfl, tdata->in_list, tlist, opts, - &tdata->sem); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out_run; - } - ret = hw_inflate4(h_ifl, tlist, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out_run; - } - ret = calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = calculate_md5(&final_md5, tdata->dst, tdata->dst_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_run; - } - } - wd_comp_free_sess(h_ifl); - wd_comp_free_sess(h_dfl); - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out_run: - wd_comp_free_sess(h_ifl); -out_ifl: - wd_comp_free_sess(h_dfl); -out_dfl: - free_chunk_list(tlist); -out: - mmap_free(tbuf, tbuf_sz); - return (void *)(uintptr_t)(ret); -} - -static void *hw_dfl_perf(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate4(h_dfl, tdata->in_list, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_dfl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_dfl); - return (void *)(uintptr_t)(ret); -} - -static void *hw_ifl_perf(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_ifl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - } - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_inflate4(h_ifl, tdata->in_list, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_ifl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_ifl); - return (void *)(uintptr_t)(ret); -} - -/* BATCH mode is used */ -void *hw_dfl_perf3(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate5(h_dfl, tdata->in_list, tdata->out_list, - tdata); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_dfl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_dfl); - return (void *)(uintptr_t)(ret); -} - -/* BATCH mode is used */ -void *hw_ifl_perf3(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_ifl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - } - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_inflate5(h_ifl, tdata->in_list, tdata->out_list, - tdata); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_ifl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_ifl); - return (void *)(uintptr_t)(ret); -} - -/* - * Load both ilist file. - */ -int load_ilist(struct hizip_test_info *info, char *model) -{ - struct test_options *opts = info->opts; - thread_data_t *tdata = &info->tdatas[0]; - chunk_list_t *p; - size_t sum = 0; - ssize_t file_sz = 0; - void *addr; - - if (!strcmp(model, "hw_ifl_perf")) { - if (!opts->is_stream) { - if (opts->fd_ilist < 0) { - printf("Missing IN list file!\n"); - return -EINVAL; - } - p = tdata->in_list; - addr = info->in_buf; - while (p) { - file_sz = read(opts->fd_ilist, p, - sizeof(chunk_list_t)); - if (file_sz < 0) - return -EFAULT; - p->addr = addr; - sum += file_sz; - if (p->next) - p->next = p + 1; - addr += p->size; - p = p->next; - } - } - } - return (int)sum; -} - -/* - * Load compression/decompression content. - */ -int load_file_data(struct hizip_test_info *info) -{ - struct test_options *opts = info->opts; - size_t file_sz; - - file_sz = read(opts->fd_in, info->in_buf, info->in_size); - if (file_sz < info->in_size) { - printf("Expect to read %ld bytes. " - "But only read %ld bytes!\n", - info->in_size, file_sz); - return -EFAULT; - } - return (int)file_sz; -} - -/* - * Store both olist file. opts->is_file must be enabled first. - */ -int store_olist(struct hizip_test_info *info, char *model) -{ - struct test_options *opts = info->opts; - thread_data_t *tdata = &info->tdatas[0]; - chunk_list_t *p; - size_t sum = 0; - ssize_t file_sz = 0; - - if (!opts->is_stream) { - if (opts->fd_olist >= 0) { - /* compress with BLOCK */ - p = tdata->out_list; - while (p) { - file_sz = write(opts->fd_olist, p, - sizeof(chunk_list_t)); - if (file_sz < sizeof(chunk_list_t)) - return -EFAULT; - file_sz = write(opts->fd_out, p->addr, - p->size); - if (file_sz < p->size) - return -EFAULT; - p = p->next; - sum += file_sz; - } - } else { - /* decompress with BLOCK */ - p = tdata->out_list; - while (p) { - file_sz = write(opts->fd_out, p->addr, - p->size); - if (file_sz < p->size) - return -EFAULT; - p = p->next; - sum += file_sz; - } - } - } else if (opts->is_stream) { - p = tdata->out_list; - file_sz = write(opts->fd_out, p->addr, p->size); - if (file_sz < p->size) - return -EFAULT; - sum = file_sz; - } - return (int)sum; -} - -static int nonenv_resource_init(struct test_options *opts, - struct hizip_test_info *info, - struct wd_sched **sched) -{ - int ret; - - info->list = get_dev_list(opts, 1); - if (!info->list) - return -EINVAL; - ret = init_ctx_config(opts, info, sched); - if (ret < 0) { - wd_free_list_accels(info->list); - return ret; - } - return 0; -} - -static void nonenv_resource_uninit(struct test_options *opts, - struct hizip_test_info *info, - struct wd_sched *sched) -{ - uninit_config(info, sched); - wd_free_list_accels(info->list); -} - -static bool event_unavailable = false; - -int test_hw(struct test_options *opts, char *model) -{ - struct hizip_test_info info = {0}; - struct wd_sched *sched = NULL; - double ilen, usec, speed; - char zbuf[120]; - int ret, zbuf_idx, ifl_flag = 0; - void *(*func)(void *); - size_t tbuf_sz = 0; - void *tbuf = NULL; - struct stat statbuf; - chunk_list_t *tlist = NULL; - int div; - __u32 num; - __u8 enable; - int nr_fds = 0; - int *perf_fds = NULL; - struct hizip_stats stats; - - if (!opts || !model) { - ret = -EINVAL; - goto out; - } - info.opts = opts; - info.stats = &stats; - - if (!event_unavailable && - perf_event_get("iommu/dev_fault", &perf_fds, &nr_fds)) { - printf("IOPF statistic unavailable\n"); - /* No need to retry and print an error on every run */ - event_unavailable = true; - } - stat_setup(&info); - - memset(zbuf, 0, 120); - if (!strcmp(model, "sw_dfl_hw_ifl")) { - func = sw_dfl_hw_ifl; - info.in_size = opts->total_len; - if (opts->is_stream) - info.out_size = opts->total_len; - else - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size; - zbuf_idx = sprintf(zbuf, "Mix SW deflate and HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_sw_ifl")) { - func = hw_dfl_sw_ifl; - info.in_size = opts->total_len; - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size; - zbuf_idx = sprintf(zbuf, "Mix HW %s %s deflate and SW inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_hw_ifl")) { - func = hw_dfl_hw_ifl; - info.in_size = opts->total_len; - if (opts->is_stream) - info.out_size = opts->total_len; - else - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size; - zbuf_idx = sprintf(zbuf, - "Mix HW %s %s deflate and HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_perf")) { - func = hw_dfl_perf; - info.in_size = opts->total_len; - info.out_size = opts->total_len * EXPANSION_RATIO; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * EXPANSION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s deflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_perf3")) { - func = hw_dfl_perf3; - info.in_size = opts->total_len; - info.out_size = opts->total_len * EXPANSION_RATIO; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * EXPANSION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s deflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_ifl_perf")) { - func = hw_ifl_perf; - info.in_size = opts->total_len; - info.out_size = opts->total_len * INFLATION_RATIO; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * INFLATION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - ifl_flag = 1; - } else if (!strcmp(model, "hw_ifl_perf3")) { - func = hw_ifl_perf3; - info.in_size = opts->total_len * EXPANSION_RATIO; - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * INFLATION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - ifl_flag = 1; - } else { - printf("Wrong model is specified:%s\n", model); - ret = -EINVAL; - goto out; - } - - if (opts->use_env) - ret = wd_comp_env_init(NULL); - else - ret = nonenv_resource_init(opts, &info, &sched); - if (ret < 0) - goto out; - - if (opts->faults & INJECT_SIG_BIND) - kill(getpid(), SIGTERM); - - if (opts->use_env) { - ret = wd_comp_get_env_param(0, opts->op_type, opts->sync_mode, &num, &enable); - if (ret < 0) - goto out; - } - - if (opts->is_file) { - ret = fstat(opts->fd_in, &statbuf); - if (ret < 0) - goto out_src; - opts->total_len = statbuf.st_size; - info.in_size = opts->total_len; - if (ifl_flag) - info.out_size = opts->total_len * INFLATION_RATIO; - else - info.out_size = opts->total_len * EXPANSION_RATIO; - /* - * If fd_ilist exists, it's inflation. - * Make sure block inflation has enough room. - */ - if (opts->fd_ilist >= 0) { - ret = fstat(opts->fd_ilist, &statbuf); - if (!ret) { - div = statbuf.st_size / sizeof(chunk_list_t); - info.in_chunk_sz = (info.in_size + div - 1) / - div; - info.out_chunk_sz = (info.out_size + div - 1) / - div; - } - } - } - info.in_buf = mmap_alloc(info.in_size); - if (!info.in_buf) { - ret = -ENOMEM; - goto out_src; - } - ret = create_send_tdata(opts, &info); - if (ret) - goto out_send; - ret = create_poll_tdata(opts, &info, opts->poll_num); - if (ret) - goto out_poll; - if (opts->is_file) { - /* in_list is created by create_send3_threads(). */ - ret = load_file_data(&info); - if (ret < 0) - goto out_buf; - ret = load_ilist(&info, model); - if (ret < 0) - goto out_buf; - } else { - if (ifl_flag) { - thread_data_t *tdata = info.tdatas; - tbuf_sz = info.in_size / EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) { - ret = -ENOMEM; - goto out_buf; - } - tlist = create_chunk_list(tbuf, tbuf_sz, - opts->block_size / - EXPANSION_RATIO); - init_chunk_list(tlist, tbuf, tbuf_sz, - opts->block_size / EXPANSION_RATIO); - gen_random_data(tbuf, tbuf_sz); - ret = sw_deflate2(tlist, tdata[0].in_list, opts); - if (ret) { - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - goto out_buf; - } - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - } else - gen_random_data(info.in_buf, info.in_size); - } - if (opts->faults & INJECT_TLB_FAULT) { - /* - * Now unmap the buffers and retry the access. Normally we - * should get an access fault, but if the TLB wasn't properly - * invalidated, the access succeeds and corrupts memory! - * This test requires small jobs, to make sure that we reuse - * the same TLB entry between the tests. Run for example with - * "-s 0x1000 -b 0x1000". - */ - ret = munmap(info.in_buf, info.in_size); - if (ret) { - printf("Failed to unmap."); - goto out_buf; - } - /* A warning if the parameters might produce false positives */ - if (opts->total_len > 0x54000) - fprintf(stderr, "NOTE: test might trash the TLB\n"); - } - stat_start(&info); - ret = attach2_threads(opts, &info, func, poll2_thread_func); - if (ret) - goto out_buf; - stat_end(&info); - info.stats->v[ST_IOPF] = perf_event_put(perf_fds, nr_fds); - if (opts->is_file) - store_olist(&info, model); - - usec = info.stats->v[ST_RUN_TIME] / 1000; - if (opts->op_type == WD_DIR_DECOMPRESS) - ilen = (float)count_chunk_list_sz(info.tdatas[0].out_list); - else - ilen = opts->total_len; - ilen *= opts->thread_num * opts->compact_run_num; - speed = ilen * 1000 * 1000 / 1024 / 1024 / usec; - if (opts->sync_mode) { - zbuf_idx += sprintf(zbuf + zbuf_idx, - " with %d send + %d poll threads", - opts->thread_num, - opts->poll_num); - } else { - zbuf_idx += sprintf(zbuf + zbuf_idx, - " with %d send threads", - opts->thread_num); - } - if (!strcmp(model, "hw_dfl_perf") || !strcmp(model, "hw_ifl_perf") || - !strcmp(model, "hw_dfl_perf3") || !strcmp(model, "hw_ifl_perf3")) { - printf("%s at %.2fMB/s in %f usec (BLK:%d, Bnum:%d).\n", - zbuf, speed, usec, opts->block_size, opts->batch_num); - } else { - printf("%s in %f usec (BLK:%d, Bnum:%d).\n", - zbuf, usec, opts->block_size, opts->batch_num); - } - free2_threads(&info); - if (opts->use_env) - wd_comp_env_uninit(); - else - nonenv_resource_uninit(opts, &info, sched); - usleep(1000); - return 0; -out_buf: -out_poll: - free2_threads(&info); - if (opts->use_env) - wd_comp_env_uninit(); - else - nonenv_resource_uninit(opts, &info, sched); - printf("Fail to run %s() (%d)!\n", model, ret); - return ret; -out_send: - mmap_free(info.in_buf, info.in_size); -out_src: - if (opts->use_env) - wd_comp_env_uninit(); - else - nonenv_resource_uninit(opts, &info, sched); -out: - printf("Fail to run %s() (%d)!\n", model, ret); - return ret; -} - -int run_self_test(struct test_options *opts) -{ - int i, f_ret = 0; - char poll_str[POLL_STRING_LEN]; - - printf("Start to run self test!\n"); - opts->alg_type = WD_ZLIB; - opts->data_fmt = WD_FLAT_BUF; - opts->sync_mode = 0; - opts->q_num = 16; - for (i = 0; i < 10; i++) { - opts->sync_mode = 0; - switch (i) { - case 0: - opts->thread_num = 1; - break; - case 1: - opts->thread_num = 2; - break; - case 2: - opts->thread_num = 4; - break; - case 3: - opts->thread_num = 8; - break; - case 4: - opts->thread_num = 16; - break; - case 5: - opts->thread_num = 1; - opts->is_stream = 1; - break; - case 6: - opts->thread_num = 2; - opts->is_stream = 1; - break; - case 7: - opts->thread_num = 4; - opts->is_stream = 1; - break; - case 8: - opts->thread_num = 8; - opts->is_stream = 1; - break; - case 9: - opts->thread_num = 16; - opts->is_stream = 1; - break; - } - f_ret |= test_hw(opts, "hw_dfl_perf"); - f_ret |= test_hw(opts, "hw_ifl_perf"); - } - opts->is_stream = 0; /* restore to BLOCK mode */ - for (i = 0; i < 5; i++) { - opts->thread_num = 8; - switch (i) { - case 0: - opts->sync_mode = 0; - break; - case 1: - opts->sync_mode = 1; opts->poll_num = 1; - break; - case 2: - opts->sync_mode = 1; opts->poll_num = 2; - break; - case 3: - opts->sync_mode = 1; opts->poll_num = 4; - break; - case 4: - opts->sync_mode = 1; opts->poll_num = 8; - break; - default: - return -EINVAL; - } - if (opts->use_env && opts->poll_num) { - memset(poll_str, 0, POLL_STRING_LEN); - sprintf(poll_str, - "sync-comp:8@0,sync-decomp:8@0," - "async-comp:8@0,async-decomp:8@0"); - setenv("WD_COMP_CTX_NUM", poll_str, 1); - memset(poll_str, 0, POLL_STRING_LEN); - sprintf(poll_str, "%d@0", opts->poll_num), - setenv("WD_COMP_ASYNC_POLL_NUM", poll_str, 1); - } - f_ret |= test_hw(opts, "sw_dfl_hw_ifl"); - f_ret |= test_hw(opts, "hw_dfl_sw_ifl"); - f_ret |= test_hw(opts, "hw_dfl_hw_ifl"); - f_ret |= test_hw(opts, "hw_dfl_perf"); - f_ret |= test_hw(opts, "hw_ifl_perf"); - } - if (!f_ret) - printf("Run self test successfully!\n"); - return f_ret; -} - -static int set_default_opts(struct test_options *opts) -{ - if (!opts->block_size) - opts->block_size = 8192; - if (!opts->total_len) { - if (opts->block_size) - opts->total_len = opts->block_size * 10; - else - opts->total_len = 8192 * 10; - } - if (!opts->thread_num) - opts->thread_num = 1; - if (!opts->q_num) - opts->q_num = opts->thread_num; - if (!opts->compact_run_num) - opts->compact_run_num = 1; - if (!opts->poll_num) - opts->poll_num = 1; - if (opts->alg_type == WD_COMP_ALG_MAX) - opts->alg_type = WD_GZIP; - return 0; -} - -static int run_one_cmd(struct test_options *opts) -{ - int ret; - - if (opts->op_type == WD_DIR_COMPRESS) { - if (opts->verify) - ret = test_hw(opts, "hw_dfl_sw_ifl"); - else - ret = test_hw(opts, "hw_dfl_perf"); - } else { - if (opts->verify) - ret = test_hw(opts, "sw_dfl_hw_ifl"); - else - ret = test_hw(opts, "hw_ifl_perf"); - } - return ret; -} - -int run_cmd(struct test_options *opts) -{ - int ret = 0, i; - int nr_children = 0, status; - pid_t pid, *pids = NULL; - bool success = true; - - set_default_opts(opts); - if (opts->children) { - pids = calloc(opts->children, sizeof(pid_t)); - if (!pids) - return -ENOMEM; - for (i = 0; i < opts->children; i++) { - pid = fork(); - if (pid < 0) { - printf("cannot fork: %d\n", errno); - success = false; - break; - } else if (pid > 0) { - /* Parent */ - pids[nr_children++] = pid; - continue; - } - /* Child */ - ret = run_one_cmd(opts); - return ret; - } - for (i = 0; i < nr_children; i++) { - pid = pids[i]; - ret = waitpid(pid, &status, 0); - if (ret < 0) { - printf("wait(pid=%d) error %d\n", pid, errno); - success = false; - continue; - } - if (WIFEXITED(status)) { - ret = WEXITSTATUS(status); - if (ret) { - printf("child %d returned with %d\n", - pid, ret); - success = false; - } - } else if (WIFSIGNALED(status)) { - ret = WTERMSIG(status); - printf("child %d killed by sig %d\n", pid, ret); - success = false; - } else { - printf("unexpected status for child %d\n", pid); - success = false; - } - } - if (success == false) { - printf("Failed to run spawn test!\n"); - if (!ret) - ret = -EINVAL; - } - } else - 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 -- 2.33.0