From ba171a4b67105bac157b6a57b46a765f92eb7920 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Thu, 4 Jan 2024 00:35:06 -0800 Subject: [PATCH 01/26] zstd compressor refactor Signed-off-by: giantcroc --- .../compression/zstd/common/BUILD | 4 +- .../compression/zstd/common/base.cc | 4 +- .../compression/zstd/common/base.h | 2 - .../zstd/common/dictionary_manager.h | 2 - .../common/compression/zstd/compressor/BUILD | 21 ++++++ .../compressor/zstd_compressor_impl_base.cc | 68 +++++++++++++++++++ .../compressor/zstd_compressor_impl_base.h | 47 +++++++++++++ .../compression/zstd/compressor/BUILD | 5 +- .../zstd/compressor/zstd_compressor_impl.cc | 55 ++------------- .../zstd/compressor/zstd_compressor_impl.h | 24 +++---- source/extensions/extensions_build_config.bzl | 2 +- 11 files changed, 158 insertions(+), 76 deletions(-) rename source/{extensions => common}/compression/zstd/common/BUILD (91%) rename source/{extensions => common}/compression/zstd/common/base.cc (86%) rename source/{extensions => common}/compression/zstd/common/base.h (92%) rename source/{extensions => common}/compression/zstd/common/dictionary_manager.h (98%) create mode 100644 source/common/compression/zstd/compressor/BUILD create mode 100644 source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc create mode 100644 source/common/compression/zstd/compressor/zstd_compressor_impl_base.h diff --git a/source/extensions/compression/zstd/common/BUILD b/source/common/compression/zstd/common/BUILD similarity index 91% rename from source/extensions/compression/zstd/common/BUILD rename to source/common/compression/zstd/common/BUILD index 98b6a3abb62f..b1b33c002112 100644 --- a/source/extensions/compression/zstd/common/BUILD +++ b/source/common/compression/zstd/common/BUILD @@ -1,12 +1,12 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_library", - "envoy_extension_package", + "envoy_package", ) licenses(["notice"]) # Apache 2 -envoy_extension_package() +envoy_package() envoy_cc_library( name = "zstd_base_lib", diff --git a/source/extensions/compression/zstd/common/base.cc b/source/common/compression/zstd/common/base.cc similarity index 86% rename from source/extensions/compression/zstd/common/base.cc rename to source/common/compression/zstd/common/base.cc index 3682f3626934..89dc2941cb2d 100644 --- a/source/extensions/compression/zstd/common/base.cc +++ b/source/common/compression/zstd/common/base.cc @@ -1,7 +1,6 @@ -#include "source/extensions/compression/zstd/common/base.h" +#include "source/common/compression/zstd/common/base.h" namespace Envoy { -namespace Extensions { namespace Compression { namespace Zstd { namespace Common { @@ -27,5 +26,4 @@ void Base::getOutput(Buffer::Instance& output_buffer) { } // namespace Common } // namespace Zstd } // namespace Compression -} // namespace Extensions } // namespace Envoy diff --git a/source/extensions/compression/zstd/common/base.h b/source/common/compression/zstd/common/base.h similarity index 92% rename from source/extensions/compression/zstd/common/base.h rename to source/common/compression/zstd/common/base.h index 6a3c626a3701..8582fe3f86f3 100644 --- a/source/extensions/compression/zstd/common/base.h +++ b/source/common/compression/zstd/common/base.h @@ -7,7 +7,6 @@ #include "zstd.h" namespace Envoy { -namespace Extensions { namespace Compression { namespace Zstd { namespace Common { @@ -29,5 +28,4 @@ struct Base { } // namespace Common } // namespace Zstd } // namespace Compression -} // namespace Extensions } // namespace Envoy diff --git a/source/extensions/compression/zstd/common/dictionary_manager.h b/source/common/compression/zstd/common/dictionary_manager.h similarity index 98% rename from source/extensions/compression/zstd/common/dictionary_manager.h rename to source/common/compression/zstd/common/dictionary_manager.h index c70f2aba25b0..276fe76f47e3 100644 --- a/source/extensions/compression/zstd/common/dictionary_manager.h +++ b/source/common/compression/zstd/common/dictionary_manager.h @@ -10,7 +10,6 @@ #include "zstd.h" namespace Envoy { -namespace Extensions { namespace Compression { namespace Zstd { namespace Common { @@ -119,5 +118,4 @@ template class } // namespace Common } // namespace Zstd } // namespace Compression -} // namespace Extensions } // namespace Envoy diff --git a/source/common/compression/zstd/compressor/BUILD b/source/common/compression/zstd/compressor/BUILD new file mode 100644 index 000000000000..75d11f2d5f55 --- /dev/null +++ b/source/common/compression/zstd/compressor/BUILD @@ -0,0 +1,21 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_library", + "envoy_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_package() + +envoy_cc_library( + name = "compressor_base", + srcs = ["zstd_compressor_impl_base.cc"], + hdrs = ["zstd_compressor_impl_base.h"], + deps = [ + "//envoy/compression/compressor:compressor_interface", + "//source/common/buffer:buffer_lib", + "//source/common/compression/zstd/common:zstd_base_lib", + "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", + ], +) diff --git a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc new file mode 100644 index 000000000000..37ef083edc8c --- /dev/null +++ b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc @@ -0,0 +1,68 @@ +#include "source/common/compression/zstd/compressor/zstd_compressor_impl_base.h" + +#include "source/common/buffer/buffer_impl.h" + +namespace Envoy { +namespace Compression { +namespace Zstd { +namespace Compressor { + +ZstdCompressorImplBase::ZstdCompressorImplBase(uint32_t compression_level, bool enable_checksum, + uint32_t strategy, const ZstdCDictManagerPtr& cdict_manager, + uint32_t chunk_size) + : Common::Base(chunk_size), cctx_(ZSTD_createCCtx(), &ZSTD_freeCCtx), + cdict_manager_(cdict_manager), compression_level_(compression_level) { + size_t result; + result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_checksumFlag, enable_checksum); + RELEASE_ASSERT(!ZSTD_isError(result), ""); + + result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_strategy, strategy); + RELEASE_ASSERT(!ZSTD_isError(result), ""); + + if (cdict_manager_) { + ZSTD_CDict* cdict = cdict_manager_->getFirstDictionary(); + result = ZSTD_CCtx_refCDict(cctx_.get(), cdict); + } else { + result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_compressionLevel, compression_level_); + } + RELEASE_ASSERT(!ZSTD_isError(result), ""); +} + +void ZstdCompressorImplBase::compress(Buffer::Instance& buffer, + Envoy::Compression::Compressor::State state) { + compressPreprocess(); + + Buffer::OwnedImpl accumulation_buffer; + for (const Buffer::RawSlice& input_slice : buffer.getRawSlices()) { + if (input_slice.len_ > 0) { + compressProcess(input_slice, accumulation_buffer); + buffer.drain(input_slice.len_); + } + } + + compressPostprocess(); + + ASSERT(buffer.length() == 0); + buffer.move(accumulation_buffer); + + if (state == Envoy::Compression::Compressor::State::Finish) { + process(buffer, ZSTD_e_end); + } +} + +void ZstdCompressorImplBase::process(Buffer::Instance& output_buffer, ZSTD_EndDirective mode) { + bool finished; + do { + const size_t remaining = ZSTD_compressStream2(cctx_.get(), &output_, &input_, mode); + getOutput(output_buffer); + // If we're on the last chunk we're finished when zstd returns 0, + // which means its consumed all the input AND finished the frame. + // Otherwise, we're finished when we've consumed all the input. + finished = (ZSTD_e_end == mode) ? (remaining == 0) : (input_.pos == input_.size); + } while (!finished); +} + +} // namespace Compressor +} // namespace Zstd +} // namespace Compression +} // namespace Envoy diff --git a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h new file mode 100644 index 000000000000..4a510c809027 --- /dev/null +++ b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h @@ -0,0 +1,47 @@ +#pragma once + +#include "envoy/compression/compressor/compressor.h" + +#include "source/common/compression/zstd/common/base.h" +#include "source/common/compression/zstd/common/dictionary_manager.h" + +namespace Envoy { +namespace Compression { +namespace Zstd { +namespace Compressor { + +using ZstdCDictManager = + Common::DictionaryManager; +using ZstdCDictManagerPtr = std::unique_ptr; + +/** + * Implementation of compressor's interface. + */ +class ZstdCompressorImplBase : public Common::Base, + public Envoy::Compression::Compressor::Compressor, + NonCopyable { +public: + ZstdCompressorImplBase(uint32_t compression_level, bool enable_checksum, uint32_t strategy, + const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size); + + // Compression::Compressor::Compressor + void compress(Buffer::Instance& buffer, Envoy::Compression::Compressor::State state) override; + + void process(Buffer::Instance& output_buffer, ZSTD_EndDirective mode); +private: + + virtual void compressPreprocess() PURE; + + virtual void compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) PURE; + + virtual void compressPostprocess() PURE; + + std::unique_ptr cctx_; + const ZstdCDictManagerPtr& cdict_manager_; + const uint32_t compression_level_; +}; + +} // namespace Compressor +} // namespace Zstd +} // namespace Compression +} // namespace Envoy diff --git a/source/extensions/compression/zstd/compressor/BUILD b/source/extensions/compression/zstd/compressor/BUILD index e6167ff1a1cb..fe53d6a123f0 100644 --- a/source/extensions/compression/zstd/compressor/BUILD +++ b/source/extensions/compression/zstd/compressor/BUILD @@ -16,8 +16,9 @@ envoy_cc_library( deps = [ "//envoy/compression/compressor:compressor_interface", "//source/common/buffer:buffer_lib", - "//source/extensions/compression/zstd/common:zstd_base_lib", - "//source/extensions/compression/zstd/common:zstd_dictionary_manager_lib", + "//source/common/compression/zstd/common:zstd_base_lib", + "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", + "//source/common/compression/zstd/compressor:compressor_base", ], ) diff --git a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc index 89d3ed754e65..415fda39e911 100644 --- a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc +++ b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc @@ -1,64 +1,19 @@ #include "source/extensions/compression/zstd/compressor/zstd_compressor_impl.h" -#include "source/common/buffer/buffer_impl.h" - namespace Envoy { namespace Extensions { namespace Compression { namespace Zstd { namespace Compressor { -ZstdCompressorImpl::ZstdCompressorImpl(uint32_t compression_level, bool enable_checksum, - uint32_t strategy, const ZstdCDictManagerPtr& cdict_manager, - uint32_t chunk_size) - : Common::Base(chunk_size), cctx_(ZSTD_createCCtx(), &ZSTD_freeCCtx), - cdict_manager_(cdict_manager), compression_level_(compression_level) { - size_t result; - result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_checksumFlag, enable_checksum); - RELEASE_ASSERT(!ZSTD_isError(result), ""); - - result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_strategy, strategy); - RELEASE_ASSERT(!ZSTD_isError(result), ""); +void ZstdCompressorImpl::compressPreprocess() {} - if (cdict_manager_) { - ZSTD_CDict* cdict = cdict_manager_->getFirstDictionary(); - result = ZSTD_CCtx_refCDict(cctx_.get(), cdict); - } else { - result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_compressionLevel, compression_level_); - } - RELEASE_ASSERT(!ZSTD_isError(result), ""); +void ZstdCompressorImpl::compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) { + setInput(input_slice); + process(accumulation_buffer, ZSTD_e_continue); } -void ZstdCompressorImpl::compress(Buffer::Instance& buffer, - Envoy::Compression::Compressor::State state) { - Buffer::OwnedImpl accumulation_buffer; - for (const Buffer::RawSlice& input_slice : buffer.getRawSlices()) { - if (input_slice.len_ > 0) { - setInput(input_slice); - process(accumulation_buffer, ZSTD_e_continue); - buffer.drain(input_slice.len_); - } - } - - ASSERT(buffer.length() == 0); - buffer.move(accumulation_buffer); - - if (state == Envoy::Compression::Compressor::State::Finish) { - process(buffer, ZSTD_e_end); - } -} - -void ZstdCompressorImpl::process(Buffer::Instance& output_buffer, ZSTD_EndDirective mode) { - bool finished; - do { - const size_t remaining = ZSTD_compressStream2(cctx_.get(), &output_, &input_, mode); - getOutput(output_buffer); - // If we're on the last chunk we're finished when zstd returns 0, - // which means its consumed all the input AND finished the frame. - // Otherwise, we're finished when we've consumed all the input. - finished = (ZSTD_e_end == mode) ? (remaining == 0) : (input_.pos == input_.size); - } while (!finished); -} +void ZstdCompressorImpl::compressPostprocess() {} } // namespace Compressor } // namespace Zstd diff --git a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h index e0adaec7caaf..847aca6cb1b7 100644 --- a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h +++ b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h @@ -2,8 +2,9 @@ #include "envoy/compression/compressor/compressor.h" -#include "source/extensions/compression/zstd/common/base.h" -#include "source/extensions/compression/zstd/common/dictionary_manager.h" +#include "source/common/compression/zstd/common/base.h" +#include "source/common/compression/zstd/common/dictionary_manager.h" +#include "source/common/compression/zstd/compressor/zstd_compressor_impl_base.h" namespace Envoy { namespace Extensions { @@ -12,28 +13,23 @@ namespace Zstd { namespace Compressor { using ZstdCDictManager = - Common::DictionaryManager; + Envoy::Compression::Zstd::Common::DictionaryManager; using ZstdCDictManagerPtr = std::unique_ptr; /** * Implementation of compressor's interface. */ -class ZstdCompressorImpl : public Common::Base, - public Envoy::Compression::Compressor::Compressor, - NonCopyable { +class ZstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdCompressorImplBase { public: ZstdCompressorImpl(uint32_t compression_level, bool enable_checksum, uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size); - - // Compression::Compressor::Compressor - void compress(Buffer::Instance& buffer, Envoy::Compression::Compressor::State state) override; + const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size):ZstdCompressorImplBase(compression_level,enable_checksum,strategy,cdict_manager,chunk_size){} private: - void process(Buffer::Instance& output_buffer, ZSTD_EndDirective mode); + void compressPreprocess() override; + + void compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) override; - std::unique_ptr cctx_; - const ZstdCDictManagerPtr& cdict_manager_; - const uint32_t compression_level_; + void compressPostprocess() override; }; } // namespace Compressor diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index a67bf3be4744..af1b6cd1c1ea 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -35,7 +35,7 @@ EXTENSIONS = { "envoy.compression.brotli.compressor": "//source/extensions/compression/brotli/compressor:config", "envoy.compression.brotli.decompressor": "//source/extensions/compression/brotli/decompressor:config", "envoy.compression.zstd.compressor": "//source/extensions/compression/zstd/compressor:config", - "envoy.compression.zstd.decompressor": "//source/extensions/compression/zstd/decompressor:config", + # "envoy.compression.zstd.decompressor": "//source/extensions/compression/zstd/decompressor:config", # # Config validators From 57df3b2b955baa124d612807846b4896f337b09d Mon Sep 17 00:00:00 2001 From: giantcroc Date: Tue, 9 Jan 2024 22:09:21 -0800 Subject: [PATCH 02/26] add qatzstd to contrib Signed-off-by: giantcroc --- api/BUILD | 1 + .../qatzstd/compressor/v3alpha/BUILD | 12 ++++ .../qatzstd/compressor/v3alpha/qatzstd.proto | 72 +++++++++++++++++++ api/versioning/BUILD | 1 + contrib/contrib_build_config.bzl | 3 +- contrib/extensions_metadata.yaml | 5 ++ .../qatzstd/compressor/source/BUILD | 35 +++++++++ .../qatzstd/compressor/source/config.cc | 50 +++++++++++++ .../qatzstd/compressor/source/config.h | 65 +++++++++++++++++ .../source/qatzstd_compressor_impl.cc | 22 ++++++ .../source/qatzstd_compressor_impl.h | 39 ++++++++++ 11 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD create mode 100644 api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto create mode 100644 contrib/qat/compression/qatzstd/compressor/source/BUILD create mode 100644 contrib/qat/compression/qatzstd/compressor/source/config.cc create mode 100644 contrib/qat/compression/qatzstd/compressor/source/config.h create mode 100644 contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc create mode 100644 contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h diff --git a/api/BUILD b/api/BUILD index 2eadff1f606f..a21eeb29a2cf 100644 --- a/api/BUILD +++ b/api/BUILD @@ -73,6 +73,7 @@ proto_library( visibility = ["//visibility:public"], deps = [ "//contrib/envoy/extensions/compression/qatzip/compressor/v3alpha:pkg", + "//contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha:pkg", "//contrib/envoy/extensions/filters/http/checksum/v3alpha:pkg", "//contrib/envoy/extensions/filters/http/dynamo/v3:pkg", "//contrib/envoy/extensions/filters/http/golang/v3alpha:pkg", diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD new file mode 100644 index 000000000000..1c1a6f6b4423 --- /dev/null +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD @@ -0,0 +1,12 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/config/core/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto new file mode 100644 index 000000000000..f58aec3d3256 --- /dev/null +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -0,0 +1,72 @@ +syntax = "proto3"; + +package envoy.extensions.compression.qatzstd.compressor.v3alpha; + +import "envoy/config/core/v3/base.proto"; + +import "google/protobuf/wrappers.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.compression.qatzstd.compressor.v3alpha"; +option java_outer_classname = "QatzstdProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/qatzstd/compressor/v3alpha"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Qatzstd Compressor] +// [#extension: envoy.compression.qatzstd.compressor] + +// [#next-free-field: 8] +message Qatzstd { + // Reference to http://facebook.github.io/zstd/zstd_manual.html + enum Strategy { + DEFAULT = 0; + FAST = 1; + DFAST = 2; + GREEDY = 3; + LAZY = 4; + LAZY2 = 5; + BTLAZY2 = 6; + BTOPT = 7; + BTULTRA = 8; + BTULTRA2 = 9; + } + + // Set compression parameters according to pre-defined compression level table. + // Note that exact compression parameters are dynamically determined, + // depending on both compression level and source content size (when known). + // Value 0 means default, and default level is 3. + // Setting a level does not automatically set all other compression parameters + // to default. Setting this will however eventually dynamically impact the compression + // parameters which have not been manually set. The manually set + // ones will 'stick'. + google.protobuf.UInt32Value compression_level = 1; + + // A 32-bits checksum of content is written at end of frame. If not set, defaults to false. + bool enable_checksum = 2; + + // The higher the value of selected strategy, the more complex it is, + // resulting in stronger and slower compression. + // Special: value 0 means "use default strategy". + Strategy strategy = 3 [(validate.rules).enum = {defined_only: true}]; + + // A dictionary for compression. Zstd offers dictionary compression, which greatly improves + // efficiency on small files and messages. Each dictionary will be generated with a dictionary ID + // that can be used to search the same dictionary during decompression. + // Please refer to `zstd manual `_ + // to train a specific dictionary for compression. + config.core.v3.DataSource dictionary = 4; + + // Value for compressor's next output buffer. If not set, defaults to 4096. + google.protobuf.UInt32Value chunk_size = 5 [(validate.rules).uint32 = {lte: 65536 gte: 4096}]; + + + // Enable QAT to accelerate zstd compresstion or not. If not set, defaults to false. + bool enable_qat_zstd = 6; + + // Fall back to software for QAT-zstd when input size is less than this value. + // Valid only enable_qat_zstd is true. 0 means no fallback at all. If not set, defaults to 4000. + google.protobuf.UInt32Value qat_zstd_fallback_threshold = 7 [(validate.rules).uint32 = {lte: 65536 gte: 0}]; +} \ No newline at end of file diff --git a/api/versioning/BUILD b/api/versioning/BUILD index 706d7d6f9d96..7a7417ffc224 100644 --- a/api/versioning/BUILD +++ b/api/versioning/BUILD @@ -10,6 +10,7 @@ proto_library( visibility = ["//visibility:public"], deps = [ "//contrib/envoy/extensions/compression/qatzip/compressor/v3alpha:pkg", + "//contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha:pkg", "//contrib/envoy/extensions/config/v3alpha:pkg", "//contrib/envoy/extensions/filters/http/checksum/v3alpha:pkg", "//contrib/envoy/extensions/filters/http/dynamo/v3:pkg", diff --git a/contrib/contrib_build_config.bzl b/contrib/contrib_build_config.bzl index b8e7811a168c..40a0b9e1fbdb 100644 --- a/contrib/contrib_build_config.bzl +++ b/contrib/contrib_build_config.bzl @@ -5,6 +5,7 @@ CONTRIB_EXTENSIONS = { # "envoy.compression.qatzip.compressor": "//contrib/qat/compression/qatzip/compressor/source:config", + "envoy.compression.qatzstd.compressor": "//contrib/qat/compression/qatzstd/compressor/source:config", # # HTTP filters @@ -85,4 +86,4 @@ CONTRIB_EXTENSIONS = { # "envoy.router.cluster_specifier_plugin.golang": "//contrib/golang/router/cluster_specifier/source:config", -} +} \ No newline at end of file diff --git a/contrib/extensions_metadata.yaml b/contrib/extensions_metadata.yaml index 8168b063da58..d8aee9d710fb 100644 --- a/contrib/extensions_metadata.yaml +++ b/contrib/extensions_metadata.yaml @@ -18,6 +18,11 @@ envoy.compression.qatzip.compressor: - envoy.compression.compressor security_posture: robust_to_untrusted_downstream_and_upstream status: alpha +envoy.compression.qatzstd.compressor: + categories: + - envoy.compression.compressor + security_posture: robust_to_untrusted_downstream_and_upstream + status: alpha envoy.filters.http.squash: categories: - envoy.filters.http diff --git a/contrib/qat/compression/qatzstd/compressor/source/BUILD b/contrib/qat/compression/qatzstd/compressor/source/BUILD new file mode 100644 index 000000000000..e87018500b5a --- /dev/null +++ b/contrib/qat/compression/qatzstd/compressor/source/BUILD @@ -0,0 +1,35 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_contrib_extension", + "envoy_cc_library", + "envoy_contrib_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_contrib_package() + +envoy_cc_library( + name = "compressor_lib", + srcs = ["qatzstd_compressor_impl.cc"], + hdrs = ["qatzstd_compressor_impl.h"], + deps = [ + "//envoy/compression/compressor:compressor_interface", + "//source/common/buffer:buffer_lib", + "//source/common/compression/zstd/common:zstd_base_lib", + "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", + "//source/common/compression/zstd/compressor:compressor_base", + ], +) + +envoy_cc_contrib_extension( + name = "config", + srcs = ["config.cc"], + hdrs = ["config.h"], + deps = [ + ":compressor_lib", + "//source/common/http:headers_lib", + "//source/extensions/compression/common/compressor:compressor_factory_base_lib", + "@envoy_api//contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha:pkg_cc_proto", + ], +) diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.cc b/contrib/qat/compression/qatzstd/compressor/source/config.cc new file mode 100644 index 000000000000..1c45923d203e --- /dev/null +++ b/contrib/qat/compression/qatzstd/compressor/source/config.cc @@ -0,0 +1,50 @@ +#include "contrib/qat/compression/qatzstd/compressor/source/config.h" + +namespace Envoy { +namespace Extensions { +namespace Compression { +namespace Qatzstd { +namespace Compressor { + +QatzstdCompressorFactory::QatzstdCompressorFactory( + const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& qatzstd, + Event::Dispatcher& dispatcher, Api::Api& api, ThreadLocal::SlotAllocator& tls) + : compression_level_( + PROTOBUF_GET_WRAPPED_OR_DEFAULT(qatzstd, compression_level, ZSTD_CLEVEL_DEFAULT)), + enable_checksum_(qatzstd.enable_checksum()), strategy_(qatzstd.strategy()), + chunk_size_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(qatzstd, chunk_size, ZSTD_CStreamOutSize())) { + if (qatzstd.has_dictionary()) { + Protobuf::RepeatedPtrField dictionaries; + dictionaries.Add()->CopyFrom(qatzstd.dictionary()); + cdict_manager_ = std::make_unique( + dictionaries, dispatcher, api, tls, true, + [this](const void* dict_buffer, size_t dict_size) -> ZSTD_CDict* { + return ZSTD_createCDict(dict_buffer, dict_size, compression_level_); + }); + } +} + +Envoy::Compression::Compressor::CompressorPtr QatzstdCompressorFactory::createCompressor() { + return std::make_unique(compression_level_, enable_checksum_, strategy_, + cdict_manager_, chunk_size_); +} + +Envoy::Compression::Compressor::CompressorFactoryPtr +QatzstdCompressorLibraryFactory::createCompressorFactoryFromProtoTyped( + const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& proto_config, + Server::Configuration::FactoryContext& context) { + return std::make_unique(proto_config, context.mainThreadDispatcher(), + context.api(), context.threadLocal()); +} + +/** + * Static registration for the zstd compressor library. @see NamedCompressorLibraryConfigFactory. + */ +REGISTER_FACTORY(QatzstdCompressorLibraryFactory, + Envoy::Compression::Compressor::NamedCompressorLibraryConfigFactory); + +} // namespace Compressor +} // namespace Qatzstd +} // namespace Compression +} // namespace Extensions +} // namespace Envoy diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.h b/contrib/qat/compression/qatzstd/compressor/source/config.h new file mode 100644 index 000000000000..c16e9a8f592d --- /dev/null +++ b/contrib/qat/compression/qatzstd/compressor/source/config.h @@ -0,0 +1,65 @@ +#pragma once + +#include "envoy/compression/compressor/factory.h" +#include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.h" +#include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.validate.h" + +#include "source/common/http/headers.h" +#include "source/extensions/compression/common/compressor/factory_base.h" +#include "contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h" + +namespace Envoy { +namespace Extensions { +namespace Compression { +namespace Qatzstd { +namespace Compressor { + +namespace { + +const std::string& qatzstdStatsPrefix() { CONSTRUCT_ON_FIRST_USE(std::string, "qatzstd."); } +const std::string& qatzstdExtensionName() { + CONSTRUCT_ON_FIRST_USE(std::string, "envoy.compression.qatzstd.compressor"); +} + +} // namespace + +class QatzstdCompressorFactory : public Envoy::Compression::Compressor::CompressorFactory { +public: + QatzstdCompressorFactory(const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& qatzstd, + Event::Dispatcher& dispatcher, Api::Api& api, + ThreadLocal::SlotAllocator& tls); + + // Envoy::Compression::Compressor::CompressorFactory + Envoy::Compression::Compressor::CompressorPtr createCompressor() override; + const std::string& statsPrefix() const override { return qatzstdStatsPrefix(); } + const std::string& contentEncoding() const override { + return Http::CustomHeaders::get().ContentEncodingValues.Zstd; + } + +private: + const uint32_t compression_level_; + const bool enable_checksum_; + const uint32_t strategy_; + const uint32_t chunk_size_; + ZstdCDictManagerPtr cdict_manager_{nullptr}; +}; + +class QatzstdCompressorLibraryFactory + : public Compression::Common::Compressor::CompressorLibraryFactoryBase< + envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd> { +public: + QatzstdCompressorLibraryFactory() : CompressorLibraryFactoryBase(qatzstdExtensionName()) {} + +private: + Envoy::Compression::Compressor::CompressorFactoryPtr createCompressorFactoryFromProtoTyped( + const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& config, + Server::Configuration::FactoryContext& context) override; +}; + +DECLARE_FACTORY(QatzstdCompressorLibraryFactory); + +} // namespace Compressor +} // namespace Qatzstd +} // namespace Compression +} // namespace Extensions +} // namespace Envoy diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc new file mode 100644 index 000000000000..e33876f2a693 --- /dev/null +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc @@ -0,0 +1,22 @@ +#include "contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h" + +namespace Envoy { +namespace Extensions { +namespace Compression { +namespace Qatzstd { +namespace Compressor { + +void QatzstdCompressorImpl::compressPreprocess() {} + +void QatzstdCompressorImpl::compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) { + setInput(input_slice); + process(accumulation_buffer, ZSTD_e_continue); +} + +void QatzstdCompressorImpl::compressPostprocess() {} + +} // namespace Compressor +} // namespace Qatzstd +} // namespace Compression +} // namespace Extensions +} // namespace Envoy diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h new file mode 100644 index 000000000000..1abd5e0d838e --- /dev/null +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h @@ -0,0 +1,39 @@ +#pragma once + +#include "envoy/compression/compressor/compressor.h" + +#include "source/common/compression/zstd/common/base.h" +#include "source/common/compression/zstd/common/dictionary_manager.h" +#include "source/common/compression/zstd/compressor/zstd_compressor_impl_base.h" + +namespace Envoy { +namespace Extensions { +namespace Compression { +namespace Qatzstd { +namespace Compressor { + +using ZstdCDictManager = + Envoy::Compression::Zstd::Common::DictionaryManager; +using ZstdCDictManagerPtr = std::unique_ptr; + +/** + * Implementation of compressor's interface. + */ +class QatzstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdCompressorImplBase { +public: + QatzstdCompressorImpl(uint32_t compression_level, bool enable_checksum, uint32_t strategy, + const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size):ZstdCompressorImplBase(compression_level,enable_checksum,strategy,cdict_manager,chunk_size){} + +private: + void compressPreprocess() override; + + void compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) override; + + void compressPostprocess() override; +}; + +} // namespace Compressor +} // namespace Qatzstd +} // namespace Compression +} // namespace Extensions +} // namespace Envoy From 425712534639ad67020aacd99c2382a403ed2548 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Tue, 9 Jan 2024 22:37:00 -0800 Subject: [PATCH 03/26] fix decompressor Signed-off-by: giantcroc --- source/extensions/compression/zstd/decompressor/BUILD | 4 ++-- .../zstd/decompressor/zstd_decompressor_impl.cc | 2 +- .../zstd/decompressor/zstd_decompressor_impl.h | 8 ++++---- source/extensions/extensions_build_config.bzl | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/extensions/compression/zstd/decompressor/BUILD b/source/extensions/compression/zstd/decompressor/BUILD index 9fc4383b939a..a0f56116492a 100644 --- a/source/extensions/compression/zstd/decompressor/BUILD +++ b/source/extensions/compression/zstd/decompressor/BUILD @@ -18,8 +18,8 @@ envoy_cc_library( "//envoy/stats:stats_interface", "//envoy/stats:stats_macros", "//source/common/buffer:buffer_lib", - "//source/extensions/compression/zstd/common:zstd_base_lib", - "//source/extensions/compression/zstd/common:zstd_dictionary_manager_lib", + "//source/common/compression/zstd/common:zstd_base_lib", + "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", ], ) diff --git a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.cc b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.cc index 7a165da1973c..e2a00232c120 100644 --- a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.cc +++ b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.cc @@ -21,7 +21,7 @@ constexpr uint64_t MaxInflateRatio = 100; ZstdDecompressorImpl::ZstdDecompressorImpl(Stats::Scope& scope, const std::string& stats_prefix, const ZstdDDictManagerPtr& ddict_manager, uint32_t chunk_size) - : Common::Base(chunk_size), dctx_(ZSTD_createDCtx(), &ZSTD_freeDCtx), + : Envoy::Compression::Zstd::Common::Base(chunk_size), dctx_(ZSTD_createDCtx(), &ZSTD_freeDCtx), ddict_manager_(ddict_manager), stats_(generateStats(stats_prefix, scope)) {} void ZstdDecompressorImpl::decompress(const Buffer::Instance& input_buffer, diff --git a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h index 597a8c72ad0e..491a1109d7ec 100644 --- a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h +++ b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h @@ -5,8 +5,8 @@ #include "envoy/stats/stats_macros.h" #include "source/common/common/logger.h" -#include "source/extensions/compression/zstd/common/base.h" -#include "source/extensions/compression/zstd/common/dictionary_manager.h" +#include "source/common/compression/zstd/common/base.h" +#include "source/common/compression/zstd/common/dictionary_manager.h" #include "zstd_errors.h" @@ -17,7 +17,7 @@ namespace Zstd { namespace Decompressor { using ZstdDDictManager = - Common::DictionaryManager; + Envoy::Compression::Zstd::Common::DictionaryManager; using ZstdDDictManagerPtr = std::unique_ptr; /** @@ -39,7 +39,7 @@ struct ZstdDecompressorStats { /** * Implementation of decompressor's interface. */ -class ZstdDecompressorImpl : public Common::Base, +class ZstdDecompressorImpl : public Envoy::Compression::Zstd::Common::Base, public Envoy::Compression::Decompressor::Decompressor, public Logger::Loggable, NonCopyable { diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index af1b6cd1c1ea..a67bf3be4744 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -35,7 +35,7 @@ EXTENSIONS = { "envoy.compression.brotli.compressor": "//source/extensions/compression/brotli/compressor:config", "envoy.compression.brotli.decompressor": "//source/extensions/compression/brotli/decompressor:config", "envoy.compression.zstd.compressor": "//source/extensions/compression/zstd/compressor:config", - # "envoy.compression.zstd.decompressor": "//source/extensions/compression/zstd/decompressor:config", + "envoy.compression.zstd.decompressor": "//source/extensions/compression/zstd/decompressor:config", # # Config validators From bc2328f55bb5cd062decfaec7544d0c619982bf7 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Wed, 10 Jan 2024 00:48:18 -0800 Subject: [PATCH 04/26] support qatzstd Signed-off-by: giantcroc --- bazel/foreign_cc/qatzstd.patch | 85 +++++++++++++++++++ bazel/repositories.bzl | 9 ++ bazel/repository_locations.bzl | 17 +++- .../qatzstd/compressor/source/BUILD | 26 ++++++ .../qatzstd/compressor/source/config.cc | 49 ++++++++++- .../qatzstd/compressor/source/config.h | 27 ++++-- .../source/qatzstd_compressor_impl.cc | 68 +++++++++++++-- .../source/qatzstd_compressor_impl.h | 31 +++++-- envoy-zstd.yaml | 62 ++++++++++++++ .../compressor/zstd_compressor_impl_base.cc | 15 ++-- .../compressor/zstd_compressor_impl_base.h | 17 ++-- .../zstd/compressor/zstd_compressor_impl.cc | 9 +- .../zstd/compressor/zstd_compressor_impl.h | 15 ++-- .../decompressor/zstd_decompressor_impl.h | 3 +- 14 files changed, 388 insertions(+), 45 deletions(-) create mode 100644 bazel/foreign_cc/qatzstd.patch create mode 100644 envoy-zstd.yaml diff --git a/bazel/foreign_cc/qatzstd.patch b/bazel/foreign_cc/qatzstd.patch new file mode 100644 index 000000000000..6cb5201b7a2b --- /dev/null +++ b/bazel/foreign_cc/qatzstd.patch @@ -0,0 +1,85 @@ +diff --git a/src/Makefile b/src/Makefile +index 1abf10d..a0c7e9a 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -41,6 +41,7 @@ LIBDIR ?= $(INSTALLDIR)/lib + INCLUDEDIR ?= $(INSTALLDIR)/include + + CP ?= cp ++MKDIR ?= mkdir + + ENABLE_USDM_DRV ?= 0 + ifneq ($(ICP_ROOT), ) +@@ -55,10 +56,8 @@ ifneq ($(ICP_ROOT), ) + else + QATFLAGS = -DINTREE + LDFLAGS = -lqat +- ifneq ($(ENABLE_USDM_DRV), 0) +- QATFLAGS += -DENABLE_USDM_DRV +- LDFLAGS += -lusdm +- endif ++ QATFLAGS += -DENABLE_USDM_DRV ++ LDFLAGS += -lusdm + endif + + ifdef ZSTDLIB +@@ -69,8 +68,8 @@ CFLAGS += -Wall -Werror -Wextra -Wcast-align -Wshadow -Wstrict-aliasing=1 \ + -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes \ + -Wundef -Wpointer-arith -Wvla -Wformat=2 -Winit-self \ + -Wfloat-equal -Wwrite-strings -Wredundant-decls -Wc++-compat \ +- -pedantic -fstack-protector-strong -fPIE -fPIC \ +- -fno-delete-null-pointer-checks -fwrapv -fno-strict-overflow ++ -pedantic -fstack-protector-strong \ ++ -fno-delete-null-pointer-checks -fwrapv + + DEBUGLEVEL ?=0 + +@@ -81,27 +80,30 @@ else + QATFLAGS += -O3 + endif + ++$(info INSTALLDIR="$(INSTALLDIR)") ++$(info CPPFLAGS="$(CPPFLAGS)") ++ + qatseqprod.o: qatseqprod.c +- $(CC) -c $(CFLAGS) $(QATFLAGS) $(DEBUGFLAGS) $^ -o $@ ++ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(QATFLAGS) $(DEBUGFLAGS) $^ -o $@ + + lib: qatseqprod.o + $(AR) rc libqatseqprod.a $^ +- $(CC) -shared $^ $(LDFLAGS) -o libqatseqprod.so ++ @echo qatseqprod library successfully build + + .PHONY: install + install: lib ++ $(MKDIR) -p $(LIBDIR) ++ $(MKDIR) -p $(INCLUDEDIR) + $(CP) libqatseqprod.a $(LIBDIR) +- $(CP) libqatseqprod.so $(LIBDIR) + $(CP) qatseqprod.h $(INCLUDEDIR) + @echo qatseqprod library successfully installed + + .PHONY: uninstall + uninstall: + $(RM) $(LIBDIR)/libqatseqprod.a +- $(RM) $(LIBDIR)/libqatseqprod.so + $(RM) $(INCLUDEDIR)/qatseqprod.h + @echo qatseqprod library successfully uninstalled + + clean: + $(RM) *.o +- $(RM) libqatseqprod.a libqatseqprod.so ++ $(RM) libqatseqprod.a +diff --git a/test/Makefile b/test/Makefile +index dff0c8e..4ba01b2 100644 +--- a/test/Makefile ++++ b/test/Makefile +@@ -34,7 +34,7 @@ + # ####################################################################### + LIB = ../src + +-LDFLAGS = $(LIB)/libqatseqprod.a -I$(LIB) ++LDFLAGS = $(LIB)/libqatseqprod.a -I$(LIB) -L$(LIB) -l:libqatseqprod.a -l:libqat.a -l:libusdm.a -l:libzstd.a -lpthread -lcrypto + + ifneq ($(ICP_ROOT), ) + LDFLAGS += -lqat_s -lusdm_drv_s -Wl,-rpath,$(ICP_ROOT)/build -L$(ICP_ROOT)/build diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 580dc80813a1..821468d5125b 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -309,6 +309,7 @@ def envoy_dependencies(skip_targets = []): _com_github_intel_ipp_crypto_crypto_mb_fips() _com_github_intel_qatlib() _com_github_intel_qatzip() + _com_github_qat_zstd() _com_github_lz4_lz4() _com_github_jbeder_yaml_cpp() _com_github_libevent_libevent() @@ -583,6 +584,14 @@ def _com_github_intel_qatzip(): build_file_content = BUILD_ALL_CONTENT, ) +def _com_github_qat_zstd(): + external_http_archive( + name = "com_github_qat_zstd", + build_file_content = BUILD_ALL_CONTENT, + patch_args = ["-p1"], + patches = ["@envoy//bazel/foreign_cc:qatzstd.patch"], + ) + def _com_github_lz4_lz4(): external_http_archive( name = "com_github_lz4_lz4", diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index a4d3ca27843b..360eee67a751 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -446,7 +446,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( urls = ["https://github.com/intel/qatlib/archive/refs/tags/{version}.tar.gz"], use_category = ["dataplane_ext"], release_date = "2023-11-15", - extensions = ["envoy.tls.key_providers.qat", "envoy.compression.qatzip.compressor"], + extensions = ["envoy.tls.key_providers.qat", "envoy.compression.qatzip.compressor","envoy.compression.qatzstd.compressor"], cpe = "N/A", license = "BSD-3-Clause", license_url = "https://github.com/intel/qatlib/blob/{version}/LICENSE", @@ -466,6 +466,21 @@ REPOSITORY_LOCATIONS_SPEC = dict( license = "BSD-3-Clause", license_url = "https://github.com/intel/QATzip/blob/{version}/LICENSE", ), + com_github_qat_zstd = dict( + project_name = "QAT-ZSTD-Plugin", + project_desc = "IntelĀ® QuickAssist Technology ZSTD Plugin (QAT ZSTD Plugin)", + project_url = "https://github.com/intel/QAT-ZSTD-Plugin/", + version = "0.1.0", + sha256 = "74c5bfbb3b0c6f1334e128ee0b43958d1d34751a4762e54e8f970c443e445f33", + strip_prefix = "QAT-ZSTD-Plugin-{version}", + urls = ["https://github.com/intel/QAT-ZSTD-Plugin/archive/refs/tags/v{version}.tar.gz"], + use_category = ["dataplane_ext"], + extensions = [ + "envoy.compression.qatzstd.compressor", + ], + release_date = "2023-09-08", + cpe = "N/A", + ), com_github_luajit_luajit = dict( project_name = "LuaJIT", project_desc = "Just-In-Time compiler for Lua", diff --git a/contrib/qat/compression/qatzstd/compressor/source/BUILD b/contrib/qat/compression/qatzstd/compressor/source/BUILD index e87018500b5a..2d849049de21 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/BUILD +++ b/contrib/qat/compression/qatzstd/compressor/source/BUILD @@ -1,3 +1,4 @@ +load("@rules_foreign_cc//foreign_cc:defs.bzl", "make") load( "//bazel:envoy_build_system.bzl", "envoy_cc_contrib_extension", @@ -9,11 +10,33 @@ licenses(["notice"]) # Apache 2 envoy_contrib_package() +make( + name = "qat-zstd", + build_data = ["@com_github_qat_zstd//:all"], + includes = [], + lib_source = "@com_github_qat_zstd//:all", + out_static_libs = ["libqatseqprod.a"], + tags = ["skip_on_windows"], + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + targets = [ + "", + "install", + ], + deps = [ + "//contrib/qat:qatlib", + "//external:zstd", + ], +) + envoy_cc_library( name = "compressor_lib", srcs = ["qatzstd_compressor_impl.cc"], hdrs = ["qatzstd_compressor_impl.h"], deps = [ + ":qat-zstd", "//envoy/compression/compressor:compressor_interface", "//source/common/buffer:buffer_lib", "//source/common/compression/zstd/common:zstd_base_lib", @@ -28,6 +51,9 @@ envoy_cc_contrib_extension( hdrs = ["config.h"], deps = [ ":compressor_lib", + ":qat-zstd", + "//envoy/event:dispatcher_interface", + "//envoy/thread_local:thread_local_interface", "//source/common/http:headers_lib", "//source/extensions/compression/common/compressor:compressor_factory_base_lib", "@envoy_api//contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha:pkg_cc_proto", diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.cc b/contrib/qat/compression/qatzstd/compressor/source/config.cc index 1c45923d203e..75dfa1598971 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/config.cc @@ -12,7 +12,11 @@ QatzstdCompressorFactory::QatzstdCompressorFactory( : compression_level_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(qatzstd, compression_level, ZSTD_CLEVEL_DEFAULT)), enable_checksum_(qatzstd.enable_checksum()), strategy_(qatzstd.strategy()), - chunk_size_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(qatzstd, chunk_size, ZSTD_CStreamOutSize())) { + chunk_size_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(qatzstd, chunk_size, ZSTD_CStreamOutSize())), + enable_qat_zstd_(qatzstd.enable_qat_zstd()), + qat_zstd_fallback_threshold_(PROTOBUF_GET_WRAPPED_OR_DEFAULT( + qatzstd, qat_zstd_fallback_threshold, DefaultQatZstdFallbackThreshold)), + tls_slot_(nullptr) { if (qatzstd.has_dictionary()) { Protobuf::RepeatedPtrField dictionaries; dictionaries.Add()->CopyFrom(qatzstd.dictionary()); @@ -22,11 +26,48 @@ QatzstdCompressorFactory::QatzstdCompressorFactory( return ZSTD_createCDict(dict_buffer, dict_size, compression_level_); }); } + if (enable_qat_zstd_) { + tls_slot_ = ThreadLocal::TypedSlot::makeUnique(tls); + tls_slot_->set([](Event::Dispatcher&) { return std::make_shared(); }); + } +} + +QatzstdCompressorFactory::QatzstdThreadLocal::QatzstdThreadLocal() + : initialized_(false), sequenceProducerState_(nullptr) {} + +QatzstdCompressorFactory::QatzstdThreadLocal::~QatzstdThreadLocal() { + if (initialized_) { + /* Free sequence producer state */ + QZSTD_freeSeqProdState(sequenceProducerState_); + /* Stop QAT device, please call this function when + you won't use QAT anymore or before the process exits */ + QZSTD_stopQatDevice(); + } +} + +void* QatzstdCompressorFactory::QatzstdThreadLocal::GetQATSession() { + // The session must be initialized only once in every worker thread. + if (!initialized_) { + + int status = QZSTD_startQatDevice(); + RELEASE_ASSERT(status == QZSTD_OK, "failed to initialize hardware"); + sequenceProducerState_ = QZSTD_createSeqProdState(); + initialized_ = true; + } + + return sequenceProducerState_; } Envoy::Compression::Compressor::CompressorPtr QatzstdCompressorFactory::createCompressor() { - return std::make_unique(compression_level_, enable_checksum_, strategy_, - cdict_manager_, chunk_size_); + if (enable_qat_zstd_) { + return std::make_unique( + compression_level_, enable_checksum_, strategy_, cdict_manager_, chunk_size_, + enable_qat_zstd_, qat_zstd_fallback_threshold_, tls_slot_->get()->GetQATSession()); + } else { + return std::make_unique(compression_level_, enable_checksum_, strategy_, + cdict_manager_, chunk_size_, enable_qat_zstd_, + qat_zstd_fallback_threshold_, nullptr); + } } Envoy::Compression::Compressor::CompressorFactoryPtr @@ -34,7 +75,7 @@ QatzstdCompressorLibraryFactory::createCompressorFactoryFromProtoTyped( const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& proto_config, Server::Configuration::FactoryContext& context) { return std::make_unique(proto_config, context.mainThreadDispatcher(), - context.api(), context.threadLocal()); + context.api(), context.threadLocal()); } /** diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.h b/contrib/qat/compression/qatzstd/compressor/source/config.h index c16e9a8f592d..0342a2f2ac9c 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.h +++ b/contrib/qat/compression/qatzstd/compressor/source/config.h @@ -1,12 +1,16 @@ #pragma once #include "envoy/compression/compressor/factory.h" -#include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.h" -#include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.validate.h" +#include "envoy/event/dispatcher.h" +#include "envoy/thread_local/thread_local.h" #include "source/common/http/headers.h" #include "source/extensions/compression/common/compressor/factory_base.h" + +#include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.h" +#include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.validate.h" #include "contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h" +#include "qatseqprod.h" namespace Envoy { namespace Extensions { @@ -14,6 +18,9 @@ namespace Compression { namespace Qatzstd { namespace Compressor { +// Default threshold for qat_zstd fallback to software. +const uint32_t DefaultQatZstdFallbackThreshold = 4000; + namespace { const std::string& qatzstdStatsPrefix() { CONSTRUCT_ON_FIRST_USE(std::string, "qatzstd."); } @@ -25,9 +32,9 @@ const std::string& qatzstdExtensionName() { class QatzstdCompressorFactory : public Envoy::Compression::Compressor::CompressorFactory { public: - QatzstdCompressorFactory(const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& qatzstd, - Event::Dispatcher& dispatcher, Api::Api& api, - ThreadLocal::SlotAllocator& tls); + QatzstdCompressorFactory( + const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& qatzstd, + Event::Dispatcher& dispatcher, Api::Api& api, ThreadLocal::SlotAllocator& tls); // Envoy::Compression::Compressor::CompressorFactory Envoy::Compression::Compressor::CompressorPtr createCompressor() override; @@ -37,11 +44,21 @@ class QatzstdCompressorFactory : public Envoy::Compression::Compressor::Compress } private: + struct QatzstdThreadLocal : public ThreadLocal::ThreadLocalObject { + QatzstdThreadLocal(); + ~QatzstdThreadLocal() override; + void* GetQATSession(); + bool initialized_; + void* sequenceProducerState_; + }; const uint32_t compression_level_; const bool enable_checksum_; const uint32_t strategy_; const uint32_t chunk_size_; ZstdCDictManagerPtr cdict_manager_{nullptr}; + const bool enable_qat_zstd_; + const uint32_t qat_zstd_fallback_threshold_; + ThreadLocal::TypedSlotPtr tls_slot_; }; class QatzstdCompressorLibraryFactory diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc index e33876f2a693..bbd13fda6043 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc @@ -6,14 +6,72 @@ namespace Compression { namespace Qatzstd { namespace Compressor { -void QatzstdCompressorImpl::compressPreprocess() {} +QatzstdCompressorImpl::QatzstdCompressorImpl(uint32_t compression_level, bool enable_checksum, + uint32_t strategy, + const ZstdCDictManagerPtr& cdict_manager, + uint32_t chunk_size, bool enable_qat_zstd, + uint32_t qat_zstd_fallback_threshold, + void* sequenceProducerState) + : ZstdCompressorImplBase(compression_level, enable_checksum, strategy, cdict_manager, + chunk_size), + enable_qat_zstd_(enable_qat_zstd), qat_zstd_fallback_threshold_(qat_zstd_fallback_threshold), + sequenceProducerState_(sequenceProducerState), input_ptr_{std::make_unique( + chunk_size)}, + input_len_(0), chunk_size_(chunk_size) { + ENVOY_LOG(debug, + "zstd new ZstdCompressorImpl, compression_level: {}, strategy: {}, chunk_size: " + "{}, enable_qat_zstd: {}, qat_zstd_fallback_threshold: {}", + compression_level, strategy, chunk_size, enable_qat_zstd, qat_zstd_fallback_threshold); + if (enable_qat_zstd_) { + /* register qatSequenceProducer */ + ZSTD_registerSequenceProducer(cctx_.get(), sequenceProducerState_, qatSequenceProducer); + size_t result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_enableSeqProducerFallback, 1); + RELEASE_ASSERT(!ZSTD_isError(result), ""); + } +} + +void QatzstdCompressorImpl::compressPreprocess(Buffer::Instance& buffer, + Envoy::Compression::Compressor::State state) { + ENVOY_LOG(debug, "zstd compress input size {}", buffer.length()); + if (enable_qat_zstd_ && state == Envoy::Compression::Compressor::State::Flush) { + // Fall back to software if input size less than threshold to achieve better performance. + if (buffer.length() < qat_zstd_fallback_threshold_) { + ENVOY_LOG(debug, "zstd compress fall back to software"); + ZSTD_registerSequenceProducer(cctx_.get(), nullptr, nullptr); + } + } +} -void QatzstdCompressorImpl::compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) { - setInput(input_slice); - process(accumulation_buffer, ZSTD_e_continue); +void QatzstdCompressorImpl::setInput(const uint8_t* input, size_t size) { + input_.src = input; + input_.pos = 0; + input_.size = size; + input_len_ = 0; } -void QatzstdCompressorImpl::compressPostprocess() {} +void QatzstdCompressorImpl::compressProcess(const Buffer::Instance& buffer, + const Buffer::RawSlice& input_slice, + Buffer::Instance& accumulation_buffer) { + if (input_slice.len_ == buffer.length()) { + setInput(static_cast(input_slice.mem_), input_slice.len_); + process(accumulation_buffer, ZSTD_e_continue); + } else { + if (input_len_ + input_slice.len_ > chunk_size_) { + setInput(input_ptr_.get(), input_len_); + process(accumulation_buffer, ZSTD_e_continue); + } + memcpy(input_ptr_.get() + input_len_, input_slice.mem_, + input_slice.len_); // NOLINT(safe-memcpy) + input_len_ += input_slice.len_; + } +} + +void QatzstdCompressorImpl::compressPostprocess(Buffer::Instance& accumulation_buffer) { + if (input_len_ > 0) { + setInput(input_ptr_.get(), input_len_); + process(accumulation_buffer, ZSTD_e_continue); + } +} } // namespace Compressor } // namespace Qatzstd diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h index 1abd5e0d838e..fc198f73a98e 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h @@ -1,11 +1,15 @@ #pragma once #include "envoy/compression/compressor/compressor.h" +#include "envoy/server/factory_context.h" +#include "source/common/common/logger.h" #include "source/common/compression/zstd/common/base.h" #include "source/common/compression/zstd/common/dictionary_manager.h" #include "source/common/compression/zstd/compressor/zstd_compressor_impl_base.h" +#include "qatseqprod.h" + namespace Envoy { namespace Extensions { namespace Compression { @@ -13,23 +17,38 @@ namespace Qatzstd { namespace Compressor { using ZstdCDictManager = - Envoy::Compression::Zstd::Common::DictionaryManager; + Envoy::Compression::Zstd::Common::DictionaryManager; using ZstdCDictManagerPtr = std::unique_ptr; /** * Implementation of compressor's interface. */ -class QatzstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdCompressorImplBase { +class QatzstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdCompressorImplBase, + public Logger::Loggable { public: QatzstdCompressorImpl(uint32_t compression_level, bool enable_checksum, uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size):ZstdCompressorImplBase(compression_level,enable_checksum,strategy,cdict_manager,chunk_size){} + const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size, + bool enable_qat_zstd, uint32_t qat_zstd_fallback_threshold, + void* sequenceProducerState); private: - void compressPreprocess() override; + void compressPreprocess(Buffer::Instance& buffer, + Envoy::Compression::Compressor::State state) override; + + void compressProcess(const Buffer::Instance& buffer, const Buffer::RawSlice& input_slice, + Buffer::Instance& accumulation_buffer) override; + + void compressPostprocess(Buffer::Instance& accumulation_buffer) override; - void compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) override; + void setInput(const uint8_t* input, size_t size); - void compressPostprocess() override; + bool enable_qat_zstd_; + const uint32_t qat_zstd_fallback_threshold_; + void* sequenceProducerState_; + std::unique_ptr input_ptr_; + uint64_t input_len_; + uint64_t chunk_size_; }; } // namespace Compressor diff --git a/envoy-zstd.yaml b/envoy-zstd.yaml new file mode 100644 index 000000000000..ff65d46ac795 --- /dev/null +++ b/envoy-zstd.yaml @@ -0,0 +1,62 @@ +static_resources: + listeners: + - address: + socket_address: + address: 0.0.0.0 + port_value: 10000 + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: backend + domains: + - "*" + routes: + - match: + prefix: "/" + route: + cluster: service + http_filters: + - name: envoy.filters.http.compressor + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor + response_direction_config: + common_config: + min_content_length: 100 + content_type: + - application/octet-stream + disable_on_etag_header: false + compressor_library: + name: text_optimized + typed_config: + "@type": type.googleapis.com/envoy.extensions.compression.qatzstd.compressor.v3alpha.Qatzstd + compression_level: 10 + enable_qat_zstd: true + qat_zstd_fallback_threshold: 0 + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: service + connect_timeout: 0.25s + type: STRICT_DNS + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: service + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 1234 +admin: + address: + socket_address: + address: 0.0.0.0 + port_value: 9901 diff --git a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc index 37ef083edc8c..af5e87f4fab8 100644 --- a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc +++ b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc @@ -8,8 +8,9 @@ namespace Zstd { namespace Compressor { ZstdCompressorImplBase::ZstdCompressorImplBase(uint32_t compression_level, bool enable_checksum, - uint32_t strategy, const ZstdCDictManagerPtr& cdict_manager, - uint32_t chunk_size) + uint32_t strategy, + const ZstdCDictManagerPtr& cdict_manager, + uint32_t chunk_size) : Common::Base(chunk_size), cctx_(ZSTD_createCCtx(), &ZSTD_freeCCtx), cdict_manager_(cdict_manager), compression_level_(compression_level) { size_t result; @@ -29,18 +30,18 @@ ZstdCompressorImplBase::ZstdCompressorImplBase(uint32_t compression_level, bool } void ZstdCompressorImplBase::compress(Buffer::Instance& buffer, - Envoy::Compression::Compressor::State state) { - compressPreprocess(); - + Envoy::Compression::Compressor::State state) { + compressPreprocess(buffer, state); + Buffer::OwnedImpl accumulation_buffer; for (const Buffer::RawSlice& input_slice : buffer.getRawSlices()) { if (input_slice.len_ > 0) { - compressProcess(input_slice, accumulation_buffer); + compressProcess(buffer, input_slice, accumulation_buffer); buffer.drain(input_slice.len_); } } - compressPostprocess(); + compressPostprocess(accumulation_buffer); ASSERT(buffer.length() == 0); buffer.move(accumulation_buffer); diff --git a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h index 4a510c809027..5da65ac4257c 100644 --- a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h +++ b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h @@ -18,23 +18,24 @@ using ZstdCDictManagerPtr = std::unique_ptr; * Implementation of compressor's interface. */ class ZstdCompressorImplBase : public Common::Base, - public Envoy::Compression::Compressor::Compressor, - NonCopyable { + public Envoy::Compression::Compressor::Compressor, + NonCopyable { public: ZstdCompressorImplBase(uint32_t compression_level, bool enable_checksum, uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size); + const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size); // Compression::Compressor::Compressor void compress(Buffer::Instance& buffer, Envoy::Compression::Compressor::State state) override; void process(Buffer::Instance& output_buffer, ZSTD_EndDirective mode); -private: - - virtual void compressPreprocess() PURE; - virtual void compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) PURE; + virtual void compressPreprocess(Buffer::Instance& buffer, + Envoy::Compression::Compressor::State state) PURE; - virtual void compressPostprocess() PURE; + virtual void compressProcess(const Buffer::Instance& buffer, const Buffer::RawSlice& input_slice, + Buffer::Instance& accumulation_buffer) PURE; + + virtual void compressPostprocess(Buffer::Instance& accumulation_buffer) PURE; std::unique_ptr cctx_; const ZstdCDictManagerPtr& cdict_manager_; diff --git a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc index 415fda39e911..fedfb736d9d0 100644 --- a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc +++ b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc @@ -6,14 +6,17 @@ namespace Compression { namespace Zstd { namespace Compressor { -void ZstdCompressorImpl::compressPreprocess() {} +void ZstdCompressorImpl::compressPreprocess(Buffer::Instance&, + Envoy::Compression::Compressor::State) {} -void ZstdCompressorImpl::compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) { +void ZstdCompressorImpl::compressProcess(const Buffer::Instance&, + const Buffer::RawSlice& input_slice, + Buffer::Instance& accumulation_buffer) { setInput(input_slice); process(accumulation_buffer, ZSTD_e_continue); } -void ZstdCompressorImpl::compressPostprocess() {} +void ZstdCompressorImpl::compressPostprocess(Buffer::Instance&) {} } // namespace Compressor } // namespace Zstd diff --git a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h index 847aca6cb1b7..dd5b9f676937 100644 --- a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h +++ b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h @@ -13,7 +13,8 @@ namespace Zstd { namespace Compressor { using ZstdCDictManager = - Envoy::Compression::Zstd::Common::DictionaryManager; + Envoy::Compression::Zstd::Common::DictionaryManager; using ZstdCDictManagerPtr = std::unique_ptr; /** @@ -22,14 +23,18 @@ using ZstdCDictManagerPtr = std::unique_ptr; class ZstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdCompressorImplBase { public: ZstdCompressorImpl(uint32_t compression_level, bool enable_checksum, uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size):ZstdCompressorImplBase(compression_level,enable_checksum,strategy,cdict_manager,chunk_size){} + const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size) + : ZstdCompressorImplBase(compression_level, enable_checksum, strategy, cdict_manager, + chunk_size) {} private: - void compressPreprocess() override; + void compressPreprocess(Buffer::Instance& buffer, + Envoy::Compression::Compressor::State state) override; - void compressProcess(const Buffer::RawSlice& input_slice, Buffer::Instance& accumulation_buffer) override; + void compressProcess(const Buffer::Instance& buffer, const Buffer::RawSlice& input_slice, + Buffer::Instance& accumulation_buffer) override; - void compressPostprocess() override; + void compressPostprocess(Buffer::Instance& accumulation_buffer) override; }; } // namespace Compressor diff --git a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h index 491a1109d7ec..e738575f494b 100644 --- a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h +++ b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h @@ -17,7 +17,8 @@ namespace Zstd { namespace Decompressor { using ZstdDDictManager = - Envoy::Compression::Zstd::Common::DictionaryManager; + Envoy::Compression::Zstd::Common::DictionaryManager; using ZstdDDictManagerPtr = std::unique_ptr; /** From e7b88ecba76636b678e2211bf7b1be4ea88ca093 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Wed, 10 Jan 2024 23:17:04 -0800 Subject: [PATCH 05/26] add qatzstd test Signed-off-by: giantcroc --- .../compression/qatzstd/compressor/test/BUILD | 20 +++ .../test/qatzstd_compressor_impl_test.cc | 159 ++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 contrib/qat/compression/qatzstd/compressor/test/BUILD create mode 100644 contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc diff --git a/contrib/qat/compression/qatzstd/compressor/test/BUILD b/contrib/qat/compression/qatzstd/compressor/test/BUILD new file mode 100644 index 000000000000..5d14ef1bf03f --- /dev/null +++ b/contrib/qat/compression/qatzstd/compressor/test/BUILD @@ -0,0 +1,20 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_contrib_package", + "envoy_cc_test", +) + +licenses(["notice"]) # Apache 2 + +envoy_contrib_package() + +envoy_cc_test( + name = "compressor_test", + srcs = ["qatzstd_compressor_impl_test.cc"], + deps = [ + "//contrib/qat/compression/qatzstd/compressor/source:config", + "//source/extensions/compression/zstd/decompressor:decompressor_lib", + "//test/mocks/server:factory_context_mocks", + "//test/test_common:utility_lib", + ], +) diff --git a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc new file mode 100644 index 000000000000..8f0faf70f1c8 --- /dev/null +++ b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc @@ -0,0 +1,159 @@ +#include "source/common/buffer/buffer_impl.h" +#include "source/common/stats/isolated_store_impl.h" +#include "contrib/qat/compression/qatzstd/compressor/source/config.h" +#include "source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h" + +#include "test/mocks/server/factory_context.h" +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" +#include "qatseqprod.h" + +namespace Envoy { +namespace Extensions { +namespace Compression { +namespace Qatzstd { +namespace Compressor { +namespace { + +class QatzstdCompressorImplTest : public testing::Test { +protected: + void drainBuffer(Buffer::OwnedImpl& buffer) { + buffer.drain(buffer.length()); + ASSERT_EQ(0, buffer.length()); + } + + void verifyWithDecompressor(Envoy::Compression::Compressor::CompressorPtr compressor) { + Buffer::OwnedImpl buffer; + Buffer::OwnedImpl accumulation_buffer; + std::string original_text{}; + for (uint64_t i = 0; i < 10; i++) { + TestUtility::feedBufferWithRandomCharacters(buffer, default_input_size_ * i, i); + original_text.append(buffer.toString()); + ASSERT_EQ(default_input_size_ * i, buffer.length()); + compressor->compress(buffer, Envoy::Compression::Compressor::State::Flush); + accumulation_buffer.add(buffer); + drainBuffer(buffer); + } + + compressor->compress(buffer, Envoy::Compression::Compressor::State::Finish); + accumulation_buffer.add(buffer); + drainBuffer(buffer); + + Stats::IsolatedStoreImpl stats_store{}; + Zstd::Decompressor::ZstdDecompressorImpl decompressor{*stats_store.rootScope(), "test.", + default_ddict_manager_, 4096}; + + decompressor.decompress(accumulation_buffer, buffer); + std::string decompressed_text{buffer.toString()}; + + ASSERT_EQ(original_text.length(), decompressed_text.length()); + EXPECT_EQ(original_text, decompressed_text); + } + + Envoy::Compression::Compressor::CompressorFactoryPtr + createQatzstdCompressorFactoryFromConfig(const std::string& json) { + envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd qatzstd_config; + TestUtility::loadFromJson(json, qatzstd_config); + + return qatzstd_compressor_library_factory_.createCompressorFactoryFromProto(qatzstd_config, + context_); + } + + static constexpr uint32_t default_compression_level_{6}; + static constexpr uint32_t default_enable_checksum_{0}; + static constexpr uint32_t default_strategy_{0}; + uint32_t default_input_size_{796}; + uint32_t default_input_round_{10}; + ZstdCDictManagerPtr default_cdict_manager_{nullptr}; + Zstd::Decompressor::ZstdDDictManagerPtr default_ddict_manager_{nullptr}; + bool enable_qat_zstd{true}; + uint32_t qat_zstd_fallback_threshold{0}; + QatzstdCompressorLibraryFactory qatzstd_compressor_library_factory_; + NiceMock context_; +}; + +class QatzstdConfigTest + : public QatzstdCompressorImplTest, + public ::testing::WithParamInterface> {}; + +// These tests should pass even if required hardware or setup steps required for qatzstd are missing. +// Qatzstd uses a sofware fallback in this case. +INSTANTIATE_TEST_SUITE_P(QatzstdConfigTestInstantiation, QatzstdConfigTest, + // First tuple has all default values. + ::testing::Values(std::make_tuple(1, 4096, true, 4096), + std::make_tuple(2, 4096, true, 4096), + std::make_tuple(3, 65536, true, 4096), + std::make_tuple(4, 4096, true, 4096), + std::make_tuple(5, 8192, true, 1024), + std::make_tuple(6, 4096, false, 1024), + std::make_tuple(7, 4096, true, 1024), + std::make_tuple(8, 8192, true, 4096), + std::make_tuple(9, 8192, true, 1024), + std::make_tuple(10, 16384, true, 1024), + std::make_tuple(11, 8192, true, 8192), + std::make_tuple(12, 4096, true, 1024))); + +TEST_P(QatzstdConfigTest, LoadConfigAndVerifyWithDecompressor) { + std::tuple config_value_tuple = GetParam(); + std::string json{fmt::format(R"EOF({{ + "compression_level": {}, + "chunk_size": {}, + "enable_qat_zstd": {}, + "qat_zstd_fallback_threshold": {}, +}})EOF", + std::get<0>(config_value_tuple), std::get<1>(config_value_tuple), + std::get<2>(config_value_tuple), std::get<3>(config_value_tuple))}; + + Envoy::Compression::Compressor::CompressorFactoryPtr qatzstd_compressor_factory = + createQatzstdCompressorFactoryFromConfig(json); + + EXPECT_EQ("zstd", qatzstd_compressor_factory->contentEncoding()); + EXPECT_EQ("qatzstd.", qatzstd_compressor_factory->statsPrefix()); + + verifyWithDecompressor(qatzstd_compressor_factory->createCompressor()); +} + +TEST_F(QatzstdCompressorImplTest, IllegalConfig) { + envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd qatzstd; + Qatzstd::Compressor::QatzstdCompressorLibraryFactory lib_factory; + NiceMock mock_context; + std::string json; + + json = R"EOF({ + "compression_level": 7, + "enable_checksum": true, + "strategy":"default", + "chunk_size": 4096, + "dictionary": { + "inline_string": "" + }, + enable_qat_zstd: true, + qat_zstd_fallback_threshold: 1024, +})EOF"; + TestUtility::loadFromJson(json, qatzstd); + EXPECT_THROW_WITH_MESSAGE(lib_factory.createCompressorFactoryFromProto(qatzstd, mock_context), + EnvoyException, "DataSource cannot be empty"); + + json = R"EOF({ + "compression_level": 7, + "enable_checksum": true, + "strategy":"default", + "chunk_size": 4096, + "dictionary": { + "inline_string": "123321123" + }, + enable_qat_zstd: true, + qat_zstd_fallback_threshold: 1024, +})EOF"; + TestUtility::loadFromJson(json, qatzstd); + EXPECT_DEATH({ lib_factory.createCompressorFactoryFromProto(qatzstd, mock_context); }, + "assert failure: id != 0. Details: Illegal Zstd dictionary"); +} + +} // namespace +} // namespace Compressor +} // namespace Qatzstd +} // namespace Compression +} // namespace Extensions +} // namespace Envoy From e500c73946bac7ba7af89c25577f69f6f8a18163 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Mon, 29 Jan 2024 23:57:47 -0800 Subject: [PATCH 06/26] fix api Signed-off-by: giantcroc --- .../extensions/compression/qatzstd/compressor/v3alpha/BUILD | 2 +- .../compression/qatzstd/compressor/v3alpha/qatzstd.proto | 2 +- contrib/qat/compression/qatzstd/compressor/source/config.cc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD index 1c1a6f6b4423..09a37ad16b83 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD @@ -7,6 +7,6 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ "//envoy/config/core/v3:pkg", - "@com_github_cncf_udpa//udpa/annotations:pkg", + "@com_github_cncf_xds//udpa/annotations:pkg", ], ) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index f58aec3d3256..f50c8d292d2d 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -12,7 +12,7 @@ import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.compression.qatzstd.compressor.v3alpha"; option java_outer_classname = "QatzstdProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/qatzstd/compressor/v3alpha"; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha"; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Qatzstd Compressor] diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.cc b/contrib/qat/compression/qatzstd/compressor/source/config.cc index 75dfa1598971..9d06dd68b6f4 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/config.cc @@ -74,8 +74,8 @@ Envoy::Compression::Compressor::CompressorFactoryPtr QatzstdCompressorLibraryFactory::createCompressorFactoryFromProtoTyped( const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& proto_config, Server::Configuration::FactoryContext& context) { - return std::make_unique(proto_config, context.mainThreadDispatcher(), - context.api(), context.threadLocal()); + return std::make_unique(proto_config, context.serverFactoryContext().mainThreadDispatcher(), + context.serverFactoryContext().api(), context.serverFactoryContext().threadLocal()); } /** From e3a33c22f5cedae5c34121ae5607196785cf7d38 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Thu, 1 Feb 2024 00:19:37 -0800 Subject: [PATCH 07/26] use logger id compression Signed-off-by: giantcroc --- .../qat/compression/qatzstd/compressor/source/config.cc | 7 ++++++- contrib/qat/compression/qatzstd/compressor/source/config.h | 3 ++- .../qatzstd/compressor/source/qatzstd_compressor_impl.h | 2 +- source/common/common/logger.h | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.cc b/contrib/qat/compression/qatzstd/compressor/source/config.cc index 9d06dd68b6f4..9fa3d2455e5b 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/config.cc @@ -50,7 +50,12 @@ void* QatzstdCompressorFactory::QatzstdThreadLocal::GetQATSession() { if (!initialized_) { int status = QZSTD_startQatDevice(); - RELEASE_ASSERT(status == QZSTD_OK, "failed to initialize hardware"); + // RELEASE_ASSERT(status == QZSTD_OK, "failed to initialize hardware"); + if(status != QZSTD_OK){ + ENVOY_LOG(warn, "Failed to initialize qat hardware"); + }else{ + ENVOY_LOG(debug, "Initialize qat hardware successful"); + } sequenceProducerState_ = QZSTD_createSeqProdState(); initialized_ = true; } diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.h b/contrib/qat/compression/qatzstd/compressor/source/config.h index 0342a2f2ac9c..3d48323504de 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.h +++ b/contrib/qat/compression/qatzstd/compressor/source/config.h @@ -5,6 +5,7 @@ #include "envoy/thread_local/thread_local.h" #include "source/common/http/headers.h" +#include "source/common/common/logger.h" #include "source/extensions/compression/common/compressor/factory_base.h" #include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.h" @@ -44,7 +45,7 @@ class QatzstdCompressorFactory : public Envoy::Compression::Compressor::Compress } private: - struct QatzstdThreadLocal : public ThreadLocal::ThreadLocalObject { + struct QatzstdThreadLocal : public ThreadLocal::ThreadLocalObject,public Logger::Loggable { QatzstdThreadLocal(); ~QatzstdThreadLocal() override; void* GetQATSession(); diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h index fc198f73a98e..38ba61bda8c2 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h @@ -25,7 +25,7 @@ using ZstdCDictManagerPtr = std::unique_ptr; * Implementation of compressor's interface. */ class QatzstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdCompressorImplBase, - public Logger::Loggable { + public Logger::Loggable { public: QatzstdCompressorImpl(uint32_t compression_level, bool enable_checksum, uint32_t strategy, const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size, diff --git a/source/common/common/logger.h b/source/common/common/logger.h index a90e43628e1e..8187f9f1a7f8 100644 --- a/source/common/common/logger.h +++ b/source/common/common/logger.h @@ -45,6 +45,7 @@ const static bool should_log = true; FUNCTION(config) \ FUNCTION(connection) \ FUNCTION(conn_handler) \ + FUNCTION(compression) \ FUNCTION(decompression) \ FUNCTION(dns) \ FUNCTION(dubbo) \ From 5b6ed535a1c4b1fd44a123a51f9fff8868b45c7d Mon Sep 17 00:00:00 2001 From: giantcroc Date: Thu, 1 Feb 2024 00:35:58 -0800 Subject: [PATCH 08/26] add doc and format Signed-off-by: giantcroc --- .../qatzstd/compressor/v3alpha/qatzstd.proto | 1 + bazel/repository_locations.bzl | 2 +- changelogs/current.yaml | 3 ++ contrib/all_contrib_extensions.bzl | 2 + .../qatzstd/compressor/source/config.cc | 9 +++-- .../qatzstd/compressor/source/config.h | 5 ++- .../compression/qatzstd/compressor/test/BUILD | 2 +- .../test/qatzstd_compressor_impl_test.cc | 39 ++++++++----------- docs/BUILD | 1 + docs/root/api-v3/config/contrib/qat/qat.rst | 1 + .../other_features/_include/qatzstd.yaml | 3 +- .../other_features/other_features.rst | 1 + .../configuration/other_features/qatzstd.rst | 34 ++++++++++++++++ source/common/common/logger.h | 2 +- tools/spelling/spelling_dictionary.txt | 1 + 15 files changed, 74 insertions(+), 32 deletions(-) rename envoy-zstd.yaml => docs/root/configuration/other_features/_include/qatzstd.yaml (96%) create mode 100644 docs/root/configuration/other_features/qatzstd.rst diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index f50c8d292d2d..6cc367022885 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -16,6 +16,7 @@ option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extens option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Qatzstd Compressor] +// Qatzstd :ref:`configuration overview `. // [#extension: envoy.compression.qatzstd.compressor] // [#next-free-field: 8] diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 360eee67a751..219b383c6135 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -446,7 +446,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( urls = ["https://github.com/intel/qatlib/archive/refs/tags/{version}.tar.gz"], use_category = ["dataplane_ext"], release_date = "2023-11-15", - extensions = ["envoy.tls.key_providers.qat", "envoy.compression.qatzip.compressor","envoy.compression.qatzstd.compressor"], + extensions = ["envoy.tls.key_providers.qat", "envoy.compression.qatzip.compressor", "envoy.compression.qatzstd.compressor"], cpe = "N/A", license = "BSD-3-Clause", license_url = "https://github.com/intel/qatlib/blob/{version}/LICENSE", diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 7314ee8850db..b2fe1f275e24 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -48,5 +48,8 @@ new_features: change: | added support for :ref:`%UPSTREAM_CONNECTION_ID% ` for the upstream connection identifier. +- area: compression + change: | + Added qatzstd :ref:`compressor `. deprecated: diff --git a/contrib/all_contrib_extensions.bzl b/contrib/all_contrib_extensions.bzl index 19c605b700bb..a9ad517a576a 100644 --- a/contrib/all_contrib_extensions.bzl +++ b/contrib/all_contrib_extensions.bzl @@ -18,6 +18,7 @@ ARM64_SKIP_CONTRIB_TARGETS = [ "envoy.tls.key_providers.qat", "envoy.network.connection_balance.dlb", "envoy.compression.qatzip.compressor", + "envoy.compression.qatzstd.compressor", ] PPC_SKIP_CONTRIB_TARGETS = [ "envoy.tls.key_providers.cryptomb", @@ -26,6 +27,7 @@ PPC_SKIP_CONTRIB_TARGETS = [ "envoy.network.connection_balance.dlb", "envoy.regex_engines.hyperscan", "envoy.compression.qatzip.compressor", + "envoy.compression.qatzstd.compressor", ] FIPS_SKIP_CONTRIB_TARGETS = [ diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.cc b/contrib/qat/compression/qatzstd/compressor/source/config.cc index 9fa3d2455e5b..778ec97ffcc6 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/config.cc @@ -51,9 +51,9 @@ void* QatzstdCompressorFactory::QatzstdThreadLocal::GetQATSession() { int status = QZSTD_startQatDevice(); // RELEASE_ASSERT(status == QZSTD_OK, "failed to initialize hardware"); - if(status != QZSTD_OK){ + if (status != QZSTD_OK) { ENVOY_LOG(warn, "Failed to initialize qat hardware"); - }else{ + } else { ENVOY_LOG(debug, "Initialize qat hardware successful"); } sequenceProducerState_ = QZSTD_createSeqProdState(); @@ -79,8 +79,9 @@ Envoy::Compression::Compressor::CompressorFactoryPtr QatzstdCompressorLibraryFactory::createCompressorFactoryFromProtoTyped( const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& proto_config, Server::Configuration::FactoryContext& context) { - return std::make_unique(proto_config, context.serverFactoryContext().mainThreadDispatcher(), - context.serverFactoryContext().api(), context.serverFactoryContext().threadLocal()); + return std::make_unique( + proto_config, context.serverFactoryContext().mainThreadDispatcher(), + context.serverFactoryContext().api(), context.serverFactoryContext().threadLocal()); } /** diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.h b/contrib/qat/compression/qatzstd/compressor/source/config.h index 3d48323504de..d7ca98cc027e 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.h +++ b/contrib/qat/compression/qatzstd/compressor/source/config.h @@ -4,8 +4,8 @@ #include "envoy/event/dispatcher.h" #include "envoy/thread_local/thread_local.h" -#include "source/common/http/headers.h" #include "source/common/common/logger.h" +#include "source/common/http/headers.h" #include "source/extensions/compression/common/compressor/factory_base.h" #include "contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.pb.h" @@ -45,7 +45,8 @@ class QatzstdCompressorFactory : public Envoy::Compression::Compressor::Compress } private: - struct QatzstdThreadLocal : public ThreadLocal::ThreadLocalObject,public Logger::Loggable { + struct QatzstdThreadLocal : public ThreadLocal::ThreadLocalObject, + public Logger::Loggable { QatzstdThreadLocal(); ~QatzstdThreadLocal() override; void* GetQATSession(); diff --git a/contrib/qat/compression/qatzstd/compressor/test/BUILD b/contrib/qat/compression/qatzstd/compressor/test/BUILD index 5d14ef1bf03f..85297caa141a 100644 --- a/contrib/qat/compression/qatzstd/compressor/test/BUILD +++ b/contrib/qat/compression/qatzstd/compressor/test/BUILD @@ -1,7 +1,7 @@ load( "//bazel:envoy_build_system.bzl", - "envoy_contrib_package", "envoy_cc_test", + "envoy_contrib_package", ) licenses(["notice"]) # Apache 2 diff --git a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc index 8f0faf70f1c8..32d582225f9e 100644 --- a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc +++ b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc @@ -1,11 +1,11 @@ #include "source/common/buffer/buffer_impl.h" #include "source/common/stats/isolated_store_impl.h" -#include "contrib/qat/compression/qatzstd/compressor/source/config.h" #include "source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/utility.h" +#include "contrib/qat/compression/qatzstd/compressor/source/config.h" #include "gtest/gtest.h" #include "qatseqprod.h" @@ -57,7 +57,7 @@ class QatzstdCompressorImplTest : public testing::Test { TestUtility::loadFromJson(json, qatzstd_config); return qatzstd_compressor_library_factory_.createCompressorFactoryFromProto(qatzstd_config, - context_); + context_); } static constexpr uint32_t default_compression_level_{6}; @@ -73,26 +73,21 @@ class QatzstdCompressorImplTest : public testing::Test { NiceMock context_; }; -class QatzstdConfigTest - : public QatzstdCompressorImplTest, - public ::testing::WithParamInterface> {}; - -// These tests should pass even if required hardware or setup steps required for qatzstd are missing. -// Qatzstd uses a sofware fallback in this case. -INSTANTIATE_TEST_SUITE_P(QatzstdConfigTestInstantiation, QatzstdConfigTest, - // First tuple has all default values. - ::testing::Values(std::make_tuple(1, 4096, true, 4096), - std::make_tuple(2, 4096, true, 4096), - std::make_tuple(3, 65536, true, 4096), - std::make_tuple(4, 4096, true, 4096), - std::make_tuple(5, 8192, true, 1024), - std::make_tuple(6, 4096, false, 1024), - std::make_tuple(7, 4096, true, 1024), - std::make_tuple(8, 8192, true, 4096), - std::make_tuple(9, 8192, true, 1024), - std::make_tuple(10, 16384, true, 1024), - std::make_tuple(11, 8192, true, 8192), - std::make_tuple(12, 4096, true, 1024))); +class QatzstdConfigTest : public QatzstdCompressorImplTest, + public ::testing::WithParamInterface> {}; + +// These tests should pass even if required hardware or setup steps required for qatzstd are +// missing. Qatzstd uses a sofware fallback in this case. +INSTANTIATE_TEST_SUITE_P( + QatzstdConfigTestInstantiation, QatzstdConfigTest, + // First tuple has all default values. + ::testing::Values(std::make_tuple(1, 4096, true, 4096), std::make_tuple(2, 4096, true, 4096), + std::make_tuple(3, 65536, true, 4096), std::make_tuple(4, 4096, true, 4096), + std::make_tuple(5, 8192, true, 1024), std::make_tuple(6, 4096, false, 1024), + std::make_tuple(7, 4096, true, 1024), std::make_tuple(8, 8192, true, 4096), + std::make_tuple(9, 8192, true, 1024), std::make_tuple(10, 16384, true, 1024), + std::make_tuple(11, 8192, true, 8192), + std::make_tuple(12, 4096, true, 1024))); TEST_P(QatzstdConfigTest, LoadConfigAndVerifyWithDecompressor) { std::tuple config_value_tuple = GetParam(); diff --git a/docs/BUILD b/docs/BUILD index 16df02c3e5a6..3497d8d9f186 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -35,6 +35,7 @@ filegroup( "root/configuration/other_features/_include/hyperscan_matcher_multiple.yaml", "root/configuration/other_features/_include/hyperscan_regex_engine.yaml", "root/configuration/other_features/_include/qatzip.yaml", + "root/configuration/other_features/_include/qatzstd.yaml", "root/intro/arch_overview/security/_include/ssl.yaml", "root/configuration/listeners/network_filters/_include/generic_proxy_filter.yaml", "root/configuration/overview/_include/xds_api/oauth-sds-example.yaml", diff --git a/docs/root/api-v3/config/contrib/qat/qat.rst b/docs/root/api-v3/config/contrib/qat/qat.rst index 3e524d700b13..c03e01dd4397 100644 --- a/docs/root/api-v3/config/contrib/qat/qat.rst +++ b/docs/root/api-v3/config/contrib/qat/qat.rst @@ -4,3 +4,4 @@ ../../../extensions/private_key_providers/qat/v3alpha/* ../../../extensions/compression/qatzip/compressor/v3alpha/* + ../../../extensions/compression/qatzstd/compressor/v3alpha/* diff --git a/envoy-zstd.yaml b/docs/root/configuration/other_features/_include/qatzstd.yaml similarity index 96% rename from envoy-zstd.yaml rename to docs/root/configuration/other_features/_include/qatzstd.yaml index ff65d46ac795..4a33cfe65094 100644 --- a/envoy-zstd.yaml +++ b/docs/root/configuration/other_features/_include/qatzstd.yaml @@ -35,8 +35,9 @@ static_resources: name: text_optimized typed_config: "@type": type.googleapis.com/envoy.extensions.compression.qatzstd.compressor.v3alpha.Qatzstd - compression_level: 10 + compression_level: 9 enable_qat_zstd: true + chunk_size: 65536 qat_zstd_fallback_threshold: 0 - name: envoy.filters.http.router typed_config: diff --git a/docs/root/configuration/other_features/other_features.rst b/docs/root/configuration/other_features/other_features.rst index b5ba3fd18aeb..fef969b04e38 100644 --- a/docs/root/configuration/other_features/other_features.rst +++ b/docs/root/configuration/other_features/other_features.rst @@ -12,3 +12,4 @@ Other features wasm wasm_service qatzip + qatzstd diff --git a/docs/root/configuration/other_features/qatzstd.rst b/docs/root/configuration/other_features/qatzstd.rst new file mode 100644 index 000000000000..9cb87d3b2c63 --- /dev/null +++ b/docs/root/configuration/other_features/qatzstd.rst @@ -0,0 +1,34 @@ +.. _config_qatzstd: + +Qatzstd Compressor +======================= + +* :ref:`v3 API reference ` + + +Qatzstd compressor provides Envoy with faster hardware-accelerated zstd compression by integrating with `IntelĀ® QuickAssist Technology (IntelĀ® QAT) `_ through the qatlib and QAT-ZSTD-Plugin libraries. + +Example configuration +--------------------- + +An example for Qatzstd compressor configuration is: + +.. literalinclude:: _include/qatzstd.yaml + :language: yaml + + +How it works +------------ + +If enabled, the Qatzstd compressor will: + +- attach Qat hardware +- create Threadlocal Qatzstd context for each worker thread + +When new http package come, one worker thread will process it using its Qatzstd context and send the data needed to be compressed to +Qat hardware using standard zstd api. + +Installing and using QAT-ZSTD-Plugin +------------------------ + +For information on how to build/install and use QAT-ZSTD-Plugin see `introduction `_. \ No newline at end of file diff --git a/source/common/common/logger.h b/source/common/common/logger.h index 8187f9f1a7f8..4f0e7375f459 100644 --- a/source/common/common/logger.h +++ b/source/common/common/logger.h @@ -45,7 +45,7 @@ const static bool should_log = true; FUNCTION(config) \ FUNCTION(connection) \ FUNCTION(conn_handler) \ - FUNCTION(compression) \ + FUNCTION(compression) \ FUNCTION(decompression) \ FUNCTION(dns) \ FUNCTION(dubbo) \ diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index d7f46a9d8c08..316a1774d69a 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -353,6 +353,7 @@ QUIC QoS qat qatzip +qatzstd RAII RANLUX RBAC From a93864f8ab880a9a8d79db1e8836fae0f6e7352f Mon Sep 17 00:00:00 2001 From: giantcroc Date: Sun, 4 Feb 2024 01:40:15 -0800 Subject: [PATCH 09/26] trim whitespace Signed-off-by: giantcroc --- .../compression/qatzstd/compressor/v3alpha/qatzstd.proto | 4 ++-- contrib/contrib_build_config.bzl | 2 +- docs/root/configuration/other_features/qatzstd.rst | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index 6cc367022885..65764d3293a4 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -63,11 +63,11 @@ message Qatzstd { // Value for compressor's next output buffer. If not set, defaults to 4096. google.protobuf.UInt32Value chunk_size = 5 [(validate.rules).uint32 = {lte: 65536 gte: 4096}]; - + // Enable QAT to accelerate zstd compresstion or not. If not set, defaults to false. bool enable_qat_zstd = 6; // Fall back to software for QAT-zstd when input size is less than this value. // Valid only enable_qat_zstd is true. 0 means no fallback at all. If not set, defaults to 4000. google.protobuf.UInt32Value qat_zstd_fallback_threshold = 7 [(validate.rules).uint32 = {lte: 65536 gte: 0}]; -} \ No newline at end of file +} diff --git a/contrib/contrib_build_config.bzl b/contrib/contrib_build_config.bzl index 40a0b9e1fbdb..49b1f7afde79 100644 --- a/contrib/contrib_build_config.bzl +++ b/contrib/contrib_build_config.bzl @@ -86,4 +86,4 @@ CONTRIB_EXTENSIONS = { # "envoy.router.cluster_specifier_plugin.golang": "//contrib/golang/router/cluster_specifier/source:config", -} \ No newline at end of file +} diff --git a/docs/root/configuration/other_features/qatzstd.rst b/docs/root/configuration/other_features/qatzstd.rst index 9cb87d3b2c63..2e965e6a3dd8 100644 --- a/docs/root/configuration/other_features/qatzstd.rst +++ b/docs/root/configuration/other_features/qatzstd.rst @@ -26,9 +26,9 @@ If enabled, the Qatzstd compressor will: - create Threadlocal Qatzstd context for each worker thread When new http package come, one worker thread will process it using its Qatzstd context and send the data needed to be compressed to -Qat hardware using standard zstd api. +Qat hardware using standard zstd api. Installing and using QAT-ZSTD-Plugin ------------------------ -For information on how to build/install and use QAT-ZSTD-Plugin see `introduction `_. \ No newline at end of file +For information on how to build/install and use QAT-ZSTD-Plugin see `introduction `_. From f624b13d6f6d56efaf3f90284cecf6e029300c31 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Sun, 4 Feb 2024 22:18:14 -0800 Subject: [PATCH 10/26] fix memcpy Signed-off-by: giantcroc --- .../qatzstd/compressor/v3alpha/qatzstd.proto | 4 ++-- .../compressor/source/qatzstd_compressor_impl.cc | 13 ++++++------- .../compressor/source/qatzstd_compressor_impl.h | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index 65764d3293a4..7f73141c2c85 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -64,10 +64,10 @@ message Qatzstd { google.protobuf.UInt32Value chunk_size = 5 [(validate.rules).uint32 = {lte: 65536 gte: 4096}]; - // Enable QAT to accelerate zstd compresstion or not. If not set, defaults to false. + // Enable QAT to accelerate zstd compression or not. If not set, defaults to false. bool enable_qat_zstd = 6; - // Fall back to software for QAT-zstd when input size is less than this value. + // Fallback to software for qatzstd when input size is less than this value. // Valid only enable_qat_zstd is true. 0 means no fallback at all. If not set, defaults to 4000. google.protobuf.UInt32Value qat_zstd_fallback_threshold = 7 [(validate.rules).uint32 = {lte: 65536 gte: 0}]; } diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc index bbd13fda6043..778fa857e24b 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc @@ -50,19 +50,18 @@ void QatzstdCompressorImpl::setInput(const uint8_t* input, size_t size) { } void QatzstdCompressorImpl::compressProcess(const Buffer::Instance& buffer, - const Buffer::RawSlice& input_slice, + const Buffer::RawSlice& slice, Buffer::Instance& accumulation_buffer) { - if (input_slice.len_ == buffer.length()) { - setInput(static_cast(input_slice.mem_), input_slice.len_); + if (slice.len_ == buffer.length()) { + setInput(static_cast(slice.mem_), slice.len_); process(accumulation_buffer, ZSTD_e_continue); } else { - if (input_len_ + input_slice.len_ > chunk_size_) { + if (input_len_ + slice.len_ > chunk_size_) { setInput(input_ptr_.get(), input_len_); process(accumulation_buffer, ZSTD_e_continue); } - memcpy(input_ptr_.get() + input_len_, input_slice.mem_, - input_slice.len_); // NOLINT(safe-memcpy) - input_len_ += input_slice.len_; + memcpy(input_ptr_.get() + input_len_, slice.mem_, slice.len_); // NOLINT(safe-memcpy) + input_len_ += slice.len_; } } diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h index 38ba61bda8c2..f5cd356d65b1 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h @@ -36,7 +36,7 @@ class QatzstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdC void compressPreprocess(Buffer::Instance& buffer, Envoy::Compression::Compressor::State state) override; - void compressProcess(const Buffer::Instance& buffer, const Buffer::RawSlice& input_slice, + void compressProcess(const Buffer::Instance& buffer, const Buffer::RawSlice& slice, Buffer::Instance& accumulation_buffer) override; void compressPostprocess(Buffer::Instance& accumulation_buffer) override; From 3752639f2228a37e2b8ae0b1d6453e2d1846acdc Mon Sep 17 00:00:00 2001 From: giantcroc Date: Tue, 20 Feb 2024 19:51:31 -0800 Subject: [PATCH 11/26] remove dictionary due to not support for qatzstd Signed-off-by: giantcroc --- .../qatzstd/compressor/v3alpha/BUILD | 1 - .../qatzstd/compressor/v3alpha/qatzstd.proto | 9 ----- .../qatzstd/compressor/source/BUILD | 2 +- .../qatzstd/compressor/source/config.cc | 22 +++-------- .../qatzstd/compressor/source/config.h | 3 +- .../source/qatzstd_compressor_impl.cc | 14 ++++--- .../source/qatzstd_compressor_impl.h | 11 +----- .../test/qatzstd_compressor_impl_test.cc | 38 ------------------- source/common/compression/zstd/common/BUILD | 11 ------ .../common/compression/zstd/compressor/BUILD | 1 - .../compressor/zstd_compressor_impl_base.cc | 14 +------ .../compressor/zstd_compressor_impl_base.h | 8 +--- .../extensions/compression/zstd/common/BUILD | 23 +++++++++++ .../zstd/common/dictionary_manager.h | 2 + .../compression/zstd/compressor/BUILD | 2 +- .../zstd/compressor/zstd_compressor_impl.cc | 15 ++++++++ .../zstd/compressor/zstd_compressor_impl.h | 11 +++--- .../compression/zstd/decompressor/BUILD | 2 +- .../decompressor/zstd_decompressor_impl.h | 5 +-- 19 files changed, 70 insertions(+), 124 deletions(-) create mode 100644 source/extensions/compression/zstd/common/BUILD rename source/{common => extensions}/compression/zstd/common/dictionary_manager.h (98%) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD index 09a37ad16b83..b514f18ab81a 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD @@ -6,7 +6,6 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ - "//envoy/config/core/v3:pkg", "@com_github_cncf_xds//udpa/annotations:pkg", ], ) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index 7f73141c2c85..19eec9aa2b0c 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package envoy.extensions.compression.qatzstd.compressor.v3alpha; -import "envoy/config/core/v3/base.proto"; - import "google/protobuf/wrappers.proto"; import "udpa/annotations/status.proto"; @@ -53,13 +51,6 @@ message Qatzstd { // Special: value 0 means "use default strategy". Strategy strategy = 3 [(validate.rules).enum = {defined_only: true}]; - // A dictionary for compression. Zstd offers dictionary compression, which greatly improves - // efficiency on small files and messages. Each dictionary will be generated with a dictionary ID - // that can be used to search the same dictionary during decompression. - // Please refer to `zstd manual `_ - // to train a specific dictionary for compression. - config.core.v3.DataSource dictionary = 4; - // Value for compressor's next output buffer. If not set, defaults to 4096. google.protobuf.UInt32Value chunk_size = 5 [(validate.rules).uint32 = {lte: 65536 gte: 4096}]; diff --git a/contrib/qat/compression/qatzstd/compressor/source/BUILD b/contrib/qat/compression/qatzstd/compressor/source/BUILD index 2d849049de21..1526a7b6de20 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/BUILD +++ b/contrib/qat/compression/qatzstd/compressor/source/BUILD @@ -38,9 +38,9 @@ envoy_cc_library( deps = [ ":qat-zstd", "//envoy/compression/compressor:compressor_interface", + "//envoy/server:factory_context_interface", "//source/common/buffer:buffer_lib", "//source/common/compression/zstd/common:zstd_base_lib", - "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", "//source/common/compression/zstd/compressor:compressor_base", ], ) diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.cc b/contrib/qat/compression/qatzstd/compressor/source/config.cc index 778ec97ffcc6..3c23295b6324 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/config.cc @@ -8,7 +8,7 @@ namespace Compressor { QatzstdCompressorFactory::QatzstdCompressorFactory( const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& qatzstd, - Event::Dispatcher& dispatcher, Api::Api& api, ThreadLocal::SlotAllocator& tls) + ThreadLocal::SlotAllocator& tls) : compression_level_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(qatzstd, compression_level, ZSTD_CLEVEL_DEFAULT)), enable_checksum_(qatzstd.enable_checksum()), strategy_(qatzstd.strategy()), @@ -17,15 +17,6 @@ QatzstdCompressorFactory::QatzstdCompressorFactory( qat_zstd_fallback_threshold_(PROTOBUF_GET_WRAPPED_OR_DEFAULT( qatzstd, qat_zstd_fallback_threshold, DefaultQatZstdFallbackThreshold)), tls_slot_(nullptr) { - if (qatzstd.has_dictionary()) { - Protobuf::RepeatedPtrField dictionaries; - dictionaries.Add()->CopyFrom(qatzstd.dictionary()); - cdict_manager_ = std::make_unique( - dictionaries, dispatcher, api, tls, true, - [this](const void* dict_buffer, size_t dict_size) -> ZSTD_CDict* { - return ZSTD_createCDict(dict_buffer, dict_size, compression_level_); - }); - } if (enable_qat_zstd_) { tls_slot_ = ThreadLocal::TypedSlot::makeUnique(tls); tls_slot_->set([](Event::Dispatcher&) { return std::make_shared(); }); @@ -66,11 +57,11 @@ void* QatzstdCompressorFactory::QatzstdThreadLocal::GetQATSession() { Envoy::Compression::Compressor::CompressorPtr QatzstdCompressorFactory::createCompressor() { if (enable_qat_zstd_) { return std::make_unique( - compression_level_, enable_checksum_, strategy_, cdict_manager_, chunk_size_, - enable_qat_zstd_, qat_zstd_fallback_threshold_, tls_slot_->get()->GetQATSession()); + compression_level_, enable_checksum_, strategy_, chunk_size_, enable_qat_zstd_, + qat_zstd_fallback_threshold_, tls_slot_->get()->GetQATSession()); } else { return std::make_unique(compression_level_, enable_checksum_, strategy_, - cdict_manager_, chunk_size_, enable_qat_zstd_, + chunk_size_, enable_qat_zstd_, qat_zstd_fallback_threshold_, nullptr); } } @@ -79,9 +70,8 @@ Envoy::Compression::Compressor::CompressorFactoryPtr QatzstdCompressorLibraryFactory::createCompressorFactoryFromProtoTyped( const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& proto_config, Server::Configuration::FactoryContext& context) { - return std::make_unique( - proto_config, context.serverFactoryContext().mainThreadDispatcher(), - context.serverFactoryContext().api(), context.serverFactoryContext().threadLocal()); + return std::make_unique(proto_config, + context.serverFactoryContext().threadLocal()); } /** diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.h b/contrib/qat/compression/qatzstd/compressor/source/config.h index d7ca98cc027e..8e78cd8123be 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.h +++ b/contrib/qat/compression/qatzstd/compressor/source/config.h @@ -35,7 +35,7 @@ class QatzstdCompressorFactory : public Envoy::Compression::Compressor::Compress public: QatzstdCompressorFactory( const envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd& qatzstd, - Event::Dispatcher& dispatcher, Api::Api& api, ThreadLocal::SlotAllocator& tls); + ThreadLocal::SlotAllocator& tls); // Envoy::Compression::Compressor::CompressorFactory Envoy::Compression::Compressor::CompressorPtr createCompressor() override; @@ -57,7 +57,6 @@ class QatzstdCompressorFactory : public Envoy::Compression::Compressor::Compress const bool enable_checksum_; const uint32_t strategy_; const uint32_t chunk_size_; - ZstdCDictManagerPtr cdict_manager_{nullptr}; const bool enable_qat_zstd_; const uint32_t qat_zstd_fallback_threshold_; ThreadLocal::TypedSlotPtr tls_slot_; diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc index 778fa857e24b..7f5971a24667 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc @@ -7,17 +7,19 @@ namespace Qatzstd { namespace Compressor { QatzstdCompressorImpl::QatzstdCompressorImpl(uint32_t compression_level, bool enable_checksum, - uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, - uint32_t chunk_size, bool enable_qat_zstd, + uint32_t strategy, uint32_t chunk_size, + bool enable_qat_zstd, uint32_t qat_zstd_fallback_threshold, void* sequenceProducerState) - : ZstdCompressorImplBase(compression_level, enable_checksum, strategy, cdict_manager, - chunk_size), + : ZstdCompressorImplBase(compression_level, enable_checksum, strategy, chunk_size), enable_qat_zstd_(enable_qat_zstd), qat_zstd_fallback_threshold_(qat_zstd_fallback_threshold), sequenceProducerState_(sequenceProducerState), input_ptr_{std::make_unique( chunk_size)}, input_len_(0), chunk_size_(chunk_size) { + size_t result; + result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_compressionLevel, compression_level_); + RELEASE_ASSERT(!ZSTD_isError(result), ""); + ENVOY_LOG(debug, "zstd new ZstdCompressorImpl, compression_level: {}, strategy: {}, chunk_size: " "{}, enable_qat_zstd: {}, qat_zstd_fallback_threshold: {}", @@ -25,7 +27,7 @@ QatzstdCompressorImpl::QatzstdCompressorImpl(uint32_t compression_level, bool en if (enable_qat_zstd_) { /* register qatSequenceProducer */ ZSTD_registerSequenceProducer(cctx_.get(), sequenceProducerState_, qatSequenceProducer); - size_t result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_enableSeqProducerFallback, 1); + result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_enableSeqProducerFallback, 1); RELEASE_ASSERT(!ZSTD_isError(result), ""); } } diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h index f5cd356d65b1..1960b13b7671 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.h @@ -5,7 +5,6 @@ #include "source/common/common/logger.h" #include "source/common/compression/zstd/common/base.h" -#include "source/common/compression/zstd/common/dictionary_manager.h" #include "source/common/compression/zstd/compressor/zstd_compressor_impl_base.h" #include "qatseqprod.h" @@ -16,11 +15,6 @@ namespace Compression { namespace Qatzstd { namespace Compressor { -using ZstdCDictManager = - Envoy::Compression::Zstd::Common::DictionaryManager; -using ZstdCDictManagerPtr = std::unique_ptr; - /** * Implementation of compressor's interface. */ @@ -28,9 +22,8 @@ class QatzstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdC public Logger::Loggable { public: QatzstdCompressorImpl(uint32_t compression_level, bool enable_checksum, uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size, - bool enable_qat_zstd, uint32_t qat_zstd_fallback_threshold, - void* sequenceProducerState); + uint32_t chunk_size, bool enable_qat_zstd, + uint32_t qat_zstd_fallback_threshold, void* sequenceProducerState); private: void compressPreprocess(Buffer::Instance& buffer, diff --git a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc index 32d582225f9e..2898ac4c055a 100644 --- a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc +++ b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc @@ -65,7 +65,6 @@ class QatzstdCompressorImplTest : public testing::Test { static constexpr uint32_t default_strategy_{0}; uint32_t default_input_size_{796}; uint32_t default_input_round_{10}; - ZstdCDictManagerPtr default_cdict_manager_{nullptr}; Zstd::Decompressor::ZstdDDictManagerPtr default_ddict_manager_{nullptr}; bool enable_qat_zstd{true}; uint32_t qat_zstd_fallback_threshold{0}; @@ -109,43 +108,6 @@ TEST_P(QatzstdConfigTest, LoadConfigAndVerifyWithDecompressor) { verifyWithDecompressor(qatzstd_compressor_factory->createCompressor()); } -TEST_F(QatzstdCompressorImplTest, IllegalConfig) { - envoy::extensions::compression::qatzstd::compressor::v3alpha::Qatzstd qatzstd; - Qatzstd::Compressor::QatzstdCompressorLibraryFactory lib_factory; - NiceMock mock_context; - std::string json; - - json = R"EOF({ - "compression_level": 7, - "enable_checksum": true, - "strategy":"default", - "chunk_size": 4096, - "dictionary": { - "inline_string": "" - }, - enable_qat_zstd: true, - qat_zstd_fallback_threshold: 1024, -})EOF"; - TestUtility::loadFromJson(json, qatzstd); - EXPECT_THROW_WITH_MESSAGE(lib_factory.createCompressorFactoryFromProto(qatzstd, mock_context), - EnvoyException, "DataSource cannot be empty"); - - json = R"EOF({ - "compression_level": 7, - "enable_checksum": true, - "strategy":"default", - "chunk_size": 4096, - "dictionary": { - "inline_string": "123321123" - }, - enable_qat_zstd: true, - qat_zstd_fallback_threshold: 1024, -})EOF"; - TestUtility::loadFromJson(json, qatzstd); - EXPECT_DEATH({ lib_factory.createCompressorFactoryFromProto(qatzstd, mock_context); }, - "assert failure: id != 0. Details: Illegal Zstd dictionary"); -} - } // namespace } // namespace Compressor } // namespace Qatzstd diff --git a/source/common/compression/zstd/common/BUILD b/source/common/compression/zstd/common/BUILD index b1b33c002112..e9ecaa5338b2 100644 --- a/source/common/compression/zstd/common/BUILD +++ b/source/common/compression/zstd/common/BUILD @@ -17,14 +17,3 @@ envoy_cc_library( "//source/common/buffer:buffer_lib", ], ) - -envoy_cc_library( - name = "zstd_dictionary_manager_lib", - hdrs = ["dictionary_manager.h"], - external_deps = ["zstd"], - deps = [ - "//envoy/event:dispatcher_interface", - "//envoy/thread_local:thread_local_interface", - "//source/common/config:datasource_lib", - ], -) diff --git a/source/common/compression/zstd/compressor/BUILD b/source/common/compression/zstd/compressor/BUILD index 75d11f2d5f55..16a3fbe97f1e 100644 --- a/source/common/compression/zstd/compressor/BUILD +++ b/source/common/compression/zstd/compressor/BUILD @@ -16,6 +16,5 @@ envoy_cc_library( "//envoy/compression/compressor:compressor_interface", "//source/common/buffer:buffer_lib", "//source/common/compression/zstd/common:zstd_base_lib", - "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", ], ) diff --git a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc index af5e87f4fab8..2a04f72b83c0 100644 --- a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc +++ b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.cc @@ -8,25 +8,15 @@ namespace Zstd { namespace Compressor { ZstdCompressorImplBase::ZstdCompressorImplBase(uint32_t compression_level, bool enable_checksum, - uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, - uint32_t chunk_size) + uint32_t strategy, uint32_t chunk_size) : Common::Base(chunk_size), cctx_(ZSTD_createCCtx(), &ZSTD_freeCCtx), - cdict_manager_(cdict_manager), compression_level_(compression_level) { + compression_level_(compression_level) { size_t result; result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_checksumFlag, enable_checksum); RELEASE_ASSERT(!ZSTD_isError(result), ""); result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_strategy, strategy); RELEASE_ASSERT(!ZSTD_isError(result), ""); - - if (cdict_manager_) { - ZSTD_CDict* cdict = cdict_manager_->getFirstDictionary(); - result = ZSTD_CCtx_refCDict(cctx_.get(), cdict); - } else { - result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_compressionLevel, compression_level_); - } - RELEASE_ASSERT(!ZSTD_isError(result), ""); } void ZstdCompressorImplBase::compress(Buffer::Instance& buffer, diff --git a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h index 5da65ac4257c..2a07b0a87e99 100644 --- a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h +++ b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h @@ -3,17 +3,12 @@ #include "envoy/compression/compressor/compressor.h" #include "source/common/compression/zstd/common/base.h" -#include "source/common/compression/zstd/common/dictionary_manager.h" namespace Envoy { namespace Compression { namespace Zstd { namespace Compressor { -using ZstdCDictManager = - Common::DictionaryManager; -using ZstdCDictManagerPtr = std::unique_ptr; - /** * Implementation of compressor's interface. */ @@ -22,7 +17,7 @@ class ZstdCompressorImplBase : public Common::Base, NonCopyable { public: ZstdCompressorImplBase(uint32_t compression_level, bool enable_checksum, uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size); + uint32_t chunk_size); // Compression::Compressor::Compressor void compress(Buffer::Instance& buffer, Envoy::Compression::Compressor::State state) override; @@ -38,7 +33,6 @@ class ZstdCompressorImplBase : public Common::Base, virtual void compressPostprocess(Buffer::Instance& accumulation_buffer) PURE; std::unique_ptr cctx_; - const ZstdCDictManagerPtr& cdict_manager_; const uint32_t compression_level_; }; diff --git a/source/extensions/compression/zstd/common/BUILD b/source/extensions/compression/zstd/common/BUILD new file mode 100644 index 000000000000..bf5e80d0a535 --- /dev/null +++ b/source/extensions/compression/zstd/common/BUILD @@ -0,0 +1,23 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_library", + "envoy_extension_package", + "envoy_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_package() + +envoy_cc_library( + name = "zstd_dictionary_manager_lib", + hdrs = ["dictionary_manager.h"], + external_deps = ["zstd"], + deps = [ + "//envoy/event:dispatcher_interface", + "//envoy/thread_local:thread_local_interface", + "//source/common/config:datasource_lib", + ], +) diff --git a/source/common/compression/zstd/common/dictionary_manager.h b/source/extensions/compression/zstd/common/dictionary_manager.h similarity index 98% rename from source/common/compression/zstd/common/dictionary_manager.h rename to source/extensions/compression/zstd/common/dictionary_manager.h index 832870187f30..45501345e5ec 100644 --- a/source/common/compression/zstd/common/dictionary_manager.h +++ b/source/extensions/compression/zstd/common/dictionary_manager.h @@ -10,6 +10,7 @@ #include "zstd.h" namespace Envoy { +namespace Extensions { namespace Compression { namespace Zstd { namespace Common { @@ -119,4 +120,5 @@ template class } // namespace Common } // namespace Zstd } // namespace Compression +} // namespace Extensions } // namespace Envoy diff --git a/source/extensions/compression/zstd/compressor/BUILD b/source/extensions/compression/zstd/compressor/BUILD index fe53d6a123f0..76c3343a3202 100644 --- a/source/extensions/compression/zstd/compressor/BUILD +++ b/source/extensions/compression/zstd/compressor/BUILD @@ -17,8 +17,8 @@ envoy_cc_library( "//envoy/compression/compressor:compressor_interface", "//source/common/buffer:buffer_lib", "//source/common/compression/zstd/common:zstd_base_lib", - "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", "//source/common/compression/zstd/compressor:compressor_base", + "//source/extensions/compression/zstd/common:zstd_dictionary_manager_lib", ], ) diff --git a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc index fedfb736d9d0..55ece012d086 100644 --- a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc +++ b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.cc @@ -6,6 +6,21 @@ namespace Compression { namespace Zstd { namespace Compressor { +ZstdCompressorImpl::ZstdCompressorImpl(uint32_t compression_level, bool enable_checksum, + uint32_t strategy, const ZstdCDictManagerPtr& cdict_manager, + uint32_t chunk_size) + : ZstdCompressorImplBase(compression_level, enable_checksum, strategy, chunk_size), + cdict_manager_(cdict_manager) { + size_t result; + if (cdict_manager_) { + ZSTD_CDict* cdict = cdict_manager_->getFirstDictionary(); + result = ZSTD_CCtx_refCDict(cctx_.get(), cdict); + } else { + result = ZSTD_CCtx_setParameter(cctx_.get(), ZSTD_c_compressionLevel, compression_level_); + } + RELEASE_ASSERT(!ZSTD_isError(result), ""); +} + void ZstdCompressorImpl::compressPreprocess(Buffer::Instance&, Envoy::Compression::Compressor::State) {} diff --git a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h index dd5b9f676937..95da3d1a8e12 100644 --- a/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h +++ b/source/extensions/compression/zstd/compressor/zstd_compressor_impl.h @@ -3,8 +3,8 @@ #include "envoy/compression/compressor/compressor.h" #include "source/common/compression/zstd/common/base.h" -#include "source/common/compression/zstd/common/dictionary_manager.h" #include "source/common/compression/zstd/compressor/zstd_compressor_impl_base.h" +#include "source/extensions/compression/zstd/common/dictionary_manager.h" namespace Envoy { namespace Extensions { @@ -13,8 +13,7 @@ namespace Zstd { namespace Compressor { using ZstdCDictManager = - Envoy::Compression::Zstd::Common::DictionaryManager; + Common::DictionaryManager; using ZstdCDictManagerPtr = std::unique_ptr; /** @@ -23,9 +22,7 @@ using ZstdCDictManagerPtr = std::unique_ptr; class ZstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdCompressorImplBase { public: ZstdCompressorImpl(uint32_t compression_level, bool enable_checksum, uint32_t strategy, - const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size) - : ZstdCompressorImplBase(compression_level, enable_checksum, strategy, cdict_manager, - chunk_size) {} + const ZstdCDictManagerPtr& cdict_manager, uint32_t chunk_size); private: void compressPreprocess(Buffer::Instance& buffer, @@ -35,6 +32,8 @@ class ZstdCompressorImpl : public Envoy::Compression::Zstd::Compressor::ZstdComp Buffer::Instance& accumulation_buffer) override; void compressPostprocess(Buffer::Instance& accumulation_buffer) override; + + const ZstdCDictManagerPtr& cdict_manager_; }; } // namespace Compressor diff --git a/source/extensions/compression/zstd/decompressor/BUILD b/source/extensions/compression/zstd/decompressor/BUILD index a0f56116492a..361a3b866f23 100644 --- a/source/extensions/compression/zstd/decompressor/BUILD +++ b/source/extensions/compression/zstd/decompressor/BUILD @@ -19,7 +19,7 @@ envoy_cc_library( "//envoy/stats:stats_macros", "//source/common/buffer:buffer_lib", "//source/common/compression/zstd/common:zstd_base_lib", - "//source/common/compression/zstd/common:zstd_dictionary_manager_lib", + "//source/extensions/compression/zstd/common:zstd_dictionary_manager_lib", ], ) diff --git a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h index e738575f494b..5f7ed470e3e4 100644 --- a/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h +++ b/source/extensions/compression/zstd/decompressor/zstd_decompressor_impl.h @@ -6,7 +6,7 @@ #include "source/common/common/logger.h" #include "source/common/compression/zstd/common/base.h" -#include "source/common/compression/zstd/common/dictionary_manager.h" +#include "source/extensions/compression/zstd/common/dictionary_manager.h" #include "zstd_errors.h" @@ -17,8 +17,7 @@ namespace Zstd { namespace Decompressor { using ZstdDDictManager = - Envoy::Compression::Zstd::Common::DictionaryManager; + Common::DictionaryManager; using ZstdDDictManagerPtr = std::unique_ptr; /** From 208120f05a1f9b3f2d0ef5d6d0fed33a22623529 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Tue, 20 Feb 2024 20:00:07 -0800 Subject: [PATCH 12/26] fix BUILD Signed-off-by: giantcroc --- source/extensions/compression/zstd/common/BUILD | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/extensions/compression/zstd/common/BUILD b/source/extensions/compression/zstd/common/BUILD index bf5e80d0a535..a0aa94556434 100644 --- a/source/extensions/compression/zstd/common/BUILD +++ b/source/extensions/compression/zstd/common/BUILD @@ -2,15 +2,12 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_library", "envoy_extension_package", - "envoy_package", ) licenses(["notice"]) # Apache 2 envoy_extension_package() -envoy_package() - envoy_cc_library( name = "zstd_dictionary_manager_lib", hdrs = ["dictionary_manager.h"], From 62360bf4984c3964a890571105ccb67b0f37edc9 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Tue, 20 Feb 2024 21:43:08 -0800 Subject: [PATCH 13/26] fix proto format Signed-off-by: giantcroc --- .../extensions/compression/qatzstd/compressor/v3alpha/BUILD | 4 +--- .../compression/qatzstd/compressor/v3alpha/qatzstd.proto | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD index b514f18ab81a..29ebf0741406 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/BUILD @@ -5,7 +5,5 @@ load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") licenses(["notice"]) # Apache 2 api_proto_package( - deps = [ - "@com_github_cncf_xds//udpa/annotations:pkg", - ], + deps = ["@com_github_cncf_xds//udpa/annotations:pkg"], ) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index 19eec9aa2b0c..ae66e873c018 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -54,11 +54,11 @@ message Qatzstd { // Value for compressor's next output buffer. If not set, defaults to 4096. google.protobuf.UInt32Value chunk_size = 5 [(validate.rules).uint32 = {lte: 65536 gte: 4096}]; - // Enable QAT to accelerate zstd compression or not. If not set, defaults to false. bool enable_qat_zstd = 6; // Fallback to software for qatzstd when input size is less than this value. // Valid only enable_qat_zstd is true. 0 means no fallback at all. If not set, defaults to 4000. - google.protobuf.UInt32Value qat_zstd_fallback_threshold = 7 [(validate.rules).uint32 = {lte: 65536 gte: 0}]; + google.protobuf.UInt32Value qat_zstd_fallback_threshold = 7 + [(validate.rules).uint32 = {lte: 65536 gte: 0}]; } From ae60cf0f80a1ef5918a5570f1f4a76f90085e7ce Mon Sep 17 00:00:00 2001 From: giantcroc Date: Wed, 21 Feb 2024 19:08:05 -0800 Subject: [PATCH 14/26] fix docs Signed-off-by: giantcroc --- docs/root/configuration/other_features/qatzstd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/root/configuration/other_features/qatzstd.rst b/docs/root/configuration/other_features/qatzstd.rst index 2e965e6a3dd8..e963c862e6d7 100644 --- a/docs/root/configuration/other_features/qatzstd.rst +++ b/docs/root/configuration/other_features/qatzstd.rst @@ -29,6 +29,6 @@ When new http package come, one worker thread will process it using its Qatzstd Qat hardware using standard zstd api. Installing and using QAT-ZSTD-Plugin ------------------------- +------------------------------------ For information on how to build/install and use QAT-ZSTD-Plugin see `introduction `_. From ec41a54e6f3bf84ab866bf6c127365721451816b Mon Sep 17 00:00:00 2001 From: giantcroc Date: Wed, 21 Feb 2024 20:03:48 -0800 Subject: [PATCH 15/26] fix clang build Signed-off-by: giantcroc --- contrib/qat/compression/qatzstd/compressor/source/BUILD | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contrib/qat/compression/qatzstd/compressor/source/BUILD b/contrib/qat/compression/qatzstd/compressor/source/BUILD index 1526a7b6de20..ba262593ba75 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/BUILD +++ b/contrib/qat/compression/qatzstd/compressor/source/BUILD @@ -13,6 +13,12 @@ envoy_contrib_package() make( name = "qat-zstd", build_data = ["@com_github_qat_zstd//:all"], + env = select({ + "//bazel:clang_build": { + "CFLAGS": "-Wno-error=newline-eof -Wno-error=strict-prototypes -Wno-error=unused-but-set-variable", + }, + "//conditions:default": {}, + }), includes = [], lib_source = "@com_github_qat_zstd//:all", out_static_libs = ["libqatseqprod.a"], From d09331d751e6ab354ca42284ddb22fdb21c4da54 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Wed, 21 Feb 2024 21:53:23 -0800 Subject: [PATCH 16/26] fix unused parameter Signed-off-by: giantcroc --- contrib/qat/compression/qatzstd/compressor/source/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/qat/compression/qatzstd/compressor/source/BUILD b/contrib/qat/compression/qatzstd/compressor/source/BUILD index ba262593ba75..359978bc3b19 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/BUILD +++ b/contrib/qat/compression/qatzstd/compressor/source/BUILD @@ -15,7 +15,7 @@ make( build_data = ["@com_github_qat_zstd//:all"], env = select({ "//bazel:clang_build": { - "CFLAGS": "-Wno-error=newline-eof -Wno-error=strict-prototypes -Wno-error=unused-but-set-variable", + "CFLAGS": "-Wno-error=unused-parameter", }, "//conditions:default": {}, }), From ca18c5cf3363b7622b23fb8661593b00ddc7f7da Mon Sep 17 00:00:00 2001 From: giantcroc Date: Thu, 22 Feb 2024 22:18:16 -0800 Subject: [PATCH 17/26] remove unused vars Signed-off-by: giantcroc --- .../qatzstd/compressor/test/qatzstd_compressor_impl_test.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc index 2898ac4c055a..c726d55dbe57 100644 --- a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc +++ b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc @@ -60,14 +60,8 @@ class QatzstdCompressorImplTest : public testing::Test { context_); } - static constexpr uint32_t default_compression_level_{6}; - static constexpr uint32_t default_enable_checksum_{0}; - static constexpr uint32_t default_strategy_{0}; uint32_t default_input_size_{796}; - uint32_t default_input_round_{10}; Zstd::Decompressor::ZstdDDictManagerPtr default_ddict_manager_{nullptr}; - bool enable_qat_zstd{true}; - uint32_t qat_zstd_fallback_threshold{0}; QatzstdCompressorLibraryFactory qatzstd_compressor_library_factory_; NiceMock context_; }; From d6444cbe8aa8001988e848d83a8769404d57779b Mon Sep 17 00:00:00 2001 From: giantcroc Date: Sun, 25 Feb 2024 22:18:53 -0800 Subject: [PATCH 18/26] use operator instead if Signed-off-by: giantcroc --- .../compression/qatzstd/compressor/source/config.cc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/contrib/qat/compression/qatzstd/compressor/source/config.cc b/contrib/qat/compression/qatzstd/compressor/source/config.cc index 3c23295b6324..67a24d530d1b 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/config.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/config.cc @@ -55,15 +55,9 @@ void* QatzstdCompressorFactory::QatzstdThreadLocal::GetQATSession() { } Envoy::Compression::Compressor::CompressorPtr QatzstdCompressorFactory::createCompressor() { - if (enable_qat_zstd_) { - return std::make_unique( - compression_level_, enable_checksum_, strategy_, chunk_size_, enable_qat_zstd_, - qat_zstd_fallback_threshold_, tls_slot_->get()->GetQATSession()); - } else { - return std::make_unique(compression_level_, enable_checksum_, strategy_, - chunk_size_, enable_qat_zstd_, - qat_zstd_fallback_threshold_, nullptr); - } + return std::make_unique( + compression_level_, enable_checksum_, strategy_, chunk_size_, enable_qat_zstd_, + qat_zstd_fallback_threshold_, enable_qat_zstd_ ? tls_slot_->get()->GetQATSession() : nullptr); } Envoy::Compression::Compressor::CompressorFactoryPtr From f1df34c8ef3e60cfcb3adee2023e49e1dd8bb815 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Mon, 26 Feb 2024 23:20:31 -0800 Subject: [PATCH 19/26] use protected Signed-off-by: giantcroc --- .../compression/zstd/compressor/zstd_compressor_impl_base.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h index 2a07b0a87e99..954b3aa17f9a 100644 --- a/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h +++ b/source/common/compression/zstd/compressor/zstd_compressor_impl_base.h @@ -24,6 +24,7 @@ class ZstdCompressorImplBase : public Common::Base, void process(Buffer::Instance& output_buffer, ZSTD_EndDirective mode); +protected: virtual void compressPreprocess(Buffer::Instance& buffer, Envoy::Compression::Compressor::State state) PURE; From ce642f2ea2dd619bed01e7b35e05d45710adff92 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Tue, 27 Feb 2024 00:11:07 -0800 Subject: [PATCH 20/26] fix comments Signed-off-by: giantcroc --- .../compression/qatzstd/compressor/v3alpha/qatzstd.proto | 7 ++++--- changelogs/current.yaml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index ae66e873c018..0f74fd0f46e1 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -37,6 +37,7 @@ message Qatzstd { // Note that exact compression parameters are dynamically determined, // depending on both compression level and source content size (when known). // Value 0 means default, and default level is 3. + // // Setting a level does not automatically set all other compression parameters // to default. Setting this will however eventually dynamically impact the compression // parameters which have not been manually set. The manually set @@ -54,11 +55,11 @@ message Qatzstd { // Value for compressor's next output buffer. If not set, defaults to 4096. google.protobuf.UInt32Value chunk_size = 5 [(validate.rules).uint32 = {lte: 65536 gte: 4096}]; - // Enable QAT to accelerate zstd compression or not. If not set, defaults to false. + // Enable QAT to accelerate Zstd compression or not. If not set, defaults to false. bool enable_qat_zstd = 6; - // Fallback to software for qatzstd when input size is less than this value. - // Valid only enable_qat_zstd is true. 0 means no fallback at all. If not set, defaults to 4000. + // Fallback to software for Qatzstd when input size is less than this value. + // Valid only ``enable_qat_zstd`` is ``true``. 0 means no fallback at all. If not set, defaults to 4000. google.protobuf.UInt32Value qat_zstd_fallback_threshold = 7 [(validate.rules).uint32 = {lte: 65536 gte: 0}]; } diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 3a6300851b51..eef884031285 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -174,7 +174,7 @@ new_features: identifier. - area: compression change: | - Added qatzstd :ref:`compressor `. + Added Qatzstd :ref:`compressor `. - area: aws_lambda change: | Added :ref:`host_rewrite ` config to be used From d48a251f30d63f7344fd6b9972abc671e668f08b Mon Sep 17 00:00:00 2001 From: giantcroc Date: Wed, 28 Feb 2024 21:53:52 -0800 Subject: [PATCH 21/26] add more api comments Signed-off-by: giantcroc --- .../compression/qatzstd/compressor/v3alpha/qatzstd.proto | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index 0f74fd0f46e1..64d47050dcdb 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -42,13 +42,14 @@ message Qatzstd { // to default. Setting this will however eventually dynamically impact the compression // parameters which have not been manually set. The manually set // ones will 'stick'. - google.protobuf.UInt32Value compression_level = 1; + google.protobuf.UInt32Value compression_level = 1 [(validate.rules).uint32 = {lte: 22 gte: 1}]; // A 32-bits checksum of content is written at end of frame. If not set, defaults to false. bool enable_checksum = 2; // The higher the value of selected strategy, the more complex it is, // resulting in stronger and slower compression. + // // Special: value 0 means "use default strategy". Strategy strategy = 3 [(validate.rules).enum = {defined_only: true}]; @@ -56,6 +57,9 @@ message Qatzstd { google.protobuf.UInt32Value chunk_size = 5 [(validate.rules).uint32 = {lte: 65536 gte: 4096}]; // Enable QAT to accelerate Zstd compression or not. If not set, defaults to false. + // + // This is useful in the case that users want to enable QAT for a period of time and disable QAT for another period of time, + // they don't have to change the config too much or prepare for another config that has software zstd compressor and just changing the value of this filed. bool enable_qat_zstd = 6; // Fallback to software for Qatzstd when input size is less than this value. From 8586ad203b75295621d2a398356c2b8e118efaab Mon Sep 17 00:00:00 2001 From: giantcroc Date: Wed, 28 Feb 2024 23:13:53 -0800 Subject: [PATCH 22/26] fix proto format Signed-off-by: giantcroc --- .../compression/qatzstd/compressor/v3alpha/qatzstd.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto index 64d47050dcdb..182722d01e4f 100644 --- a/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto +++ b/api/contrib/envoy/extensions/compression/qatzstd/compressor/v3alpha/qatzstd.proto @@ -58,7 +58,7 @@ message Qatzstd { // Enable QAT to accelerate Zstd compression or not. If not set, defaults to false. // - // This is useful in the case that users want to enable QAT for a period of time and disable QAT for another period of time, + // This is useful in the case that users want to enable QAT for a period of time and disable QAT for another period of time, // they don't have to change the config too much or prepare for another config that has software zstd compressor and just changing the value of this filed. bool enable_qat_zstd = 6; From 895c54e9fd9a664cc140b4e0fdf2fd21777558e9 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Mon, 4 Mar 2024 22:21:46 -0800 Subject: [PATCH 23/26] test multi-slices Signed-off-by: giantcroc --- .../qatzstd/compressor/source/qatzstd_compressor_impl.cc | 6 +++++- .../qatzstd/compressor/test/qatzstd_compressor_impl_test.cc | 4 ++-- test/test_common/utility.cc | 6 ++++-- test/test_common/utility.h | 3 ++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc index 7f5971a24667..7b1cb85a8aae 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc +++ b/contrib/qat/compression/qatzstd/compressor/source/qatzstd_compressor_impl.cc @@ -54,7 +54,11 @@ void QatzstdCompressorImpl::setInput(const uint8_t* input, size_t size) { void QatzstdCompressorImpl::compressProcess(const Buffer::Instance& buffer, const Buffer::RawSlice& slice, Buffer::Instance& accumulation_buffer) { - if (slice.len_ == buffer.length()) { + if (slice.len_ == buffer.length() || slice.len_ > chunk_size_) { + if (input_len_ > 0) { + setInput(input_ptr_.get(), input_len_); + process(accumulation_buffer, ZSTD_e_continue); + } setInput(static_cast(slice.mem_), slice.len_); process(accumulation_buffer, ZSTD_e_continue); } else { diff --git a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc index c726d55dbe57..257a23061ed2 100644 --- a/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc +++ b/contrib/qat/compression/qatzstd/compressor/test/qatzstd_compressor_impl_test.cc @@ -28,9 +28,9 @@ class QatzstdCompressorImplTest : public testing::Test { Buffer::OwnedImpl accumulation_buffer; std::string original_text{}; for (uint64_t i = 0; i < 10; i++) { - TestUtility::feedBufferWithRandomCharacters(buffer, default_input_size_ * i, i); + TestUtility::feedBufferWithRandomCharacters(buffer, default_input_size_ * i, i, i); original_text.append(buffer.toString()); - ASSERT_EQ(default_input_size_ * i, buffer.length()); + ASSERT_EQ(default_input_size_ * i * i, buffer.length()); compressor->compress(buffer, Envoy::Compression::Compressor::State::Flush); accumulation_buffer.add(buffer); drainBuffer(buffer); diff --git a/test/test_common/utility.cc b/test/test_common/utility.cc index 7f40c6e3efd3..a8650f0147ed 100644 --- a/test/test_common/utility.cc +++ b/test/test_common/utility.cc @@ -130,7 +130,7 @@ bool TestUtility::rawSlicesEqual(const Buffer::RawSlice* lhs, const Buffer::RawS } void TestUtility::feedBufferWithRandomCharacters(Buffer::Instance& buffer, uint64_t n_char, - uint64_t seed) { + uint64_t n_slice, uint64_t seed) { const std::string sample = "Neque porro quisquam est qui dolorem ipsum.."; std::mt19937 generate(seed); std::uniform_int_distribution<> distribute(1, sample.length() - 1); @@ -138,7 +138,9 @@ void TestUtility::feedBufferWithRandomCharacters(Buffer::Instance& buffer, uint6 for (uint64_t n = 0; n < n_char; ++n) { str += sample.at(distribute(generate)); } - buffer.add(str); + for (uint64_t n = 0; n < n_slice; ++n) { + buffer.add(str); + } } Stats::CounterSharedPtr TestUtility::findCounter(Stats::Store& store, const std::string& name) { diff --git a/test/test_common/utility.h b/test/test_common/utility.h index c365450e83a4..c14a4d3137b2 100644 --- a/test/test_common/utility.h +++ b/test/test_common/utility.h @@ -177,10 +177,11 @@ class TestUtility { * Feed a buffer with random characters. * @param buffer supplies the buffer to be fed. * @param n_char number of characters that should be added to the supplied buffer. + * @param n_slice number of slices (default = 1). * @param seed seeds pseudo-random number generator (default = 0). */ static void feedBufferWithRandomCharacters(Buffer::Instance& buffer, uint64_t n_char, - uint64_t seed = 0); + uint64_t n_slice = 1, uint64_t seed = 0); /** * Finds a stat in a vector with the given name. From dba5d95a1cdbbdd9aa1d53653183f4f3a39df1a8 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Mon, 4 Mar 2024 22:46:33 -0800 Subject: [PATCH 24/26] fix test Signed-off-by: giantcroc --- test/test_common/utility.cc | 2 +- test/test_common/utility.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_common/utility.cc b/test/test_common/utility.cc index a8650f0147ed..8b1843373671 100644 --- a/test/test_common/utility.cc +++ b/test/test_common/utility.cc @@ -130,7 +130,7 @@ bool TestUtility::rawSlicesEqual(const Buffer::RawSlice* lhs, const Buffer::RawS } void TestUtility::feedBufferWithRandomCharacters(Buffer::Instance& buffer, uint64_t n_char, - uint64_t n_slice, uint64_t seed) { + uint64_t seed, uint64_t n_slice) { const std::string sample = "Neque porro quisquam est qui dolorem ipsum.."; std::mt19937 generate(seed); std::uniform_int_distribution<> distribute(1, sample.length() - 1); diff --git a/test/test_common/utility.h b/test/test_common/utility.h index c14a4d3137b2..77e0785ea210 100644 --- a/test/test_common/utility.h +++ b/test/test_common/utility.h @@ -177,11 +177,11 @@ class TestUtility { * Feed a buffer with random characters. * @param buffer supplies the buffer to be fed. * @param n_char number of characters that should be added to the supplied buffer. - * @param n_slice number of slices (default = 1). * @param seed seeds pseudo-random number generator (default = 0). + * @param n_slice number of slices (default = 1). */ static void feedBufferWithRandomCharacters(Buffer::Instance& buffer, uint64_t n_char, - uint64_t n_slice = 1, uint64_t seed = 0); + uint64_t seed = 0, uint64_t n_slice = 1); /** * Finds a stat in a vector with the given name. From 50ca04e378227c76c158ea968d7e08146044c8d8 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Mon, 11 Mar 2024 23:46:22 -0700 Subject: [PATCH 25/26] reduce patch size Signed-off-by: giantcroc --- bazel/foreign_cc/qatzstd.patch | 88 ++----------------- contrib/qat/BUILD | 6 +- .../qatzstd/compressor/source/BUILD | 8 +- 3 files changed, 18 insertions(+), 84 deletions(-) diff --git a/bazel/foreign_cc/qatzstd.patch b/bazel/foreign_cc/qatzstd.patch index 6cb5201b7a2b..84bd231db5e9 100644 --- a/bazel/foreign_cc/qatzstd.patch +++ b/bazel/foreign_cc/qatzstd.patch @@ -1,85 +1,13 @@ diff --git a/src/Makefile b/src/Makefile -index 1abf10d..a0c7e9a 100644 +index 1abf10d..c5fa3a6 100644 --- a/src/Makefile +++ b/src/Makefile -@@ -41,6 +41,7 @@ LIBDIR ?= $(INSTALLDIR)/lib - INCLUDEDIR ?= $(INSTALLDIR)/include - - CP ?= cp -+MKDIR ?= mkdir - - ENABLE_USDM_DRV ?= 0 - ifneq ($(ICP_ROOT), ) -@@ -55,10 +56,8 @@ ifneq ($(ICP_ROOT), ) +@@ -54,7 +54,7 @@ ifneq ($(ICP_ROOT), ) + endif else QATFLAGS = -DINTREE - LDFLAGS = -lqat -- ifneq ($(ENABLE_USDM_DRV), 0) -- QATFLAGS += -DENABLE_USDM_DRV -- LDFLAGS += -lusdm -- endif -+ QATFLAGS += -DENABLE_USDM_DRV -+ LDFLAGS += -lusdm - endif - - ifdef ZSTDLIB -@@ -69,8 +68,8 @@ CFLAGS += -Wall -Werror -Wextra -Wcast-align -Wshadow -Wstrict-aliasing=1 \ - -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes \ - -Wundef -Wpointer-arith -Wvla -Wformat=2 -Winit-self \ - -Wfloat-equal -Wwrite-strings -Wredundant-decls -Wc++-compat \ -- -pedantic -fstack-protector-strong -fPIE -fPIC \ -- -fno-delete-null-pointer-checks -fwrapv -fno-strict-overflow -+ -pedantic -fstack-protector-strong \ -+ -fno-delete-null-pointer-checks -fwrapv - - DEBUGLEVEL ?=0 - -@@ -81,27 +80,30 @@ else - QATFLAGS += -O3 - endif - -+$(info INSTALLDIR="$(INSTALLDIR)") -+$(info CPPFLAGS="$(CPPFLAGS)") -+ - qatseqprod.o: qatseqprod.c -- $(CC) -c $(CFLAGS) $(QATFLAGS) $(DEBUGFLAGS) $^ -o $@ -+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(QATFLAGS) $(DEBUGFLAGS) $^ -o $@ - - lib: qatseqprod.o - $(AR) rc libqatseqprod.a $^ -- $(CC) -shared $^ $(LDFLAGS) -o libqatseqprod.so -+ @echo qatseqprod library successfully build - - .PHONY: install - install: lib -+ $(MKDIR) -p $(LIBDIR) -+ $(MKDIR) -p $(INCLUDEDIR) - $(CP) libqatseqprod.a $(LIBDIR) -- $(CP) libqatseqprod.so $(LIBDIR) - $(CP) qatseqprod.h $(INCLUDEDIR) - @echo qatseqprod library successfully installed - - .PHONY: uninstall - uninstall: - $(RM) $(LIBDIR)/libqatseqprod.a -- $(RM) $(LIBDIR)/libqatseqprod.so - $(RM) $(INCLUDEDIR)/qatseqprod.h - @echo qatseqprod library successfully uninstalled - - clean: - $(RM) *.o -- $(RM) libqatseqprod.a libqatseqprod.so -+ $(RM) libqatseqprod.a -diff --git a/test/Makefile b/test/Makefile -index dff0c8e..4ba01b2 100644 ---- a/test/Makefile -+++ b/test/Makefile -@@ -34,7 +34,7 @@ - # ####################################################################### - LIB = ../src - --LDFLAGS = $(LIB)/libqatseqprod.a -I$(LIB) -+LDFLAGS = $(LIB)/libqatseqprod.a -I$(LIB) -L$(LIB) -l:libqatseqprod.a -l:libqat.a -l:libusdm.a -l:libzstd.a -lpthread -lcrypto - - ifneq ($(ICP_ROOT), ) - LDFLAGS += -lqat_s -lusdm_drv_s -Wl,-rpath,$(ICP_ROOT)/build -L$(ICP_ROOT)/build +- LDFLAGS = -lqat ++ LDFLAGS += -lqat + ifneq ($(ENABLE_USDM_DRV), 0) + QATFLAGS += -DENABLE_USDM_DRV + LDFLAGS += -lusdm diff --git a/contrib/qat/BUILD b/contrib/qat/BUILD index d435976e4953..08ddf04136c3 100644 --- a/contrib/qat/BUILD +++ b/contrib/qat/BUILD @@ -20,12 +20,16 @@ configure_make( configure_options = [ "--disable-fast-crc-in-assembler", "--disable-systemd", - "--disable-shared", "--with-pic", + "--enable-shared", "--enable-static", "--enable-samples=no", ], lib_source = "@com_github_intel_qatlib//:all", + out_shared_libs = [ + "libqat.so", + "libusdm.so", + ], out_static_libs = [ "libqat.a", "libusdm.a", diff --git a/contrib/qat/compression/qatzstd/compressor/source/BUILD b/contrib/qat/compression/qatzstd/compressor/source/BUILD index 359978bc3b19..960fa2b9b55e 100644 --- a/contrib/qat/compression/qatzstd/compressor/source/BUILD +++ b/contrib/qat/compression/qatzstd/compressor/source/BUILD @@ -15,9 +15,11 @@ make( build_data = ["@com_github_qat_zstd//:all"], env = select({ "//bazel:clang_build": { - "CFLAGS": "-Wno-error=unused-parameter", + "CFLAGS": "-Wno-error=unused-parameter -Wno-error=unused-command-line-argument -I$$EXT_BUILD_DEPS/qatlib/include -I$$EXT_BUILD_DEPS/zstd/include", + }, + "//conditions:default": { + "CFLAGS": "-I$$EXT_BUILD_DEPS/qatlib/include -I$$EXT_BUILD_DEPS/zstd/include", }, - "//conditions:default": {}, }), includes = [], lib_source = "@com_github_qat_zstd//:all", @@ -28,7 +30,7 @@ make( "@platforms//cpu:x86_64", ], targets = [ - "", + "ENABLE_USDM_DRV=1", "install", ], deps = [ From 23530c9e7cd6b57f6089e3bdd2e1d0248ae05f0b Mon Sep 17 00:00:00 2001 From: giantcroc Date: Sat, 16 Mar 2024 23:09:49 -0700 Subject: [PATCH 26/26] Kick CI Signed-off-by: giantcroc