xref: /dpdk/lib/compressdev/rte_comp.h (revision 5d52418fa4b9a7f28eaedc1d88ec5cf330381c0e)
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