While I am still going through RFC in details, inline are my inputs to some of the points.
On Thu, Oct 12, 2017 at 10:34 PM, Trahe, Fiona <fiona.tr...@intel.com> wrote: > > With the vast amounts of data being transported around networks and stored in > storage systems, reducing data size is becoming ever more important. There > are both software libraries and hardware devices available that provide > compression, but no common API. This RFC proposes a compression API for DPDK > 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, for > stateful it wouldn't be.) > > > Note 1: Split of functionality above/below API > When considering whether features should be supported on the API or not, the > decision was based on the following: > The purpose of the API is to decouple the application from the > compute-intensive functions needed for compression by abstracting them under > a common API. These can then be implemented by either hardware accelerators > or optimised software libraries. Where features are not compute-intensive and > unlikely to be offloaded or optimised, there's nothing to be gained by each > PMD having 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. > . Prepending/appending protocol headers (gzip, zlib) > . 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, > allowing pattern matching across multiple sequential packets. This will be > supported on the API, but in the interests of getting an initial RFC out for > feedback, there are placeholder parameters on the API. Feedback welcome on > what parameters are needed for this feature. > We would like to see this as part of Specification. We will provide more details on what we(cavium) require. > > > Note 3: The tricky question of where the API belongs > We considered > 1. Extending cryptodev > 2. New acceldev APIs for device handling + compressdev APIs for data path > 3. New acceldev for all APIs > 4. New compressdev API > > We're proposing option 4, here's why: > 1. Extending cryptodev: > . + Nice code re-use. > . + Consistent with Linux kernel and BSD approaches. > . - But not a good name. > . - Would inevitably lead to some cryptodev API breakage - can be > minimised, but then looks hacky. E.g. > rte_cryptodev_info.max_nb_queue_pairs currently. Would need to > extend to > rte_cryptodev_info.max_nb_queue_pairs (Ideally rename this to > max_nb_sym_.... but that's an API breakage) > rte_cryptodev_info.max_nb_comp_queue_pairs > rte_cryptodev_info.max_nb_asym_queue_pairs > Similarly fn names, e.g. rte_cryptodev_queue_pair_setup. > Rename to rte_cryptodev_sym_queue_pair_setup, add _comp and _asym > fns? Or add parameter? > 2. New acceldev APIs for device handling + compressdev APIs for data path: > ~70% of cryptodev code is device-handling which is common to all > accelerators. > Rather than providing new compressdev APIs, provide APIs which can be > used for compression > and also other accelerators, e.g. bbdev, FPGAs. Would look like > rte_acceldev_info_get(), > rte_acceldev_configure(), rte_compress_enqueue_burst(), etc > . + Nice future code re-use. > . + No cryptodev API breakage, though would be nice over time to move to > acceldev APIs for > cryptodev and deprecate cryptodev APIs. > . - acceldev either has to understand structs for all services with > resulting dependencies OR > it's independent with minimal type-checking, lots of void* and > casting. > . - potential API churn if services have different needs > . - usability - application has to sometimes use acceldev, sometimes > compressdev > 3. New acceldev for all APIs: > . As 2 but with only the xforms and ops different for each service. All > APIs are rte_acceldev_.... > . Similar pros/cons. > . - No flexibility for accelerators services to have service-specific > APIs. Services are more tightly coupled. > 4. New compressdev API: (possibly with an acceldev under the hood) > . + Better name > . + Usability - rte_compdev_... for everything > . + No cryptodev API breakage > . + Flexibility to add any compression-specific APIs if needed. > . + Simpler, more decoupled code > . - More code duplication. > May in a later iteration implement an acceldev under the hood, for > code re-use, but > this is hidden from applications. Service APIs could pick and > choose whatever makes sense > from acceldev. POC on this in-progress, also awaiting Hemant > Agrawal's proposed > rte_raw_device RFC, which may fit the acceldev role. > > Note 4: Chaining of compression with other services. > Option 1 would make it easy to chain compression with sym crypto. Though > not with other non-crypto > operations if this is a future use-case. However it can be achieved with > any option, following the pattern > of rte_security API, so is not a factor in above decision. > We are in favor of solution #4. Apart from reasons as you stated, nature of both operations are very different and it add lots of complexity to both ends (crypto + compression) to co-exist with different behavior. However I would like to understand more about acceldev proposal? Is there any document that I can see to understands its purpose? > > > 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 { > + RTE_COMP_NULL = 1, > + /**< NULL compression algorithm. */ > + RTE_COMP_DEFLATE, > + /**< DEFLATE compression algorithm > + * https://tools.ietf.org/html/rfc1951 */ > + RTE_COMP_LIST_END > +}; > + We support LZS offload as well, need to extend with RTE_COMP_LZS. > + > +/** Compression checksum types */ > +enum rte_comp_checksum_type { > + RTE_COMP_NONE, > + /**< No checksum generated */ > + RTE_COMP_CRC32, > + /**< Generates a CRC32 checksum, as used by gzip */ > + RTE_COMP_ADLER32, > + /**< Generates an Adler-32 checksum, as used by zlib */ > + RTE_COMP_CRC32_ADLER32, > + /**< Generates both Adler-32 and CRC32 checksums, concatenated. > + * CRC32 is in the lower 32bits, Adler-32 in the upper 32 bits. > + */ > +}; > + In addition to these we support SHA1 and SHA256. To incorporate these, we suggest the following: enum rte_comp_integrity_algo { RTE_COMP_NONE, RTE_COMP_CRC32, RTE_COMP_ADLER32, RTE_COMP_CRC32_ADLER32, RTE_COMP_SHA1, RTE_COMP_SHA256, }; > + > +/** Compression Deflate Huffman Type */ > +enum rte_comp_huffman { > + RTE_COMP_STATIC, > + /**< Static encoding */ > + RTE_COMP_DYNAMIC, > + /**< Dynamic encoding */ > +}; > + We would like to see a RTE_COMP_DEFAULT for situations where application cannot make a choice. Also, To be more consistent to naming and deflate RFC1951, should be renamed as RTE_COMP_FIXED and RTE_COMP_DYNAMIC. > +/** Compression integrity check */ > +enum rte_comp_integrity_check { > + RTE_COMP_NO_VERIFY, > + /**< No integrity check on output data */ > + RTE_COMP_VERIFY, > + /**< Integrity check on output data. Only applies to compress > operation. > + * After compress operation done, decompress and verify it matches > original data. > + */ This looks more to me as diagnostic tool / test app.. It should be part of an Application than a library > +}; > + > +enum rte_comp_flush_flag { > + RTE_COMP_FLUSH_NONE, > + /**< TODO */ > + RTE_COMP_FLUSH_FULL, > + /**< TODO */ > + RTE_COMP_FLUSH_FINAL > + /**< TODO */ > +}; > + We need to add RTE_COMP_FLUSH_SYNC. Also, there could be some algorithms where these FLUSH type may not be relevant or not all may be supported , so what are PMD expectations for such case? > + > +/** Status of compression operation */ > +enum rte_comp_op_status { > + RTE_COMP_OP_STATUS_SUCCESS, > + /**< Operation completed successfully */ > + RTE_COMP_OP_STATUS_NOT_PROCESSED, > + /**< Operation has not yet been processed by the device */ > + RTE_COMP_OP_STATUS_INVALID_SESSION, > + /**< operation failed due to invalid session arguments */ > + RTE_COMP_OP_STATUS_INVALID_ARGS, > + /**< Operation failed due to invalid arguments in request */ > + RTE_COMP_OP_STATUS_ERROR, > + /**< Error handling operation */ > + RTE_COMP_OP_STATUS_OVERFLOW, If I understand the purpose correctly then this indicates a situation where output buffer exhausted during compression/decompression. So it should be renamed as RTE_COMP_OP_STATUS_OUT_OF_SPACE > + /**< Output buffer filled up before all data in input buffer was > consumed */ This could also arise where input buffer is fully consumed during decompression. So comment can be more generic such as “Output buffer exhausted during operation.” > + RTE_COMP_OP_STATUS_VERIFY_FAILED > + /**< Decompression after compression failed to regenerate original > data */ Believe it isn't needed to be part of Spec. > + > + //Note: > + //QAT API has 19 error types. > + //ISA-l has 5 inflate and 6 deflate errors. > + //zlib has 6 errors > + //Propose only include common subset in status - only values where > appl should have different behaviour. > + //Add separate error field on op return which a PMD could populate > with PMD-specific debug info. Probably should add RTE_COMP_OP_STATUS_INVALID_STATE in case an API is invoked in invalid state. Rest Subset looks self-contained. > +}; > + > + > +/** Compression transform types */ > +enum rte_comp_xform_type { > + RTE_COMP_COMPRESS, > + /**< Compression service - compress */ > + RTE_COMP_DECOMPRESS, > + /**< Compression service - decompress */ > + RTE_COMP_CHECKSUM > + /** Compression service - generate checksum */ > +}; > + Enumeration may be renamed as rte_comp_op_type > +/** Parameters specific to the deflate algorithm */ > +struct rte_comp_deflate_params { > + enum rte_comp_huffman huffman; > + /**< 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 { > + enum rte_comp_algorithm algo; > + /**< Algorithm to use for compress operation */ > + union { > + struct rte_comp_deflate_params deflate; > + /**< Parameters specific to the deflate algorithm */ > + }; /**< Algorithm specific parameters */ > + uint8_t level; > + /**< Compression level > + * Range is 1-9, where 1 is fastest compression > + * but worst, i.e. highest, compression ratio. > + * Higher numbers may give better compression ratios and are likely > slower. > + * The number is interpreted by each PMD differently. > + */ Different implementations of same algo may have different levels supported. So, we can add enum alongside this parameter such as: enum rte_comp_compression_level { RTE_COMP_COMPRESSION_LEVEL_DEFAULT=0, /** Use PMD Default */ RTE_COMP_COMPRESSION_LEVEL_MIN=1, /** Fastest Compression */ RTE_COMP_COMPRESSION_LEVEL_MAX=9 /** Maximum level supported by compression PMD */ } > +}; > + > +/** > + * Session Setup Data for stateful compress transform. > + * Extra params for stateful transform > + */ > +struct rte_comp_compress_stateful_params { > + //TODO : add extra params just needed for stateful, e.g. > + // history buffer size, window size, state, state buffers, etc...? I will provide my comments on it in another email. > +}; > +/* Session Setup Data for compress transform. */ > +struct rte_comp_compress_xform { > + struct rte_comp_compress_common_params cmn; > + 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 { > + enum rte_comp_algorithm algo; > + /**< Algorithm to use for decompression */ > +}; > +/** > + * Session Setup Data for decompress transform. > + * Extra params for stateful transform > + */ > +struct rte_comp_decompress_stateful_params { > + //TODO : add extra params just needed for stateful, e.g. > + // history buffer size, window size, state, state buffers, etc...? > +}; > +/* Session Setup Data for decompress transform. */ > +struct rte_comp_decompress_xform { > + struct rte_comp_decompress_common_params cmn; > + struct rte_comp_decompress_stateful_params stateful; > +}; > + > +/** > + * Generate checksum on uncompressed data. > + * Applies to both compress and decompress operations. */ > +/* Session Setup Data for checksum transform. */ > +struct rte_comp_checksum_xform { > + enum rte_comp_checksum_type chksum_type; > + /**< This parameter determines the checksum type */ > +}; > + > + > +/** > + * Compression transform structure. > + * > + * This is used to specify the compression transforms required, multiple > transforms > + * 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 transform > + * is contained within the union. > + * The supported combinations are: > + * - compress-only > + * - decompress-only > + * - generate checksum and compress input data > + * - decompress input data, generate checksum on output data > + * > + */ > +struct rte_comp_xform { > + struct rte_comp_xform *next; > + /**< next xform in chain */ > + enum rte_comp_xform_type type; > + /**< xform type */ > + union { > + struct rte_comp_compress_xform compress; > + /**< xform for compress operation */ > + struct rte_comp_decompress_xform decompress; > + /**< xform for decompress operation */ > + struct rte_comp_checksum_xform chksum; > + /**< xform to generate checksums */ We need compress+checksum(and decompress+checksum) as a single xform instead of requiring 2 xforms. The use of xform chain will introduce needless overhead for the most typical use-cases of comp+checksum(and decomp+checksum). > + }; > +}; > + > + > +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 data. > + * > + * Comp operations are enqueued and dequeued in comp PMDs using the > + * rte_compdev_enqueue_burst() / rte_compdev_dequeue_burst() APIs > + */ > +struct rte_comp_op { > + uint8_t status; > + /**< > + * operation status - use values from enum rte_comp_status. > + * This is reset to > + * RTE_COMP_OP_STATUS_NOT_PROCESSED on allocation from mempool and > + * will be set to RTE_COMP_OP_STATUS_SUCCESS after operation > + * is successfully processed by a PMD > + */ > + uint16_t debug_status; > + /**< > + * Status of the operation is returned in the rte_crypto_op. > + * This field allows the PMD to pass back extra > + * pmd-specific debug information. Value is not defined on the API. > + */ > + struct rte_comp_session *session; > + /**< Handle for the initialised session context */ > + struct rte_mempool *mempool; > + /**< mempool from which operation is allocated */ > + phys_addr_t phys_addr; > + /**< physical address of this operation */ > + > + struct rte_mbuf *m_src; /**< source mbuf */ > + struct rte_mbuf *m_dst; /**< destination mbuf */ > + > + struct { > + uint32_t offset; > + /**< Starting point for compression or decompression, > + * specified as number of bytes from start of packet in > + * source buffer. > + * Starting point for checksum generation in compress direction. > + */ > + uint32_t length; > + /**< The length, in bytes, of the data in source buffer > + * to be compressed or decompressed. > + * Also the length of the data over which the checksum > + * should be generated in compress direction > + */ > + } src; > + struct { > + uint32_t offset; > + /**< Starting point for writing output data, specified as > + * number of bytes from start of packet in m_dst > + * buffer. Starting point for checksum generation in > + * decompress direction. > + */ > + } dst; > + enum rte_comp_flush_flag flush_flag; > + /**< defines flush characteristics for the output data. > + * Only applicable in compress direction. > + */ > + enum rte_comp_integrity_check verify; > + /**< Specifies if the output data should be verified. > + Only applicable in compress direction. > + */ Again, believe we can get away with this by moving to application. Thanks Shally > + uint64_t input_chksum; > + /**< An input checksum can be provided to generate a > + * cumulative checksum across sequential blocks. > + * Checksum type is as specified in chksum_type in xform. > + */ > + uint64_t output_chksum; > + /**< If a checksum is generated it will be written in here. > + * Checksum type is as specified in chksum_type in xform. > + */ > + uint32_t consumed; > + /**< The number of bytes from the source buffer > + * which were compressed/decompressed. > + */ > + uint32_t produced; > + /**< The number of bytes written to the destination buffer > + * which were compressed/decompressed. > + */ > + /* > + TODO - Are any extra params needed on stateful op or are all in xform? > + rte_comp_op_common_params/_stateful_params? > + extra values apply to flush flag > + */ > +}; > + > + > + 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 > from 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 */ > + #define RTE_COMPDEV_FF_CPU_ARM_CE (1ULL << 11) > + /**< Utilises ARM CPU Cryptographic Extensions */ > + > + #define RTE_COMP_FF_MBUF_SCATTER_GATHER (1ULL << 12) > + /**< Scatter-gather mbufs are supported */ > + #define RTE_COMP_FF_STATEFUL > (1ULL << 13) > + /**< Stateful compression is supported */ > + #define RTE_COMPDEV_FF_MULTI_PKT_CHECKSUM (1ULL << 14) > + /**< Generation of checksum across multiple packets is supported */ > + > + > + > +/** Compression device information */ > +struct rte_compdev_info { > + const char *driver_name; /**< Driver name. */ > + uint8_t driver_id; /**< Driver identifier */ > + struct rte_device *dev; /**< Device information. */ > + > + uint64_t feature_flags; > + /**< device feature flags */ > + const struct rte_comp_capabilities *capabilities; > + /**< Array of devices capabilities */ > > + unsigned max_nb_queue_pairs; > + /**< Maximum number of queues pairs supported by device. */ > + unsigned max_nb_sessions; > + /**< Maximum number of sessions supported by device. */ > + unsigned int max_nb_sessions_per_qp; > + /**< Maximum number of sessions per queue pair. > + * Default 0 for infinite sessions > + */ > + /* TODO uint8_t needs_intermediate_buffer OR should this be a feature > flag? Or not necessary? */ > +}; > + > + > +/** Compression device statistics */ > +struct rte_compdev_stats { > + uint64_t enqueued_count; > + /**< Count of all operations enqueued */ > + uint64_t dequeued_count; > + /**< Count of all operations dequeued */ > + > + uint64_t enqueue_err_count; > + /**< Total error count on operations enqueued */ > + uint64_t dequeue_err_count; > + /**< Total error count on operations dequeued */ > +}; > + > + > +/** Compression device configuration structure */ > +struct rte_compdev_config { > + int socket_id; > + /**< Socket to allocate resources on */ > + uint16_t nb_queue_pairs; > + /**< Total number of queue pairs to configure on a device. */ > + uint32_t comp_intermediate_buf_size; > + /**< For deflate algorithm HW accelerators usually need to allocate > + * a pool of intermediate buffers for dynamic compression. > + * This indicates the buffer size and should be > + * set a little larger than the expected max source buffer size. > + * if the output of static compression doesn't fit in the > + * intermediate buffer dynamic compression may not be possible, > + * in this case the accelerator may revert back to static compression. > + */ > +}; > + > + > +/** Compression device queue pair configuration structure. */ > +struct rte_compdev_qp_conf { > + uint32_t nb_descriptors; /**< Number of descriptors per queue pair */ > +}; > + > + > +typedef uint16_t (*dequeue_pkt_burst_t)(void *qp, > + struct rte_comp_op **ops, uint16_t nb_ops); > +/**< Dequeue processed packets from queue pair of a device. */ > + > +typedef uint16_t (*enqueue_pkt_burst_t)(void *qp, > + struct rte_comp_op **ops, uint16_t nb_ops); > +/**< Enqueue packets for processing on queue pair of a device. */ > + > + > + > +/** The data structure associated with each compression device. */ > +struct rte_compdev { > + > + dequeue_pkt_burst_t dequeue_burst; > + /**< Pointer to PMD receive function. */ > + enqueue_pkt_burst_t enqueue_burst; > + /**< Pointer to PMD transmit function. */ > + > + struct rte_compdev_data *data; > + /**< Pointer to device data */ > + struct rte_compdev_ops *dev_ops; > + /**< Functions exported by PMD */ > + uint64_t feature_flags; > + /**< Supported features */ > + > + struct rte_device *device; > + /**< Backing device */ > + > + uint8_t driver_id; > + /**< driver identifier*/ > + > + uint8_t attached : 1; > + /**< 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 { > + uint8_t dev_id; > + /**< Device ID for this instance */ > + uint8_t socket_id; > + /**< Socket ID where memory is allocated */ > + char name[RTE_COMPDEV_NAME_MAX_LEN]; > + /**< Unique identifier name */ > + > + uint8_t dev_started : 1; > + /**< Device state: STARTED(1)/STOPPED(0) */ > + > + void **queue_pairs; > + /**< Array of pointers to queue pairs. */ > + uint16_t nb_queue_pairs; > + /**< Number of device queue pairs. */ > + > + void *dev_private; > + /**< 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" policy > + * 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 dev_id The compression device identifier > + * @param qp_id The index of the queue pair from which to > + * retrieve processed packets. The value must be > + * in the range [0, nb_queue_pair - 1] previously > + * supplied to rte_compdev_configure(). > + * @param ops The address of an array of pointers to > + * *rte_comp_op* structures that must be > + * large enough to store *nb_ops* pointers in it. > + * @param nb_ops The maximum number of operations to dequeue. > + * > + * @return > + * - The number of operations actually dequeued, which is the number > + * of pointers to *rte_comp_op* structures effectively supplied to the > + * *ops* array. > + */ > +static inline uint16_t > +rte_compdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, > + struct rte_comp_op **ops, uint16_t nb_ops) > +{ > + struct rte_compdev *dev = &rte_compdevs[dev_id]; > + > + nb_ops = (*dev->dequeue_burst) > + (dev->data->queue_pairs[qp_id], ops, nb_ops); > + > + 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 dev_id The identifier of the device. > + * @param qp_id The index of the queue pair which packets are > + * to be enqueued for processing. The value > + * must be in the range [0, nb_queue_pairs - 1] > + * previously supplied to > + * *rte_compdev_configure*. > + * @param ops The address of an array of *nb_ops* pointers > + * to *rte_comp_op* structures which contain > + * the operations to be processed. > + * @param nb_ops The number of operations to process. > + * > + * @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, > + struct rte_comp_op **ops, uint16_t nb_ops) > +{ > + struct rte_compdev *dev = &rte_cryptodevs[dev_id]; > + > + return (*dev->enqueue_burst)( > + dev->data->queue_pairs[qp_id], ops, nb_ops); > +} > + > > /* All session APIs stripped from RFC for simplicity. */ > > +/** compression device operations function pointer table */ > +struct rte_compdev_ops { > + compdev_configure_t dev_configure; /**< Configure device. */ > + compdev_start_t dev_start; /**< Start device. */ > + compdev_stop_t dev_stop; /**< Stop device. */ > + compdev_close_t dev_close; /**< Close device. */ > + > + compdev_info_get_t dev_infos_get; /**< Get device info. */ > + > + compdev_stats_get_t stats_get; > + /**< Get device statistics. */ > + compdev_stats_reset_t stats_reset; > + /**< Reset device statistics. */ > + > + compdev_queue_pair_setup_t queue_pair_setup; > + /**< Set up a device queue pair. */ > + compdev_queue_pair_release_t queue_pair_release; > + /**< Release a queue pair. */ > + compdev_queue_pair_start_t queue_pair_start; > + /**< Start a queue pair. */ > + compdev_queue_pair_stop_t queue_pair_stop; > + /**< Stop a queue pair. */ > + compdev_queue_pair_count_t queue_pair_count; > + /**< Get count of the queue pairs. */ > + > + comp_get_session_private_size_t session_get_size; > + /**< Return private session. */ > + comp_configure_session_t session_configure; > + /**< Configure a comp session. */ > + comp_free_session_t session_clear; > + /**< Clear a comp sessions private data. */ > + comp_queue_pair_attach_session_t qp_attach_session; > + /**< Attach session to queue pair. */ > + comp_queue_pair_attach_session_t qp_detach_session; > + /**< Detach session from queue pair. */ > +}; > > > >