pax_global_header00006660000000000000000000000064150026337700014515gustar00rootroot0000000000000052 comment=10dbadbab384ab3a0cb514163ff1aa47c2bf42f2 QATzip-1.3.1/000077500000000000000000000000001500263377000126675ustar00rootroot00000000000000QATzip-1.3.1/.github/000077500000000000000000000000001500263377000142275ustar00rootroot00000000000000QATzip-1.3.1/.github/CODEOWNERS000066400000000000000000000001341500263377000156200ustar00rootroot00000000000000* chengfei.zhu@intel.com xinghong.chen@intel.com lihui.zhang@intel.com david.qian@intel.com QATzip-1.3.1/.github/dependabot.yml000066400000000000000000000010021500263377000170500ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "github-actions" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "monthly" QATzip-1.3.1/.gitignore000066400000000000000000000005431500263377000146610ustar00rootroot00000000000000# automake file autom4te.cache m4 src/.deps src/.libs utils/.deps test/.deps aclocal.m4 Makefile Makefile.in ar-lib compile config.guess config.log config.status config.sub configure depcomp install-sh libtool ltmain.sh missing qatzip.spec # compile obj src/*.lo src/*.o src/*.la utils/*.o test/*.o # app test/bt test/qatzip-test utils/qzip utils/qzstdQATzip-1.3.1/LICENSE000066400000000000000000000033731500263377000137020ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QATzip-1.3.1/LICENSE.LZ4000066400000000000000000000024371500263377000143120ustar00rootroot00000000000000LZ4 Library Copyright (c) 2011-2020, Yann Collet All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. QATzip-1.3.1/LICENSE.XXHASH000066400000000000000000000025551500263377000147050ustar00rootroot00000000000000xxHash Library Copyright (c) 2012-2021 Yann Collet All rights reserved. BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. QATzip-1.3.1/LICENSE.ZLIB000066400000000000000000000017521500263377000144400ustar00rootroot00000000000000Copyright notice: (C) 1995-2022 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu QATzip-1.3.1/LICENSE.ZSTD000066400000000000000000000030151500263377000144560ustar00rootroot00000000000000BSD License For Zstandard software Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook, nor Meta, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. QATzip-1.3.1/Makefile.am000066400000000000000000000100521500263377000147210ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QZIP_DIR = $(top_builddir)/utils TEST_DIR = $(top_builddir)/test QATZIP_LIB_DIR = $(top_builddir)/src QATZIP_LIB = libqatzip.la CODE_FORMATTING_BIN = $(top_builddir)/test/code_format_tests/format.sh DIST_SUBDIRS = src utils test SUBDIRS = src utils test pkgincludedir = $(includedir) pkginclude_HEADERS = include/qatzip.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = qatzip.pc dist_man_MANS = \ man/qzip.1 EXTRA_DIST = \ LICENSE \ README.md \ include/qz_utils.h \ src/xxhash.h \ src/qatzip_internal.h \ src/qatzip_page_table.h \ utils/qzip.h \ utils/qzstd.h \ test/code_format_tests \ test/performance_tests \ docs/QATzip-man.pdf \ config_file/ $(QATZIP_LIB): @make -C $(QATZIP_LIB_DIR) $(QATZIP_LIB) qzip: $(QATZIP_LIB) @make -C $(QZIP_DIR) qzip qzip_obj_without_main: @make -C $(QZIP_DIR) qzip_obj_without_main qatzip-test:$(QATZIP_LIB) @make -C $(TEST_DIR) qatzip-test bt:$(QATZIP_LIB) @make -C $(TEST_DIR) bt qzstd: $(QATZIP_LIB) if QATZIP_LZ4S_POSTPROCESS_AC @make -C $(QZIP_DIR) qzstd else @echo "Error : please enable lz4s postprocessing in configure!" endif AM_CFLAGS=-DENABLE_TESTLOG testlog: clean @make -C $(QATZIP_LIB_DIR) $(QATZIP_LIB) AM_CFLAGS=$(AM_CFLAGS) @make -C $(QZIP_DIR) qzip @make -C $(TEST_DIR) qatzip-test @make -C $(TEST_DIR) bt if QATZIP_LZ4S_POSTPROCESS_AC @make -C $(QZIP_DIR) qzstd endif check_code: @echo -e "\n\nPerforming code formatting tests..." @if ! $(CODE_FORMATTING_BIN); then \ echo "Check code format FAILED!!! :("; \ exit 1; \ fi clean-local: @make -C $(TEST_DIR) clean ######################## # RPM package building # ######################## rpm: clean dist qatzip.spec @mkdir -p rpmbuild/BUILD rpmbuild/RPMS rpmbuild/SOURCES rpmbuild/SPECS rpmbuild/SRPMS @cp $(PACKAGE)-$(VERSION).tar.gz rpmbuild/SOURCES/ @cp qatzip.spec rpmbuild/SPECS/ @rpmbuild --define "_topdir $(abs_srcdir)/rpmbuild" -ba rpmbuild/SPECS/qatzip.spec rpmclean: @rm -fr rpmbuild .PHONY: rpm rpmclean libqatzip qzip qatzip-test check_code \ qzip_obj_without_main bt $(QATZIP_LIB) clean-local \ qzstd QATzip-1.3.1/README.md000066400000000000000000000471341500263377000141570ustar00rootroot00000000000000# Intel® QuickAssist Technology (QAT) QATzip Library ## Table of Contents - [Introduction](#introduction) - [Licensing](#licensing) - [Features](#features) - [Hardware Requirements](#hardware-requirements) - [Software Requirements](#software-requirements) - [Additional Information](#additional-information) - [Limitations](#limitations) - [Installation Instructions](#installation-instructions) - [Install with the in-tree QAT package](#install-with-the-in-tree-QAT-package) - [Install with the out-of-tree QAT package](#install-with-the-out-of-tree-QAT-package) - [Configuration](#configuration) - [Enable qzstd](#enable-qzstd) - [Test QATzip](#test-qatzip) - [Performance Test With QATzip](#performance-test-with-qatzip) - [QATzip API manual](#qatzip-api-manual) - [Intended Audience](#intended-audience) - [Open Issues](#open-issues) - [Legal](#legal) ## Introduction QATzip is a user space library which builds on top of the Intel® QuickAssist Technology user space library, to provide extended accelerated compression and decompression services by offloading the actual compression and decompression request(s) to the Intel® Chipset Series. QATzip produces data using the standard gzip\* format (RFC1952) with extended headers or [lz4\* blocks][7] with [lz4\* frame format][8]. The data can be decompressed with a compliant gzip\* or lz4\* implementation. QATzip is designed to take full advantage of the performance provided by Intel® QuickAssist Technology. The currently supported formats include: |Data Format|Algorithm|QAT device|Description| | :---------------: | :---------------: |:---------------: | :------------------------------------------------------------: | | `QZ_DEFLATE_4B` | deflate\* | QAT 1.x and QAT 2.0|Data is in DEFLATE\* with a 4 byte header| | `QZ_DEFLATE_GZIP` | deflate\* | QAT 1.x and QAT 2.0|Data is in DEFLATE\* wrapped by Gzip\* header and footer| | `QZ_DEFLATE_GZIP_EXT` | deflate\* | QAT 1.x and QAT 2.0|Data is in DEFLATE\* wrapped by Intel® QAT Gzip\* extension header and footer| | `QZ_DEFLATE_RAW` | deflate\* | QAT 1.x and QAT 2.0|Data is in raw DEFLATE\* without any additional header. (Only support compression, decompression will fallback to software) | | `QZ_LZ4` | lz4\* | QAT 2.0|Data is in LZ4\* wrapped by lz4\* frame | | `QZ_LZ4S` | lz4s\* | QAT 2.0|Data is in LZ4S\* blocks | ## Licensing The Licensing of the files within this project is split as follows: Intel® Quickassist Technology (QAT) QATzip - BSD License. Please see the `LICENSE` file contained in the top level folder. Further details can be found in the file headers of the relevant files. Example Intel® Quickassist Technology Driver Configuration Files contained within the folder hierarchy `config_file` - Dual BSD/GPLv2 License. Please see the file headers of the configuration files, and the full GPLv2 license contained in the file `LICENSE.GPL` within the `config_file` folder. ## Features * Acceleration of compression and decompression utilizing Intel® QuickAssist Technology, including a utility to compress and decompress files. * Dynamic memory allocation for zero copy, by exposing qzMalloc() and qzFree() allowing working buffers to be pinned, contiguous buffers that can be used for DMA operations to and from the hardware. * Instance over-subscription, allowing a number of threads in the same process to seamlessly share a smaller number of hardware instances. * Memory allocation backed by huge page and kernel memory to provide access to pinned, contiguous memory. Allocating from huge-page when kernel memory contention. * Configurable accelerator device sharing among processes. * Optional software failover for both compression and decompression services. QATzip may switch to software if there is insufficient system resources including acceleration instances or memory. This feature allows for a common software stack between server platforms that have acceleration devices and non-accelerated platforms. * Provide streaming interface of compression and decompression to achieve better compression ratio and throughput for data sets that are submitted piecemeal. * Provide Async interface of compression and decompression in library to achieve lower latency and higher throughput(qzip utility don't support this feature). It's beneficial for fewer instances or smaller data packets(below 64KB). * Provide Latency sensitive mode, which should be utilized when the device is under significant load. This mode enables QATzip to offload part of the workload to the CPU, taking advantage of Intel's multi-core processors to achieve improved throughput and reduced latency under high-stress conditions. * 'qzip' utility supports compression from regular file, pipeline and block device. * For QATzip GZIP\* format, try hardware decompression first before switching to software decompression. * Enable adaptive polling mechanism to save CPU usage in stress mode. * 'qzip' utility supports compression files and directories into 7z format. * Support QATzip Gzip\* format, it includes 10 bytes header and 8 bytes footer: `| ID1 (1B) | ID2(0x8B) (1B) | Compression Method (8 = DEFLATE*) (1B) | Flags (1B) | Modification Time (4B) | Extra Flags (1B) | OS (1B) | Deflate Block| CRC32(4B)| ISIZE(4B)|` * Support QATzip Gzip\* extended format. This consists of the standard 10 byte Gzip* header and follows RFC 1952 to extend the header by an additional 14 bytes. The extended headers structure is below: `| Length of ext. header (2B) | SI1('Q') (1B) | SI2('Z') (1B) | Length of subheader (2B) | Intel(R) defined field 'Chunksize' (4B) | Intel(R) defined field 'Blocksize' (4B) | ` * Support Intel® QATzip 4 byte header, the header indicates the length of the compressed block followed by the header. `| Intel(R) defined Header (4B)|deflate\* block|` * Support QATzip lz4* format. This format is structured as follows: `| MagicNb(4B) |FLG(1B)|BD(1B)| CS(8B)|HC(1B)| |lz4\* Block | EndMark(4B)|` ## Hardware Requirements This QATzip library supports compression and decompression offload to the following acceleration devices: * [Intel® C62X Series Chipset][1] * [Intel® Communications Chipset 8925 to 8955 Series][2] * [Intel® Communications Chipset 8960 to 8970 Series][3] * [Intel® C3XXX Series Chipset][4] * [Intel® 4XXX Series][5] ## Software Requirements This release was validated on the following: * QATzip has been tested with the latest Intel® QuickAssist Acceleration Driver. Please download the QAT driver from the link [Intel® QuickAssist Technology][6] * QATzip has been tested by Intel® on CentOS\* 7.8.2003 with kernel 3.10.0-1127.19.1.el7.x86\_64 * Zlib\* library of version 1.2.7 or higher * Suggest GCC\* of version 4.8.5 or higher * lz4\* library of version 1.8.3 or higher * zstd\* library of version 1.5.0 or higher * numactl-devel\* ## Additional Information * For QAT 1.x, the compression level in QATzip could be mapped to standard zlib\* as below: * QATzip level 1 - 4, similar to zlib\* level 1 - 4. * QATzip level 5 - 8, we map them to QATzip level 4. * QATzip level 9, we will use software zlib\* to compress as level 9. * For QAT 2.0, the compression level in QATzip could be mapped to standard zlib\* or lz4\* as below: * Will be updated in future releases. * QATzip Compression Level Mapping: | QATzip Level |QAT Level| QAT 2.0(deflate\*, LZ4\*, LZ4s\*) |QAT1.7/1.8(Deflate\*) | | ---- | --- | ---- | ---- | | 1 | CPA_DC_L1 |2(HW_L1) | DEPTH_1 | | 2 | CPA_DC_L2 |2(HW_L1) | DEPTH_4 | | 3 | CPA_DC_L3 |2(HW_L1) | DEPTH_8 | | 4 | CPA_DC_L4 |2(HW_L1) | DEPTH_16 | | 5 | CPA_DC_L5 |2(HW_L1) | DEPTH_16 | | 6 | CPA_DC_L6 |8(HW_L6) | DEPTH_16 | | 7 | CPA_DC_L7 |8(HW_L6) | DEPTH_16 | | 8 | CPA_DC_L8 |8(HW_L6) | DEPTH_16 | | 9 | CPA_DC_L9 |16(HW_L9) | DEPTH_16 | | 10 | CPA_DC_L10 |16(HW_L9) | Unsupported | | 11 | CPA_DC_L11 |16(HW_L9) | Unsupported | | 12 | CPA_DC_L12 |16(HW_L9) | Unsupported | ## Limitations * The partitioned internal chunk size of 16 KB is disabled, this chunk is used for QAT hardware DMA. * For stream object, user should reset the stream object by calling qzEndStream() before reuse it in the other session. * For stream object, user should clear stream object by calling qzEndStream() before clear session object with qzTeardownSession(). Otherwise, memory leak happens. * For stream object, stream length must be smaller than `strm_buff_sz`, or QATzip would generate multiple deflate block in order and has the last block with BFIN set. * For stream object, we will optimize the performance of the pre-allocation process using a thread-local stream buffer list in a future release. * For 7z format, decompression only supports \*.7z archives compressed by qzip. * For 7z format, decompression only supports software. * For 7z format, the header compression is not supported. * For lz4\* (de)compression, QATzip only supports 32KB history buffer. * For zstd format compression, qzstd only supports `hw_buffer_sz` which is less than 128KB. * Stream APIs only support "DEFLATE_GZIP", "DEFLATE_GZIP_EXT", "DEFLATE_RAW" for compression and "DEFLATE_GZIP", "DEFLATE_GZIP_EXT" for decompression now. * DEFLATE_RAW hardware decompression is supported, if want to offload to HW, then the input data must be single complete deflate block and it's uncompressed size have to smaller than the HW buffer size, otherwise, it would fallback to sw(The API's input dest len have to set down by the customer). If input data is multi-blocks and software backup is enabled, then it would fallback to sw. * DEFLATE_ZLIB hardware compression and decompression is supported, if want to offload to HW, then the input data must be single complete deflate block and it's compressed size have to smaller or equal than the HW buffer size, otherwise, it would fallback to sw(The API's input dest len have to set down by the customer). If input data is multi-blocks then only first complete block will be decompressed by HW and user need to call decompress with next block. * When Async API is used, instance over-subscription is currently unsupported. This implies that the number of threads should ideally not surpass the number of instances. Each thread maintains its own session and instance. Otherwise, any additional threads will offload the workload to software * Latency sensitive mode is not advisable to enable in low-stress scenarios or for smaller data workloads (below 8KB), as QATzip may experience decreased throughput. ## Installation Instructions ### Install with the in-tree QAT package * Please refer to [link][11]. ### Install with the out-of-tree QAT package 1. The Installation of the out-of-tree QAT package refer to [link][12]. > **Note**
> - If you run QAT as **non-root** user, more steps need to be manually applied, please refer to [link][13].
> - If SVM is not enabled, memory passed to QAT hardware must be DMA’able, Intel provides a USDM component > which allocates/frees DMA-able memory. Please refer to [link][14] for USDM setting. 2. Install the package dependencies by running the below command: ``` sudo dnf install -y autoconf automake libtool zlib-devel lz4-devel For Debian-based distros like Ubuntu, use these names for the latter two packages: sudo apt -y install zlib1g-dev liblz4-dev ``` 3. Configure the QATzip library by running the following commands: ``` cd QATzip/ export QZ_ROOT=`pwd` export ICP_ROOT=/QAT/PACKAGE/PATH ./autogen.sh ./configure ``` > **Note**
> For more configure options, please run "./configure -h" for help. 4. Build and install the QATzip library by running the below commands: ``` make clean make sudo make install ``` ### Configuration > **Note**
> This section is only required when you are using out-of-tree QAT package. if you are > using qatlib with in-tree QAT package, please refer to [link][16] for details on configuring qatlib. QAT programmer’s guide which provides information on the architecture of the software and usage guidelines, allows customization of runtime operation. * [Intel® QAT 1.7 linux Programmer's Guide][9] * [Intel® QAT 2.0 linux Programmer's Guide][10] The Intel® QATzip comes with some tuning example conf files to use. you can replace the old conf file(under /etc/) by them. The detailed info about Configurable options, please refer Programmer's Guide manual. The process section name(in configuration file) is the key change for QATzip. There are two way to change: * QAT Driver default conf file does not contain a [SHIM] section which the Intel® QATzip requires by default. You can follow below step to replace them. * The default section name in the QATzip can be modified if required by setting the environment variable "QAT_SECTION_NAME". To update the configuration file, copy the configure file(s) from the directory of `$QZ_ROOT/config_file/$YOUR_PLATFORM/$CONFIG_TYPE/*.conf` to the directory of `/etc` `YOUR_PLATFORM`: the QAT hardware platform, c6xx for Intel® C62X Series Chipset, dh895xcc for Intel® Communications Chipset 8925 to 8955 Series `CONFIG_TYPE`: tuned configure file(s) for different usage, `multiple_process_opt` for multiple process optimization, `multiple_thread_opt` for multiple thread optimization. **Restart QAT driver** ```bash service qat_service restart ``` With current configuration, each PCI-e device in C6XX platform could support 32 processes in maximum. ### Enable qzstd If you want to enable lz4s + postprocessing pipeline, you have to compile qzstd which is a sample app to support ZSTD format compression/decompression. Before enabling qzstd, make sure that you have installed zstd static lib. **Compile qzstd** ```bash cd $QZ_ROOT ./autogen.sh ./configure --enable-lz4s-postprocessing make clean make qzstd ``` **test qzstd** ```bash qzstd $your_input_file ``` ### Build Docker Image Also there is dockerfile available for QAT Compression Base which can be built into docker images. Please refer [here](dockerfiles/README.md) for more details. ## Test QATzip Run the following command to check if the QATzip is setup correctly for compressing or decompressing files: ```bash qzip -k $your_input_file -O gzipext -A deflate ``` ### File compression in 7z: ```bash qzip -O 7z FILE1 FILE2 FILE3... -o result.7z ``` ### Dir compression in 7z: ```bash qzip -O 7z DIR1 DIR2 DIR3... -o result.7z ``` ### Decompression file in 7z: ```bash qzip -d result.7z ``` ### Dir Decompression with -R: If the DIR contains files that are compressed by qzip and using gzip/gzipext format, then it should be add `-R` option to decompress them: ```bash qzip -d -R DIR ``` ## Performance Test With QATzip Please run the QATzip (de)compression performance test with the following command. Please update the drive configuration and process/thread argument in run_perf_test.sh before running the performance test. Note that when number for threads changed, the argument "max_huge_pages_per_process" in run_perf_test.sh should be changed accordingly, at least 6 times of threads number. ```bash cd $QZ_ROOT/test/performance_tests ./run_perf_test.sh ``` ## QATzip API Manual Please refer to file `QATzip-man.pdf` under the `docs` folder Please refer to the [link][15] for QAT documents ## Open Issues Known issues relating to the QATzip are described in this section. ### QATAPP-26069 | Title | Buffers allocated with qzMalloc() can't be freed after calling qzMemDestory | |----------|:------------- | Reference | QATAPP-26069 | | Description | If the users call qzFree after qzMemDestory, they may encounter free memory error "free(): invalid pointe" | | Implication | User use qzMalloc API to allocate continuous memory | | Resolution | Ensure qzMemDestory is invoked after qzFree, now we use attribute destructor to invoke qzMemDestory| | Affected OS | Linux | ### QATAPP-33809 | Title | Failures using standalone mode in multi-threaded application | |----------|:------------- | Reference | QATAPP-33809 | | Description | If a multi-threaded application using standalone mode (no qatmgr) calls icp_sal_userStart() in one thread and icp_sal_userStop() in a different thread, errors like "Incorrect thread xxx for section SSL_INT_X. Expected yyy" will be seen.  | | Implication | Standalone mode is typically used when running in a container and this error has been seen there. If icp_sal_userStop() is called in a separate thread, after this error is seen some resources, e.g. memory, will not be freed. As long as the process finishes after calling icp_sal_userStop(), the resources will be freed by the OS. However, if the process doesn't end and icp_sal_userStart() is called again, the behavior will be undefined.| | Resolution | If running in standalone mode in a multi-threaded process, it's recommended to call icp_sal_userStart() and icp_sal_userStop() in the same thread to avoid seeing these errors.| | Affected OS | Linux | | Driver/Module | CPM-IA - General | ## Intended Audience The target audience is software developers, test and validation engineers, system integrators, end users and consumers for QATzip integrated Intel® Quick Assist Technology ## Legal Intel® disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade. This document contains information on products, services and/or processes in development. All information provided here is subject to change without notice. Contact your Intel® representative to obtain the latest forecast , schedule, specifications and road maps. The products and services described may contain defects or errors known as errata which may cause deviations from published specifications. Current characterized errata are available on request. Copies of documents which have an order number and are referenced in this document may be obtained by calling 1-800-548-4725 or by visiting www.intel.com/design/literature.htm. Intel, the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries. \*Other names and brands may be claimed as the property of others [1]:https://www.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/purley/intel-xeon-scalable-processors.html [2]:https://www.intel.com/content/www/us/en/ethernet-products/gigabit-server-adapters/quickassist-adapter-8950-brief.html [3]:https://www.intel.com/content/www/us/en/ethernet-products/gigabit-server-adapters/quickassist-adapter-8960-8970-brief.html [4]:https://www.intel.com/content/www/us/en/products/docs/processors/atom/c-series/c3000-family-brief.html [5]:https://www.intel.com/content/www/us/en/products/details/processors/xeon/scalable.html [6]:https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html [7]:https://github.com/lz4/lz4/blob/dev/doc/lz4_Block_format.md [8]:https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md [9]:https://www.intel.com/content/www/us/en/content-details/710060/intel-quickassist-technology-software-for-linux-programmer-s-guide-hw-version-1-7.html [10]:https://intel.github.io/quickassist/PG/configuration_files_index.html [11]:https://intel.github.io/quickassist/qatlib/qatzip.html [12]:https://intel.github.io/quickassist/GSG/2.X/installation.html [13]:https://intel.github.io/quickassist/GSG/2.X/installation.html#running-applications-as-non-root-user [14]:https://intel.github.io/quickassist/PG/infrastructure_memory_management.html#huge-pages [15]:https://intel.github.io/quickassist [16]:https://intel.github.io/quickassist/qatlib/configuration.html# QATzip-1.3.1/SECURITY.md000066400000000000000000000003461500263377000144630ustar00rootroot00000000000000# Security Policy ## Reporting a Security Vulnerability Visit https://intel.com/security for information on how to report security vulnerabilities. Do not report any security vulnerability as a regular issue in this repository. QATzip-1.3.1/autogen.sh000077500000000000000000000034411500263377000146720ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ #!/bin/sh mkdir -p m4 autoreconf -vif QATzip-1.3.1/config_file/000077500000000000000000000000001500263377000151335ustar00rootroot00000000000000QATzip-1.3.1/config_file/4xxx/000077500000000000000000000000001500263377000160465ustar00rootroot00000000000000QATzip-1.3.1/config_file/4xxx/multiple_process_opt/000077500000000000000000000000001500263377000223215ustar00rootroot00000000000000QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev0.conf000066400000000000000000000117041500263377000250240ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev1.conf000066400000000000000000000117041500263377000250250ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev2.conf000066400000000000000000000117041500263377000250260ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev3.conf000066400000000000000000000117041500263377000250270ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev4.conf000066400000000000000000000117041500263377000250300ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev5.conf000066400000000000000000000117041500263377000250310ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev6.conf000066400000000000000000000117041500263377000250320ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_process_opt/4xxx_dev7.conf000066400000000000000000000117041500263377000250330ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/000077500000000000000000000000001500263377000221125ustar00rootroot00000000000000QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev0.conf000066400000000000000000000133661500263377000246230ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev1.conf000066400000000000000000000133661500263377000246240ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev2.conf000066400000000000000000000133661500263377000246250ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev3.conf000066400000000000000000000133661500263377000246260ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev4.conf000066400000000000000000000133661500263377000246270ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev5.conf000066400000000000000000000133661500263377000246300ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev6.conf000066400000000000000000000133661500263377000246310ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/4xxx/multiple_thread_opt/4xxx_dev7.conf000066400000000000000000000133661500263377000246320ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 # Data Compression - User instance #4 Dc4Name = "Dc4" Dc4IsPolled = 1 # List of core affinities Dc4CoreAffinity = 5 # Data Compression - User instance #5 Dc5Name = "Dc5" Dc5IsPolled = 1 # List of core affinities Dc5CoreAffinity = 6 # Data Compression - User instance #6 Dc6Name = "Dc6" Dc6IsPolled = 1 # List of core affinities Dc6CoreAffinity = 7 # Data Compression - User instance #7 Dc7Name = "Dc7" Dc7IsPolled = 1 # List of core affinities Dc7CoreAffinity = 8 QATzip-1.3.1/config_file/LICENSE.BSD000066400000000000000000000033731500263377000165550ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QATzip-1.3.1/config_file/LICENSE.GPL000066400000000000000000000431031500263377000165620ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. QATzip-1.3.1/config_file/c3xxx/000077500000000000000000000000001500263377000162105ustar00rootroot00000000000000QATzip-1.3.1/config_file/c3xxx/multiple_process_opt/000077500000000000000000000000001500263377000224635ustar00rootroot00000000000000QATzip-1.3.1/config_file/c3xxx/multiple_process_opt/c3xxx_dev0.conf000066400000000000000000000114271500263377000253320ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * # Rate Limiting * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/c3xxx/multiple_thread_opt/000077500000000000000000000000001500263377000222545ustar00rootroot00000000000000QATzip-1.3.1/config_file/c3xxx/multiple_thread_opt/c3xxx_dev0.conf000066400000000000000000000122011500263377000251120ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * # Rate Limiting * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # # List of core affinities Dc1CoreAffinity = 2 # # # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # # List of core affinities Dc2CoreAffinity = 3 # # # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # # List of core affinities Dc3CoreAffinity = 4 QATzip-1.3.1/config_file/c6xx/000077500000000000000000000000001500263377000160235ustar00rootroot00000000000000QATzip-1.3.1/config_file/c6xx/multiple_process_opt/000077500000000000000000000000001500263377000222765ustar00rootroot00000000000000QATzip-1.3.1/config_file/c6xx/multiple_process_opt/c6xx_dev0.conf000066400000000000000000000123701500263377000247560ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/c6xx/multiple_process_opt/c6xx_dev1.conf000066400000000000000000000123701500263377000247570ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/c6xx/multiple_process_opt/c6xx_dev2.conf000066400000000000000000000123701500263377000247600ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/c6xx/multiple_thread_opt/000077500000000000000000000000001500263377000220675ustar00rootroot00000000000000QATzip-1.3.1/config_file/c6xx/multiple_thread_opt/c6xx_dev0.conf000066400000000000000000000131261500263377000245470ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 QATzip-1.3.1/config_file/c6xx/multiple_thread_opt/c6xx_dev1.conf000066400000000000000000000131261500263377000245500ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 QATzip-1.3.1/config_file/c6xx/multiple_thread_opt/c6xx_dev2.conf000066400000000000000000000131261500263377000245510ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 QATzip-1.3.1/config_file/dh895xcc/000077500000000000000000000000001500263377000164725ustar00rootroot00000000000000QATzip-1.3.1/config_file/dh895xcc/multiple_process_opt/000077500000000000000000000000001500263377000227455ustar00rootroot00000000000000QATzip-1.3.1/config_file/dh895xcc/multiple_process_opt/dh895xcc_dev0.conf000066400000000000000000000100511500263377000260660ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (MCA and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.3.1/config_file/dh895xcc/multiple_thread_opt/000077500000000000000000000000001500263377000225365ustar00rootroot00000000000000QATzip-1.3.1/config_file/dh895xcc/multiple_thread_opt/dh895xcc_dev0.conf000066400000000000000000000106121500263377000256620ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (MCA and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 1 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 2 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 3 QATzip-1.3.1/configure.ac000066400000000000000000000232551500263377000151640ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([qatzip], [1.3.1], []) AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability foreign subdir-objects tar-pax]) AM_SILENT_RULES([yes]) AC_USE_SYSTEM_EXTENSIONS AC_CONFIG_MACRO_DIRS([m4]) # The lib version would be calculate from this value # Not directly use this version, if the LIBQATZIP_VERSION is x.y.z # lib major version would be x-z, second version is z, and last is y AC_SUBST([LIBQATZIP_VERSION], [5:0:2]) # Checks for programs. AC_PROG_AWK AC_PROG_CC AC_PROG_LN_S AC_PROG_MAKE_SET AM_PROG_AR AC_PATH_TOOL(PKGCONFIG, pkg-config) LT_PREREQ([2.4]) LT_INIT # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL AC_C_INLINE AC_TYPE_INT64_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T # Checks for system header files. AC_CHECK_HEADERS([stdio.h stdarg.h fcntl.h limits.h memory.h \ unistd.h stdint.h stdlib.h string.h sys/ioctl.h \ sys/time.h sys/types.h sys/stat.h unistd.h utime.h \ pthread.h sched.h]) # Checks for library functions. AC_CHECK_FUNCS([atexit getcwd gettimeofday \ memmove memset mkdir munmap \ realpath strdup strerror strrchr \ strtol strtoul utime fork malloc mmap \ sched_getcpu]) # Checks for pthread. AC_CHECK_LIB([pthread], [pthread_create], , [AC_MSG_ERROR([not found pthread_create in -lpthread])]) #check for numa. AC_CHECK_HEADER([numa.h], , [AC_MSG_ERROR([numa.h not found])]) #check for zlib. AC_CHECK_HEADER([zlib.h], , [AC_MSG_ERROR([zlib.h not found])]) AC_MSG_CHECKING(zlib version) AC_TRY_COMPILE( [#include ], [#if ZLIB_VERNUM < 0x1270 #error zlib version is too old ... #endif], [AC_MSG_RESULT([ok])], [AC_MSG_ERROR([zlib version must be 1.2.7 or higher.]) ]) AC_CHECK_LIB([numa], [numa_node_of_cpu], , AC_MSG_ERROR([numa_node_of_cpu not found])) AC_CHECK_LIB([z], [deflate], , AC_MSG_ERROR([deflate not found])) #check for lz4 lib AC_CHECK_HEADER([lz4.h], , [AC_MSG_ERROR([lz4.h not found])]) AC_CHECK_HEADER([lz4frame.h], , [AC_MSG_ERROR([lz4frame.h not found])]) AC_CHECK_LIB([lz4], [LZ4F_compressFrame], , AC_MSG_ERROR([LZ4F_compressFrame not found])) ##check for xxhash lib #AC_CHECK_HEADER([xxhash.h],,[AC_MSG_ERROR([not found xxhash.h])]) #AC_CHECK_LIB([xxhash], [XXH32_update], ,AC_MSG_ERROR([not found XXH32_update in -lxxhash])) AC_DEFINE(XXH_NAMESPACE, QATZIP_, "Prefix xxhash API with QATZIP_") #with ICP_ROOT AC_ARG_WITH([ICP_ROOT], AS_HELP_STRING([--with-ICP_ROOT=PATH],[Used to link Cpa library]), AS_IF( [test "$withval" = "yes"], AC_MSG_ERROR([--with-ICP_ROOT=PATH requires a PATH]), [ICP_ROOT="$withval"] ) ) #check for qat header file. ICP_INCLUDE_CFLAGS= AS_IF([test ! -z "${ICP_ROOT}"], [ #check for OOT relative header and lib AC_MSG_CHECKING([qat header files from ${ICP_ROOT}]) AS_IF([test ! -e ${ICP_ROOT}/quickassist/include/cpa.h || test ! -e ${ICP_ROOT}/quickassist/include/dc/cpa_dc.h || test ! -e ${ICP_ROOT}/quickassist/utilities/libusdm_drv/qae_mem.h || test ! -e ${ICP_ROOT}/quickassist/lookaside/access_layer/include/icp_sal_poll.h || test ! -e ${ICP_ROOT}/quickassist/lookaside/access_layer/include/icp_sal_user.h], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([QAT header files not found in $ICP_ROOT, please check \$ICP_ROOT]) ], [ AC_MSG_RESULT([yes]) ICP_INCLUDE_CFLAGS=" -I${ICP_ROOT}/quickassist/include \ -I${ICP_ROOT}/quickassist/include/dc/ \ -I${ICP_ROOT}/quickassist/utilities/libusdm_drv/ \ -I${ICP_ROOT}/quickassist/lookaside/access_layer/include/ " LDFLAGS+=" -Wl,-rpath,${ICP_ROOT}/build/ -L${ICP_ROOT}/build/ " ] ) AC_SUBST(ICP_INCLUDE_CFLAGS) AC_CHECK_LIB(qat_s, cpaDcCompressData2, , [ AC_MSG_ERROR([cpaDcCompressData2 not found cpaDcCompressData2]) ] ) #check for icp_adf_get_numDevices/icp_sal_userIsQatAvailable AC_CHECK_LIB(qat_s, icp_adf_get_numDevices, [ADF_CFLAGS="-DADF_PCI_API" AC_SUBST(ADF_CFLAGS)], [ AC_CHECK_LIB(qat_s, icp_sal_userIsQatAvailable, [SAL_CFLAGS="-DSAL_DEV_API" AC_SUBST(SAL_CFLAGS)], [AC_MSG_ERROR([icp_sal_userIsQatAvailable/icp_adf_get_numDevices not found])] ) ] ) #check for usdm lib AC_CHECK_LIB(usdm_drv_s, qaeMemAllocNUMA, , [AC_MSG_ERROR([qaeMemAllocNUMA not found])]) ], [ #check for qat lib. AC_MSG_CHECKING([qat header files from sys usr]) AC_CHECK_HEADERS( [qat/cpa.h qat/cpa_dc.h qat/qae_mem.h qat/icp_sal_poll.h qat/icp_sal_user.h], [ AC_DEFINE([HAVE_QAT_HEADERS], [], [QAT header files in include/qat subdirectory]) ], [AC_MSG_ERROR([qat header files not found])], [#ifdef HAVE_QAT_CPA_H # include #endif ] ) AC_CHECK_LIB(qat, cpaDcCompressData2, , [ AC_MSG_ERROR([cpaDcCompressData2 not found])], [-lusdm -lcrypto]) #check for icp_adf_get_numDevices/icp_sal_userIsQatAvailable AC_CHECK_LIB(qat, icp_adf_get_numDevices, [ADF_CFLAGS="-DADF_PCI_API" AC_SUBST(ADF_CFLAGS)], [ AC_CHECK_LIB(qat, icp_sal_userIsQatAvailable, [SAL_CFLAGS="-DSAL_DEV_API" AC_SUBST(SAL_CFLAGS)], [AC_MSG_ERROR([icp_sal_userIsQatAvailable/icp_adf_get_numDevices not found])], [-lusdm -lcrypto] ) ] ) #check for usdm lib AC_CHECK_LIB(usdm, qaeMemAllocNUMA,, [AC_MSG_ERROR([qaeMemAllocNUMA not found])]) ]) #check for compile flags AC_MSG_CHECKING([cflags]) CFLAGS+=' -Wall -Werror -std=gnu99 -pedantic \ -fstack-protector-strong -fPIE -fPIC \ -fno-delete-null-pointer-checks -fwrapv' AS_IF([test "x${CC}" = "xgcc"], [CFLAGS+=' -fno-strict-overflow'], []) AC_MSG_RESULT([yes]) #check for compile flags AC_MSG_CHECKING([ldflags]) LDFLAGS+=' -fstack-protector-strong -fPIC -pie -z relro -z now -Wl,-z,noexecstack' AC_MSG_RESULT([yes]) #Enable debug mode AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enable debug mode]), [ debug=true CFLAGS+=' -g -DQATZIP_DEBUG -O0' ] , [ debug=false CFLAGS+=' -O2' AS_IF([test "x${CC}" = "xgcc"], [CFLAGS+=' -D_FORTIFY_SOURCE=2'], []) ] ) AM_CONDITIONAL([QATZIP_DEBUG_AC], [test x$debug = xtrue]) #Enable qatzip symbol AC_ARG_ENABLE(symbol, AS_HELP_STRING([--enable-symbol], [Enable qatzip symbol]), [ symbol=true CFLAGS+=' -g' ], [ symbol=false ] ) AM_CONDITIONAL([QATZIP_SYMBOL_AC], [test x$symbol = xtrue]) #Enable qatzip pthread_barrier AC_ARG_ENABLE(pthread_barrier, AS_HELP_STRING([--enable-pthread-barrier], [Enable pthread_barrier]), [ pthread_barrier=true CFLAGS+=' -DENABLE_THREAD_BARRIER' ], [ pthread_barrier=false ] ) AM_CONDITIONAL([QATZIP_PTHREAD_BARRIER_AC], [test x$pthread_barrier = xtrue]) #Enable lz4s-postprocessing AC_ARG_ENABLE(lz4s_postprocessing, AS_HELP_STRING([--enable-lz4s-postprocessing], [Enable lz4s and zstd post processing]), [ lz4s_postprocessing=true #check for zstd lib SAVE_CFLAGS=${CFLAGS} CFLAGS= AC_CHECK_HEADER([zstd.h]) AC_CHECK_LIB([zstd], [ZSTD_compressCCtx]) CFLAGS=${SAVE_CFLAGS} ZSTD_LIBADD='-lpthread -Bstatic -lzstd' AC_SUBST(ZSTD_LIBADD) ], [ lz4s_postprocessing=false ] ) AM_CONDITIONAL([QATZIP_LZ4S_POSTPROCESS_AC], [test x$lz4s_postprocessing = xtrue]) AC_CONFIG_FILES([Makefile qatzip.spec src/Makefile test/Makefile utils/Makefile] qatzip.pc) AC_OUTPUT QATzip-1.3.1/dockerfiles/000077500000000000000000000000001500263377000151615ustar00rootroot00000000000000QATzip-1.3.1/dockerfiles/Dockerfile000066400000000000000000000135611500263377000171610ustar00rootroot00000000000000#========================================================================== # \ # \ # BSD LICENSE \ # \ # Copyright(c) 2024 Intel Corporation. \ # All rights reserved. \ # \ # Redistribution and use in source and binary forms, with or without \ # modification, are permitted provided that the following conditions \ # are met: \ # \ # * Redistributions of source code must retain the above copyright \ # notice, this list of conditions and the following disclaimer. \ # * Redistributions in binary form must reproduce the above copyright \ # notice, this list of conditions and the following disclaimer in \ # the documentation and/or other materials provided with the \ # distribution. \ # * Neither the name of Intel Corporation nor the names of its \ # contributors may be used to endorse or promote products derived \ # from this software without specific prior written permission. \ # \ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR \ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, \ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY \ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ # \ # \ #========================================================================== ARG UBUNTU_BASE=ubuntu:22.04 FROM ${UBUNTU_BASE} AS builder ARG QATLIB_VERSION="24.02.0" ARG QATZIP_VERSION="v1.3.1" ARG QATZSTD_PLUG_VERSION="v0.2.0" ARG ZSTD_VERSION="v1.5.5" ARG GID ENV DEBIAN_FRONTEND=noninteractive # Install required packages RUN apt-get update && \ apt-get install -y apt-utils # Upgrade all other packages RUN apt-get upgrade -y && \ apt-get install -y \ libudev-dev \ make \ gcc \ g++ \ nasm \ pkg-config \ libssl-dev \ libpcre3-dev \ zlib1g-dev \ libreadline-dev \ lua5.4 \ liblua5.4-dev \ autoconf \ automake \ cmake \ git \ ca-certificates \ liblz4-dev \ lz4 \ p7zip-full \ libnuma-dev \ numactl \ gzip \ libtool && \ git clone --depth 1 -b $QATLIB_VERSION https://github.com/intel/qatlib && \ git clone --depth 1 -b $QATZIP_VERSION https://github.com/intel/QATzip.git && \ git clone --depth 1 -b $QATZSTD_PLUG_VERSION https://github.com/intel/QAT-ZSTD-Plugin.git && \ git clone --depth 1 -b $ZSTD_VERSION https://github.com/facebook/zstd.git && \ git clone --depth 1 -b $ZSTD_VERSION https://github.com/facebook/zstd.git zstd_with_plugin # Create a non-root user and group RUN groupadd -r appuser && useradd -r -g appuser -s /bin/bash appuser # Build and Install QATLib WORKDIR /qatlib RUN ./autogen.sh && \ ./configure --enable-systemd=no && \ make -j && \ make install samples-install && \ groupadd qat -g ${GID} && \ usermod -a -G qat appuser #Build ZSTD WORKDIR /zstd/lib RUN make -j WORKDIR /zstd/ RUN make install # Build & Install QATzip WORKDIR /QATzip RUN ./autogen.sh && \ ./configure --enable-lz4s-postprocessing && \ make qzstd && make install -j #Build ZSTD_WITH_PLUGIN WORKDIR /zstd_with_plugin/lib RUN make -j #Build and Install qatzstdplugin WORKDIR /QAT-ZSTD-Plugin RUN make clean && \ make ENABLE_USDM_DRV=0 DEBUGLEVEL=2 -j #Install ZSTD WORKDIR /zstd_with_plugin/ RUN make QAT_SUPPORT=1 SEQPRODLIB=/QAT-ZSTD-Plugin/src PREFIX=/zstd_with_plugin/ -j && \ make install #Added to remove libc library for vulnerability issue RUN apt-get purge -y linux-libc-dev FROM ${UBUNTU_BASE} RUN apt-get update && \ apt-get upgrade -y COPY --from=builder /usr/local/lib/libqat.so.4.2.0 /usr/lib/ COPY --from=builder /usr/local/lib/libusdm.so.0.1.0 /usr/lib/ COPY --from=builder /usr/local/lib/libqatzip.so.3.2.0 /usr/lib/ COPY --from=builder /usr/local/bin/qzip /usr/bin/qzip COPY --from=builder /usr/local/bin/qatzip-test /usr/bin/qatzip-test COPY --from=builder /QATzip/utils/qzstd /usr/bin/qzstd COPY --from=builder /usr/lib/p7zip/7z /usr/bin/7z COPY --from=builder /usr/lib/p7zip/7za /usr/bin/7za COPY --from=builder /usr/lib/p7zip/7zr /usr/bin/7zr COPY --from=builder /zstd_with_plugin/programs/zstd/ /usr/bin/ COPY --from=builder /usr/bin/lz4 /usr/bin/lz4 COPY --from=builder /usr/bin/numactl /usr/bin/numactl COPY --from=builder /usr/bin/gzip /usr/bin/gzip COPY --from=builder /usr/lib/x86_64-linux-gnu/libnuma.so.1 /usr/lib/x86_64-linux-gnu/libnuma.so.1 COPY --from=builder /etc/group /etc/group COPY --from=builder /etc/passwd /etc/passwd RUN ldconfig #Switch to non-root user USER appuser ENV QAT_POLICY=1 ENV LD_LIBRARY_PATH="/usr/bin" QATzip-1.3.1/dockerfiles/README.md000066400000000000000000000055351500263377000164500ustar00rootroot00000000000000# Intel® QuickAssist Technology(QAT) QATZip\* Container support QATZip Dockerfiles contains QAT Compression Base (qatzip and zst with zstdplugin) which can be built into docker images on the platforms with [Intel® QuickAssist 4xxx Series](https://www.intel.com/content/www/us/en/products/details/processors/xeon/scalable.html) QAT device. This Dockerfile (QAT Compression Base) is build and tested with software versions mentioned in [software_requirements] (../README.md#software-requirements)section. ## Docker setup and testing Refer [here](https://intel.github.io/quickassist/AppNotes/Containers/setup.html) for setting up the host for QAT_HW (qatlib intree) if the platform has QAT 4xxx Hardware device. Stop QAT service if any running on the host. ### QAT_HW settings Follow the below steps to enable required service. The service should be dc alone for compression. in step 2 depending on the particular use case. Configure the required service only to get best performance. 1. Bring down the QAT devices ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo down > /sys/bus/pci/devices/$i/qat/state;done ``` 2. Set up the required crypto service(s) ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo “dc“ > /sys/bus/pci/devices/$i/qat/cfg_services;done ``` 3. Bring up the QAT devices ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo up> /sys/bus/pci/devices/$i/qat/state;done ``` 4. Check the status of the QAT devices ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do cat /sys/bus/pci/devices/$i/qat/state;done ``` 5. Enable VF for the PF in the host ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo 16|sudo tee /sys/bus/pci/devices/$i/sriov_numvfs; done ``` 6. Add QAT group and Permission to the VF devices in the host ``` chown root.qat /dev/vfio/* chmod 660 /dev/vfio/* ``` ### Image creation Docker images can be build using the below command with appropiate image name. ``` docker build --build-arg GID=$(getent group qat | cut -d ':' -f 3) -t --no-cache ``` Note: GID is the group id of qat group in the host. ### Testing QAT Compression base using qzip\* utility ##Compression using 7z ``` docker run -it --cap-add=IPC_LOCK --security-opt seccomp=unconfined --security-opt apparmor=unconfined $(for i in `ls /dev/vfio/*`; do echo --device $i; done) --env QAT_POLICY=1 --ulimit memlock=524288000:524288000 qzip -k $your_input_file -O gzipext -A deflate ``` ##Decompress using 7z ``` docker run -it --cap-add=IPC_LOCK --security-opt seccomp=unconfined --security-opt apparmor=unconfined $(for i in `ls /dev/vfio/*`; do echo --device $i; done) --env QAT_POLICY=1 --ulimit memlock=524288000:524288000 qzip -d $your_input_file.7z ``` NOTE: "Warning, users who have access to the docker group also have root access" QATzip-1.3.1/docs/000077500000000000000000000000001500263377000136175ustar00rootroot00000000000000QATzip-1.3.1/docs/QATzip-man.pdf000066400000000000000000012670701500263377000162500ustar00rootroot00000000000000%PDF-1.5 % 2 0 obj << /Type /ObjStm /N 100 /First 827 /Length 1464 /Filter /FlateDecode >> stream x͙n7olq}h 7-'Fmɕm4jw%Rr"?%G )R8AEd/ H ep1BN tQ$N(+lB9MRzO@4"@IB;!Q+/Ɏ%)RF:; ![ZaC dD!( dH1]*Y!%$j9S B8Z"nR,BH@ XYrdCAln !Rr'B$A42E)y!p&`R$YZKE4⃄#IɳK )!*-$+,Bּ1!WBj@!%զ{䅐; G  m!& */B`Q ss$v^Mbg(]|>{϶iKx1xvÿ?RR2gtOfe2$3z̄{U}jMz?xNwB^e=;cO'6kR]TsK暛e%{8mKVl|q=)_CunWspՈI8LW8Lw8M0edfΦUS2U:;X?p3{M^vx]f*[ya z<{X^P77S=˯09函Z'g85VNdF&s'Kk℣_>{VՏ w(ѭKu^o>6Y_{H߫cJŘb@͛ۖm]E-kX> stream xՙKo7<&y9'h&(m4_PbѺbsEi%qiq;.ypȕ!(j2W{E]֊\2qkP4QƕHoDtt8jn D A+J@V DpX>n6p=B :j-^pZ' -TxF fQF1B50(F!(Vu"~"B aǀ ۰LGa M"he`2APx`2beB ae nE䬆VLb ?k,u Ai#c8"h8t%\+w,N `@q,KFCdRDDAx#˘E뛈QkxA#}0\-a8"p{aF >[ |4BCad Hdg`ьx.Q+N@c /1f(Cpp"" "@/^cuznԳLFzhzhzrY?i0P4:I6IQ4r,iIs.DOH3Mwglswϋuӗx<aq^i2@?iX=Te=='.y'."m0n8 #e`M7lTdl9Si.T*v:l‡*=2UؾcJ.?!Xih24:I˾R<(c$ cgnKRGqr;|S&?p/Ek'vٯpvι8m!nl$ffzunWzQ~NFZ[`GEv"6Z ֟%(2@Qh7Me+{iVi@;48?=ݧybG3R_, 9 } XA.#DYn/=BiBJ}p^Ffe69-HLꮰ%{/=jJ1)dKh.>f8[/]y8TWPi_Amg罇4|⫚jOj*{Q θquu=9hc=˻:?˻W<^W{~ܻϳvu|̏"k?}*T zWe(%[ҝ?Zݡ|H2l|^K/ +N7vvӚdn 㬃5#q\ q;(=k_.C_+6V嗽2ؗ'v}^9_{ endstream endobj 404 0 obj << /Type /ObjStm /N 100 /First 886 /Length 1490 /Filter /FlateDecode >> stream xՙKo7<&rI@ uCKb+Zr,9n&j)DZ X4wArkRX5rAX*-kGA^K#63JZ WBiQB>PhlPrJ@TbcZ+T TT*z0X%-i"T =zB'EW$!YFPj О{yHPzHRxl; R6 F0F0XBc@0a`#bw**5Iɦg5y'Is (9ƣPp*;#8<Z[ga,RN:=AK Ag`ggz$t8(7h ƒ.J§!A/W0$^HA607;A< :&;<8  l VذH0CT<"+qr*N~'oŋ[햛9\ϕ|)^xϿRs.L\S\wg-;.Xg$Yc.~ƩT={.θ;^MGQ.mfXf;%tq ͗.V\(\)<6o2/Y\[oru.J;NցuM-}̵\̝>-Vv<:GTAk6dkճMƼɲK)jRY[]"s= TꩠKMC1(rmPBxVj_ /|\Z˵~yv}o VtCX˔֓`oTV%jݷ.:(4r>e2>ɧ1R+#&@7o[yٶ)lG uqd/[nzi#nq|Ōd9GQbLV>\M_;z~V[Xo ]3ݫ:6F[)Tmi0㟗0SwmEoL:o:.ZAۿm}ӗLiM \_vIYH/,ӔJ JzoCr?x endstream endobj 605 0 obj << /Type /ObjStm /N 100 /First 886 /Length 1540 /Filter /FlateDecode >> stream xXn9}#$-!$ȍh$d!@$\S;dl@J59u]+N[\2 WcW\kT.BſIEğJ:͢ *'Ohg` NEga)c#|\T8QVƳ73Fp2zD)@d YŀIV@䔁6 rFHY 5 h@LcP1ul@Z"! 0#9eP 34CM!rkfY> )e<P01"͎p4"'aϰl>YyHP3xtLvyx>a]aT0&,L37wp&*녀 j| Yq8CLGߜ]Uo47G8}? wcuDaWtTB{9 ,9d+Lq:~x?v!ý$?e٩ <_t_'2]M; )8sB5塽S$7ap"~VAߐW-)MM.́;mY]xieC+5U\zuj~YpLjwt!W`iϜkBU`[KX6T loqgU;\!XE#-UQS&)heҘ7W{r'g=~lv&g.m߂ *@ $p|s~iY< endstream endobj 806 0 obj << /Type /ObjStm /N 100 /First 888 /Length 1498 /Filter /FlateDecode >> stream xZnG}߯Gx1}. !9x[x8B~IM(J>Ffgx{k#]]sN1ŒX61qTx6!$|Lޙ&%O2Ҥx<єx | W ٸ B1.2..S7.EAIN%2L! qH vVW`0H' 0 ;)) '6> ,s2"3Sr4J2$ M+ބ.2.rI&$YU؄,@; o G-!gE$"Lo7FLf(mBE`EFpd9\! sl0QD6Q"L|& $bHl1 &0B$k,gDa(% .XdO . LfA C0b+ 30e\$`6O f`$1'LLMd)N\4KKDr(XR^(TP\D!$%Y9ÒGQ r,ѡ 'NCB>5Oɋŵyg}|NqcE  >n56Z|-mqp(Xi7z\.6:OAM0/XRTe~:vҝ-yƻb~s1&AIvԎ@4,\wrxtOB̾.W&D`6r=WfL /D;Mw 6S?ւ*ʖZ5q9R=c0&L~,֜kwbn د8^itE]lBǢZ*a%hjMѴKj’j'n[RMs;;n o&{(o_&BB8 oC~6L᱿Лbo9x5'İp\5*&cXsϖ=z3i;YRhB&~}C _hZRx;~Fj He9 Ob.ST]y'曘:JW1胮Iq#| Y`}QFg}uG5Z:V~,+O9T벁ZK-1FK#> y˅nrҕCkK@G (UؠfC]dڽ-ܼlMjuugua6l endstream endobj 1090 0 obj << /Length 156 /Filter /FlateDecode >> stream xڅ0C~ōɐ.i*!eC BRb|=220ٲ, @7GWYl[lXo%jLCӮǮ0,H* GlŁi q> stream x3PHW0Pp2Ac( endstream endobj 1132 0 obj << /Length 725 /Filter /FlateDecode >> stream x[s@нhXx6aS$U't& Þ;ߞ=(FG0Xc@{,h Ҵ!kv&A/l1S$;l*)9'L1)In ֌@7%4':b̀Ra2&ғU5^gPBL00140gyՇ}# |e`sO$;R))01{sOhB,Žɺ.Bғ71O̓~Մ )4YdVYTZB7l>hpnk~2X(C ej~B$,jQ ,Uئ¶dL; Ls@jA+w+ăIzi{Ղ %q&ќOq8J w,a x, 2E6K%׾Uk^vk]6fUߥMiN$Ƽ \@<_y=Ep* ˏ[^!]i:0[;5SykUa%Up| j_v:K,({V`ԯe 㡪 tٍضϓqrut tKmNѾ):(lw.GqnRtkS8?S* Kk^޳=pjGat j ZJ!]fXS!kƺ[y29` endstream endobj 1171 0 obj << /Length 902 /Filter /FlateDecode >> stream x[O0 ?&|<҂`0"MC(iW-1s/I!%$5DZϱ&Ύ4 (HM3g:uϽho{_w8{YS " 9#s H7+#8QsN;'֪tnۺ~G1C+]eCӤL nKnp' oO.FB:r.V/Goxͦs0Y~Yؼv >@N`M'~7,ea=G~?J:>}N{~^C .#RۃHGZgE?2N\͉YD FnW3d]n2JNa2 zJ( qnx(rPR=v͑|uۢێG dݸDWIęb_njt[J (ڈBc>?4 *R eURżwo^1>b(w(VW76'PL!^׊0.e(.Ȼ74$EK SSXpGz\d]gIS/TlyX͞ -|}RjHi{ fM5`}B #_Wx))%+!yQB>a2 v82_y㱕CANE8oRV  PV%MD5D Qvl2ռ=!ڀk$L,d4 x n7O'u7]c٘CQT]Pg$Rţi393P RVGWnbt9A\_+ endstream endobj 1007 0 obj << /Type /ObjStm /N 100 /First 1000 /Length 2237 /Filter /FlateDecode >> stream x[o~_Ǥ{" N$@G&F])NۿkmK(`f7 gH-ĐbASH%;!:K#JNNԠ `NpZPb<CUg1$ΚTckDgxTsY0HF19crR}XuɱܨH9Uiu(8PI>(1,SvVR`jeБp \8UTq΅Kъ* c@\۪EMA:>IRKUP`<%Txؾ)cH1hj%+NqЦ{(52;Am|۷9hU7`T a t"-lu:018XVjȉ3&% *,> ؔ[9*ƀ1f哜K3$XcT 3%h+h)% j{,TRXnrXZѯHC~> }n)7 &yrrQ|t65ζ-kCu^?k㖔rtSJio)YɢTٓ'as6^ gዛ_br)M<ї᫯ξx777@"o^EoSo7{s֛C0YjM_΂K 7$Ȫ_ ؖ?; ry)oY*D.ɆUTt$).[\KHG ՛7z~wGHFGIFJ7?%HQ(Q?XۃPқ_"vxzxdGIfJvJGIGJqJ*GRfr{X?wuv9Q;(9̱$H݁>Unb)l۽v.Om^mn{Lg7Wۛ}۷|s!NZulHJ}}^`<#!ǩI{@\UJ3x}uq݅yؼ~؅wIcKSi>?$x//徜ziմ;  tB;aȝ(S:99uΩsNsӞ'kҝmoٵ]luSP|ӗ=N/0V IH銺sTRPسy} 'hSz/Қ04ejiI*6Y3uA"ԊR&%(S ?. 脼\'օh ' b:&T0a~QEڊZ&Q1@,SU!kmʩ2e?cmZ݄\h%fkl#sЬnciT?;$+и;u U!ELa`EΆ4@KT` \ksTa2@/6`Md:B!HhuOG& 8ra DFd#JYgĬwH<8NVh&5 q^2IŔL-mv] Sh<T$uOB#Γ*2a4GHJ0d?f|/H.SNvVO>OoQϷ[-|zE=ߢQ̽>p#}tK]G>t9K,v9k笝ʚ9b7ʬVk|g+倈d9^y!)'0nZBăglHy7(K,T@2HiM `^kAׯ"`B咸tw.dSr !T%ox6X7bH·"Zf’"\L4&%$l-De> b^ BXRb&],د)[xiY=/@4M l"7l`>;e$3{nlsDKiJ L[F%eKlBAxaJ <3\|HJ (4i+GmF0 H~ #9iD(Pnk|MV\tC"$MڞI@YiD9^OYr70xL Z9-$cJe~%Yiy' ~Emc fīy6<`%lp;  endstream endobj 1204 0 obj << /Length 1004 /Filter /FlateDecode >> stream x]s8+t lΦƞEPPRfmHIWp uIf m̈G9kt*`(+ TB(0&0=0_c"{~KӴ<<:~=^Tx>@b{3q 9 LFF<#%b W HmDu b!~2y|~Sbb Ϳ n.Is^ݧ<m0nqF>6QH>:x٢C:Y{9O/Δ)5LO|ƽB>J*/Ιqۜ5ϛ &sKy͑m3c*<8}r7} [v<`<;֠_[s/*<әˬ\SN_!&p|<]Z;]8鄅M,&2PrZd7^IB/Y(glǽ %^wq$͒IR Z #qǪ~g{yL">vH' BE!k2yE($ˍn .E`':p6-ojd;Άnռ2S4"K7s*>ckӷnj"PEc,Z,Hrnad,6J(6=8r&EZsZ^\pVTLLU疱W)\:u7wK<g^,kJwdtz"tP۳5Q5Y[M5i\_QP HV2f,5i4'܋fҁ6n]${|nv:8I %Ǻ ,֭!csv=B%]!/Mw'5ۻx*谝8 JEYwµyZ%xFbr苟 x'คVϿ5 H`1TgL3aʍ.WѮl;ch 9 endstream endobj 1238 0 obj << /Length 866 /Filter /FlateDecode >> stream x[S0)Nx]uqfu7aRX@!7ҭ:-jRZ(i䟓\ǃo?BP0A)|;ɝ{1> 1HoΫ:Gcv! )$ D;R_)`BΨy?5ݪ)4%HBs QU $S*T;$tC6hL:ɳ폂!ȁsQo|R:6~5J!P`xq/}P4p\ލ%b$ $ӕu̬V@ehs3kE9g _\!Aj u٩o62>9+1rFNl6}rYn7hLRa {=j3]RӽwMQ j( W&|zRxi =Klڈ'Mc VP䉺(m@ql Qv5;].k7ʳ2(UV&:sT4R7QlroMfӉ܃lbl"3ΙBaZرTwU[vWfyw/XC endstream endobj 1271 0 obj << /Length 938 /Filter /FlateDecode >> stream x[s8zPunmӇM3Lj/6MO_F)f$5_H77?WRBP0HM`:?璘O'`LAΕ<9z=ݎ=^T ]^!0Vg 3jG`28BMvd!ȕR`ڞr cL(Ln8mrLv;kS6ed= jnf +YH6UqGܱfɋ޵KϽ7h];J]g+/޹;~X0"h ƜAb6,ab#Dx;DHLʱ2_E}K$Aׄ|B~*!P#ǔbo_&u~- VI +I lAi-J$Co{S4gV<.I^;SI6t6F~-fYwT$%{_܉q"UǫUuW?92te/? @FC&:\^&E.S O0ȉvCQ!EvL8 S/&~FNNW?L>^f>4&Y=F)z5xXq?W^_: f@wtUmO4?TTd +|\A{(_Z7h|(yg > stream xn@~Y slۤ"5U;Y%0ė;ƆDJf5?}΀ p}y~RBP0A%@h}\C 6G^9ty؞BP *@Ls Ss0.=ԄUϓM @I;P)0DP9ԐL)ōɂ?Z¤ET$t`< 0p.05]Ԁb$;R; q]-h>].>v4¨KpInPk`*<{s6@w1S=` ÅY,Zh>_fҥȕr|VyMxYES(S`&M46aTQ<29|->9AHE47 Ċ2I^kp>/P,$rjU45 dO!p"]]b LuUd/>pen7Pk=KoNPt'}YQ5duňOcG}WT5t,)ғ}zJ[z3_Őۢ_KkI/9_c|_l<{kUtW1[ˢA\J8Is# ZhE/hU#^tR9oЮ{1qH_ժ}Am]C- =Hœ'\:Z%T5kۿH`Պ< rqsLj6> stream x[]}_EW*$0 @f7wHL`fasJu==jjuJU8-\8sQ{N!SR *5Gb>,&CZB+\3AZ蜭%Zk V*dk TݧeC[ׂ1$k L6xV bд.$c ͤr^j yHb1F+A5HibZ 3% %gk==4 iϡSWSR9ԡ%TNj UVz l Ui\mރ A jzB+e-_IWhՠ4y20 %9fVM[)41mÎ$45 L#15$> :ːCmG еFNCqf &B,2|f׆ nMH6m%k mVonx(MMUmy@܆>>Xg:!YhxCfZf hK!3 M)o F>tQp1C`Mg1Xץ Pݖ8l/ٳӫrN_^~~_uHoN=<~\~~w^I,sTh cG[9QY8 ܾ Ÿ>|Mcow9DUcSʣCDooGl+HG2JX ^ݾ{y ^_]\\wĥHsMrlm捾7jFy!p%W\]z/^{s/Os<4\rs%76o.kZZZ4X W+KTR5 |~D 0ɢPg!46=,,!"5$ 0U\6I L*Օ$a~ĎSK|}FF.1IHY11#05DXi 0iƂS")-`Kc2 Hıf+B:TpyL xI)ZF+Zđ(FE9\Ub%;'Z%gTLW, udm`JXu -p1^ 7hxqr0m 8q.fԷy&Wx>XhgFQT|'#4tA'nmLȉ?ݿr}/h 9Q:~AU ]P?I@g~v }/{OXaͦIA-_,Q !DsMi3y +jDx3{22 %wJď4^ޖ#bqc-#JMU/kʛV_Ht-qE3Z%ZrjJ83g}Fy$͠k iG4W5T}>G)WyDu]-E[:# Y t,'<#7ъ?s|;ɏ$?>H~| Aɏ$?>H~| Aɏ$=r<~|ڃRsN endstream endobj 1332 0 obj << /Length 886 /Filter /FlateDecode >> stream xKs0:Do#EL r&0CS$NIIvɉJsAg_w|"p$;}N^4j~(%syze6[\(A*WB8S0으̴!R;/e7$W뮟Uq9pm*!hbWXe69]͗(Usy=Kp8!#V:h12gl>=>} w6@+ӬhI%r.c g#QH7#,q_'tz}z[|| pyhO %Q*5 FeTXK֮iW>Ʃ7|&H^R8 )E״82'H ozh-<´|oڋ:DWS i^"CLAvM)%8zdF@]S”p2,3 RYd`$&idpߤ~2StA+)\8WnEy Q<ᔓs(=u ikLJHQau\/j>xzIeF5Yj'OYEy~6ɠێ@PÔxJG^}r2jCދGM^D׬#4Sx$!^MaЫɗD/Q-U~ AG[,y]{AX͋yOuv2A`7V2vP*U+bi_ir\]mJ,蓥¶V`\GmvvopC{7(s9,eק7O6Ŗoύe DpJ endstream endobj 1365 0 obj << /Length 797 /Filter /FlateDecode >> stream xOo0;G8ijm̑&NIVYUino?7I$&u Q3+:R֛@@sOCPp<@kB($7g?L*YZB BKs PBF]֩[swl0_v)Lq Sg9E)OTHg~>8a cl/mOxͦ =: Eই[.L*NC9Vu!課[lnúex'Q=߯k"zJaڌGr@BAIPܹpmZ6c _,m@۞h ݗH'D87mM"tz a?zpe:mM0F endstream endobj 1398 0 obj << /Length 901 /Filter /FlateDecode >> stream x[S0w~E'}D(ZkN88^~;eT.㜜ZnV (AA%VVnU> ۧɳ9W~yB)~ y H)䌚?ȡfn6% A ͧ* 6_\y!5_f~P.xALc"pdA;9ğ=s#XfIg>(9 jY4FT;-%\h#KG`C-¹WiUQ#j]!lXU.OB! g+XhWMJH}X޹ RW(gAxҪg*hĺ{[ګUc*H[,UD>.ڿ=:M4]I;OO^/)OjtWqk[퇂( 9 (&FfcpIKl.j[UUך-J,$T= fC/Vß92Vmuץi)JҨI8LM.id=߅Ұv8]`4-n{ g'i´ƴnxl}qA,m)e٩d;J%B3I ufABPv=G %j'!͔FzhcnBV8zk"kw;+sܶTX:AwZJ_U_Y˲TлIhRu/Gw! =`_4}o3TXLݣe1pۡF@="w.Ӊ/ Fd,7E,t#P}nYU$ U804A82gxYÞ\X4M&t \ endstream endobj 1305 0 obj << /Type /ObjStm /N 100 /First 1024 /Length 2459 /Filter /FlateDecode >> stream xڽ[K72J& ̀3^8N3cCw2>t;'r0}>T:*q>j*ZB.D}Г0vJj_YM ?旒*Wb[XڤS?Ɖ Mx&b.Y"5@3#z;m$#0^Su3Vf|&b)ܫkx!I\c$49zKu6"HzdjԤ<8)&qI\Ф6m< 9FK:ғK#/(MPo C@dԥÈzj我5kMM|SRj%NM `m9BS/":کYR>T|\aSiq1%wN3l>{tv}X̘6`Ryibq;!_ۢh sBe(o:NR Sp߭>L𧶹:ߪ: (7l_82񍓹D?m82| ;oÙlfgۨ2Q+㌤٣G4ȹYoɌ`5;gCFQJG#Uˌ|,6 Uy:Q[]qL2\PqF61mHihpr/EdTĘ.ӆVQU/Ys{QpOoo渧idgL~ُw@NϾ{N/yH>\س:} 7|ݛs=?Oo_sKKVgCxcZOaMQ4 C(!B#4iC2nH| A`*eGXhY L鰆Ze:7abӫXEW2!1c6 oNB*%9*ΉFR:geN7bFJFV VeVL6bČY1ɊuRL6b~ɋVI1H]EJFR| MI1IeRL6b~KVZ&d')V 1I1I5seRLvb~{ERL7b!sӝ^̉NN"'91.̉FN (i}ߵ,N>RC URL>R|+CR|w/bA0iLA0iLuBf -[ bx-X `-4Bs =4cB$Z&t#)Ob")I1S*)fI(VI1HbJFRlxޣeRbέ URv^_L>R~Ol#)6tY&lMk" endstream endobj 1403 0 obj << /Length 552 /Filter /FlateDecode >> stream xo0W1ywguЪFFe @5~G:@8kIq9?!Nɛw2b-3-3Nrnn \J^[=l|*ZWEgiKZE`&=X˭D%```j䈡V\ w|J`tqy܎S pm-3$8\q??Ol֘ AC*r2Q˔gִntEC^$L-nֻ5bGO؎adVg rE)Oaϛ6S泦PTB3F]K2BKpRu=58N 'J, bICoD?[$YUfCM"+E'GM~ܙ NȀ'?njDžjVǬ99 z-O ^('Ǎ,Wȍ]|?Lu7,DŵQeȚґ6Ku(e,.C\k -q5sۏ4AKcӯi}ߜ,i0@!^ endstream endobj 1407 0 obj << /Length 278 /Filter /FlateDecode >> stream xݑ1O0Wc6( lCP)mH|@+{v{9x̜$f"E%T#3p(u>vPژz~p ba 4[PJo޻V}*rIih$ ~*. &cL3 8f !b\lMvjoGZێGq&}:1;rmYR(@[ђL ;wm맕ҥs9*OA  '|ZZ[8wU @ endstream endobj 1412 0 obj << /Length 210 /Filter /FlateDecode >> stream xڕnB1 F> stream x]o0+|KVv4₁PH5MgNfh -79ǎ>9`ETtngɋ<9:f  0RJ|ɲ:s+JÚv"d"L?[\}R-$$>2Ƹ@ !k\Gm,q^jL N㗽SvA"g\f2<:Uⶀ Ei_Fk"֕}ׅԞĵŀktiGD1Q4%qW~LRIS˜gaڤfBh}[rtSnp*$!A7΅ Mkx @<-$rX; IZ afta輴[ o6fѽ9p:ȷ )E[oG^_y? yz$म3Yˮ UqjێI}Up4ۼTcMݱ¯j~}k@uM)A>H['8ҩ endstream endobj 1450 0 obj << /Length 208 /Filter /FlateDecode >> stream xڕn1 h"(aW%A[w3 o}w0WRE8Ft)Օc\+J콦+OionkH_nx֌,UDWJ endstream endobj 1456 0 obj << /Length 308 /Filter /FlateDecode >> stream xՑ?O0|W#V:ƥ4A >=uJ "L qTT&()FcmA:45Ih`:" M Svo+Rr} JNEN )?OuK)ZJT(K._.8+k" u7~ֱ''"6yBu>a~GҰ|E>a/NzdjBd֋ aǣyge>|m ܑeXrcL%?Z>U-ٳM %: endstream endobj 1461 0 obj << /Length 209 /Filter /FlateDecode >> stream xڕ=O1 wLɭZ"[P!*Wɖ/n32u") uĢXk1BMl?v\z9بטz,Kٖb_XΔ]^7V`]iL|wxVOfL *䒄jb 4⨵C=ks{5?||ٚe]QwiJV endstream endobj 1510 0 obj << /Length 1058 /Filter /FlateDecode >> stream xŘ]s6+<{fQ$YKGf!l;t<^#LNm6-P`B 6sIGX{԰vyWODzU˳ oZwѼfad B7ѾS&E3w㖟 6UN~OsYwpQd8pU ZPRK!'Ch ċDh,HD` Z`L7>59Bʒdٖ֢ |V\iY%\_Y7ֈ66oH-[ 1|D_[ 1a,!wuc/)1D ŝlc-a|p=>pe"Ub"B4m~0cgڻu7#t77۞s~=`Te9׽s]AͿhw!-wcbwArN ΝBQ\u8p/ht.*:/׃pU̮[kKG9='9Ń0+9 \T tI^S`Ϡ>}i@^.kr"d ڑr}d +ODYc??uw 3ŪTY: 4[퍂DBQP~CYN;9P{i^9Es0,al$`fٟϟ oAhhIFeg "m-}8%m?%ף`A) =4+DQ:{D}3;~*a"D!MVm$T=X n5<6૙?Ѷ X d  դM'2>Sd-:cBNSjrln':شUb5nf(MZMg5ʭđEIeZg/im*-`?({k[+&`~-]Hskw{ڢi`7n]g4;"I 2+̂ E/:ruIv2W^=5*yjճ]P endstream endobj 1399 0 obj << /Type /ObjStm /N 100 /First 1000 /Length 2775 /Filter /FlateDecode >> stream x[]o\}ׯc.g83$#@b#mph~uR*h_3ȱdݍځ/w;{8TS9`!ӧ9FG0NJ>u-p__S`i.R`ȥ Iڟ22kBBͿjz% k 豘ܪK-eu4&cp"AjOhĐ,)%_$ } GTSm jd?]T\BxJaR-AzH`ɷMHeQ3% fܠ%ޮ`-5PDͿD D:WiY=^ Lu6{ǹsílbrکЭũON=:Y}d沿OV_竿Z=72|zGuKh%^YRd`ѣzV>,?\uv-YcSѭEl1t$W\Roȇ`0F7=n, #!xLbk+<<^41!,# )01.4'GExĖO6t sCCT f+CiL=0p{>!zWnv6 #ްU0{>$Y; 6Hz|[cJ1rєh-cT-6DdWf'/ajHZ"9$¯iSW{IdXuh}#GJD0ԉih;PW^@ԕm@_^̞V0J";L]==?>!>2~ ^d /Dz?/ޜo®ijO/X}. ڰsuv@@ƠAv=hi h 6$!]KϏEX/H1 M-gY0p}\X{9<R]RQs*FABN!-PCo!z_y5Lzk3x}wfK=HeϒWɢ d*cZ i n(7%t"5S1-t*/_1Vr\zS9>8E!*Agp 8qqP bM`Zb\\.": 5?B4a~ P)2ԮܑA[GLc 5y6ߧ(oWO..7 F~x~dg8&߬fۓoic){J7|ͫjA ϋ6e \~Tt=11c0$C2<$󐜇<$!9c2$~zgrLnK%fw~~|5_|< e-{[EC,D8u\W7Ϧ YF/l=x6腏Eԓ61KyZ`(G-xw=D||P$֐z(ݟ6ޥg_/E h!uĈ9P.<96iɴa}9- V-ߗ:H#*ߧ@r=J|NQi-X JBcdʎwRгe4w5[ͯbȗ>:ݟ-O~!z@G:_bր"`2Q ujiW7J[,u.ϧe8M~aQz-ob{2Y%|wL%w$\I$%Q釗|: *=jAE$(_x]ħU/Y__"h!X,Kb޵MٿRybl4l4l4l4l4l4l4i(ː\2$! eH.Cr<e&8Lq,0Yad2e&8Lq,0Ynې܆6$kz}v,qFCRD JR ;ʌj>z+_'' /eӾ8p\-0 Q& wI 'v{G43@0d0&|h=1.wٛ_@pz6nC-}ZݬnvZмrU?n vŬv=W-mvc{m0ϮZgMe-&[KyRw3Y K$vu &#T;THюXj0i*ktds{:];pӞִۍe"UlH~iA5,^vw{I .@.:Cf@Z*֬>m :1j?M~˪`-Kd~ yݶ]]o405f63us+nE2ѐvz2d9;݀Ԛ#vZX/k2eVmTTkT7F endstream endobj 1667 0 obj << /Length 2670 /Filter /FlateDecode >> stream x\[s~Gza n-MO~z F(lmQwOw} \yś6*d}EadIYQ6ETUck 8apYew6ZN%UV9.xŷ kqlHZ( k#f[i <&Ż ~Y *#%lZb\PE(׆`M')KU.+WdP*V>_ !_#GUZ5.燐v4wZtRf4w; mO2~I?/%5P'PzS,4jz8VܴiDx vNivz~e>)5[)]v Jt]c:nEu9i!BA&l!V2 Ao^؈է]ƮvZ SkW?Mi87eZNK?LVs4ue~!Jzc>O^84iLu?onoZ9tFO>^#νl4PUd,~ Zt( vX$4T/T/Ĵz7k|ȧ]B^^2aaK]}Tsr@͹~4[D![^Rl c[Q^FkLKrXUǁ/Xk{.iu {vPPo /3|GA,ϫUpXV|nw;|yN "aXj^|T)VJtt 60%ӆބ&>2\~Q 20Bqk/BldclD7L-(cja2'g Yаs {Aa_?yvRvHvjL7wI P`2 `  MN$;$ QKS*@\ jKP aa[!e̸Yp Py0QJxoQp>4K (VF (8^mqB l[E+4^#NK3}Lb \Ҳ% 1̓9=iQi; S,=2VeF&FnPW;&c$(ہO];aw|RH"]uT2D: G,ų3R=7~>G^)I\<:|8\BD?QeB秪a9!%ںClDmV,hI.)ÈGkV%?lɺo{alE5l<2lrJk S%`cD,g SOE?cr[K|JB*gn\n-mqc ܐxgg9 ?7t΅Q[,$W/0΅8YҲ+eK.澑 /#[Q/(sO()EEP$82b"t (r}/ovE)cIbPƤ5 Y6+39ۢxb[Dšat,g[om oA) qхB[5%AMN6 HbJw]t~w"Be%pz0⒜VLGakZb""TPu65&g:wXB7 Ү4Qyjp~Ey<,AE?tLrͧ!QS%Vg~hw#w9 ^b<6(%g4 ޘ1T%$)Ckpm?[i^u`8&%ՇZP" ?:0ѼQvlK9,\"E`bi+q 9םdi#+I%-f#ފzǛxӟx*ߌdlfQ ˕:3A={*5C3EQ(#%vpX [9%QFMوۈvyO6&cڥy)s2,a#! [McܑV6C}q8X_D耺PK"QdlŬPT%q±UPWlui0%QE)isM*/`FGDqKMn,1%c`,e`D%Gy~ܓvC1GBpxERF5|Фu- cЏ@aЫj endstream endobj 1528 0 obj << /Type /ObjStm /N 100 /First 1032 /Length 3927 /Filter /FlateDecode >> stream x\]oufD|"@m 6ދ4Ekk@_D9+`d 0$yy$9ly Kd+K4 X|惴h{2-Y{xt? |  i\⒒8^IKphIb\xIE]]J1%/D~,$ #Fq) ocH 2W#N$ Fٯ09..$>Er8ɋxE!tQedkB8/c3@î@X0qpS<#Z.‹W,9C@T9J^rNГHYrRhXJ q)PR$70qR?WRpݧޟxhQ܅IxOkFe[M@ ̠zMsJziidcҨ/naAB9umzt?HWn'ЬS]2]k@\fQYՑ{xoaKŠҙ첳czqM^=-JK{ =Eىe=K>"{i2SH`q/1,n7$3-Vh=z\Gy}l1!5R$xGε"Gxى?_oo޼k7ח۟_W?}Iy~m"̸yuDTt6lc'a̫֣My%HjQh'z}ms۪4-z-h/ A{ԛ$AzXy7ɖ{?xF`qު:UgzD ީm0-XWdFaч|Cάն- A!fyw68<ƥ ~\h9~?7[8n6%_v@fz W Q/9 ׯoH}| Ol/^}溽o]Y~{_\!~7o}n!o߽i&?]e9J(? ˷x贎5ǻρ́΁ 8AH8Y&Ld2e"DY'Nd:u"D։Y'Md6m"Dl&Mdy"牜'ry"牜'ry"\&re"\&re"\&rCuA44<2:6y&rq"lj'rq"lj'rq"&ri"&ri"&2Md4i"DL&2MduN:}PA>w>I8%.!OxY&eup1mCLvpAݏɟlSU``iڷL -B˜Gt\9rbKHTNGdn6 [4w?Nk&OՊ:gUz[͵=n^3kQR(&$r?r2lխ1ˊ4|9O>{"RNE3-vJ﫠␇]Th'ӓl9mW}ϖ N,Eat[ʣ}'19T8~CaNO ciٞjx>yf.b[7۬h5P)KuF-g猜- kʓLRI=v*[ u jP!2A}<zw=ۥ|[ȘY0?~hFxI05HS\('xjlbꉲ1I#/N +xNMOFUIP:VJ[ƕ!ٷ4bv4(UX:/+D!_!GW5t+y#kahB[ƙ/j\ Y=A4\]/&4W{#6G|ŒY->',F8ڭ> stream xWr6}Wp/ԃ^qԲc1IFCU^_"GH.v5q95xFhEDFMϲgNID뷲Wi|12g/X.Ȝ47<s(C(d撔h">!4B] ?^^ #|*űֈRıU#:=[/HbYc<`a`}oYRQw[-r2l?foM_n^R=6mڪϸZYi1<*]Vf[-Cn O#{I'Z6~mܕmv#h:'Hջd]M.0LUfYfPcͧ> stream xڽXrH}WP/j=;7n#g-"ͭ(#Z 28o3(O ӧ{t7`kna,q|G2+YFZ^@K0>?o,p ګWezLVh&+ `0}[glp |}C6rk:x;'FԑKy0=]|i )*u@e1aױ<a_h5U2O`됪dT0Us8QOnnGU4M.M>_jRD)t$OԑRm8JcO`tvL** z FR\7H"ͺǭT 0 ,D-'7vY7G3q^ȄΗFi|RO]i}>ɢ*rUod$69[I7WE᠋T!.__z:`eEgat3ǫ<xHXA4@ T2sloˊMAr|oJi=[dr<͵Pv޽Z4MVj@l͆ e*!$fъA'A_]u13+}ĉ!E$X⶿tF^%M5~fBn31>=EExwz;9s&Q>{@ܑ"#r]]>^BTwa~4q~bb⿨k endstream endobj 1751 0 obj << /Length 1290 /Filter /FlateDecode >> stream xXYo8~У OY7 @>,PlÑd_C%[kXO|7% EϜ 0 } "|έ4ϱhRdRVURfO9C"`J]F#![0D!<־8(tq,uVcDO{!" S ؝y:>6y9 ;〠vVr_esSwvS'@QU UZ|/:{ʕsHX'a@õsfSޘcWɅLfzaLhuR{R㭮4% p~r1QfX uѭ%xLr 4^!Wr^=I#u>dqa[SD pB]oeUpGVFūOFo+3 Ll64&QH pCsJ3]\<OIѽ4zGsT`>,򢮬T/!iYȽ52=$ۤpaQ:m'wS.`IS֖pԹ,s0BXZ.:0/Tou歙o%K Q0ALs[[]l[7 ajڣ܍8J'V-CbѱB#֡ p8  a7Y M-`ԔQN#6&VUG7 ߍ;W@@*g2}AX._<,UG 7NkK5eɵ[I6JPJCÙι;uH 3$#ۇtX%'B96"&XK#T{' ׺7އ;L.6)|m~5bcL{͇4}joq>x;#sKXHRn0,VSEm a-*{,_AjPa*yiU|؊נquy|R_|*A$8h+Usu 2Yt&1o;.e6M^kRn;mh_ӭYVbѼ)+3K#=`,49O ʤhkO mz-EmZ&@שuvז[@66qnuռ\{nChEjӸ@oW2e<\4J\{,M- endstream endobj 1707 0 obj << /Type /ObjStm /N 100 /First 1004 /Length 2712 /Filter /FlateDecode >> stream x[ێ}߯u J$b!!dTZg|}N$<˱&Tu]%J(> p0HH|"W@~,@zD_&ƌ$Q|,# }-l̜WAbua3 V]N 9AjE$(Ò ֿMA}!roKК9 u|`ƤcQ ρHӐbr9$cǢ%T9>Őc(d,+!:!grrOn)| ˡFU(,P@RHj>3&ܱS 5mŨ?(@QfjIx&kЈkn`{s{5Un^ [X(p/F{ M$}_Ds2rd.. 0W҇C+OB<N}"YS gn2%vB7WY~1Ww_5s=c=nQ\I+c=yr?-a7g~o}b^.~ϻۥ]9=8|*LTH}< a{c\r+e4N~-Tb5?/8ÿχ 3D8#, N.%~F#R44G[P}s\m;Mti1 xxCAs:*ȁzϊZ`ѺDMJ3+cQT!A1q_ $ )%~ 䭵:ڈ7u!N^KmǷA*pM&9%U1`PPk@ee,,/scdo@LaUtP;h8P3>(_r;Va 'VD-8)*Be\`ZVeiYӑU}tͪDAhtUA= R4y:5x%WsKG7X(S|c~`Wv[M!,6 -T1[FuΉYybȰ|V~Ǵ:ޡ(-6yXlIzj}0e$޳YJ2Oc5V.qhǬQ-Os<4whk,9 l3 2rR,¬WCE++^*u%74W̎y*RUuӻ*Si.*t&PeqկHT B4~(oGYAy5N(Pz==d!+dk0!yŽ(GpKtT,ˈ#FeU>b0RVZAhcuZF|!:wUWyD֎&R[5'%N#ཛ@Abzs/@v2d-\&oDT&#+4om2Q?tCks|v!ա$_kx_p]8|qUˇO\z%?{Dػg꥛H7WJK] g< /Ël|[o]/o]U/_e~=~us誴jaoo[g&q|Wq⍉@m?(m)_lFRn&p0[D͛UOh|`j^*R6@S5?Z/OanƳb*F>,yB>/+/XH.<4'*1RK^ ԴڪK\'ˈQ4\cꝽw?%Q!2mV 0Ļ@E){[@4W55F' W}&}8j7w4څ(t޶"$7 IQ[K(4qf%E1-Z;ăh6N86MBfG< |LoJ>vŻv}}ђׯ^|~N]DOn0!@=>L{.}]ܧ:%(L(_X9tE@h {Ԇ#&aM(j&L޷̶Qo3t endstream endobj 1764 0 obj << /Length 1787 /Filter /FlateDecode >> stream xڵXKs6W!gB\;vI;u^d2 YPGTw P$xX A3`ʋYg6FĜ8 hɝ5Vty]ߪ+e(6/ۉMڼ*QxfxX 3F[|̌ x x8Hɝ0 dmu4cu:L;9e1LWǽj gW!7"g1/d1'\FtW 2eSgѻ^za|,]7#%/80Vqϑ ڲ}f"P[Z_0R24ӫmޠY.3!5&.nyӒDAtOqδ[ABS)1-w=~h'Kıl`̓#K`DŇ F7ϳB(eU C99؉h%xU`@ϋ!mQqkkq 2>D&B)Z ! })& 6)=nGߞ8 KpQ3 n@A8( [{ ziUQQ~F{ã_E` 9eļ ]Cj+ 2`IT-0fB9TKnE`嗂ʮs=V@, OY"󓓴WejEӨ$7hmn"b)'"DD]WXd%5MCAJC˰̥2Iw77P~s5H[@E=v.)fE@ϋ!maJA#+]x  @4/t[TW2QRd0ӕ=8`tramRgTԪ?~RY6Ė6M)wB9 5<Ų5|id%e 5ڴp!NRDTQI⡃lhU]e,,hAI^$TM:DڵoB1rNz}b"OzTA^gQiB@{>jm)&; j)tK|RhP}CRpSl^zQH6J^z+josfӼ=B!6O1W ψSW81H+TmBO@ďyTAP;_ f"}`w\PDZ"d9[nPٮz[z>hھU1:Qq'K5@wwnCM]32=_Cs;E^տ4pAlP 5A[5HWz9n6(yߐߤj3`- YBV::ҏ3d\Re)}y䭶Cc.n5 , U3B@if= /Swwйӯ h׌AoVcoBj Aj5ib̈́UySOq5Ш`j8{%;BP)1(FLX/DNϦͨTHeDZ.UOf<=豧T/:W<ܽV]k7{LUM W 2.r X2BB:9U܁dѱ+3Bƽ^`P~b>SRl :A̵Mqh?߿ޏs. " 8|^$>uE)ꤝ{/ljt endstream endobj 1768 0 obj << /Length 2124 /Filter /FlateDecode >> stream xڝY[s۶~ׯSFP)'N$N>$M'`wHn㼈.v?{Lr.H8w8I bsT 9Ԥz]ow{4E]R![e䯉Aߓ ˥X˶^s{`Wn=1Jo50\c\RUt?hZeH9 eQS'"KM'QSlw#jo _03Ӧ%zrP2̀aay@| Kfs%izWн)u\76+l| & m ܄K* ttև+m݊n{d߻?޾,"b܉heLO4y=$F7hzտ4? BYO=uvGҟۆ6jwM(\[ri[u1qktr!3iQցHNueLuwe?̀Pj05M+x2AۢJX֭N1}Z9r"uil`1t32)K\%:5XZ[S1,i<[qeBlC'h:NFUGd39@s<{aF<"y>rpF|8I@gM@Y#nlW`=F7Ծntx;#u›-x٧^OJGEW½ !g]ӮuѓPj@,P<+,Q'fHEID(NՍs'A[a[s?-Dkg젗O?ejK%3#G?Q-[>,-kf2龿\Ɓ—N"t )HBNZd`0}[{w a;3K(1+Li)5Э&NQ\CIqpyܹM{%`s_u$ATEOPKHE(c^”6Ij@,b)3f ΢']BeKȋحY>.ŝeTrVz 5=5X+iy0ӶApԦ8 Ŋ ?\Ԏ{/PT;R̸s ~(XaoG]JVumJDžzbTQw{T}My2!88MFIP99bBHN8ʉ|0mu &G4PvrztA7uq:}cc5)o$)Ofz:=aNI4iTv  LgHlMymL-BX? #iiӊMm!̩< TW،=мxzwDt6, /B&8y+b2DpMSLRJUTGğQّ8QD=?#)$20D(=dk3%<> stream xY]s8}ў<ݴfޗM;Y .i_W lb̾ĉ\9W`Ƨ䷏m4V-a9 b6ݔٷg 1b}W& lN-{{e;nGxr|´mdSfx7ll L6~W MęvuQ~UeVGԂ ofMT3BIY !ЛyF ,aQ 9 uS"@JSb!ʨa1Y<%~889YMg`xSi0|AG ;Lh8NrvpbG3§OFnomemش|pfO]L]Q#?LKNz6 "ۗLX8733?wzUܕf^RŊ !Jm_Fa%@pl#zf K` g&wX;M_'q,edpQ[aA=V0 [ Avσ(T!AT,=naӂց [ko_d= \fs12_1UՖ Uve,AsT&UN鹏rA23 :[rv9AIzžh `=RT0~X甿l =Z0A4 Ϲ8`ubiO Fi:sWsX) :PhE,ݸ[c+5Czu`:ǢGM4 Lq&M,D'&0Po5@N׉/KˇqwN{^/Kh翨6=ArHϝabHB-C\=}RqLIp(ޛn> 5ml:@8&@9KUmJTiDip@,iA>^VN2σs;BkIL[[d£0&mɎK,wU|9! nM75Қ]DuQѯ( -~lqآ)g7 yqw[Wgen,7ةfTXgV Ls£0 vm:dMWr\,'F8Qzb>[Q[g` }cEƯTX0ABټA s`BM:HR9:ݿ(/zxmQN^gdT;M9[?9Ί_=(`jR$ѹOva!F6(DlN0ۗ+jH}DU#|̲ca`RŽJr#!}pt-Nn1O b[|\NH\C=9.}{z/{A>ڻ34*IOX SNipnu*f@1mH2vGoWYo<\f@VYTci]r/H&Wm- ˣ]~r]LN7m| >? ~ qhGBh|*9|?2< ?D endstream endobj 1797 0 obj << /Length 824 /Filter /FlateDecode >> stream xڽr0~ -E&e\& LG4/ŤW$_C6]ad?;7ַ:c >H B0Db$):g^ۗʊ5+r5p1u;> #_7KPZWlb0ȬGR Ob@ @mܚYHgGajFj.D"]QgosH_cDp!W*!p0-iJ 5 ˺.9]  vdZ. &X5HX@T ,_ [@w2UZ, "9O #xi>. yu0n HP܏Ui7uI!%|M{Qzh񉶍z=FFV3~Ǔ?u|[эXu A=p\ىwBNVd_N rѤf'@N:ᜊHG\Q ٳ`ʌw̙ʝŶqgX"f`?i 5Ks#mNYf;V?7D,n5{h.R =דSuKW;vc#qa?n]`E8̃bC74=3e!J–[C% endstream endobj 1804 0 obj << /Length 1489 /Filter /FlateDecode >> stream xڭYr8}+h&3256lVSOB-,f~[16daӭ>G-{.;_ z!RR2o 0 E$p=DvyLp 粻dG~/lQYɝo\3 QH7Ytbo }0b*^ 6ޏ][?1B%:$(~ |pk5NUT9 玌A  m0C ȢA+*0 `ps=u~-=m"VdZI|2ItI6kso-TI2ru"hMfrR`$UP PH^]_{;h>*͇QouzV@FLQD97 0=!cK?vy-QN/$T t'N Y=_vi'mjVRc\j8hj}&]`2jV$m,Q%8K:.ujF)T>Dѯ.(J{aMzlR;q:F:#_86';/f|6GD%Hd& pV}0&ACLk!\"X0LvlN9gAx 0^(Q-l0a qeŲ1[X==ȵr?4 nL@X"14B\i{ a BȲQgI' C%.@,zl)&Y) }g!7yɪdƁ`~'`|[ rVX-]$+`GoZzt۫RU6ql~F͍# o }h$i$`3psa*|3ߝ ϖvniŀi2`d2&^8L;lAR9Wmg[oXQFUu w^R/f|KӣhN5+a_$B2&' #,J8gŲ`8c,m׉pAXI'"j 򙓿9gh|'ϧ@rLW$eĶKR\|- endstream endobj 1812 0 obj << /Length 2368 /Filter /FlateDecode >> stream xڽr۶_5S1 '7vwr8V_t<4ٜR"Bq?X"(>3Eed޵ǼG-^2/ $KY%apo>"yfI nכ캪mhQ GyGG,B3o {{,̻ՐkOĀL ڻ8:?bC)0KfHlfS4QBiΨIβevM{Ww4>?^WYlҲ0+sei;3,ř8"fޜ cb jMς0F[Tu: i3K i#I4HX4 8ɪ@Uǀ*`17(lg9J~:84c`(HCRp1۪r%:48fu_le8 H BZX{D?vߧ~ @/y&l՛F^h"=rz!D} 9c?[Enz4VK *_l6uUdHxup\ 0q'eQоSvrx}G=R`J= Ⱊol[Y5ycg C۬JAt!U*CWT ,&o% `o`8#OJxb1يS~0 iX0 r!atGmlnd ܬPS}3d!xdǴRJ ܩ 190p&1s =NmWvM#<} /{H 41AMk4KJ׫ʐ++Yz;KtC&ߖ )E6O#t 5nk0rg`_X~=4\!WE$28u`J?m RѺs٧L/k٘)(Iքz[F'q6ј;FBgz LÁ~]mf)17ٙ]ikHuמg UP}2=mԶ$Wa;2YT߃mdY4H36AiZ+akcFF#tt`ӚUo &y8Q#J? c(ÂW0χ_` A98u\PChg#'6``517T)φPQ9>4 w/l`{xЫs fV*φj#MCu5`hdrhόtnLupRH@'!6TCӬ[zlOXÆ=w<hRR^j Ymw&ՄࡲŖFEKB\cӚ3Z)P4afdk*؟Ì̙ ЩM_Y˂>f H2ؒꆍ*Z:!.2DC9!2Dhj`cF`vC6:(F -;~C#L\OpרqxJR岲O'Ad]_Ok6u> 7Q74>WfIkM8ذV6%嬟- ~{3^(6ᱽ Kx֭Al&p<Bd8ɂIsՊ%Fҹ(,(;| S}?dT ,.%h,HE393VklE #+a5!MU<pԡOss}ݚTn. I?rSOw*qN˩h0HDa멎߃R*k&`'%6xYx? ?5N_7$D ^Ez;iuƗpՈ%T] endstream endobj 1755 0 obj << /Type /ObjStm /N 100 /First 971 /Length 2336 /Filter /FlateDecode >> stream xZKocrW= H! ؤBR_fwd$ATMOu(pv11".G2B] رYPCF!3d{ y^̚'yTW%ۈQf1US] )M$lM@DKdDP:aF J0F|00D1xӼY/y 3fin={/2Ěў4aS'693n<ٙûo^x__oܛ^EI6'lחv}y/m|}w{0@l0x!G(5}ܮ(,ȶE"{k_RBڂS,ޖH9uEbˍZLcC2AFu>}ňD:n")NSu 6CS^~ê g3[@h7pGtp/y9KI^03&]ǜSṵ<x9 yȋhg cvXwѧSgUeUuU5.£ O]xs|s$ʦQ aH%v;vl$#k}pl//޾}}SI=#x5\ݐ˘ВJCC!ڣ8%OrAdG;F{0MuP҂*G*uAuWE !bNC)O*4TZ?XN^sZ]$dq}jRuyæ5+6jg%FfM85eEnEQY{5`,zxs#^,7UBmd! ezBwW忢͢Gk[P-Iߧqa[> *a¾t Fʀ`}Qa`1&T8ik2 ʷgoOoe@teh9Ŝ4BYU_u爧P:(j։.t*tR41 gUs(Cuh}Լ֡wquh=HlGS)N }UDO>f/0]IV}Zဵp"Z} >ڮ13A rV:he O``0x% sYLv ЦbC ȧ$%C!Jeؽc\| B":6=Sܰmru\O~Ea]Q|yE3~]y*I$:_SbCai!n[k|n1o3/0C[O0+Zbc3zyAc@?%%; endstream endobj 1826 0 obj << /Length 1320 /Filter /FlateDecode >> stream xڭY]s:}WfoY$@JoiI q!>{G] ;ع{6si)M+4E8Ĺ0' ^&yPSVxµE1 ["rg~`Ĵplg:٫w5j>g*m4΢lSSbQ<CSJ#W#N,hB+!he~k5;Qwu^flgL~AbNF9"\gs ![ #֗k ](X5pE3Nßǥ IZŁBrYJ0>X08H&(.jW0t䯂hBhwq)Kf +H,ʖL[|A- J|TǷgWcqZB$]c[VI2BO)#:w=4#rq]j]EdB&sѻ7jw6-m*0=r؝`ci&(aP-%ɹ,4CZnjt~9咡IP VNRVIU0ą@\D a[e!IH^NRV"D`Ate,7 W?j;9%IDA(YNRV׬Ƀ}7 .q!ʰLYf)J'C!2ykS# #%kCr  moķNi!paIW|D/<CwcCî+$Npz&0㝙Tfz5tبuBN웗yt7z),*Er,3gm3P,,ʴߓR+sp5 xFX6AhZۤ%߾=' |o4MVq endstream endobj 1836 0 obj << /Length 1575 /Filter /FlateDecode >> stream xYK8WpXqL%L2Q.b1<<2;뷅$llquSέѫ% Ϝ‘Ȑ"8xc*MTEu~*LL\\M93$$So vZBrgv7 ;sx̼s0RfqZԑ(( q V2yRe@ZC\ V5Us_ౙ;&B/$텆cZ{XL˧hkK}łI1"1`.4gQkwyvƒ{5VZ"j [8plB|YyOUã؍KPY`_< :Ϊ0cI+}]AݔSln$Xȹf#Ga̖zB͓ɼRk;q`un<3(ͻUTx(.}5|`FN~KT7} VwadZ>rY]Z6ia L_*k&TS;gksG!I35BFT.W*H֮P F= n/=B\aE_A$E1TO$\€ 0GC5߄l(O &Iy]_BBDry !v[>X9Pr'*0]מАUt_=Ppz80R|(0\ɚ]5Pf/B9C^z O!80A= &rv/!.Oy\; CsMkB%36Tf:BUfh^ KM]vhc6)m6;%KWC,!yMt#wH}mOqU*SIy~= Cp ~T{kMؿ8k^_|fo&ub%Řt2`^@lc]%#W&&}SoUy^Ѧ4X"\R'Vi]Q3n:tJA`!" {=p$3kTiHnQB˜1 :hzOc`2n^V&k*(CMٲȳ6TQwJݱ"W;REnM<)Jl3?G:Ηv4t{:+ضP[ڨ=Qܚjma]-oq}d H |}#4 aX 6aR;a9%t)2vdVzp g!')Y8pqXZ ,[ji5hP[ZUPM!U#7F̠4UETu&ؼɛ%=ުMٶ6R endstream endobj 1845 0 obj << /Length 1889 /Filter /FlateDecode >> stream xYIs6W(D(NH<|*!)3n%3_[J媬+볻3 k4E8÷WQhFu8EiYpƈpՍG6ɛ|-lOZ̓E)R y#i` %4C1hj0ǎ Q"!ˆ$A(a% +#rD9G4aOfZ1sg+v+&aDdhDi}l1\꧘ǛQ U۶w[TVʫ`C\@  ۷& >Oi,wV-NN1N~D6C (Nx s"(!'?H1bzF*WmA' O?c( B*4d)m+ 0EZݏ0Qq<}NNI4~aA~(٣ f%@H4۪ ~1ن NUM?caD <$N,.W Hݘ^@Oc M;9cKLVʵox%2r}\&R(P6a0xj:[vy "t1ʸ;Ճ+\|\6DS6"]Da{fǜAzdе(\I ҺuU[Vѣb q`$=EcOC!!`%( ȑ8P<" fƲc`e1pv_HBC8A=Ccj:(؍ѝ1,KXRxfxqXݨǸ`۵ 4ƃ`Hc2VVv Qn?6ʅmev5^_||zوɤG N41& /+}wObe΍n ,ۥ6~u iȕj\2H=NB@QRnGj :]vw-$W^>  |z^"6nތPB ^5nm*vm\tGMy7P_ao+-'wlVufnV[3w<_Cz݋綃3NS&C/G7`^%oKrWujө㪠AZZ:͗Cwtu=p9FbB}ywa}w#wU֛a)[{>tM־`?86Ƞ k|0#?> "r*j@pm^p&f͔_vɄ&s^;i=@[2!]a͸1Jp~8rK^f̃;hdSa<flh,U/ ͜*y:0M84R<> 씦sbP[<(䭱 #LӇvud3xa<BG_H!Ĵ̠n|I{)cbd,ޟSʨwf ׈oY+ܺ3 3(Hw}x)+*W/s[}Kj?) endstream endobj 1854 0 obj << /Length 2055 /Filter /FlateDecode >> stream xZY6~_A剩*@7]N|CbX`vXsY@b9W4 jֽg?\-;09"Nzo.ۿu]\lʤ"n\]?_}r]1PJ݋_o.>_-#>kEۋó,on-0Wˬwo.#ĥQ6x#6p|Wq6rE])42œY L16D)u V.uK-はZ081]- 2 X3b\T<왨tn<ΒfHsAF]tC/yUy$҅07@u%3lɁ)Cr IH,)Or&(!uЪq8uöIhJEv^l9jCJ`VdHZx ,8I+ːՓPk&(t`m5x^:$72Or V/81MbʒJh+NoTU:!@غHFVx$ALd9T4N MgTG=2izf*B,"ZE>6;=;9/,"z4D< Ot:FFrKލM"MbKBPd(ٕyu4'8XE2$əi)aLQ~kYx,{*-iRf(}&*%#{ܗdd "0[E2$Z^pra~:U>rsSLQ*?]LqF؟үȚȳG=\fۼ/ŋ'ݥzaXZHfEϊRD*kiڼS9*bUnC1ќ$6KB3*NT!کl84V)/sblj; lܔfiCY/i,l;8'e8SA 232@z/;a${ ώH($-\&gA eK$bE$ڛn_>Q uš)uQ`>U6"/jjE"8&L3PqO|/ "2Ģ1mp@?zHgEX5#Fw!vZØ#-q]$CƕBie/K T"{}#M\ Ցa={>Q'LyBrUEOr&CXV  ~YQcęl04h3]c47$Shey]N݋,9`yweR~U9cOK)jU8oPMNP'3_V/J<ڔE^4- rwƤ[o[FSwu4a e¬*tg?yFGY]k*ӶFb^r}m<(~!x8\V]bڽ7a\*3o 4;; ^&t/v^r\4J}ћ5yMXJ!:%gѨ6RTA8{-½IN\FՀe1-x5Dq\|g'T+Q5 S zr`" ٍ4 J伟, OOa@aQ֗[JژGPEU;Q]nKrkb{=iWMpXZg`[I5؛MRΜ~C7aݯ7*ʫ^,jh@0eP # NzAk 3EtWhMq#=-H56hݓ`,,|d #(qGs˷_.#[l !{3vv(K? eFxQmB wZ}I> stream xZےF}߯UYèIv XIUK.!%]\]^} خ6aF* &پ0`w;c:ʆ *ojD!(⍷]O\!m\011Z|O?|um zV7u5 Lɴ޻ ,g>9׫5#us3? ii2/v/Vɜ)4ڷx쑘Z L"Lx`&|3-憻(2eE,^.}ĸJFPN0cb[ەtꏇo~;^Z٣{SCYXV-#ֽ7_.ZfS qi^攆C:  _X?A[Po 1OԹg j#?1ZO: n:T&yXU(\B2Ft|u&yl[KGm݇`"RLdcm94g7HRqx-Ok]Bh ~3z̯U<{ &aǤ5%B":)eSO:קۿ#d ]&{=۷y]Fsu_a.: SGZᖖ> }ZR0(SK+,n=fS>f-<]Gn$o n xT)ޑ.HZ#եH'%K^Y8W"Zo ;|> stream xZI۶ϯQ .GIN{rx/Ih3b"e.vƿ>7I$]N$@ yr?7 Pyyxt|s uv-Qp,J\uxjOcqq9P{ͧ:9揿o?90pȑq y &cR{.F}dAN'ՌN?n dE,Q=w_,Ó%bf\y(J5=p.|>Dz=zqCN0vn %S1'&khiyws̢8QB,̺yr"t}VKkMmMho|;%zrvyLKO45`uQ=nwit|jLMey, a {9!@xZn"q?1jT ke|uK0Cy=X82!x?l]cլ͌Z E*Y-%|e >&=rdzh aH =׉&/"?ikW E$&?> _uz+gK*XQƞ Jʵ8)J#e|sJaT]0jic2OzV/Bh4:օV57K¢0pB04[ɘs<ܤ"`^]E OO4ޫ'CTCP{ֺlR͡Ljp1[~} K) F@LRC!$T݄9D&WETX@~ 0 ̾ /^2d 6mͱ6 :2\n]%JUWdvYY<^Z·Ћ"Lt~%lzu NJx0H4DAgih(I#V"}H>AUW #ׅ|,g,#ͳuӥL;0}o׊{Ι؟cacI :+X@amAIBhh4r^PV]D#mWq!Q4Z;+4Ky4DЅ\GOOg r?C}Q>h l"+؊O}3dBA:> +ONuz!Q(|3e<ǁllK&ܜ[^`{r}0[!p=O2Vׄ0b$lQ\;W, 2{Mm_5|lč@@J)b 8tJ]Cr~f=ĆWxx1[\ݥ^r;3k:WG8Χ+(ha8 W-Z]P%r^yƭXwP~9_F<`nTE VzaokThf<9|lf0ʴF`I\gSdt%o;S.j 4P)&Be~.FUz}YE~)OĿwXR}s&ʪ[y_1(3?5z- D2ɓ2;iP2i{ Q  k}c endstream endobj 1877 0 obj << /Length 2559 /Filter /FlateDecode >> stream xZYs8~#U!^ޙuʳɬc{kj&reV"v "y_AEGwQ/_4~Ŕ$Q)'ٟxA(`E.fs'uo˺p/]0K=6Lp囋/Rocxi=˙O X{w/bFxBjD9^~7ۦhۻ)WR1)FA![V)X.PBĉt'lAWȕa…k=0C%DHh.B8Z4p(ʥӊD3NG*dĝap1a!%ԶHBDwV5OY,=У1]&ˡUVuy7.]mԁؘr*]$H3jB`aʹԿBL7 fkdBF]N`Qc݌Խ߬aM> ߽dLj;%v#JljKhEȤ" %" <;bq+J؂UV  dLҁ,Øiׅ! 4AF^7`Nx*`SWВi^ʤ !5*K\jiVioZɳ~IJ‚F,`P@Pƺ,&pT!VˆC[8i8l^ %8'o5BjX[՝iwU⟮Jzz3at &D%¦j̽sɧ2ojeG2ߠޭs#!]0M׃Ɇw zN?"rJItwgP<ړx}RNDjH'qhУHB9{lPex?&;HH̃sٺ-> stream xڽYm۸Bmଈ-p׻kf YBmɑlv}g8Dڽl !r8y87QpD7?ݼyAiw BdHWmOYK(Xk`e1B:S/40N34l)AbʷKR%8lDF*&mXpjw/f¸xU`EP<Nol[ öڶeA_Tbv} V؞ AYyV$6 x3&V*1$aDP RJGӚ=4w4 1Q-Ft{)? jzE(J «k/tN"$WDjE c*cMpb,a tr`N5ZygA`_C5rG%x>x/;3ؓR)q64FI j̣ɱM\jE8t_ oz#0I QHǠ1&Oɘ;~Zau ӵ'CJ `m2,t.;١Er,rq075(Y{"Oұ֕  XHna^GFCnfi>yٓqi!~m7^ :*skɋ@iعNE*A@~Kv(;.QdY$3nCiN"'mX DȪk iaîM7>FߍfK\G'JA 4lҕ@k]aK_SXsQD" ͜ `͹Y(`(J晴&E> stream xڭے6)vIH.'{H6SvIU)k @6O $ z[OV-lpgywZ-#q,ק!"Qg' 1b}կwYX&]*QZE\-ryȣZm[!OFYߪ+6Lh$/WXOv5^;yL8lmTD9!Lz6|mn0}6j'D5%|TS"ʨ20WՔĚ#Md0lZy]YJlsw,m2K)Ffm'4Vn4T~8TT?Y킿KyQE7#o "c;8Ndغ4ٰf!F6$Y0\gH#]BDM-M|rȦM]{9ųrxt<\!&S3lHF>\0N("zE`u5e=MSCTb#2®mvFatNW,KUP=r502fƫWw$CL-b0NԲ 8DY=M3Pxu9:%w0aFy٦t0sLe qkF(%ˈQ֛U@T׊ۦ: \2]GE),>GOVR0`ߌt#uA^8métffizB7۫#KR>:QQ5:%WYؽo,ƣ c#c`0 gl!f_'jYn G"˾Dq=M2,?޾l8V}uIe)rWPFU<6n%pskNu/\uk)td}~%O֯k)z_ 0AY'FM_}zA'mRe(R=@8ODԵzwL?SSCJ|xwp&\l t/Arɦ޲M=M׳{r "/.5ڽ.`& 6.|Tmy>H ԃ5HhqP3b6B#r@ 00ў+Lyh=-|Y0cD6ڲZ]x#PTj$y9Xсzalc\5SH# ̍}=1$qS0O\U||h X Ԭjf-sLP/ >pr\f|vͧѝMXcUmi'(0"Ǎu-o]Om޾j0HMu>iR/*%L6_o+u|: [lH eoy"2`!O5Ёw7ï?}}o=XOsDZ|N:wٮL"a'i^EOGsc'HQ_c(Q>ِ0()1{.bZ(?,O>-޿af zf.=DKt7 i==pT0\&qd(Aj髞3l x.nA endstream endobj 1903 0 obj << /Length 2004 /Filter /FlateDecode >> stream xZߓ~߿G<+mlolۇ6#k80kC Ñ{WohH!^8 Hb!> ٜD&}cٖ" w~G7CIZ~z|1p(&[l>x) aL [{W]Fn b8F AF. <n4m!U'󇷀/B" 9(LۻG3 <,g͍[r,c$xhy| zQGܺ ; phT 1tւ΋"Iʞr*)WQD:bP0NW5}Bp]4#q-A5"pLOiqd&`6ʪցb& j*xc7M*s "AЛtCA[>j`kqL_Es`l+$@r*[w2Wt_gI)OIVEw`U,s1$Q}FϵTu9~^^$ƱClt1 -G8Y63AyP/z'_ۡ4B>Y(Pp %RpĤ{>՟3Rca91$7^>.v%|[rLSR G(wDOa\> m LʎzX#B'Nyw'\< v.li|;R> j10ɯdhQIk*"Dz/};sA-v )hXcq.u"i!6un %Zfw`qu:lwS&s#z7%~Q7MBBZ [&Ū,bgpP]}KșmeHąGR2ɺ*4mE(D$+j34 eԝP3ox~Re~qau endstream endobj 1819 0 obj << /Type /ObjStm /N 100 /First 975 /Length 1913 /Filter /FlateDecode >> stream xZߏ ~_1,QHi ᒇ-`<Af\lok<8(GI]$_ڞK >H2.su!vɅe3.3P)§KX(%%0+^]*,ͱ%\KN3Lr%?+G_҇ J>CZ݈Տ]kA|k*3HECr .!jQf73gY֎H6UHnFb+phɷ`r,CN].QsmOn6VH曱u!\rjqT2H=l6L>]<7q!7JPamfԨc[`Mⶋ!#+$ GCi8p)Z'IM iUr ɢa $cSXJd+R 4\^@jer)m5XWMwe7=vF|ѿgaxyէaf6q"b o_E`n¢kun ksgW7/9wu̿H-p֚!jR5_R 9fh}g KpR _9 YH"OSbK:U%%uMS1Q %W=Tj_OmbHLSfDe}xdt?2*R6|Wt+O ͎;eC| O|oO)ci'j l0L.c4łVZtJ1.`Mk9>rZr+V_#<||ہk8;m{c`8{8aB-F@r6l>Sxߚyim{NOېrwh% 9q2]TTzw}YOyPb)m9߇FƼӣinj꺧 endstream endobj 1912 0 obj << /Length 1923 /Filter /FlateDecode >> stream xZ[s8~ϯ` ĪcvKڤdM6$\M!ɆXd0H;OGGػ,BIɼ+/( "$o=&8A|^/ɔ2$*3mGV2{o؛ûF, !;;pQnj8a6G Mc|m%iT]a4F鏯DR/@Qޔ 8:|rzqtz}JKjt#o<oJ4H?Ϡ3E-DX(l|bT!i5&Ҷ)AnԱt*%p,JcSuM\!mu"$'OP'XS̜̑aWݛ*H zy],̩F@ .-x:P*\ptc{|fċe<~=o=+g i ?t02"򢊯kQ:}89%4@a )tu2֗ tu5aO >nL#幛"tM|, I7I )1_ Y榺i|J2]Ճ~ vv ltKmP#z jp[/6桎}үK>uw[@&'wx$3=s8 WfV`?_Zv )[O00C=Rܧ`DOh

Kj#ɟaN:1An21O,\ׅe:P)3N4uiWqm'`_s6$HſQ2 xPtQKüvp m`an*R)!ɮmM_)fl҇b EQ2  a2'3X38I6Zm0T7ڨ[Ix]v:WJPM'+-XmZVyw$($h ϑ')EA(':: M6Dɻeo[6I"!q MDXB%"X!d9I6fg#a YT&t|Řf6uw66얨uz}k[ Hֽ,Wn 9"[~ B* TB0TȮ,TE1}bh]o{ = ?&T®6^OY=v9 "X_O˜*9Tu5U%ڷ QwP M$a(fA x+{1 aއr(l(j񜣨[$wubwjrVwYf^, :"$›Rq%CGxsut~|tf{ºBނ}R[/0N5 vU7D|\0EaL4J# *ڧGޞ0d[wx}!4 Il-Oot.6l5vk7 0y3I6oDYb߂PYn0yEYHJMë$Kx5C7 Tsp9챊4 endstream endobj 1918 0 obj << /Length 2162 /Filter /FlateDecode >> stream xڽZKs۶Wp)D^ɥoRgܛ6n.nӎ(SHDԃd.<@| v|;> `0p"Ae/އeZ."Rq}w;gs\Uޫ^tb|;_Y³X;[ Ka+ƈ)Aar^#mĻ|NY'v1Z=Truu<xH,,Ao=jw8_P >RRVS: BP ^ 11(@3o օCSiQڪ*-4^_:̵:'ɣ^mHtxWA &N{">;O7 Qce.xBp+D,}!`t5 "!G7吂|T M'9^VsgqK㲒}LgrjD8".m N$^f*JN>l6 Ï~V%/6$}Sdznb)츕:L?P8]>-3)ֵйP$]&QX xUm#h@*/e+gB2AOQfԴl--(x+K>vWXjvע(WEn|MX@jWt"ha26aNIM\N'נ+ZW߅>=g,]UZm iF_ƨ}U@891ko`FX*I*4*(iO09bg_2lPG0pADL #T=i[#z@uXiz&D`!]9U8 :Mh`~R-ߜp00޺zVE'Y:fws *6(Ȭ r<92d1:܃NɀPD[XLm ks2NK9MBU|&܅5IWdUnhMbPO$VG 8qQzVE{FbҪ ǩ5ZMq\u[P/¿d*jrCM@UF.}ηAƮ8DΦ1} tP38]\@\/`H^7A8ǡӼz$Je4[щtf/-}lo{̱$h摒EGC`;:đ`/?{Dhq;@lne:|M`}xInhOi\Èt:'xooW_j6,Tkh&2q[tN9ԏ9چr}bx!^ja{&FQmN.2L6:TUUivL$=Hscs.hkca0Dxk jUk}5L.䦚¾ 'PY2v)2Y_LzBK`_b4β;QxFB$ $k,*MŚq~x2-ܚnYvtHUd> K=LF!N<,mm^_v8mk/\ endstream endobj 1927 0 obj << /Length 2458 /Filter /FlateDecode >> stream xZr8)x" HzB{&-P0e6r}}&C*,Dx_ꪠ#/J$heϾ>)zk"~1?qڭyThj.PR$R~oGlO B˪tv@ !X++8F@S2L&g%~}oRʸPnN l_ XCR,3zF/6/ҫkhҁ$+*UȄҎ&k d$u!"8B;xsuʊ>jI 㙝|np.hW ~xfCHkYMI4\Yy+W2"f}.YAK˗J!֫مvgq26Ce&3ZC*~ |U5>ՠ י(*^Rk?/,;euU~'0 4^^D`NU/RF,V*bi"4R(rE?o!e J+;Ia̺maz!stGxٷe@ïo.!-`xgx#HS@"FE:1@@JSE(+nSyY`*FJ5Te׮huA̾. dcr0.|Gb1|a͂lB =!U]ZpTUc[jfeDZIfs'T~q:g{M75e0RӠKUgV`@,"lR݄+®xw4_Y֍5:WyN3@eX DC?FM4D3l `CʹҲD'0JNgx8G+VlCS>bfY Xd[ȸîfKi2ᕌujh )L'1lWa5y&xع҆& (!FZ<eeg/H-_+Y @mH) fpE&gc5u=c [VPNPKzD,aZ҃t1K)>!t214@$V9ZVD#+M86D\F660vNJp1JESӛiY4FPje|Z"^iO=~SZ ڂ'!)Жo R5:MuprĢl'0K൭]qa6$|8}FѣEk'J{Ŕ/Df;3D$2'a_٘u @L | 4y ]'|1FrpRlj)&:I/0pmHHđiNTBN-jܬ,%('2ɕeB0Rwf$-a1+!GpM07w=pӦq|Q43>jN1ڪƙx Y!ٮd7@4%&o{ѿEgop_q(TĿ`\ŁHZ?fC[ Xkfa%iRwB,LΗya"%B1Xl\^ 1z;`UKwWUi/]U{L1 Eitގ$RR}"/a pDV$Y@&A3 iP'v\sn}gĥ/ֻvhZuw^׻w)P;7Jn'=Jx"q ܐ/o9`h ZtGdJٰf״7ɢ?Nf_ K endstream endobj 1936 0 obj << /Length 1631 /Filter /FlateDecode >> stream xXYo8~У ,IQn"z50dU$GG YI]`9$gESʣ bHxQKE 'yMg,) 4oU9(BGPD!F (Hc<`7}F Ep\[Ƿˆl&ds 4(bA;'Ӻ1^[+KXN9[;Q Mo5/Ws!]֪h B$NƁ|^s:cL&SVe r߃K@pXL eG00,Ac0LuM-FE~o}VeQn hZHAO1mJe iLJ"`8@T[ڢή 66,>$$Rg:8j GlHy!3y$TEQPAY ,K5cfC>߲B8 YŘt(48gtΠ(h\ܽ''Eε=j+c ΀:ۻŲlâUUIzDapvkgR0&M>9 ʋ6i@d/3rryQs4 $A$N繡"a%5#m̚юfCpt^)Lkt{\L49(|Ht}M<5-BuEi{0٦,$CdYY8`yf>nw*mܪ~o`3`'P e2">KH+4 y`Өtvgwi3θQf^mWfxpQdKO]~iw>{'X+Q8=Wŵm`:VE-d| x"BjkVҮ(J]yj'(;y1Gؑ>xӹEw0D3!֮6u8X1#{΍f84Q)If)kU/6 4w๽xPx#Ʌ a? jw.Iq6RE/[HxP<=c -m^ U:a.@IQ᠉7a #(`HO\`l^9j@4gMHמ_ލ{u}\g7\L42^bn#z[z(B 5WP /ʽ<3-\n{u?Ao^65:bpb0X Y7Nv8X@D?T!CNGL_o𦁀> stream xŚ_s6)(8Q8{NuڴaD"  )$3w/ ohaOˋ=Crcyc>Eef_,3Ĉ ~H},fo~+"(4_\-/]x[yȣZo/ #[qq&uŧ ĈrU~h<̾S6 `+ eZdކ`a[#Lx x!‰QNC-:唸2jF.U9%Qsd6 ZJlswZj2K)FfMVX$.IECV.WEI^ZoW_rSh#q%#֦Ɇ!$C u093%x!rN"Myrn Mwsg&uy4g_3$WMl3!i\M  ڦ,V#׵_8T:U,F)T|#IYB4KxTM$,]Cӏ.3uI W}*[nɺsg&L|9:amDAiOQax. zCi(4#vbP{"Jk$8$:RX.Nr(rYԁO67!lNLҧtnL]b2j('ItLM| Źwf(Pb<"|NMBwGG*&T~8LRQ?~yS}5 Vw&ӁB;]f!C$UWZm h.Bpb634AYQ !mZ]f-l#4)cJD]_IB9<v M I2T0cJv~C:̰.I?[Ȧ-`0;MuY5ؾ6 edTdq Gt yYcuve*}*YUIbDdoiFMi;ȡ:ыK+pʑ!?:p[IğSsΑOվ^Sr]x1|3ؿ0w'Pfw:s,yįu-m6D/eM5vz~ݐ>$̃lɦ'z j.{gH= ڰ=xףwTtuGqzlami$-m)m9~Oiġv]s~wG&Xka#nKG$0{TbSժ5K%UKId f6o xQ>\V4ZD\nhNa<-66M؅XxIX̳OWr[&C8C:VÔIPQY> хq?z8JFv֑խJmxÏ}_>ʶ]#i29 lZ7@,őۂ;oww˫=̌3ӄu)n tC;n'`xV?*?%Tei[g̎vQkDOCl #DPى1a?R8xQ2+AbܰcM_2 SͱP{_=4Ք?h"6I2SA;Sr`6F-?>,Wrϟ{eF7Z 9'尿j`[Px6lwl L3IjYAx3?Wfp$ *Mgi^,a%b$~n{)KtK OzIm_۝atþ&>Ri~v F)K!gcg^DWrd\d*@W=X.&R.2bjqwc}t@[y/i~ -bӋ:Z6uawq<5=b< ҁyaNmX93vQ`{]EiuOr*sI bEn.䰘oɹ>S|v**W s"p(\>T"Z7=7Yi>RGP-ON`xt 4r~Bm׎+ `]9Q*Eq%U~WN:Te\WosUv^j_϶] j.T U5Â"YP4 ErLϏ2DrlcF endstream endobj 1951 0 obj << /Length 1216 /Filter /FlateDecode >> stream xXs8~Уy@߲I/mi=iJ Ęr,` ؽdv[GL8RJ!1(&GL۸bYjgxr16}Xj«۷?FC ,7Jw`Gsa V̤}K}}PKLLq/Li!yBPa=b!`  H*ɀ%I%\T`HCx4r,N$1עJJ(܋u4Z)S©j6)gzq΍{J$ŶzQn͗oe2 NնrP`Q8rh3'"OU9_r]X߰0xRy=TuL1ՑrNi5#R, *|1ьwچ8j+=[gI 9 &Y:Iw9ǂۏ Hg|{ QUvA H0ڄl|qy$ vәi[HSڏuxŵ W% Z7d|5~}$TSզ}p5%"Q;0}!iVU]뇿./}#mauܺ ^fmfpN~A=sަm$yΪh+IhDCLt">imٱcKr%T3h7UR%Ek CֻV.ҎYjR 3*kh竼F0fS1QBHYa Xcsqu#MOЈL仟1f@SnjTg`Z%)OHU 6jQS6 fƺ޳BXk*qW;x/Gp`B<UH`Cr"Pzi;mIZ,;L*^sPJJ @yHp?;o_DŽ4 &2> stream xXRH+z)-[SSd 1YLHR%Ѓs[j˓YT=6Awɘ(Z)w( 8T aE4A'ĥrWgI57>I˨e]<0< (%.m!@bp>!џc),] .\>1>Z !:9󲢌4- [>U70ƐCfY0 vJK:i|5%,ͪxL^],fn]r}3Jy8 Ì:W";? b=Ɯ2J2F$?ʆg~(B- ACNq(htr3v̠YZKn:&R@(ҹGLP\֥_jv%ؼYټ:Z[&\ȓz *1p z ♢_\Sm1c‹orRƦ+ KB/?jb$Ɣ]&`5@c0=#L*UtoB8`/l7:Tz&E]5O@VV$0%Q6Аo9VWǣӳBݤ*lWdZssz+ eXﶰ_أl42a\cm[Á\*;]ίky׹E|lSy#@Ɓ7Ok׹w.L〳HqQ+;>Nd`o:@ګ4_o[>[^gu~kϤ&?$) endstream endobj 1971 0 obj << /Length 1266 /Filter /FlateDecode >> stream xXKs6WHΔ0 ]{N֥q2E%MeR&$ίizؒr~}`MA߇ 8#Mp҆aEpn#i0FjGgòe93?qz.2|Xj\$A8e_{D07)^|@Bp` t38 5LittPXbBǟ:բ*?I\[!5bX__ŐFpS)OA06Q oUq= SN|xH*-QB)6RI?o_Cy7 2Uh3!>Hig{& z_Oe0.oi\%F `a1''1VhXڽH =p6/U6Z?/gU& =ꚋ8-!xH! ûժpQP2j.r8e;; #XY ,էẐl;݇?72C]Pӗ{!{GmV<Κc n}F758({)~Ĵ:>k]{5Z {s]7@8{ gE,45(,T y]+ߦق1 xBSLD(&*J$  Br(/#h6=>dP*)ϊ|)8T`ycF2?o^'d+gSqYA¦c Z"|zdg'jU^T߶0yq RX ni%;軱?Q1hkM## MZjlb%ggJ=T2+U̮GR) KxZbTٰj^s9ijWh4|Vpܚ<:CM8O7Q5XKMl6~jtBbr`P.Ǵ!K9U½#zӫvX|ZSi:NL502[?:<{%G@ endstream endobj 1978 0 obj << /Length 1526 /Filter /FlateDecode >> stream xYYs6~ׯ#5SA>NIñՇM6g$Ra]$ eyva,Jɼ0 TH$|}~5ozLgT/| C`^$u~W=EErUyUzLE[u6`.hP027+˛7-LtݦMfV9Εk@)5L3ݒ8&CAxnHMc'ݚ^$dev7 )fim37)q.eU:4ӳ@uec,vec!bS=`tm魙9@KAϨ7Iulk쳍, Qӟ-n7FXlqFJg@y!Z.ڡ[Y>{آ^Wn#+pnT?S¡.{PThzn'b Ӓ⨿#Ocy촂p`$D4.5Q$mW q̆;L-kir̥{'xz>ěv4Ӥ &[nMbs aJXU1^.0$`9$-Vo,2(W8?({(PП0#iTBbAZP-G8H f\ҁJ8~z*n a{RZ^Ϩ:ԫ=O}.  endstream endobj 1988 0 obj << /Length 1672 /Filter /FlateDecode >> stream xYYs6~ׯ4|t&u&v&%D"q_E8qLBowIa遳+1qx+ vH)G܎>~ ~{`s_:S`zt5Fk(Wb A1A'JYꍿM/6yYؽZ .\hJJ-a`qy ff V, q. n`´W//ڞ&B"BzʥUV"5ȣeV2pMg&͗ Xb#{(v ];ørD婕@ êփx@#KϾ~3~??{wpU)˜Ffd4^gE|'%zD'.ՇfsXN(9Bl e !ޠT@0"0#ja)UbfQ3EG 3'6Q09.W@p]7ahn_ )e"Tprq!U!Mbf !a|a乪Pj0$x۳S`؀U"O\%A:"&<[$û_\q{G @ce.\UF2m$X*,w׆)EL0uWkz4bz9q8NޚP; B4ÛhP/]Gqngrc5]vR;ZZ+cjKu6lItɠde38">l돗Av4$hp"2VHCa6ɭJaQ`gBj~u6p~97r | %`'~SiJ%TÁ֗IF#hW?,:|VS+bq0vbC}'֬1%7O~#6R[5~;VzH 5R ݔ@{=Diژ1[zi cfAM6 ЈoMUHX䇲Hk7ˬ%فJލqŲR݅Q˂,uY T Q $=t2}U)~ <vLj:yzE| hO%  ;Rx1'@a,γ= n/~m&~5&aG< }7zq.}4Y%mO"*8tb#>AGIaa"')o'ҳԽ䬊5G^jVe罹I;IFS=!cwEyOfoT*mkw6vf[g9ޖ &.";{4u19 [  \\IGo> stream xZn[7}Wqp8!hxw] hmPUt %N4W:@ KKsf&kRJ e-d2o78E[(pSDAYPт| :M,+9["K&;ja0-@ fg99,'XL6N֐smUwun Ȇ [ͻρiI}8sodm [X$Q_@X7P)$BNДd RR"7nukBJ s, Kg`5_$˰aҗކ_ -ڝƉSJnUU w[0~I 5%T] 57Zgj SU;Hj=ѨOY&4MaK ˃To(V8wВU7ꛧ|ЖL\al|Ǚ:LN`iqZ}2 fb@(9#Zw8@[ކ!ަ9`f&IWLS'Of/v /.WgWo.~>}\/D~}ٷ/?;+0 `_'OymbfO_^_߿}?޼}z\y16|uER ٧0)|fm4%O5u*:N a`T4 l9Z{ vOBo#l i*y2׿A%vsg rl@Z6aٳ|Ğٳab*\{ɳl-/y;ޭ_MHmo߬ @|̠gKt9n sW:m |1EryAւ]W4*2`Ysy+ -^v_Nlx*rQjiJV2Uka^hʒ9 {XpXp,b: ̥Fi?VĂzX6?C`QI!*=FTzLQ}I3P[(9oyg+^obj|+d"xo5gG5?S!S͓dV\rPri0]uO޹!{*MVc2 1 8G >ʄ`PB~5M#Pp_(`s. MHC' kGZ'9GelƲ,s檫E%~ǤHp`QQc?YCS{}1|1% :I t#fŌ7b&a5n7yd ϖz2 !Dp*5Q7OƉ;;;3h|ő[-z8Uj3CVd"XJebp^/%oMm:==l&a ?‹TBvcyzs[Z)kBMPuXTy#,NWUY~XK(2FƐȺ]՝aެ^8j m$ͫLWM.emȢv[o1mE>"[vLs6jJ0CelY^c =:(bZc{ .9?YZU3q ,R9y |c> Vb: j3O'NP/޷ķ#l {0'oS,[O]4dv./ϹL>{ixZ]"PY\YUMiVƲU;FOBH endstream endobj 1999 0 obj << /Length 2186 /Filter /FlateDecode >> stream xY_sHUE3 podqbm\-FH@{z@ 8A4=7=[K[^szX taJY~0%l`7Kz.suzU̷Y2;~`RuQ92_^<\he ׊fq&iεzy.Ȭۋə-^`k2:eۤ5b$\OP`\y/Cƅ=2 #BVtJCud?1~?M>M.[( RN— 7G{9^Zg,.$ZL`TwO#EU|P WW5=1/}ΓHgNuTx$6N8 y8Kw*3u@\7@*3xat7ĦޮgI (AgK$/FvU z9c!Xy&fn;4 Kcl#Toc(5C|2,Y@}M?xS&qvn0w]q]Iiώ#FT0IcH:vQ/;uN^}=<^ l SU UkP;uv^_hKs?ܬ8ThғTF(1]E`]ر -T=@',9p}sqMn=c<. Y!N+x!(#i^H;ޖe܍Z4.kM"|*S{8*!&#V^1>F-&A˳l4vv~áZ7hk5ڨqK+2w?@쇨vb!-yn׮˼.,N3ʔ &`j[LzPbyZTiމ)p)#iuzq#ּEW+]-{vپZEf}ƠZl3d'g`g H}K+L fgscPIdAm o7 j؄#l-2fNG4y  !:Q]GjЪj=`r}6P&1/ԍLr"$o:fqB8Xѓ5aJY1Xɸ54+4Dk^,ֆLtы2r}-5"]=nqTk#){jx)!BzU&t4_Pˬ#RE]z rdV@!!-TFT}~Sa]z: 0v3Y[vgDx$- Qp<אS ~Ń:/5_>2&(j@pCHEi邑1>]uWzU7 HqS]IشTu#0tO}U¡T'ߟh,N)=<$YlDM4 }h# =]4T8EY-ڟot*ôE F.(Re1&MEzTag.Ѱ.^ ! M/dg2]{ƃM^Ct@*RBPxE;5 ȍApE <d]е:|\|=͚?(TW~=PBDٞTsч/$ޑEW\8ֹΏ;w@bA$u@ yUhR'|pjU]z.\R9IICW]%@ [ endstream endobj 2005 0 obj << /Length 2145 /Filter /FlateDecode >> stream xŚ[s6)HͬQ/iӦӸm;ZbMeJРDSr/"pp!q17ӉFFJ2Q"IYK\Rӯ*se,V˸~=滄sb`~{ŧ 8!HSL.~ '3]3:yK>$\1n-/-'7F)F,QB"Nl@i()^v]3Fm>CAo̓y.I <,$ 'ل4[,R ExX\aP$G@OQ3#`ȴ |^3s#Ri9ɫjQ|waZ\` " KDz9V3k`R2pACz0ĸPmi0=k|{3& Rgbwqk`B8o+w~oWo:Q,NCɢ)>Y!) k`C!@p@VHzؐ+K։dE v(1rXCbp5X0`  U PN P<' h9D:$b> \Ś}jXX6V;_~Hj'פ6AIزlF^y=j#bŞYq EYFP Ŋٻ_Fd} 50|Ia_RaFPl$C2@IĮ1$"I`u;96ӫӁ vݜev{ n$o#Hbɾ 6\-<NʞÐXq+AG`5\djɀU,ƆK6XŒ:U+Vf؁ed$/oUKfdJ\ es?+Uz\L~K`o,oj^=Cܬ=}ei(/e,7esw-VzHeoQlC]IhRۍxj<.K.=)W H {H{$(&w WYHt,Du, g:ڑԪrT@?[Zk̈́} n@hDt:B֮ѩ6]lԄ h/ظ)8cf&wyOrwp!mԮ֖Հfin[#/-Ӿ-: R:A9?{`̗:Mb9[Ta%RpW;̫-48P7iV^YaF eByYʉpc_AU|[L+eF3m*˥};T 1*2mWQyշW6$,P.߄fhlU¾xT4ܟ\O(2{ȡzBRo¿ z Le#a.;QlHf֠4SvW쯓 ?[^L`WGښ6>F Ԩj~gmٰ]jd]FZgТhZL:&6:˪{̴A3ۇI[ r HqT֦Gyd'(_DpB<A6LBBzbGef-S,]_xÇy:Oh>p8ŘY&+8B.Oo޼'u&͠>FgGI8bT캄;lp;@D[Cn΄ ةĥѱ SjS]1&|> stream xڽZYs8~T!8y>isg}%V&rd"eq"EJ>F׍<8tۏw|.sf w] (r3;G0' ӽټLxB=>ʕLT}=y>)w?3_X;OrpJFܞ}>VOPMWihkAQ2y`G5wwD΄ n8~?ޜ8'.bFi+xWJsO8BP \+ǭsݬ%  1_T.c~I(@Ml'84i?rn-M{x1A>[{dpO7HE=(rC IcLȂtL(6RFjbaL#S8[b)Mc+y^[! Yl¤#R&I>\>2|a27rkmQ[RKӱ Ud?TS1!N?x´JrM^+!?([7Cӓm 㘌~w}3b+gFB"/d!7K*ʿIE XY\* Ib/=be'\(/̲&iAIK*S\,MoMtl3A 56ƆLƎU#Nr~TbK*FѬDkf8ȼ98_ZNw@w0IW@z,JuttPrP9ecJ=j0N[04U[GFjݴFu{<2+s`F+gӱP.U^+}Ii:fRS P <@Z6X.t&]5~v4iҬ0 ~L_ha3r]5 ׅʘ!.>DJ 9lb\ǿ"(ĈۡjT*-sR#W#InԳ"L <e8qe)3&0*F)fL  "gj?)*~]d23zPC(eM(cuuA}B0 %aS1,7@0Բ0ޒ2ZW**U#ݶfV]BPjuth:: ڝܓ7"Duޚ'/OcNe 9ǐ֯#!y^H6ev G'%p,Wכwه⪫ ow.`4 AJ8kY|@GO}`A< h~8\侌 Qf حهw/gAt j*Q\AH}^z?%Xi:˼.[Z(ڇby a1!F$ºDNMzH/NZDTsdZ5&`It遝<"uldkW]dkB~+pQ=W}XCTߩeyq&|& ':M[s-7YZӰ-E ՋaU_\˟cS].u ;h(Z|lOu=WJWu]u endstream endobj 2020 0 obj << /Length 1214 /Filter /FlateDecode >> stream xXs8~_#̜Ux]N:uؐN ဍ2s,o$;y?s:zwɴ/%ssGatO$4tn]7JACy&f>pΐP ͧ]LG?GC6 Z#M3[nc'>81_;+ %:<QQz-c-#kT2O+Q]ҦC(E`˜h0iO[l헊#ƕH J1?'rξalSz+nRH(+LJAZXgnl$60Xc8` Eb7$&SUUGTQx istWDM!D ?: u}t7Yd :i6$\IŇ&[2NR 5SJ?EdR(sa7"*ܼs\E40;m A.j"_ɬ}1$?, ~Uﱝ$E)~7Ka4wMU+ѣiY!Lmo< V\܇zJzc 4>nDv}U+D9(_gnbf  %PeKIl%q{MICFr2+ҶXᮥ 9HY0$[ 431erǕՓSY * 1w|.Pq0HPGee=;נֆaYЭ7WwI.߯u+44|y&)4wTRKU@‡)tW98f F[ D:Ḵ1rg0CC9Wćڿa&7Hrt}-! +ǏA` z8mKO`7/p7<C b)VbP嗁Yʷ°&8~Qn2O͚:Nɦ VrXO8񾄁f~"(a\^tڱڄ3ii^oHA(䟒-Jf,M6ѣp^nj{NCm1X@7{݄*/N]%tk|ioGI$n5iut_^Qm, endstream endobj 2028 0 obj << /Length 1209 /Filter /FlateDecode >> stream xXs8~_G)~igKRܥ 1rԆp6ĎfX~]G]ތGy"+xB#P3(2~XPEk?`a-&˅Ί(DW:GLbt޽G8B?c) }]I0fh~ZkE1YK̸PB8,C/-?I6tW8  PPDP)Wg]ޞ]A7,fNK;ec"(RY˼sZ,)(P;T±[s|&[vbLjek%<^OT&Vx_ zK#;H`C~Ϥd<#  X]6]ƅjv9 2i@|ϵ.&-ܺI>'XNzOto6.֋00fc>^R& |JC1 Y+D<*W!{UHf;t4 b547u GTs# hU=ln%8Qtl#R0d܇<D]l*8;FF8ݖ dtg )!Qw\zYe|@(`I:\s.\ p.m . sX> p6 h@$Ùr0/ qH\A6Q6*jCnrfN3*lEaRC=fj{] c@:B8M[pfE¶+1lOfeK疍#ZUŴ-@v,L&:Gl0qu'mnJUq1?n{mQu&uf^L^$="EwSk sv[4Ijf|xXDЮnǽ mG^-­{5ЬNtz-bci 0/Ϡ~0K<+JAM7(kƉZsU!lXVCz|j4[$%n#o3}=Xj72 |VzW_ڇ_/i J/cy 5rzs]&v{sz:ߤ??# endstream endobj 2036 0 obj << /Length 1744 /Filter /FlateDecode >> stream xڭZ[s8~Ԫ\^v&6v4m܇ݶ!6!{,|wn9G [WWKYYӅb99Ěέ/6Gd^oBn4d6Kn5\z(m5xl2zTf*mD]P$rPնjM99=Lܧ" cERhG(KҞ24 ~MԬ  V4UMt 댮;Ī@p E, , 10փ0T)EA0Ln=AtˋK9uXϣyk3s8?s5 @lXpabX|Pp<+xۋOhsx7wC=WhqŰ(#|\ jUuv7q1 ;@vٷ5R3ф8ߊhJAA聡%bNYϣ"=֛}m gքxs5cƫF& EP-'v55aySxUOxLAi:4|Oi"#"u FՔ ò VYl> stream xZ[s:~ϯўU]<&'$i98fjCji F sX~Z `a9s-yͬr0rmry;>qB@[ȥܚN| ma<_UR[XvK9 I%'5yʿ$RC(#T1(F]Ѐǫ.7\٘OHs#VJ ioмM”NNci.¿\m~s|MmW! 6QoeilOrq)`fH~%S]UlW~T օcZR#*lホ8R6w Ò7Vk^iV,uvH_ %Zg*9=e&vi`ݨᨥ@XЉ l>OKUNBljP4[]C9Od;* 3~:9FdAi;s Q W> stream xXKSHWQ:R&tIHRl2dvɯO4-j3PvG<89X$%՚f$@ ,fgXe9ͳFp:z~)(#Pyrx}PH %? R2w YOHʤS6#WVwO-ݣżn,WimӪsc6{nQ(}glO!WAZ,’6~γqսoE2͚e{oitOzʪ(|*?9 V wէ iW;9i㾂F!Me=/5D$4H- J!b V HXyuEG kK  jmD Cʥ00[3#HEʑIEgc^3||%s0XɎ!zW?diva~N\n0k0w=U'v;} m|r-w8"@ȍ]UIW]GoIA/{> stream xYKs6WHT [g&c1%NeRɤ)BiKL{v^~^](P,% w(2P1EY)re&`#Nk+fR'TE/EZJѯѷ8 (BAz?3x&QypF2}a#*|Ԓ F DxB0]1a*yƘ?c4; YqJ(+LVLAVᇳ˫۳KOLi"AWf }i0+LAN磓t;ҸT("цLff&)AOO rDJahX϶apJ"KFmjIT6.hcDhiBdJKj}~}.-5͋nkj]}fzf6LˏZQb?Rh|U^Wz]%ٝ?]d`pxWEjUL*^6Yi{4/fJe4xCceϷvh}<ɜ.ή>]̷ERzg:O\$˥ WG^C nbUՑcÿ„q^Nfpr['̺Vu a՘0Y[ Ko["̣⡜ė.2LE2`6 A@Z(p,S& zNދ )mܮZɑ`G%GWd֛X$-h.n׭on\VI, {qJ 7nNSD8BHM5YBJ(vA*jG*ȾV?sp8pTi3Xwڊ>׹ެ@;.i@Q4.GgAvu 8FP+$Z 8Utl“dؽc'&^8Da1 3!7X>9G;Jo鴮cbHa `" B| .w4y6 @,w8|;+?Wn l7. }Ob H'U)W9&Wggn{j{Uمys"ҿpS2kLv/O ܪT۷Zm皔,ӻy>AǃK%!Od"l8qRף/β i$}/Zp ]o tz6qЄW4Fâ3 RP#ϗ!O"/jφ=7i7Mۜ )Yn~v;^w3w7땫#3%a3;v1]G9 /2+xݜU#uO1pIb TbM Jerv1o={Wu@ǾE7 *)J TܻT07Wf endstream endobj 2069 0 obj << /Length 793 /Filter /FlateDecode >> stream xڕUMo01k'-BY/i)fK/Ǜgw7UVEՖVEA:' qUt!z1=pi߮!2GKDů~PUJi[F6`{O<8=9# 6:}S6ڵ&NcXW*~)c:NYԵfKIo>9XVik{<~y;`覕aܭe&숁w8'ӣ޴j&<=YN3቙{+ se$ުZfC8h]U0\w}?>z}9L3m~KT> stream xŚ[s+xDUut8Ek:٤TXZ3 #3Mw z?˓}`"OJf--#WJ(Zn/6wg,w/MSd80U˓'bT2][ɗ?g?[1ϵ; W:" vbD.jjI˵ًwAfiai!gpQl>.)沮|1Z"SZt?cNMΎ5ؼ6 Nue|g$.r̮,?YG]\: J7Q)*8ȮK)%r=Z˧VWT@6Vma(tk OγD|(zֱfs{naXxcl~r5)HUN Ad?#rڌzf>~VjP#DX:sdh  3'`_ݻُƩ'.*ǘ)/8`RSN(Iub4 8]o"<$" WNR rZ̯7=S PM@~.ݙ2/68C*q=gp^pə$C%G&*AB'nEgs=wXn ؑ*ȸSlDaKv* bb-4IF `ɴ^0Ӆj3"L`|*ROz/a p"24X޵$VЬ8.\+]a@,t.T2N˛j\QftR8^s#qIگaEB'2IE2ım`OE*ϫ=ߍH]eiIeFfՊ3#>;=xbi w'.FD Rc0tJi2J'P+S$žk@4u~v~qѩ?pNJR˭igϹ젶}᧰|5{yju篕?}SedҵX.N7>M2nOM˦]}ۛtX=ꁿG8EGg`ZBIl!c0"2pqI J$u ^eq|a #N&2E1j'iYVϦ F*,~C0zh -ܷv(dZ9&La":ӏRC+-Duyh6MGQ<ˤu_f̣ڃT2a<#4GhCSΦ_av.=_ _IVOW%;-q Lc=pIVdF[\ͯdqM%S}vq$TvAp$+R燏A.d*b/M?p9 endstream endobj 2081 0 obj << /Length 857 /Filter /FlateDecode >> stream xWR0+tQLKa1$vpZ׶:qս&t<}:+iRH +;zNg46 ~:=(lD N{׷E ".ߜ"!L`tջ5LRǠĠ(613Y0zҳr`úCNC/=` Hs*waLbȇ0UDc&@\)Mr|{ (]9lZLa 4˚aUWM>I4 dI!r#O5O R pz7A# q#0&5C;*=?֛}(WUe括 3sJ/,5|мcavD 9֬X@Y'=_=\$as)pZˋ09/&- H֑N_x7wx_, @ 2Uqy\`m^ۺIpû * Dԭp]TкKfGgFv6- k2 ǬVʭg?NO]#smjwuKu(D`v&FfŵN7Y;*=FYRBoQf4^׸b `"dq&vkN  ,Zμt7O|78ܶ5}@*wU$c&I^Zcޝei1v<Ǒ2̨G[ 2d~TM?RݷQ0pUH -2}dVWԶAZN/6Y/ endstream endobj 1993 0 obj << /Type /ObjStm /N 100 /First 975 /Length 1825 /Filter /FlateDecode >> stream xZ][}ׯcBqHgZ faZ^hrk ^ɫ]) ]^޹̙! j .'WYC]TFv9EkZQBpվP4b!5}XLwkmև/2>@ b} jZ/ }h)MI.]1٧R#v1MYNdZxQ?J:8Т:/k0"i3ǥi2"5uQ\bR֗]f^$ %;Tm萬UL,ӌAfEA('0 ^6jĨ)91FH-DJ4YD6s)GKm}hij&-px#VGs`lƢU`C`89̀,K ``26 "PZ$&ٕifA'x*%ZhDh6G%U1x縷`& ^pÁ"'hnb\,xR,LԘN MT uB4U1R:U C0 )h3X,-FW.k%^ͿqW_AZpWL)i6|7/P>aG/7w 7 ((LO7 9=E}B#6ABlKFw~zjsWn7/l|bnͿGcj ןnljZ߆WU@W䵾x[(18ysҫ6ͬF4GOfW_k6j}nۨ̿`.1R="^90B/[^֯!ÿw}" R#`Z|]ְLc4wLJr5gnפ {A3ݮ?}x~k-Veʫx%Ò K: a5VφI%O'] /Ð211,ֶBBN+)J*@ ord'D"c>{Of8[qJ61Qz(q<%ou@0{*}H~`5zE~~],EQDNn*dzSDAg*tQ^Ѫ%&tsq!y+ys@QL}¨=ғ&%ON@ێc%3*xb]\݇P,>aulqd99v CݸE}tʆc67b1T-JTuhvAJWyR:*:j]1D#">a.m%_ze_j;#Rɲ^!r~;. oT+J'TNͧv^G'G&d:)2↴S-!v=^ iW. ,юT:5Gŧ֣]8'F6Yϟ,A"cs$ra vߓ}I$ԕY3㲖1*c,Ÿ .#^jlAҕ۵E ) &(}YOl< h:mn&ʁ<}9us붱)SK*o}5Ϸ#PV8UNyQQ),:} Gvp>-3 >犀 vhS2R1bN' zB06^HXx> stream xڕ=O@ x7/+*Ub@Vu(Q!5@KJX,ٯaX,nlB&ȔB@l b+=]zGNۺ7w|*jebwܕ~܏oC?}B,C2Sdmmd9yKM7NxO\b&cWwRYn]K{{QeqUVe.Uo N endstream endobj 2098 0 obj << /Length 717 /Filter /FlateDecode >> stream xڽU]O0}ﯰ!ikiӀTԥҤKz)m by{=F p>A [O~f3*N K92ln*hل!I¿ٯHQB, e޶{VZV:תFtIb< q # .MYPxZW|n%d#B$|أ3N@ SNC8TUݢw9:xǒQ(8ߝ_Fbu#(̝YSz )O@3o35p%hݨ;ۛNvIs("bVpK7c> stream xڭVMs8Wj/p/$HmmUIjNط̔ c٦ bׯv5Oݯ_ 5@ltuOCˆs f+  9""c0['/ @9$zERoebF#M0!a َ~!{?4 P0sDn"H4iqi!:x 1$cvEc6G~u 0,CNs\ca&e٤Wz>ָ̫{RC1-~wv-ۇㄳvYRg SƼ[uZ=wn#cm@ 3]e?2Q4+%'**{&ҥ~1PjfٜvQQ$ti: $i<Ԁo~Ci3-)MegJ뀧l8w>w(ޟNh1Tq5~fUR-D n73#TV\ϵSXNVvײ#];DRhOskaw+TOS]wMKr`+ew=  !׈MHzG ] zy]y2/64 endstream endobj 2140 0 obj << /Length 838 /Filter /FlateDecode >> stream xڵVo0~_ai/ -miSJ6M*M`֭lHvi'}DF' D! )C)t cBi*-~@|jƎOK/4LErObu6zQM C2-A ] (Dq`gh:?L4e%XHӑ]> 3L !7%B,6zsHێ;J`9zWyԓdHHpsZ*]:P"_Q;؞|zzzɄ ,pAN,kKsMj` _v I,}j h'cbÉgꍝsEޔκM9Y i]qv{?44ȨgE#Lbn Q*„fs?=,Ĕ!>YZCle&~զJ7ܨKhVIbdQK_g1ƥ)l?}$ЪqQ8T[9d")328^PK'Ҭ׬:AUnb@ 0』7[95&N7\sЌb9'pYAb݁>tm22}:`QUdsE11 !!EV'ĭ5ltUc=)굗2Q*ڢE#xY1h u01x&$d')n>V(B[m-; :M|+AhgyݡE4Ǵ,]Sz޴ =oԳSΝmgE_ #g؁q endstream endobj 2147 0 obj << /Length 902 /Filter /FlateDecode >> stream xڽWR0}Wљ)B;QRt<pDY撯JSJH^#sήv%ƈ :>bnzh0BqA!s?B^8`=hYv({ӴY!B~ 'ˁ9 qcGin4]!n^_ЍշIO54#ݰ uЉ쌧ҍS)8]IVj f<>wR8!n܍; V*blQv~YF9-."G 9w$Ǟ FqqA0,U1lIݰTf|^h=7#L22nv 7^j3gv f.kZZzƬ*kxfS:.kD&d5w}dG cLgV{CEc_ʌ*t?7ersrc=zF,5ҥ^Qny9&g+]o mmuv6 1k,zzF3UVoe`:S~ÁEݪ!Lo4.9P]iCsBXU~I7R6r%vmeتDZDy؍B_A#u & Fa[[y+mVB Rn endstream endobj 2167 0 obj << /Length 1000 /Filter /FlateDecode >> stream xڵVn8}WQlVLR`\(0i 02m (GKrbN苸Å"zq>xw(0|"0Dјᐢ:bgJW5k6mLX825{7<{>xP&Xqc棴8F[=@~`: ?,PUUtN&-3#JqrYp&G B ExB4<:}2>-d~ ݎB@zQ*+ @`!I=C̢{<\gRyAz%* endstream endobj 2086 0 obj << /Type /ObjStm /N 100 /First 961 /Length 2568 /Filter /FlateDecode >> stream xZMcrᐬ"%|H,V8 p󊳣N4 2TE{L: hJ(4DDqO4O)xMh)<ao,.!$SѺ2Ybufz.ܨi {- @S(įa1Z0a𑓙LR~ _C(h @@h!D7DC# 7rDɏy0u0OiEX1u*6`PQ.![WF]X?K8"EAѲc,X~KѢq$ϖB6&غ, [}* =|06Dt4C+Op;)H7(>rY#?!v/RQm25K. DS.c\I˜I,hILO&cOXzImmC٣Q􂰭"I"2) hY0+Y yLtKAEU`8U*c3nb3@ҊFDOZ~hL-J݅GI ٳ7K7&N1xu.ӏ_|1_]NϞMv-`$2|^$vU vW%]aݷWE^Noy>NF??wP_׈_b]z{wF_~ufJrv#ƫpbc&9$ٔOMяgS'fî{Cc'oq7}uuqݟv_ Bo4j1:ۯ&JtQv_vjBws{ׯ[f$e}ի.+.ѼrhkUPF틳cD,ӑQ/9ƂA>Ԣ ֥,珚JvF tV"'iQ+uYHg^[E('Zh8R9ݓ$4Թ늠kY}BO5@!:QE:){/\zi{U.܏zRmn2N9;#87Cp ɘ'IM`jsmbs>n .쌸`G+oG%dCy\~jI ?*)F?Ouh]Cr-59b#ɘ0H#ǿo~~8#ˮ@Hܼܣ@AIK"Wisn>;!UXپiv\}GI^@1 zqN=l=ؤYtV Q0xsJ_h뺲.c-=ڵ9wJX1e:UA#k.TjTA! ,fe8q||CcP.1>EU ]*kUqN}'!c*.h?1Ym3 uG%5m J>t`eHFؚJWӏ||9}ѿ{b?8x @XӁX%b@߃) w!ڔb_Osk$IP1k-4%ɢ<0 Vc=NyojUɀA+1`{d+YJޔ%u%^ڔ|b<-AForh;~mY ܾ҄״E㶃: *,cw`W7ey9vJjA/5)zH+t[֙"z ߐ0TFtNOw{5ʚ<Z mVu&o{rCR v8 &Җf ݜQWx<"lSۻx{攍$-73ͽ'ACQANr9.#rָcz{)Nqjqm~bTKBFfe^SMKs~-O7`O_{\y=u,u#EkOjkO'FwDmP>:0;A#zDiOVŞOS!;9HKD~ȱ?@ O99Dᄆ-~u@G. kucA Y6g endstream endobj 2186 0 obj << /Length 1060 /Filter /FlateDecode >> stream xڽWn8}W X$%X`7(P CZDBuqtI|}"Hvt#9< >L^Nf7|p }Α-toyN/׽ʢLu,IB|r}D;9r={br7!&Sғ'HCg0eB(m¸hf[ٔZ̒k2 BULh |-tSĞr{YȺo*p1(6T3{w+ -宒CǴlMeOͳ~ZQwɦhJ?;_a~.lJ6_I\ke[IAJi1|J3{sN X*.ƻu#EmfR=urk𓑳Sl}Z6n˜Y@֐~HC`]yDCgY>3Vfr>2  _G,iazYșD1e=DKo;0v~g{p@l4Y>v7kѾhOp烻봒rn 6zP{ރ}P2 e 4{6FկF٦:my λfGC]𭾨B WQl3b}kw\-+_]g+ h;{RT}?Lp^w1L]¼LEQTi>SyOJp`cjOgp<]GMd3p.S8gUڮU7:aq٩V4c7a`&u=Kdln\F] ZC P#=7st_-ӯFOtys/\!Lpk<{ W̹O]~%C? endstream endobj 2204 0 obj << /Length 908 /Filter /FlateDecode >> stream xڽV[o }ϯіR ޶uӺOdy1IQmt\VM%`| tp~$ ( tb(i< Cĉwl>WeYtb&Lں}1:;žQ~^=z U{Dؐ`]\%&{5{Xc6B# HI1Qj$ֺ8]xQ^]uuM9f=ZYVv"jv"&mD˟XZV9^:EQdwVΛL* 6 {s &އqն̞ӹqo왛{4igH`Yz%o[bϘS;3_npq8v䉕|YD~wu-AkqSWq4꫞>8D9GVNy3bEZ3a}ynM1fbGLX[~N?^^Ő IdmBDǬWz*~Yw:p|lu8 !l,WL:5ER~P[,/9 endstream endobj 2219 0 obj << /Length 1086 /Filter /FlateDecode >> stream xڵVmo6_!`_$`fH`5K@e!K-L/DK~":̀}(Rw~ttu^( Q䉄x{ySS^uBVΨP- ;s+BA7BHlXg1x ̲&OcWں> 17&@N0m}bNH0Y08LW@0gC,|ˇ۳ke} _ endstream endobj 2239 0 obj << /Length 818 /Filter /FlateDecode >> stream xVo0~_ai/AvIXMj O!H$i#cu=0K# 1$>Fq$"Ut;*bi)\F!GX"<"@^>i^NZPϔ={sCXGRLǃA3S,Bd,0^!O]a7\ǻsȕY{ʋ_6^Ud>!zfHl?d [Y OY&6]cza>V"EQj.deɍ&4R-Uluu#{(0bSi "unliUZ ayTM7aBR$78g꩛|VQڵ>S"EPRCԐ#5VBUpQf\a+Ahaq60;H>WkÏ?* !3z+ŋLZQeI"Bo(;UjfTXuhײ_5cZ~4:Syp΍$_qWvwDa2lW |]K8Su# ?;O4Rx(5 00ui7ke{QmYdp7b(fEx[h>AY!Լ"FRF endstream endobj 2170 0 obj << /Type /ObjStm /N 100 /First 956 /Length 2415 /Filter /FlateDecode >> stream xZ]o\ }cER@nv6A`4h_C͌83bs4IQ5"D}:*dŘ0P] ǔMPF `$ ]JQ`Q] \mk9c8fE>fxĤ*wɠ1):ˎ_،@GX D6M)0D|C$;Xg!.lC>E *@bck8o)<%p`V6۩JShd`T,^O@%5i2SN fQ)$4 2wɩڢ"i ǀo T'KT$rKKړOG\B;j_2 )CRE Ru D edJ4-dCRd>-Y>}K᮳o߾:9ǜ\gd{pOwZ}mZ/*Q؃w3R #VL*w @=z6OAdձ?ԢD,O$g|x>+)OYt/'Oy]4|1n'ǘ]^X-ϟl~nS՜>6~^ hUEȗ 0b?;Kk5{/^t:t B9u/pl/ߜd|n}毛m2*.I,Q8>sloO.{i-2GAQmf+b{r# y= 5Oib5kLM^;XC۵qPu8nD{qy~ośkxwxy)8(uiK0.GD/v}VH7)c{ҸLex*Aƶ,:MB騾gJ6Z2R(>V2"r&DGZzK&G㠺6Iq6#)( xŧhY_wy#y?yI3NyB1 >p}A-@Qq {/c9)5Ьa&T'Їwj {X>16]Bz|lg&Ɨ&|/Tj瑙Q8y KJO:*o-Gr?9&/$-O< ify֦U48ݙkBQC)|̳jO t bīhCj!UizsB1KL*`z%ݛ`hQx=O! IʊCDPu8Ngb_m(iFHZiU4ڮE{ Vh8q#r]yߵdPerb,tr'ex2Nu뤵 ~Xb -uOוyj ɈS01ۅ/m ˾׳#hC2&yu),h l3 4]^-pu@2vK2923 :mw([յKzy%j {.2׫]IZWu؇OއdH܅c받,uX*wJSa7Y۰T2}{w2G2GK˜u\> {/AK8vrA$|ͱlVt r; 0-ˬ ehy4OK2ٛ/W{AU*1PfpdAj%BڻT^FSoٰBy408𚅕PߏI]W`Xm`tucErỷL㘒2O vHueaA2y8C1] ~ahQ!ގN_ZcI)kvrH@u˩ɁA8x%XPwKgc9G<]99~!bYe.D)kDJet% ;Sf%.uԕ0H߼R׼{?Ž endstream endobj 2256 0 obj << /Length 1042 /Filter /FlateDecode >> stream xڝVێ6}W\EZA $чnCi[X]l]v}I%ٱ}h9sp''7|p}΁W:OڊL> Q:yJ}{6;S@.0| AR?Z` xZ+$H;着.fN]ɲAٙϛҧs(|}c !ltVXll'iw>f,!]pM˻mI=cP@N1B[&:% N/;2r((t~:OQTD%[ uPy\9m^no` ֏ظF2PZh.ښh LVn'"ZőNjS%o楶iWf-%+ڥ4O<<QI1m*=KT}~FD[ǽf5nTѡxN./-û"lcG׼Y^Ru(+˥08H=K]7kܶ.K<j˨LaJBЍxbʆlˬvᾶjd%A *L]|(Uz~_jeB~V zIfޢX Dmlk:rdNhnd&͕_Eb6!CIy;,P ,΢^ɛ^b>_]եA ޷bWkXؤV_Z/f.UM?˵jвY$OK8JPޅ0Aڡv9T]Yqxpg,Q^n}ܔC"8m\2  8~j:*_?y3 }82C  endstream endobj 2269 0 obj << /Length 708 /Filter /FlateDecode >> stream xVMo0+|4\`z6kVKiYqR!_?$$M.E|1 z8]"s 0r9£2.d9Wa(s08*,T Ej~''&ыeIlȉy_ Ev]RD1`ٞ ˕ pc#}j0LOh`$qpbd GuYQH [r^l%]wp$\,ku^ i-go,x֏Y2R&I35:jL$~,b+^Z[xqC׫Bk = - _߃o/n{N xܽBgJȓIj[oa8|j7 Yď@5d$wm\Ez;Ѻ7"7V qi12y"gYHw[oíH"5JVՓKN@.e+oݺCj=,'kA'PgBZ9+5Um .'6Qul{K$rڿy+⫚3E5+Y:ZS2I_  cp/X+Xûw`m51.MܙGThaܓâ 2<3m /uw endstream endobj 2295 0 obj << /Length 1052 /Filter /FlateDecode >> stream xWQoF~@ X~}g6ľܥ XoG!cXYF1+)bZ,;Q~rA+M◛{9'oܝP "戺26їNl+맡Z8#BFM2M՞XuFvVs[y`H,c}WHŲcJ_gSPl/j1d Ʒ7 HyPüTægDF_>WAcZ825hblJfec t̉IvG`>L7ugWk~U?)hV"}1#?=:RyVE1c endstream endobj 2313 0 obj << /Length 767 /Filter /FlateDecode >> stream xڵMs0:mrдP2 :d<XScK&+KNlBeZj-qfGn"<($8 h6G7V #i*T=OEIZ_ӅeVHu;@b?tOj| FggQ#Cʸ%h. Bz y>yR,GS :_.ON'ƤvclB2m:F? AHl)DPK<)8[tnHRDggJy{eeRg~=6@gm#~_^Of_M;[i菜v 'H1u)x[ͤ"#-`b"[qCnya&jb6sV1=X+k|{fqY˅쉭u*u_?Di+X#1NL!It; rS. KǦ+@-2xg9ϯDxh2+pO_OD eMN=l<++qծäFUR~?3&ʼndY 1NHR+4X|X#*ׯ\$T.YKr$;zߥN7W.`' q蒌{q)eb7?o endstream endobj 2327 0 obj << /Length 996 /Filter /FlateDecode >> stream xWn8}W /").ɦ@Foia2# fPl˕f}2% gΜ! JAg+#Rr!E/%RÒpn_K}a_"ڝ3;eh&- c;+(Dw.}Cq>B}@Ge>i]&J:8/uWv'NG<47oG,{5Ѡ,J+=U&$H;裸hzS#>Qny a'oLttYlJ ?S CjWf:^#V1~WpS=]GQN~akDDb)a!<> stream xZ[o}ׯe?!`i@EkMT4>g(؊? k,p83YK]Μ:ulBT9Jn#U#Ju=H4~Ȳ䬥bޑ'4UچB"Y%@X*]N܆ 2eHf'W\ O\;,%9|\hcY'?v/Sk>ɅzN0&hcҗ C Fț `7l:r䣏=xծ|}'rѰW?8|E,o^V v0nM',1.P{;<:;|O8%M:y/T@gƹ'E"VyyufOϗg؛/_秃>MyoXUȲ }31՞Tr9¾{{qSX,0ւA eH4M2Mx< Zd^އ甌W!+uIR,0GĞP|5*O>*l!#ZKUuj4BtD}Mk@H[˒V Tf坺ʼKL?ک}"8(e75XoKHL cG5Ϻx$wn!qA*zk5膞ĕ\nPƒn,* jQ4&Wx᫋H;ۄڶQ \ж\&[&V67q<8nO7f3}" \oi<yWS0{˲D yf_EtPY( X731؝Wnmz]'Zmi1i-$Hȩu}%#I4:&8SB 3gEY\&?beA3_sQCFC./AThPkWI e](FC 0څeCej'*,=<-4K2Һ4(7:BRDjYAZ1B4O&!T}w.(`g)2 L0ε'@o֊u1 vb}eUhO"6-UGOv ! kZ9ȵ,=QUmζA}`Tu 2uS+ 6UB2}4?zl7{ TNRVYT}Eګ,ǝТUf0*;ui;';u5اK.}nSVC]6.M4.T6fF}پl޾xon3W:&9:z-鶣WD[ Pě32y[/-W՛VM@%3`SuZH9=Um <x2dx4O8yև@~9-IQӸ,*4ee4b Px].1 Tl5 _$~LFC/g^3{DM{ǚxGRǧ00b/Q{JnXWP:l9q#1HڋNW DҨe^ 2#1֪澤p6AqMC!)^t\Jœx[ü[s{{-hƽ9)SY DŲs}qʩrT@vBFBmbWFз8#3;}B|} WG גo5ck|l;^PB^Soojsp,ׇFANMps]D+;T}S RA"#K/mvM!0JAծ3rXI/ΩIK5"}<:an #k]|(v-Pۄ ]ݕ2mB~CVݞ'Xnq7 )%XE\& dFE&iiVip|IpOioܥ{nLY2Tw[Ut[-mxdk. endstream endobj 2344 0 obj << /Length 846 /Filter /FlateDecode >> stream x͗r0y -J%AlY&cl5Ȯ/-sdɉcBV%\G>!h:g'8C @Aİ(е1%sx2Y/3c6VŌ f\O0GPL a;']ʝt>T}[}{yCBqǑguEc];=M뭿l Q . l%SKӭ \?˕g]NgcfZfT|gAqZatɗJfn{JjFgTB>ٗƆ#LC4LiB|4K̪2W|i?kfTUIXvݢy<~IfV3܋yWVx L"LKԑnɊ[Vev7`ݕyG]4\]>um*|0#%jJL:Q0~Hlb+kU[|D6mVuʦEZ\jxGa/]}P V6q%lKJ&?&r&ٿO^J2tdvtED:8L҄΅wqtmWRӝfxe2j͕v7K8n:{F&vw)4 .nfLE的^taPv Ӣݛvp6i<դ56ХN>>>sMjKi|,5K-=G47[@0 endstream endobj 2348 0 obj << /Length 213 /Filter /FlateDecode >> stream xڕ=o1 ɀ|9hتfC W. $P!ʿouɒ<!bl!!FfA֐HfMk1[T_.jfB殯9K@"chZ4eB[EpoUϛS CM`7;{W*r!nϺ]UY_i;W}M endstream endobj 2383 0 obj << /Length 700 /Filter /FlateDecode >> stream xŕ]o0+,.plmI._#N%N&NaֆHs缜 ph UhGvې: h86cq h}X\75._!DfDA`oMdJeR.@Ø[F鮼mRgFitc=+)~+5t&fpDL rlEdmUWIM[&ll#jq-gP2`+Y|s*J4-0t(x2- wpNri}XIj\CR l)LU3m bBǩxK7LUjYYF\ŨpHxҒ\XKVE<>H| gSvZy/[=-DG"d&dqHqMu5)[7il$tZW.V҅n"-k^>cN482T\~^0q#8@K'Q5h /͉P o'~N?jDԉ endstream endobj 2461 0 obj << /Length 1450 /Filter /FlateDecode >> stream x͚[o6+ l`fy)jh1(ő8uSneZwKSl;/IM\ك/);WC [W[Gb%+or\ԥ-dzm1+~\wԑ/U"Dwغ^[0+-3m?XY뤅WxnJ ,G׸b}˹hp9?ǘ.?5 2-iiNyQ?p>?u9Px'bK(r\A됶R^oF.i0Uj63r>qG$U>A*qgJ D6n Nh,Ѽ!fq]LA 0MB hl3)pt;RsYFzmw@%:T[gYi09"_y}Oy:8@dd^ X~ kĝT^,}b:r/<$ 0ʪxzq(7w}z\@?,>__-"ٍF3VԮU1slfސ AN3rj2 {Wpa )r:f%yF$1Ѝe9H9r] rLj(w q0a?)ht&q﬊%/C4^u3KTI0bz;\ H3; Ӱ%܆.Vj,yj+#4+'f|ToB#ji &GI Ah(fGc(R6ƣhvѡ痿N;nn:кg櫍c1˪&Ǜ돒:ʶ t]xƿ|Y{w<ܩޗ{aH5Bm?{ 6m0#'siyG9tڄ!tM*CJD衣dڌEn+u8~t߯W`ܞ/#H endstream endobj 2334 0 obj << /Type /ObjStm /N 100 /First 992 /Length 3406 /Filter /FlateDecode >> stream x[aq~b?6_8p8 a$tw鄦}fO,H֮[D8I|93 y>P\BI5t^"-;y{?uӅҍ[H<3'-Bahm@G讎1YG2+ۋ|S܇><b_Di^=BdC@ה"aE}sok?kZ#,4a[rkv~|rb/ϖy=_<>˗/^ޅxs*C7o{t`,xK{nlH(2u)3帊~M0Hʴ p+xa՞'\]nEb 𺼚R\#S^Ӏ)-q(B= l{μ‰,8]ea#÷֘>ۇ7?|ի^~[hk둩jcϹ jZv.Vme"]{!hX-jQBkֳxCaz*-0%5Fgě$lV=l}9<:U;Nb[&_5gݚi PY~RA- o XFnTL0?/=[Qw}s~x 9kГ^dT߈p3HsIe5qsԕ.(Ճ+6X:~σσ çOb|qǻmHkc_߿yhݟov+\=2j!`I`<َOKBVz2m2D?cw?(H]݇03zdS·Fng|`VPCáhB{f:))H4)Y<@ ]%:l6'9iM0FrBS4ϫ U#Q\ϫUcn)Zum GԿˊ?b~U?Wi!/gf4%{%"͆0382i6t6ۆL2%˔,SL2%˔,SL2%)9MiJN9c`JBi@ Ȏ?N0ׯkg jT 4=$ >K!{ nܦpg}|W5:V[3g_5$VNY0YdHXE _ɧ3Ȯ/VVOG_y|s%j p/G05n_ЮQn\U>4ak0!\:$;Y`x@LX>8qVK_:Z[zKueEж b]Y,ShJ#Җim 1YU]K-ݪΘ>|, 5TShy7)fy~jԎԭKH);AK(C@15[2Wg ቄBD cW:aHeuQ7 Z}S _O̽MS[!@\gFy·t}v#;s|b:{UT~| nwX?R~U}' K4+,iVXҬYaYa+Ag#F 4:S2M4%ӔLS2M4%ӔLS2M4%)O~JS<.a?%)O~JSrÔ0%)9LaJSrÔS2O<%S2O<%S2Oɳdzdzygo]X E[%IKb9" *y qvK.^!?(lghN=ǤeqE f!!~#z ܐ :\tCmDmxNkY.HQ^[V[T{ ]FJg*"b,hw n`nhy ]bV6atbo֑9jT VozvnaXy)*H/JpJޮb bOvs}bw}jAG Y):)FDŽt0._ctVGmq葷^`Ls>8U>Kpw4wiBm57.uS; o(ܶ޻J[q}poSLxݽS roӘ.1D~!^ z蚢[y%Nm+pTQ P$we%0% $7(3C.~k~7)àsQ֚E1M^Q^&=EmWG8h֞cLq97X_C gс[Y ~!>㺔+#93>vV0Oi_)yM Q&9fMV'DBP endstream endobj 2610 0 obj << /Length 1764 /Filter /FlateDecode >> stream xZYsH~ׯ`kRPMf*yЁl]lǎSZ @e@G'!냞f0waTuJiHWsn9#MQ8UH! "B?z{=?i ~|e?/|u>r$"YaX P"psd!J\oTs}xH5G4rI2!gJ8Q/+DT"*F74KY1 !6K@Z0Q!ٵ[7JivG |ùXi7\Q;wN{E>eV/D(x"^aqfK|A$N”0E"3oQ/Q*12&($D6}5+u uYgqX5~v;xq!BA$wv6%s31*dH!x(8) OTd5Q>,JClȎӏ/^K3!7owgyi ݻ8f;nxW-o$-@RU%Ω礲oN/cQC8sBRnHۨui৩ 'WOwuZvҜdꇱ0h;'ޓ槸7qZϮX&>qF9ME:teɬGf]: Zյ 0v:WnliĄDeU`zVe USYՈ(I:O~߿<] DߠqM9`;Aۑ')k'Uf4AGyva>p0򓻘۹!{`m 3*#/,>eq 2]k:8SbqxǷ6įG-T g_V)dSz2E ,+T&ͦ=<7% ߒG#H-"0 ɿDxOAD0KZtm)Ij?GW8tp}O{߽I#۬YzSB}L\^%b=eE7Xp wk6]Y5Dc\}:+Ti^rlnbe4Q+ڡ>N+n"fNJ:T&$u)*ӧ+J}m,HuwdbI طrm^.,K) ]AԵs'{| dTB)pWlw"zf 9uZLd-]#6*,hGT^HȨ3hT@ :P8`ʼGˬyCҎs>a,eFm8Q0Ư@.ТJc#T ޥʹJ%WjWZf=[iME=JdU4g+ϕ<@@}i=]6YB~m՛Y.`Z0Iu#Co~d?m39vsOh4+JM\-h]%X-:h9n> stream x\]\7r}ׯbc]NOLjqF#d~Oۚna3]ܪbS$is[>n> x#aclm7C( 1LQzm^0l>@b_ I7B$jVo٬P؈B56Q(%=聏F9= d7F[Evf/ Ef%˸Fa:Eޘ|Jj+-`׈yK>mp~K| _8kඒKaG3Fv n;<ɼ)dieS]Tp` 5#ٲdṖld2aa2g8#y6D0]hCa0yĄODw9-k|"@v#q|ψY ꃇ0Y1"qp`0,zrFz y"*'$F Zt81bp5130`mNߌ{viՀhzs1ӳ&!'g _ZR<l &)bb6WL/;jB'_qm?~wnڡ^on7~^yk~Oh-=UvD'nn>_B%hs:Lԑow{~K &ܷg폯^WʹkL؊ur*|j9URiyfV讗\.w;OnOqOle6=E)ipc8z8;H]r~01`@n9p|Bb =sTJ+wOunILԏJh.. _qWp<]M11p~GiL4K(&-KW@aWg]sL%@UMm@=БPFƼG \E~BvGrӣԓI@|  1qag9ɟ6z`J'L=d{J|M ^2zg$J(ArI%.HG #葡t.]^(Pg+PWf(HCrCD\g.WE34h9ezQ)vmJ]];wh|GQՓY9U84 O<@\JvutCLXr|?)C*s|̜ @!l:$LlK$Z^Z"Ln*!4?DjK(4/ pAboh>ӃzWQLr7~O,Li ӡDM-h2PC'I⃢;I1By&EbVA\M8& $ۜP_;ɠhؤg8o 7-~r8cr2™Zeۢyo}[F7zmo;BtF)/Dv /)M;Ɩ^9)LUI2b\!F؁Y:E>Z02s0HvՆZP@Ѕоy{Yqϭ!Ökx :O h?w}n7_|vuS\mc@Л۷wm>_F/T@ rNjSr##.opcg`ۏ7={ڏ 5kր ,eeZiYeeZiYeeZ,e9.qYr\e^yYe^!^!𲜖,e9-iYNrZӲ,˲,˲,˲,˲,˲,˲,˲,˲.˺,벬˲.˺,벬˲.˺,e9/yYr^,s nB 랁̸*`^X:bJJRTH%ijlR*r6-:-R?.[Fό?g]U%h!:W $$WPԂ~8NiDJq^FAϧ/.a=O8m?S4hXOJ%1& M.JR4?vL/˟ ʲ)+y= s4CZ!J|+G& 2$(S;^>uWeP9[ D$KaԎ59oQSv?pO%.xi,J0UjgL ɣSJm>y9$2 Zg\JiaAUKL,Hc5 Joz)' h$xXH+DOA+LĊaGPX'aB-"~>NjCm8λOAwܟ˒,Π|}F* dq24;gVېI{*)my 0QvܞcNҬ2ZI'p WWΐlgb<4qF;>oe 2?Y'I}jU[Hs>g+`ȱ`۬MqZsC8bzf½ ɦ W{Ђ9il[jov䮑ɞv( xC{lU A~2RiA: j 66[6mio1Jg>y%:5)!\|Ik5%$8@\RC5sGtI ӱ)kbZ-3g48czADŽW;Y@;-vMBq-6Μ;n{ȵlb>p.4b>SvWѾ{/Ǜ7ݾܕ޼zO䁗D#*[B,0&Mt `ev2\՞_@{W}?ܾ'E #6{N+<u CTsĽ+j9r tGҔˢ܏:`<#;Laϒ?hFNWbr>Ȧ=^u_⟾ wC,wwd tL134F(I+x6 'bl;Ì @BFItޝ9 G#5ߊOSWp!A3yFp~/]̅u$w$z(ESP 7%IF=@3DQ}{a&vP3,;O eIL#fp+%ktw!xD󾻝Sƿ;?|<͞ Ʂ.P9u6xt.'Ԉm4B0g=]Ko/9 &<֊ Rs^G%7f5\NŎ/xcUvH̕׀IO{,\" uR@TYP;~bߍ;a7z endstream endobj 2739 0 obj << /Length 2655 /Filter /FlateDecode >> stream x\[o۸~ϯУ m]8@ۅjimͯߡ$H[K";I&O~;?yvMbU'MQ*b,0t ǟP^<@˛u&5=yu~aKm"^|&3{&ND ]یY'-*Z1B7>]L݀V]?;⬙"dh; +,/Ia${~oJW)Sx/c'v؉i`$H" 3GOY" uȐ0^*F힗z^ j/n,ݚy^0id-lv1de-=uhhärZ X!q#0Ւx.4F=ƙQu۪?u;0KW V Dd GnfEX;(zn5ܚ ܈ ke TpGLſS!(9-.,‚naPش/3qר6S}˩i`d= vH{CGHSA,҄V[Ń#*:\ґZGW!H:n%B+,.|lT [MtE'zgZq(4IG RH 3юCnA{Xi4GH5q}uG b21CfVw0C' ) DE[$o](r9?.fChF4 -AefT?\Y2=A@5Aa>PbZγLΨt.NR**[@&"ܬr nD FJ#.5˦%Rcо%#u vWi6MODDZ+"ND Ę W"RD0iT;-EPthFyYx{_<^"C/ZMB0Ll'w@kʒmoO] W؇ zM W85y߸Qr.~{yg|8FpЕ 8# {U9/rΨWň&荬P &"/4 qf_z &G=_XL_LMϩfZhcjIm:~g I`)Ac` lQ/-:QǘX;@؆qDಀ6D^ k(M`q ahE5)yX?a(T[p va=H!g9+ܖt;f,á!Uqv_^@݆#A%bQa{ OtJ0H)T(dA_nx̒ .} iOKT<2[5vY{[ wŽO'jԷe/_IȦRHY lll+K P$dԠH^g$+|CL}g֬<xɍ%V'2a Jy"aZ/?ݱg'ఄ`[j ~1 BV~ItQ 4:[,! 7.Өk#SA*TR@ÞL,5ۣ<j})몪S9BoR`夝e%U!T"Hu~踥"5)9N))"\N444&j*\nDCwEʺT?lꢙH T5r$ƿɑGfFKu )H`"5QTAh,prٮfW-C*%1t=4b%!=N 'EvSKj} X1Ğ*A=ǨUH5 ŶaR4d|lkU kӑ+ly^i:;UMYJ2b$k`R `)ѥ{DB)t0? ffʬ ~ak/H;=jd/*5@|pd9ooXbඬ~̓܋ͪˋ\Mm_-n)ٓ-4;&2X@sL>z]*Է~x82..5Nӭ~bDp"B`&4{~vv=msyG 2mfO(X*}rQ׹aĚ.p|hawR $'TvyD3 {Dyr5G).SS=[cœx:]QzeG"=Yw &[\WL٥ ZNt.qk'\G\ G:_ endstream endobj 2626 0 obj << /Type /ObjStm /N 100 /First 1041 /Length 3869 /Filter /FlateDecode >> stream x\]7r}ׯ䥇ŪbN$d `1[69(]!-ŹXudOd[آbXTY_Y HFGP#ۨ["IQ"GF_#ڢ('rI},wsd۸ϛ&Dse>e)aemb-qB>GM)dKP~9G">K1,C0">'w^b6P|SN0(b8`q`J]2АN`٢ f]1S̆ r'uRgAː]1ÇM8b6;lĔ0JM[:A&Rrz&8  `T;F2_h@ |@_z GXJl;WRɅt'秘"lp%Cf^=S̖ߘH9^}_?/_z?ϟ~ǯF_Ë?z:p=C1,c>lvz}w?o/wu LRSg֚2в~^nBsĝH MҶrhʳi15qi>BiKw!Ҿ_HEZqk:Z3>&f8+B6!U잫R !KXt1)6$& 9PȄGx, e|62ia:h5Q'+v A-Ǖa=vzbl!ʮGnR6.u:{tef^bTx\e V }.\)qΑ[ô% fXKnS%֎ưKWZY2zj =N#ѣr)|P,x4+ˈ%;t ZPF]%;b+`[d}va/m֥F4URJcJڏP.LRv9{LGXPPj5-J+hK[oQF2G.εivttY+|"&*h1l=H](AjmS˓u|/*=zT5XOjG~r#Y42"R5ˑxj[QSGHQ*6Ql {X\_PC*z9P:-FQr4Dȵ-F> -AJԒ&##pb?%`*ˤjzTI9[We~B#?mworDJP6z_o>Vb鶇Q /^|}>EOܛO(Ѕ[59FI\Oo\xRg+TQΣЛfS]+wKy:q~I1ACŷ oTr}ryH U:q[qȋ(3io2[-PTcB6&JDӥ4qiq9u%n64l2qVivIt=MSů.Zىs)Z4hwߏz>&6nHf7? PFEAm$!~^%_dԤQߛcmr7iD97GVRƜR¹EUTS,;?N}~)kٻ}R34c+9/|⃤PW~ {|Z Zr% 8)i?Q=ғ3b^4WQA~\$o]óJq7]\PΙos?{&Lo$ܱk%҃BcAO>Ao"[;A|ۭZ<,n0՟ysiZ*z\Ч7?JVHT< NV+QA߹mF:V}*Kq;:BbA~:?I`,zjT 6xn%U*&%K*}{& 畮%^~U ϗ[wV,!6ܳXgEXE-SnpY97֝H-46YJo5!^:slUbk2$+x/]-T};fr勜W>c1?ϧve(X:tھl{VY1#X{=Ҕ^֣ݏ endstream endobj 2803 0 obj << /Length 1767 /Filter /FlateDecode >> stream xZ[SF~L_^R3!2aZ[I. g-B;@\sݕs`uygy|)s>rF)9ODۣsxإ؝Bsۙhөu vu~9pΐP 1WA9SCp;!̽q0b+@bKEp]!ZWSH (I4L(Xl7b<;Χ}{2=7ì$/[S:Hv$?6B+)ntEI|@'5SCkpޠs@Tթ3| |Tkš i ۣGsG(R꿀cyO)|D<x%% _]*$ E<haB\տ= &dYt%ՃfClM$U:l2)nCŃ\</iYkN1< [01+ٕrhvfWBSծ{U>A[uw -+8Ƿ`z{ Y2o 5HgZ=M"<ٲպ{,\F%FDlR [lK%1D/*qR\ =EUjh^ _!O[qh%}onI 7$[XKǷdr%%魸Ta"iOfsqį ԳnE㢡[0[Je~dDb^43u pmtǩDT5R[>6XP2e: ʖK6 ܹY #NMnfGpݓC=@qe o3 ZwE(mB F%7ЭcC{(%DT=~ٸc52̨3= ;kS(^$zjD] ӓX.58+^TY!ԣ(Rl@hK%H,.+kvwn~Uն2&j%!e~~~_eZ"ٓBLKWp-p7),(l ΅n< 1p)xUg֥ʙqbNr*M܎D(+hR.(:6?<,Y7+T;+FvxFsZ\9@-kXI-~lhJdS#ތul*R1vbN8a#LgQZѴ(Q,uI7lfЎM ) $qWg:SZ"r2􋥮}a~N[SqGoޞ6Ba|D%c܀Ũ [ejaڡV=;=]J[ lN]0/׶*41&!?kISpcyuwSW^su,?g) endstream endobj 2753 0 obj << /Type /ObjStm /N 100 /First 1033 /Length 3357 /Filter /FlateDecode >> stream x\]䶱}_EbU,pr0b?$1 C(H^5ޅ;=2bPţb} MaĉRO, 47t^hz#O]&"K޲8( Z4Q&g_3bPCA-tG)yYF?tG)6qC8ݡEʼn~!gLl⢂NB&VDxLx&濥0eDҐBqR&O*ť&qI'-4Sx"O4yLx¦$O0c&1 RLyV-%L9bC3Z{lR6c䩤ɦkq ?&jb >u8-OrYh\5]!@0 8B6u/VyU}3-] V=CVD i+:7<vKYh_< @9*+Œu臤-)ڂ؅yV[l-ՍVL 1!)?tq\9`_^nI[XC<tܖ8?$qR)j7ܦr"K'V=7x]V:eA2LY[Gבmk.+,쬔sKfܻ!5Yr*ص@y-[뉢fjC4…ȔĨHqBd籠n+%<+)^n@"ЏjY$,VVc%ȔUGZ9/YhūXuE@D= '@oc!WbGuӫpfQeqo pkx'>9y] _T\3S@Reӎd* xq_(0nVαƵ3ArS*td!>e9ƫzm%k`*K 26g?{޼#3߂C52K-v[3ja/Zۚ F>^&\fԋn{DDz'rKHA#_=u)EZrGVL |9tXVr#1G6me8qpx/?1tsr%yagse#{nis8QO8 ׅc'5Zɘ'59H0MH!vұ$T $FԸ4ղኔ2rCn#Ic'Տe߅ K1heQn) uXR7ݎ߇IY9)"p<^{8 ei1%hmKCV~qRFFV0^WV*~60[s7 Gc 9Pc:XC\BeMU!\AְYE?R9d .cYNefT [-2VN8JYh_pOi3cS9h{HZrn5^C+ymo$|J| pQI/HcS'^a % z鉧+;L@ӳо'psо"3 *ϙ j,R0X2Џ4v5ϵuE!_Z4V%5U8f1~ڗX(jf۪Ϲ4zڐB Z^_'Z13H Ov4gsb]̖ ^CE:> stream xڭr0y \B+X;X;*:TRn~V8cBr8@] p0f161`;2 urˤLWˇhtJd\g*T[29䄂J#0{7@ -jhکDXjJf!D3-oGO8Ban:6Š@Da|e&m&XCj+f'DJ!D!2]TeosDzkiRe%CDhݭw5 t x; ֏Lq؝uE)uȩb S;:P[Cpnhױ7gBZi/Ù޷^8 /M1LCŒ>:`D gLE-b1k½( DߩJVUb4l&>y*/\V&}ܤ3  ~ڔtG~8||5,[vSXb$6(,*G$M4 ;K^UP9@_ endstream endobj 2821 0 obj << /Length 791 /Filter /FlateDecode >> stream xV]o0}ϯ4i'vBhUCB h~؁O Al>{/ @HkZm`!c@ f@7W%rŠv)FeUpV8erg㲎J,fшoc`Zs{)bUs\A"ڨmC0h] wA\t 3 3 )"GFEtr(WtPw:uI̐-b k @ SaĹ"B:FUrut|Uŏ0Um p [*es/GwX,y+GR#`6ykRPqoaLq'[xPx s~hԠ8ޠr/}kԛ߆{ډ(2!s`p)k)~8п2y%ײw_J-# v^OjC4upL*uVx*Z^zA[G!3^1lo %Tբ:.ci$;L|\? ;|K9|k"+"/[o:fnHVUV~h(Gl˫Lm\0y/RRphWfQ޺sZO^{L Hi+ż{ rrp.='K,} endstream endobj 2827 0 obj << /Length 857 /Filter /FlateDecode >> stream xV]s8}L_}hݺvM۴]Z ^lo_ $Rgq3F{] 3:=:.K`#pl@A7/[@#ʸȫi]b;yIviЎt`> :tsxDwU0BQ1sAJ%k1Dhf#Ob<*Qc|N ]a @RHByHi.x՝BXa ISHD8DԪQ^z)8nrǕ|,ZEi.e̘*¤Ȉl_&5(/gmAнޤ?{l+/'(sP TkjtR(it%uVC SJ*vٮ4Nv@jgcU݌:L&^~S[%4]+(/Q0NZ>1a :n[mv];6M !K6O[u@Gr%Z ?nd1>xoNV=a1z5KPEON5MR.1jkYVb)E Hq!M, +;$ %|I3BDzÕP|#Ts8G8ih1Ek+]--;[FT*&qߪI_D埴ثOaݒ ը^^7sߜ_ߟM fx<1q?ʜkbeIjZV!}:O` #-3 '#} 2aZ-gȿ9ӫh6gՋ--+z$Oh`e*J*>Kĭ) endstream endobj 2832 0 obj << /Length 724 /Filter /FlateDecode >> stream xڵVkO0_iJ#~d߆hb⡈5nFSAٱ&,EUJk{5sۍހJ a9 %@r NٴCU'vf(;:QFU6UhLPDX~yX+RBI0]x$zn HC ~+ `,0`7`{A034-BcjN#i; /?Y XkSw}toرS[z@CD1 57}70?-l7^e2XC;v2q'ia2YS~tZ6[f]nwMlnɍO?Ჰ-rfY%B-Z.SMc2/w4=Y78]bL'Tw0S<]V9wu0_UeL.콥in>/L endstream endobj 2836 0 obj << /Length 587 /Filter /FlateDecode >> stream xڥn0y K86[B.5!ԦB,!)R[ $!Ktw~,V+Su]"6cKncL,Ι\"erMֱ\liITh4Sf"`S0h,5 %2^vJB5 33!4E1B}8JZ2 892 2J"^&5IT](0$OUex n 4ۭg7&H.XD6G6˯U{ɪDUh!©zԶ ~V:ZJ_f} wsImwNqjRjq ܁ 8@K;BgxoƮIBbzhPMj} {}י N%\P-#~ EŦ8՛x4*A3\6r"ZyTgҐK*J.ETD:ε,ˎUS1gTSBˢrL*Wqol? e JN endstream endobj 2808 0 obj << /Type /ObjStm /N 100 /First 946 /Length 1831 /Filter /FlateDecode >> stream xYMoϯ1pX~@IX}ج`==2ɯϫȫ g=~S]Uz,HH!K P[ k9X́ \'BA$!Do+QlHR0#B8Pb  e %T APNJ( Dj.@"n ,'+g7"-.`e.B.*0hq K볯ZsK¾Rx'_:Q(08`ExZ(BK.EPӒ+6u4?'9 Dv.2,n@%_YqV ;duŁDŽG\$A2/"_U`Bہ}1Y%R+P ީT6 "*A@TX'T8TnA[$frm 7A*'`/HJu ‹Hrao~Gi <Ѣ9TH]XnjRMM0WjòbT由EE-"kN} m^l Jᇰ?bu"?|ճX)<KVE굂9GB>,QT#N3\s>^\_݆/eI_]p({N0POɟHh's$҂'Mw߃1oǗm W/ᓝ~Ƌ~ ^w7o-ӻ_¥ iA(q~)w2,f-_ 7ۗw]}fo?nog(d@% @Pj$FP4p_/{2lp:`'_޿{3(φCtIej<3Z#abBkQ7o`Oa3Zƹ~nܦ< rBPޗI0sƴ+4>fhdN@ OQ1e9A ^r ޥZkl >{بW87˦v:/64+-uԹ$iX1$iJ>5 _+=>,,jD™adrОdwye"øOTgNYҐGK8u_'|\j5̩,!"hFg͸%SFqy,\Z> 0r;L ;Ё hp\ЭyLlON8 N(U>[N0}`toG}`( }ZL G`%I ;hj\c>+e_`'-rs6й<_"99WX|pT?.~ 5RVV]>tQP:K>'-~ 3d`vN;)ʾsl;mSv8PՆyEhiWqm=]+gVxD~|=J|ιAG{+^ho|x>8[VOF{K endstream endobj 2841 0 obj << /Length 685 /Filter /FlateDecode >> stream xڵ[o0goY6UH몈'DM_?C i)Rl |_pfrƀ&aDf;{LFAvGuf/1w2v%Fd$PBwUV0-N9P0Z7D)@msX<9SbTŠo]Z4 tU--!R?a}sػU.#ma- m%c(~q yc^Kꐕ !ͩ1J/5ey`.#Q&"3ֆ%z"BII ;A?|]蕂 #L}ܳ|d)륤W- XCDr I"3kK$H^1- 714n< lhɦ:1H|FkgAÑH,̪T(z?=OgP__/d endstream endobj 2847 0 obj << /Length 723 /Filter /FlateDecode >> stream xڭQo0{V%!Jk+D t뷟IUfK[(],&D PT0wi)ِ [ZlC2-yR&uN*hJN(=I hY0Hr]h[w;3U묿t-A%Tt|gsa[iBg4[&|zڽ%mBQ`cU}I*+XDٛkFE}L*D6כGWbͻWޙi^nHٓfٳ V4hʣy*6> Z΃b3Y8c,XcECP; %"3ӒyDv`e ,i\żjV7oWÑ7H>0zp˾"pD>t_})z0/3~â*>l2dS&M+* u.liCX!RQYkYJbg|@0.?A[?M&B%fq/zo:,㎗Ss ͉(3-=NZxk h{ߝ <=g9l:-3ݕ YY1>v1[hu6;l۱K0ٝ/WzATd ̀c֪BzI ΧtMn_#R endstream endobj 2853 0 obj << /Length 656 /Filter /FlateDecode >> stream xڭ]o0+,Mi1c70HK[B4UQnԲ1ݯ8@hh騸H8NtX Pr$P$łdF lQpOtfw (V.#깞w $3rT$ΣCY: CRĬ LO⁁ vb 0 R%kZ\'ˋ8I/_:qFY.шE+ $C,DNg& b QH0B`5׋yڃ®|\@*Z.2)td> sp2ZRaQfْ 4KkƧX^)F5|d" U!_)G&Y ԃ+tH׾sJm $R`et۞8> stream xڭUn@}WlU)m)/@0%)!F i&e&Mă93sfYjE.d(G +%RŒp mx>b\wٮ|U}8{Z.Y>ӫV7~ZDD]leMo9҈~e7W gzڂ%`*e1U gI0i'QQ{Ѡ1%E { HP}˵vWn@IQ5W#aV$ǔqs+ \aIԐ)x&Yo8Da iҼoF= Mͣ_͓?Ήsչ_g{xa~rD: UV*+Tߺq^ÐdIu %%)5CB'DOY1Cu?~NͬFWb']-ɭ?hn*Ѡ\TbR<<+Fkg!zTtAOOgQYWf.ft7=-QE?AE8QpN`pkԭ+*j#8|(fs2Yy||J*Pz^˸4\׽<)c!$sbxoC~1a`?,zoK endstream endobj 2875 0 obj << /Length 709 /Filter /FlateDecode >> stream xڽV[o0~WXK򀱝vzYĨR/B14$m NSDrb|;A` 8lFpO09R D n- $[I: &X~DS2fLzrdcdɹLҾ'u1G[qGjr9iX͝_N)0WM@ظj2Mb/E1Dq!B@u.b,$+V`4K,GIQcwC\Lu[<4 a~"~N~0+K maCiҫ|\&?VUV;O&vD xM ///z g6Z&Z1nu g ~c-ƸjX!abi; g27VY6.ʑ8*"cj=IDs;}{n1i%:ּz˭ǙTLT lʴ$KkMFlt6W])y.mZ<t]ZT4y1_ W:5n AXv/(;U@&TVoR>_:a=]*)qs2sE$6]Hx4vqd? endstream endobj 2838 0 obj << /Type /ObjStm /N 100 /First 938 /Length 1876 /Filter /FlateDecode >> stream xY]o\}_K9!`Hl-i6!OLju̵lZއHs8U*.85NSt]TR-iʎD1%%[GPX I,0APT5Uh5:Ӭ5u1\zMiu1Dq e1&JFY k>K6R3fږ1!;̔uQ -ZBʢ  )g! p'&BkaO$!lj8!XIFP l SXdPAPMUҦR0w E"Y0P"|P#\e("D&"Bs RfN&' _bSŒ,24ť)..Gۣ"n9 b@rFT$#Pfrð&Dg& R ! hXLJK› ce"^V^ e|FStAq^6d4Y,.LE)\qۘNj 2] d*Vdq怉IMw* FcTI@)n^l_K ;׿w%x3$>|x'$ٛmTjlǒek8~L9x;yzww/^넂^'#V'2 j솋i.W›~{7m/tr\mMa6f  ?<Ә⵾z p9k4D_˚?,%@$WMTK5էddTiS͵ZO3jڦ:9NpHzQPՇ|*08b7znRml^(V(XDmXVEq#X?I8~V)s i4 %F+bflGMG50#aScE֢/O'0>4Ӵs~1MsggA9+M\,}l7mtU"TY#Pʅ5!쇄Ŀ D@sMuI4({>P&kp5I)|nʨj軛ݧ+=}MiO=p' ,}^ JD<:ؑaS)6#y fŹʓkhhlƥ|Gz|Gz|Gy9Eׇ4y.Kr{Ζf[mᇁ#n0q!RJϢX2 <!ԏ È4@X21re3p\V |1޾]ۗwWWgdpd}m- ~ڶAyiҀ Hh8Z#;+ؾ˃]?I_Mn?׉硂mõo'Ovs?Wri8XLci,!FU]%5bkbhNi&\gc".٤:W7:F7*^<~2X endstream endobj 2887 0 obj << /Length 787 /Filter /FlateDecode >> stream xWMo@Wі~%JCRPrCQNl6]ppQ*U9 /73:L# HaR"Q4"f1.x!U4I˸gi}yweFASԻh`"1;Lˡew^QЄmn_-=+~3oY중i6NiŽ e}+BB AՍ$AiQ{Ƭ>h&K_-lFdiኚx&7=]u:tԒNnZA ݤPIAR RHn$mͶxB fģ}h l lӋPr+B$~JI^Eizo᰸OQ> stream xr0<0S ]YIIVYqi?}9'B?g3 HrN@t s r 1btLyrޙ<7Azt=\Li2:1zhTAl&KQ) (Pv $?+oe&9uPWIc:yAc;Mor]{8=x(/Cb qvhx •~BJY-t};:YaF8Jo1:Cs.0P1 Y+7?71i6,=c2dr $, !¼]S_EV>琚BMI>+I/uMAN?K;uIێS <*Q^C,ɟ\fHMluQ{`׃f%* (҆`H5Y6&" ٨j͛{EaPr#M{;TK( + 1!j|Pv(HQ=Y ȷd4HױS=aApp{7_g_A{[ Yj 烈oA b/W{g6-3U%H,{z+,~LqOF}Fe<M6} 24=0vg4ߡtî,#z?r']:J endstream endobj 2914 0 obj << /Length 640 /Filter /FlateDecode >> stream xOO@{z{ 8AEqHSIADҠ"oޟE6`NIpБ9H|cì`8K:]'gL% 7;(օGnM9UipJd|9pBttޱ1SZV#v\XDVgpi$(>edȦOEuugZ3Š6Č`E^!Zfsq|9=6nlHvl'A}ߺ*(Y9xkKj@)Y+A]!ʪJˇ9EƀaE:ɧpgMQ7Y5şa.ivM;MUZ0[%RQڰOؐF?4_$QYx^AFԕ[i.gXD̥=dZY{Pe ąbgDʸhP(ݗVTII Sm*eQըQcj$J՚Nc Uʩߗshu6?)5V#S'Y7e{5>,6"àPLg endstream endobj 2934 0 obj << /Length 643 /Filter /FlateDecode >> stream xݗMo@{2Ǵ(اQ$p j¯; U+3zJ&5r]a@)A1RD#QL浸64yUlOzLw:Ǝ=F]zw}R X32{|'KJV0'ӿ$ƹ BAެ_1?36#s" \fQR N\ apR>{vٱjL;'bćcj)N4L@2W>nϯgW3R(L2Mn'- endstream endobj 2877 0 obj << /Type /ObjStm /N 100 /First 993 /Length 2079 /Filter /FlateDecode >> stream xZn$}W1~.,€/PbkĻXs,h6 ާ8VV͑hے!#H 9 !% zPcE[CJ.JQZh5BM?^JJ=5\'kII02}v5_>s۲`xz(Z=6_%!+OH1ٻ-57"1)Jך/%dҵs:j]ۻq9׳g߆Xk .%*"quϯξq"!&fD68s@jq-6<{pVR9EEh|FAUBw6 =/~y;pcW7^ ?[8C/eY垔WoyN`_]]}uz= 4 4 < qh\G7~o^}?gwכ{^-nK>5"LP [,bȈmĊW=Ha]@ps{}˯͛`Xzyy$aLj^GPa1=ؿy{Y~2 y]mmeە.A*KZ嵴9:"h\cE`՘PL,4/N Ekg-jc=4nU]i톶fIp;l[!moڡj;-٢ob5J~ܷ 6Yfl٦ƶB()-6ѠsZD-*X-3F)7PtKuXfZ6]lۺYմm:rBLQMQkVRZTҏzwZtëe^C.$eXgU&Ydx@ͷul$oQתm^mkҚ"a݈37C8e~@ lNsI&$>$0 [}7fL9OjSc;66LNOOӌM4Ʊ/*j4c)1'#gS=o hKC&UF0r6r6r66jcOI7%p7PJ&U|&U+mce4|EiӬXe"%ȥ9fhtRj%Tq$)z$' Yk4CrRp˱9NfJO);=S"9ݵ'PƟR16TL{έX+IhLKiƌ2QM4LDc,4i>oB9 H ߓ(cs$/`%aul i#w4.'ΩIKz#{^Pk>.}Q >9LKpN>Պ1I4cJ{j4[dӌR#4с&>ȇp័¸HhlEc+[؊GZ#Vgawn@yH+M,y-oWMYmu,UZaSahvllnب N o$ i,5 X>2p\qQXp>3ߨ\es2yJ!oU;5 IDǛ$!<3IfPA%innS9$a?K('uKe9?v'ųQ쿭;&lO)S CnjQrӌb2gCAd*ӌsShti< -:X'D48h쿊6 ?)O4D4(DLU%k endstream endobj 2943 0 obj << /Length 503 /Filter /FlateDecode >> stream xݕMO@sz&jH DQ [(j֮>j`sZ-$ZHD+ 4t6@ҖGU2q:/Y+K<# .s褆u0$pFGmx48$VCǜa(PpQ,(|xN>ͷ[<ɿYɃ!DM7ۘ}B#@gt#u~]N'40-+/2'C4KFw( \N B7U|n\e=I/8Mʙª裑/<]~zdpyڀdm£1:{ՃR>]f{'m'Wѹ^|sysX@ט5\!BOs>1>Hz1Z&=e×ciZ}OC_ך-JUm;8/ ?_G§-GŸOʐa^  endstream endobj 3029 0 obj << /Length 1112 /Filter /FlateDecode >> stream xݙ[sH@8E./3&څ?u?u>O2^[\ 5xto['guu{0ז'PAa@ qK`\۶ќ#g*Hypu}ɝAX/m~{A'A Ъ=!)MT쑎:yVV4jvNvc8Gi:ߴhNi:3"ie2()* En"hR53πsVK2i$^ nGŘ0Q$neUȥ`UL)\*%C ~  DUk< I#AiRל.a5X[B7ZtMf^~t[%Cn LRn6E7^ ϪZ+[ tRpf\6SA3rPT` Py^thǦ h+cOD쾿 G1ИzT{HN[Ip:ʁбy t("Eجǯ1f;F؋/!g̷V_Gt6"HOW_E ֫pU[Oyڻnx"(^9|ٿ lmkڨg >ЖSx#; endstream endobj 2937 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 3028 /Filter /FlateDecode >> stream x[ێ}߯ceX$ N$a! Csg)vC/ZNS<] :&EmIOj$ࢧH]Z |>I;Ilh$Y4ɨY*3KqKi*œ2cSAX,j%Iel$X4*$N^3\I7ܒUdgxKuO6c>dCHpLN5I&WM}C*h-y0GoW#JFMMB(O[Syhj|li}(DC)/W=A#7bhk]Rɵ^SK'n50̡ݦnHMz8kw~l4VLl74AD?,A&<3 n T" *VпRb*s)`+PB:XY.UҨvA͂ +,"`.AwibS)ˠ @H ,4^HWhYC8 Z=Z 1P+TAQZ#^T(8ν8FPH)>pYi +NSrpz8m\=yruËɓt9[ ''P?~ \>A\P}n:NO}>:=8}{g_f:]]yͫvÏisA3wz"t;/@ŕteqe-d-]{o1߽'ί&|[0i~M &j >*]tYÿOOj~>;^n?RBeiT܊8} ~{;ݪ՛b܊^˝` ^g5yMVn[8ݝϣ"VZvX֢}X&KF@kόf>Jk-Z~~ܴ;*Nr:=ކB`l5Us@_-J.7s7;݄IԸ9ә%ϰ|(MdmԶo;77GHf0~mlKﷹM#~f䜙m6 $3㗉8ȿ2[Vv+Ax] ] [Ee_}QE-mQnr[ۢ(E-mQE9XcQE9XcQE9(E/}Qr_(Ey,cQXǢ<(Ey,ByV Ym-b-Z,ʲ(ˢ,,ʲ(ˢ,,ʲ(ˢ\(E.uQg+8 JuAQ_/aҎoAT|.~r63٘(=z  ëTn0:KT`/d~0T*lÏR2<'C QWu؈i /GY(0 [I-Vb+i3Cm&0-F}Ao܅ Bl龞hMO 0]*H;v Bi"Ƣc4OSpA)Ge$2n՟U$6B,U7YĜ{ꀻpڞ ' 7wD%n0gՏ1_4;"۟e0LlS!p/" t{gl([64yY7J. f sqimQx# EX3Bq `?wQS]"m`cA ~ SllY3yO]\ZAyŽּoWN m B3nQOTzc> stream xYvH}+Q֚- UQp1N~ 0iM`79g) ޹@Z$8`P@hYlxX=p `_7iɑeQ,-qfnN $ !\y((Pa5XCO%5 sӓ+*`7.1nRww$kd& 8aEuwΖIm4&K"KG0A-Pg$Tkv~JlEe=sj )IfS]!C?W:I-/E?fK\x7d6Oh#3Z|=Bpt$7=r5j83Å^#*_̛8tv{ttMor:묣9CEY9\+/wy?2GnREJ47S ( HK R5/q3o^MqL?}{YPg^CPK endstream endobj 3158 0 obj << /Length 977 /Filter /FlateDecode >> stream xYs:ȣl| eBI^:;\ Z6v}<sZ4u-@]]\t}Ss @oU'Jt~m[ӵ_7< |U ~Sy 'gY~l\*ؿ(<54Ek3 ݯ_:-Ͽ>lxWL̮:kT{ᵸP~L+RUmHA%QNx=t~ty|I]95 l9[MMzW;~UϸS?D endstream endobj 3031 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2362 /Filter /FlateDecode >> stream x[ˎ WhltE$`p 3^$1p<`A`9TAR5Anۭ::*ZRIT$T 4 _d.6i拫$]DKHL D:5 #Q7Gl0%&v 4.'@_wJ5/(դ IRjJ,kI98IV %]dPK5Ym[d%MdZmS4R#s^RiDIuΩ9J zu(iR/cRiPbeL䑺:+NG!!i9bZ֧A0;UcjvIſ F̮s*@V[Z-t5ת~kakaDuAC XQaK"sc~3W%~+@ua7k؍k7pxbwMc7@r7@ٯ"*Lg.ߤ8]/n~lO?L3?Y}z,] |9'o>}z.~<]^>(/=~wx;w=~xݓm͟_KzMP{ p0ˇG|ruNkE!HºC % !%%%%%%%5555555555----------[ @nr -[ @r={ @Of~B.?>N#+.K.IFvgմ!(VlX!ߧ_<&\ SZwF$8|@}M$7 a7%ap[\TFds$$ †N"Q-w؂LO$=قvCֲ+>ѽ°)T68(ݐCQeuEpˍH44t+ؼ܌6H471׃&J縉Є&e$ehK3alŨ $X.hiΤFF]U"P63'ny92D$YMpAACynnHirCEkq ͑%]x$igЧ*esP!$D57${aAdK Zxaj%WW:!Q8|H,6(~smEWݡ V^zM0/q0FHtˏe&AGph5{MpN|i{f NtrOIY\H튝.ᙜ= Ϩ[.{ܞqJ=AUDM8-6>us'eT+ IDeǹ WҼF9J  >IlŭCHހP4oBQ$!IhdM7+d@=N'(AjJn$II+ N&D_Cq2,WSd_R$Ps5Q;^&g*!^5W'Dkq?ٶ#jQMI'o0­7B2| IPcWO\Hq4qLnȩv)q ߊz O}bCo@QNgkՑӯ0Fu?25pzzi#^xU>UW#^x ?>PC4 Cd d d d d d d d d d ddddddYEd5cb$bj@ZJ^m[m~oHo/zC+7r Ab ސ@b $v{CGXzC+a7t w{CGx v{Cv>z􆢑!'CKkhUnkÈPo A5rm 8,nkKkh%:D~kKkh%:ZI춆 VHDk(H췆 V{~5rm Abi $v[Cф5(EN  Ev8 v;CGX:C+$fgheGGa>b|7$ٛmԩy:b/b endstream endobj 3264 0 obj << /Length 1248 /Filter /FlateDecode >> stream xŚr8y _B3bODȒR1L-$O20I )>w%QRN7-ٲcY"ۖ%MT KwMGi}_%CdW؃ōčJ+m˶fH7EJ;{'0u\j\7}Mھ&GE[lD]0 0˒쯥ZIiHwZnυɪj|DIL<^RUK!I&$ ^D:Dgu3Npu_ 8Hbt\}Ar ܫ^Z?7ÿ n$_udG(Nsh7XK0eL1DU<1>d7OTvݞ 0'\Gf}g8D}0Lz ưS&}ZnFsv.ŰZƼ^L| Ų $YѾv%ԊTrk4qBUe)%<µ9DE^2M,'c`Ű$d+ss(0rMY1bK$#~ĜY6[%&[be]H X7`w$4 CBSf ;=!-& BP#Jb?[9 ^ &',G ͹ 3=Lg.YȵOHl(pCa᫤6urYu> =%̉($ه-O'.[P w}-7,TNa[#ٺƸ\s:ߙ8@ث&ݝ>=\sg#KdQeGauQ8I+#h\Yqkp˗ [a N85^̽Eчj\ )QUd4|ݔu~ŏMzGs:I[9kѮ7|ARoSv&>5T'Ɉf9TM1n OQ "=ͭ3-#lK Jv4}Xn&-e+|VکpE~0ex:nFbx?\ {W\7̈́Y]iڟٖMFp<>4?9˜}) *a$/g4X9OZt>ex:ϔ#ϛ5d~*!yTd7O y.>t)ϔaqOhX?ɱGq̶lk"l dm8iȦiW٢ĥN>gtE_뽭غ,|J%I endstream endobj 3160 0 obj << /Type /ObjStm /N 100 /First 1020 /Length 2856 /Filter /FlateDecode >> stream xڽ[ˎ\Wpld*ۂ Z$PA`Ę19.Yڋ+ {}xnVSIL5,ZI25i\HQdSizHɕZa倔ο\c%>5U;iKu:QTTYI$',I{$ W(J/#~h[-zc2{*7$t}V M]O9:$d+K}BLFQF5$Vg*4nijy}1m='Áp5Al±fD5(xKޒn-d=yid#9+KBtG%Cvo2%c4О)԰:Bmp9ԥq1,Ow(Tl^KXR;REE?PҸT%OU ZR[%Ե̾>}şǠP?ԱGI̡,>К6(JPDs'hbz W $gu5~"fIԒ׍{I<=HY&c@6@!b-1H>a/q0qPfq1A򊺗Jy' DA%O( 2wnPJHkU< 9) ͐\DYY2[s&8xfHsAiW򍗥n:^Xeɀ-:X G !'PdHAJg6q@;Y;ݶ}&qtf!jw^*\J-$+'w0{)dAMWx7߃b<,]^>~.woxoWý{\~|/iɣϞ3po8K!uSs[H,Z,4>:vwz|Nk5Jqh5=ۮ)jzr>Ba7=OBW72]_)RVs"o> stream xŚ]s:3'>}IIΤ9=ӴQEC`P wW }4]`:Cw <;Lp߿g4O9 ,)Zjo<=h}]dYһi@d,[YX &/=-jbrnP/C,Se5/ࠧ{Oa-5_lI.*ܯW=pn5K V^uS 0Z[!bEQE<%bFc`% әc ahOZDm)ڤшG8kxE:jFXD(SaDl$3GM I*?PܚHr&!ej%j":QbF׸LRl̛㽟q܅*mEڑ*0"AGs ;=sٰp'1ES;x;VW,nu_T=nÖUvkI (JE!t\Up*HKc(uY f':TYD.\>"g`vs| io šgгwL쉌Ie3asAqdMI![QEs9_5$W2U5i QJ]JUO endstream endobj 3266 0 obj << /Type /ObjStm /N 100 /First 1017 /Length 2506 /Filter /FlateDecode >> stream xڽ[ˎWpoxYE@0`[P I$<34)ޮdӭE$fL&[XJ*IX(U'$0'4UcjjMhDO4rj$wZe̵9 Du8Dj"Ek1s\Ouu渑r8ZQ)q7u ;3*=T2GP79CT }^ ,dk8 6T&U`@1k=U*.fp@ H;SkqRmBXs燅MvMf<'Ag8#f\H1d%JyL?% DV HIp^=Q(# {Q= gi^A)<+P'ܼEc(9T@X9VdWO+:N{͏2xן?tyU)}]Oxoϟw(a~˯|#MyQgkgqg0qr?EώÚ  K!Ah5Dpg -8[plقg GpyGpyGp go-AHD у 3g )8SpL3g 98sp3g98Kp,Yg 1N\Qvm3jG1) mdTaMauN %T#Iڑoab;jod0mґYG'Dޥ _= րhrg [\(W&py<ās 4[oDŽyh;_+?Qo Y4 V4۵}NRb{'Aa6&bXa1,-hvv{|1hEh+/#5y~k$oD& Alw:َC4C d,*@Tg͐StOXz|+/) bi d哮MC+gZr Ȥ:inOn0v|7 {M[D-v|r K/0e6ܔ[G/05M aqRjwKo-z|6c4>nvCwr<=Ҏǀߍ"0xo[׵ҏǠ*d Wc }a)xW 1ϯv+^9zn}@حxx˳^ū77T?%ob=RZj^!O {Ox\WYM{VsKb{r6H+y}3գ2 f~NTD]_֌Lsurj0DH2rʿ=+c礨[_?B.'N0ղoZ}OkfpyBWo ;I$y /ԫg-> stream xZ]6}ϯ1Hʇc;3ͪv7QUu`4`ɬp{}m0fjWq\5<m"-<@ gV4`#l;uS@'S o4pn,۰L0ODq ʩϣ g6z kы0/4&µF.(+"}m88I0!Zwy/^q6*Zgs>㪡ky\'b\.E6!W_L𓈏r φy~-iQxsNrIq&In02݁s#p<_NrVRy'&N:j([B\_lzWȦ H,"M2{@E8!'ow$}Sk,LӦ3D)9Ÿc`,kRƼhZz ,z|7ܛ ?ppz{.R@pJ8D:.Ɨoz+G6e"+*S$M4T"I%b2DVt͛ 6UjSF_/Q5p'NXp4uלӼȚmt8]YiNNHVBNsl8;l2ѐg[#S1Rs oU#~\TO)D㈣\'UttE&#NxYK(#r9G"g@@pT4]28WB cr~Z2FBpΉ|W!~顎"Ql~].d,,7T6tln격3)I >v@'ɫ0%7_C3.֑4#ےHK HFYP_5{eFpTBbxjіtlW!'X@àZܨ32xI|]^S6xq-^L õǼEu!B-hNh=5\_yF?3 endstream endobj 3438 0 obj << /Length 341 /Filter /FlateDecode >> stream xڕQO0)qM\mk_$`D`dlm[7 Kw͟B.BMRDRpD)LϢi[0w "KR`Z 4QH]mFæ,@H'&V0AcDO)$4NZ1BPI4:ܴ*c<L}jOz>3p >g0ݩm0^ly͢v+8;-^Ra2(*ٞ- [^W칵Ul=[RCO3q"> stream x[߫ }%K aaBHv6{)K%9qR5 I3W>,KG֪?I4Ou "9faR9y^{VK󓞤u$O2,LkIcz*HjfyIq$I[o&0&;&K1u'ǜ^<,uJZp^aG$+L&yQa, k's@-c.ԒusDO6\2JrUkq n}jPkc{)yж8AaHaB|p]+_t^SqZ+m`iqfSkX@͇RSkCR/SkCS _-e`p{"Z:{S^O}LF B@(FFUH0n(' ֬XFF9/xZ"BKJQRjR0tj`tR3Q ! s- +e, ii%E6 S`S&Td4Ş 9d|b5yik\R(īCgju<Ѕ Ȝʸ{?ݧ˗o<?_w~P^]xoe<>} ȕjr1Ya%#}>}5,&E.kXo"@d yo3Nъ|&?}x~ }؇u}:aۇ/1]}4]^>~,w!w<||w?}}zgz%M}nÓ>-0wXFišA65hkaθ A][%ٗd_}I%9XcI%9XcI%9Xےܖ$%-mInKr[ےܖ$%/}IKr_ܗ$%y,cIKXǒ<$%y,&655k`kkk֠,K,ɲ$˒,K,ɲ$˒,K,ɺ$뒬K.ɺ$뒬K^%:ǽwI $op7fkoP \C La@(#*‹^It̲jߥ'sg*jzDWW+`$|ZHH7zcr11, Т"z][!0rd̆+M 00%)9 jF&M6Ӊ ZF? !"|$< &{RLZ q!K=H#`!"\vwbwRwmFͬJ`3=0pN˶OtXhxM8-3S!$+Gso *"tdȜi{"I,KfGD挟ktv8b: x$xI `4[mv{ jz6Y>0``/&0ԙS$KfepXM&U,* zѲk7ngI/v}<^u=lY Gܶ&8,GrgǮyK?!39G~Ao* e 7YĂ~Px+Qk/ ;6Dy=.A1.gESALB,g9j z4?PKM dμ&YXҟu^+[J6W2q& &[5cH.`0ۭuK Sw$0CzjYH = gB` cݸZwA, o¶i`f~3||\E2R=.1Z=:XgͶ$x{쩁D4tZރ5lЈ .eap/ .IW48~z>84D_N! NWS'A e6 VѰth)t\6E@Θ@Eĵ\vaeA6m L ,=8"_P & ׾kl,a!x(4 3dSȨ };% 7,$M Xe*$8[aYZ'unl"h"9h74 kyT[f1&np8ABKc{boP3҄f6DZ+ /xD fyT[ىcFMǬ{ۥ q^]!7aKOqٞ|p65 ,MQㆡ_oa GgJ'{.>Gp}kr#M D%+2 v\;IQ#'lS©I(1a7 cDl1nQE7} ~#l\5o Aasƹ>js,O>^?Aqڦoۼ*B\k M=\(^-`0$cGG!>;>1O00 mb`7= Monu#Տ|V1`VE.xť lpOMy1LLݶ)+S~zoDjgkL~߀w+cC7!ÿx endstream endobj 3454 0 obj << /Length1 1416 /Length2 6052 /Length3 0 /Length 7019 /Filter /FlateDecode >> stream xڍwT6҄RE:QCH* $$ IU*H* H)*J/_PϽ_VJޙyfϳΛwv05$Iuu5 $, 89XW~) #RPF XOuW XK@@!Ho -Tx큺@-$p*#Qhߏ@n(,))~W:P C!.sïP8 2NX,JJPS@x=X'! C{# n? 8Np AÀx+ C`)04:HS!~u~l,W?_(醂 GWza! C< pWuPMOg>  Ga1Ōe۬WFX ?8ﻷuA =>[pP& $ą%D0w $x7 +pgA!Q@0? @<`@,?`0`pnoh 0{$_G,htO)ߟTRBz}B $"?]Op@/]ߨ{C? O]L/R42;R{+!npW??ښ#]D[ORؤwY8)}EW&Ң^YC"i!ɮxEtOnAKіzeZ T }3]QZVsbUXTD.W<3c3NVaӾ8;J\SQhB͌oF-ZhzU2mq߷kJ YWkqq4R Ȟl-28A9VRW[)a=A^ދ@=aGI`&t0@H߽.m:(PnT-7E੡pD/]O+SeIaݤe}J'?~iW'F(.6FU1R"H& s殰#3N5vVssJ,=.obH\zя N*ܲn{Y6!l:;^򵖯U`A%HvMYZ!N1vy:<mA-@I߫ ĽiNF !OHѠG7& @7t}g ajS%'$yg*=ƺݱKh"P (.mВ̜ F.Q~1G!TN^Dz;|Ш9`2Vp0;X^fQͺJ,gPջ7MfoHۋ<7.tAw;3!͇~<wx`l޳[c'iyMlq 5'Bgt+o-_p|n^N>vj8cgآ -ִ&h^ce`>x/8/ :e4x;6xدfu$2Tp<LV9Yߺe1JIvsȂx`^i3e7 h jg'zH֞*E`׺6 p{# mud+pai@&EV [[eU`W盟^7Q&C,lQR }2G|PSMJ"1nl}@@sP!+(/s.{ɚCC{rO:&|;u]~ %nTR_[#{&fcZI?2`X@hE)!gœ'{1=^4h92oeùakz;4veP,1̜;+f:<&.,=XipՄ=XeVAS@Υfx3(H~!M5f<2>;¥ܒGكr ѽ+oFK$׹gzAЃAgz9q:qOzMR+3a,}3.IOOL"LV$2D}׊Xaʌk +JfJRoV $Ѽ1K(j 0(MHA}!PWHCCx.%*o׻zo^F҈,x7sLi31@B,q3iU44yg-e uix8[~<+Jt^^Mff4#[ΦV'@mWj ИNOPnHԅ ÁS3qzџᷙ?yjbCsW>r{Srר{W|۬3[eCb-c{w;fZ|`dNCA&G}sJ> nkZ TDwR^|a>R|btD+DF38=hIR0e;іIͷ/k/FyO$U R&:)+5Q l,qG؂UMI|; dSQQo3m_\Rwߩzg%SrܤT˪Euk{aS3drEyg{صʲj!\a#1,εk]j$An3& Oq5#B藷ʋ QݢT^:*o"v3$D}rZRNy4ȫȚ<y9X=GVIĶj񌟨޵@ܫXt9 (Gs BȸRJ{\9Cb +m a779^$w{R)?K˦ݓlnQ s6~h-}}u@] &8Xơ@|(&AhoKjt3-l1NWcj >Z@]*Շdaav[Qww:BOi753{ӈѯ,_?zsHXlF@/rx*t|DžiPb;2jJr*8UeYvKqс8GЯsHT+Nh Eȫp[g.Q-MN\k׃B ̶K Q7Ӑ :T+C,J\[_L&ҡ#L+!ȗvfD+~Jj{E]p ,s=pPjBEsP*UC6uwpf\c'~nfY?tp[_\Ni'Q&"HLE뷨9'Ku[K6>ka 񽭥e[/=ڢϨ brgYVEJ0RVB!]jt4gw vo7{dBgN]NW|IGCyo{JsRGZl4K>Fl2| J4r3Y|춄Okw0Ĭߟm~]JlAj$VDbRt)?Ww|ܔvYHIVcML>'4 rvXQn{3j9Ax0 ^iJ`cŋ2 gKVY3!wog9 }DQ美-{5N@겹eա*T^h`']mk,cag䕩 M&. Dq7oB}[百^͍lxzܩ"PIdJƺgforדm3^9ZtHQ?<ơ{52qK$I_a+|SzR*tseWʑibcz[=Hhh%ʏ*dgq#)tYeBVmz0l$P Q8uL5ԶwegUV33jv"іB&P­<)u"%C(R%Hv#xQ+,GWU ]]|;҆ш! z?kMn`ZIFJzgЫBi(s;K;e5#zmI21ښKX#"r*M֬; #w4k^Y m ,r's֞=Sw.yqj]cAti{ŖbFKo~ɲk)+n|NT'mY?*z!b Ƣc_- ] KbfR:;I&*2<)[Vߒ_~O(4#!ØcMSw; C^DPշvS !I<*퐄K?QrVn%R.C8LbqTFhWh5G[%(n@ta'iv)`u$F@clEUoW_?=$% !lOA bG((wy4m dv K5.ES1)]P+ކ2l^Y?Շ*5}Aw+y?L'Ku2R]:C VQqՌT~?/6dmɿ\DnwXGy];p RE*j!9;a2O+ͣD.`1aE/%T8x֘:ο0Y)T|L~@Rt|dۆl#/` aqFz\_K_g~uPԑ9n^|:6lU־Ș6{GǪ1mtNQ?!E g^ؗQ>L<{N_Ed&svXHI'jgҟѐ:G'2E0}1t;h#o ~峊ƻ5_+w: <* k?_.P60FPfkq+:v8&R;#X R*+ ]'Qו e\ouF<.lrN[D/6 XKaQ_]Ȓpq@@uUk#$Մ`XcKptzy錔 AIBζt36 |E[ϝ>v圱5GD-?\Tu Z$"qr,8jLŅK;J2prݷ\s~ a~Ѳ$:cNLJ juxL> ͋y->jŁync>yRXPHid{G %źQxz qKʽwǟ;V>|Fz`Ga\xmI6.rv kz7ٌ(I(^ endstream endobj 3456 0 obj << /Length1 1397 /Length2 5932 /Length3 0 /Length 6894 /Filter /FlateDecode >> stream xڍtT.)"]21Cwt0 0 14 ݂"HwJH4"H{׺wZ|{gww?d瑳E$PT@ ?hG9 F0w8! 0 S8M$ `q t(BM^ * ]}(1zC9`119; A4!( D(a(`t@\y!.Hw{in7Ѓyܽ`_ .?p?~}p( DmWXn`^U B./a;(78{ /bP@wEyz  HA?E; v_?uB  ;8|'LU/"DED07+wˍ  C / ߁Z`0El`p0?6zp=07 4lgHW@ߘ#}<`"VсvO* tug1-$0HnA7ݐ0}ФDDPcjl.UEABCأ =>0[8 2 Gt_t_1NBPˆ>P/  _і-7|$ @CZv@",'POwwtn_o`>0(*XrZ%Gͳ6*vj3gUZNʜS/Q+[:kɻ2}ZP+xà͞&qs2'q#FqB^ {el{l53ެdE"ja-ZmUEtbF;+z&~5c*_cͣR^2K$yW[_ V Yg G(I) U-]fzmoT^l#(q-x'(re=nDLϡuĮֺ׾V/3 RajIؗ}`'PDWSJ0\?Gŏ_ޞf3g,$Xn!^c5a}nV8>sY~tk[J@N(KE@' CаaH\M͙<[VqdM|bb:Yz wTZ.Z,W2쥽|l!k'Y3Qٝy~ch[q}dftLQ^X헟clρ]ywƊa2 =C0 /~`L*>OCG @1)E2|H [DAG/OcbWTTJ;r`6~V`dF1] ilB W5Y",NJ,k -+1OZ|K{-V7Cbؗ6~L*EY%aź^;J{R;!*: )1BtƜC`~t@"EU7˼[Nks3+0TTjOݏ3Gn}ڄԫjٯ-7tJGŨ_a.2};`bz 9 qZk-\$J>pY}0>x/%>9Nb( m9׷2^̉嚑`\d HH.jMC"2 ōnj9r&t[6.'_0šb$jfuȄUj4\>2²uQ0+|elk ΄j]F^y[ĸ&m`:yҜi6|Qx]g:2NF Ux=Recrug!jY`6즈ؾ:5$ɴy`xvm;Zm|Z'vnӇHe |Zd_xK8e߾?iKrf/>/HE~z٣{i#?41m+VםFSS~aWeJ»X?s'ى +l$Y(H(-?Zc|5YYLu5˿?o'ɩRu6Va3xgqH?6{E"S/[~yj_P;eY%\[=KM%8.3LSr#lzֻ`/2l2 \H#765$?0rdZ8+@_>Rhbȭ xdyψ{4ǹތ֭,Jo*W\@w'FYD19Ɯ8bTu*E0=vF5|<񁗤XE%K~zqCe%{پX'& Q|, NTwĔF{rkK!_"ڃD &]dsK#P7w& J}$|M6ʜ`o?dڦY-J$r~0D@!Lf'yܦ 1{4j:)گY﷌mn|>cRzHˑ-jbټmg$nUWaӛ:3Ͻs"M!AV٧K@t\ÞpApMKˇH <}!P}nHTf-{ͤ{ē:8hFXG$RB-RuP,KCCJ־0:ަy9fEPG d}"hSgL=o"wUA:d0xUU<BB  5_'h+=)M,0OOϭek U U}y,@aɯOk]L֒dD)s*)icTY7!ǭ~BcGJ>4Ha9fOKQsj͚Q qV|}Z`JA~2(i ʱ9RYy!z41.fuhgMz̹k;@ld)Ys+=ɴO_c0dn3ѹpcsGc^Ly{;? L8j?p R VsF,'%j3yfh91 MՑ@6j V]J?!.^I3fF7(•ULmD('Aғpd`(\~rPm7˷^rX~m̓သb3>wKd6bf(k#N_ю27l{\b*Ύl,/iTs4̴뉏 ^UyR5o~ҥUHh0J]Uj@K+oGKBU-K~m$P,WE,'j`~ygF*dJ':Yg]z.xYzcdW75 ߺSJI7}&p<c =! O]Q^ܬ{%I4S|m*}cABk.)-A`M3:'@>g6nc52(yகCǢC5AajD{3 ΀%Չ ԺVs7a4$:8#pRKV!?c'~9i!TJ~az|-kuϬ7q'b_o2(}Oo Y(dLgҍ[ڌRq%Y4}Xd( \ ȎtNS-d77i]"m~qLY(ʠY} ) ћ2d5׫;촶vkR% hܠIXcUaX-BHQ[/W@b0+: ُ|9OX"O4fՋu CU߀A%7'զ]фQ/-k~m˜yv?0iVqo A_nj?-M$|^)kojWhe˧@RS0oOYF=]'/2N΁zK|2z k\W5V=Uw+z &FP,S ׁ}pCL"(jrd×[ilE~(Gx< \pV[pTLumZIɥsU_b$\7͞VTykTFrbA =>T(fpr!ws?`"\8t sذ EBFs ,[>9H䆰_ZY2[ȷ^M4cZ[8>=+fxƳN׫+;ko)|?#:'j{ ۼi$5筩'sSB6f\1L~DFkPrm>UT4):DCun+I6ul> T[Cۣk +g2sLMao[$dcfֳSlٵomX'4@NP)n޵!$IW";t3JW`FsۜLTgiܫQd½_uH t~-## b*tL`\/.M|R?FkpP=I~HHg[0/H$bƹ||Sgߵ܆G%*6pL4$r9a X bmAh"af#9Iy?HhJBċLYk'%:O_Ļ2%C:8)$5[>u܂̜-:KV+H7IWoe+C׹_2ӯ7# XG%:TM)9LVX*Zi3c==/@Z\|M픻MexXo{\*ZPet?}ĕaPKu& !E#xj';c2de ז&w2x68{=ȹL@9mqc&nnt6OKyA46d9e#RR,X܃;'ro[F>AhJ}4C_ssL)^Ac2SXcd̙[xbO4[M;&OJAEfoIG?hU.~J9*~YHx_[7tB}Oe.;CY2uo&w?ܥ n~O޽u]hlj$b/BׇaZAG0{GaibY+Ko'̬( kRi)z[ʄQˎy{,`FsM\-Е5޻m..|Jj㹬Tg{#T=)ʗҴX/ i{3~38nfΪcS'S~:u[ ֺB|NR\Xt4Xe1NWh5^N K2v_X?5V UJHsei1“/Hg`M4L [~VMT O;#QDfSʎ/v8 @ʢG6v \3[ٕ7/Jf%}P2OsHo~NSpRo4ۏe& _)WҒa!A<.E2Rbon}X4W\dNuv#VoͳvaXD t;1Ӑod59-X}o?\- endstream endobj 3458 0 obj << /Length1 1388 /Length2 5940 /Length3 0 /Length 6894 /Filter /FlateDecode >> stream xڍtTT.H(R*JJKjfZK@R@ A)NAiEEcssZYk~ygۣ*h"0XX "eg7B`nRvFI/XN4<DIBH,/ CPz!m@cHnG',Ϳ^.7;w{ `P :]qaP$`!Xvb$ 7:p nZЁl&@9!0h7H 2ȿU ЮnP/8 p@WEK(_@(C$=9Py ܰ kE_epWDQX p}ܬ k8 Pt4F!=J!8|p, #,. IWy#_7 A p-@8qzxw)#`X@: wc.~~B~մL-xlDwp/,E\u;\ G[8[E0)7bDsa+c'm4NVnt:S<f~XQAX1_\_1`.G?!(6keqz(Dԗw8KjMm@PRڃ5A䯆8/?*<=p&3)7UhD4봴Ֆhb0l}ek&3o51l%2&C'USw bO|zJ!U!i?ef,HN)מ`4,+g$6qc9fjNCysJ,J|ܿF'69A ۘwrnP <)ĉǷxPO6xS@2:7b0ќ_C8(ix_PuAfKVgIw Y6O+&itzLrMD&\pq%'qgn~+YZ;*&W3]18,8zz9NC5Wχf+Jy;dY26fXon($tءƥ;C4a|sg7DB!<٠QnGU1w|#:9I6?Lxk코NeKlQ3O),-NCvX&>|u']f' >_ V躶`'P  8eÁn_{Hõ2uDnGdY-Cy OnFrڂjBtLs01ZOcʘI-uGTm5( g^ hӿӂ10A;_ŝ1D~I7 8S &7lQz{4uL" ߮-;5rBӳӘfyPͰ4gpasbv|JHCq xl,\fKۀڥi{Oz:AzXByЬMWB'}7Oy̞ȞiZs h.5x)=i.}~ WwNu*ׅ w<4/RFGέ (j&-$v#Ǫӈۚo+9Nl4YlYFj]TomT$]WZAI6޵,W>\=!"$'<[MPw}CE`7qvwbjۏs۟>rkxx4O}в 6N^8%R1: L⠴6M9a_hN{3,$Rwsʼ[l'q-ķSZ*?iQPWT{;^|8{-@B^@x°P"p tdVMtzW9' g3WۈX(> ͡q_T 1}hTK`{Ȉ齧n0H[9e6cN3zO&?0`d#z*cʁ+y;qI9߉}#]NZ.&\|}|a .M2f_H|G\)p%4W |XBL i39tQB[}7X6i5o0?8|}oh6 VY#aNtmוqL;T{9DOzQ7#~Y޲+&=WyJ&9Zk$YIn}kMݟoGo on4豴 # `vVqnr'MNemi5@4<}.WI2?do<AHf-#'3y|\ ώOsNIGtQ}74,rAP'[nS ytOeURC_\obj‹Y}`dQ2#ǧ9Q K5E6n\2|h\DXiKs+~(YvTU'KՏap%&HMn1zS+HY1?nQT$yzu3GA{d%E L17oߚn;w~W '*#6z%1}Z\(qW, mG ׊,xr~Zqvi߼Q`ӳHދ"K |jݱ/漬ٮI`c:vt{tLGk#r^-=qln,U4ӱ4z!YGq%@IGY'!F́"O' c)ɝs#[|¼ySƊr]+g(0=K30ǐKK5GC#7nlA8T.ԹB7߬lv1Ol+lj2G_~:bFx=tWRnquj<_C$?jkP5^jT!J?UFF)^ !Mdl`r+bȮZtnF>= x7{y~\nhj1{sa/lԤZX.07.ԭZC} + y~o-gݑwbKEO>>s+eǨ[ʫ?SOSBhgt3*xTLR^U[pwg(*P$[f6ѳUhn_7J C`ontEBbJՋc"l4sc?A~chU~diZObN@4ϰjH#P]ۑa<&Uw AǼkw6eQ#JժR¹7~X8}>1ᡘ3)jl :V1@rbռ}H6Ysv <8󭜛4f«@Eu q/VTԌp\xwc{>9lK SlnbV͔e7v[cٴ3E#fV6'z;~ +}\H'׮ )q[Q^zەi ג2=cK)U0KN%$"o>nٰgUh 44 R&hSxLRhZ_J^f!)NWƚ PX}]#q-qn;D!rػ2r]7<"W*{c_T8֢[oftU~Ȁ(/ne<T>i"HObŎ쨵X(N79OyM1/% γ> 7C*M`|CL=@UN?w5>ΌTdi`Y6~p0Md,9bމ3JeS]ewB)FDLJfTNvk=:*ǯ5]ߟdDt2 m=)S M263uFֆ(s:/o(^^stj!_7cL[i۵BCj4@[DiW&t.WA~_ݗe'(ڒeCg J̿ݣy)DGD|ަ%%O #ГA1vdfeSD7T؜qvjLYYV'={N>@pq!w.Uw*)Bٝt'zȕw.-,u#z厝Pif6OJ+4*x^-Yǜ3DL"LmDB5+٦AQxQ!߮@ ]?4g EvCF/aC>\lH 9S֣CЌ) 6]AaPF< X>/t{zKxsT뛎iwbNoV=:BcMEtS6ѵPڶ0^X5"r*zKc)stЩUL̵r!1u~>#kxMQҊWĨKFGdKDI~ǪpNe U}96m=Z Bws̹ǀ4Rv!N@Y-a)謆@$~Rw76=ȳ <`vv΅%d^Sf %wW~_o bs `k¯B!\wEZc ;}PjũGjg;wWQ?,O03ʉFWNGƂRヲ.3GinFac=ݺUD`*5^Łm<3D*_`$ΘoLZᮠ^J>/#)@h8TŸ>ڝ."%Y?X@^\R1Ip^}8`c"Yz'm:^&z%I 6=ÌTriqGY/Wl/WTHx!+]W*)ZVB٬_[e endstream endobj 3460 0 obj << /Length1 1423 /Length2 6229 /Length3 0 /Length 7207 /Filter /FlateDecode >> stream xڍxTS6"J5 &T.% Wޫ HR7 R._xZ߷~gw,zH;  %چ ٍ`h8o;! C"$16%0F"pHK! Po CHEȮt9:1} p@|PhNPW̎0`hzFI z{{ ]QHGn>7 0^P{:`WFN0_C` p@aB<Pfw@ p п @n`/ p]-F($&vy}P%(+ 昕HWW("U W0ï6=0wO Do# JPw$k#_7oo3@74|^PA = Aagǘ1,_YafD} =bA]M3}S?-˩ I%Ā$3UG8 9K?3\(DB0C,%W s`W\O4FH 5%]m=h0F G A"@0 jCCb_v_zP=$ ˇAah*# H_b=_<|VRP8/vlwψ ?Lg"ĵL1z e!p3wa?6ga[C?$4R7~ ?W舣a5܁ "ZHJ:*? A:\(,3ŊDVH[3EIžM:!u6{6 E{Vm6s iIq`S`:<0j ͵ [sa$; $d& ?ᙂmtAROGysg*)7=QGHL!f{}I/Eޒ(56 3Az]Rr &¤FFZ[X:%#gH(]>W0=_}*"v?hy膒~Ymo7<5 ,lt85"īm#A68<uL!=alb 1~o'gږZݰ kx 9AMuX㴅gԡ\Jd3zI{s!BBxF;C($H} bdSBɡp.DSg%R謗=e[=Ơ$Tw/=wt#??۲2ugP nŋ6Y-;l!/2O-2S>Һڰj]ZTK'LQ rvwx#/.Mu2d+d&`~HȄUI0H Y%KiD oX PZE0 uwp!.Yf\cdPɪ5r-,\Rwh:Ev܋߷|5 a19)u3ZF9siׯ`*p> d5Su%ĊmTa&ȆedٞԻR#d6ʪV}kN˦28ePDHG2#g×?H3KBA%~g]ِ彘MYj>9;o8l9^1 ,ZWHٝ |5rT<]Y|>\ |?A/Ff4*9c@r;8{=O.oxH q,X/_/l ȶ:ݖ#>8CS2Ē~F{ؔ6H$qXoNd8o;x-U`=,BKOӤ&E44Hq;NJ[UϱSUee /fٮO{2RbeηCK9{?v36dZf[xGK:QkqEWErIj:6GKmӓ|̯sߴ6ڣq׶r @ k܉ɳ aP1z3j\J0󰈾s&W* w\{W f'ɀWXq;0̛ :m5ᅾy) K^w)y%0*7A߾XI؛9cC/D\A#wt>o/ȷj&K تl5Z^ t`0[(9Y)2i (ӛVyH'yoZ"<5F?5[s,eˉZT5AtÛ5םhxWu%Qj\)B/)ZPPڅuB -NPc}2{dZXk" 릠;ٺ?]"c(IHoৌ5:QGaÅWm7$n4V\ C?jKόYd9ȐU\t5>4\Ń/H CxEeG})FƧ[)VʰQ2 ن5s9-~Mo}Ory@֔$sy={DZ&1Np%ljةXKm+l뿄1o:gG%c %0N=ȨYPRU5>T}δv=eT/|Ƌba/̽~˔{LaJ߆&ժT_:НG#nO8H2I~ڒȖ[br{B+NvenF\Ov 1^6i[8gZ⾅|6qa֨#7+qYk|DcxZ V~mYz$zE Պqe@V=o&{SƱz!W?1gzDuzQ_ʘ7?2:p%W :K|^۔H$#R0:,JG䮵b 2zCIB7\ݎ?kD!C~O St+0>b;P.jIt&|l% YkC**|^qA$O!k{3g_bW+S"MQʼnAU}7g_ vqGqe^:?=9WeY^;!X:~{4e9.TH]}vR,7tV nyo[\|G iPwLƌk˰8'봉E.I7^xSwK;J:%}pd-.VQܴA͆E~/"Ce%rX3 &q^AH\q x:_qANMv~MRõ2$c)'f2~J:7:LOi̹dXl?s)@^`Ĩm'(y^Xu2$R?WN.}HE.FmD=sasqa٫=8^֒+⚦|;p ׯ})+nZFSF.6?fɓ{ojsI= q=ްN4>Csnltq~0r,H [!Jǝ?2pZ{^t{k֖}ɿC9WȁZi=uR⭞x|zhZrd|4\]{9a7p%}:,,;vc/}NI̛Cntu *rzhH vy0͍ Gl"Y˜mM ^͵犫u,P FzI4 Ǽy5Ə3U_豶kGFVuLwA)eU\ig0{lF)G|\qp_?KRo}$Pl|t\Ҵޮ66h`m>MGGMm 1TF+ t{hBY悞S#F\a`E##i[[̤]ܰ*+48;޳# _ zXL#P>Azj 6{vi.jϬ'<>&iJ'EEu71,ٺpɷb(ԥd X_hqΌ6%KO},*6#X-+]ɳbȚ Q_l/M:|`Q+{/P/C&>TtY:z,ғuAaZzWWG a*bu@-)^z8%Deq%4u P. KzP;(2%M=ܠa֌v­."5NrX4l5?8TM! </!p=W־eG R%-KL"OolIS u!$B%teB\L/]J*:Gj9^|f*%y`\b^gy5O"L%CuK,͞ZWYHg >qkk`/d%^tͱ#~FQdd)剫"L9JװvLQ͋_*`["GpC']<۷w3^چKP |n.ڝkLﴉc[jw}z}fWX/.>r">NG\1vz1i /,r!}Tﱶ 0P8G!S ɋSatTs϶BֲO ,gb ).ԫ?R%?8Eբ|JholF-;p*j!6y'˕oeɐԂ"g\˺aw:J ]Up^e`,pǩo?$\Rn? 9.Yő[߾R %g*k^+zRW6|\;iIR O]L*-+979o*ȌE4Ky}gTkdyó: bDzf;?Y =B{Jz'xZP0gM|fǻZ7j^SxC"Y&.>(.G9o+RݠG{q o;֤^շusknx]~4jY.ws2w"y  ^vͰ7߷ꏐOk*})sT+g%W jR vprQo q;=7wbab :<@",;ܳY/uZt. {I}l܍'8VpLZ6naIg>Tzd7ͣE\SLxp S;SJ;BMd ޾:T1'=U}k[v/O gD:z?|/:,G~u c÷6iw6&BڴHJn* ȠɇbizE!PVn}Ӷa_Dxt @ZN!UW&(w)Rd5]9E Ħ ^f[Q:<[/S?ǚe?no<<rSZˡ)"Hi˻h*ĵ z̑J>OօC9CI )8%NoޏK Ctv۾>^\Bj$݈($7,F8U1ި%qh b#ml Z>HzimT۟l[l[Imm6Ϯ~/2]UϪwl)Ș+-"T&9>Z6YrofOTx^SC8`7  7sJ/@i˓}’8>F/VFHa5n _kf4R"gbZxӳeA֥z>Q1xvJkJe^菇<]u!Xύ7 -+]w|Tf){Ku JFjrpr)K2'b52^,Oݝ::N7X{)EW0atm׵J=EcқMxC+)!oH7?L>j5cy#I>j1?TG{lߛYF^?cK.'N` dcMK#~" (D endstream endobj 3462 0 obj << /Length1 1399 /Length2 6072 /Length3 0 /Length 7039 /Filter /FlateDecode >> stream xڍtT.(04Hwt8  1HIHH4" %݂19߹w{׬>}cc瑵AXCpO o"'bc3a"6C( /< F10 DjN$,@0&/@ #\0;{z8 Yg(`=#G@`P?JpHأP.@'/ٍ|zP7(j50@ 3/Gآvou#<0!l]0Ww_ "fEĄEPW bU;'uAlC@aP @!ݡ;APk Nhjg|$ `Ƈ7 lp'/TXD!< !G?DD,m?p[@OcWBU pG|B|-)77;;0'hQhh"67ǴPGUQ`dvh1y07%F/9P׷_1 ZCP}"3~!a{/$ id@S$ѯkYO'-W7 `7]!H$}Łn_VB/ȣ0*YO#x˭OLzP^kg*O=)3UyGvBJ CgU'[Ao7&t Q3F?E:6* Z6Lv΀d, 8eԠ9Y<,@V ,L9{,>cp~?'MzWpy%KPRubZwW) 芜#k@t|΀F!YXfRX]S0?{Ool#)`,p]2غzTѠ kN~ᝡNC[ZڗK .MQB 35$~QPܑtd)Shg3xZ @q( ٲեqP+nKu܃!KĜZ X*%9kKܷJ /5@G RQ"{r֭zXվ __)bSu։R =3D)K߯Mf~n*qiq]g~HRT?2S@]|MiCKm2D\(l>t) n:*o w@V9X]} ;ޑ*9!x%Uâۜ*秮tvG';êyY"4R@)%'2q[W,U5}sX1d!9ݔ3J4t3,յ^X1vEkH ,H뚫}mq5nȩVAfCC3MH߂-4Uc*nnaYoPD _~|g*#aQ~-djvYV{.Iǜ0/ܝTنeQ8=kG`rV˖8 4!D%a8ҟe {zópaϙt>> T_.YL.ha8#@GmgHsԨ'={,}Ep `$ 74LKM)^y*Ҡ(3{v]WuWߚK.HUVMIsix2Nϝ2!Uڂy}[;&4~%B~'#*BT@SXB֝ir7EvG~;#֘ޞG/7.>IBdPmGߋ_QHDca%zⅥ*Lv|9K9hr|B!D:驕[Bo"ܸq8 F{5ۊgCP @YC/9 fg"W3Mq x\ "nyyMRUqA ٴ?+~:}upzg |mxeXLXsv3;~Z+و' h^{7K8cij_]?.7 7RآNG˥&Z^;Y@'WOzf߯JWǃg9YMz#Gfyj,Cf ͝]y0%T;STq%?_v;@z氱p0 yʉ t>:JODǴTQ5v\6I3ZM杹[[bMIY&6_obLP#\s W~`dXShوY`g|WF饯y\ZabV~D\zZ,>(N?"x#y ό2j>4]NPc U[2&x@_Hs{!ۺ0lqkU+ԡnbJaJ5Fn 4hx4.nC*~ 0:""T(Ѣ̭"nBۀog9 gN4mh3Dq ^K?./pbn~L[!FК&9)&%*^ccaL O͛vܲ ų:we.<+5Zc rIYW+Gr_zHt6϶ ;RZx;&l0~Rӛm\SjnsȺY 4cLfg8׺d/y;aMKh72'ww] ͱWeu}uDf U˕_I=ɿ0CppŊL}bc:p;9i)y% N~QZ>ӻ1<]ӞmRO=艺r!GGb2Dq*;bγ"/p;puJM;3LHtmKiL,5ѧFmi7kEc{ں]SDU(d( J6|R}`T<Rl~)MO|?"j)sBUзYH1BQCӛj&ipBligBu8* x>/c.>⎍}L톱zdSÎqIkDJsۜ9pŎy["ɿ[zJ]:=+1E#XE줭E_bL\ jg_<[u8d5빌!1u xR<~#@xLWi{'ɘ[xڅeAđ :oBbT0=bxxZ~roDSV~5Ie&Wi3Ac5?050"Q)v,jF~+Q`mʲ@y*E.9NUz 3_W9p-_8Ý`plŕvmـЛ0l f'9cs$Ԭ]w q1c Գ!Q,닶߻Gk}KJ۠פZO !;N+ L9}ߎX*/ӱ61ec1&C#ɀBuRmGOKGŽal״4GF?eבC$=4 몋|)?fm;Xգ7{Xl3I+8cp*-{ TN䧟ԤdRAYH%H0Gė)CJ Wj.1ҨOQdk/޴݉ aU&p ÓzFW;^Wrh,bF lddR9.?sFr$bGYA3His䓠ޱd CNf( ظGT F Iq^23v8j-'xhHt\kO޳̜4>VYw~tHԊN mCU+x螦ȣ[jHGy@ৣNz{A"5+$xc+ ,wIP)؍s =34lYzFLÊ:Tyy:6;kgZyı [ȃl[./mZ:=5?-=Cpr ,_ وlObš;AA>t1ON/;5mu5إ CpcB-1k3v Uc,c;ID=S# Cv$/Jbu &k&wqGfsdҮ4F#7mH\SiķZYdl\WګRlwgR[cA_Saf=O=サvKn5`)rS-Ij38cE[`4&0BS ɊH,sA'jU&ZR"5gy}#&97P.buu'GZd!,wgh쫅SMoqh`&5յĨrxAQPe+!7=FnulڍB,tYOpP鶈0|=֯`#o9Y+c@*7DFm6, !]͉'SezX[G8{[(# f"K@T(w-oaY+2w^&KЩ8rP-*-:7~GlNT]j%xqSlK«ifG-gC~Hk)' #"F-ל q'o\'tJ3ݞnK]@SG=:)##PǢ]929> !UO;Ե?u")s\̜cVAt3OVir:[YFzHmxzB<:u/hO])= \:z(lKJNR;ߐGA<;ůlg҉m*é c :B3UfH]Q=GSc+%ScY|=oen^Y /- _Q: ݊&}yPqFk{jy3wl(hAU*6tK-ay)N'Ӗ{ݯ%VLS"H϶ci~L^KT%bP|x1Ǭ~A"F$eL!{"Gd]{n0J7HM8J-C9!Amiky&.$냻*LjcSdO^ҮyLT<0IF׊[%}> stream xڍuTo6-N et]: #6Ft " tHI -Hw<9{vOܟ،LT`(G& ej@0X X7_eGc(rPC!X PHPD (")+"% E`9в@u74uQH8C#kEddUh@pw܍PE~H+z  'A`&p  5 q 9#0pS= 7"08h4#8q P$t%B CP@:!@CM}+ a!n. AAq+5U\@,AjQWܔ505;~է@á ٬+ {@j!lDxzu 0'8(=p_f~F_0 x@@,  <DD0 t;!d{θ@[0{"@Ͽq􂡐n~q_amC:MU d$$""@))`?A'VyS-nL/x\Q8!X }SwῲHiz6f;^X P8 Gp:XN*H'DA`?8ÌXI 0_\_6&8N>W E~LTBA!~0N} f2PDaq!@\A{(4Zŀ g_߸X(A caQ Ʃ7Yp%[p/ 8EFW0-'-6ɺ'F=,YJ֘]XōtҨ@f!_й4X<m'-iX*=vjMD<-'#:V* /0+62@w`!%[3Jn:A5W;k;jmA"H%o6!ۜޞt|*Ɋ(FZ]܁>FG9u18O V?5}-.ڿj}0tFiX`y<;ސKeOkBj:UۢyUIrnc>*>,Ekw:` -~@$ڣ(/)LP!z0=/wX֘뢖7AX' tԥ^y]g](LBdd-r>ۆ9(+Cد}R9}B tzǶ*3\?jaj_䡵w {嚝|.YaOܳ$bc\( e0PJ GIHöT%['b?ʟy~e|pD=6MY=TN-ĭ+ ,>&-bˣcM $Ffpwl(*_x݁QH9 #薬dϬ+2Ժ-Xվ'A.:4(7Րioa'czB`##ZaV(pϖ1hv/|Bk:,_UJR& Cd+ƍn{{0$nPcyxX0(#0%·u 5WvNM$l>?8X=5gW{{6.Bi5O:S\R_vH"AGz"z.'+CP{*s,6-+/́⃆Z[Bm!-@n` }Ƭke +6#d"Gr⋡ <ޤf!yĪGKI1엧["7ʪ^fG94%ߞ.9Ok7|;f~vE@x(W5|gNEy4,#I# 8*2[v;y{i+7xG52NAWfQO;g2SOo1 HI0SJVrm9έ|ij<^c~I (U~(Z+prVOjSK~,A|6ZIbf1ʢ< at+ Wҟ6of><ʮ{HGUFq3oNn/c#LvF?@dԳ'I,)߾<{Bm6 ^.{g.Nn"qZT:,9SZ.=df 3?5{8C<\j0H5!sj"SQs -/_4lC|P'+NX+' MM=LB5Oő2g̀}-k䰹$1f9e0&5L')'UB[?*uh+lug?ŭ3> 9(K_#?r!xZj4Lcj '|>P, g<%Fo`:h%Ɣ1᳡G% bҠ Bn޴6!!PM5U _P@iq]/&yRFz55<hΟ;y#1LEkOD\a,N]OT >N[tB(6)|p J$̖_9c-o>! =I]Ȩ "nEehqq GJ (]ߦ "&zAFaœ@w5ﭩ> wST%!YDn>~ޱT\Poy7gYi%nʱOɵ'jz(S. IXY1їz"w\q4[`J*xe7l\b-fIZ+x},ז:+CzKP}}>`p y"?XH#l挻Qmc%<>9h!+ "?JiDŽOQs: `JTr?M"Yv?n)ӑVj5bbjOu ƋEhw,oYxJ~ax`{ih~j`fau;;p(eȮPmQ5a3d0BV>jyy3\_XPnG3/DɐRى&Ebp霥gɨ H>zpZ iZ`]by.%~D@)Uܻn}c䗟\8K5R0G7 Y7 _ŒpTWnafΧ/a6~یeKҸ{)9iy8*͒U-oȋ WFQoNkM=}&4UMIب>q`?zCovU#>Q(mzzA~q.#_]^b )Hiu]t=݇ySlNv]P?"BSxs.A:БJfֳEjš/VF(c_7}ևj7Wvv$ܗ= |#wu+\VVy`0VȶBE6xņr[k`); /%ѠifaJa{O_N8fԱӷ2%ʮ+{|}ˌXiyI'Mu%x}34b>x<*ڶ4KTUzk OjG; mL< [_w]ɒH<%2FPg ɚ,F{']ҝ|u-FϿʖ%2州: ), ɶT |D9jr2o\}9{2?Z*iʢĊ6^qdq&3bϒH#)\4ڂr?ۖ /Hˮ2$p(~HyM˦6v{FW)K@jj6`nQ {ST/1ڜq^<M'Z6fsu}R+*<vZU::迈6s7cr>3^3yHx_RdQo}?}ͮqY E*iƄyP4uu}w5(}t'h:=~sDtg8jMa•njz: ZKD(=wDsZՑm|8pYS,'=}\ת,Cܭ/Oؔ gO9/_Kx}$O}A> stream xڬct]-Ix;:cIxc۶m۶m۶n>3=Ϲ3Ƴj͚Uc}S7X[913rdL-ƎFV822A; 4 &82RYA?-]N{Sc+'%/FE `Zr2JQe( hgsԷ05HT#k;,VfOt1,MLvzV{` 02p4_lFXw73q*'$<Lmo 6ihmOI:Z. Mm,\ fcg/ G{S+d@ Z;Y'^F/@ #z8&9 66cgPĭLa7t>'ݿ gf3pdPߩL'-Ov -ha!gwaR =Wa Tq2+#=MEL]r&#=׮le0UfOֳ he__ *b4N7JJ6R  k;H7O&&Cas-`g[2#ӿ?WZFYQtг2;^ V RRDž4zms}*SB9t߫'9?[\Nm>%1-(9$T=m4~ EgWR[Uv ߡ&~\=Q8`> y$FkGA;=#?~z躁ǣɌ%J?ǞhM:#P2!hhC(!I5Kz#?%c[f5lk+i»JBz@L`!%{=Tݞ0(g^`ȝBt"<e:2nNșvoP2ONY;P)8j #4+ˌDސ'ױHBAi8 eaثᰮ-PW]&[6k@~L'ɬ<́WL_l^1v{]}F.A1ϲ8<Ė*VcK*~M闧ijXzb".} - :w܁jДOlRe_zs_6mk t"zorcbR,9gzX2gp9R As{PPRUcR'RȆJMw닆NqQ,i[J_T;6R@2YkqRR>4UIZK|amw18tNH(`Ktv+OYp`DPWc_('^BOej./V *=y i4ޒՏz;_'l:PG`gK'?f,|83fE)on2Q^Q4`|p b}5!klGe֦rل'~+4z^yȦ&M{V~ǬiI x'|yJw5a155qhRK[)+M\ʠ<o* pqYPp`)NE'6^H!iXX`=,>)7idؿv3ego67{f{O,ʬwt 3aX+ʫN<уX49l7pNow! P]A F}ʧΛ3ʑevV,D]x)bp D(ueQvLZx[`smP.&l*r꽭+6S^܎;(Ё}<ަ7pn:{4c4B^;x9#W"髑װ/qU k-HM^f4#K4X"܉Re{5Z&Lsb _}+PEH<}!=̱? AVL0JS/(|3рԷeZsEE/Vip4۴z2 Lo"_-ݮU J֙K0 mx3 6%uD ,cxfK P{*5Mco#04H$tNfr߽a0 G3ezOmbAj%Ʊ87IXkZsTұL^ۼۮ%룽J' ,w33N8DmORۼFN8*EvKsloK:MzZk i&E31iZkێZ9G b{Lc\_- yx\qz;-E@$r.]CNymJv,eΈt﴾T=JBA}NvBdbe͓#t'|//DfLZtںN#5L&}P7]^ _BLg'+zA;:-g- $4Bn*bA g $|إV9 ?֯"Un娨چ,jĘ$+@Ҫr}*+,m]2O/eP*V7 =z`_a#Ff H)2 tyR 8)Q~)Z9V\켻@B\qAL_kmmALc?tlL)$$F1ɻ5!|y*>ub Qo( D$ɶ L '"/ଟGA6R'}(27͚{D) S4Du #>^71s#7| Ehs8tp^ȄrmIY :*b$Z@+5w`W,j:d$/5>4|J >pI>Flw\./* s}ci3؂hV $ܬmC -'LL(')SbJV2|akg}y2ef<0i{p T2_ Q> 1iK?R|kn̵)i1(M ڎƶ%i9tP{s?l% 'x !"`=F 2M},o!LFoi)p-A+-#iAe]%el|~g@7)pV{7vɬ؍oN+ąɛZ*ɡ(vam]P㤸$]2#K}Is;@!N9Kwi@gھ"zy1SiB8#o~ ղrNFu1| sOW>mX[~ዹ @5MK&nQ2[_ݎG9GSOy?FsԖQ#EKOõ$vyh6gbgED%M,)LCo3p2 P \ghX4ݓe1ECHBeKq7 ?U3w9jyE}rbL+J1H;Q[|({N=띐oWJTV51mںh4̤4jx0z3.E#+8&P!V6FHnt!$AO@bsm ' N0Ej_w;L|/̇ʐ di Tcqٿdٳ`bi }xb}El#BnK8=SsRsjVY4%QU3o0f U2,rh=>c:F% uhyQqy&-"<9,"V*&xL 5iw .i3 7)Нq=B:cNGȊu[&c)ˣ--r:s8z0jr2yNUwgZS«t"ˊR2Nl8A9b\jϫ:VύW 5!S(M/ yXt1PfE\^\SY&`42F&vWjAd M!yH <-T3Np^k@KAq_Ye^Elʲmjf]nb极e~w&p=Œfu6AݤQT!9 ct;O^k%x؊s$‰]hM+(b($4ҞNKWG>OE?@[&I.ql{t,G˔W Y6'n߬"x̲*$)K+xر"[ \)GU=K1p:E!u]59;V ( a]Eއ,L2g x 3Dxx_!vRe[9v]q:pCBzR(10o2rc>}02fFTaoY n"( ȘѕU\ $ķM8o˄60Bԗj-i޾VXypϠoF Ul52$!)ө*By*:̵~iݢssZؚ//g98ɨ{*|}yh1;_/DN >,ֹr&uYSR"vM%YC4uCoWzy>عҿ<ׄ|0\irsI1|vUV]g7սKklяݥwŤ-ZSI;e$X jOؖi]ؿA2V2uh'Am@ڔ%}3wdm[6v˾4hfTfZ~Վv5]gep/x't?i_)! [& ť<{˧;ɟLokuz@ߌεxU+E5CWXsRDau^pqC!DGnޗəuCh rV`ԢŻ pHt^XY4C3/=2}7tǸ+DR G$7QHU*h쬭2rDEQߜ>SlkF%hfXdB옭l;ԫ{^ڐrUrwm*Û\w9b=#J}Er1}vA) vਧwC[wPz1EWDY|ƭj*}-6HDpw Q߿qRw.|?d H[y8lH٨2vQiVZ Qe36(0~ItAU?1"LAr{4ަj u~/%r וqxYDg||Af'S_&ٞ[:~B0jutA.tzAPXMOXىz7V9J/%F]b"jӍd %f5L [`Y ",.C.dR~e^{Nyf! P (cnSy8[R!} UPIJ,:6IJ;vV힑M| r V`f=(R5hqi4F,kNXg{vX`!Cv|*J}LF-@kјYz~Oy .Od}$wh͝H뒣 jёrl[6kM'u܅csᢔJcyjP?10ɡr<98$1v|z^=8xp;cLƶI詀 H|[V!^^Ԣ./Q%A|>k/ ˮjTo(p!I5^cA!7 mʚ~]ݰr\O)}{[- Lٗ>%PV gT-D *v[ݟCh&y=;!(}(qzjPI%3=\[?+{=_\<&S{J0Pj8# _> 0羬 yhS 6?:'M{-@ܧo~{ jX-PjEYI v#8 C;,4<`e=ƑْX/%w'E"f!;)X݉C H8I@M8XE%M?cKa(~O7k "n 6 ymb:k8ǰ@NwfZ{|&6Ngzy锤r2"pDa1#|!&ܧMdo D@3Ѳ> mD}ioQ2y[BFjD)R}`FT1O@(щ]9o[:co_#S5D_s%LLN[RR -}{S3*tc L쯾DWd̳Ap 4)s]-2  'My #fdaCSBaMJnˆkA'{;7U)t=TFOwYC+]({<(WwLkDhE($f#7Q6haG@\xm͖5l"ȷK_.wq8 p{h|'vNqnn8CR(2{$m4avstu0( a q\FsE(fmXHk7~Uq6fhc$SX.:/΄qI_v݈rҖ$s5C|u!9z>;^Dhn!Þ`a!u1TmJF1<`6Vy;fޥYOw! #WT^ۼUVh5e4X>9J(Ra7ӹMR2N`(Iy|7m&Hz[vb^!|쁫J-2HGx]yMјuFS2) &Ra9n-ԷMLV\pg$bjKzY_NagZGF]6Gjm}+#_yamjO6AT+( Xܯ`8ݵtU[[Chx$G >5+鿝u3椋];Y..7gOaQMa@EVI[>Fd{/ۈB7򥢘N>T̵XͲ>?nUt0bpz\&-3\>gU6e=O5;c`nYVڈV {GvL/sئ&㔀3ѬUKړ8vN=2k2"Yʵjb(rJŞcU65;]wt*-upJ. S%KsN@FIƹI-GyhXc$4Pt>9&W1oʬuJÊ7f>Ď9z42q#4ֵ2XryR+v6ڊy>sLSV[Y;r}Z}H}ȷx43JM WMk \nfnOu g~´N$~RGF0U t`|h]XS(X _i 1s'p6|Pjn`hdyl ̟0_W&Ŏ`ZzDNn4¹R=IC)'[Ia3}Ɣ`)uS.Kj~gnq qEo9Y h \a"d|c-~@?W{&ĞN@!\dwsY߈E!|bf[LWKI=ry+f)G97GR'=;$j.Bb[SU-Ȯt #_hBa[Ii$oxYK*^*6-0 M^2 \VdR!%hUQ;f!CGUHqu2 !==g84;qV*J}{`20Sj%&[ e+Q鍤V(J/8 w V 8k,~rɽD)>Rl> ulXF3$}d[wV/o?g׵Jnso[*RV:mmʪzg+` ћ"COE!4.xup\Rhamʵ}l&;I1qm뭶H!-d1.>hB#o69D4<)`1wAQZXuM)JAN_35'*B1-c?#lHk|bƐ$CeO$B֙~2'vČ^jOƫo!#lΰ#泔 VPp`&JK^k&؆ ɗ,;T,èyRl?BkW; /< DIđ焆n1bi!0B|F陲eeH{r-BA4KR)xT@}B Fnr+eWi+yڌ?Ah'n""I#tcǼ(89L(BQ_0CkےQA(g x~Pт΂Ts3op!Rq2.shROS;hv+NŠUL VaYkS);ڵ^EO;s}4}`o2I~5=! ?r}0ȧe\{ خHpaxy#UJó͠5[!v_Z:?p݊s"h3Iئɵas):6&,ٔTkō=(("CX\ՖTM֮SwxEuvk$6Th0-7!x~c_A}3i:{{gM#G-bJ)5xJ<ЎBH0R&Ғc{]9 umFH.2"Iޏ"R~϶h2 OjP d 4QW<. CDcѓdf(!ausPQ+ ׇ͒?{`c5md:RxЦ&P_Afq!O1 Pf)$QilH}u3/֗]xާVnPb;̈́glvt_!FEm!&/эQFbeɹt6)L06kn:be4> G@y$I bg>u/z=/#[.d %ruCG>'i:')=뚜blhΪX 0gKROHR3 3 d/ \Iٿ Xw0qdI>c)%*o9'v{AC!06SU[ƳNF6L;@պJVFLjY1c/MYl W~p.rn\tĠدTs"Z8h: 4CYXITSr@fcA%Qg|ˣ=p7 n(Mڹ#wI,1HKYf7r4WzfX *6Y@J}"#ήvg,)v2H|rPy}~L?oկ\NO}Z|t)MaʡC)*iաVɩ.pvP*i1Mb N>֛*AvpVh{Y+ !{; j(6NwƪF h ϱ64X/]u71RWc8G7 ۨ礍}Nxt4K :P5-yt joA}^ev9^CsS,v$_!xV=vSn1|߸kR5~EXA uPNoљiVP4+[j+BQO0*%Ďx#v_HgP_a# 7c<n/MìQ?V#uߘf\OPx uh$;NuzՒXK>?%WSS@K񸝧{} ,jC&1sdM5\vd4"X|x 5kۼGukv~!1<9ni~Xlxv_~R8E;ywPyp#6O!X5u[.7c ڕ*Ny68L:'mkH+!?KE vQ0.a~ɓNY@O ܤژ޿Ћ Thj2d\:NdKCc)ك2{uپ_Lh2E k ޝaAW&t+[˽:p +Ϩ^mo`J!zDTaYHAU9=#u˓4El>D3(dv"VqУd^j9)YC'E)3'QDM@"#I.\FgćyDsnTTq~D@7NTiƩN95H{J[mGO*-15ZG flQjw}39/aXF +k p>ٮK/ȵ,ÙfOYiun8u,nx.0WV04$hDpWQy= 9.즠8 A=hٟ[BITMTޚr|B[H6]/[բ1$nAX@=vW?})]}[y[ )>#96}InPcsr>A,ʘv~giA^*~oX9!YK%™iB> stream xڭTeX]ŝnMpCp'8Ah Hw $>ίN)9u/)P!P}0uSbUZ:ڂk4::)0 {c t7@3S@@ eYZAZ:L^`9?8m>@ ,@@,QVY MlNϭ@f@; `auۙ~a{撀L9 jt  ,&v@ ;3['<-=C30 xΪF:V&߹!g`oino?33 5AP+w.S q5q{L) W,0ln @iO_}G&nx`Czi}m Cc,vNN?b3LEٺ́hl9GKqU6=2WؚG' 3u7wU<EYVN.6 h Y,LlgǮegۂs0M+o^^\gבWT}^?ϛts;[{~HJڻ>?'׿_&P0` x_'ÿHۙٛ 6s5s@39{3@hQVN j/9e>ɡk˃jf6:mG^4L98+|ٍ 0Su"=",Bl_9Zї]ז|T' yhQT2dqL^xPhnaO$d(BŞfXbs"E A*.u_~5g) ;kD3jΜV/_S#L[zLY4S(-gnU O\r߮wtRQᷙ"iNyP#V R(xi=]PNخ/Sh[od#gӬKzyAn=u.< !&[jS7I&Ҕ;_3hVN* f}slc;~ÚvVmBp-90_ \R8Xq*43Z i1YQJ$GT[uSpS7!1ˎUX\ÎF1ݶC˽A@~ B6 nHoڽB;t Hm9Z2.!-f=NWR=h$[&0e#R?<h+BvЧI&(8OY-0\32xr QiᨭfJHVa皗q@xD{QReiaAHsŊTAsvր@ 'GQq\b-CAeHuJK*quuS-k₠F_`&G&k5|vMZ(ʒU{,Caǜ_w7Z|dN>-f`oVvu݄Uʱ毖]pih̒…&9ysF)_$*O;\WSX9Ba[4y<ރRnu:41haSiҩ ~]^Yp:q0"w֞ ;{Iwvf&<GETs DV8?E321^WKf-"Y;.rԳ@3̄Kѧ[0?)}+vz=ڟ. 42+E!vצ oP':{GxxP:j!vh#rCss0oL:rvW)BğX%KxSHQx}ʠZCQBӕIQ?'Y3tCXud}雽 ct+}RZNwRP …A1m8ƱzOlT鯭H!\Nȋ pwA, 뼂hsvBPO !Jj.o0ja0V,fT.D4J8:a!+.hS9D?u5/(#OK2s6s{)gOz5G޷X>+ٍ[%+-^28tC-T(16 t|wS7j5p&3#tOi2s%5!HYt^gnM+2O}$-O#8QyZ.?eڎЈ6rO|vބ^U*RHUq7V& z-hp,CdUIQ3[v)4?*&h mke>@iV 37_eSOMAj^v7R|h!B+g9Kߝ+=z-\2́=ni^:Q]zv%KMLLwJ|oe4W^ {Jzqa?vnkZr͕In}ɘ4tpe d0`ϩixq"A=p"(jarul1|.՚}e?r"t?G&}:bXbgct3O,T+}kNVUԱޓ\݈v4C˿%ib6l' "Ye([vNZ1 |s~1Ą"wݶv&ZH_Ocl>t K#윬iq,H>da\Z#TЭ%8c>ݑaH'xV6'y\(~Hi=Єx婲;U-=vh#UdM7Nƾ@n/4Ӈ'%4{ei4Ri\f] ,w~C]4g򯇉+6 s_l4ƪ!u'5ky:jsՍƸ7D7.S_+Yq^DVJA~c DU+POfQ1R5@ZR ɤ$堸iz۔#TG0ɥ> ?q( dBQ/S8ZCa$%Kgۋ 8c!Ɵ}l-\6n{' 2%/`Di> y[P'>ט9EWs/X.9W'ظgb^XFKG2Î ׋ 2:j*^b|NВ2{H~"3 f嫥*62ў.Z ;I[üLMm!\uK|5FpSZp] 'j^FJqo;J(VfccKJNXO$B(cT^_}IPSGo9@ ;Q)(jEJb > u&U+x^{"ZZL>.Tp]#|Zb|{~LdHJ>U)GZ)&N@~yt"BuAN{`̸'q¤\nڙHjNJ&W@a#m:5XX4h\()6 PJ<$Ğ*N &x *Q<. x#u?F.xD#.[3f)@%2=儨;V"e9քPzS:@q8"ѸFk{"VώxaWn"[T0D(>iP4wEoK IlT ߄=Jˇ\E/d2tXa7S2KF«?tZ%Yr2qKA* L>>}: GDW17' e8wmntMb)5F-5#vg?"i^DCzm08Z+ZkySY*_{uk#]gDȴTibh(2&t nƵ26L֓iEqWm Mt̥!w+X&YGx$OC)JB5ڌp O&ދSgKMɒXl  BV#.O]~tW_15^h)L;]nfvd Q2D\|#t!)S!l"p*i,6#u"^SP۝{+&T5OݜP5q|ynsW8Ie<9:nzT/Ip{ fMxczXeu'ٱA+[ RS<:)hW/6>%Ic%G*(>2W*`o0 4, aEH:B1;ۖybBN)KB/Dw!mDWמlRLxd? U/68|q5%%wuzYMKIQZju/?fKa/ɷb yBd]U!m{lј;U҄A絛NVfړG-Q׼z>7sSd#MS&=^ןr*k4EI^nI- '$e9G,L}?F* JƒT|O3!}b <S`S_yMDdP6Lz#x5uQKcy,izx9Hة Ǧ]/4샍Lx&PxBr}aSR'Fd~Pʼ?5*V$3'p#˿q)ܵ;V);u„X{;dz]땩J8uB&(^<2 |EA4, %ǵtd5yUػ]a#_]:Aw¿.O'MnDpʳ6ϲ<鬒-&-^iyYȚ;ué.͡QY03o9 cDB /!ғ=Vw)C"пdrŽJ̔#p/Ȳ+ܻYȕ^;p}3#<33R2;P$;V*m&K\ KddJ̌w$Qk0!f܄&`(xJSx|#9b07ؘ YVSGfNDC;4cq&`;RZ*j +}e ;_ H?XO_D[>t/)$ )ƤO'[cvv"[=![sIqe1X Pw=rb{-?k~m)QnzF\eG֧]E4'3.6QzBC._(78Ўzǝk݄HeMK QemCՎAۋBwVp_U>g-z}=l [XS:^~#:kZѕ79CwZ$)!NR;dqM Y,i;C, )gm=EZ/Q){7K| pW"V6 6֣5V @fa|孴>R TK1_Jl*?nϺ`衔q}dO1pj9ۻ ib5]F[ejBL_iຠ c1n1F/S&Eɕ!eY< MAUn,HQn -v |nKь";dnIJ@e+\#ZBΧ:k$zORrZ_!;vfW#2<"}sR k|ɛ4ZpyG"s5dq×E;BA**eKsK֝k3[iڎrcGHk.u+Pks 2ap(k%[1 <tHM$~QqT*|W|YLZJ!%hGwI[-<'{]Un:qT,4F57? F DжEeA>k?J J{~W^^@wpM^^VQRWG_q;jO D%,;ę g7$0OfiXfyleIr:T9k3wd =bҳ_uBF|Q`Ry ^NÌTK68i]dg/:u$|54no of`2"Ã>k=kD./kltvir3hx7çˤ[p=@Nؒ`{hbEqrӁ;U? ٿ  oć*7~/gK>#ײKyhBg))Wm%9͉dzœI.X-HϏUň 0!LJf&?-|:՞E)ߦ\<\爄ɭ+ZIk9Yp "!?t^5gꃻuke2JPs^MnWFf^ƦxS}fxz?s@->=??aA"ZYǘrmo* 3Z55ⶴSp=n).SĄEEj-K'lRD*sFaRXВ=,w @DLԗYE5 ϹN aEAn~q"~Ѯ)DxOpNXP7\a *:cF9۔ aQb+Y6M=.޿of/ ]t|mh~|jV񦸳FژGy{4ǧ0'֦Y풌ԎXEژZ{d=+BG)-o5v[j*L|7LX'Mꊥb(ۭmbBW2Mft'q&?HQfVQ\քas/)2Jj҆+g_s/-~PcGF*%F5{ȅY̧6|n 6DPr;I;< .CRY%MdF,ۿF]Y"FOk^\Ζj[➵a7~LOu,Uˑf=j&?Wl8s+:3fTL3zYnΐe>S0+.*A2ͶFs#TG%䤞(Q{ dEA1?(Jn R@sLn}~t]`V1S0V`w'hԗqM1qBSu>̓RpߥQ(%۸˺XgFVLR,CWj[G')-\gY7穊+Zt؟>%i`EٗCBw\nEecK~G.7L|1g? 1.NqLoj'=Ԭ I6ra03_;^sMTjhxp\@oI!"YS oŬ'XḸ&ۄ1z!7&@.m&IǤhE2mHխ8!>Ir)06vedKJsѕSQ?[)' z- -⎼4Dڔh{%լ]bSc!YR6/}7i)}hӂё qKW܈)M>ڵXKhi^踃J{*jˊq~ endstream endobj 3470 0 obj << /Length1 1608 /Length2 10493 /Length3 0 /Length 11318 /Filter /FlateDecode >> stream xڭtUTݒ- k6Ɲw[Np?}zOfͪYH iM쌀bv ZF:. GJ*4Yي\u @h `b0rrr‘-A U%uJjjZ 㦓-hmgo}@/*9`ja +hJʉ(T@[5@ ca uRL8lM,*͉K `p[|\r쁎6NN '- ;_>vw})9-A "b 27 343v}0^t0p6tfh7 g' [28 MNN0uu[߶;8X֦tpL9A,lI[S;#?&s: f򃄡;h G/gH ߩL E7qU_Ŝ m> a2vkhca?Dk: 'IGm>`cI h`26Zo m2Oqښ+yM.("B(A*Y;:!$dedg23<6f' o e An폢.?tF9Qښ|r;;:~(k(?94[3LIOUafht1B תUu,7xLW7>wd#E;ԅaMޙ<&CY#ke +FL=V<ـbcPST+zƟhev|~OGFrgc\kU1Yy@%T.uV ,)!Ϗ#DM+m%WfB8q4/.]A\|3^peY}C) j]8ԆaaNvDs}[;a}":R\Vh>{0I3(GiҬD>Tfx<X3UJqxO7٬ V;]"f.pj\&cCx F><6qYh UiҜ@h4hδ#[Q)ۓ QeR䖉68wMn|$VsWvT9s4A;8HKl4+&O"Z7g?lxpX?.]|2N6bddzP.lEa[9q8@y_܂[A/a*Tkv ݽ<$qv5rzaĈNCRU)E)6*i=!|2;}AeqdL2&yP Pք@0$&RSbcyoĚwW:!#Х/yGZ!ˋNXV>-hmfX7Xڅt$`aBl[t,p/PNlƗ&<ԭl蔐Qh?,c91'vϥNGB,~CN Ӟ 42IFNۊ3UwDo?v#kEh:q!?>{kԛ0abu &mށܢg"0%۠JbR˯&[o]3B64"a?%u"ڢʰռ"'\m~)FM1Cs*znEzZWF/GPYGEkyGVvUCZ=di0؛ÃhD<ʆ Z|vԀ|75<4tQ[rp5fhS$U IuW6ʍG]" 7؛@4u-ՈmòQ[ Mb)2pO_?},0N6IZfOVJҾv!2=+C +=N6K.mmXJ1CPP.<4ŚH臛9UT ʭz.KR6v&. L8Ӛ)q@ޫ{I:hj/4ZuO`EW28LZ XLڗBsq]vy==kHX0>y:(_&jzV8z&Z>\xyfPșgLCP]p G (r.a I.5i6XVMuI5@X>5h^pu?dRM.sKy~gs ڻ!ni'{,n[ʢ8M¢*ϕ5)9 ?Z~ChE !gdj)T߮Pb:l/ށ&qlS}FG_[\HvW8Zu]RXckFogțCK.{2%e3MgȐ%=eɁaC #w3#d maJHi!,vy,#?bG,omH p_JTw}%/߭pOe+볖J1Ţsp&P.&dmN[qZLbB/Y6$<鶤:+ hxM[J FJM`]s0F-3܌o0r6OA/6J#i&džo+4b,OT4ئ}wD-@CzJ'>v޵JYټ\y-1 {;}Bɰ c3 C)(%j ='MK ySNB SjcN4)m X`C G&\FSu>0PGW㋊1,uK;$ -{xb7)RQ,^e@ef"7u*7WxjSr;>]{ J/6nI+\URNgqiT%DN1 نx˨CqlmؤWC c 9"]|H[?{&XV'ѩLB9`_0mPI`0_ &-\ YGeLI:$QpAsA~K)HJ ز$(캨:F慦W!B"QtZGi&n$6 *WM˺ҋV%0_IFإ7u=':OպB}֯흡-/7D@*#rQibeOu)FZIDZ<@2IL|EF{7l#[0VΞ+sY?xs0t_;pTun^3xօ 9Y8$d8o-(zX pC¶/2 )1z06\;XqA*<+g~û8sԥY,+1YgAt.)뜅nj9XeS$ɯ}trR܃h=B$wNV3v|]N뼗$D鎠uA=]M,)L0)`8q[!4IY6;EN?.""%˺l ^=Zd2#LVVvԽ•r&0g?_k}K$xCԐ:TaOAEOMZJ3N ü(hd'kPk5Gt\ (\#fBrgyqn =WtYuMS(xT {{2OT)Sҵw传\2D{>˳Y=O|Rw ξxq;7l%ZRD\9NtASU$J8ahM@BhgWo_AQ|ڇ1nKdyc[<8!Nd`^3̟Ϋdi[3l4JQb;Vr< 4ۨ;Yq9QʯP>[!PeziaXɓ֊^V _〖$`wvB'^.8/6X!,#BTWש8pAslìO歌B7+{U3zzCAXf s#30 JNNsgӧXiR:PbQvjnYrϸ/M>7nV{N[~.||ZQdt0*KAC ~HEçnf!=֏]vʥ*)^%,Uw}L EB#}xpRdd=$/ W u41W%/ڸ zKyڳ`볕_Z'X=DE@9f@>,V~nZ/ yKSt?]ݻh\xQ"h\8pccѓ§}-8a?3LdxYZ{Dі5B5jv_;{<E0W1KJGŸbJtD=֥^Zt VbˠyyfɡJ*j<ާV7 22zF[>>dLz;as-[t,$#rk j~],Ѐ2AɎIFOZ~pe63E\E6JX$zbtdƌfYaG }krw+ ᯳Eϊ"|F6ICc4AW]I^&Mi)xi Zo|kjׯ sVYN)%TwϗqXB{dϷkA$",hs6-C JSqCtsPg/e8Y8,ڒ!%'@TQu= eΊ+(8zLbgrF={~)S]N![u w[8<!M9l\.ՅVUyY8ÇLVi'uL&Sv)k>ծڕ񙃷&i"?w ߓyEhm"`M}$\U^q-o`kߴ"|}\2Pҝ Q4?5p\R Jf(rߘF`GehX=`|cO6xLrL#EN@CfP0o`~ی>g3ʒDIbx'kfImz"Q540\`{Uy8A)H_J94ݣWKpvշl6*^R*#w9ZTY-mZ\_{Gp)ŻuU7 &Iȸ k3=`<^3^fq:"V@xlkΚH ^Zu lخPX8~<| *$l?|es<7jGbo8kw%}O9 VI%GߢT PZG1c_Rؒ!ksR-uknr󄈊GHtS=иX8&V!ɋ9;ax#ш/kEXIPc[DX UId`D A(9Mߏ Tɨ [GʮLg3doEZ,)%Hu ӓΚy+jHD )gTgU`hC~bpk1Al:.+ ?x6 9,w{TUը j"ư1LxAΉW$]-bl(y4DoףGI:Y_ 0.3$t 5*~>8_8$~9jf]q==~Dț@FMj\PU9$Y<<`3^A:F`͕]Ӱo c;p 0DJ8_P0#lWj \Lghlt -cX?@.ʥ X_Ґ['q}&7^_%P~TS=C͛1.#i y02xkr?ƠMkݸ\u7.$J];9S?\[U\<㭅) O)¹T>r^uk{=[i. 5{*g ur,v{%N,̻1hi~ˌ5՝llOg8{MjlC-eN,fWz-_9oB.Z.t3$SS|+Ű;Ys!DoǿBRF=a܀:8}Q-+i3ٱqN"@E߶ܸ:ZS;ؠrfeNmAOH\¬xO|cs96dlVA SҔ_B^^blqiֺWfLzG?Ԋڛ.cRK/XٮKbBRm/ZU\Jkf݇>[sL.OwʾI7Rk _ Ȟ)}9̫fi7w!+K+tRQ$mXγpΛϑ&WҽkRȻ4Ȭ0/S'Vʴ>}{vTF__ 0°UItNXKD\B13\=sS[jSd-i\ͱ# we_EE5Bbh~XC'myc  oRIfLgݪFz:Tdτ1|5$󋚽L&$qId[mPU[no vkb`EuDk ORs{4T^PP:r]$HR^ɂS⁚Dh:@j:A4gӓRK}TO4q`g~=,˼3\82}-,eB&ەg%oXG#U rE}_DOA +]>`T,}rlI4 x&Bղ.<ݱ鯘&]^XՊqՍ9L\h> stream xڭeT\]-w Nn\q<@{p Npwί{Ϗ=^5k͚%ƦP`e@VvABhxxih$@S Q-R@s''C@@ rXYCZ: LLm0O# hrr:B(/j5`icH+e@G jfocP1: 0_[6Ssa}w\6o׀@3 vqqy{ظ@@Gs{W얠9Aoo*bqޢJK'7 YyZ]FBLm]o,3 -.6VZ-..o4oyM= 4@\o1!ol%/bn@?;3 o"L-@ %22@e&/+k_qW6ux-ۖq(EWpu1y[Aޚ/Bbn 4?v7%`{G[W)(0Mks;ǿ|[QfSQTPfv?o3tz|Y/%`b]>!?<}h xf'xdo4Ҏ C1ux2]e&#/ ۦ~KTq*uoNn UoT׭}1 t>MsߌDeLjj#m ixY|3:shi~iKo@_-yUEA)ՋziUCݼ$"[]pqdT/|ڍku\ھ8Wo4$䟑וsÑ)Ueb1D.Qw{* )\L;uh5_v*ϬAUM]B5bQ>smfM$Py!=DӎϦԠ5 _Qi gMzj"=T:!gf@\g>嬋:ȫxfnIHa)zzw:-f?5m*%Sn19=toevYAͥ 8aq㥵Jk~dEun$c6SVptet)^ wSoڶmɻ|C$uUUpIg#"I^j귫f>Xb)U!,sI2ɳ)G%ytxd4hF!\wJ8>m[(;=r{z~ 6<1+Ofq8^`埸_a6X-#ڬYEfIR"0"Lg|{nčBy-(WĨP~b1_+u@MNN4.'#Pu%,A}j4,20JTf j"=T`۰#P_Lv=?\`p xJ#Ls[/6|'e'zzA_O-&KgeH=ĎNb3K4-&KIFMuRNGnw,SeD r^oHx x)`_Sbj/{{~pMH=塣{V!4_c}< D!l`(h$q-5HccC 1dB*.)Sw֛_91PG|atTfāf;Q73|ڔ ;NMk &ٮda .bTݭd {ž8FAaBq^k6fGMd$'T97 ɳhJ4#eP<MQ׬Ç!p? 2\$0 @z^tPn+V#NN~**;s_ѸE3l\31,Ey$]=YW<}S8>ۻfa"Nmbe;Z~ujȟJmtLŞ\)wVY-dGI s\.\RusD\HM0bTƄE2mlgh@qB?ZtpH8 фɜuNEV즮Vn1Np;Z)d~&M~ IM"Ru}DZJǼI~ Yp\@v: %K~kw#>%bq%2/gy.t1 X]{ vI;mE54<~h8֠uh3.e)F>Rj<֜ŐK}i&UEn ;aHбmEDeQXY-HU NyacMC)E9H Ʌzi9*S!kez,Ȅx '|晪lL9rA;rM[xa8bb*1;|9\^kΘMT.rms-q\hlcK$;˫$p2oϭVA8Ј_D6q-tĻ;ZҡLYt3b 3`h{EBb- ΚdϱOIsM|1`Z"-}/tyY0Q;r%gX$mgDy{Bb䛽vօN'LRpq5#&E܈t۱b~yf48/r+) j9ՏTVvC~a>kTa7h:4FFۻmW#9xg~zCv ;0}`bȳ~tP;>$^,;@TNT~q-n't.HIyY|fZ:=g{݌$$ڋqkK)FKN^a? \ z7XLٻTU9YIYٌh05"=2Hh]x>ll+Xy|/0m6tj窰<{_T˳f+_zh/(-\L !L̓Oc\{t?&%?eE 0qcQ6,on*N?xbq3( !]UEx;g‡_lkt l\-TvwVFĂwT$e/qWdgSN4u{.F.q7Wz 9VM>OK̰u !BlV T^b;іlꔚSbկRhar~Ye[# o3 `Et! >'}$5FT:TU~6|myb^Dόx+SԂ-%c &_P+YGHHˌjӌO &$0_׏_ui, O˃o1#^:nډSbAUsҼ? <8?}{C|+S܃H> RM 3/X:a͑W8R"T(NfNw§1c?.d= >EnuYcgN&&<}>s/0ES҈AܩϪc0ֆpV,z]xXiFҩ3C_R)Xu_ FP5eʷ9Z nܭJP:}FEX֏ZxQ9qPrQl"YL P> ]FSmڥwFJ .0|;7+4ٞW ﻕ8&2.b O)K h1GmLNЎ;cm&Y1%*tVmhe+q#_oa!z-B|DgGA"4udyfIJ#vBGWǶɠYJt%qsUք;+=4=dߟl<|G {EAxO,P#t&|͟DžR@y!( 4q>;bq[X~ќp(4͋4KYl%oJ>Ci#GQoV_K2 .w>ւ[;C"xP{9=Cr0:0Tۿ).D/Zg[dAYocpMϊshN [x!>)W$lŢs[&qỎy3w|cLy6գ^ fwv\Rdь-IIzmxrL,}~6EEl=mK; [c-tu[i/hFki6I.]k֭I؏ {~TWTrJ)*KiʸrTDNJYP:M*h{J*n}KoObeĺT)`͚tXtA)ㅫb7{o"|JqӆUevBW1(\ئT4aO/p'Qb݀/]!vD(-U$׶D7dLe~rtb=ʻ9V\وAu7FVFډV/"r_pWԈL%8S\cfU)_s AJγ=Q zp-bOB=?umBc)~V9vqtYPzKwwk n#{Y-[nX ZnC : |S>;鵦 g5?lwCY;Lpœv4˧r ]\m!>G76lyz<9UZ*vp_i|RDC>|=6K9Z.x—Z9 /a!sƒe&3_@.Џ54Pc@.N">G-%prߦ*V xLzM4 Ls=ẂR;_ BUzBݗH:*vLL I5،#b71h)Β\1~Ǐ{,"aRPMԀS'Тωp5> hm0ċvF&CƟ;'ded6񒪽QK\iF#^EMX;g'RB|;mr{QJR5 o"K#"QZSdv.`|Ә)jy7t$:| o[: LSQ/3Ek4nt{bO S1݀ɭ a{ۍc{YR{)0`!{ȒC\s6ƄţҤ+Vt |h[.0vM9CTfcSZb;SxteV@ew5B&Ck2>n>(;xv[CJ 4w6[cO#L܌LNy**@ǯHa䑷O'Fӈ̐R0޾tgCz⃬pO&6yTj:2 z0"GXj2dґ#@x>ʒr2s꽗AD%uATlN$`$UShS'M?vc(!XWx?$Eᶞ)C{Ѹ;IX->j|#˦F, I"? =?[ +/SuF䟋YqQ}X _~y,@;z8P*Y5 e?Y2:0xQy/kggZc{CՖyrk|[B><D\݉lO6hK\ )qUDga1JuPT=cэ 6TnEO恪[thZV0ɀIS^ R /d@}$;loM6o̔0'[fs2݅'5)< {QWY;q[cB;Rx_ #1kOdmmP|i2qP5±:i$ x|y.lR"tZ>Dc1ݟ(ϩ!̸sq .+U?EI/I~)L<NoHt[|XmJSӽ^-ߣ#}*a^J_\l!Pcp0 4xPs{$ɄÅ~*jTu5xW,n딅0:$4y@wG=/L"AsJaV2葌$$pS( cԣ="kõq|JG S9viElA~j=YB#om2 R1 +U[YԤnLn.Ek)LKiؐM&Ot .GzCEkl4ZNlh"[;af۩(<_=0FK-Lݵl㷓Օ7Y H\^oD(zwR&q~٤M”o[yէ:%zE@(7K%O%JP~d1z~6Vq8OlU.@<1  T-00ˈ|Uikc Fj N*-67LKG7yL1ckQ۬;r@LeM":rEX/#Z@Uu {5,277Qs-T%4҇+ );kWFdl(=Cd|IR?Lߺ[0"(~a3iib$ܯӬ/ӌ6`Z !pqTGU[L$Fy힄MS5j#^ ivt}"`vX&GUeqS^M x4ىCXK;=8t Y[I?Wrk3godD ^Wf,\/S?W=X9!b'cf]A]Z:C}2b"m Ȗ4LIEq q;5WbW{l8Ⱦ$"D-8o[e;ʗ22CϚ)UPXuk"Ų1cquZrcӣ<7:P!d ӀMk9 6 nWQvuk4-FBRD^r Aw~3.m)0YZ^XqQґ؆j2{F~>Ŕ E8rK[6σ~$"BڜPfoƤU\KQ T-uJ8}͸yB@ ݯ}5W=w'T$J{?p1r0ҔU0ع?BCC7˱Kh+HL5\WF(_('F$z'qeRjRNY !zR/Dca[|\$-֐CfCj⪹1:* "Ez?Fܜ0ЈCA4O]jaXxLűU@0j9W;28n#Owg vp h}.Qi^?u׽M^((H Cp"=V҆YeY١|g,v4` QWWnPy9D&mq5!U3?3fע++cOX&^'GdguU5r."Teo+,v AV%&?}m}LIZwd 2 4yc, &J]밋J93=ò,޺xOl4Wʃ!=Eh$ !v-rC9gm)~ ss>ieJ]YRj] + -EݥPW#}}V)߽'p}'(XGSE<`z ƅn3ٽru 693݂$\l<s?DQ]MG0 s*M|0[[o@Sn'M1]j,>`˹MIǴy x8* [Ji;֘G|~1PdᢷU2BSjCKc\:Լx _lVB})C^9PmWퟜ‘CO%,իT>`wΊISoiw4swJLcMchͯy]kT Gm!^z-oN{ac =b%DK3d4!WnO歅䘠X޼2G*Y.)C,ITw5U *CHҙ#hP:oo0VrA`[ZuLj.j>2m%чa)S0?sl&Jk.z?vF6v R`1 (BD++W~4GRxN 诲"lq0!Oe!Ӌ3\K#bZG 8)a`.8^YsO/ҙ//i"U,@LL#92-{P/RxzFnFɰ 6^"9|q ;Z+>}%qn=̘DuLMcv9$OHB- } K Ī̿NFpn \)QEC ?3zc*jz$S8N0N.)p}q;2-EwHޕnLu~gC}T&NڽuuK$m\z0ҩ}A/ 뽧yfȑ/S o_9 w zhv>R&u~tߘzwS w|f"e+4e̍V[ZfHì\ʽZ}V B'Ew7Y ;rp#G$"&G׵K:S"ad?I=>S kX('cDIeBhNw +ʉem ' ,cc>CXd}+L[+O4+xn,zj g~‘*0|0 aCˍ:LC(X8 1i}9L K7s$A3Ac "WΙo'&P`CsX(үCl@U^(3 O'-;ݶ)Z|ϟ0&#_#7B~|t[DhG..RBy =Gw?Ws79'姍*Ģ&PgG8v;hZBJ]*᪸~H>-7 w<:s}rL&ݑN4?A,x_ [!JuOޠ'h:!Hl)Xq~PaTøno娰f;5cKT+Mp'XZOpC\HȲS MxR{x&n$ j/I: tRpWE(Zr@Ee咭{RM*f?gD4O԰ qh=h$8;$/.SkgazAu"CMtx0{ˉ}w{Qs~F3܁@V-5a(X^ﯾZyI+VV#bt|Z1cG+ޞ?ݳ/,9րD\PVVH|NZ0ϯjzjic eX@#l$P75X{s,^e? Ҭ+vfZz endstream endobj 3474 0 obj << /Length1 1144 /Length2 10786 /Length3 0 /Length 11556 /Filter /FlateDecode >> stream xuseX\M-Np Awkph=Xn5kΝ|9?NZ֖ZEE(lbk810y 6FΎ  !SQY8YC:AN1^ r,@^ 7/˟5ퟁ% [ `mC;ۀ!Nvv`1ؑ` sw03wЪh~g70r';ZA.`k[2C6+V$nbWZs'';^ff;Sh;1S8D/Gf&f6Ӕ; b /bwK&v {g !3;8@ +l3R7 xyLA֎`/ S# prp{y!L,F`?o?0{y@}ZP[@6`_Q""$YG?@"KCLm<(Y *):Y6.~,yZ?sH8[[?? wkl, ?:N k cad(a6Qp261CL~q`%[G,?85s c+H)15T`//x?g7S 6F^5 z_%Lʸ3é~LƎa ӭoULĞsÝ!4b.X+ M$j#Ƅ #BxTïzvCu /uF^zE%(:dCro@DZW?SE)koe^v1I(2hdQp۰ gf{E8|$~isu> Cw2ͦٻbEy]FE!YAEǟ㐳[0~G:v{QbxdTJQM,(t8:26okze0𾵱!UcoeJodE]vckZJǶ2mWiUNɨfvK|ZC wd${g Js[j3+f`X\8| nNRx^_"թ7.Ul2EF 4ձ/k5w6VP{U Btf~v!pZŗ1ŘBXH Lyӄgk&:w=\训Y]2;hkg*r仐=1aN-^3YfK, )#Qc]5MիD⼗_ljgST ~L >%&4u2vGXGMN2z)դ8OWǴO䛹v^ GhuJlSq 3B*|֣kP-X{:jT'"*Nb=J'!QfiɤRW(!v~SLrطp e5Q-E*/`g"+).C:FSLRHZJZ %*% BE #V(#~nKѽ3j5[7oВIy2sQ &V[<(Y/`m9s=/E491ç,-km 96\𷤌wB;T6G J*趎fR%%B(iG6HïbQ4I]cdh1ȅn~[ċ<ƒš7r>iaԥB +`tc|hJEX#p[E~.N*0/\zJ@'4wDl/+xQ}!X:SE'`^M "8Mp^ KVQݟ4q^fj-i!S˾_{4!oR܍X舮'^4Ua0\Iα4},d]m#A "'g.ߐA-(AZu~UZ[fN֒j^ե<l!! #-]dkd{ЛX/gPtm1FȹO&;) D gāI 1 mFr Uj3 hnK z~϶niXNC<ߺ^ܓu&AD-,#V 3s! 4֒MȚ5Z\SVJtOzl2T&޼l)/z;8v`D̋E aiyjX![CiFz".I$c4sJ&i S#twL$P9(bKwydbB`xfcb"7 e vk\Z1y^lS U3Œ˄0@\?| N8aLp &p ?u, N7W^ନK)g1]1bu &'a*ݯΦvJaI/~! #6Zb\r޽SD @=[d=HiGH@"z&̞NY !1{HD߯t Ul\UpQ{6L@'>uoɔ 2Xs7aM(D,ט ͢K{ij6[~4xŜ xEymg2ÓdFgÜkOm՛#!;g a0 E_D0v٥sqj*:T zQ8bmG6C~ ?Zw}:ک!{+R?&"+wpE;{b\!ى  ?JDi1h"-P #uKb(Zs2"3&38օ?0O)4A&D[7kY/7@g{G q+tl )3IrlC ﻸ3*[ 5PcqjZ @FnpO6 \<Q8"%hWG~wF ](_YFR[qiӛ0 ytD}ʻY4m o2A0Z}kԑbZ0HI U#'j'a%% U%!-NWx4jkKWϡ#Dykّڔ Sە7jr6=è1]Ļ ޮ/D_O=Lǻѱ|0 Ϯo*@J3E"M ^fk(NL8癁[PVYԤ+-$DvǶ>#"-:vؤ@!A(xՁ0?\<5vpL1а0EӸD 9s{H^NC_ʟ).ݘ=Oˬɝϟ:d;eT~E0 )͉KƏ/f_l_#\ˎcmΪ^[6 ΋A&mo-.bè)m-aW 6,&CTi%ڻk΋Օ|~tZeٚ:"q/UocG/NgLac \&L۾7/)OJD)p4ֽ5ɝ'o/ӼLk}"t\5)[&]"h8h|ޝhciq}mBPN{6>.B˔s-#&UgV~z~  o$Mt8Y7eTBլ+%I.e* TTw"g_|E;`t4V4x{3սwdv#1`YԪ㳤3葭ubXdi@ *d?.Yi6%nK/rCOmMBk_ǛO(魰f/[)1`]4afR?0m-_9ĉ EH9=;>{HK%X&?䄸QD7>k=dȤPię̦<xLýjnj7ӗCPHJiO=E{j6y. ~"^v6h}Nu[b3a23ۚ0:*2zVGI=kzsƹ^FBGCI !Ep49Ͱ8=\9F^hf6I9}f^+)µcTĚRr~"QGoy:Ն]:]nn0y#i |TPBkpd_I(4FJ *Ku=AG*.'vZ`s֥-D`wWN &rl?sɟ"GzwhPT cث@2I^(S|E`N zdrZ?̠=4>vM}9M^}֝;ߡѣJa(~FVLl&}Y)Z!NiW}@ _k3AHijIżtdﱌr2xXJ ]o=M`_hB#?\5 |Id$twI*=+(T(? ((9.FxܭpY؍zWK@2 L(Ԇ}0Q|+7Mc09C[HGqIN7I0eґm>+rj՚r՘~ _rly`WfTKom޻JR(RZr+;IFW}WzTtCzX]A<Eg=IpZF#34 xHťHUqjGg{s?p$ZY7m!B+ns۽~Ґ;$<4QV)&5,{ &.Rдl݆8kN*~ /gmUa`}fFXA}Y+ȟ2 QzWH Ӭi?˃'l Y e΅ߗ}&zœeRQa[<;V1<{ʣW 3.r9w L9f}[cĵD40f:Mo<:G}ם{km4!^nd- /GrךZLVpEP0//mQ( y3}5w^eyaZuY=%똖DH42c>@>cj!gl|R1{4o?ClasB}мv\QsHd,OQǯڍ}5b;cK;Zx8+euks>Y(}v ]r]i1&W*O$ŗa8> Kѝݦ*5y7OfZ\7 cr߽K9Ⱦ)a׀VXHL隱#f$;Gq. @NĴi~+~BjV;ĉ qeO\K]4?e&6PcjmI%~ 1-&|PՍA|!ht ] !ݬ愤-9><, ePV9m:GEs~j$h@7f>ZOVήI`@,m+ K3aCڃI{{i~/waAs$A+)ug&ImiV̽`hl#p]oo%ԸC.Kޤ; E!Nù&~8<(-GUiQkE?3nj}64e UEn0ڎ2jih;rӼ"}I+ bL7D eQZX$)t F^TaԺ`Ɉank k,`jQbn_ڗ<=e'KI*/H8BBL5?ԑ;-NdJ*c y![ @}ee8,S]L $(X Yي}vIiT,ODݎFb7 Zc?1j2D؏@.xNiKsyJ{xtHkv9+ nzY̌&7^NmvCW+t˔4.cfl89D\ 鬟J&PN_miaW~Rmŗ.) (=nvP@1' B4M9jj8aU+;=mfkna1+`o;g5|%L+j,m]41ܴ5dR,oE ;!T9Hkx̰[ܴ_Ʈ^uqVvpQ,takllzo48[j1׻e! gB2ݏ>?:M*o9sѿDZr>YELgǟ \ovd"~7cYdkm(# ت`Lc#L~Nzr;%m # Hץ$P)D"pu!$TnnӶ{J֋/ᅥ7x<\<ܕYVU eړ^jQِ ڝ voyїq/S?SBv?=y0(Ɨ`p0zWGl0 H#xh^ L4X:qMR+k}C^so0lPŽlT4P,b(N 0ɮcWm?[yTL9! fy:Z/ش>B:~}Q{ًyW´UD(uoD!M(&kx߂x dzX+cZ3A7N@k[7K{]_ nR$;C-rfirhC;="CCOE[6 Q#D&gUd|]&HM)^  z#<G;p"LbpaSG":+-L 1u0߬~-Mj]ʎiZ E&<~ R"f$Cۣk)on@r${]^f*6A0*D~b`J05t0Q$ZgVYVzk)(ҩr:.L FםL)aÒE qPд5txEd_Ld{bI-v]VDrʠN9bЏX,{k'ͪ,g6n***q3DRmɱ|G6&tق +# UhA*8[BykSfn1J91u2ɝ4_#!iZΨ4aE7ۆ.'5}s> 9}o X}Kv'~<4ssFC-i@1,Ia^幹xװ }y!G[2n dyagNO Yثp5A\b^*Rx NҴq$m zTy9(.4pB&mE+8ǃ.DBm>bB*2SA仇8t;Ro+ɒxF OjE^H,8:_Y%{^'l}pWc؊-kiE#}H04غ@H`2DCCHehS*Œ36|v_Q`'j| 㒫+*35ln*1e/H߶Oы/{keRi`M ߓ8Gχl$B8 }U`o+'o *#9|k^T  <{YՍjgO#Zf]= 1XuX06P=L# Ⱦo;!ħp R섵@ex2`l\D |QLB A  K5W<]pyw_ hx. -m_fHZʱj<|dHei0bŗIZLVm4,03ƻrJWܟY.s[$y+9`mL;pe_hej7=w*<`Nwd$^5`#G2݀MBL g/V֘$W܀F";_k1%tֿJ5r[L86} 3t+nۅڐE{NoMjoܤg$JTbaKnCk`HnqJ@xj1> stream xmteX]I-ww;];8!$݂C=GwLߙQUk^6{U &1 3ؕ 7ss0+2\Mo)"&&o34u}Ѵv(:Ylo{V:8TAU+~$`W 7GG;BltXUϙ^ +kW6 @6@;?o[aji*erm#? ) cvd]Yފ[H8Ioy m`,A`?۳psd܀rrxƬ.VvV>V^ 4f##Ol4s,o ;>!,@3ە ZuV2uuyYYY|]oseS{ EEYAQ^[X&6^;/'O>.j WU;ˁ-|67tvyS%O;+[0\oZy[QH7ݟ3y[.E۽=?f2LAv^pK] le0\A@ U_* [.? p s[0MR@$;XV 71:[6wsv~ӟ7%D h`.jS~_'F?ǭuFƉgW߶7-WRuZFJ 20e|wDHB#Sp,#<_?&:SX) ;(d CIJd9SDŽB2fPP.ʮ6e*_kc.MwL} }դLgSz BI#ve*\*xͫD^AiZp0;1 T6~ (sǕmljgJ%(3@70g0:&9X0zb;&-R*([8,k;%{ )!1VƵB>DMn3c!z43it]* 1lH=7J ?i.|as` E:^5~d.W|jR"3VGQ^hƬ ?RIڨH`xlơuqYT9}Z)Mr&y]n@mRthFJf{dSl/Ʊ|4X+2leH6&sxd5P*Il[ݹ-[zT5:z6)dnȷ^QZ} , qY_c\_|Զ,@J!$% [\ Zr)S"tH`?(U\å4lGb`+˥1-p旸h%r* 萁@Cz ;K^ \mB:!!ʻZ0U9h}mwzȥ v;^m{ww. 2}mYK_|)0)o.US`HlFO{G~|q'ܕ.Ы4,>iH:WO'1 d&W kEǥP*H=>')͈@~9&, iO墆1RuhVqKv|gB.0׹a ,>R`YG֔\A˾a,:H9lx59E>.|Y NbyƬUja>mwilHA&c㙓Š1p?jf``5Ars-21HR}&׍~NdndWUB& Cw'Ȏ+cA-MeRp}mr9.G*m&)w NQ)&Fs(ac(-yb;]vUGkj9dG%b4IC>TQ,Nkl`tw+4햼uڲS_.b,IIWR(_L2u x! lr|#dH!߼OeΕo| =ŕn$ckYB&!Wt: '#^5iKl)]]O F)3 طqn0S+GqtҤzt)NXQpcRDP "BpH)JH -K[dp]:mm3ZYx03,2[G+M0qxb R*qNMjaR|i(Уwt)7 3{uh a|YL9O#-vv;XgJ-r/ژ۩ b}ƃ$)x6 $Y*zNӉ3qf 3#uA]mW/RRk6Ͼ'–l3qNGJ$M(g0Xl611wjt$DK<V-^Cr?w'PXdW_j? ڵJd ~خm[:&2ҦH71-BT~ĐBFtǼkY\SD.: DQiXw^"gA,~J5wo;}>mܴ :0?tz.lrVepEP,34@xVCqd6VF-\I2}¸T3[?5W-lHsASfiiVEh v7R5kDs˩:#3x,g%Y\<u*8[X8+1hHPeҬ&(82.rQc&M GtXb\v˖(p/Ą;&?y~rˑh=:Lifhy ՟~'=pDCV#nP\VL^V|[$Gsm̂UE C ໤_# <7y")V˗[5m dHbLi_?Bmz6t­0G`}E}:aϪFKnɸ}YW-Yxsiv:F)C3Ä*dYsɽ|  W= UFQ#ٻeɇ={ b3.Hs|+뙧]*"sةM'tSS(зuk'.(m`#>Mz}+sqZK%Yֲ h/a籴]<[Pkx??+](3Sma bJbaNn'|7Ze{nZ6C<10ѹ۸dV#-6yrp~$ph|%fs#Mj[k(ZrXF@Ti:,>l""]jb(})#-p|TLHRuU5Gdbͪ< 1\qXP8}P % 򮡀E=c^ww.UJ<8$]UsTǶM%0ճBJ(8];0qȧU' +"z(كx0yǟUV[Ow6#p9@Sz -kokizJOYk5ϟx<F´rWozצO"jR_#UwžUd_F~0c8aP}V6쭚ݽCb.τJ[;7Cb.}Yu_m U>I1@, ŕO^涆E:6֯NAP -Y-ӛQ&Ѣ橉([v4H dY73UڣGq/>fH >$h&n]\8 M=mOaoKrQa R'"X`~4wZ3_$-~Ǭn;*j/O*5hG%FQ%^"5ՇU y!C]{;!~njpخ3$jfnM㢾cR#&"TKiMI΁B9?> ;mOZzw\;XĨUn,v06kdcu=UlEn!.ѷ\e&|-& e7NnJ"]T$:¯V,>KRžb 4*>Ko[t{puK2 qWWR{iGk 2YWbJ0iٌ5}p< p4Oby 26S8 z O.«ՎJbWx'憭NdvQGDnM ]iB*f n,+z;ƛm1s,3&dw^)~E,YĘs+;mOf[b/"mhG)Zyp^+y+v崑cމnQL¡`~ri!>#M9-Dx3k+ 5GDž)g)d}L(BS?(~~<(bU 򉜉p>PS^}($6yʆE<# 9Ho{W2k[ SQZ}ʲALh-L1%F@F;sZw%ŕvxhq$}6f~ݞ4GP.П^I<+ ]^wmkE Վ  6dT%&;x˵nGwj*T60[vD8q-2|Pϐ= i.! s~.&"H-Vܷ9nZp?Fl`&;NgeeF:O Aj7FNZ[1|yL#3}jsSN 7JÐf::_\r@mqǑ`&)l8C,~w$Xɟ>l!~>|q[O=~jmk GeN,V|//weG=*^If9Ѩd6nU4>hqPr>h5ekQjxgiP5C9LM E~j`O ე[,D-.Q$SUCBql_l^ oSğYK%=i`dAlh4ETW7;xd9gIeP CjF%H<6͹:lǃ +ypGUYEsKѧck; 7D+M@+&FxThv8%&gPd/Jod,l|\Đ[ 'k~}³27DA6u5'M2TMn}C;u[Fxir.73.蘾xD$33MFz] 3'Yߣ(Zp8wܾ(leΙ"}%(< QE#8aPwL-Vin2G-~Ʉ_@TÍ7`9KVC.9+ |M VwfD{u]iaaNN g+Ŝiz PR?dի<}JLS質CN)/  'AFioxk;iýB;#7&Fy&VMUrEEZ= 1¾텑L) QNS?ӑjWqXu6bp(Fd#A7bKYN̚{${ |=Jrps΅Xki4"Y&,*!=!]>UePE#v 2qTBpp=슮{=,&KR|VL߈a*fO:hȩNz;[P HefaGѨ0(1g5$bJrʇZmy%`&" fi|A 8 N!SڀlcΑ$jn.cZä[Q\׸cA$Z\aũtl{zTɮ1dk0óaVA+xP"Z3%R`XI0tPpQJC-,Baňpvl0 `/\A!: rk`qwRxi.m~I)>}DmվDֽٌdjyhDx iSt|Pfl)Xfisf> stream x[[o~ϯs"}Ih%` ă leןq=cI#i{UWuOJPJie+mSJ"d%BBWz00$ a+uJDDpCj3d)h' ;3 0V4#Tځ t0)UQ'k*U**+H'**%jLdsLT&JX'+$^a|pWTAp@ %u e!@*xa e8t-ы0+DH Jh kd+ql +h`BXYIcH j]4^*r%j9 C!9GA)$:9HI>uF HASW&-]@`CGc6~"4]IviJ:R~@44|Ӣ: Y$NsIq8-8AZD 创j$!(011(&k: 38s8YC=)X E cJC`( #aRt\ g v>aO$9mŎ?~l_F_v~OÊSAӴ}\ W+vdb|/;s2+u g؅ޭJ&-&]m;FGRvNkjcf~W.=--?ȉqDTYlb[%{hAw4]X;R!A>Kנ|W#b 76N+dbaIs z^o%5l3'qržնv%0ɰZ̮ j% HJI4^~Byx?ô?HJ҃O(~7h)B}'} Wufh>88~*b6*3`lilSN2&* YN(,&62]!!ȇs lġla&1)4 qd5n$m$ mԔv ]m lݚlM|NYris6y| RۤtjAƶs5FHS G/j8qDJN2Q ?Xhd +ZBDb@i) q8ZiHGQ*1ԍm28gʫm"V--Ȳa t:k 7z6'Ay<t/_Tyo韸5l"Hũœ,{ZӷE_jiْD M~•l2/c֥ݳpHz ^Male@P_oz#Fύ8${"FffO*igUҀ MMӗe2'_WuE,Գj>Ksqp/_z.8 g#&?HCO٣i=ao=\=s\P; o>FGQ =q4/߃vq&)>);փy=ez6wc6蟷&޿y,|ht?fyk`:y1|%6={u1 :[u己7}= Y A g. v2r8LFZF6z^,p68o`vd*&_<y@65܇ynP_'׳Wo01e6*B PXc\ivmcycjX-M}cS=g%{kvް숽c;f'6`˫z:Wv2X1,"Mيh2rXHVXt4d_Ꮪ}\O9`]]c6da؈]15__M:`ZI,QQ((8}g߯|:|W6'Ŵ f3r:dt[_/Ѱ;q[;S 7xZuǰa.'ב:\^zI|7Bj2}t,=D_IѷRDTX(;{Xb/B}9eH7qCR`Rz]x{ˮ<_~;Ъ>f^&Q!msr mU+w{ Қ:p+gS6BAț R7壎*'ףQEqYJru9;ua~Bf/?Zķ/l< >>liMД+:B:.PE˭ ;_i=>(R9PXDS"U͎.1Sꓡ91_iq5P\LXYWIeU°J.iTkBBBq9"&WmG"AK)|Y]~'sP^XyvZ?*?a/ b_\/=bXkS/ ~{KVćR^}YU!^p[7|{KGjE,勖oyW䛛{+!2HsҌo nsҊ+u~;,+V;(gĽ(vJ~׻]ͬ O-tSڭҊ~Fl&x߁SZѻ4 v/`|{P%}YbۉT#0|3(4wMlDˑ"Xz3-EYd:\T&LjpKQ&8BK}6KsQ>넌7Y2>nwo,*E,*$ !b_;ωHyQ![t ٪ E_IDJÑw$6qDJr{l"n+g~iJP*i9IC4$+*f`V4dv "5D$dBAqJ:_䮜-O/Z(/m)ʼ%!.L8[]YxHv *CHxJ(\x⁍tzE)7FUKwѮ9I'sK\ηE*O.B!\E@ĭZYWs_I!P/Wȇi!%i@H LK ^_G1MT縉tko=#oalڬNC AcAz5"3tp8 3NC]0Obأ!_0g^Pu1׭Pɰ@l@!? MCSb6bڠNPLnb:A1(z( E 6(]6ڠNPTj;AQ(j( E 6(Y"7"۠NPdh";A(b( E 6(QͰn a;Q"sHm26*ҿRi[藫(ۂBp 9%fj1}as /o-^]zy%*Z.Z |74[wv :Gڋ=IѓPˠe T_iJmvkgpp]8V¡[ƯeZ.T-^fuk 5k}[7] 뵾-.Z߫ujU;Sհ endstream endobj 3483 0 obj << /Type /ObjStm /N 100 /First 883 /Length 1696 /Filter /FlateDecode >> stream x}͊V ~0G00 !,f1<~*[GM=>tyck>lSm>6piF45ۈk{kы2m3õ)|v]Cބp0 b[HcˆDU!e`A+=uCPߑp] l7F2jCFc" 6ug6թ6 4TVE.9n#6TmN`BuJ&4`F:,hP'u@y5 /:AFmFCqF * AADAL#E$s AAd4H+A^ κ Z E O4Ȅ?QAf"hA^H Q+4(يgiiHu#q#UMVW8"z{aEy 0"Ndf 1&}&=<פ/O>'6/>=_^A?ο|uo׳Zc?ZFŮ5JvzVyVJKТDkQ5V˴}/ٷg웳o%}sdo'{+~JۮEV`Z5]buTdo&ikRd2d#hek^{؋g/%{ %c/ΞKKƞ=9=;{.S`{rT3dO=eϒ )c?,2VzkͽJൖyZ25Z+ւZ^kZZ˼kZ ^kך{V ZÎV/֯VvDkAk~/YjQMkZUZAÎZ3hL\dWG7-g%{堕Wg%{ 5c^Jk^%׌8{)s`/{q\^2dρ=gSɞ{ؓ='gO%Sƞ,2ϒ g~:Qg?J#Gɾ#c?}/~d컳%}wdoξZ ^{TyrJڣʛ^J൚yJV2Z)VJ^+JZɼVkZ ^+׊{mwW]|#_~~u}`J,>N{Ez ϛ{wk,կƳqO#6o^Ad~(Ҩ\}.OK -ޯӺx?.ikRu'aJ$h%IԵAeZӵJzeT쟫3F|]oMߣ$><ɣDlXp|w)Gna>ua)WH6(n1UZPȇBTjn M%vea:tN;z;O]v3 endstream endobj 3484 0 obj << /Type /ObjStm /N 100 /First 885 /Length 1818 /Filter /FlateDecode >> stream x}+zyி=`Y_0M?%TK#w9tM6c߈ QѾ ^u>69h!JxխУmݷ^y;vz6GW3Xq78[v1,V;M졆NQ,uX,X  ANU4ͱ]1 m1"P4Ƃ(Ju#GرU(;:ظmE zI7}:70$qDPˎ@,z. ".c,  >8PƧ0%CmۆT?oJ_~~o0u˟;y}?~;.Q_W=~~$\toGbմ[bw[^0{EǥEҤU/-^uMÆmQSBnDl MDiv?n Zg<9s>TF{U]x]꼧3בէ#/u{ݺͷGZZz.+Hɑ7<2ˆ#}Hq!׎p'GGzHpJRe]/4iq/ϰI+h뒶zBK.kbo{ d/V%˒$Z`/KK>b\yɞ{G>+`]ю|)}+o)Vxҍ)c|ߍ H)wSO7+ʒq=%38ėc5iv3-$iQE+Y.3W?hYҒB띑O-YjٟUNZ//wIZ'b߃`]~WB*uc.&)"oAl(bKw+[wsdH 0Hen. XiI2E+S$L޻@L|9|$^&&|H>UT9,ӳw|O.29E#dݩ`h+lh}Lʔk})/ߖf^&}:)IR#yJe9|NīWVs<7 {GH@6S K9OA>NAUs9OA>kIҪ )'\9G䳖%>u%m5gV%\E9G-[bh%{MbͺdHl%\%6Gb,٧*9e>7W͑,KK>by>6WKs>Ҙiɞ{G63-٧l*9i>e3W̑ܖS6s̍ZWJjnt -:> stream xڵ}]%7r~E=Z!d00 ,0`0>xa Vkw_'xnݬ̼`od Iܓτz~"==;y .>Ew%SRyRzy?I|$2?iNheAG)mDO|@;~"Rhi|Os! yld Lz8m+Ey5,3y+(Wn?&]O0~r[N6;[N6cWxj܊-ϖy1gٖ}۳ \ }s]<@;\[A=dW v4G1|t3ky5UCQɛrOMBAjy˱h7u<<=n-‹d~{QU[AF9O㗧W_/Z_sWॳrqC0tBnD#5?F?T3 >"̏K+96\qs&rRsME B mxx`; PX0<$xqO͏\PSn2@mD!!v8Q&1T\=2}[:c5Px88( ўRa kkr./< VH Dӎ\5-j1HQ@:OV1e4Xr]a )|R*V :+l&ʩ\tRL}dtD+@ H0m T -S) p q 7wd)yZ?::|^+b}ɡ7ME]*"iYGGo>ڧk.kP2\!{׿hqSމY¬dNONAM 'Z|ѹ&ӵ3) Esb:g? BaJ@IȨT 8Aã,P;. ^4kt::"[o9QKe9 >L>:zLo-\]VVZgN0 sCf38(?E!6vJC\4ցq|>.yҴ?67C!*30.tfmۦuI~i mǎ3f2%m.VUo:oUCq5ɡtS'­ r^Z@FJT.MnIoLxMԱppRb04 '^7&NNtfkClc'YJ6MV&]LC>K߾v"^XRrȴ8-vz,]c!킓!-)[zɐu"KWML;}Xpdm7bo $vH Z혇sDj4uOnQAnQ@PS4tF\A`Q8>\(2%wO}1}tGaL2PN.OqVaObż׃m;_Ҕrafn%Na,;@F',;GPeE.9tCRK\ɘv Z貱 @a1pe|m QaNWlcp9-QcL5=a"!ffI\D$~EPHIpCnƑڣÂ2;Y@|.oI j% 9@?}wЭm`i4H+Z}!W:{6-\L=]U_isRVzLäLp% )0uY}nEJ(HNs~9ED[!ZY2I֣n,y~ln%bۜ֐!R"9==]S_L4Qڊ{p(`xvԽb!{SA@ǯ\|MmL>VVDӄjbM316W]"ڀTܫGw{ꮛ]yAy(4Ns&"hmݭ,=]SfH$k.`'~&tlh t8{E&dŅ Ґt k).OQ@fqbXn.)C]ѥ^"^HdT,9s{?}oM1,x;}ecuqdu2/dr=`~e\ڊLU.]s6o@V:L`{bkP8>!fM@ jBr {%v5R3O;[9.nux}UoȽwMwO}ۙ K$(|*k> [SC2\sŔ2Ճ$m\ VTЍQ7 gQɨS6-ˍtA}žCEd,Ů0i,rЭDjG16p0BÔwMwW}]Q8?|Ȏ"P),Vp>ԕJthm(Q \fw ĽP-Ti"mNښ<2 Cl\qqycu:j(i v  (Y>Mϩ^9+ig{j!@f{u D([sg &E}z[lh6Ԝ $sevu~mK꺽&qIEd*j٢jU,GZb\T+5h2X4&A#n{cL5={\,@G7(5&}|_KK4[Z>z߇0CZAUWRPNT]jqJkӌ̳L PPzVgBV# /ۛf:T-؆| XPs=]S_Mjp S@K PQ4Pb ZOe ሂ Df"sIڏr1XT+]*!c̴"m6o0Ph;TlԲE9skdtQ*-wwMwW}Omن״RJ*WQ[Hvkaj5hurIb{hJoq >t{Lvق< u%GȔ!֦ÈmP{I.l{<-g+BE!۫ u^x{{黦 T jy&x:C8]}V!JJ\ͯpF;52vAFȜwгe,{=ff8p5Qف)7(`]U*! A( KܛpS0T{1c]껷wMwO}CUj9,PYtH>J! y=@&GKp L{=p5Oeuއ@Һboeնnj&+e (٦lW)6Z튜k="4wJə|rl黦YO;kE5,Zw179F.WTHƘlwhϯze/?~ץ5όy]ex՗u!ú ql~p;x^1K;Һh[*蟯4_B~/vνi烃Vf5_뵮l"ǵy_n}\Fr}][ ^^ʺ]]~~e>:}}Lh`|p }+l{Y6OL! Vq=|if/Lru+4+ G/i6OLjXɗϿ/q㧟F vBGݶC,TKr󥢳1ĎcBj !:e#1 UDJ.9:7?<*j `Cm[aD-ﮦp2F(U!̣5ߎ_/O~'($C'(Iy=.z~& Bl쥸GMKyXa\ܚ}0L+¨avNlD<I"BT1IĶBJRr(F3Eռ[bdE3O)|.73P8jA60bCAX򶱬#b['q`&#(ZUupp0\hrWcr_rw1|)L7lpR$i݄&z`luw#Js=I2Xx=V vHT9؍kDVX@ںM?kY]sXs$)F,)wħ3i$ ȏJ۠XkM#!-Oi[ Ȑ#ǩH2r1=[F9me:\̢{"xؿxާ*L=+;܇c@4-GhШ([di&t<]1a4sŏs"lVyQ@6;Pi7X(hT̳rhf#S,(M6omeg Јy2:֋ϐ\?7+ Rŕݺz%kVsj?ܜ1A2h2}:ib :R P)q؉],Dl r^ov |.ks55p15},xuPv4j6>z.7oiE:e(ؙA.DNra8N@eƀԃZ[!ݥv"v;7/ݫ}r q".D"/RuG6s|h.i`ѥFqD^ks@@fl3C'u.v/CE7S l^ /k%Zoؼ޻Q~zv|`]cFmZm6+î^yŮO Uj/Xޠh;ʽ".WNd˜+` 2a_! YkS!iwuenP,! \m>^#ǴƳ`RX sO71u=YEa>xiw9v8\O`@sXUu@dAI)XJ7Gl`5Su.\9q1>(ݐހ^@F endstream endobj 3636 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20240506222357-04'00') /ModDate (D:20240506222357-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 3555 0 obj << /Type /ObjStm /N 81 /First 846 /Length 3575 /Filter /FlateDecode >> stream xڥ\K ϯ1}^dUA&N.Y,Zr k3>$>$[lUlbpYR u؅]D0HuȔ|qBsLׂL%(c8#U. E RLΔ̚I$vsRT7.TFg2v2[#IB( dv2al.J2T2FO6 t:y<ȕ0(+U@CYqwN\(hU (YP2@F !Jdb)<"G$gɢIւO"KB d >`Z(Y#kR2$kѳZ EHS`O"0H/gԓ!5J5^r'W$k)DyXDY@R1p.: d-I!i@0I D d "Y$֨=DL5ʤT`$k9|?y*d %Fpd-9ܽ~}wCaz~ӗi}Uz_d2Mw, ?t&+h-M= ]?Fc/w߿y~{xhl2(M?iDYf(_̬h&\-¢fUaad,<ɢ*5=+@9+@^(vRl'&Dlh$A/7݌|-^攴R !YX`HZ*v Ar$/,4E#\ &6(}2_m$N44B¨Ft5RyBk_Y$-{`CK'˷g~ld8ҞIVO g^]m ҹ_k;>7CW{ h!8C @W 6eK 7.Mp+ zNC.8g?p>p>p>p>Zppΰi?[r/Xr/JқJZ*v]'\˵W2Rn)]tzC5k[ZnbN)ƶ#ͧHɀo oAE "m^]@pQ@#1s tiXk b"NnOmG*ATk%VE~b?- HnQ@ZYN|dhF6Am>uH %@Uu9zlvճ3PN;Q Gݷpe7Sbi>| - |!Y`}=G `+\d+\J}NV||c5]H1 A <|#eӏ|.<¡bl odQNWFݰ.8R ٯ_ 8"e8'ދoEY`:lPgEo FoGr`xh؅Gl#qG' Eu :G+^?Zr/Xs88iyԱ W WH?ڹh0wRؖoF|ng\t= x 7(]x @!R?F+^dk5)[M 9i)㡩c ZQ3ꇙo5I}xy$s~)gx;~w֚k`;ղ [cZ۝P^Zk}\4ƊKΐ)A$m@«m<\ZVÛ$hH7:V(VY$!!?ncY>XNH%G7H% pBn$ұ `02(  ;F~zr]'y- 7]{yYW|v(e5z* _u~EқKی{5jEFFPG媇AAXfG^ A`kOּ0e UA`\prn-h;` `3_*B~Q^7RO|]W6VFex[(Aj\ Xa{}>9 N뺆W^'(M$UKuGֲvtQeW0ao.nJ0<2j~ZG"wS_Hi9B4ra ?~C n]E\Ywi-_.m:z@5jlDuQ@]| 5{s)v[PŵQA5 ykY%O7B/l, KUVAT~V/f_I*(JԅX)W3<|z|OwPC|\iŋ̑0SkBwr"KI PBǕGWe,ӐFrq ɕfs48Rsqgk9P\ˈ)Dak8~1V㱖88OX.JYy j@O xkd^#[nN\7ē޳6,^W|zq8E-~c:kegcF9fk/F4Q6_y8FӔq<&qtϘ4|qL B=CˆNPt5GQyg`"0sEק3c>>98 3S/;zFE0jFsK}€sp>4Gczquړ%E()BIۍ[_?@_D?Oo<`3Nx TX$M/p}kJ9$jH/c'`۠}ԅԿ n諟{!#(Wh-09@U1~%f_{}SQDM?ۨncXZG-zTPq@1>m7o_]+UYCjPf("bٺ5ԬMFQK@W߱zHFZ4Rn~7R(mTU;zH~ V tה 3x`}!I Pwfa'ۦuNם ug/7gWBhu}ƾ> Hnu7'[ժȐ/o>H7Vz7t~7=G㿟sۻh#Pb/z ]\~qz?&az_>?</_$}V'a endstream endobj 3637 0 obj << /Type /XRef /Index [0 3638] /Size 3638 /W [1 3 1] /Root 3635 0 R /Info 3636 0 R /ID [<4E36D0647FB154814DC65ED4A44CF1C8> <4E36D0647FB154814DC65ED4A44CF1C8>] /Length 8647 /Filter /FlateDecode >> stream x%icovq_Wo/ꮮ}߻݋{} +c\a(HD^]R^@$D (q)( rD%4&/9vw{?PoP,PX6_XX2I.1'wUnɭ.qrS…H:a Gܤp ,[+\Y0rX!wQnBV][- L][%X+9Yur7V㍯%2>FGr0lx[`m]\|Sb.-Y.iRE}_n\ 8(Ln\x- yQurv)7Ox N˝ [rsp^\X }|% 9~,W\+Qxn= ^˽ށ?[0U{'2Pn#x,^ <(J {)|/E3V_ /R&={*Q.>[Ѩ- lwTO<>G2ݢ\|Bvm3]Η3)|/19"srw\],wU@wImfr ݺ*BN1})TQ9/x4*"B]+F_N.>Ubﮗk](w@"Trgػ[*r].>w{w\| B-g>;*yb[*{P.zVػuUݣr+N {\UMw{fxV8$^qar&/a.9|9*$co-"wH0*wD.>Vw].vPߔ;!C-wJn0 wW.t ޗ B(r1Sr! >{.S/^ʅ{{B}+Q.ػl*}XOw?Eo=Q/'yb\Erc0Oa ^4S…H.LNb0ͤp ,[+\>5B. 2!\ 0*aZ0H +EƟQ͗LY\-UR6.w[.>)g][.ôtދ@O!>}:L3.<}:L>/<JH{{/&yS{1-΀bﭐ+ ρbﭒ KA&\VEP=B3ob96 bѷNx{ͷ{m>ޣo (++3P;r//@\6#{Ϥ|.?{M* J.F b96 G[|7*{./Ip3bp 1C嘡y_\J6 "9g]a .r&m2L([B΄Ҽ)\ L(0!gBi^rBkIX'*ra+ Q~"B-0f%6.gm^r&.-gm{`Ky>/|Nx8r3#pTΕ[s<%<','i9Kf/zVnqar;\sY<*$go[Aș!U9|3>Vw]<( o97cH4śar61are0C9KfHEXΒ[ʹRm\xc , ^ݓ.|o\e4>\L[\LaOY.&Q䁂'5(9k47 `Fs5 `\Y9%\bO'), O R0Z2ʭ.rְ JX%ZX%X+,:(x OƇ( c6dow lhpl(>)b.-Q +">/Q 8(gq!8,wT.9Gr͐or֗Ͱ8+g-, y8KpA.ΒE$,Y O^g**Ix ~Qxnʹ~ނr<^}/wxNxx<#x,'T+Wg0*Ƚrcr\UMSa|rNx184v0*]SV}eE9LՇBɹdG ˹dr`\o^6cV xf̪b/1gf**oB՛BU;PeU@CB>P_}!Ub(rk>P"TpSӁb(+%b(*@ }`_RU p! {?)lxVMJ;8vp4YP6O5 'F<BP5A9a)G7USZ5O <@ @Y @!t,?PF#{$0J08,EbXKadLdIaGsA X `5LX `=l 6;`'ݰ> ðƒῈw18'$p98e\p 6܁pxے‰Nx 9 ^x =|0Aid&&d l-L. 6d 6&JR8]*ݞ0 2X+`%0`=l 6 `;쀝 Cxp;#c>?CpQ83py(2T \kpNڤpgOpnmw܇cxOA|P:u>A=2)<8RKSިF}URx-r R#gTe:GgOK#Q:G9usDuިF7Q:oyuި3C}4;wq MO x|ŰY,`3M}4_Wa:٧/I:=,WT:թ_ T:7չMunsST:7Yd^yi>V! g>CDؗdaFϐ},KC / M#ߥ!#Yr1 ҐKC&x\7d! ymhQ 76k3lNCx 6fc+G:w))|{OL-hqWrM{N.8'ɣmRVz4lҐwKC}iC.r񐋇\lOqԼ$9#`'}iOmIb g)-հG85*:b؆e)L}pF{qp<{18'M Spp[㸋p T[܃貸 גd ONdx<(g/ ~-BZ%ɻoqaAkdH85Lx@Ak1iQFڅ$Z3YLx|P3ikiL8jikѣ,I~5oMOLn Q>$OJ /ju|O]=$rkA'&iv[Fx*Y ,Nx1e~ܝh#Y$!}&N'h(!TG!v!#h'Hډs. Tg{| oGvh!Jߋ!ci++2vv:*V;(-;ĉ$7QsڡeZvhٹ$9ӲC-;tdpHۡ`YC$oųC;KSoų!W$VJ67wOJ[4md0$?Nah81ng`VmCy ttX$H1m5MijMG/ #>}6}>;ؚxh8vPkZԚ4uLittRR&4=﹤' aR0m짣x{Ts/=yoKlZLGPY{c֞p^!)o>@i{t둬GʤUg{UbL{k,z?"}=;cQwhAB/OЋv*Ʉ h-yL;7HcS. VhnhӈhM`ۋ7"Iq+?Eފ1D㽏Iq a DCDt@LxF2 `]bJb 쇽IDA8cpNI8 spp.% W! F<'xo:{b(A=6aĞp]bg/xW[x|OF/tݹE[nQ(ݢt-tǴR"rK'LkhZ z]Z\Ңj-}--hfiFKK-+-hWim*/4-hqDk{/)^wME6bĮ~lF}G c6yU>y$bhYnEG4vDH5(9o ѕ-<ѳgy=1\Zʥ\Zʥ\Zʥ\Zʥ\Zʥ\Zʥ\Zʥ\Zʥ\Zʥ\Zʥ\Zߺ7P)-_UKYUKYUKYUKT@KT@KT@KT@KT@KT@KT@kT*$2J*겢+G* i*),%i+ˁF V0 QL*,P`e H[T* *e_R| >FfrG GrfhOتUΪYĪ^nV)EP+r tNUGETP3ή(ɲ*O@S Ty*Ft0UTTEREUt+U8'7$9䜓sN99䜓sN99䜓sN99䜓sN99䜓sN99䜓sN99䜓sN994i<:rY*grY*grY*oNߜ9}s7oNߜydkR1fze52S`f-OGgscslٔVUW9_|UW9_||UW9_|UW9_|UW9_|UW9_|UW9_|UW9_|UW9_|G\/ߝƝ*)~IS~ʢ¤9r|5QTbQNeleg9ƾl.k+*(w8^Ec[_BV%Ʊ0˗MeW~aoiƥa#4jVO%o6n6n05F=YX UUc jKCSڝ0čMM MmLaaFf SK`tנB9AeThPAThPaڸ`6ر᢭ANkAjAjA!7x o]z cCo^Б0E65̓ w Ӱw W$?ejY"߃SԺ;NSkԝt*:uWEj)"}x#%|j Z§%|j Z§%|jAZߩwڋ5»" O_ZH-SRV;(RKԊ>?>OS<>OS<>O-XR? ~T@ƋJ=uEԚ=uWEjZۧ=[V+Rk]u|^*?uEjo"O-ZnH-SkG}Ԣ?_ a A RX K`), X `5LX 6B))yj*_6f[alvn{apa8GpNi8g2\p .CU܄[p]L'BNLxv gtg-ȴg(܃ swM{2wd2d57sL̅W٧>}O\7%}sI\7%}sI\7%}sI7%}sI\7 '|} '|} '|} '|} '|} '|} '|} '|} '|} '|} '|} '|}&s9R_- endstream endobj startxref 346988 %%EOF QATzip-1.3.1/include/000077500000000000000000000000001500263377000143125ustar00rootroot00000000000000QATzip-1.3.1/include/qatzip.h000077500000000000000000003340061500263377000160040ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /** ***************************************************************************** * @file qatzip.h * * @defgroup qatZip Data Compression API * * @description * These functions specify the API for data compression operations. * * @remarks * * *****************************************************************************/ #ifndef _QATZIP_H #define _QATZIP_H #ifdef __cplusplus extern"C" { #endif #include #include /** ***************************************************************************** * @ingroup qatZip * QATzip Major Version Number * @description * The QATzip API major version number. This number will be incremented * when significant changes to the API have occurred. * The combination of the major and minor number definitions represent * the complete version number for this interface. * *****************************************************************************/ #define QATZIP_API_VERSION_NUM_MAJOR (2) /** ***************************************************************************** * @ingroup qatZip * QATzip Minor Version Number * @description * The QATzip API minor version number. This number will be incremented * when minor changes to the API have occurred. The combination of the major * and minor number definitions represent the complete version number for * this interface. *****************************************************************************/ #define QATZIP_API_VERSION_NUM_MINOR (5) /* Define a macro as an integer to test */ #define QATZIP_API_VERSION (QATZIP_API_VERSION_NUM_MAJOR * 10000 + \ QATZIP_API_VERSION_NUM_MINOR * 100) /** * These macros define how the project will be built * QATZIP_LINK_DLL must be defined if linking the DLL * QATZIP_BUILD_DLL must be defined when building a DLL * No definition required if building the project as static library */ #if defined QATZIP_LINK_DLL #define QATZIP_API __declspec(dllimport) #elif defined QATZIP_BUILD_DLL #define QATZIP_API __declspec(dllexport) #else #define QATZIP_API #endif /** ***************************************************************************** * * This API provides access to underlying compression functions in QAT * hardware. The API supports an implementation that provides compression * service in software if all of the required resources are not available * to execute the compression service in hardware. * * The API supports threaded applications. * Applications can create threads and each of these threads can invoke the * API defined herein. * * For simplicity, initializations and setup function calls are not * required to obtain compression services. If the initialization and setup * functions are not called before compression or decompression requests, then * they will be called with default arguments from within the compression or * decompression functions. This results in several legal calling scenarios, * described below. * * Scenario 1 - All functions explicitly invoked by caller, with all arguments provided. * * qzInit(&sess, sw_backup); * qzSetupSession(&sess, ¶ms); * qzCompress(&sess, src, &src_len, dest, &dest_len, 1); * qzDecompress(&sess, src, &src_len, dest, &dest_len); * qzTeardownSession(&sess); * qzClose(&sess); * * * Scenario 2 - Initialization function called, setup function not invoked by caller. * This scenario can be used to specify the sw_backup argument to * qzInit. * * qzInit(&sess, sw_backup); * qzCompress(&sess, src, &src_len, dest, &dest_len, 1); * calls qzSetupSession(sess, NULL); * qzTeardownSession(&sess); * qzClose(&sess); * * * Scenario 3 - Calling application simply invokes the actual qzCompress functions. * * qzCompress(&sess, src, &src_len, dest, &dest_len, 0); * calls qzInit(sess, 1); * calls qzSetupSession(sess, NULL); * qzCompress(&sess, src, &src_len, dest, &dest_len, 1); * * Notes: Invoking qzSetupSession with NULL for params sets up a session with * default session attributed, detailed in the function description below. * * If an application terminates without invoking tear down and close * functions, process termination will invoke memory and hardware instance * cleanup. * * If a thread terminates without invoking tear down and close functions, * memory and hardware are not cleaned up until the application exits. * * Additions for QAT 2.0 and beyond platforms though Extending * QzSessionParamsGen3_T, QzDataFormatGen3_T and Using qzSetupSessionGen3 * to setup session. * 1. Addition of LZ4 and LZ4s * 2. Addition of post processing functions for out of LZ4s * 3. Compression level up to 12 for LZ4 and LZ4s * 4. Support for gzip header with additional compression algorithms * *****************************************************************************/ /** ***************************************************************************** * @ingroup qatZip * Supported Huffman Headers * * @description * This enumerated list identifies the Huffman header types * supported by QATzip. * *****************************************************************************/ typedef enum QzHuffmanHdr_E { QZ_DYNAMIC_HDR = 0, /**< Full Dynamic Huffman Trees */ QZ_STATIC_HDR /**< Static Huffman Trees */ } QzHuffmanHdr_T; /** ***************************************************************************** * @ingroup qatZip * Supported memory types * * @description * This enumerated list identifies memory types supported * by QATzip. * *****************************************************************************/ typedef enum PinMem_E { COMMON_MEM = 0, /**< Allocate non-contiguous memory */ PINNED_MEM /**< Allocate contiguous memory */ } PinMem_T; /** ***************************************************************************** * @ingroup qatZip * Compress or decompress setting * * @description * This enumerated list identifies the session directions * supported by QATzip. A session can be compress, decompress * or both. * *****************************************************************************/ typedef enum QzDirection_E { QZ_DIR_COMPRESS = 0, /**< Session will be used for compression */ QZ_DIR_DECOMPRESS, /**< Session will be used for decompression */ QZ_DIR_BOTH /**< Session will be used for both compression and decompression */ } QzDirection_T; /** ***************************************************************************** * @ingroup qatZip * Streaming API input and output format * * @description * This enumerated list identifies the data format supported by * QATzip streaming API. A format can be raw deflate data block, deflate * block wrapped by GZip header and footer, or deflate data block wrapped * by GZip extension header and footer. * *****************************************************************************/ typedef enum QzDataFormat_E { QZ_DEFLATE_4B = 0, /**< Data is in raw deflate format with 4 byte header */ QZ_DEFLATE_GZIP, /**< Data is in deflate wrapped by GZip header and footer */ QZ_DEFLATE_GZIP_EXT, /**< Data is in deflate wrapped by GZip extended header and footer */ QZ_DEFLATE_RAW, /**< Data is in raw deflate format */ QZ_FMT_NUM } QzDataFormat_T; /** ***************************************************************************** * @ingroup qatZip * Supported polling mode * * @description * Specifies whether the instance must be busy polling, * or be periodical polling. * *****************************************************************************/ typedef enum QzPollingMode_E { QZ_PERIODICAL_POLLING = 0, /**< No busy polling */ QZ_BUSY_POLLING, /**< busy polling */ } QzPollingMode_T; /** ***************************************************************************** * @ingroup qatZip * Supported checksum type * * @description * This enumerated list identifies the checksum type for input/output * data. The format can be CRC32, Adler or none. * *****************************************************************************/ typedef enum QzCrcType_E { QZ_CRC32 = 0, /**< CRC32 checksum */ QZ_ADLER, /**< Adler checksum */ NONE /**< No checksum */ } QzCrcType_T; /** ***************************************************************************** * @ingroup qatZip * Software Component type * * @description * This enumerated list specifies the type of software that is being * described. * *****************************************************************************/ typedef enum QzSoftwareComponentType_E { QZ_COMPONENT_FIRMWARE = 0, QZ_COMPONENT_KERNEL_DRIVER, QZ_COMPONENT_USER_DRIVER, QZ_COMPONENT_QATZIP_API, QZ_COMPONENT_SOFTWARE_PROVIDER } QzSoftwareComponentType_T; /** ***************************************************************************** * @ingroup qatZip * QATzip Session Status definitions and function return codes * * @description * This list identifies valid values for session status and function * return codes. * *****************************************************************************/ #define QZ_OK (0) /**< Success */ #define QZ_DUPLICATE (1) /**< Can not process function again. No failure */ #define QZ_FORCE_SW (2) /**< Using SW: Switch to software because of previous block */ #define QZ_PARAMS (-1) /**< Invalid parameter in function call */ #define QZ_FAIL (-2) /**< Unspecified error */ #define QZ_BUF_ERROR (-3) /**< Insufficient buffer error */ #define QZ_DATA_ERROR (-4) /**< Input data was corrupted */ #define QZ_TIMEOUT (-5) /**< Operation timed out */ #define QZ_INTEG (-100) /**< Integrity checked failed */ #define QZ_NO_HW (11) /**< Using SW: No QAT HW detected */ #define QZ_NO_MDRV (12) /**< Using SW: No memory driver detected */ #define QZ_NO_INST_ATTACH (13) /**< Using SW: Could not attach to an instance */ #define QZ_LOW_MEM (14) /**< Using SW: Not enough pinned memory */ #define QZ_LOW_DEST_MEM (15) /**< Using SW: Not enough pinned memory for dest buffer */ #define QZ_UNSUPPORTED_FMT (16) /**< Using SW: QAT device does not support data format */ #define QZ_NONE (100) /**< Device uninitialized */ #define QZ_NOSW_NO_HW (-101) /**< Not using SW: No QAT HW detected */ #define QZ_NOSW_NO_MDRV (-102) /**< Not using SW: No memory driver detected */ #define QZ_NOSW_NO_INST_ATTACH (-103) /**< Not using SW: Could not attach to instance */ #define QZ_NOSW_LOW_MEM (-104) /**< Not using SW: not enough pinned memory */ #define QZ_NO_SW_AVAIL (-105) /**sw_backup that is set to 1. * * Before this function is called, the hardware must have been * successfully started via qzInit. * * If *sess includes an existing hardware or software session, then * QZ_DUPLICATE will be returned without modifying the existing session. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] params Parameters for session * * * @retval QZ_OK Function executed successfully. A hardware * or software based compression session has been * created * @retval QZ_DUPLICATE *sess includes an existing hardware or * software session * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @retval QZ_NOSW_NO_HW No hardware and no sw session being * established * @retval QZ_NOSW_NO_MDRV No memory driver. No software session * established * @retval QZ_NOSW_NO_INST_ATTACH No instance available * No software session established * @retval QZ_NO_LOW_MEM Not enough pinned memory available * No software session established * @retval QZ_UNSUPPORTED_FMT No support for requested algorithm; * using software * @retval QZ_NOSW_UNSUPPORTED_FMT No support for requested algorithm; * No software session established * @retval QZ_NO_SW_AVAIL No software is available. This may returned * when sw_backup is set to 1 but the session * does not support software backup or software * backup is unavailable to the application. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzSetupSession(QzSession_T *sess, QzSessionParams_T *params); QATZIP_API int qzSetupSessionDeflate(QzSession_T *sess, QzSessionParamsDeflate_T *params); QATZIP_API int qzSetupSessionLZ4(QzSession_T *sess, QzSessionParamsLZ4_T *params); QATZIP_API int qzSetupSessionLZ4S(QzSession_T *sess, QzSessionParamsLZ4S_T *params); QATZIP_API int qzSetupSessionDeflateExt(QzSession_T *sess, QzSessionParamsDeflateExt_T *params); /** ***************************************************************************** * @ingroup qatZip * Compress a buffer * * @description * This function will compress a buffer if either a hardware based * session or a software based session is available. If no session has * been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and qzSetupSession. * * The resulting compressed block of data will be composed of one or more * gzip blocks, as per RFC 1952. * * This function will place completed compression blocks in the output * buffer. * * The caller must check the updated src_len. This value will be the * number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter dest_len will be set to the number of bytes produced in * the destination buffer. This value may be zero if no data was produced * which may occur if the consumed data is retained internally. A * possible reason for this may be small amounts of data in the src * buffer. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in,out] src_len Length of source buffer. Modified to number * of bytes consumed * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of compressed data when * function returns * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * @param[in,out] ext_rc qzCompressExt only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last); QATZIP_API int qzCompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Compress a buffer and return the CRC checksum * * @description * This function will compress a buffer if either a hardware based * session or a software based session is available. If no session has been * established - as indicated by the contents of *sess - then this function * will attempt to set up a session using qzInit and qzSetupSession. * * The resulting compressed block of data will be composed of one or more * gzip blocks, as per RFC 1952. * * This function will place completed compression blocks in the output * buffer and put CRC32 or CRC64 checksum for compressed input data in * the user provided buffer *crc. * * The caller must check the updated src_len. This value will be the * number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter dest_len will be set to the number of bytes produced in * the destination buffer. This value may be zero if no data was produced * which may occur if the consumed data is retained internally. A * possible reason for this may be small amounts of data in the src * buffer. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in,out] src_len Length of source buffer. Modified to number * of bytes consumed * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of compressed data when * function returns * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * @param[in,out] crc Pointer to CRC32 or CRC64 checksum buffer * @param[in,out] ext_rc qzCompressCrcExt or qzCompressCrc64Ext only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompressCrc(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc); QATZIP_API int qzCompressCrcExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc, uint64_t *ext_rc); QATZIP_API int qzCompressCrc64(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *crc); QATZIP_API int qzCompressCrc64Ext(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *crc, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Compress a buffer and write metadata for each compressed block into * the opaque metadata structure. * * @description * This function will compress a buffer if either a hardware based * session or a software based session is available. If no session has * been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and * qzSetupSession. * * This function will place completed compression blocks in the output * buffer. * * The caller must check the updated src_len. This value will be the * number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter dest_len will be set to the number of bytes produced in * the destination buffer. This value may be zero if no data was produced * which may occur if the consumed data is retained internally. A * possible reason for this may be small amounts of data in the src * buffer. * * The metadata for each compressed block will be written into the opaque * metadata structure specified as function param metadata. * * comp_thrshold specifies compression threshold of a block. * If compressed size of the block is > comp_thrshold, the * compression function shall copy the uncompressed data to the output * buffer and set the size of the block in the metadata to the size of the * uncompressed block. If the compressed size of the block is <= * comp_thrshold, the compressed data will be copied to the output buffer * and the compressed size will be set in the metadata. * * hw_buff_sz_override specifies the data size to be used for the each * compression operation. It overrides the hw_buff_sz parameter specified * at session creation. If 0 is provided for this parameter, then the * hw_buff_sz specified at session creation will be used. Memory for the * opaque metadata structure should be allocated based on the hw_buff_sz * or the hw_buff_sz_override that is used for the compression operation. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and * session data) * @param[in] src Point to source buffer. * @param[in,out] src_len Length of source buffer. Modified to * number of bytes consumed. * @param[in] dest Point to destination buffer. * @param[in,out] dest_len Length of destination buffer. Modified * to length of compressed data when * function returns. * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * @param[in,out] ext_rc If not NULL, ext_rc point to a location * where extended return codes may be * returned. See extended return code * section for details. if NULL, no * extended information will be provided. * @param[in,out] metadata Pointer to opaque metadata. * @param[in] hw_buff_sz_override Data size to be used for compression. * @param[in] comp_thrshold Compressed block threshold. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess or metadata is NULL or Member of * params is invalid, hw_buff_sz_override * is invalid data size. * @retval QZ_METADATA_OVERFLOW Unable to populate metadata due to * insufficient memory allocated. * @retval QZ_NOT_SUPPORTED Compression with metadata is not * supported with given algorithm * or format. * @retval QZ_NOSW_NO_HW Function did not find an installed * kernel driver or software provider. * @retval QZ_NOSW_NO_INST_ATTACH No instance available. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompressWithMetadataExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *ext_rc, QzMetadataBlob_T metadata, uint32_t hw_buff_sz_override, uint32_t comp_thrshold); /** ***************************************************************************** * @ingroup qatZip * Compress a buffer with asynchronous or synchronous model * * @description * These functions has the same compression ability as "qzCompress", * but with asynchronous or synchronous model. * * If user provide the callback function(callback is not NULL), it would * work as asynchronous model. Otherwise, it would work as synchronous * model, just like "qzCompress". * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * No * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Pointer to source buffer. * @param[in] dest Pointer to destination buffer. * @param[in] callback User-defined callback Function to be called upon * completion of the compression operation. it could * be NULL, then it's an synchronous call, otherwise, * it's asynchronous call. * @param[in,out] qzResults Pointer to QzResult, It have to allocate by user. * * @retval QZ_OK Request submit successfully. * @retval QZ_FAIL Request submit failed. * @retval QZ_PARAMS *sess is NULL or member of params is invalid. * * @pre * None * @post * None * @note * None * @see * None * *****************************************************************************/ QATZIP_API int qzCompress2(QzSession_T *sess, const unsigned char *src, unsigned char *dest, qzAsyncCallbackFn callback, QzResult_T *qzResults); /** ***************************************************************************** * @ingroup qatZip * Decompress a buffer * * @description * This function will decompress a buffer if either a hardware based * session or a software based session is available. If no session has been * established - as indicated by the contents of *sess - then this function * will attempt to set up a session using qzInit and qzSetupSession. * * The input compressed block of data will be composed of one or more * gzip blocks, as per RFC 1952. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in] src_len Length of source buffer. Modified to * length of processed compressed data * when function returns * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of decompressed data when * function returns * @param[in,out] ext_rc qzDecompressExt only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len); QATZIP_API int qzDecompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Decompress a buffer and return the CRC checksum * * @description * This function will decompress a buffer if either a hardware based * session or a software based session is available. If no session has been * established - as indicated by the contents of *sess - then this function * will attempt to set up a session using qzInit and qzSetupSession. * * This function will place completed decompression chunks in the output * buffer and put the CRC32 or CRC64 checksum for compressed input data in * the user provided buffer *crc. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in] src_len Length of source buffer. Modified to * length of processed compressed data * when function returns * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of decompressed data when * function returns * @param[in,out] crc Pointer to CRC32 or CRC64 checksum buffer * @param[in,out] ext_rc qzDecompressCrcExt or qzDecompressCrc64Ext only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompressCrc(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned long *crc); QATZIP_API int qzDecompressCrcExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned long *crc, uint64_t *ext_rc); QATZIP_API int qzDecompressCrc64(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *crc); QATZIP_API int qzDecompressCrc64Ext(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *crc, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Decompress a buffer with metadata. * * @description * This function will decompress a buffer if either a hardware based * session or a software based session is available. * If no session has been established - as indicated by the content * of *sess - then this function will attempt to set up a session using * qzInit and qzSetupSession. * * The metadata function parameter specifies metadata of compressed file * which can be used for regular or parallel decompression. * * hw_buff_sz_override specifies the data size to be used for the each * decompression operation. It overrides the hw_buff_sz parameter specified * at session creation. If 0 is provided for this parameter, then the * hw_buff_sz specified at session creation will be used. Memory for the * opaque metadata structure should be allocated based on the hw_buff_sz * or the hw_buff_sz_override that is used for the compression operation. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in] src_len Length of source buffer. Modified to * length of processed compressed data * when function returns * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of decompressed data when * function returns * @param[in,out] ext_rc If not NULL, ext_rc points to a location * where extended return codes may be * returned. See extended return code * section for details. * if NULL, no extended information will be * provided. * @param[in] metadata Pointer to opaque metadata. * @param[in] hw_buff_sz_override Expected size of decompressed block. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS *sess or metadata is NULL or Member of * params is invalid, hw_buff_sz_override * is invalid data size. * @retval QZ_METADATA_OVERFLOW Unable to populate metadata due to * insufficient memory allocated. * @retval QZ_NOT_SUPPORTED Decompression with metadata is not * supported with given algorithm * or format. * @retval QZ_NOSW_NO_HW Function did not find an installed * kernel driver or software provider. * @retval QZ_NOSW_NO_INST_ATTACH No instance available. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompressWithMetadataExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc, QzMetadataBlob_T metadata, uint32_t hw_buff_sz_override); /** ***************************************************************************** * @ingroup qatZip * Decompress a buffer with asynchronous or synchronous model * * @description * These functions has the same decompression ability as "qzDecompress", * but with asynchronous or synchronous model. * * If user provide the callback function(callback is not NULL), it would * work as asynchronous model. Otherwise, it would work as synchronous * model, just like "qzDecompress". * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * No * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Pointer to source buffer containing compressed data. * @param[in] dest Pointer to destination buffer where decompressed * data will be stored. * @param[in] callback User-defined callback function to be called upon * completion of the decompression operation. it could * be NULL, then it's an synchronous call, otherwise, * it's asynchronous call. * @param[in,out] qzResults Pointer to QzResult, It have to allocate by user. * * @retval QZ_OK Decompression request submitted successfully. * @retval QZ_FAIL Decompression request submission failed. * @retval QZ_PARAMS *sess is NULL or member of params is invalid. * * @pre * None * @post * None * @note * None * @see * None * *****************************************************************************/ QATZIP_API int qzDecompress2(QzSession_T *sess, const unsigned char *src, unsigned char *dest, qzAsyncCallbackFn callback, QzResult_T *qzResults); /** ***************************************************************************** * @ingroup qatZip * Uninitialize a QATzip session * * @description * This function disconnects a session from a hardware instance and * deallocates buffers. If no session has been initialized, then no * action will take place. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzTeardownSession(QzSession_T *sess); /** ***************************************************************************** * @ingroup qatZip * Terminates a QATzip session * * @description * This function closes the connection with QAT. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzClose(QzSession_T *sess); /** ***************************************************************************** * @ingroup qatZip * Get current QAT status * * @description * This function retrieves the status of QAT in the platform. * The status structure will be filled in as follows: * qat_hw_count Number of discovered QAT devices on PCU bus * qat_service_init 1 if qzInit has been successfully run, 0 otherwise * qat_mem_drvr 1 if the QAT memory driver is installed, 0 otherwise * qat_instance_attach 1 if session has attached to a hardware instance, * 0 otherwise * memory_alloced Amount of memory, in kilobytes, from kernel or huge * pages allocated by this process/thread. * using_huge_pages 1 if memory is being allocated from huge pages, 0 if * memory is being allocated from standard kernel memory * hw_session_status Hw session status: one of: * QZ_OK * QZ_FAIL * QZ_NO_HW * QZ_NO_MDRV * QZ_NO_INST_ATTACH * QZ_LOW_MEM * QZ_NOSW_NO_HW * QZ_NOSW_NO_MDRV * QZ_NOSW_NO_INST_ATTACH * QZ_NOSW_LOW_MEM * QZ_NO_SW_AVAIL * * Applications should verify the elements of the status structure are * correct for the required operations. It should be noted that some * information will be available only after qzInit has been called, either * implicitly or explicitly. The qat_service_init element of the status * structure will indicate if initialization has taken place. * * The hw_session_status will depend on the availability of hardware based * compression and software based compression. The following table indicates * what hw_session_status based on the availability of compression engines * and the sw_backup flag. * * | HW | SW Engine | sw_backup | hw_session_stat | * | avail | avail | setting | | * |-------|-----------|-----------|-------------------| * | N | N | 0 | QZ_NOSW_NO_HW | * | N | N | 1 | QZ_NOSW_NO_HW | * | N | Y | 0 | QZ_FAIL | * | N | Y | 1 | QZ_NO_HW (1) | * | Y | N | 0 | QZ_OK | * | Y | N | 1 | QZ_NO_SW_AVAIL (2)| * | Y | Y | 0 | QZ_OK | * | Y | Y | 1 | QZ_OK | * * Note 1: * If an application indicates software backup is required by setting * sw_backup=1, and a software engine is available and if no hardware based * compression engine is available then the hw_session_status will be set * to QZ_NO_HW. All compression and decompression will use the software * engine. * Note 2: * If an application indicates software backup is required by setting * sw_backup=1, and if no software based compression engine is available * then the hw_session_status will be set to QZ_NO_SW_AVAIL. In this * case, QAT based compression may be used however no software backup * will available. * If the application relies on software backup being avialable, then * this return code can be treated as an error. * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] status Pointer to QATzip status structure * @retval QZ_OK Function executed successfully. The hardware based * compression session has been created * @retval QZ_PARAMS *status is NULL * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetStatus(QzSession_T *sess, QzStatus_T *status); /** ***************************************************************************** return end of stream. *****************************************************************************/ QATZIP_API int qzGetDeflateEndOfStream(QzSession_T *sess, unsigned char *endofstream); /** ***************************************************************************** * @ingroup qatZip * Get the maximum compressed output length * * @description * Get the maximum compressed output length. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] * src_sz Input data length in bytes * sess Session handle * (pointer to opaque instance and session data) * * @retval dest_sz Max compressed data output length in bytes. * When src_sz is equal to 0, the return value is QZ_COMPRESSED_SZ_OF_EMPTY_FILE(34). * When integer overflow happens, the return value is 0 * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ #define QZ_SKID_PAD_SZ 48 #define QZ_COMPRESSED_SZ_OF_EMPTY_FILE 34 QATZIP_API unsigned int qzMaxCompressedLength(unsigned int src_sz, QzSession_T *sess); /** ***************************************************************************** * @ingroup qatZip * Set default QzSessionParams_T value * * @description * Set default QzSessionParams_T value. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] * defaults The pointer to value to be set as default * * @retval QZ_OK Success on setting default value * @retval QZ_PARAM Fail to set default value * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzSetDefaults(QzSessionParams_T *defaults); QATZIP_API int qzSetDefaultsDeflate(QzSessionParamsDeflate_T *defaults); QATZIP_API int qzSetDefaultsLZ4(QzSessionParamsLZ4_T *defaults); QATZIP_API int qzSetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults); QATZIP_API int qzSetDefaultsDeflateExt(QzSessionParamsDeflateExt_T *defaults); /** ***************************************************************************** * @ingroup qatZip * Get default QzSessionParams_T value * * @description * Get default QzSessionParams_T value. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] defaults The pointer to default value * * @retval QZ_OK Success on getting default value * @retval QZ_PARAM Fail to get default value * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetDefaults(QzSessionParams_T *defaults); QATZIP_API int qzGetDefaultsDeflate(QzSessionParamsDeflate_T *defaults); QATZIP_API int qzGetDefaultsLZ4(QzSessionParamsLZ4_T *defaults); QATZIP_API int qzGetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults); QATZIP_API int qzGetDefaultsDeflateExt(QzSessionParamsDeflateExt_T *defaults); /** ***************************************************************************** * @ingroup qatZip * Allocate different types of memory * * @description * Allocate different types of memory. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sz Memory size to be allocated * @param[in] numa NUMA node (0 or greater) from which to allocate memory * QZ_AUTO_SELECT_NUMA_NODE (-1) to auto select optimal NUMA node * @param[in] force_pinned PINNED_MEM allocate contiguous memory * COMMON_MEM allocate non-contiguous memory * * @retval NULL Fail to allocate memory * @retval address The address of allocated memory * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API void *qzMalloc(size_t sz, int numa, int force_pinned); /** ***************************************************************************** * @ingroup qatZip * Allocate memory for metadata. * * @description * Allocate memory for metadata. The function takes the size of entire * input buffer and the data size at which individual block will be * compressed. These parameters will be used to calculate and allocate * required memory for metadata. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in, out] metadata Pointer to opaque metadata. * @param[in] data_size Size of uncompressed buffer. * @param[in] hw_buff_sz Data size at which individual block * will be compressed. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *metadata is NULL, or data_size is 0, * or data_size is greater than 1GB, or * incorrect hw_buff_sz. * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzAllocateMetadata(QzMetadataBlob_T *metadata, size_t data_size, uint32_t hw_buff_sz); /** ***************************************************************************** * @ingroup qatZip * Free allocated memory * * @description * Free allocated memory. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] m Memory address to be freed * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API void qzFree(void *m); /** ***************************************************************************** * @ingroup qatZip * Free memory allocated for metadata. * * @description * Free memory allocated for metadata. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] metadata Pointer to opaque metadata. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS metadata is NULL. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzFreeMetadata(QzMetadataBlob_T metadata); /** ***************************************************************************** * @ingroup qatZip * Check whether the address is available * * @description * Check whether the address is available. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] * a Address to be checked * * @retval 1 The address is available * @retval 0 The address is not available * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMemFindAddr(unsigned char *a); /** ***************************************************************************** * @ingroup qatZip * QATzip Stream data storage * * @description * This structure contains metadata needed for stream operation. * *****************************************************************************/ typedef struct QzStream_S { unsigned int in_sz; /**< Set by application, reset by QATzip to indicate consumed data */ unsigned int out_sz; /**< Set by application, reset by QATzip to indicate processed data */ unsigned char *in ; /**< Input data pointer set by application */ unsigned char *out ; /**< Output data pointer set by application */ unsigned int pending_in; /**< Unprocessed bytes held in QATzip */ unsigned int pending_out; /**< Processed bytes held in QATzip */ QzCrcType_T crc_type; /**< Checksum type in Adler, CRC32 or none */ unsigned int crc_32; /**< Checksum value */ unsigned long long reserved; /**< Reserved for future use */ void *opaque; /**< Internal storage managed by QATzip */ } QzStream_T; /** ***************************************************************************** * @ingroup qatZip * Compress data in stream and return checksum * * @description * This function will compress data in stream buffer if either a hardware * based session or a software based session is available. If no session * has been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and qzSetupSession. * The function will start to compress the data when receiving sufficient * number of bytes - as defined by hw_buff_sz in QzSessionParams_T - or * reaching the end of input data - as indicated by last parameter. * * The resulting compressed block of data will be composed of one or more * gzip blocks, per RFC 1952, or deflate blocks, per RFC 1951. * * This function will place completed compression blocks in the *out * of QzStream_T structure and put checksum for compressed input data * in crc32 of QzStream_T structure. * * The caller must check the updated in_sz of QzStream_T. This value will * be the number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter out_sz in QzStream_T will be set to the number of bytes * produced in the destination buffer. This value may be zero if no data * was produced which may occur if the consumed data is retained internally. * A possible reason for this may be small amounts of data in the src * buffer. * * The caller must check the updated pending_in of QzStream_T. This value * will be the number of unprocessed bytes held in QATzip. The calling API * may have to feed more input data or indicate reaching the end of input * and call again. * * The caller must check the updated pending_out of QzStream_T. This value * will be the number of processed bytes held in QATzip. The calling API * may have to process the destination buffer and call again. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in,out] strm Stream handle * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * (always set to 1 in the Microsoft(R) * Windows(TM) QATzip implementation) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last); /** ***************************************************************************** * @ingroup qatZip * Decompress data in stream and return checksum * * @description * This function will decompress data in stream buffer if either a hardware * based session or a software based session is available. If no session * has been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and qzSetupSession. * The function will start to decompress the data when receiving sufficient * number of bytes - as defined by hw_buff_sz in QzSessionParams_T - or * reaching the end of input data - as indicated by last parameter. * * The input compressed block of data will be composed of one or more * gzip blocks, per RFC 1952, or deflate blocks, per RFC 1951. * * This function will place completed decompression blocks in the *out * of QzStream_T structure and put checksum for decompressed data in * crc32 of QzStream_T structure. * * The caller must check the updated in_sz of QzStream_T. This value will * be the number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter out_sz in QzStream_T will be set to the number of bytes * produced in the destination buffer. This value may be zero if no data * was produced which may occur if the consumed data is retained internally. * A possible reason for this may be small amounts of data in the src * buffer. * * The caller must check the updated pending_in of QzStream_T. This value * will be the number of unprocessed bytes held in QATzip. The calling API * may have to feed more input data or indicate reaching the end of input * and call again. * * The caller must check the updated pending_out of QzStream_T. This value * will be the number of processed bytes held in QATzip. The calling API * may have to process the destination buffer and call again. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in,out] strm Stream handle * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @retval QZ_NEED_MORE *last is set but end of block is absent * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last); /** ***************************************************************************** * @ingroup qatZip * Terminates a QATzip stream * * @description * This function disconnects stream handle from session handle then reset * stream flag and release stream memory. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzEndStream(QzSession_T *sess, QzStream_T *strm); /** ***************************************************************************** * @ingroup qatZip * Requests the release versions of the QATZip Library sub components. * * @description * Populate an array of pre-allocated QzSoftwareVersionInfo_T structs * with the names and versions of QATzip sub components. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in, out] api_info pointer to a QzSoftwareVersionInfo_T * structure to populate. * @param[in, out] num_elem pointer to an unsigned int expressing * how many elements are in the array * provided in api_info * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_NO_SW_AVAIL Function did not find a software provider for * fallback * @retval QZ_NO_HW Function did not find an installed kernel driver * @retval QZ_NOSW_NO_HW Functions did not find an installed kernel driver or software provider * @retval QZ_PARAMS *api_info or num_elem is NULL or not large * enough to store all QzSoftwareVersionInfo_T * structures * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetSoftwareComponentVersionList(QzSoftwareVersionInfo_T *api_info, unsigned int *num_elem); /** ***************************************************************************** * @ingroup qatZip * Requests the number of Software components used by the QATZip library * * @description * This function populates num_elem variable with the number of * software components available to the library. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in, out] num_elem pointer to an unsigned int to populate * how many software componets are associated * with QATZip * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_NO_SW_AVAIL Function did not find a software provider for * fallback * @retval QZ_NO_HW Function did not find an installed kernel driver * @retval QZ_NOSW_NO_HW Functions did not find an installed kernel driver or software provider * @retval QZ_PARAMS *num_elem is NULL * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetSoftwareComponentCount(unsigned int *num_elem); /** ***************************************************************************** * @ingroup qatZip * Requests the CRC64 configuration of the provided session * * @description * This function populates crc64_config with the CRC64 configuration * details of sess. This function has a dependency on invoking a setup * session function first. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[out] crc64_config Configuration for CRC 64 generation. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Session was not setup * @retval QZ_PARAMS *sess or *crc64_config is NULL * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetSessionCrc64Config(QzSession_T *sess, QzCrc64Config_T *crc64_config); /** ***************************************************************************** * @ingroup qatZip * Requests the CRC32 configuration of the provided session * * @description * This function populates crc32_config with the CRC32 configuration * details of sess. This function has a dependency on invoking a setup * session function first. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[out] crc32_config Configuration for CRC32 generation. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Session was not setup * @retval QZ_PARAMS *sess or *crc32_config is NULL * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetSessionCrc32Config(QzSession_T *sess, QzCrc32Config_T *crc32_config); /** ***************************************************************************** * @ingroup qatZip * Sets the CRC64 configuration of the provided session with a * user defined set of parameters. * * @description * This function populates the CRC64 configuration details of sess * using the paramaters provided in crc64_config. This function has a * dependency on invoking a setup session function first. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] crc64_config Configuration for CRC64 generation. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Session was not setup * @retval QZ_PARAMS *sess or *crc64_config is NULL or contains * invalid paramters. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzSetSessionCrc64Config(QzSession_T *sess, QzCrc64Config_T *crc64_config); /** ***************************************************************************** * @ingroup qatZip * Sets the CRC32 configuration of the provided session with a * user defined set of parameters. * * @description * This function populates the CRC32 configuration details of sess * using the paramaters provided in crc32_config. This function has a * dependency on invoking a setup session function first. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] crc32_config Configuration for CRC32 generation. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Session was not setup * @retval QZ_PARAMS *sess or *crc32_config is NULL or contains * invalid parameters. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzSetSessionCrc32Config(QzSession_T *sess, QzCrc32Config_T *crc32_config); /** ***************************************************************************** * @ingroup qatZip * Read metadata parameters. * * @description * This function reads metadata information for the block specified by the * function param block_num. * * block_offset returns offset value in bytes from the previous compressed * block of the compressed data. * * block_size returns the block size in bytes of the compressed block. * Some blocks may be uncompressed if size > threshold as specified during * compression and the size returned will reflect the same. * * block_flags returns the value 1 if the data is compressed and 0 if the * data is not compressed. * * block_hash returns the xxHash value of the plain text of the hw_buff_sz * payload sent for compression operation. * * If NULL is specified for any of the metadata parameters (block_offset, * block_size, block_flags, block_hash) reading the parameter value * will be ignored. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] block_num Block number of which metadata * information should be read. * @param[in] metadata Pointer to opaque metadata. * @param[in, out] block_offset Pointer to the block offset value. * @param[in, out] block_size Pointer to the block size value. * @param[in, out] block_flags Pointer to the block flags value. * @param[in, out] block_hash Pointer to the block xxHash value. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS Metadata is NULL. * @retval QZ_OUT_OF_RANGE block_num specified is out of range. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMetadataBlockRead(uint32_t block_num, QzMetadataBlob_T metadata, uint32_t *block_offset, uint32_t *block_size, uint32_t *block_flags, uint32_t *block_hash); /** ***************************************************************************** * @ingroup qatZip * Write metadata parameters. * * @description * This function writes metadata information for the block specified by the * function param block_num. * * block_offset writes offset value in bytes from the previous compressed * block of the compressed data. * * block_size writes the block size in bytes of the compressed block. * * block_flags causes the metadata to indicate the data is compressed if * passed a value of 1 and indicates uncompressed if value * passed is zero (0). * * block_hash writes the xxHash value of the plain text of the hw_buff_sz * payload sent for compression operation. * * If NULL is specified for any of the metadata parameters (block_offset, * block_size, block_flags, block_hash) writing the parameter value * into metadata will be ignored. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] block_num Block number into which metadata information * should be written. * @param[in, out] metadata Pointer to opaque metadata. * @param[in] block_offset Pointer to the block offset value. * @param[in] block_size Pointer to the block size value. * @param[in] block_flags Pointer to the block flags value. * @param[in] block_hash Pointer to the block xxHash value. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS Metadata is NULL. * @retval QZ_OUT_OF_RANGE block_num specified is out of range. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMetadataBlockWrite(uint32_t block_num, QzMetadataBlob_T metadata, uint32_t *block_offset, uint32_t *block_size, uint32_t *block_flags, uint32_t *block_hash); /** ***************************************************************************** * @ingroup qatZip * Read CRC64 of a metadata block. * * @description * This function reads the input and output CRC64 for the block specified by * the function param block_num. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] block_num Block number of which CRC64 should be read. * @param[in] metadata Pointer to opaque metadata. * @param[out] input_crc Pointer to the CRC64 calculation on input * buffer. * @param[out] output_crc Pointer to the CRC64 calculation on output * buffer. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS Metadata is NULL or checksum mismatch. * @retval QZ_OUT_OF_RANGE block_num specified is out of range. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMetadataBlockGetCrc64(uint32_t block_num, QzMetadataBlob_T metadata, uint64_t *input_crc, uint64_t *output_crc); /** ***************************************************************************** * @ingroup qatZip * Read CRC32 of a metadata block. * * @description * This function reads the input and output CRC32 for the block specified by * the function param block_num. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] block_num Block number of which CRC32 should be read. * @param[in] metadata Pointer to opaque metadata. * @param[out] input_crc Pointer to the CRC32 calculation on input * buffer. * @param[out] output_crc Pointer to the CRC32 calculation on output * buffer. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS Metadata is NULL or checksum mismatch. * @retval QZ_OUT_OF_RANGE block_num specified is out of range. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMetadataBlockGetCrc32(uint32_t block_num, QzMetadataBlob_T metadata, uint32_t *input_crc, uint32_t *output_crc); #ifdef __cplusplus } #endif #endif QATzip-1.3.1/include/qz_utils.h000066400000000000000000000115551500263377000163440ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /** ***************************************************************************** * @file qz_utils.h * * @defgroup qatzip debug API * * @description * These functions specify the API for debug operations. * * @remarks * * *****************************************************************************/ #ifndef _QZ_UTILS_H_ #define _QZ_UTILS_H_ #include #include #include #include #include #include "qatzip.h" typedef enum SERV_E { COMPRESSION = 0, DECOMPRESSION } Serv_T; typedef enum ENGINE_E { HW = 0, SW } Engine_T; typedef struct ThreadList_S { unsigned int thread_id; unsigned int comp_hw_count; unsigned int comp_sw_count; unsigned int decomp_hw_count; unsigned int decomp_sw_count; struct ThreadList_S *next; } ThreadList_T; typedef struct QatThread_S { ThreadList_T *comp_th_list; unsigned int num_comp_th; pthread_mutex_t comp_lock; ThreadList_T *decomp_th_list; unsigned int num_decomp_th; pthread_mutex_t decomp_lock; } QatThread_T; typedef struct QzRingHeadTail_S { uint32_t head; uint32_t tail; } QzRingHeadTail_T; typedef struct QzRing_S { uint32_t size; /**< Size of ring. */ uint32_t mask; /**< Mask (size-1) of ring. */ uint32_t capacity; /**< Usable size of ring */ void **elems; QzRingHeadTail_T prod; QzRingHeadTail_T cons; } QzRing_T; QzRing_T *QzRingCreate(int size); void QzRingFree(QzRing_T *ring); void QzClearRing(QzRing_T *ring); int QzRingProduceEnQueue(QzRing_T *ring, void *obj, int is_single_producer); void *QzRingConsumeDequeue(QzRing_T *ring, int is_single_consumer); extern void initDebugLock(void); extern void dumpThreadInfo(void); extern void insertThread(unsigned int th_id, Serv_T serv_type, Engine_T engine_type); /* QATzip log API * could change the log level on runtime */ void logMessage(QzLogLevel_T level, const char *file, int line, const char *format, ...); #define LOG(level, ...) logMessage(level, __FILE__, __LINE__, __VA_ARGS__) #define QZ_PRINT(...) LOG(LOG_NONE, __VA_ARGS__) #define QZ_ERROR(...) LOG(LOG_ERROR, __VA_ARGS__) #define QZ_WARN(...) LOG(LOG_WARNING, __VA_ARGS__) #define QZ_INFO(...) LOG(LOG_INFO, __VA_ARGS__) #define QZ_DEBUG(...) LOG(LOG_DEBUG1, __VA_ARGS__) #define QZ_TEST(...) LOG(LOG_DEBUG2, __VA_ARGS__) #define QZ_MEM_PRINT(...) LOG(LOG_DEBUG3, __VA_ARGS__) #ifdef ENABLE_TESTLOG #define QZ_TESTLOG(debuglevel, Readable, tag, ...) { \ FILE *fd = debuglevel > 1 ? stdout : stderr; \ fprintf(fd, "Tag: %s; ", tag); \ if (Readable) { \ fprintf(fd, "Time: %s %s; Location: %s->%s->%d; ", \ __DATE__, __TIME__, __FILE__, __func__, __LINE__); \ } else { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC_RAW, &ts); \ fprintf(fd, "Time: %ld.%06lds; ", ts.tv_sec, ts.tv_nsec / 1000); \ } \ fprintf(fd, "%s", "Info: "); \ fprintf(fd, __VA_ARGS__); \ fprintf(fd, " \n"); \ } #endif #endif QATzip-1.3.1/man/000077500000000000000000000000001500263377000134425ustar00rootroot00000000000000QATzip-1.3.1/man/qatzip-test.1000066400000000000000000000073341500263377000160200ustar00rootroot00000000000000.TH QATZIP-TEST 1 local .SH NAME qatzip-test \- test app for compression or decompression function and perf with qat acceleration .SH SYNOPSIS .ll +8 .B qatzip-test .RB [ " \-m:t:A:C:D:F:L:T:i:l:e:s:r:B:O:S:P:M:b:p:g:vh " ] [ .I "name \&..." ] .ll -8 .br .SH DESCRIPTION QATzip is a user space library which builds on top of the Intel QuickAssist Technology user space library, to provide extended accelerated compression and decompression services by offloading the actual compression and decompression request(s) to the Intel Chipset Series. qatzip-test is the test tool for validating QATzip user space library's functional and performance. It could construct different testing scenarios by combining various software selectable parameters, then Capture and analyze performance data The parameters include different compression data formats, block size, hw buffer size, test threads and so on... qatzip-test tool is design to take full advantage of the performance provided by Intel® QuickAssist Technology. .SH OPTIONS .TP .B \-m set test mode for different function of qatzip 1 test memcpy feature 2 test Memory 3 test comp/decomp by default parameters 4 test comp/decomp by configurable parameters 5 test comp/decomp by format parameters test set default configurable parameters .TP .B \-i input source file, default by random generate data .TP .B \-t maximum forks permitted in the current thread .TP .B \-l Test case loop count, default is 2 .TP .B \-v verify, disabled by default .TP .B \-e enable/disable QAT HW. enabled by default .TP .B \-s enable/disable QAT session setup, enabled by default .TP .B \-A set compression algorithm, deflate/lz4/lz4s .TP .B \-B enable/disable QATzip sw fallback .TP .B \-C set HW buffer size .B \-b set API source block size .TP .B \-D set compression or decompression, comp | decomp | both .TP .B \-O set data format, deflate | gzip | gzipext | deflate_4B | lz4 | lz4s .TP .B \-T set huffman tree type, static | dynamic .SH COPYRIGHT .nf ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ .fi QATzip-1.3.1/man/qzip.1000066400000000000000000000057301500263377000145140ustar00rootroot00000000000000.TH QZIP 1 local .SH NAME qzip \- compress or decompress with qat acceleration .SH SYNOPSIS .ll +8 .B qzip .RB [ " \-AdfhHkLCro " ] [ .I "name \&..." ] .ll -8 .br .SH DESCRIPTION QATzip is a user space library which builds on top of the Intel QuickAssist Technology user space library, to provide extended accelerated compression and decompression services by offloading the actual compression and decompression request(s) to the Intel Chipset Series. QATzip produces data using the standard gzip format (RFC1952) with extended headers. The data can be decompressed with a compliant gzip implementation. QATzip is design to take full advantage of the performance provided by Intel® QuickAssist Technology. .SH OPTIONS .TP .B \-A --algorithm set algorithm type, currently only support deflate .TP .B \-d --decompress decompress .TP .B \-f --force force overwrite of output file and compress links .TP .B \-h --help give this help .TP .B \-H --huffmanhdr set huffman header type .TP .B \-k --keep Keep (don't delete) input files during compression or decompression. .TP .B \-L --level set compression level .TP .B \-C --chunksz set chunk size .TP .B \-r set max in-flight request number .TP .B \-o set output file name .SH COPYRIGHT .nf ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ .fi QATzip-1.3.1/qatzip.pc.in000066400000000000000000000004551500263377000151340ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: qatzip Description: Higher level library provides access to Intel QAT compression URL: https://github.com/intel/QATzip Version: @VERSION@ Libs: -L${libdir} -lqatzip Cflags: -I${includedir} Requires: zlib, liblz4 QATzip-1.3.1/qatzip.spec.in000066400000000000000000000112461500263377000154640ustar00rootroot00000000000000# SPDX-License-Identifier: MIT %global githubname @PACKAGE@ %global libqatzip_soversion 3 Name: @PACKAGE@ Version: @VERSION@ Release: 1%{?dist} Summary: Intel QuickAssist Technology (QAT) QATzip Library License: BSD URL: https://github.com/intel/%{githubname} Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz BuildRequires: gcc >= 4.8.5 BuildRequires: zlib-devel >= 1.2.7 BuildRequires: qatlib-devel >= 22.07.0 BuildRequires: autoconf automake libtool make lz4-devel numactl-devel # The purpose of the package is to support hardware that only exists on x86_64 platforms # https://bugzilla.redhat.com/show_bug.cgi?id=1987280 ExclusiveArch: x86_64 %description QATzip is a user space library which builds on top of the Intel QuickAssist Technology user space library, to provide extended accelerated compression and decompression services by offloading the actual compression and decompression request(s) to the Intel Chipset Series. QATzip produces data using the standard gzip* format (RFC1952) with extended headers. The data can be decompressed with a compliant gzip* implementation. QATzip is designed to take full advantage of the performance provided by Intel QuickAssist Technology. %package libs Summary: Libraries for the qatzip package %description libs This package contains libraries for applications to use the QATzip APIs. %package devel Summary: Development components for the libqatzip package Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description devel This package contains headers and libraries required to build applications that use the QATzip APIs. %prep %autosetup -p0 -n %{githubname}-%{version} %build %set_build_flags autoreconf -vif ./configure \ --bindir=%{_bindir} \ --libdir=%{_libdir} \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ --prefix=%{_prefix} \ --enable-symbol %make_build %install %make_install rm %{buildroot}/%{_libdir}/libqatzip.a rm %{buildroot}/%{_libdir}/libqatzip.la rm -vf %{buildroot}%{_mandir}/*.pdf # Check section is not available for these functional and performance tests require special hardware. %files %license LICENSE* %{_mandir}/man1/qzip.1* %{_bindir}/qzip %{_bindir}/qatzip-test %files libs %license LICENSE* %{_libdir}/libqatzip.so.%{libqatzip_soversion}* %files devel %doc docs/QATzip-man.pdf %{_includedir}/qatzip.h %{_libdir}/libqatzip.so %{_libdir}/pkgconfig/*.pc %changelog * Thu Apr 10 2025 xinghong - 1.3.1-1 - Update to qatzip v1.3.1 - Fix qatzip docker file build broken issue * Tue Mar 18 2025 xinghong - 1.3.0-1 - Update to qatzip v1.3.0 - Support Latency sesitive mode for qatzip - Add a suit of comp/decomp API to support Async offloading - Support zlib format and end of stream flag - Fix some bugs * Fri Jan 05 2024 taorong - 1.2.0-1 - Update to qatzip v1.2.0 - Add qatzip-test tool - SW fallback - Fix some bugs * Mon Mar 06 2023 xinghong - 1.1.2-1 - Update to qatzip v1.1.2 - Update README, update driver configure files - Fix some bugs * Fri Jan 20 2023 Fedora Release Engineering - 1.1.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild * Wed Jan 11 2023 Vladis Dronov - 1.1.1-1 - Update to qatzip v1.1.1 - Add support for pkgconfig * Thu Nov 24 2022 Vladis Dronov - 1.1.0-1 - Rebuild for qatzip v1.1.0 * Mon Aug 08 2022 Vladis Dronov - 1.0.9-1 - Rebuild for qatzip v1.0.9 - Update to require qatlib-devel >= 22.07.0 due to soversion bump * Fri Jul 22 2022 Fedora Release Engineering - 1.0.7-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild * Wed Feb 09 2022 Vladis Dronov - 1.0.7-1 - Rebuild for qatzip v1.0.7 - Fix snprintf truncation check (bz 2046925) - Add -fstack-protector-strong build option (bz 2044889) * Fri Jan 21 2022 Fedora Release Engineering - 1.0.6-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild * Mon Sep 13 2021 zm627 - 1.0.6-3 - Rebuild for qatzip v1.0.6 * Sun Sep 12 2021 zm627 - 1.0.6-2 - Upload new qatzip source package and rebuild * Sun Sep 12 2021 zm627 - 1.0.6-1 - Update to latest qatlib and qatzip upstream release * Sun Sep 12 2021 zm627 - 1.0.5-3 - Add ExcludeArch ticket number * Sun Sep 12 2021 zm627 - 1.0.5-2 - Rebuilt for qatlib v21.08 * Tue Jul 13 2021 Ma Zheng - 1.0.5-1 - Initial version of RPM Package QATzip-1.3.1/specgen.sh000077500000000000000000000042111500263377000146500ustar00rootroot00000000000000#! /bin/bash ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ set -o errexit # extract version numbers from qatzip_internal.h VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < src/qatzip_internal.h` # Generate qatzip.spec echo "Generating qatzip.spec" echo "QATzip version: $VER" sed < qatzip.spec.in 's/VERSION/'"$VER"'/g'> qatzip.spec if [ -f qatzip.spec ];then echo "qatzip.spec generated" else echo "Failed to generate qatzip.spec" fi QATzip-1.3.1/src/000077500000000000000000000000001500263377000134565ustar00rootroot00000000000000QATzip-1.3.1/src/Makefile.am000066400000000000000000000051451500263377000155170ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ lib_LTLIBRARIES = libqatzip.la libqatzip_la_SOURCES = \ qatzip.c \ qatzip_counter.c \ qatzip_gzip.c \ qatzip_mem.c \ qatzip_stream.c \ qatzip_sw.c \ qatzip_utils.c \ qatzip_lz4.c \ xxhash.c libqatzip_la_CFLAGS = \ -I./ \ -I../include/ \ $(COMMON_CFLAGS) \ $(SAL_CFLAGS) \ $(ADF_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) \ $(AM_CFLAGS) libqatzip_la_LDFLAGS = \ -version-info $(LIBQATZIP_VERSION) \ $(ICP_LDFLAGS) libqatzip_la_LIBADD= $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) QATzip-1.3.1/src/qatzip.c000077500000000000000000004432521500263377000151470ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #define XXH_NAMESPACE QATZIP_ #include "xxhash.h" #ifdef HAVE_QAT_HEADERS #include #include #include #include #include #else #include #include #include #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" /* * Process address space name described in the config file for this device. */ const char *g_dev_tag = "SHIM"; const unsigned int g_polling_interval[] = { 10, 10, 20, 30, 60, 100, 200, 400, 600, 1000, 2000, 4000, 8000, 16000, 32000, 64000 }; #define INTER_SZ(src_sz) (2 * (src_sz)) #define msleep(x) usleep((x) * 1000) #define POLLING_LIST_NUM (sizeof(g_polling_interval) \ / sizeof(unsigned int)) #define MAX_GRAB_RETRY (10) #define GET_BUFFER_SLEEP_NSEC 10 #define QAT_SECTION_NAME_SIZE 32 #define POLL_EVENT_INTERVAL_TIME 1000 # define NSEC_TO_SEC 1000000000L struct timespec mb_poll_timeout_time = { 0, 10000000 }; /****************************************************** * If enable new compression algorithm, extend new params * structure in API. please add default here. ******************************************************/ QzSessionParamsInternal_T g_sess_params_internal_default = { .huffman_hdr = QZ_HUFF_HDR_DEFAULT, .direction = QZ_DIRECTION_DEFAULT, .data_fmt = DATA_FORMAT_DEFAULT, .comp_lvl = QZ_COMP_LEVEL_DEFAULT, .comp_algorithm = QZ_COMP_ALGOL_DEFAULT, .max_forks = QZ_MAX_FORK_DEFAULT, .sw_backup = QZ_SW_BACKUP_DEFAULT, .hw_buff_sz = QZ_HW_BUFF_SZ, .strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT, .input_sz_thrshold = QZ_COMP_THRESHOLD_DEFAULT, .req_cnt_thrshold = QZ_REQ_THRESHOLD_DEFAULT, .wait_cnt_thrshold = QZ_WAIT_CNT_THRESHOLD_DEFAULT, .polling_mode = QZ_PERIODICAL_POLLING, .lz4s_mini_match = 3, .qzCallback = NULL, .qzCallback_external = NULL, .stop_decompression_stream_end = 0, .zlib_format = 0 }; pthread_mutex_t g_sess_params_lock = PTHREAD_MUTEX_INITIALIZER; processData_T g_process = { .qz_init_status = QZ_NONE, .qat_available = QZ_NONE, .async_req_key = PTHREAD_KEYS_MAX }; pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; __thread ThreadData_T g_thread = { .ppid = 0, }; int async_queue_size = DEFAULT_ASYNC_QUEUE_SIZE; static int setInstance(unsigned int dev_id, QzInstanceList_T *new_instance, QzHardware_T *qat_hw) { if (dev_id >= QAT_MAX_DEVICES || NULL == new_instance || NULL == qat_hw || NULL != new_instance->next) { return QZ_PARAMS; } QzInstanceList_T *instances = &qat_hw->devices[dev_id]; /* first instance */ if (NULL == instances->next) { qat_hw->dev_num++; } while (instances->next) { instances = instances->next; } instances->next = new_instance; if (dev_id > qat_hw->max_dev_id) { qat_hw->max_dev_id = dev_id; } return QZ_OK; } static QzInstanceList_T *getInstance(unsigned int dev_id, QzHardware_T *qat_hw) { if (dev_id >= QAT_MAX_DEVICES || NULL == qat_hw) { return NULL; } QzInstanceList_T *instances = &qat_hw->devices[dev_id]; QzInstanceList_T *first_instance = instances->next; int i; /* no instance */ if (NULL == first_instance) { goto exit; } instances->next = first_instance->next; /* last instance */ if (NULL == instances->next && qat_hw->dev_num > 0) { qat_hw->dev_num--; if (qat_hw->max_dev_id > 0 && dev_id == qat_hw->max_dev_id) { for (i = qat_hw->max_dev_id - 1; i >= 0; i--) { if (qat_hw->devices[i].next) { qat_hw->max_dev_id = i; break; } } } } exit: return first_instance; } static void clearDevices(QzHardware_T *qat_hw) { if (NULL == qat_hw || 0 == qat_hw->dev_num) { return; } for (int i = 0; i < qat_hw->max_dev_id; i++) { QzInstanceList_T *inst = getInstance(i, qat_hw); while (inst) { free(inst); inst = getInstance(i, qat_hw); } } } static void dcCallback(void *cbtag, CpaStatus stat) { long tag, i, j; tag = (long)cbtag; j = GET_LOWER_16BITS(tag); i = tag >> 16; if (g_process.qz_inst[i].stream[j].src1 != g_process.qz_inst[i].stream[j].src2) { QZ_WARN("FLOW ERROR IN CBi src1 != src2\n"); goto print_err; } if (g_process.qz_inst[i].stream[j].sink1 != g_process.qz_inst[i].stream[j].sink2) { QZ_WARN("FLOW ERROR IN CBi sink1 != sink2\n"); goto print_err; } if (g_process.qz_inst[i].stream[j].src2 != (g_process.qz_inst[i].stream[j].sink1 + 1)) { QZ_WARN("FLOW ERROR IN CBi src2 != sink1 + 1\n"); goto print_err; } g_process.qz_inst[i].stream[j].sink1++; g_process.qz_inst[i].stream[j].job_status = stat; goto done; print_err: QZ_ERROR("FLOW ERROR IN CBi %ld %ld\n", i, j); done: return; } static void dcEventCallback(const CpaInstanceHandle instanceHandle, void *pCallbackTag, const CpaInstanceEvent instanceEvent) { long i = (long)pCallbackTag; switch (instanceEvent) { case CPA_INSTANCE_EVENT_RESTARTING: QZ_INFO("QAT instance %ld detected Event 'restarting'\n", i); break; case CPA_INSTANCE_EVENT_RESTARTED: g_process.qz_inst[i].heartbeat = CPA_STATUS_SUCCESS; QZ_INFO("QAT instance %ld detected Event 'restarted'\n", i); break; case CPA_INSTANCE_EVENT_FATAL_ERROR: g_process.qz_inst[i].heartbeat = CPA_STATUS_FAIL; QZ_INFO("QAT instance %ld detected Event 'fatal error'\n", i); break; default: QZ_ERROR("QAT instance %ld detected Unknow Event!\n", i); } } static void *PollingHeartBeat(void *arg) { CpaStatus status = CPA_STATUS_SUCCESS; while (true) { status = icp_sal_poll_device_events(); if (CPA_STATUS_SUCCESS != status) { QZ_INFO("Polling device heartbeat is failure!\n"); continue; } /* This time may effect the sw fallback times */ usleep(POLL_EVENT_INTERVAL_TIME); } return ((void *)NULL); } typedef enum QzLSMPath_E { LSM_QAT, LSM_SW, } QzLSMPath_T; static inline int chooseLSMPath(QzSess_T *qz_sess) { int path; if (qz_sess->SWT.arr_avg < (qz_sess->RRT.arr_avg + qz_sess->PPT.arr_avg)) { path = LSM_SW; } else { path = LSM_QAT; } return path; } /* * Check the capabilities of instance to ensure that it * supports the data format. For LZ4 or LZ4s if * QAT API Version is less than 3.1, will return QZ_FAIL. */ static inline int qzCheckInstCap(CpaDcInstanceCapabilities *inst_cap, const QzSessionParamsInternal_T *params) { assert(inst_cap != NULL); switch (params->data_fmt) { case LZ4_FH: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) if (!inst_cap->statelessLZ4Compression || !inst_cap->statelessLZ4Decompression || !inst_cap->checksumXXHash32) { return QZ_FAIL; } #else QZ_ERROR("QAT driver does not support lz4 algorithm\n"); return QZ_FAIL; #endif break; case LZ4S_BK: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) if (!inst_cap->checksumXXHash32 || !inst_cap->statelessLZ4SCompression) { return QZ_FAIL; } #else QZ_ERROR("QAT driver does not support lz4s algorithm\n"); return QZ_FAIL; #endif break; case DEFLATE_4B: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_RAW: case DEFLATE_ZLIB: default: if (!inst_cap->statelessDeflateCompression || !inst_cap->statelessDeflateDecompression || !inst_cap->checksumCRC32) { return QZ_FAIL; } /* check if instance support dynamic huffman */ if (!inst_cap->dynamicHuffman && (params->huffman_hdr == QZ_DYNAMIC_HDR)) { return QZ_FAIL; } /* always open the Cnv */ if (!inst_cap->compressAndVerify) { return QZ_FAIL; } /* will extend multi-type checksum check, data format check autoSelect check, Dictionary support, stateful support ..... */ break; } return QZ_OK; } static int qzGrabInstance(int hint, const QzSessionParamsInternal_T *params) { int i, j, rc, f; if (QZ_NONE == g_process.qz_init_status) { return -1; } if (hint >= g_process.num_instances || hint < 0) { hint = 0; } /*otherwise loop through all of them*/ f = 0; for (j = 0; j < MAX_GRAB_RETRY; j++) { for (i = 0; i < g_process.num_instances; i++) { if (f == 0) { i = hint; f = 1; } ; /* Before locking the instance, we need to ensure that * the instance supports the data format. */ if (QZ_OK != qzCheckInstCap(&g_process.qz_inst[i].instance_cap, params)) { continue; } if (CPA_STATUS_SUCCESS != g_process.qz_inst[i].heartbeat) { continue; } rc = __sync_lock_test_and_set(&(g_process.qz_inst[i].lock), 1); if (0 == rc) { return i; } } } return -1; } static int getUnusedBuffer(unsigned long i, int j) { int k; Cpa16U max; max = g_process.qz_inst[i].dest_count; if (j < 0) { j = 0; } else if (j >= max) { j = GET_LOWER_16BITS(max); } for (k = j; k < max; k++) { if ((g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].src2) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink1) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink2)) { return k; } } for (k = 0; k < max; k++) { if ((g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].src2) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink1) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink2)) { return k; } } return -1; } static void qzReleaseInstance(int i) { __sync_lock_release(&(g_process.qz_inst[i].lock)); } static void init_timers(void) { int i; for (i = 1; i < MAX_THREAD_TMR; i++) { g_thread.timer[i].tv_sec = 0; g_thread.timer[i].tv_usec = 0; } gettimeofday(&g_thread.timer[0], NULL); } static void stopQat(void) { int i; CpaStatus status = CPA_STATUS_SUCCESS; /* Those all show No HW, stopQAT do nothing */ if (CPA_FALSE == g_process.qat_available || QZ_NONE == g_process.qz_init_status || QZ_NO_HW == g_process.qz_init_status || QZ_NOSW_NO_HW == g_process.qz_init_status) { goto reset; } /* scenario: it's called from inside qzinit, Hw init failed */ if (QZ_NO_INST_ATTACH == g_process.qz_init_status) { if (NULL != g_process.dc_inst_handle) { free(g_process.dc_inst_handle); g_process.dc_inst_handle = NULL; } if (NULL != g_process.qz_inst) { free(g_process.qz_inst); g_process.qz_inst = NULL; } (void)icp_sal_userStop(); goto reset; } QZ_INFO("Call stopQat.\n"); /* scenario: qzinit succeed. outside qzinit */ if (QZ_OK == g_process.qz_init_status) { if (NULL != g_process.dc_inst_handle && NULL != g_process.qz_inst) { for (i = 0; i < g_process.num_instances; i++) { status = cpaDcStopInstance(g_process.dc_inst_handle[i]); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Stop instance failed, status=%d\n", status); } } free(g_process.dc_inst_handle); g_process.dc_inst_handle = NULL; free(g_process.qz_inst); g_process.qz_inst = NULL; } (void)icp_sal_userStop(); } else { QZ_WARN("qz init status is invalid, status=%d\n", g_process.qz_init_status); goto reset; } reset: g_process.num_instances = (Cpa16U)0; g_process.qz_init_status = QZ_NONE; g_process.qat_available = QZ_NONE; } static void exitFunc(void) __attribute__((destructor)); static void exitFunc(void) { int i = 0; if (0 != g_process.t_poll_heartbeat) { QZ_INFO("cancel the thread!\n"); pthread_cancel(g_process.t_poll_heartbeat); pthread_join(g_process.t_poll_heartbeat, NULL); } if (PTHREAD_KEYS_MAX != g_process.async_req_key) { pthread_key_delete(g_process.async_req_key); } for (i = 0; i < g_process.num_instances; i++) { removeSession(i); cleanUpInstMem(i); } streamBufferCleanup(); stopQat(); qzMemDestory(); #ifdef QATZIP_DEBUG dumpThreadInfo(); #endif } static unsigned int getWaitCnt(QzSession_T *sess) { QzSess_T *qz_sess; if (sess->internal != NULL) { qz_sess = (QzSess_T *)sess->internal; return qz_sess->sess_params.wait_cnt_thrshold; } else { return g_sess_params_internal_default.wait_cnt_thrshold; } } #define BACKOUT(hw_status) \ stopQat(); \ if (1 == sw_backup) { \ g_process.qz_init_status = QZ_NO_HW; \ QZ_WARN("g_process.qz_init_status = QZ_NO_HW\n"); \ rc = QZ_OK; \ } else if (0 == sw_backup) { \ g_process.qz_init_status = QZ_NOSW_NO_HW; \ QZ_WARN("g_process.qz_init_status = QZ_NOSW_NO_HW\n"); \ rc = hw_status; \ } \ goto done; #define QZ_HW_BACKOUT(hw_status) \ if(qat_hw) { \ clearDevices(qat_hw); \ free(qat_hw); \ } \ BACKOUT(hw_status); const char *getSectionName(void) { static char section_name[QAT_SECTION_NAME_SIZE]; int len; char *pre_section_name; #if __GLIBC_PREREQ(2, 17) pre_section_name = secure_getenv("QAT_SECTION_NAME"); #else pre_section_name = getenv("QAT_SECTION_NAME"); #endif if (!pre_section_name || !(len = strlen(pre_section_name))) { pre_section_name = (char *)g_dev_tag; } else if (len >= QAT_SECTION_NAME_SIZE) { QZ_ERROR("The length of QAT_SECTION_NAME exceeds the limit.\n"); } strncpy(section_name, pre_section_name, QAT_SECTION_NAME_SIZE - 1); section_name[QAT_SECTION_NAME_SIZE - 1] = '\0'; return section_name; } static void AsyncCtrlDestructor(void *arg) { QzSession_T *sess = (QzSession_T *) arg; QzSess_T *qz_sess = (QzSess_T *) sess->internal; if (qz_sess == NULL) { QZ_DEBUG("Teardown session have called\n"); return; } QzAsynctrl_T *async_ctrl = qz_sess->async_ctrl; if (0 != async_ctrl->async_consume_t) { async_ctrl->async_ctrl_init = 0; pthread_join(async_ctrl->async_consume_t, NULL); } if (NULL != async_ctrl->async_req_ring) { QzRingFree(async_ctrl->async_req_ring); } sem_destroy(&(async_ctrl->sem)); free(async_ctrl); return; } /* Initialize the QAT hardware, get the QAT instance for current * process. * Note: return value doesn't same as qz_init_status, because return * value align limitation. * * After qzInit, there only are three status to qz_init_status * 1. QZ_OK * 2. QZ_NO_HW * 3. QZ_NOSW_NO_HW */ int qzInit(QzSession_T *sess, unsigned char sw_backup) { CpaStatus status; int rc = QZ_NOSW_NO_HW, i; unsigned int dev_id = 0; QzHardware_T *qat_hw = NULL; unsigned int instance_found = 0; static atomic_int waiting = 0; static atomic_int wait_cnt = 0; #ifdef ADF_PCI_API Cpa32U pcie_count = 0; #endif if (unlikely(sess == NULL)) { return QZ_PARAMS; } if (unlikely(sw_backup > 1)) { return QZ_PARAMS; } if (CPA_FALSE == g_process.qat_available || QZ_OK == g_process.qz_init_status) { return QZ_DUPLICATE; } if (unlikely(0 != pthread_mutex_lock(&g_lock))) { return QZ_NOSW_NO_HW; } if (QZ_OK == g_process.qz_init_status) { if (unlikely(0 != pthread_mutex_unlock(&g_lock))) { return QZ_NOSW_NO_HW; } if (g_process.sw_backup != sw_backup) { g_process.sw_backup = sw_backup; } return QZ_DUPLICATE; } g_thread.pid = getpid(); g_thread.ppid = getppid(); init_timers(); /* Init all local thread key here */ if (unlikely(0 != pthread_key_create(&g_process.async_req_key, AsyncCtrlDestructor))) { QZ_ERROR("Init local thread key failed\n"); g_process.async_req_key = PTHREAD_KEYS_MAX; BACKOUT(QZ_NOSW_NO_HW); } g_process.sw_backup = sw_backup; if (waiting && wait_cnt > 0) { wait_cnt--; BACKOUT(QZ_NOSW_NO_HW); } waiting = 0; /* Start HW initialization. it could be first call qzinit or * Before HW init failed, which mean qz_init_status may be * QZ_NOSW_NO_HW or QZ_NO_HW */ #ifdef SAL_DEV_API g_process.qat_available = icp_sal_userIsQatAvailable(); if (CPA_FALSE == g_process.qat_available) { QZ_ERROR("Error no hardware, switch to SW if permitted\n"); BACKOUT(QZ_NOSW_NO_HW); } #else status = icp_adf_get_numDevices(&pcie_count); if (CPA_STATUS_SUCCESS != status) { g_process.qat_available = CPA_FALSE; } if (pcie_count >= 1) { g_process.qat_available = CPA_TRUE; } else { g_process.qat_available = CPA_FALSE; } if (CPA_FALSE == g_process.qat_available) { QZ_WARN("Error no hardware, switch to SW if permitted status = %d\n", status); BACKOUT(QZ_NOSW_NO_HW); } #endif status = icp_sal_userStartMultiProcess(getSectionName(), CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error userStarMultiProcess(%d), switch to SW if permitted\n", status); waiting = 1; wait_cnt = getWaitCnt(sess); BACKOUT(QZ_NOSW_NO_HW); } /* This status only show inside qzinit. And will replace to others when qzinit finished */ g_process.qz_init_status = QZ_NO_INST_ATTACH; status = cpaDcGetNumInstances(&g_process.num_instances); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcGetNumInstances status = %d\n", status); BACKOUT(QZ_NOSW_NO_INST_ATTACH); } QZ_INFO("Number of instance: %u\n", g_process.num_instances); g_process.dc_inst_handle = malloc(g_process.num_instances * sizeof(CpaInstanceHandle)); g_process.qz_inst = calloc(g_process.num_instances, sizeof(QzInstance_T)); if (unlikely(NULL == g_process.dc_inst_handle || NULL == g_process.qz_inst)) { QZ_ERROR("malloc failed\n"); BACKOUT(QZ_NOSW_LOW_MEM); } status = cpaDcGetInstances(g_process.num_instances, g_process.dc_inst_handle); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcGetInstances status = %d\n", status); BACKOUT(QZ_NOSW_NO_INST_ATTACH); } qat_hw = calloc(1, sizeof(QzHardware_T)); if (unlikely(NULL == qat_hw)) { QZ_ERROR("malloc failed\n"); BACKOUT(QZ_NOSW_LOW_MEM); } for (i = 0; i < g_process.num_instances; i++) { QzInstanceList_T *new_inst = calloc(1, sizeof(QzInstanceList_T)); if (unlikely(NULL == new_inst)) { QZ_ERROR("malloc failed\n"); QZ_HW_BACKOUT(QZ_NOSW_LOW_MEM); } status = cpaDcInstanceGetInfo2(g_process.dc_inst_handle[i], &new_inst->instance.instance_info); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcInstanceGetInfo2 status = %d\n", status); free(new_inst); QZ_HW_BACKOUT(QZ_NOSW_NO_HW); } status = cpaDcQueryCapabilities(g_process.dc_inst_handle[i], &new_inst->instance.instance_cap); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcQueryCapabilities status = %d\n", status); free(new_inst); QZ_HW_BACKOUT(QZ_NOSW_NO_HW); } new_inst->instance.lock = 0; new_inst->instance.heartbeat = CPA_STATUS_SUCCESS; new_inst->instance.mem_setup = 0; new_inst->instance.cpa_sess_setup = 0; new_inst->instance.num_retries = 0; new_inst->dc_inst_handle = g_process.dc_inst_handle[i]; dev_id = new_inst->instance.instance_info.physInstId.packageId; if (unlikely(QZ_OK != setInstance(dev_id, new_inst, qat_hw))) { QZ_ERROR("Insert instance on device %d failed\n", dev_id); QZ_HW_BACKOUT(QZ_NOSW_NO_INST_ATTACH); } } /* shuffle instance */ for (i = 0; instance_found < g_process.num_instances; i++) { dev_id = i % (qat_hw->max_dev_id + 1); QzInstanceList_T *new_inst = getInstance(dev_id, qat_hw); if (NULL == new_inst) { continue; } QZ_MEMCPY(&g_process.qz_inst[instance_found], &new_inst->instance, sizeof(QzInstance_T), sizeof(QzInstance_T)); g_process.dc_inst_handle[instance_found] = new_inst->dc_inst_handle; free(new_inst); instance_found++; } /* Set EventCallback after instance shuffle */ for (long index = 0; index < instance_found; index++) { status = cpaDcInstanceSetNotificationCb(g_process.dc_inst_handle[index], dcEventCallback, (void *)index); if (CPA_STATUS_SUCCESS != status) { QZ_WARN("Error in cpaDcInstanceSetNotificationCb status = %d\n", status); QZ_HW_BACKOUT(QZ_NOSW_NO_INST_ATTACH); } } /* Start device heartbeat event detect thread */ if (unlikely(0 != pthread_create(&g_process.t_poll_heartbeat, NULL, PollingHeartBeat, NULL))) { QZ_WARN("Error Start polling heartbeat events thread failed!\n"); g_process.t_poll_heartbeat = 0; } QZ_DEBUG("the polling event thread id is %lu\n", g_process.t_poll_heartbeat); clearDevices(qat_hw); free(qat_hw); rc = g_process.qz_init_status = QZ_OK; done: initDebugLock(); if (unlikely(0 != pthread_mutex_unlock(&g_lock))) { return QZ_NOSW_NO_HW; } return rc; } /* Free up the DMAable memory buffers used by QAT * internally, those buffers are source buffer, * intermediate buffer and destination buffer */ void cleanUpInstMem(int i) { int j; /*intermediate buffers*/ if (NULL != g_process.qz_inst[i].intermediate_buffers) { for (j = 0; j < g_process.qz_inst[i].intermediate_cnt; j++) { if (NULL != g_process.qz_inst[i].intermediate_buffers[j]) { if (NULL != g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData) { qzFree(g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData); g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData = NULL; } if (NULL != g_process.qz_inst[i].intermediate_buffers[j]->pBuffers) { if (NULL != g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData) { qzFree(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData); g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData = NULL; } qzFree(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers); g_process.qz_inst[i].intermediate_buffers[j]->pBuffers = NULL; } qzFree(g_process.qz_inst[i].intermediate_buffers[j]); g_process.qz_inst[i].intermediate_buffers[j] = NULL; } } free(g_process.qz_inst[i].intermediate_buffers); g_process.qz_inst[i].intermediate_buffers = NULL; } /*src buffers*/ if (NULL != g_process.qz_inst[i].src_buffers) { for (j = 0; j < g_process.qz_inst[i].src_count; j++) { if (NULL != g_process.qz_inst[i].src_buffers[j]) { if (NULL != g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData) { qzFree(g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData); g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData = NULL; } if (NULL != g_process.qz_inst[i].src_buffers[j]->pBuffers) { if (NULL != g_process.qz_inst[i].src_buffers[j]->pBuffers->pData) { qzFree(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData); g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = NULL; } qzFree(g_process.qz_inst[i].src_buffers[j]->pBuffers); g_process.qz_inst[i].src_buffers[j]->pBuffers = NULL; } qzFree(g_process.qz_inst[i].src_buffers[j]); g_process.qz_inst[i].src_buffers[j] = NULL; } } free(g_process.qz_inst[i].src_buffers); g_process.qz_inst[i].src_buffers = NULL; } /*dest buffers*/ if (NULL != g_process.qz_inst[i].dest_buffers) { for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if (NULL != g_process.qz_inst[i].dest_buffers[j]) { if (NULL != g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData) { qzFree(g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData); g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData = NULL; } if (NULL != g_process.qz_inst[i].dest_buffers[j]->pBuffers) { if (NULL != g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData) { qzFree(g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData); g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = NULL; } qzFree(g_process.qz_inst[i].dest_buffers[j]->pBuffers); g_process.qz_inst[i].dest_buffers[j]->pBuffers = NULL; } qzFree(g_process.qz_inst[i].dest_buffers[j]); g_process.qz_inst[i].dest_buffers[j] = NULL; } } free(g_process.qz_inst[i].dest_buffers); g_process.qz_inst[i].dest_buffers = NULL; } /*stream buffer*/ if (NULL != g_process.qz_inst[i].stream) { free(g_process.qz_inst[i].stream); g_process.qz_inst[i].stream = NULL; } qzFree(g_process.qz_inst[i].cpaSess); g_process.qz_inst[i].mem_setup = 0; } #define QZ_INST_MEM_CHECK(ptr, i) \ if (NULL == (ptr)) { \ cleanUpInstMem((i)); \ rc = sw_backup ? QZ_LOW_MEM : QZ_NOSW_LOW_MEM; \ goto done_inst; \ } #define QZ_INST_MEM_STATUS_CHECK(status, i) \ if (CPA_STATUS_SUCCESS != status) { \ cleanUpInstMem((i)); \ rc = sw_backup ? QZ_NO_INST_ATTACH : QZ_NOSW_NO_INST_ATTACH; \ goto done_inst; \ } /* Allocate the DMAable memory buffers used by QAT * internally, those buffers are source buffer, * intermediate buffer and destination buffer */ static int getInstMem(int i, QzSessionParamsInternal_T *params) { int j; CpaStatus status; CpaStatus rc; unsigned int src_sz; unsigned int inter_sz; unsigned int dest_sz; unsigned char sw_backup; rc = QZ_OK; /* WARN: this will mean the first sess will setup down the inst * buffer size, if it's very small, then we can't make then * any larger in the whole process. please refer test mode 17 */ src_sz = params->hw_buff_sz; inter_sz = INTER_SZ(src_sz); dest_sz = DEST_SZ(src_sz); sw_backup = params->sw_backup; QZ_MEM_PRINT("getInstMem: Setting up memory for inst %d\n", i); status = cpaDcBufferListGetMetaSize(g_process.dc_inst_handle[i], 1, &(g_process.qz_inst[i].buff_meta_size)); QZ_INST_MEM_STATUS_CHECK(status, i); status = cpaDcGetNumIntermediateBuffers(g_process.dc_inst_handle[i], &(g_process.qz_inst[i].intermediate_cnt)); QZ_INST_MEM_STATUS_CHECK(status, i); g_process.qz_inst[i].intermediate_buffers = calloc(1, (size_t)(g_process.qz_inst[i].intermediate_cnt * sizeof( CpaBufferList *))); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers, i); for (j = 0; j < g_process.qz_inst[i].intermediate_cnt; j++) { g_process.qz_inst[i].intermediate_buffers[j] = (CpaBufferList *) qzMalloc(sizeof(CpaBufferList), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers[j], i); if (0 != g_process.qz_inst[i].buff_meta_size) { g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData = qzMalloc((size_t)(g_process.qz_inst[i].buff_meta_size), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK( g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData, i); } else { g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData = NULL; } g_process.qz_inst[i].intermediate_buffers[j]->pBuffers = (CpaFlatBuffer *) qzMalloc(sizeof(CpaFlatBuffer), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers, i); g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData = (Cpa8U *) qzMalloc(inter_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData, i); g_process.qz_inst[i].intermediate_buffers[j]->numBuffers = (Cpa32U)1; g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->dataLenInBytes = inter_sz; } g_process.qz_inst[i].src_count = NUM_BUFF; g_process.qz_inst[i].dest_count = NUM_BUFF; if (params->hw_buff_sz <= 8 * 1024) { g_process.qz_inst[i].src_count = NUM_BUFF_8K; g_process.qz_inst[i].dest_count = NUM_BUFF_8K; } g_process.qz_inst[i].src_buffers = calloc(1, (size_t)( g_process.qz_inst[i].src_count * sizeof(CpaBufferList *))); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers, i); g_process.qz_inst[i].dest_buffers = calloc(1, g_process.qz_inst[i].dest_count * sizeof(CpaBufferList *)); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers, i); g_process.qz_inst[i].stream = calloc(g_process.qz_inst[i].dest_count, sizeof(QzCpaStream_T)); QZ_INST_MEM_CHECK(g_process.qz_inst[i].stream, i); for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { g_process.qz_inst[i].stream[j].seq = 0; g_process.qz_inst[i].stream[j].src1 = 0; g_process.qz_inst[i].stream[j].src2 = 0; g_process.qz_inst[i].stream[j].sink1 = 0; g_process.qz_inst[i].stream[j].sink2 = 0; g_process.qz_inst[i].src_buffers[j] = (CpaBufferList *) qzMalloc(sizeof(CpaBufferList), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers[j], i); if (0 != g_process.qz_inst[i].buff_meta_size) { g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData = qzMalloc(g_process.qz_inst[i].buff_meta_size, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData, i); } else { g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData = NULL; } g_process.qz_inst[i].src_buffers[j]->pBuffers = (CpaFlatBuffer *) qzMalloc(sizeof(CpaFlatBuffer), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers, i); g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = (Cpa8U *) qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData, i); /* The orig_src points internal pre-allocated pinned buffer. */ g_process.qz_inst[i].stream[j].orig_src = g_process.qz_inst[i].src_buffers[j]->pBuffers->pData; g_process.qz_inst[i].src_buffers[j]->numBuffers = (Cpa32U)1; g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes = src_sz; } for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { g_process.qz_inst[i].dest_buffers[j] = (CpaBufferList *) qzMalloc(sizeof(CpaBufferList), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers[j], i); if (0 != g_process.qz_inst[i].buff_meta_size) { g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData = qzMalloc(g_process.qz_inst[i].buff_meta_size, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData, i); } else { g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData = NULL; } g_process.qz_inst[i].dest_buffers[j]->pBuffers = (CpaFlatBuffer *) qzMalloc(sizeof(CpaFlatBuffer), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers, i); g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = (Cpa8U *) qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, i); /* The orig_dest points internal pre-allocated pinned buffer. */ g_process.qz_inst[i].stream[j].orig_dest = g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData; g_process.qz_inst[i].dest_buffers[j]->numBuffers = (Cpa32U)1; g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes = dest_sz; } status = cpaDcSetAddressTranslation(g_process.dc_inst_handle[i], qaeVirtToPhysNUMA); QZ_INST_MEM_STATUS_CHECK(status, i); g_process.qz_inst[i].inst_start_status = cpaDcStartInstance(g_process.dc_inst_handle[i], g_process.qz_inst[i].intermediate_cnt, g_process.qz_inst[i].intermediate_buffers); QZ_INST_MEM_STATUS_CHECK(g_process.qz_inst[i].inst_start_status, i); g_process.qz_inst[i].mem_setup = 1; done_inst: return rc; } /* Initialize the QAT session parameters associate with current * process's QAT instance, the session parameters include various * configurations for compression/decompression request */ int qzSetupSession(QzSession_T *sess, QzSessionParams_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParams_T temp = {0}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaults(&temp); params = &temp; } if (qzCheckParams(params) != QZ_OK) { return QZ_PARAMS; } if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } sess->hw_session_stat = QZ_FAIL; qz_sess = (QzSess_T *)sess->internal; qzSetParams(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } int qzSetupSessionDeflate(QzSession_T *sess, QzSessionParamsDeflate_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParamsDeflate_T temp = {{0}}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaultsDeflate(&temp); params = &temp; } if (qzCheckParamsDeflate(params) != QZ_OK) { return QZ_PARAMS; } if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } sess->hw_session_stat = QZ_FAIL; qz_sess = (QzSess_T *)sess->internal; qzSetParamsDeflate(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } int qzSetupSessionDeflateExt(QzSession_T *sess, QzSessionParamsDeflateExt_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParamsDeflateExt_T temp = {{{0}}}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaultsDeflateExt(&temp); params = &temp; } if (qzCheckParamsDeflateExt(params) != QZ_OK) { return QZ_PARAMS; } if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } sess->hw_session_stat = QZ_FAIL; qz_sess = (QzSess_T *)sess->internal; if (qz_sess->qzdeflateExtData != NULL) { free(qz_sess->qzdeflateExtData); qz_sess->qzdeflateExtData = NULL; } qz_sess->qzdeflateExtData = calloc(1, sizeof(QzDeflateExtCustomData_T)); if (unlikely(NULL == qz_sess->qzdeflateExtData)) { QZ_ERROR("qz_sess qzdeflateExtData NULL "); } qzSetParamsDeflateExt(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { if (qz_sess->qzdeflateExtData != NULL) { free(qz_sess->qzdeflateExtData); qz_sess->qzdeflateExtData = NULL; } free(sess->internal); sess->internal = NULL; return rc; } return rc; } int qzSetupSessionLZ4(QzSession_T *sess, QzSessionParamsLZ4_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParamsLZ4_T temp = {{0}}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaultsLZ4(&temp); params = &temp; } if (qzCheckParamsLZ4(params) != QZ_OK) { return QZ_PARAMS; } if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } sess->hw_session_stat = QZ_FAIL; qz_sess = (QzSess_T *)sess->internal; qzSetParamsLZ4(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } int qzSetupSessionLZ4S(QzSession_T *sess, QzSessionParamsLZ4S_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParamsLZ4S_T temp = {{0}}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaultsLZ4S(&temp); params = &temp; } if (qzCheckParamsLZ4S(params) != QZ_OK) { return QZ_PARAMS; } if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } sess->hw_session_stat = QZ_FAIL; qz_sess = (QzSess_T *)sess->internal; qzSetParamsLZ4S(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } /* Set up the QAT session associate with current process's * QAT instance */ int qzSetupHW(QzSession_T *sess, int i) { QzSess_T *qz_sess; int rc = QZ_OK; if (g_process.qz_init_status != QZ_OK) { /*hw not present*/ return g_process.qz_init_status; } qz_sess = (QzSess_T *)sess->internal; qz_sess->inst_hint = i; qz_sess->seq = 0; qz_sess->seq_in = 0; if (0 == g_process.qz_inst[i].mem_setup) { rc = getInstMem(i, &(qz_sess->sess_params)); if (QZ_OK != rc) { goto done_sess; } } if (0 == g_process.qz_inst[i].cpa_sess_setup) { /*setup and start DC session*/ QZ_INFO("setup and start DC session %d\n", i); qz_sess->sess_status = cpaDcGetSessionSize(g_process.dc_inst_handle[i], &qz_sess->session_setup_data, &qz_sess->session_size, &qz_sess->ctx_size); if (CPA_STATUS_SUCCESS == qz_sess->sess_status) { g_process.qz_inst[i].cpaSess = qzMalloc((size_t)(qz_sess->session_size), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (NULL == g_process.qz_inst[i].cpaSess) { rc = qz_sess->sess_params.sw_backup ? QZ_LOW_MEM : QZ_NOSW_LOW_MEM; goto done_sess; } } else { rc = QZ_FAIL; goto done_sess; } QZ_INFO("cpaDcInitSession %d\n", i); qz_sess->sess_status = cpaDcInitSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, &qz_sess->session_setup_data, NULL, dcCallback); if (qz_sess->sess_status != CPA_STATUS_SUCCESS) { rc = QZ_FAIL; } g_process.qz_inst[i].session_setup_data = qz_sess->session_setup_data; } if (rc == QZ_OK) { g_process.qz_inst[i].cpa_sess_setup = 1; } done_sess: return rc; } /* * Update cpa session of instance i, it will remove cpa session first, * and reallocate memory and re-initialize cpa session based on * session setup data. */ int qzUpdateCpaSession(QzSession_T *sess, int i) { QzSess_T *qz_sess; CpaStatus ret = CPA_STATUS_SUCCESS; assert(sess); g_process.qz_inst[i].cpa_sess_setup = 0; qz_sess = (QzSess_T *)sess->internal; assert(qz_sess); /* Remove cpa session */ ret = cpaDcRemoveSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess); if (ret != CPA_STATUS_SUCCESS) { QZ_ERROR("qzUpdateCpaSession: remove session failed\n"); return QZ_FAIL; } /* free memory of capSess */ qzFree(g_process.qz_inst[i].cpaSess); /* As the session setup data has been updated, need to get the size of * session again. */ ret = cpaDcGetSessionSize(g_process.dc_inst_handle[i], &qz_sess->session_setup_data, &qz_sess->session_size, &qz_sess->ctx_size); if (ret != CPA_STATUS_SUCCESS) { QZ_ERROR("qzUpdateCpaSession: get session size failed\n"); return QZ_FAIL; } g_process.qz_inst[i].cpaSess = qzMalloc((size_t)(qz_sess->session_size), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!g_process.qz_inst[i].cpaSess) { QZ_ERROR("qzUpdateCpaSession: allocate session failed\n"); return QZ_FAIL; } ret = cpaDcInitSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, &qz_sess->session_setup_data, NULL, dcCallback); if (ret != CPA_STATUS_SUCCESS) { QZ_ERROR("qzUpdateCpaSession: init session failed\n"); free(g_process.qz_inst[i].cpaSess); g_process.qz_inst[i].cpaSess = NULL; return QZ_FAIL; } g_process.qz_inst[i].session_setup_data = qz_sess->session_setup_data; g_process.qz_inst[i].cpa_sess_setup = 1; return QZ_OK; } /* The internal function to send the compression request * to the QAT hardware. * Note: * Only when request offload success, 'submitted' and 'seq' plus, * And update src_ptr, remaining and send_sz * sess->thd_sess_stat only carry QZ_OK and QZ_FAIL */ static void *doCompressIn(void *in) { unsigned long tag; int i, j; unsigned int done = 0; unsigned int src_send_sz; unsigned int remaining; unsigned char *src_ptr; unsigned int hw_buff_sz; CpaStatus rc; QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; struct timespec sleep_time; sleep_time.tv_sec = 0; sleep_time.tv_nsec = GET_BUFFER_SLEEP_NSEC; QZ_TEST("Always enable CnV\n"); i = qz_sess->inst_hint; j = -1; /* For offlod request, src_ptr, remaining and src_send_sz will update */ hw_buff_sz = qz_sess->sess_params.hw_buff_sz; src_ptr = qz_sess->src + qz_sess->qz_in_len; remaining = *qz_sess->src_sz - qz_sess->qz_in_len; src_send_sz = (remaining < hw_buff_sz) ? remaining : hw_buff_sz; QZ_DEBUG("doCompressIn: Need to g_process %u hw_buff_sz %u bytes\n", remaining, hw_buff_sz); while (!done) { if (g_process.qz_inst[i].heartbeat != CPA_STATUS_SUCCESS) { /* Device die, Fallback to sw, don't offload request to HW */ rc = compInSWFallback(i, j, sess, src_ptr, src_send_sz); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } else { /* HW offload */ do { j = getUnusedBuffer(i, j); if (unlikely(-1 == j)) { nanosleep(&sleep_time, NULL); } } while (-1 == j); QZ_DEBUG("getUnusedBuffer returned %d\n", j); g_process.qz_inst[i].stream[j].src1++; /*update stream src1*/ compBufferSetup(i, j, qz_sess, src_ptr, remaining, hw_buff_sz, src_send_sz); g_process.qz_inst[i].stream[j].src2++;/*this buffer is in use*/ do { tag = ((unsigned long)i << 16) | (unsigned long)j; QZ_DEBUG("Comp Sending %u bytes ,opData.flushFlag = %d, i = %d j = %d seq = %ld tag = %ld\n", g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes, g_process.qz_inst[i].stream[j].opData.flushFlag, i, j, g_process.qz_inst[i].stream[j].seq, tag); rc = cpaDcCompressData2(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, g_process.qz_inst[i].src_buffers[j], g_process.qz_inst[i].dest_buffers[j], &g_process.qz_inst[i].stream[j].opData, &g_process.qz_inst[i].stream[j].res, (void *)(tag)); if (unlikely(CPA_STATUS_RETRY == rc)) { g_process.qz_inst[i].num_retries++; usleep(g_polling_interval[qz_sess->polling_idx]); } if (unlikely(g_process.qz_inst[i].num_retries > MAX_NUM_RETRY)) { QZ_WARN("instance %d retry count:%d exceed the max count: %d\n", i, g_process.qz_inst[i].num_retries, MAX_NUM_RETRY); break; } } while (rc == CPA_STATUS_RETRY); g_process.qz_inst[i].num_retries = 0; if (unlikely(CPA_STATUS_SUCCESS != rc)) { QZ_WARN("Inst %d, buffer %d, Error in compIn offload: %d\n", i, j, rc); compInBufferCleanUp(i, j); rc = compInSWFallback(i, j, sess, src_ptr, src_send_sz); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } } QZ_DEBUG("remaining = %u, src_send_sz = %u, seq = %ld\n", remaining, src_send_sz, qz_sess->seq); /* update the request src info status */ src_ptr += src_send_sz; remaining -= src_send_sz; src_send_sz = (remaining < hw_buff_sz) ? remaining : hw_buff_sz; /* update qz_sess status */ qz_sess->seq++; qz_sess->submitted++; if (unlikely(qz_sess->stop_submitting)) { remaining = 0; } if (0 == remaining) { done = 1; qz_sess->last_submitted = 1; } } return ((void *)NULL); err_exit: /*reset the qz_sess status*/ qz_sess->stop_submitting = 1; qz_sess->last_submitted = 1; sess->thd_sess_stat = QZ_FAIL; return ((void *)NULL); } /* The internal function to g_process the compression response * from the QAT hardware * sess->thd_sess_stat only carry QZ_OK and QZ_FAIL and QZ_BUF_ERROR */ static void *doCompressOut(void *in) { int i = 0, j = 0; int rc = 0; int good = -1; CpaDcRqResults *resl; CpaStatus sts; unsigned int sleep_cnt = 0; QzSession_T *sess = (QzSession_T *) in; QzSess_T *qz_sess = (QzSess_T *) sess->internal; long dest_avail_len = (long)(*qz_sess->dest_sz - qz_sess->qz_out_len); i = qz_sess->inst_hint; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; QzPollingMode_T polling_mode = qz_sess->sess_params.polling_mode; while ((qz_sess->last_submitted == 0) || (qz_sess->processed < qz_sess->submitted)) { /* Poll for responses */ good = 0; /* For this call, return error, we have to make sure all stream buffer is reset * which is not just for RestoreSrcCpastreamBuffer, but also * make src1, src2, sink1, sink2 equal, and all switch. */ sts = icp_sal_DcPollInstance(g_process.dc_inst_handle[i], 0); if (unlikely(CPA_STATUS_FAIL == sts)) { /* this will cause the in-flight request is not finished */ QZ_ERROR("Error in DcPoll: %d\n", sts); goto err_exit; } /*fake a retrieve*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if ((g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in) && (g_process.qz_inst[i].stream[j].src1 == g_process.qz_inst[i].stream[j].src2) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].src1) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].sink2 + 1)) { good = 1; QZ_DEBUG("doCompressOut: Processing seqnumber %2.2d " "%2.2d %4.4ld, PID: %d, TID: %lu\n", i, j, g_process.qz_inst[i].stream[j].seq, getpid(), pthread_self()); if (unlikely(QZ_BUF_ERROR == sess->thd_sess_stat)) { compOutSkipErrorRespond(i, j, qz_sess); continue; } /* res.status is passed into QAT by cpaDcCompressData2, and changed in * dcCompression_ProcessCallback, it's type is CpaDcReqStatus. * job_status is from the dccallback, it's type is CpaStatus. * Generally, the res.status should have more detailed info about device error * we assume fallback feature will always call callback func, as well as * cpaDcCompressData2 return success. res.status and job_status should * all return Error status, but with different error number. */ resl = &g_process.qz_inst[i].stream[j].res; if (unlikely(CPA_STATUS_SUCCESS != g_process.qz_inst[i].stream[j].job_status || CPA_DC_OK != resl->status)) { QZ_DEBUG("Error(%d) in callback: %d, %d, ReqStatus: %d\n", g_process.qz_inst[i].stream[j].job_status, i, j, g_process.qz_inst[i].stream[j].res.status); /* polled error/dummy respond , fallback to sw */ rc = compOutSWFallback(i, j, sess, &dest_avail_len); if (QZ_FAIL == rc) { QZ_ERROR("Error in SW CompOut:inst %d, buffer %d, seq %ld\n", i, j, qz_sess->seq_in); goto err_exit; } if (QZ_BUF_ERROR == rc) { continue; } } else { /* polled HW respond */ QZ_DEBUG("\tHW CompOut: consumed = %d, produced = %d, seq_in = %ld\n", resl->consumed, resl->produced, g_process.qz_inst[i].stream[j].seq); unsigned int dest_receive_sz = outputHeaderSz(data_fmt) + resl->produced + outputFooterSz(data_fmt); if (QZ_OK != compOutCheckDestLen(i, j, sess, &dest_avail_len, dest_receive_sz)) { continue; } /* Update qz_sess info and clean dest buffer */ outputHeaderGen(qz_sess->next_dest, resl, data_fmt); qz_sess->next_dest += outputHeaderSz(data_fmt); qz_sess->qz_out_len += outputHeaderSz(data_fmt); compOutValidDestBufferCleanUp(i, j, qz_sess, resl->produced); qz_sess->next_dest += resl->produced; qz_sess->qz_in_len += resl->consumed; if (likely(NULL != qz_sess->crc32 && IS_DEFLATE(data_fmt))) { if (0 == *(qz_sess->crc32)) { *(qz_sess->crc32) = resl->checksum; } else { *(qz_sess->crc32) = crc32_combine(*(qz_sess->crc32), resl->checksum, resl->consumed); } } qz_sess->qz_out_len += resl->produced; outputFooterGen(qz_sess->next_dest, resl, data_fmt); qz_sess->next_dest += outputFooterSz(data_fmt); qz_sess->qz_out_len += outputFooterSz(data_fmt); } /* process finished! */ compOutProcessedRespond(i, j, qz_sess); break; } } if (QZ_PERIODICAL_POLLING == polling_mode) { if (0 == good) { qz_sess->polling_idx = (qz_sess->polling_idx >= POLLING_LIST_NUM - 1) ? (POLLING_LIST_NUM - 1) : (qz_sess->polling_idx + 1); QZ_DEBUG("comp sleep for %d usec..., for inst %d\n", g_polling_interval[qz_sess->polling_idx], i); usleep(g_polling_interval[qz_sess->polling_idx]); sleep_cnt++; } else { qz_sess->polling_idx = (qz_sess->polling_idx == 0) ? (0) : (qz_sess->polling_idx - 1); } } } QZ_DEBUG("Comp sleep_cnt: %u\n", sleep_cnt); if (qz_sess->stop_submitting || qz_sess->last_submitted) { qz_sess->last_processed = 1; } else { qz_sess->last_processed = 0; } return NULL; err_exit: sess->thd_sess_stat = QZ_FAIL; qz_sess->stop_submitting = 1; qz_sess->last_processed = 1; /*clean stream buffer*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { RestoreSrcCpastreamBuffer(i, j); RestoreDestCpastreamBuffer(i, j); ResetCpastreamSink(i, j); } return NULL; } unsigned char getSwBackup(QzSession_T *sess) { QzSess_T *qz_sess; if (sess->internal != NULL) { qz_sess = (QzSess_T *)sess->internal; return qz_sess->sess_params.sw_backup; } else { return g_sess_params_internal_default.sw_backup; } } static void resetQzsess(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, const unsigned char *dest, unsigned int *dest_len, unsigned int last) { QzSess_T *qz_sess; qz_sess = (QzSess_T *)(sess->internal); sess->thd_sess_stat = QZ_OK; qz_sess->submitted = 0; qz_sess->processed = 0; qz_sess->last_submitted = 0; qz_sess->last_processed = 0; qz_sess->stop_submitting = 0; qz_sess->qz_in_len = 0; qz_sess->qz_out_len = 0; qz_sess->force_sw = 0; qz_sess->single_thread = 0; qz_sess->seq = 0; qz_sess->seq_in = 0; qz_sess->src = (unsigned char *)src; qz_sess->src_sz = src_len; qz_sess->dest_sz = dest_len; qz_sess->next_dest = (unsigned char *)dest; qz_sess->last = last; } static int lz4sPostProcess(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc) { QzSess_T *qz_sess; qz_sess = (QzSess_T *)(sess->internal); if (sess->thd_sess_stat == QZ_OK || (sess->thd_sess_stat == QZ_BUF_ERROR && 0 != *src_len)) { int error_code = 0; int callback_status = qz_sess->sess_params.qzCallback( qz_sess->sess_params.qzCallback_external, src, src_len, dest, dest_len, &error_code); if (callback_status == QZ_OK) { qz_sess->qz_out_len = *dest_len; if (!ext_rc) { QZ_ERROR("Invalid ext_rc pointer!\n"); } else { *ext_rc = 0; } } else { QZ_ERROR("Error when call lz4s post-processing callback\n"); if (!ext_rc) { QZ_ERROR("Invalid ext_rc pointer!\n"); } else { *ext_rc = (uint64_t)error_code; } sess->thd_sess_stat = callback_status; return sess->thd_sess_stat; } } else { QZ_ERROR("Error lz4s compresse failed\n"); return QZ_FAIL; } return QZ_OK; } /* The QATzip compression API */ int qzCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { return qzCompressExt(sess, src, src_len, dest, dest_len, last, NULL); } int qzCompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *ext_rc) { if (NULL == sess || (last != 0 && last != 1)) { if (NULL != src_len) { *src_len = 0; } if (NULL != dest_len) { *dest_len = 0; } return QZ_PARAMS; } return qzCompressCrcExt(sess, src, src_len, dest, dest_len, last, NULL, ext_rc); } int qzCompressCrc(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc) { return qzCompressCrcExt(sess, src, src_len, dest, dest_len, last, crc, NULL); } int qzCompressCrcExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc, uint64_t *ext_rc) { int i, reqcnt; QzSess_T *qz_sess; int rc; if (unlikely(NULL == sess || \ NULL == src || \ NULL == src_len || \ NULL == dest || \ NULL == dest_len || \ (last != 0 && last != 1))) { rc = QZ_PARAMS; goto err_exit; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { goto err_exit; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { if (g_sess_params_internal_default.data_fmt == LZ4_FH) { rc = qzSetupSessionLZ4(sess, NULL); } else if (g_sess_params_internal_default.data_fmt == LZ4S_BK) { rc = qzSetupSessionLZ4S(sess, NULL); } else if (g_sess_params_internal_default.data_fmt == DEFLATE_ZLIB) { rc = qzSetupSessionDeflateExt(sess, NULL); } else { rc = qzSetupSessionDeflate(sess, NULL); } if (unlikely(QZ_SETUP_SESSION_FAIL(rc))) { goto err_exit; } } qz_sess = (QzSess_T *)(sess->internal); if (g_sess_params_internal_default.data_fmt == DEFLATE_ZLIB) { qz_sess->sess_params.data_fmt = DEFLATE_ZLIB; } DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; if (unlikely(data_fmt != DEFLATE_4B && data_fmt != DEFLATE_RAW && data_fmt != DEFLATE_GZIP && data_fmt != DEFLATE_GZIP_EXT && data_fmt != LZ4_FH && data_fmt != DEFLATE_ZLIB && data_fmt != LZ4S_BK)) { QZ_ERROR("Unknown data format: %d\n", data_fmt); rc = QZ_UNSUPPORTED_FMT; goto err_exit; } QZ_DEBUG("qzCompressCrc data_fmt: %d, input crc32 is 0x%lX\n", data_fmt, crc ? *crc : 0); qz_sess->crc32 = crc; if (*src_len < qz_sess->sess_params.input_sz_thrshold || g_process.qz_init_status == QZ_NO_HW || sess->hw_session_stat == QZ_NO_HW #if !((CPA_DC_API_VERSION_NUM_MAJOR >= 3) && (CPA_DC_API_VERSION_NUM_MINOR >= 0)) || qz_sess->sess_params.comp_lvl == 9 #endif ) { QZ_INFO("compression src_len=%u, sess_params.input_sz_thrshold = %u, " "process.qz_init_status = %d, sess->hw_session_stat = %ld, " " switch to software.\n", *src_len, qz_sess->sess_params.input_sz_thrshold, g_process.qz_init_status, sess->hw_session_stat); goto sw_compression; } else if (sess->hw_session_stat != QZ_OK && sess->hw_session_stat != QZ_NO_INST_ATTACH) { rc = sess->hw_session_stat; goto err_exit; } if (qz_sess->sess_params.is_sensitive_mode == true && chooseLSMPath(qz_sess) == LSM_SW) { rc = compLSMFallback(sess, src, src_len, dest, dest_len, last); return rc; } unsigned long start_time_stamp, end_time_stamp; start_time_stamp = rdtsc(); i = qzGrabInstance(qz_sess->inst_hint, &(qz_sess->sess_params)); if (unlikely(i == -1)) { if (qz_sess->sess_params.sw_backup == 1) { goto sw_compression; } else { sess->hw_session_stat = QZ_NO_INST_ATTACH; rc = QZ_NOSW_NO_INST_ATTACH; goto err_exit; } /*Make this a s/w compression*/ } QZ_INFO("qzCompress: inst is %d\n", i); qz_sess->inst_hint = i; if (likely(0 == g_process.qz_inst[i].mem_setup || 0 == g_process.qz_inst[i].cpa_sess_setup)) { QZ_INFO("Getting HW resources for inst %d\n", i); rc = qzSetupHW(sess, i); if (unlikely(QZ_OK != rc)) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_compression; } else { goto err_exit; } } } else if (memcmp(&g_process.qz_inst[i].session_setup_data, &qz_sess->session_setup_data, sizeof(CpaDcSessionSetupData))) { /* session_setup_data of qz_sess is not same with instance i, need to update cpa session of instance i. */ rc = qzUpdateCpaSession(sess, i); if (QZ_OK != rc) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_compression; } else { goto err_exit; } } } #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), COMPRESSION, HW); #endif resetQzsess(sess, src, src_len, dest, dest_len, last); reqcnt = *src_len / qz_sess->sess_params.hw_buff_sz; if (*src_len % qz_sess->sess_params.hw_buff_sz) { reqcnt++; } if (reqcnt > qz_sess->sess_params.req_cnt_thrshold) { pthread_create(&(qz_sess->c_th_i), NULL, doCompressIn, (void *)sess); doCompressOut((void *)sess); pthread_join(qz_sess->c_th_i, NULL); } else { qz_sess->single_thread = 1; doCompressIn((void *)sess); doCompressOut((void *)sess); } qzReleaseInstance(i); end_time_stamp = rdtsc(); if (qz_sess->sess_params.is_sensitive_mode == true) { metrixUpdate(&qz_sess->RRT, (end_time_stamp - start_time_stamp)); } rc = sess->thd_sess_stat; if (qz_sess->seq != qz_sess->seq_in) { /* this means the HW get data already error, qz_in_len and qz_out_len can't equal */ QZ_ERROR("The thread : %lu, Compress API failed! fatal error!\n", pthread_self()); goto err_exit; } /* if failure need to fallback to sw */ if (QZ_OK != sess->thd_sess_stat && QZ_BUF_ERROR != rc && qz_sess->sess_params.sw_backup == 1) { const unsigned char *sw_src = src + qz_sess->qz_in_len; unsigned int sw_src_len = *src_len - qz_sess->qz_in_len; unsigned char *sw_dest = qz_sess->next_dest; unsigned int sw_dest_len = *dest_len - (qz_sess->next_dest - dest); QZ_DEBUG("SW Comp Sending %u bytes, the rest comp all fallback to SW", sw_src_len); rc = qzSWCompress(sess, sw_src, &sw_src_len, sw_dest, &sw_dest_len, last); if (QZ_OK == rc) { qz_sess->qz_in_len += sw_src_len; qz_sess->qz_out_len += sw_dest_len; qz_sess->next_dest += sw_dest_len; sess->thd_sess_stat = rc; } else { QZ_ERROR("SW Comp fallback failure! compress error!\n"); } } *dest_len = qz_sess->next_dest - dest; *src_len = GET_LOWER_32BITS(qz_sess->qz_in_len); sess->total_in += qz_sess->qz_in_len; sess->total_out += qz_sess->qz_out_len; QZ_INFO("*** total_in = %lu total_out = %lu src_len = %u dest_len = %u ***\n", sess->total_in, sess->total_out, *src_len, *dest_len); assert(*dest_len == qz_sess->qz_out_len); //trigger post-processing if (data_fmt == LZ4S_BK && qz_sess->sess_params.qzCallback) { unsigned long spp_time_stamp = rdtsc(); rc = lz4sPostProcess(sess, src, src_len, dest, dest_len, ext_rc); if (QZ_OK != rc) { goto err_exit; } unsigned long epp_time_stamp = rdtsc(); if (qz_sess->sess_params.is_sensitive_mode == true) { metrixUpdate(&qz_sess->PPT, (epp_time_stamp - spp_time_stamp)); } } return sess->thd_sess_stat; sw_compression: QZ_INFO("The thread : %lu, Compress API SW fallback due to HW limitaions!\n", pthread_self()); return qzSWCompress(sess, src, src_len, dest, dest_len, last); err_exit: if (NULL != src_len) { *src_len = 0; } if (NULL != dest_len) { *dest_len = 0; } return rc; } /* The internal function to send the decompression request * to the QAT hardware * sess->thd_sess_stat carry QZ_OK && QZ_DATA_ERROR && QZ_BUF_ERROR && QZ_FAIL */ static void *doDecompressIn(void *in) { unsigned long i, tag; int rc = 0; int j; unsigned int done = 0; unsigned int remaining; unsigned int src_avail_len, dest_avail_len; unsigned int tmp_src_avail_len, tmp_dest_avail_len; unsigned char *src_ptr; unsigned char *dest_ptr; QzGzH_T hdr = {{0}, 0}; QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; struct timespec sleep_time; sleep_time.tv_sec = 0; sleep_time.tv_nsec = GET_BUFFER_SLEEP_NSEC; i = qz_sess->inst_hint; j = -1; /* For offlod request, src_ptr, dest_ptr, remaining and src_avail_len, dest_avail_len will update */ src_ptr = qz_sess->src + qz_sess->qz_in_len; dest_ptr = qz_sess->next_dest; remaining = *qz_sess->src_sz - qz_sess->qz_in_len; src_avail_len = remaining; dest_avail_len = (long)(*qz_sess->dest_sz - qz_sess->qz_out_len); QZ_DEBUG("doDecompressIn: Need to g_process %d bytes\n", remaining); /* rc will only maintain in this function, thd_sess_stat will return the error status */ while (!done) { QZ_DEBUG("src_avail_len is %u, dest_avail_len is %u\n", src_avail_len, dest_avail_len); rc = checkHeader(qz_sess, src_ptr, src_avail_len, dest_avail_len, &hdr); if (QZ_OK != rc && QZ_FORCE_SW != rc) { sess->thd_sess_stat = rc; goto err_exit; } if (g_process.qz_inst[i].heartbeat != CPA_STATUS_SUCCESS || QZ_FORCE_SW == rc) { tmp_src_avail_len = src_avail_len; tmp_dest_avail_len = dest_avail_len; rc = decompInSWFallback(i, j, sess, src_ptr, dest_ptr, &tmp_src_avail_len, &tmp_dest_avail_len); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } else { /*HW decompression*/ do { j = getUnusedBuffer(i, j); /* if decompres is in single thread mode, no body gone consume the * buffer, it shows something wrong in program, need to exit with * error, otherwise, program will hang at the nanosleep, it would * never get the avaliable buffer. */ if (qz_sess->single_thread) { if (unlikely((-1 == j) || ((0 == qz_sess->seq % qz_sess->sess_params.req_cnt_thrshold) && (qz_sess->seq > qz_sess->seq_in)))) { return ((void *) NULL); } } else { if (unlikely(-1 == j)) { nanosleep(&sleep_time, NULL); } } } while (-1 == j); QZ_DEBUG("getUnusedBuffer returned %d\n", j); g_process.qz_inst[i].stream[j].src1++;/*this buffer is in use*/ decompBufferSetup(i, j, qz_sess, src_ptr, dest_ptr, src_avail_len, &hdr, &tmp_src_avail_len, &tmp_dest_avail_len); g_process.qz_inst[i].stream[j].src2++;/*this buffer is in use*/ do { tag = (i << 16) | j; QZ_DEBUG("Decomp Sending i = %ld j = %d src_ptr = %p dest_ptr = %p seq = %ld tag = %ld\n", i, j, src_ptr, dest_ptr, g_process.qz_inst[i].stream[j].seq, tag); rc = cpaDcDecompressData(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, g_process.qz_inst[i].src_buffers[j], g_process.qz_inst[i].dest_buffers[j], &g_process.qz_inst[i].stream[j].res, CPA_DC_FLUSH_FINAL, (void *)(tag)); if (unlikely(CPA_STATUS_RETRY == rc)) { g_process.qz_inst[i].num_retries++; usleep(g_polling_interval[qz_sess->polling_idx]); } if (unlikely(g_process.qz_inst[i].num_retries > MAX_NUM_RETRY)) { QZ_WARN("instance %lu retry count:%d exceed the max count: %d\n", i, g_process.qz_inst[i].num_retries, MAX_NUM_RETRY); break; } } while (rc == CPA_STATUS_RETRY); g_process.qz_inst[i].num_retries = 0; if (unlikely(CPA_STATUS_SUCCESS != rc)) { QZ_WARN("Inst %ld, buffer %d, Error in decompIn offload: %d\n", i, j, rc); decompInBufferCleanUp(i, j); tmp_src_avail_len = src_avail_len; tmp_dest_avail_len = dest_avail_len; rc = decompInSWFallback(i, j, sess, src_ptr, dest_ptr, &tmp_src_avail_len, &tmp_dest_avail_len); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } } /* update the request src info status */ src_ptr += tmp_src_avail_len; dest_ptr += tmp_dest_avail_len; src_avail_len -= tmp_src_avail_len; dest_avail_len -= tmp_dest_avail_len; remaining -= tmp_src_avail_len; /* update qz_sess status */ qz_sess->seq++; qz_sess->submitted++; /*stop_decompression_stream_end is valid for gzip and gzip ext where multiple decompress requests can be submitted. Given we can identify streams/chunk with header and footer. Zlib and deflate raw always takes decompression as a single job as we cannot identify the stream boundries.Job size can be as big as QAT HW buffer*/ if (qz_sess->stop_submitting || qz_sess->sess_params.stop_decompression_stream_end == 1) { remaining = 0; } QZ_DEBUG("src_ptr is %p, remaining is %d\n", src_ptr, remaining); if (0 == remaining) { done = 1; qz_sess->last_submitted = 1; } } return ((void *)NULL); err_exit: /*reset the qz_sess status*/ qz_sess->stop_submitting = 1; qz_sess->last_submitted = 1; return ((void *)NULL); } /* The internal function to g_process the decompression response * from the QAT hardware */ /* A fix for the chunksize test performance. Without the attribute * cold it will lead to a performance drop in the chunksize test. * Will root cause it and fix it in the future version * * sess->thd_sess_stat carry QZ_OK && QZ_DATA_ERROR && QZ_FAIL * QZ_DATA_ERROR it seems have conflict with decompressIn */ static void *__attribute__((cold)) doDecompressOut(void *in) { int i = 0, j = 0, good; int rc = 0; CpaDcRqResults *resl; CpaStatus sts; unsigned int sleep_cnt = 0; unsigned int done = 0; unsigned int src_send_sz; unsigned int dest_avail_len; QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; QzPollingMode_T polling_mode = qz_sess->sess_params.polling_mode; i = qz_sess->inst_hint; dest_avail_len = *qz_sess->dest_sz - qz_sess->qz_out_len; while (!done) { /* Poll for responses */ good = 0; sts = icp_sal_DcPollInstance(g_process.dc_inst_handle[i], 0); if (unlikely(CPA_STATUS_FAIL == sts)) { /* if this error, we don't know which buffer is swapped */ QZ_ERROR("Error in DcPoll: %d\n", sts); goto err_exit; } /*fake a retrieve*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if ((g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in) && (g_process.qz_inst[i].stream[j].src1 == g_process.qz_inst[i].stream[j].src2) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].src1) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].sink2 + 1)) { good = 1; QZ_DEBUG("doDecompressOut: Processing seqnumber %2.2d %2.2d %4.4ld\n", i, j, g_process.qz_inst[i].stream[j].seq); if (unlikely(QZ_DATA_ERROR == sess->thd_sess_stat)) { decompOutSkipErrorRespond(i, j, qz_sess); continue; } if (unlikely(CPA_STATUS_SUCCESS != g_process.qz_inst[i].stream[j].job_status)) { QZ_DEBUG("Error(%d) in callback: %d, %d, ReqStatus: %d\n", g_process.qz_inst[i].stream[j].job_status, i, j, g_process.qz_inst[i].stream[j].res.status); /* polled error/dummy respond , fallback to sw */ rc = decompOutSWFallback(i, j, sess, &dest_avail_len); if (QZ_FAIL == rc) { QZ_ERROR("Error in SW deCompOut:inst %d, buffer %d, seq %ld\n", i, j, qz_sess->seq_in); /* Need to swap buffer, even sw fallback failed */ swapDataBuffer(i, j); goto err_exit; } } else { resl = &g_process.qz_inst[i].stream[j].res; QZ_DEBUG("\tHW DecompOut: consumed = %d, produced = %d, seq_in = %ld, src_send_sz = %u\n", resl->consumed, resl->produced, g_process.qz_inst[i].stream[j].seq, g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes); /* update the qz_sess info and clean dest buffer */ decompOutValidDestBufferCleanUp(i, j, qz_sess, resl, dest_avail_len); if (QZ_OK != decompOutCheckSum(i, j, sess, resl)) { continue; } /* changed src_send_sz to actual data consumed by HW. */ src_send_sz = resl->consumed; qz_sess->next_dest += resl->produced; qz_sess->qz_in_len += (outputHeaderSz(data_fmt) + src_send_sz + outputFooterSz(data_fmt)); qz_sess->qz_out_len += resl->produced; dest_avail_len -= resl->produced; if (resl->endOfLastBlock == CPA_TRUE) { QZ_DEBUG("\tHW DecompOut: endOfLastBlock \n"); setDeflateEndOfStream(qz_sess, 1); } } decompOutProcessedRespond(i, j, qz_sess); break; } } if (qz_sess->single_thread) { done = (qz_sess->processed == qz_sess->submitted); } else { done = (qz_sess->last_submitted) && (qz_sess->processed == qz_sess->submitted); } if (QZ_PERIODICAL_POLLING == polling_mode) { if (0 == good) { qz_sess->polling_idx = (qz_sess->polling_idx >= POLLING_LIST_NUM - 1) ? (POLLING_LIST_NUM - 1) : (qz_sess->polling_idx + 1); QZ_DEBUG("decomp sleep for %d usec..., for inst %d\n", g_polling_interval[qz_sess->polling_idx], i); usleep(g_polling_interval[qz_sess->polling_idx]); sleep_cnt++; } else { qz_sess->polling_idx = (qz_sess->polling_idx == 0) ? (0) : (qz_sess->polling_idx - 1); } } } QZ_DEBUG("Decomp sleep_cnt: %u\n", sleep_cnt); qz_sess->last_processed = qz_sess->last_submitted ? 1 : 0; return NULL; err_exit: qz_sess->stop_submitting = 1; qz_sess->last_processed = 1; sess->thd_sess_stat = QZ_FAIL; /* clean stream buffer */ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { RestoreSrcCpastreamBuffer(i, j); RestoreDestCpastreamBuffer(i, j); ResetCpastreamSink(i, j); } /* need add flag for buffer swap. swapDataBuffer(i, j); */ return ((void *)NULL); } /* The internal function to process the single thread decompress * in qzDecompress() */ static void *doQzDecompressSingleThread(void *in) { QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; qz_sess->last_processed = 0; while (!qz_sess->last_processed) { doDecompressIn((void *)sess); doDecompressOut((void *)sess); } return NULL; } /* The QATzip decompression API */ int qzDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { return qzDecompressCrcExt(sess, src, src_len, dest, dest_len, NULL, NULL); } int qzDecompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc) { return qzDecompressCrcExt(sess, src, src_len, dest, dest_len, NULL, ext_rc); } int qzDecompressCrc(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned long *crc) { return qzDecompressCrcExt(sess, src, src_len, dest, dest_len, crc, NULL); } int qzDecompressCrcExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned long *crc, uint64_t *ext_rc) { int rc; int i, reqcnt; QzSess_T *qz_sess; QzGzH_T *hdr = (QzGzH_T *)src; if (unlikely(NULL == sess || \ NULL == src || \ NULL == src_len || \ NULL == dest || \ NULL == dest_len)) { rc = QZ_PARAMS; goto err_exit; } if (0 == *src_len) { *dest_len = 0; return QZ_OK; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { goto err_exit; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { if (g_sess_params_internal_default.data_fmt == LZ4_FH) { rc = qzSetupSessionLZ4(sess, NULL); } else if (g_sess_params_internal_default.data_fmt == LZ4S_BK) { rc = qzSetupSessionLZ4S(sess, NULL); } else if (g_sess_params_internal_default.data_fmt == DEFLATE_ZLIB) { rc = qzSetupSessionDeflateExt(sess, NULL); } else { rc = qzSetupSessionDeflate(sess, NULL); } if (unlikely(QZ_SETUP_SESSION_FAIL(rc))) { goto err_exit; } } qz_sess = (QzSess_T *)(sess->internal); if (g_sess_params_internal_default.data_fmt == DEFLATE_ZLIB) { qz_sess->sess_params.data_fmt = DEFLATE_ZLIB; } // by default end of stream is set to 0 setDeflateEndOfStream(qz_sess, 0); DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; if (unlikely(data_fmt != DEFLATE_RAW && data_fmt != DEFLATE_4B && data_fmt != DEFLATE_GZIP && data_fmt != LZ4_FH && data_fmt != DEFLATE_ZLIB && data_fmt != DEFLATE_GZIP_EXT)) { QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); rc = QZ_UNSUPPORTED_FMT; goto err_exit; } QZ_DEBUG("qzDecompress data_fmt: %d\n", data_fmt); if ((data_fmt == DEFLATE_GZIP_EXT && hdr->extra.qz_e.src_sz < qz_sess->sess_params.input_sz_thrshold) || g_process.qz_init_status == QZ_NO_HW || sess->hw_session_stat == QZ_NO_HW || !(isQATProcessable(src, src_len, qz_sess)) || qz_sess->inflate_stat == InflateOK) { QZ_INFO("decompression src_len=%u, hdr->extra.qz_e.src_sz = %u, " "g_process.qz_init_status = %d, sess->hw_session_stat = %ld, " "isQATProcessable = %d, switch to software.\n", *src_len, hdr->extra.qz_e.src_sz, g_process.qz_init_status, sess->hw_session_stat, isQATProcessable(src, src_len, qz_sess)); /* If sw_backup is 1, fallback to software compression. */ if (qz_sess->sess_params.sw_backup == 1) { goto sw_decompression; } else { rc = QZ_FAIL; goto err_exit; } } else if (sess->hw_session_stat != QZ_OK && sess->hw_session_stat != QZ_NO_INST_ATTACH) { rc = sess->hw_session_stat; goto err_exit; } if (qz_sess->sess_params.is_sensitive_mode == true && chooseLSMPath(qz_sess) == LSM_SW) { rc = decompLSMFallback(sess, src, src_len, dest, dest_len); return rc; } unsigned long start_time_stamp, end_time_stamp; start_time_stamp = rdtsc(); i = qzGrabInstance(qz_sess->inst_hint, &(qz_sess->sess_params)); if (unlikely(i == -1)) { if (qz_sess->sess_params.sw_backup == 1) { QZ_INFO("Don't grab HW instance, fallback to sw\n"); goto sw_decompression; } else { sess->hw_session_stat = QZ_NO_INST_ATTACH; rc = QZ_NOSW_NO_INST_ATTACH; goto err_exit; } /*Make this a s/w compression*/ } QZ_INFO("qzDecompress: inst is %d\n", i); qz_sess->inst_hint = i; if (likely(0 == g_process.qz_inst[i].mem_setup || 0 == g_process.qz_inst[i].cpa_sess_setup)) { QZ_INFO("Getting HW resources for inst %d\n", i); rc = qzSetupHW(sess, i); if (unlikely(QZ_OK != rc)) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_decompression; } else { goto err_exit; } } } else if (memcmp(&g_process.qz_inst[i].session_setup_data, &qz_sess->session_setup_data, sizeof(CpaDcSessionSetupData))) { /* session_setup_data of qz_sess is not same with instance i, need to update cpa session of instance i. */ rc = qzUpdateCpaSession(sess, i); if (QZ_OK != rc) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_decompression; } else { goto err_exit; } } } #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), DECOMPRESSION, HW); #endif resetQzsess(sess, src, src_len, dest, dest_len, 0); reqcnt = *src_len / (qz_sess->sess_params.hw_buff_sz / 2); if (*src_len % (qz_sess->sess_params.hw_buff_sz / 2)) { reqcnt++; } if (reqcnt > qz_sess->sess_params.req_cnt_thrshold) { qz_sess->single_thread = 0; pthread_create(&(qz_sess->c_th_i), NULL, doDecompressIn, (void *)sess); doDecompressOut((void *)sess); pthread_join(qz_sess->c_th_i, NULL); } else { qz_sess->single_thread = 1; doQzDecompressSingleThread((void *)sess); } qzReleaseInstance(i); end_time_stamp = rdtsc(); if (qz_sess->sess_params.is_sensitive_mode == true) { metrixUpdate(&qz_sess->RRT, (end_time_stamp - start_time_stamp)); } QZ_DEBUG("PRoduced %lu bytes\n", sess->total_out); rc = sess->thd_sess_stat; if (qz_sess->seq != qz_sess->seq_in) { /* this means the HW get data already error, qz_in_len and qz_out_len can't corresponding */ QZ_ERROR("The thread : %lu, Decompress API failed! error status %d!\n", pthread_self(), rc); goto err_exit; } /* if failure need to fallback to sw */ if (QZ_OK != sess->thd_sess_stat && QZ_BUF_ERROR != sess->thd_sess_stat && QZ_DATA_ERROR != sess->thd_sess_stat && qz_sess->sess_params.sw_backup == 1) { const unsigned char *sw_src = src + qz_sess->qz_in_len; unsigned int sw_src_len = *src_len - qz_sess->qz_in_len; unsigned char *sw_dest = qz_sess->next_dest; unsigned int sw_dest_len = *dest_len - (qz_sess->next_dest - dest); QZ_DEBUG("SW deComp Sending %u bytes, the rest decomp all fallback to SW", sw_src_len); rc = qzSWDecompressMulti(sess, sw_src, &sw_src_len, sw_dest, &sw_dest_len); if (QZ_OK == rc) { qz_sess->qz_in_len += sw_src_len; qz_sess->qz_out_len += sw_dest_len; qz_sess->next_dest += sw_dest_len; sess->thd_sess_stat = rc; } else { QZ_ERROR("SW deComp fallback failure! decompress error!\n"); } } *src_len = GET_LOWER_32BITS(qz_sess->qz_in_len); *dest_len = qz_sess->next_dest - dest; assert(*dest_len == qz_sess->qz_out_len); sess->total_in += qz_sess->qz_in_len; sess->total_out += qz_sess->qz_out_len; QZ_INFO("*** total_in=%lu total_out=%lu src_len=%u dest_len=%u rc=%d ***\n", sess->total_in, sess->total_out, *src_len, *dest_len, rc); return sess->thd_sess_stat; sw_decompression: QZ_INFO("The thread : %lu, DeCompress API SW fallback due to HW limitations!\n", pthread_self()); return qzSWDecompressMulti(sess, src, src_len, dest, dest_len); err_exit: if (NULL != src_len) { *src_len = 0; } if (NULL != dest_len) { *dest_len = 0; } return rc; } int qzTeardownSession(QzSession_T *sess) { if (unlikely(sess == NULL)) { return QZ_PARAMS; } if (likely(NULL != sess->internal)) { QzSess_T *qz_sess = (QzSess_T *) sess->internal; if (likely(NULL != qz_sess->inflate_strm)) { inflateEnd(qz_sess->inflate_strm); free(qz_sess->inflate_strm); qz_sess->inflate_strm = NULL; } if (likely(NULL != qz_sess->deflate_strm)) { deflateEnd(qz_sess->deflate_strm); free(qz_sess->deflate_strm); qz_sess->deflate_strm = NULL; } if (unlikely(NULL != qz_sess->RRT.latency_array)) { free(qz_sess->RRT.latency_array); qz_sess->RRT.latency_array = NULL; } if (unlikely(NULL != qz_sess->PPT.latency_array)) { free(qz_sess->PPT.latency_array); qz_sess->PPT.latency_array = NULL; } if (unlikely(NULL != qz_sess->SWT.latency_array)) { free(qz_sess->SWT.latency_array); qz_sess->SWT.latency_array = NULL; } if (qz_sess->qzdeflateExtData != NULL) { free(qz_sess->qzdeflateExtData); qz_sess->qzdeflateExtData = NULL; } // Delete the async relative job and queue if (NULL != qz_sess->async_ctrl) { AsyncCtrlDestructor(sess); } free(sess->internal); sess->internal = NULL; } return QZ_OK; } void removeSession(int i) { CpaStatus status = CPA_STATUS_SUCCESS; if (0 == g_process.qz_inst[i].cpa_sess_setup) { return; } /* Remove session */ if ((NULL != g_process.dc_inst_handle[i]) && (NULL != g_process.qz_inst[i].cpaSess)) { status = cpaDcRemoveSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess); if (CPA_STATUS_SUCCESS == status) { /* Deallocate session memory */ qzFree(g_process.qz_inst[i].cpaSess); g_process.qz_inst[i].cpaSess = NULL; g_process.qz_inst[i].cpa_sess_setup = 0; } else { QZ_ERROR("ERROR in Remove Instance %d session\n", i); } } } int qzClose(QzSession_T *sess) { if (unlikely(sess == NULL)) { return QZ_PARAMS; } return QZ_OK; } int qzGetStatus(QzSession_T *sess, QzStatus_T *status) { if (sess == NULL || status == NULL) { return QZ_PARAMS; } return QZ_OK; } int qzGetDeflateEndOfStream(QzSession_T *sess, unsigned char *endofstream) { if (sess == NULL || endofstream == NULL) { return QZ_PARAMS; } if (sess->internal != NULL) { QzSess_T *qz_sess; qz_sess = (QzSess_T *)sess->internal; *endofstream = getDeflateEndOfStream(qz_sess); return QZ_OK; } return QZ_PARAMS; } int qzSetDefaults(QzSessionParams_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParams(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParams(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzSetDefaultsDeflate(QzSessionParamsDeflate_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParamsDeflate(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParamsDeflate(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzSetDefaultsDeflateExt(QzSessionParamsDeflateExt_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParamsDeflateExt(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParamsDeflateExt(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzSetDefaultsLZ4(QzSessionParamsLZ4_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParamsLZ4(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParamsLZ4(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzSetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParamsLZ4S(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParamsLZ4S(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaults(QzSessionParams_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParams(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaultsDeflate(QzSessionParamsDeflate_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParamsDeflate(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaultsDeflateExt(QzSessionParamsDeflateExt_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParamsDeflateExt(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaultsLZ4(QzSessionParamsLZ4_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParamsLZ4(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParamsLZ4S(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } static unsigned int qzDeflateBound(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; unsigned int chunk_cnt = 0; unsigned int hw_buffer_sz = 0; QzSess_T *qz_sess = NULL; CpaDcHuffType huffman_type; CpaStatus status = CPA_STATUS_SUCCESS; qz_sess = (QzSess_T *)sess->internal; /* Get the Huffman Tree type. */ if (qz_sess->sess_params.huffman_hdr == QZ_DYNAMIC_HDR) { huffman_type = CPA_DC_HT_FULL_DYNAMIC; } else { huffman_type = CPA_DC_HT_STATIC; } status = cpaDcDeflateCompressBound(NULL, huffman_type, src_sz, &dest_sz); if (status != CPA_STATUS_SUCCESS) { return 0; } hw_buffer_sz = qz_sess->sess_params.hw_buff_sz; /* cpaDcDeflateCompressBound only provides the maximum output size of deflate blocks, * it does not include gzip/gzip-ext header and footer size, so we need to update dest_sz * for header and footer size. */ /* Calculate how many gzip/gzip-ext headers and footers will be generated. */ chunk_cnt = src_sz / hw_buffer_sz + src_sz % hw_buffer_sz ? 1 : 0; if (qz_sess->sess_params.data_fmt == DEFLATE_ZLIB) { dest_sz += chunk_cnt * outputHeaderSz(qz_sess->sess_params.data_fmt) + chunk_cnt * outputFooterSz(qz_sess->sess_params.data_fmt); } else { dest_sz += chunk_cnt * (qzGzipHeaderSz() + stdGzipFooterSz()); } return dest_sz; } static unsigned int qzLZ4SBound(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; CpaStatus status = CPA_STATUS_SUCCESS; #if CPA_DC_API_VERSION_AT_LEAST(3, 1) status = cpaDcLZ4SCompressBound(NULL, src_sz, &dest_sz); if (status != CPA_STATUS_SUCCESS) { return 0; } #else (void)status; return 0; #endif return dest_sz; } static unsigned int qzLZ4Bound(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; unsigned int chunk_cnt = 0; QzSess_T *qz_sess = NULL; CpaStatus status = CPA_STATUS_SUCCESS; assert(sess); assert(sess->internal); #if CPA_DC_API_VERSION_AT_LEAST(3, 1) status = cpaDcLZ4CompressBound(NULL, src_sz, &dest_sz); if (status != CPA_STATUS_SUCCESS) { return 0; } #else (void)status; return 0; #endif /* cpaDcLZ4CompressBound only provides the maximum output size of lz4 blocks, * it does not include lz4 frames header and footer size, so we need to update dest_sz * for header and footer size. */ /* Calculate how many frames header and footer will be generated */ qz_sess = (QzSess_T *)sess->internal; chunk_cnt = src_sz / qz_sess->sess_params.hw_buff_sz + src_sz % qz_sess->sess_params.hw_buff_sz ? 1 : 0; dest_sz += chunk_cnt * outputHeaderSz(qz_sess->sess_params.data_fmt) + chunk_cnt * outputFooterSz(qz_sess->sess_params.data_fmt); return dest_sz; } unsigned int qzMaxCompressedLength(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; unsigned int chunk_cnt = 0; QzSess_T *qz_sess = NULL; if (src_sz == 0) { return QZ_COMPRESSED_SZ_OF_EMPTY_FILE; } if (sess == NULL || sess->internal == NULL || sess->hw_session_stat != QZ_OK) { uint64_t in_sz = src_sz; uint64_t out_sz = 0; out_sz = QZ_CEIL_DIV(9 * in_sz, 8) + QZ_SKID_PAD_SZ; chunk_cnt = in_sz / QZ_HW_BUFF_SZ + in_sz % QZ_HW_BUFF_SZ ? 1 : 0; out_sz += chunk_cnt * (qzGzipHeaderSz() + stdGzipFooterSz()); if (out_sz & 0xffffffff00000000UL) return 0; dest_sz = (unsigned int)out_sz; return dest_sz; } qz_sess = (QzSess_T *)sess->internal; switch (qz_sess->sess_params.data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: case DEFLATE_ZLIB: dest_sz = qzDeflateBound(src_sz, sess); break; case LZ4_FH: dest_sz = qzLZ4Bound(src_sz, sess); break; case LZ4S_BK: dest_sz = qzLZ4SBound(src_sz, sess); break; default: dest_sz = 0; break; } QZ_DEBUG("src_sz is %u, dest_sz is %u\n", src_sz, dest_sz); return dest_sz; } int qzGetSoftwareComponentCount(unsigned int *num_elem) { QZ_ERROR("qatzip don't support qzGetSoftwareComponentCount API yet!\n"); return QZ_FAIL; } int qzGetSoftwareComponentVersionList(QzSoftwareVersionInfo_T *api_info, unsigned int *num_elem) { QZ_ERROR("qatzip don't support qzGetSoftwareComponentVersionList API yet!\n"); return QZ_FAIL; } /** ***************************************************************************** * @ingroup qatZip Async API * Async API implement *****************************************************************************/ /* Get absolute time by relative time. */ static void get_sem_wait_abs_time(struct timespec *polling_abs_timeout, const struct timespec polling_timeout) { clock_gettime(CLOCK_REALTIME, polling_abs_timeout); /* Get current real time. */ polling_abs_timeout->tv_sec += polling_timeout.tv_sec; polling_abs_timeout->tv_nsec += polling_timeout.tv_nsec; polling_abs_timeout->tv_sec += polling_abs_timeout->tv_nsec / NSEC_TO_SEC; polling_abs_timeout->tv_nsec = polling_abs_timeout->tv_nsec % NSEC_TO_SEC; } /* This function call async callback function and process req pointer * if sess is not null, then recover sess status to ok */ void CallAsyncbackfn(QzAsyncReq_T **req_pointer, int status, QzSession_T *sess) { QzAsyncReq_T *req = *req_pointer; if (status != QZ_OK) { req->qzResults->src_len = 0; req->qzResults->dest_len = 0; } req->qzResults->status = status; req->qzAsyncallback(req->qzResults); free(req); *req_pointer = NULL; if (sess) { sess->thd_sess_stat = QZ_OK; } } static int AsyncCompressIn(QzAsyncReq_T *req) { unsigned long tag; int i, j; unsigned int done = 0; unsigned int src_send_sz; unsigned int remaining; unsigned char *src_ptr; unsigned int hw_buff_sz; CpaStatus rc; QzSession_T *sess = req->sess; QzSess_T *qz_sess = (QzSess_T *)sess->internal; struct timespec sleep_time; sleep_time.tv_sec = 0; sleep_time.tv_nsec = GET_BUFFER_SLEEP_NSEC; QZ_DEBUG("Always enable CnV\n"); i = qz_sess->inst_hint; j = -1; qz_sess->src = (unsigned char *)req->src; qz_sess->src_sz = &(req->qzResults->src_len); qz_sess->dest_sz = &(req->qzResults->dest_len); qz_sess->next_dest = req->dest; qz_sess->last = 1; qz_sess->crc32 = req->qzResults->crc != NULL && QZ_CRC32_VALID(req->qzResults->crc->valid_flags) ? (unsigned long *)req->qzResults->crc->in_crc.crc_32 : NULL; /* For offlod request, src_ptr, remaining and src_send_sz will update */ hw_buff_sz = qz_sess->sess_params.hw_buff_sz; src_ptr = qz_sess->src; remaining = *qz_sess->src_sz; src_send_sz = (remaining < hw_buff_sz) ? remaining : hw_buff_sz; QZ_DEBUG("doCompressIn: Need to g_process %u bytes\n", remaining); // don't support the sw fallback for async API while (!done) { /* HW offload */ do { j = getUnusedBuffer(i, j); if (unlikely(-1 == j)) { nanosleep(&sleep_time, NULL); } } while (-1 == j); QZ_DEBUG("getUnusedBuffer returned %d\n", j); g_process.qz_inst[i].stream[j].src1++; /*update stream src1*/ compBufferSetup(i, j, qz_sess, src_ptr, remaining, hw_buff_sz, src_send_sz); g_process.qz_inst[i].stream[j].req = req; g_process.qz_inst[i].stream[j].src2++;/*this buffer is in use*/ do { tag = ((unsigned long)i << 16) | (unsigned long)j; QZ_DEBUG("Comp Sending %u bytes ,opData.flushFlag = %d, i = %d j = %d seq = %ld tag = %ld\n", g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes, g_process.qz_inst[i].stream[j].opData.flushFlag, i, j, g_process.qz_inst[i].stream[j].seq, tag); rc = cpaDcCompressData2(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, g_process.qz_inst[i].src_buffers[j], g_process.qz_inst[i].dest_buffers[j], &g_process.qz_inst[i].stream[j].opData, &g_process.qz_inst[i].stream[j].res, (void *)(tag)); if (unlikely(CPA_STATUS_RETRY == rc)) { g_process.qz_inst[i].num_retries++; usleep(g_polling_interval[qz_sess->polling_idx]); } if (unlikely(g_process.qz_inst[i].num_retries > MAX_NUM_RETRY)) { QZ_ERROR("instance %d retry count:%d exceed the max count: %d\n", i, g_process.qz_inst[i].num_retries, MAX_NUM_RETRY); break; } } while (rc == CPA_STATUS_RETRY); g_process.qz_inst[i].num_retries = 0; if (unlikely(CPA_STATUS_SUCCESS != rc)) { QZ_ERROR("Inst %d, buffer %d, Error in compIn offload: %d\n", i, j, rc); compInBufferCleanUp(i, j); goto err_exit; } QZ_DEBUG("remaining = %u, src_send_sz = %u, seq = %ld\n", remaining, src_send_sz, qz_sess->seq); /* update the request src info status */ src_ptr += src_send_sz; remaining -= src_send_sz; src_send_sz = (remaining < hw_buff_sz) ? remaining : hw_buff_sz; /* update qz_sess status */ qz_sess->seq++; qz_sess->submitted++; if (unlikely(qz_sess->stop_submitting)) { remaining = 0; } if (0 == remaining) { done = 1; // qz_sess->last_submitted = 1; } } return QZ_OK; err_exit: /*reset the qz_sess status*/ qz_sess->stop_submitting = 1; // qz_sess->last_submitted = 1; sess->thd_sess_stat = QZ_FAIL; return QZ_FAIL; } /* The internal function to g_process the compression response * from the QAT hardware * sess->thd_sess_stat only carry QZ_OK and QZ_FAIL and QZ_BUF_ERROR */ static void *AsyncCompressOut(void *in) { int j = 0, good = -1; CpaDcRqResults *resl; CpaStatus sts; unsigned int sleep_cnt = 0; /* The req may have different size, some req would grab numbers of * stream buffer, those two pointer is used to check if the preview * request have process finished and called callback function. */ QzAsyncReq_T *req = NULL; QzAsyncReq_T *req_prv = NULL; QzSession_T *sess = (QzSession_T *) in; QzSess_T *qz_sess = (QzSess_T *) sess->internal; unsigned long *qz_crc32 = NULL; int i = qz_sess->inst_hint; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; QzPollingMode_T polling_mode = qz_sess->sess_params.polling_mode; while (((qz_sess->last_submitted == 0) || (qz_sess->processed < qz_sess->submitted))) { /* Poll for responses */ good = 0; /* For this call, return error, we have to make sure all stream buffer is reset * which is not just for RestoreSrcCpastreamBuffer, but also * make src1, src2, sink1, sink2 equal, and all switch. */ sts = icp_sal_DcPollInstance(g_process.dc_inst_handle[i], 0); if (unlikely(CPA_STATUS_FAIL == sts)) { /* this will cause the in-flight request is not finished */ QZ_ERROR("Error in DcPoll: %d\n", sts); /* TODO: This would cause the background polling thread exit * Maybe we should never let this happend, otherwise we need * mechanism to check the status of this polling thread. */ goto err_exit; } /*fake a retrieve*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if ((g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in) && (g_process.qz_inst[i].stream[j].src1 == g_process.qz_inst[i].stream[j].src2) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].src1) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].sink2 + 1)) { good = 1; QZ_DEBUG("doCompressOut: Processing seqnumber %2.2d " "%2.2d %4.4ld, PID: %d, TID: %lu\n", i, j, g_process.qz_inst[i].stream[j].seq, getpid(), pthread_self()); req = g_process.qz_inst[i].stream[j].req; /* Exception handling */ if ((sess->thd_sess_stat == QZ_BUF_ERROR || sess->thd_sess_stat == QZ_FAIL)) { /* The preview error request have complete, send failed status to callback * function, and change the session status to ok, start process new request */ if (req_prv != NULL && req != req_prv) { CallAsyncbackfn(&req_prv, QZ_FAIL, sess); } else { compOutSkipErrorRespond(i, j, qz_sess); req_prv = req; /* if process equel to submit, it means a request definatly complete */ if (qz_sess->processed == qz_sess->submitted) { CallAsyncbackfn(&req_prv, QZ_FAIL, sess); } /* if issue is from submit, only check if all submit processed */ if (qz_sess->stop_submitting) { qz_sess->stop_submitting = 0; } continue; } } resl = &g_process.qz_inst[i].stream[j].res; /* res.status is passed into QAT by cpaDcCompressData2, and changed in * dcCompression_ProcessCallback, it's type is CpaDcReqStatus. * job_status is from the dccallback, it's type is CpaStatus. * Generally, the res.status should have more detailed info about device error * we assume fallback feature will always call callback func, as well as * cpaDcCompressData2 return success. res.status and job_status should * all return Error status, but with different error number. */ if (unlikely(CPA_STATUS_SUCCESS != g_process.qz_inst[i].stream[j].job_status || CPA_DC_OK != resl->status)) { QZ_DEBUG("Error(%d) in callback: %d, %d, ReqStatus: %d\n", g_process.qz_inst[i].stream[j].job_status, i, j, g_process.qz_inst[i].stream[j].res.status); compOutSkipErrorRespond(i, j, qz_sess); /* Even one request failed, we still allow Compressin thread * to offload new request */ sess->thd_sess_stat = QZ_FAIL; /* If it's last buffer of request, excute Exception handle directly */ if (qz_sess->processed == qz_sess->submitted) { CallAsyncbackfn(&req, QZ_FAIL, sess); req_prv = NULL; } continue; } /* polled HW respond */ QZ_DEBUG("\tHW CompOut: consumed = %d, produced = %d, seq_in = %ld\n", resl->consumed, resl->produced, g_process.qz_inst[i].stream[j].seq); unsigned int dest_receive_sz = outputHeaderSz(data_fmt) + resl->produced + outputFooterSz(data_fmt); if (QZ_OK != AsyncCompOutCheckDestLen(i, j, sess, dest_receive_sz)) { if (qz_sess->processed == qz_sess->submitted) { CallAsyncbackfn(&req, QZ_FAIL, sess); req_prv = NULL; } continue; } /* Update qz_sess info and clean dest buffer */ outputHeaderGen(req->dest, resl, data_fmt); req->dest += outputHeaderSz(data_fmt); req->req_out_len += outputHeaderSz(data_fmt); AsyncCompOutValidDestBufferCleanUp(i, j, resl->produced); req->dest += resl->produced; req->req_in_len += resl->consumed; qz_crc32 = req->qzResults->crc != NULL && QZ_CRC32_VALID(req->qzResults->crc->valid_flags) ? (unsigned long *)req->qzResults->crc->in_crc.crc_32 : NULL; if (likely(NULL != qz_crc32 && IS_DEFLATE(data_fmt))) { if (0 == *(qz_crc32)) { *(qz_crc32) = resl->checksum; } else { *(qz_crc32) = crc32_combine(*(qz_crc32), resl->checksum, resl->consumed); } } req->req_out_len += resl->produced; outputFooterGen(req->dest, resl, data_fmt); req->dest += outputFooterSz(data_fmt); req->req_out_len += outputFooterSz(data_fmt); /* process finished! */ compOutProcessedRespond(i, j, qz_sess); if (req->req_in_len == req->qzResults->src_len) { req->qzResults->dest_len = req->req_out_len; CallAsyncbackfn(&req, QZ_OK, NULL); req_prv = NULL; } else { req_prv = req; } break; } } if (QZ_PERIODICAL_POLLING == polling_mode) { if (0 == good) { qz_sess->polling_idx = (qz_sess->polling_idx >= POLLING_LIST_NUM - 1) ? (POLLING_LIST_NUM - 1) : (qz_sess->polling_idx + 1); QZ_DEBUG("comp sleep for %d usec..., for inst %d\n", g_polling_interval[qz_sess->polling_idx], i); usleep(g_polling_interval[qz_sess->polling_idx]); sleep_cnt++; } else { qz_sess->polling_idx = (qz_sess->polling_idx == 0) ? (0) : (qz_sess->polling_idx - 1); } } } QZ_DEBUG("Comp sleep_cnt: %u\n", sleep_cnt); if (qz_sess->stop_submitting || qz_sess->last_submitted) { qz_sess->last_processed = 1; } else { qz_sess->last_processed = 0; } pthread_exit((void *)NULL); err_exit: sess->thd_sess_stat = QZ_FAIL; qz_sess->stop_submitting = 1; qz_sess->last_processed = 1; /*clean stream buffer*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { RestoreSrcCpastreamBuffer(i, j); RestoreDestCpastreamBuffer(i, j); ResetCpastreamSink(i, j); } pthread_exit((void *)NULL); } static int AsyncDeCompressIn(QzAsyncReq_T *req) { unsigned long i, tag; int rc; int j; unsigned int done = 0; unsigned int remaining; unsigned int src_avail_len, dest_avail_len; unsigned int tmp_src_avail_len, tmp_dest_avail_len; unsigned char *src_ptr; unsigned char *dest_ptr; QzGzH_T hdr = {{0}, 0}; QzSession_T *sess = req->sess; QzSess_T *qz_sess = (QzSess_T *)sess->internal; struct timespec sleep_time; sleep_time.tv_sec = 0; sleep_time.tv_nsec = GET_BUFFER_SLEEP_NSEC; i = qz_sess->inst_hint; j = -1; qz_sess->src = (unsigned char *)req->src; qz_sess->src_sz = &(req->qzResults->src_len); qz_sess->dest_sz = &(req->qzResults->dest_len); qz_sess->next_dest = req->dest; qz_sess->last = 1; qz_sess->crc32 = req->qzResults->crc != NULL && QZ_CRC32_VALID(req->qzResults->crc->valid_flags) ? (unsigned long *)req->qzResults->crc->in_crc.crc_32 : NULL; /* For offlod request, src_ptr, dest_ptr, remaining and src_avail_len, * dest_avail_len will loop update */ src_ptr = qz_sess->src; dest_ptr = qz_sess->next_dest; remaining = *qz_sess->src_sz; src_avail_len = remaining; dest_avail_len = *qz_sess->dest_sz; QZ_DEBUG("doDecompressIn: Need to g_process %d bytes\n", remaining); /* rc will only maintain in this function, thd_sess_stat will return the error status */ while (!done) { QZ_DEBUG("src_avail_len is %u, dest_avail_len is %u\n", src_avail_len, dest_avail_len); rc = checkHeader(qz_sess, src_ptr, src_avail_len, dest_avail_len, &hdr); if (QZ_OK != rc && QZ_FORCE_SW != rc) { sess->thd_sess_stat = rc; goto err_exit; } if (g_process.qz_inst[i].heartbeat != CPA_STATUS_SUCCESS || QZ_FORCE_SW == rc) { tmp_src_avail_len = src_avail_len; tmp_dest_avail_len = dest_avail_len; rc = decompInSWFallback(i, j, sess, src_ptr, dest_ptr, &tmp_src_avail_len, &tmp_dest_avail_len); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } /* Decomp inside offloading function, have to reset data like decomp out */ qz_sess->qz_in_len -= tmp_src_avail_len; qz_sess->qz_out_len -= tmp_dest_avail_len; qz_sess->next_dest -= tmp_dest_avail_len; if (req != NULL) { req->dest += tmp_dest_avail_len; req->req_in_len += tmp_src_avail_len; req->req_out_len += tmp_dest_avail_len; req->qzResults->dest_len -= tmp_dest_avail_len; if (req->req_in_len == req->qzResults->src_len) { req->qzResults->dest_len = req->req_out_len; CallAsyncbackfn(&req, QZ_OK, NULL); } } else { QZ_ERROR("instance %lu, req callback func flow error\n", i); } } else { /*HW decompression*/ do { j = getUnusedBuffer(i, j); if (unlikely(-1 == j)) { nanosleep(&sleep_time, NULL); } } while (-1 == j); QZ_DEBUG("getUnusedBuffer returned %d\n", j); g_process.qz_inst[i].stream[j].src1++;/*this buffer is in use*/ decompBufferSetup(i, j, qz_sess, src_ptr, dest_ptr, src_avail_len, &hdr, &tmp_src_avail_len, &tmp_dest_avail_len); g_process.qz_inst[i].stream[j].req = req; g_process.qz_inst[i].stream[j].src2++;/*this buffer is in use*/ do { tag = (i << 16) | j; QZ_DEBUG("Decomp Sending i = %ld j = %d src_ptr = %p dest_ptr = %p seq = %ld tag = %ld\n", i, j, src_ptr, dest_ptr, g_process.qz_inst[i].stream[j].seq, tag); rc = cpaDcDecompressData(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, g_process.qz_inst[i].src_buffers[j], g_process.qz_inst[i].dest_buffers[j], &g_process.qz_inst[i].stream[j].res, CPA_DC_FLUSH_FINAL, (void *)(tag)); if (unlikely(CPA_STATUS_RETRY == rc)) { g_process.qz_inst[i].num_retries++; usleep(g_polling_interval[qz_sess->polling_idx]); } if (unlikely(g_process.qz_inst[i].num_retries > MAX_NUM_RETRY)) { QZ_ERROR("instance %lu retry count:%d exceed the max count: %d\n", i, g_process.qz_inst[i].num_retries, MAX_NUM_RETRY); break; } } while (rc == CPA_STATUS_RETRY); g_process.qz_inst[i].num_retries = 0; if (unlikely(CPA_STATUS_SUCCESS != rc)) { QZ_ERROR("Inst %ld, buffer %d, Error in decompIn offload: %d\n", i, j, rc); decompInBufferCleanUp(i, j); tmp_src_avail_len = src_avail_len; tmp_dest_avail_len = dest_avail_len; rc = decompInSWFallback(i, j, sess, src_ptr, dest_ptr, &tmp_src_avail_len, &tmp_dest_avail_len); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } qz_sess->qz_in_len -= tmp_src_avail_len; qz_sess->qz_out_len -= tmp_dest_avail_len; qz_sess->next_dest -= tmp_dest_avail_len; if (req != NULL) { req->dest += tmp_dest_avail_len; req->req_in_len += tmp_src_avail_len; req->req_out_len += tmp_dest_avail_len; req->qzResults->dest_len -= tmp_dest_avail_len; if (req->req_in_len == req->qzResults->src_len) { req->qzResults->dest_len = req->req_out_len; CallAsyncbackfn(&req, QZ_OK, NULL); } } else { QZ_ERROR("instance %lu, req callback func flow error\n", i); } } } /* update the request src info status */ src_ptr += tmp_src_avail_len; dest_ptr += tmp_dest_avail_len; src_avail_len -= tmp_src_avail_len; dest_avail_len -= tmp_dest_avail_len; remaining -= tmp_src_avail_len; /* update qz_sess status */ qz_sess->seq++; qz_sess->submitted++; if (qz_sess->stop_submitting) { remaining = 0; } QZ_DEBUG("src_ptr is %p, remaining is %d\n", src_ptr, remaining); if (0 == remaining) { done = 1; // qz_sess->last_submitted = 1; } } qz_sess->force_sw = 0; return QZ_OK; err_exit: /*reset the qz_sess status*/ qz_sess->stop_submitting = 1; // qz_sess->last_submitted = 1; return QZ_FAIL; } static void *AsyncDecompressOut(void *in) { int i = 0, j = 0, good; int rc = 0; CpaDcRqResults *resl; CpaStatus sts; unsigned int sleep_cnt = 0; unsigned int src_send_sz; QzAsyncReq_T *req = NULL; QzAsyncReq_T *req_prv = NULL; QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; QzPollingMode_T polling_mode = qz_sess->sess_params.polling_mode; i = qz_sess->inst_hint; while ((qz_sess->last_submitted == 0) || (qz_sess->processed < qz_sess->submitted)) { /* Poll for responses */ good = 0; sts = icp_sal_DcPollInstance(g_process.dc_inst_handle[i], 0); if (unlikely(CPA_STATUS_FAIL == sts)) { /* if this error, we don't know which buffer is swapped */ QZ_ERROR("Error in DcPoll: %d\n", sts); goto err_exit; } /*fake a retrieve*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if ((g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in) && (g_process.qz_inst[i].stream[j].src1 == g_process.qz_inst[i].stream[j].src2) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].src1) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].sink2 + 1)) { good = 1; QZ_DEBUG("doDecompressOut: Processing seqnumber %2.2d %2.2d %4.4ld\n", i, j, g_process.qz_inst[i].stream[j].seq); req = g_process.qz_inst[i].stream[j].req; /* Exception handling */ if ((sess->thd_sess_stat == QZ_DATA_ERROR || sess->thd_sess_stat == QZ_FAIL)) { /* The preview error request have complete, send failed status to callback * function, and change the session status to ok, start process new request */ if (req_prv != NULL && req != req_prv) { CallAsyncbackfn(&req_prv, QZ_FAIL, sess); } else { decompOutSkipErrorRespond(i, j, qz_sess); req_prv = req; /* if process equel to submit, it means a request definatly complete */ if (qz_sess->processed == qz_sess->submitted) { CallAsyncbackfn(&req_prv, QZ_FAIL, sess); } /* if issue is from submit, only check if all submit processed */ if (qz_sess->stop_submitting) { qz_sess->stop_submitting = 0; } continue; } } if (unlikely(CPA_STATUS_SUCCESS != g_process.qz_inst[i].stream[j].job_status)) { QZ_DEBUG("Error(%d) in callback: %d, %d, ReqStatus: %d\n", g_process.qz_inst[i].stream[j].job_status, i, j, g_process.qz_inst[i].stream[j].res.status); /* polled error/dummy respond , fallback to sw */ rc = AsyncDecompOutSWFallback(i, j, sess, req); if (QZ_FAIL == rc) { QZ_ERROR("Error in SW deCompOut:inst %d, buffer %d, seq %ld\n", i, j, qz_sess->seq_in); decompOutSkipErrorRespond(i, j, qz_sess); sess->thd_sess_stat = QZ_FAIL; /* If it's last buffer of request, excute Exception handle directly */ if (qz_sess->processed == qz_sess->submitted) { CallAsyncbackfn(&req, QZ_FAIL, sess); req_prv = NULL; } continue; } } else { resl = &g_process.qz_inst[i].stream[j].res; QZ_DEBUG("\tHW DecompOut: consumed = %d, produced = %d, seq_in = %ld, src_send_sz = %u\n", resl->consumed, resl->produced, g_process.qz_inst[i].stream[j].seq, g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes); /* update the qz_sess info and clean dest buffer */ AsyncDecompOutValidDestBufferCleanUp(i, j, qz_sess, resl, req); if (QZ_OK != decompOutCheckSum(i, j, sess, resl)) { if (qz_sess->processed == qz_sess->submitted) { CallAsyncbackfn(&req, QZ_FAIL, sess); req_prv = NULL; } continue; } src_send_sz = g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes; req->dest += resl->produced; req->req_in_len += (outputHeaderSz(data_fmt) + src_send_sz + outputFooterSz(data_fmt)); req->req_out_len += resl->produced; req->qzResults->dest_len -= resl->produced; } decompOutProcessedRespond(i, j, qz_sess); if (req->req_in_len == req->qzResults->src_len) { req->qzResults->dest_len = req->req_out_len; CallAsyncbackfn(&req, QZ_OK, NULL); req_prv = NULL; } else { req_prv = req; } break; } } if (QZ_PERIODICAL_POLLING == polling_mode) { if (0 == good) { qz_sess->polling_idx = (qz_sess->polling_idx >= POLLING_LIST_NUM - 1) ? (POLLING_LIST_NUM - 1) : (qz_sess->polling_idx + 1); QZ_DEBUG("decomp sleep for %d usec..., for inst %d\n", g_polling_interval[qz_sess->polling_idx], i); usleep(g_polling_interval[qz_sess->polling_idx]); sleep_cnt++; } else { qz_sess->polling_idx = (qz_sess->polling_idx == 0) ? (0) : (qz_sess->polling_idx - 1); } } } QZ_DEBUG("Decomp sleep_cnt: %u\n", sleep_cnt); qz_sess->last_processed = qz_sess->last_submitted ? 1 : 0; return ((void *)NULL); err_exit: qz_sess->stop_submitting = 1; qz_sess->last_processed = 1; sess->thd_sess_stat = QZ_FAIL; /* clean stream buffer */ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { RestoreSrcCpastreamBuffer(i, j); RestoreDestCpastreamBuffer(i, j); ResetCpastreamSink(i, j); } /* need add flag for buffer swap. swapDataBuffer(i, j); */ return ((void *)NULL); } int GetStableInstance(QzSession_T *sess) { int i, rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; i = qzGrabInstance(qz_sess->inst_hint, &(qz_sess->sess_params)); if (unlikely(i == -1)) { QZ_DEBUG("Async API didn't grab instance!\n"); goto exit; } // check if the instance mem setup if (0 == g_process.qz_inst[i].mem_setup || 0 == g_process.qz_inst[i].cpa_sess_setup) { QZ_DEBUG("Getting HW resources for inst %d\n", i); rc = qzSetupHW(sess, i); if (unlikely(QZ_OK != rc)) { qzReleaseInstance(i); i = -1; goto exit; } } else if (memcmp(&g_process.qz_inst[i].session_setup_data, &qz_sess->session_setup_data, sizeof(CpaDcSessionSetupData))) { /* session_setup_data of qz_sess is not same with instance i, need to update cpa session of instance i. */ rc = qzUpdateCpaSession(sess, i); if (QZ_OK != rc) { qzReleaseInstance(i); i = -1; goto exit; } } qz_sess->inst_hint = i; exit: return i; } void CheckAsyncPollingDirection(QzSession_T *sess, QzAsyncOperationType_T op_type) { void *(*work_thread)(void *); QzSess_T *qz_sess = (QzSess_T *)sess->internal; QzAsynctrl_T *async_ctrl = qz_sess->async_ctrl; int direct = op_type & ASYNC_POLLING_MASK; if (direct == async_ctrl->async_polling_direct) { return; } qz_sess->last_submitted = 1; pthread_join(async_ctrl->async_polling_t, NULL); resetQzsess(sess, NULL, NULL, NULL, NULL, 0); async_ctrl->async_polling_direct = direct; work_thread = direct ? AsyncDecompressOut : AsyncCompressOut; pthread_create(&(async_ctrl->async_polling_t), NULL, work_thread, (void *)sess); } static void *AsyncReqConsumeJob(void *arg) { int rc = QZ_FAIL; QzSession_T *sess = (QzSession_T *)arg; QzSess_T *qz_sess = (QzSess_T *)sess->internal; QzAsynctrl_T *async_ctrl = qz_sess->async_ctrl; QzAsyncReq_T *req; unsigned long *qz_crc32 = NULL; struct timespec mb_polling_abs_timeout; int instance = GetStableInstance(sess); if (-1 != instance) { pthread_create(&(async_ctrl->async_polling_t), NULL, AsyncCompressOut, (void *)sess); } // if the queue is not empty, deal with all inflight requeses. while (async_ctrl->async_ctrl_init) { get_sem_wait_abs_time(&mb_polling_abs_timeout, mb_poll_timeout_time); if (sem_timedwait(&(async_ctrl->sem), &mb_polling_abs_timeout)) { QZ_DEBUG("The async queue is waiting for request!\n"); continue; } req = QzRingConsumeDequeue(async_ctrl->async_req_ring, 0); if (NULL == req) { sem_post(&(async_ctrl->sem)); QZ_DEBUG("dequeue async req failed\n"); continue; } if (instance != -1) { switch (req->op_type) { case QZ_COMPRESS: /* if compressIn failed, need to wait all request * dummy up, and call async function, send failed * status to async caller. */ CheckAsyncPollingDirection(sess, req->op_type); rc = AsyncCompressIn(req); if (QZ_OK != rc) { QZ_ERROR("instance %d, comp req submit failed\n", instance); /* Should wait in this place, until sess status * recover to ok, then start next req process. */ while (qz_sess->stop_submitting && qz_sess->seq != qz_sess->seq_in) { usleep(g_polling_interval[qz_sess->polling_idx]); } resetQzsess(sess, NULL, NULL, NULL, NULL, 0); } break; case QZ_DECOMPRESS: CheckAsyncPollingDirection(sess, req->op_type); rc = AsyncDeCompressIn(req); if (QZ_OK != rc) { QZ_ERROR("instance %d, decomp req submit failed\n", instance); /* Should wait in this place, until sess status * recover to ok, then start next req process. */ while (qz_sess->stop_submitting && qz_sess->seq != qz_sess->seq_in) { usleep(g_polling_interval[qz_sess->polling_idx]); } resetQzsess(sess, NULL, NULL, NULL, NULL, 0); } break; default: rc = QZ_FAIL; QZ_ERROR("async_op_type is incorrect!\n"); break; } /* req callback when offload failed */ if (QZ_OK != rc && req != NULL) { req->qzResults->status = rc; req->qzAsyncallback(req->qzResults); free(req); } } else { qz_crc32 = req->qzResults->crc != NULL && QZ_CRC32_VALID(req->qzResults->crc->valid_flags) ? (unsigned long *)req->qzResults->crc->in_crc.crc_32 : NULL; switch (req->op_type) { case QZ_COMPRESS: rc = qzCompressCrcExt(req->sess, req->src, &(req->qzResults->src_len), req->dest, &(req->qzResults->dest_len), 1, qz_crc32, &(req->qzResults->ext_rc)); break; case QZ_DECOMPRESS: rc = qzDecompressCrcExt(req->sess, req->src, &(req->qzResults->src_len), req->dest, &(req->qzResults->dest_len), qz_crc32, &(req->qzResults->ext_rc)); break; default: QZ_ERROR("async_op_type is incorrect!\n"); break; } req->qzResults->status = rc; req->qzAsyncallback(req->qzResults); resetQzsess(req->sess, NULL, NULL, NULL, NULL, 1); free(req); // try to grab instance again; instance = GetStableInstance(sess); if (-1 != instance) { pthread_create(&(async_ctrl->async_polling_t), NULL, AsyncCompressOut, (void *)sess); } } } qz_sess->last_submitted = 1; // wait polling thread complete if (0 != async_ctrl->async_polling_t) { pthread_join(async_ctrl->async_polling_t, NULL); } QzClearRing(async_ctrl->async_req_ring); if (instance != -1) { qzReleaseInstance(instance); } pthread_exit((void *)NULL); } int qzSetupAsyncCtrl(QzSession_T *sess) { QzSess_T *qz_sess; int rc = QZ_OK; qz_sess = (QzSess_T *)(sess->internal); if (qz_sess->async_ctrl == NULL) { qz_sess->async_ctrl = calloc(1, sizeof(QzAsynctrl_T)); qz_sess->async_ctrl->async_ctrl_init = 1; qz_sess->async_ctrl->async_req_key = g_process.async_req_key; sem_init(&(qz_sess->async_ctrl->sem), 0, 0); // Setup the request queue qz_sess->async_ctrl->async_req_ring = QzRingCreate(async_queue_size); if (unlikely(NULL == qz_sess->async_ctrl->async_req_ring)) { QZ_ERROR("Create async request queue failed!\n"); goto err_exit; } // Setup the consume thread if (unlikely(0 != pthread_create(&(qz_sess->async_ctrl->async_consume_t), NULL, AsyncReqConsumeJob, (void *)sess))) { QZ_ERROR("Start async consume polling thread failed\n"); QzRingFree(qz_sess->async_ctrl->async_req_ring); goto err_exit; } pthread_setspecific(qz_sess->async_ctrl->async_req_key, sess); } return rc; err_exit: rc = QZ_FAIL; sem_destroy(&(qz_sess->async_ctrl->sem)); free(qz_sess->async_ctrl); qz_sess->async_ctrl = NULL; return rc; } int qzAsyncSetupHWSession(QzSession_T *sess, QzDirection_T direct) { QzSess_T *qz_sess; int rc; /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { goto err_exit; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { if (g_sess_params_internal_default.data_fmt == LZ4_FH) { rc = qzSetupSessionLZ4(sess, NULL); } else if (g_sess_params_internal_default.data_fmt == LZ4S_BK) { rc = qzSetupSessionLZ4S(sess, NULL); } else { rc = qzSetupSessionDeflate(sess, NULL); } if (unlikely(QZ_SETUP_SESSION_FAIL(rc))) { goto err_exit; } } qz_sess = (QzSess_T *)(sess->internal); DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; if ((direct == QZ_DIR_COMPRESS && data_fmt > LZ4S_BK) || (direct == QZ_DIR_DECOMPRESS && data_fmt > LZ4_FH) || (data_fmt < DEFLATE_4B)) { QZ_ERROR("Unknown data format: %d\n", data_fmt); rc = QZ_UNSUPPORTED_FMT; goto err_exit; } rc = QZ_OK; err_exit: return rc; } int qzAsyncReqSubmit(QzSession_T *sess, QzAsyncReq_T *req, QzDirection_T direct) { QzSess_T *qz_sess; int rc; rc = qzAsyncSetupHWSession(sess, direct); if (rc != QZ_OK) { return rc; } rc = qzSetupAsyncCtrl(sess); if (rc != QZ_OK) { return rc; } qz_sess = (QzSess_T *)(sess->internal); rc = QzRingProduceEnQueue(qz_sess->async_ctrl->async_req_ring, req, 1); if (QZ_OK != rc) { QZ_DEBUG("Push infight async requese failed\n"); } else { sem_post(&(qz_sess->async_ctrl->sem)); // __sync_fetch_and_add(&(qz_sess->async_ctrl->num_req), 1); } return rc; } int populateAsyncReq(QzSession_T *sess, const unsigned char *src, unsigned char *dest, qzAsyncCallbackFn callback, QzResult_T *qzResults, QzAsyncOperationType_T op_type, QzAsyncReq_T *req) { if (unlikely(NULL == sess || \ NULL == src || \ NULL == dest || \ NULL == callback || \ NULL == req)) { QZ_ERROR("Async API input params is incorrect\n"); goto err_exit; } req->sess = sess; req->src = src; req->dest = dest; req->qzResults = qzResults; req->qzAsyncallback = callback; req->op_type = op_type; req->req_src = src; req->req_in_len = 0; req->req_dest = dest; req->req_out_len = 0; return QZ_OK; err_exit: qzResults->src_len = 0; qzResults->dest_len = 0; return QZ_PARAMS; } int qzCompress2(QzSession_T *sess, const unsigned char *src, unsigned char *dest, qzAsyncCallbackFn callback, QzResult_T *qzResults) { int rc; if (NULL == qzResults) { QZ_ERROR("For qzCompress2, QzResult_T params is null pointer!\n"); return QZ_PARAMS; } // callback is NULL, use synchronous model. otherwise asynchronous model if (NULL == callback) { // linux qatzip only support input crc32. unsigned long *qz_crc32 = qzResults->crc != NULL && QZ_CRC32_VALID(qzResults->crc->valid_flags) ? (unsigned long *)qzResults->crc->in_crc.crc_32 : NULL; rc = qzCompressCrcExt(sess, src, &(qzResults->src_len), dest, &(qzResults->dest_len), 1, qz_crc32, &(qzResults->ext_rc)); qzResults->status = rc; return rc; } /* For now, use glibc calloc to create request, it may reduce async perf * when request num is small, But as the number of requests increases, the * glibc memory slab would help to reduce the Memory allocation overhead. * For future, we would use the request memory pool to replace currect * implement. */ QzAsyncReq_T *req = calloc(1, sizeof(QzAsyncReq_T)); rc = populateAsyncReq(sess, src, dest, callback, qzResults, QZ_COMPRESS, req); if (QZ_OK != rc) { goto exit; } rc = qzAsyncReqSubmit(sess, req, QZ_DIR_COMPRESS); if (QZ_OK != rc) { goto exit; } return QZ_OK; exit: free(req); return rc; } int qzDecompress2(QzSession_T *sess, const unsigned char *src, unsigned char *dest, qzAsyncCallbackFn callback, QzResult_T *qzResults) { int rc; if (NULL == qzResults) { QZ_ERROR("For qzDecompress2, QzResult_T params is null pointer!\n"); return QZ_PARAMS; } // callback is NULL, use synchronous model. otherwise asynchronous model if (NULL == callback) { // linux qatzip only support input crc32. unsigned long *qz_crc32 = qzResults->crc != NULL && QZ_CRC32_VALID(qzResults->crc->valid_flags) ? (unsigned long *)qzResults->crc->in_crc.crc_32 : NULL; rc = qzDecompressCrcExt(sess, src, &(qzResults->src_len), dest, &(qzResults->dest_len), qz_crc32, &(qzResults->ext_rc)); qzResults->status = rc; return rc; } /* For now, use glibc calloc to create request, it may reduce async perf * when request num is small, But as the number of requests increases, the * glibc memory slab would help to reduce the Memory allocation overhead. * For future, we would use the request memory pool to replace currect * implement. */ QzAsyncReq_T *req = calloc(1, sizeof(QzAsyncReq_T)); rc = populateAsyncReq(sess, src, dest, callback, qzResults, QZ_DECOMPRESS, req); if (QZ_OK != rc) { goto exit; } rc = qzAsyncReqSubmit(sess, req, QZ_DIR_DECOMPRESS); if (QZ_OK != rc) { goto exit; } return QZ_OK; exit: free(req); return rc; } QATzip-1.3.1/src/qatzip_counter.c000077500000000000000000000054031500263377000166760ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" extern processData_T g_process; void dumpCounters(QzInstance_T *inst) { int i; if (inst->mem_setup == 0) { QZ_INFO("\tNot in use\n"); return; } for (i = 0; i < inst->dest_count; i++) { QZ_INFO("\tbuffer %d\t ses %ld\t %ld %ld %ld %ld\n", i, inst->stream[i].seq, inst->stream[i].src1, inst->stream[i].src2, inst->stream[i].sink1, inst->stream[i].sink2); } } void dumpAllCounters(void) { int i; for (i = 0; i < g_process.num_instances; i++) { QZ_INFO("Instance %d\n", i); dumpCounters(&g_process.qz_inst[i]); QZ_INFO("\n"); } } QATzip-1.3.1/src/qatzip_gzip.c000077500000000000000000000230331500263377000161670ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" #pragma pack(push, 1) inline unsigned long qzGzipHeaderSz(void) { return sizeof(QzGzH_T); } inline unsigned long stdGzipHeaderSz(void) { return sizeof(StdGzH_T); } inline unsigned long qz4BHeaderSz(void) { return sizeof(Qz4BH_T); } inline unsigned long stdGzipFooterSz(void) { return sizeof(StdGzF_T); } inline unsigned long stdZlibHeaderSz(void) { return sizeof(StdZlibH_T); } inline unsigned long stdZlibFooterSz(void) { return sizeof(StdZlibF_T); } void qzGzipHeaderExtraFieldGen(unsigned char *ptr, CpaDcRqResults *res) { QzExtraField_T *extra; extra = (QzExtraField_T *)ptr; extra->st1 = 'Q'; extra->st2 = 'Z'; extra->x2_len = (uint16_t)sizeof(extra->qz_e); extra->qz_e.src_sz = res->consumed; extra->qz_e.dest_sz = res->produced; } void qzGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { assert(ptr != NULL); assert(res != NULL); QzGzH_T *hdr; hdr = (QzGzH_T *)ptr; hdr->std_hdr.id1 = 0x1f; hdr->std_hdr.id2 = 0x8b; hdr->std_hdr.cm = QZ_DEFLATE; hdr->std_hdr.flag = 0x04; /*Fextra BIT SET*/ hdr->std_hdr.mtime[0] = (char)0; hdr->std_hdr.mtime[1] = (char)0; hdr->std_hdr.mtime[2] = (char)0; hdr->std_hdr.mtime[3] = (char)0; hdr->std_hdr.xfl = 0; hdr->std_hdr.os = 255; hdr->x_len = (uint16_t)sizeof(hdr->extra); qzGzipHeaderExtraFieldGen((unsigned char *)&hdr->extra, res); } void stdGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { assert(ptr != NULL); assert(res != NULL); StdGzH_T *hdr; hdr = (StdGzH_T *)ptr; hdr->id1 = 0x1f; hdr->id2 = 0x8b; hdr->cm = QZ_DEFLATE; hdr->flag = 0x00; hdr->mtime[0] = (char)0; hdr->mtime[1] = (char)0; hdr->mtime[2] = (char)0; hdr->mtime[3] = (char)0; hdr->xfl = 0; hdr->os = 255; } void qz4BHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { Qz4BH_T *hdr; hdr = (Qz4BH_T *)ptr; hdr->blk_size = res->produced; } int isQATDeflateProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess) { QzGzH_T *h = (QzGzH_T *)ptr; Qz4BH_T *h_4B; StdGzF_T *qzFooter = NULL; long buff_sz = (DEST_SZ(qz_sess->sess_params.hw_buff_sz) < *src_len ? DEST_SZ( (long)(qz_sess->sess_params.hw_buff_sz)) : *src_len); if (qz_sess->sess_params.data_fmt == DEFLATE_4B) { h_4B = (Qz4BH_T *)ptr; if (h_4B->blk_size > DEST_SZ(qz_sess->sess_params.hw_buff_sz)) { return 0; } return 1; } if (qz_sess->sess_params.data_fmt == DEFLATE_ZLIB) { if (qzVerifyZlibHeader(ptr, src_len) == 1) { return 1; } QZ_ERROR("isQATDeflateProcessable qzVerifyZlibHeader failed\n"); return 0; } /*check if HW can process*/ if (h->std_hdr.id1 == 0x1f && \ h->std_hdr.id2 == 0x8b && \ h->std_hdr.cm == QZ_DEFLATE && \ h->std_hdr.flag == 0x00) { qzFooter = (StdGzF_T *)(findStdGzipFooter((const unsigned char *)h, buff_sz)); if ((unsigned char *)qzFooter - ptr - stdGzipHeaderSz() > DEST_SZ( (unsigned long)(qz_sess->sess_params.hw_buff_sz)) || qzFooter->i_size > qz_sess->sess_params.hw_buff_sz) { return 0; } qz_sess->sess_params.data_fmt = DEFLATE_GZIP; return 1; } /* Besides standard GZIP header, only Gzip header with QZ extension can be processed by QAT */ if (h->std_hdr.id1 != 0x1f || \ h->std_hdr.id2 != 0x8b || \ h->std_hdr.cm != QZ_DEFLATE) { /* There are two possibilities when h is not a gzip header: */ /* 1, wrong data */ /* 2, It is the 2nd, 3rd... part of the file with the standard gzip header. */ return -1; } return (h->extra.st1 == 'Q' && \ h->extra.st2 == 'Z'); } int qzGzipHeaderExt(const unsigned char *const ptr, QzGzH_T *hdr) { QzGzH_T *h; h = (QzGzH_T *)ptr; if (h->std_hdr.id1 != 0x1f || \ h->std_hdr.id2 != 0x8b || \ h->extra.st1 != 'Q' || \ h->extra.st2 != 'Z' || \ h->std_hdr.cm != QZ_DEFLATE || \ h->std_hdr.flag != 0x04 || \ (h->std_hdr.xfl != 0 && h->std_hdr.xfl != 2 && \ h->std_hdr.xfl != 4) || \ h->std_hdr.os != 255 || \ h->x_len != sizeof(h->extra) || \ h->extra.x2_len != sizeof(h->extra.qz_e)) { QZ_DEBUG("id1: %x, id2: %x, st1: %c, st2: %c, cm: %d, flag: %d," "xfl: %d, os: %d, x_len: %d, x2_len: %d\n", h->std_hdr.id1, h->std_hdr.id2, h->extra.st1, h->extra.st2, h->std_hdr.cm, h->std_hdr.flag, h->std_hdr.xfl, h->std_hdr.os, h->x_len, h->extra.x2_len); return QZ_FAIL; } QZ_MEMCPY(hdr, ptr, sizeof(*hdr), sizeof(*hdr)); return QZ_OK; } void qzGzipFooterGen(unsigned char *ptr, CpaDcRqResults *res) { assert(NULL != ptr); assert(NULL != res); StdGzF_T *ftr; ftr = (StdGzF_T *)ptr; ftr->crc32 = res->checksum; ftr->i_size = res->consumed; } void qzGzipFooterExt(const unsigned char *const ptr, StdGzF_T *ftr) { QZ_MEMCPY(ftr, ptr, sizeof(*ftr), sizeof(*ftr)); } unsigned char *findStdGzipFooter(const unsigned char *src_ptr, long src_avail_len) { StdGzH_T *gzHeader = NULL; unsigned int offset = stdGzipHeaderSz() + stdGzipFooterSz(); while (src_avail_len >= offset + stdGzipHeaderSz()) { gzHeader = (StdGzH_T *)(src_ptr + offset); if (gzHeader->id1 == 0x1f && \ gzHeader->id2 == 0x8b && \ gzHeader->cm == QZ_DEFLATE && \ gzHeader->flag == 0x00) { return (void *)((unsigned char *)gzHeader - stdGzipFooterSz()); } offset++; } return (void *)((unsigned char *)src_ptr + src_avail_len - stdGzipFooterSz()); } void stdZlibHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { assert(ptr != NULL); assert(res != NULL); StdZlibH_T *hdr; hdr = (StdZlibH_T *)ptr; hdr->cmf = QZ_ZLIB_HEADER_CMF; hdr->flags = QZ_ZLIB_HEADER_FLG_DEFAULT; } void qzZlibFooterGen(unsigned char *ptr, CpaDcRqResults *res) { assert(NULL != ptr); StdZlibF_T *ftr; ftr = (StdZlibF_T *)ptr; ftr->adler32 = htonl(res->checksum); QZ_DEBUG("qzZlibFooterGen checksum = 0x%x\n", ftr->adler32); } int qzVerifyZlibHeader(const unsigned char *ptr, const unsigned int *const src_len) { assert(ptr != NULL); if (*src_len < stdZlibHeaderSz()) return 0; StdZlibH_T *h = (StdZlibH_T *)ptr; unsigned char CMF = h->cmf; if ((CMF & 0x0F) != QZ_DEFLATE) { QZ_ERROR("qzVerifyZlibHeader failed invalid CM\n"); return 0; } //check for window size, valid values are from 0-7. if ((CMF >> 4) > 7) { QZ_ERROR("qzVerifyZlibHeader failed invalid CINFO\n"); return 0; } //check for valid zlib flags. unsigned char FLG = h->flags; unsigned char FDICT = (FLG & 0x20) >> 5; if ((FDICT != 0) || ((CMF * 256 + FLG) % 31 != 0)) { QZ_ERROR("qzVerifyZlibHeader failed invalid FLG\n"); return 0; } return 1; } #pragma pack(pop) QATzip-1.3.1/src/qatzip_internal.h000077500000000000000000000613201500263377000170400ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _QATZIPP_H #define _QATZIPP_H #ifdef __cplusplus extern"C" { #endif #ifdef HAVE_QAT_HEADERS #include #else #include #endif #include #include #include #include #include #include #include #include "qz_utils.h" /** * define release version */ #define QATZIP_VERSION "1.3.1" #define SUCCESS 1 #define FAILURE 0 #define QZ_WAIT_SW_PENDING 10 #define NUM_BUFF (32) /** * For less than 8K hardware buffer size, it needs more in-flight buffers * to reach peak performance */ #define NUM_BUFF_8K (128) #define MAX_NUM_RETRY ((int)500) #define MAX_BUFFERS ((int)100) #define MAX_THREAD_TMR ((int)100) #define GET_LOWER_32BITS(v) ((v) & 0xFFFFFFFF) #define GET_LOWER_16BITS(v) ((v) & 0xFFFF) #define GET_LOWER_8BITS(v) ((v) & 0xFF) /*For Sync mode, request counts must less than NUM_BUFF. *If then the request can't get adequate unused buffer and will be hanged * */ #if QZ_REQ_THRESHOLD_MAXIMUM > NUM_BUFF #error QZ_REQ_THRESHOLD_MAXIMUM should not be larger than NUM_BUFF #endif #define QAT_MAX_DEVICES (32 * 32) #define STORED_BLK_MAX_LEN 65535 #define STORED_BLK_HDR_SZ 5 #define QZ_INIT_FAIL(rc) (QZ_OK != rc && \ QZ_DUPLICATE != rc) #define QZ_SETUP_SESSION_FAIL(rc) (QZ_PARAMS == rc || \ QZ_NOSW_NO_HW == rc || \ QZ_NOSW_LOW_MEM == rc) #define likely(x) __builtin_expect (!!(x), 1) #define unlikely(x) __builtin_expect (!!(x), 0) #define DEST_SZ(src_sz) (((9U * (src_sz)) / 8U) + 1024U) /* The minimal supported CAP_DC API version */ #ifndef CPA_DC_API_VERSION_AT_LEAST #define CPA_DC_API_VERSION_AT_LEAST(major, minor) \ (CPA_DC_API_VERSION_NUM_MAJOR > major || \ (CPA_DC_API_VERSION_NUM_MAJOR == major && \ CPA_DC_API_VERSION_NUM_MINOR >= minor)) #endif #define QZ_CEIL_DIV(x, y) (((x) + (y)-1) / (y)) /* macros for lz4 */ #define QZ_LZ4_MAGIC 0x184D2204U #define QZ_LZ4_MAGIC_SKIPPABLE 0x184D2A50U #define QZ_LZ4_VERSION 0x1 #define QZ_LZ4_BLK_INDEP 0x0 #define QZ_LZ4_BLK_CKS_FLAG 0x0 #define QZ_LZ4_DICT_ID_FLAG 0x0 #define QZ_LZ4_CNT_SIZE_FLAG 0x1 #define QZ_LZ4_CNT_CKS_FLAG 0x1 #define QZ_LZ4_ENDMARK 0x0 #define QZ_LZ4_MAX_BLK_SIZE 0x4 #define QZ_LZ4_MAGIC_SIZE 4 //lz4 magic number length #define QZ_LZ4_FD_SIZE 11 //lz4 frame descriptor length #define QZ_LZ4_HEADER_SIZE (QZ_LZ4_MAGIC_SIZE + \ QZ_LZ4_FD_SIZE) //lz4 frame header length #define QZ_LZ4_CHECKSUM_SIZE 4 //lz4 checksum length #define QZ_LZ4_ENDMARK_SIZE 4 //lz4 endmark length #define QZ_LZ4_FOOTER_SIZE (QZ_LZ4_CHECKSUM_SIZE + \ QZ_LZ4_ENDMARK_SIZE) //lz4 frame footer length #define QZ_LZ4_BLK_HEADER_SIZE 4 //lz4 block header length #define QZ_LZ4_STOREDBLOCK_FLAG 0x80000000U #define QZ_LZ4_STORED_HEADER_SIZE 4 //https://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like //https://datatracker.ietf.org/doc/html/rfc1950 //zlib header CMF #define QZ_ZLIB_HEADER_CMF 0x78 // zlib magic header FLG with different compression level #define QZ_ZLIB_HEADER_FLG_LOW 0x01 #define QZ_ZLIB_HEADER_FLG_FAST 0x5E #define QZ_ZLIB_HEADER_FLG_DEFAULT 0x9C #define QZ_ZLIB_HEADER_FLG_BEST 0xDA #define DATA_FORMAT_DEFAULT DEFLATE_GZIP_EXT #define IS_DEFLATE_RAW(fmt) (DEFLATE_RAW == (fmt)) #define IS_DEFLATE(fmt) \ (DEFLATE_RAW == (fmt) || DEFLATE_GZIP == (fmt) || \ DEFLATE_GZIP_EXT == (fmt) || DEFLATE_4B == (fmt) || DEFLATE_ZLIB == (fmt)) struct QzAsyncReq_S; typedef struct QzAsyncReq_S QzAsyncReq_T; typedef struct QzCpaStream_S { signed long seq; signed long src1; signed long src2; signed long sink1; signed long sink2; CpaDcRqResults res; CpaStatus job_status; unsigned char *orig_src; unsigned char *orig_dest; int src_need_reset; int dest_need_reset; unsigned int checksum; unsigned int orgdatalen; CpaDcOpData opData; QzAsyncReq_T *req; } QzCpaStream_T; typedef struct QzInstance_S { CpaInstanceInfo2 instance_info; CpaDcInstanceCapabilities instance_cap; CpaBufferList **intermediate_buffers; Cpa32U buff_meta_size; /* Tracks memory where the intermediate buffers reside. */ Cpa16U intermediate_cnt; CpaBufferList **src_buffers; CpaBufferList **dest_buffers; Cpa16U src_count; Cpa16U dest_count; QzCpaStream_T *stream; unsigned int lock; /*heartbeat represent device status, which will be changed by polling events thread*/ CpaStatus heartbeat; unsigned char mem_setup; unsigned char cpa_sess_setup; CpaStatus inst_start_status; unsigned int num_retries; CpaDcSessionHandle cpaSess; CpaDcSessionSetupData session_setup_data; } QzInstance_T; typedef struct QzInstanceList_S { QzInstance_T instance; CpaInstanceHandle dc_inst_handle; struct QzInstanceList_S *next; } QzInstanceList_T; typedef struct QzHardware_S { QzInstanceList_T devices[QAT_MAX_DEVICES]; unsigned int dev_num; unsigned int max_dev_id; } QzHardware_T; typedef struct ProccesData_S { char qz_init_status; unsigned char sw_backup; CpaInstanceHandle *dc_inst_handle; QzInstance_T *qz_inst; Cpa16U num_instances; atomic_char qat_available; /* this thread handler is for keep polling device fatal events.*/ pthread_t t_poll_heartbeat; /* Define pthread key here, for different thread local variable */ pthread_key_t async_req_key; } processData_T; typedef enum { InflateError = -1, InflateNull = 0, InflateInited, InflateOK, InflateEnd } InflateState_T; typedef enum { DeflateNull = 0, DeflateInited } DeflateState_T; // Include all support data format // Don't change the enumeration order typedef enum DataFormatInternal_E { DEFLATE_4B = 0, /**< Data is in raw deflate format with 4 byte header */ DEFLATE_GZIP, /**< Data is in deflate wrapped by GZip header and footer */ DEFLATE_GZIP_EXT, /**< Data is in deflate wrapped by GZip extended header and footer */ DEFLATE_RAW, /**< Data is in raw deflate format */ LZ4_FH, /**< Data is in LZ4 format with frame headers */ LZ4S_BK, /**< Data is in LZ4s sequences with block header, it's only for post processed */ DEFLATE_ZLIB, /**< Data is in deflate wrapped by zlib header and footer */ } DataFormatInternal_T; // Include all support session parameters typedef struct QzSessionParamsInternal_S { QzHuffmanHdr_T huffman_hdr; /**< Dynamic or Static Huffman headers */ QzDirection_T direction; /**< Compress or decompress */ DataFormatInternal_T data_fmt; /**< Deflate, deflate with GZip or deflate with GZip ext */ unsigned int comp_lvl; /**< Compression level 1 to 12 for QAT CPM2.0. */ /**< If the comp_algorithm is deflate, values > max will be set to max */ unsigned char comp_algorithm; /**< Compress/decompression algorithms */ unsigned int max_forks; /**< Maximum forks permitted in the current thread */ /**< 0 means no forking permitted */ unsigned char sw_backup; /**< bit field defining SW configuration (see QZ_SW_* definitions) */ unsigned int hw_buff_sz; /**< Default buffer size, must be a power of 2k */ /**< 4K,8K,16K,32K,64K,128K */ unsigned int strm_buff_sz; /**< Stream buffer size between [1K .. 2M - 5K] */ /**< Default strm_buf_sz equals to hw_buff_sz */ unsigned int input_sz_thrshold; /**< Default threshold of compression service's input size */ /**< for sw failover, if the size of input request is less */ /**< than the threshold, QATzip will route the request */ /**< to software */ unsigned int req_cnt_thrshold; /**< Set between 1 and NUM_BUFF, default NUM_BUFF */ /**< NUM_BUFF is defined in qatzip_internal.h */ unsigned int wait_cnt_thrshold; /**< When previous try failed, wait for specific number of calls */ /**< before retrying to open device. Default threshold is 8 */ qzLZ4SCallbackFn qzCallback; /**< post processing callback for zstd compression*/ void *qzCallback_external; /**< An opaque pointer provided by the user to be passed */ /**< into qzCallback during post processing*/ QzPollingMode_T polling_mode; /**< 0 means no busy polling, 1 means busy polling */ unsigned int is_sensitive_mode; /**< 0 means disable sensitive mode, 1 means enable sensitive mode*/ unsigned int lz4s_mini_match; /**< Set lz4s dictionary mini match, which would be 3 or 4 */ unsigned char stop_decompression_stream_end; /* stop decompression at end the stream, default is 0 */ unsigned char zlib_format; } QzSessionParamsInternal_T; /* lsm_met_len_shift is global variable */ #define LSM_MET_DEPTH (1<<(lsm_met_len_shift)) typedef struct LatencyMetrix_S { unsigned long *latency_array; unsigned long arr_idx; unsigned long arr_total; unsigned long arr_avg; unsigned long invoke_counter; #ifdef QATZIP_DEBUG unsigned long sess_lat_total; unsigned long sess_lat_avg; unsigned long max_latency; unsigned long min_latency; unsigned long max_cnt; unsigned long min_cnt; #endif } LatencyMetrix_T; /* This mask should change according to QzAsyncOperationType_E enum */ #define ASYNC_POLLING_MASK 1 #define DEFAULT_ASYNC_QUEUE_SIZE 1024 /* compress is even, decompress is odd */ typedef enum QzAsyncOperationType_E { QZ_COMPRESS = 0, QZ_DECOMPRESS = 1, } QzAsyncOperationType_T; struct QzAsyncReq_S { QzSession_T *sess; const unsigned char *src; unsigned char *dest; QzResult_T *qzResults; qzAsyncCallbackFn qzAsyncallback; QzAsyncOperationType_T op_type; const unsigned char *req_src; unsigned int req_in_len; unsigned char *req_dest; unsigned int req_out_len; }; typedef struct QzAsynctrl_S { int async_ctrl_init; QzRing_T *async_req_ring; pthread_key_t async_req_key; pthread_t async_consume_t; pthread_t async_polling_t; int async_polling_direct; sem_t sem; } QzAsynctrl_T; typedef struct QzSess_S { int inst_hint; /*which instance we last used*/ QzSessionParamsInternal_T sess_params; CpaDcSessionSetupData session_setup_data; Cpa32U session_size; Cpa32U ctx_size; CpaStatus sess_status; int submitted; int processed; int last_submitted; int last_processed; int stop_submitting; signed long seq; signed long seq_in; pthread_t c_th_i; pthread_t c_th_o; unsigned char *src; unsigned int *src_sz; unsigned int *dest_sz; unsigned char *next_dest; int force_sw; InflateState_T inflate_stat; void *strm; z_stream *inflate_strm; unsigned long qz_in_len; unsigned long qz_out_len; unsigned long *crc32; unsigned int last; unsigned int single_thread; unsigned int polling_idx; z_stream *deflate_strm; DeflateState_T deflate_stat; LZ4F_dctx *dctx; void *qzdeflateExtData; /**< An opaque pointer containing extended results for deflate session*/ /* LSM */ LatencyMetrix_T RRT; LatencyMetrix_T PPT; LatencyMetrix_T SWT; /* Async mode */ QzAsynctrl_T *async_ctrl; } QzSess_T; typedef struct QzStreamBuf_S { unsigned int buf_len; unsigned char *in_buf; unsigned char *out_buf; unsigned int out_offset; unsigned int in_offset; unsigned int flush_more; } QzStreamBuf_T; typedef struct ThreadData_S { pid_t ppid; pid_t pid; struct timeval timer[MAX_THREAD_TMR]; } ThreadData_T; typedef struct QzExtraHeader_S { uint32_t src_sz; uint32_t dest_sz; } QzExtraHeader_T; typedef struct QzExtraField_S { unsigned char st1; unsigned char st2; uint16_t x2_len; QzExtraHeader_T qz_e; } QzExtraField_T; typedef struct StdGzH_S { unsigned char id1; unsigned char id2; unsigned char cm; unsigned char flag; unsigned char mtime[4]; unsigned char xfl; unsigned char os; } StdGzH_T; typedef struct QzGzH_S { StdGzH_T std_hdr; uint16_t x_len; QzExtraField_T extra; } QzGzH_T; typedef struct Qz4BH_S { uint32_t blk_size; } Qz4BH_T; typedef struct StdGzF_S { uint32_t crc32; uint32_t i_size; } StdGzF_T; typedef struct QzMem_S { int flag; unsigned char *addr; int sz; int numa; } QzMem_T; // custom deflateExt data structure typedef struct QzDeflateExtCustomData_S { unsigned char end_of_stream; } QzDeflateExtCustomData_T; typedef struct StdZLIBH_S { // (CMF) defines compression method and flags (in case of "deflate", the window size). unsigned char cmf; unsigned char flags; } StdZlibH_T; typedef struct StdZlibF_T { uint32_t adler32; /* adler32 checksum */ } StdZlibF_T; #pragma pack(push, 1) /* lz4 frame header */ typedef struct QzLZ4H_S { uint32_t magic; /* LZ4 magic number */ uint8_t flag_desc; uint8_t block_desc; uint64_t cnt_size; uint8_t hdr_cksum; /* header checksum */ } QzLZ4H_T; /* lz4 frame footer */ typedef struct QzLZ4F_S { uint32_t end_mark; /* LZ4 end mark */ uint32_t cnt_cksum; /* content checksum */ } QzLZ4F_T; #pragma pack(pop) void dumpAllCounters(void); int qzSetupHW(QzSession_T *sess, int i); unsigned long qzGzipHeaderSz(void); unsigned long qz4BHeaderSz(void); unsigned long stdGzipHeaderSz(void); unsigned long stdGzipFooterSz(void); unsigned long stdZlibHeaderSz(void); unsigned long stdZlibFooterSz(void); unsigned long outputHeaderSz(DataFormatInternal_T data_fmt); unsigned long outputFooterSz(DataFormatInternal_T data_fmt); void qzGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res); void qz4BHeaderGen(unsigned char *ptr, CpaDcRqResults *res); void stdGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res); int qzGzipHeaderExt(const unsigned char *const ptr, QzGzH_T *hdr); void outputHeaderGen(unsigned char *ptr, CpaDcRqResults *res, DataFormatInternal_T data_fmt); void qzGzipFooterGen(unsigned char *ptr, CpaDcRqResults *res); void outputFooterGen(unsigned char *ptr, CpaDcRqResults *res, DataFormatInternal_T data_fmt); void qzGzipFooterExt(const unsigned char *const ptr, StdGzF_T *ftr); void stdZlibHeaderGen(unsigned char *ptr, CpaDcRqResults *res); int qzVerifyZlibHeader(const unsigned char *ptr, const unsigned int *const src_len); void qzZlibFooterGen(unsigned char *ptr, CpaDcRqResults *res); int isQATProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess); int qzSWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last); int qzSWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *uncompressed_buf_len, unsigned char *dest, unsigned int *compressed_buffer_len); int qzSWDecompressMulti(QzSession_T *sess, const unsigned char *src, unsigned int *uncompressed_buf_len, unsigned char *dest, unsigned int *compressed_buffer_len); unsigned char getSwBackup(QzSession_T *sess); void setDeflateEndOfStream(QzSess_T *sess, unsigned char val); unsigned char getDeflateEndOfStream(QzSess_T *qz_sess); #ifdef ADF_PCI_API extern CpaStatus icp_adf_get_numDevices(Cpa32U *); #endif int initStream(QzSession_T *sess, QzStream_T *strm); void *qzMemSet(void *ptr, unsigned char filler, unsigned int count); unsigned char *findStdGzipFooter(const unsigned char *src_ptr, long src_avail_len); void removeSession(int i); void cleanUpInstMem(int i); void qzMemDestory(void); void streamBufferCleanup(void); //lz4 functions unsigned long qzLZ4HeaderSz(void); unsigned long qzLZ4FooterSz(void); void qzLZ4HeaderGen(unsigned char *ptr, CpaDcRqResults *res); void qzLZ4FooterGen(unsigned char *ptr, CpaDcRqResults *res); unsigned char *findLZ4Footer(const unsigned char *src_ptr, long src_avail_len); int qzVerifyLZ4FrameHeader(const unsigned char *const ptr, uint32_t len); int isQATLZ4Processable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess); int isQATDeflateProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess); unsigned long qzLZ4SBlockHeaderSz(void); void qzLZ4SBlockHeaderGen(unsigned char *ptr, CpaDcRqResults *res); int qzSetupSessionInternal(QzSession_T *sess); int qzCheckParams(QzSessionParams_T *params); int qzCheckParamsDeflate(QzSessionParamsDeflate_T *params); int qzCheckParamsLZ4(QzSessionParamsLZ4_T *params); int qzCheckParamsLZ4S(QzSessionParamsLZ4S_T *params); int qzCheckParamsDeflateExt(QzSessionParamsDeflateExt_T *params); void qzGetParams(QzSessionParamsInternal_T *internal_params, QzSessionParams_T *params); void qzGetParamsDeflate(QzSessionParamsInternal_T *internal_params, QzSessionParamsDeflate_T *params); void qzGetParamsLZ4(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4_T *params); void qzGetParamsLZ4S(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4S_T *params); void qzGetParamsDeflateExt(QzSessionParamsInternal_T *internal_params, QzSessionParamsDeflateExt_T *params); void qzSetParamsLZ4S(QzSessionParamsLZ4S_T *params, QzSessionParamsInternal_T *internal_params); void qzSetParamsLZ4(QzSessionParamsLZ4_T *params, QzSessionParamsInternal_T *internal_params); void qzSetParamsDeflate(QzSessionParamsDeflate_T *params, QzSessionParamsInternal_T *internal_params); void qzSetParams(QzSessionParams_T *params, QzSessionParamsInternal_T *internal_params); void qzSetParamsDeflateExt(QzSessionParamsDeflateExt_T *params, QzSessionParamsInternal_T *internal_params); /* SW Fallback for HW request offload failed or HW respond in Error status */ int compInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned int src_send_sz); int compOutSWFallback(int i, int j, QzSession_T *sess, long *dest_avail_len); int decompInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len); int decompOutSWFallback(int i, int j, QzSession_T *sess, unsigned int *dest_avail_len); /* Stream pData may need reset, which is caused by driver API params limitation, when setup buffer, may feed pinned pointer or common pointer to pBuffer. */ void RestoreDestCpastreamBuffer(int i, int j); void RestoreSrcCpastreamBuffer(int i, int j); void ResetCpastreamSink(int i, int j); /* compression stream/src/dest buffer setup, and cleanup */ void compBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned int src_remaining, unsigned int hw_buff_sz, unsigned int src_send_sz); void compInBufferCleanUp(int i, int j); void compOutSrcBufferCleanUp(int i, int j); void compOutErrorDestBufferCleanUp(int i, int j); void compOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, unsigned int dest_receive_sz); /* docompressOut successful respond process, or error respond process */ void compOutProcessedRespond(int i, int j, QzSess_T *qz_sess); void compOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess); int compOutCheckDestLen(int i, int j, QzSession_T *sess, long *dest_avail_len, long dest_receive_sz); int checkHeader(QzSess_T *qz_sess, unsigned char *src, unsigned int src_avail_len, unsigned int dest_avail_len, QzGzH_T *hdr); /* decompression stream/src/dest buffer setup, and cleanup */ void swapDataBuffer(unsigned long i, int j); void decompBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int src_avail_len, QzGzH_T *hdr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len); void decompInBufferCleanUp(int i, int j); void decompOutSrcBufferCleanUp(int i, int j); void decompOutErrorDestBufferCleanUp(int i, int j); void decompOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, CpaDcRqResults *resl, unsigned int dest_avail_len); /* dodecompressOut successful respond process, or error respond process */ void decompOutProcessedRespond(int i, int j, QzSess_T *qz_sess); void decompOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess); int decompOutCheckSum(int i, int j, QzSession_T *sess, CpaDcRqResults *resl); /* LSM */ static inline uint64_t rdtsc() { unsigned int lo, hi; __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi)); return ((uint64_t)hi << 32) | lo; } void metrixReset(LatencyMetrix_T *m); void metrixUpdate(LatencyMetrix_T *m, unsigned long val); int compLSMFallback(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last); int decompLSMFallback(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len); /* Internal Async API */ int AsyncCompOutCheckDestLen(int i, int j, QzSession_T *sess, long dest_receive_sz); void AsyncCompOutValidDestBufferCleanUp(int i, int j, unsigned int dest_receive_sz); int AsyncDecompOutSWFallback(int i, int j, QzSession_T *sess, QzAsyncReq_T *req); void AsyncDecompOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, CpaDcRqResults *resl, QzAsyncReq_T *req); int populateAsyncReq(QzSession_T *sess, const unsigned char *src, unsigned char *dest, qzAsyncCallbackFn callback, QzResult_T *qzResults, QzAsyncOperationType_T op_type, QzAsyncReq_T *req); int qzAsyncReqSubmit(QzSession_T *sess, QzAsyncReq_T *req, QzDirection_T direct); int qzAsyncSetupHWSession(QzSession_T *sess, QzDirection_T direct); int qzSetupAsyncCtrl(QzSession_T *sess); int GetStableInstance(QzSession_T *sess); #endif //_QATZIPP_H QATzip-1.3.1/src/qatzip_lz4.c000066400000000000000000000164731500263377000157360ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #define XXH_NAMESPACE QATZIP_ #include "xxhash.h" #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" inline unsigned long qzLZ4HeaderSz(void) { return QZ_LZ4_HEADER_SIZE; } inline unsigned long qzLZ4FooterSz(void) { return QZ_LZ4_FOOTER_SIZE; } int qzVerifyLZ4FrameHeader(const unsigned char *const ptr, uint32_t len) { QzLZ4H_T *hdr = NULL; assert(ptr != NULL); assert(len >= QZ_LZ4_HEADER_SIZE); QZ_DEBUG("qzVerifyLZ4FrameHeader\n"); hdr = (QzLZ4H_T *)ptr; //Skippable frames if ((hdr->magic & 0xFFFFFFF0U) == QZ_LZ4_MAGIC_SKIPPABLE) { /*for skippalbe frames, fallback to software decompression */ QZ_WARN("qzVerifyLZ4FrameHeader: skip frames, switch to software.\n"); return QZ_FORCE_SW; } //Unknown magic number if (hdr->magic != QZ_LZ4_MAGIC) { QZ_ERROR("qzVerifyLZ4FrameHeader: unknown lz4 frame magic number %x.\n", hdr->magic); return QZ_FAIL; } //No support for unknown lz4 version if ((hdr->flag_desc >> 6 & 0x3) != QZ_LZ4_VERSION) { QZ_ERROR("qzVerifyLZ4FrameHeader: unknown lz4 frame version number.\n"); return QZ_FAIL; } if ((hdr->flag_desc & 0x1) != QZ_LZ4_DICT_ID_FLAG || (hdr->flag_desc >> 4 & 0x1) != QZ_LZ4_BLK_CKS_FLAG || (hdr->flag_desc >> 2 & 0x1) != QZ_LZ4_CNT_CKS_FLAG || (hdr->flag_desc >> 3 & 0x1) != QZ_LZ4_CNT_SIZE_FLAG) { QZ_WARN("qzVerifyLZ4FrameHeader: unsupported lz4 frame header \ switch to software.\n"); return QZ_FORCE_SW; } return QZ_OK; } void qzLZ4HeaderGen(unsigned char *ptr, CpaDcRqResults *res) { QzLZ4H_T *hdr = NULL; unsigned char *hc_start = NULL; assert(ptr != NULL); assert(res != NULL); hdr = (QzLZ4H_T *)ptr; hdr->magic = QZ_LZ4_MAGIC; //flag descriptor hdr->flag_desc = (unsigned char)(((QZ_LZ4_VERSION & 0x03) << 6) + ((QZ_LZ4_BLK_INDEP & 0x01) << 5) + ((QZ_LZ4_BLK_CKS_FLAG & 0x01) << 4) + ((QZ_LZ4_CNT_SIZE_FLAG & 0x01) << 3) + ((QZ_LZ4_CNT_CKS_FLAG & 0x01) << 2) + (QZ_LZ4_DICT_ID_FLAG & 0x01)); //block descriptor hdr->block_desc = (unsigned char)((QZ_LZ4_MAX_BLK_SIZE & 0x07) << 4); //content size hdr->cnt_size = res->consumed; //header checksum hc_start = ptr + QZ_LZ4_MAGIC_SIZE; hdr->hdr_cksum = (unsigned char)((XXH32(hc_start, QZ_LZ4_FD_SIZE - 1, 0) >> 8) & 0xff); } void qzLZ4FooterGen(unsigned char *ptr, CpaDcRqResults *res) { QzLZ4F_T *footer = NULL; assert(ptr != NULL); footer = (QzLZ4F_T *)ptr; footer->end_mark = QZ_LZ4_ENDMARK; footer->cnt_cksum = res->checksum; } unsigned char *findLZ4Footer(const unsigned char *src_ptr, long src_avail_len) { const unsigned char *lz4_footer = NULL; unsigned int block_sz = 0; unsigned int frame_sz = 0; assert(src_ptr != NULL); //the src_avail_len should be equal or greater than minimum of frame size if (src_avail_len < (QZ_LZ4_HEADER_SIZE + QZ_LZ4_BLK_HEADER_SIZE + QZ_LZ4_FOOTER_SIZE)) { return NULL; } block_sz = (*(unsigned int *)(src_ptr + QZ_LZ4_HEADER_SIZE)) & 0x7fffffff; frame_sz = block_sz + QZ_LZ4_HEADER_SIZE + QZ_LZ4_BLK_HEADER_SIZE + QZ_LZ4_FOOTER_SIZE; while (src_avail_len >= frame_sz) { lz4_footer = (src_ptr + frame_sz - QZ_LZ4_FOOTER_SIZE); if (*(unsigned int *)lz4_footer == (unsigned int)0x0) { return (unsigned char *)lz4_footer; } block_sz = (*(unsigned int *)lz4_footer) & 0x7fffffff; frame_sz += block_sz + QZ_LZ4_BLK_HEADER_SIZE; } return NULL; } int isQATLZ4Processable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess) { QzLZ4H_T *hdr = (QzLZ4H_T *)ptr; QzLZ4F_T *footer = NULL; if (*src_len < QZ_LZ4_HEADER_SIZE) { return 0; } //Skippable frames if ((hdr->magic & 0xFFFFFFF0U) == QZ_LZ4_MAGIC_SKIPPABLE) { /*for skippalbe frames, fallback to software decompression */ return 0; } //Unknown magic number if (hdr->magic != QZ_LZ4_MAGIC) { return 0; } //No support for unknown lz4 version if ((hdr->flag_desc >> 6 & 0x3) != QZ_LZ4_VERSION) { return 0; } if ((hdr->flag_desc & 0x1) != QZ_LZ4_DICT_ID_FLAG || (hdr->flag_desc >> 4 & 0x1) != QZ_LZ4_BLK_CKS_FLAG || (hdr->flag_desc >> 2 & 0x1) != QZ_LZ4_CNT_CKS_FLAG || (hdr->flag_desc >> 3 & 0x1) != QZ_LZ4_CNT_SIZE_FLAG) { return 0; } footer = (QzLZ4F_T *)findLZ4Footer(ptr, *src_len); if (footer == NULL || ((unsigned int)((unsigned char *)footer - ptr - QZ_LZ4_HEADER_SIZE)) > DEST_SZ( qz_sess->sess_params.hw_buff_sz)) { return 0; } return 1; } inline unsigned long qzLZ4SBlockHeaderSz(void) { return QZ_LZ4_BLK_HEADER_SIZE; } void qzLZ4SBlockHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { assert(ptr != NULL); assert(res != NULL); //block header contains block size unsigned int *blk_size = (unsigned int *)(ptr); *blk_size = (unsigned int)res->produced; } QATzip-1.3.1/src/qatzip_mem.c000077500000000000000000000146451500263377000160050ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #include #else #include #include #include #endif #include "qatzip.h" #include "qz_utils.h" #include "qatzip_internal.h" #include "qatzip_page_table.h" #define __STDC_WANT_LIB_EXT1__ 1 #include static QzPageTable_T g_qz_page_table = {{{0}}}; static pthread_mutex_t g_qz_table_lock = PTHREAD_MUTEX_INITIALIZER; static atomic_int g_table_init = 0; static __thread unsigned char *g_a; extern processData_T g_process; void *doUserMemset(void *const ptr, unsigned char filler, const unsigned int count) { unsigned int lim = 0; volatile unsigned char *volatile dstPtr = ptr; while (lim < count) { dstPtr[lim++] = filler; } return (void *)dstPtr; } /* * * Fills a memory zone with a given constant byte, * * returns pointer to the memory zone. * */ void *qzMemSet(void *ptr, unsigned char filler, unsigned int count) { if (ptr == NULL) { QZ_ERROR("Invalid input memory pointer!"); return NULL; } #ifdef __STDC_LIB_EXT1__ errno_t result = memset_s( ptr, sizeof(ptr), filler, count) /* Supported on C11 standard */ if (result != 0) { QZ_ERROR("memset failed by the reason of %d", result); } return ptr; #else return doUserMemset( ptr, filler, count); /* Platform-independent secure memset */ #endif /* __STDC_LIB_EXT1__ */ } int qzMemFindAddr(unsigned char *a) { int rc = 0; unsigned long al, b; al = (unsigned long)a; b = (al & PAGE_MASK); rc = (PINNED == loadAddr(&g_qz_page_table, (void *)b)) ? PINNED_MEM : COMMON_MEM; if (0 != rc) { QZ_MEM_PRINT("Find 0x%lx in page table\n", b); } return rc; } static void qzMemUnRegAddr(unsigned char *a) { return; } static int qzMemRegAddr(unsigned char *a, size_t sz) { int rc; unsigned long al, b; if (0 != pthread_mutex_lock(&g_qz_table_lock)) { return -1; } /*addr already registered*/ if ((1 == qzMemFindAddr(a)) && (1 == qzMemFindAddr(a + sz - 1))) { pthread_mutex_unlock(&g_qz_table_lock); return 0; } al = (unsigned long)a; b = (al & PAGE_MASK); sz += (al - b); QZ_MEM_PRINT("4 KB page is 0x%lx\n", b); QZ_MEM_PRINT("Inserting 0x%lx size %lx to page table\n", b, sz); rc = storeMmapRange(&g_qz_page_table, (void *)b, PINNED, sz); pthread_mutex_unlock(&g_qz_table_lock); return rc; } void qzMemDestory(void) { if (0 == g_table_init) { return; } if (0 != pthread_mutex_lock(&g_qz_table_lock)) { return; } freePageTable(&g_qz_page_table); g_table_init = 0; if (0 != pthread_mutex_unlock(&g_qz_table_lock)) { return; } } void *qzMalloc(size_t sz, int numa, int pinned) { int status; int real_numa; QzSession_T temp_sess; qzMemSet(&temp_sess, 0, sizeof(QzSession_T)); if (0 == g_table_init) { if (0 != pthread_mutex_lock(&g_qz_table_lock)) { return NULL; } if (0 == g_table_init) { qzMemSet(&g_qz_page_table, 0, sizeof(QzPageTable_T)); g_table_init = 1; } if (0 != pthread_mutex_unlock(&g_qz_table_lock)) { return NULL; } } if (1 == pinned && QZ_NONE == g_process.qz_init_status) { status = qzInit(&temp_sess, 1); if (QZ_INIT_FAIL(status)) { QZ_ERROR("QAT init failed with error: %d\n", status); return NULL; } } if (numa == QZ_AUTO_SELECT_NUMA_NODE) { int cpu_id = sched_getcpu(); real_numa = numa_node_of_cpu(cpu_id); if (real_numa == -1) { QZ_ERROR("couldn't find NUMA node of CPU %d\n", cpu_id); return NULL; } } else { real_numa = numa; } g_a = qaeMemAllocNUMA(sz, real_numa, 64); if (NULL == g_a) { if (0 == pinned) { QZ_MEM_PRINT("regular malloc\n"); g_a = malloc(sz); } } else { if (0 != qzMemRegAddr(g_a, sz)) { qaeMemFreeNUMA((void **)&g_a); return NULL; } } return g_a; } void qzFree(void *m) { if (NULL == m) { return; } QZ_MEM_PRINT("\t\tfreeing 0x%lx\n", (unsigned long)m); if (1 == qzMemFindAddr(m)) { qaeMemFreeNUMA((void **)&m); qzMemUnRegAddr(m); } else { free(m); } m = NULL; } QATzip-1.3.1/src/qatzip_page_table.h000066400000000000000000000122251500263377000173040ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _QATZIP_PAGE_TABLE_H #define _QATZIP_PAGE_TABLE_H #include #include #include #define PAGE_SHIFT (12) #define PAGE_SIZE (0x1000) #define PAGE_MASK (~(PAGE_SIZE - 1)) #define LEVEL_SIZE (PAGE_SIZE / sizeof(uint64_t)) #define PINNED (-1) typedef struct __attribute__((__packed__)) { uint32_t offset : 12; uint32_t idxl0 : 9; uint32_t idxl1 : 9; uint32_t idxl2 : 9; uint32_t idxl3 : 9; } QzPageEntry_T; typedef union { uint64_t addr; QzPageEntry_T pg_entry; } QzPageIndex_T; typedef struct QzPageTable_T { union { uint64_t mt; struct QzPageTable_T *pt; } next[LEVEL_SIZE]; } QzPageTable_T; static inline void *nextLevel(QzPageTable_T *volatile *ptr) { QzPageTable_T *old_ptr = *ptr; QzPageTable_T *new_ptr; if (NULL != old_ptr) return old_ptr; new_ptr = mmap(NULL, sizeof(QzPageTable_T), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if ((void *) - 1 == new_ptr) { QZ_ERROR("nextLevel: mmap error\n"); return NULL; } if (!__sync_bool_compare_and_swap(ptr, NULL, new_ptr)) munmap(new_ptr, sizeof(QzPageTable_T)); return *ptr; } static inline void freePageLevel(QzPageTable_T *const level, const size_t iter) { size_t i = 0; if (0 == iter) return; for (i = 0; i < LEVEL_SIZE; ++i) { QzPageTable_T *pt = level->next[i].pt; if (NULL != pt) { freePageLevel(pt, iter - 1); munmap(pt, sizeof(QzPageTable_T)); } } } static inline void freePageTable(QzPageTable_T *const table) { /* There are 1+3 levels in 48-bit page table for 4KB pages. */ freePageLevel(table, 3); /* Reset global root table. */ qzMemSet(table, 0, sizeof(QzPageTable_T)); } static inline int storeAddr(QzPageTable_T *level, uintptr_t virt, uint64_t type) { QzPageIndex_T id; id.addr = virt; level = nextLevel(&level->next[id.pg_entry.idxl3].pt); if (NULL == level) { return -1; } level = nextLevel(&level->next[id.pg_entry.idxl2].pt); if (NULL == level) { return -1; } level = nextLevel(&level->next[id.pg_entry.idxl1].pt); if (NULL == level) { return -1; } level->next[id.pg_entry.idxl0].mt = type; return 0; } static inline int storeMmapRange(QzPageTable_T *p_level, void *p_virt, uint64_t type, size_t p_size) { size_t offset; size_t page_size = PAGE_SIZE; const uintptr_t virt = (uintptr_t)p_virt; for (offset = 0; offset < p_size; offset += page_size) { if (0 != storeAddr(p_level, virt + offset, type)) { return -1; } } return 0; } static inline uint64_t loadAddr(QzPageTable_T *level, void *virt) { QzPageIndex_T id; id.addr = (uintptr_t)virt; level = level->next[id.pg_entry.idxl3].pt; if (NULL == level) return 0; level = level->next[id.pg_entry.idxl2].pt; if (NULL == level) return 0; level = level->next[id.pg_entry.idxl1].pt; if (NULL == level) return 0; return level->next[id.pg_entry.idxl0].mt; } #endif QATzip-1.3.1/src/qatzip_stream.c000066400000000000000000000563611500263377000165200ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifdef HAVE_QAT_HEADERS #include #include #include #include #include #else #include #include #include #include #include #endif #include #include #include #include #include #define STREAM_BUFF_LIST_SZ 8 typedef struct StreamBuffNode_S { void *buffer; size_t size; int pinned; struct StreamBuffNode_S *next; struct StreamBuffNode_S *prev; } StreamBuffNode_T; typedef struct StreamBuffNodeList_S { StreamBuffNode_T *head; StreamBuffNode_T *tail; unsigned int size; pthread_mutex_t mutex; } StreamBuffNodeList_T; StreamBuffNodeList_T g_strm_buff_list_free = { .head = NULL, .tail = NULL, .size = 0, .mutex = PTHREAD_MUTEX_INITIALIZER }; StreamBuffNodeList_T g_strm_buff_list_used = { .head = NULL, .tail = NULL, .size = 0, .mutex = PTHREAD_MUTEX_INITIALIZER }; static inline int addNodeToList(StreamBuffNode_T *node, StreamBuffNodeList_T *buff_list) { buff_list->size += 1; node->next = NULL; if (NULL == buff_list->tail) { buff_list->head = node; node->prev = NULL; } else { node->prev = buff_list->tail; buff_list->tail->next = node; } buff_list->tail = node; return SUCCESS; } static inline int removeNodeFromList(StreamBuffNode_T *node, StreamBuffNodeList_T *buff_list) { buff_list->size -= 1; if (NULL != node->prev) { node->prev->next = node->next; if (NULL != node->next) { node->next->prev = node->prev; } else { buff_list->tail = node->prev; } } else { if (NULL != node->next) { node->next->prev = NULL; buff_list->head = node->next; } else { buff_list->head = NULL; buff_list->tail = NULL; } } return SUCCESS; } void streamBufferCleanup(void) { StreamBuffNode_T *node; StreamBuffNode_T *next; if (unlikely(0 != pthread_mutex_lock(&g_strm_buff_list_used.mutex))) { QZ_ERROR("Failed to get Mutex Lock.\n"); return; } node = g_strm_buff_list_used.head; while (node != NULL) { next = node->next; removeNodeFromList(node, &g_strm_buff_list_used); qzFree(node->buffer); free(node); node = next; } if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_used.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); return; } if (unlikely(0 != pthread_mutex_lock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to get Mutex Lock.\n"); return; } node = g_strm_buff_list_free.head; while (node != NULL) { next = node->next; removeNodeFromList(node, &g_strm_buff_list_free); qzFree(node->buffer); free(node); node = next; } if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); return; } } static void *getNodeBuffFromFreeList(size_t sz, int pinned) { pthread_mutex_lock(&g_strm_buff_list_free.mutex); pthread_mutex_lock(&g_strm_buff_list_used.mutex); void *retval = NULL; StreamBuffNode_T *node; for (node = g_strm_buff_list_free.head; node != NULL; node = node->next) { if (pinned == node->pinned && sz <= node->size) { if (!removeNodeFromList(node, &g_strm_buff_list_free)) { retval = NULL; goto done; } if (!addNodeToList(node, &g_strm_buff_list_used)) { retval = NULL; goto done; } retval = node->buffer; goto done; } } done: pthread_mutex_unlock(&g_strm_buff_list_used.mutex); pthread_mutex_unlock(&g_strm_buff_list_free.mutex); return retval; } static void allocSomeNodesForFreeList(size_t sz, int numa, int pinned) { StreamBuffNode_T *node; int i; for (i = 0; i < STREAM_BUFF_LIST_SZ; ++i) { node = malloc(sizeof(StreamBuffNode_T)); if (NULL == node) { break; } node->buffer = qzMalloc(sz, numa, pinned); if (NULL == node->buffer) { free(node); break; } node->pinned = pinned; node->size = sz; if (unlikely(0 != pthread_mutex_lock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to get Mutex Lock.\n"); free(node); return; } if (!addNodeToList(node, &g_strm_buff_list_free)) { free(node); if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); return; } } if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); free(node); return; } } } static void *streamBufferAlloc(size_t sz, int numa, int pinned) { StreamBuffNode_T *node = getNodeBuffFromFreeList(sz, pinned); if (NULL == node) { //try to add some nodes to free list allocSomeNodesForFreeList(sz, numa, pinned); node = getNodeBuffFromFreeList(sz, pinned); } return node; } static void streamBufferFree(void *addr) { StreamBuffNode_T *node; pthread_mutex_lock(&g_strm_buff_list_free.mutex); pthread_mutex_lock(&g_strm_buff_list_used.mutex); for (node = g_strm_buff_list_used.head; node != NULL; node = node->next) { if (addr == node->buffer) { if (removeNodeFromList(node, &g_strm_buff_list_used) == FAILURE) { QZ_ERROR("Fail to remove Node for streamBufferFree"); goto done; } if (STREAM_BUFF_LIST_SZ <= g_strm_buff_list_free.size) { qzFree(node->buffer); free(node); } else { addNodeToList(node, &g_strm_buff_list_free); } addr = NULL; goto done; } } done: pthread_mutex_unlock(&g_strm_buff_list_used.mutex); pthread_mutex_unlock(&g_strm_buff_list_free.mutex); } int initStream(QzSession_T *sess, QzStream_T *strm) { int rc = QZ_FAIL; QzSess_T *qz_sess = NULL; QzStreamBuf_T *stream_buf = NULL; if (NULL != strm->opaque) { return QZ_DUPLICATE; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { return QZ_FAIL; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { rc = qzSetupSessionDeflate(sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { return QZ_FAIL; } } qz_sess = (QzSess_T *)(sess->internal); qz_sess->strm = strm; strm->opaque = malloc(sizeof(QzStreamBuf_T)); stream_buf = (QzStreamBuf_T *) strm->opaque; if (NULL == stream_buf) { QZ_ERROR("Fail to allocate memory for QzStreamBuf"); return QZ_FAIL; } stream_buf->out_offset = 0; stream_buf->in_offset = 0; stream_buf->flush_more = 0; stream_buf->buf_len = qz_sess->sess_params.strm_buff_sz; stream_buf->in_buf = streamBufferAlloc(stream_buf->buf_len, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); stream_buf->out_buf = streamBufferAlloc(stream_buf->buf_len, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (NULL == stream_buf->in_buf) { QZ_INFO("stream_buf->in_buf : PINNED_MEM failed, try COMMON_MEM\n"); stream_buf->in_buf = streamBufferAlloc(stream_buf->buf_len, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); } if (NULL == stream_buf->out_buf) { QZ_INFO("stream_buf->out_buf : PINNED_MEM failed, try COMMON_MEM\n"); stream_buf->out_buf = streamBufferAlloc(stream_buf->buf_len, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); } if (NULL == stream_buf->in_buf || NULL == stream_buf->out_buf) { goto clear; } QZ_INFO("Allocate stream buf %u\n", stream_buf->buf_len); strm->pending_in = 0; strm->pending_out = 0; strm->crc_32 = 0; return QZ_OK; clear: if (NULL == stream_buf->in_buf) { QZ_ERROR("Fail to allocate memory for in_buf of QzStreamBuf"); } else { qzFree(stream_buf->in_buf); } if (NULL == stream_buf->out_buf) { QZ_ERROR("Fail to allocate memory for out_buf of QzStreamBuf"); } else { qzFree(stream_buf->out_buf); } free(stream_buf); stream_buf = NULL; strm->opaque = NULL; return QZ_FAIL; } static unsigned int copyStreamInput(QzStream_T *strm, unsigned char *in) { unsigned int cpy_cnt = 0; unsigned int avail_in = 0; QzStreamBuf_T *stream_buf = strm->opaque; avail_in = stream_buf->buf_len - strm->pending_in; cpy_cnt = (strm->in_sz > avail_in) ? avail_in : strm->in_sz; QZ_MEMCPY(stream_buf->in_buf + strm->pending_in, in, cpy_cnt, strm->in_sz); QZ_INFO("Copy to input from %p, to %p, count %u\n", in, stream_buf->in_buf + strm->pending_in, cpy_cnt); strm->pending_in += cpy_cnt; strm->in_sz -= cpy_cnt; return cpy_cnt; } static unsigned int copyStreamOutput(QzStream_T *strm, unsigned char *out) { unsigned int cpy_cnt = 0; unsigned int avail_out = 0; QzStreamBuf_T *stream_buf = strm->opaque; avail_out = strm->out_sz; cpy_cnt = (strm->pending_out > avail_out) ? avail_out : strm->pending_out; QZ_MEMCPY(out, stream_buf->out_buf + stream_buf->out_offset, avail_out, cpy_cnt); QZ_INFO("copy %u to user output\n", cpy_cnt); strm->out_sz -= cpy_cnt; strm->pending_out -= cpy_cnt; stream_buf->out_offset += cpy_cnt; if (strm->pending_out == 0) { stream_buf->out_offset = 0; } return cpy_cnt; } int qzCompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last) { int rc = QZ_FAIL; unsigned long *strm_crc = NULL; unsigned int input_len = 0; unsigned int output_len = 0; unsigned int copied_output = 0; unsigned int copied_input = 0; unsigned int copied_input_last = 0; unsigned int copy_more = 1; unsigned int inbuf_offset = 0; unsigned int consumed = 0; unsigned int produced = 0; unsigned int strm_last = 0; QzStreamBuf_T *stream_buf = NULL; QzSess_T *qz_sess = NULL; DataFormatInternal_T data_fmt = DEFLATE_GZIP_EXT; if (NULL == sess || \ NULL == strm || \ (last != 0 && last != 1)) { rc = QZ_PARAMS; if (NULL != strm) { strm->in_sz = 0; strm->out_sz = 0; } goto end; } if (NULL == strm->out) { rc = QZ_PARAMS; strm->in_sz = 0; strm->out_sz = 0; goto end; } if (NULL == strm->in && \ strm->in_sz > 0) { rc = QZ_PARAMS; strm->in_sz = 0; strm->out_sz = 0; goto end; } if (NULL == strm->opaque) { rc = initStream(sess, strm); if (QZ_OK != rc) { goto done; } } switch (strm->crc_type) { case QZ_CRC32: case QZ_ADLER: default: strm_crc = (unsigned long *)&strm->crc_32; break; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { return QZ_FAIL; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { rc = qzSetupSessionDeflate(sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { strm->in_sz = 0; strm->out_sz = 0; return QZ_FAIL; } } qz_sess = (QzSess_T *)(sess->internal); data_fmt = qz_sess->sess_params.data_fmt; if (data_fmt != DEFLATE_RAW && data_fmt != DEFLATE_GZIP_EXT) { QZ_ERROR("Invalid data format: %d\n", data_fmt); strm->in_sz = 0; strm->out_sz = 0; return QZ_PARAMS; } stream_buf = (QzStreamBuf_T *) strm->opaque; while (strm->pending_out > 0) { copied_output = copyStreamOutput(strm, strm->out + produced); produced += copied_output; if (0 == copied_output || (0 == strm->pending_out && 0 == strm->pending_in && 0 == strm->in_sz)) { rc = QZ_OK; /* When pending_out and pending_in are all greater than zero, we * set the flush_more flag to indicate that we should not copy more * input and should do the process(compression or decompression) */ if (strm->pending_in > 0) { stream_buf->flush_more = 1; } goto done; } } while (0 == strm->pending_out) { if (copy_more == 1 && stream_buf->flush_more != 1) { copied_input_last = copied_input; // Note, strm->in == NULL and strm->in_sz == 0, will not cause // copyStreamInput failed, but it's Dangerous behavior. if (NULL != strm->in) { copied_input += copyStreamInput(strm, strm->in + consumed); } if (strm->pending_in < stream_buf->buf_len && last != 1) { rc = QZ_OK; goto done; } else { copy_more = 0; } } input_len = strm->pending_in; output_len = stream_buf->buf_len; if (stream_buf->flush_more == 1) { inbuf_offset = stream_buf->in_offset; stream_buf->flush_more = 0; } strm_last = (0 == strm->in_sz && last) ? 1 : 0; QZ_DEBUG("Before Call qzCompressCrc input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); rc = qzCompressCrc(sess, stream_buf->in_buf + inbuf_offset, &input_len, stream_buf->out_buf, &output_len, strm_last, strm_crc); strm->pending_in -= input_len; strm->pending_out = output_len; copied_output = copyStreamOutput(strm, strm->out + produced); consumed = copied_input; produced += copied_output; inbuf_offset += input_len; stream_buf->in_offset = inbuf_offset; QZ_DEBUG("After Call qzCompressCrc input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); if (QZ_BUF_ERROR == rc) { if (0 == input_len) { QZ_ERROR("ERROR in copy stream output, stream buf size = %u\n", stream_buf->buf_len); copied_input = copied_input_last; rc = QZ_FAIL; goto done; } else { rc = QZ_OK; } } if (QZ_OK != rc) { copied_input = copied_input_last; rc = QZ_FAIL; goto done; } if (0 == strm->pending_in) { copy_more = 1; inbuf_offset = 0; } if (0 == strm->pending_in && 0 == strm->in_sz) { rc = QZ_OK; goto done; } } done: strm->in_sz = copied_input; strm->out_sz = produced; QZ_DEBUG("Exit Compress Stream input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); end: return rc; } int qzDecompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last) { int rc = QZ_FAIL; unsigned int input_len = 0; unsigned int output_len = 0; unsigned int copied_output = 0; unsigned int copied_input = 0; unsigned int copied_input_last = 0; unsigned int consumed = 0; unsigned int produced = 0; unsigned int copy_more = 1; unsigned int inbuf_offset = 0; QzStreamBuf_T *stream_buf = NULL; if (NULL == sess || \ NULL == strm || \ (last != 0 && last != 1)) { rc = QZ_PARAMS; if (NULL != strm) { strm->in_sz = 0; strm->out_sz = 0; } goto end; } if (NULL == strm->in || \ NULL == strm->out) { rc = QZ_PARAMS; strm->in_sz = 0; strm->out_sz = 0; goto end; } if (NULL == strm->opaque) { rc = initStream(sess, strm); if (QZ_OK != rc) { goto done; } } stream_buf = (QzStreamBuf_T *) strm->opaque; QZ_INFO("Decompress Stream Start...\n"); while (strm->pending_out > 0) { copied_output = copyStreamOutput(strm, strm->out + produced); produced += copied_output; if (0 == copied_output) { rc = QZ_OK; if (strm->pending_in > 0) { /* We need to handle all the input that has left pending in the input buffer next time we are called. * Otherwise we'd append additional bits to the pending data, violate the buffer's boundary and * corrupt the memory behind the boundary. */ stream_buf->flush_more = 1; } QZ_INFO("No space for pending output...\n"); goto done; } QZ_INFO("Copy output %u bytes\n", copied_output); } while (0 == strm->pending_out) { if (1 == copy_more && stream_buf->flush_more != 1) { copied_input_last = copied_input; copied_input += copyStreamInput(strm, strm->in + consumed); if (strm->pending_in < stream_buf->buf_len && last != 1) { rc = QZ_OK; QZ_INFO("Batch more input data...\n"); goto done; } else { copy_more = 0; } } if (stream_buf->flush_more == 1) { /* We need to flush all the input that has left pending in the input buffer since the previous call to this function. * Otherwise we'd append additional bits to the pending data, violate the buffer's boundary and * corrupt the memory behind the boundary. */ stream_buf->flush_more = 0; inbuf_offset = stream_buf->in_offset; } input_len = strm->pending_in; output_len = stream_buf->buf_len; QZ_DEBUG("Before Call qzDecompress input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); rc = qzDecompress(sess, stream_buf->in_buf + inbuf_offset, &input_len, stream_buf->out_buf, &output_len); QZ_DEBUG("Return code = %d\n", rc); if (QZ_OK != rc && QZ_BUF_ERROR != rc) { copied_input = copied_input_last; goto done; } inbuf_offset += input_len; stream_buf->in_offset = inbuf_offset; consumed = copied_input; strm->pending_in -= input_len; strm->pending_out = output_len; copied_output = copyStreamOutput(strm, strm->out + produced); produced += copied_output; QZ_DEBUG("Copy output %u bytes\n", copied_output); QZ_DEBUG("After Call qzDecompress input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); if (QZ_BUF_ERROR == rc) { if (0 == input_len) { QZ_ERROR("Error in qzDecompressStream, stream buf size = %u\n", stream_buf->buf_len); copied_input = copied_input_last; rc = QZ_FAIL; goto done; } else { QZ_INFO("Recoverable buffer error occurs... \n"); rc = QZ_OK; } } if (0 == strm->pending_in) { copy_more = 1; inbuf_offset = 0; } if (0 == strm->pending_in && 0 == strm->in_sz) { rc = QZ_OK; goto done; } } done: strm->in_sz = copied_input; strm->out_sz = produced; QZ_DEBUG("Exit Decompress Stream input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); end: return rc; } int qzEndStream(QzSession_T *sess, QzStream_T *strm) { int rc = QZ_FAIL; QzStreamBuf_T *stream_buf = NULL; if (NULL == sess || \ NULL == strm) { rc = QZ_PARAMS; goto exit; } if (NULL == strm->opaque) { rc = QZ_OK; goto done; } stream_buf = (QzStreamBuf_T *)strm->opaque; streamBufferFree(stream_buf->out_buf); streamBufferFree(stream_buf->in_buf); free(stream_buf); strm->opaque = NULL; rc = QZ_OK; done: strm->pending_in = 0; strm->pending_out = 0; strm->in_sz = 0; strm->out_sz = 0; exit: return rc; } QATzip-1.3.1/src/qatzip_sw.c000077500000000000000000001015451500263377000156540ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" #define GZIP_WRAPPER 16 extern processData_T g_process; static const QzExtraField_T g_extra_field = { .st1 = 'Q', .st2 = 'Z', .x2_len = (uint16_t)sizeof(g_extra_field.qz_e), .qz_e.src_sz = 0, .qz_e.dest_sz = 0, }; static void gen_qatzip_hdr(gz_header *hdr) { qzMemSet(hdr, 0, sizeof(gz_header)); hdr->extra = (Bytef *)&g_extra_field; hdr->extra_len = (uInt)sizeof(g_extra_field); hdr->os = 255; } int qzDeflateSWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { int ret; z_stream *stream = NULL; int flush_flag; int last_loop_in; int last_loop_out; int current_loop_in; int current_loop_out; gz_header hdr; unsigned int left_input_sz = *src_len; unsigned int left_output_sz = *dest_len; unsigned int send_sz; unsigned int total_in = 0, total_out = 0; QzSess_T *qz_sess = NULL; int windows_bits = 0; int comp_level = Z_DEFAULT_COMPRESSION; DataFormatInternal_T data_fmt = DATA_FORMAT_DEFAULT; unsigned int chunk_sz = QZ_HW_BUFF_SZ; QzGzH_T *qz_hdr = NULL; Qz4BH_T *qz4B_header = NULL; *src_len = 0; *dest_len = 0; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; qz_sess->force_sw = 1; comp_level = qz_sess->sess_params.comp_lvl; data_fmt = qz_sess->sess_params.data_fmt; chunk_sz = qz_sess->sess_params.hw_buff_sz; stream = qz_sess->deflate_strm; if (DeflateNull == qz_sess->deflate_stat) { if (NULL == stream) { stream = calloc(1, sizeof(z_stream)); if (NULL == stream) { return QZ_FAIL; } qz_sess->deflate_strm = stream; } stream->zalloc = (alloc_func)0; stream->zfree = (free_func)0; stream->opaque = (voidpf)0; stream->total_in = 0; stream->total_out = 0; switch (data_fmt) { case DEFLATE_4B: case DEFLATE_RAW: windows_bits = -MAX_WBITS; break; case DEFLATE_ZLIB: windows_bits = MAX_WBITS; break; case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: default: windows_bits = MAX_WBITS + GZIP_WRAPPER; break; } /*Gzip header*/ if (Z_OK != deflateInit2(stream, comp_level, Z_DEFLATED, windows_bits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) { qz_sess->deflate_stat = DeflateNull; return QZ_FAIL; } qz_sess->deflate_stat = DeflateInited; if (DEFLATE_GZIP_EXT == data_fmt) { gen_qatzip_hdr(&hdr); if (Z_OK != deflateSetHeader(stream, &hdr)) { qz_sess->deflate_stat = DeflateNull; stream->total_in = 0; stream->total_out = 0; return QZ_FAIL; } qz_hdr = (QzGzH_T *)dest; } else if (DEFLATE_4B == data_fmt) { /* Need to reserve 4 bytes to fill the compressed length. */ qz4B_header = (Qz4BH_T *)dest; dest = dest + sizeof(Qz4BH_T); } } #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), COMPRESSION, SW); #endif do { send_sz = left_input_sz > chunk_sz ? chunk_sz : left_input_sz; left_input_sz -= send_sz; if (0 == left_input_sz && 1 == last) { flush_flag = Z_FINISH; } else { flush_flag = Z_FULL_FLUSH; } stream->next_in = (z_const Bytef *)src + total_in; stream->avail_in = send_sz; stream->next_out = (Bytef *)dest + total_out; stream->avail_out = left_output_sz; last_loop_in = GET_LOWER_32BITS(stream->total_in); last_loop_out = GET_LOWER_32BITS(stream->total_out); ret = deflate(stream, flush_flag); if ((Z_STREAM_END != ret && Z_FINISH == flush_flag) || (Z_OK != ret && Z_FULL_FLUSH == flush_flag)) { QZ_ERROR("ERR: deflate failed with return code: %d flush_flag: %d\n", ret, flush_flag); stream->total_in = 0; stream->total_out = 0; qz_sess->deflate_stat = DeflateNull; return QZ_FAIL; } current_loop_in = GET_LOWER_32BITS(stream->total_in) - last_loop_in; current_loop_out = GET_LOWER_32BITS(stream->total_out) - last_loop_out; left_output_sz -= current_loop_out; total_out += current_loop_out; total_in += current_loop_in; *src_len = total_in; *dest_len = total_out; if (NULL != qz_sess->crc32) { if (DEFLATE_RAW == data_fmt) { *qz_sess->crc32 = crc32(*qz_sess->crc32, src + total_in - current_loop_in, current_loop_in); } else { if (0 == *qz_sess->crc32) { *qz_sess->crc32 = stream->adler; } else { *qz_sess->crc32 = crc32_combine(*qz_sess->crc32, stream->adler, *src_len); } } } } while (left_input_sz); if (1 == last) { /* * When data_fmt is DEFLATE_GZIP_EXT, * we should fill src_sz & dest_sz in gzipext header field. */ if (DEFLATE_GZIP_EXT == data_fmt && qz_hdr) { qz_hdr->extra.qz_e.src_sz = stream->total_in; qz_hdr->extra.qz_e.dest_sz = stream->total_out - outputHeaderSz(data_fmt) - outputFooterSz(data_fmt); } else if (DEFLATE_4B == data_fmt && qz4B_header) { qz4B_header->blk_size = stream->total_out; *dest_len = *dest_len + sizeof(Qz4BH_T); } ret = deflateEnd(stream); stream->total_in = 0; stream->total_out = 0; qz_sess->deflate_stat = DeflateNull; if (Z_OK != ret) { return QZ_FAIL; } } return QZ_OK; } int qzDeflateSWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { z_stream *stream = NULL; int ret = QZ_OK; int zlib_ret = Z_OK; DataFormatInternal_T data_fmt; int windows_bits = 0; unsigned int total_in; unsigned int total_out; unsigned int qz4B_header_len = 0; QzSess_T *qz_sess = (QzSess_T *) sess->internal; qz_sess->force_sw = 1; stream = qz_sess->inflate_strm; data_fmt = qz_sess->sess_params.data_fmt; if (NULL == stream) { stream = calloc(1, sizeof(z_stream)); if (NULL == stream) { *src_len = 0; *dest_len = 0; return QZ_FAIL; } stream->zalloc = (alloc_func)0; stream->zfree = (free_func)0; stream->opaque = (voidpf)0; stream->total_in = 0; stream->total_out = 0; qz_sess->inflate_strm = stream; } stream->next_in = (z_const Bytef *)src; stream->avail_in = *src_len; stream->next_out = (Bytef *)dest; stream->avail_out = *dest_len; *src_len = 0; *dest_len = 0; QZ_INFO("decomp_sw data_fmt: %d\n", data_fmt); switch (data_fmt) { case DEFLATE_4B: case DEFLATE_RAW: windows_bits = -MAX_WBITS; break; case DEFLATE_ZLIB: windows_bits = MAX_WBITS; break; case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: default: windows_bits = MAX_WBITS + GZIP_WRAPPER; break; } if (InflateNull == qz_sess->inflate_stat) { if (DEFLATE_4B == data_fmt) { /* For DEFLATE_4B, we need to skip the header. */ stream->next_in = (z_const Bytef *)stream->next_in + sizeof(Qz4BH_T); stream->avail_in = stream->avail_in - sizeof(Qz4BH_T); qz4B_header_len = sizeof(Qz4BH_T); } ret = inflateInit2(stream, windows_bits); if (Z_OK != ret) { ret = QZ_FAIL; goto done; } QZ_INFO("\n****** inflate init done with win_bits: %d *****\n", windows_bits); qz_sess->inflate_stat = InflateInited; stream->total_in = 0; total_in = 0; stream->total_out = 0; total_out = 0; } else { total_in = GET_LOWER_32BITS(stream->total_in); total_out = GET_LOWER_32BITS(stream->total_out); } zlib_ret = inflate(stream, Z_SYNC_FLUSH); setDeflateEndOfStream(qz_sess, 0); switch (zlib_ret) { case Z_OK: if (QZ_LOW_DEST_MEM == sess->thd_sess_stat) { QZ_INFO("ERR: inflate failed with Z_DATA_ERROR\n"); ret = QZ_DATA_ERROR; qz_sess->inflate_stat = InflateError; goto done; } ret = QZ_OK; qz_sess->inflate_stat = InflateOK; break; case Z_STREAM_END: ret = QZ_OK; qz_sess->inflate_stat = InflateEnd; setDeflateEndOfStream(qz_sess, 1); break; case Z_DATA_ERROR: QZ_INFO("ERR: inflate failed with Z_DATA_ERROR\n"); ret = QZ_DATA_ERROR; qz_sess->inflate_stat = InflateError; goto done; default: QZ_INFO("ERR: inflate failed with error code %d\n", ret); ret = QZ_FAIL; qz_sess->inflate_stat = InflateError; goto done; } *dest_len = GET_LOWER_32BITS(stream->total_out - total_out); /* for Deflate_4B, we need to add the length of Deflate 4B header. */ *src_len = GET_LOWER_32BITS(stream->total_in - total_in + qz4B_header_len); done: QZ_DEBUG("Exit qzSWDecompress total_in: %lu total_out: %lu " "avail_in: %u avail_out: %u msg: %s " "src_len: %u dest_len: %u\n", stream->total_in, stream->total_out, stream->avail_in, stream->avail_out, stream->msg, *src_len, *dest_len); if (zlib_ret == Z_STREAM_END || QZ_LOW_DEST_MEM == sess->thd_sess_stat) { if (Z_OK != inflateEnd(stream)) { QZ_INFO("inflateEnd failed.\n"); ret = QZ_FAIL; } qz_sess->inflate_stat = InflateNull; QZ_INFO("\n****** inflate end done *****\n"); } return ret; } int qzSWDecompressMultiGzip(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { int ret = QZ_OK; unsigned int total_in = 0; unsigned int total_out = 0; const unsigned int input_len = *src_len; const unsigned int output_len = *dest_len; unsigned int cur_input_len = input_len; unsigned int cur_output_len = output_len; QzSess_T *qz_sess = (QzSess_T *) sess->internal; #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), DECOMPRESSION, SW); #endif QZ_INFO("Start qzSWDecompressMultiGzip: src_len %u dest_len %u\n", *src_len, *dest_len); *src_len = 0; *dest_len = 0; while (total_in < input_len && total_out < output_len) { ret = qzDeflateSWDecompress(sess, src + total_in, &cur_input_len, dest + total_out, &cur_output_len); if (ret != QZ_OK) { goto out; } total_in += cur_input_len; total_out += cur_output_len; cur_input_len = input_len - total_in; cur_output_len = output_len - total_out; *src_len = total_in; *dest_len = total_out; if (getDeflateEndOfStream(qz_sess) == 1 && qz_sess->sess_params.stop_decompression_stream_end == 1) { goto out; } } out: QZ_INFO("Exit qzSWDecompressMultiGzip: src_len %u dest_len %u\n", *src_len, *dest_len); return ret; } int qzLZ4SWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { size_t total_out = 0; assert(sess); assert(sess->internal); QzSess_T *qz_sess = (QzSess_T *)sess->internal; LZ4F_preferences_t preferences = {0}; preferences.frameInfo.contentChecksumFlag = 1; preferences.frameInfo.contentSize = *src_len; preferences.autoFlush = 1; preferences.compressionLevel = qz_sess->sess_params.comp_lvl; total_out = LZ4F_compressFrame(dest, *dest_len, src, *src_len, &preferences); if (LZ4F_isError(total_out)) { QZ_ERROR("LZ4F_compressUpdate error: %s\n", LZ4F_getErrorName(total_out)); goto lz4_compress_fail; } *dest_len = total_out; QZ_INFO("Exit qzLZ4SWCompress: src_len %u dest_len %u\n", *src_len, *dest_len); return QZ_OK; lz4_compress_fail: *src_len = 0; *dest_len = 0; return QZ_FAIL; } int qzLZ4SWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { size_t in_sz = 0; size_t out_sz = 0; size_t ret = QZ_OK; QzSess_T *qz_sess = NULL; QZ_INFO("Enter qzLZ4SWDecompress: src_len %u dest_len %u\n", *src_len, *dest_len); qz_sess = (QzSess_T *) sess->internal; if (qz_sess->dctx == NULL) { ret = LZ4F_createDecompressionContext(&(qz_sess->dctx), LZ4F_VERSION); if (LZ4F_isError(ret)) { QZ_ERROR("LZ4F_createDecompressionContext error: %s\n", LZ4F_getErrorName(ret)); goto lz4_decompress_fail; } } in_sz = *src_len; out_sz = *dest_len; ret = LZ4F_decompress(qz_sess->dctx, dest, (size_t *)&out_sz, src, (size_t *)&in_sz, NULL); if (LZ4F_isError(ret)) { QZ_ERROR("LZ4F_decompress error: %s\n", LZ4F_getErrorName(ret)); goto lz4_decompress_fail; } else if (ret == 0) { /* * when ret == 0, it means that a frame be fully decompressed, * we need to free the dctx, not reuse it to decompress another frame. */ LZ4F_freeDecompressionContext(qz_sess->dctx); qz_sess->dctx = NULL; } else { /* * when ret > 0, it means that the compressed data is not a fully frame, * it needs more compressed data to decompress. The remaining compressed data * was stored in dctx. */ QZ_INFO("LZ4F_decompress: incomplete compressed data, need more data\n"); } *src_len = in_sz; *dest_len = out_sz; QZ_INFO("Exit qzLZ4SWDecompress: src_len %u dest_len %u\n", *src_len, *dest_len); return QZ_OK; lz4_decompress_fail: if (qz_sess->dctx != NULL) { LZ4F_freeDecompressionContext(qz_sess->dctx); qz_sess->dctx = NULL; } *src_len = 0; *dest_len = 0; return QZ_FAIL; } int qzSWDecompressMultiLZ4(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { int ret = QZ_OK; unsigned int total_in = 0; unsigned int total_out = 0; const unsigned int input_len = *src_len; const unsigned int output_len = *dest_len; unsigned int cur_input_len = input_len; unsigned int cur_output_len = output_len; #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), DECOMPRESSION, SW); #endif QZ_INFO("Start qzSWDecompressMultiLz4: src_len %u dest_len %u\n", *src_len, *dest_len); *src_len = 0; *dest_len = 0; while (total_in < input_len && total_out < output_len) { ret = qzLZ4SWDecompress(sess, src + total_in, &cur_input_len, dest + total_out, &cur_output_len); if (ret != QZ_OK) { goto out; } total_in += cur_input_len; total_out += cur_output_len; cur_input_len = input_len - total_in; cur_output_len = output_len - total_out; *src_len = total_in; *dest_len = total_out; } out: QZ_INFO("Exit qzSWDecompressMultiLz4: src_len %u dest_len %u\n", *src_len, *dest_len); return ret; } /* The software failover function for compression request */ int qzSWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { #ifdef ENABLE_TESTLOG QZ_TESTLOG(2, 0, "SW_FALLBACK", "sw fallback happend!"); #endif int ret = QZ_FAIL; DataFormatInternal_T data_fmt; QzSess_T *qz_sess = NULL; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: case DEFLATE_ZLIB: ret = qzDeflateSWCompress(sess, src, src_len, dest, dest_len, last); break; case LZ4_FH: ret = qzLZ4SWCompress(sess, src, src_len, dest, dest_len, last); break; default: QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); *src_len = 0; *dest_len = 0; ret = QZ_FAIL; break; } return ret; } /* The software failover function for decompression request */ int qzSWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { #ifdef ENABLE_TESTLOG QZ_TESTLOG(2, 0, "SW_FALLBACK", "sw fallback happend!"); #endif int ret = QZ_FAIL; DataFormatInternal_T data_fmt; QzSess_T *qz_sess = NULL; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: case DEFLATE_ZLIB: ret = qzDeflateSWDecompress(sess, src, src_len, dest, dest_len); break; case LZ4_FH: ret = qzLZ4SWDecompress(sess, src, src_len, dest, dest_len); break; default: QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); *src_len = 0; *dest_len = 0; ret = QZ_FAIL; break; } return ret; } int qzSWDecompressMulti(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { #ifdef ENABLE_TESTLOG QZ_TESTLOG(2, 0, "SW_FALLBACK", "sw fallback happend!"); #endif int ret = QZ_FAIL; DataFormatInternal_T data_fmt; QzSess_T *qz_sess = NULL; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: case DEFLATE_ZLIB: ret = qzSWDecompressMultiGzip(sess, src, src_len, dest, dest_len); break; case LZ4_FH: ret = qzSWDecompressMultiLZ4(sess, src, src_len, dest, dest_len); break; default: QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); *src_len = 0; *dest_len = 0; ret = QZ_FAIL; break; } return ret; } int compInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned int src_send_sz) { int rc; unsigned int dest_receive_sz = DEST_SZ(src_send_sz); QzSess_T *qz_sess = (QzSess_T *)sess->internal; if (!qz_sess->sess_params.sw_backup) { QZ_ERROR("The instance %d heartbeat down, Don't enable sw fallback, compressIn error!\n", i); return QZ_FAIL; } if (qz_sess->single_thread) { QZ_INFO("The instance %d fallback to sw, single_thread, back to API level fallback!\n", i); return QZ_FAIL; } if (qz_sess->stop_submitting) { QZ_INFO("compInSWFallback stop submit\n"); return QZ_FAIL; } if (qz_sess->seq != qz_sess->seq_in) { return QZ_WAIT_SW_PENDING; } QZ_DEBUG("SW CompIn Sending %u bytes, seq = %ld, instance = %d\n", src_send_sz, qz_sess->seq, i); /* sw fallback here */ rc = qzSWCompress(sess, src_ptr, &src_send_sz, qz_sess->next_dest, &dest_receive_sz, qz_sess->last); QZ_DEBUG("SW CompIn src_ptr %p, dst_ptr %p, Sending %u bytes, seq = %ld\n", src_ptr, qz_sess->next_dest, src_send_sz, qz_sess->seq); if (unlikely(QZ_OK != rc)) { QZ_ERROR("SW CompIn fallback failure! compress error!\n"); return QZ_FAIL; } /* For SW compress, have to update ComputeOut status first */ qz_sess->next_dest += dest_receive_sz; qz_sess->qz_in_len += src_send_sz; qz_sess->qz_out_len += dest_receive_sz; qz_sess->seq_in++; qz_sess->processed++; return QZ_OK; } int compOutSWFallback(int i, int j, QzSession_T *sess, long *dest_avail_len) { int rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; unsigned int src_send_sz = g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes; /* sw dest buffer is align with the inst hw buffer size */ unsigned int dest_receive_sz = outputHeaderSz(qz_sess->sess_params.data_fmt) + g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes; unsigned char *src_ptr = g_process.qz_inst[i].src_buffers[j]->pBuffers->pData; unsigned char *dest_ptr = g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData; if (!qz_sess->sess_params.sw_backup) { QZ_ERROR("The instance %d heartbeat down, Don't enable sw fallback, compressOut error!\n", i); return QZ_FAIL; } QZ_DEBUG("The request get dummy emty respond, offload to software!\n"); QZ_DEBUG("SW CompOut src_ptr %p, dst_ptr %p, Sending %u bytes, seq = %ld\n", src_ptr, dest_ptr, src_send_sz, g_process.qz_inst[i].stream[j].seq); rc = qzSWCompress(sess, src_ptr, &src_send_sz, dest_ptr, &dest_receive_sz, qz_sess->last); if (QZ_OK != rc) { QZ_ERROR("SW CompOut fallback failure! compress error!\n"); return QZ_FAIL; } rc = compOutCheckDestLen(i, j, sess, dest_avail_len, dest_receive_sz); if (QZ_OK != rc) { return rc; } /* Update qz_sess info and clean dest buffer */ compOutValidDestBufferCleanUp(i, j, qz_sess, dest_receive_sz); qz_sess->next_dest += dest_receive_sz; qz_sess->qz_in_len += src_send_sz; qz_sess->qz_out_len += dest_receive_sz; return rc; } int decompInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len) { int rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; if (!qz_sess->sess_params.sw_backup) { QZ_ERROR("The instance %d heartbeat down, Don't enable sw fallback, decompressIn error!\n", i); sess->thd_sess_stat = QZ_FAIL; return QZ_FAIL; } if (qz_sess->single_thread) { QZ_INFO("The instance %d fallback to sw, single_thread, back to API level fallback!\n", i); sess->thd_sess_stat = QZ_FAIL; return QZ_FAIL; } if (qz_sess->stop_submitting) { QZ_INFO("decompInSWFallback stop submit\n"); return QZ_FAIL; } if (qz_sess->seq != qz_sess->seq_in) { return QZ_WAIT_SW_PENDING; } QZ_DEBUG("SW DecompIn src_ptr %p, dest_ptr %p, Sending %u bytes, seq = %ld, instance = %d\n", src_ptr, dest_ptr, *tmp_src_avail_len, qz_sess->seq, i); rc = qzSWDecompress(sess, src_ptr, tmp_src_avail_len, dest_ptr, tmp_dest_avail_len); if (unlikely(QZ_OK != rc)) { QZ_ERROR("SW deCompIn fallback failure! decompress error!\n"); sess->thd_sess_stat = QZ_FAIL; return QZ_FAIL; } /* For compressIn fallback, need to update seq_in first */ qz_sess->seq_in++; qz_sess->processed++; qz_sess->qz_in_len += *tmp_src_avail_len; qz_sess->qz_out_len += *tmp_dest_avail_len; qz_sess->next_dest += *tmp_dest_avail_len; return QZ_OK; } int decompOutSWFallback(int i, int j, QzSession_T *sess, unsigned int *dest_avail_len) { int rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; unsigned int src_send_sz = g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes; unsigned int dest_receive_sz = g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes; /* pinned buffer ptr already strip header, need retrieve. * use original src_ptr and consumed len to get src_ptr for this request. */ unsigned char *src_ptr = qz_sess->src + qz_sess->qz_in_len; src_send_sz += (outputHeaderSz(data_fmt) + outputFooterSz(data_fmt)) ; if (!qz_sess->sess_params.sw_backup) { QZ_ERROR("The instance %d heartbeat down, Don't enable sw fallback, decompressOut error!\n", i); return QZ_FAIL; } QZ_DEBUG("The request get dummy empty respond, offload to software!\n"); QZ_DEBUG("SW DecompOut src_ptr %p, dest_ptr %p, Sending %u bytes, receive %u bytes, seq = %ld\n", src_ptr, qz_sess->next_dest, src_send_sz, dest_receive_sz, g_process.qz_inst[i].stream[j].seq); rc = qzSWDecompress(sess, src_ptr, &src_send_sz, qz_sess->next_dest, &dest_receive_sz); if (QZ_OK != rc) { QZ_ERROR("SW deCompOut fallback failure! decompress error!\n"); return QZ_FAIL; } /* update qz_sess info, Don't need clean dest buffer */ decompOutErrorDestBufferCleanUp(i, j); qz_sess->next_dest += dest_receive_sz; qz_sess->qz_in_len += src_send_sz; qz_sess->qz_out_len += dest_receive_sz; *dest_avail_len -= dest_receive_sz; return QZ_OK; } /* This func is the wrapper func of compression sw fallback * but with latency measure and metrixUpdate, first it would * update sw latency matrix with this time latency value. * Then update HW latency matrix with zero, it's for regression * back to HW, in case, qatzip would always stuck on Lsm SW * fallback */ int compLSMFallback(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { int rc; unsigned long start_time_stamp, end_time_stamp; QzSess_T *qz_sess = (QzSess_T *)sess->internal; start_time_stamp = rdtsc(); /* sw fallback here */ rc = qzSWCompress(sess, src, src_len, dest, dest_len, last); if (unlikely(QZ_OK != rc)) { QZ_ERROR("SW LSM fallback failure! compress error!\n"); return QZ_FAIL; } end_time_stamp = rdtsc(); /* The reduction for sw latency here is for offloading more request to * SW when QAT devcie is busy, maybe we could optimize this value in * the future. */ metrixUpdate(&qz_sess->SWT, (end_time_stamp - start_time_stamp) >> 2); metrixUpdate(&qz_sess->RRT, 0); metrixUpdate(&qz_sess->PPT, 0); QZ_DEBUG("LSM mode, insert SWT %ld\n", (end_time_stamp - start_time_stamp)); return QZ_OK; } /* This func is the wrapper func of decompression sw fallback * but with latency measure and metrixUpdate, first it would * update sw latency matrix with this time latency value. * Then update HW latency matrix with zero, it's for regression * back to HW, in case, qatzip would always stuck on Lsm SW * fallback */ int decompLSMFallback(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { int rc; unsigned long start_time_stamp, end_time_stamp; QzSess_T *qz_sess = (QzSess_T *)sess->internal; start_time_stamp = rdtsc(); /* sw fallback here */ rc = qzSWDecompressMulti(sess, src, src_len, dest, dest_len); if (unlikely(QZ_OK != rc)) { QZ_ERROR("SW LSM fallback failure! decompress error!\n"); return QZ_FAIL; } end_time_stamp = rdtsc(); /* The reduction for sw latency here is for offloading more request to * SW when QAT devcie is busy, maybe we could optimize this value in * the future. */ metrixUpdate(&qz_sess->SWT, (end_time_stamp - start_time_stamp) >> 2); metrixUpdate(&qz_sess->RRT, 0); metrixUpdate(&qz_sess->PPT, 0); QZ_DEBUG("LSM mode, insert SWT %ld\n", (end_time_stamp - start_time_stamp)); return QZ_OK; } int AsyncDecompOutSWFallback(int i, int j, QzSession_T *sess, QzAsyncReq_T *req) { int rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; unsigned int src_send_sz = g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes; unsigned int dest_receive_sz = g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes; /* pinned buffer ptr already strip header, need retrieve. * use original src_ptr and consumed len to get src_ptr for this request. */ const unsigned char *src_ptr = req->src + req->req_in_len; src_send_sz += (outputHeaderSz(data_fmt) + outputFooterSz(data_fmt)) ; if (!qz_sess->sess_params.sw_backup) { QZ_DEBUG("The instance %d heartbeat is failure, Don't enable sw fallback, decompressOut fatal ERROR!\n", i); return QZ_FAIL; } QZ_DEBUG("The request get dummy empty respond, offload to software!\n"); QZ_DEBUG("SW DecompOut src_ptr %p, dest_ptr %p, Sending %u bytes, receive %u bytes, seq = %ld\n", src_ptr, req->dest, src_send_sz, dest_receive_sz, g_process.qz_inst[i].stream[j].seq); rc = qzSWDecompress(sess, src_ptr, &src_send_sz, req->dest, &dest_receive_sz); if (QZ_OK != rc) { QZ_ERROR("SW deCompOut fallback failure! compress fatal ERROR!\n"); return QZ_FAIL; } /* update qz_sess info, Don't need clean dest buffer */ decompOutErrorDestBufferCleanUp(i, j); req->dest += dest_receive_sz; req->req_in_len += src_send_sz; req->req_out_len += dest_receive_sz; req->qzResults->dest_len -= dest_receive_sz; return QZ_OK; } QATzip-1.3.1/src/qatzip_utils.c000066400000000000000000001576541500263377000163740ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include #include "qatzip_internal.h" static QatThread_T g_qat_thread; extern processData_T g_process; #ifdef QATZIP_DEBUG static void doInsertThread(unsigned int th_id, ThreadList_T **thd_list, unsigned int *num_thd, pthread_mutex_t *lock, Serv_T serv_type, Engine_T engine_type) { ThreadList_T *node; ThreadList_T *prev_node; if (0 != pthread_mutex_lock(lock)) { return; } for (prev_node = node = *thd_list; node; node = node->next) { if (node->thread_id == th_id) { break; } prev_node = node; } if (!node) { node = (ThreadList_T *)calloc(1, sizeof(*node)); if (!node) { QZ_ERROR("[ERROR]: alloc memory failed in file(%s) line(%d)\n", __FILE__, __LINE__); goto done; } node->thread_id = th_id; ++*num_thd; if (prev_node) { prev_node->next = node; } else { *thd_list = node; } } if (SW == engine_type) { if (COMPRESSION == serv_type) { ++node->comp_sw_count; } else if (DECOMPRESSION == serv_type) { ++node->decomp_sw_count; } } else if (HW == engine_type) { if (COMPRESSION == serv_type) { ++node->comp_hw_count; } else if (DECOMPRESSION == serv_type) { ++node->decomp_hw_count; } } done: (void)pthread_mutex_unlock(lock); } void insertThread(unsigned int th_id, Serv_T serv_type, Engine_T engine_type) { QatThread_T *th_list = &g_qat_thread; if (COMPRESSION == serv_type) { doInsertThread(th_id, &th_list->comp_th_list, &th_list->num_comp_th, &th_list->comp_lock, serv_type, engine_type); } else if (DECOMPRESSION == serv_type) { doInsertThread(th_id, &th_list->decomp_th_list, &th_list->num_decomp_th, &th_list->decomp_lock, serv_type, engine_type); } } static void doDumpThreadInfo(ThreadList_T *node, unsigned int num_node, Serv_T type) { unsigned int i; char *serv_title; if (num_node > 0) { i = 0; if (COMPRESSION == type) { serv_title = "Compression"; } else { serv_title = "Decompression"; } QZ_INFO("%s num_th %u\n", serv_title, num_node); while (node) { QZ_INFO("th_id: %u comp_hw_count: %u comp_sw_count: %u " "decomp_hw_count: %u decomp_sw_count: %u\n", node->thread_id, node->comp_hw_count, node->comp_sw_count, node->decomp_hw_count, node->decomp_sw_count); i++; node = node->next; if (i == num_node) { break; } } if (node) { QZ_ERROR("[ERROR]: there's node left in the list\n"); } QZ_INFO("\n"); } } void dumpThreadInfo(void) { QatThread_T *th_list = &g_qat_thread; doDumpThreadInfo(th_list->comp_th_list, th_list->num_comp_th, COMPRESSION); doDumpThreadInfo(th_list->decomp_th_list, th_list->num_decomp_th, DECOMPRESSION); } #endif QzLogLevel_T currentLogLevel = LOG_WARNING; QzLogLevel_T qzSetLogLevel(QzLogLevel_T level) { QzLogLevel_T oldLogLevel = currentLogLevel; currentLogLevel = level; return oldLogLevel; } const char *getLogLevelString(QzLogLevel_T level) { switch (level) { case LOG_ERROR: return "Error"; case LOG_WARNING: return "Warning"; case LOG_INFO: return "Info"; case LOG_DEBUG1: return "Debug"; case LOG_DEBUG2: return "Test"; case LOG_DEBUG3: return "Memory"; default: return "UNKNOWN"; } } void logMessage(QzLogLevel_T level, const char *file, int line, const char *format, ...) { if (level > currentLogLevel) return; time_t now = time(NULL); struct tm *tm_info = localtime(&now); char time_buffer[26]; strftime(time_buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info); FILE *output = stderr; switch (level) { case LOG_NONE: output = stdout; break; case LOG_ERROR: case LOG_WARNING: output = stderr; fprintf(output, "[%s] [%s] (%s:%d): ", getLogLevelString(level), time_buffer, file, line); break; case LOG_INFO: case LOG_DEBUG1: case LOG_DEBUG2: case LOG_DEBUG3: output = stdout; fprintf(output, "[%s]: ", getLogLevelString(level)); break; default: break; } va_list args; va_start(args, format); vfprintf(output, format, args); va_end(args); } void initDebugLock(void) { pthread_mutex_init(&g_qat_thread.comp_lock, NULL); pthread_mutex_init(&g_qat_thread.decomp_lock, NULL); } /* LSM TODO: * expose global variabled (mention variable name) to API Level to tune * LSM Mode Performance lsm_sw_met_seed is the emprical mean of sw Latence */ unsigned int lsm_met_len_shift = 6; unsigned int lsm_sw_met_seed = 1000; static int qzSetupDcSessionData(CpaDcSessionSetupData *session_setup_data, QzSessionParamsInternal_T *params) { assert(session_setup_data); assert(params); session_setup_data->compLevel = params->comp_lvl; switch (params->data_fmt) { case DEFLATE_4B: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_RAW: case DEFLATE_ZLIB: session_setup_data->compType = CPA_DC_DEFLATE; if (params->data_fmt == DEFLATE_ZLIB) { session_setup_data->checksum = CPA_DC_ADLER32; } else { session_setup_data->checksum = CPA_DC_CRC32; } session_setup_data->autoSelectBestHuffmanTree = CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS; if (params->huffman_hdr == QZ_DYNAMIC_HDR) { session_setup_data->huffType = CPA_DC_HT_FULL_DYNAMIC; } else { session_setup_data->huffType = CPA_DC_HT_STATIC; } break; case LZ4_FH: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) session_setup_data->compType = CPA_DC_LZ4; session_setup_data->checksum = CPA_DC_XXHASH32; session_setup_data->lz4BlockChecksum = 0; session_setup_data->lz4BlockMaxSize = CPA_DC_LZ4_MAX_BLOCK_SIZE_64K; break; #else QZ_ERROR("QAT driver does not support lz4 algorithm\n"); return QZ_UNSUPPORTED_FMT; #endif case LZ4S_BK: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) session_setup_data->compType = CPA_DC_LZ4S; session_setup_data->checksum = CPA_DC_XXHASH32; if (params->lz4s_mini_match == 4) { session_setup_data->minMatch = CPA_DC_MIN_4_BYTE_MATCH; } else { session_setup_data->minMatch = CPA_DC_MIN_3_BYTE_MATCH; } break; #else QZ_ERROR("QAT driver does not support lz4s algorithm\n"); return QZ_UNSUPPORTED_FMT; #endif default: return QZ_UNSUPPORTED_FMT; } switch (params->direction) { case QZ_DIR_COMPRESS: session_setup_data->sessDirection = CPA_DC_DIR_COMPRESS; break; case QZ_DIR_DECOMPRESS: session_setup_data->sessDirection = CPA_DC_DIR_DECOMPRESS; break; default: session_setup_data->sessDirection = CPA_DC_DIR_COMBINED; } session_setup_data->sessState = CPA_DC_STATELESS; #if CPA_DC_API_VERSION_AT_LEAST(3, 1) session_setup_data->windowSize = (Cpa32U)7; #else session_setup_data->deflateWindowSize = (Cpa32U)7; session_setup_data->fileType = CPA_DC_FT_ASCII; #endif return QZ_OK; } int qzSetupSessionInternal(QzSession_T *sess) { int rc; QzSess_T *qz_sess; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *)sess->internal; rc = qzSetupDcSessionData(&qz_sess->session_setup_data, &qz_sess->sess_params); if (rc != QZ_OK) { return rc; } /* LSM setup */ if (qz_sess->sess_params.is_sensitive_mode == true) { metrixReset(&qz_sess->RRT); metrixReset(&qz_sess->PPT); metrixReset(&qz_sess->SWT); qz_sess->SWT.arr_avg = lsm_sw_met_seed; } qz_sess->inst_hint = -1; qz_sess->seq = 0; qz_sess->seq_in = 0; qz_sess->polling_idx = 0; qz_sess->force_sw = 0; qz_sess->inflate_strm = NULL; qz_sess->inflate_stat = InflateNull; qz_sess->deflate_strm = NULL; qz_sess->deflate_stat = DeflateNull; qz_sess->dctx = NULL; if (g_process.qz_init_status != QZ_OK) { /*hw not present*/ if (qz_sess->sess_params.sw_backup == 1) { sess->hw_session_stat = QZ_NO_HW; rc = QZ_OK; } else { sess->hw_session_stat = QZ_NOSW_NO_HW; rc = QZ_NOSW_NO_HW; } } else { sess->hw_session_stat = QZ_OK; rc = QZ_OK; } return rc; } int qzCheckParams(QzSessionParams_T *params) { assert(params); if (params->huffman_hdr > QZ_STATIC_HDR) { QZ_ERROR("Invalid huffman_hdr value\n"); return QZ_PARAMS; } if ((params->comp_lvl < QZ_DEFLATE_COMP_LVL_MINIMUM) || (params->comp_lvl > QZ_DEFLATE_COMP_LVL_MAXIMUM)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } if (params->direction > QZ_DIR_BOTH) { QZ_ERROR("Invalid direction value\n"); return QZ_PARAMS; } if (params->comp_algorithm != QZ_DEFLATE) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->sw_backup > 1) { QZ_ERROR("Invalid sw_backup value\n"); return QZ_PARAMS; } if ((params->hw_buff_sz < QZ_HW_BUFF_MIN_SZ) || (params->hw_buff_sz > QZ_HW_BUFF_MAX_SZ)) { QZ_ERROR("Invalid hw_buff_sz value\n"); return QZ_PARAMS; } if ((params->strm_buff_sz < QZ_STRM_BUFF_MIN_SZ) || (params->strm_buff_sz > QZ_STRM_BUFF_MAX_SZ)) { QZ_ERROR("Invalid strm_buff_sz value\n"); return QZ_PARAMS; } if (params->input_sz_thrshold < QZ_COMP_THRESHOLD_MINIMUM) { QZ_ERROR("Invalid input_sz_thrshold value\n"); return QZ_PARAMS; } if ((params->req_cnt_thrshold < QZ_REQ_THRESHOLD_MINIMUM) || (params->req_cnt_thrshold > QZ_REQ_THRESHOLD_MAXIMUM)) { QZ_ERROR("Invalid req_cnt_thrshold value\n"); return QZ_PARAMS; } if (params->hw_buff_sz & (params->hw_buff_sz - 1)) { QZ_ERROR("Invalid hw_buff_sz value, must be a power of 2k\n"); return QZ_PARAMS; } return QZ_OK; } static int qzCheckParamsCommon(QzSessionParamsCommon_T *params) { assert(params); if (params->direction > QZ_DIR_BOTH) { QZ_ERROR("Invalid direction value\n"); return QZ_PARAMS; } if ((params->comp_algorithm != QZ_DEFLATE) && (params->comp_algorithm != QZ_LZ4) && (params->comp_algorithm != QZ_LZ4s) && (params->comp_algorithm != QZ_ZSTD)) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->sw_backup > 1) { QZ_ERROR("Invalid sw_backup value\n"); return QZ_PARAMS; } if ((params->hw_buff_sz < QZ_HW_BUFF_MIN_SZ) || (params->hw_buff_sz > QZ_HW_BUFF_MAX_SZ)) { QZ_ERROR("Invalid hw_buff_sz value\n"); return QZ_PARAMS; } if ((params->strm_buff_sz < QZ_STRM_BUFF_MIN_SZ) || (params->strm_buff_sz > QZ_STRM_BUFF_MAX_SZ)) { QZ_ERROR("Invalid strm_buff_sz value\n"); return QZ_PARAMS; } if (params->input_sz_thrshold < QZ_COMP_THRESHOLD_MINIMUM) { QZ_ERROR("Invalid input_sz_thrshold value\n"); return QZ_PARAMS; } if ((params->req_cnt_thrshold < QZ_REQ_THRESHOLD_MINIMUM) || (params->req_cnt_thrshold > QZ_REQ_THRESHOLD_MAXIMUM)) { QZ_ERROR("Invalid req_cnt_thrshold value\n"); return QZ_PARAMS; } if (params->hw_buff_sz & (params->hw_buff_sz - 1)) { QZ_ERROR("Invalid hw_buff_sz value, must be a power of 2k\n"); return QZ_PARAMS; } return QZ_OK; } int qzCheckParamsDeflate(QzSessionParamsDeflate_T *params) { assert(params); if (qzCheckParamsCommon(¶ms->common_params) != QZ_OK) { return QZ_PARAMS; } if (params->common_params.comp_algorithm != QZ_DEFLATE) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->huffman_hdr > QZ_STATIC_HDR) { QZ_ERROR("Invalid huffman_hdr value\n"); return QZ_PARAMS; } if ((params->common_params.comp_lvl < QZ_LZS_COMP_LVL_MINIMUM) || (params->common_params.comp_lvl > QZ_DEFLATE_COMP_LVL_MAXIMUM_Gen3)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } if (params->data_fmt > QZ_DEFLATE_RAW) { QZ_ERROR("Invalid data_fmt value\n"); return QZ_PARAMS; } return QZ_OK; } int qzCheckParamsDeflateExt(QzSessionParamsDeflateExt_T *params) { assert(params); if (qzCheckParamsCommon(¶ms->deflate_params.common_params) != QZ_OK) { return QZ_PARAMS; } if (params->deflate_params.common_params.comp_algorithm != QZ_DEFLATE) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->deflate_params.huffman_hdr > QZ_STATIC_HDR) { QZ_ERROR("Invalid huffman_hdr value\n"); return QZ_PARAMS; } if ((params->deflate_params.common_params.comp_lvl < QZ_LZS_COMP_LVL_MINIMUM) || (params->deflate_params.common_params.comp_lvl > QZ_DEFLATE_COMP_LVL_MAXIMUM_Gen3)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } QZ_DEBUG(" data_fmt value = %d , zlib_format = %d ", params->deflate_params.data_fmt, params->zlib_format); if ((params->zlib_format == 0) && (params->deflate_params.data_fmt > QZ_DEFLATE_RAW)) { QZ_ERROR("Invalid data_fmt value\n"); return QZ_PARAMS; } return QZ_OK; /* if (qzCheckParamsDeflate(¶ms->deflate_params) != QZ_OK) { return QZ_PARAMS; } return QZ_OK; */ } int qzCheckParamsLZ4(QzSessionParamsLZ4_T *params) { assert(params); if (qzCheckParamsCommon(¶ms->common_params) != QZ_OK) { return QZ_PARAMS; } if (params->common_params.comp_algorithm != QZ_LZ4) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if ((params->common_params.comp_lvl < QZ_LZS_COMP_LVL_MINIMUM) || (params->common_params.comp_lvl > QZ_LZS_COMP_LVL_MAXIMUM)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } return QZ_OK; } int qzCheckParamsLZ4S(QzSessionParamsLZ4S_T *params) { assert(params); if (qzCheckParamsCommon(¶ms->common_params) != QZ_OK) { return QZ_PARAMS; } if (params->common_params.comp_algorithm != QZ_LZ4s) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->common_params.direction != QZ_DIR_COMPRESS) { QZ_ERROR("LZ4s only support compression direction\n"); return QZ_PARAMS; } if ((params->common_params.comp_lvl < QZ_LZS_COMP_LVL_MINIMUM) || (params->common_params.comp_lvl > QZ_LZS_COMP_LVL_MAXIMUM)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } if ((params->lz4s_mini_match < 3) || (params->lz4s_mini_match > 4)) { QZ_ERROR("Invalid lz4s_mini_match value\n"); return QZ_PARAMS; } return QZ_OK; } static void qzSetParamsCommon(QzSessionParamsCommon_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); internal_params->direction = params->direction; internal_params->comp_lvl = params->comp_lvl; internal_params->comp_algorithm = params->comp_algorithm; internal_params->max_forks = params->max_forks; internal_params->sw_backup = params->sw_backup; internal_params->hw_buff_sz = params->hw_buff_sz; internal_params->strm_buff_sz = params->strm_buff_sz; internal_params->input_sz_thrshold = params->input_sz_thrshold; internal_params->req_cnt_thrshold = params->req_cnt_thrshold; internal_params->wait_cnt_thrshold = params->wait_cnt_thrshold; internal_params->polling_mode = params->polling_mode; internal_params->is_sensitive_mode = params->is_sensitive_mode; } /** * Set session params into internal params */ void qzSetParams(QzSessionParams_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); internal_params->direction = params->direction; internal_params->comp_lvl = params->comp_lvl; internal_params->comp_algorithm = params->comp_algorithm; internal_params->max_forks = params->max_forks; internal_params->sw_backup = params->sw_backup; internal_params->hw_buff_sz = params->hw_buff_sz; internal_params->strm_buff_sz = params->strm_buff_sz; internal_params->input_sz_thrshold = params->input_sz_thrshold; internal_params->req_cnt_thrshold = params->req_cnt_thrshold; internal_params->wait_cnt_thrshold = params->wait_cnt_thrshold; if (params->data_fmt == QZ_DEFLATE_4B) { internal_params->data_fmt = DEFLATE_4B; } else if (params->data_fmt == QZ_DEFLATE_GZIP) { internal_params->data_fmt = DEFLATE_GZIP; } else if (params->data_fmt == QZ_DEFLATE_RAW) { internal_params->data_fmt = DEFLATE_RAW; } else { internal_params->data_fmt = DEFLATE_GZIP_EXT; } internal_params->huffman_hdr = params->huffman_hdr; } /** * Set deflate session params into internal params */ void qzSetParamsDeflate(QzSessionParamsDeflate_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); qzSetParamsCommon(¶ms->common_params, internal_params); if (params->data_fmt == QZ_DEFLATE_4B) { internal_params->data_fmt = DEFLATE_4B; } else if (params->data_fmt == QZ_DEFLATE_GZIP) { internal_params->data_fmt = DEFLATE_GZIP; } else if (params->data_fmt == QZ_DEFLATE_RAW) { internal_params->data_fmt = DEFLATE_RAW; } else { internal_params->data_fmt = DEFLATE_GZIP_EXT; } internal_params->huffman_hdr = params->huffman_hdr; } /** * Set deflate ext session params into internal params */ void qzSetParamsDeflateExt(QzSessionParamsDeflateExt_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); qzSetParamsDeflate(¶ms->deflate_params, internal_params); if (params->zlib_format == 1) { internal_params->data_fmt = DEFLATE_ZLIB; internal_params->zlib_format = 1; } internal_params->stop_decompression_stream_end = params->stop_decompression_stream_end; } void qzSetParamsLZ4(QzSessionParamsLZ4_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); qzSetParamsCommon(¶ms->common_params, internal_params); internal_params->data_fmt = LZ4_FH; } /** * Set LZ4S session params into internal params */ void qzSetParamsLZ4S(QzSessionParamsLZ4S_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); qzSetParamsCommon(¶ms->common_params, internal_params); internal_params->data_fmt = LZ4S_BK; internal_params->qzCallback = params->qzCallback; internal_params->qzCallback_external = params->qzCallback_external; internal_params->lz4s_mini_match = params->lz4s_mini_match; } /** * Get session params from internal params */ void qzGetParams(QzSessionParamsInternal_T *internal_params, QzSessionParams_T *params) { assert(params); assert(internal_params); params->direction = internal_params->direction; params->comp_lvl = internal_params->comp_lvl; params->comp_algorithm = internal_params->comp_algorithm; params->max_forks = internal_params->max_forks; params->sw_backup = internal_params->sw_backup; params->hw_buff_sz = internal_params->hw_buff_sz; params->strm_buff_sz = internal_params->strm_buff_sz; params->input_sz_thrshold = internal_params->input_sz_thrshold; params->req_cnt_thrshold = internal_params->req_cnt_thrshold; params->wait_cnt_thrshold = internal_params->wait_cnt_thrshold; if (internal_params->data_fmt == DEFLATE_4B) { params->data_fmt = QZ_DEFLATE_4B; } else if (internal_params->data_fmt == DEFLATE_GZIP) { params->data_fmt = QZ_DEFLATE_GZIP; } else if (internal_params->data_fmt == DEFLATE_RAW) { params->data_fmt = QZ_DEFLATE_RAW; } else { params->data_fmt = QZ_DEFLATE_GZIP_EXT; } params->huffman_hdr = internal_params->huffman_hdr; } static void qzGetParamsCommon(QzSessionParamsInternal_T *internal_params, QzSessionParamsCommon_T *params) { assert(params); assert(internal_params); params->direction = internal_params->direction; params->comp_lvl = internal_params->comp_lvl; params->comp_algorithm = internal_params->comp_algorithm; params->max_forks = internal_params->max_forks; params->sw_backup = internal_params->sw_backup; params->hw_buff_sz = internal_params->hw_buff_sz; params->strm_buff_sz = internal_params->strm_buff_sz; params->input_sz_thrshold = internal_params->input_sz_thrshold; params->req_cnt_thrshold = internal_params->req_cnt_thrshold; params->wait_cnt_thrshold = internal_params->wait_cnt_thrshold; params->polling_mode = internal_params->polling_mode; params->is_sensitive_mode = internal_params->is_sensitive_mode; } /** * Get deflate session params from internal params */ void qzGetParamsDeflate(QzSessionParamsInternal_T *internal_params, QzSessionParamsDeflate_T *params) { assert(params); assert(internal_params); qzGetParamsCommon(internal_params, ¶ms->common_params); if (internal_params->data_fmt == DEFLATE_4B) { params->data_fmt = QZ_DEFLATE_4B; } else if (internal_params->data_fmt == DEFLATE_GZIP) { params->data_fmt = QZ_DEFLATE_GZIP; } else if (internal_params->data_fmt == DEFLATE_RAW) { params->data_fmt = QZ_DEFLATE_RAW; } else { params->data_fmt = QZ_DEFLATE_GZIP_EXT; } params->huffman_hdr = internal_params->huffman_hdr; params->common_params.comp_algorithm = QZ_DEFLATE; } /** * Get deflateExt session params from internal params */ void qzGetParamsDeflateExt(QzSessionParamsInternal_T *internal_params, QzSessionParamsDeflateExt_T *params) { assert(params); assert(internal_params); qzGetParamsDeflate(internal_params, ¶ms->deflate_params); if (internal_params->data_fmt == DEFLATE_ZLIB) { internal_params->zlib_format = 1; } params->stop_decompression_stream_end = internal_params->stop_decompression_stream_end; params->zlib_format = internal_params->zlib_format; } /** * Get LZ4 session params from internal params */ void qzGetParamsLZ4(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4_T *params) { assert(params); assert(internal_params); qzGetParamsCommon(internal_params, ¶ms->common_params); params->common_params.comp_algorithm = QZ_LZ4; } /** * Get LZ4S session params from internal params */ void qzGetParamsLZ4S(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4S_T *params) { assert(params); assert(internal_params); qzGetParamsCommon(internal_params, ¶ms->common_params); params->common_params.comp_algorithm = QZ_LZ4s; /* LZ4s only support compression. */ params->common_params.direction = QZ_DIR_COMPRESS; params->qzCallback = internal_params->qzCallback; params->qzCallback_external = internal_params->qzCallback_external; params->lz4s_mini_match = internal_params->lz4s_mini_match; } inline unsigned long outputFooterSz(DataFormatInternal_T data_fmt) { unsigned long size = 0; switch (data_fmt) { case DEFLATE_4B: /* fall through */ case DEFLATE_RAW: size = 0; break; case LZ4_FH: size = qzLZ4FooterSz(); break; case LZ4S_BK: size = 0; break; case DEFLATE_ZLIB: size = stdZlibFooterSz(); break; case DEFLATE_GZIP_EXT: default: size = stdGzipFooterSz(); break; } return size; } unsigned long outputHeaderSz(DataFormatInternal_T data_fmt) { unsigned long size = 0; switch (data_fmt) { case DEFLATE_4B: size = qz4BHeaderSz(); break; case DEFLATE_RAW: break; case DEFLATE_GZIP: size = stdGzipHeaderSz(); break; case LZ4_FH: size = qzLZ4HeaderSz(); break; case LZ4S_BK: size = qzLZ4SBlockHeaderSz(); break; case DEFLATE_ZLIB: size = stdZlibHeaderSz(); break; case DEFLATE_GZIP_EXT: default: size = qzGzipHeaderSz(); break; } return size; } void outputHeaderGen(unsigned char *ptr, CpaDcRqResults *res, DataFormatInternal_T data_fmt) { switch (data_fmt) { case DEFLATE_4B: qz4BHeaderGen(ptr, res); break; case DEFLATE_RAW: break; case DEFLATE_GZIP: stdGzipHeaderGen(ptr, res); break; case LZ4_FH: qzLZ4HeaderGen(ptr, res); break; case LZ4S_BK: qzLZ4SBlockHeaderGen(ptr, res); break; case DEFLATE_ZLIB: stdZlibHeaderGen(ptr, res); break; case DEFLATE_GZIP_EXT: default: qzGzipHeaderGen(ptr, res); break; } } inline void outputFooterGen(unsigned char *ptr, CpaDcRqResults *res, DataFormatInternal_T data_fmt) { switch (data_fmt) { case DEFLATE_RAW: break; case LZ4_FH: qzLZ4FooterGen(ptr, res); break; case LZ4S_BK: break; case DEFLATE_ZLIB: qzZlibFooterGen(ptr, res); break; case DEFLATE_GZIP_EXT: default: qzGzipFooterGen(ptr, res); break; } } int isQATProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess) { uint32_t rc = 0; DataFormatInternal_T data_fmt; assert(ptr != NULL); assert(src_len != NULL); assert(qz_sess != NULL); data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_4B: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_ZLIB: rc = isQATDeflateProcessable(ptr, src_len, qz_sess); break; case LZ4_FH: rc = isQATLZ4Processable(ptr, src_len, qz_sess); break; case DEFLATE_RAW: if (*src_len < qz_sess->sess_params.input_sz_thrshold) { QZ_DEBUG("isQATProcessable: deflate_raw src_len is less than input threshhold\n"); rc = 0; } else { rc = 1; } break; default: rc = 0; break; } return rc; } void RestoreDestCpastreamBuffer(int i, int j) { if (g_process.qz_inst[i].stream[j].dest_need_reset) { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } } void RestoreSrcCpastreamBuffer(int i, int j) { if (g_process.qz_inst[i].stream[j].src_need_reset) { g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_src; g_process.qz_inst[i].stream[j].src_need_reset = 0; } } void ResetCpastreamSink(int i, int j) { g_process.qz_inst[i].stream[j].src1 = 0; g_process.qz_inst[i].stream[j].src2 = 0; g_process.qz_inst[i].stream[j].sink1 = 0; g_process.qz_inst[i].stream[j].sink2 = 0; } /* This setup function will always match with buffer clean up function * during error offload flow. */ void compBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned int src_remaining, unsigned int hw_buff_sz, unsigned int src_send_sz) { unsigned int dest_receive_sz = 0; /* Get the qz_sess status of this request */ CpaDcOpData *opData = NULL; CpaBoolean need_cont_mem = g_process.qz_inst[i].instance_info.requiresPhysicallyContiguousMemory; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; /* setup stream buffer */ g_process.qz_inst[i].stream[j].seq = qz_sess->seq; /*update stream seq*/ g_process.qz_inst[i].stream[j].res.checksum = 0; /* setup opData */ opData = &g_process.qz_inst[i].stream[j].opData; opData->inputSkipData.skipMode = CPA_DC_SKIP_DISABLED; opData->outputSkipData.skipMode = CPA_DC_SKIP_DISABLED; opData->compressAndVerify = CPA_TRUE; if (IS_DEFLATE_RAW(data_fmt) && (1 != qz_sess->last || src_remaining > hw_buff_sz)) { opData->flushFlag = CPA_DC_FLUSH_FULL; } else { opData->flushFlag = CPA_DC_FLUSH_FINAL; } QZ_DEBUG("sending seq number %d %d %ld, opData.flushFlag %d\n", i, j, qz_sess->seq, opData->flushFlag); /*Get feed src/dest buffer size*/ dest_receive_sz = *qz_sess->dest_sz > DEST_SZ(src_send_sz) ? DEST_SZ(src_send_sz) - outputHeaderSz(data_fmt) : *qz_sess->dest_sz - outputHeaderSz(data_fmt); QZ_DEBUG("compBufferSetup dest_receive_sz = %d , src_send_sz = %d\n", dest_receive_sz, src_send_sz); g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes = src_send_sz; g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes = dest_receive_sz; if (!need_cont_mem) { QZ_DEBUG("Compress SVM Enabled in doCompressIn\n"); } /*Feed src/dest buffer*/ if ((COMMON_MEM == qzMemFindAddr(src_ptr)) && need_cont_mem) { QZ_MEMCPY(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData, src_ptr, src_send_sz, src_remaining); g_process.qz_inst[i].stream[j].src_need_reset = 0; } else { g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = src_ptr; g_process.qz_inst[i].stream[j].src_need_reset = 1; } /*using zerocopy for the first request while dest buffer is pinned*/ if (unlikely((0 == g_process.qz_inst[i].stream[j].seq) && (!need_cont_mem || qzMemFindAddr(qz_sess->next_dest)))) { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = qz_sess->next_dest + outputHeaderSz(data_fmt); g_process.qz_inst[i].stream[j].dest_need_reset = 1; } } /* when offload request failed after setup the buffer. * use this function to cleanup setup buffer. */ void compInBufferCleanUp(int i, int j) { RestoreDestCpastreamBuffer(i, j); RestoreSrcCpastreamBuffer(i, j); g_process.qz_inst[i].stream[j].src1 -= 1; g_process.qz_inst[i].stream[j].src2 -= 1; } /* when offload request successfully, Using below functions to process * clean up work during compressOut. There are clean up buffer function * in correct process flow or error process flow. */ void compOutSrcBufferCleanUp(int i, int j) { RestoreSrcCpastreamBuffer(i, j); } void compOutErrorDestBufferCleanUp(int i, int j) { RestoreDestCpastreamBuffer(i, j); } void compOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, unsigned int dest_receive_sz) { CpaBoolean need_cont_mem = g_process.qz_inst[i].instance_info.requiresPhysicallyContiguousMemory; if (!need_cont_mem) { QZ_DEBUG("Compress SVM Enabled in doCompressOut\n"); } if (g_process.qz_inst[i].stream[j].dest_need_reset) { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } else { QZ_MEMCPY(qz_sess->next_dest, g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, *qz_sess->dest_sz - qz_sess->qz_out_len, dest_receive_sz); } } /* Process respond means to reset or update sess status * And clean up buffer. */ void compOutProcessedRespond(int i, int j, QzSess_T *qz_sess) { compOutSrcBufferCleanUp(i, j); /* Update the seq_in and process, clean buffer */ assert(g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in); g_process.qz_inst[i].stream[j].sink2++; qz_sess->processed++; qz_sess->seq_in++; } void compOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess) { compOutErrorDestBufferCleanUp(i, j); compOutProcessedRespond(i, j, qz_sess); } int compOutCheckDestLen(int i, int j, QzSession_T *sess, long *dest_avail_len, long dest_receive_sz) { QzSess_T *qz_sess = (QzSess_T *)sess->internal; *dest_avail_len -= dest_receive_sz; if (unlikely(*dest_avail_len < 0)) { QZ_DEBUG("doCompressOut: inadequate output buffer length: %ld, outlen: %ld\n", (long)(*qz_sess->dest_sz), qz_sess->qz_out_len); compOutSkipErrorRespond(i, j, qz_sess); qz_sess->stop_submitting = 1; sess->thd_sess_stat = QZ_BUF_ERROR; return sess->thd_sess_stat; } return QZ_OK; } /*To handle compression expansion*/ void swapDataBuffer(unsigned long i, int j) { Cpa8U *p_tmp_data; p_tmp_data = g_process.qz_inst[i].src_buffers[j]->pBuffers->pData; g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData; g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = p_tmp_data; p_tmp_data = g_process.qz_inst[i].stream[j].orig_src; g_process.qz_inst[i].stream[j].orig_src = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].orig_dest = p_tmp_data; } /* Note: * CheckHeader return value * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Decompress stop, Fatal error * @retval QZ_FORCE_SW Decompress fallback sw * @retval QZ_BUF_ERROR Return to decompress API * @retval QZ_DATA_ERROR Return to decompress API */ int checkHeader(QzSess_T *qz_sess, unsigned char *src, unsigned int src_avail_len, unsigned int dest_avail_len, QzGzH_T *hdr) { unsigned char *src_ptr = src; unsigned int compressed_sz = 0; unsigned int uncompressed_sz = 0; StdGzF_T *qzFooter = NULL; int isEndWithFooter = 0; int ret = 0; QzLZ4H_T *qzLZ4Header = NULL; QzLZ4F_T *lz4Footer = NULL; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; if ((src_avail_len <= 0) || (dest_avail_len <= 0)) { QZ_DEBUG("checkHeader: insufficient %s buffer length\n", (dest_avail_len <= 0) ? "destation" : "source"); return QZ_BUF_ERROR; } if (src_avail_len < outputHeaderSz(data_fmt)) { QZ_DEBUG("checkHeader: incomplete source buffer\n"); return QZ_DATA_ERROR; } if (1 == qz_sess->force_sw) { return QZ_FORCE_SW; } switch (data_fmt) { case DEFLATE_GZIP: qzFooter = (StdGzF_T *)(findStdGzipFooter(src_ptr, src_avail_len)); compressed_sz = (unsigned char *)qzFooter - src_ptr - stdGzipHeaderSz(); uncompressed_sz = qzFooter->i_size; if ((unsigned char *)qzFooter == src_ptr + src_avail_len - stdGzipFooterSz()) { isEndWithFooter = 1; } QZ_DEBUG("checkHeader: DEFLATE_GZIP compressed_sz = %u , uncompressed_sz = %u \n", compressed_sz, uncompressed_sz); break; case DEFLATE_GZIP_EXT: if (QZ_OK != qzGzipHeaderExt(src_ptr, hdr)) { return QZ_FAIL; } compressed_sz = (long)(hdr->extra.qz_e.dest_sz); uncompressed_sz = (long)(hdr->extra.qz_e.src_sz); QZ_DEBUG("checkHeader: DEFLATE_GZIP_EXT compressed_sz = %u , uncompressed_sz = %u \n", compressed_sz, uncompressed_sz); break; case DEFLATE_4B: compressed_sz = *(int *)src_ptr; uncompressed_sz = (qz_sess->sess_params.hw_buff_sz > dest_avail_len) ? dest_avail_len : qz_sess->sess_params.hw_buff_sz; break; case LZ4_FH: ret = qzVerifyLZ4FrameHeader(src_ptr, src_avail_len); if (ret != QZ_OK) { return ret; } lz4Footer = (QzLZ4F_T *)findLZ4Footer(src_ptr, src_avail_len); if (NULL == lz4Footer) { QZ_DEBUG("checkHeader: incomplete source buffer\n"); return QZ_DATA_ERROR; } qzLZ4Header = (QzLZ4H_T *)src_ptr; compressed_sz = (unsigned char *)lz4Footer - src_ptr - qzLZ4HeaderSz(); uncompressed_sz = qzLZ4Header->cnt_size; break; case DEFLATE_RAW: compressed_sz = *(qz_sess->src_sz); uncompressed_sz = *(qz_sess->dest_sz); QZ_DEBUG("checkHeader: DEFLATE_RAW HW Decompression enabled uncompressed_sz is %u \n", uncompressed_sz); break; case DEFLATE_ZLIB: compressed_sz = src_avail_len - stdZlibFooterSz() - stdZlibHeaderSz(); uncompressed_sz = (qz_sess->sess_params.hw_buff_sz > dest_avail_len) ? dest_avail_len : qz_sess->sess_params.hw_buff_sz; QZ_DEBUG("checkHeader DEFLATE_ZLIB: compressed_sz %u uncompressed_sz %u \n", compressed_sz, uncompressed_sz); break; default: return QZ_FAIL; } if ((compressed_sz > DEST_SZ((long)(qz_sess->sess_params.hw_buff_sz))) || (uncompressed_sz > qz_sess->sess_params.hw_buff_sz)) { if (1 == qz_sess->sess_params.sw_backup) { if (DEFLATE_GZIP == data_fmt && 1 == isEndWithFooter) { return QZ_FORCE_SW; } qz_sess->force_sw = 1; return QZ_FORCE_SW; } else { return QZ_FAIL; } } if (compressed_sz + outputHeaderSz(data_fmt) + outputFooterSz(data_fmt) > src_avail_len) { QZ_DEBUG("checkHeader: incomplete source buffer\n"); return QZ_DATA_ERROR; } else if (uncompressed_sz > dest_avail_len) { QZ_DEBUG("checkHeader: insufficient destination buffer length\n"); return QZ_BUF_ERROR; } hdr->extra.qz_e.dest_sz = compressed_sz; hdr->extra.qz_e.src_sz = uncompressed_sz; return QZ_OK; } /* Below Buffer and respond process function is exact same means with * Compression */ void decompBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int src_avail_len, QzGzH_T *hdr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len) { StdGzF_T *qzFooter = NULL; QzLZ4F_T *lz4Footer = NULL; StdZlibF_T *zlibFooter = NULL; unsigned int src_send_sz = 0; unsigned int dest_receive_sz = 0; int src_mem_type = qzMemFindAddr(src_ptr); int dest_mem_type = qzMemFindAddr(dest_ptr); DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; CpaBoolean need_cont_mem = g_process.qz_inst[i].instance_info.requiresPhysicallyContiguousMemory; if (!need_cont_mem) { QZ_DEBUG("Decompress SVM Enabled in doDecompressIn\n"); } g_process.qz_inst[i].stream[j].seq = qz_sess->seq; g_process.qz_inst[i].stream[j].res.checksum = 0; swapDataBuffer(i, j); src_ptr += outputHeaderSz(data_fmt); src_send_sz = hdr->extra.qz_e.dest_sz; dest_receive_sz = hdr->extra.qz_e.src_sz; g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes = src_send_sz; g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes = dest_receive_sz; QZ_DEBUG("doDecompressIn: Sending %u bytes starting at 0x%lx\n", src_send_sz, (unsigned long)src_ptr); QZ_DEBUG("sending seq number %d %d %ld\n", i, j, qz_sess->seq); if (DEFLATE_GZIP_EXT == data_fmt || DEFLATE_GZIP == data_fmt) { qzFooter = (StdGzF_T *)(src_ptr + src_send_sz); g_process.qz_inst[i].stream[j].checksum = qzFooter->crc32; g_process.qz_inst[i].stream[j].orgdatalen = qzFooter->i_size; } else if (LZ4_FH == data_fmt) { lz4Footer = (QzLZ4F_T *)(src_ptr + src_send_sz); //TODO g_process.qz_inst[i].stream[j].checksum = lz4Footer->cnt_cksum; g_process.qz_inst[i].stream[j].orgdatalen = hdr->extra.qz_e.src_sz; } else if (DEFLATE_ZLIB == data_fmt) { zlibFooter = (StdZlibF_T *)(src_ptr + src_send_sz); g_process.qz_inst[i].stream[j].checksum = zlibFooter->adler32; g_process.qz_inst[i].stream[j].orgdatalen = hdr->extra.qz_e.src_sz; //uncompressed size stored in checkheader } /*set up src dest buffers*/ if ((COMMON_MEM == src_mem_type) && need_cont_mem) { QZ_DEBUG("memory copy in doDecompressIn\n"); QZ_MEMCPY(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData, src_ptr, src_avail_len, src_send_sz); g_process.qz_inst[i].stream[j].src_need_reset = 0; } else { g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = src_ptr; g_process.qz_inst[i].stream[j].src_need_reset = 1; } if ((COMMON_MEM == dest_mem_type) && need_cont_mem) { g_process.qz_inst[i].stream[j].dest_need_reset = 0; } else { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = dest_ptr; g_process.qz_inst[i].stream[j].dest_need_reset = 1; } *tmp_src_avail_len = (outputHeaderSz(data_fmt) + src_send_sz + outputFooterSz( data_fmt)); *tmp_dest_avail_len = dest_receive_sz; } void decompInBufferCleanUp(int i, int j) { /*clean stream buffer*/ g_process.qz_inst[i].stream[j].src1 -= 1; g_process.qz_inst[i].stream[j].src2 -= 1; RestoreDestCpastreamBuffer(i, j); RestoreSrcCpastreamBuffer(i, j); swapDataBuffer(i, j); } void decompOutSrcBufferCleanUp(int i, int j) { RestoreSrcCpastreamBuffer(i, j); } void decompOutErrorDestBufferCleanUp(int i, int j) { RestoreDestCpastreamBuffer(i, j); } void decompOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, CpaDcRqResults *resl, unsigned int dest_avail_len) { if (!g_process.qz_inst[i].stream[j].dest_need_reset) { QZ_DEBUG("memory copy in doDecompressOut\n"); QZ_MEMCPY(qz_sess->next_dest, g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, dest_avail_len, resl->produced); } else { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } } void decompOutProcessedRespond(int i, int j, QzSess_T *qz_sess) { decompOutSrcBufferCleanUp(i, j); swapDataBuffer(i, j); /*swap pdata back after decompress*/ assert(g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in); g_process.qz_inst[i].stream[j].sink2++; qz_sess->seq_in++; qz_sess->processed++; } void decompOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess) { decompOutErrorDestBufferCleanUp(i, j); decompOutProcessedRespond(i, j, qz_sess); } int decompOutCheckSum(int i, int j, QzSession_T *sess, CpaDcRqResults *resl) { QzSess_T *qz_sess = (QzSess_T *)sess->internal; //alder32_swap to read the checksum in proper order. if (qz_sess->sess_params.data_fmt == DEFLATE_ZLIB) { if (resl->consumed < g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes) { // we need to refetch trailer from the end of consumed length which is the stream end unsigned char *src_ptr = qz_sess->src + qz_sess->qz_in_len + outputHeaderSz( qz_sess->sess_params.data_fmt); StdZlibF_T *zlibFooter = (StdZlibF_T *)(src_ptr + resl->consumed); g_process.qz_inst[i].stream[j].checksum = zlibFooter->adler32; if (qz_sess->single_thread && (qz_sess->sess_params.stop_decompression_stream_end == 0)) { qz_sess->last_submitted = 0; } QZ_DEBUG("src_ptr %p qz_sess->qz_in_len %lu data checksum %x\n", src_ptr, qz_sess->qz_in_len, g_process.qz_inst[i].stream[j].checksum); } else { qz_sess->last_submitted = 1; } g_process.qz_inst[i].stream[j].checksum = ntohl( g_process.qz_inst[i].stream[j].checksum); QZ_DEBUG("After resp checksum: %x data checksum %x\n", resl->checksum, g_process.qz_inst[i].stream[j].checksum); } if ((qz_sess->sess_params.data_fmt != DEFLATE_4B) && (qz_sess->sess_params.data_fmt != DEFLATE_RAW) && unlikely(resl->checksum != g_process.qz_inst[i].stream[j].checksum || (resl->produced != g_process.qz_inst[i].stream[j].orgdatalen && qz_sess->sess_params.data_fmt != DEFLATE_ZLIB))) { QZ_ERROR("Error in check footer, inst %d, stream %d\n", i, j); QZ_DEBUG("resp checksum: %x data checksum %x data_fmt %d\n", resl->checksum, g_process.qz_inst[i].stream[j].checksum, qz_sess->sess_params.data_fmt); QZ_DEBUG("resp produced :%d data produced: %d\n", resl->produced, g_process.qz_inst[i].stream[j].orgdatalen); decompOutProcessedRespond(i, j, qz_sess); qz_sess->stop_submitting = 1; sess->thd_sess_stat = QZ_DATA_ERROR; return sess->thd_sess_stat; } return QZ_OK; } void setDeflateEndOfStream(QzSess_T *qz_sess, unsigned char val) { QzDeflateExtCustomData_T *data = (QzDeflateExtCustomData_T *) qz_sess->qzdeflateExtData; if (data != NULL) { data->end_of_stream = val; QZ_DEBUG("\tHW setDeflateEndOfStream: setting end_of_stream to %d \n", val); } } unsigned char getDeflateEndOfStream(QzSess_T *qz_sess) { QzDeflateExtCustomData_T *data = (QzDeflateExtCustomData_T *) qz_sess->qzdeflateExtData; if (data != NULL) { QZ_DEBUG("\tHW getDeflateEndOfStream: end_of_stream %d \n", data->end_of_stream); return data->end_of_stream; } return 0; } inline void metrixReset(LatencyMetrix_T *m) { if (m == NULL) { return; } if (m->latency_array == NULL) { m->latency_array = calloc(LSM_MET_DEPTH, sizeof(*(m->latency_array))); } for (int i = 0; i < LSM_MET_DEPTH; i++) { m->latency_array[i] = 0; } m->arr_total = 0; m->arr_avg = 0; m->arr_idx = 0; #ifdef QATZIP_DEBUG m->invoke_counter = 0; m->sess_lat_total = 0; m->sess_lat_avg = 0; #endif } inline void metrixUpdate(LatencyMetrix_T *m, unsigned long val) { if (m == NULL) { return; } m->arr_total -= m->latency_array[m->arr_idx]; m->latency_array[m->arr_idx] = val; m->arr_total += m->latency_array[m->arr_idx]; m->arr_avg = m->arr_total >> lsm_met_len_shift; if (++m->arr_idx >= LSM_MET_DEPTH) { m->arr_idx = 0; } if (val != 0) { m->invoke_counter++; } #ifdef QATZIP_DEBUG m->sess_lat_total += val; if (m->invoke_counter != 0) { m->sess_lat_avg = (m->sess_lat_total) / (m->invoke_counter); } if (val < m->min_latency) { m->min_latency = val; m->min_cnt = m->invoke_counter; } if (val > m->min_latency) { m->max_latency = val; m->max_cnt = m->invoke_counter; } #endif QZ_INFO("The latency for request %lu is %lu, avg is %lu\n", m->arr_idx, val, m->arr_avg); return; } int AsyncCompOutCheckDestLen(int i, int j, QzSession_T *sess, long dest_receive_sz) { QzSess_T *qz_sess = (QzSess_T *)sess->internal; QzAsyncReq_T *req = g_process.qz_inst[i].stream[j].req; long remaining = req->qzResults->dest_len - req->req_out_len - dest_receive_sz; if (unlikely(remaining < 0)) { compOutSkipErrorRespond(i, j, qz_sess); // qz_sess->stop_submitting = 1; sess->thd_sess_stat = QZ_BUF_ERROR; return sess->thd_sess_stat; } return QZ_OK; } void AsyncCompOutValidDestBufferCleanUp(int i, int j, unsigned int dest_receive_sz) { QzAsyncReq_T *req = g_process.qz_inst[i].stream[j].req; CpaBoolean need_cont_mem = g_process.qz_inst[i].instance_info.requiresPhysicallyContiguousMemory; if (!need_cont_mem) { QZ_DEBUG("Compress SVM Enabled in doCompressOut\n"); } if (g_process.qz_inst[i].stream[j].dest_need_reset) { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } else { QZ_MEMCPY(req->dest, g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, req->qzResults->dest_len - req->req_out_len, dest_receive_sz); } } void AsyncDecompOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, CpaDcRqResults *resl, QzAsyncReq_T *req) { if (!g_process.qz_inst[i].stream[j].dest_need_reset) { QZ_DEBUG("memory copy in doDecompressOut\n"); QZ_MEMCPY(req->dest, g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, req->qzResults->dest_len, resl->produced); } else { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } } static int QzRingMoveProdHead(QzRing_T *ring, uint32_t *old_head, uint32_t *new_head, int is_single_producer) { const uint32_t capacity = ring->capacity; int success = 0; uint32_t free_entries = 0; do { *old_head = ring->prod.head; *new_head = *old_head + 1; free_entries = (capacity + ring->cons.tail - *old_head); if (1 > free_entries) return QZ_FAIL; if (is_single_producer) { ring->prod.head = *new_head; success = 1; } else { success = __sync_bool_compare_and_swap((uint32_t *)(uintptr_t)&ring->prod.head, *old_head, *new_head); } } while (success == 0); return QZ_OK; } static void QzRingEnqueueElem(QzRing_T *ring, uint32_t prod_head, void *obj) { prod_head = prod_head % ring->capacity; ring->elems[prod_head] = obj; } static void QzRingUpdatTail(QzRingHeadTail_T *ht, uint32_t old_val, uint32_t new_val, uint32_t single) { if (!single) __sync_bool_compare_and_swap((volatile uint32_t *)(uintptr_t)&ht->tail, old_val, new_val); else ht->tail = new_val; } static int QzRingMoveConsHead(QzRing_T *ring, uint32_t *old_head, uint32_t *new_head, int is_single_consumer) { int success; int entries = 0; do { *old_head = ring->cons.head; entries = (ring->prod.tail - *old_head); if (1 > entries) return QZ_FAIL; *new_head = *old_head + 1; if (is_single_consumer) { ring->cons.head = *new_head; success = 1; } else { success = __sync_bool_compare_and_swap((uint32_t *)(uintptr_t)&ring->cons.head, *old_head, *new_head); } } while (success == 0); return QZ_OK; } static void *QzRingDequeueElem(QzRing_T *ring, uint32_t cons_head) { void *obj; cons_head = cons_head % ring->capacity; obj = ring->elems[cons_head]; ring->elems[cons_head] = NULL; return obj; } QzRing_T *QzRingCreate(int size) { if (size < 1) { QZ_ERROR("Create ring size is incorrect\n"); return NULL; } QzRing_T *ring; ring = (QzRing_T *)calloc(1, sizeof(QzRing_T)); ring->elems = (void *)calloc(size, sizeof(void *)); ring->size = size; ring->mask = size - 1; ring->capacity = size; return ring; } void QzClearRing(QzRing_T *ring) { for (int i = 0; i < ring->size; i++) { if (NULL != ring->elems[i]) { free(ring->elems[i]); ring->elems[i] = NULL; } } ring->mask = ring->size - 1; ring->capacity = ring->size; ring->cons.head = 0; ring->cons.tail = 0; ring->prod.head = 0; ring->prod.tail = 0; } void QzRingFree(QzRing_T *ring) { if (ring != NULL) { if (ring->elems != NULL) { free(ring->elems); } free(ring); } } int QzRingProduceEnQueue(QzRing_T *ring, void *obj, int is_single_producer) { uint32_t prod_head, prod_next; int rc = QZ_OK; rc = QzRingMoveProdHead(ring, &prod_head, &prod_next, is_single_producer); if (QZ_FAIL == rc) return rc; QzRingEnqueueElem(ring, prod_head, obj); QzRingUpdatTail(&ring->prod, prod_head, prod_next, is_single_producer); return rc; } void *QzRingConsumeDequeue(QzRing_T *ring, int is_single_consumer) { uint32_t cons_head = 0; uint32_t cons_next = 0; // uint32_t entries; int rc = 0; void *obj = NULL; rc = QzRingMoveConsHead(ring, &cons_head, &cons_next, is_single_consumer); if (QZ_FAIL == rc) return NULL; obj = QzRingDequeueElem(ring, cons_head); QzRingUpdatTail(&ring->cons, cons_head, cons_next, is_single_consumer); return obj; } QATzip-1.3.1/src/xxhash.c000066400000000000000000001061731500263377000151350ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /*************************************************************************** * xxHash - Fast Hash algorithm * Copyright (C) 2012-2016, Yann Collet * * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You can contact the author at : * - xxHash homepage: http://www.xxhash.com * - xxHash source repository : https://github.com/Cyan4973/xxHash ***************************************************************************/ /* ************************************* * Tuning parameters ***************************************/ /*!XXH_FORCE_MEMORY_ACCESS : * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. * The below switch allow to select different access method for improved performance. * Method 0 (default) : use `memcpy()`. Safe and portable. * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. * It can generate buggy code on targets which do not support unaligned memory accesses. * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) * See http://stackoverflow.com/a/32095106/646947 for details. * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) # define XXH_FORCE_MEMORY_ACCESS 2 # elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ || defined(__ARM_ARCH_7S__) )) # define XXH_FORCE_MEMORY_ACCESS 1 # endif #endif /*!XXH_ACCEPT_NULL_INPUT_POINTER : * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault. * When this macro is enabled, xxHash actively checks input for null pointer. * It it is, result for null input pointers is the same as a null-length input. */ #ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */ # define XXH_ACCEPT_NULL_INPUT_POINTER 0 #endif /*!XXH_FORCE_NATIVE_FORMAT : * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. * Results are therefore identical for little-endian and big-endian CPU. * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. * Should endian-independence be of no importance for your application, you may set the #define below to 1, * to improve speed for Big-endian CPU. * This option has no impact on Little_Endian CPU. */ #ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ # define XXH_FORCE_NATIVE_FORMAT 0 #endif /*!XXH_FORCE_ALIGN_CHECK : * This is a minor performance trick, only useful with lots of very small keys. * It means : check for aligned/unaligned input. * The check costs one initial branch per hash; * set it to 0 when the input is guaranteed to be aligned, * or when alignment doesn't matter for performance. */ #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ # if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) # define XXH_FORCE_ALIGN_CHECK 0 # else # define XXH_FORCE_ALIGN_CHECK 1 # endif #endif /* ************************************* * Includes & Memory related functions ***************************************/ /*! Modify the local functions below should you wish to use some other memory routines * for malloc(), free() */ #include static void *XXH_malloc(size_t s) { return malloc(s); } static void XXH_free(void *p) { free(p); } /*! and for memcpy() */ #include static void *XXH_memcpy(void *dest, const void *src, size_t size) { return memcpy(dest, src, size); } #include /* assert */ #define XXH_STATIC_LINKING_ONLY #include "xxhash.h" /* ************************************* * Compiler Specific Options ***************************************/ #ifdef _MSC_VER /* Visual Studio */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # define FORCE_INLINE static __forceinline #else # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif # else # define FORCE_INLINE static # endif /* __STDC_VERSION__ */ #endif /* ************************************* * Basic Types ***************************************/ #ifndef MEM_MODULE # if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; # else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; # endif #endif #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ static U32 XXH_read32(const void *memPtr) { return *(const U32 *) memPtr; } #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ typedef union { U32 u32; } __attribute__((packed)) unalign; static U32 XXH_read32(const void *ptr) { return ((const unalign *)ptr)->u32; } #else /* portable and safe solution. Generally efficient. * see : http://stackoverflow.com/a/32095106/646947 */ static U32 XXH_read32(const void *memPtr) { U32 val; memcpy(&val, memPtr, sizeof(val)); return val; } #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ /* **************************************** * Compiler-specific Functions and Macros ******************************************/ #define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) /* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ #if defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) # define XXH_rotl64(x,r) _rotl64(x,r) #else # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) # define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) #endif #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap32 _byteswap_ulong #elif XXH_GCC_VERSION >= 403 # define XXH_swap32 __builtin_bswap32 #else static U32 XXH_swap32(U32 x) { return ((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff); } #endif /* ************************************* * Architecture Macros ***************************************/ typedef enum { XXH_bigEndian = 0, XXH_littleEndian = 1 } XXH_endianess; /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ #ifndef XXH_CPU_LITTLE_ENDIAN static int XXH_isLittleEndian(void) { const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } # define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() #endif /* *************************** * Memory reads *****************************/ typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; FORCE_INLINE U32 XXH_readLE32_align(const void *ptr, XXH_endianess endian, XXH_alignment align) { if (align == XXH_unaligned) return endian == XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32( ptr)); else return endian == XXH_littleEndian ? *(const U32 *)ptr : XXH_swap32(* (const U32 *)ptr); } FORCE_INLINE U32 XXH_readLE32(const void *ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); } static U32 XXH_readBE32(const void *ptr) { return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); } /* ************************************* * Macros ***************************************/ #define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } /* use after variable declarations */ XXH_PUBLIC_API unsigned XXH_versionNumber(void) { return XXH_VERSION_NUMBER; } /* ******************************************************************* * 32-bit hash functions *********************************************************************/ static const U32 PRIME32_1 = 2654435761U; static const U32 PRIME32_2 = 2246822519U; static const U32 PRIME32_3 = 3266489917U; static const U32 PRIME32_4 = 668265263U; static const U32 PRIME32_5 = 374761393U; static U32 XXH32_round(U32 seed, U32 input) { seed += input * PRIME32_2; seed = XXH_rotl32(seed, 13); seed *= PRIME32_1; return seed; } /* mix all bits */ static U32 XXH32_avalanche(U32 h32) { h32 ^= h32 >> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return (h32); } #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) static U32 XXH32_finalize(U32 h32, const void *ptr, size_t len, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)ptr; #define PROCESS1 \ h32 += (*p++) * PRIME32_5; \ h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; #define PROCESS4 \ h32 += XXH_get32bits(p) * PRIME32_3; \ p+=4; \ h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; switch (len & 15) { /* or switch(bEnd - p) */ case 12: PROCESS4; /* fallthrough */ case 8: PROCESS4; /* fallthrough */ case 4: PROCESS4; return XXH32_avalanche(h32); case 13: PROCESS4; /* fallthrough */ case 9: PROCESS4; /* fallthrough */ case 5: PROCESS4; PROCESS1; return XXH32_avalanche(h32); case 14: PROCESS4; /* fallthrough */ case 10: PROCESS4; /* fallthrough */ case 6: PROCESS4; PROCESS1; PROCESS1; return XXH32_avalanche(h32); case 15: PROCESS4; /* fallthrough */ case 11: PROCESS4; /* fallthrough */ case 7: PROCESS4; /* fallthrough */ case 3: PROCESS1; /* fallthrough */ case 2: PROCESS1; /* fallthrough */ case 1: PROCESS1; /* fallthrough */ case 0: return XXH32_avalanche(h32); } assert(0); return h32; /* reaching this point is deemed impossible */ } FORCE_INLINE U32 XXH32_endian_align(const void *input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)input; const BYTE *bEnd = p + len; U32 h32; #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) if (p == NULL) { len = 0; bEnd = p = (const BYTE *)(size_t)16; } #endif if (len >= 16) { const BYTE *const limit = bEnd - 15; U32 v1 = seed + PRIME32_1 + PRIME32_2; U32 v2 = seed + PRIME32_2; U32 v3 = seed + 0; U32 v4 = seed - PRIME32_1; do { v1 = XXH32_round(v1, XXH_get32bits(p)); p += 4; v2 = XXH32_round(v2, XXH_get32bits(p)); p += 4; v3 = XXH32_round(v3, XXH_get32bits(p)); p += 4; v4 = XXH32_round(v4, XXH_get32bits(p)); p += 4; } while (p < limit); h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); } else { h32 = seed + PRIME32_5; } h32 += (U32)len; return XXH32_finalize(h32, p, len & 15, endian, align); } XXH_PUBLIC_API unsigned int XXH32(const void *input, size_t len, unsigned int seed) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if (XXH_FORCE_ALIGN_CHECK) { if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); } } if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); } /*====== Hash streaming ======*/ XXH_PUBLIC_API XXH32_state_t *XXH32_createState(void) { return (XXH32_state_t *)XXH_malloc(sizeof(XXH32_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr) { XXH_free(statePtr); return XXH_OK; } XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dstState, const XXH32_state_t *srcState) { memcpy(dstState, srcState, sizeof(*dstState)); } XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned int seed) { XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); state.v1 = seed + PRIME32_1 + PRIME32_2; state.v2 = seed + PRIME32_2; state.v3 = seed + 0; state.v4 = seed - PRIME32_1; /* do not write into reserved, planned to be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); return XXH_OK; } FORCE_INLINE XXH_errorcode XXH32_update_endian(XXH32_state_t *state, const void *input, size_t len, XXH_endianess endian) { if (input == NULL) #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) return XXH_OK; #else return XXH_ERROR; #endif { const BYTE *p = (const BYTE *)input; const BYTE *const bEnd = p + len; state->total_len_32 += (unsigned)len; state->large_len |= (len >= 16) | (state->total_len_32 >= 16); if (state->memsize + len < 16) { /* fill in tmp buffer */ XXH_memcpy((BYTE *)(state->mem32) + state->memsize, input, len); state->memsize += (unsigned)len; return XXH_OK; } if (state->memsize) { /* some data left from previous update */ XXH_memcpy((BYTE *)(state->mem32) + state->memsize, input, 16 - state->memsize); { const U32 *p32 = state->mem32; state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); } p += 16 - state->memsize; state->memsize = 0; } if (p <= bEnd - 16) { const BYTE *const limit = bEnd - 16; U32 v1 = state->v1; U32 v2 = state->v2; U32 v3 = state->v3; U32 v4 = state->v4; do { v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p += 4; v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p += 4; v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p += 4; v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p += 4; } while (p <= limit); state->v1 = v1; state->v2 = v2; state->v3 = v3; state->v4 = v4; } if (p < bEnd) { XXH_memcpy(state->mem32, p, (size_t)(bEnd - p)); state->memsize = (unsigned)(bEnd - p); } } return XXH_OK; } XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *state_in, const void *input, size_t len) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_update_endian(state_in, input, len, XXH_littleEndian); else return XXH32_update_endian(state_in, input, len, XXH_bigEndian); } FORCE_INLINE U32 XXH32_digest_endian(const XXH32_state_t *state, XXH_endianess endian) { U32 h32; if (state->large_len) { h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); } else { h32 = state->v3 /* == seed */ + PRIME32_5; } h32 += state->total_len_32; return XXH32_finalize(h32, state->mem32, state->memsize, endian, XXH_aligned); } XXH_PUBLIC_API unsigned int XXH32_digest(const XXH32_state_t *state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_digest_endian(state_in, XXH_littleEndian); else return XXH32_digest_endian(state_in, XXH_bigEndian); } /*====== Canonical representation ======*/ /*! Default XXH result types are basic unsigned 32 and 64 bits. * The canonical representation follows human-readable write convention, aka big-endian (large digits first). * These functions allow transformation of hash result into and from its canonical format. * This way, hash values can be written into a file or buffer, remaining comparable across different systems. */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t *dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t *src) { return XXH_readBE32(src); } #ifndef XXH_NO_LONG_LONG /* ******************************************************************* * 64-bit hash functions *********************************************************************/ /*====== Memory access ======*/ #ifndef MEM_MODULE # define MEM_MODULE # if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include typedef uint64_t U64; # else /* if compiler doesn't support unsigned long long, replace by another 64-bit type */ typedef unsigned long long U64; # endif #endif #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ static U64 XXH_read64(const void *memPtr) { return *(const U64 *) memPtr; } #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64; static U64 XXH_read64(const void *ptr) { return ((const unalign64 *)ptr)->u64; } #else /* portable and safe solution. Generally efficient. * see : http://stackoverflow.com/a/32095106/646947 */ static U64 XXH_read64(const void *memPtr) { U64 val; memcpy(&val, memPtr, sizeof(val)); return val; } #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap64 _byteswap_uint64 #elif XXH_GCC_VERSION >= 403 # define XXH_swap64 __builtin_bswap64 #else static U64 XXH_swap64(U64 x) { return ((x << 56) & 0xff00000000000000ULL) | ((x << 40) & 0x00ff000000000000ULL) | ((x << 24) & 0x0000ff0000000000ULL) | ((x << 8) & 0x000000ff00000000ULL) | ((x >> 8) & 0x00000000ff000000ULL) | ((x >> 24) & 0x0000000000ff0000ULL) | ((x >> 40) & 0x000000000000ff00ULL) | ((x >> 56) & 0x00000000000000ffULL); } #endif FORCE_INLINE U64 XXH_readLE64_align(const void *ptr, XXH_endianess endian, XXH_alignment align) { if (align == XXH_unaligned) return endian == XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64( ptr)); else return endian == XXH_littleEndian ? *(const U64 *)ptr : XXH_swap64(* (const U64 *)ptr); } FORCE_INLINE U64 XXH_readLE64(const void *ptr, XXH_endianess endian) { return XXH_readLE64_align(ptr, endian, XXH_unaligned); } static U64 XXH_readBE64(const void *ptr) { return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); } /*====== xxh64 ======*/ static const U64 PRIME64_1 = 11400714785074694791ULL; static const U64 PRIME64_2 = 14029467366897019727ULL; static const U64 PRIME64_3 = 1609587929392839161ULL; static const U64 PRIME64_4 = 9650029242287828579ULL; static const U64 PRIME64_5 = 2870177450012600261ULL; static U64 XXH64_round(U64 acc, U64 input) { acc += input * PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= PRIME64_1; return acc; } static U64 XXH64_mergeRound(U64 acc, U64 val) { val = XXH64_round(0, val); acc ^= val; acc = acc * PRIME64_1 + PRIME64_4; return acc; } static U64 XXH64_avalanche(U64 h64) { h64 ^= h64 >> 33; h64 *= PRIME64_2; h64 ^= h64 >> 29; h64 *= PRIME64_3; h64 ^= h64 >> 32; return h64; } #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) static U64 XXH64_finalize(U64 h64, const void *ptr, size_t len, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)ptr; #define PROCESS1_64 \ h64 ^= (*p++) * PRIME64_5; \ h64 = XXH_rotl64(h64, 11) * PRIME64_1; #define PROCESS4_64 \ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; \ p+=4; \ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; #define PROCESS8_64 { \ U64 const k1 = XXH64_round(0, XXH_get64bits(p)); \ p+=8; \ h64 ^= k1; \ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \ } switch (len & 31) { case 24: PROCESS8_64; /* fallthrough */ case 16: PROCESS8_64; /* fallthrough */ case 8: PROCESS8_64; return XXH64_avalanche(h64); case 28: PROCESS8_64; /* fallthrough */ case 20: PROCESS8_64; /* fallthrough */ case 12: PROCESS8_64; /* fallthrough */ case 4: PROCESS4_64; return XXH64_avalanche(h64); case 25: PROCESS8_64; /* fallthrough */ case 17: PROCESS8_64; /* fallthrough */ case 9: PROCESS8_64; PROCESS1_64; return XXH64_avalanche(h64); case 29: PROCESS8_64; /* fallthrough */ case 21: PROCESS8_64; /* fallthrough */ case 13: PROCESS8_64; /* fallthrough */ case 5: PROCESS4_64; PROCESS1_64; return XXH64_avalanche(h64); case 26: PROCESS8_64; /* fallthrough */ case 18: PROCESS8_64; /* fallthrough */ case 10: PROCESS8_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 30: PROCESS8_64; /* fallthrough */ case 22: PROCESS8_64; /* fallthrough */ case 14: PROCESS8_64; /* fallthrough */ case 6: PROCESS4_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 27: PROCESS8_64; /* fallthrough */ case 19: PROCESS8_64; /* fallthrough */ case 11: PROCESS8_64; PROCESS1_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 31: PROCESS8_64; /* fallthrough */ case 23: PROCESS8_64; /* fallthrough */ case 15: PROCESS8_64; /* fallthrough */ case 7: PROCESS4_64; /* fallthrough */ case 3: PROCESS1_64; /* fallthrough */ case 2: PROCESS1_64; /* fallthrough */ case 1: PROCESS1_64; /* fallthrough */ case 0: return XXH64_avalanche(h64); } /* impossible to reach */ assert(0); return 0; /* unreachable, but some compilers complain without it */ } FORCE_INLINE U64 XXH64_endian_align(const void *input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)input; const BYTE *bEnd = p + len; U64 h64; #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) if (p == NULL) { len = 0; bEnd = p = (const BYTE *)(size_t)32; } #endif if (len >= 32) { const BYTE *const limit = bEnd - 32; U64 v1 = seed + PRIME64_1 + PRIME64_2; U64 v2 = seed + PRIME64_2; U64 v3 = seed + 0; U64 v4 = seed - PRIME64_1; do { v1 = XXH64_round(v1, XXH_get64bits(p)); p += 8; v2 = XXH64_round(v2, XXH_get64bits(p)); p += 8; v3 = XXH64_round(v3, XXH_get64bits(p)); p += 8; v4 = XXH64_round(v4, XXH_get64bits(p)); p += 8; } while (p <= limit); h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = seed + PRIME64_5; } h64 += (U64) len; return XXH64_finalize(h64, p, len, endian, align); } XXH_PUBLIC_API unsigned long long XXH64(const void *input, size_t len, unsigned long long seed) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if (XXH_FORCE_ALIGN_CHECK) { if ((((size_t)input) & 7) == 0) { /* Input is aligned, let's leverage the speed advantage */ if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); else return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); } } if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); else return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); } /*====== Hash Streaming ======*/ XXH_PUBLIC_API XXH64_state_t *XXH64_createState(void) { return (XXH64_state_t *)XXH_malloc(sizeof(XXH64_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr) { XXH_free(statePtr); return XXH_OK; } XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t *dstState, const XXH64_state_t *srcState) { memcpy(dstState, srcState, sizeof(*dstState)); } XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr, unsigned long long seed) { XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); state.v1 = seed + PRIME64_1 + PRIME64_2; state.v2 = seed + PRIME64_2; state.v3 = seed + 0; state.v4 = seed - PRIME64_1; /* do not write into reserved, planned to be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); return XXH_OK; } FORCE_INLINE XXH_errorcode XXH64_update_endian(XXH64_state_t *state, const void *input, size_t len, XXH_endianess endian) { if (input == NULL) #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) return XXH_OK; #else return XXH_ERROR; #endif { const BYTE *p = (const BYTE *)input; const BYTE *const bEnd = p + len; state->total_len += len; if (state->memsize + len < 32) { /* fill in tmp buffer */ XXH_memcpy(((BYTE *)state->mem64) + state->memsize, input, len); state->memsize += (U32)len; return XXH_OK; } if (state->memsize) { /* tmp buffer is full */ XXH_memcpy(((BYTE *)state->mem64) + state->memsize, input, 32 - state->memsize); state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64 + 0, endian)); state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64 + 1, endian)); state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64 + 2, endian)); state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64 + 3, endian)); p += 32 - state->memsize; state->memsize = 0; } if (p + 32 <= bEnd) { const BYTE *const limit = bEnd - 32; U64 v1 = state->v1; U64 v2 = state->v2; U64 v3 = state->v3; U64 v4 = state->v4; do { v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p += 8; v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p += 8; v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p += 8; v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p += 8; } while (p <= limit); state->v1 = v1; state->v2 = v2; state->v3 = v3; state->v4 = v4; } if (p < bEnd) { XXH_memcpy(state->mem64, p, (size_t)(bEnd - p)); state->memsize = (unsigned)(bEnd - p); } } return XXH_OK; } XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH64_state_t *state_in, const void *input, size_t len) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_update_endian(state_in, input, len, XXH_littleEndian); else return XXH64_update_endian(state_in, input, len, XXH_bigEndian); } FORCE_INLINE U64 XXH64_digest_endian(const XXH64_state_t *state, XXH_endianess endian) { U64 h64; if (state->total_len >= 32) { U64 const v1 = state->v1; U64 const v2 = state->v2; U64 const v3 = state->v3; U64 const v4 = state->v4; h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = state->v3 /*seed*/ + PRIME64_5; } h64 += (U64) state->total_len; return XXH64_finalize(h64, state->mem64, (size_t)state->total_len, endian, XXH_aligned); } XXH_PUBLIC_API unsigned long long XXH64_digest(const XXH64_state_t *state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_digest_endian(state_in, XXH_littleEndian); else return XXH64_digest_endian(state_in, XXH_bigEndian); } /*====== Canonical representation ======*/ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t *dst, XXH64_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t *src) { return XXH_readBE64(src); } #endif /* XXH_NO_LONG_LONG */ QATzip-1.3.1/src/xxhash.h000066400000000000000000000342101500263377000151320ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /*************************************************************************** * xxHash - Fast Hash algorithm * Copyright (C) 2012-2016, Yann Collet * * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You can contact the author at : * - xxHash homepage: http://www.xxhash.com * - xxHash source repository : https://github.com/Cyan4973/xxHash ***************************************************************************/ #ifndef XXHASH_H_5627135585666179 #define XXHASH_H_5627135585666179 1 #if defined (__cplusplus) extern "C" { #endif /* **************************** * Definitions ******************************/ #include /* size_t */ typedef enum { XXH_OK = 0, XXH_ERROR } XXH_errorcode; /* **************************** * API modifier ******************************/ /** XXH_INLINE_ALL (and XXH_PRIVATE_API) * This is useful to include xxhash functions in `static` mode * in order to inline them, and remove their symbol from the public list. * Inlining can offer dramatic performance improvement on small keys. * Methodology : * #define XXH_INLINE_ALL * #include "xxhash.h" * `xxhash.c` is automatically included. * It's not useful to compile and link it as a separate module. */ #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # ifndef XXH_STATIC_LINKING_ONLY # define XXH_STATIC_LINKING_ONLY # endif # if defined(__GNUC__) # define XXH_PUBLIC_API static __inline __attribute__((unused)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) # define XXH_PUBLIC_API static __inline # else /* this version may generate warnings for unused static functions */ # define XXH_PUBLIC_API static # endif #else # define XXH_PUBLIC_API /* do nothing */ #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ /*! XXH_NAMESPACE, aka Namespace Emulation : * * If you want to include _and expose_ xxHash functions from within your own library, * but also want to avoid symbol collisions with other libraries which may also include xxHash, * * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). * * Note that no change is required within the calling program as long as it includes `xxhash.h` : * regular symbol name will be automatically translated by this header. */ #ifdef XXH_NAMESPACE # define XXH_CAT(A,B) A##B # define XXH_NAME2(A,B) XXH_CAT(A,B) # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) # define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) # define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) # define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) # define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) # define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) # define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) # define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) #endif /* ************************************* * Version ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 6 #define XXH_VERSION_RELEASE 5 #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) XXH_PUBLIC_API unsigned XXH_versionNumber(void); /*-********************************************************************** * 32-bit hash ************************************************************************/ typedef unsigned int XXH32_hash_t; /*! XXH32() : Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input". The memory between input & input+length must be valid (allocated and read-accessible). "seed" can be used to alter the result predictably. Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ XXH_PUBLIC_API XXH32_hash_t XXH32(const void *input, size_t length, unsigned int seed); /*====== Streaming ======*/ typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ XXH_PUBLIC_API XXH32_state_t *XXH32_createState(void); XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr); XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dst_state, const XXH32_state_t *src_state); XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned int seed); XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *statePtr, const void *input, size_t length); XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t *statePtr); /* * Streaming functions generate the xxHash of an input provided in multiple segments. * Note that, for small input, they are slower than single-call functions, due to state management. * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. * * XXH state must first be allocated, using XXH*_createState() . * * Start a new hash by initializing state with a seed, using XXH*_reset(). * * Then, feed the hash state by calling XXH*_update() as many times as necessary. * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. * * Finally, a hash value can be produced anytime, by using XXH*_digest(). * This function returns the nn-bits hash as an int or long long. * * It's still possible to continue inserting input into the hash state after a digest, * and generate some new hashes later on, by calling again XXH*_digest(). * * When done, free XXH state space if it was allocated dynamically. */ /*====== Canonical representation ======*/ typedef struct { unsigned char digest[4]; } XXH32_canonical_t; XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t *dst, XXH32_hash_t hash); XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t *src); /* Default result type for XXH functions are primitive unsigned 32 and 64 bits. * The canonical representation uses human-readable write convention, aka big-endian (large digits first). * These functions allow transformation of hash result into and from its canonical format. * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. */ #ifndef XXH_NO_LONG_LONG /*-********************************************************************** * 64-bit hash ************************************************************************/ typedef unsigned long long XXH64_hash_t; /*! XXH64() : Calculate the 64-bit hash of sequence of length "len" stored at memory address "input". "seed" can be used to alter the result predictably. This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark). */ XXH_PUBLIC_API XXH64_hash_t XXH64(const void *input, size_t length, unsigned long long seed); /*====== Streaming ======*/ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ XXH_PUBLIC_API XXH64_state_t *XXH64_createState(void); XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr); XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t *dst_state, const XXH64_state_t *src_state); XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr, unsigned long long seed); XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH64_state_t *statePtr, const void *input, size_t length); XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t *statePtr); /*====== Canonical representation ======*/ typedef struct { unsigned char digest[8]; } XXH64_canonical_t; XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t *dst, XXH64_hash_t hash); XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t *src); #endif /* XXH_NO_LONG_LONG */ #ifdef XXH_STATIC_LINKING_ONLY /* ================================================================================================ This section contains declarations which are not guaranteed to remain stable. They may change in future versions, becoming incompatible with a different version of the library. These declarations should only be used with static linking. Never use them in association with dynamic linking ! =================================================================================================== */ /* These definitions are only present to allow * static allocation of XXH state, on stack or in a struct for example. * Never **ever** use members directly. */ #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include struct XXH32_state_s { uint32_t total_len_32; uint32_t large_len; uint32_t v1; uint32_t v2; uint32_t v3; uint32_t v4; uint32_t mem32[4]; uint32_t memsize; uint32_t reserved; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH32_state_t */ struct XXH64_state_s { uint64_t total_len; uint64_t v1; uint64_t v2; uint64_t v3; uint64_t v4; uint64_t mem64[4]; uint32_t memsize; uint32_t reserved[2]; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH64_state_t */ # else struct XXH32_state_s { unsigned total_len_32; unsigned large_len; unsigned v1; unsigned v2; unsigned v3; unsigned v4; unsigned mem32[4]; unsigned memsize; unsigned reserved; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH32_state_t */ # ifndef XXH_NO_LONG_LONG /* remove 64-bit support */ struct XXH64_state_s { unsigned long long total_len; unsigned long long v1; unsigned long long v2; unsigned long long v3; unsigned long long v4; unsigned long long mem64[4]; unsigned memsize; unsigned reserved[2]; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH64_state_t */ # endif # endif #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */ #endif #endif /* XXH_STATIC_LINKING_ONLY */ #if defined (__cplusplus) } #endif #endif /* XXHASH_H_5627135585666179 */ QATzip-1.3.1/test/000077500000000000000000000000001500263377000136465ustar00rootroot00000000000000QATzip-1.3.1/test/Makefile.am000066400000000000000000000051531500263377000157060ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ noinst_PROGRAMS = bt bin_PROGRAMS = qatzip-test qatzip_test_SOURCES = main.c qatzip_test_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) qatzip_test_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) qatzip_test_LDFLAGS = \ $(ICP_LDFLAGS) bt_SOURCES = bt.c bt_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) bt_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) bt_LDFLAGS = \ $(ICP_LDFLAGS) QATzip-1.3.1/test/README.md000066400000000000000000000156761500263377000151440ustar00rootroot00000000000000# Intel® QuickAssist Technology (QAT) qatzip-test app ## Table of Contents - [Introduction](#introduction) - [Input Parameters](#Input-Parameters) - [Limitations](#limitations) - [qatzip-test command](#qatzip-test-command) ## Introduction qatzip-test is a utility to verify qatzip library functions and collect performance data. And you can use it to verify the peak performance of QAT devices also. It has a rich set of input parameters that can help you simulate QAT usage in various situations. And you can also use it as a demo of how to use the qatzip library API. ## Licensing The Licensing of the files within this project is split as follows: Intel® Quickassist Technology (QAT) QATzip - BSD License. Please see the `LICENSE` file contained in the top level folder. Further details can be found in the file headers of the relevant files. Example Intel® Quickassist Technology Driver Configuration Files contained within the folder hierarchy `config_file` - Dual BSD/GPLv2 License. Please see the file headers of the configuration files, and the full GPLv2 license contained in the file `LICENSE.GPL` within the `config_file` folder. ## Input Parameters Required options: - -m testMode 2 test hugepage alloc Memory 4 test comp/decomp by configurable parameters 5 test comp/decomp by format parameters 6 test session setup process according to configurable parameters 7 test decompress sw failover 8 test compression/decompression mixed sw failover 9 test stream compression 10 test stream compression based on common memory 11 test stream compression with multi-block 12 test stream decompression with multi-block 13 test negative case, stream compression with invalid chuck size 14 test negative case, stream compression with invalid params size 15 test negative case, stream decompression with invalid params size 16 test negative case, end of stream with invalid params size 17 test negative case, Mixed decompression sw failover 18 test comp/decomp by configurable parameters with thread safe flag 20 test stream with pending out 21 test hugepage alloc Memory in fork process 22 test negative case, stream decompression with buffer error 23 test compression performance with LSM enable 24 test decompression performance with LSM enable 25 test Heterogeneous offload performance with LSM enable 26 test comp/decomp by configurable parameters with extra setup session 27 test end of stream flag detection 28 test Async comp/decomp by configurable parameters 29 test Async comp/decomp performance by configurable parameters 30 test negative case, decompression with invalid end of stream 31 test decompression with valid end of stream during multi-stream Optional options can be: - ``` -i inputfile``` - Input test file, default by generating random data and default test size is 512KB. - ``` -C hw_buff_sz``` - HW buffer size, default is 64K. - ``` -b block_size``` - Input src buffer size at API level, It must be the power of 2. The minimum is 4k, and maximum is 1M. Default is input file size. - ``` -t thread_count``` - Maximum fork thread permitted in the current test, 0 means no forking permitted. - ``` -l loop_count``` - The loop for same test condition, default is 2. - ``` -L comp_lvl``` - compression level. default is 1. - ``` -A comp_algorithm``` - deflate | lz4 | lz4s. - ``` -T huffmanType``` - static | dynamic, set huffmanType to deflate algorithm. - ``` -D direction``` - Test compression/decompression direction, comp | decomp | both, default is comp. - ``` -O data_fmt``` - deflate | gzip | gzipext | deflate_4B | lz4 | lz4s | zlib. For zlib and deflate raw the block size must be same as HW buffer size, e.g '-b' and '-C' should be same. - ``` -B swBack``` - enable | disable SW failover, enabled by default. - ``` -e init engine``` - enable | disable HW engine. enabled by default. - ``` -s init session``` - enable | disable session setup. enabled by default. - ``` -r req_cnt_thrshold``` - max in-flight request num, default is 16. - ``` -M svm ``` - set perf mode with file input, default is non svm mode. When set to svm, all memory will be allocated with malloc instead of qzMalloc, This option is only applied to mode 4. - ``` -p compress_buf_type``` - pinned | common, default is common,This option is only applied to file compression test in mode 4, If set common, memory of compress buffer will be allocated through malloc, If set pinned, memory of compress buffer will be allocated in huge page, allocation limit is 2M\n" - ``` -P polling``` - set polling mode, default is periodical polling, when set busy polling mode, it would automatically enable the LSM(latency sensitive mode) - ``` -g loglevel``` - set qatzip loglevel(none|error|warn|info|debug) - ``` -q async_queue_sz``` - set async queue size, default is 1024 - ``` -v ``` - verify compression/decompression result, disabled by default. - ``` -a ``` - Enable Latency sensitive mode. - ``` -h ``` - Print this help message ## Limitations * If "-t" thread number is larger than driver dc instances, have to enable SW failover, like "-B 1" * For LSM test(mode 23-25), it require the maximum dc instance configure to build heavy pressure situation for QAT device, please setup 64 dc instances in driver config, and use the same number of threads. because LSM would consume the cpu resource, please make sure cpu usage is not in pressure when you test. * For Async test(mode 28-29), if you want to test very smaller input file or you set the very smaller block size like "-b 4096", It maybe cause the async queue full and failed, then you have to increase the queue size by setting "-q". * For negative case, it may dump the error log from the qatzip library, those logs are expected, but if you don't want to dump those log, please set "-g none". * For some code format like: deflate raw or zlib, if you want to test decompression of them, you have to enable SW failover, like "-B 1", otherwise, you have to make sure the block size is smaller or equal to HW buffer size, like "-b 4096 -C 4096". ## qatzip-test command Run the following command as the example to verify qatzip library functions and collect performance data, Test mode 4 is major test mode for different format and algorithm verify. ### Test mode 4: ```bash qatzip-test -m 4 -t 8 -l 100 -i inputfile -C 65536 -b 524288 -L 1 -A deflate -O gzipext -T dynamic qatzip-test -m 4 -t 10 -l 100 -l 1 -A lz4 -O lz4 ``` ### Test mode 23: ```bash qatzip-test -m 23 -l 1000 -t 64 -i calgary -b 65536 -e enable -B 1 -a qatzip-test -m 23 -l 1000 -t 64 -i calgary -b 65536 -e enable -B 0 -a qatzip-test -m 23 -l 1000 -t 64 -i calgary -b 65536 -e disable -B 0 -a ``` ### Test mode 29: ```bash qatzip-test -m 4 -l 2000 -t 8 -B 0 -D decomp -L 1 -i calgary -T dynamic -C 4096 -b 4096 qatzip-test -m 4 -l 2000 -t 8 -D comp -L 1 -i calgary -A lz4 -O lz4 -q 2048 ``` QATzip-1.3.1/test/bt.c000077500000000000000000000137741500263377000144360ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include "qatzip.h" #define DEFAULT_BUF_LEN (256*1024) void usage(void) { printf("-f fit decompress buffers to size (default full buffers)\n"); printf("-s skip specific number of bytes\n"); printf("-S start test at specific position of source buffer\n"); printf("-E finish test at specific position of source buffer\n"); printf("-c corpus flag for data in source buffer: 0 - iterative, 1 - random, 2 - 'A'\n"); return; } int main(int argc, char *argv[]) { unsigned int i, j, rc, d_len, s_len, s2_len, src_sz, dest_sz; unsigned char *src, *dest, *src2; QzSession_T sess = {0}; int c; int fit = 0; int start = 1; int skip = 1; int end = DEFAULT_BUF_LEN; int corpus = 0; // 0 = iterative, 1 = random srand((time(NULL) & 0xffffffff)); while ((c = getopt(argc, argv, "fS:s:E:c:")) != -1) { switch (c) { case 'f': fit = 1; break; case 's': skip = atoi(optarg); if (skip <= 1) { usage(); return -1; } printf("Will skip by %d\n", skip); break; case 'S': start = atoi(optarg); printf("Will start at %d\n", start); break; case 'E': end = atoi(optarg); printf("Will end at %d\n", end); break; case 'c': corpus = atoi(optarg); printf("corpus = "); if (corpus == 0) { printf("iterative\n"); } else if (corpus == 1) { printf("randon\n"); } if (corpus == 2) { printf("\"A\"\n"); } break; default: usage(); return -1; } } src_sz = DEFAULT_BUF_LEN; dest_sz = (9 * src_sz / 8) + 1024; src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, 1); dest = qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, 1); src2 = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, 1); if (NULL == src || NULL == dest || NULL == src2) { return -1; } i = DEFAULT_BUF_LEN; if (corpus == 0) { for (j = 0; j < i; j++) { src[j] = (char)(j % 200); } } else if (corpus == 1) { for (j = 0; j < i; j++) { src[j] = (char)rand() % 255; } } else { for (j = 0; j < i; j++) { src[j] = (char)'A'; } } printf("src = 0x%lx, src2 = 0x%lx, dest = 0x%lx\n", (long unsigned int)src, (long unsigned int)src2, (long unsigned int)dest); printf("fit = %d\n", fit); for (i = start; i < end; i += skip) { s_len = i; d_len = dest_sz; rc = qzCompress(&sess, src, &s_len, dest, &d_len, 1); // printf( "rc = %d, src = %d, dest = %d\n", // rc, s_len, d_len ); if (rc == 0) { if (1 == fit) { s2_len = s_len; } else { s2_len = DEFAULT_BUF_LEN; } rc = qzDecompress(&sess, dest, &d_len, src2, &s2_len); // printf( "rc2 = %d, src = %d, dest = %d\n", // rc2, d_len, s2_len ); if (rc == 0) { if (s2_len != s_len) { printf("mismatch orig\t%d\tcomp %d\tdec %d\t %d\n", s_len, d_len, s2_len, (s_len - s2_len)); printf("\t\t%d\t%d\t%d\n", (s_len % (64 * 1024)), (d_len % (64 * 1024)), (s2_len % (64 * 1024))); goto error; } if (memcmp(src, src2, s_len) != 0) { printf("memcmp mismatch - len = %d\t%d\n", s_len, (s_len % (64 * 1024))); goto error; } } else { printf("return from decomress is %d\t len = %d\t%d\n", rc, s_len, (s_len % (64 * 1024))); goto error; } } else { goto error; } } return 0; error: qzTeardownSession(&sess); qzFree(src); qzFree(dest); qzFree(src2); return rc; } QATzip-1.3.1/test/code_format_tests/000077500000000000000000000000001500263377000173525ustar00rootroot00000000000000QATzip-1.3.1/test/code_format_tests/astylerc000066400000000000000000000045661500263377000211360ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ # Bracket Style style=kr --keep-one-line-blocks # K&R brackets # Indentation indent=spaces # 4 white space min-conditional-indent=0 # Padding unpad-paren # Remove all spaces with parens that aren't requested below pad-oper # Put spaces around operators pad-header # Put spaces between if/while/for etc. and the first paren # Pointers align-pointer=name # Align the * next to the variable name # Line wrapping max-code-length=80 # 80 character line limit break-after-logical # For if statements, wrap to the next line after logical operator # Line endings lineend=linux # LF line endings # General options suffix=none formatted QATzip-1.3.1/test/code_format_tests/format.sh000077500000000000000000000047271500263377000212130ustar00rootroot00000000000000#!/usr/bin/bash ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ # exit on errors set -e : ${QZ_ROOT?} readonly BASEDIR=$(readlink -f $(dirname $0)) declare -i rc=0 rm -f $BASEDIR/astyle.log if hash astyle; then echo -n "Checking coding style..." find $QZ_ROOT -iregex '.*\.[ch]' | \ xargs astyle --options=$BASEDIR/astylerc | \ tee -a $BASEDIR/astyle.log if grep -q "^Formatted" $BASEDIR/astyle.log; then echo -e "ERRORS detected\n" grep --color=auto "^Formatted.*" $BASEDIR/astyle.log echo "Incorrect code style detected in one or more files." echo "The files have been automatically formatted." rc=1 else echo " OK" fi else echo "You do not have astyle installed so your code style is not being checked!" rc=2 fi exit $rc QATzip-1.3.1/test/main.c000077500000000000000000007043671500263377000147620ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #define _POSIX_C_SOURCE 200112L #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include /* QAT headers */ #ifdef HAVE_QAT_HEADERS #include #include #include #else #include #include #include #endif #include #include #include #include #define QZ_FMT_NAME "QZ" #define GZIP_FMT_NAME "GZIP" #define MAX_FMT_NAME 8 #define MAX_NUMA_NODE 8 #define ARRAY_LEN(arr) (sizeof(arr) / sizeof((arr)[0])) #define KB (1024) #define MB (KB * KB) /* According to different platforms, * instance total = instance on each device * num of device */ #define G_PROCESS_NUM_INSTANCES_4 4 /* instance=4 * device=1 */ #define G_PROCESS_NUM_INSTANCES_8 8 /* instance=1 * device=8 */ #define G_PROCESS_NUM_INSTANCES_12 12 /* instance=4 * device=3 */ #define G_PROCESS_NUM_INSTANCES_16 16 /* instance=4 * device=4 */ #define G_PROCESS_NUM_INSTANCES_32 32 /* instance=4 * device=8 */ #define G_PROCESS_NUM_INSTANCES_64 64 /* instance=4 * device=16 */ #define MAX_HUGEPAGE_FILE "/sys/module/usdm_drv/parameters/max_huge_pages" #define QZ_INIT_HW_FAIL(rc) (QZ_DUPLICATE != rc && \ (QZ_OK != rc || \ QZ_NO_HW == g_process.qz_init_status)) #if CPA_DC_API_VERSION_AT_LEAST(3, 1) #define COMP_LVL_MAXIMUM QZ_LZS_COMP_LVL_MAXIMUM #else #define COMP_LVL_MAXIMUM QZ_DEFLATE_COMP_LVL_MAXIMUM #endif typedef void *(QzThdOps)(void *); typedef enum { UNKNOWN, QZ, GZIP, FMT_NUM } QzFormatId_T; typedef struct QzFormat_S { char fmt_name[MAX_FMT_NAME]; QzFormatId_T fmt; } QzFormat_T; QzFormat_T g_format_list[] = { {QZ_FMT_NAME, QZ}, {GZIP_FMT_NAME, GZIP} }; typedef struct QzBlock_S { QzFormatId_T fmt; unsigned int size; struct QzBlock_S *next; } QzBlock_T; typedef enum { COMP = 0, DECOMP, BOTH } ServiceType_T; typedef enum { TEST_DEFLATE = 0, TEST_GZIP, TEST_GZIPEXT, TEST_DEFLATE_4B, TEST_LZ4, TEST_LZ4S, TEST_ZLIB } TEST_FORMAT_T; typedef struct CPUCore_S { int seq; int used; } CPUCore_T; typedef struct NUMANode_S { int num_cores; CPUCore_T *core; } NUMANode_T; typedef struct { long thd_id; ServiceType_T service; int count; int verify_data; int debug; size_t src_sz; size_t comp_out_sz; size_t decomp_out_sz; int max_forks; unsigned char *src; unsigned char *comp_out; unsigned char *decomp_out; int gen_data; int comp_algorithm; int sw_backup; int hw_buff_sz; int comp_lvl; int req_cnt_thrshold; int huffman_hdr; QzPollingMode_T polling_mode; TEST_FORMAT_T test_format; QzThdOps *ops; QzBlock_T *blks; int init_engine_disabled; int init_sess_disabled; int thread_sleep; int block_size; unsigned int is_sensitive_mode; } TestArg_T; const unsigned int USDM_ALLOC_MAX_SZ = (2 * MB - 5 * KB); const unsigned int DEFAULT_STREAM_BUF_SZ = 256 * KB; const unsigned int QATZIP_MAX_HW_SZ = 512 * KB; const unsigned int MAX_HUGE_PAGE_SZ = 2 * MB; static pthread_mutex_t g_lock_print = PTHREAD_MUTEX_INITIALIZER; #ifndef ENABLE_THREAD_BARRIER static pthread_mutex_t g_cond_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t g_ready_cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t g_start_cond = PTHREAD_COND_INITIALIZER; static int g_ready_to_start; static atomic_int g_ready_thread_count; #else static pthread_barrier_t g_bar; #endif char *g_input_file_name = NULL; static bool g_perf_svm = false; static struct timeval g_timers[100][100]; static struct timeval g_timer_start; extern void dumpAllCounters(void); static int test_thread_safe_flag = 0; extern processData_T g_process; extern unsigned int lsm_met_len_shift; // Async test mode global variable extern int async_queue_size; static int Async_retry_max = 100; static int Async_retry_interval = 10; QzBlock_T *parseFormatOption(char *buf) { char *str = buf, *sub_str = NULL; char *delim = "/", *sub_delim = ":"; char *token, *sub_token; char *saveptr, *sub_saveptr; int i, j, fmt_idx; unsigned int fmt_found = 0; QzBlock_T *blk = NULL; QzBlock_T *head, *prev, *r; unsigned int list_len = sizeof(g_format_list) / sizeof(QzFormat_T); head = malloc(sizeof(QzBlock_T)); assert(NULL != head); head->next = NULL; prev = head; for (i = 1; ; i++, str = NULL) { token = strtok_r(str, delim, &saveptr); if (NULL == token) { break; } QZ_DEBUG("String[%d]: %s\n", i, token); fmt_found = 0; blk = NULL; for (j = 1, sub_str = token; ; j++, sub_str = NULL) { sub_token = strtok_r(sub_str, sub_delim, &sub_saveptr); if (NULL == sub_token) { break; } QZ_DEBUG(" -[%d]-> %s\n", j, sub_token); if (fmt_found) { blk->size = atoi(sub_token); break; } char *tmp = sub_token; while (*tmp) { *tmp = GET_LOWER_8BITS(toupper(*tmp)); tmp++; } for (fmt_idx = 0; fmt_idx < list_len; fmt_idx++) { if (0 == strcmp(sub_token, g_format_list[fmt_idx].fmt_name)) { blk = calloc(1, sizeof(QzBlock_T)); assert(NULL != blk); blk->fmt = g_format_list[fmt_idx].fmt; blk->next = NULL; prev->next = blk; fmt_found = 1; break; } } } if (NULL != blk) { prev = blk; } } blk = head->next; i = 1; while (blk) { QZ_INFO("[INFO] Block%d: format -%8s, \tsize - %d\n", i++, g_format_list[blk->fmt - 1].fmt_name, blk->size); blk = blk->next; } if (NULL == head->next) { r = head->next; free(head); } else { r = head; } return r; } static void genRandomData(uint8_t *data, size_t size) { size_t i, j; char c; uint8_t *ptr = data; while (ptr < (data + size)) { j = rand() % 100; c = GET_LOWER_8BITS((rand() % 65 + 90)); for (i = (size_t)0; i < j; i++) { *ptr = c; ptr++; if (ptr >= (data + size)) { break; } } } } static void sigInt(int sig) { dumpAllCounters(); _exit(1); } static void timeCheck(int i, long tid) { gettimeofday(&g_timers[i][tid], NULL); } #ifdef TESTMAIN_DUMP_TIMERS static void dumpTimers(int tid) { int i; unsigned long long start, local, diff; start = (g_timer_start.tv_sec * 1000000) + g_timer_start.tv_usec; if (0 == tid) { QZ_INFO("[ts]: %lld\n", start); } QZ_INFO("[%5.5d]", tid); for (i = 0; i < 15; i++) { local = (g_timers[i][tid].tv_sec * 1000000) + g_timers[i][tid].tv_usec; if (local > 0) { diff = local - start; QZ_INFO(" %lld", diff); } else { QZ_INFO(" -"); } } QZ_INFO("\n"); } #endif static void dumpInputData(size_t size, uint8_t *data) { int fd; ssize_t ulen; char temp_file[] = "QATZip_Input_XXXXXX"; if (0 == size || NULL == data) return; fd = mkstemp(temp_file); if (-1 == fd) { QZ_ERROR("Creat dump file Failed\n"); return; } ulen = write(fd, data, size); if (ulen != (ssize_t) size) { QZ_ERROR("Creat dump file Failed\n"); return; } close(fd); } static void dumpOutputData(size_t size, uint8_t *data, char *filename) { int fd = 0; ssize_t ulen; char *output_filename = NULL; char tmp_filename[] = "QATZip_Output_XXXXXX.gz"; const unsigned int suffix_len = 3; if (0 == size || NULL == data) return; if (NULL == filename) { output_filename = tmp_filename; } else { output_filename = filename; } if (NULL == filename) { fd = mkstemps(output_filename, suffix_len); } else { fd = open(output_filename, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); } if (-1 == fd) { QZ_ERROR("Creat dump file Failed\n"); goto done; } ulen = write(fd, data, size); if (ulen != (ssize_t) size) { QZ_ERROR("Creat dump file Failed\n"); goto done; } done: if (fd >= 0) { close(fd); } } static void dumpDecompressedData(size_t size, uint8_t *data, char *filename) { int fd = 0; ssize_t ulen; char *filename_ptr = NULL; char *output_filename = NULL; unsigned int filename_len = 0; const char *suffix = ".decomp"; const unsigned int suffix_len = strlen(suffix); if (0 == size || NULL == data || NULL == filename) return; filename_len = strlen(filename); filename_ptr = filename; filename_len = (filename_len + suffix_len + 1 + 7) / 8 * 8; output_filename = (char *) calloc(1, filename_len); if (NULL == output_filename) { QZ_ERROR("Creat dump file Failed\n"); goto done; } snprintf(output_filename, filename_len, "%s%s", filename_ptr, suffix); fd = open(output_filename, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IRGRP | S_IROTH); if (-1 == fd) { QZ_ERROR("Creat dump file Failed\n"); goto done; } ulen = write(fd, data, size); if (ulen != (ssize_t) size) { QZ_ERROR("Creat dump file Failed\n"); goto done; } done: free(output_filename); if (fd >= 0) { close(fd); } } int qzSetupDeflateExt(QzSession_T *sess, TestArg_T *arg) { int status; QzSessionParamsDeflateExt_T params = {{{0}}}; status = qzGetDefaultsDeflateExt(¶ms); if (status < 0) { QZ_ERROR("Get defaults params error with error: %d\n", status); return QZ_FAIL; } switch (arg->test_format) { case TEST_DEFLATE: params.deflate_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIP: params.deflate_params.data_fmt = QZ_DEFLATE_GZIP; break; case TEST_GZIPEXT: params.deflate_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; case TEST_DEFLATE_4B: params.deflate_params.data_fmt = QZ_DEFLATE_4B; break; case TEST_ZLIB: params.deflate_params.data_fmt = QZ_DEFLATE_RAW; params.zlib_format = 1; break; default: QZ_ERROR("Unsupported data format\n"); return QZ_FAIL; } params.deflate_params.huffman_hdr = arg->huffman_hdr; params.deflate_params.common_params.comp_lvl = arg->comp_lvl; params.deflate_params.common_params.comp_algorithm = QZ_DEFLATE; params.deflate_params.common_params.hw_buff_sz = arg->hw_buff_sz; params.deflate_params.common_params.polling_mode = arg->polling_mode; params.deflate_params.common_params.req_cnt_thrshold = arg->req_cnt_thrshold; params.deflate_params.common_params.max_forks = arg->max_forks; params.deflate_params.common_params.sw_backup = arg->sw_backup; status = qzSetupSessionDeflateExt(sess, ¶ms); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return QZ_FAIL; } return QZ_OK; } int qzSetupDeflate(QzSession_T *sess, TestArg_T *arg) { int status; QzSessionParamsDeflate_T params; status = qzGetDefaultsDeflate(¶ms); if (status < 0) { QZ_ERROR("Get defaults params error with error: %d\n", status); return QZ_FAIL; } switch (arg->test_format) { case TEST_DEFLATE: params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIP: params.data_fmt = QZ_DEFLATE_GZIP; break; case TEST_GZIPEXT: params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; case TEST_DEFLATE_4B: params.data_fmt = QZ_DEFLATE_4B; break; default: QZ_ERROR("Unsupported data format\n"); return QZ_FAIL; } params.huffman_hdr = arg->huffman_hdr; params.common_params.comp_lvl = arg->comp_lvl; params.common_params.comp_algorithm = arg->comp_algorithm; params.common_params.hw_buff_sz = arg->hw_buff_sz; params.common_params.polling_mode = arg->polling_mode; params.common_params.req_cnt_thrshold = arg->req_cnt_thrshold; params.common_params.max_forks = arg->max_forks; params.common_params.sw_backup = arg->sw_backup; params.common_params.is_sensitive_mode = arg->is_sensitive_mode; status = qzSetupSessionDeflate(sess, ¶ms); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return QZ_FAIL; } return QZ_OK; } int qzSetupLZ4(QzSession_T *sess, TestArg_T *arg) { int status; QzSessionParamsLZ4_T params; status = qzGetDefaultsLZ4(¶ms); if (status < 0) { QZ_ERROR("Get defaults params error with error: %d\n", status); return QZ_FAIL; } params.common_params.comp_lvl = arg->comp_lvl; params.common_params.comp_algorithm = arg->comp_algorithm; params.common_params.hw_buff_sz = arg->hw_buff_sz; params.common_params.polling_mode = arg->polling_mode; params.common_params.req_cnt_thrshold = arg->req_cnt_thrshold; params.common_params.max_forks = arg->max_forks; params.common_params.sw_backup = arg->sw_backup; params.common_params.is_sensitive_mode = arg->is_sensitive_mode; status = qzSetupSessionLZ4(sess, ¶ms); if (status) { QZ_ERROR("Session setup failed with error: %d\n", status); return QZ_FAIL; } return QZ_OK; } int qzSetupLZ4S(QzSession_T *sess, TestArg_T *arg) { int status; QzSessionParamsLZ4S_T params; status = qzGetDefaultsLZ4S(¶ms); if (status < 0) { QZ_ERROR("Get defaults params error with error: %d\n", status); return QZ_FAIL; } params.common_params.comp_lvl = arg->comp_lvl; params.common_params.comp_algorithm = arg->comp_algorithm; params.common_params.hw_buff_sz = arg->hw_buff_sz; params.common_params.polling_mode = arg->polling_mode; params.common_params.req_cnt_thrshold = arg->req_cnt_thrshold; params.common_params.max_forks = arg->max_forks; params.common_params.sw_backup = arg->sw_backup; params.common_params.is_sensitive_mode = arg->is_sensitive_mode; status = qzSetupSessionLZ4S(sess, ¶ms); if (status) { QZ_ERROR("Session setup failed with error: %d\n", status); return QZ_FAIL; } return QZ_OK; } int qzInitSetupsessionExt(QzSession_T *sess, TestArg_T *arg) { int rc = QZ_OK; if (!((TestArg_T *)arg)->init_engine_disabled) { rc = qzInit(sess, arg->sw_backup); if (QZ_INIT_FAIL(rc)) { return rc; } } if (!((TestArg_T *)arg)->init_sess_disabled) { switch (arg->test_format) { case TEST_DEFLATE: case TEST_GZIP: case TEST_GZIPEXT: case TEST_ZLIB: QZ_DEBUG("calling qzSetupDeflateExt \n"); rc = qzSetupDeflateExt(sess, arg); break; default: QZ_ERROR("Unsupported data format\n"); return QZ_FAIL; } if (QZ_SETUP_SESSION_FAIL(rc)) { return rc; } } return rc; } int qzInitSetupsession(QzSession_T *sess, TestArg_T *arg) { int rc = QZ_OK; if (!((TestArg_T *)arg)->init_engine_disabled) { rc = qzInit(sess, arg->sw_backup); if (QZ_INIT_FAIL(rc)) { return rc; } } if (!((TestArg_T *)arg)->init_sess_disabled) { switch (arg->test_format) { case TEST_DEFLATE: case TEST_GZIP: case TEST_GZIPEXT: rc = qzSetupDeflate(sess, arg); break; case TEST_LZ4: rc = qzSetupLZ4(sess, arg); break; case TEST_LZ4S: rc = qzSetupLZ4S(sess, arg); break; case TEST_ZLIB: rc = qzSetupDeflateExt(sess, arg); break; default: QZ_ERROR("Unsupported data format\n"); return QZ_FAIL; } if (QZ_SETUP_SESSION_FAIL(rc)) { return rc; } } return rc; } void *qzDecompressSwQz(void *arg) { int rc, k; unsigned char *src = NULL, *comp_out = NULL; unsigned char *decomp_sw_out = NULL, *decomp_qz_out = NULL; size_t src_sz, comp_out_sz, decomp_sw_out_sz, decomp_qz_out_sz; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const int verify_data = 1; const int count = ((TestArg_T *)arg)->count; QzSession_T sess = {0}; QzSessionParams_T cus_params = {0}; if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_sw_out_sz = org_src_sz; decomp_qz_out_sz = org_src_sz; QZ_DEBUG("Hello from qzDecompressSwQz tid=%ld, count=%d, service=2, " "verify_data=%d\n", tid, count, verify_data); src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_sw_out = qzMalloc(decomp_sw_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_qz_out = qzMalloc(decomp_qz_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!src || !comp_out || !decomp_sw_out || !decomp_qz_out) { QZ_ERROR("Malloc failed\n"); goto done; } el_m = 0; QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); comp_out_sz = org_src_sz; //Compress 1st { //Set default hwBufferSize to 64KB cus_params.hw_buff_sz = 64 * 1024; if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto done; } QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); unsigned int last = 0; rc = qzCompress(&sess, src, (uint32_t *)(&src_sz), comp_out, (uint32_t *)(&comp_out_sz), last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto done; } if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); qzTeardownSession(&sess); } //Decompress SW { cus_params.hw_buff_sz = 32 * 1024; //32KB if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect hw_buff_sz %u.\n", cus_params.hw_buff_sz); goto done; } QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_sw_out_sz); qzSetupSession(&sess, NULL); unsigned int tmp_comp_out_sz = GET_LOWER_32BITS(comp_out_sz); rc = qzDecompress(&sess, comp_out, (uint32_t *)(&tmp_comp_out_sz), decomp_sw_out, (uint32_t *)(&decomp_sw_out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } if (decomp_sw_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu\n!", decomp_sw_out_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after SW Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_sw_out_sz); qzTeardownSession(&sess); } //Decompress QAT { //Reset default hwBufferSize to 64KB cus_params.hw_buff_sz = 64 * 1024; if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect hw_buff_sz %u.\n", cus_params.hw_buff_sz); goto done; } QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_qz_out_sz); qzSetupSession(&sess, NULL); unsigned int tmp_comp_out_sz = GET_LOWER_32BITS(comp_out_sz); rc = qzDecompress(&sess, comp_out, (uint32_t *)&tmp_comp_out_sz, decomp_qz_out, (uint32_t *)(&decomp_qz_out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } if (decomp_qz_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_qz_out_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after QZ Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_qz_out_sz); qzTeardownSession(&sess); } (void)gettimeofday(&te, NULL); { QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_sw_out, org_src_sz)) { QZ_ERROR("ERROR: SW Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); goto done; } if (memcmp(src, decomp_qz_out, org_src_sz)) { QZ_ERROR("ERROR: QZip Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); goto done; } QZ_DEBUG("reset data..\n"); memset(comp_out, 0, comp_out_sz); memset(decomp_sw_out, 0, decomp_sw_out_sz); memset(decomp_qz_out, 0, decomp_qz_out_sz); } ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz * 8;// bits rate *= 2; rate /= 1024; rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps rc = pthread_mutex_lock(&g_lock_print); assert(0 == rc); QZ_PRINT("[INFO] srv=BOTH, tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); QZ_PRINT(", comp_len=%lu, sw_decomp_len=%lu", comp_out_sz, decomp_sw_out_sz); QZ_PRINT(", comp_len=%lu, qz_decomp_len=%lu", comp_out_sz, decomp_qz_out_sz); QZ_PRINT("\n"); rc = pthread_mutex_unlock(&g_lock_print); assert(0 == rc); done: qzFree(src); qzFree(comp_out); qzFree(decomp_sw_out); qzFree(decomp_qz_out); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressDecompressWithFormatOption(void *arg) { int rc = 0, k; unsigned char *src, *comp_out, *decomp_out; size_t src_sz, comp_out_sz, decomp_out_sz; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const int verify_data = 1; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; QzBlock_T *head, *blk; QzSession_T sess = {0}; if (!org_src_sz) { pthread_exit((void *)"input size is 0"); } head = ((TestArg_T *)arg)->blks; if (head == NULL) { pthread_exit((void *)"No Input -F options or phrase options failed\n"); } blk = head->next; if (blk == NULL) { pthread_exit((void *)"No Input -F options or phrase options failed\n"); } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; QZ_DEBUG("Hello from qzCompressDecompressWithFormatOption tid=%ld, count=%d, service=2, " "verify_data=%d\n", tid, count, verify_data); rc = qzInitSetupsession(&sess, (TestArg_T *)arg); if (rc != QZ_OK) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInitSetupsession rc = %d\n", rc); if (gen_data) { src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { src = ((TestArg_T *)arg)->src; comp_out = ((TestArg_T *)arg)->comp_out; decomp_out = ((TestArg_T *)arg)->decomp_out; } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } el_m = 0; if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); //Compress 1st { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); unsigned int remaining = GET_LOWER_32BITS(src_sz), tmp_src_sz = 0, last = 0; unsigned int tmp_comp_out_sz = GET_LOWER_32BITS(comp_out_sz); unsigned int comp_available_out = GET_LOWER_32BITS(comp_out_sz); unsigned char *tmp_src = src, *tmp_comp_out = comp_out; comp_out_sz = (size_t)0; while (remaining) { if (remaining > blk->size) { tmp_src_sz = blk->size; last = 0; } else { tmp_src_sz = remaining; last = 1; } tmp_comp_out_sz = comp_available_out; if (QZ == blk->fmt) { rc = qzCompress(&sess, tmp_src, &tmp_src_sz, tmp_comp_out, &tmp_comp_out_sz, last); } else { rc = qzSWCompress(&sess, tmp_src, &tmp_src_sz, tmp_comp_out, &tmp_comp_out_sz, last); } tmp_src += tmp_src_sz; tmp_comp_out += tmp_comp_out_sz; comp_out_sz += tmp_comp_out_sz; comp_available_out -= tmp_comp_out_sz; remaining -= tmp_src_sz; QZ_DEBUG("[Thead%ld] Compress: format is %4s, remaining %u, tmp_src_sz is %u\n", tid, g_format_list[blk->fmt - 1].fmt_name, remaining, tmp_src_sz); blk = (blk->next) ? blk->next : head->next; } if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto done; } if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu\n!", src_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } //Decompress { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); unsigned int remaining = GET_LOWER_32BITS(comp_out_sz); unsigned int decomp_available_out = GET_LOWER_32BITS(decomp_out_sz); unsigned char *tmp_comp_out = comp_out, *tmp_decomp_out = decomp_out; unsigned int tmp_comp_out_sz, tmp_decomp_out_sz, decomp_out_sz = 0; while (remaining) { tmp_comp_out_sz = remaining; tmp_decomp_out_sz = decomp_available_out; rc = qzDecompress(&sess, tmp_comp_out, &tmp_comp_out_sz, tmp_decomp_out, &tmp_decomp_out_sz); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } tmp_comp_out += tmp_comp_out_sz; tmp_decomp_out += tmp_decomp_out_sz; decomp_out_sz += tmp_decomp_out_sz; remaining -= tmp_comp_out_sz; decomp_available_out -= tmp_decomp_out_sz; QZ_DEBUG("[Thead%ld] Decompress: remaining %d, tmp_decomp_out_sz is %u\n", tid, remaining, tmp_decomp_out_sz); } if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %u != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %u\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); goto done; } QZ_DEBUG("reset data..\n"); memset(comp_out, 0, (size_t)comp_out_sz); memset(decomp_out, 0, (size_t)decomp_out_sz); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz * 8;// bits rate *= 2; rate /= 1024; rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps rc = pthread_mutex_lock(&g_lock_print); assert(0 == rc); QZ_PRINT("[INFO] srv=BOTH, tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); QZ_PRINT(", comp_len=%lu, decomp_len=%lu", comp_out_sz, decomp_out_sz); QZ_PRINT("\n"); rc = pthread_mutex_unlock(&g_lock_print); assert(0 == rc); done: if (gen_data) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzSetupParamFuncTest(void *arg) { QzSessionParams_T def_params = {0}; QzSessionParams_T new_params = {0}; QzSessionParams_T cus_params = {0}; unsigned char *src, *dest; size_t src_sz, dest_sz, test_dest_sz;; int rc; QzSession_T sess = {0}; src_sz = 256 * 1024; test_dest_sz = dest_sz = 256 * 1024 * 2; src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); dest = qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); if (!src || !dest) { QZ_ERROR("Malloc failed\n"); return NULL; } if (qzGetDefaults(&def_params) != QZ_OK || qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } rc = qzInit(&sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("Err: fail to init HW with ret: %d.\n", rc); goto end; } rc = qzSetupSession(&sess, &def_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto end; } rc = qzCompress(&sess, src, (uint32_t *)(&src_sz), dest, (uint32_t *)(&test_dest_sz), 1); if (rc != QZ_OK) { QZ_ERROR("Err: fail to compress data with ret: %d\n", rc); goto end; } QZ_INFO("With default params, input_len:%lu, output_len:%lu.\n", src_sz, test_dest_sz); test_dest_sz = dest_sz; // Negative Test cus_params.huffman_hdr = QZ_STATIC_HDR + 1; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect huffman: %d.\n", cus_params.huffman_hdr); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.direction = QZ_DIR_BOTH + 1; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect direction: %d.\n", cus_params.direction); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.comp_lvl = 0; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect comp_level: %d.\n", cus_params.comp_lvl); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.comp_lvl = (COMP_LVL_MAXIMUM + 1); if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect comp_level: %d.\n", cus_params.comp_lvl); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.sw_backup = 2; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect sw_backup: %d.\n", cus_params.sw_backup); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.hw_buff_sz = 0; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.hw_buff_sz = 1025; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.hw_buff_sz = 2 * 1024 * 1024; //2M if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } // Positive Test cus_params.huffman_hdr = (QZ_HUFF_HDR_DEFAULT == QZ_DYNAMIC_HDR) ? QZ_STATIC_HDR : QZ_DYNAMIC_HDR; if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to set default params.\n"); goto end; } if (qzGetDefaults(&new_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } if (memcmp(&def_params, &new_params, sizeof(QzSessionParams_T)) == 0) { QZ_ERROR("Err: set default params fail.\n"); goto end; } if (memcmp(&cus_params, &new_params, sizeof(QzSessionParams_T)) != 0) { QZ_ERROR("Err: set default params fail with incorrect value.\n"); QZ_ERROR(" cus_params.huff(%d) != new_params.huff(%d).\n", cus_params.huffman_hdr, new_params.huffman_hdr); goto end; } rc = qzSetupSession(&sess, &new_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto end; } rc = qzCompress(&sess, src, (uint32_t *)(&src_sz), dest, (uint32_t *)(&test_dest_sz), 1); if (rc != QZ_OK) { QZ_ERROR("Err: fail to compress data with ret: %d\n", rc); goto end; } QZ_ERROR("With custom params, input_len:%lu, output_len:%lu.\n", src_sz, test_dest_sz); end: qzFree(src); qzFree(dest); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzTestStopDecompressionOnStreamEnd(void *arg) { /* 1. create a random block of data 2. compress it in multiple streams of size same as HW buffer size(64 K) 3. send the entire compressed blocks for decompression. 4. Since the stop_decompression_stream_end is set , the decompress function will process single block. 5. check whether only first block is decompressed. 6. Size of the decompressed data should be same as HW buffer size i.e chunk/block size. 7. close the session */ int rc; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; size_t org_chunk_sz, comp_sz_partial; QzSessionParamsDeflateExt_T params = {{{0}}}; unsigned char *endofstream = (unsigned char *) malloc(sizeof(char)); orig_sz = comp_sz = decomp_sz = 512 * 1024; /*512K*/ orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } rc = qzGetDefaultsDeflateExt(¶ms); if (rc < 0) { QZ_ERROR("Get defaults params error with error: %d\n", rc); goto done; } switch (((TestArg_T *)arg)->test_format) { case TEST_GZIP: params.deflate_params.data_fmt = QZ_DEFLATE_GZIP; break; case TEST_GZIPEXT: params.deflate_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; case TEST_ZLIB: params.deflate_params.data_fmt = QZ_DEFLATE_RAW; params.zlib_format = 1; break; default: QZ_ERROR("Unsupported data format\n"); goto done; } params.deflate_params.huffman_hdr = ((TestArg_T *)arg)->huffman_hdr; params.deflate_params.common_params.comp_lvl = ((TestArg_T *)arg)->comp_lvl; params.deflate_params.common_params.comp_algorithm = QZ_DEFLATE; params.deflate_params.common_params.hw_buff_sz = QZ_HW_BUFF_SZ; // 64K params.deflate_params.common_params.direction = QZ_DIR_BOTH; params.deflate_params.common_params.polling_mode = QZ_BUSY_POLLING; params.deflate_params.common_params.req_cnt_thrshold = (( TestArg_T *)arg)->req_cnt_thrshold; params.deflate_params.common_params.max_forks = ((TestArg_T *)arg)->max_forks; params.deflate_params.common_params.sw_backup = 0; params.deflate_params.common_params.strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT; params.stop_decompression_stream_end = 1; rc = qzSetupSessionDeflateExt(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSessionDeflateExt for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(orig_src, orig_sz); /*do compress Data*/ src_sz = orig_sz; org_chunk_sz = params.deflate_params.common_params.hw_buff_sz; rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: qzTestEndOfStreamDetectionCompression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: qzTestEndOfStreamDetection After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } QZ_DEBUG("qzTestStopDecompressionOnStreamEndZlib compress src_sz : %lu comp_sz %lu\n", src_sz, comp_sz); /*do decompress Data*/ rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("FAILED: Decompression success with Error\n"); goto done; } if (decomp_sz != org_chunk_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_chunk_sz: %lu \n!", decomp_sz, org_chunk_sz); goto done; } rc = qzGetDeflateEndOfStream(&sess, endofstream); QZ_DEBUG("qzGetDeflateEndOfStream return: %d\n", *endofstream); if (*endofstream != 1) { QZ_ERROR("ERROR: End of stream not detected \n!"); goto done; } QZ_INFO("Decompress stop at first stream end, decomp_sz %lu\n", decomp_sz); /*send only partial compressed block stream for decompression. Checksum check will fail and return QZ_DATA_ERROR for zlib and gzip_ext, for gzip partial stream will give QZ_FAIL. Also endofstream would not be set. */ memset(decomp_src, 0, decomp_sz); comp_sz_partial = 1100; rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz_partial), decomp_src, (uint32_t *)(&decomp_sz)); if (rc == QZ_OK) { QZ_ERROR("FAILED: Decompression should return error for partial stream\n"); } rc = qzGetDeflateEndOfStream(&sess, endofstream); if (*endofstream != 0) { QZ_ERROR("ERROR: incorrect end of stream detected for Partial stream \n!"); } rc = 0; QZ_PRINT("qzTestStopDecompressionOnStreamEnd : PASS\n"); done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzTestStopDecompressionOnStreamEndMultiStream(void *arg) { /* 1. compress first block of size 4k. 2. compress second block of size 4k. 3. send the entire compressed 8k blocks for decompression. 4. Since the stop_decompression_stream_end is set , the decompress function will process single block. 5. check whether only first block is decompressed. 6. Size of the decompressed data should be same as block size(4k). 7. close the session */ int rc; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src, *multicomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz, multicomp_sz; QzSessionParamsDeflateExt_T params = {{{0}}}; unsigned char *endofstream = (unsigned char *) malloc(sizeof(char)); orig_sz = comp_sz = 4 * 1024; /*4K*/ multicomp_sz = decomp_sz = 8 * 1024; /*8K*/ orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); multicomp_src = qzMalloc(multicomp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } rc = qzGetDefaultsDeflateExt(¶ms); if (rc < 0) { QZ_ERROR("Get defaults params error with error: %d\n", rc); goto done; } switch (((TestArg_T *)arg)->test_format) { case TEST_DEFLATE: params.deflate_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIP: params.deflate_params.data_fmt = QZ_DEFLATE_GZIP; break; case TEST_GZIPEXT: params.deflate_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; case TEST_ZLIB: params.deflate_params.data_fmt = QZ_DEFLATE_RAW; params.zlib_format = 1; break; default: QZ_ERROR("Unsupported data format\n"); goto done; } params.deflate_params.huffman_hdr = ((TestArg_T *)arg)->huffman_hdr; params.deflate_params.common_params.comp_lvl = ((TestArg_T *)arg)->comp_lvl; params.deflate_params.common_params.comp_algorithm = QZ_DEFLATE; params.deflate_params.common_params.hw_buff_sz = QZ_HW_BUFF_SZ; // 64K params.deflate_params.common_params.direction = QZ_DIR_BOTH; params.deflate_params.common_params.polling_mode = QZ_BUSY_POLLING; params.deflate_params.common_params.req_cnt_thrshold = (( TestArg_T *)arg)->req_cnt_thrshold; params.deflate_params.common_params.max_forks = ((TestArg_T *)arg)->max_forks; params.deflate_params.common_params.sw_backup = 0; params.deflate_params.common_params.strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT; params.stop_decompression_stream_end = 1; rc = qzSetupSessionDeflateExt(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSessionDeflateExt for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(orig_src, orig_sz); /*do compress Data in 2 streams*/ src_sz = orig_sz; rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: qzTestStopDecompressionOnStreamEndMultiStream FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: qzTestStopDecompressionOnStreamEndMultiStream After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } QZ_DEBUG("qzTestStopDecompressionOnStreamEndMultiStream compress1 src_sz : %lu compressed size: %lu\n", src_sz, comp_sz); memset(multicomp_src, 0, multicomp_sz); // copy the first compressed stream in compressed buffer. memcpy(multicomp_src, comp_src, comp_sz); multicomp_sz = comp_sz; //clear the comp_src and reset comp_sz and again compress the data comp_sz = orig_sz; memset(comp_src, 0, comp_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: qzTestStopDecompressionOnStreamEndMultiStream FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: qzTestStopDecompressionOnStreamEndMultiStream After Compression src_sz: %lu != orig_sz: %lu \n!", src_sz, orig_sz); goto done; } QZ_DEBUG("qzTestStopDecompressionOnStreamEndZlib compress2 src_sz : %lu compressed size %lu\n", src_sz, comp_sz); // copy the first compressed stream in compressed buffer. memcpy(multicomp_src + multicomp_sz, comp_src, comp_sz); multicomp_sz += comp_sz; /*do decompress Data*/ QZ_DEBUG("qzTestStopDecompressionOnStreamEndZlib decompress multicomp_sz : %lu \n", multicomp_sz); rc = qzDecompress(&sess, multicomp_src, (uint32_t *)(&multicomp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("FAILED: Decompression success with Error\n"); goto done; } if (decomp_sz != src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != src_sz: %lu \n!", decomp_sz, src_sz); goto done; } rc = qzGetDeflateEndOfStream(&sess, endofstream); QZ_DEBUG("qzGetDeflateEndOfStream return: %d\n", *endofstream); if (*endofstream != 1) { QZ_ERROR("ERROR: End of stream not detected \n!"); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); qzFree(multicomp_src); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzTestEndOfStreamDetection(void *arg) { /* 1. create a random block of data 2. compress it. 3. send entire block for decompression and check End of stream 4. it should return true. 5. clear the decompression buffer. 6. send only part of compressed data for decompression. 7. query end of stream which should return false 8. close the session */ int rc; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz, comp_sz_partial; QzSessionParamsDeflateExt_T params = {{{0}}}; unsigned char *endofstream = (unsigned char *) malloc(sizeof(char)); orig_sz = comp_sz = decomp_sz = 64 * 1024; /*64K*/ orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } rc = qzGetDefaultsDeflateExt(¶ms); if (rc < 0) { QZ_ERROR("Get defaults params error with error: %d\n", rc); goto done; } params.deflate_params.data_fmt = QZ_DEFLATE_RAW; params.deflate_params.huffman_hdr = ((TestArg_T *)arg)->huffman_hdr; params.deflate_params.common_params.comp_lvl = ((TestArg_T *)arg)->comp_lvl; params.deflate_params.common_params.comp_algorithm = QZ_DEFLATE; params.deflate_params.common_params.hw_buff_sz = QZ_HW_BUFF_MAX_SZ; params.deflate_params.common_params.direction = QZ_DIR_BOTH; params.deflate_params.common_params.polling_mode = QZ_BUSY_POLLING; params.deflate_params.common_params.req_cnt_thrshold = (( TestArg_T *)arg)->req_cnt_thrshold; params.deflate_params.common_params.max_forks = ((TestArg_T *)arg)->max_forks; params.deflate_params.common_params.sw_backup = 0; params.deflate_params.common_params.strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT; rc = qzSetupSessionDeflateExt(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSessionDeflateExt for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(orig_src, orig_sz); /*do compress Data*/ src_sz = orig_sz; rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: qzTestEndOfStreamDetectionCompression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: qzTestEndOfStreamDetection After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } /*do decompress Data*/ rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("FAILED: Decompression success with Error\n"); goto done; } rc = qzGetDeflateEndOfStream(&sess, endofstream); QZ_DEBUG("qzGetDeflateEndOfStream return: %d\n", *endofstream); assert(*endofstream == 1); //send only half of the compressed stream for decompression. and check if eos is not found. //clear the existing decompressed buffer. memset(decomp_src, 0, decomp_sz); comp_sz_partial = 1100; rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz_partial), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("FAILED: Decompression success with Error\n"); goto done; } rc = qzGetDeflateEndOfStream(&sess, endofstream); QZ_DEBUG("qzGetDeflateEndOfStream return: %d\n", *endofstream); assert(*endofstream == 0); rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressAndDecompressExt(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out; int *compressed_blocks_sz = NULL; size_t src_sz, comp_out_sz, decomp_out_sz; size_t block_size, in_sz, out_sz, consumed, produced; size_t num_blocks; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const ServiceType_T service = ((TestArg_T *)arg)->service; const int verify_data = ((TestArg_T *)arg)->verify_data; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; int thread_sleep = ((TestArg_T *)arg)->thread_sleep; QzSession_T sess = {0}; if (!org_src_sz) { pthread_exit((void *)"input size is 0\n"); } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; QZ_DEBUG("Hello from qzCompressAndDecompressExt tid=%ld, count=%d, service=%d, " "verify_data=%d\n", tid, count, service, verify_data); rc = qzInitSetupsessionExt(&sess, (TestArg_T *)arg); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } //timeCheck(3, tid); /* The sleep is for enabling the sw fallback in test. sw fallback simulate hang will happen when detect process generate the 'fatal events'. but detect will happen every seconds. The sleep will guarantee that test capture the 'fatal events' and fallback */ if (thread_sleep > 0) { usleep(thread_sleep); } QZ_DEBUG("qzInitSetupsessionExt rc = %d\n", rc); if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } el_m = 0; if (gen_data) { QZ_DEBUG("Gen Data... src_sz = %lu\n", src_sz); genRandomData(src, src_sz); } //timeCheck(4, tid); block_size = ((TestArg_T *)arg)->block_size; if (-1 == block_size) { block_size = src_sz; } num_blocks = src_sz / block_size + (src_sz % block_size ? 1 : 0); compressed_blocks_sz = malloc(sizeof(int) * num_blocks); if (NULL == compressed_blocks_sz) { QZ_ERROR("Malloc failed\n"); goto done; } memset(compressed_blocks_sz, 0, sizeof(int) * num_blocks); // Compress the data for testing if (DECOMP == service) { consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("DEBUG: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ rc = pthread_mutex_lock(&g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", rc); goto done; } g_ready_thread_count++; rc = pthread_cond_signal(&g_ready_cond); if (rc != 0) { QZ_ERROR("Failure to pthread_cond_signal, status = %d\n", rc); goto done; } while (!g_ready_to_start) { rc = pthread_cond_wait(&g_start_cond, &g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to pthread_cond_wait, status = %d\n", rc); goto done; } } rc = pthread_mutex_unlock(&g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", rc); goto done; } #endif // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); if (DECOMP != service) { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } if (COMP != service) { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; } decomp_out_sz = produced; if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); if (verify_data && COMP != service) { QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); dumpInputData(src_sz, src); goto done; } if (BOTH == service) { QZ_DEBUG("reset data..\n"); memset(comp_out, 0, comp_out_sz); memset(decomp_out, 0, decomp_out_sz); } } ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } /* Verify the last compress is enough decompress data for verify */ if (verify_data && COMP == service) { QZ_DEBUG("verify compress thread %ld, before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; } QZ_DEBUG("verify compressed data..\n"); decomp_out_sz = produced; if (decomp_out_sz != org_src_sz || memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } //timeCheck(5, tid); sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits if (BOTH == service) { rate *= 2; } rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps if (0 != pthread_mutex_lock(&g_lock_print)) { goto done; } QZ_INFO("[INFO] srv="); if (COMP == service) { QZ_INFO("COMP"); } else if (DECOMP == service) { QZ_INFO("DECOMP"); } else if (BOTH == service) { QZ_INFO("BOTH"); } else { QZ_ERROR("UNKNOWN\n"); pthread_mutex_unlock(&g_lock_print); goto done; } QZ_INFO(", tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); if (DECOMP != service) { QZ_INFO(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); } if (COMP != service) { QZ_INFO(", comp_len=%lu, decomp_len=%lu", comp_out_sz, decomp_out_sz); } QZ_INFO("\n"); if (test_thread_safe_flag == 1) { if (thread_sleep == 0) { srand(time(NULL)); thread_sleep = (rand() % 500 + 1) * 1000; } usleep(thread_sleep); } pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); } if (compressed_blocks_sz != NULL) { free(compressed_blocks_sz); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressAndDecompress(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out; int *compressed_blocks_sz = NULL; size_t src_sz, comp_out_sz, decomp_out_sz; size_t block_size, in_sz, out_sz, consumed, produced; size_t num_blocks; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const ServiceType_T service = ((TestArg_T *)arg)->service; const int verify_data = ((TestArg_T *)arg)->verify_data; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; int thread_sleep = ((TestArg_T *)arg)->thread_sleep; QzSession_T sess = {0}; if (!org_src_sz) { pthread_exit((void *)"input size is 0\n"); } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; QZ_DEBUG("Hello from qzCompressAndDecompress tid=%ld, count=%d, service=%d, " "verify_data=%d\n", tid, count, service, verify_data); rc = qzInitSetupsession(&sess, (TestArg_T *)arg); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } //timeCheck(3, tid); /* The sleep is for enabling the sw fallback in test. sw fallback simulate hang will happen when detect process generate the 'fatal events'. but detect will happen every seconds. The sleep will guarantee that test capture the 'fatal events' and fallback */ if (thread_sleep > 0) { usleep(thread_sleep); } QZ_DEBUG("qzInitSetupsession rc = %d\n", rc); if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } el_m = 0; if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } //timeCheck(4, tid); block_size = ((TestArg_T *)arg)->block_size; if (-1 == block_size) { block_size = src_sz; } num_blocks = src_sz / block_size + (src_sz % block_size ? 1 : 0); compressed_blocks_sz = malloc(sizeof(int) * num_blocks); if (NULL == compressed_blocks_sz) { QZ_ERROR("Malloc failed\n"); goto done; } memset(compressed_blocks_sz, 0, sizeof(int) * num_blocks); // Compress the data for testing if (DECOMP == service) { consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ rc = pthread_mutex_lock(&g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", rc); goto done; } g_ready_thread_count++; rc = pthread_cond_signal(&g_ready_cond); if (rc != 0) { QZ_ERROR("Failure to pthread_cond_signal, status = %d\n", rc); goto done; } while (!g_ready_to_start) { rc = pthread_cond_wait(&g_start_cond, &g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to pthread_cond_wait, status = %d\n", rc); goto done; } } rc = pthread_mutex_unlock(&g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", rc); goto done; } #endif // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); if (DECOMP != service) { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } if (COMP != service) { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; } decomp_out_sz = produced; QZ_DEBUG("DEBUG: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); if (verify_data && COMP != service) { QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); dumpInputData(src_sz, src); goto done; } if (BOTH == service) { QZ_DEBUG("reset data..\n"); memset(comp_out, 0, comp_out_sz); memset(decomp_out, 0, decomp_out_sz); } } ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } /* Verify the last compress is enough decompress data for verify */ if (verify_data && COMP == service) { QZ_DEBUG("verify compress thread %ld, before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; } QZ_DEBUG("verify compressed data..\n"); decomp_out_sz = produced; if (decomp_out_sz != org_src_sz || memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } //timeCheck(5, tid); sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits if (BOTH == service) { rate *= 2; } rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps if (0 != pthread_mutex_lock(&g_lock_print)) { goto done; } QZ_PRINT("[INFO] srv="); if (COMP == service) { QZ_PRINT("COMP"); } else if (DECOMP == service) { QZ_PRINT("DECOMP"); } else if (BOTH == service) { QZ_PRINT("BOTH"); } else { QZ_ERROR("UNKNOWN\n"); pthread_mutex_unlock(&g_lock_print); goto done; } QZ_PRINT(", tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); if (DECOMP != service) { QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); } if (COMP != service) { QZ_PRINT(", comp_len=%lu, decomp_len=%lu", comp_out_sz, decomp_out_sz); } QZ_PRINT("\n"); if (test_thread_safe_flag == 1) { if (thread_sleep == 0) { srand(time(NULL)); thread_sleep = (rand() % 500 + 1) * 1000; } usleep(thread_sleep); } pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); } if (compressed_blocks_sz != NULL) { free(compressed_blocks_sz); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzMemFuncTest(void *test_arg) { int i; unsigned char *ptr[1000]; unsigned char *ptr2[1000]; unsigned success = 0; const long tid = ((TestArg_T *)test_arg)->thd_id; QZ_DEBUG("Hello from test2 thread id %ld\n", tid); for (i = 0; i < 1000; i++) { ptr[i] = qzMalloc(100000, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); ptr2[i] = qzMalloc(100000, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); if (ptr[i] == NULL || ptr2[i] == NULL) { QZ_ERROR("[Test2 %ld]\tptr[%d]=0x%lx\t0x%lx\n", tid, i, (unsigned long)ptr[i], (unsigned long)ptr2[i]); if (ptr[i]) { qzFree(ptr[i]); } if (ptr2[i]) { qzFree(ptr2[i]); } break; } success++; } for (i = 0; i < success; i++) { qzFree(ptr[i]); qzFree(ptr2[i]); } for (i = 0; i < success; i++) { if (1 == qzMemFindAddr(ptr[i])) { QZ_DEBUG("[Test2 %ld]\tptr[%d]=0x%lx\tstill as pinned memory after qzFree.\n", tid, i, (unsigned long)ptr[i]); break; } } pthread_exit((void *)NULL); } int qzCompressDecompressWithParams(const TestArg_T *arg, QzSessionParams_T *comp_params, QzSessionParams_T *decomp_params) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; orig_sz = comp_sz = decomp_sz = arg->src_sz; orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return -1; } genRandomData(orig_src, orig_sz); /*do compress Data*/ src_sz = orig_sz; if (qzSetDefaults(comp_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } rc = qzCompress(&comp_sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } /*do decompress Data*/ if (qzSetDefaults(decomp_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } rc = qzDecompress(&decomp_sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); qzClose(&comp_sess); qzClose(&decomp_sess); return rc; } void *qzCompressStreamAndDecompress(void *arg) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; QzStream_T comp_strm = {0}; QzSessionParams_T comp_params = {0}, decomp_params = {0}; uint8_t *orig_src = NULL, *comp_src = NULL, *decomp_src = NULL; size_t orig_sz, comp_sz, decomp_sz; unsigned int slice_sz = 0, done = 0; unsigned int consumed = 0, produced = 0; unsigned int input_left = 0, last = 0; unsigned int decomp_out_sz = 0; int org_in_sz; int offset = 0; TestArg_T *test_arg = (TestArg_T *) arg; orig_sz = comp_sz = decomp_sz = test_arg->src_sz; orig_src = malloc(orig_sz); if (NULL == orig_src) { QZ_ERROR("Err: fail to malloc memory\n"); goto exit; } comp_src = malloc(comp_sz); if (NULL == comp_src) { QZ_ERROR("Err: fail to malloc memory\n"); goto exit; } decomp_src = calloc(orig_sz, 1); if (NULL == decomp_src) { QZ_ERROR("Err: fail to malloc memory\n"); goto exit; } if (qzGetDefaults(&comp_params) != QZ_OK) { QZ_ERROR("Err: get params fail with incorrect compress params.\n"); goto exit; } if (qzGetDefaults(&decomp_params) != QZ_OK) { QZ_ERROR("Err: get params fail with incorrect decompress params.\n"); goto exit; } slice_sz = comp_params.hw_buff_sz / 4; rc = qzInit(&comp_sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("Err: fail to init HW with ret: %d.\n", rc); goto exit; } switch (test_arg->test_format) { case TEST_DEFLATE: comp_params.data_fmt = QZ_DEFLATE_RAW; decomp_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: comp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; decomp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: QZ_ERROR("Unsupported data format in Stream API\n"); goto exit; } QZ_DEBUG("*** Data Format: %d ***\n", comp_params.data_fmt); rc = qzSetupSession(&comp_sess, &comp_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto exit; } rc = qzSetupSession(&decomp_sess, &decomp_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto exit; } genRandomData(orig_src, orig_sz); while (!done) { input_left = orig_sz - consumed; comp_strm.in = orig_src + consumed; comp_strm.out = comp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = comp_sz - produced; last = (((consumed + comp_strm.in_sz) == orig_sz) ? 1 : 0); rc = qzCompressStream(&comp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed is %u, in_sz is %d\n", consumed, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out) { done = 1; } } decomp_out_sz = produced; qzEndStream(&comp_sess, &comp_strm); QZ_DEBUG("qzCompressStream consumed: %d produced: %d\n", consumed, produced); comp_sz = produced; rc = qzDecompress(&decomp_sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(produced, comp_src); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } if (memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpOutputData(comp_sz, comp_src, "comp_out"); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } QZ_PRINT("qzCompressStreamAndDecompress Test PASS\n"); QZ_DEBUG("*** Decompress Stream Test 1 ***\n"); comp_sz = produced; done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); while (!done) { input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = decomp_sz - produced; last = (comp_sz == (consumed + comp_strm.in_sz)) ? 1 : 0; org_in_sz = comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpOutputData(comp_sz, comp_src, "decomp_stream__input"); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed: %d produced: %d input_left: %d last: %d, pending_in: %d, pending_out: %d\n", consumed, produced, input_left, last, comp_strm.pending_in, comp_strm.pending_out); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out && org_in_sz == comp_strm.in_sz) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Memory compare FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_PRINT("*** Decompress Stream Test 1 PASS ***\n"); if (comp_params.data_fmt != QZ_DEFLATE_GZIP_EXT) { goto test_2_end; } QZ_DEBUG("*** Decompress Stream Test 2 ***\n"); done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); QzGzH_T hdr; while (!done) { if (QZ_OK != qzGzipHeaderExt(comp_src + offset, &hdr)) { QZ_ERROR("ERROR: extracting header failed\n"); goto exit; } input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = sizeof(QzGzH_T) + hdr.extra.qz_e.dest_sz + sizeof(StdGzF_T); comp_strm.out_sz = decomp_sz - produced; last = 1; offset += comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Memcmp with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; if (offset == comp_sz) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_PRINT("*** Decompress Stream Test 2 PASS ***\n"); test_2_end: if (comp_params.data_fmt == QZ_DEFLATE_GZIP_EXT) { goto test_3_end; } QZ_DEBUG("*** Decompress Stream Test 3 ***\n"); done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); while (!done) { input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > 256) ? 256 : input_left; comp_strm.out_sz = decomp_sz - produced; last = 1; org_in_sz = comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed: %u produced: %u input_left: %u last: %u, pending_in: %u, pending_out: %u " "org_in_sz: %d in_sz: %u\n", consumed, produced, input_left, last, comp_strm.pending_in, comp_strm.pending_out, org_in_sz, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out && org_in_sz == comp_strm.in_sz && produced == orig_sz && comp_sz - consumed == 0) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Memory compare FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_PRINT("*** Decompress Stream Test 3 PASS***\n"); test_3_end: QZ_DEBUG("*** Decompress Stream Test 4 ***\n"); done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); while (!done) { input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = decomp_sz - produced; last = (comp_sz == (consumed + comp_strm.in_sz)) ? 1 : 0; org_in_sz = comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed: %u produced: %u input_left: %u last: %u, pending_in: %u, pending_out: %u " "org_in_sz: %d in_sz: %u\n", consumed, produced, input_left, last, comp_strm.pending_in, comp_strm.pending_out, org_in_sz, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out && org_in_sz == comp_strm.in_sz && produced == orig_sz && comp_sz - consumed == 0) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Memory compare FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_PRINT("*** Decompress Stream Test 4 PASS***\n"); QZ_PRINT("Compress Stream and Decompress function test: PASS\n"); exit: if (NULL != orig_src) { free(orig_src); orig_src = NULL; } if (NULL != comp_src) { free(comp_src); comp_src = NULL; } if (NULL != decomp_src) { free(decomp_src); decomp_src = NULL; } qzEndStream(&comp_sess, &comp_strm); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); return NULL; } void *qzCompressStreamOnCommonMem(void *thd_arg) { int rc, k; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz, avail_dest_sz; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; const long tid = test_arg->thd_id; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzCompressStreamOnCommonMem id %ld\n", tid); timeCheck(0, tid); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } timeCheck(1, tid); //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } timeCheck(2, tid); QZ_DEBUG("qzSetupSession rc = %d\n", rc); src_sz = QATZIP_MAX_HW_SZ; avail_dest_sz = dest_sz = QATZIP_MAX_HW_SZ; if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); dest = qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } el_m = 0; if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } timeCheck(3, tid); for (k = 0; k < test_arg->count; k++) { dest_sz = avail_dest_sz; (void)gettimeofday(&ts, NULL); comp_strm.in = src; comp_strm.out = dest; comp_strm.in_sz = src_sz; comp_strm.out_sz = dest_sz; last = 1; rc = qzCompressStream(&sess, &comp_strm, last); qzEndStream(&sess, &comp_strm); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } (void)gettimeofday(&te, NULL); QZ_DEBUG("Compressed %lu bytes into %lu\n", src_sz, dest_sz); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } timeCheck(4, tid); sec = (long double)(el_m); sec = sec / 1000000.0; rate = src_sz * test_arg->count * 8; // bits rate = rate / 1000000000.0; // gigbits rate = rate / sec;// Gbps QZ_PRINT("[%ld] elapsed microsec = %llu bytes = %lu rate = %Lf Gbps\n", tid, el_m, src_sz, rate); done: timeCheck(5, tid); if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressStreamOutput(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzCompressStreamOutput\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; switch (test_arg->test_format) { case TEST_DEFLATE: params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: break; } rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); dest = qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; filename = (char *) calloc(1, strlen(g_input_file_name) + 4); if (NULL != filename) { snprintf(filename, strlen(g_input_file_name) + 4, "%s.%s", g_input_file_name, "gz"); } else { QZ_ERROR("Calloc failed\n"); goto done; } } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } { // Add header and tailer for DEFLATE_RAW data, this is simulate from // nginx qatzip module, and it's convenient for us to valid correctness. if (params.data_fmt == QZ_DEFLATE_RAW) { static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; memcpy(dest, gzheader, 10); comp_strm.out = dest + 10; } else { comp_strm.out = dest; } comp_strm.in = src; comp_strm.in_sz = src_sz; comp_strm.out_sz = dest_sz; last = 1; rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } QZ_DEBUG("Compressed %lu bytes into %lu\n", src_sz, dest_sz); // Add tailer for Deflate raw data. if (params.data_fmt == QZ_DEFLATE_RAW) { StdGzF_T *tailer = (StdGzF_T *)(comp_strm.out + comp_strm.out_sz); tailer->crc32 = comp_strm.crc_32; tailer->i_size = comp_strm.in_sz; comp_strm.out_sz += 18; comp_strm.out = dest; } dumpOutputData(comp_strm.out_sz, comp_strm.out, filename); qzEndStream(&sess, &comp_strm); } done: if (gen_data) { qzFree(src); qzFree(dest); } else { free(filename); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzDecompressStreamInput(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; unsigned int consumed, done; QzStream_T decomp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzDecompressStreamInput\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = 1024 * 1024; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { QZ_ERROR("Err: No input file.\n"); goto done; } src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->decomp_out; dest_sz = test_arg->decomp_out_sz; consumed = 0; done = 0; filename = g_input_file_name; if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } { while (!done) { decomp_strm.in = src + consumed; decomp_strm.in_sz = src_sz - consumed; decomp_strm.out = dest; decomp_strm.out_sz = dest_sz; last = 1; rc = qzDecompressStream(&sess, &decomp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzDecompressStream FAILED, return: %d\n", rc); goto done; } QZ_DEBUG("Decompressed %lu bytes into %lu\n", src_sz, dest_sz); dumpDecompressedData(decomp_strm.out_sz, decomp_strm.out, filename); consumed += decomp_strm.in_sz; if (src_sz == consumed && decomp_strm.pending_out == 0) { done = 1; } } qzEndStream(&sess, &decomp_strm); } done: if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressStreamInvalidChunkSize(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; QzSessionParams_T params = {0}; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; const long tid = test_arg->thd_id; QzSession_T sess = {0}; QZ_INFO("Hello from qzCompressStreamInvalidChunkSize id %ld\n", tid); timeCheck(0, tid); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } params.hw_buff_sz = 525312; /*513k*/ rc = qzSetupSession(&sess, ¶ms); if (rc != QZ_PARAMS) { pthread_exit((void *) "qzCompressStreamInvalidChunkSize input param check FAILED"); } params.hw_buff_sz = 100; rc = qzSetupSession(&sess, ¶ms); if (rc != QZ_PARAMS) { pthread_exit((void *) "qzCompressStreamInvalidChunkSize input param check FAILED"); } QZ_PRINT("qzCompressStreamInvalidChunkSize : PASS\n"); done: timeCheck(5, tid); if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressStreamInvalidQzStreamParam(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; const long tid = test_arg->thd_id; QzSession_T sess = {0}; QZ_INFO("Hello from qzCompressStreamInvalidQzStreamParam id %ld\n", tid); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); dest = qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; filename = (char *) calloc(1, strlen(g_input_file_name) + 4); if (NULL != filename) { snprintf(filename, strlen(g_input_file_name) + 4, "%s.%s", g_input_file_name, "gz"); } else { QZ_ERROR("Calloc failed\n"); goto done; } } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } { /*case 1: set strm all params to zero*/ last = 1; memset(&comp_strm, 0, sizeof(QzStream_T)); rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_PARAMS) { QZ_ERROR("qzCompressStream FAILED, return: %d\n", rc); goto done; } QZ_DEBUG("Compressed %lu bytes into %lu\n", src_sz, dest_sz); /*case 2: set strm in, our ptr to NULL, but in_sz, out_sz not zero*/ memset(&comp_strm, 0, sizeof(QzStream_T)); comp_strm.in_sz = src_sz; comp_strm.out_sz = dest_sz; rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_PARAMS) { QZ_ERROR("qzCompressStream FAILED, return: %d\n", rc); goto done; } dumpOutputData(comp_strm.out_sz, comp_strm.out, filename); qzEndStream(&sess, &comp_strm); } QZ_PRINT("qzCompressStreamInvalidQzStreamParam : PASS\n"); done: if (gen_data) { qzFree(src); qzFree(dest); } else { free(filename); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *testqzDecompressStreamInvalidParam(void *arg, int test_no) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; QzStream_T comp_strm = {0}; QzSessionParams_T comp_params = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, comp_sz, decomp_sz; unsigned int slice_sz = 0, done = 0; unsigned int consumed = 0, produced = 0; unsigned int input_left = 0, last = 0; QzSession_T *test_sess = NULL; QzStream_T *test_strm = NULL; TestArg_T *test_arg = (TestArg_T *) arg; orig_sz = comp_sz = decomp_sz = test_arg->src_sz; orig_src = malloc(orig_sz); comp_src = malloc(comp_sz); decomp_src = calloc(orig_sz, 1); if (qzGetDefaults(&comp_params) != QZ_OK) { free(orig_src); free(comp_src); free(decomp_src); QZ_ERROR("Err: fail to get default params.\n"); return NULL; } slice_sz = comp_params.hw_buff_sz / 4; if (NULL == orig_src || NULL == comp_src || NULL == decomp_src) { free(orig_src); free(comp_src); free(decomp_src); QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return NULL; } switch (test_arg->test_format) { case TEST_DEFLATE: comp_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: comp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: QZ_ERROR("Unsupported data format in Stream API\n"); free(orig_src); free(comp_src); free(decomp_src); return NULL; } QZ_DEBUG("*** Data Format: %d ***\n", comp_params.data_fmt); genRandomData(orig_src, orig_sz); while (!done) { input_left = orig_sz - consumed; comp_strm.in = orig_src + consumed; comp_strm.out = comp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = comp_sz - produced; last = (((consumed + comp_strm.in_sz) == orig_sz) ? 1 : 0); rc = qzCompressStream(&comp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed is %u, in_sz is %d\n", consumed, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out) { done = 1; } } qzEndStream(&comp_sess, &comp_strm); QZ_DEBUG("qzCompressStream consumed: %d produced: %d\n", consumed, produced); comp_sz = produced; rc = qzDecompress(&decomp_sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(produced, comp_src); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } if (memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpOutputData(comp_sz, comp_src, "comp_out"); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } QZ_PRINT("qzDecompress Test PASS\n"); QZ_DEBUG("*** Decompress Stream Test ***\n"); comp_sz = produced; done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = decomp_sz - produced; last = (comp_sz == (consumed + comp_strm.in_sz)) ? 1 : 0; if (1 == test_no) { QZ_DEBUG("T#############T DecompressStream Session is null Test ***\n"); test_strm = &comp_strm; } else if (2 == test_no) { QZ_DEBUG("T#############T DecompressStream Neg parameter for last is -1 Test ***\n"); last = -1; test_sess = &comp_sess; test_strm = &comp_strm; } else if (3 == test_no) { QZ_DEBUG("T#############T DecompressStream Neg parameter for last is 2 Test ***\n"); last = 2; test_sess = &comp_sess; test_strm = &comp_strm; } else if (4 == test_no) { QZ_DEBUG("T#############T DecompressStream Neg parameter for strm null Test ***\n"); test_sess = &comp_sess; } else { //nothing to do goto exit; } rc = qzDecompressStream(test_sess, test_strm, last); if (rc == QZ_OK) { QZ_ERROR("T#############T ERROR: qzDecompressStream negative test FAILED: %d*** \n", rc); dumpOutputData(comp_sz, comp_src, "decomp_stream__input"); goto exit; } QZ_DEBUG("T#############T: qzDecompressStream return value: %d*** \n", rc); exit: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); qzEndStream(&comp_sess, &comp_strm); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); qzClose(&comp_sess); qzClose(&decomp_sess); return NULL; } void *qzDecompressStreamNegParam(void *arg) { int test_no = 0; for (test_no = 1; test_no <= 5; test_no++) { QZ_DEBUG("*** qzDecompressStreamNegParam test_no: %d ***\n", test_no); testqzDecompressStreamInvalidParam(arg, test_no); } return NULL; } void *testqzEndStreamInvalidParam(void *arg, int test_no) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; QzStream_T comp_strm = {0}; QzSessionParams_T comp_params = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, comp_sz, decomp_sz; unsigned int slice_sz = 0, done = 0; unsigned int consumed = 0, produced = 0; unsigned int input_left = 0, last = 0; QzSession_T *test_sess = NULL; QzStream_T *test_strm = NULL; TestArg_T *test_arg = (TestArg_T *) arg; orig_sz = comp_sz = decomp_sz = test_arg->src_sz; orig_src = malloc(orig_sz); comp_src = malloc(comp_sz); decomp_src = calloc(orig_sz, 1); if (qzGetDefaults(&comp_params) != QZ_OK) { free(orig_src); free(comp_src); free(decomp_src); QZ_ERROR("Err: fail to get default params.\n"); return NULL; } slice_sz = comp_params.hw_buff_sz / 4; if (NULL == orig_src || NULL == comp_src || NULL == decomp_src) { free(orig_src); free(comp_src); free(decomp_src); QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return NULL; } switch (test_arg->test_format) { case TEST_DEFLATE: comp_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: comp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: QZ_ERROR("Unsupported data format in Stream API\n"); free(orig_src); free(comp_src); free(decomp_src); return NULL; } QZ_DEBUG("*** Data Format: %d ***\n", comp_params.data_fmt); genRandomData(orig_src, orig_sz); while (!done) { input_left = orig_sz - consumed; comp_strm.in = orig_src + consumed; comp_strm.out = comp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = comp_sz - produced; last = (((consumed + comp_strm.in_sz) == orig_sz) ? 1 : 0); rc = qzCompressStream(&comp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed is %u, in_sz is %d\n", consumed, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out) { done = 1; } } if (1 == test_no) { QZ_DEBUG("T#############T qzEndStream Session is null Test ***\n"); test_strm = &comp_strm; } else if (2 == test_no) { QZ_DEBUG("T#############T qzEndStream stream is null Test ***\n"); test_sess = &comp_sess; } else { goto exit; } rc = qzEndStream(test_sess, test_strm); if (rc == QZ_OK) { QZ_ERROR("\nT#############T ERROR: qzEndStream negative test FAILED,return: %d*** \n", rc); goto exit; } QZ_DEBUG("T#############T: qzEndStream return value: %d*** \n", rc); exit: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); qzEndStream(&comp_sess, &comp_strm); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); qzClose(&comp_sess); qzClose(&decomp_sess); return NULL; } void *qzEndStreamNegParam(void *arg) { int test_no = 0; for (test_no = 1; test_no <= 3; test_no++) { QZ_DEBUG("*** qzEndStreamNegParam test_no: %d ***\n", test_no); testqzEndStreamInvalidParam(arg, test_no); } return NULL; } void *qzInitPcieCountCheck(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; unsigned int consumed, done; QzStream_T decomp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Start qzInitPcieCountCheck test\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit1 error. rc = %d\n", rc); } QZ_DEBUG("qzInit1 done. rc = %d, g_process.qat_available = %d\n", rc, g_process.qat_available); qzClose(&sess); QZ_DEBUG("qzClose done. g_process.qat_available = %d\n", g_process.qat_available); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit2 error. rc = %d\n", rc); } QZ_DEBUG("qzInit2 done. rc = %d, g_process.qat_available = %d\n", rc, g_process.qat_available); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = 1024 * 1024; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { QZ_ERROR("Err: No input file.\n"); goto done; } src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->decomp_out; dest_sz = test_arg->decomp_out_sz; consumed = 0; done = 0; filename = g_input_file_name; if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } { while (!done) { decomp_strm.in = src + consumed; decomp_strm.in_sz = src_sz - consumed; decomp_strm.out = dest; decomp_strm.out_sz = dest_sz; last = 1; rc = qzDecompressStream(&sess, &decomp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzDecompressStream FAILED, return: %d\n", rc); goto done; } QZ_DEBUG("Decompressed %lu bytes into %lu\n", src_sz, dest_sz); dumpDecompressedData(decomp_strm.out_sz, decomp_strm.out, filename); consumed += decomp_strm.in_sz; if (src_sz == consumed && decomp_strm.pending_out == 0) { done = 1; } } qzEndStream(&sess, &decomp_strm); } done: if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressDecompressSwQZMixed(void *arg) { enum TestType_E { SW_SW, SW_QZ, QZ_SW, QZ_QZ, NUM_OF_TEST }; struct TestParams_T { enum TestType_E type; char *name; QzSessionParams_T *comp_params; QzSessionParams_T *decomp_params; }; QzSessionParams_T sw_comp_params = {0}, qz_comp_params = {0}, sw_decomp_params = {0}, qz_decomp_params = {0}; int i = 0; if ((qzGetDefaults(&sw_comp_params) != QZ_OK) || (qzGetDefaults(&qz_comp_params) != QZ_OK) || (qzGetDefaults(&sw_decomp_params) != QZ_OK) || (qzGetDefaults(&qz_decomp_params) != QZ_OK)) { QZ_ERROR("Err: fail to get default params.\n"); return NULL; } sw_comp_params.input_sz_thrshold = 512 * 1024; qz_comp_params.input_sz_thrshold = 1024; sw_decomp_params.input_sz_thrshold = 512 * 1024; qz_decomp_params.input_sz_thrshold = 1024; struct TestParams_T test_params[NUM_OF_TEST] = { (struct TestParams_T){SW_SW, "SW compress SW decompress", &sw_comp_params, &sw_decomp_params}, (struct TestParams_T){SW_QZ, "SW compress QZ decompress", &sw_comp_params, &qz_decomp_params}, (struct TestParams_T){QZ_SW, "QZ compress SW decompress", &qz_comp_params, &sw_decomp_params}, (struct TestParams_T){QZ_QZ, "QZ compress QZ decompress", &qz_comp_params, &qz_decomp_params}, }; ((TestArg_T *) arg)->src_sz = 128 * 1024; //128KB for (i = 0; i < NUM_OF_TEST; i++) { if (qzCompressDecompressWithParams(arg, test_params[i].comp_params, test_params[i].decomp_params) < 0) { QZ_ERROR("ERROR: HW/SW mixed function test in: %s \n", test_params[i].name); return NULL; } } QZ_PRINT("HW/SW mixed function test: PASS\n"); return NULL; } int qzDecompressFailedAtUnknownGzipHeader(void) { int rc; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; orig_sz = comp_sz = decomp_sz = 64 * 1024; /*64K*/ orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return -1; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.sw_backup = 0; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(orig_src, orig_sz); /*do compress Data*/ src_sz = orig_sz; rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } /*wrap bad block*/ hdr = (QzGzH_T *)comp_src; hdr->std_hdr.id1 = 0; /* id1 !=0x1f */ /*do decompress Data*/ rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_FAIL) { QZ_ERROR("FAILED: Decompression success with Error GipHeader\n"); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressSWFailedAtUnknownGzipBlock(void) { int rc = 0; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; unsigned int produce; orig_sz = comp_sz = decomp_sz = USDM_ALLOC_MAX_SZ; orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.hw_buff_sz = QZ_HW_BUFF_MAX_SZ; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress Data*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } hdr = (QzGzH_T *)comp_src; produce = hdr->extra.qz_e.dest_sz; /*wrap unknown block*/ memset(hdr + qzGzipHeaderSz(), 0, (size_t)produce); /*Scenario1: produce > DEST_SZ(params.hw_buff_sz)*/ /*set minimum hw size 16K*/ params.hw_buff_sz = 16 * 1024; while (produce < DEST_SZ(params.hw_buff_sz)) { params.hw_buff_sz *= 2; } QZ_DEBUG("produce: %u, DEST_SZ(hw_sz): %d\n", produce, DEST_SZ(params.hw_buff_sz)); rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("ERROR: qzSetupSession FAILED with return value: %d\n", rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_FAIL && rc != QZ_DATA_ERROR) { QZ_ERROR("FAILED: Decompression success with Error Unknown Gzip block\n"); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressHWFailedAtUnknownGzipBlock(void) { int rc = 0; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; QzSessionParams_T params = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; uint32_t produce; orig_sz = comp_sz = decomp_sz = USDM_ALLOC_MAX_SZ; orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.sw_backup = 0; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress Data*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } hdr = (QzGzH_T *)comp_src; produce = hdr->extra.qz_e.dest_sz; /*wrap unknown block*/ memset(hdr + qzGzipHeaderSz(), 'Q', (size_t)produce); /*do Decompress Data*/ rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_FAIL && rc != QZ_DATA_ERROR) { QZ_ERROR("FAILED: Decompression success with Error Unknown Gzip block\n"); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressForceSW(void) { int rc = 0; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; uint32_t consume, produce; orig_sz = comp_sz = decomp_sz = USDM_ALLOC_MAX_SZ; orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.hw_buff_sz = QZ_HW_BUFF_MAX_SZ; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress Data*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } hdr = (QzGzH_T *)comp_src; consume = hdr->extra.qz_e.src_sz; produce = hdr->extra.qz_e.dest_sz; qzTeardownSession(&sess); /*Scenario1: produce > DEST_SZ(params.hw_buff_sz)*/ /*set minimum hw size 2K*/ params.hw_buff_sz = 2 * 1024; while (produce < DEST_SZ(params.hw_buff_sz)) { params.hw_buff_sz *= 2; } QZ_DEBUG("produce: %d, DEST_SZ(hw_sz): %d\n", produce, DEST_SZ(params.hw_buff_sz)); rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("ERROR: qzSetupSession FAILED with return value: %d\n", rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression success with Error GipHeader\n"); goto done; } (void)qzTeardownSession(&sess); /*Scenario2: consume > qzSess->sess_params.hw_buff_sz*/ /*set maximum hw size 1M*/ params.hw_buff_sz = QATZIP_MAX_HW_SZ; while (consume < params.hw_buff_sz) { params.hw_buff_sz /= 2; } QZ_DEBUG("consume: %d, hw_sz: %d\n", consume, params.hw_buff_sz); rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("ERROR: qzSetupSession FAILED with return value: %d\n", rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression success with Error GipHeader\n"); goto done; } done: (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressStandalone(void) { int rc = 0; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; orig_sz = src_sz = comp_sz = decomp_sz = 4 * KB; orig_src = calloc(1, orig_sz); comp_src = calloc(1, comp_sz); decomp_src = calloc(1, decomp_sz); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.hw_buff_sz = 1 * KB; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression failed, orig_sc:%lu != decomp_src:%lu\n", orig_sz, decomp_sz); goto done; } rc = 0; done: free(orig_src); free(comp_src); free(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzCompressFailedAtBufferOverflow(void) { int rc = QZ_BUF_ERROR; QzSession_T sess = {0}; QzSessionParams_T params = {0}; uint8_t *src, *low_comp, *comp, *low_decomp; size_t orig_sz = 64 * KB, low_comp_sz = 1 * KB, comp_sz = orig_sz, low_decomp_sz = 1 * KB; src = calloc(1, orig_sz); low_comp = calloc(1, low_comp_sz); comp = calloc(1, comp_sz); low_decomp = calloc(1, low_decomp_sz); if (NULL == src || NULL == low_comp || NULL == comp || NULL == low_decomp) { goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.hw_buff_sz = 1 * KB; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(src, orig_sz); rc = qzCompress(&sess, src, (uint32_t *)(&orig_sz), comp, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression fail with overflow buffer length:rc = %d\n", rc); goto done; } rc = 0; rc = qzDecompress(&sess, comp, (uint32_t *)(&comp_sz), low_decomp, (uint32_t *)(&low_decomp_sz)); if (rc != QZ_BUF_ERROR) { QZ_ERROR("FAILED: Decompression success with overflow buffer length:rc = %d\n", rc); goto done; } rc = 0; orig_sz = 64 * KB; rc = qzCompress(&sess, src, (uint32_t *)(&orig_sz), low_comp, (uint32_t *)(&low_comp_sz), 1); if (rc != QZ_BUF_ERROR) { QZ_ERROR("FAILED: Compression success with overflow buffer length:rc = %d\n", rc); goto done; } rc = 0; done: free(src); free(comp); free(low_comp); free(low_decomp); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int doQzCompressCrcCheck(size_t orig_sz) { int rc = QZ_BUF_ERROR; QzSession_T sess = {0}; uint8_t *src, *comp; size_t comp_sz = orig_sz; unsigned long crc_sw = 0, crc_qz = 0; src = calloc(1, orig_sz); comp = calloc(1, comp_sz); if (NULL == src || NULL == comp) { goto done; } genRandomData(src, orig_sz); crc_sw = crc32(crc_sw, src, GET_LOWER_32BITS(orig_sz)); rc = qzCompressCrc(&sess, src, (uint32_t *)(&orig_sz), comp, (uint32_t *)(&comp_sz), 1, &crc_qz); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression fail with overflow buffer length:rc = %d\n", rc); goto done; } if (crc_sw != crc_qz) { QZ_ERROR("ERROR: Compression fail on CRC check: SW CRC %lu, QATzip CRC %lu\n", crc_sw, crc_qz); rc = QZ_FAIL; } done: free(src); free(comp); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzCompressCrcCheck(void) { size_t test_sz_qz = (64 * KB), test_sz_sw = (QZ_COMP_THRESHOLD_DEFAULT - 1); size_t test_sz[] = {test_sz_qz, test_sz_sw}; int i, rc = 0; for (i = 0; i < ARRAY_LEN(test_sz); i++) { rc = doQzCompressCrcCheck(test_sz[i]); if (QZ_OK != rc) { goto done; } } done: return rc; } int qzCompressSWL9DecompressHW(void) { int rc = 0; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; orig_sz = comp_sz = decomp_sz = 4 * MB; orig_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); comp_src = qzMalloc(comp_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); decomp_src = qzMalloc(orig_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.input_sz_thrshold = orig_sz + 1; params.comp_lvl = QZ_DEFLATE_COMP_LVL_MAXIMUM; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress data by software*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } /*decompress data by hardware*/ params.input_sz_thrshold = QZ_COMP_THRESHOLD_DEFAULT; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, (size_t)orig_sz)) { QZ_ERROR("ERROR: Decompression success with Error GipHeader\n"); goto done; } done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzFuncTests(void) { int i = 0; int (*sw_failover_func_tests[])(void) = { qzDecompressFailedAtUnknownGzipHeader, qzDecompressSWFailedAtUnknownGzipBlock, qzDecompressHWFailedAtUnknownGzipBlock, qzDecompressStandalone, qzDecompressForceSW, qzCompressSWL9DecompressHW, }; for (i = 0; i < ARRAY_LEN(sw_failover_func_tests); i++) { if (sw_failover_func_tests[i]()) { QZ_ERROR("SWFailOverFunc[%d] : failed\n", i); return -1; } } QZ_PRINT("SWFailOverFunc test : Passed\n"); int (*qz_compress_negative_tests[])(void) = { qzCompressFailedAtBufferOverflow, }; for (i = 0; i < ARRAY_LEN(qz_compress_negative_tests); i++) { if (qz_compress_negative_tests[i]()) { QZ_ERROR("qzCompressNegative[%d] : failed\n", i); return -1; } } QZ_PRINT("qzCompressNegative test : Passed\n"); int (*qz_compress_crc_positive[])(void) = { qzCompressCrcCheck, }; for (i = 0; i < ARRAY_LEN(qz_compress_crc_positive); i++) { if (qz_compress_crc_positive[i]()) { QZ_ERROR("qz_compress_crc_positive[%d] : failed\n", i); return -1; } } QZ_PRINT("qz_compress_crc_positive test : Passed\n"); return 0; } void *qzCompressStreamWithPendingOut(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; unsigned char *out; unsigned int out_sz = 0; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzCompressStreamWithPendingOut\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); dest = qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; filename = (char *) calloc(1, strlen(g_input_file_name) + 4); if (NULL != filename) { snprintf(filename, strlen(g_input_file_name) + 4, "%s.%s", g_input_file_name, "gz"); } else { QZ_ERROR("Calloc failed\n"); goto done; } } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } out = dest; comp_strm.in = src; comp_strm.out = dest; comp_strm.in_sz = src_sz; comp_strm.out_sz = 8192; last = 1; if (comp_strm.in_sz) { rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } out_sz += comp_strm.out_sz; QZ_DEBUG("qzCompressStream in: in:%p out:%p in_sz:%ud out_sz:%ud last:%d", comp_strm.in, comp_strm.out, comp_strm.in_sz, comp_strm.out_sz, last); } while (comp_strm.pending_out > 0) { comp_strm.in = src; comp_strm.out += comp_strm.out_sz; comp_strm.in_sz = 0; comp_strm.out_sz = 8192; last = 1; rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } out_sz += comp_strm.out_sz; QZ_DEBUG("qzCompressStream in: in:%p out:%p in_sz:%ud out_sz:%ud last:%d", comp_strm.in, comp_strm.out, comp_strm.in_sz, comp_strm.out_sz, last); } dumpOutputData(out_sz, out, filename); qzEndStream(&sess, &comp_strm); done: if (gen_data) { qzFree(src); qzFree(dest); } else { free(filename); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *forkResourceCheck(void *arg) { int rc = -1; pid_t pid; int status; char max_hp_str[10] = {0}; int hp_params_fd; size_t number_huge_pages; char *stop = NULL; QzSession_T sess = {0}; QZ_DEBUG("Hello from forkResourceCheck\n"); QZ_INFO("This is parent process, my pid = %d\n", getpid()); QZ_INFO("Before qzInit, qz_init_status in parent process is %d\n", g_process.qz_init_status); if (!((TestArg_T *)arg)->init_engine_disabled) { rc = qzInit(&sess, ((TestArg_T *)arg)->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } } pid = fork(); if (pid > 0) { QZ_INFO("After qzInit, qz_init_status in parent process is %d\n", g_process.qz_init_status); QZ_INFO("instID in parent process is %s\n", g_process.qz_inst[0].instance_info.instID); hp_params_fd = open(MAX_HUGEPAGE_FILE, O_RDONLY); if (hp_params_fd < 0) { QZ_ERROR("Open %s failed\n", MAX_HUGEPAGE_FILE); goto done; } if (read(hp_params_fd, max_hp_str, sizeof(max_hp_str)) < 0) { QZ_ERROR("Read max_huge_pages from %s failed\n", MAX_HUGEPAGE_FILE); close(hp_params_fd); goto done; } number_huge_pages = strtoul(max_hp_str, &stop, 0); if (*stop != '\n') { QZ_ERROR("convert from %s to size_t failed\n", max_hp_str); close(hp_params_fd); goto done; } QZ_INFO("After qzInit, number_huge_pages in parent process is %d\n", (int)number_huge_pages); close(hp_params_fd); wait(&status); } else if (pid == 0) { sleep(2); QZ_INFO("This is child process, my pid = %d\n", getpid()); QZ_INFO("This is child process, my ppid = %d\n", getppid()); g_process.qz_init_status = QZ_NONE; QZ_INFO("Before qzInit, qz_init_status in child process is %d\n", g_process.qz_init_status); if (!((TestArg_T *)arg)->init_engine_disabled) { rc = qzInit(&sess, ((TestArg_T *)arg)->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_INFO("After qzInit, qz_init_status in child process is %d\n", g_process.qz_init_status); QZ_INFO("instID in child process is %s\n", g_process.qz_inst[0].instance_info.instID); } hp_params_fd = open(MAX_HUGEPAGE_FILE, O_RDONLY); if (hp_params_fd < 0) { QZ_ERROR("Open %s failed\n", MAX_HUGEPAGE_FILE); goto done; } if (read(hp_params_fd, max_hp_str, sizeof(max_hp_str)) < 0) { QZ_ERROR("Read max_huge_pages from %s failed\n", MAX_HUGEPAGE_FILE); close(hp_params_fd); goto done; } number_huge_pages = strtoul(max_hp_str, &stop, 0); if (*stop != '\n') { QZ_ERROR("convert from %s to size_t failed\n", max_hp_str); close(hp_params_fd); goto done; } QZ_INFO("After qzInit, number_huge_pages in child process is %d\n", (int)number_huge_pages); close(hp_params_fd); exit(0); } else { perror("fork"); } done: pthread_exit((void *)NULL); } void *qzDecompressStreamWithBufferError(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T decomp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 1; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzDecompressStreamWithBufferError\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT - 1; params.sw_backup = 0; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); dest = qzMalloc(dest_sz, QZ_AUTO_SELECT_NUMA_NODE, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } /*dest_recv_sz > dest_avail_len*/ decomp_strm.in = src; decomp_strm.out = dest; decomp_strm.in_sz = src_sz; decomp_strm.out_sz = dest_sz; rc = qzDecompressStream(&sess, &decomp_strm, last); assert(QZ_FAIL == rc); rc = qzEndStream(&sess, &decomp_strm); done: if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzLSMcompressPerf(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out; int *compressed_blocks_sz = NULL; size_t src_sz, comp_out_sz, decomp_out_sz; size_t block_size, in_sz, out_sz, consumed, produced; size_t num_blocks; struct timeval ts, te; unsigned long long ts_m = 0, te_m = 0, el_m = 0; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const int verify_data = ((TestArg_T *)arg)->verify_data; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; const int SW_only_flag = ((TestArg_T *)arg)->init_engine_disabled; ((TestArg_T *)arg)->init_engine_disabled = 0; const int HW_only_flag = !((TestArg_T *)arg)->sw_backup; ((TestArg_T *)arg)->sw_backup = 1; const unsigned long LSM_max_avg = ULONG_MAX; QzSession_T sess = {0}; QzSess_T *qz_sess = NULL; src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; rc = qzInitSetupsession(&sess, (TestArg_T *)arg); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } qz_sess = (QzSess_T *)(sess.internal); if (qz_sess == NULL) { pthread_exit((void *)"qzInit failed"); } /* According to contorl flow, adjust LSM matrix table*/ if (HW_only_flag) { if (qz_sess->sess_params.is_sensitive_mode) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->SWT.latency_array[i] = LSM_max_avg; } } qz_sess->SWT.arr_avg = LSM_max_avg; } if (SW_only_flag) { if (qz_sess->sess_params.is_sensitive_mode) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->RRT.latency_array[i] = LSM_max_avg; qz_sess->PPT.latency_array[i] = LSM_max_avg; } } qz_sess->PPT.arr_avg = LSM_max_avg; qz_sess->RRT.arr_avg = LSM_max_avg; } /* perpare the test data */ if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } if (gen_data) { genRandomData(src, src_sz); } /* split the src to multiple block */ block_size = ((TestArg_T *)arg)->block_size == -1 ? src_sz : ((TestArg_T *)arg)->block_size; num_blocks = src_sz / block_size + (src_sz % block_size ? 1 : 0); compressed_blocks_sz = malloc(sizeof(int) * num_blocks); memset(compressed_blocks_sz, 0, sizeof(int) * num_blocks); // QZ_PRINT("src len: %lu, block: %lu, num block: %lu\n", src_sz, block_size, num_blocks); /* sync the different thread */ #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ pthread_mutex_lock(&g_cond_mutex); g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); while (!g_ready_to_start) { pthread_cond_wait(&g_start_cond, &g_cond_mutex); } pthread_mutex_unlock(&g_cond_mutex); #endif /* loop test */ for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; /* Because sw would insert 0 to RRT Matrix table every time. * Have to update the Matrix to Max */ if (SW_only_flag) { for (int i = 0; i < LSM_MET_DEPTH; i++) { if (qz_sess->sess_params.is_sensitive_mode) { qz_sess->RRT.latency_array[i] = LSM_max_avg; qz_sess->PPT.latency_array[i] = LSM_max_avg; } } qz_sess->PPT.arr_avg = LSM_max_avg; qz_sess->RRT.arr_avg = LSM_max_avg; } } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } (void)gettimeofday(&te, NULL); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } /* Verify the last compress is enough decompress data for verify */ if (verify_data) { consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } consumed += in_sz; produced += out_sz; } QZ_DEBUG("verify compressed data..\n"); decomp_out_sz = produced; if (decomp_out_sz != org_src_sz || memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("compressed data is uncorrect\n"); goto done; } } sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps pthread_mutex_lock(&g_lock_print); #ifdef QATZIP_DEBUG QZ_PRINT("[INFO]:RRT Total call: %ld, Total avg: %ld\n", qz_sess->RRT.invoke_counter, qz_sess->RRT.sess_lat_avg); QZ_PRINT("[INFO]:SWT Total call: %ld, Total avg: %ld\n", qz_sess->SWT.invoke_counter, qz_sess->SWT.sess_lat_avg); QZ_PRINT("[INFO]:PPT Total call: %ld, Total avg: %ld\n", qz_sess->PPT.invoke_counter, qz_sess->PPT.sess_lat_avg); #endif QZ_PRINT("[INFO] The AVG latency is RRT: %ld, SWT: %ld, PPT: %ld\n", qz_sess->RRT.arr_avg, qz_sess->SWT.arr_avg, qz_sess->PPT.arr_avg); QZ_PRINT("[INFO] invoke counter is RRT: %ld, SWT: %ld, PPT: %ld\n", qz_sess->RRT.invoke_counter, qz_sess->SWT.invoke_counter, qz_sess->PPT.invoke_counter); QZ_PRINT("[INFO] tid=%ld, count=%d, msec=%llu, bytes=%lu, %Lf Gbps", tid, count, el_m, org_src_sz, rate); QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%\n", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); } if (compressed_blocks_sz != NULL) { free(compressed_blocks_sz); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzLSMdecompressPerf(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out; int *compressed_blocks_sz = NULL; size_t src_sz, comp_out_sz, decomp_out_sz; size_t block_size, in_sz, out_sz, consumed, produced; size_t num_blocks; struct timeval ts, te; unsigned long long ts_m = 0, te_m = 0, el_m = 0; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const int verify_data = ((TestArg_T *)arg)->verify_data; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; const int SW_only_flag = ((TestArg_T *)arg)->init_engine_disabled; ((TestArg_T *)arg)->init_engine_disabled = 0; const int HW_only_flag = !((TestArg_T *)arg)->sw_backup; ((TestArg_T *)arg)->sw_backup = 1; const unsigned long LSM_max_avg = ULONG_MAX; QzSession_T sess = {0}; QzSess_T *qz_sess; src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; rc = qzInitSetupsession(&sess, (TestArg_T *)arg); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } /* According to contorl flow, adjust LSM matrix table*/ qz_sess = (QzSess_T *)(sess.internal); if (qz_sess == NULL) { pthread_exit((void *)"qzInit failed"); } if (HW_only_flag) { if (qz_sess->sess_params.is_sensitive_mode) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->SWT.latency_array[i] = LSM_max_avg; } } qz_sess->SWT.arr_avg = LSM_max_avg; } if (SW_only_flag) { if (qz_sess->sess_params.is_sensitive_mode) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->RRT.latency_array[i] = LSM_max_avg; qz_sess->PPT.latency_array[i] = LSM_max_avg; } } qz_sess->PPT.arr_avg = LSM_max_avg; qz_sess->RRT.arr_avg = LSM_max_avg; } /* perpare the test data */ if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } if (gen_data) { genRandomData(src, src_sz); } /* split the src to multiple block */ block_size = ((TestArg_T *)arg)->block_size == -1 ? src_sz : ((TestArg_T *)arg)->block_size; num_blocks = src_sz / block_size + (src_sz % block_size ? 1 : 0); compressed_blocks_sz = malloc(sizeof(int) * num_blocks); memset(compressed_blocks_sz, 0, sizeof(int) * num_blocks); /* Prepare decompress src buffer */ consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } /* sync the different thread */ #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ pthread_mutex_lock(&g_cond_mutex); g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); while (!g_ready_to_start) { pthread_cond_wait(&g_start_cond, &g_cond_mutex); } pthread_mutex_unlock(&g_cond_mutex); #endif /* loop test */ for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; /* Because sw would insert 0 to RRT Matrix table every time. * Have to update the Matrix to Max */ if (SW_only_flag) { if (qz_sess->sess_params.is_sensitive_mode) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->RRT.latency_array[i] = LSM_max_avg; qz_sess->PPT.latency_array[i] = LSM_max_avg; } } qz_sess->PPT.arr_avg = LSM_max_avg; qz_sess->RRT.arr_avg = LSM_max_avg; } } decomp_out_sz = produced; if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } /* Verify the last compress is enough decompress data for verify */ if (verify_data) { if (memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); dumpInputData(src_sz, src); goto done; } } sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps pthread_mutex_lock(&g_lock_print); #ifdef QATZIP_DEBUG QZ_PRINT("[INFO]:RRT Total call: %ld, Total avg: %ld\n", qz_sess->RRT.invoke_counter, qz_sess->RRT.sess_lat_avg); QZ_PRINT("[INFO]:SWT Total call: %ld, Total avg: %ld\n", qz_sess->SWT.invoke_counter, qz_sess->SWT.sess_lat_avg); QZ_PRINT("[INFO]:PPT Total call: %ld, Total avg: %ld\n", qz_sess->PPT.invoke_counter, qz_sess->PPT.sess_lat_avg); #endif QZ_PRINT("[INFO] The AVG latency is RRT: %ld, SWT: %ld, PPT: %ld\n", qz_sess->RRT.arr_avg, qz_sess->SWT.arr_avg, qz_sess->PPT.arr_avg); QZ_PRINT("[INFO] invoke counter is RRT: %ld, SWT: %ld, PPT: %ld\n", qz_sess->RRT.invoke_counter, qz_sess->SWT.invoke_counter, qz_sess->PPT.invoke_counter); QZ_PRINT("[INFO] tid=%ld, count=%d, msec=%llu, bytes=%lu, %Lf Gbps", tid, count, el_m, org_src_sz, rate); QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%\n", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); } if (compressed_blocks_sz != NULL) { free(compressed_blocks_sz); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzLSMHeterogeneousPerf(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out, *decomp_src; size_t src_sz, comp_out_sz, decomp_out_sz; size_t consumed, produced; struct timeval ts, te; unsigned long long ts_m = 0, te_m = 0, el_m = 0; long double sec, rate; /* parse the input params */ const ServiceType_T service = ((TestArg_T *)arg)->service; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; /* LSM params */ const int SW_only_flag = ((TestArg_T *)arg)->init_engine_disabled; ((TestArg_T *)arg)->init_engine_disabled = 0; const int HW_only_flag = !((TestArg_T *)arg)->sw_backup; ((TestArg_T *)arg)->sw_backup = 1; const unsigned long LSM_max_avg = ULONG_MAX; /* max 64kb and min 1 kb */ const int max_block = 64; const int min_block = 1; QzSession_T sess = {0}; QzSess_T *qz_sess; src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; unsigned int block_num = 0; unsigned int *block_in_len = malloc((src_sz / min_block / 1024) * sizeof(unsigned int)); unsigned int *block_out_len = malloc((src_sz / min_block / 1024) * sizeof(unsigned int)); int direction = BOTH; rc = qzInitSetupsession(&sess, (TestArg_T *)arg); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } /* According to contorl flow, adjust LSM matrix table*/ qz_sess = (QzSess_T *)(sess.internal); if (qz_sess == NULL) { pthread_exit((void *)"qzInit failed"); } if (HW_only_flag) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->SWT.latency_array[i] = LSM_max_avg; } qz_sess->SWT.arr_avg = LSM_max_avg; } if (SW_only_flag) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->RRT.latency_array[i] = LSM_max_avg; qz_sess->PPT.latency_array[i] = LSM_max_avg; } qz_sess->PPT.arr_avg = LSM_max_avg; qz_sess->RRT.arr_avg = LSM_max_avg; } /* perpare the test data */ if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); decomp_src = qzMalloc(comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; decomp_src = malloc(comp_out_sz); } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } if (gen_data) { genRandomData(src, src_sz); } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ pthread_mutex_lock(&g_cond_mutex); g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); while (!g_ready_to_start) { pthread_cond_wait(&g_start_cond, &g_cond_mutex); } pthread_mutex_unlock(&g_cond_mutex); #endif /* loop test */ for (k = 0; k < count; k++) { /* Generate the random block size */ { block_num = 0; produced = 0; consumed = 0; int block_size; srand(time(0)); while (produced < org_src_sz) { block_size = (rand() % (max_block - min_block + 1) + min_block) * 1024; block_size = (org_src_sz - produced) > block_size ? block_size : (org_src_sz - produced); block_in_len[block_num] = block_size; block_out_len[block_num] = block_size * 2; produced += block_size; block_num++; QZ_DEBUG("the block %ld is %ld\n", block_num, block_size); } if (produced != org_src_sz) { QZ_ERROR("ERROR: Rondom block error!\n"); goto done; } /* prepare decomp buffer data */ if (service != COMP) { produced = 0; consumed = 0; int temp = qz_sess->sess_params.is_sensitive_mode; qz_sess->sess_params.is_sensitive_mode = 0; for (unsigned int i = 0; i < block_num; i++) { rc = qzCompress(&sess, src + consumed, &block_in_len[i], decomp_src + produced, &block_out_len[i], 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto done; } consumed = consumed + block_in_len[i]; produced = produced + block_out_len[i]; } qz_sess->sess_params.is_sensitive_mode = temp; } } (void)gettimeofday(&ts, NULL); { /* reset params for each loop */ consumed = 0; produced = 0; unsigned int in_sz; unsigned int out_sz; for (unsigned int i = 0; i < block_num ; i++) { in_sz = block_in_len[i]; out_sz = block_out_len[i]; if (service == BOTH) { direction = rand() % 2 ? COMP : DECOMP; } if (service == COMP || direction == COMP) { out_sz = comp_out_sz; rc = qzCompress(&sess, src + consumed, &in_sz, comp_out, &out_sz, 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto done; } } if (service == DECOMP || direction == DECOMP) { in_sz = org_src_sz; rc = qzDecompress(&sess, decomp_src + produced, &out_sz, decomp_out, &in_sz); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } } consumed = consumed + block_in_len[i]; produced = produced + block_out_len[i]; /* Because sw would insert 0 to RRT Matrix table every time. * Have to update the Matrix to Max */ if (SW_only_flag) { if (qz_sess->sess_params.is_sensitive_mode) { for (int i = 0; i < LSM_MET_DEPTH; i++) { qz_sess->RRT.latency_array[i] = LSM_max_avg; qz_sess->PPT.latency_array[i] = LSM_max_avg; } } qz_sess->PPT.arr_avg = LSM_max_avg; qz_sess->RRT.arr_avg = LSM_max_avg; } } } (void)gettimeofday(&te, NULL); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps pthread_mutex_lock(&g_lock_print); #ifdef QATZIP_DEBUG QZ_PRINT("[INFO]:RRT Total call: %ld, Total avg: %ld\n", qz_sess->RRT.invoke_counter, qz_sess->RRT.sess_lat_avg); QZ_PRINT("[INFO]:SWT Total call: %ld, Total avg: %ld\n", qz_sess->SWT.invoke_counter, qz_sess->SWT.sess_lat_avg); QZ_PRINT("[INFO]:PPT Total call: %ld, Total avg: %ld\n", qz_sess->PPT.invoke_counter, qz_sess->PPT.sess_lat_avg); #endif QZ_PRINT("[INFO] The AVG latency is RRT: %ld, SWT: %ld, PPT: %ld\n", qz_sess->RRT.arr_avg, qz_sess->SWT.arr_avg, qz_sess->PPT.arr_avg); QZ_PRINT("[INFO] invoke counter is RRT: %ld, SWT: %ld, PPT: %ld\n", qz_sess->RRT.invoke_counter, qz_sess->SWT.invoke_counter, qz_sess->PPT.invoke_counter); QZ_PRINT("[INFO] tid=%ld, count=%d, msec=%llu, bytes=%lu, %Lf Gbps", tid, count, el_m, org_src_sz, rate); QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%\n", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); } free(block_in_len); free(block_out_len); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } /* Async mode test */ typedef struct CallbackParam_S { sem_t *sem; int num; unsigned char *out; unsigned char *temp_dest; size_t *src_len; size_t *dest_len; size_t *total_produce; } CallbackParam_T; static int TestqzAsyncCallbackFn(QzResult_T *qz_result) { CallbackParam_T *param = (CallbackParam_T *)qz_result->cb_tag; sem_t *sem = param->sem; int num = param->num; unsigned char *out = param->out; unsigned char *temp_dest = param->temp_dest; size_t *total_produce = param->total_produce; if (qz_result->status != QZ_OK) { QZ_ERROR("The request %d failed\n", num); sem_post(sem); return QZ_FAIL; } memcpy(out + (*total_produce), temp_dest, *param->dest_len); *total_produce = *total_produce + *param->dest_len; sem_post(sem); QZ_DEBUG("[AsyncCallback]: num: %d, dest_out: %p, dest_len: %lu\n", num, out, *param->dest_len); return QZ_OK; } void *qzAsyncCompressAndDecompress(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out; int *compressed_blocks_sz = NULL; size_t src_sz, comp_out_sz, decomp_out_sz; size_t block_size, in_sz, out_sz, consumed, produced; size_t num_blocks; struct timeval ts, te; unsigned long long ts_m = 0, te_m = 0, el_m = 0; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const ServiceType_T service = ((TestArg_T *)arg)->service; const int verify_data = ((TestArg_T *)arg)->verify_data; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; QzSession_T sess = {0}; sem_t sem; sem_init(&sem, 0, 0); int num_retry = 0; if (!org_src_sz) { pthread_exit((void *)"input size is 0\n"); } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; QZ_DEBUG("Hello from qzAsyncCompressAndDecompress tid=%ld, count=%d, service=%d, " "verify_data=%d\n", tid, count, service, verify_data); rc = qzInitSetupsession(&sess, (TestArg_T *)arg); QZ_DEBUG("qzInitSetupsession rc = %d\n", rc); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, 0, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, 0, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, 0, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } block_size = ((TestArg_T *)arg)->block_size; if (-1 == block_size) { block_size = src_sz; } num_blocks = src_sz / block_size + (src_sz % block_size ? 1 : 0); // alloc source compressed_blocks_sz = calloc(num_blocks, sizeof(int)); unsigned char *temp_comp_dest = (gen_data && !g_perf_svm) ? qzMalloc(block_size * 2, 0, PINNED_MEM) : malloc(block_size * 2); QzResult_T *qz_result = calloc(num_blocks, sizeof(QzResult_T)); CallbackParam_T *ctg_tag = calloc(num_blocks, sizeof(CallbackParam_T)); // Compress the data for testing if (DECOMP == service) { consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { /* if pthread error exit from those prepare decompression step * would cause the test-main thread hang. */ QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ pthread_mutex_lock(&g_cond_mutex); g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); while (!g_ready_to_start) { pthread_cond_wait(&g_start_cond, &g_cond_mutex); } pthread_mutex_unlock(&g_cond_mutex); #endif // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); if (DECOMP != service) { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; ctg_tag[i].sem = &sem; ctg_tag[i].num = i; ctg_tag[i].out = comp_out; ctg_tag[i].temp_dest = temp_comp_dest; ctg_tag[i].total_produce = &produced; ctg_tag[i].src_len = (size_t *) & (qz_result[i].src_len); ctg_tag[i].dest_len = (size_t *) & (qz_result[i].dest_len); qz_result[i].cb_tag = &(ctg_tag[i]); qz_result[i].src_len = in_sz; qz_result[i].dest_len = out_sz; do { rc = qzCompress2(&sess, src + consumed, temp_comp_dest, TestqzAsyncCallbackFn, &(qz_result[i])); if (unlikely(QZ_FAIL == rc)) { num_retry++; usleep(Async_retry_interval); } if (unlikely(num_retry > Async_retry_max)) { QZ_ERROR("Async submit retry max, you could try to" "extend async queue\n"); break; } } while (rc != QZ_OK); if (rc != QZ_OK) { QZ_ERROR("ERROR: Async compression offload retry\ too much time: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; num_retry = 0; } for (int i = 0; i < num_blocks; i ++) { sem_wait(&sem); } for (int i = 0; i < num_blocks; i ++) { compressed_blocks_sz[i] = qz_result[i].dest_len; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } if (COMP != service) { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; ctg_tag[i].sem = &sem; ctg_tag[i].num = i; ctg_tag[i].out = decomp_out; ctg_tag[i].temp_dest = temp_comp_dest; ctg_tag[i].total_produce = &produced; ctg_tag[i].src_len = (size_t *) & (qz_result[i].src_len); ctg_tag[i].dest_len = (size_t *) & (qz_result[i].dest_len); qz_result[i].cb_tag = &(ctg_tag[i]); qz_result[i].src_len = in_sz; qz_result[i].dest_len = out_sz; do { rc = qzDecompress2(&sess, comp_out + consumed, temp_comp_dest, TestqzAsyncCallbackFn, &(qz_result[i])); if (unlikely(QZ_FAIL == rc)) { num_retry++; usleep(Async_retry_interval); } if (unlikely(num_retry > Async_retry_max)) { QZ_ERROR("Async submit retry max, you could try to" "extend async queue\n"); break; } } while (rc != QZ_OK); if (rc != QZ_OK) { QZ_ERROR("ERROR: Async decompression offload retry\ too much time: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; num_retry = 0; } for (int i = 0; i < num_blocks; i ++) { sem_wait(&sem); } decomp_out_sz = produced; if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } if (verify_data && COMP != service) { QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); dumpInputData(src_sz, src); goto done; } if (BOTH == service) { QZ_DEBUG("reset data..\n"); memset(comp_out, 0, comp_out_sz); memset(decomp_out, 0, decomp_out_sz); } } /* Verify the last compress is enough decompress data for verify */ if (verify_data && COMP == service) { QZ_DEBUG("verify compress thread %ld, before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; } QZ_DEBUG("verify compressed data..\n"); decomp_out_sz = produced; if (decomp_out_sz != org_src_sz || memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } // print result sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits if (BOTH == service) { rate *= 2; } rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps pthread_mutex_lock(&g_lock_print); QZ_PRINT("[INFO] srv="); if (COMP == service) { QZ_PRINT("COMP"); } else if (DECOMP == service) { QZ_PRINT("DECOMP"); } else if (BOTH == service) { QZ_PRINT("BOTH"); } else { QZ_ERROR("UNKNOWN\n"); pthread_mutex_unlock(&g_lock_print); goto done; } QZ_PRINT(", tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); if (DECOMP != service) { QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); } if (COMP != service) { QZ_PRINT(", comp_len=%lu, decomp_len=%lu", comp_out_sz, decomp_out_sz); } QZ_PRINT("\n"); pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); qzFree(temp_comp_dest); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); free(temp_comp_dest); } if (compressed_blocks_sz != NULL) { free(compressed_blocks_sz); } if (ctg_tag != NULL) { free(ctg_tag); } if (qz_result != NULL) { free(qz_result); } sem_destroy(&sem); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } typedef struct CallbackParamPerf_S { int *req_count; int totall_block; pthread_mutex_t *mutex; pthread_cond_t *all_callbacks_called; int num; } CallbackParamPerf_T; static int TestqzAsyncPerfSignalCallbackFn(QzResult_T *qz_result) { CallbackParamPerf_T *param = (CallbackParamPerf_T *)qz_result->cb_tag; int *req_count = param->req_count; int totall_block = param->totall_block; pthread_mutex_t *mutex = param->mutex; pthread_cond_t *all_callbacks_called = param->all_callbacks_called; int num = param->num; if (qz_result->status != QZ_OK) { QZ_ERROR("The request %d failed\n", num); return QZ_FAIL; } pthread_mutex_lock(mutex); *req_count += 1; if (*req_count == totall_block) { pthread_cond_signal(all_callbacks_called); } pthread_mutex_unlock(mutex); QZ_DEBUG("[AsyncCallback]: num: %d\n", num); return QZ_OK; } void *qzAsyncPerfCompressAndDecompress(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out; int *compressed_blocks_sz = NULL; size_t src_sz, comp_out_sz, decomp_out_sz; size_t block_size, in_sz, out_sz, consumed, produced; size_t num_blocks; struct timeval ts, te; unsigned long long ts_m = 0, te_m = 0, el_m = 0; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const ServiceType_T service = ((TestArg_T *)arg)->service; const int verify_data = ((TestArg_T *)arg)->verify_data; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; QzSession_T sess = {0}; sem_t sem; sem_init(&sem, 0, 0); int req_count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t all_callbacks_called = PTHREAD_COND_INITIALIZER; int num_retry = 0; if (!org_src_sz) { pthread_exit((void *)"input size is 0\n"); } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; QZ_DEBUG("Hello from qzAsyncCompressAndDecompress tid=%ld, count=%d, service=%d, " "verify_data=%d\n", tid, count, service, verify_data); rc = qzInitSetupsession(&sess, (TestArg_T *)arg); QZ_DEBUG("qzInitSetupsession rc = %d\n", rc); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, 0, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, 0, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, 0, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } block_size = ((TestArg_T *)arg)->block_size; if (-1 == block_size) { block_size = src_sz; } num_blocks = src_sz / block_size + (src_sz % block_size ? 1 : 0); // alloc source compressed_blocks_sz = calloc(num_blocks, sizeof(int)); QzResult_T *qz_result = calloc(num_blocks, sizeof(QzResult_T)); CallbackParamPerf_T *ctg_tag = calloc(num_blocks, sizeof(CallbackParamPerf_T)); // Compress the data for testing if (DECOMP == service) { consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed += in_sz; produced += in_sz * 2; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ pthread_mutex_lock(&g_cond_mutex); g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); while (!g_ready_to_start) { pthread_cond_wait(&g_start_cond, &g_cond_mutex); } pthread_mutex_unlock(&g_cond_mutex); #endif // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); if (DECOMP != service) { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; ctg_tag[i].req_count = &req_count; ctg_tag[i].totall_block = num_blocks; ctg_tag[i].mutex = &mutex; ctg_tag[i].all_callbacks_called = &all_callbacks_called; ctg_tag[i].num = i; qz_result[i].cb_tag = &(ctg_tag[i]); qz_result[i].src_len = in_sz; qz_result[i].dest_len = out_sz; do { rc = qzCompress2(&sess, src + consumed, comp_out + produced, TestqzAsyncPerfSignalCallbackFn, &qz_result[i]); if (unlikely(QZ_FAIL == rc)) { num_retry++; usleep(Async_retry_interval); } if (unlikely(num_retry > Async_retry_max)) { QZ_ERROR("Async submit retry max, you could try to" "extend async queue\n"); break; } } while (rc != QZ_OK); if (rc != QZ_OK) { QZ_ERROR("ERROR: Async compression offload retry\ too much time: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } num_retry = 0; consumed += in_sz; produced += in_sz * 2; } pthread_mutex_lock(&mutex); pthread_cond_wait(&all_callbacks_called, &mutex); pthread_mutex_unlock(&mutex); req_count = 0; int comp_output_size = 0; for (int i = 0; i < num_blocks; i ++) { compressed_blocks_sz[i] = qz_result[i].dest_len; comp_output_size += qz_result[i].dest_len; } src_sz = consumed; comp_out_sz = comp_output_size; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } if (COMP != service) { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; ctg_tag[i].req_count = &req_count; ctg_tag[i].totall_block = num_blocks; ctg_tag[i].mutex = &mutex; ctg_tag[i].all_callbacks_called = &all_callbacks_called; ctg_tag[i].num = i; qz_result[i].cb_tag = &(ctg_tag[i]); qz_result[i].src_len = in_sz; qz_result[i].dest_len = out_sz; do { rc = qzDecompress2(&sess, comp_out + consumed, decomp_out + produced, TestqzAsyncPerfSignalCallbackFn, &qz_result[i]); if (unlikely(QZ_FAIL == rc)) { num_retry++; usleep(Async_retry_interval); } if (unlikely(num_retry > Async_retry_max)) { QZ_ERROR("Async submit retry max, you could try to" "extend async queue\n"); break; } } while (rc != QZ_OK); if (rc != QZ_OK) { QZ_ERROR("ERROR: Async decompression offload retry\ too much time: %d\n", rc); dumpInputData(src_sz, src); goto done; } num_retry = 0; consumed += block_size * 2; produced += block_size; } pthread_mutex_lock(&mutex); pthread_cond_wait(&all_callbacks_called, &mutex); pthread_mutex_unlock(&mutex); req_count = 0; int decomp_output_size = 0; for (int i = 0; i < num_blocks; i ++) { decomp_output_size += qz_result[i].dest_len; } decomp_out_sz = decomp_output_size; if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } // print result sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits if (BOTH == service) { rate *= 2; } rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps pthread_mutex_lock(&g_lock_print); QZ_PRINT("[INFO] srv="); if (COMP == service) { QZ_PRINT("COMP"); } else if (DECOMP == service) { QZ_PRINT("DECOMP"); } else if (BOTH == service) { QZ_PRINT("BOTH"); } else { QZ_ERROR("UNKNOWN\n"); pthread_mutex_unlock(&g_lock_print); goto done; } QZ_PRINT(", tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); if (DECOMP != service) { QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); } if (COMP != service) { QZ_PRINT(", comp_len=%lu, decomp_len=%lu", comp_out_sz, decomp_out_sz); } QZ_PRINT("\n"); pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); } if (compressed_blocks_sz != NULL) { free(compressed_blocks_sz); } if (ctg_tag != NULL) { free(ctg_tag); } if (qz_result != NULL) { free(qz_result); } sem_destroy(&sem); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } #define STR_INTER(N) #N #define STR(N) STR_INTER(N) #define USAGE_STRING(MAX_LVL) \ "Usage: %s [options]\n" \ "\n" \ "Required options:\n" \ "\n" \ " -m testMode 1 test memcpy feature\n" \ " 2 test Memory\n" \ " 3 test comp/decomp by default parameters\n" \ " 4 test comp/decomp by configurable parameters\n" \ " 5 test comp/decomp by format parameters\n" \ " 6 test set default configurable parameters\n" \ "\n" \ "Optional options can be:\n" \ "\n" \ " -i inputfile input source file\n" \ " default by random generate data \n" \ " -t thread_count maximum forks permitted in the current thread\n" \ " 0 means no forking permitted. \n" \ " -l loop count default is 2\n" \ " -v verify, disabled by default\n" \ " -e init engine enable | disable. enabled by default\n" \ " -s init session enable | disable. enabled by default\n" \ " -A comp_algorithm deflate | lz4 | lz4s\n" \ " -B swBack 0 means disable sw\n" \ " 1 means enable sw\n" \ " -C hw_buff_sz default 64K\n" \ " -b block_size If set this option, the test will split test\n" \ " data into pieces. qzCompress/qzDecompress will\n"\ " de/compress block_size bytes every time.\n" \ " It must be the power of 2. The minimum is 4k,\n" \ " and maximum is 1M. Default is -1, don't split \n" \ " the test data.\n" \ " -D direction comp | decomp | both\n" \ " -F format [comp format]:[orig data size]/...\n" \ " -L comp_lvl 1 - " STR(MAX_LVL) "\n" \ " -O data_fmt deflate | gzip | gzipext | deflate_4B | lz4 | lz4s | zlib\n"\ " For zlib and deflate raw the block size must be same \n"\ " as HW buffer size, e.g '-b' and '-C' should be same. \n" \ " -T huffmanType static | dynamic\n" \ " -r req_cnt_thrshold max in-flight request num, default is 16\n" \ " -S thread_sleep the unit is milliseconds, default is a random time\n" \ " -P polling set polling mode, default is periodical polling\n" \ " when set busy polling mode, it would automaticlly \n" \ " enable the LSM(latency sensitive mode) \n" \ " -M svm set perf mode with file input, default is non\n" \ " svm mode. When set to svm, all memory will\n" \ " be allocated with malloc instead of qzMalloc\n" \ " This option is only applied to test case 4\n" \ " -p compress_buf_type pinned | common, default is common\n" \ " This option is only applied to file compression test in case 4\n" \ " If set common, memory of compress buffer will be allocated through malloc\n" \ " If set pinned, memory of compress buffer will be allocated in huge page, the\n" \ " allocation limit is 2M\n" \ " -g loglevel set qatzip loglevel(none|error|warn|info|debug)\n" \ " -a sensitive_mode Enable Latency sensitive mode\n" \ " -q async_queue_sz default is 100, it's for async queue size\n" \ " -h Print this help message\n" void qzPrintUsageAndExit(char *progName) { QZ_ERROR(USAGE_STRING(COMP_LVL_MAXIMUM), progName); exit(-1); } static int qz_do_g_process_Check(void) { if (g_process.qz_init_status == QZ_OK && g_process.sw_backup == 1 && (g_process.num_instances == G_PROCESS_NUM_INSTANCES_12 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_4 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_16 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_32 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_8 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_64) && g_process.qat_available == CPA_TRUE) { return QZ_OK; } else { return QZ_FAIL; } } int main(int argc, char *argv[]) { int rc = 0, ret = 0, rc_check = 0; int i = 0; void *p_rc; int thread_count = 1, test = 0; ServiceType_T service = COMP; pthread_t threads[100] = {0}; TestArg_T test_arg[100] = {0}; struct sigaction s1; int block_size = -1; PinMem_T compress_buf_type = COMMON_MEM; TestArg_T args = {0}; unsigned char *input_buf = NULL; unsigned int input_buf_len = QATZIP_MAX_HW_SZ; int thread_sleep = 0; s1.sa_handler = sigInt; sigemptyset(&s1.sa_mask); s1.sa_flags = 0; sigaction(SIGINT, &s1, NULL); const char *optstring = "m:t:A:C:D:F:L:T:i:l:e:s:r:B:O:S:P:M:b:p:g:d:q:vha"; int opt = 0, loop_cnt = 2, verify = 0; int disable_init_engine = 0, disable_init_session = 0; char *stop = NULL; QzThdOps *qzThdOps = NULL; QzBlock_T *qzBlocks = NULL; errno = 0; QzSessionParamsDeflate_T default_params = {{0}}; rc = qzGetDefaultsDeflate(&default_params); if (rc != QZ_OK) { QZ_ERROR("Get default params error\n"); return -1; } args.test_format = TEST_GZIPEXT; args.comp_algorithm = default_params.common_params.comp_algorithm; args.sw_backup = default_params.common_params.sw_backup; args.hw_buff_sz = default_params.common_params.hw_buff_sz; args.comp_lvl = default_params.common_params.comp_lvl; args.huffman_hdr = default_params.huffman_hdr; args.polling_mode = default_params.common_params.polling_mode; args.req_cnt_thrshold = default_params.common_params.req_cnt_thrshold; args.max_forks = default_params.common_params.max_forks; while ((opt = getopt(argc, argv, optstring)) != -1) { switch (opt) { case 'm': // test case test = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error input: %s\n", optarg); return -1; } break; case 't': thread_count = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); args.max_forks = thread_count; if (*stop != '\0' || errno || thread_count > 100) { QZ_ERROR("Error thread count arg: %s\n", optarg); return -1; } break; case 'A': if (strcmp(optarg, "deflate") == 0) { args.comp_algorithm = QZ_DEFLATE; } else if (strcmp(optarg, "lz4") == 0) { args.comp_algorithm = QZ_LZ4; } else if (strcmp(optarg, "lz4s") == 0) { args.comp_algorithm = QZ_LZ4s; } else { QZ_ERROR("Error service arg: %s\n", optarg); return -1; } break; case 'O': if (strcmp(optarg, "deflate") == 0) { args.test_format = TEST_DEFLATE; } else if (strcmp(optarg, "gzip") == 0) { args.test_format = TEST_GZIP; } else if (strcmp(optarg, "gzipext") == 0) { args.test_format = TEST_GZIPEXT; } else if (strcmp(optarg, "deflate_4B") == 0) { args.test_format = TEST_DEFLATE_4B; } else if (strcmp(optarg, "lz4") == 0) { args.test_format = TEST_LZ4; } else if (strcmp(optarg, "lz4s") == 0) { args.test_format = TEST_LZ4S; } else if (strcmp(optarg, "zlib") == 0) { args.test_format = TEST_ZLIB; } else { QZ_ERROR("Error service arg: %s\n", optarg); return -1; } break; case 'B': args.sw_backup = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno || (args.sw_backup != 0 && args.sw_backup != 1)) { QZ_ERROR("Error input: %s\n", optarg); return -1; } break; case 'C': args.hw_buff_sz = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno || args.hw_buff_sz > USDM_ALLOC_MAX_SZ / 2) { QZ_ERROR("Error chunkSize arg: %s\n", optarg); return -1; } break; case 'D': if (strcmp(optarg, "comp") == 0) { service = COMP; } else if (strcmp(optarg, "decomp") == 0) { service = DECOMP; } else if (strcmp(optarg, "both") == 0) { service = BOTH; } else { QZ_ERROR("Error service arg: %s\n", optarg); return -1; } break; case 'F': qzBlocks = parseFormatOption(optarg); if (NULL == qzBlocks) { QZ_ERROR("Error format arg: %s\n", optarg); return -1; } break; case 'L': args.comp_lvl = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno || \ args.comp_lvl > COMP_LVL_MAXIMUM || args.comp_lvl <= 0) { QZ_ERROR("Error compLevel arg: %s\n", optarg); return -1; } break; case 'T': if (strcmp(optarg, "static") == 0) { args.huffman_hdr = QZ_STATIC_HDR; } else if (strcmp(optarg, "dynamic") == 0) { args.huffman_hdr = QZ_DYNAMIC_HDR; } else { QZ_ERROR("Error huffman arg: %s\n", optarg); return -1; } break; case 'l': loop_cnt = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error loop count arg: %s\n", optarg); return -1; } break; case 'v': verify = 1; break; case 'a': args.is_sensitive_mode = true; break; case 'i': g_input_file_name = optarg; break; case 'e': if (strcmp(optarg, "enable") == 0) { disable_init_engine = 0; } else if (strcmp(optarg, "disable") == 0) { disable_init_engine = 1; } else { QZ_ERROR("Error init qat engine arg: %s\n", optarg); return -1; } break; case 's': if (strcmp(optarg, "enable") == 0) { disable_init_session = 0; } else if (strcmp(optarg, "disable") == 0) { disable_init_session = 1; } else { QZ_ERROR("Error init qat session arg: %s\n", optarg); return -1; } break; case 'r': args.req_cnt_thrshold = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error req_cnt_thrshold arg: %s\n", optarg); return -1; } break; case 'S': thread_sleep = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error thread_sleep arg: %s\n", optarg); return -1; } thread_sleep *= 1000; break; case 'P': if (strcmp(optarg, "busy") == 0) { args.polling_mode = QZ_BUSY_POLLING; } else { QZ_ERROR("Error set polling mode: %s\n", optarg); return -1; } break; case 'M': if (strcmp(optarg, "svm") == 0) { g_perf_svm = true; } else { QZ_ERROR("Error set perf mode: %s\n", optarg); return -1; } break; case 'b': block_size = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno || ((block_size & (block_size - 1)) != 0) || block_size < 1024 || block_size > 1024 * 1024) { QZ_ERROR("Error block size arg: %s, please set it to the power of 2 in range of 4k to 1M.\n", optarg); return -1; } break; case 'p': if (strcmp(optarg, "pinned") == 0) { compress_buf_type = PINNED_MEM; } else if (strcmp(optarg, "common") == 0) { compress_buf_type = COMMON_MEM; } else { QZ_ERROR("Error compress_buf_type arg: %s\n", optarg); return -1; } break; case 'g': if (strcmp(optarg, "none") == 0) { qzSetLogLevel(LOG_NONE); } else if (strcmp(optarg, "error") == 0) { qzSetLogLevel(LOG_ERROR); } else if (strcmp(optarg, "warn") == 0) { qzSetLogLevel(LOG_WARNING); } else if (strcmp(optarg, "info") == 0) { qzSetLogLevel(LOG_INFO); } else if (strcmp(optarg, "debug") == 0) { qzSetLogLevel(LOG_DEBUG1); } else { QZ_ERROR("Error log level: %s\n", optarg); } break; case 'q': async_queue_size = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error async queue size arg: %s\n", optarg); return -1; } break; case 'd': lsm_met_len_shift = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); break; default: qzPrintUsageAndExit(argv[0]); } } if (test == 0) { qzPrintUsageAndExit(argv[0]); } switch (test) { case 1: QZ_ERROR("Test mode 1 has been removed\n"); return 0; case 2: qzThdOps = qzMemFuncTest; break; case 3: QZ_ERROR("Test mode 3 has been removed\n"); return 0; case 4: qzThdOps = qzCompressAndDecompress; break; case 5: qzThdOps = qzCompressDecompressWithFormatOption; break; case 6: qzThdOps = qzSetupParamFuncTest; break; case 7: qzThdOps = qzDecompressSwQz; break; case 8: qzThdOps = qzCompressDecompressSwQZMixed; break; case 9: qzThdOps = qzCompressStreamAndDecompress; break; case 10: qzThdOps = qzCompressStreamOnCommonMem; break; case 11: qzThdOps = qzCompressStreamOutput; break; case 12: qzThdOps = qzDecompressStreamInput; break; case 13: qzThdOps = qzCompressStreamInvalidChunkSize; break; case 14: qzThdOps = qzCompressStreamInvalidQzStreamParam; break; case 15: qzThdOps = qzDecompressStreamNegParam; break; case 16: qzThdOps = qzEndStreamNegParam; break; case 17: return qzFuncTests(); break; case 18: test_thread_safe_flag = 1; qzThdOps = qzCompressAndDecompress; break; case 19: qzThdOps = qzInitPcieCountCheck; break; case 20: qzThdOps = qzCompressStreamWithPendingOut; break; case 21: qzThdOps = forkResourceCheck; break; case 22: qzThdOps = qzDecompressStreamWithBufferError; break; case 23: qzThdOps = qzLSMcompressPerf; break; case 24: qzThdOps = qzLSMdecompressPerf; break; case 25: qzThdOps = qzLSMHeterogeneousPerf; break; case 26: qzThdOps = qzCompressAndDecompressExt; break; case 27: qzThdOps = qzTestEndOfStreamDetection; break; case 28: qzThdOps = qzAsyncCompressAndDecompress; break; case 29: qzThdOps = qzAsyncPerfCompressAndDecompress; break; case 30: qzThdOps = qzTestStopDecompressionOnStreamEnd; break; case 31: qzThdOps = qzTestStopDecompressionOnStreamEndMultiStream; break; default: goto done; } if (g_input_file_name != NULL) { FILE *file; struct stat file_state; if (stat(g_input_file_name, &file_state)) { QZ_ERROR("ERROR: fail to get stat of file %s\n", g_input_file_name); return -1; } input_buf_len = GET_LOWER_32BITS((file_state.st_size > QATZIP_MAX_HW_SZ ? QATZIP_MAX_HW_SZ : file_state.st_size)); if (test == 4 || test == 10 || test == 11 || test == 12 || test == 23 || test == 24 || test == 25 || test == 26 || test == 28 || test == 29) { input_buf_len = GET_LOWER_32BITS(file_state.st_size); } if (compress_buf_type == PINNED_MEM) { if (input_buf_len > MAX_HUGE_PAGE_SZ) { QZ_ERROR("ERROR: only can allocate 2M memory in huge page\n"); return -1; } input_buf = qzMalloc(input_buf_len, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { input_buf = malloc(input_buf_len); } if (!input_buf) { QZ_ERROR("ERROR: fail to alloc %d bytes of memory with qzMalloc\n", input_buf_len); return -1; } file = fopen(g_input_file_name, "rb"); if (!file) { QZ_ERROR("ERROR: fail to read file %s\n", g_input_file_name); goto done; } if (fread(input_buf, 1, input_buf_len, file) != input_buf_len) { QZ_ERROR("ERROR: fail to read file %s\n", g_input_file_name); fclose(file); goto done; } else { QZ_DEBUG("Read %d bytes from file %s\n", input_buf_len, g_input_file_name); } fclose(file); } for (i = 0; i < thread_count; i++) { test_arg[i] = args; test_arg[i].thd_id = i; test_arg[i].service = service; test_arg[i].verify_data = verify; test_arg[i].debug = 0; test_arg[i].count = loop_cnt; test_arg[i].src_sz = GET_LOWER_32BITS(input_buf_len); if (compress_buf_type == PINNED_MEM) { test_arg[i].comp_out_sz = test_arg[i].src_sz; test_arg[i].src = input_buf; test_arg[i].comp_out = qzMalloc(test_arg[i].comp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); test_arg[i].decomp_out_sz = test_arg[i].src_sz; test_arg[i].decomp_out = qzMalloc(test_arg[i].decomp_out_sz, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); } else { test_arg[i].comp_out_sz = test_arg[i].src_sz * 2; test_arg[i].src = input_buf; test_arg[i].comp_out = malloc(test_arg[i].comp_out_sz); test_arg[i].decomp_out_sz = test_arg[i].src_sz * 5; test_arg[i].decomp_out = malloc(test_arg[i].decomp_out_sz); } test_arg[i].gen_data = g_input_file_name ? 0 : 1; test_arg[i].init_engine_disabled = disable_init_engine; test_arg[i].init_sess_disabled = disable_init_session; test_arg[i].ops = qzThdOps; test_arg[i].blks = qzBlocks; test_arg[i].thread_sleep = thread_sleep; test_arg[i].block_size = block_size; if (!test_arg[i].comp_out || !test_arg[i].decomp_out) { QZ_ERROR("ERROR: fail to create memory for thread %d\n", i); goto done; } } srand((uint32_t)getpid()); (void)gettimeofday(&g_timer_start, NULL); #ifdef ENABLE_THREAD_BARRIER pthread_barrier_init(&g_bar, NULL, thread_count); #endif for (i = 0; i < thread_count; i++) { rc = pthread_create(&threads[i], NULL, test_arg[i].ops, (void *)&test_arg[i]); if (0 != rc) { QZ_ERROR("Error from pthread_create %d\n", rc); goto done; } } #ifndef ENABLE_THREAD_BARRIER /*for qzCompressAndDecompress test*/ if (test == 4 || test == 18 || test == 23 || test == 24 || test == 25 || test == 26 || test == 28 || test == 29) { ret = pthread_mutex_lock(&g_cond_mutex); if (ret != 0) { QZ_ERROR("Failure to get Mutex Lock, status = %d\n", ret); goto done; } while (g_ready_thread_count < thread_count) { ret = pthread_cond_wait(&g_ready_cond, &g_cond_mutex); if (ret != 0) { pthread_mutex_unlock(&g_cond_mutex); QZ_ERROR("Failure calling pthread_cond_wait, status = %d\n", ret); goto done; } } g_ready_to_start = 1; ret = pthread_cond_broadcast(&g_start_cond); if (ret != 0) { pthread_mutex_unlock(&g_cond_mutex); QZ_ERROR("Failure calling pthread_cond_broadcast, status = %d\n", ret); goto done; } ret = pthread_mutex_unlock(&g_cond_mutex); if (ret != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", ret); goto done; } } #endif for (i = 0; i < thread_count; i++) { timeCheck(10, i); rc = pthread_join(threads[i], (void *)&p_rc); if (0 != rc) { QZ_ERROR("Error from pthread_join %d\n", rc); break; } if (NULL != p_rc) { QZ_ERROR("Error from pthread_exit %s\n", (char *)p_rc); ret = -1; } } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_destroy(&g_bar); #endif if (test == 18) { rc_check = qz_do_g_process_Check(); if (QZ_OK == rc_check) { QZ_PRINT("Check g_process PASSED\n"); } else { ret = -1; QZ_PRINT("Check g_process FAILED\n"); } } done: if (NULL != qzBlocks) { QzBlock_T *tmp, *blk = qzBlocks; while (blk) { tmp = blk; blk = blk->next; free(tmp); } } /* free memory */ if (NULL != input_buf) { if (compress_buf_type == PINNED_MEM) { qzFree(input_buf); } else { free(input_buf); } } for (i = 0; i < thread_count; i++) { if (NULL != test_arg[i].comp_out) { if (compress_buf_type == PINNED_MEM) { qzFree(test_arg[i].comp_out); } else { free(test_arg[i].comp_out); } } if (NULL != test_arg[i].decomp_out) { if (compress_buf_type == PINNED_MEM) { qzFree(test_arg[i].decomp_out); } else { free(test_arg[i].decomp_out); } } } return (ret != 0) ? ret : rc; } QATzip-1.3.1/test/performance_tests/000077500000000000000000000000001500263377000173715ustar00rootroot00000000000000QATzip-1.3.1/test/performance_tests/config_file/000077500000000000000000000000001500263377000216355ustar00rootroot00000000000000QATzip-1.3.1/test/performance_tests/config_file/4xxx/000077500000000000000000000000001500263377000225505ustar00rootroot00000000000000QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev0.conf000066400000000000000000000127141500263377000252550ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev1.conf000066400000000000000000000127141500263377000252560ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev2.conf000066400000000000000000000127141500263377000252570ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev3.conf000066400000000000000000000127141500263377000252600ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev4.conf000066400000000000000000000127141500263377000252610ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev5.conf000066400000000000000000000127141500263377000252620ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev6.conf000066400000000000000000000127141500263377000252630ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/4xxx/4xxx_dev7.conf000066400000000000000000000127141500263377000252640ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.3.1/test/performance_tests/config_file/c3xxx/000077500000000000000000000000001500263377000227125ustar00rootroot00000000000000QATzip-1.3.1/test/performance_tests/config_file/c3xxx/c3xxx_dev0.conf000066400000000000000000000132361500263377000255610ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 4 LimitDevAccess = 1 # Crypto - User instance #0 Cy0Name = "SSL0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "SSL1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 1 # Crypto - User instance #2 Cy2Name = "SSL2" Cy2IsPolled = 1 # List of core affinities Cy2CoreAffinity = 2 # Crypto - User instance #3 Cy3Name = "SSL3" Cy3IsPolled = 1 # List of core affinities Cy3CoreAffinity = 3 # Crypto - User instance #4 Cy4Name = "SSL4" Cy4IsPolled = 1 # List of core affinities Cy4CoreAffinity = 4 # Crypto - User instance #5 Cy5Name = "SSL5" Cy5IsPolled = 1 # List of core affinities Cy5CoreAffinity = 5 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 1 QATzip-1.3.1/test/performance_tests/config_file/c6xx/000077500000000000000000000000001500263377000225255ustar00rootroot00000000000000QATzip-1.3.1/test/performance_tests/config_file/c6xx/c6xx_dev0.conf000066400000000000000000000112671500263377000252110ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.3.1/test/performance_tests/config_file/c6xx/c6xx_dev1.conf000066400000000000000000000112671500263377000252120ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.3.1/test/performance_tests/config_file/c6xx/c6xx_dev2.conf000066400000000000000000000112671500263377000252130ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.3.1/test/performance_tests/config_file/dh895xcc/000077500000000000000000000000001500263377000231745ustar00rootroot00000000000000QATzip-1.3.1/test/performance_tests/config_file/dh895xcc/dh895xcc_dev0.conf000066400000000000000000000105131500263377000263200ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # This flag is to enable SSF features StorageEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.3.1/test/performance_tests/run_perf_test.sh000077500000000000000000000106671500263377000226210ustar00rootroot00000000000000#! /bin/bash ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ set -e echo "***QZ_ROOT run_perf_test.sh start" rm -f result_comp_stderr rm -f result_decomp_stderr CURRENT_PATH=`dirname $(readlink -f "$0")` #check whether qatzip-test exists if [ ! -f "$QZ_ROOT/test/qatzip-test" ]; then echo "$QZ_ROOT/test/qatzip-test: No such file. Compile first!" exit 1 fi #get the type of QAT hardware platform=`lspci | grep Co-processor | awk '{print $6}' | head -1` if [[ $platform != "37c8" && $platform != "4940" ]] then platform=`lspci | grep Co-processor | awk '{print $5}' | head -1` if [[ $platform != "DH895XCC" && $platform != "C62x" ]] then platform=`lspci | grep Co-processor | awk '{print $7}' | head -1` if [ $platform != "C3000" ] then echo "Unsupported Platform: `lspci | grep Co-processor` " exit 1 fi fi fi echo "platform=$platform" #Replace the driver configuration files and configure hugepages echo "Replace the driver configuration files and configure hugepages." if [[ $platform = "37c8" || $platform = "C62x" ]] then process=24 \cp $CURRENT_PATH/config_file/c6xx/c6xx_dev0.conf /etc \cp $CURRENT_PATH/config_file/c6xx/c6xx_dev1.conf /etc \cp $CURRENT_PATH/config_file/c6xx/c6xx_dev2.conf /etc elif [ $platform = "DH895XCC" ] then process=8 \cp $CURRENT_PATH/config_file/dh895xcc/dh895xcc_dev0.conf /etc elif [ $platform = "4940" ] then process=48 \cp $CURRENT_PATH/config_file/4xxx/4xxx*.conf /etc elif [ $platform = "C3000" ] then process=4 \cp $CURRENT_PATH/config_file/c3xxx/c3xxx_dev0.conf /etc fi /etc/init.d/qat_service restart echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages rmmod usdm_drv insmod $ICP_ROOT/build/usdm_drv.ko max_huge_pages=1024 max_huge_pages_per_process=24 sleep 5 #Perform performance test echo "Perform performance test" thread=4 if [ $platform = "4940" ] then thread=1 fi echo > result_comp cpu_list=0 for((numProc_comp = 0; numProc_comp < $process; numProc_comp ++)) do taskset -c $cpu_list $QZ_ROOT/test/qatzip-test -m 4 -l 1000 -t $thread -D comp >> result_comp 2>> result_comp_stderr & cpu_list=$(($cpu_list + 1)) done wait compthroughput=`awk '{sum+=$8} END{print sum}' result_comp` echo "compthroughput=$compthroughput Gbps" echo > result_decomp cpu_list=0 for((numProc_decomp = 0; numProc_decomp < $process; numProc_decomp ++)) do taskset -c $cpu_list $QZ_ROOT/test/qatzip-test -m 4 -l 1000 -t $thread -D decomp >> result_decomp 2>> result_decomp_stderr & cpu_list=$(($cpu_list + 1)) done wait decompthroughput=`awk '{sum+=$8} END{print sum}' result_decomp` echo "decompthroughput=$decompthroughput Gbps" rm -f result_comp rm -f result_decomp echo "***QZ_ROOT run_perf_test.sh end" QATzip-1.3.1/utils/000077500000000000000000000000001500263377000140275ustar00rootroot00000000000000QATzip-1.3.1/utils/Makefile.am000066400000000000000000000061641500263377000160720ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ bin_PROGRAMS = qzip qzip_SOURCES = \ qzip_7z.c \ qzip_main.c \ qzip.c qzip_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) qzip_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) qzip_LDFLAGS = \ $(ICP_LDFLAGS) qzip_obj_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) if QATZIP_LZ4S_POSTPROCESS_AC noinst_PROGRAMS = qzstd qzstd_SOURCES = \ qzstd.c \ qzstd_main.c qzstd_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) qzstd_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) \ $(ZSTD_LIBADD) qzstd_LDFLAGS = \ $(ICP_LDFLAGS) endif qzip_obj_without_main: qzip.c qzip_7z.c $(CC) $^ -c $(qzip_obj_CFLAGS) QATzip-1.3.1/utils/qzip.c000066400000000000000000000734631500263377000151730ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzip.h" char const *const g_license_msg[] = { "Copyright (C) 2021 Intel Corporation.", 0 }; char *g_program_name = NULL; /* program name */ int g_decompress = 0; /* g_decompress (-d) */ int g_keep = 0; /* keep (don't delete) input files */ QzSession_T g_sess; QzipParams_T g_params_th = { .huffman_hdr = QZ_HUFF_HDR_DEFAULT, .direction = QZ_DIRECTION_DEFAULT, .data_fmt = QZIP_DEFLATE_GZIP_EXT, .comp_lvl = QZ_COMP_LEVEL_DEFAULT, .comp_algorithm = QZ_COMP_ALGOL_DEFAULT, .hw_buff_sz = QZ_HW_BUFF_SZ, .polling_mode = QZ_PERIODICAL_POLLING, .req_cnt_thrshold = QZ_REQ_THRESHOLD_DEFAULT, .is_sensitive_mode = false, }; /* Estimate maximum data expansion after decompression */ const unsigned int g_bufsz_expansion_ratio[] = {5, 20, 50, 100}; /* Command line options*/ char const g_short_opts[] = "A:H:L:C:r:o:O:P:g:b:dfhkVRs"; const struct option g_long_opts[] = { /* { name has_arg *flag val } */ {"decompress", 0, 0, 'd'}, /* decompress */ {"uncompress", 0, 0, 'd'}, /* decompress */ {"force", 0, 0, 'f'}, /* force overwrite of output file */ {"help", 0, 0, 'h'}, /* give help */ {"keep", 0, 0, 'k'}, /* keep (don't delete) input files */ {"version", 0, 0, 'V'}, /* display version number */ {"algorithm", 1, 0, 'A'}, /* set algorithm type */ {"huffmanhdr", 1, 0, 'H'}, /* set huffman header type */ {"level", 1, 0, 'L'}, /* set compression level */ {"chunksz", 1, 0, 'C'}, /* set chunk size */ {"output", 1, 0, 'O'}, /* set output header format(gzip, gzipext, 7z, deflate_4B, lz4, lz4s) */ {"recursive", 0, 0, 'R'}, /* set recursive mode when compressing a directory */ {"polling", 1, 0, 'P'}, /* set polling mode when compressing and decompressing */ {"loglevel", 1, 0, 'g'}, /* set log level */ {"blocksz", 1, 0, 'b'}, /* set block source buffer size */ {"lsm", 1, 0, 's'}, /* enable latency sensitive mode */ { 0, 0, 0, 0 } }; const unsigned int USDM_ALLOC_MAX_SZ = (2 * 1024 * 1024 - 5 * 1024); unsigned int block_buff_len = SRC_BUFF_LEN; void tryHelp(void) { QZ_PRINT("Try `%s --help' for more information.\n", g_program_name); exit(ERROR); } void help(void) { static char const *const help_msg[] = { "Compress or uncompress FILEs (by default, compress FILES in-place).", "", "Mandatory arguments to long options are mandatory for short options " "too.", "", " -A, --algorithm set algorithm type", " -d, --decompress decompress", " -f, --force force overwrite of output file and compress links", " -h, --help give this help", " -H, --huffmanhdr set huffman header type", " -k, --keep keep (don't delete) input files", " -V, --version display version number", " -L, --level set compression level", " -C, --chunksz set chunk size", " -O, --output set output header format(gzip|gzipext|7z|deflate_4B|lz4|lz4s)", " -r, set max in-flight request number", " -R, set Recursive mode for a directory", " -o, set output file name", " -P, --polling set polling mode, only supports busy polling settings", " -s, enable latency sensitive mode", " -g, --loglevel set qatzip loglevel(none|error|warn|info|debug)", " -b, --blocksz If set this option, the qzip will split input file into pieces.", " qzCompress/qzDecompress will process block_size bytes every time.", "", "With no FILE, read standard input.", 0 }; char const *const *p = help_msg; QZ_PRINT("Usage: %s [OPTION]... [FILE]...\n", g_program_name); while (*p) { QZ_PRINT("%s\n", *p++); } } void freeTimeList(RunTimeList_T *time_list) { RunTimeList_T *time_node = time_list; RunTimeList_T *pre_time_node = NULL; while (time_node) { pre_time_node = time_node; time_node = time_node->next; free(pre_time_node); } } void displayStats(RunTimeList_T *time_list, off_t insize, off_t outsize, int is_compress) { /* Calculate time taken (from begin to end) in micro seconds */ unsigned long us_begin = 0; unsigned long us_end = 0; double us_diff = 0; RunTimeList_T *time_node = time_list; while (time_node) { us_begin = time_node->time_s.tv_sec * 1000000 + time_node->time_s.tv_usec; us_end = time_node->time_e.tv_sec * 1000000 + time_node->time_e.tv_usec; us_diff += (us_end - us_begin); time_node = time_node->next; } if (insize) { assert(0 != us_diff); double size = (is_compress) ? insize : outsize; double throughput = (size * CHAR_BIT) / us_diff; /* in MB (megabytes) */ double compressionRatio = ((double)insize) / ((double)outsize); double spaceSavings = 1 - ((double)outsize) / ((double)insize); QZ_PRINT("Time taken: %9.3lf ms\n", us_diff / 1000); QZ_PRINT("Throughput: %9.3lf Mbit/s\n", throughput); if (is_compress) { QZ_PRINT("Space Savings: %9.3lf %%\n", spaceSavings * 100.0); QZ_PRINT("Compression ratio: %.3lf : 1\n", compressionRatio); } } } int doProcessBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int dst_len, RunTimeList_T *time_list, FILE *dst_file, off_t *dst_file_size, int is_compress) { int ret = QZ_FAIL; unsigned int done = 0; unsigned int bytes_written = 0; RunTimeList_T *time_node = time_list; /* block size for compression API level offload */ unsigned int block_src_len = *src_len; unsigned int block_dest_len = dst_len; unsigned int consumed = 0; unsigned int produced = 0; while (time_node->next) { time_node = time_node->next; } while (!done) { RunTimeList_T *run_time = calloc(1, sizeof(RunTimeList_T)); assert(NULL != run_time); run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); /* Do actual work */ if (is_compress) { block_src_len = (*src_len - consumed) > block_buff_len ? block_buff_len : (*src_len - consumed); block_dest_len = dst_len - produced; ret = qzCompress(sess, src + consumed, &block_src_len, dst + produced, &block_dest_len, 1); if (QZ_BUF_ERROR == ret && 0 == block_src_len) { done = 1; } } else { ret = qzDecompress(sess, src + consumed, &block_src_len, dst + produced, &block_dest_len); if (QZ_DATA_ERROR == ret || (QZ_BUF_ERROR == ret && 0 == block_src_len) || (QZ_OK == ret && block_src_len < *src_len)) { done = 1; } } if (ret != QZ_OK && ret != QZ_BUF_ERROR && ret != QZ_DATA_ERROR) { const char *op = (is_compress) ? "Compression" : "Decompression"; QZ_ERROR("doProcessBuffer:%s failed with error: %d\n", op, ret); break; } gettimeofday(&run_time->time_e, NULL); consumed += block_src_len; produced += block_dest_len; if (0 == (*src_len - consumed)) { done = 1; } } bytes_written = fwrite(dst, 1, produced, dst_file); assert(bytes_written == produced); *dst_file_size = bytes_written; *src_len = consumed; return ret; } void doProcessFile(QzSession_T *sess, const char *src_file_name, const char *dst_file_name, int is_compress) { int ret = OK; struct stat src_file_stat; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; off_t src_file_size = 0, dst_file_size = 0, file_remaining = 0; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; FILE *src_file = NULL; FILE *dst_file = NULL; unsigned int bytes_read = 0; unsigned int bytes_lookahead = 0; long offset_revert = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; int src_fd = 0; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); assert(NULL != time_list_head); gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; //open file src_fd = open(src_file_name, O_RDONLY); if (src_fd < 0) { QZ_INFO("Open input file %s failed\n", src_file_name); exit(ERROR); } ret = fstat(src_fd, &src_file_stat); assert(!ret); if (S_ISBLK(src_file_stat.st_mode)) { /* ioctl return device size / 512, so device size = src_file_size * 512 */ if (ioctl(src_fd, BLKGETSIZE, &src_file_size) < 0) { close(src_fd); perror(src_file_name); exit(ERROR); } src_file_size *= 512; } else { src_file_size = src_file_stat.st_size; } src_buffer_size = (src_file_size > SRC_BUFF_LEN) ? SRC_BUFF_LEN : src_file_size; if (is_compress) { dst_buffer_size = qzMaxCompressedLength(src_buffer_size, sess); if (0 == dst_buffer_size) { perror("During SW compression, src file size is less than HW size!\n"); exit(ERROR); } } else { /* decompress */ dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; } if (0 == src_file_size && is_compress) { dst_buffer_size = 1024; } src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(dst_buffer_size); assert(dst_buffer != NULL); src_file = fdopen(src_fd, "r"); assert(src_file != NULL); dst_file = fopen(dst_file_name, "w"); assert(dst_file != NULL); file_remaining = src_file_size; read_more = 1; do { if (read_more) { bytes_read = fread(src_buffer, 1, src_buffer_size, src_file); QZ_INFO("Reading input file %s (%u Bytes)\n", src_file_name, bytes_read); } else { bytes_read = file_remaining; } puts((is_compress) ? "Compressing..." : "Decompressing..."); bytes_lookahead = bytes_read; ret = doProcessBuffer(sess, src_buffer, &bytes_read, dst_buffer, dst_buffer_size, time_list_head, dst_file, &dst_file_size, is_compress); if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { if (0 != bytes_read) { offset_revert = (long)bytes_read - (long)bytes_lookahead; if (-1 == fseek(src_file, offset_revert, SEEK_CUR)) { ret = ERROR; goto exit; } read_more = 1; } else if (QZ_BUF_ERROR == ret) { //dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more destination buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer with size " "%u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { read_more = 1; } file_remaining -= bytes_read; } while (file_remaining > 0); displayStats(time_list_head, src_file_size, dst_file_size, is_compress); exit: freeTimeList(time_list_head); fclose(src_file); fclose(dst_file); close(src_fd); free(src_buffer); free(dst_buffer); if (!g_keep && OK == ret) { unlink(src_file_name); } if (ret) { exit(ret); } } int qzipSetupSessionDeflate(QzSession_T *sess, QzipParams_T *params) { int status; QzSessionParamsDeflateExt_T deflate_params_ext; status = qzGetDefaultsDeflateExt(&deflate_params_ext); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } switch (params->data_fmt) { case QZIP_DEFLATE_4B: deflate_params_ext.deflate_params.data_fmt = QZ_DEFLATE_4B; break; case QZIP_DEFLATE_GZIP: deflate_params_ext.deflate_params.data_fmt = QZ_DEFLATE_GZIP; break; case QZIP_DEFLATE_GZIP_EXT: deflate_params_ext.deflate_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; case QZIP_DEFLATE_RAW: deflate_params_ext.deflate_params.data_fmt = QZ_DEFLATE_RAW; deflate_params_ext.stop_decompression_stream_end = 1; break; default: QZ_ERROR("Unsupported data format\n"); return ERROR; } deflate_params_ext.deflate_params.huffman_hdr = params->huffman_hdr; deflate_params_ext.deflate_params.common_params.direction = params->direction; deflate_params_ext.deflate_params.common_params.comp_lvl = params->comp_lvl; deflate_params_ext.deflate_params.common_params.comp_algorithm = params->comp_algorithm; deflate_params_ext.deflate_params.common_params.hw_buff_sz = params->hw_buff_sz; deflate_params_ext.deflate_params.common_params.polling_mode = params->polling_mode; deflate_params_ext.deflate_params.common_params.req_cnt_thrshold = params->req_cnt_thrshold; deflate_params_ext.deflate_params.common_params.is_sensitive_mode = params->is_sensitive_mode; status = qzSetupSessionDeflateExt(sess, &deflate_params_ext); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } return OK; } int qzipSetupSessionLZ4(QzSession_T *sess, QzipParams_T *params) { int status; QzSessionParamsLZ4_T lz4_params; status = qzGetDefaultsLZ4(&lz4_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } lz4_params.common_params.direction = params->direction; lz4_params.common_params.comp_lvl = params->comp_lvl; lz4_params.common_params.comp_algorithm = params->comp_algorithm; lz4_params.common_params.hw_buff_sz = params->hw_buff_sz; lz4_params.common_params.polling_mode = params->polling_mode; lz4_params.common_params.req_cnt_thrshold = params->req_cnt_thrshold; lz4_params.common_params.is_sensitive_mode = params->is_sensitive_mode; status = qzSetupSessionLZ4(sess, &lz4_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } return OK; } int qzipSetupSessionLZ4S(QzSession_T *sess, QzipParams_T *params) { int status; QzSessionParamsLZ4S_T lz4s_params; status = qzGetDefaultsLZ4S(&lz4s_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } lz4s_params.common_params.direction = params->direction; lz4s_params.common_params.comp_lvl = params->comp_lvl; lz4s_params.common_params.comp_algorithm = params->comp_algorithm; lz4s_params.common_params.hw_buff_sz = params->hw_buff_sz; lz4s_params.common_params.polling_mode = params->polling_mode; lz4s_params.common_params.req_cnt_thrshold = params->req_cnt_thrshold; lz4s_params.common_params.is_sensitive_mode = params->is_sensitive_mode; status = qzSetupSessionLZ4S(sess, &lz4s_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } return OK; } int qatzipSetup(QzSession_T *sess, QzipParams_T *params) { int status; QZ_DEBUG("mw>>> sess=%p\n", sess); status = qzInit(sess, 1); if (status != QZ_OK && status != QZ_DUPLICATE) { QZ_ERROR("QAT init failed with error: %d\n", status); return ERROR; } QZ_DEBUG("QAT init OK with error: %d\n", status); switch (params->data_fmt) { case QZIP_DEFLATE_4B: case QZIP_DEFLATE_GZIP: case QZIP_DEFLATE_GZIP_EXT: case QZIP_DEFLATE_RAW: status = qzipSetupSessionDeflate(sess, params); if (status != OK) { QZ_ERROR("qzipSetupSessionDeflate fail with error: %d\n", status); } break; case QZIP_LZ4_FH: status = qzipSetupSessionLZ4(sess, params); if (status != OK) { QZ_ERROR("qzipSetupSessionLZ4 fail with error: %d\n", status); } break; case QZIP_LZ4S_BK: status = qzipSetupSessionLZ4S(sess, params); if (status != OK) { QZ_ERROR("qzipSetupSessionLZ4S fail with error: %d\n", status); } break; default: QZ_ERROR("Unsupported data format\n"); return ERROR; } QZ_DEBUG("Session setup OK with error: %d\n", status); return 0; } int qatzipClose(QzSession_T *sess) { qzTeardownSession(sess); qzClose(sess); return 0; } QzSuffix_T getSuffix(const char *filename) { QzSuffix_T s = E_SUFFIX_UNKNOWN; size_t len = strlen(filename); if (len >= strlen(SUFFIX_GZ) && !strcmp(filename + (len - strlen(SUFFIX_GZ)), SUFFIX_GZ)) { s = E_SUFFIX_GZ; } else if (len >= strlen(SUFFIX_7Z) && !strcmp(filename + (len - strlen(SUFFIX_7Z)), SUFFIX_7Z)) { s = E_SUFFIX_7Z; } else if (len >= strlen(SUFFIX_LZ4) && !strcmp(filename + (len - strlen(SUFFIX_LZ4)), SUFFIX_LZ4)) { s = E_SUFFIX_LZ4; } else if (len >= strlen(SUFFIX_LZ4S) && !strcmp(filename + (len - strlen(SUFFIX_LZ4S)), SUFFIX_LZ4S)) { s = E_SUFFIX_LZ4S; } return s; } bool hasSuffix(const char *fname) { size_t len = strlen(fname); switch (g_params_th.data_fmt) { case QZIP_LZ4_FH: if (len >= strlen(SUFFIX_LZ4) && !strcmp(fname + (len - strlen(SUFFIX_LZ4)), SUFFIX_LZ4)) { return 1; } break; case QZIP_LZ4S_BK: if (len >= strlen(SUFFIX_LZ4S) && !strcmp(fname + (len - strlen(SUFFIX_LZ4S)), SUFFIX_LZ4S)) { return 1; } break; case QZIP_DEFLATE_RAW: case QZIP_DEFLATE_GZIP_EXT: case QZIP_DEFLATE_GZIP: case QZIP_DEFLATE_4B: default: if (len >= strlen(SUFFIX_GZ) && !strcmp(fname + (len - strlen(SUFFIX_GZ)), SUFFIX_GZ)) { return 1; } else if (len >= strlen(SUFFIX_7Z) && !strcmp(fname + (len - strlen(SUFFIX_7Z)), SUFFIX_7Z)) { return 1; } break; } return 0; } QzSuffixCheckStatus_T checkSuffix(QzSuffix_T suffix, int is_format_set) { if (E_SUFFIX_GZ == suffix) { if (!is_format_set) { // format is not specified, reassign data format by suffix instead of default value g_params_th.data_fmt = QZIP_DEFLATE_GZIP_EXT; return E_CHECK_SUFFIX_OK; } if (QZIP_DEFLATE_GZIP_EXT != g_params_th.data_fmt && QZIP_DEFLATE_GZIP != g_params_th.data_fmt && QZIP_DEFLATE_4B != g_params_th.data_fmt) { return E_CHECK_SUFFIX_FORMAT_UNMATCH; } else { return E_CHECK_SUFFIX_OK; } } else if (E_SUFFIX_7Z == suffix) { if (!is_format_set) { g_params_th.data_fmt = QZIP_DEFLATE_RAW; return E_CHECK_SUFFIX_OK; } if (QZIP_DEFLATE_RAW != g_params_th.data_fmt) { return E_CHECK_SUFFIX_FORMAT_UNMATCH; } else { return E_CHECK_SUFFIX_OK; } } else if (E_SUFFIX_LZ4 == suffix) { if (!is_format_set) { g_params_th.data_fmt = QZIP_LZ4_FH; return E_CHECK_SUFFIX_OK; } if (QZIP_LZ4_FH != g_params_th.data_fmt) { return E_CHECK_SUFFIX_FORMAT_UNMATCH; } else { return E_CHECK_SUFFIX_OK; } } else { //unsupported suffix return E_CHECK_SUFFIX_UNSUPPORT; } } int makeOutName(const char *in_name, const char *out_name, char *oname, int is_compress) { if (is_compress) { if (hasSuffix(in_name)) { QZ_ERROR("Warning: %s already has suffix -- unchanged\n", in_name); return -1; } /* add suffix */ if (g_params_th.data_fmt == QZIP_LZ4_FH) { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_LZ4); } else if (g_params_th.data_fmt == QZIP_LZ4S_BK) { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_LZ4S); } else if (g_params_th.data_fmt == QZIP_DEFLATE_RAW) { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_7Z); } else { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_GZ); } } else { if (!hasSuffix(in_name)) { QZ_ERROR("%s: Wrong suffix. Supported suffix: 7z/gz/lz4\n", in_name); return -1; } /* remove suffix */ snprintf(oname, MAX_PATH_LEN, "%s", out_name ? out_name : in_name); if (NULL == out_name) { if (g_params_th.data_fmt == QZIP_LZ4_FH) { oname[strlen(in_name) - strlen(SUFFIX_LZ4)] = '\0'; } else { oname[strlen(in_name) - strlen(SUFFIX_GZ)] = '\0'; } } } return 0; } /* Makes a complete file system path by adding a file name to the path of its * parent directory. */ void mkPath(char *path, const char *dirpath, char *file) { const int nprinted = snprintf(path, MAX_PATH_LEN, "%s/%s", dirpath, file); if (nprinted >= MAX_PATH_LEN || nprinted < 0) { /* truncated, or output error */ assert(0); } } void processDir(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress) { DIR *dir; struct dirent *entry; char inpath[MAX_PATH_LEN]; dir = opendir(in_name); assert(dir); while ((entry = readdir(dir))) { /* Ignore anything starting with ".", which includes the special * files ".", "..", as well as hidden files. */ if (entry->d_name[0] == '.') { continue; } /* Qualify the file with its parent directory to obtain a complete * path. */ mkPath(inpath, in_name, entry->d_name); processFile(sess, inpath, out_name, is_compress); } closedir(dir); } void processFile(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress) { int ret; struct stat fstat; struct timespec timebuf[2]; ret = stat(in_name, &fstat); if (ret) { perror(in_name); exit(-1); } if (S_ISDIR(fstat.st_mode)) { processDir(sess, in_name, out_name, is_compress); } else { char oname[MAX_PATH_LEN]; memset(oname, 0, MAX_PATH_LEN); if (makeOutName(in_name, out_name, oname, is_compress)) { return; } doProcessFile(sess, in_name, oname, is_compress); if (access(oname, F_OK) == 0) { //update src file stat to dst file memset(timebuf, 0, sizeof(timebuf)); timebuf[0].tv_nsec = UTIME_NOW; timebuf[1].tv_sec = fstat.st_mtime; utimensat(AT_FDCWD, oname, timebuf, 0); } } } void version(void) { char const *const *p = g_license_msg; QZ_PRINT("%s v%s\n", g_program_name, QZIP_VERSION); while (*p) { QZ_PRINT("%s\n", *p++); } } char *qzipBaseName(char *fname) { char *p; if ((p = strrchr(fname, '/')) != NULL) { fname = p + 1; } return fname; } void processStream(QzSession_T *sess, FILE *src_file, FILE *dst_file, int is_compress) { int ret = OK; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; off_t dst_file_size = 0; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; unsigned int bytes_read = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); assert(NULL != time_list_head); gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; int pending_in = 0; int bytes_input = 0; src_buffer_size = SRC_BUFF_LEN; if (is_compress) { dst_buffer_size = qzMaxCompressedLength(src_buffer_size, sess); if (0 == dst_buffer_size) { perror("During SW compression, src file size is less than HW size!\n"); exit(ERROR); } } else { /* decompress */ dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; } src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(dst_buffer_size); assert(dst_buffer != NULL); read_more = 1; while (!feof(stdin)) { if (read_more) { bytes_read = fread(src_buffer + pending_in, 1, src_buffer_size - pending_in, src_file); if (0 == is_compress) { bytes_read += pending_in; bytes_input = bytes_read; pending_in = 0; } } ret = doProcessBuffer(sess, src_buffer, &bytes_read, dst_buffer, dst_buffer_size, time_list_head, dst_file, &dst_file_size, is_compress); if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { if (!is_compress) { pending_in = bytes_input - bytes_read; } if (0 != bytes_read) { if (!is_compress && pending_in > 0) { memmove(src_buffer, src_buffer + bytes_read, src_buffer_size - bytes_read); } read_more = 1; } else if (QZ_BUF_ERROR == ret) { // dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more destination buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer with size " "%u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { read_more = 1; } } exit: freeTimeList(time_list_head); free(src_buffer); free(dst_buffer); if (ret) { exit(ret); } } QATzip-1.3.1/utils/qzip.h000066400000000000000000000672131500263377000151740ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _UTILS_QZIP_H #define _UTILS_QZIP_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* new QATzip interface */ #ifdef HAVE_QAT_HEADERS #include #else #include #endif #include #include #include #include /* qzip version */ #define QZIP_VERSION "1.3.1" /* field offset in signature header */ #define SIGNATUREHEADER_OFFSET_BASE 8 #define SIGNATUREHEADER_OFFSET_NEXTHEADER_OFFSET 4 #define SIGNATUREHEADER_OFFSET_NEXTHEADER_SIZE 12 #define SIGNATUREHEADER_OFFSET_NEXTHEADER_CRC 20 /* resolving status */ #define RESOLVE_STATUS_IN_HEADER 0x0001 #define RESOLVE_STATUS_IN_ARCHIVE_PROPERTIES 0x0002 #define RESOLVE_STATUS_IN_STREAMSINFO 0x0004 #define RESOLVE_STATUS_IN_FILESINFO 0x0008 #define RESOLVE_STATUS_IN_PACKINFO 0x0010 #define RESOLVE_STATUS_IN_CODERSINFO 0x0020 #define RESOLVE_STATUS_IN_SUBSTREAMSINFO 0x0040 /* definitions of 7z archive tags */ #define PROPERTY_ID_END 0x00 #define PROPERTY_ID_HEADER 0x01 #define PROPERTY_ID_ARCHIVE_PROPERTIES 0x02 #define PROPERTY_ID_ADDITIONAL_STREAMSINFO 0x03 #define PROPERTY_ID_MAIN_STREAMSINFO 0x04 #define PROPERTY_ID_FILESINFO 0x05 #define PROPERTY_ID_PACKINFO 0x06 #define PROPERTY_ID_UNPACKINFO 0x07 #define PROPERTY_ID_SUBSTREAMSINFO 0x08 #define PROPERTY_ID_SIZE 0x09 #define PROPERTY_ID_CRC 0x0a #define PROPERTY_ID_FOLDER 0x0b #define PROPERTY_ID_CODERS_UNPACK_SIZE 0x0c #define PROPERTY_ID_NUM_UNPACK_STREAM 0x0d #define PROPERTY_ID_EMPTY_STREAM 0x0e #define PROPERTY_ID_EMPTY_FILE 0x0f #define PROPERTY_ID_ANTI 0x10 #define PROPERTY_ID_NAME 0x11 #define PROPERTY_ID_CTIME 0x12 #define PROPERTY_ID_ATIME 0x13 #define PROPERTY_ID_MTIME 0x14 /* Support windows(low 16 bit) and unix(high 16 bit) */ #define PROPERTY_ID_ATTRIBUTES 0x15 #define PROPERTY_ID_COMMENT 0x16 #define PROPERTY_ID_ENCODED_HEADER 0x17 #define PROPERTY_ID_STARTPOS 0x18 #define PROPERTY_ID_DUMMY 0x19 #define PROPERTY_CONTENT_DUMMY 0x00 #define FLAG_ATTR_DEFINED_SET 0x01 #define FLAG_ATTR_DEFINED_UNSET 0x00 #define FLAG_ATTR_EXTERNAL_UNSET 0x00 /* 7z format version */ #define G_7ZHEADER_MAJOR_VERSION 0x00 #define G_7ZHEADER_MINOR_VERSION 0x04 /* default size for allocating memory for one node */ #define QZ_DIRLIST_DEFAULT_NUM_PER_NODE 100 #define QZ_FILELIST_DEFAULT_NUM_PER_NODE 1000 /* archiveproperties develop ID */ #define QZ7Z_DEVELOP_PREFIX 0x3ful #define QZ7Z_DEVELOP_ID ('Q'*1ul<<32|'A'<<24|'T'<<16|'7'<<8|'z') #define QZ7Z_DEVELOP_SUBID 0x0a01ul /* return codes from qzip */ #define OK 0 #define ERROR 1 /* internal return codes for functions that implement 7z format */ #define QZ7Z_OK OK #define QZ7Z_ERR_INVALID_SIZE -200 #define QZ7Z_ERR_OPEN -201 #define QZ7Z_ERR_OOM -202 #define QZ7Z_ERR_CONCAT_FILE -203 #define QZ7Z_ERR_STAT -204 #define QZ7Z_ERR_IOCTL -205 #define QZ7Z_ERR_END_HEADER -206 #define QZ7Z_ERR_NULL_INPUT_LIST -207 #define QZ7Z_ERR_REMOVE -208 #define QZ7Z_ERR_RESOLVE_END_HEADER -209 #define QZ7Z_ERR_NOT_EXPECTED_CHAR -210 #define QZ7Z_ERR_GETCWD -211 #define QZ7Z_ERR_READ_EOF -212 #define QZ7Z_ERR_READ_LESS -213 #define QZ7Z_ERR_WRITE_EOF -214 #define QZ7Z_ERR_WRITE_LESS -215 #define QZ7Z_ERR_MKDIR -216 #define QZ7Z_ERR_CHDIR -217 #define QZ7Z_ERR_CREATE_TEMP -218 #define QZ7Z_ERR_HEADER_CRC -219 #define QZ7Z_ERR_TIMES -220 #define QZ7Z_ERR_SIG_HEADER_BROKEN -221 #define QZ7Z_ERR_READLINK -222 #define QZ7Z_ERR_SIG_HEADER -223 #define QZ7Z_ERR_RESOLVE_SUBSTREAMS -224 #define QZ7Z_ERR_UNEXPECTED -225 #define MAX_PATH_LEN 1024 /* max pathname length */ #define SUFFIX_GZ ".gz" #define SUFFIX_7Z ".7z" #define SUFFIX_LZ4 ".lz4" #define SUFFIX_LZ4S ".lz4s" #define QZIP_GET_LOWER_32BITS(v) ((v) & 0xFFFFFFFF) /* Read file Buffer, Larger buffer to reduce I/O times */ #define SRC_BUFF_LEN (512 * 1024 * 1024) extern unsigned int block_buff_len; typedef enum QzSuffix_E { E_SUFFIX_GZ, E_SUFFIX_7Z, E_SUFFIX_LZ4, E_SUFFIX_LZ4S, E_SUFFIX_UNKNOWN = 999 } QzSuffix_T; typedef enum QzSuffixCheckStatus_E { E_CHECK_SUFFIX_OK, E_CHECK_SUFFIX_UNSUPPORT, E_CHECK_SUFFIX_FORMAT_UNMATCH } QzSuffixCheckStatus_T; typedef enum QzipDataFormat_E { QZIP_DEFLATE_4B = 0, /**< Data is in raw deflate format with 4 byte header */ QZIP_DEFLATE_GZIP, /**< Data is in deflate wrapped by GZip header and footer */ QZIP_DEFLATE_GZIP_EXT, /**< Data is in deflate wrapped by GZip extended header and footer */ QZIP_DEFLATE_RAW, /**< Data is in raw deflate format */ QZIP_LZ4_FH, /**< Data is in LZ4 format with frame headers */ QZIP_LZ4S_BK, /**< Data is in LZ4s format with block headers */ } QzipDataFormat_T; typedef struct QzipParams_S { QzHuffmanHdr_T huffman_hdr; QzDirection_T direction; QzipDataFormat_T data_fmt; unsigned int comp_lvl; unsigned char comp_algorithm; unsigned char force; unsigned char keep; unsigned int hw_buff_sz; unsigned int polling_mode; unsigned int recursive_mode; unsigned int req_cnt_thrshold; char *output_filename; unsigned int is_sensitive_mode; } QzipParams_T; #define QZ7Z_PROPERTY_ID_INTEL7Z_1001 ((QZ7Z_DEVELOP_PREFIX << 56) | \ (QZ7Z_DEVELOP_ID << 16) | \ (QZ7Z_DEVELOP_SUBID)) /* check allocated memory */ #define CHECK_ALLOC_RETURN_VALUE(p) \ if (NULL == p) {\ printf("%s:%d oom\n", __FILE__, __LINE__); \ exit(-QZ7Z_ERR_OOM);\ } /* check fread return */ #define CHECK_FREAD_RETURN(ret, n) if((ret) != (n)) { \ if (feof(fp)) { \ fprintf(stderr, "fread reach EOF.\n"); \ exit(-QZ7Z_ERR_READ_EOF); \ } else { \ fprintf(stderr, "fread errors.\n"); \ exit(-QZ7Z_ERR_READ_LESS); \ } \ } /* check fwrite return */ #define CHECK_FWRITE_RETURN(ret, n) CHECK_FWRITE_RETURN_FP(fp, ret, n) #define CHECK_FWRITE_RETURN_FP(fp, ret, n) if((ret) != (n)) { \ if (feof((fp))) { \ fprintf(stderr, "fwrite reach EOF.\n"); \ exit(-QZ7Z_ERR_WRITE_EOF); \ } else { \ fprintf(stderr, "fwrite errors.\n"); \ exit(-QZ7Z_ERR_WRITE_LESS); \ } \ } typedef struct RunTimeList_S { struct timeval time_s; struct timeval time_e; struct RunTimeList_S *next; } RunTimeList_T; /* Windows FILETIME structure * contains a 64-bit value representing the number of 100-nanosecond intervals * since January 1, 1601 (UTC). */ /* 1601 to 1970 is 369 years plus 89 leap days */ #define NUM_DAYS (134774UL) /* time in seconds from 1601 Jan 1 to 1970 Jan 1 */ #define DELTA_TIME (NUM_DAYS * (24 * 60 * 60UL)) #define NANO_SEC 1000000000UL #define TICKS_PER_SEC 10000000UL typedef struct FILETIME { uint32_t low; uint32_t high; } FILETIME_T; /** ****************************************************************************** * @ingroup qatZip * Qatzip linked list node structure * * @description * Qatzip linked list node structure * ******************************************************************************/ typedef struct QzListNode_S { uint32_t num; // number of allocated region per node uint32_t used; // used space of element void **items; struct QzListNode_S *next; } QzListNode_T; /** ****************************************************************************** * @ingroup qatZip * Qatzip linked list head structure * * @description * Qatzip linked list head structure * ******************************************************************************/ typedef struct QzListHead_S { uint32_t total; // total elements uint32_t num; // number of allocated region per node QzListNode_T *next; } QzListHead_T; /** ****************************************************************************** * @ingroup qatZip * A file or a directory compressed by qatzip * * @description * This structure contains a file or directory and it's attributes * ******************************************************************************/ typedef struct Qz7zFileItem_S { char *fileName; /* dynamic allocated memory for filename(pathname) */ unsigned char isDir; /* 1byte */ unsigned char isEmpty; /* 1byte */ /* is empty file */ unsigned char isSymLink; /* 1byte */ /* is symbol link */ unsigned char isAnti; /* 1byte */ /* is anti file(on windows) */ uint32_t baseNameLength; /* base pathname length */ uint32_t nameLength; /* memory allocated length */ size_t size; /* for file it's file's length*/ uint32_t crc; uint32_t attribute; uint64_t atime; uint32_t atime_nano; uint64_t mtime; uint32_t mtime_nano; } Qz7zFileItem_T; /** ****************************************************************************** * @ingroup qatZip * 7z signature header * * @description * This structure contains a 7z signature header * ******************************************************************************/ typedef struct Qz7zSignatureHeader_S { unsigned char signature[6]; /* {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}*/ unsigned char majorVersion; /* 0x00 */ unsigned char minorVersion; /* 0x04 */ uint32_t startHeaderCRC; uint64_t nextHeaderOffset; uint64_t nextHeaderSize; uint32_t nextHeaderCRC; } Qz7zSignatureHeader_T; /** ****************************************************************************** * @ingroup qatZip * 7z Coder Info * * @description * This structure presents Coder info * ******************************************************************************/ typedef struct Qz7zDigest_S { unsigned char allAreDefined; uint64_t numStreams; uint64_t numDefined; uint32_t *crc; /* array: CRC[NumDefined] */ } Qz7zDigest_T; /** ****************************************************************************** * @ingroup qatZip * 7z Pack Info structure * * @description * This structure presents a 7z pack info * ******************************************************************************/ typedef struct Qz7zPackInfo_S { uint64_t PackPos; uint64_t NumPackStreams; uint64_t *PackSize; /* PackSize[NumPackStreams] */ Qz7zDigest_T *PackStreamDigests; /* not used */ } Qz7zPackInfo_T; /** ****************************************************************************** * @ingroup qatZip * First byte of 7z Coder Info structure * * @description * This structure contains some attributes of a coder * ******************************************************************************/ typedef union Qz7zCoderFirstByte_S { struct { unsigned CodecIdSize : 4; unsigned IsComplexCoder : 1; unsigned HasAttributes : 1; unsigned Reserved : 1; unsigned MoreAlterMethods: 1; /* not used: 0 for ever */ } st; unsigned char uc; } Qz7zCoderFirstByte_T; /** ****************************************************************************** * @ingroup qatZip * 7z Coder Info list * * @description * This structure is Coder info list node * ******************************************************************************/ typedef struct Qz7zCoder_S { Qz7zCoderFirstByte_T coderFirstByte; unsigned char *codecID ; /* CodecID[CodecIdSize] */ uint64_t numInStreams; /* if it is complex coder */ uint64_t numOutStreams; /* if it is complex coder */ uint64_t propertySize; /* if there are attributes */ unsigned char *properties; /* array: Properties[PropertiSize] if there are attributes */ struct Qz7zCoder_S *next; } Qz7zCoder_T; /** ****************************************************************************** * @ingroup qatZip * 7z Folder Info * * @description * This structure is Folder info * ******************************************************************************/ typedef struct Qz7zFolderInfo_S { uint64_t numCoders; Qz7zCoder_T *coder_list; QzListHead_T *items; /* fileitems list */ uint64_t numBindPairs; uint64_t *inIndex; /* array: InIndex[NumBindPairs] */ uint64_t *outIndex; /* array: InIndex[NumBindPairs] */ uint64_t numPackedStreams; uint64_t *index; /* array: Index[NumPackedStreams] */ } Qz7zFolderInfo_T; typedef struct Qz7zFolderLoc_S { QzListNode_T *node; unsigned int index; size_t pos; } Qz7zFolderLoc_T; typedef struct Qz7zFolderHandle_S { Qz7zFolderInfo_T *folder; Qz7zFolderLoc_T *loc; } Qz7zFolderHandle_T; /** ****************************************************************************** * @ingroup qatZip * 7z Coder Info * * @description * This structure presents Coder info * The folders points to an array of all the folders * This part contains all the folders info here, in one struct variable. * ******************************************************************************/ typedef struct Qz7zCodersInfo_S { uint64_t numFolders; Qz7zFolderInfo_T *folders; /* array folders[numFolders] */ uint64_t dataStreamIndex; uint64_t *unPackSize; /* array: unPackSize[numFolders] */ Qz7zDigest_T *unPackDigests; /* not used */ } Qz7zCodersInfo_T ; /** ****************************************************************************** * @ingroup qatZip * 7z Substreams Info * * @description * This structure presents Substreams info * ******************************************************************************/ typedef struct Qz7zSubstreamsInfo_S { uint64_t numFolders; uint64_t *numUnPackStreams; /* NumUnPackStreams[numFolders] */ uint64_t *unPackSize; /* unPackSize[AllNumFiles - 1], AllNumFiles is sum of the array NumUnPackStreamsInFolders */ Qz7zDigest_T *digests; /* points to digests structure with all non-empty files num*/ } Qz7zSubstreamsInfo_T; /** ****************************************************************************** * @ingroup qatZip * 7z Streams Info structure * * @description * This structure presents a 7z streams info * ******************************************************************************/ typedef struct Qz7zStreamsInfo_S { Qz7zPackInfo_T *packInfo; Qz7zCodersInfo_T *codersInfo; Qz7zSubstreamsInfo_T *substreamsInfo; } Qz7zStreamsInfo_T; /** ****************************************************************************** * @ingroup qatZip * 7z Files Info structure * * @description * This structure presents a 7z files info. It is used for compressing * ******************************************************************************/ typedef struct Qz7zFilesInfo_S { uint64_t num; QzListHead_T *head[2]; } Qz7zFilesInfo_T; /** ****************************************************************************** * @ingroup qatZip * 7z Files Info structure * * @description * This structure presents a 7z files info. It is used for decompressing * ******************************************************************************/ typedef struct Qz7zFilesInfo_DEC_S { uint64_t dir_num; uint64_t file_num; Qz7zFileItem_T *items; } Qz7zFilesInfo_Dec_T; /** ****************************************************************************** * @ingroup qatZip * 7z Files ArchiveProperties structure * * @description * This structure presents a 7z Archive Properties Info, if there are more * than one properties, the `next` points to the next property * ******************************************************************************/ typedef struct Qz7zArchiveProperty_S { uint64_t id; uint64_t size; unsigned char *data; struct Qz7zArchiveProperty_S *next; } Qz7zArchiveProperty_T; /** ****************************************************************************** * @ingroup qatZip * 7z End header structure * * @description * This structure contains a 7z end header * ******************************************************************************/ typedef struct Qz7zEndHeader_S { Qz7zArchiveProperty_T *propertyInfo; Qz7zStreamsInfo_T *streamsInfo; Qz7zFilesInfo_T *filesInfo; Qz7zFilesInfo_Dec_T *filesInfo_Dec; } Qz7zEndHeader_T; /** ****************************************************************************** * @ingroup qatZip * 7z Category * * @description * This structure presents a 7z category * ******************************************************************************/ typedef struct QzCatagory_S { unsigned char cat_id; const char *cat_name; QzListHead_T *cat_files; } QzCatagory_T; /** ****************************************************************************** * @ingroup qatZip * 7z Category table * * @description * This structure presents all categories * ******************************************************************************/ typedef struct QzCatagoryTable_S { unsigned int cat_num; QzCatagory_T *catas; /* array: catas[cat_num] */ } QzCatagoryTable_T; /** ****************************************************************************** * @ingroup qatZip * Qatzip items list structure * * @description * the structure is used for hold input arguments * items[0] is the list of all directory and empty file * items[1] is the list of all non-empty file * ******************************************************************************/ typedef struct Qz7zItemList_S { QzListHead_T *items[2]; QzCatagoryTable_T *table; } Qz7zItemList_T; /* create a list return list head */ QzListHead_T *qzListCreate(int num_per_node); /* Add one element's address to the list */ void qzListAdd(QzListHead_T *head, void **node); /* Get an element's address from a list */ void *qzListGet(QzListHead_T *head, int index); /* Free all allocated memory pointed by head */ void qzListDestroy(QzListHead_T *head); /* create the file items list */ Qz7zFileItem_T *fileItemCreate(char *pfilename); /* destroy the items list */ void itemListDestroy(Qz7zItemList_T *p); /* process the cmdline inputs */ Qz7zItemList_T *itemListCreate(int n, char **files); /* * resolve functions */ Qz7zSignatureHeader_T *resolveSignatureHeader(FILE *fp); Qz7zArchiveProperty_T *resolveArchiveProperties(FILE *fp); Qz7zPackInfo_T *resolvePackInfo(FILE *fp); Qz7zCodersInfo_T *resolveCodersInfo(FILE *fp); Qz7zSubstreamsInfo_T *resolveSubstreamsInfo(int n_folder, FILE *fp); Qz7zFilesInfo_Dec_T *resolveFilesInfo(FILE *fp); Qz7zStreamsInfo_T *resolveMainStreamsInfo(FILE *fp); Qz7zEndHeader_T *resolveEndHeader(FILE *fp, Qz7zSignatureHeader_T *sheader); /* create category list */ QzCatagoryTable_T *createCatagoryList(void); int scanFilesIntoCatagory(Qz7zItemList_T *the_list); /* * generate functions */ Qz7zSignatureHeader_T *generateSignatureHeader(void); Qz7zArchiveProperty_T *generatePropertyInfo(void); Qz7zPackInfo_T *generatePackInfo(Qz7zItemList_T *the_list, size_t compressed_size); Qz7zFolderInfo_T *generateFolderInfo(Qz7zItemList_T *the_list, int n_folders); Qz7zCodersInfo_T *generateCodersInfo(Qz7zItemList_T *the_list); Qz7zDigest_T *generateDigestInfo(QzListHead_T *head); Qz7zSubstreamsInfo_T *generateSubstreamsInfo(Qz7zItemList_T *the_list); Qz7zFilesInfo_T *generateFilesInfo(Qz7zItemList_T *the_list); Qz7zEndHeader_T *generateEndHeader(Qz7zItemList_T *the_list, size_t compressed_size); /* * write function */ int writeSignatureHeader(Qz7zSignatureHeader_T *header, FILE *fp); size_t writeArchiveProperties(Qz7zArchiveProperty_T *property, FILE *fp, uint32_t *crc); size_t writePackInfo(Qz7zPackInfo_T *pack, FILE *fp, uint32_t *crc); size_t writeFolder(Qz7zFolderInfo_T *folder, FILE *fp, uint32_t *crc); size_t writeCodersInfo(Qz7zCodersInfo_T *coders, FILE *fp, uint32_t *crc); size_t writeDigestInfo(Qz7zDigest_T *digest, FILE *fp, uint32_t *crc); size_t writeStreamsInfo(Qz7zStreamsInfo_T *streams, FILE *fp, uint32_t *crc); size_t writeFilesInfo(Qz7zFilesInfo_T *files, FILE *fp, uint32_t *crc); size_t writeSubstreamsInfo(Qz7zSubstreamsInfo_T *substreams, FILE *fp, uint32_t *crc); size_t writeEndHeader(Qz7zEndHeader_T *header, FILE *fp, uint32_t *crc); /* * free functions */ void freePropertyInfo(Qz7zArchiveProperty_T *info); void freePackInfo(Qz7zPackInfo_T *info); void freeCodersInfo(Qz7zCodersInfo_T *info); void freeSubstreamsInfo(Qz7zSubstreamsInfo_T *info); void freeStreamsInfo(Qz7zStreamsInfo_T *info); void freeFilesInfo(Qz7zFilesInfo_T *info); void freeFilesDecInfo(Qz7zFilesInfo_Dec_T *info); void freeEndHeader(Qz7zEndHeader_T *eheader, int is_compress); /* the main API for compress into 7z format */ int qz7zCompress(QzSession_T *sess, Qz7zItemList_T *the_list, const char *out_name); /* the main API for decompress a 7z file */ int qz7zDecompress(QzSession_T *sess, const char *archive); /* * UINT64 conversion functions */ /* conversion from real uint64_t to UINT64 */ int getExtraByteNum(uint64_t n); int getUint64Bytes(uint64_t n, unsigned char *u64); /* conversion from UINT64 to uint64_t */ int getExtraByteNum2(uint8_t first); uint64_t getU64FromBytes(FILE *fp); #ifdef QZ7Z_DEBUG void printSignatureHeader(Qz7zSignatureHeader_T *sheader); void printEndHeader(Qz7zEndHeader_T *eheader); #endif /* create the directory in path of newdir */ int createDir(const char *newdir, int back); /* delete source files represented by the list */ int deleteSourceFile(Qz7zItemList_T *the_list); /* check whether the file is 7z archive */ int check7zArchive(const char *archive); /* check whether the filename is directory */ int checkDirectory(const char *filename); void freeTimeList(RunTimeList_T *time_list); void displayStats(RunTimeList_T *time_list, off_t insize, off_t outsize, int is_compress); void tryHelp(void); void help(void); void version(void); char *qzipBaseName(char *fname); QzSuffix_T getSuffix(const char *filename); bool hasSuffix(const char *fname); QzSuffixCheckStatus_T checkSuffix(QzSuffix_T suffix, int is_format_set); int makeOutName(const char *in_name, const char *out_name, char *oname, int is_compress); /* Makes a complete file system path by adding a file name to the path of its * parent directory. */ void mkPath(char *path, const char *dirpath, char *file); /* * internal api functions */ int qatzipSetup(QzSession_T *sess, QzipParams_T *params); int qatzipClose(QzSession_T *sess); void processFile(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress); int doProcessBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int dst_len, RunTimeList_T *time_list, FILE *dst_file, off_t *dst_file_size, int is_compress); void doProcessFile(QzSession_T *sess, const char *src_file_name, const char *dst_file_name, int is_compress); void processDir(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress); void processStream(QzSession_T *sess, FILE *src_file, FILE *dst_file, int is_compress); int doCompressFile(QzSession_T *sess, Qz7zItemList_T *list, const char *dst_file_name); int doDecompressFile(QzSession_T *sess, const char *src_file_name); /* * extern declaration */ extern char const *const g_license_msg[2]; extern char *g_program_name; extern int g_decompress; /* g_decompress (-d) */ extern int g_keep; /* keep (don't delete) input files */ extern QzSession_T g_sess; extern QzipParams_T g_params_th; /* Estimate maximum data expansion after decompression */ extern const unsigned int g_bufsz_expansion_ratio[4]; /* Command line options*/ extern char const g_short_opts[]; extern const struct option g_long_opts[]; extern const unsigned int USDM_ALLOC_MAX_SZ; #endif QATzip-1.3.1/utils/qzip_7z.c000066400000000000000000003055571500263377000156150ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzip.h" #define OK 0 #define ERROR 1 static const unsigned char g_header_signature[] = { '7', 'z', 0xBC, 0xAF, 0x27, 0x1C }; static const char g_deflate_codecId[] = { 0x04, 0x01, 0x08 }; static const char g_property_data[] = { 'Q', 'A', 'T' }; static uint64_t const extra_byte_boundary[] = { 0x0, 0x7f, 0x3fff, 0x1fffff, 0xfffffff, 0x7ffffffff, 0x3ffffffffff, 0x1ffffffffffff, 0xffffffffffffff }; static uint8_t const first_byte_table[] = { 0, 0x80/* 1000 0000 */, 0xc0/* 1100 0000 */, 0xe0/* 1110 0000 */, 0xf0/* 1111 0000 */, 0xf8/* 1111 1000 */, 0xfc/* 1111 1100 */, 0xfe/* 1111 1110 */, 0xff/* 1111 1111 */ }; FILETIME_T unixtimeToFiletime(unsigned long t, uint32_t nsec) { FILETIME_T ft; unsigned long long secs = t * TICKS_PER_SEC + DELTA_TIME * TICKS_PER_SEC + nsec / 100; ft.low = (uint32_t)secs; ft.high = (uint32_t)(secs >> 32); return ft; } time_t filetimeToUnixtime(FILETIME_T ft) { time_t t; uint64_t ti; ti = (uint64_t)ft.high << 32; ti += ft.low; t = ti / TICKS_PER_SEC - DELTA_TIME; return t; } #define writeByte(b, fp, crc) writeTag(b, fp, crc) static size_t writeTag(unsigned char tag, FILE *fp, uint32_t *crc) { size_t n; n = fwrite(&tag, sizeof(unsigned char), 1, fp); CHECK_FWRITE_RETURN(n, 1) *crc = crc32(*crc, &tag, 1); return n; } static size_t writeTime(unsigned int t, FILE *fp, uint32_t *crc) { size_t n; n = fwrite(&t, sizeof(unsigned int), 1, fp); CHECK_FWRITE_RETURN(n, 1) *crc = crc32(*crc, (unsigned char *)&t, 4); return 4; } static size_t writeNumber(uint64_t u64, FILE *fp, uint32_t *crc) { uint64_t size; int n; unsigned char u64_bytes[9]; n = getUint64Bytes(u64, u64_bytes); size = fwrite(u64_bytes, sizeof(unsigned char), n, fp); CHECK_FWRITE_RETURN(size, n) *crc = crc32(*crc, u64_bytes, n); return size; } static unsigned char readByte(FILE *fp) { unsigned char c; int n; n = fread(&c, 1, 1, fp); CHECK_FREAD_RETURN(n, 1) return c; } static void skipNByte(int n, FILE *fp) { fseek(fp, n, SEEK_CUR); } static uint32_t readCRC(FILE *fp) { uint32_t crc; int n; n = fread(&crc, sizeof(uint32_t), 1, fp); CHECK_FREAD_RETURN(n, 1) return crc; } int getExtraByteNum2(uint8_t first) { int i; if (first == 0xff) return 8; for (i = 0; i < sizeof(first_byte_table) - 1; ++i) { if (first >= first_byte_table[i] && first < first_byte_table[i + 1]) break; } return i; } int getExtraByteNum(uint64_t n) { int i; int boundary_len = sizeof(extra_byte_boundary) / sizeof(extra_byte_boundary[0]); if (n == 0) return 0; for (i = 0; i < boundary_len; ++i) { if (n > extra_byte_boundary[i]) continue; break; } return i ? i - 1 : i; } /* * from UINT64 to uint64_t */ uint64_t getU64FromBytes(FILE *fp) { int i; int k; int extra; uint64_t ret; unsigned char c; uint8_t p = 0; unsigned char buf[8] = {0}; c = readByte(fp); extra = getExtraByteNum2(c); for (i = 0, k = 7; i < extra; ++i, --k) { p += 1 << k; } for (i = 0; i < extra; ++i) { buf[i] = readByte(fp); } if (extra != 7 && extra != 8) { buf[i] = c & ~p; } memcpy(&ret, buf, sizeof(buf)); return ret; } /** * get the number n's UINT64 form * n: the number * p: the bytes * return: total bytes */ int getUint64Bytes(uint64_t n, unsigned char *p) { int i; int extra = getExtraByteNum(n); uint64_t number = n; unsigned char first_byte; for (i = 0; i < extra; ++i) { number /= 0x100; } first_byte = number | first_byte_table[extra]; number = n; p[0] = first_byte; for (i = 0; i < extra; ++i) { p[i + 1] = number % 0x100; number /= 0x100; } return extra + 1; } /** * this means no category, every files are in one folder * the folder number/packed streams number is equal to * the number of category names * default is the last one, DO NOT delete it, add new * category names in front of it */ static const char *g_category_names[] = { "default" }; #ifdef QZ7Z_DEBUG void printSignatureHeader(Qz7zSignatureHeader_T *sheader) { QZ_DEBUG("-----signature header start-----\n"); QZ_DEBUG("signature: %c %c %x %x %x %x\n", sheader->signature[0], sheader->signature[1], sheader->signature[2], sheader->signature[3], sheader->signature[4], sheader->signature[5]); QZ_DEBUG("major version: %d minor version: %d\n", sheader->majorVersion, sheader->minorVersion); QZ_DEBUG("nextheaderoffset: %lu\n", sheader->nextHeaderOffset); QZ_DEBUG("nextHeaderSize: %lu\n", sheader->nextHeaderSize); QZ_DEBUG("nextHeaderCRC: %u\n", sheader->nextHeaderCRC); QZ_DEBUG("startHeaderCRC: %u\n", sheader->startHeaderCRC); QZ_DEBUG("-----end of signature header-----\n"); } void printEndHeader(Qz7zEndHeader_T *eheader) { int i; int j; QZ_DEBUG("-----print end header-------\n"); if (eheader->propertyInfo) { QZ_DEBUG(" ----------ArchiveProperties-------------\n"); QZ_DEBUG("Develop ID: %lx \n", eheader->propertyInfo->id); } if (eheader->streamsInfo) { QZ_DEBUG(" ----------StreamsInfo ------------------\n"); QZ_DEBUG(" NumPackStreams: %lu\n", eheader->streamsInfo->packInfo->NumPackStreams); QZ_DEBUG(" PackSize: "); for (i = 0; i < eheader->streamsInfo->packInfo->NumPackStreams; ++i) { QZ_DEBUG("%lu ", eheader->streamsInfo->packInfo->PackSize[i]); } QZ_DEBUG("\n ----------CodersInfo -------------------\n"); QZ_DEBUG(" NumFolders: %lu\n", eheader->streamsInfo->codersInfo->numFolders); for (i = 0; i < eheader->streamsInfo->codersInfo->numFolders; ++i) { QZ_DEBUG(" %lu ", eheader->streamsInfo->codersInfo->unPackSize[i]); } QZ_DEBUG("\n ----------SubstreamsInfo-------------------\n"); QZ_DEBUG(" NumUnpackSubstreamsInFolders: \n"); for (i = 0; i < eheader->streamsInfo->codersInfo->numFolders; ++i) { if (eheader->streamsInfo->substreamsInfo->numUnPackStreams) { QZ_DEBUG(" %lu ", eheader->streamsInfo->substreamsInfo-> numUnPackStreams[i]); QZ_DEBUG("\n unpacksize: \n"); for (j = 0; j < eheader->streamsInfo->substreamsInfo-> numUnPackStreams[i]; ++j) { QZ_DEBUG(" %lu ", eheader->streamsInfo->substreamsInfo-> unPackSize[j]); } } } } if (eheader->filesInfo) { QZ_DEBUG("\n --------------FilesInfo -------------\n"); } } #endif static int doCompressBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int *dst_len, RunTimeList_T *time_list, FILE *dst_file, off_t *dst_file_size, int last) { int ret = QZ_FAIL; unsigned int done = 0; unsigned int buf_processed = 0; unsigned int buf_remaining = *src_len; unsigned int bytes_written; unsigned int output_len = 0; RunTimeList_T *time_node = time_list; while (time_node->next) { time_node = time_node->next; } while (!done) { RunTimeList_T *run_time = calloc(1, sizeof(RunTimeList_T)); CHECK_ALLOC_RETURN_VALUE(run_time) run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); /* do actual work */ ret = qzCompress(sess, src, src_len, dst, dst_len, last); if (QZ_BUF_ERROR == ret && 0 == *src_len) { done = 1; } QZ_DEBUG("qzCompress returned: src_len=%u dst_len=%u\n", *src_len, *dst_len); if (ret != QZ_OK && ret != QZ_BUF_ERROR && ret != QZ_DATA_ERROR) { QZ_ERROR("doCompressBuffer in qzip_7z.c :failed with error: %d\n", ret); break; } gettimeofday(&run_time->time_e, NULL); bytes_written = fwrite(dst, 1, *dst_len, dst_file); CHECK_FWRITE_RETURN_FP(dst_file, bytes_written, *dst_len) *dst_file_size += bytes_written; buf_processed += *src_len; buf_remaining -= *src_len; output_len += *dst_len; if (0 == buf_remaining) { done = 1; } src += *src_len; QZ_DEBUG("src_len is %u ,buf_remaining is %u\n", *src_len, buf_remaining); *src_len = buf_remaining; } *src_len = buf_processed; *dst_len = output_len; return ret; } static int doDecompressBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int *dst_len, RunTimeList_T *time_list, int last) { int ret = QZ_FAIL; unsigned int done = 0; unsigned int buf_processed = 0; unsigned int src_remain = *src_len; unsigned int output_len = 0; RunTimeList_T *time_node = time_list; unsigned int src_remain_output = *dst_len; unsigned int total = *dst_len; while (time_node->next) { time_node = time_node->next; } while (!done) { RunTimeList_T *run_time = calloc(1, sizeof(RunTimeList_T)); CHECK_ALLOC_RETURN_VALUE(run_time) run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); /* do actual work */ ret = qzDecompress(sess, src, src_len, dst, &src_remain_output); if (QZ_DATA_ERROR == ret || (QZ_BUF_ERROR == ret && 0 == *src_len)) { done = 1; } if (ret != QZ_OK && ret != QZ_BUF_ERROR && ret != QZ_DATA_ERROR) { QZ_ERROR("doDecompressBuffer in qzip_7z.c :failed with error: %d\n", ret); break; } gettimeofday(&run_time->time_e, NULL); *dst_len = src_remain_output; buf_processed += *src_len; src_remain -= *src_len; output_len += *dst_len; src_remain_output = total - output_len; if (0 == src_remain) { done = 1; } if (0 == src_remain_output) { done = 1; } src += *src_len; QZ_DEBUG("src_len is %u ,src_remain is %u\n", *src_len, src_remain); *src_len = src_remain; } *src_len = buf_processed; *dst_len = output_len; return ret; } int doCompressFile(QzSession_T *sess, Qz7zItemList_T *list, const char *dst_file_name) { int ret = OK; struct stat src_file_stat; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0, dst_buffer_max_size = 0; off_t src_file_size = 0, dst_file_size = 0, file_remaining = 0; const char *src_file_name = NULL; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; FILE *src_file = NULL; FILE *dst_file = NULL; Qz7zEndHeader_T *eheader = NULL; unsigned int bytes_read = 0; unsigned long bytes_processed = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; int src_fd = -1; uint64_t eheader_size; uint32_t crc = 0; uint32_t start_crc = 0; uint64_t non_empty_number = 0; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); Qz7zSignatureHeader_T *sheader = NULL; size_t total_compressed_size = 0; int is_last; int n_part; // how much parts can the src file be splited int n_part_i; if (!time_list_head) { QZ_DEBUG("malloc time_list_head error\n"); ret = QZ7Z_ERR_OOM; goto exit; } gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; dst_file = fopen(dst_file_name, "w+"); if (!dst_file) { QZ_ERROR("Cannot open file: %s\n", dst_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } sheader = generateSignatureHeader(); if (!sheader) { QZ_ERROR("Cannot generate signature header, out of memory"); ret = QZ7Z_ERR_OOM; goto exit; } src_buffer = malloc(SRC_BUFF_LEN); if (!src_buffer) { QZ_DEBUG("malloc error\n"); ret = QZ7Z_ERR_OOM; goto exit; } dst_buffer_max_size = qzMaxCompressedLength(SRC_BUFF_LEN, sess); dst_buffer = malloc(dst_buffer_max_size); if (!dst_buffer) { QZ_DEBUG("malloc error\n"); ret = QZ7Z_ERR_OOM; goto exit; } writeSignatureHeader(sheader, dst_file); non_empty_number = list->items[1]->total; if (non_empty_number) { for (int i = 0; i < non_empty_number; ++i) { Qz7zFileItem_T *cur_file = qzListGet(list->items[1], i); src_file_name = cur_file->fileName; if (!cur_file->isSymLink) { src_fd = open(src_file_name, O_RDONLY); if (src_fd < 0) { ret = QZ7Z_ERR_OPEN; goto exit; } ret = fstat(src_fd, &src_file_stat); if (ret) { QZ_ERROR("stat(): failed\n"); ret = QZ7Z_ERR_STAT; goto exit; } src_file = fdopen(src_fd, "r"); if (!src_file) { QZ_ERROR("create %s error\n", src_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } } else { ret = lstat(src_file_name, &src_file_stat); if (ret) { QZ_ERROR("lstat(): failed\n"); ret = QZ7Z_ERR_STAT; goto exit; } } if (S_ISBLK(src_file_stat.st_mode)) { if (ioctl(src_fd, BLKGETSIZE, &src_file_size) < 0) { perror(src_file_name); ret = QZ7Z_ERR_IOCTL; goto exit; } src_file_size *= 512; } else { src_file_size = src_file_stat.st_size; } src_buffer_size = (src_file_size > SRC_BUFF_LEN) ? SRC_BUFF_LEN : src_file_size; dst_buffer_size = qzMaxCompressedLength(src_buffer_size, sess); file_remaining = src_file_size; read_more = 1; n_part = src_file_size / SRC_BUFF_LEN; n_part = (src_file_size % SRC_BUFF_LEN) ? n_part + 1 : n_part; is_last = 0; n_part_i = 1; do { is_last = (i == non_empty_number - 1) && (n_part_i++ == n_part); if (read_more) { if (cur_file->isSymLink) { int size; size = readlink(cur_file->fileName, (char *)src_buffer, src_buffer_size); bytes_read = size; } else { bytes_read = fread(src_buffer, 1, src_buffer_size, src_file); QZ_INFO("Reading input file %s (%u Bytes)\n", src_file_name, bytes_read); } } else { bytes_read = file_remaining; } puts("Compressing..."); unsigned int dest_len = dst_buffer_size; ret = doCompressBuffer(sess, src_buffer, &bytes_read, dst_buffer, &dest_len, time_list_head, dst_file, &dst_file_size, is_last); if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { bytes_processed += bytes_read; if (0 != bytes_read) { if (-1 == fseek(src_file, bytes_processed, SEEK_SET)) { ret = ERROR; goto exit; } read_more = 1; } else if (QZ_BUF_ERROR == ret) { // dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more destination " "buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer " "with size %u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { if (cur_file->isSymLink) { read_more = 0; } else { read_more = 1; } } file_remaining -= bytes_read; total_compressed_size = dst_file_size; } while (file_remaining > 0); if (!cur_file->isSymLink) { fclose(src_file); src_file = NULL; if (src_fd >= 0) { close(src_fd); src_fd = -1; } } }// end for } else { QZ_INFO("Compressing...\n"); } eheader = generateEndHeader(list, total_compressed_size); if (!eheader) { QZ_ERROR("cannot allocate for end header\n"); ret = QZ7Z_ERR_OOM; goto exit; } eheader_size = writeEndHeader(eheader, dst_file, &crc); if (eheader_size == 0) { QZ_ERROR("Cannot write 7z end header\n"); ret = QZ7Z_ERR_END_HEADER; goto exit; } QZ_DEBUG("total compressed: %lu\n" "eheader_size: %lu\n" "crc: %x\n", total_compressed_size, eheader_size, crc); unsigned char start_header[24]; memcpy(start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_OFFSET, &total_compressed_size, sizeof(total_compressed_size)); memcpy(start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_SIZE, &eheader_size, sizeof(eheader_size)); memcpy(start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_CRC, &crc, sizeof(crc)); start_crc = crc32(start_crc, start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_OFFSET, 20); memcpy(start_header, &start_crc, sizeof(start_crc)); fseek(dst_file, SIGNATUREHEADER_OFFSET_BASE, SEEK_SET); fwrite(start_header, 1, sizeof(start_header), dst_file); displayStats(time_list_head, src_file_size, dst_file_size, 1/* is_compress */); exit: if (eheader) { freeEndHeader(eheader, 1); } if (src_file) { fclose(src_file); } if (dst_buffer) { free(dst_buffer); } if (src_buffer) { free(src_buffer); } if (sheader) { qzFree(sheader); } if (dst_file) { fclose(dst_file); } if (src_fd >= 0) { close(src_fd); } freeTimeList(time_list_head); if (!g_keep && OK == ret) { int re = deleteSourceFile(list); if (re != QZ7Z_OK) { QZ_ERROR("deleteSourceFile error: %d\n", re); return re; } } return ret; } int qz7zCompress(QzSession_T *sess, Qz7zItemList_T *list, const char *out_name) { char oname[MAX_PATH_LEN]; memset(oname, 0, MAX_PATH_LEN); //add 7z suffix if (makeOutName(out_name, out_name, oname, 1) == 0) { out_name = oname; } return doCompressFile(sess, list, out_name); } int deleteSourceFile(Qz7zItemList_T *list) { if (list == NULL) { QZ_ERROR("the input is NULL\n"); return QZ7Z_ERR_NULL_INPUT_LIST; } QzListHead_T *head; QzListNode_T *ptr; for (int i = 1; i >= 0; i--) { head = list->items[i]; if (head->total == 0) { continue; } int n_node = (head->total + (head->num - 1)) / head->num; for (int node = n_node - 1; node >= 0; node--) { ptr = head->next; int end = 0; while (end < node) { ptr = ptr->next; end++; } for (int j = ptr->used - 1; j >= 0; j--) { Qz7zFileItem_T *item = (Qz7zFileItem_T *)(*(ptr->items + j)); int re = remove(item->fileName); if (re != 0) { QZ_ERROR("Remove error\n"); return QZ7Z_ERR_REMOVE; } } } } return QZ7Z_OK; } Qz7zSignatureHeader_T *resolveSignatureHeader(FILE *fp) { int n; Qz7zSignatureHeader_T *sheader = qzMalloc(sizeof(Qz7zSignatureHeader_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (sheader) { n = fread(&sheader->signature, sizeof(unsigned char), 6, fp); CHECK_FREAD_RETURN(n, 6); n = fread(&sheader->majorVersion, sizeof(unsigned char), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->minorVersion, sizeof(unsigned char), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->startHeaderCRC, sizeof(uint32_t), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->nextHeaderOffset, sizeof(uint64_t), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->nextHeaderSize, sizeof(uint64_t), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->nextHeaderCRC, sizeof(uint32_t), 1, fp); CHECK_FREAD_RETURN(n, 1); } else { QZ_ERROR("malloc error\n"); } return sheader; } #define QZ7Z_DEVELOP_ID_PREFIX_SHIFT 56 #define QZ7Z_DEVELOP_ID_SHIFT 16 Qz7zArchiveProperty_T *resolveArchiveProperties(FILE *fp) { Qz7zArchiveProperty_T *property = qzMalloc(sizeof(Qz7zArchiveProperty_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!property) { QZ_ERROR("malloc property error\n"); return NULL; } uint64_t size; uint64_t id = getU64FromBytes(fp); if ((id >> QZ7Z_DEVELOP_ID_PREFIX_SHIFT) != 0x3f /* 7z dev id prefix */) { QZ_ERROR("7z file ArchiveProperties develop ID error.\n" "develop ID should starts with 0x3f\n"); goto error; } QZ_DEBUG("id = %lu\n", id); if (((id >> QZ7Z_DEVELOP_ID_SHIFT) & 0xffffffffff) != QZ7Z_DEVELOP_ID) { QZ_ERROR("7z file ArchiveProperties develop ID(%lu) error.\n" , id >> 16 & 0xffffffffff); goto error; } if ((id & 0xffff) != QZ7Z_DEVELOP_SUBID) { QZ_ERROR("7z file ArchiveProperties develop subID(%lu) error.\n" , id & 0xffff); goto error; } property->id = id; size = getU64FromBytes(fp); skipNByte(size, fp); if (readByte(fp) != PROPERTY_ID_END) { QZ_ERROR("Resolve PackInfo: kEnd (0x00) expected\n"); goto error; } return property; error: if (property) { qzFree(property); } return NULL; } Qz7zPackInfo_T *resolvePackInfo(FILE *fp) { Qz7zPackInfo_T *pack = qzMalloc(sizeof(Qz7zPackInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!pack) { QZ_ERROR("malloc pack error\n"); return NULL; } pack->PackPos = getU64FromBytes(fp); pack->NumPackStreams = getU64FromBytes(fp); pack->PackSize = qzMalloc(pack->NumPackStreams * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!pack->PackSize) { goto error; } if (readByte(fp) != PROPERTY_ID_SIZE) { QZ_ERROR("Resolve PackInfo: kSize (0x09) expected\n"); goto error; } for (int i = 0; i < pack->NumPackStreams; ++i) { pack->PackSize[i] = getU64FromBytes(fp); } if (readByte(fp) != PROPERTY_ID_END) { QZ_ERROR("Resolve PackInfo: kEnd (0x00) expected\n"); goto error; } return pack; error: if (pack) { qzFree(pack->PackSize); qzFree(pack); } return NULL; } Qz7zCodersInfo_T *resolveCodersInfo(FILE *fp) { unsigned char c; int i_folder = 0; Qz7zCodersInfo_T *coders = qzMalloc(sizeof(Qz7zCodersInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!coders) { QZ_ERROR("malloc coders\n"); return NULL; } if ((c = readByte(fp)) != PROPERTY_ID_FOLDER) { QZ_ERROR("Resolve CodersInfo: kFolders(0x0b) expected: %02x\n", c); goto error; } coders->numFolders = getU64FromBytes(fp); coders->folders = qzMalloc(coders->numFolders * sizeof(Qz7zFolderInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!coders->folders) { QZ_ERROR("malloc folders error\n"); goto error; } if ((c = readByte(fp)) == 0) { for (i_folder = 0; i_folder < coders->numFolders; ++i_folder) { Qz7zFolderInfo_T *p = &coders->folders[i_folder]; size_t n; unsigned int id_size; p->numCoders = readByte(fp); p->coder_list = qzMalloc(sizeof(Qz7zCoder_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!p->coder_list) { goto error; } p->coder_list->coderFirstByte.uc = readByte(fp); id_size = p->coder_list->coderFirstByte.st.CodecIdSize; p->coder_list->codecID = qzMalloc(id_size, QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!p->coder_list->codecID) { QZ_ERROR("malloc error\n"); goto error; } n = fread(p->coder_list->codecID, 1, id_size, fp); CHECK_FREAD_RETURN(n, id_size) QZ_DEBUG("codec id: %0x %0x %0x \n", p->coder_list->codecID[0], p->coder_list->codecID[1], p->coder_list->codecID[2]); } } else if (c == 1) { coders->dataStreamIndex = getU64FromBytes(fp); } else { QZ_ERROR("Folders(0x00) or DataStreamIndex(0x01) expected\n"); goto error; } if ((c = readByte(fp)) != PROPERTY_ID_CODERS_UNPACK_SIZE) { QZ_ERROR("Resolve CodersInfo: kCoderUnpackSize(0x0c) expected: %02x\n", c); goto error; } coders->unPackSize = qzMalloc(coders->numFolders * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!coders->unPackSize) { QZ_ERROR("malloc error\n"); goto error; } for (int i = 0; i < coders->numFolders; ++i) { coders->unPackSize[i] = getU64FromBytes(fp); } if (readByte(fp) != PROPERTY_ID_END) { QZ_ERROR("Resolve CodersInfo: kEnd (0x00) expected\n"); goto error; } QZ_DEBUG("Resolve CodersInfo: finished\n"); return coders; error: freeCodersInfo(coders); return NULL; } Qz7zSubstreamsInfo_T *resolveSubstreamsInfo(int n_folder, FILE *fp) { unsigned char c; int total = 1; int end = 0; int unpackstreams_resolved = 0; int unpacksize_resolved = 0; int digests_resolved = 0; Qz7zSubstreamsInfo_T *substreams = qzMalloc(sizeof(Qz7zSubstreamsInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreams) { QZ_ERROR("malloc error\n"); return NULL; } memset(substreams, 0, sizeof(Qz7zSubstreamsInfo_T)); while (!end) { c = readByte(fp); switch (c) { case PROPERTY_ID_NUM_UNPACK_STREAM: if (unpackstreams_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } total = 0; QZ_DEBUG("Resolve SubstreamsInfo: number folders: %d\n", n_folder); substreams->numUnPackStreams = qzMalloc(n_folder * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreams->numUnPackStreams) { QZ_ERROR("malloc error\n"); goto error; } for (int i = 0; i < n_folder; ++i) { substreams->numUnPackStreams[i] = getU64FromBytes(fp); QZ_DEBUG(" numUnPackStreams[i] = %lu\n", substreams->numUnPackStreams[i]); total += substreams->numUnPackStreams[i]; } QZ_DEBUG("resolve numUnpackStreams(0x0d) done\n"); unpackstreams_resolved = 1; break; case PROPERTY_ID_SIZE: if (unpacksize_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } if (total - n_folder == 0) { QZ_DEBUG("every folder has one file. No unpacksize part. \n"); } else { substreams->unPackSize = qzMalloc((total - n_folder) * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreams->unPackSize) { QZ_DEBUG("malloc error\n"); goto error; } for (int i = 0; i < total - n_folder; ++i) { substreams->unPackSize[i] = getU64FromBytes(fp); QZ_DEBUG("unpacksize: %lu total:%d folder:%d\n", substreams->unPackSize[i], total, n_folder); } } QZ_DEBUG("resolve kSize(0x09) done \n"); unpacksize_resolved = 1; break; case PROPERTY_ID_CRC: if (digests_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } substreams->digests = qzMalloc(sizeof(Qz7zDigest_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreams->digests) { QZ_ERROR("malloc error\n"); goto error; } if ((c = readByte(fp)) != 1) { QZ_DEBUG("Resolve Substreams Info: not allaredefined ERROR. " "c = %02x\n", c); goto error; } substreams->digests->allAreDefined = 1; QZ_DEBUG(" read allaredefined : 111 total: %d\n", total); substreams->digests->numDefined = total; substreams->digests->crc = qzMalloc(total * sizeof(uint32_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreams->digests->crc) { QZ_ERROR("malloc error\n"); goto error; } for (int i = 0; i < total; ++i) { readCRC(fp); } QZ_DEBUG("resolve CRC(0x0a) done of substreams\n"); digests_resolved = 1; break; case PROPERTY_ID_END: end = 1; break; default: QZ_ERROR("resolve unexpected byte\n"); goto error; } } QZ_DEBUG("Resolve SubstreamsInfo: finished\n"); return substreams; error: freeSubstreamsInfo(substreams); return NULL; } static int readNames(Qz7zFileItem_T *p, uint64_t num, FILE *fp) { unsigned char c; uint64_t u64; int i, j; char path[PATH_MAX]; /* wc is used to store a wchar_t for ASCII, it is stored at wc[0] and wc[1] is '\0' */ char wc[2]; size_t n; u64 = getU64FromBytes(fp); // size QZ_DEBUG("u64 = %lu\n", u64); (void)u64; c = readByte(fp); if (c != 0) { QZ_ERROR("0x11 label external is not 0. Exit. c = %d\n", c); return QZ7Z_ERR_NOT_EXPECTED_CHAR; } for (i = 0; i < num; ++i) { memset(path, 0, sizeof(path)); j = 0; while (1) { n = fread(wc, 1, sizeof(wc), fp); CHECK_FREAD_RETURN(n, sizeof(wc)) if (!wc[0] && !wc[1]) // two-zero byte means the end break; path[j++] = wc[0]; } path[j] = 0; QZ_DEBUG("path: %s length: %d\n", path, j); (p + i)->nameLength = j + 1; // not include terminal null byte (p + i)->fileName = malloc(j + 1); CHECK_ALLOC_RETURN_VALUE((p + i)->fileName) strncpy((p + i)->fileName, path, j + 1); } return QZ7Z_OK; } static int readTimes(Qz7zFileItem_T *p, uint64_t num, FILE *fp) { uint64_t section_size; size_t nr; FILETIME_T ft; section_size = getU64FromBytes(fp); (void)section_size; if (readByte(fp) != 1) { QZ_ERROR("Resolve Times: AllAreDefined must be 1\n"); return QZ7Z_ERR_TIMES; } if (readByte(fp) != 0) { QZ_ERROR("Resolve Times: External must be 0\n"); return QZ7Z_ERR_TIMES; } for (int i = 0; i < num; ++i) { nr = fread(&ft.low, sizeof(uint32_t), 1, fp); if (nr < 1) { QZ_ERROR("readTimes: fread error\n"); return QZ7Z_ERR_READ_LESS; } nr = fread(&ft.high, sizeof(uint32_t), 1, fp); if (nr < 1) { QZ_ERROR("readTimes: fread error\n"); return QZ7Z_ERR_READ_LESS; } (p + i)->mtime = filetimeToUnixtime(ft); (p + i)->atime = filetimeToUnixtime(ft); } return QZ7Z_OK; } static int readAttributes(Qz7zFileItem_T *p, uint64_t num, FILE *fp) { unsigned char c; uint64_t u64; uint32_t attr; size_t nr; u64 = getU64FromBytes(fp); // size (void)u64; c = readByte(fp); // AllAreDefined if (c != 1) { QZ_ERROR("Resolve Attributes: AllAreDefined is not 1. Exit. " "c = %d\n", c); return QZ7Z_ERR_NOT_EXPECTED_CHAR; } c = readByte(fp); // External if (c != 0) { QZ_ERROR("Resolve Attributes: External is not 0. Exit. c = %d\n", c); return QZ7Z_ERR_NOT_EXPECTED_CHAR; } for (int i = 0; i < num; ++i) { nr = fread(&attr, sizeof(uint32_t), 1, fp); if (nr < 1) { QZ_ERROR("readAttributes: fread error\n"); return QZ7Z_ERR_READ_LESS; } (p + i)->attribute = attr; } return QZ7Z_OK; } Qz7zFilesInfo_Dec_T *resolveFilesInfo(FILE *fp) { int n; int i; int j; int end; int file_index; unsigned char c; uint64_t u64; uint64_t total_num; uint64_t dir_num; uint64_t file_num; Qz7zFilesInfo_Dec_T *files = qzMalloc(sizeof(Qz7zFilesInfo_Dec_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!files) { QZ_ERROR("malloc error\n"); return NULL; } memset(files, 0, sizeof(Qz7zFilesInfo_Dec_T)); total_num = getU64FromBytes(fp); Qz7zFileItem_T *p = qzMalloc(total_num * sizeof( Qz7zFileItem_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!p) { QZ_ERROR("malloc error\n"); goto error; } memset(p, 0, total_num * sizeof(*p)); end = 0; while (!end) { switch ((c = readByte(fp))) { case PROPERTY_ID_END: end = 1; break; case PROPERTY_ID_EMPTY_STREAM: file_index = 0; dir_num = 0; /* n bytes to hold this information */ n = (total_num % 8) ? (total_num / 8 + 1) : (total_num / 8); u64 = getU64FromBytes(fp); /* property size */ file_index = 0; for (i = 0; i < n; ++i) { // read n bytes property c = readByte(fp); for (j = 7; j >= 0; --j) { int is_dir = !!(c & 1 << j); p[file_index++].isDir = is_dir; if (is_dir) { dir_num++; } if (total_num == file_index) { break; } } } file_num = total_num - dir_num; files->file_num = file_num; files->dir_num = dir_num; break; case PROPERTY_ID_EMPTY_FILE: file_index = 0; u64 = getU64FromBytes(fp); // property size for (i = 0; i < u64; ++i) { c = readByte(fp); for (j = 7; j >= 0; --j) { p[file_index].isEmpty = !!(c & 1 << j); if (p[file_index].isEmpty) { p[file_index].isDir = 0; } file_index++; if (total_num == file_index) break; } } break; case PROPERTY_ID_NAME: if (readNames(p, total_num, fp) < 0) { goto error; } break; case PROPERTY_ID_CTIME: case PROPERTY_ID_ATIME: case PROPERTY_ID_MTIME: if (readTimes(p, total_num, fp) < 0) { goto error; } break; case PROPERTY_ID_ATTRIBUTES: if (readAttributes(p, total_num, fp) < 0) { goto error; } break; case PROPERTY_ID_DUMMY: c = readByte(fp); if (c) { skipNByte(c, fp); } break; default: QZ_ERROR("Not expected attribute\n"); goto error; } } files->items = p; return files; error: if (p) { qzFree(p); } if (files) { qzFree(files); } return NULL; } Qz7zStreamsInfo_T *resolveMainStreamsInfo(FILE *fp) { unsigned char c; int end = 0; int pack_info_resolved = 0; int coders_info_allocated = 0; int coders_info_resolved = 0; int substreams_info_resolved = 0; Qz7zStreamsInfo_T *streamsInfo = malloc(sizeof(Qz7zStreamsInfo_T)); if (!streamsInfo) { QZ_ERROR("malloc error\n"); return NULL; } memset(streamsInfo, 0, sizeof(Qz7zStreamsInfo_T)); while (!end) { switch (c = readByte(fp)) { case PROPERTY_ID_PACKINFO: if (pack_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } streamsInfo->packInfo = resolvePackInfo(fp); if (!streamsInfo->packInfo) { QZ_ERROR("Resolve Pack Info error\n"); goto error; } pack_info_resolved = 1; break; case PROPERTY_ID_UNPACKINFO: if (coders_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } streamsInfo->codersInfo = resolveCodersInfo(fp); if (!streamsInfo->codersInfo) { QZ_ERROR("Resolve Coders Info error\n"); goto error; } coders_info_allocated = 1; coders_info_resolved = 1; break; case PROPERTY_ID_SUBSTREAMSINFO: if (substreams_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } if (!coders_info_allocated) { QZ_ERROR("No coders info\n"); goto error; } streamsInfo->substreamsInfo = resolveSubstreamsInfo(streamsInfo ->codersInfo->numFolders, fp); if (!streamsInfo->substreamsInfo) { QZ_ERROR("Resolve Substreams Info error\n"); goto error; } substreams_info_resolved = 1; break; case PROPERTY_ID_END: end = 1; break; default: QZ_ERROR("Resolve Mainstreams Info Error\n"); goto error; } } return streamsInfo; error: freeStreamsInfo(streamsInfo); return NULL; } Qz7zEndHeader_T *resolveEndHeader(FILE *fp, Qz7zSignatureHeader_T *sheader) { Qz7zEndHeader_T *eheader = malloc(sizeof(Qz7zEndHeader_T)); if (!eheader) { QZ_ERROR("malloc error\n"); return NULL; } memset(eheader, 0, sizeof(Qz7zEndHeader_T)); unsigned int status = 0; unsigned char c; int end = 0; int has_archive_property = 0; int archive_property_resolved = 0; int streams_info_resolved = 0; int files_info_resolved = 0; fseek(fp, sheader->nextHeaderOffset + 0x20, SEEK_CUR); while (!end) { switch (c = readByte(fp)) { case PROPERTY_ID_HEADER: status = RESOLVE_STATUS_IN_HEADER; break; case PROPERTY_ID_ARCHIVE_PROPERTIES: if (archive_property_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } has_archive_property = 1; status = RESOLVE_STATUS_IN_ARCHIVE_PROPERTIES; eheader->propertyInfo = resolveArchiveProperties(fp); if (!eheader->propertyInfo) { QZ_ERROR("Resolve Archive property error\n"); goto error; } archive_property_resolved = 1; break; case PROPERTY_ID_MAIN_STREAMSINFO: if (streams_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } status = RESOLVE_STATUS_IN_STREAMSINFO; eheader->streamsInfo = resolveMainStreamsInfo(fp); if (!eheader->streamsInfo) { QZ_ERROR("malloc error\n"); goto error; } streams_info_resolved = 1; break; case PROPERTY_ID_FILESINFO: if (files_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } status = RESOLVE_STATUS_IN_FILESINFO; eheader->filesInfo_Dec = resolveFilesInfo(fp); if (!eheader->filesInfo_Dec) { QZ_ERROR("Resolve Files Info error\n"); goto error; } files_info_resolved = 1; break; case PROPERTY_ID_END: QZ_DEBUG("read kEnd: %d\n\n\n", status); if (status == RESOLVE_STATUS_IN_FILESINFO) end = 1; break; default: QZ_ERROR("Resolve End Header Error\n"); goto error; } } if (!has_archive_property) { QZ_ERROR("ERROR: property 'QAT7z' not found\n"); QZ_ERROR("This archive is not compressed by QAT,"); QZ_ERROR("QAT only support 7z archive compressed by QAT\n"); goto error; } return eheader; error: freeEndHeader(eheader, 0); return NULL; } static int createEmptyFile(const char *filename) { FILE *fp = fopen(filename, "w"); if (!fp) { QZ_ERROR("create %s error\n", filename); return -1; } fclose(fp); return 0; } /** * create `newdir` at current directory * back: 1 return to original dir, 0 otherwise */ int createDir(const char *newdir, int back) { int ret; char *dirc, *basec; char pwd[PATH_MAX]; char dir_name[PATH_MAX + 1] = {0}; char base_name[PATH_MAX + 1] = {0}; if (!getcwd(pwd, sizeof(pwd))) { return QZ7Z_ERR_GETCWD; } QZ_DEBUG("working directory: %s\n", pwd); strncpy(dir_name, newdir, PATH_MAX); strncpy(base_name, newdir, PATH_MAX); dirc = dirname(dir_name); basec = basename(base_name); if (!strcmp(dirc, ".")) { if (mkdir(newdir, 0755) < 0) { if (errno != EEXIST) { perror("create dir failed\n"); return QZ7Z_ERR_MKDIR; } } if (chdir(newdir) < 0) { perror("cannot change working dir\n"); return QZ7Z_ERR_CHDIR; } if (back) { if (chdir(pwd) < 0) { perror("cannot change working dir\n"); return QZ7Z_ERR_CHDIR; } } return QZ7Z_OK; } if ((ret = createDir(dirc, 0)) < 0) return ret; if ((ret = createDir(basec, 0)) < 0) return ret; if (back) { if (chdir(pwd) < 0) { perror("cannot change working dir\n"); return QZ7Z_ERR_CHDIR; } } return QZ7Z_OK; } void decompressEmptyfilesAndDirectories(Qz7zFilesInfo_Dec_T *info) { uint64_t num = info->dir_num; Qz7zFileItem_T *p = info->items; for (int i = 0; i < num; ++i) { if (p[i].isDir) { createDir(p[i].fileName, 1); } else { createEmptyFile(p[i].fileName); } } } int checkHeaderCRC(Qz7zSignatureHeader_T *sh, FILE *fp) { uint32_t crc = 0; crc = crc32(crc, (unsigned char *)&sh->nextHeaderOffset, sizeof(uint64_t)); crc = crc32(crc, (unsigned char *)&sh->nextHeaderSize, sizeof(uint64_t)); crc = crc32(crc, (unsigned char *)&sh->nextHeaderCRC, sizeof(uint32_t)); if (crc != sh->startHeaderCRC) { QZ_ERROR("Signature CRC failed\n"); return -1; } size_t n; unsigned char buf[4096]; crc = 0; fseek(fp, sh->nextHeaderOffset + 0x20, SEEK_SET); while ((n = fread(buf, 1, sizeof(buf), fp))) { crc = crc32(crc, buf, n); } if (crc != sh->nextHeaderCRC) { QZ_ERROR("End header CRC failed\n"); return -1; } fseek(fp, 0, SEEK_SET); return 0; } void freePropertyInfo(Qz7zArchiveProperty_T *info) { Qz7zArchiveProperty_T *cur = info; while (cur) { free(cur->data); cur = cur->next; } qzFree(info); } void freePackInfo(Qz7zPackInfo_T *info) { if (info) { qzFree(info->PackSize); qzFree(info); } } void freeCodersInfo(Qz7zCodersInfo_T *info) { if (info) { if (info->folders) { for (int i = 0; i < info->numFolders; ++i) { Qz7zCoder_T *cur = info->folders[i].coder_list; while (cur) { qzFree(cur->codecID); cur = cur->next; } qzFree(info->folders[i].coder_list); } qzFree(info->folders); } qzFree(info->unPackSize); qzFree(info); } } void freeSubstreamsInfo(Qz7zSubstreamsInfo_T *info) { if (info) { qzFree(info->numUnPackStreams); qzFree(info->unPackSize); if (info->digests) { qzFree(info->digests->crc); qzFree(info->digests); } qzFree(info); } } void freeStreamsInfo(Qz7zStreamsInfo_T *info) { if (info) { freePackInfo(info->packInfo); freeCodersInfo(info->codersInfo); freeSubstreamsInfo(info->substreamsInfo); free(info); } } void freeFilesInfo(Qz7zFilesInfo_T *info) { qzFree(info); } void freeFilesDecInfo(Qz7zFilesInfo_Dec_T *info) { if (info) { qzFree(info->items); qzFree(info); } } void freeEndHeader(Qz7zEndHeader_T *h, int is_compress) { freePropertyInfo(h->propertyInfo); freeStreamsInfo(h->streamsInfo); if (is_compress) { freeFilesInfo(h->filesInfo); } else { freeFilesDecInfo(h->filesInfo_Dec); } free(h); } static int convertToSymlink(const char *name) { char resolved_path[PATH_MAX + 1]; FILE *file = fopen(name, "rb"); if (file) { char buf[1000 + 1]; char *ret = fgets(buf, sizeof(buf) - 1, file); fclose(file); /* To avoid CWE-22: Improper Limitation of a Pathname to a Restricted Directory * ('Path Traversal') attacks. * http://cwe.mitre.org/data/definitions/22.htm */ if (!realpath(name, resolved_path)) { return -1; } if (ret) { int ir = unlink(name); if (ir == 0) { ir = symlink(buf, name); } return ir; } } return -1; } int doDecompressFile(QzSession_T *sess, const char *src_file_name) { int ret = OK; struct stat src_file_stat; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; unsigned int saved_dst_buffer_size = 0; off_t src_file_size = 0, dst_file_size = 0, file_remaining = 0; unsigned char *src_buffer = NULL; unsigned char *src_buffer_orig = NULL; unsigned char *dst_buffer = NULL; FILE *src_file = NULL; FILE *dst_file = NULL; unsigned int bytes_read = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; int src_fd = -1; Qz7zFileItem_T *p = NULL; uint64_t dir_num = 0; uint64_t fil_num = 0; uint64_t file_index = 0; int is_last; int n_part; // how much parts can the src file be splitted int n_part_i; Qz7zSignatureHeader_T *sheader = NULL; Qz7zEndHeader_T *eheader = NULL; RunTimeList_T *run_time = NULL; \ RunTimeList_T *time_node = NULL; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); if (!time_list_head) { QZ_DEBUG("malloc RunTimeList_T error\n"); ret = QZ7Z_ERR_OOM; goto exit; } gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; time_node = time_list_head; run_time = calloc(1, sizeof(RunTimeList_T)); if (!run_time) { QZ_DEBUG("malloc RunTimeList_T error\n"); ret = QZ7Z_ERR_OOM; goto exit; } run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); src_file = fopen(src_file_name, "r"); if (src_file == NULL) { QZ_ERROR("cannot open file %s: %d\n", src_file_name, errno); ret = QZ7Z_ERR_OPEN; goto exit; } sheader = resolveSignatureHeader(src_file); if (!sheader) { QZ_ERROR("Resolve signature header\n"); ret = QZ7Z_ERR_SIG_HEADER; goto exit; } #ifdef QZ7Z_DEBUG print_signature_header(sheader); #endif if (checkHeaderCRC(sheader, src_file) < 0) { QZ_ERROR("Header error: CRC check failed\n"); ret = QZ7Z_ERR_HEADER_CRC; goto exit; } eheader = resolveEndHeader(src_file, sheader); if (!eheader) { QZ_ERROR("Cannot resolve end header\n"); ret = QZ7Z_ERR_RESOLVE_END_HEADER; goto exit; } fclose(src_file); src_file = NULL; // decode the dir p = eheader->filesInfo_Dec->items; dir_num = eheader->filesInfo_Dec->dir_num; fil_num = eheader->filesInfo_Dec->file_num; decompressEmptyfilesAndDirectories(eheader->filesInfo_Dec); // decode the content if (eheader->streamsInfo) { uint64_t folder_num = eheader->streamsInfo->codersInfo->numFolders; Qz7zFileItem_T *file_items = eheader->filesInfo_Dec->items + eheader->filesInfo_Dec->dir_num; for (int i = 0; i < folder_num; ++i) { uint64_t num_files_in_folder = eheader->streamsInfo->substreamsInfo->numUnPackStreams[i]; uint64_t total_unPack_size = eheader->streamsInfo->codersInfo->unPackSize[i]; for (int j = 0; j < num_files_in_folder - 1; ++file_index, ++j) { (file_items + file_index)->size = eheader->streamsInfo->substreamsInfo->unPackSize[j]; total_unPack_size -= (file_items + file_index)->size; } (file_items + file_index)->size = total_unPack_size; } src_fd = open(src_file_name, O_RDONLY); if (src_fd < 0) { QZ_INFO("Open input file %s failed\n", src_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } ret = fstat(src_fd, &src_file_stat); assert(!ret); if (S_ISBLK(src_file_stat.st_mode)) { if (ioctl(src_fd, BLKGETSIZE, &src_file_size) < 0) { perror(src_file_name); ret = QZ7Z_ERR_IOCTL; goto exit; } src_file_size *= 512; } else { src_file_size = src_file_stat.st_size; } src_file_size -= sheader->nextHeaderSize; src_file_size -= 32; src_buffer_size = (src_file_size > SRC_BUFF_LEN) ? SRC_BUFF_LEN : src_file_size; dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; saved_dst_buffer_size = dst_buffer_size; src_buffer = malloc(src_buffer_size); if (!src_buffer) { QZ_ERROR("malloc error\n"); goto exit; } src_buffer_orig = src_buffer; dst_buffer = malloc(dst_buffer_size); if (!dst_buffer) { QZ_ERROR("malloc error\n"); goto exit; } src_file = fopen(src_file_name, "r"); if (!src_file) { QZ_ERROR("file open error: %s\n", src_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } // skip the signature header fseek(src_file, 32, SEEK_SET); int i = 0; // file index file_remaining = src_file_size; read_more = 1; n_part = src_file_size / SRC_BUFF_LEN; n_part = (src_file_size % SRC_BUFF_LEN) ? n_part + 1 : n_part; is_last = 0; n_part_i = 1; off_t cur_offset; cur_offset = 0; off_t file_read_processed_size = 0; int need_check_file_with_same_name = 1; do { is_last = (n_part_i++ == n_part); if (read_more) { src_buffer = src_buffer_orig; bytes_read = fread(src_buffer, 1, src_buffer_size, src_file); QZ_INFO("Reading input file %s (%u Bytes)\n", src_file_name, bytes_read); } else { bytes_read = file_remaining; } puts("Decompressing..."); if (n_part > 1 && is_last) bytes_read -= sheader->nextHeaderSize; int buffer_remaining = bytes_read; do { unsigned int bytes_processed = buffer_remaining; ret = doDecompressBuffer(sess, src_buffer, &bytes_processed, dst_buffer, &dst_buffer_size, time_list_head, is_last); file_read_processed_size += bytes_processed; src_buffer += bytes_processed; buffer_remaining -= bytes_processed; if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { if (0 != bytes_processed) { if (-1 == fseek(src_file, file_read_processed_size, SEEK_SET)) { ret = ERROR; goto exit; } read_more = 1; } else if (QZ_BUF_ERROR == ret) { //dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more" "destination buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer " "with size %u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { read_more = 1; unsigned int dst_left; unsigned char *dst_write; size_t n_written; unsigned int st_mode; Qz7zFileItem_T *cur_file; dst_write = dst_buffer; dst_left = dst_buffer_size; dst_file_size += dst_buffer_size; while (dst_left) { cur_file = p + dir_num + i; st_mode = (cur_file->attribute) >> 16; if (need_check_file_with_same_name) { dst_file = fopen(cur_file->fileName, "w+"); } else { dst_file = fopen(cur_file->fileName, "a"); } if (NULL == dst_file) { if (S_ISLNK(st_mode)) { QZ_DEBUG("open an broken soft-link file, " "need to delete it\n"); if (!remove(cur_file->fileName)) { QZ_DEBUG("remove file %s error\n", cur_file->fileName); ret = ERROR; goto exit; } dst_file = fopen(cur_file->fileName, "a"); if (NULL == dst_file) { QZ_DEBUG("open file %s error\n", cur_file->fileName); ret = ERROR; goto exit; } } else { QZ_DEBUG("open file error\n"); ret = ERROR; goto exit; } } if (cur_file->size - cur_offset <= dst_left) { n_written = fwrite(dst_write, 1, cur_file->size - cur_offset, dst_file); if (n_written == cur_file->size - cur_offset) { ++i; need_check_file_with_same_name = 1; cur_offset = 0; } else { need_check_file_with_same_name = 0; cur_offset += n_written; } dst_left -= n_written; dst_write += n_written; } else { n_written = fwrite(dst_write, 1, dst_left, dst_file); dst_write = dst_buffer; cur_offset += dst_left; dst_left = 0; need_check_file_with_same_name = 0; } fclose(dst_file); dst_file = NULL; if (need_check_file_with_same_name) { if (S_ISLNK(st_mode)) { convertToSymlink(cur_file->fileName); } } }// end while dst_buffer_size = saved_dst_buffer_size; } } while (buffer_remaining); file_remaining -= bytes_read; } while (file_remaining > 0); } else { QZ_INFO("Decompressing...\n"); } gettimeofday(&run_time->time_e, NULL); // restore the time struct utimbuf tb; for (int i = 0; i < dir_num + fil_num; ++i) { tb.actime = p[i].atime; tb.modtime = p[i].mtime; utime(p[i].fileName, &tb); } // restore the attribute for (int i = 0; i < dir_num + fil_num; ++i) { __mode_t mode = p[i].attribute >> 16; /* * If the file is a symbolic link, don't change it mode and skip it. * Otherwise, it will change the mode of linked file. */ if (S_ISLNK(mode)) continue; chmod(p[i].fileName, p[i].attribute >> 16); } displayStats(time_list_head, src_file_size, dst_file_size, 0/* is_compress */); exit: if (dst_file) { fclose(dst_file); } if (src_file) { fclose(src_file); } if (dst_buffer) { free(dst_buffer); } if (src_buffer_orig) { free(src_buffer_orig); } if (eheader) { freeEndHeader(eheader, 0); } if (sheader) { qzFree(sheader); } if (src_fd >= 0) { close(src_fd); } freeTimeList(time_list_head); if (!g_keep && OK == ret) { int re = remove(src_file_name); if (re != 0) { QZ_ERROR("deleteSourceFile error: %d\n", re); return re; } } return ret; } /* * the main decompress API for 7z file */ int qz7zDecompress(QzSession_T *sess, const char *archive) { return doDecompressFile(sess, archive); } /* * calculate a file's crc */ static int64_t calculateCRC(char *filename, size_t n) { FILE *fp; uint32_t crc = 0; size_t ret; size_t remaining = n; size_t len; unsigned char *buf; buf = malloc(SRC_BUFF_LEN); if (!buf) { QZ_ERROR("oom\n"); return QZ7Z_ERR_OOM; } fp = fopen(filename, "r"); if (!fp) { QZ_ERROR("filename open error\n"); free(buf); return QZ7Z_ERR_OPEN; } while (remaining > 0) { if (remaining > SRC_BUFF_LEN) len = SRC_BUFF_LEN; else len = remaining; ret = fread(buf, 1, len, fp); CHECK_FREAD_RETURN(ret, len) crc = crc32(crc, buf, len); remaining -= len; } free(buf); fclose(fp); QZ_DEBUG("%s crc: %08x\n", filename, crc); return crc; } void qzListDestroy(QzListHead_T *head) { Qz7zFileItem_T *fi; QzListNode_T *node, *tmp_node; node = head->next; do { for (int j = 0; j < node->used; ++j) { fi = node->items[j]; if (fi) { if (fi->fileName) { free(fi->fileName); fi->fileName = NULL; } free(fi); fi = NULL; } } free(node->items); tmp_node = node; node = node->next; free(tmp_node); } while (node); free(head); } void itemListDestroy(Qz7zItemList_T *p) { QzListHead_T *h; for (int i = 0; i < 2; ++i) { h = p->items[i]; qzListDestroy(h); } QzCatagoryTable_T *table = p->table; QzCatagory_T cat; if (table) { for (int i = 0; i < table->cat_num; ++i) { cat = table->catas[i]; free(cat.cat_files->next->items); free(cat.cat_files->next); free(cat.cat_files); } free(table->catas); free(table); } free(p); } static uint32_t calculateSymCRC(char *filename, size_t n) { uint32_t crc = 0; char *buf; buf = malloc(PATH_MAX + 1); if (!buf) { QZ_ERROR("oom\n"); return 0; } ssize_t size = readlink(filename, buf, PATH_MAX); if ((unsigned int)size != (unsigned int)n) { QZ_ERROR("readlink error\n"); free(buf); return 0; } crc = crc32(crc, (unsigned char *)buf, n); free(buf); return crc; } Qz7zFileItem_T *fileItemCreate(char *f) { Qz7zFileItem_T *p = malloc(sizeof(Qz7zFileItem_T)); if (p) { memset(p, 0, sizeof(Qz7zFileItem_T)); p->nameLength = strlen(f) + 1; p->fileName = (char *)malloc(p->nameLength); if (!p->fileName) { QZ_ERROR("oom\n"); free(p); return NULL; } memset(p->fileName, 0, p->nameLength); strcpy(p->fileName, f); struct stat buf; if (lstat(p->fileName, &buf) < 0) { QZ_ERROR("stat func error\n"); free(p->fileName); free(p); return NULL; } if (S_ISLNK(buf.st_mode)) { p->isSymLink = 1; p->crc = calculateSymCRC(p->fileName, buf.st_size); p->size = buf.st_size; } else if (S_ISDIR(buf.st_mode)) { p->isDir = 1; } else { p->size = buf.st_size; p->isEmpty = buf.st_size ? 0 : 1; p->crc = calculateCRC(p->fileName, p->size); } p->mtime = buf.st_mtime; p->mtime_nano = buf.st_mtim.tv_nsec; p->atime = buf.st_atime; p->atime_nano = buf.st_atim.tv_nsec; //p-7zip use 0x80000 as a unix file flag p->attribute = buf.st_mode << 16 | (0x8000); } return p; } #define QZ7Z_LIST_DEFAULT_NUM_PER_NODE 1000 void qzListAdd(QzListHead_T *head, void **fi) { // let cur points to the first node QzListNode_T *cur = head->next; QzListNode_T *last = cur; while (cur && cur->used == cur->num) { last = cur; cur = cur->next; } if (cur) { // this node is not full #ifdef QZ7Z_DEBUG QZ_DEBUG("Before Add : head num: %d total: %d last->used: %d\n", head->num, head->total, cur->used); #endif cur->items[cur->used++] = *fi; head->total++; } else { cur = (QzListNode_T *)malloc(head->num * sizeof(QzListNode_T)); CHECK_ALLOC_RETURN_VALUE(cur); cur->num = head->num; cur->used = 0; cur->next = NULL; #ifdef QZ7Z_DEBUG QZ_DEBUG("applying a new node\n"); #endif cur->items = (void **)malloc(head->num * sizeof(void *)); CHECK_ALLOC_RETURN_VALUE(cur->items) last->next = cur; #ifdef QZ7Z_DEBUG QZ_DEBUG("Before Add : head num: %d total: %d cur->used: %d\n", head->num, head->total, cur->used); #endif cur->items[cur->used++] = *fi; head->total++; } #ifdef QZ7Z_DEBUG QZ_DEBUG(" add %s to list %p : total: %u\n", ((Qz7zFileItem_T *)(*fi))->fileName, (void *)head, head->total); QZ_DEBUG("After Add : head num: %d total: %d last->used: %d\n", head->num, head->total, cur->used); #endif } void *qzListGet(QzListHead_T *head, int index) { int i; if (index >= head->total) { QZ_ERROR("qzListGet: index out of total\n"); return NULL; } QzListNode_T *cur = head->next; int steps = index / head->num; for (i = 0; i < steps; ++i) { cur = cur->next; } return cur->items[index % head->num]; } QzListHead_T *qzListCreate(int num_per_node) { QzListNode_T *node; if (num_per_node <= 0) { num_per_node = QZ7Z_LIST_DEFAULT_NUM_PER_NODE; } QzListHead_T *p = (QzListHead_T *)malloc(sizeof(QzListHead_T)); CHECK_ALLOC_RETURN_VALUE(p) node = (QzListNode_T *)malloc(sizeof(QzListNode_T)); CHECK_ALLOC_RETURN_VALUE(node) node->items = (void **)malloc(num_per_node * sizeof(void *)); CHECK_ALLOC_RETURN_VALUE(node->items) node->num = num_per_node; node->used = 0; node->next = NULL; p->next = node; p->num = num_per_node; p->total = 0; return p; } Qz7zSignatureHeader_T *generateSignatureHeader(void) { Qz7zSignatureHeader_T *header = qzMalloc(sizeof(Qz7zSignatureHeader_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!header) { QZ_ERROR("malloc error\n"); return NULL; } for (int i = 0; i < 6; ++i) { header->signature[i] = g_header_signature[i]; } header->majorVersion = G_7ZHEADER_MAJOR_VERSION; header->minorVersion = G_7ZHEADER_MINOR_VERSION; return header; } Qz7zPackInfo_T *generatePackInfo(Qz7zItemList_T *the_list, size_t compressed_size) { Qz7zPackInfo_T *pack = qzMalloc(sizeof(Qz7zPackInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!pack) { QZ_ERROR("malloc error\n"); return NULL; } memset(pack, 0, sizeof(Qz7zPackInfo_T)); pack->PackPos = 0; pack->NumPackStreams = the_list->table->cat_num; pack->PackSize = qzMalloc(pack->NumPackStreams * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!pack->PackSize) { qzFree(pack); return NULL; } pack->PackSize[0] = compressed_size; pack->PackStreamDigests = NULL; return pack; } static Qz7zCoder_T *generateCoder(void) { Qz7zCoder_T *coder = qzMalloc(sizeof(Qz7zCoder_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!coder) { QZ_ERROR("malloc error\n"); return NULL; } coder->coderFirstByte.uc = 0x03; /* 0000 0011 */ coder->codecID = qzMalloc(3 * sizeof(unsigned char), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!coder->codecID) { QZ_ERROR("malloc error\n"); return NULL; } memcpy((char *)coder->codecID, g_deflate_codecId, 3); coder->numInStreams = 0; coder->numOutStreams = 0; coder->propertySize = 0; coder->properties = NULL; coder->next = NULL; return coder; } Qz7zFolderInfo_T *generateFolderInfo(Qz7zItemList_T *the_list, int n_folders) { if (n_folders <= 0) { n_folders = 1; } Qz7zFolderInfo_T *folders = qzMalloc(n_folders * sizeof(Qz7zFolderInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!folders) { QZ_ERROR("malloc error\n"); return NULL; } folders->items = the_list->items[1]; folders->numCoders = 1; folders->coder_list = generateCoder(); folders->numBindPairs = 0; folders->inIndex = NULL; folders->outIndex = NULL; folders->numPackedStreams = 0; folders->index = NULL; return folders; } Qz7zCodersInfo_T *generateCodersInfo(Qz7zItemList_T *the_list) { Qz7zCodersInfo_T *coders = qzMalloc(sizeof(Qz7zCodersInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!coders) { QZ_ERROR("malloc error\n"); return NULL; } coders->numFolders = the_list->table->cat_num; coders->folders = generateFolderInfo(the_list, coders->numFolders); if (!coders->folders) { QZ_ERROR("malloc error\n"); qzFree(coders); return NULL; } coders->unPackSize = qzMalloc(coders->numFolders * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!coders->unPackSize) { QZ_ERROR("malloc error\n"); qzFree(coders->folders); qzFree(coders); return NULL; } for (int i = 0; i < coders->numFolders; ++i) { QzCatagory_T *cat = &(the_list->table->catas[i]); coders->unPackSize[i] = 0; for (int j = 0; j < cat->cat_files->total; ++j) { Qz7zFileItem_T *p = (Qz7zFileItem_T *)qzListGet(cat->cat_files, j); coders->unPackSize[i] += p->size; } } coders->unPackDigests = NULL; /* not used */ return coders; } Qz7zDigest_T *generateDigestInfo(QzListHead_T *head) { Qz7zDigest_T *digests = qzMalloc(sizeof(Qz7zDigest_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!digests) { QZ_ERROR("malloc error\n"); return NULL; } digests->allAreDefined = 1; digests->numStreams = head->total; digests->numDefined = head->total; digests->crc = qzMalloc(digests->numDefined * sizeof(uint32_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!digests->crc) { QZ_ERROR("malloc error\n"); qzFree(digests); return NULL; } for (int i = 0; i < digests->numDefined; ++i) { Qz7zFileItem_T *p = (Qz7zFileItem_T *)qzListGet(head, i); (digests->crc)[i] = p->crc; } return digests; } Qz7zSubstreamsInfo_T *generateSubstreamsInfo(Qz7zItemList_T *the_list) { int index_of_file = 0; // index of all files in the list Qz7zFileItem_T *fi; Qz7zSubstreamsInfo_T *substreamsInfo = qzMalloc(sizeof(Qz7zSubstreamsInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreamsInfo) { QZ_ERROR("malloc error\n"); return NULL; } memset(substreamsInfo, 0, sizeof(Qz7zSubstreamsInfo_T)); QzListHead_T *h = the_list->items[1]; uint64_t total_files = h->total; if (!total_files) { qzFree(substreamsInfo); return NULL; } substreamsInfo->numFolders = the_list->table->cat_num; substreamsInfo->numUnPackStreams = qzMalloc(substreamsInfo->numFolders * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreamsInfo->numUnPackStreams) { QZ_ERROR("malloc error\n"); qzFree(substreamsInfo); return NULL; } // n_files - n_folder if (total_files != 1) { substreamsInfo->unPackSize = qzMalloc((total_files - 1) * sizeof(uint64_t), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!substreamsInfo->unPackSize) { QZ_ERROR("malloc error\n"); qzFree(substreamsInfo->numUnPackStreams); qzFree(substreamsInfo); return NULL; } } for (int i = 0; i < substreamsInfo->numFolders; ++i) { h = the_list->table->catas[i].cat_files; substreamsInfo->numUnPackStreams[i] = h->total; if (h->total == 1 || total_files == 1) continue; // folder has one file, don't need the unpacksize for (int j = 0; j < h->total - 1; ++j) { fi = qzListGet(h, j); substreamsInfo->unPackSize[index_of_file++] = fi->size; } } substreamsInfo->digests = generateDigestInfo(h); if (!substreamsInfo->digests) { QZ_ERROR("malloc error\n"); if (substreamsInfo->unPackSize) { qzFree(substreamsInfo->unPackSize); } qzFree(substreamsInfo->numUnPackStreams); qzFree(substreamsInfo); return NULL; } return substreamsInfo; } Qz7zFilesInfo_T *generateFilesInfo(Qz7zItemList_T *the_list) { Qz7zFilesInfo_T *filesInfo = qzMalloc(sizeof(Qz7zFilesInfo_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!filesInfo) { QZ_ERROR("malloc error\n"); return NULL; } memset(filesInfo, 0, sizeof(Qz7zFilesInfo_T)); filesInfo->num = the_list->items[0]->total + the_list->items[1]->total; filesInfo->head[0] = the_list->items[0]; filesInfo->head[1] = the_list->items[1]; return filesInfo; } Qz7zStreamsInfo_T *generateStreamsInfo(Qz7zItemList_T *the_list, size_t compressed_size) { uint64_t n = the_list->items[1]->total; if (!n) return NULL; Qz7zStreamsInfo_T *streams = malloc(sizeof(Qz7zStreamsInfo_T)); CHECK_ALLOC_RETURN_VALUE(streams) streams->packInfo = generatePackInfo(the_list, compressed_size); streams->codersInfo = generateCodersInfo(the_list); streams->substreamsInfo = generateSubstreamsInfo(the_list); return streams; } Qz7zArchiveProperty_T *generatePropertyInfo(void) { Qz7zArchiveProperty_T *property = qzMalloc(sizeof(Qz7zArchiveProperty_T), QZ_AUTO_SELECT_NUMA_NODE, PINNED_MEM); if (!property) { QZ_ERROR("malloc error\n"); return NULL; } property->id = QZ7Z_PROPERTY_ID_INTEL7Z_1001; property->size = sizeof(g_property_data); property->data = malloc(property->size * sizeof(unsigned char)); CHECK_ALLOC_RETURN_VALUE(property->data) memcpy(property->data, g_property_data, property->size); property->next = NULL; return property; } Qz7zEndHeader_T *generateEndHeader(Qz7zItemList_T *the_list, size_t compressed_size) { Qz7zEndHeader_T *header = malloc(sizeof(Qz7zEndHeader_T)); CHECK_ALLOC_RETURN_VALUE(header) header->propertyInfo = generatePropertyInfo(); header->streamsInfo = generateStreamsInfo(the_list, compressed_size); header->filesInfo = generateFilesInfo(the_list); return header; } QzCatagoryTable_T *createCatagoryList(void) { QzCatagoryTable_T *cat_tbl; cat_tbl = malloc(sizeof(QzCatagoryTable_T)); CHECK_ALLOC_RETURN_VALUE(cat_tbl) cat_tbl->cat_num = sizeof(g_category_names) / sizeof(g_category_names[0]); cat_tbl->catas = malloc(cat_tbl->cat_num * sizeof(QzCatagory_T)); CHECK_ALLOC_RETURN_VALUE(cat_tbl->catas) // the last one for all other files for (int i = 0; i < cat_tbl->cat_num; ++i) { cat_tbl->catas[i].cat_id = i; cat_tbl->catas[i].cat_name = g_category_names[i]; cat_tbl->catas[i].cat_files = qzListCreate(1000); } return cat_tbl; } int getCatagory(QzCatagoryTable_T *tbl, Qz7zFileItem_T *p) { return 0; } /* * return 0 success * -1 failed */ int scanFilesIntoCatagory(Qz7zItemList_T *the_list) { int cat_index; QzListHead_T *files = the_list->items[1]; QzCatagory_T *cat = the_list->table->catas; for (int i = 0; i < files->total; ++i) { Qz7zFileItem_T *p = qzListGet(files, i); // decide the category for the fileitem cat_index = getCatagory(the_list->table, p); // add to the category list qzListAdd(cat[cat_index].cat_files, (void **)&p); } return 0; } int writeSignatureHeader(Qz7zSignatureHeader_T *header, FILE *fp) { size_t n; n = fwrite(header->signature, 1, sizeof(header->signature), fp); CHECK_FWRITE_RETURN(n, sizeof(header->signature)) n = fwrite(&header->majorVersion, 1, sizeof(header->majorVersion), fp); CHECK_FWRITE_RETURN(n, sizeof(header->majorVersion)) n = fwrite(&header->minorVersion, 1, sizeof(header->minorVersion), fp); CHECK_FWRITE_RETURN(n, sizeof(header->minorVersion)) n = fwrite(&header->startHeaderCRC, 1, sizeof(header->startHeaderCRC), fp); CHECK_FWRITE_RETURN(n, sizeof(header->startHeaderCRC)) n = fwrite(&header->nextHeaderOffset, 1, sizeof(header->nextHeaderOffset), fp); CHECK_FWRITE_RETURN(n, sizeof(header->nextHeaderOffset)) n = fwrite(&header->nextHeaderSize, 1, sizeof(header->nextHeaderSize), fp); CHECK_FWRITE_RETURN(n, sizeof(header->nextHeaderSize)) n = fwrite(&header->nextHeaderCRC, 1, sizeof(header->nextHeaderCRC), fp); CHECK_FWRITE_RETURN(n, sizeof(header->nextHeaderCRC)) return QZ7Z_OK; } /* * write property structure to file * if crc is not null, return the crc of the bytes that have written * return the bytes of written */ size_t writeArchiveProperties(Qz7zArchiveProperty_T *property, FILE *fp, uint32_t *crc) { size_t size; size_t total_size = 0; total_size += writeTag(PROPERTY_ID_ARCHIVE_PROPERTIES, fp, crc); total_size += writeNumber(property->id, fp, crc); total_size += writeNumber(property->size, fp, crc); size = fwrite(property->data, 1, property->size, fp); CHECK_FWRITE_RETURN(size, property->size) *crc = crc32(*crc, property->data, property->size); total_size += size; total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writePackInfo(Qz7zPackInfo_T *pack, FILE *fp, uint32_t *crc) { int i; size_t total_size = 0; total_size += writeTag(PROPERTY_ID_PACKINFO, fp, crc); total_size += writeNumber(pack->PackPos, fp, crc); total_size += writeNumber(pack->NumPackStreams, fp, crc); total_size += writeTag(PROPERTY_ID_SIZE, fp, crc); for (i = 0; i < pack->NumPackStreams; ++i) { total_size += writeNumber(pack->PackSize[i], fp, crc); } total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writeFolder(Qz7zFolderInfo_T *folder, FILE *fp, uint32_t *crc) { int i; size_t size; size_t total_size = 0; Qz7zCoder_T *coder = folder->coder_list; total_size += writeNumber(folder->numCoders, fp, crc); for (i = 0; i < folder->numCoders; ++i) { total_size += writeByte(coder->coderFirstByte.uc, fp, crc); size = fwrite(coder->codecID, sizeof(unsigned char), coder->coderFirstByte.st.CodecIdSize, fp); CHECK_FWRITE_RETURN(size, coder->coderFirstByte.st.CodecIdSize) total_size += size; *crc = crc32(*crc, coder->codecID, coder->coderFirstByte.st.CodecIdSize); } return total_size; } size_t writeCodersInfo(Qz7zCodersInfo_T *coders, FILE *fp, uint32_t *crc) { int i; size_t total_size = 0; total_size += writeTag(PROPERTY_ID_UNPACKINFO, fp, crc); total_size += writeTag(PROPERTY_ID_FOLDER, fp, crc); total_size += writeNumber(coders->numFolders, fp, crc); total_size += writeByte(0, fp, crc); // external = 0 for (i = 0; i < coders->numFolders; ++i) { total_size += writeFolder(&coders->folders[i], fp, crc); } total_size += writeTag(PROPERTY_ID_CODERS_UNPACK_SIZE, fp, crc); for (i = 0; i < coders->numFolders; ++i) { total_size += writeNumber(coders->unPackSize[i], fp, crc); } total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writeDigestInfo(Qz7zDigest_T *digest, FILE *fp, uint32_t *crc) { int i; size_t size; size_t total_size = 0; total_size += writeByte(digest->allAreDefined, fp, crc); for (i = 0; i < digest->numStreams; ++i) { size = fwrite(&digest->crc[i], sizeof(digest->crc[i]), 1, fp); CHECK_FWRITE_RETURN(size, 1) total_size += size * sizeof(digest->crc[i]); *crc = crc32(*crc, (unsigned char *)&digest->crc[i], sizeof(digest->crc[i])); } return total_size; } size_t writeSubstreamsInfo(Qz7zSubstreamsInfo_T *substreams, FILE *fp, uint32_t *crc) { int i, j; int total_index = 0; size_t total_size = 0; if (!substreams) return 0; total_size += writeTag(PROPERTY_ID_SUBSTREAMSINFO, fp, crc); total_size += writeTag(PROPERTY_ID_NUM_UNPACK_STREAM, fp, crc); for (i = 0; i < substreams->numFolders; ++i) { total_size += writeNumber(substreams->numUnPackStreams[i], fp, crc); } total_size += writeTag(PROPERTY_ID_SIZE, fp, crc); for (i = 0; i < substreams->numFolders; ++i) { for (j = 0; j < substreams->numUnPackStreams[i] - 1; ++j) { total_size += writeNumber(substreams->unPackSize[total_index++], fp, crc); } } total_size += writeTag(PROPERTY_ID_CRC, fp, crc); total_size += writeDigestInfo(substreams->digests, fp, crc); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writeStreamsInfo(Qz7zStreamsInfo_T *streams, FILE *fp, uint32_t *crc) { size_t total_size = 0; if (!streams) return 0; total_size += writeTag(PROPERTY_ID_MAIN_STREAMSINFO, fp, crc); total_size += writePackInfo(streams->packInfo, fp, crc); total_size += writeCodersInfo(streams->codersInfo, fp, crc); total_size += writeSubstreamsInfo(streams->substreamsInfo, fp, crc); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } static unsigned char *calculateEmptyStreamProperty(int m, int n, uint64_t *size) { unsigned char *res; unsigned char sum = 0; *size = (!((m + n) % 8)) ? (m + n) / 8 : (m + n) / 8 + 1; res = malloc(*size); CHECK_ALLOC_RETURN_VALUE(res) memset(res, 0, *size); int i, j = 0, k; for (i = 0; i < m / 8; ++i) { res[j++] = 0xff; } for (i = 0, k = 7; i < m % 8; ++i, --k) { sum += 1 << k; } res[j++] = sum; return res; } static unsigned char *calculateEmptyFileProperty(Qz7zFilesInfo_T *files, int m, uint64_t *size) { int i, j; *size = (!((m) % 8)) ? (m) / 8 : ((m) / 8 + 1); unsigned char *res = malloc(*size); CHECK_ALLOC_RETURN_VALUE(res) memset(res, 0, *size); int total_index = 0; for (i = 0; i < *size; ++i) { for (j = 7; j >= 0; --j) { Qz7zFileItem_T *p = qzListGet(files->head[0], total_index++); if (!p) { QZ_ERROR("Cannot get the file from list\n"); free(res); return NULL; } if (p->isEmpty) { QZ_DEBUG("%s is empty stream: i=%d j=%d\n", p->fileName, i, j); res[i] += 1 << j; } if (total_index == m) break; } } return res; } static unsigned char *genNamesPart(QzListHead_T *head_dir, QzListHead_T *head_file, uint64_t *size) { int i; int j; // for buf index int k; uint64_t n_dir = head_dir->total; uint64_t n_file = head_file->total; Qz7zFileItem_T *p; unsigned char *buf; int buf_len = 0; for (i = 0; i < n_dir; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_dir, i); buf_len += 2 * (p->nameLength - p->baseNameLength); } for (i = 0; i < n_file; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_file, i); buf_len += 2 * (p->nameLength - p->baseNameLength); } buf = malloc(buf_len + 1); CHECK_ALLOC_RETURN_VALUE(buf) k = 0; buf[k++] = 0; for (i = 0; i < n_dir; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_dir, i); for (j = p->baseNameLength; j < p->nameLength; ++j) { buf[k++] = p->fileName[j]; buf[k++] = 0; } } for (i = 0; i < n_file; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_file, i); for (j = p->baseNameLength; j < p->nameLength; ++j) { buf[k++] = p->fileName[j]; buf[k++] = 0; } } *size = k; return buf; } static uint32_t *genAttributes(QzListHead_T *head_dir, QzListHead_T *head_file) { int i; int k; uint64_t n_dir = head_dir->total; uint64_t n_file = head_file->total; Qz7zFileItem_T *p; uint32_t *buf; buf = malloc(sizeof(((Qz7zFileItem_T *)0)->attribute) * (n_dir + n_file)); CHECK_ALLOC_RETURN_VALUE(buf) k = 0; for (i = 0; i < n_dir; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_dir, i); buf[k++] = p->attribute; } for (i = 0; i < n_file; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_file, i); buf[k++] = p->attribute; } return buf; } static int checkZerobyteFiles(Qz7zFilesInfo_T *files) { Qz7zFileItem_T *pfile; int i; int n = files->head[0]->total; for (i = 0; i < n; ++i) { pfile = qzListGet(files->head[0], i); if (!pfile) { QZ_ERROR("Cannot get file from list\n"); exit(ERROR); } if (pfile->isEmpty) return 1; } return 0; } size_t writeFilesInfo(Qz7zFilesInfo_T *files, FILE *fp, uint32_t *crc) { int n_emptystream = files->head[0]->total; int n_file = files->head[1]->total; uint64_t size = 0; size_t ret_size; unsigned char *p; uint64_t total_size = 0; unsigned char *buf; uint32_t *attributes; int has_zerobyte_file = 0; total_size += writeTag(PROPERTY_ID_FILESINFO, fp, crc); total_size += writeNumber(files->num, fp, crc); total_size += writeTag(PROPERTY_ID_EMPTY_STREAM, fp, crc); p = calculateEmptyStreamProperty(n_emptystream, n_file, &size); total_size += writeNumber(size, fp, crc); ret_size = fwrite(p, 1, size, fp); CHECK_FWRITE_RETURN(size, ret_size) total_size += ret_size; *crc = crc32(*crc, p, size); free(p); p = NULL; has_zerobyte_file = checkZerobyteFiles(files); if (n_emptystream && has_zerobyte_file) { total_size += writeTag(PROPERTY_ID_EMPTY_FILE, fp, crc); p = calculateEmptyFileProperty(files, n_emptystream, &size); if (!p) { QZ_ERROR("Cannot calculate emptyfile property\n"); exit(ERROR); } total_size += writeNumber(size, fp, crc); ret_size = fwrite(p, 1, size, fp); CHECK_FWRITE_RETURN(size, ret_size) total_size += ret_size; *crc = crc32(*crc, p, size); free(p); p = NULL; } total_size += writeTag(PROPERTY_ID_DUMMY, fp, crc); total_size += writeNumber(2, fp, crc); total_size += writeByte(PROPERTY_CONTENT_DUMMY, fp, crc); total_size += writeByte(PROPERTY_CONTENT_DUMMY, fp, crc); total_size += writeTag(PROPERTY_ID_NAME, fp, crc); buf = genNamesPart(files->head[0], files->head[1], &size); total_size += writeNumber(size, fp, crc); ret_size = fwrite(buf, 1, size, fp); CHECK_FWRITE_RETURN(ret_size, size) total_size += ret_size; *crc = crc32(*crc, buf, size); free(buf); int i; Qz7zFileItem_T *pfile; FILETIME_T win_time; total_size += writeTag(PROPERTY_ID_MTIME, fp, crc); total_size += writeNumber((n_emptystream + n_file) * 8 + 2, fp, crc); total_size += writeTag(1, fp, crc); total_size += writeTag(0, fp, crc); for (i = 0; i < n_emptystream; ++i) { pfile = (Qz7zFileItem_T *)qzListGet(files->head[0], i); win_time = unixtimeToFiletime(pfile->mtime, pfile->mtime_nano); total_size += writeTime(win_time.low, fp, crc); total_size += writeTime(win_time.high, fp, crc); } for (i = 0; i < n_file; ++i) { pfile = (Qz7zFileItem_T *)qzListGet(files->head[1], i); win_time = unixtimeToFiletime(pfile->mtime, pfile->mtime_nano); total_size += writeTime(win_time.low, fp, crc); total_size += writeTime(win_time.high, fp, crc); } total_size += writeTag(PROPERTY_ID_ATTRIBUTES, fp, crc); attributes = genAttributes(files->head[0], files->head[1]); size = 2 + 4 * (n_emptystream + n_file); total_size += writeNumber(size, fp, crc); total_size += writeByte(FLAG_ATTR_DEFINED_SET, fp, crc); total_size += writeByte(FLAG_ATTR_EXTERNAL_UNSET, fp, crc); for (i = 0; i < n_emptystream + n_file; ++i) { total_size += writeTime(attributes[i], fp, crc); } free(attributes); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } /** * return total size that has written */ size_t writeEndHeader(Qz7zEndHeader_T *header, FILE *fp, uint32_t *crc) { size_t total_size = 0; if (!crc) { QZ_ERROR("bad crc param\n"); return 0; } total_size += writeTag(PROPERTY_ID_HEADER, fp, crc); total_size += writeArchiveProperties(header->propertyInfo, fp, crc); total_size += writeStreamsInfo(header->streamsInfo, fp, crc); total_size += writeFilesInfo(header->filesInfo, fp, crc); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } Qz7zItemList_T *itemListCreate(int n, char **files) { int i; uint32_t dir_index = 0; // the index of next processing directory in the dir list Qz7zFileItem_T *fi = NULL; DIR *dirp = NULL; char *dirc = NULL; char *absolute_path; char dir_name[PATH_MAX + 1] = {0}; char path[PATH_MAX]; Qz7zItemList_T *res = calloc(1, sizeof(Qz7zItemList_T)); if (!res) { QZ_ERROR("malloc error\n"); return NULL; } res->items[0] = qzListCreate(QZ_DIRLIST_DEFAULT_NUM_PER_NODE); res->items[1] = qzListCreate(QZ_FILELIST_DEFAULT_NUM_PER_NODE); QzListHead_T *dirs_head = res->items[0]; QZ_DEBUG("dirs_head : %p\n", (void *)dirs_head); QzListHead_T *files_head = res->items[1]; QZ_DEBUG("files_head : %p\n", (void *)files_head); for (i = 0; i < n; ++i) { #ifdef QZ7Z_DEBUG QZ_DEBUG("process %dth parameter: %s\n", i + 1, files[optind]); #endif absolute_path = realpath(files[optind], path); if (NULL == absolute_path) { goto error; } strncpy(dir_name, absolute_path, PATH_MAX); dirc = dirname(dir_name); fi = fileItemCreate(absolute_path); if (!fi) { QZ_ERROR("Cannot create file\n"); goto error; } if (strcmp(dirc, "/")) { fi->baseNameLength = strlen(dirc) + 1; } else { fi->baseNameLength = strlen(dirc); } if (fi->isDir || fi->isEmpty) { qzListAdd(dirs_head, (void **)&fi); // add it to directory list while (dir_index < dirs_head->total) { Qz7zFileItem_T *processing = (Qz7zFileItem_T *)qzListGet(dirs_head, dir_index); if (processing == NULL) { QZ_DEBUG("qzListGet got NULL!\n"); goto error; } QZ_DEBUG("processing: %s\n", processing->fileName); if (processing->isDir) { struct dirent *dentry; dirp = opendir(processing->fileName); if (!dirp) { QZ_ERROR("errors ocurs: %s \n", strerror(errno)); goto error; } while ((dentry = readdir(dirp))) { char file_path[PATH_MAX + 1]; memset(file_path, 0, PATH_MAX + 1); if (!strcmp(dentry->d_name, ".")) continue; if (!strcmp(dentry->d_name, "..")) continue; snprintf(file_path, sizeof file_path, "%s/%s", processing->fileName, dentry->d_name); QZ_DEBUG(" file_path: %s\n", file_path); Qz7zFileItem_T *anotherfile = fileItemCreate(file_path); if (!anotherfile) { QZ_ERROR("Cannot create file\n"); closedir(dirp); goto error; } if (strcmp(dirc, "/")) { anotherfile->baseNameLength = strlen(dirc) + 1; } else { anotherfile->baseNameLength = strlen(dirc); } if (anotherfile->isDir || anotherfile->isEmpty) { qzListAdd(dirs_head, (void **)&anotherfile); } else { qzListAdd(files_head, (void **)&anotherfile); } } closedir(dirp); } dir_index++; } } else { qzListAdd(files_head, (void **)&fi); } optind++; }// end for /* now the res->items has been resolved successfully */ res->table = createCatagoryList(); scanFilesIntoCatagory(res); return res; error: if (res) { itemListDestroy(res); } return NULL; } /** * return 1 if 7z archive is good, others if not */ int check7zArchive(const char *archive) { int sig_wrong; size_t n; unsigned char buf[8]; FILE *fp = fopen(archive, "r"); if (!fp) { perror(archive); return QZ7Z_ERR_OPEN; } n = fread(buf, 1, sizeof(buf), fp); if (n < sizeof(buf)) { fclose(fp); return -1; } if ((sig_wrong = memcmp(buf, g_header_signature, sizeof(g_header_signature)))) { QZ_ERROR("The archive signature header is broken\n"); fclose(fp); return QZ7Z_ERR_SIG_HEADER_BROKEN; } if (buf[6] != 0 || buf[7] != 4) { QZ_DEBUG("Warning: The 7z archive version is not 0.4\n"); QZ_DEBUG("Warning: Maybe has some issues for other version\n"); } fclose(fp); return 1; } /* * 1 if filename is dir, 0 if not */ int checkDirectory(const char *filename) { struct stat buf; stat(filename, &buf); if (S_ISDIR(buf.st_mode)) { return 1; } else { return 0; } } QATzip-1.3.1/utils/qzip_main.c000066400000000000000000000313141500263377000161640ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzip.h" int main(int argc, char **argv) { int ret = QZ_OK; int arg_count; /* number of files or directories to process */ g_program_name = qzipBaseName(argv[0]); char *out_name = NULL; FILE *stream_out = NULL; int option_f = 0; Qz7zItemList_T *the_list; int is_good_7z = 0; int is_dir = 0; int recursive_mode = 0; errno = 0; int is_format_set = 0; char resolved_path[PATH_MAX]; while (true) { int optc; int long_idx = -1; char *stop = NULL; optc = getopt_long(argc, argv, g_short_opts, g_long_opts, &long_idx); if (optc < 0) { break; } switch (optc) { case 'd': g_decompress = 1; break; case 'h': help(); exit(OK); break; case 'k': g_keep = 1; break; case 'V': version(); exit(OK); break; case 'R': recursive_mode = 1; break; case 's': g_params_th.is_sensitive_mode = true; break; case 'A': if (strcmp(optarg, "deflate") == 0) { g_params_th.comp_algorithm = QZ_DEFLATE; } else if (strcmp(optarg, "lz4") == 0) { g_params_th.comp_algorithm = QZ_LZ4; } else if (strcmp(optarg, "lz4s") == 0) { g_params_th.comp_algorithm = QZ_LZ4s; } else if (strcmp(optarg, "zstd") == 0) { g_params_th.comp_algorithm = QZ_ZSTD; } else { printf("Error service arg: %s\n", optarg); return -1; } break; case 'H': if (strcmp(optarg, "static") == 0) { g_params_th.huffman_hdr = QZ_STATIC_HDR; } else if (strcmp(optarg, "dynamic") == 0) { g_params_th.huffman_hdr = QZ_DYNAMIC_HDR; } else { printf("Error huffman arg: %s\n", optarg); return -1; } break; case 'O': if (strcmp(optarg, "gzip") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_GZIP; } else if (strcmp(optarg, "gzipext") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_GZIP_EXT; } else if (strcmp(optarg, "7z") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_RAW; } else if (strcmp(optarg, "deflate_4B") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_4B; } else if (strcmp(optarg, "lz4") == 0) { g_params_th.data_fmt = QZIP_LZ4_FH; } else if (strcmp(optarg, "lz4s") == 0) { g_params_th.data_fmt = QZIP_LZ4S_BK; } else { printf("Error gzip header format arg: %s\n", optarg); return -1; } is_format_set = 1; break; case 'o': out_name = optarg; break; case 'L': g_params_th.comp_lvl = QZIP_GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || ERANGE == errno || g_params_th.comp_lvl > QZ_DEFLATE_COMP_LVL_MAXIMUM || g_params_th.comp_lvl <= 0) { printf("Error compLevel arg: %s\n", optarg); return -1; } break; case 'C': g_params_th.hw_buff_sz = QZIP_GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || ERANGE == errno || g_params_th.hw_buff_sz > USDM_ALLOC_MAX_SZ / 2) { printf("Error chunk size arg: %s\n", optarg); return -1; } break; case 'r': g_params_th.req_cnt_thrshold = QZIP_GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno) { printf("Error request count threshold: %s\n", optarg); return -1; } break; case 'f': option_f = 1; break; case 'P': if (strcmp(optarg, "busy") == 0) { g_params_th.polling_mode = QZ_BUSY_POLLING; } else { printf("Error set polling mode: %s\n", optarg); return -1; } break; case 'g': if (strcmp(optarg, "none") == 0) { qzSetLogLevel(LOG_NONE); } else if (strcmp(optarg, "error") == 0) { qzSetLogLevel(LOG_ERROR); } else if (strcmp(optarg, "warn") == 0) { qzSetLogLevel(LOG_WARNING); } else if (strcmp(optarg, "info") == 0) { qzSetLogLevel(LOG_INFO); } else if (strcmp(optarg, "debug") == 0) { qzSetLogLevel(LOG_DEBUG1); } else { printf("Error log level: %s\n", optarg); return -1; } break; case 'b': block_buff_len = QZIP_GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || ERANGE == errno || block_buff_len > 512 * 1024 * 1024) { printf("Error block size arg: %s\n", optarg); return -1; } break; default: tryHelp(); } } arg_count = argc - optind; if (0 == arg_count && isatty(fileno((FILE *)stdin))) { help(); exit(OK); } if (g_decompress) { if (g_params_th.data_fmt == QZIP_LZ4S_BK) { QZ_ERROR("Don't support lz4s decompression.\n"); exit(ERROR); } g_params_th.direction = QZ_DIR_DECOMPRESS; } else { g_params_th.direction = QZ_DIR_COMPRESS; } if (0 == arg_count) { if (isatty(fileno((FILE *)stdout)) && 0 == option_f && 0 == g_decompress) { printf("qzip: compressed data not written to a terminal. " "Use -f to force compression.\n"); printf("For help, type: qzip -h\n"); } else { if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } stream_out = stdout; stdout = freopen(NULL, "w", stdout); processStream(&g_sess, stdin, stream_out, g_decompress == 0); } } else if (g_params_th.data_fmt == QZIP_DEFLATE_RAW && !g_decompress) { //compress into 7z QZ_DEBUG("going to compress files into 7z archive ...\n"); if (!out_name) { QZ_ERROR("Should use '-o' to specify an output name\n"); help(); exit(ERROR); } if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } for (int i = 0, j = optind; i < arg_count; ++i, ++j) { if (access(argv[j], F_OK)) { QZ_ERROR("%s: No such file or directory\n", argv[j]); exit(ERROR); } } the_list = itemListCreate(arg_count, argv); if (!the_list) { exit(ERROR); } ret = qz7zCompress(&g_sess, the_list, out_name); itemListDestroy(the_list); } else { // decompress from 7z; compress into gz; decompress from gz while (optind < argc) { /* To avoid CWE-22: Improper Limitation of a Pathname to a Restricted Directory * ('Path Traversal') attacks. * http://cwe.mitre.org/data/definitions/22.html */ if (!realpath(argv[optind], resolved_path)) { QZ_ERROR("%s: No such file or directory\n", argv[optind]); exit(ERROR); } QzSuffix_T suffix = getSuffix(argv[optind]); is_dir = checkDirectory(argv[optind]); if (g_decompress && !is_dir) { QzSuffixCheckStatus_T check_res = checkSuffix(suffix, is_format_set); if (E_CHECK_SUFFIX_UNSUPPORT == check_res) { QZ_ERROR("Error: %s: Wrong suffix. Supported suffix: 7z/gz/lz4.\n", argv[optind]); exit(ERROR); } if (E_CHECK_SUFFIX_FORMAT_UNMATCH == check_res) { QZ_ERROR("Error: %s: Suffix is not matched with format\n", argv[optind]); exit(ERROR); } } if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } if (g_decompress) { if (!recursive_mode) { if (suffix == E_SUFFIX_7Z) { is_good_7z = check7zArchive(argv[optind]); if (is_good_7z < 0) { exit(ERROR); } if (arg_count > 1) { fprintf(stderr, "only support decompressing ONE 7z " "archive for ONE command!\n"); exit(ERROR); } QZ_DEBUG(" this is a 7z archive, " "going to decompress ... \n"); g_params_th.data_fmt = QZIP_DEFLATE_RAW; if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } ret = qz7zDecompress(&g_sess, argv[optind++]); } else if (suffix == E_SUFFIX_GZ) { processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } else if (suffix == E_SUFFIX_LZ4) { if (g_params_th.data_fmt != QZIP_LZ4_FH) { QZ_ERROR("Error: Suffix(.lz4) doesn't match the data format," "please confirm the data format\n"); exit(ERROR); } processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } else { QZ_ERROR("Error: %s: Wrong suffix. Supported suffix: " "7z/gz/lz4.\n", argv[optind]); exit(ERROR); } } else { processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } } else { // compress processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } } } if (qatzipClose(&g_sess)) { exit(ERROR); } return ret; } QATzip-1.3.1/utils/qzstd.c000066400000000000000000000435111500263377000153440ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzstd.h" QzSession_T qzstd_g_sess; QzSessionParamsLZ4S_T g_sess_params = {{0}}; QzSessionParamsLZ4S_T sess_params_zstd_default = { .common_params.direction = QZ_DIR_COMPRESS, .common_params.comp_lvl = QZ_COMP_LEVEL_DEFAULT, .common_params.comp_algorithm = QZ_LZ4s, .common_params.max_forks = QZ_MAX_FORK_DEFAULT, .common_params.sw_backup = QZ_SW_BACKUP_DEFAULT, .common_params.hw_buff_sz = QZ_HW_BUFF_SZ, .common_params.strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT, .common_params.input_sz_thrshold = QZ_COMP_THRESHOLD_DEFAULT, .common_params.req_cnt_thrshold = QZ_REQ_THRESHOLD_DEFAULT, .common_params.wait_cnt_thrshold = QZ_WAIT_CNT_THRESHOLD_DEFAULT, .common_params.polling_mode = QZ_PERIODICAL_POLLING, .lz4s_mini_match = 3, .qzCallback = zstdCallBack, .qzCallback_external = NULL }; static unsigned int LZ4MINMATCH = 2; void qzstd_help() { static char const *const help_msg[] = { "Compress or uncompress a file with zstandard format.", "", " -d, decompress", " -h, show help information", " -L, set compression level of QAT", " -g, set qatzip loglevel(none|error|warn|info|debug)", " -o, set output file name", " -C, set zstd block size && QAT hw buffer size", " -r, set max in-flight request number", " -P, set polling mode, only supports busy polling settings", " -m, set the mini match size for the lz4s search algorithm, \ only support mini_match 3 and 4", "", "Only support one input file.", 0 }; char const *const *p = help_msg; while (*p) { printf("%s\n", *p++); } } static double get_time_diff(struct timeval time_e, struct timeval time_s) { unsigned long us_begin = time_s.tv_sec * 1000000 + time_s.tv_usec; unsigned long us_end = time_e.tv_sec * 1000000 + time_e.tv_usec; return us_end - us_begin; } unsigned qzstd_isLittleEndian(void) { const union { U32 u; BYTE c[4]; } one = {1}; /* don't use static : performance detrimental */ return one.c[0]; } static U16 qzstd_read16(const void *memPtr) { U16 val; memcpy(&val, memPtr, sizeof(val)); return val; } U16 qzstd_readLE16(const void *memPtr) { if (qzstd_isLittleEndian()) { return qzstd_read16(memPtr); } else { const BYTE *p = (const BYTE *)memPtr; return (U16)((U16)p[0] + (p[1] << 8)); } } void decLz4Block(unsigned char *lz4s, int lz4sSize, ZSTD_Sequence *zstdSeqs, unsigned int *seq_offset) { unsigned char *ip = lz4s; unsigned char *endip = lz4s + lz4sSize; while (ip < endip && lz4sSize > 0) { size_t length = 0; size_t offset = 0; unsigned int literalLen = 0, matchlen = 0; /* get literal length */ unsigned const token = *ip++; if ((length = (token >> ML_BITS)) == RUN_MASK) { unsigned s; do { s = *ip++; length += s; } while (s == 255); } literalLen = (unsigned short)length; ip += length; if (ip == endip) { // Meet the end of the LZ4 sequence /* update ZSTD_Sequence */ zstdSeqs[*seq_offset].litLength += literalLen; continue; } /* get matchPos */ offset = qzstd_readLE16(ip); ip += 2; /* get match length */ length = token & ML_MASK; if (length == ML_MASK) { unsigned s; do { s = *ip++; length += s; } while (s == 255); } if (length != 0) { length += LZ4MINMATCH; matchlen = (unsigned short)length; /* update ZSTD_Sequence */ zstdSeqs[*seq_offset].offset = offset; zstdSeqs[*seq_offset].litLength += literalLen; zstdSeqs[*seq_offset].matchLength = matchlen; ++(*seq_offset); assert(*seq_offset <= ZSTD_SEQUENCES_SIZE); } else { if (literalLen > 0) { /* When match length is 0, the literalLen needs to be temporarily stored and processed together with the next data block. If also ip == endip, need to convert sequences to seqStore.*/ zstdSeqs[*seq_offset].litLength += literalLen; } } } assert(ip == endip); } inline int getLz4FrameHeaderSz() { return QZ_LZ4_HEADER_SIZE; } inline int getLz4BlkHeaderSz() { return QZ_LZ4_BLK_HEADER_SIZE; } inline int getLZ4FooterSz() { return QZ_LZ4_FOOTER_SIZE; } int getContentSize(unsigned char *const ptr) { QzLZ4H_T *hdr = NULL; hdr = (QzLZ4H_T *)ptr; assert(hdr->magic == QZ_LZ4_MAGIC); return hdr->cnt_size; } unsigned int getBlockSize(unsigned char *const ptr) { unsigned int blk_sz = *(unsigned int *)ptr; return blk_sz; } int zstdCallBack(void *external, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, int *ExtStatus) { int ret = QZ_OK; //copied data is used to decode //original data will be overwrote by ZSTD_compressSequences unsigned char *dest_data = (unsigned char *)malloc(*dest_len); assert(dest_data != NULL); memcpy(dest_data, dest, *dest_len); unsigned char *cur = dest_data; unsigned char *end = dest_data + *dest_len; ZSTD_Sequence *zstd_seqs = (ZSTD_Sequence *)calloc(ZSTD_SEQUENCES_SIZE, sizeof(ZSTD_Sequence)); assert(zstd_seqs != NULL); ZSTD_CCtx *zc = (ZSTD_CCtx *)external; unsigned int produced = 0; unsigned int consumed = 0; unsigned int cnt_sz = 0, blk_sz = 0; //content size and block size unsigned int dec_offset = 0; while (cur < end && *dest_len > 0) { //decode block header and get block size blk_sz = getBlockSize(cur); cur += getLz4BlkHeaderSz(); //decode lz4s sequences into zstd sequences decLz4Block(cur, blk_sz, zstd_seqs, &dec_offset); cur += blk_sz; cnt_sz = 0; for (unsigned int i = 0; i < dec_offset + 1 ; i++) { cnt_sz += (zstd_seqs[i].litLength + zstd_seqs[i].matchLength) ; } assert(cnt_sz <= MAX_BLOCK_SIZE); // compress sequence to zstd frame int compressed_sz = ZSTD_compressSequences(zc, dest + produced, ZSTD_compressBound(cnt_sz), zstd_seqs, dec_offset + 1, src + consumed, cnt_sz); if (compressed_sz < 0) { ret = QZ_POST_PROCESS_ERROR; *ExtStatus = compressed_sz; QZ_ERROR("%s : ZSTD API ZSTD_compressSequences failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, *ExtStatus, DECODE_ZSTD_ERROR_CODE(*ExtStatus)); goto done; } //reuse zstd_seqs memset(zstd_seqs, 0, ZSTD_SEQUENCES_SIZE * sizeof(ZSTD_Sequence)); dec_offset = 0; produced += compressed_sz; consumed += cnt_sz; } *dest_len = produced; done: free(dest_data); free(zstd_seqs); return ret; } int qzZstdGetDefaults(QzSessionParamsLZ4S_T *defaults) { if (defaults == NULL) { QZ_ERROR("%s : QzSessionParams ptr is empty\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } QZ_MEMCPY(defaults, &sess_params_zstd_default, sizeof(QzSessionParamsLZ4S_T), sizeof(QzSessionParamsLZ4S_T)); return QZSTD_OK; } int compressFile(int in_file, int out_file) { long input_file_size = 0; long output_file_size = 0; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; unsigned int max_dst_buffer_size = 0; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; unsigned int block_size = ZSRC_BUFF_LEN; long file_remaining = 0; unsigned int bytes_read = 0; int rc = QZSTD_OK; int is_compress = 1; uint64_t callback_error_code = 0; //initial zstd context ZSTD_CCtx *zc = ZSTD_createCCtx(); if (zc == NULL) { QZ_ERROR("%s : ZSTD_createCCtx failed\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } ZSTD_CCtx_setParameter(zc, ZSTD_c_blockDelimiters, ZSTD_sf_explicitBlockDelimiters); g_sess_params.qzCallback_external = (void *)zc; /* Different mini_match would use different LZ4MINMATCH to decode * lz4s sequence. note that when it is mini_match is 4, the LZ4MINMATCH * should be 3. if mini match is 3, then LZ4MINMATCH should be 2*/ LZ4MINMATCH = g_sess_params.lz4s_mini_match == 4 ? 3 : 2; /* Align zstd minmatch to the QAT minmatch */ ZSTD_CCtx_setParameter( zc, ZSTD_c_minMatch, g_sess_params.lz4s_mini_match >= 4 ? 4 : 3 ); //setup session int ret = qzInit(&qzstd_g_sess, g_sess_params.common_params.sw_backup); if (ret != QZ_OK && ret != QZ_DUPLICATE) { QZ_ERROR("%s : qzInit failed with error code %d\n", QZ_ERROR_TYPE, ret); return QZSTD_ERROR; } ret = qzSetupSessionLZ4S(&qzstd_g_sess, &g_sess_params); if (ret != QZ_OK) { QZ_ERROR("%s : qzSetupSession failed with error code %d\n", QZ_ERROR_TYPE, ret); return QZSTD_ERROR; } //get input file size input_file_size = lseek(in_file, 0, SEEK_END); lseek(in_file, 0, SEEK_SET); src_buffer_size = (input_file_size > block_size) ? block_size : input_file_size; int max_zstd_sz = ZSTD_compressBound(src_buffer_size); int max_lz4_sz = LZ4_compressBound(src_buffer_size); max_dst_buffer_size = (max_zstd_sz > max_lz4_sz) ? max_zstd_sz * 2 : max_lz4_sz * 2; src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(max_dst_buffer_size); assert(dst_buffer != NULL); file_remaining = input_file_size; struct timeval time_s; struct timeval time_e; double time = 0.0f; do { bytes_read = read(in_file, src_buffer, src_buffer_size); QZ_INFO("Reading input file (%u Bytes)\n", bytes_read); puts("compressing..."); dst_buffer_size = max_dst_buffer_size; gettimeofday(&time_s, NULL); if (bytes_read < g_sess_params.common_params.input_sz_thrshold) { //goto sw compress dst_buffer_size = ZSTD_compressCCtx(zc, dst_buffer, dst_buffer_size, src_buffer, bytes_read, 1); if ((int)dst_buffer_size <= 0) { QZ_ERROR("%s : ZSTD API ZSTD_compressCCtx failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, dst_buffer_size, DECODE_ZSTD_ERROR_CODE(dst_buffer_size)); rc = QZSTD_ERROR; goto done; } } else { //compress by qat int ret = qzCompressExt(&qzstd_g_sess, src_buffer, (unsigned int *)(&bytes_read), dst_buffer, &dst_buffer_size, 1, &callback_error_code); if (QZ_BUF_ERROR == ret && 0 != bytes_read) { if (-1 == lseek(in_file, bytes_read - src_buffer_size, SEEK_CUR)) { QZ_ERROR("%s : failed to re-seek input file\n", QZSTD_ERROR_TYPE); rc = QZSTD_ERROR; goto done; } } else if (QZ_POST_PROCESS_ERROR == ret) { QZ_ERROR("%s : ZSTD API ZSTD_compressSequences failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, ret, DECODE_ZSTD_ERROR_CODE((size_t)callback_error_code)); rc = QZSTD_ERROR; goto done; } else if (QZ_OK != ret) { QZ_ERROR("%s : qzCompress failed with error code %d\n", QZ_ERROR_TYPE, ret); rc = QZSTD_ERROR; goto done; } } gettimeofday(&time_e, NULL); time += get_time_diff(time_e, time_s); size_t write_size = write(out_file, dst_buffer, dst_buffer_size); if (write_size != dst_buffer_size) { QZ_ERROR("%s : failed to write output data into file\n", QZSTD_ERROR_TYPE); rc = QZSTD_ERROR; goto done; } output_file_size += write_size; file_remaining -= bytes_read; src_buffer_size = (src_buffer_size < file_remaining) ? src_buffer_size : file_remaining; } while (file_remaining > 0); QzstdDisplayStats(time, input_file_size, output_file_size, is_compress); done: //release resource if (zc != NULL) { ZSTD_freeCCtx(zc); } free(src_buffer); free(dst_buffer); qzTeardownSession(&qzstd_g_sess); qzClose(&qzstd_g_sess); return rc; } int decompressFile(int in_file, int out_file) { long input_file_size = 0; long output_file_size = 0; size_t src_buffer_size = ZSTD_DStreamInSize(); size_t dst_buffer_size = ZSTD_DStreamOutSize(); unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; int rc = QZSTD_OK; int is_compress = 0; struct timeval time_s; struct timeval time_e; double time = 0.0f; //get input file size input_file_size = lseek(in_file, 0, SEEK_END); lseek(in_file, 0, SEEK_SET); src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(dst_buffer_size); assert(dst_buffer != NULL); ZSTD_DCtx *zstd_dctx = ZSTD_createDCtx(); assert(zstd_dctx != NULL); size_t bytes_read = 0; size_t bytes_write = 0; long file_remaining = 0; file_remaining = input_file_size; int ret = 0; do { bytes_read = read(in_file, src_buffer, src_buffer_size); QZ_INFO("Reading input file (%lu Bytes)\n", bytes_read); puts("Decompressing..."); ZSTD_inBuffer input = { src_buffer, bytes_read, 0 }; while (input.pos < input.size) { ZSTD_outBuffer output = { dst_buffer, dst_buffer_size, 0 }; gettimeofday(&time_s, NULL); ret = ZSTD_decompressStream(zstd_dctx, &output, &input); if (ret < 0) { QZ_ERROR("%s : ZSTD API ZSTD_decompressStream failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, ret, DECODE_ZSTD_ERROR_CODE(ret)); rc = QZSTD_ERROR; goto done; } gettimeofday(&time_e, NULL); time += get_time_diff(time_e, time_s); bytes_write = write(out_file, dst_buffer, output.pos); output_file_size += bytes_write; } file_remaining -= bytes_read; src_buffer_size = (src_buffer_size < file_remaining) ? src_buffer_size : file_remaining; } while (file_remaining > 0); if (ret != 0) { QZ_ERROR("%s : ZSTD API ZSTD_decompressStream failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, ret, DECODE_ZSTD_ERROR_CODE(ret)); rc = QZSTD_ERROR; goto done; } QzstdDisplayStats(time, input_file_size, output_file_size, is_compress); done: ZSTD_freeDCtx(zstd_dctx); free(src_buffer); free(dst_buffer); return rc; } void QzstdDisplayStats(double time, off_t insize, off_t outsize, int is_compress) { if (insize && outsize) { assert(0 != time); double size = (is_compress) ? insize : outsize; double throughput = (size * CHAR_BIT) / time; /* in MB (megabytes) */ double compressionRatio = ((double)insize) / ((double)outsize); double spaceSavings = 1 - ((double)outsize) / ((double)insize); QZ_PRINT("Time taken: %9.3lf ms\n", time / 1000); QZ_PRINT("Throughput: %9.3lf Mbit/s\n", throughput); if (is_compress) { QZ_PRINT("Space Savings: %9.3lf %%\n", spaceSavings * 100.0); QZ_PRINT("Compression ratio: %.3lf : 1\n", compressionRatio); } } } QATzip-1.3.1/utils/qzstd.h000066400000000000000000000107241500263377000153510ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _UTILS_QZSTD_H #define _UTILS_QZSTD_H #define ZSTD_STATIC_LINKING_ONLY #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #else #include #endif #include /* For qzstd app, there are three types of return errors. * 1. The errors are from top layer software stack * e.g read/write file and app input parameter error. * 2. The errors are from qatzip lib. * e.g QZ_DUPLICATE or QZ_NOSW_NO_HW, error code defined * in qatzip.h * 3. The errors come from zstd lib. * e.g ZSTD_ErrorCode list. error code defined in zstd_error.h * * Note: * Because different type of error may have the same error code * value, To avoid app return value confusion in shell. Use * QZ_ERROR function to print error type and error code. */ // app return status #define QZSTD_OK 0 #define QZSTD_ERROR 1 // Error type for log capture. #define QZSTD_ERROR_TYPE "[QZSTD_ERROR]" #define QZ_ERROR_TYPE "[QZ_LIB_ERROR]" #define ZSTD_ERROR_TYPE "[ZSTD_LIB_ERROR]" #define KB (1024) #define MB (KB * KB) #define ZSTD_SEQUENCES_SIZE (1024 * 32) #define ML_BITS 4 #define ML_MASK ((1U << ML_BITS) - 1) #define RUN_BITS (8 - ML_BITS) #define RUN_MASK ((1U << RUN_BITS) - 1) typedef uint8_t BYTE; typedef uint16_t U16; typedef int16_t S16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; typedef int64_t S64; #define QATZIP_MAX_HW_SZ (512 * KB) #define ZSRC_BUFF_LEN (512 * MB) #define MAX_BLOCK_SIZE (128 * KB) #define DECODE_ZSTD_ERROR_CODE(error_code) \ ZSTD_getErrorString(ZSTD_getErrorCode((size_t)error_code)) void QzstdDisplayStats(double time, off_t insize, off_t outsize, int is_compress); void qzstd_help(); void decLz4Block(unsigned char *lz4s, int lz4sSize, ZSTD_Sequence *zstdSeqs, unsigned int *seq_offset); int qzZstdGetDefaults(QzSessionParamsLZ4S_T *defaults); int compressFile(int in_file, int out_file); int decompressFile(int in_file, int out_file); int zstdCallBack(void *external, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, int *ExtStatus); int getLz4FrameHeaderSz(); int getLz4BlkHeaderSz(); int getLZ4FooterSz(); int getContentSize(unsigned char *const ptr); unsigned int getBlockSize(unsigned char *const ptr); #endif QATzip-1.3.1/utils/qzstd_main.c000066400000000000000000000171211500263377000163460ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /* sample zstd-qat application */ #include #include #include #include #include #include #include "qzstd.h" extern QzSessionParamsLZ4S_T g_sess_params; int main(int argc, char **argv) { int decompress = 0; struct stat in_file_state; char out_path [PATH_MAX] = {0}; char in_path[PATH_MAX] = {0}; char *out_filename = NULL; char *in_filename = NULL; int in_file = -1; int out_file = -1; char *tmp = NULL; char *suffix = NULL; if (qzZstdGetDefaults(&g_sess_params) != QZ_OK) { return QZSTD_ERROR; } const char *optPatten = "dhC:L:o:r:P:m:g:"; char *stop = NULL; int ch; while ((ch = getopt(argc, argv, optPatten)) >= 0) { switch (ch) { case 'd': decompress = 1; break; case 'C': g_sess_params.common_params.hw_buff_sz = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); // make sure chunk size smaller than 128kB to fit zstd block size limitation. if (g_sess_params.common_params.hw_buff_sz > 128 * KB) { QZ_ERROR("%s : block size can't bigger than 128 KB\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } break; case 'h': qzstd_help(); return QZSTD_OK; case 'L': g_sess_params.common_params.comp_lvl = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); break; case 'o': out_filename = optarg; break; case 'r': g_sess_params.common_params.req_cnt_thrshold = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); break; case 'P': if (strcmp(optarg, "busy") == 0) { g_sess_params.common_params.polling_mode = QZ_BUSY_POLLING; } else { QZ_ERROR("%s : set wrong polling mode: %s\n", QZSTD_ERROR_TYPE, optarg); return QZSTD_ERROR; } break; case 'm': g_sess_params.lz4s_mini_match = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (g_sess_params.lz4s_mini_match != 3 && g_sess_params.lz4s_mini_match != 4) { QZ_ERROR("%s : mini_match can only set 3 or 4!\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } break; case 'g': if (strcmp(optarg, "none") == 0) { qzSetLogLevel(LOG_NONE); } else if (strcmp(optarg, "error") == 0) { qzSetLogLevel(LOG_ERROR); } else if (strcmp(optarg, "warn") == 0) { qzSetLogLevel(LOG_WARNING); } else if (strcmp(optarg, "info") == 0) { qzSetLogLevel(LOG_INFO); } else if (strcmp(optarg, "debug") == 0) { qzSetLogLevel(LOG_DEBUG1); } else { printf("Error log level: %s\n", optarg); return -1; } break; default: qzstd_help(); return QZSTD_OK; } } int arg_count = argc - optind; if (arg_count == 0 || arg_count > 1) { QZ_ERROR("%s : only support one file as input\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } /* argv[optind] is the input file name, need to check the input filename */ in_filename = argv[optind]; in_filename = realpath(in_filename, in_path); if (!in_filename) { QZ_ERROR("Please check input file name %s\n", in_filename); return QZSTD_ERROR; } /* * For compression, if the output file name is not be specified * we need to suffix the input filename with .zst as the output filename */ if (!decompress && !out_filename) { tmp = strrchr(in_filename, '/'); assert(tmp); strncpy(out_path, tmp + 1, PATH_MAX - 1); strcat(out_path, ".zst"); out_filename = &out_path[0]; } /* check the input filename suffix for decompression, * if output file name is not specified, we need to unsuffix the * input filename as the output filename */ if (decompress) { suffix = strrchr(in_filename, '.'); if (suffix == NULL) { QZ_ERROR("%s : unsupported file format\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } if (strcmp(suffix, ".zst")) { QZ_ERROR("%s : unsupported file format\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } if (!out_filename) { tmp = strrchr(in_filename, '/'); assert(tmp); strncpy(out_path, tmp + 1, PATH_MAX - 1); suffix = strrchr(out_path, '.'); assert(suffix); suffix[0] = '\0'; out_filename = &out_path[0]; } } in_file = open(in_filename, O_RDONLY); if (in_file < 0) { perror("Cannot open input file"); return QZSTD_ERROR; } if (fstat(in_file, &in_file_state)) { perror("Cannot get file stat"); close(in_file); return QZSTD_ERROR; } out_file = open(out_filename, O_CREAT | O_WRONLY, in_file_state.st_mode); if (out_file == -1) { perror("Cannot open output file"); close(in_file); return QZSTD_ERROR; } if (!decompress) { int rc = compressFile(in_file, out_file); if (rc != QZSTD_OK) { close(in_file); close(out_file); return QZSTD_ERROR; } } else { int rc = decompressFile(in_file, out_file); if (rc != QZSTD_OK) { close(in_file); close(out_file); return QZSTD_ERROR; } } close(in_file); close(out_file); return QZSTD_OK; }