1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017-2018 Intel Corporation 3 */ 4 5 #ifndef _RTE_COMP_H_ 6 #define _RTE_COMP_H_ 7 8 /** 9 * @file rte_comp.h 10 * 11 * RTE definitions for Data Compression Service 12 */ 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 #include <rte_compat.h> 19 #include <rte_mbuf.h> 20 21 /** 22 * compression service feature flags 23 * 24 * @note New features flags should be added to the end of the list 25 * 26 * Keep these flags synchronised with rte_comp_get_feature_name() 27 */ 28 #define RTE_COMP_FF_STATEFUL_COMPRESSION (1ULL << 0) 29 /**< Stateful compression is supported */ 30 #define RTE_COMP_FF_STATEFUL_DECOMPRESSION (1ULL << 1) 31 /**< Stateful decompression is supported */ 32 #define RTE_COMP_FF_OOP_SGL_IN_SGL_OUT (1ULL << 2) 33 /**< Out-of-place Scatter-gather (SGL) buffers, 34 * with multiple segments, are supported in input and output 35 */ 36 #define RTE_COMP_FF_OOP_SGL_IN_LB_OUT (1ULL << 3) 37 /**< Out-of-place Scatter-gather (SGL) buffers are supported 38 * in input, combined with linear buffers (LB), with a 39 * single segment, in output 40 */ 41 #define RTE_COMP_FF_OOP_LB_IN_SGL_OUT (1ULL << 4) 42 /**< Out-of-place Scatter-gather (SGL) buffers are supported 43 * in output, combined with linear buffers (LB) in input 44 */ 45 #define RTE_COMP_FF_ADLER32_CHECKSUM (1ULL << 5) 46 /**< Adler-32 Checksum is supported */ 47 #define RTE_COMP_FF_CRC32_CHECKSUM (1ULL << 6) 48 /**< CRC32 Checksum is supported */ 49 #define RTE_COMP_FF_CRC32_ADLER32_CHECKSUM (1ULL << 7) 50 /**< Adler-32/CRC32 Checksum is supported */ 51 #define RTE_COMP_FF_MULTI_PKT_CHECKSUM (1ULL << 8) 52 /**< Generation of checksum across multiple stateless packets is supported */ 53 #define RTE_COMP_FF_SHA1_HASH (1ULL << 9) 54 /**< SHA1 Hash is supported */ 55 #define RTE_COMP_FF_SHA2_SHA256_HASH (1ULL << 10) 56 /**< SHA256 Hash of SHA2 family is supported */ 57 #define RTE_COMP_FF_NONCOMPRESSED_BLOCKS (1ULL << 11) 58 /**< Creation of non-compressed blocks using RTE_COMP_LEVEL_NONE is supported */ 59 #define RTE_COMP_FF_SHAREABLE_PRIV_XFORM (1ULL << 12) 60 /**< Private xforms created by the PMD can be shared 61 * across multiple stateless operations. If not set, then app needs 62 * to create as many priv_xforms as it expects to have stateless 63 * operations in-flight. 64 */ 65 #define RTE_COMP_FF_HUFFMAN_FIXED (1ULL << 13) 66 /**< Fixed huffman encoding is supported */ 67 #define RTE_COMP_FF_HUFFMAN_DYNAMIC (1ULL << 14) 68 /**< Dynamic huffman encoding is supported */ 69 #define RTE_COMP_FF_XXHASH32_CHECKSUM (1ULL << 15) 70 /**< xxHash-32 Checksum is supported */ 71 #define RTE_COMP_FF_LZ4_DICT_ID (1ULL << 16) 72 /**< LZ4 dictionary ID is supported */ 73 #define RTE_COMP_FF_LZ4_CONTENT_WITH_CHECKSUM (1ULL << 17) 74 /**< LZ4 content with checksum is supported */ 75 #define RTE_COMP_FF_LZ4_CONTENT_SIZE (1ULL << 18) 76 /**< LZ4 content size is supported */ 77 #define RTE_COMP_FF_LZ4_BLOCK_INDEPENDENCE (1ULL << 19) 78 /**< LZ4 block independent is supported */ 79 #define RTE_COMP_FF_LZ4_BLOCK_WITH_CHECKSUM (1ULL << 20) 80 /**< LZ4 block with checksum is supported */ 81 82 /** Status of comp operation */ 83 enum rte_comp_op_status { 84 RTE_COMP_OP_STATUS_SUCCESS = 0, 85 /**< Operation completed successfully */ 86 RTE_COMP_OP_STATUS_NOT_PROCESSED, 87 /**< Operation has not yet been processed by the device */ 88 RTE_COMP_OP_STATUS_INVALID_ARGS, 89 /**< Operation failed due to invalid arguments in request */ 90 RTE_COMP_OP_STATUS_ERROR, 91 /**< Error handling operation */ 92 RTE_COMP_OP_STATUS_INVALID_STATE, 93 /**< Operation is invoked in invalid state */ 94 RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED, 95 /**< Output buffer ran out of space before operation completed. 96 * Error case. Application must resubmit all data with a larger 97 * output buffer. 98 */ 99 RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE, 100 /**< Output buffer ran out of space before operation completed, but this 101 * is not an error case. Output data up to op.produced can be used and 102 * next op in the stream should continue on from op.consumed+1. 103 */ 104 }; 105 106 /** Compression Algorithms */ 107 enum rte_comp_algorithm { 108 RTE_COMP_ALGO_UNSPECIFIED = 0, 109 /** No Compression algorithm */ 110 RTE_COMP_ALGO_NULL, 111 /**< No compression. 112 * Pass-through, data is copied unchanged from source buffer to 113 * destination buffer. 114 */ 115 RTE_COMP_ALGO_DEFLATE, 116 /**< DEFLATE compression algorithm 117 * https://tools.ietf.org/html/rfc1951 118 */ 119 RTE_COMP_ALGO_LZS, 120 /**< LZS compression algorithm 121 * https://tools.ietf.org/html/rfc2395 122 */ 123 RTE_COMP_ALGO_LZ4, 124 /**< LZ4 compression algorithm 125 * https://github.com/lz4/lz4 126 */ 127 }; 128 129 /** Compression Hash Algorithms */ 130 enum rte_comp_hash_algorithm { 131 RTE_COMP_HASH_ALGO_NONE = 0, 132 /**< No hash */ 133 RTE_COMP_HASH_ALGO_SHA1, 134 /**< SHA1 hash algorithm */ 135 RTE_COMP_HASH_ALGO_SHA2_256, 136 /**< SHA256 hash algorithm of SHA2 family */ 137 }; 138 139 /**< Compression Level. 140 * The number is interpreted by each PMD differently. However, lower numbers 141 * give fastest compression, at the expense of compression ratio while 142 * higher numbers may give better compression ratios but are likely slower. 143 */ 144 #define RTE_COMP_LEVEL_PMD_DEFAULT (-1) 145 /** Use PMD Default */ 146 #define RTE_COMP_LEVEL_NONE (0) 147 /** Output uncompressed blocks if supported by the specified algorithm */ 148 #define RTE_COMP_LEVEL_MIN (1) 149 /** Use minimum compression level supported by the PMD */ 150 #define RTE_COMP_LEVEL_MAX (9) 151 /** Use maximum compression level supported by the PMD */ 152 153 /** Compression checksum types */ 154 enum rte_comp_checksum_type { 155 RTE_COMP_CHECKSUM_NONE, 156 /**< No checksum generated */ 157 RTE_COMP_CHECKSUM_CRC32, 158 /**< Generates a CRC32 checksum, as used by gzip */ 159 RTE_COMP_CHECKSUM_ADLER32, 160 /**< Generates an Adler-32 checksum, as used by zlib */ 161 RTE_COMP_CHECKSUM_CRC32_ADLER32, 162 /**< Generates both Adler-32 and CRC32 checksums, concatenated. 163 * CRC32 is in the lower 32bits, Adler-32 in the upper 32 bits. 164 */ 165 RTE_COMP_CHECKSUM_XXHASH32, 166 /**< Generates a xxHash-32 checksum, as used by LZ4. 167 * https://github.com/Cyan4973/xxHash/blob/dev/doc/xxhash_spec.md 168 */ 169 }; 170 171 /** Compression Huffman Type - used by DEFLATE algorithm */ 172 enum rte_comp_huffman { 173 RTE_COMP_HUFFMAN_DEFAULT, 174 /**< PMD may choose which Huffman codes to use */ 175 RTE_COMP_HUFFMAN_FIXED, 176 /**< Use Fixed Huffman codes */ 177 RTE_COMP_HUFFMAN_DYNAMIC, 178 /**< Use Dynamic Huffman codes */ 179 }; 180 181 /** Compression flush flags */ 182 enum rte_comp_flush_flag { 183 RTE_COMP_FLUSH_NONE, 184 /**< Data is not flushed. Output may remain in the compressor and be 185 * processed during a following op. It may not be possible to decompress 186 * output until a later op with some other flush flag has been sent. 187 */ 188 RTE_COMP_FLUSH_SYNC, 189 /**< All data should be flushed to output buffer. Output data can be 190 * decompressed. However state and history is not cleared, so future 191 * operations may use history from this operation. 192 */ 193 RTE_COMP_FLUSH_FULL, 194 /**< All data should be flushed to output buffer. Output data can be 195 * decompressed. State and history data is cleared, so future 196 * ops will be independent of ops processed before this. 197 */ 198 RTE_COMP_FLUSH_FINAL 199 /**< Same as RTE_COMP_FLUSH_FULL but if op.algo is RTE_COMP_ALGO_DEFLATE 200 * then bfinal bit is set in the last block. 201 */ 202 }; 203 204 /** Compression transform types */ 205 enum rte_comp_xform_type { 206 RTE_COMP_COMPRESS, 207 /**< Compression service - compress */ 208 RTE_COMP_DECOMPRESS, 209 /**< Compression service - decompress */ 210 }; 211 212 /** Compression operation type */ 213 enum rte_comp_op_type { 214 RTE_COMP_OP_STATELESS, 215 /**< All data to be processed is submitted in the op, no state or 216 * history from previous ops is used and none will be stored for future 217 * ops. Flush flag must be set to either FLUSH_FULL or FLUSH_FINAL. 218 */ 219 RTE_COMP_OP_STATEFUL 220 /**< There may be more data to be processed after this op, it's part of 221 * a stream of data. State and history from previous ops can be used 222 * and resulting state and history can be stored for future ops, 223 * depending on flush flag. 224 */ 225 }; 226 227 /** Parameters specific to the deflate algorithm */ 228 struct rte_comp_deflate_params { 229 enum rte_comp_huffman huffman; 230 /**< Compression huffman encoding type */ 231 }; 232 233 /** 234 * Dictionary ID flag 235 * If this flag is set, a 4-byte dict-ID field will be present, 236 * after the descriptor flags and the content size. 237 */ 238 #define RTE_COMP_LZ4_FLAG_DICT_ID (1 << 0) 239 240 /** 241 * Content checksum flag 242 * If this flag is set, a 32-bit content checksum 243 * will be appended after the end mark. 244 */ 245 #define RTE_COMP_LZ4_FLAG_CONTENT_CHECKSUM (1 << 2) 246 247 /** 248 * Content size flag 249 * If this flag is set, the uncompressed size of data included within the frame 250 * will be present as an 8-byte unsigned little-endian value, after the flags. 251 * Content size usage is optional. 252 */ 253 #define RTE_COMP_LZ4_FLAG_CONTENT_SIZE (1 << 3) 254 255 /** 256 * Block checksum flag. 257 * If this flag is set, each data block will be followed by a 4-byte checksum, 258 * calculated with the xxHash-32 algorithm on the raw (compressed) data block. 259 * The intent is to detect data corruption (storage or transmission errors) 260 * immediately, before decoding. 261 * Block checksum usage is optional. 262 */ 263 #define RTE_COMP_LZ4_FLAG_BLOCK_CHECKSUM (1 << 4) 264 265 /** 266 * Block independence flag. 267 * If this flag is set to 1, blocks are independent. 268 * If this flag is set to 0, each block depends on previous ones 269 * (up to LZ4 window size, which is 64 KB). 270 * In such case, it is necessary to decode all blocks in sequence. 271 * Block dependency improves compression ratio, especially for small blocks. 272 * On the other hand, it makes random access or multi-threaded decoding impossible. 273 */ 274 #define RTE_COMP_LZ4_FLAG_BLOCK_INDEPENDENCE (1 << 5) 275 276 /** Parameters specific to the LZ4 algorithm */ 277 struct rte_comp_lz4_params { 278 uint8_t flags; 279 /**< Compression LZ4 parameter flags. 280 * Based on LZ4 standard flags: 281 * https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md#frame-descriptor 282 */ 283 }; 284 285 /** Setup Data for compression */ 286 struct rte_comp_compress_xform { 287 enum rte_comp_algorithm algo; 288 /**< Algorithm to use for compress operation */ 289 union { 290 struct rte_comp_deflate_params deflate; 291 /**< Parameters specific to the deflate algorithm */ 292 struct rte_comp_lz4_params lz4; 293 /**< Parameters specific to the LZ4 algorithm */ 294 }; /**< Algorithm specific parameters */ 295 int level; 296 /**< Compression level */ 297 uint8_t window_size; 298 /**< Base two log value of sliding window to be used. If window size 299 * can't be supported by the PMD then it may fall back to a smaller 300 * size. This is likely to result in a worse compression ratio. 301 */ 302 enum rte_comp_checksum_type chksum; 303 /**< Type of checksum to generate on the uncompressed data */ 304 enum rte_comp_hash_algorithm hash_algo; 305 /**< Hash algorithm to be used with compress operation. Hash is always 306 * done on plaintext. 307 */ 308 }; 309 310 /** 311 * Setup Data for decompression. 312 */ 313 struct rte_comp_decompress_xform { 314 enum rte_comp_algorithm algo; 315 /**< Algorithm to use for decompression */ 316 enum rte_comp_checksum_type chksum; 317 /**< Type of checksum to generate on the decompressed data */ 318 uint8_t window_size; 319 /**< Base two log value of sliding window which was used to generate 320 * compressed data. If window size can't be supported by the PMD then 321 * setup of stream or private_xform should fail. 322 */ 323 union { 324 struct rte_comp_lz4_params lz4; 325 /**< Parameters specific to the LZ4 algorithm */ 326 }; /**< Algorithm specific parameters */ 327 enum rte_comp_hash_algorithm hash_algo; 328 /**< Hash algorithm to be used with decompress operation. Hash is always 329 * done on plaintext. 330 */ 331 }; 332 333 /** 334 * Compression transform structure. 335 * 336 * This is used to specify the compression transforms required. 337 * Each transform structure can hold a single transform, the type field is 338 * used to specify which transform is contained within the union. 339 */ 340 struct rte_comp_xform { 341 enum rte_comp_xform_type type; 342 /**< xform type */ 343 union { 344 struct rte_comp_compress_xform compress; 345 /**< xform for compress operation */ 346 struct rte_comp_decompress_xform decompress; 347 /**< decompress xform */ 348 }; 349 }; 350 351 /** 352 * Compression Operation. 353 * 354 * This structure contains data relating to performing a compression 355 * operation on the referenced mbuf data buffers. 356 * 357 * Comp operations are enqueued and dequeued in comp PMDs using the 358 * rte_compressdev_enqueue_burst() / rte_compressdev_dequeue_burst() APIs 359 */ 360 struct rte_comp_op { 361 enum rte_comp_op_type op_type; 362 union { 363 void *private_xform; 364 /**< Stateless private PMD data derived from an rte_comp_xform. 365 * A handle returned by rte_compressdev_private_xform_create() 366 * must be attached to operations of op_type RTE_COMP_STATELESS. 367 */ 368 void *stream; 369 /**< Private PMD data derived initially from an rte_comp_xform, 370 * which holds state and history data and evolves as operations 371 * are processed. rte_compressdev_stream_create() must be called 372 * on a device for all STATEFUL data streams and the resulting 373 * stream attached to the one or more operations associated 374 * with the data stream. 375 * All operations in a stream must be sent to the same device. 376 */ 377 }; 378 379 struct rte_mempool *mempool; 380 /**< Pool from which operation is allocated */ 381 rte_iova_t iova_addr; 382 /**< IOVA address of this operation */ 383 struct rte_mbuf *m_src; 384 /**< source mbuf 385 * The total size of the input buffer(s) can be retrieved using 386 * rte_pktmbuf_pkt_len(m_src). The max data size which can fit in a 387 * single mbuf is limited by the uint16_t rte_mbuf.data_len to 64k-1. 388 * If the input data is bigger than this it can be passed to the PMD in 389 * a chain of mbufs if the PMD's capabilities indicate it supports this. 390 */ 391 struct rte_mbuf *m_dst; 392 /**< destination mbuf 393 * The total size of the output buffer(s) can be retrieved using 394 * rte_pktmbuf_pkt_len(m_dst). The max data size which can fit in a 395 * single mbuf is limited by the uint16_t rte_mbuf.data_len to 64k-1. 396 * If the output data is expected to be bigger than this a chain of 397 * mbufs can be passed to the PMD if the PMD's capabilities indicate 398 * it supports this. 399 * 400 * @note, if incompressible data is passed to an engine for compression 401 * using RTE_COMP_ALGO_DEFLATE, it's possible for the output data 402 * to be larger than the uncompressed data, due to the inclusion 403 * of the DEFLATE header blocks. The size of m_dst should accommodate 404 * this, else OUT_OF_SPACE errors can be expected in this case. 405 */ 406 407 struct { 408 uint32_t offset; 409 /**< Starting point for compression or decompression, 410 * specified as number of bytes from start of packet in 411 * source buffer. 412 * This offset starts from the first segment 413 * of the buffer, in case the m_src is a chain of mbufs. 414 * Starting point for checksum generation in compress direction. 415 */ 416 uint32_t length; 417 /**< The length, in bytes, of the data in source buffer 418 * to be compressed or decompressed. 419 * Also the length of the data over which the checksum 420 * should be generated in compress direction 421 */ 422 } src; 423 struct { 424 uint32_t offset; 425 /**< Starting point for writing output data, specified as 426 * number of bytes from start of packet in dest 427 * buffer. 428 * This offset starts from the first segment 429 * of the buffer, in case the m_dst is a chain of mbufs. 430 * Starting point for checksum generation in 431 * decompress direction. 432 */ 433 } dst; 434 struct { 435 uint8_t *digest; 436 /**< Output buffer to store hash output, if enabled in xform. 437 * Buffer would contain valid value only after an op with 438 * flush flag = RTE_COMP_FLUSH_FULL/FLUSH_FINAL is processed 439 * successfully. 440 * 441 * Length of buffer should be contiguous and large enough to 442 * accommodate digest produced by specific hash algo. 443 */ 444 rte_iova_t iova_addr; 445 /**< IO address of the buffer */ 446 } hash; 447 enum rte_comp_flush_flag flush_flag; 448 /**< Defines flush characteristics for the output data. 449 * Only applicable in compress direction 450 */ 451 uint64_t input_chksum; 452 /**< An input checksum can be provided to generate a 453 * cumulative checksum across sequential blocks in a STATELESS stream. 454 * Checksum type is as specified in xform chksum_type 455 */ 456 uint64_t output_chksum; 457 /**< If a checksum is generated it will be written in here. 458 * Checksum type is as specified in xform chksum_type. 459 */ 460 uint32_t consumed; 461 /**< The number of bytes from the source buffer 462 * which were compressed/decompressed. 463 */ 464 uint32_t produced; 465 /**< The number of bytes written to the destination buffer 466 * which were compressed/decompressed. 467 */ 468 uint64_t debug_status; 469 /**< 470 * Status of the operation is returned in the status param. 471 * This field allows the PMD to pass back extra 472 * pmd-specific debug information. Value is not defined on the API. 473 */ 474 uint8_t status; 475 /**< 476 * Operation status - use values from enum rte_comp_status. 477 * This is reset to 478 * RTE_COMP_OP_STATUS_NOT_PROCESSED on allocation from mempool and 479 * will be set to RTE_COMP_OP_STATUS_SUCCESS after operation 480 * is successfully processed by a PMD 481 */ 482 } __rte_cache_aligned; 483 484 /** 485 * Creates an operation pool 486 * 487 * @param name 488 * Compress pool name 489 * @param nb_elts 490 * Number of elements in pool 491 * @param cache_size 492 * Number of elements to cache on lcore, see 493 * *rte_mempool_create* for further details about cache size 494 * @param user_size 495 * Size of private data to allocate for user with each operation 496 * @param socket_id 497 * Socket to identifier allocate memory on 498 * @return 499 * - On success pointer to mempool 500 * - On failure NULL 501 */ 502 __rte_experimental 503 struct rte_mempool * 504 rte_comp_op_pool_create(const char *name, 505 unsigned int nb_elts, unsigned int cache_size, 506 uint16_t user_size, int socket_id); 507 508 /** 509 * Allocate an operation from a mempool with default parameters set 510 * 511 * @param mempool 512 * Compress operation mempool 513 * 514 * @return 515 * - On success returns a valid rte_comp_op structure 516 * - On failure returns NULL 517 */ 518 __rte_experimental 519 struct rte_comp_op * 520 rte_comp_op_alloc(struct rte_mempool *mempool); 521 522 /** 523 * Bulk allocate operations from a mempool with default parameters set 524 * 525 * @param mempool 526 * Compress operation mempool 527 * @param ops 528 * Array to place allocated operations 529 * @param nb_ops 530 * Number of operations to allocate 531 * @return 532 * - nb_ops: Success, the nb_ops requested was allocated 533 * - 0: Not enough entries in the mempool; no ops are retrieved. 534 */ 535 __rte_experimental 536 int 537 rte_comp_op_bulk_alloc(struct rte_mempool *mempool, 538 struct rte_comp_op **ops, uint16_t nb_ops); 539 540 /** 541 * Free operation structure 542 * If operation has been allocate from a rte_mempool, then the operation will 543 * be returned to the mempool. 544 * 545 * @param op 546 * Compress operation pointer allocated from rte_comp_op_alloc() 547 * If op is NULL, no operation is performed. 548 */ 549 __rte_experimental 550 void 551 rte_comp_op_free(struct rte_comp_op *op); 552 553 /** 554 * Bulk free operation structures 555 * If operations have been allocated from an rte_mempool, then the operations 556 * will be returned to the mempool. 557 * The array entry will be cleared. 558 * 559 * @param ops 560 * Array of Compress operations 561 * @param nb_ops 562 * Number of operations to free 563 */ 564 __rte_experimental 565 void 566 rte_comp_op_bulk_free(struct rte_comp_op **ops, uint16_t nb_ops); 567 568 /** 569 * Get the name of a compress service feature flag 570 * 571 * @param flag 572 * The mask describing the flag 573 * 574 * @return 575 * The name of this flag, or NULL if it's not a valid feature flag. 576 */ 577 __rte_experimental 578 const char * 579 rte_comp_get_feature_name(uint64_t flag); 580 581 #ifdef __cplusplus 582 } 583 #endif 584 585 #endif /* _RTE_COMP_H_ */ 586