diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/compressor/zlib | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/compressor/zlib')
-rw-r--r-- | src/compressor/zlib/CMakeLists.txt | 47 | ||||
-rw-r--r-- | src/compressor/zlib/CompressionPluginZlib.cc | 38 | ||||
-rw-r--r-- | src/compressor/zlib/CompressionPluginZlib.h | 54 | ||||
-rw-r--r-- | src/compressor/zlib/ZlibCompressor.cc | 246 | ||||
-rw-r--r-- | src/compressor/zlib/ZlibCompressor.h | 46 |
5 files changed, 431 insertions, 0 deletions
diff --git a/src/compressor/zlib/CMakeLists.txt b/src/compressor/zlib/CMakeLists.txt new file mode 100644 index 00000000..51aba083 --- /dev/null +++ b/src/compressor/zlib/CMakeLists.txt @@ -0,0 +1,47 @@ +# zlib + +if(HAVE_INTEL_SSE4_1 AND HAVE_BETTER_YASM_ELF64 AND (NOT APPLE)) + set(zlib_sources + CompressionPluginZlib.cc + ZlibCompressor.cc + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc32_gzip.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc32_gzip_base.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/detect_repeated_char.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/encode_df.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/encode_df_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/flatten_ll.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/huff_codes.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/hufftables_c.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_base.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_body_01.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_body_02.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_body_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_finish.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_base.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_body_01.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_body_02.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_body_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_finish.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_multibinary.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_update_histogram_01.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_update_histogram_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/proc_heap.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/rfc1951_lookup.asm + ) +else(HAVE_INTEL_SSE4_1 AND HAVE_BETTER_YASM_ELF64 AND (NOT APPLE)) + set(zlib_sources + CompressionPluginZlib.cc + ZlibCompressor.cc + ) +endif(HAVE_INTEL_SSE4_1 AND HAVE_BETTER_YASM_ELF64 AND (NOT APPLE)) + +add_library(ceph_zlib SHARED ${zlib_sources}) +target_link_libraries(ceph_zlib ZLIB::ZLIB) +target_include_directories(ceph_zlib SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src/isa-l/include") +set_target_properties(ceph_zlib PROPERTIES + VERSION 2.0.0 + SOVERSION 2 + INSTALL_RPATH "") +install(TARGETS ceph_zlib DESTINATION ${compressor_plugin_dir}) diff --git a/src/compressor/zlib/CompressionPluginZlib.cc b/src/compressor/zlib/CompressionPluginZlib.cc new file mode 100644 index 00000000..2215b9a4 --- /dev/null +++ b/src/compressor/zlib/CompressionPluginZlib.cc @@ -0,0 +1,38 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2015 Mirantis, Inc. + * + * Author: Alyona Kiseleva <akiselyova@mirantis.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + */ + + +// ----------------------------------------------------------------------------- +#include "acconfig.h" +#include "ceph_ver.h" +#include "common/ceph_context.h" +#include "CompressionPluginZlib.h" + +// ----------------------------------------------------------------------------- + +const char *__ceph_plugin_version() +{ + return CEPH_GIT_NICE_VER; +} + +// ----------------------------------------------------------------------------- + +int __ceph_plugin_init(CephContext *cct, + const std::string& type, + const std::string& name) +{ + PluginRegistry *instance = cct->get_plugin_registry(); + + return instance->add(type, name, new CompressionPluginZlib(cct)); +} diff --git a/src/compressor/zlib/CompressionPluginZlib.h b/src/compressor/zlib/CompressionPluginZlib.h new file mode 100644 index 00000000..38320c0c --- /dev/null +++ b/src/compressor/zlib/CompressionPluginZlib.h @@ -0,0 +1,54 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2015 Mirantis, Inc. + * + * Author: Alyona Kiseleva <akiselyova@mirantis.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + */ + +#ifndef CEPH_COMPRESSION_PLUGIN_ZLIB_H +#define CEPH_COMPRESSION_PLUGIN_ZLIB_H + +// ----------------------------------------------------------------------------- +#include "arch/probe.h" +#include "arch/intel.h" +#include "arch/arm.h" +#include "compressor/CompressionPlugin.h" +#include "ZlibCompressor.h" + +// ----------------------------------------------------------------------------- + +class CompressionPluginZlib : public CompressionPlugin { +public: + bool has_isal = false; + + explicit CompressionPluginZlib(CephContext *cct) : CompressionPlugin(cct) + {} + + int factory(CompressorRef *cs, + std::ostream *ss) override + { + bool isal = false; +#if defined(__i386__) || defined(__x86_64__) + // other arches or lack of support result in isal = false + if (cct->_conf->compressor_zlib_isal) { + ceph_arch_probe(); + isal = (ceph_arch_intel_pclmul && ceph_arch_intel_sse41); + } +#endif + if (compressor == 0 || has_isal != isal) { + compressor = std::make_shared<ZlibCompressor>(cct, isal); + has_isal = isal; + } + *cs = compressor; + return 0; + } +}; + +#endif diff --git a/src/compressor/zlib/ZlibCompressor.cc b/src/compressor/zlib/ZlibCompressor.cc new file mode 100644 index 00000000..e3064d2a --- /dev/null +++ b/src/compressor/zlib/ZlibCompressor.cc @@ -0,0 +1,246 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2015 Mirantis, Inc. + * + * Author: Alyona Kiseleva <akiselyova@mirantis.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + */ + +// ----------------------------------------------------------------------------- +#include "common/debug.h" +#include "ZlibCompressor.h" +#include "osd/osd_types.h" +#include "isa-l/include/igzip_lib.h" +// ----------------------------------------------------------------------------- + +#include <zlib.h> + +// ----------------------------------------------------------------------------- +#define dout_context cct +#define dout_subsys ceph_subsys_compressor +#undef dout_prefix +#define dout_prefix _prefix(_dout) +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- + +static ostream& +_prefix(std::ostream* _dout) +{ + return *_dout << "ZlibCompressor: "; +} +// ----------------------------------------------------------------------------- + +#define MAX_LEN (CEPH_PAGE_SIZE) + +// default window size for Zlib 1.2.8, negated for raw deflate +#define ZLIB_DEFAULT_WIN_SIZE -15 + +// desired memory usage level. increasing to 9 doesn't speed things up +// significantly (helps only on >=16K blocks) and sometimes degrades +// compression ratio. +#define ZLIB_MEMORY_LEVEL 8 + +int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out) +{ + int ret; + unsigned have; + z_stream strm; + unsigned char* c_in; + int begin = 1; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit2(&strm, cct->_conf->compressor_zlib_level, Z_DEFLATED, ZLIB_DEFAULT_WIN_SIZE, ZLIB_MEMORY_LEVEL, Z_DEFAULT_STRATEGY); + if (ret != Z_OK) { + dout(1) << "Compression init error: init return " + << ret << " instead of Z_OK" << dendl; + return -1; + } + + for (ceph::bufferlist::buffers_t::const_iterator i = in.buffers().begin(); + i != in.buffers().end();) { + + c_in = (unsigned char*) (*i).c_str(); + long unsigned int len = (*i).length(); + ++i; + + strm.avail_in = len; + int flush = i != in.buffers().end() ? Z_NO_FLUSH : Z_FINISH; + + strm.next_in = c_in; + do { + bufferptr ptr = buffer::create_page_aligned(MAX_LEN); + strm.next_out = (unsigned char*)ptr.c_str() + begin; + strm.avail_out = MAX_LEN - begin; + if (begin) { + // put a compressor variation mark in front of compressed stream, not used at the moment + ptr.c_str()[0] = 0; + begin = 0; + } + ret = deflate(&strm, flush); /* no bad return value */ + if (ret == Z_STREAM_ERROR) { + dout(1) << "Compression error: compress return Z_STREAM_ERROR(" + << ret << ")" << dendl; + deflateEnd(&strm); + return -1; + } + have = MAX_LEN - strm.avail_out; + out.append(ptr, 0, have); + } while (strm.avail_out == 0); + if (strm.avail_in != 0) { + dout(10) << "Compression error: unused input" << dendl; + deflateEnd(&strm); + return -1; + } + } + + deflateEnd(&strm); + return 0; +} + +#if __x86_64__ && defined(HAVE_BETTER_YASM_ELF64) +int ZlibCompressor::isal_compress(const bufferlist &in, bufferlist &out) +{ + int ret; + unsigned have; + isal_zstream strm; + unsigned char* c_in; + int begin = 1; + + /* allocate deflate state */ + isal_deflate_init(&strm); + strm.end_of_stream = 0; + + for (ceph::bufferlist::buffers_t::const_iterator i = in.buffers().begin(); + i != in.buffers().end();) { + + c_in = (unsigned char*) (*i).c_str(); + long unsigned int len = (*i).length(); + ++i; + + strm.avail_in = len; + strm.end_of_stream = (i == in.buffers().end()); + strm.flush = FINISH_FLUSH; + + strm.next_in = c_in; + + do { + bufferptr ptr = buffer::create_page_aligned(MAX_LEN); + strm.next_out = (unsigned char*)ptr.c_str() + begin; + strm.avail_out = MAX_LEN - begin; + if (begin) { + // put a compressor variation mark in front of compressed stream, not used at the moment + ptr.c_str()[0] = 1; + begin = 0; + } + ret = isal_deflate(&strm); + if (ret != COMP_OK) { + dout(1) << "Compression error: isal_deflate return error (" + << ret << ")" << dendl; + return -1; + } + have = MAX_LEN - strm.avail_out; + out.append(ptr, 0, have); + } while (strm.avail_out == 0); + if (strm.avail_in != 0) { + dout(10) << "Compression error: unused input" << dendl; + return -1; + } + } + + return 0; +} +#endif + +int ZlibCompressor::compress(const bufferlist &in, bufferlist &out) +{ +#ifdef HAVE_QATZIP + if (qat_enabled) + return qat_accel.compress(in, out); +#endif +#if __x86_64__ && defined(HAVE_BETTER_YASM_ELF64) + if (isal_enabled) + return isal_compress(in, out); + else + return zlib_compress(in, out); +#else + return zlib_compress(in, out); +#endif +} + +int ZlibCompressor::decompress(bufferlist::const_iterator &p, size_t compressed_size, bufferlist &out) +{ +#ifdef HAVE_QATZIP + if (qat_enabled) + return qat_accel.decompress(p, compressed_size, out); +#endif + + int ret; + unsigned have; + z_stream strm; + const char* c_in; + int begin = 1; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + + // choose the variation of compressor + ret = inflateInit2(&strm, ZLIB_DEFAULT_WIN_SIZE); + if (ret != Z_OK) { + dout(1) << "Decompression init error: init return " + << ret << " instead of Z_OK" << dendl; + return -1; + } + + size_t remaining = std::min<size_t>(p.get_remaining(), compressed_size); + + while(remaining) { + long unsigned int len = p.get_ptr_and_advance(remaining, &c_in); + remaining -= len; + strm.avail_in = len - begin; + strm.next_in = (unsigned char*)c_in + begin; + begin = 0; + + do { + strm.avail_out = MAX_LEN; + bufferptr ptr = buffer::create_page_aligned(MAX_LEN); + strm.next_out = (unsigned char*)ptr.c_str(); + ret = inflate(&strm, Z_NO_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR) { + dout(1) << "Decompression error: decompress return " + << ret << dendl; + inflateEnd(&strm); + return -1; + } + have = MAX_LEN - strm.avail_out; + out.append(ptr, 0, have); + } while (strm.avail_out == 0); + } + + /* clean up and return */ + (void)inflateEnd(&strm); + return 0; +} + +int ZlibCompressor::decompress(const bufferlist &in, bufferlist &out) +{ +#ifdef HAVE_QATZIP + if (qat_enabled) + return qat_accel.decompress(in, out); +#endif + auto i = std::cbegin(in); + return decompress(i, in.length(), out); +} diff --git a/src/compressor/zlib/ZlibCompressor.h b/src/compressor/zlib/ZlibCompressor.h new file mode 100644 index 00000000..d770547a --- /dev/null +++ b/src/compressor/zlib/ZlibCompressor.h @@ -0,0 +1,46 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2015 Mirantis, Inc. + * + * Author: Alyona Kiseleva <akiselyova@mirantis.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + */ + +#ifndef CEPH_COMPRESSION_ZLIB_H +#define CEPH_COMPRESSION_ZLIB_H + +#include "common/config.h" +#include "compressor/Compressor.h" + +class ZlibCompressor : public Compressor { + bool isal_enabled; + CephContext *const cct; +public: + ZlibCompressor(CephContext *cct, bool isal) + : Compressor(COMP_ALG_ZLIB, "zlib"), isal_enabled(isal), cct(cct) { +#ifdef HAVE_QATZIP + if (cct->_conf->qat_compressor_enabled && qat_accel.init("zlib")) + qat_enabled = true; + else + qat_enabled = false; +#endif + } + + int compress(const bufferlist &in, bufferlist &out) override; + int decompress(const bufferlist &in, bufferlist &out) override; + int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &out) override; +private: + int zlib_compress(const bufferlist &in, bufferlist &out); + int isal_compress(const bufferlist &in, bufferlist &out); + }; + + +#endif |