From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 1635B1B3D1 for ; Thu, 12 Oct 2017 19:05:03 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Oct 2017 10:05:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,367,1503385200"; d="scan'208";a="1230098154" Received: from irsmsx107.ger.corp.intel.com ([163.33.3.99]) by fmsmga002.fm.intel.com with ESMTP; 12 Oct 2017 10:04:33 -0700 Received: from irsmsx101.ger.corp.intel.com ([169.254.1.22]) by IRSMSX107.ger.corp.intel.com ([169.254.10.239]) with mapi id 14.03.0319.002; Thu, 12 Oct 2017 18:04:32 +0100 From: "Trahe, Fiona" To: "dev@dpdk.org" CC: "Trahe, Fiona" , "Doherty, Declan" , "De Lara Guarch, Pablo" , "Richardson, Bruce" Thread-Topic: [RFC] Compression API in DPDK Thread-Index: AdNDe5cVAzjxCOtoRH2TNNZhDVbPqQ== Date: Thu, 12 Oct 2017 17:04:31 +0000 Message-ID: <348A99DA5F5B7549AA880327E580B435892A8BEC@IRSMSX101.ger.corp.intel.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZTA4MGE4MGQtYmFmMC00MzBhLWExMWMtNGQzZjUzYTE1NmNkIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE2LjUuOS4zIiwiVHJ1c3RlZExhYmVsSGFzaCI6IjdnditCdVB0bFdxZERyZzNjdHp1N3JDaDhsZjdcL2V3RThDNnBaVUs4cUtJPSJ9 x-ctpclassification: CTP_IC dlp-product: dlpe-windows dlp-version: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [163.33.239.182] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: [dpdk-dev] [RFC] Compression API in DPDK X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Oct 2017 17:05:05 -0000 With the vast amounts of data being transported around networks and stored = in storage systems, reducing data size is becoming ever more important. The= re are both software libraries and hardware devices available that provide = compression, but no common API. This RFC proposes a compression API for DPD= K to address this need. Features: . Deflate Algorithm (https://tools.ietf.org/html/rfc1951), other algorithms= can be added later. . Static and Dynamic Huffman encoding. . Compression levels . Checksum generation . Asynchronous burst API . Session-based. (for stateless a session may be useable across devices, fo= r stateful it wouldn't be.)=20 Note 1: Split of functionality above/below API When considering whether features should be supported on the API or not, th= e decision was based on the following: The purpose of the API is to decouple the application from the compute-inte= nsive functions needed for compression by abstracting them under a common A= PI. These can then be implemented by either hardware accelerators or optimi= sed software libraries. Where features are not compute-intensive and unlike= ly to be offloaded or optimised, there's nothing to be gained by each PMD h= aving to separately implement them, and it makes more sense for them to be = done above the API. So the following are not handled on the API and can be = done above.=20 . Prepending/appending protocol headers (gzip, zlib)=20 . File-handling, breaking files up into packets, reassembling. . Synchronous API Note 2: Stateful compression. A better compression ratio can be achieved by using stateful compression, a= llowing pattern matching across multiple=A0sequential packets. This will be= supported on the API, but in the interests of getting an initial RFC out f= or feedback, there are placeholder parameters on the API. Feedback welcome = on what parameters are needed for this feature. Note 3: The tricky question of where the API belongs We considered=20 1. Extending cryptodev 2. New acceldev APIs for device handling + compressdev APIs for data path=20 3. New acceldev for all APIs 4. New compressdev API We're proposing option 4, here's why: 1. Extending cryptodev: =A0=A0=A0 . =A0+ Nice code re-use. =A0=A0=A0 .=A0 + Consistent with Linux kernel and BSD approaches. =A0=A0=A0 . =A0- But not a good name.=20 =A0=A0=A0=A0. =A0- Would inevitably lead to some cryptodev API breakage - c= an be minimised, but then looks hacky. E.g.=20 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0rte_cryptodev_info.max_nb_queue_pairs c= urrently. Would need to extend to=20 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0rte_cryptodev_info.max_nb_queue_pairs (= Ideally rename this to max_nb_sym_.... but that's an API breakage) =A0=A0=A0 =A0=A0=A0=A0=A0=A0=A0=A0rte_cryptodev_info.max_nb_comp_queue_pair= s =A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0=A0rte_cryptodev_info.max_nb_asym_queue_pair= s =A0=A0=A0=A0=A0 =A0=A0=A0=A0Similarly fn names, e.g. rte_cryptodev_queue_pa= ir_setup.=20 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0Rename to rte_cryptodev_sym_queue_pair_set= up, add _comp and _asym fns? Or add parameter? 2. New acceldev APIs for device handling + compressdev APIs for data path:= =20 =A0=A0=A0=A0~70% of cryptodev code is device-handling which is common to al= l accelerators. =A0=A0=A0 Rather than providing new compressdev APIs, provide APIs which ca= n be used for compression =A0=A0=A0 and also other accelerators, e.g. bbdev, FPGAs. Would look like r= te_acceldev_info_get(), =A0=A0=A0 rte_acceldev_configure(), rte_compress_enqueue_burst(), etc =A0=A0=A0 . + Nice future code re-use.=20 =A0=A0=A0=A0. + No cryptodev API breakage, though would be nice over time t= o move to acceldev APIs for =A0=A0=A0=A0=A0=A0=A0=A0=A0 cryptodev and deprecate cryptodev APIs.=20 =A0=A0=A0=A0. - acceldev either has to understand structs for all services = with resulting dependencies OR =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 it's independent with minimal type-checki= ng, lots of void* and casting. =A0=A0=A0 . - potential API churn if services have different needs =A0=A0=A0 . - usability - application has to sometimes use acceldev, someti= mes compressdev 3. New acceldev for all APIs: =A0=A0=A0 . As 2 but with only the xforms and ops different for each servic= e. All APIs are rte_acceldev_.... =A0=A0=A0 . Similar pros/cons.=20 =A0=A0=A0=A0. - No flexibility for accelerators services to have service-sp= ecific APIs. Services are more tightly coupled. 4. New compressdev API: (possibly with an acceldev under the hood) =A0=A0=A0 . + Better name =A0=A0=A0 . + Usability - rte_compdev_... for everything=20 =A0=A0=A0=A0. + No cryptodev API breakage =A0=A0=A0 . + Flexibility to add any compression-specific APIs if needed.=20 =A0=A0=A0=A0. + Simpler, more decoupled code =A0=A0=A0 . - More code duplication.=20 May in a later iteration implement an acceldev under the hood, fo= r code re-use, but =A0=A0=A0=A0=A0=A0=A0=A0=A0 this is hidden from applications. Service APIs = could pick and choose whatever makes sense =A0=A0=A0=A0=A0=A0=A0=A0=A0 from acceldev. POC on this in-progress, also aw= aiting Hemant Agrawal's proposed =A0=A0=A0=A0=A0=A0=A0=A0=A0 rte_raw_device RFC, which may fit the acceldev = role.=20 Note 4: Chaining of compression with other services. =A0=A0=A0 Option 1 would make it easy to chain compression with sym crypto.= Though not with other non-crypto =A0=A0=A0 operations if this is a future use-case. However it can be achiev= ed with any option, following the pattern =A0=A0=A0 of rte_security API, so is not a factor in above decision. Code extracts below: diff --git a/lib/librte_compressdev/rte_comp.h b/lib/librte_compressdev/rte= _comp.h +/** + * @file rte_comp.h + * + * RTE definitions for Data Compression Service + * + */ + +/** Compression Algorithms */ +enum rte_comp_algorithm { +=A0=A0=A0=A0=A0 RTE_COMP_NULL =3D 1, +=A0=A0=A0=A0=A0 /**< NULL compression algorithm. */ +=A0=A0=A0=A0=A0 RTE_COMP_DEFLATE, +=A0=A0=A0=A0=A0 /**< DEFLATE compression algorithm +=A0=A0=A0=A0=A0 * https://tools.ietf.org/html/rfc1951 */ +=A0=A0=A0=A0=A0 RTE_COMP_LIST_END +}; + + +/** Compression checksum types */ +enum rte_comp_checksum_type { +=A0=A0=A0=A0=A0 RTE_COMP_NONE, +=A0=A0=A0=A0=A0 /**< No checksum generated */ +=A0=A0=A0=A0=A0 RTE_COMP_CRC32, +=A0=A0=A0=A0=A0 /**< Generates a CRC32 checksum, as used by gzip */ +=A0=A0=A0=A0=A0 RTE_COMP_ADLER32, +=A0=A0=A0=A0=A0 /**< Generates an Adler-32 checksum, as used by zlib */ +=A0=A0=A0=A0=A0 RTE_COMP_CRC32_ADLER32, +=A0=A0=A0=A0=A0 /**< Generates both Adler-32 and CRC32 checksums, concaten= ated. +=A0=A0=A0=A0=A0 * CRC32 is in the lower 32bits, Adler-32 in the upper 32 b= its. +=A0=A0=A0=A0=A0 */ +}; + + +/** Compression Deflate Huffman Type */ +enum rte_comp_huffman { +=A0=A0=A0=A0=A0 RTE_COMP_STATIC, +=A0=A0=A0=A0=A0 /**< Static encoding */ +=A0=A0=A0=A0=A0 RTE_COMP_DYNAMIC, +=A0=A0=A0=A0=A0 /**< Dynamic encoding */ +}; + +/** Compression integrity check */ +enum rte_comp_integrity_check { +=A0=A0=A0=A0=A0 RTE_COMP_NO_VERIFY, +=A0=A0=A0=A0=A0 /**< No integrity check on output data */ +=A0=A0=A0=A0=A0 RTE_COMP_VERIFY, +=A0=A0=A0=A0=A0 /**< Integrity check on output data. Only applies to compr= ess operation. +=A0=A0=A0=A0=A0 * After compress operation done, decompress and verify it = matches original data. +=A0=A0=A0=A0=A0 */ +}; + +enum rte_comp_flush_flag { +=A0=A0=A0=A0=A0 RTE_COMP_FLUSH_NONE, +=A0=A0=A0=A0=A0 /**< TODO */ +=A0=A0=A0=A0=A0 RTE_COMP_FLUSH_FULL, +=A0=A0=A0=A0=A0 /**< TODO */ +=A0=A0=A0=A0=A0 RTE_COMP_FLUSH_FINAL +=A0=A0=A0=A0=A0 /**< TODO */ +}; + + +/** Status of compression operation */ +enum rte_comp_op_status { +=A0=A0=A0=A0=A0 RTE_COMP_OP_STATUS_SUCCESS, +=A0=A0=A0=A0=A0 /**< Operation completed successfully */ +=A0=A0=A0=A0=A0 RTE_COMP_OP_STATUS_NOT_PROCESSED, +=A0=A0=A0=A0=A0 /**< Operation has not yet been processed by the device */ +=A0=A0=A0=A0=A0 RTE_COMP_OP_STATUS_INVALID_SESSION, +=A0=A0=A0=A0=A0 /**< operation failed due to invalid session arguments */ +=A0=A0=A0=A0=A0 RTE_COMP_OP_STATUS_INVALID_ARGS, +=A0=A0=A0=A0=A0 /**< Operation failed due to invalid arguments in request = */ +=A0=A0=A0=A0=A0 RTE_COMP_OP_STATUS_ERROR, +=A0=A0=A0=A0=A0 /**< Error handling operation */ +=A0=A0=A0=A0=A0 RTE_COMP_OP_STATUS_OVERFLOW, +=A0=A0=A0=A0=A0 /**< Output buffer filled up before all data in input buff= er was consumed */ +=A0=A0=A0=A0=A0 RTE_COMP_OP_STATUS_VERIFY_FAILED +=A0=A0=A0=A0=A0 /**< Decompression after compression failed to regenerate = original data */ + +=A0=A0=A0 =A0=A0//Note: +=A0=A0=A0=A0=A0 //QAT API has 19 error types. +=A0=A0=A0=A0=A0 //ISA-l has 5 inflate and 6 deflate errors. +=A0=A0=A0=A0=A0 //zlib has 6 errors +=A0=A0=A0=A0=A0 //Propose only include common subset in status - only valu= es where appl should have different behaviour. +=A0=A0=A0=A0=A0 //Add separate error field on op return which a PMD could = populate with PMD-specific debug info. +}; + + +/** Compression transform types */ +enum rte_comp_xform_type { +=A0=A0=A0=A0=A0 RTE_COMP_COMPRESS, +=A0=A0=A0=A0=A0 /**< Compression service - compress */ +=A0=A0=A0=A0=A0 RTE_COMP_DECOMPRESS, +=A0=A0=A0=A0=A0 /**< Compression service - decompress */ +=A0=A0=A0=A0=A0 RTE_COMP_CHECKSUM +=A0=A0=A0=A0=A0 /** Compression service - generate checksum */ +}; + +/** Parameters specific to the deflate algorithm */ +struct rte_comp_deflate_params { +=A0=A0=A0=A0=A0 enum rte_comp_huffman huffman; +=A0=A0=A0=A0=A0 /**< Compression huffman encoding type */ +}; + +/** + * Session Setup Data common to all compress transforms. + * Includes parameters common to stateless and stateful + */ +struct rte_comp_compress_common_params { +=A0=A0=A0=A0=A0 enum rte_comp_algorithm algo; +=A0=A0=A0=A0=A0 /**< Algorithm to use for compress operation */ +=A0=A0=A0=A0=A0 union { +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_deflate_params deflate; +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< Parameters specific to the deflate = algorithm */ +=A0=A0=A0=A0=A0 }; /**< Algorithm specific parameters */ +=A0=A0=A0=A0=A0 uint8_t level; +=A0=A0=A0=A0=A0 /**< Compression level +=A0=A0=A0=A0=A0 * Range is 1-9, where 1 is fastest compression +=A0=A0=A0=A0=A0 * but worst, i.e. highest, compression ratio. +=A0=A0=A0=A0=A0 * Higher numbers may give better compression ratios and ar= e likely slower. +=A0=A0=A0=A0=A0 * The number is interpreted by each PMD differently. + =A0=A0=A0=A0 =A0*/ +}; + +/** + * Session Setup Data for stateful compress transform. + * Extra params for stateful transform + */ +struct rte_comp_compress_stateful_params { +=A0=A0=A0=A0=A0 //TODO : add extra params just needed for stateful, e.g. +=A0=A0=A0=A0=A0 // history buffer size, window size, state, state buffers,= etc...? +}; +/* Session Setup Data for compress transform. */ +struct rte_comp_compress_xform { +=A0=A0=A0=A0=A0 struct rte_comp_compress_common_params cmn; +=A0=A0=A0=A0=A0 struct rte_comp_compress_stateful_params stateful; +}; + +/** + * Session Setup Data common to all decompress transforms. + * Includes parameters common to stateless and stateful + */ +struct rte_comp_decompress_common_params { +=A0=A0=A0=A0=A0 enum rte_comp_algorithm algo; +=A0=A0=A0=A0=A0 /**< Algorithm to use for decompression */ +}; +/** + *=A0 Session Setup Data for decompress transform. + * Extra params for stateful transform + */ +struct rte_comp_decompress_stateful_params { +=A0=A0=A0=A0=A0 //TODO : add extra params just needed for stateful, e.g. +=A0=A0=A0=A0=A0 // history buffer size, window size, state, state buffers,= etc...? +}; +/* Session Setup Data for decompress transform. */ +struct rte_comp_decompress_xform { +=A0=A0=A0=A0=A0 struct rte_comp_decompress_common_params cmn; +=A0=A0=A0=A0=A0 struct rte_comp_decompress_stateful_params stateful; +}; + +/** + *=A0 Generate checksum on uncompressed data. + * Applies to both compress and decompress operations. */ +/* Session Setup Data for checksum transform. */ +struct rte_comp_checksum_xform { +=A0=A0=A0=A0=A0 enum rte_comp_checksum_type chksum_type; +=A0=A0=A0=A0=A0 /**< This parameter determines the checksum type */ +}; + + +/** + * Compression transform structure. + * + * This is used to specify the compression transforms required, multiple t= ransforms + * can be chained together to specify a chain of transforms such as + * generate checksum, then compress. Each transform structure can + * hold a single transform, the type field is used to specify which transf= orm + * is contained within the union. + * The supported combinations are: + *=A0 - compress-only + *=A0 - decompress-only + *=A0 - generate checksum and compress input data + *=A0 - decompress input data, generate checksum on output data + * + */ +struct rte_comp_xform { +=A0=A0=A0=A0=A0 struct rte_comp_xform *next; +=A0=A0=A0=A0=A0 /**< next xform in chain */ +=A0=A0=A0=A0=A0 enum rte_comp_xform_type type; +=A0=A0=A0=A0=A0 /**< xform type */ +=A0=A0=A0=A0=A0 union { +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_compress_xform compress; +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< xform for compress operation */ +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_decompress_xform decompr= ess; +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< xform for decompress operation */ +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_checksum_xform chksum; +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< xform to generate checksums */ +=A0=A0=A0=A0=A0 }; +}; + + +struct rte_comp_session; + +/** + * Compression Operation. + * + * This structure contains data relating to performing a compression + * operation on the referenced mbuf data buffers. + * + * All compression operations are Out-of-place (OOP) operations, + * as the size of the output data is different to the size of the input da= ta. + * + * Comp operations are enqueued and dequeued in comp PMDs using the + * rte_compdev_enqueue_burst() / rte_compdev_dequeue_burst() APIs + */ +struct rte_comp_op { +=A0=A0=A0=A0=A0 uint8_t status; +=A0=A0=A0=A0=A0 /**< +=A0=A0=A0=A0=A0 * operation status - use values from enum rte_comp_status. +=A0=A0=A0=A0=A0 * This is reset to +=A0=A0=A0=A0=A0 * RTE_COMP_OP_STATUS_NOT_PROCESSED on allocation from memp= ool and +=A0=A0=A0=A0=A0 * will be set to RTE_COMP_OP_STATUS_SUCCESS after operatio= n +=A0=A0=A0=A0=A0 * is successfully processed by a PMD +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 uint16_t debug_status; +=A0=A0=A0=A0=A0 /**< +=A0=A0=A0=A0=A0 * Status of the operation is returned in the rte_crypto_op= . +=A0=A0=A0=A0=A0 * This field allows the PMD to pass back extra +=A0=A0=A0=A0=A0 * pmd-specific debug information. Value is not defined on = the API. +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 struct rte_comp_session *session; +=A0=A0=A0=A0=A0 /**< Handle for the initialised session context */ +=A0=A0=A0=A0=A0 struct rte_mempool *mempool; +=A0=A0=A0=A0=A0 /**< mempool from which operation is allocated */ +=A0=A0=A0=A0=A0 phys_addr_t phys_addr; +=A0=A0=A0=A0=A0 /**< physical address of this operation */ + +=A0=A0=A0=A0=A0 struct rte_mbuf *m_src;=A0=A0 /**< source mbuf */ +=A0=A0=A0=A0=A0 struct rte_mbuf *m_dst;=A0=A0 /**< destination mbuf */ + +=A0=A0=A0=A0=A0 struct { +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 uint32_t offset; +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< Starting point for compression or d= ecompression, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * specified as number of bytes from star= t of packet in +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * source buffer. +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * Starting point for checksum generation= in compress direction. +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 uint32_t length; +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< The length, in bytes, of the data i= n source buffer +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * to be compressed or decompressed. +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * Also the length of the data over which= the checksum +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * should be generated in compress direct= ion +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 } src; +=A0=A0=A0=A0=A0 struct { +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 uint32_t offset; +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< Starting point for writing output d= ata, specified as +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * number of bytes from start of packet i= n m_dst +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * buffer. Starting point for checksum ge= neration in +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * decompress direction. +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 } dst; +=A0=A0=A0=A0=A0 enum rte_comp_flush_flag flush_flag; +=A0=A0=A0=A0=A0 /**< defines flush characteristics for the output data. +=A0=A0=A0=A0=A0 * Only applicable in compress direction. +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 enum rte_comp_integrity_check verify; +=A0=A0=A0=A0=A0 /**< Specifies if the output data should be verified. +=A0=A0=A0=A0=A0=A0=A0 Only applicable in compress direction. +=A0=A0=A0 =A0=A0*/ +=A0=A0=A0=A0=A0 uint64_t input_chksum; +=A0=A0=A0=A0=A0 /**< An input checksum can be provided to generate a +=A0=A0=A0=A0=A0 * cumulative checksum across sequential blocks. +=A0=A0=A0=A0=A0 * Checksum type is as specified in chksum_type in xform. +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 uint64_t output_chksum; +=A0=A0=A0=A0=A0 /**< If a checksum is generated it will be written in here= . +=A0=A0=A0=A0=A0 * Checksum type is as specified in chksum_type in xform. +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 uint32_t consumed; +=A0=A0=A0=A0=A0 /**< The number of bytes from the source buffer +=A0=A0=A0=A0=A0 * which were compressed/decompressed. +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 uint32_t produced; +=A0=A0=A0=A0=A0 /**< The number of bytes written to the destination buffer +=A0=A0=A0=A0=A0 * which were compressed/decompressed. +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 /* +=A0=A0=A0=A0=A0 TODO - Are any extra params needed on stateful op or are a= ll in xform? +=A0=A0=A0=A0=A0 rte_comp_op_common_params/_stateful_params? +=A0=A0 =A0=A0=A0extra values apply to flush flag +=A0=A0=A0=A0=A0 */ +}; + + + int + rte_compdev_configure(uint8_t dev_id, struct rte_compdev_config *config); + int + rte_compdev_start(uint8_t dev_id); + void + rte_compdev_stop(uint8_t dev_id); /* etc...Rest of APIs follow same pattern, similar to cryptodev, stripped f= rom RFC for simplicity. */ +/** + * Compression supported feature flags + * + * Note: + * New features flags should be added to the end of the list + * + * Keep these flags synchronised with rte_compdev_get_comp_feature_name() + * Note: bit numbers here are same as on cryptodev, hence the gaps. + * This is an implementation detail which may change. + */ + #define RTE_COMPDEV_FF_CPU_SSE (1ULL << 3) + /**< Utilises CPU SIMD SSE instructions */ + #define RTE_COMPDEV_FF_CPU_AVX (1ULL << 4) + /**< Utilises CPU SIMD AVX instructions */ + #define RTE_COMPDEV_FF_CPU_AVX2 (1ULL << 5) + /**< Utilises CPU SIMD AVX2 instructions */ + #define RTE_COMPDEV_FF_HW_ACCELERATED (1ULL << 7) + /**< Operations are off-loaded to an external hardware accelerator */ + #define RTE_COMPDEV_FF_CPU_AVX512 (1ULL << 8) + /**< Utilises CPU SIMD AVX512 instructions */ + #define RTE_COMPDEV_FF_CPU_NEON (1ULL << 10) + /**< Utilises CPU NEON instructions */ =20 + #define RTE_COMPDEV_FF_CPU_ARM_CE (1ULL << 11) + /**< Utilises ARM CPU Cryptographic Extensions */ + + #define=A0=A0=A0=A0 RTE_COMP_FF_MBUF_SCATTER_GATHER=A0=A0=A0=A0=A0=A0=A0 = (1ULL << 12) + /**< Scatter-gather mbufs are supported */ + #define=A0=A0=A0=A0 RTE_COMP_FF_STATEFUL=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (1ULL << = 13) + /**< Stateful compression is supported */ + #define=A0=A0=A0=A0 RTE_COMPDEV_FF_MULTI_PKT_CHECKSUM=A0=A0=A0=A0=A0 = (1ULL << 14) + /**< Generation of checksum across multiple packets is supported */ + + + +/**=A0 Compression device information */ +struct rte_compdev_info { +=A0=A0=A0=A0=A0 const char *driver_name;=A0 /**< Driver name. */ +=A0=A0=A0=A0=A0 uint8_t driver_id;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 /**< Driver identifier */ +=A0=A0=A0=A0=A0 struct rte_device *dev;=A0=A0=A0=A0=A0=A0=A0=A0=A0 /**< De= vice information. */ + +=A0=A0=A0=A0=A0 uint64_t feature_flags; +=A0=A0=A0=A0=A0 /**< device feature flags */ + =A0=A0 const struct rte_comp_capabilities *capabilities; +=A0=A0=A0=A0=A0 /**< Array of devices capabilities */ +=A0=A0=A0=A0=A0 unsigned max_nb_queue_pairs; +=A0=A0=A0=A0=A0 /**< Maximum number of queues pairs supported by device. *= / +=A0=A0=A0=A0=A0 unsigned max_nb_sessions; +=A0=A0=A0=A0=A0 /**< Maximum number of sessions supported by device. */ +=A0=A0=A0=A0=A0 unsigned int max_nb_sessions_per_qp; +=A0=A0=A0=A0=A0 /**< Maximum number of sessions per queue pair. +=A0=A0=A0=A0=A0 * Default 0 for infinite sessions +=A0=A0=A0=A0=A0 */ +=A0=A0=A0=A0=A0 /* TODO uint8_t needs_intermediate_buffer OR should this b= e a feature flag? Or not necessary? */ +}; + + +/** Compression device statistics */ +struct rte_compdev_stats { +=A0=A0=A0=A0=A0 uint64_t enqueued_count; +=A0=A0=A0=A0=A0 /**< Count of all operations enqueued */ +=A0=A0=A0=A0=A0 uint64_t dequeued_count; +=A0=A0=A0=A0=A0 /**< Count of all operations dequeued */ + +=A0=A0=A0=A0=A0 uint64_t enqueue_err_count; +=A0=A0=A0=A0=A0 /**< Total error count on operations enqueued */ +=A0=A0=A0=A0=A0 uint64_t dequeue_err_count; +=A0=A0=A0=A0=A0 /**< Total error count on operations dequeued */ +}; + + +/** Compression device configuration structure */ +struct rte_compdev_config { +=A0=A0=A0=A0=A0 int socket_id;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=20 + /**< Socket to allocate resources on */ +=A0=A0=A0=A0=A0 uint16_t nb_queue_pairs; +=A0=A0=A0=A0=A0 /**< Total number of queue pairs to configure on a device.= */ +=A0=A0 uint32_t comp_intermediate_buf_size; +=A0=A0=A0=A0=A0/**< For deflate algorithm HW accelerators usually need to = allocate +=A0=A0=A0=A0=A0 * a pool of intermediate buffers for dynamic compression. +=A0=A0=A0=A0=A0 * This indicates the buffer size and should be +=A0=A0=A0=A0=A0 * set a little larger than the expected max source buffer = size. +=A0=A0=A0=A0=A0 * if the output of static compression doesn't fit in the +=A0=A0=A0=A0=A0 * intermediate buffer dynamic compression may not be possi= ble, +=A0=A0=A0=A0=A0 * in this case the accelerator may revert back to static c= ompression. +=A0=A0=A0=A0=A0 */ +}; + + +/** Compression device queue pair configuration structure. */ +struct rte_compdev_qp_conf { +=A0=A0=A0=A0=A0 uint32_t nb_descriptors; /**< Number of descriptors per qu= eue pair */ +}; + + +typedef uint16_t (*dequeue_pkt_burst_t)(void *qp, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_op **ops, uint16_t nb_op= s); +/**< Dequeue processed packets from queue pair of a device. */ + +typedef uint16_t (*enqueue_pkt_burst_t)(void *qp, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_op **ops, uint16_t nb_op= s); +/**< Enqueue packets for processing on queue pair of a device. */ + + + +/** The data structure associated with each compression device. */ +struct rte_compdev { + +=A0=A0=A0=A0=A0 dequeue_pkt_burst_t dequeue_burst; +=A0=A0=A0=A0=A0 /**< Pointer to PMD receive function. */ +=A0=A0=A0=A0=A0 enqueue_pkt_burst_t enqueue_burst; +=A0=A0=A0=A0=A0 /**< Pointer to PMD transmit function. */ + +=A0=A0=A0=A0=A0 struct rte_compdev_data *data; +=A0=A0=A0=A0=A0 /**< Pointer to device data */ +=A0=A0=A0=A0=A0 struct rte_compdev_ops *dev_ops; +=A0=A0=A0=A0=A0 /**< Functions exported by PMD */ +=A0=A0=A0=A0=A0 uint64_t feature_flags; +=A0=A0=A0=A0=A0 /**< Supported features */ +=A0=A0=A0=A0=A0=20 + struct rte_device *device; +=A0=A0=A0=A0=A0 /**< Backing device */ + +=A0=A0=A0=A0=A0 uint8_t driver_id; +=A0=A0=A0=A0=A0 /**< driver identifier*/ + +=A0=A0=A0=A0=A0 uint8_t attached : 1; +=A0=A0=A0=A0=A0 /**< Flag indicating the device is attached */ + +} + +/** + * + * The data part, with no function pointers, associated with each device. + * + * This structure is safe to place in shared memory to be common among + * different processes in a multi-process configuration. + */ +struct rte_compdev_data { +=A0=A0=A0=A0=A0 uint8_t dev_id; +=A0=A0=A0=A0=A0 /**< Device ID for this instance */ +=A0=A0=A0=A0=A0 uint8_t socket_id; +=A0=A0=A0=A0=A0 /**< Socket ID where memory is allocated */ +=A0=A0=A0=A0=A0 char name[RTE_COMPDEV_NAME_MAX_LEN]; +=A0=A0=A0=A0=A0 /**< Unique identifier name */ + +=A0=A0=A0=A0=A0 uint8_t dev_started : 1; +=A0=A0=A0=A0=A0 /**< Device state: STARTED(1)/STOPPED(0) */ + +=A0=A0=A0=A0=A0 void **queue_pairs; +=A0=A0=A0=A0=A0 /**< Array of pointers to queue pairs. */ +=A0=A0=A0=A0=A0 uint16_t nb_queue_pairs; +=A0=A0=A0=A0=A0 /**< Number of device queue pairs. */ + +=A0=A0=A0=A0=A0 void *dev_private; +=A0=A0=A0=A0=A0 /**< PMD-specific private data */ +} + + +/** + * + * Dequeue a burst of processed compression operations from a queue on the + * device. The dequeued operation are stored in *rte_comp_op* structures + * whose pointers are supplied in the *ops* array. + * + * The rte_compdev_dequeue_burst() function returns the number of ops + * actually dequeued, which is the number of *rte_comp_op* data structures + * effectively supplied into the *ops* array. + * + * A return value equal to *nb_ops* indicates that the queue contained + * at least *nb_ops* operations, and this is likely to signify that other + * processed operations remain in the devices output queue. Applications + * implementing a "retrieve as many processed operations as possible" poli= cy + * can check this specific case and keep invoking the + * rte_compdev_dequeue_burst() function until a value less than + * *nb_ops* is returned. + * + * The rte_compdev_dequeue_burst() function does not provide any error + * notification to avoid the corresponding overhead. + * + * @param=A0=A0 dev_id=A0=A0=A0=A0=A0=A0 The compression device identifier + * @param=A0=A0 qp_id=A0=A0=A0=A0=A0=A0=A0 The index of the queue pair fro= m which to + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 retri= eve processed packets. The value must be + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 in th= e range [0, nb_queue_pair - 1] previously + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 suppl= ied to rte_compdev_configure(). + * @param=A0=A0 ops=A0=A0=A0=A0=A0=A0=A0=A0=A0 The address of an array of = pointers to + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 *rte_= comp_op* structures that must be + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 large= enough to store *nb_ops* pointers in it. + * @param=A0=A0 nb_ops=A0=A0=A0=A0=A0=A0 The maximum number of operations = to dequeue. + * + * @return + *=A0=A0 - The number of operations actually dequeued, which is the number + *=A0=A0 of pointers to *rte_comp_op* structures effectively supplied to t= he + *=A0=A0 *ops* array. + */ +static inline uint16_t +rte_compdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_op **ops, uint16_t nb_op= s) +{ +=A0=A0=A0=A0=A0 struct rte_compdev *dev =3D &rte_compdevs[dev_id]; + +=A0=A0=A0=A0=A0 nb_ops =3D (*dev->dequeue_burst) +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (dev->data->queue_p= airs[qp_id], ops, nb_ops); + +=A0=A0=A0=A0=A0 return nb_ops; +} + +/** + * Enqueue a burst of operations for processing on a compression device. + * + * The rte_compdev_enqueue_burst() function is invoked to place + * comp operations on the queue *qp_id* of the device designated by + * its *dev_id*. + * + * The *nb_ops* parameter is the number of operations to process which are + * supplied in the *ops* array of *rte_comp_op* structures. + * + * The rte_compdev_enqueue_burst() function returns the number of + * operations it actually enqueued for processing. A return value equal to + * *nb_ops* means that all packets have been enqueued. + * + * @param=A0=A0 dev_id=A0=A0=A0=A0=A0=A0 The identifier of the device. + * @param=A0=A0 qp_id=A0=A0=A0=A0=A0=A0=A0 The index of the queue pair whi= ch packets are + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 to be= enqueued for processing. The value + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 must = be in the range [0, nb_queue_pairs - 1] + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 previ= ously supplied to + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 *rte_= compdev_configure*. + * @param=A0=A0 ops=A0=A0=A0=A0=A0=A0=A0=A0=A0 The address of an array of = *nb_ops* pointers + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 to *r= te_comp_op* structures which contain + *=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 the o= perations to be processed. + * @param=A0=A0 nb_ops=A0=A0=A0=A0=A0=A0 The number of operations to proce= ss. + * + * @return + * The number of operations actually enqueued on the device. The return + * value can be less than the value of the *nb_ops* parameter when the + * device's queue is full or if invalid parameters are specified in + * a *rte_comp_op*. + */ +static inline uint16_t +rte_compdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct rte_comp_op **ops, uint16_t nb_op= s) +{ +=A0=A0=A0=A0=A0 struct rte_compdev *dev =3D &rte_cryptodevs[dev_id]; + +=A0=A0=A0=A0=A0 return (*dev->enqueue_burst)( +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 dev->data->queue_pa= irs[qp_id], ops, nb_ops); +} + /* All session APIs stripped from RFC for simplicity. */ +/** compression device operations function pointer table */ +struct rte_compdev_ops { +=A0=A0=A0=A0=A0 compdev_configure_t dev_configure;=A0=A0=A0 /**< Configure= device. */ +=A0=A0=A0=A0=A0 compdev_start_t dev_start;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 /**< Start device. */ +=A0=A0=A0=A0=A0 compdev_stop_t dev_stop;=A0=A0=A0=A0=A0=A0=A0 /**< Stop de= vice. */ +=A0=A0=A0=A0=A0 compdev_close_t dev_close;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 /**< Close device. */ + +=A0=A0=A0=A0=A0 compdev_info_get_t dev_infos_get;=A0=A0=A0=A0 /**< Get dev= ice info. */ + +=A0=A0=A0=A0=A0 compdev_stats_get_t stats_get; +=A0=A0=A0=A0=A0 /**< Get device statistics. */ +=A0=A0=A0=A0=A0 compdev_stats_reset_t stats_reset; +=A0=A0=A0=A0=A0 /**< Reset device statistics. */ + +=A0=A0=A0=A0=A0 compdev_queue_pair_setup_t queue_pair_setup; +=A0=A0=A0=A0=A0 /**< Set up a device queue pair. */ +=A0=A0=A0=A0=A0 compdev_queue_pair_release_t queue_pair_release; +=A0=A0=A0=A0=A0 /**< Release a queue pair. */ +=A0=A0=A0=A0=A0 compdev_queue_pair_start_t queue_pair_start; +=A0=A0=A0=A0=A0 /**< Start a queue pair. */ +=A0=A0=A0=A0=A0 compdev_queue_pair_stop_t queue_pair_stop; +=A0=A0=A0=A0=A0 /**< Stop a queue pair. */ +=A0=A0=A0=A0=A0 compdev_queue_pair_count_t queue_pair_count; +=A0=A0=A0=A0=A0 /**< Get count of the queue pairs. */ + + comp_get_session_private_size_t session_get_size; +=A0=A0=A0=A0=A0 /**< Return private session. */ +=A0=A0=A0=A0=A0 comp_configure_session_t session_configure; +=A0=A0=A0=A0=A0 /**< Configure a comp session. */ +=A0=A0=A0=A0=A0 comp_free_session_t session_clear; +=A0=A0=A0=A0=A0 /**< Clear a comp sessions private data. */ +=A0=A0=A0=A0=A0 comp_queue_pair_attach_session_t qp_attach_session; +=A0=A0=A0=A0=A0 /**< Attach session to queue pair. */ +=A0=A0=A0=A0=A0 comp_queue_pair_attach_session_t qp_detach_session; +=A0=A0=A0=A0=A0 /**< Detach session from queue pair. */ +};