xref: /dpdk/doc/guides/prog_guide/compressdev.rst (revision 4c9484373fcd0aa4a240fdb2e797269eb2f26b9b)
1a584d3beSAshish Gupta..  SPDX-License-Identifier: BSD-3-Clause
2a584d3beSAshish Gupta    Copyright(c) 2017-2018 Cavium Networks.
3a584d3beSAshish Gupta
4a584d3beSAshish GuptaCompression Device Library
5*4c948437SCiara Power==========================
6a584d3beSAshish Gupta
7a584d3beSAshish GuptaThe compression framework provides a generic set of APIs to perform compression services
8a584d3beSAshish Guptaas well as to query and configure compression devices both physical(hardware) and virtual(software)
9a584d3beSAshish Guptato perform those services. The framework currently only supports lossless compression schemes:
10a584d3beSAshish GuptaDeflate and LZS.
11a584d3beSAshish Gupta
12a584d3beSAshish GuptaDevice Management
13a584d3beSAshish Gupta-----------------
14a584d3beSAshish Gupta
15a584d3beSAshish GuptaDevice Creation
16a584d3beSAshish Gupta~~~~~~~~~~~~~~~
17a584d3beSAshish Gupta
18a584d3beSAshish GuptaPhysical compression devices are discovered during the bus probe of the EAL function
19a584d3beSAshish Guptawhich is executed at DPDK initialization, based on their unique device identifier.
20d629b7b5SJohn McNamaraFor e.g. PCI devices can be identified using PCI BDF (bus/bridge, device, function).
21a584d3beSAshish GuptaSpecific physical compression devices, like other physical devices in DPDK can be
22db27370bSStephen Hemmingerlisted using the EAL command line options.
23a584d3beSAshish Gupta
24a584d3beSAshish GuptaVirtual devices can be created by two mechanisms, either using the EAL command
25a584d3beSAshish Guptaline options or from within the application using an EAL API directly.
26a584d3beSAshish Gupta
27a584d3beSAshish GuptaFrom the command line using the --vdev EAL option
28a584d3beSAshish Gupta
29a584d3beSAshish Gupta.. code-block:: console
30a584d3beSAshish Gupta
3135bd0a5cSSean Morrissey   --vdev  '<PMD name>,socket_id=0'
32a584d3beSAshish Gupta
33a584d3beSAshish Gupta.. Note::
34a584d3beSAshish Gupta
35*4c948437SCiara Power   * If a DPDK application requires multiple software compression PMD devices then the
36*4c948437SCiara Power     required number of ``--vdev`` args with appropriate libraries are to be added.
37a584d3beSAshish Gupta
38*4c948437SCiara Power   * An application with multiple compression device instances exposed by the same PMD must
39a584d3beSAshish Gupta     specify a unique name for each device.
40a584d3beSAshish Gupta
41a584d3beSAshish Gupta   Example: ``--vdev  'pmd0' --vdev  'pmd1'``
42a584d3beSAshish Gupta
43a584d3beSAshish GuptaOr, by using the rte_vdev_init API within the application code.
44a584d3beSAshish Gupta
45a584d3beSAshish Gupta.. code-block:: c
46a584d3beSAshish Gupta
47a584d3beSAshish Gupta   rte_vdev_init("<pmd_name>","socket_id=0")
48a584d3beSAshish Gupta
49a584d3beSAshish GuptaAll virtual compression devices support the following initialization parameters:
50a584d3beSAshish Gupta
51a584d3beSAshish Gupta* ``socket_id`` - socket on which to allocate the device resources on.
52a584d3beSAshish Gupta
53a584d3beSAshish GuptaDevice Identification
54a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~
55a584d3beSAshish Gupta
56*4c948437SCiara PowerEach device, whether virtual or physical, is uniquely designated by two
57a584d3beSAshish Guptaidentifiers:
58a584d3beSAshish Gupta
59a584d3beSAshish Gupta- A unique device index used to designate the compression device in all functions
60a584d3beSAshish Gupta  exported by the compressdev API.
61a584d3beSAshish Gupta
62a584d3beSAshish Gupta- A device name used to designate the compression device in console messages, for
63a584d3beSAshish Gupta  administration or debugging purposes.
64a584d3beSAshish Gupta
65a584d3beSAshish GuptaDevice Configuration
66a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~
67a584d3beSAshish Gupta
68a584d3beSAshish GuptaThe configuration of each compression device includes the following operations:
69a584d3beSAshish Gupta
70a584d3beSAshish Gupta- Allocation of resources, including hardware resources if a physical device.
71a584d3beSAshish Gupta- Resetting the device into a well-known default state.
72a584d3beSAshish Gupta- Initialization of statistics counters.
73a584d3beSAshish Gupta
74a584d3beSAshish GuptaThe ``rte_compressdev_configure`` API is used to configure a compression device.
75a584d3beSAshish Gupta
76a584d3beSAshish GuptaThe ``rte_compressdev_config`` structure is used to pass the configuration
77a584d3beSAshish Guptaparameters.
78a584d3beSAshish Gupta
79*4c948437SCiara PowerSee the `DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_ for details.
80a584d3beSAshish Gupta
81a584d3beSAshish GuptaConfiguration of Queue Pairs
82a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83a584d3beSAshish Gupta
84a584d3beSAshish GuptaEach compression device queue pair is individually configured through the
85a584d3beSAshish Gupta``rte_compressdev_queue_pair_setup`` API.
86a584d3beSAshish Gupta
87a584d3beSAshish GuptaThe ``max_inflight_ops`` is used to pass maximum number of
88*4c948437SCiara Power``rte_comp_op`` that could be present in a queue at a time.
89*4c948437SCiara PowerThe PMD can then allocate resources accordingly on a specified socket.
90a584d3beSAshish Gupta
91*4c948437SCiara PowerSee the `DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_ for details.
92a584d3beSAshish Gupta
93*4c948437SCiara PowerLogical Cores, Memory and Queue Pair Relationships
94*4c948437SCiara Power~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95a584d3beSAshish Gupta
96*4c948437SCiara PowerThe Compressdev library supports NUMA similarly as described in Cryptodev library section.
97a584d3beSAshish Gupta
98*4c948437SCiara PowerA queue pair cannot be shared, and should be exclusively used by a single processing
99*4c948437SCiara Powercontext for enqueuing operations or dequeuing operations on the same compression device,
100a584d3beSAshish Guptasince sharing would require global locks and hinder performance. It is however possible
101a584d3beSAshish Guptato use a different logical core to dequeue an operation on a queue pair from the logical
102*4c948437SCiara Powercore on which it was enqueued. This means that for a compression burst, enqueue/dequeue
103a584d3beSAshish GuptaAPIs are a logical place to transition from one logical core to another in a
104a584d3beSAshish Guptadata processing pipeline.
105a584d3beSAshish Gupta
106a584d3beSAshish GuptaDevice Features and Capabilities
107*4c948437SCiara Power--------------------------------
108a584d3beSAshish Gupta
109a584d3beSAshish GuptaCompression devices define their functionality through two mechanisms, global device
110*4c948437SCiara Powerfeatures and algorithm features. Global device features identify device
111*4c948437SCiara Powerwide level features which are applicable to the whole device, such as supported hardware
112a584d3beSAshish Guptaacceleration and CPU features. List of compression device features can be seen in the
113a584d3beSAshish GuptaRTE_COMPDEV_FF_XXX macros.
114a584d3beSAshish Gupta
115*4c948437SCiara PowerThe algorithm features are features which the device supports per-algorithm,
116*4c948437SCiara Powersuch as a stateful compression/decompression, checksums operation etc.
117*4c948437SCiara PowerThe list of algorithm features can be seen in the RTE_COMP_FF_XXX macros.
118a584d3beSAshish Gupta
119a584d3beSAshish GuptaCapabilities
120a584d3beSAshish Gupta~~~~~~~~~~~~
121a584d3beSAshish GuptaEach PMD has a list of capabilities, including algorithms listed in
122*4c948437SCiara Powerthe enum ``rte_comp_algorithm``, its associated feature flag, and
123*4c948437SCiara Powersliding window range in log base 2 value. The sliding window range
124*4c948437SCiara Powerdefines the minimum and maximum size of a lookup window that an algorithm uses
125a584d3beSAshish Guptato find duplicates.
126a584d3beSAshish Gupta
127*4c948437SCiara PowerSee the `DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_ for details.
128a584d3beSAshish Gupta
129a584d3beSAshish GuptaEach Compression poll mode driver defines its array of capabilities
130*4c948437SCiara Powerfor each algorithm it supports. See the PMD implementation for capability
131a584d3beSAshish Guptainitialization.
132a584d3beSAshish Gupta
133a584d3beSAshish GuptaCapabilities Discovery
134a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~
135a584d3beSAshish Gupta
136*4c948437SCiara PowerPMD capability and features are discovered via the ``rte_compressdev_info_get`` function.
137a584d3beSAshish Gupta
138a584d3beSAshish GuptaThe ``rte_compressdev_info`` structure contains all the relevant information for the device.
139a584d3beSAshish Gupta
140*4c948437SCiara PowerSee the `DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_ for details.
141a584d3beSAshish Gupta
142a584d3beSAshish GuptaCompression Operation
143*4c948437SCiara Power---------------------
144a584d3beSAshish Gupta
145a584d3beSAshish GuptaDPDK compression supports two types of compression methodologies:
146a584d3beSAshish Gupta
147*4c948437SCiara Power- Stateless - data associated with a compression operation is compressed without any reference
148a584d3beSAshish Gupta  to another compression operation.
149a584d3beSAshish Gupta
150*4c948437SCiara Power- Stateful - data in each compression operation is compressed with reference to previous compression
151a584d3beSAshish Gupta  operations in the same data stream i.e. history of data is maintained between the operations.
152a584d3beSAshish Gupta
153*4c948437SCiara PowerFor more explanation, please refer to the RFC https://www.ietf.org/rfc/rfc1951.txt
154a584d3beSAshish Gupta
155a584d3beSAshish GuptaOperation Representation
156a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~
157a584d3beSAshish Gupta
158*4c948437SCiara PowerA compression operation is described via ``struct rte_comp_op``, which contains both input and
159a584d3beSAshish Guptaoutput data. The operation structure includes the operation type (stateless or stateful),
160*4c948437SCiara Powerthe operation status, the priv_xform/stream handle, source, destination and checksum buffer
161a584d3beSAshish Guptapointers. It also contains the source mempool from which the operation is allocated.
162*4c948437SCiara PowerThe PMD updates the consumed field with the amount of data read from the source buffer,
163*4c948437SCiara Powerand the produced field with the amount of data written into the destination buffer,
164*4c948437SCiara Poweralong with status of operation.
165*4c948437SCiara PowerSee the section :ref:`compressdev_prod_cons_op_status`: for more details.
166a584d3beSAshish Gupta
167*4c948437SCiara PowerThe compression operations mempool also has the ability to allocate private memory with the
168*4c948437SCiara Poweroperation for the application's use. The application software is responsible for specifying
169*4c948437SCiara Powerall the operation specific fields in the ``rte_comp_op`` structure, which are then used
170a584d3beSAshish Guptaby the compression PMD to process the requested operation.
171a584d3beSAshish Gupta
172a584d3beSAshish Gupta
173a584d3beSAshish GuptaOperation Management and Allocation
174a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
175a584d3beSAshish Gupta
176a584d3beSAshish GuptaThe compressdev library provides an API set for managing compression operations which
177a584d3beSAshish Guptautilize the Mempool Library to allocate operation buffers. Therefore, it ensures
178a584d3beSAshish Guptathat the compression operation is interleaved optimally across the channels and
179a584d3beSAshish Guptaranks for optimal processing.
180a584d3beSAshish Gupta
181a584d3beSAshish GuptaA ``rte_comp_op`` contains a field indicating the pool it originated from.
182a584d3beSAshish Gupta
183a584d3beSAshish Gupta``rte_comp_op_alloc()`` and ``rte_comp_op_bulk_alloc()`` are used to allocate
184a584d3beSAshish Guptacompression operations from a given compression operation mempool.
185*4c948437SCiara PowerThe operation gets reset before being returned to a user so that the operation
186a584d3beSAshish Guptais always in a good known state before use by the application.
187a584d3beSAshish Gupta
188a584d3beSAshish Gupta``rte_comp_op_free()`` is called by the application to return an operation to
189a584d3beSAshish Guptaits allocating pool.
190a584d3beSAshish Gupta
191*4c948437SCiara PowerSee the `DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_ for details.
192a584d3beSAshish Gupta
193a584d3beSAshish GuptaPassing source data as mbuf-chain
194*4c948437SCiara Power~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195a584d3beSAshish GuptaIf input data is scattered across several different buffers, then
196*4c948437SCiara Powerthe application can either parse through all such buffers and make one
197a584d3beSAshish Guptambuf-chain and enqueue it for processing or, alternatively, it can
198*4c948437SCiara Powermake multiple sequential enqueue_burst() calls for each of them,
199*4c948437SCiara Powerprocessing them statefully. See :ref:`compressdev_stateful_op`:
200a584d3beSAshish Guptafor stateful processing of ops.
201a584d3beSAshish Gupta
202a584d3beSAshish GuptaOperation Status
203a584d3beSAshish Gupta~~~~~~~~~~~~~~~~
204*4c948437SCiara PowerEach operation carries status information updated by the PMD after it is processed.
205*4c948437SCiara PowerThe following are currently supported:
206a584d3beSAshish Gupta
207a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_SUCCESS,
208a584d3beSAshish Gupta    Operation is successfully completed
209a584d3beSAshish Gupta
210a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_NOT_PROCESSED,
211a584d3beSAshish Gupta    Operation has not yet been processed by the device
212a584d3beSAshish Gupta
213a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_INVALID_ARGS,
214a584d3beSAshish Gupta    Operation failed due to invalid arguments in request
215a584d3beSAshish Gupta
216a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_ERROR,
217a584d3beSAshish Gupta    Operation failed because of internal error
218a584d3beSAshish Gupta
219a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_INVALID_STATE,
220a584d3beSAshish Gupta    Operation is invoked in invalid state
221a584d3beSAshish Gupta
222a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED,
223a584d3beSAshish Gupta    Output buffer ran out of space during processing. Error case,
224a584d3beSAshish Gupta    PMD cannot continue from here.
225a584d3beSAshish Gupta
226a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE,
227a584d3beSAshish Gupta    Output buffer ran out of space before operation completed, but this
228a584d3beSAshish Gupta    is not an error case. Output data up to op.produced can be used and
229*4c948437SCiara Power    the next op in the stream should continue on from op.consumed+1.
230a584d3beSAshish Gupta
231f7095d41SFiona TraheOperation status after enqueue / dequeue
232f7095d41SFiona Trahe~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
233f7095d41SFiona TraheSome of the above values may arise in the op after an
234*4c948437SCiara Power``rte_compressdev_enqueue_burst()``. If the number of ops enqueued < the number of ops requested
235*4c948437SCiara Powerthen the app should check the op.status of nb_enqd+1.
236*4c948437SCiara PowerIf the status is RTE_COMP_OP_STATUS_NOT_PROCESSED, it likely indicates a full-queue case for a
237*4c948437SCiara Powerhardware device, and a retry after dequeuing some ops is likely to be successful.
238*4c948437SCiara PowerIf the op holds any other status, e.g. RTE_COMP_OP_STATUS_INVALID_ARGS, a retry with
239f7095d41SFiona Trahethe same op is unlikely to be successful.
240f7095d41SFiona Trahe
241f7095d41SFiona Trahe
242*4c948437SCiara Power.. _compressdev_prod_cons_op_status:
243*4c948437SCiara Power
244a584d3beSAshish GuptaProduced, Consumed And Operation Status
245a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246a584d3beSAshish Gupta
247*4c948437SCiara Power- If the status is RTE_COMP_OP_STATUS_SUCCESS,
248a584d3beSAshish Gupta    consumed = amount of data read from input buffer, and
249a584d3beSAshish Gupta    produced = amount of data written in destination buffer
250f7095d41SFiona Trahe- If status is RTE_COMP_OP_STATUS_ERROR,
251f7095d41SFiona Trahe    consumed = produced = undefined
252a584d3beSAshish Gupta- If status is RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED,
253a584d3beSAshish Gupta    consumed = 0 and
254a584d3beSAshish Gupta    produced = usually 0, but in decompression cases a PMD may return > 0
255a584d3beSAshish Gupta    i.e. amount of data successfully produced until out of space condition
256a584d3beSAshish Gupta    hit. Application can consume output data in this case, if required.
257a584d3beSAshish Gupta- If status is RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE,
258a584d3beSAshish Gupta    consumed = amount of data read, and
259a584d3beSAshish Gupta    produced = amount of data successfully produced until
260*4c948437SCiara Power    out of space condition hit. The PMD has ability to recover
261*4c948437SCiara Power    from here, so an application can submit the next op from
262*4c948437SCiara Power    consumed+1, and a destination buffer with available space.
263a584d3beSAshish Gupta
264a584d3beSAshish GuptaTransforms
265a584d3beSAshish Gupta----------
266a584d3beSAshish Gupta
267a584d3beSAshish GuptaCompression transforms (``rte_comp_xform``) are the mechanism
268a584d3beSAshish Guptato specify the details of the compression operation such as algorithm,
269*4c948437SCiara Powerwindow size, and checksum.
270a584d3beSAshish Gupta
271a584d3beSAshish GuptaCompression API Hash support
272a584d3beSAshish Gupta----------------------------
273a584d3beSAshish Gupta
274*4c948437SCiara PowerThe compression API allows an application to enable digest calculation
275a584d3beSAshish Guptaalongside compression and decompression of data. A PMD reflects its
276a584d3beSAshish Guptasupport for hash algorithms via capability algo feature flags.
277*4c948437SCiara PowerIf supported, the PMD always calculates the digest on plaintext i.e.
278a584d3beSAshish Guptabefore compression and after decompression.
279a584d3beSAshish Gupta
280a584d3beSAshish GuptaCurrently supported list of hash algos are SHA-1 and SHA2 family
281a584d3beSAshish GuptaSHA256.
282a584d3beSAshish Gupta
283*4c948437SCiara PowerSee the `DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_ for details.
284a584d3beSAshish Gupta
285*4c948437SCiara PowerIf required, the application should set the valid hash algo in compress
286a584d3beSAshish Guptaor decompress xforms during ``rte_compressdev_stream_create()``
287*4c948437SCiara Poweror ``rte_compressdev_private_xform_create()``, and pass a valid
288a584d3beSAshish Guptaoutput buffer in ``rte_comp_op`` hash field struct to store the
289*4c948437SCiara Powerresulting digest. The buffer passed should be contiguous and large
290*4c948437SCiara Powerenough to store digest, which is 20 bytes for SHA-1 and
291a584d3beSAshish Gupta32 bytes for SHA2-256.
292a584d3beSAshish Gupta
293a584d3beSAshish GuptaCompression API Stateless operation
294a584d3beSAshish Gupta------------------------------------
295a584d3beSAshish Gupta
296a584d3beSAshish GuptaAn op is processed stateless if it has
297a584d3beSAshish Gupta- op_type set to RTE_COMP_OP_STATELESS
2981525374aSAdam Dybkowski- flush value set to RTE_COMP_FLUSH_FULL or RTE_COMP_FLUSH_FINAL
299a584d3beSAshish Gupta(required only on compression side),
300a584d3beSAshish Gupta- All required input in source buffer
301a584d3beSAshish Gupta
302*4c948437SCiara PowerWhen all of the above conditions are met, the PMD initiates stateless processing
303a584d3beSAshish Guptaand releases acquired resources after processing of current operation is
304*4c948437SCiara Powercomplete. The application can enqueue multiple stateless ops in a single burst
305a584d3beSAshish Guptaand must attach priv_xform handle to such ops.
306a584d3beSAshish Gupta
307a584d3beSAshish Guptapriv_xform in Stateless operation
308a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
309a584d3beSAshish Gupta
310*4c948437SCiara PowerA priv_xform is private data managed internally by the PMD to do stateless processing.
311*4c948437SCiara PowerA priv_xform is initialized by an application providing a generic xform structure
312*4c948437SCiara Powerto ``rte_compressdev_private_xform_create``, which returns an opaque priv_xform reference.
313*4c948437SCiara PowerIf the PMD supports SHAREABLE priv_xform, indicated via algorithm feature flag,
314*4c948437SCiara Powerthen the application can attach the same priv_xform with many stateless ops at a time.
315*4c948437SCiara PowerIf not, then the application needs to create as many priv_xforms as it expects to have
316*4c948437SCiara Powerstateless operations in-flight.
317a584d3beSAshish Gupta
318a584d3beSAshish Gupta.. figure:: img/stateless-op.*
319a584d3beSAshish Gupta
320a584d3beSAshish Gupta   Stateless Ops using Non-Shareable priv_xform
321a584d3beSAshish Gupta
322a584d3beSAshish Gupta
323a584d3beSAshish Gupta.. figure:: img/stateless-op-shared.*
324a584d3beSAshish Gupta
325a584d3beSAshish Gupta   Stateless Ops using Shareable priv_xform
326a584d3beSAshish Gupta
327a584d3beSAshish Gupta
328*4c948437SCiara PowerThe application should call ``rte_compressdev_private_xform_create()`` and attach it to a stateless
329*4c948437SCiara Powerop before enqueuing them for processing and free via ``rte_compressdev_private_xform_free()``
330*4c948437SCiara Powerduring termination.
331a584d3beSAshish Gupta
332a584d3beSAshish GuptaAn example pseudocode to setup and process NUM_OPS stateless ops with each of length OP_LEN
333a584d3beSAshish Guptausing priv_xform would look like:
334a584d3beSAshish Gupta
335a584d3beSAshish Gupta.. code-block:: c
336a584d3beSAshish Gupta
337a584d3beSAshish Gupta    /*
338a584d3beSAshish Gupta     * pseudocode for stateless compression
339a584d3beSAshish Gupta     */
340a584d3beSAshish Gupta
34135bd0a5cSSean Morrissey    uint8_t cdev_id = rte_compressdev_get_dev_id(<PMD name>);
342a584d3beSAshish Gupta
343a584d3beSAshish Gupta    /* configure the device. */
344a584d3beSAshish Gupta    if (rte_compressdev_configure(cdev_id, &conf) < 0)
345a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to configure compressdev %u", cdev_id);
346a584d3beSAshish Gupta
347a584d3beSAshish Gupta    if (rte_compressdev_queue_pair_setup(cdev_id, 0, NUM_MAX_INFLIGHT_OPS,
348a584d3beSAshish Gupta                            socket_id()) < 0)
349a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
350a584d3beSAshish Gupta
351a584d3beSAshish Gupta    if (rte_compressdev_start(cdev_id) < 0)
352a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to start device\n");
353a584d3beSAshish Gupta
354a584d3beSAshish Gupta    /* setup compress transform */
3551525374aSAdam Dybkowski    struct rte_comp_xform compress_xform = {
356a584d3beSAshish Gupta        .type = RTE_COMP_COMPRESS,
357a584d3beSAshish Gupta        .compress = {
358a584d3beSAshish Gupta            .algo = RTE_COMP_ALGO_DEFLATE,
359a584d3beSAshish Gupta            .deflate = {
360a584d3beSAshish Gupta                .huffman = RTE_COMP_HUFFMAN_DEFAULT
361a584d3beSAshish Gupta            },
362a584d3beSAshish Gupta            .level = RTE_COMP_LEVEL_PMD_DEFAULT,
363a584d3beSAshish Gupta            .chksum = RTE_COMP_CHECKSUM_NONE,
364a584d3beSAshish Gupta            .window_size = DEFAULT_WINDOW_SIZE,
365a584d3beSAshish Gupta            .hash_algo = RTE_COMP_HASH_ALGO_NONE
366a584d3beSAshish Gupta        }
367a584d3beSAshish Gupta    };
368a584d3beSAshish Gupta
369a584d3beSAshish Gupta    /* create priv_xform and initialize it for the compression device. */
3701525374aSAdam Dybkowski    rte_compressdev_info dev_info;
371a584d3beSAshish Gupta    void *priv_xform = NULL;
3721525374aSAdam Dybkowski    int shareable = 1;
373a584d3beSAshish Gupta    rte_compressdev_info_get(cdev_id, &dev_info);
3741525374aSAdam Dybkowski    if (dev_info.capabilities->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
3751525374aSAdam Dybkowski        rte_compressdev_private_xform_create(cdev_id, &compress_xform, &priv_xform);
376a584d3beSAshish Gupta    } else {
377a584d3beSAshish Gupta        shareable = 0;
378a584d3beSAshish Gupta    }
379a584d3beSAshish Gupta
380a584d3beSAshish Gupta    /* create operation pool via call to rte_comp_op_pool_create and alloc ops */
3811525374aSAdam Dybkowski    struct rte_comp_op *comp_ops[NUM_OPS];
382a584d3beSAshish Gupta    rte_comp_op_bulk_alloc(op_pool, comp_ops, NUM_OPS);
383a584d3beSAshish Gupta
384a584d3beSAshish Gupta    /* prepare ops for compression operations */
385a584d3beSAshish Gupta    for (i = 0; i < NUM_OPS; i++) {
386a584d3beSAshish Gupta        struct rte_comp_op *op = comp_ops[i];
387a584d3beSAshish Gupta        if (!shareable)
3881525374aSAdam Dybkowski            rte_compressdev_private_xform_create(cdev_id, &compress_xform, &op->priv_xform)
389a584d3beSAshish Gupta        else
3901525374aSAdam Dybkowski            op->private_xform = priv_xform;
3911525374aSAdam Dybkowski        op->op_type = RTE_COMP_OP_STATELESS;
3921525374aSAdam Dybkowski        op->flush_flag = RTE_COMP_FLUSH_FINAL;
393a584d3beSAshish Gupta
394a584d3beSAshish Gupta        op->src.offset = 0;
395a584d3beSAshish Gupta        op->dst.offset = 0;
396a584d3beSAshish Gupta        op->src.length = OP_LEN;
397a584d3beSAshish Gupta        op->input_chksum = 0;
398a584d3beSAshish Gupta        setup op->m_src and op->m_dst;
399a584d3beSAshish Gupta    }
400a584d3beSAshish Gupta    num_enqd = rte_compressdev_enqueue_burst(cdev_id, 0, comp_ops, NUM_OPS);
401d629b7b5SJohn McNamara    /* wait for this to complete before enqueuing next*/
402a584d3beSAshish Gupta    do {
403a584d3beSAshish Gupta        num_deque = rte_compressdev_dequeue_burst(cdev_id, 0 , &processed_ops, NUM_OPS);
404a584d3beSAshish Gupta    } while (num_dqud < num_enqd);
405a584d3beSAshish Gupta
406a584d3beSAshish Gupta
407a584d3beSAshish GuptaStateless and OUT_OF_SPACE
408*4c948437SCiara Power~~~~~~~~~~~~~~~~~~~~~~~~~~
409a584d3beSAshish Gupta
410*4c948437SCiara PowerOUT_OF_SPACE is a condition when the output buffer runs out of space and where the PMD
411*4c948437SCiara Powerstill has more data to produce. If the PMD runs into such condition, then the PMD returns
412*4c948437SCiara PowerRTE_COMP_OP_OUT_OF_SPACE_TERMINATED error. In such case, the PMD resets itself and can set
413a584d3beSAshish Guptaconsumed=0 and produced=amount of output it could produce before hitting out_of_space.
414*4c948437SCiara PowerThe application would need to resubmit the whole input with a larger output buffer, if it
415a584d3beSAshish Guptawants the operation to be completed.
416a584d3beSAshish Gupta
417a584d3beSAshish GuptaHash in Stateless
418a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~
419*4c948437SCiara PowerIf hash is enabled, the digest buffer will contain valid data after an op is successfully
420a584d3beSAshish Guptaprocessed i.e. dequeued with status = RTE_COMP_OP_STATUS_SUCCESS.
421a584d3beSAshish Gupta
422a584d3beSAshish GuptaChecksum in Stateless
423a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~
424*4c948437SCiara PowerIf checksum is enabled, checksum will only be available after an op is successfully
425a584d3beSAshish Guptaprocessed i.e. dequeued with status = RTE_COMP_OP_STATUS_SUCCESS.
426a584d3beSAshish Gupta
427*4c948437SCiara Power.. _compressdev_stateful_op:
428*4c948437SCiara Power
429a584d3beSAshish GuptaCompression API Stateful operation
430a584d3beSAshish Gupta-----------------------------------
431a584d3beSAshish Gupta
432*4c948437SCiara PowerThe compression API provides RTE_COMP_FF_STATEFUL_COMPRESSION and
433*4c948437SCiara PowerRTE_COMP_FF_STATEFUL_DECOMPRESSION feature flag for the PMD to reflect
434a584d3beSAshish Guptaits support for Stateful operations.
435a584d3beSAshish Gupta
436*4c948437SCiara PowerA Stateful operation in DPDK compression means the application invokes enqueue
437*4c948437SCiara Powerburst() multiple times to process a related chunk of data because the
438*4c948437SCiara Powerapplication broke the data into several ops.
439a584d3beSAshish Gupta
440*4c948437SCiara PowerIn such cases
441a584d3beSAshish Gupta- ops are setup with op_type RTE_COMP_OP_STATEFUL,
442*4c948437SCiara Power- all ops except the last are set with flush value = RTE_COMP_FLUSH_NONE/SYNC
443*4c948437SCiara Powerand the last is set with flush value RTE_COMP_FLUSH_FULL/FINAL.
444a584d3beSAshish Gupta
445*4c948437SCiara PowerIn case of either one or all of the above conditions, the PMD initiates
446*4c948437SCiara Powerstateful processing and releases acquired resources after processing the
447a584d3beSAshish Guptaoperation with flush value = RTE_COMP_FLUSH_FULL/FINAL is complete.
448*4c948437SCiara PowerUnlike stateless, the application can enqueue only one stateful op from
449*4c948437SCiara Powera particular stream at a time and must attach a stream handle
450a584d3beSAshish Guptato each op.
451a584d3beSAshish Gupta
452a584d3beSAshish GuptaStream in Stateful operation
453a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~
454a584d3beSAshish Gupta
455*4c948437SCiara PowerA stream in DPDK compression is a logical entity which identifies a related set of ops.
456*4c948437SCiara PowerFor example, one large file broken into multiple chunks, then the file is represented by a stream,
457*4c948437SCiara Powerand each chunk of that file is represented by a compression op ``rte_comp_op``.
458*4c948437SCiara PowerWhenever an application wants stateful processing of such data, then it must get a stream handle
459*4c948437SCiara Powervia making call to ``rte_compressdev_stream_create()`` with an xform, which will return an opaque
460*4c948437SCiara Powerstream handle to attach to all of the ops carrying data of that stream.
461*4c948437SCiara PowerIn stateful processing, every op requires previous op data for compression/decompression.
462*4c948437SCiara PowerA PMD allocates and sets up resources such as history, states, etc. within a stream,
463*4c948437SCiara Powerwhich are maintained during the processing of related ops.
464a584d3beSAshish Gupta
465*4c948437SCiara PowerUnlike priv_xforms, a stream is always a NON_SHAREABLE entity. One stream handle must be attached
466*4c948437SCiara Powerto only one set of related ops and cannot be reused until all of them are processed with a
467*4c948437SCiara Powersuccess/failure status.
468a584d3beSAshish Gupta
469a584d3beSAshish Gupta.. figure:: img/stateful-op.*
470a584d3beSAshish Gupta
471a584d3beSAshish Gupta   Stateful Ops
472a584d3beSAshish Gupta
473a584d3beSAshish Gupta
474*4c948437SCiara PowerAn application should call ``rte_compressdev_stream_create()`` and attach it to the op before
4751525374aSAdam Dybkowskienqueuing them for processing and free via ``rte_compressdev_stream_free()`` during
476*4c948437SCiara Powertermination. All ops that are to be processed statefully should carry the *same* stream.
477a584d3beSAshish Gupta
478*4c948437SCiara PowerSee the `DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_ for details.
479a584d3beSAshish Gupta
480*4c948437SCiara PowerAn example pseudocode to set up and process a stream having NUM_CHUNKS,
481*4c948437SCiara Powerwith each chunk size of CHUNK_LEN, would look like:
482a584d3beSAshish Gupta
483a584d3beSAshish Gupta.. code-block:: c
484a584d3beSAshish Gupta
485a584d3beSAshish Gupta    /*
486a584d3beSAshish Gupta     * pseudocode for stateful compression
487a584d3beSAshish Gupta     */
488a584d3beSAshish Gupta
48935bd0a5cSSean Morrissey    uint8_t cdev_id = rte_compressdev_get_dev_id(<PMD name>);
490a584d3beSAshish Gupta
491a584d3beSAshish Gupta    /* configure the  device. */
492a584d3beSAshish Gupta    if (rte_compressdev_configure(cdev_id, &conf) < 0)
493a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to configure compressdev %u", cdev_id);
494a584d3beSAshish Gupta
495a584d3beSAshish Gupta    if (rte_compressdev_queue_pair_setup(cdev_id, 0, NUM_MAX_INFLIGHT_OPS,
496a584d3beSAshish Gupta                                    socket_id()) < 0)
497a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
498a584d3beSAshish Gupta
499a584d3beSAshish Gupta    if (rte_compressdev_start(cdev_id) < 0)
500a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to start device\n");
501a584d3beSAshish Gupta
502a584d3beSAshish Gupta    /* setup compress transform. */
5031525374aSAdam Dybkowski    struct rte_comp_xform compress_xform = {
504a584d3beSAshish Gupta        .type = RTE_COMP_COMPRESS,
505a584d3beSAshish Gupta        .compress = {
506a584d3beSAshish Gupta            .algo = RTE_COMP_ALGO_DEFLATE,
507a584d3beSAshish Gupta            .deflate = {
508a584d3beSAshish Gupta                .huffman = RTE_COMP_HUFFMAN_DEFAULT
509a584d3beSAshish Gupta            },
510a584d3beSAshish Gupta            .level = RTE_COMP_LEVEL_PMD_DEFAULT,
511a584d3beSAshish Gupta            .chksum = RTE_COMP_CHECKSUM_NONE,
512a584d3beSAshish Gupta            .window_size = DEFAULT_WINDOW_SIZE,
513a584d3beSAshish Gupta            .hash_algo = RTE_COMP_HASH_ALGO_NONE
514a584d3beSAshish Gupta        }
515a584d3beSAshish Gupta    };
516a584d3beSAshish Gupta
517a584d3beSAshish Gupta    /* create stream */
5181525374aSAdam Dybkowski    void *stream;
5191525374aSAdam Dybkowski    rte_compressdev_stream_create(cdev_id, &compress_xform, &stream);
520a584d3beSAshish Gupta
521a584d3beSAshish Gupta    /* create an op pool and allocate ops */
522a584d3beSAshish Gupta    rte_comp_op_bulk_alloc(op_pool, comp_ops, NUM_CHUNKS);
523a584d3beSAshish Gupta
524a584d3beSAshish Gupta    /* Prepare source and destination mbufs for compression operations */
525a584d3beSAshish Gupta    unsigned int i;
526a584d3beSAshish Gupta    for (i = 0; i < NUM_CHUNKS; i++) {
527a584d3beSAshish Gupta        if (rte_pktmbuf_append(mbufs[i], CHUNK_LEN) == NULL)
528a584d3beSAshish Gupta            rte_exit(EXIT_FAILURE, "Not enough room in the mbuf\n");
529a584d3beSAshish Gupta        comp_ops[i]->m_src = mbufs[i];
530a584d3beSAshish Gupta        if (rte_pktmbuf_append(dst_mbufs[i], CHUNK_LEN) == NULL)
531a584d3beSAshish Gupta            rte_exit(EXIT_FAILURE, "Not enough room in the mbuf\n");
532a584d3beSAshish Gupta        comp_ops[i]->m_dst = dst_mbufs[i];
533a584d3beSAshish Gupta    }
534a584d3beSAshish Gupta
535a584d3beSAshish Gupta    /* Set up the compress operations. */
536a584d3beSAshish Gupta    for (i = 0; i < NUM_CHUNKS; i++) {
537a584d3beSAshish Gupta        struct rte_comp_op *op = comp_ops[i];
538a584d3beSAshish Gupta        op->stream = stream;
539a584d3beSAshish Gupta        op->m_src = src_buf[i];
540a584d3beSAshish Gupta        op->m_dst = dst_buf[i];
5411525374aSAdam Dybkowski        op->op_type = RTE_COMP_OP_STATEFUL;
542a584d3beSAshish Gupta        if (i == NUM_CHUNKS-1) {
543a584d3beSAshish Gupta            /* set to final, if last chunk*/
5441525374aSAdam Dybkowski            op->flush_flag = RTE_COMP_FLUSH_FINAL;
545a584d3beSAshish Gupta        } else {
546a584d3beSAshish Gupta            /* set to NONE, for all intermediary ops */
5471525374aSAdam Dybkowski            op->flush_flag = RTE_COMP_FLUSH_NONE;
548a584d3beSAshish Gupta        }
549a584d3beSAshish Gupta        op->src.offset = 0;
550a584d3beSAshish Gupta        op->dst.offset = 0;
551a584d3beSAshish Gupta        op->src.length = CHUNK_LEN;
552a584d3beSAshish Gupta        op->input_chksum = 0;
553a584d3beSAshish Gupta        num_enqd = rte_compressdev_enqueue_burst(cdev_id, 0, &op[i], 1);
554d629b7b5SJohn McNamara        /* wait for this to complete before enqueuing next*/
555a584d3beSAshish Gupta        do {
556a584d3beSAshish Gupta            num_deqd = rte_compressdev_dequeue_burst(cdev_id, 0 , &processed_ops, 1);
557a584d3beSAshish Gupta        } while (num_deqd < num_enqd);
5581525374aSAdam Dybkowski        /* analyze the amount of consumed and produced data before pushing next op*/
559a584d3beSAshish Gupta    }
560a584d3beSAshish Gupta
561a584d3beSAshish Gupta
562a584d3beSAshish GuptaStateful and OUT_OF_SPACE
563*4c948437SCiara Power~~~~~~~~~~~~~~~~~~~~~~~~~
564a584d3beSAshish Gupta
565*4c948437SCiara PowerIf a PMD supports stateful operation, then an OUT_OF_SPACE status is not an actual
566*4c948437SCiara Powererror for the PMD. In such a case, the PMD returns with status
567a584d3beSAshish GuptaRTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE with consumed = number of input bytes
568*4c948437SCiara Powerread, and produced = length of complete output buffer.
569*4c948437SCiara PowerThe application should enqueue the next op with source starting at consumed+1, and an
570a584d3beSAshish Guptaoutput buffer with available space.
571a584d3beSAshish Gupta
572a584d3beSAshish GuptaHash in Stateful
573a584d3beSAshish Gupta~~~~~~~~~~~~~~~~
574*4c948437SCiara PowerIf enabled, the digest buffer will contain valid digest after the last op in a stream
5751525374aSAdam Dybkowski(having flush = RTE_COMP_FLUSH_FINAL) is successfully processed i.e. dequeued
576a584d3beSAshish Guptawith status = RTE_COMP_OP_STATUS_SUCCESS.
577a584d3beSAshish Gupta
578a584d3beSAshish GuptaChecksum in Stateful
579a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~
580*4c948437SCiara PowerIf enabled, the checksum will only be available after the last op in a stream
5811525374aSAdam Dybkowski(having flush = RTE_COMP_FLUSH_FINAL) is successfully processed i.e. dequeued
582a584d3beSAshish Guptawith status = RTE_COMP_OP_STATUS_SUCCESS.
583a584d3beSAshish Gupta
584a584d3beSAshish GuptaBurst in compression API
585*4c948437SCiara Power------------------------
586a584d3beSAshish Gupta
587a584d3beSAshish GuptaScheduling of compression operations on DPDK's application data path is
588a584d3beSAshish Guptaperformed using a burst oriented asynchronous API set. A queue pair on a compression
589*4c948437SCiara Powerdevice accepts a burst of compression operations using the enqueue burst API.
590*4c948437SCiara PowerOn physical devices the enqueue burst API will place the operations to be processed
591a584d3beSAshish Guptaon the device's hardware input queue, for virtual devices the processing of the
592a584d3beSAshish Guptaoperations is usually completed during the enqueue call to the compression
593a584d3beSAshish Guptadevice. The dequeue burst API will retrieve any processed operations available
594a584d3beSAshish Guptafrom the queue pair on the compression device, from physical devices this is usually
595*4c948437SCiara Powerdirectly from the devices processed queue, and for virtual device's from an
5966b1a74efSThierry Herbelot``rte_ring`` where processed operations are placed after being processed on the
597a584d3beSAshish Guptaenqueue call.
598a584d3beSAshish Gupta
599*4c948437SCiara PowerA burst in DPDK compression can be a combination of stateless and stateful operations with a
600*4c948437SCiara Powercondition that for stateful ops only one op at a time should be enqueued from a particular stream
601*4c948437SCiara Poweri.e. two ops should never belong to the same stream in a single burst.
602*4c948437SCiara PowerHowever, a burst may contain multiple stateful ops, as long as each op is attached to a different
603*4c948437SCiara Powerstream, i.e. a burst can look like:
604a584d3beSAshish Gupta
605a584d3beSAshish Gupta+---------------+--------------+--------------+-----------------+--------------+--------------+
606a584d3beSAshish Gupta| enqueue_burst | op1.no_flush | op2.no_flush | op3.flush_final | op4.no_flush | op5.no_flush |
607a584d3beSAshish Gupta+---------------+--------------+--------------+-----------------+--------------+--------------+
608a584d3beSAshish Gupta
609*4c948437SCiara PowerWhere, op1 .. op5 all belong to different independent data units. op1, op2, op4, op5 must be
610*4c948437SCiara Powerstateful as stateless ops can only use flush full or final and op3 can be of type stateless or
611*4c948437SCiara Powerstateful. Every op with type set to RTE_COMP_OP_STATELESS must be attached to priv_xform and
612*4c948437SCiara Powerevery op with type set to RTE_COMP_OP_STATEFUL *must* be attached to stream.
613a584d3beSAshish Gupta
614a584d3beSAshish GuptaSince each operation in a burst is independent and thus can be completed
615*4c948437SCiara Powerout of order, applications which need ordering should setup a per-op user data
616*4c948437SCiara Powerarea, with reordering information so that it can determine enqueue order at
617a584d3beSAshish Guptadequeue.
618a584d3beSAshish Gupta
619*4c948437SCiara PowerAlso, if multiple threads calls enqueue_burst() on the same queue pair then it's
620*4c948437SCiara Powerthe application's responsibility to use a proper locking mechanism to ensure
621*4c948437SCiara Powerexclusive enqueuing of operations.
622a584d3beSAshish Gupta
623a584d3beSAshish GuptaEnqueue / Dequeue Burst APIs
624a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~
625a584d3beSAshish Gupta
626a584d3beSAshish GuptaThe burst enqueue API uses a compression device identifier and a queue pair
627a584d3beSAshish Guptaidentifier to specify the compression device queue pair to schedule the processing on.
628a584d3beSAshish GuptaThe ``nb_ops`` parameter is the number of operations to process which are
629a584d3beSAshish Guptasupplied in the ``ops`` array of ``rte_comp_op`` structures.
630a584d3beSAshish GuptaThe enqueue function returns the number of operations it actually enqueued for
631a584d3beSAshish Guptaprocessing, a return value equal to ``nb_ops`` means that all packets have been
632a584d3beSAshish Guptaenqueued.
633a584d3beSAshish Gupta
634a584d3beSAshish GuptaThe dequeue API uses the same format as the enqueue API but
635a584d3beSAshish Guptathe ``nb_ops`` and ``ops`` parameters are now used to specify the max processed
636a584d3beSAshish Guptaoperations the user wishes to retrieve and the location in which to store them.
637a584d3beSAshish GuptaThe API call returns the actual number of processed operations returned, this
638a584d3beSAshish Guptacan never be larger than ``nb_ops``.
639a584d3beSAshish Gupta
640a584d3beSAshish GuptaSample code
641a584d3beSAshish Gupta-----------
642a584d3beSAshish Gupta
643a584d3beSAshish GuptaThere are unit test applications that show how to use the compressdev library inside
644*4c948437SCiara Power``app/test/test_compressdev.c``
645a584d3beSAshish Gupta
646a584d3beSAshish GuptaCompression Device API
647a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~
648a584d3beSAshish Gupta
649*4c948437SCiara PowerThe compressdev Library API is described in the
650*4c948437SCiara Power`DPDK API Reference <https://doc.dpdk.org/api/rte__compressdev_8h.html>`_.
651